-
Notifications
You must be signed in to change notification settings - Fork 14
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
Implement concurrent.futures.ProcessPoolExecutor interface #1155
Conversation
Example code: ``` from concurrent.futures import ProcessPoolExecutor from pyiron_atomistics import Project pr = Project('test') job = pr.create.job.Lammps("lmp") job.structure = pr.create.structure.ase.bulk("Al", cubic=True) job.server.executor = ProcessPoolExecutor() job.server.cores = 2 fs = job.run() print(fs.done()) print(fs.result()) print(fs.done()) ```
An alternative suggestion would be to attach the future object to job.server.future, then the run function does not return any output, if that is more desirable. |
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.
Yeah, looks good. I do think the future should be put somewhere else, probably on the server as you suggest. But that's the only non-local/big change; the rest is just a bunch of very specific requests.
EDIT: Ok actually, I have one more UX concern: the error raised when you mix executor
children with masters is not very clear. E.g.
from concurrent.futures import ProcessPoolExecutor
from pyiron_atomistics import Project
pr = Project('tmp')
pr.remove_jobs(recursive=True, silently=True)
job = pr.create.job.Lammps("lmp")
job.structure = pr.create.structure.ase.bulk("Al", cubic=True)
job.server.executor = ProcessPoolExecutor(max_workers=4)
master = pr.create.job.Murnaghan("murn")
master.ref_job = job
master.run()
Runs fine without the executor line, but with it gives a stack trace ending in
File ~/work/pyiron/pyiron_base/pyiron_base/jobs/master/parallel.py:556, in ParallelMaster.run_static(self)
554 self._run_if_master_modal_child_non_modal(job)
555 else:
--> 556 raise TypeError()
557 else:
558 self.status.collect = True
TypeError:
It would be great to have something more informative. I also checked SerialMasterBase
and it's got the same safety else: raise TypeError()
clause that should keep the behaviour reasonable, but will need its own informative error message.
The future is now moved to
Done. |
fc997f7
to
5fb644c
Compare
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.
I like the modifications and they addressed all my original concerns, but per my comment on 1154 I played around a bit combining it with other elements of the codebase and ran into trouble.
The issue I see is that this is not yet deeply integrated enough with the rest of the Server.run_mode
options. What is needed is to think through the different combinations of user actions, decide what the outcome of these actions should be, and then enforce these outcomes in the tests -- and the test part really is crticial, e.g. "turning it on and turning it off again" was never actually tested and my original suggestion resulted in an exception!
I'm not familiar off-hand with all the ways we have to modify the run_mode
, but here is one example of what I'm thinking of:
from concurrent.futures import ProcessPoolExecutor
from pyiron_atomistics import Project
pr = Project('tmp')
pr.remove_jobs(recursive=True, silently=True)
job = pr.create.job.Lammps("lmp")
job.structure = pr.atomistics.structure.bulk("Al")
job.server.executor = ProcessPoolExecutor()
print(job.server.run_mode)
# >>> executor
job.interactive_open()
print(job.server.run_mode, job.server.executor is not None)
# >>> interactive True
job.run()
print(job.output.energy_pot, job.server.future)
# >>> [-3.36] None
job2 = job.copy()
print(job.server.run_mode, job2.server.run_mode)
# >>> interactive executor
I think it's fine that turning on interactive_open()
supplanted the executor
and left the future
empty, but then It's weird that the server.executor
stays populated. Even worse, if we copy the interactively-opened job, the copy winds up with a different run mode! In this particular case, I guess setting the run mode to interactive needs to clear the executor to None
?
I don't have super strong opinions right now about what the behaviour should be, but it shouldn't be left up to chance/side effects and decisions about the intended interface need to be enforced by the tests.
@samwaseda, I think that after this PR is resolved most of the remaining changes for flux in particular over in #1154 will be pretty straightforward; it's probably more worthwhile for you to review here before reading there.
Co-authored-by: Liam Huber <[email protected]>
I fixed the issue and reset the executor when the run_mode is changed afterwards. Currently, the interactive mode is not yet compatible to the executor, these are two separate developments and we have to think more how an integration could look like. |
Co-authored-by: Liam Huber <[email protected]>
@liamhuber , @niklassiemer and @samwaseda Any other feedback? Otherwise I would like to merge this pull request, so we can merge the flux pull request on Friday and have everything ready next Monday. |
Am generally happy with this new interface, it feels more natural and powerful. If this works with other concurrent futures executors (and I don't see why not) it might also give us a why replace remote jobs with specific executors, like parsl or dask (notwithstanding their other shortcomings). A small additional feature I would like is that One can of worms I think we need to open is canceling futures. Say I submit a bunch of things and make a mistake or my workflow converges and I don't need additional calculations. I suppose Other than that, I think it's good stuff. |
I like the idea and I guess we can extend this concept in a way that if you remove the jobs using The other way of cancelling the futures resulting the job status to change sounds more difficult to me and would require more of a rewrite of the integration of the |
Do I understand correctly that with the last commit we can simply use |
You can always use
|
ok that was not quite my question. I wanted to ask whether |
no, and this was never the case. You can use |
Aaand one of my kids needs to be picked up from daycare sick. Probably won't be able to do this. |
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.
I am fine with this state of the new interface.
Just for clarity, the development releases can target any branch (correct me if I'm wrong about this, @srmnitc). So while it looks like we'll merge this by the end of the week anyhow, there is no actual need to merge it in order to dev release the functionality -- the dev release can target #1154 directly. This is the point of the dev-release workflow: to allow releasing functionality without feeling time-pressured to merge things into main. |
As far as I can see the dev release is not yet pushed to conda. |
Yes correct! |
I was hoping some of you would add a review, since the tests pass, I will go ahead and merge. |
@jan-janssen @liamhuber Both base and atomistics have the dev release functionality now. |
Co-authored-by: Liam Huber <[email protected]>
I'm re-reviewing. Almost done. Please hold changes for a minute |
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.
- I implemented your suggestion to not copy jobs with futures that aren't done and tested it
- I still want the job-independent tests moved out of the job tests and into the server tests
K super, thanks! EDIT: thanks for waiting. For future readers I'm not just thanking myself -- there was a timely thumbs up 😝 All done. A couple more minor requests re testing. I still get a little nervous about potential weird states that |
Co-authored-by: Liam Huber <[email protected]>
Co-authored-by: Liam Huber <[email protected]>
Co-authored-by: Liam Huber <[email protected]>
@liamhuber I merged your changes plus fixes - so from my perspective it is ready to be merged now. What do you think? |
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.
I would still like the server-only tests moved to the lowest place they can go, but that's not approval-prohibiting.
🚀
Done |
Example code: