executorlib 1.9.1__tar.gz → 1.9.3__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. executorlib-1.9.3/.gitignore +218 -0
  2. {executorlib-1.9.1 → executorlib-1.9.3}/PKG-INFO +22 -20
  3. {executorlib-1.9.1 → executorlib-1.9.3}/README.md +14 -12
  4. {executorlib-1.9.1 → executorlib-1.9.3}/pyproject.toml +8 -8
  5. {executorlib-1.9.1 → executorlib-1.9.3}/src/executorlib/_version.py +2 -2
  6. {executorlib-1.9.1 → executorlib-1.9.3}/src/executorlib/executor/flux.py +12 -12
  7. {executorlib-1.9.1 → executorlib-1.9.3}/src/executorlib/executor/single.py +8 -8
  8. {executorlib-1.9.1 → executorlib-1.9.3}/src/executorlib/executor/slurm.py +10 -10
  9. {executorlib-1.9.1 → executorlib-1.9.3}/src/executorlib/standalone/command.py +4 -4
  10. {executorlib-1.9.1 → executorlib-1.9.3}/src/executorlib/standalone/validate.py +2 -1
  11. {executorlib-1.9.1 → executorlib-1.9.3}/src/executorlib/task_scheduler/file/backend.py +14 -7
  12. {executorlib-1.9.1 → executorlib-1.9.3}/src/executorlib/task_scheduler/file/spawner_pysqa.py +10 -3
  13. {executorlib-1.9.1 → executorlib-1.9.3}/src/executorlib/task_scheduler/interactive/blockallocation.py +57 -5
  14. {executorlib-1.9.1 → executorlib-1.9.3}/src/executorlib/task_scheduler/interactive/spawner_flux.py +5 -5
  15. {executorlib-1.9.1 → executorlib-1.9.3}/src/executorlib/task_scheduler/interactive/spawner_pysqa.py +6 -4
  16. {executorlib-1.9.1 → executorlib-1.9.3}/src/executorlib/task_scheduler/interactive/spawner_slurm.py +4 -4
  17. executorlib-1.9.1/.gitignore +0 -5
  18. {executorlib-1.9.1 → executorlib-1.9.3}/LICENSE +0 -0
  19. {executorlib-1.9.1 → executorlib-1.9.3}/src/executorlib/__init__.py +0 -0
  20. {executorlib-1.9.1 → executorlib-1.9.3}/src/executorlib/api.py +0 -0
  21. {executorlib-1.9.1 → executorlib-1.9.3}/src/executorlib/backend/__init__.py +0 -0
  22. {executorlib-1.9.1 → executorlib-1.9.3}/src/executorlib/backend/cache_parallel.py +0 -0
  23. {executorlib-1.9.1 → executorlib-1.9.3}/src/executorlib/backend/cache_serial.py +0 -0
  24. {executorlib-1.9.1 → executorlib-1.9.3}/src/executorlib/backend/interactive_parallel.py +0 -0
  25. {executorlib-1.9.1 → executorlib-1.9.3}/src/executorlib/backend/interactive_serial.py +0 -0
  26. {executorlib-1.9.1 → executorlib-1.9.3}/src/executorlib/executor/__init__.py +0 -0
  27. {executorlib-1.9.1 → executorlib-1.9.3}/src/executorlib/executor/base.py +0 -0
  28. {executorlib-1.9.1 → executorlib-1.9.3}/src/executorlib/standalone/__init__.py +0 -0
  29. {executorlib-1.9.1 → executorlib-1.9.3}/src/executorlib/standalone/batched.py +0 -0
  30. {executorlib-1.9.1 → executorlib-1.9.3}/src/executorlib/standalone/error.py +0 -0
  31. {executorlib-1.9.1 → executorlib-1.9.3}/src/executorlib/standalone/hdf.py +0 -0
  32. {executorlib-1.9.1 → executorlib-1.9.3}/src/executorlib/standalone/inputcheck.py +0 -0
  33. {executorlib-1.9.1 → executorlib-1.9.3}/src/executorlib/standalone/interactive/__init__.py +0 -0
  34. {executorlib-1.9.1 → executorlib-1.9.3}/src/executorlib/standalone/interactive/arguments.py +0 -0
  35. {executorlib-1.9.1 → executorlib-1.9.3}/src/executorlib/standalone/interactive/backend.py +0 -0
  36. {executorlib-1.9.1 → executorlib-1.9.3}/src/executorlib/standalone/interactive/communication.py +0 -0
  37. {executorlib-1.9.1 → executorlib-1.9.3}/src/executorlib/standalone/interactive/spawner.py +0 -0
  38. {executorlib-1.9.1 → executorlib-1.9.3}/src/executorlib/standalone/queue.py +0 -0
  39. {executorlib-1.9.1 → executorlib-1.9.3}/src/executorlib/standalone/scheduler.py +0 -0
  40. {executorlib-1.9.1 → executorlib-1.9.3}/src/executorlib/standalone/select.py +0 -0
  41. {executorlib-1.9.1 → executorlib-1.9.3}/src/executorlib/standalone/serialize.py +0 -0
  42. {executorlib-1.9.1 → executorlib-1.9.3}/src/executorlib/task_scheduler/__init__.py +0 -0
  43. {executorlib-1.9.1 → executorlib-1.9.3}/src/executorlib/task_scheduler/base.py +0 -0
  44. {executorlib-1.9.1 → executorlib-1.9.3}/src/executorlib/task_scheduler/file/__init__.py +0 -0
  45. {executorlib-1.9.1 → executorlib-1.9.3}/src/executorlib/task_scheduler/file/shared.py +0 -0
  46. {executorlib-1.9.1 → executorlib-1.9.3}/src/executorlib/task_scheduler/file/spawner_subprocess.py +0 -0
  47. {executorlib-1.9.1 → executorlib-1.9.3}/src/executorlib/task_scheduler/file/task_scheduler.py +0 -0
  48. {executorlib-1.9.1 → executorlib-1.9.3}/src/executorlib/task_scheduler/interactive/__init__.py +0 -0
  49. {executorlib-1.9.1 → executorlib-1.9.3}/src/executorlib/task_scheduler/interactive/dependency.py +0 -0
  50. {executorlib-1.9.1 → executorlib-1.9.3}/src/executorlib/task_scheduler/interactive/dependency_plot.py +0 -0
  51. {executorlib-1.9.1 → executorlib-1.9.3}/src/executorlib/task_scheduler/interactive/onetoone.py +0 -0
  52. {executorlib-1.9.1 → executorlib-1.9.3}/src/executorlib/task_scheduler/interactive/shared.py +0 -0
