Repository navigation
Close a stage's LAMMPS session when the stage raises - #286
Merged
Merged
Conversation
Every stage method (run_averaging, run_integration, reversible_scaling, temperature_scaling, pressure_scaling, scan_temperature_range) creates its own LAMMPS session and closes it as its last statement, so an exception anywhere in the stage leaves the session open. In library mode that keeps the pylammpsmpi/executorlib workers alive until the process exits. `BaseRunner` gains `__enter__`/`__exit__`, and `Phase` gains a context that closes the session opened by the stage it wraps. The routines now run each stage call as `with job: job.stage(...)`. Stage bodies are untouched apart from creating the session via `self._open_lammps()`, which remembers it. On success the stage has already closed the session and the second close is a no-op on both backends (`LibraryRunner` guards on `_closed`; the executable runner's buffer is already empty and the restart-file removal is guarded). If `close()` itself fails while an exception is propagating, the close error is logged and the original exception wins. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
`Phase._open_lammps()` only learns about the runner once `ph.create_object()` returns, so a failure while setting the session up left it open: `create_object` emits the init commands after constructing the runner, and `LibraryRunner.__init__` activates ML-IAP after the executor already exists. Close the runner in both places before re-raising, through its `__exit__` so a failing close cannot mask the setup error. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Contributor
Author
|
@srmnitc I had issues before with calphy/executorlib when lammps errors during a run, e.g. on exploding 'Domain too large for neighbor bins'. This should help. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Each stage method (
run_averaging,run_integration,reversible_scaling,temperature_scaling,pressure_scaling,scan_temperature_range) creates its own LAMMPS session and closes it as its last statement. So if anything in the stage raises, the session stays open. In library mode that keeps the pylammpsmpi/executorlib workers alive until the process exits.Changes
BaseRunnergets__enter__/__exit__, which close the session on the way out, with or without an exception (calphy/runner.py).Phasegets the same:__exit__closes the session opened by the stage it wraps. Stages now create their session withlmp = self._open_lammps()instead ofph.create_object(...), so the job remembers it. Stage bodies are otherwise unchanged.routines.py(and the averaging call indcci.py), each stage call becomesOn success the stage has already closed the session itself, and the second close does nothing on both backends:
LibraryRunnerchecks_closed, the executable runner's buffer is already empty, and the restart-file removal checks that the file exists.__exit__never suppresses the exception. Ifclose()itself fails while an exception is already propagating, the close error is logged and the original exception is re-raised. A dead LAMMPS worker can easily make the close fail, but the error that matters is the one that got us there.Setup failures are covered too.
create_objectemits the init commands after it has constructed the runner, andLibraryRunner.__init__activates ML-IAP after the executor already exists. If either step raises, the runner closes itself (through__exit__) before the error propagates, because at that point nobody else holds a reference to it.The DCCI driver's own two-cell sessions (
dcci.py,lmps[phase]) are not touched here.Testing
close()raises when no exception is in flight and does not mask one that is,with job:closes the session of a failed stage, and a failure in ML-IAP activation or in the init commands closes the executor. Both of those fail without the fix.🤖 Generated with Claude Code