Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Write an example of multiple federates using a single core #100

Open
trevorhardy opened this issue Dec 19, 2023 · 10 comments
Open

Write an example of multiple federates using a single core #100

trevorhardy opened this issue Dec 19, 2023 · 10 comments
Assignees
Labels
documentation Need to add documentation to an existing example new example New example needed

Comments

@trevorhardy
Copy link
Contributor

HELICS allows multiple federates to use a single core, effectively representing multiple federates in a single executable. This is more commonly used by developers and is something of a special edge case in the user space. It would be good to have an example of it, though.

@trevorhardy trevorhardy added the enhancement New feature or request label Dec 19, 2023
@trevorhardy trevorhardy added the new example New example needed label Mar 26, 2024
@trevorhardy trevorhardy added documentation Need to add documentation to an existing example and removed enhancement New feature or request labels Jan 2, 2025
@trevorhardy
Copy link
Contributor Author

@phlptp, I've been poking around in the C API and I'm not sure it is possible to put multiple federates on a single core right now. There's helicsFederateGetCore() which could be used to get the core object from an existing federate. I'm not seeing, though, a way to tell a new federate to use an existing core. I assume this would be something that would be defined as a part of the federateInfo object but if its there, I'm not seeing it. Maybe something like helicsFederateInfoSetCore?

Or maybe I'm entirely mis-understanding how to go about this.

@phlptp
Copy link
Member

phlptp commented Jan 2, 2025 via email

@trevorhardy
Copy link
Contributor Author

trevorhardy commented Jan 2, 2025

@phlptp, next challenge with this: handling blocking calls. I'm trying to enter executing mode with two federates and I thought I could use the helicsEnterExecutingModeAsync() to allow both federates on the same core to enter executing mode without blocking each other and then I would just need to call helicsEnterExecutingModeComplete(). Since both had requested to enter executing mode (asynchronously) both would have been granted executing mode and the ...complete() would confirm this and the co-simulation would proceed.

Here's the code:

h.helicsFederateEnterExecutingModeAsync(battery_fed)
h.helicsFederateEnterExecutingModeAsync(charger_fed)
h.helicsFederateEnterExecutingModeComplete(battery_fed) # Should have been granted executing mode, right?
h.helicsFederateEnterExecutingModeComplete(charger_fed)

Right now, I'm making it through the first two lines but the third line never returns. I am misunderstanding how this should work?

@phlptp
Copy link
Member

phlptp commented Jan 2, 2025

Do you have a third federate in there? If there is just two of them that should work? If there is a third or some other reason it is blocking then the third line will block until it is granted. There is also an "isAsyncOperationComplete" method that would tell you if the method has completed.

@trevorhardy
Copy link
Contributor Author

Good call on the federate count; I had fat-fingered the number of federates the common-core was looking for.

Now the hang-up appears to be the wait_for current_time_update flag that the battery has set. Even when I move the battery's ...complete() to the last line it blocks. When I clear the flag it is able to move past that point.

@phlptp
Copy link
Member

phlptp commented Jan 2, 2025

If the battery has that flag set it won't be able to grant the time unless the charger will not generate any data at time zero, so it would need to have requested the next time, otherwise it is still executing at time 0 and could send the battery a message at that time. So you would need to requestTimeAsync on the charger before the complete for the executing mode on the battery.

@trevorhardy
Copy link
Contributor Author

This is the order I have now and hangs if battery has wait_for_current_time_update set:

h.helicsFederateEnterExecutingModeAsync(charger_fed)
h.helicsFederateEnterExecutingModeAsync(battery_fed)
h.helicsFederateEnterExecutingModeComplete(charger_fed)
h.helicsFederateEnterExecutingModeComplete(battery_fed)

"charger_fed" is able to complete but the last line never returns. Clearing the flag allows both federates to complete.

@phlptp
Copy link
Member

phlptp commented Jan 2, 2025

This is what you would need for the battery to enter executing mode with the flag set

h.helicsFederateEnterExecutingModeAsync(charger_fed)
h.helicsFederateEnterExecutingModeAsync(battery_fed)
h.helicsFederateEnterExecutingModeComplete(charger_fed)
h.helicsFederateRequestTimeAsync(charger_fed,1.0)
h.helicsFederateEnterExecutingModeComplete(battery_fed)

@trevorhardy
Copy link
Contributor Author

OK, after much trial and error, I got the whole example to run to completion. Thanks for the guidance, @phlptp.

Now I've got to figure out why the results don't match the example on which it is based.

@trevorhardy
Copy link
Contributor Author

Example is now working and produces the same results as the fundamental default example on which it is based. Next up, write up the documentation page and get this pushed up into the repos.

trevorhardy added a commit that referenced this issue Jan 4, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Need to add documentation to an existing example new example New example needed
Projects
None yet
Development

No branches or pull requests

3 participants