@@ -0,0 +1,218 @@
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[codz]
4
+ *$py.class
5
+
6
+ # C extensions
7
+ *.so
8
+
9
+ # Distribution / packaging
10
+ .Python
11
+ build/
12
+ develop-eggs/
13
+ dist/
14
+ downloads/
15
+ eggs/
16
+ .eggs/
17
+ lib/
18
+ lib64/
19
+ parts/
20
+ sdist/
21
+ var/
22
+ wheels/
23
+ share/python-wheels/
24
+ *.egg-info/
25
+ .installed.cfg
26
+ *.egg
27
+ MANIFEST
28
+
29
+ # PyInstaller
30
+ # Usually these files are written by a python script from a template
31
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
32
+ *.manifest
33
+ *.spec
34
+
35
+ # Installer logs
36
+ pip-log.txt
37
+ pip-delete-this-directory.txt
38
+
39
+ # Unit test / coverage reports
40
+ htmlcov/
41
+ .tox/
42
+ .nox/
43
+ .coverage
44
+ .coverage.*
45
+ .cache
46
+ nosetests.xml
47
+ coverage.xml
48
+ *.cover
49
+ *.py.cover
50
+ .hypothesis/
51
+ .pytest_cache/
52
+ cover/
53
+
54
+ # Translations
55
+ *.mo
56
+ *.pot
57
+
58
+ # Django stuff:
59
+ *.log
60
+ local_settings.py
61
+ db.sqlite3
62
+ db.sqlite3-journal
63
+
64
+ # Flask stuff:
65
+ instance/
66
+ .webassets-cache
67
+
68
+ # Scrapy stuff:
69
+ .scrapy
70
+
71
+ # Sphinx documentation
72
+ docs/_build/
73
+
74
+ # PyBuilder
75
+ .pybuilder/
76
+ target/
77
+
78
+ # Jupyter Notebook
79
+ .ipynb_checkpoints
80
+
81
+ # IPython
82
+ profile_default/
83
+ ipython_config.py
84
+
85
+ # pyenv
86
+ # For a library or package, you might want to ignore these files since the code is
87
+ # intended to run in multiple environments; otherwise, check them in:
88
+ # .python-version
89
+
90
+ # pipenv
91
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
92
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
93
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
94
+ # install all needed dependencies.
95
+ # Pipfile.lock
96
+
97
+ # UV
98
+ # Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
99
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
100
+ # commonly ignored for libraries.
101
+ # uv.lock
102
+
103
+ # poetry
104
+ # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
105
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
106
+ # commonly ignored for libraries.
107
+ # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
108
+ # poetry.lock
109
+ # poetry.toml
110
+
111
+ # pdm
112
+ # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
113
+ # pdm recommends including project-wide configuration in pdm.toml, but excluding .pdm-python.
114
+ # https://pdm-project.org/en/latest/usage/project/#working-with-version-control
115
+ # pdm.lock
116
+ # pdm.toml
117
+ .pdm-python
118
+ .pdm-build/
119
+
120
+ # pixi
121
+ # Similar to Pipfile.lock, it is generally recommended to include pixi.lock in version control.
122
+ # pixi.lock
123
+ # Pixi creates a virtual environment in the .pixi directory, just like venv module creates one
124
+ # in the .venv directory. It is recommended not to include this directory in version control.
125
+ .pixi
126
+
127
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
128
+ __pypackages__/
129
+
130
+ # Celery stuff
131
+ celerybeat-schedule
132
+ celerybeat.pid
133
+
134
+ # Redis
135
+ *.rdb
136
+ *.aof
137
+ *.pid
138
+
139
+ # RabbitMQ
140
+ mnesia/
141
+ rabbitmq/
142
+ rabbitmq-data/
143
+
144
+ # ActiveMQ
145
+ activemq-data/
146
+
147
+ # SageMath parsed files
148
+ *.sage.py
149
+
150
+ # Environments
151
+ .env
152
+ .envrc
153
+ .venv
154
+ env/
155
+ venv/
156
+ ENV/
157
+ env.bak/
158
+ venv.bak/
159
+
160
+ # Spyder project settings
161
+ .spyderproject
162
+ .spyproject
163
+
164
+ # Rope project settings
165
+ .ropeproject
166
+
167
+ # mkdocs documentation
168
+ /site
169
+
170
+ # mypy
171
+ .mypy_cache/
172
+ .dmypy.json
173
+ dmypy.json
174
+
175
+ # Pyre type checker
176
+ .pyre/
177
+
178
+ # pytype static type analyzer
179
+ .pytype/
180
+
181
+ # Cython debug symbols
182
+ cython_debug/
183
+
184
+ # PyCharm
185
+ # JetBrains specific template is maintained in a separate JetBrains.gitignore that can
186
+ # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
187
+ # and can be added to the global gitignore or merged into this file. For a more nuclear
188
+ # option (not recommended) you can uncomment the following to ignore the entire idea folder.
189
+ # .idea/
190
+
191
+ # Abstra
192
+ # Abstra is an AI-powered process automation framework.
193
+ # Ignore directories containing user credentials, local state, and settings.
194
+ # Learn more at https://abstra.io/docs
195
+ .abstra/
196
+
197
+ # Visual Studio Code
198
+ # Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore
199
+ # that can be found at https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore
200
+ # and can be added to the global gitignore or merged into this file. However, if you prefer,
201
+ # you could uncomment the following to ignore the entire vscode folder
202
+ # .vscode/
203
+ # Temporary file for partial code execution
204
+ tempCodeRunnerFile.py
205
+
206
+ # Ruff stuff:
207
+ .ruff_cache/
208
+
209
+ # PyPI configuration file
210
+ .pypirc
211
+
212
+ # Marimo
213
+ marimo/_static/
214
+ marimo/_lsp/
215
+ __marimo__/
216
+
217
+ # Streamlit
218
+ .streamlit/secrets.toml
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: executorlib
3
- Version: 1.9.1
3
+ Version: 1.9.3
4
4
  Summary: Up-scale python functions for high performance computing (HPC) with executorlib.
5
5
  Project-URL: Homepage, https://github.com/pyiron/executorlib
6
6
  Project-URL: Documentation, https://executorlib.readthedocs.io
@@ -50,18 +50,18 @@ Requires-Python: <3.14,>3.9
50
50
  Requires-Dist: cloudpickle<=3.1.2,>=2.0.0
51
51
  Requires-Dist: pyzmq<=27.1.0,>=25.0.0
52
52
  Provides-Extra: all
53
- Requires-Dist: h5py<=3.15.1,>=3.6.0; extra == 'all'
53
+ Requires-Dist: h5py<=3.16.0,>=3.6.0; extra == 'all'
54
54
  Requires-Dist: ipython<=9.9.0,>=7.33.0; extra == 'all'
55
55
  Requires-Dist: mpi4py<=4.1.1,>=3.1.4; extra == 'all'
56
56
  Requires-Dist: networkx<=3.6.1,>=2.8.8; extra == 'all'
57
- Requires-Dist: pydantic<=2.12.5,>=2.5.3; extra == 'all'
57
+ Requires-Dist: pydantic<=2.13.4,>=2.5.3; extra == 'all'
58
58
  Requires-Dist: pygraphviz<=1.14,>=1.10; extra == 'all'
59
- Requires-Dist: pysqa==0.3.5; extra == 'all'
59
+ Requires-Dist: pysqa==0.4.1; extra == 'all'
60
60
  Provides-Extra: cache
61
- Requires-Dist: h5py<=3.15.1,>=3.6.0; extra == 'cache'
61
+ Requires-Dist: h5py<=3.16.0,>=3.6.0; extra == 'cache'
62
62
  Provides-Extra: cluster
63
- Requires-Dist: h5py<=3.15.1,>=3.6.0; extra == 'cluster'
64
- Requires-Dist: pysqa==0.3.5; extra == 'cluster'
63
+ Requires-Dist: h5py<=3.16.0,>=3.6.0; extra == 'cluster'
64
+ Requires-Dist: pysqa==0.4.1; extra == 'cluster'
65
65
  Provides-Extra: graph
66
66
  Requires-Dist: networkx<=3.6.1,>=2.8.8; extra == 'graph'
67
67
  Requires-Dist: pygraphviz<=1.14,>=1.10; extra == 'graph'
@@ -72,7 +72,7 @@ Requires-Dist: pygraphviz<=1.14,>=1.10; extra == 'graphnotebook'
72
72
  Provides-Extra: mpi
73
73
  Requires-Dist: mpi4py<=4.1.1,>=3.1.4; extra == 'mpi'
74
74
  Provides-Extra: validation
75
- Requires-Dist: pydantic<=2.12.5,>=2.5.3; extra == 'validation'
75
+ Requires-Dist: pydantic<=2.13.4,>=2.5.3; extra == 'validation'
76
76
  Description-Content-Type: text/markdown
77
77
 
78
78
  # executorlib
@@ -221,23 +221,25 @@ as hierarchical job scheduler within the allocations.
221
221
  * [SLURM with Flux](https://executorlib.readthedocs.io/en/latest/3-hpc-job.html#slurm-with-flux)
222
222
  * [Flux](https://executorlib.readthedocs.io/en/latest/3-hpc-job.html#flux)
223
223
  * [Application](https://executorlib.readthedocs.io/en/latest/application.html)
224
- * [GPAW](https://executorlib.readthedocs.io/en/latest/5-1-gpaw.html)
225
- * [Quantum Espresso](https://executorlib.readthedocs.io/en/latest/5-2-quantum-espresso.html)
224
+ * [GPAW](https://executorlib.readthedocs.io/en/latest/4-1-gpaw.html)
225
+ * [Quantum Espresso](https://executorlib.readthedocs.io/en/latest/4-2-quantum-espresso.html)
226
226
  * [Trouble Shooting](https://executorlib.readthedocs.io/en/latest/trouble_shooting.html)
227
227
  * [Filesystem Usage](https://executorlib.readthedocs.io/en/latest/trouble_shooting.html#filesystem-usage)
228
228
  * [Firewall Issues](https://executorlib.readthedocs.io/en/latest/trouble_shooting.html#firewall-issues)
229
229
  * [Message Passing Interface](https://executorlib.readthedocs.io/en/latest/trouble_shooting.html#message-passing-interface)
230
+ * [Test Coverage for Integration Tests](https://executorlib.readthedocs.io/en/latest/trouble_shooting.html#test-coverage-for-integration-tests)
230
231
  * [Python Version](https://executorlib.readthedocs.io/en/latest/trouble_shooting.html#python-version)
231
232
  * [Resource Dictionary](https://executorlib.readthedocs.io/en/latest/trouble_shooting.html#resource-dictionary)
232
233
  * [SSH Connection](https://executorlib.readthedocs.io/en/latest/trouble_shooting.html#ssh-connection)
233
- * [Support & Contribution](https://executorlib.readthedocs.io/en/latest/4-developer.html)
234
- * [Issues](https://executorlib.readthedocs.io/en/latest/4-developer.html#issues)
235
- * [Pull Requests](https://executorlib.readthedocs.io/en/latest/4-developer.html#pull-requests)
236
- * [License](https://executorlib.readthedocs.io/en/latest/4-developer.html#license)
237
- * [Modules](https://executorlib.readthedocs.io/en/latest/4-developer.html#modules)
238
- * [Interface Class Hierarchy](https://executorlib.readthedocs.io/en/latest/4-developer.html#interface-class-hierarchy)
239
- * [Test Environment](https://executorlib.readthedocs.io/en/latest/4-developer.html#test-environment)
240
- * [Communication](https://executorlib.readthedocs.io/en/latest/4-developer.html#communication)
241
- * [External Libraries](https://executorlib.readthedocs.io/en/latest/4-developer.html#external-libraries)
242
- * [External Executables](https://executorlib.readthedocs.io/en/latest/4-developer.html#external-executables)
234
+ * [Support & Contribution](https://executorlib.readthedocs.io/en/latest/5-developer.html)
235
+ * [Issues](https://executorlib.readthedocs.io/en/latest/5-developer.html#issues)
236
+ * [Pull Requests](https://executorlib.readthedocs.io/en/latest/5-developer.html#pull-requests)
237
+ * [License](https://executorlib.readthedocs.io/en/latest/5-developer.html#license)
238
+ * [Modules](https://executorlib.readthedocs.io/en/latest/5-developer.html#modules)
239
+ * [Interface Class Hierarchy](https://executorlib.readthedocs.io/en/latest/5-developer.html#interface-class-hierarchy)
240
+ * [Execution Flow](https://executorlib.readthedocs.io/en/latest/5-developer.html#execution-flow)
241
+ * [Test Environment](https://executorlib.readthedocs.io/en/latest/5-developer.html#test-environment)
242
+ * [Communication](https://executorlib.readthedocs.io/en/latest/5-developer.html#communication)
243
+ * [External Libraries](https://executorlib.readthedocs.io/en/latest/5-developer.html#external-libraries)
244
+ * [External Executables](https://executorlib.readthedocs.io/en/latest/5-developer.html#external-executables)
243
245
  * [Interface](https://executorlib.readthedocs.io/en/latest/api.html)
@@ -144,23 +144,25 @@ as hierarchical job scheduler within the allocations.
144
144
  * [SLURM with Flux](https://executorlib.readthedocs.io/en/latest/3-hpc-job.html#slurm-with-flux)
145
145
  * [Flux](https://executorlib.readthedocs.io/en/latest/3-hpc-job.html#flux)
146
146
  * [Application](https://executorlib.readthedocs.io/en/latest/application.html)
147
- * [GPAW](https://executorlib.readthedocs.io/en/latest/5-1-gpaw.html)
148
- * [Quantum Espresso](https://executorlib.readthedocs.io/en/latest/5-2-quantum-espresso.html)
147
+ * [GPAW](https://executorlib.readthedocs.io/en/latest/4-1-gpaw.html)
148
+ * [Quantum Espresso](https://executorlib.readthedocs.io/en/latest/4-2-quantum-espresso.html)
149
149
  * [Trouble Shooting](https://executorlib.readthedocs.io/en/latest/trouble_shooting.html)
150
150
  * [Filesystem Usage](https://executorlib.readthedocs.io/en/latest/trouble_shooting.html#filesystem-usage)
151
151
  * [Firewall Issues](https://executorlib.readthedocs.io/en/latest/trouble_shooting.html#firewall-issues)
152
152
  * [Message Passing Interface](https://executorlib.readthedocs.io/en/latest/trouble_shooting.html#message-passing-interface)
153
+ * [Test Coverage for Integration Tests](https://executorlib.readthedocs.io/en/latest/trouble_shooting.html#test-coverage-for-integration-tests)
153
154
  * [Python Version](https://executorlib.readthedocs.io/en/latest/trouble_shooting.html#python-version)
154
155
  * [Resource Dictionary](https://executorlib.readthedocs.io/en/latest/trouble_shooting.html#resource-dictionary)
155
156
  * [SSH Connection](https://executorlib.readthedocs.io/en/latest/trouble_shooting.html#ssh-connection)
156
- * [Support & Contribution](https://executorlib.readthedocs.io/en/latest/4-developer.html)
157
- * [Issues](https://executorlib.readthedocs.io/en/latest/4-developer.html#issues)
158
- * [Pull Requests](https://executorlib.readthedocs.io/en/latest/4-developer.html#pull-requests)
159
- * [License](https://executorlib.readthedocs.io/en/latest/4-developer.html#license)
160
- * [Modules](https://executorlib.readthedocs.io/en/latest/4-developer.html#modules)
161
- * [Interface Class Hierarchy](https://executorlib.readthedocs.io/en/latest/4-developer.html#interface-class-hierarchy)
162
- * [Test Environment](https://executorlib.readthedocs.io/en/latest/4-developer.html#test-environment)
163
- * [Communication](https://executorlib.readthedocs.io/en/latest/4-developer.html#communication)
164
- * [External Libraries](https://executorlib.readthedocs.io/en/latest/4-developer.html#external-libraries)
165
- * [External Executables](https://executorlib.readthedocs.io/en/latest/4-developer.html#external-executables)
157
+ * [Support & Contribution](https://executorlib.readthedocs.io/en/latest/5-developer.html)
158
+ * [Issues](https://executorlib.readthedocs.io/en/latest/5-developer.html#issues)
159
+ * [Pull Requests](https://executorlib.readthedocs.io/en/latest/5-developer.html#pull-requests)
160
+ * [License](https://executorlib.readthedocs.io/en/latest/5-developer.html#license)
161
+ * [Modules](https://executorlib.readthedocs.io/en/latest/5-developer.html#modules)
162
+ * [Interface Class Hierarchy](https://executorlib.readthedocs.io/en/latest/5-developer.html#interface-class-hierarchy)
163
+ * [Execution Flow](https://executorlib.readthedocs.io/en/latest/5-developer.html#execution-flow)
164
+ * [Test Environment](https://executorlib.readthedocs.io/en/latest/5-developer.html#test-environment)
165
+ * [Communication](https://executorlib.readthedocs.io/en/latest/5-developer.html#communication)
166
+ * [External Libraries](https://executorlib.readthedocs.io/en/latest/5-developer.html#external-libraries)
167
+ * [External Executables](https://executorlib.readthedocs.io/en/latest/5-developer.html#external-executables)
166
168
  * [Interface](https://executorlib.readthedocs.io/en/latest/api.html)
@@ -1,6 +1,6 @@
1
1
  [build-system]
2
2
  requires = [
3
- "hatchling>=1.27.0,<=1.28.0",
3
+ "hatchling>=1.27.0,<=1.29.0",
4
4
  "hatch-vcs==0.5.0",
5
5
  "cloudpickle>=2.0.0,<=3.1.2",
6
6
  "pyzmq>=25.0.0,<=27.1.0",
@@ -40,7 +40,7 @@ Documentation = "https://executorlib.readthedocs.io"
40
40
  Repository = "https://github.com/pyiron/executorlib"
41
41
 
42
42
  [project.optional-dependencies]
43
- cache = ["h5py>=3.6.0,<=3.15.1"]
43
+ cache = ["h5py>=3.6.0,<=3.16.0"]
44
44
  graph = [
45
45
  "pygraphviz>=1.10,<=1.14",
46
46
  "networkx>=2.8.8,<=3.6.1",
@@ -52,17 +52,17 @@ graphnotebook = [
52
52
  ]
53
53
  mpi = ["mpi4py>=3.1.4,<=4.1.1"]
54
54
  cluster = [
55
- "pysqa==0.3.5",
56
- "h5py>=3.6.0,<=3.15.1",
55
+ "pysqa==0.4.1",
56
+ "h5py>=3.6.0,<=3.16.0",
57
57
  ]
58
58
  validation = [
59
- "pydantic>=2.5.3,<=2.12.5",
59
+ "pydantic>=2.5.3,<=2.13.4",
60
60
  ]
61
61
  all = [
62
62
  "mpi4py>=3.1.4,<=4.1.1",
63
- "pysqa==0.3.5",
64
- "h5py>=3.6.0,<=3.15.1",
65
- "pydantic>=2.5.3,<=2.12.5",
63
+ "pysqa==0.4.1",
64
+ "h5py>=3.6.0,<=3.16.0",
65
+ "pydantic>=2.5.3,<=2.13.4",
66
66
  "pygraphviz>=1.10,<=1.14",
67
67
  "networkx>=2.8.8,<=3.6.1",
68
68
  "ipython>=7.33.0,<=9.9.0",
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
28
28
  commit_id: COMMIT_ID
29
29
  __commit_id__: COMMIT_ID
30
30
 
31
- __version__ = version = '1.9.1'
32
- __version_tuple__ = version_tuple = (1, 9, 1)
31
+ __version__ = version = '1.9.3'
32
+ __version_tuple__ = version_tuple = (1, 9, 3)
33
33
 
34
34
  __commit_id__ = commit_id = None
@@ -51,11 +51,11 @@ class FluxJobExecutor(BaseExecutor):
51
51
  do not allow other tasks to use the same compute node.
52
52
  * error_log_file (str): path to the error log file, primarily used to merge the log of
53
53
  multiple tasks in one file.
54
- * run_time_limit (int): the maximum time the execution of the submitted Python function is
55
- allowed to take in seconds.
54
+ * run_time_max (int): the maximum time the execution of the submitted Python function is
55
+ allowed to take in seconds.
56
56
  * priority (int): the queuing system priority assigned to a given Python function to
57
57
  influence the scheduling.
58
- *`slurm_cmd_args (list): Additional command line arguments for the srun call (SLURM only)
58
+ * slurm_cmd_args (list): Additional command line arguments for the srun call (SLURM only)
59
59
  pmi_mode (str): PMI interface to use (OpenMPI v5 requires pmix) default is None
60
60
  flux_executor (flux.job.FluxExecutor): Flux Python interface to submit the workers to flux
61
61
  flux_executor_nesting (bool): Provide hierarchically nested Flux job scheduler inside the submitted function.
@@ -154,7 +154,7 @@ class FluxJobExecutor(BaseExecutor):
154
154
  - do not allow other tasks to use the same compute node.
155
155
  * error_log_file (str): path to the error log file, primarily used to merge the log of
156
156
  multiple tasks in one file.
157
- * run_time_limit (int): the maximum time the execution of the submitted Python
157
+ * run_time_max (int): the maximum time the execution of the submitted Python
158
158
  function is allowed to take in seconds.
159
159
  * priority (int): the queuing system priority assigned to a given Python function to
160
160
  influence the scheduling.
@@ -283,11 +283,11 @@ class FluxClusterExecutor(BaseExecutor):
283
283
  do not allow other tasks to use the same compute node.
284
284
  * error_log_file (str): path to the error log file, primarily used to merge the log of
285
285
  multiple tasks in one file.
286
- * run_time_limit (int): the maximum time the execution of the submitted Python function is
287
- allowed to take in seconds.
286
+ * run_time_max (int): the maximum time the execution of the submitted Python function is
287
+ allowed to take in seconds.
288
288
  * priority (int): the queuing system priority assigned to a given Python function to
289
289
  influence the scheduling.
290
- *`slurm_cmd_args (list): Additional command line arguments for the srun call (SLURM only)
290
+ * slurm_cmd_args (list): Additional command line arguments for the srun call (SLURM only)
291
291
  pysqa_config_directory (str, optional): path to the pysqa config directory (only for pysqa based backend).
292
292
  pmi_mode (str): PMI interface to use (OpenMPI v5 requires pmix) default is None
293
293
  hostname_localhost (boolean): use localhost instead of the hostname to establish the zmq connection. In the
@@ -380,7 +380,7 @@ class FluxClusterExecutor(BaseExecutor):
380
380
  - do not allow other tasks to use the same compute node.
381
381
  * error_log_file (str): path to the error log file, primarily used to merge the log of
382
382
  multiple tasks in one file.
383
- * run_time_limit (int): the maximum time the execution of the submitted Python
383
+ * run_time_max (int): the maximum time the execution of the submitted Python
384
384
  function is allowed to take in seconds.
385
385
  * priority (int): the queuing system priority assigned to a given Python function to
386
386
  influence the scheduling.
@@ -417,7 +417,7 @@ class FluxClusterExecutor(BaseExecutor):
417
417
  "cwd": None,
418
418
  "openmpi_oversubscribe": openmpi_oversubscribe,
419
419
  "slurm_cmd_args": [],
420
- "run_time_limit": None,
420
+ "run_time_max": None,
421
421
  }
422
422
  if resource_dict is None:
423
423
  resource_dict = {}
@@ -540,11 +540,11 @@ def create_flux_executor(
540
540
  do not allow other tasks to use the same compute node.
541
541
  * error_log_file (str): path to the error log file, primarily used to merge the log of
542
542
  multiple tasks in one file.
543
- * run_time_limit (int): the maximum time the execution of the submitted Python function is
544
- allowed to take in seconds.
543
+ * run_time_max (int): the maximum time the execution of the submitted Python function is
544
+ allowed to take in seconds.
545
545
  * priority (int): the queuing system priority assigned to a given Python function to
546
546
  influence the scheduling.
547
- *`slurm_cmd_args (list): Additional command line arguments for the srun call (SLURM only)
547
+ * slurm_cmd_args (list): Additional command line arguments for the srun call (SLURM only)
548
548
  pmi_mode (str): PMI interface to use (OpenMPI v5 requires pmix) default is None
549
549
  flux_executor (flux.job.FluxExecutor): Flux Python interface to submit the workers to flux
550
550
  flux_executor_nesting (bool): Provide hierarchically nested Flux job scheduler inside the submitted function.
@@ -50,8 +50,8 @@ class SingleNodeExecutor(BaseExecutor):
50
50
  do not allow other tasks to use the same compute node.
51
51
  * error_log_file (str): path to the error log file, primarily used to merge the log of
52
52
  multiple tasks in one file.
53
- * run_time_limit (int): the maximum time the execution of the submitted Python function is
54
- allowed to take in seconds.
53
+ * run_time_max (int): the maximum time the execution of the submitted Python function is
54
+ allowed to take in seconds.
55
55
  * priority (int): the queuing system priority assigned to a given Python function to
56
56
  influence the scheduling.
57
57
  * slurm_cmd_args (list): Additional command line arguments for the srun call (SLURM only)
@@ -145,7 +145,7 @@ class SingleNodeExecutor(BaseExecutor):
145
145
  - do not allow other tasks to use the same compute node.
146
146
  * error_log_file (str): path to the error log file, primarily used to merge the log of
147
147
  multiple tasks in one file.
148
- * run_time_limit (int): the maximum time the execution of the submitted Python
148
+ * run_time_max (int): the maximum time the execution of the submitted Python
149
149
  function is allowed to take in seconds.
150
150
  * priority (int): the queuing system priority assigned to a given Python function to
151
151
  influence the scheduling.
@@ -259,8 +259,8 @@ class TestClusterExecutor(BaseExecutor):
259
259
  do not allow other tasks to use the same compute node.
260
260
  * error_log_file (str): path to the error log file, primarily used to merge the log of
261
261
  multiple tasks in one file.
262
- * run_time_limit (int): the maximum time the execution of the submitted Python function is
263
- allowed to take in seconds.
262
+ * run_time_max (int): the maximum time the execution of the submitted Python function is
263
+ allowed to take in seconds.
264
264
  * priority (int): the queuing system priority assigned to a given Python function to
265
265
  influence the scheduling.
266
266
  * slurm_cmd_args (list): Additional command line arguments for the srun call (SLURM only)
@@ -350,7 +350,7 @@ class TestClusterExecutor(BaseExecutor):
350
350
  - do not allow other tasks to use the same compute node.
351
351
  * error_log_file (str): path to the error log file, primarily used to merge the log of
352
352
  multiple tasks in one file.
353
- * run_time_limit (int): the maximum time the execution of the submitted Python
353
+ * run_time_max (int): the maximum time the execution of the submitted Python
354
354
  function is allowed to take in seconds.
355
355
  * priority (int): the queuing system priority assigned to a given Python function to
356
356
  influence the scheduling.
@@ -479,8 +479,8 @@ def create_single_node_executor(
479
479
  do not allow other tasks to use the same compute node.
480
480
  * error_log_file (str): path to the error log file, primarily used to merge the log of
481
481
  multiple tasks in one file.
482
- * run_time_limit (int): the maximum time the execution of the submitted Python function is
483
- allowed to take in seconds.
482
+ * run_time_max (int): the maximum time the execution of the submitted Python function is
483
+ allowed to take in seconds.
484
484
  * priority (int): the queuing system priority assigned to a given Python function to
485
485
  influence the scheduling.
486
486
  * slurm_cmd_args (list): Additional command line arguments for the srun call (SLURM only)
@@ -52,11 +52,11 @@ class SlurmClusterExecutor(BaseExecutor):
52
52
  do not allow other tasks to use the same compute node.
53
53
  * error_log_file (str): path to the error log file, primarily used to merge the log of
54
54
  multiple tasks in one file.
55
- * run_time_limit (int): the maximum time the execution of the submitted Python function is
56
- allowed to take in seconds.
55
+ * run_time_max (int): the maximum time the execution of the submitted Python function is
56
+ allowed to take in seconds.
57
57
  * priority (int): the queuing system priority assigned to a given Python function to
58
58
  influence the scheduling.
59
- *`slurm_cmd_args (list): Additional command line arguments for the srun call (SLURM only)
59
+ * slurm_cmd_args (list): Additional command line arguments for the srun call (SLURM only)
60
60
  pysqa_config_directory (str, optional): path to the pysqa config directory (only for pysqa based backend).
61
61
  pmi_mode (str): PMI interface to use (OpenMPI v5 requires pmix) default is None
62
62
  hostname_localhost (boolean): use localhost instead of the hostname to establish the zmq connection. In the
@@ -149,7 +149,7 @@ class SlurmClusterExecutor(BaseExecutor):
149
149
  - do not allow other tasks to use the same compute node.
150
150
  * error_log_file (str): path to the error log file, primarily used to merge the log of
151
151
  multiple tasks in one file.
152
- * run_time_limit (int): the maximum time the execution of the submitted Python
152
+ * run_time_max (int): the maximum time the execution of the submitted Python
153
153
  function is allowed to take in seconds.
154
154
  * priority (int): the queuing system priority assigned to a given Python function to
155
155
  influence the scheduling.
@@ -293,11 +293,11 @@ class SlurmJobExecutor(BaseExecutor):
293
293
  do not allow other tasks to use the same compute node.
294
294
  * error_log_file (str): path to the error log file, primarily used to merge the log of
295
295
  multiple tasks in one file.
296
- * run_time_limit (int): the maximum time the execution of the submitted Python function is
297
- allowed to take in seconds.
296
+ * run_time_max (int): the maximum time the execution of the submitted Python function is
297
+ allowed to take in seconds.
298
298
  * priority (int): the queuing system priority assigned to a given Python function to
299
299
  influence the scheduling.
300
- *`slurm_cmd_args (list): Additional command line arguments for the srun call (SLURM only)
300
+ * slurm_cmd_args (list): Additional command line arguments for the srun call (SLURM only)
301
301
  pmi_mode (str): PMI interface to use (OpenMPI v5 requires pmix) default is None
302
302
  hostname_localhost (boolean): use localhost instead of the hostname to establish the zmq connection. In the
303
303
  context of an HPC cluster this essential to be able to communicate to an
@@ -390,7 +390,7 @@ class SlurmJobExecutor(BaseExecutor):
390
390
  - do not allow other tasks to use the same compute node.
391
391
  * error_log_file (str): path to the error log file, primarily used to merge the log of
392
392
  multiple tasks in one file.
393
- * run_time_limit (int): the maximum time the execution of the submitted Python
393
+ * run_time_max (int): the maximum time the execution of the submitted Python
394
394
  function is allowed to take in seconds.
395
395
  * priority (int): the queuing system priority assigned to a given Python function to
396
396
  influence the scheduling.
@@ -518,8 +518,8 @@ def create_slurm_executor(
518
518
  do not allow other tasks to use the same compute node.
519
519
  * error_log_file (str): path to the error log file, primarily used to merge the log of
520
520
  multiple tasks in one file.
521
- * run_time_limit (int): the maximum time the execution of the submitted Python function is
522
- allowed to take in seconds.
521
+ * run_time_max (int): the maximum time the execution of the submitted Python function is
522
+ allowed to take in seconds.
523
523
  * priority (int): the queuing system priority assigned to a given Python function to
524
524
  influence the scheduling.
525
525
  * slurm_cmd_args (list): Additional command line arguments for the srun call (SLURM only)
@@ -126,7 +126,7 @@ def generate_slurm_command(
126
126
  openmpi_oversubscribe: bool = False,
127
127
  slurm_cmd_args: Optional[list[str]] = None,
128
128
  pmi_mode: Optional[str] = None,
129
- run_time_limit: Optional[int] = None,
129
+ run_time_max: Optional[int] = None,
130
130
  ) -> list[str]:
131
131
  """
132
132
  Generate the command list for the SLURM interface.
@@ -141,7 +141,7 @@ def generate_slurm_command(
141
141
  openmpi_oversubscribe (bool, optional): Whether to oversubscribe the cores. Defaults to False.
142
142
  slurm_cmd_args (list[str], optional): Additional command line arguments. Defaults to [].
143
143
  pmi_mode (str): PMI interface to use (OpenMPI v5 requires pmix) default is None
144
- run_time_limit (int): The maximum runtime in seconds for each task. Default: None
144
+ run_time_max (int): The maximum runtime in seconds for each task. Default: None
145
145
 
146
146
  Returns:
147
147
  list[str]: The generated command list.
@@ -161,8 +161,8 @@ def generate_slurm_command(
161
161
  command_prepend_lst += ["--exact"]
162
162
  if openmpi_oversubscribe:
163
163
  command_prepend_lst += ["--oversubscribe"]
164
- if run_time_limit is not None:
165
- command_prepend_lst += ["--time=" + str(run_time_limit // 60 + 1)]
164
+ if run_time_max is not None:
165
+ command_prepend_lst += ["--time=" + str(run_time_max // 60 + 1)]
166
166
  if slurm_cmd_args is not None and len(slurm_cmd_args) > 0:
167
167
  command_prepend_lst += slurm_cmd_args
168
168
  return command_prepend_lst
@@ -23,9 +23,10 @@ class ResourceDictValidation(BaseModel):
23
23
  num_nodes: Optional[int] = None
24
24
  exclusive: Optional[bool] = None
25
25
  error_log_file: Optional[str] = None
26
- run_time_limit: Optional[int] = None
26
+ run_time_max: Optional[int] = None
27
27
  priority: Optional[int] = None
28
28
  slurm_cmd_args: Optional[list[str]] = None
29
+ submission_template: Optional[str] = None
29
30
 
30
31
  if HAS_PYDANTIC:
31
32
 
@@ -45,15 +45,22 @@ def backend_write_file(file_name: str, output: Any, runtime: float) -> None:
45
45
  """
46
46
  file_name_out = os.path.splitext(file_name)[0][:-2]
47
47
  os.rename(file_name, file_name_out + "_r.h5")
48
- if "result" in output:
49
- dump(
50
- file_name=file_name_out + "_r.h5",
51
- data_dict={"output": output["result"], "runtime": runtime},
52
- )
53
- else:
48
+ try:
49
+ if "result" in output:
50
+ dump(
51
+ file_name=file_name_out + "_r.h5",
52
+ data_dict={"output": output["result"], "runtime": runtime},
53
+ )
54
+ else:
55
+ dump(
56
+ file_name=file_name_out + "_r.h5",
57
+ data_dict={"error": output["error"], "runtime": runtime},
58
+ )
59
+ except Exception as serialize_error:
60
+ # Serialization failed — store the error so the job is not stuck
54
61
  dump(
55
62
  file_name=file_name_out + "_r.h5",
56
- data_dict={"error": output["error"], "runtime": runtime},
63
+ data_dict={"error": serialize_error, "runtime": runtime},
57
64
  )
58
65
  os.rename(file_name_out + "_r.h5", file_name_out + "_o.h5")
59
66
 
@@ -1,4 +1,5 @@
1
1
  import os
2
+ from subprocess import CalledProcessError
2
3
  from typing import Optional
3
4
 
4
5
  from pysqa import QueueAdapter
@@ -69,7 +70,7 @@ def execute_with_pysqa(
69
70
  "command": " ".join(command),
70
71
  "dependency_list": [str(qid) for qid in task_dependent_lst],
71
72
  "working_directory": os.path.abspath(cwd),
72
- "run_time_max": resource_dict.get("run_time_limit"),
73
+ "run_time_max": resource_dict.get("run_time_max"),
73
74
  }
74
75
  if "cwd" in resource_dict:
75
76
  del resource_dict["cwd"]
@@ -90,8 +91,14 @@ def execute_with_pysqa(
90
91
  )
91
92
  submit_kwargs.update(resource_dict)
92
93
  set_current_directory_in_environment()
93
- queue_id = qa.submit_job(**submit_kwargs)
94
- dump(file_name=file_name, data_dict={"queue_id": queue_id})
94
+ try:
95
+ queue_id = qa.submit_job(**submit_kwargs)
96
+ except (ValueError, CalledProcessError) as error:
97
+ dump(file_name=file_name, data_dict={"error": error})
98
+ file_name_out = os.path.splitext(file_name)[0][:-2]
99
+ os.rename(file_name_out + "_i.h5", file_name_out + "_o.h5")
100
+ else:
101
+ dump(file_name=file_name, data_dict={"queue_id": queue_id})
95
102
  return queue_id
96
103
 
97
104
 
@@ -1,7 +1,7 @@
1
1
  import queue
2
2
  import random
3
3
  from concurrent.futures import Future
4
- from threading import Event, Thread
4
+ from threading import Event, Lock, Thread
5
5
  from typing import Callable, Optional
6
6
 
7
7
  from executorlib.standalone.command import get_interactive_execute_command
@@ -83,6 +83,8 @@ class BlockAllocationTaskScheduler(TaskSchedulerBase):
83
83
  self_id = random.getrandbits(128)
84
84
  self._self_id = self_id
85
85
  _interrupt_bootup_dict[self._self_id] = False
86
+ alive_workers = [max_workers]
87
+ alive_workers_lock = Lock()
86
88
  bootup_events = [Event() for _ in range(self._max_workers)]
87
89
  bootup_events[0].set()
88
90
  self._set_process(
@@ -99,6 +101,8 @@ class BlockAllocationTaskScheduler(TaskSchedulerBase):
99
101
  if worker_id + 1 < self._max_workers
100
102
  else None
101
103
  ),
104
+ "alive_workers": alive_workers,
105
+ "alive_workers_lock": alive_workers_lock,
102
106
  },
103
107
  )
104
108
  for worker_id in range(self._max_workers)
@@ -227,6 +231,8 @@ def _execute_multiple_tasks(
227
231
  restart_limit: int = 0,
228
232
  bootup_event: Optional[Event] = None,
229
233
  next_bootup_event: Optional[Event] = None,
234
+ alive_workers: Optional[list] = None,
235
+ alive_workers_lock: Optional[Lock] = None,
230
236
  **kwargs,
231
237
  ) -> None:
232
238
  """
@@ -258,6 +264,9 @@ def _execute_multiple_tasks(
258
264
  bootup_event (Event): Event to wait on before submitting the job to the scheduler, ensuring workers are
259
265
  submitted in worker_id order.
260
266
  next_bootup_event (Event): Event to signal after job submission, unblocking the next worker.
267
+ alive_workers (list): Single-element list [N] tracking how many worker threads are still alive. Shared across
268
+ all worker threads; decremented when a worker is permanently dead.
269
+ alive_workers_lock (Lock): Lock protecting alive_workers from concurrent modification.
261
270
  """
262
271
  if bootup_event is not None:
263
272
  bootup_event.wait()
@@ -279,11 +288,13 @@ def _execute_multiple_tasks(
279
288
  )
280
289
  restart_counter = 0
281
290
  while True:
282
- if not interface.status and restart_counter > restart_limit:
283
- interface.status = True # no more restarts
284
- interface_initialization_exception = ExecutorlibSocketError(
285
- "SocketInterface crashed during execution."
291
+ if not interface.status and restart_counter >= restart_limit:
292
+ _drain_dead_worker(
293
+ future_queue=future_queue,
294
+ alive_workers=alive_workers,
295
+ alive_workers_lock=alive_workers_lock,
286
296
  )
297
+ break
287
298
  elif not interface.status:
288
299
  interface.bootup()
289
300
  interface_initialization_exception = _set_init_function(
@@ -321,6 +332,47 @@ def _execute_multiple_tasks(
321
332
  task_done(future_queue=future_queue)
322
333
 
323
334
 
335
+ def _drain_dead_worker(
336
+ future_queue: queue.Queue,
337
+ alive_workers: Optional[list] = None,
338
+ alive_workers_lock: Optional[Lock] = None,
339
+ ) -> None:
340
+ """Handle a permanently dead worker by recycling or failing its tasks.
341
+
342
+ If healthy workers remain, tasks are recycled back into the shared queue
343
+ so they can be picked up. If all workers are dead, tasks are failed
344
+ immediately with ExecutorlibSocketError. In both cases, the worker's
345
+ shutdown message is consumed to prevent hangs in shutdown().
346
+ """
347
+ if alive_workers is not None and alive_workers_lock is not None:
348
+ with alive_workers_lock:
349
+ if alive_workers[0] > 0:
350
+ alive_workers[0] -= 1
351
+ while True:
352
+ try:
353
+ task_dict = future_queue.get(timeout=1)
354
+ except queue.Empty:
355
+ continue
356
+ if "shutdown" in task_dict and task_dict["shutdown"]:
357
+ task_done(future_queue=future_queue)
358
+ break
359
+ elif "fn" in task_dict and "future" in task_dict:
360
+ if alive_workers is not None and alive_workers_lock is not None:
361
+ with alive_workers_lock:
362
+ has_healthy_workers = alive_workers[0] > 0
363
+ else:
364
+ has_healthy_workers = False
365
+ if has_healthy_workers:
366
+ future_queue.put(task_dict)
367
+ task_done(future_queue=future_queue)
368
+ else:
369
+ f = task_dict.pop("future")
370
+ f.set_exception(
371
+ ExecutorlibSocketError("SocketInterface crashed during execution.")
372
+ )
373
+ task_done(future_queue=future_queue)
374
+
375
+
324
376
  def _set_init_function(
325
377
  interface: SocketInterface,
326
378
  init_function: Optional[Callable] = None,
@@ -44,7 +44,7 @@ class FluxPythonSpawner(BaseSpawner):
44
44
  flux_executor (flux.job.FluxExecutor, optional): The FluxExecutor instance. Defaults to None.
45
45
  flux_executor_nesting (bool, optional): Whether to use nested FluxExecutor. Defaults to False.
46
46
  flux_log_files (bool, optional): Write flux stdout and stderr files. Defaults to False.
47
- run_time_limit (int): The maximum runtime in seconds for each task. Default: None
47
+ run_time_max (int): The maximum runtime in seconds for each task. Default: None
48
48
  """
49
49
 
50
50
  def __init__(
@@ -62,7 +62,7 @@ class FluxPythonSpawner(BaseSpawner):
62
62
  flux_executor: Optional[flux.job.FluxExecutor] = None,
63
63
  flux_executor_nesting: bool = False,
64
64
  flux_log_files: bool = False,
65
- run_time_limit: Optional[int] = None,
65
+ run_time_max: Optional[int] = None,
66
66
  ):
67
67
  super().__init__(
68
68
  cwd=cwd,
@@ -80,7 +80,7 @@ class FluxPythonSpawner(BaseSpawner):
80
80
  self._flux_log_files = flux_log_files
81
81
  self._priority = priority
82
82
  self._future = None
83
- self._run_time_limit = run_time_limit
83
+ self._run_time_max = run_time_max
84
84
 
85
85
  def bootup(
86
86
  self,
@@ -131,8 +131,8 @@ class FluxPythonSpawner(BaseSpawner):
131
131
  if self._cwd is not None:
132
132
  jobspec.cwd = self._cwd
133
133
  os.makedirs(self._cwd, exist_ok=True)
134
- if self._run_time_limit is not None:
135
- jobspec.duration = self._run_time_limit
134
+ if self._run_time_max is not None:
135
+ jobspec.duration = self._run_time_max
136
136
  file_prefix = "flux_" + str(self._worker_id)
137
137
  if self._flux_log_files and self._cwd is not None:
138
138
  jobspec.stderr = os.path.join(self._cwd, file_prefix + ".err")
@@ -32,7 +32,7 @@ class PysqaSpawner(BaseSpawner):
32
32
  pmi_mode: Optional[str] = None,
33
33
  config_directory: Optional[str] = None,
34
34
  backend: Optional[str] = None,
35
- run_time_limit: Optional[int] = None,
35
+ run_time_max: Optional[int] = None,
36
36
  **kwargs,
37
37
  ):
38
38
  """
@@ -52,7 +52,7 @@ class PysqaSpawner(BaseSpawner):
52
52
  pmi_mode (str, optional): PMI interface to use (OpenMPI v5 requires pmix) default is None
53
53
  config_directory (str, optional): path to the pysqa config directory (only for pysqa based backend).
54
54
  backend (str): name of the backend used to spawn tasks.
55
- run_time_limit (int): The maximum runtime in seconds for each task. Default: None
55
+ run_time_max (int): The maximum runtime in seconds for each task. Default: None
56
56
  """
57
57
  super().__init__(
58
58
  cwd=cwd,
@@ -71,7 +71,7 @@ class PysqaSpawner(BaseSpawner):
71
71
  self._pysqa_submission_kwargs = kwargs
72
72
  self._process: Optional[int] = None
73
73
  self._queue_adapter: Optional[QueueAdapter] = None
74
- self._run_time_limit = run_time_limit
74
+ self._run_time_max = run_time_max
75
75
 
76
76
  def bootup(
77
77
  self,
@@ -195,7 +195,7 @@ class PysqaSpawner(BaseSpawner):
195
195
  command=" ".join(self.generate_command(command_lst=command_lst)),
196
196
  working_directory=working_directory,
197
197
  cores=int(self._cores * self._threads_per_core),
198
- run_time_max=self._run_time_limit,
198
+ run_time_max=self._run_time_max,
199
199
  **self._pysqa_submission_kwargs,
200
200
  )
201
201
 
@@ -238,6 +238,8 @@ def create_pysqa_block_allocation_scheduler(
238
238
  cores_per_worker = executor_kwargs.get("cores", 1)
239
239
  if "cwd" in executor_kwargs and executor_kwargs["cwd"] is not None:
240
240
  executor_kwargs["cwd"] = os.path.abspath(executor_kwargs["cwd"])
241
+ elif cache_directory is not None:
242
+ executor_kwargs["cwd"] = os.path.abspath(cache_directory)
241
243
  if cache_directory is not None:
242
244
  executor_kwargs["cache_directory"] = os.path.abspath(cache_directory)
243
245
  else:
@@ -32,7 +32,7 @@ class SrunSpawner(SubprocessSpawner):
32
32
  openmpi_oversubscribe: bool = False,
33
33
  slurm_cmd_args: Optional[list[str]] = None,
34
34
  pmi_mode: Optional[str] = None,
35
- run_time_limit: Optional[int] = None,
35
+ run_time_max: Optional[int] = None,
36
36
  ):
37
37
  """
38
38
  Srun interface implementation.
@@ -48,7 +48,7 @@ class SrunSpawner(SubprocessSpawner):
48
48
  openmpi_oversubscribe (bool, optional): Whether to oversubscribe the cores. Defaults to False.
49
49
  slurm_cmd_args (list[str], optional): Additional command line arguments. Defaults to [].
50
50
  pmi_mode (str): PMI interface to use (OpenMPI v5 requires pmix) default is None
51
- run_time_limit (int): The maximum runtime in seconds for each task. Default: None
51
+ run_time_max (int): The maximum runtime in seconds for each task. Default: None
52
52
  """
53
53
  super().__init__(
54
54
  cwd=cwd,
@@ -62,7 +62,7 @@ class SrunSpawner(SubprocessSpawner):
62
62
  self._num_nodes = num_nodes
63
63
  self._exclusive = exclusive
64
64
  self._pmi_mode = pmi_mode
65
- self._run_time_limit = run_time_limit
65
+ self._run_time_max = run_time_max
66
66
 
67
67
  def generate_command(self, command_lst: list[str]) -> list[str]:
68
68
  """
@@ -84,7 +84,7 @@ class SrunSpawner(SubprocessSpawner):
84
84
  openmpi_oversubscribe=self._openmpi_oversubscribe,
85
85
  slurm_cmd_args=self._slurm_cmd_args,
86
86
  pmi_mode=self._pmi_mode,
87
- run_time_limit=self._run_time_limit,
87
+ run_time_max=self._run_time_max,
88
88
  )
89
89
  return super().generate_command(
90
90
  command_lst=command_prepend_lst + command_lst,
@@ -1,5 +0,0 @@
1
- *.pyc
2
- .DS_Store
3
- .coverage
4
- .idea/
5
- .vscode/
File without changes