-
Notifications
You must be signed in to change notification settings - Fork 2
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
Use parallel processing #140
Conversation
This changes the server to send a list of several p-frames to the clients. The clients process the frames in parallel using python's multiprocessing module. The tables used by photospline are shared between the processes. The number of parallel trays can be controlled with the new option --parallel-trays
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the benefit of parallelizing within a client, in terms of empirical performance? Is the main lag in the icetray IO or computational? I've assumed it's computational. With the ewms-pilot framework, if a single one of these "grouped" pixels caused an exception or the pixel "group" lands on a bad worker node, then the whole "group" will need to be auto-re-enqueued instead of a single pixel.
This should work. I'm just not terribly happy with doing multiple pixels per message, as it goes somewhat against the long-term vision for EWMS. I'd be happier with the ewms-pilot processing multiple messages in parallel. (at least, as long as the message processing time was >> 1 second, so it's actually compute bound) I assume it's using shared memory for the tables, and has the potential problem of boost::interprocess screwing up the shared memory lock? Is there any protection on that not creating a black hole node? |
I think parallelizing the client would be better accomplished by the ewms-pilot. Here, each client would create multiple processes each with an icetray for an arbitrary number of messages. This is currently in the planning stage. |
Added @briedel as he asked for this. |
Worth pointing out: packing too much into a single message will eventually throttle the broker Similarly, this could slow down the overall performance since we're waiting for all the pixels in a group to finish before sending the pixelrecos |
We are requesting 5 GB of RAM per pixel right now. This is really inefficient if we want to run this on the grid or expensive if we run this in the cloud and running photospline is shared memory mode is really finicky on the client side. I rather have this inside icetray to keep the implementation details away from the pilot beyond “batching” events together somehow. |
Based on the specs I got from @briedel, I identified three possible ways to accomplish parallel processing:
I went with 3 because it seemed like the easiest to implement. I don't know what ewms-pilot is, so I didn't consider it when choosing a solution. I would need more information to asses which one is best. Also note that using subprocess for multiple trays is exactly the same as how triggered corsika works and so far we haven't had any issues with shared memory locks Also note that the current main branch calls |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Giving a proper review of the changes, I think the code generally looks fine. I'm not sure if we want the default number of subprocesses to be 8 or 1 though.
|
||
# loop over the pframes to run in parallel | ||
for i, pframe in enumerate(pframes): | ||
outpath = Path(f"out{i:04}.pkl") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could this use a more unique path, either using tempfile
or maybe with the parent process pid? I'm thinking of the possibility of running two instances side by side, which could happen in EWMS.
@kjmeagher thanks for finding this. This should be optimized to one allocation, definitely |
@kjmeagher we talked this over and I think we've found a way to do this parallelization that's also friendly with message passing. If you wrap https://github.com/icecube/skymap_scanner/blob/main/skymap_scanner/client/client.py#L83-L96 with multiple async-loop calls, then the ewms-pilot will make a subprocess for each pilot. Each pilot processes a stream of messages (each with a single pixel & icetray). Note, you will need to give unique names to each pilot's in/out files, see https://github.com/icecube/skymap_scanner/blob/main/skymap_scanner/client/client.py#L73-L74. The This solves the slow-pixel problem by removing the grouped-pixels constraint. It doesn't solve the bad-node problem or the boost's potential shared-memory lock problem, but hopefully, the tradeoff is worth it. So, |
@ric-evans how does your plan propose to share memory? Will |
Right, this problem is specific to a particular reco, and we want to keep the scanner client generalized to support other styles of recos in the future. I think this is better suited to be solved when the tray is initiated, rather than in client.py. Are there shared memory tools within the photonics service we can use? Something that uses /dev/shm? |
Yes, good catch. The |
I think it already is using /dev/shm and iirc I thought we were able to get that working with the containers. @briedel are jobs still hanging for you on the cloud? |
They are not hanging anymore, but this with special settings for |
I don't know much about the internals of photospline so maybe @cnweaver or @jvansanten could say if there is a way to access the same instance in photospline in multiple different processes |
Yes, that was the entire point of the photospline v2 rewrite of the evaluation interface. I3PhotoSplineService should do this automatically, which is what was causing the hangs in containers, which are now fixed only by configuring the containers to have not-actually-shared shared memory. This is something that containers pretty much are designed to make difficult, so if people insist on using them, I don't think there's anything we can do/improve from the photospline/photonics side (in terms of enabling sharing; there are some race conditions which are exceedingly difficult to fix and can also cause hangs.) |
Thanks, @cnweaver. So, as long as we're running our multiple processes within the same container, will photospline take care of shared memory between these processes? |
I think that should work, providing the container-isolated shared memory is turned on. However, I don't think anyone has yet tried it. |
Does python multiprocessing somehow get around this containerization? My impression was that it wouldn't, but I don't have a sense of how pods work on the cloud. |
Using |
This changes the server to send a list of several p-frames to the clients.
The clients process the frames in parallel using python's multiprocessing
module. The tables used by photospline are shared between the processes.
The number of parallel trays can be controlled with the new option --parallel-trays