-
Notifications
You must be signed in to change notification settings - Fork 21
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
Running endless loops in parallel #196
Comments
How many PEs did you use to run the above code? Entry methods will run to completion or until the coroutine running the entry method voluntarily yields execution. If the above is running on one PE, one entry method will run forever. Here you will probably want at least 3 PEs: one for each Ox/Ax and one for the main chare. To ensure the Ox/Ax chares are placed on different PEs, you can change the chare creation to the following: ax_proxy = Chare(Ax, onPE=1)
ox_proxy = Chare(Ox, onPE=2) |
Hi ZwFink, Hmm, I applied your suggestions and tried 3 PEs and it still does not work...
In IntelliJ the output looks like this
|
Hi @ZwFink, this issue is related to the one you helped me a few days ago #194. @rd-marcel-haugwitz and me are working on this together. The last hint you gave me was this class ClientMap(ArrayMap):
def procNum(self, index):
return 0
...
myMap = Group(ClientMap)
controller = Array(Controller, args=[num_clients, num_cameras_per_client], map=myMap)
controller.run_forever() This works perfectly fine. Is this bad practice? Is there a better way to achieve this? |
Hi @ZwFink and @martinkoenig, with the ClientMap it works when I am starting with at least 2 PEs :-)
Thank you both for your help! Marcel |
Hi, the client map helped, but unfortunately we still have a problem. In our project we are making use of Reducers and Futures. In combination with endless loops this is not working. Do you have any idea? Are we doing something wrong?
|
That's interesting that using a PE map solves the problem. I think there are two problems here:
I think this issue was first a case of number 1, but then perhaps became a case of number 2. If we change the original example you provided to use import time
from charm4py import Chare, charm, coro, Array, Future
starttime = time.time()
class Ax(Chare):
def __init__(self, done_future):
self.done_future = done_future
@coro
def run(self):
iter_num = 0
while iter_num < 1000:
iter_num += 1
print(f'AX - I am element with counter {iter_num} ', self.thisIndex, 'on PE', charm.myPe())
if not iter_num % 100:
charm.sleep(1)
self.done_future()
class Ox(Chare):
def __init__(self, done_future):
self.done_future = done_future
@coro
def run(self):
iter_num = 0
while iter_num < 1000:
iter_num += 1
print(f'OX - I am element with counter {iter_num} ', self.thisIndex, 'on PE', charm.myPe())
if not iter_num % 100:
charm.sleep(1)
self.done_future()
def main(args):
done_future = Future(2)
ax_proxy = Chare(Ax, onPE=1, args=[done_future])
ox_proxy = Chare(Ox, onPE=1, args=[done_future])
combined_proxies = charm.combine(ax_proxy, ox_proxy)
combined_proxies.run()
done_future.get()
charm.exit()
charm.start(main) I also changed the code so a finite number of iterations are done, but this was just to control the amount of output put to the screen. In the output you will see that both Ax and Ox are printing. Also, if you change the above code so Ax/Ox are on separate PEs, you will see that both run at the same time but one always displays its output before the other. Also, changing the code so Ax/Ox write to a file rather than stdout shows that both run in parallel when used in different PEs. |
And regarding your most recent code, it looks like reductions might currently require all PEs to participate in some form, even if the PE's chares do not contribute anything. This might be a technical limitation of Charm++, which I will look into. For now, after each loop you can call @coro
def run_endless(self):
while True:
print('OX - I am element', self.thisIndex, 'on PE', charm.myPe())
time.sleep(1)
charm.sleep(0) And the output contains:
It's important to remember to use |
Hi @ZwFink, Thanks for help! |
Of course, but I'm saying that charm.sleep(0) could be used to overcome the issues with reductions outlined above at the cost of a few microseconds per camera image. You could do something like: while True:
image_data = get_image(image_source)
image_processor.process(image_data)
charm.sleep(0) Here the runtime won't actually sleep but will do the bookkeeping necessary to make progress on reductions happening on other PEs make progress and continue the next loop iteration. Does that make sense? It's a bit wonky but will fix that particular issue. |
I should have specified earlier that |
Hi @ZwFink , I added the webserver to the sample code (Installation of flask is required):
|
Hi,
I would like to run two classes with endlessly running loops in parallel.
But only one endless loop is starting....
Am I missing something? I am seeing only the output of one method in the console...
The text was updated successfully, but these errors were encountered: