executorlib 1.9.4__py3-none-any.whl → 1.10.1__py3-none-any.whl

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.
executorlib/_version.py CHANGED
@@ -18,7 +18,7 @@ version_tuple: tuple[int | str, ...]
18
18
  commit_id: str | None
19
19
  __commit_id__: str | None
20
20
 
21
- __version__ = version = '1.9.4'
22
- __version_tuple__ = version_tuple = (1, 9, 4)
21
+ __version__ = version = '1.10.1'
22
+ __version_tuple__ = version_tuple = (1, 10, 1)
23
23
 
24
24
  __commit_id__ = commit_id = None
@@ -12,7 +12,7 @@ from executorlib.standalone.interactive.communication import (
12
12
  )
13
13
 
14
14
 
15
- def main(argument_lst: Optional[list[str]] = None):
15
+ def evaluate_cmd(argument_lst: Optional[list[str]] = None):
16
16
  """
17
17
  The main function of the program.
18
18
 
@@ -90,4 +90,4 @@ def main(argument_lst: Optional[list[str]] = None):
90
90
 
91
91
 
92
92
  if __name__ == "__main__":
93
- main(argument_lst=sys.argv)
93
+ evaluate_cmd(argument_lst=sys.argv)
@@ -38,7 +38,10 @@ def dump(file_name: Optional[str], data_dict: dict) -> None:
38
38
  with contextlib.suppress(ValueError):
39
39
  fname.create_dataset(
40
40
  name="/" + group_dict[data_key],
41
- data=np.void(cloudpickle.dumps(data_value)),
41
+ data=np.frombuffer(
42
+ cloudpickle.dumps(data_value), dtype=np.uint8
43
+ ),
44
+ compression="gzip",
42
45
  )
43
46
 
44
47
 
@@ -55,26 +58,26 @@ def load(file_name: str) -> dict:
55
58
  with h5py.File(file_name, "r") as hdf:
56
59
  data_dict = {}
57
60
  if "function" in hdf:
58
- data_dict["fn"] = cloudpickle.loads(np.void(hdf["/function"]))
61
+ data_dict["fn"] = cloudpickle.loads(hdf["/function"][()].tobytes())
59
62
  else:
60
63
  raise TypeError("Function not found in HDF5 file.")
61
64
  if "input_args" in hdf:
62
- data_dict["args"] = cloudpickle.loads(np.void(hdf["/input_args"]))
65
+ data_dict["args"] = cloudpickle.loads(hdf["/input_args"][()].tobytes())
63
66
  else:
64
67
  data_dict["args"] = ()
65
68
  if "input_kwargs" in hdf:
66
- data_dict["kwargs"] = cloudpickle.loads(np.void(hdf["/input_kwargs"]))
69
+ data_dict["kwargs"] = cloudpickle.loads(hdf["/input_kwargs"][()].tobytes())
67
70
  else:
68
71
  data_dict["kwargs"] = {}
69
72
  if "resource_dict" in hdf:
70
73
  data_dict["resource_dict"] = cloudpickle.loads(
71
- np.void(hdf["/resource_dict"])
74
+ hdf["/resource_dict"][()].tobytes()
72
75
  )
73
76
  else:
74
77
  data_dict["resource_dict"] = {}
75
78
  if "error_log_file" in hdf:
76
79
  data_dict["error_log_file"] = cloudpickle.loads(
77
- np.void(hdf["/error_log_file"])
80
+ hdf["/error_log_file"][()].tobytes()
78
81
  )
79
82
  return data_dict
80
83
 
@@ -93,9 +96,9 @@ def get_output(file_name: str) -> tuple[bool, bool, Any]:
93
96
  def get_output_helper(file_name: str) -> tuple[bool, bool, Any]:
94
97
  with h5py.File(file_name, "r") as hdf:
95
98
  if "output" in hdf:
96
- return True, True, cloudpickle.loads(np.void(hdf["/output"]))
99
+ return True, True, cloudpickle.loads(hdf["/output"][()].tobytes())
97
100
  elif "error" in hdf:
98
- return True, False, cloudpickle.loads(np.void(hdf["/error"]))
101
+ return True, False, cloudpickle.loads(hdf["/error"][()].tobytes())
99
102
  else:
100
103
  return False, False, None
101
104
 
@@ -122,7 +125,7 @@ def get_runtime(file_name: str) -> float:
122
125
  """
123
126
  with h5py.File(file_name, "r") as hdf:
124
127
  if "runtime" in hdf:
125
- return cloudpickle.loads(np.void(hdf["/runtime"]))
128
+ return cloudpickle.loads(hdf["/runtime"][()].tobytes())
126
129
  else:
127
130
  return 0.0
128
131
 
@@ -140,7 +143,7 @@ def get_queue_id(file_name: Optional[str]) -> Optional[int]:
140
143
  if file_name is not None and os.path.exists(file_name):
141
144
  with h5py.File(file_name, "r") as hdf:
142
145
  if "queue_id" in hdf:
143
- return cloudpickle.loads(np.void(hdf["/queue_id"]))
146
+ return cloudpickle.loads(hdf["/queue_id"][()].tobytes())
144
147
  return None
145
148
 
146
149
 
@@ -230,7 +233,7 @@ def _get_content_of_file(file_name: str) -> dict:
230
233
  """
231
234
  with h5py.File(file_name, "r") as hdf:
232
235
  return {
233
- key: cloudpickle.loads(np.void(hdf["/" + key]))
236
+ key: cloudpickle.loads(hdf["/" + key][()].tobytes())
234
237
  for key in group_dict.values()
235
238
  if key in hdf
236
239
  }
@@ -189,7 +189,7 @@ class PysqaSpawner(BaseSpawner):
189
189
  if self._cwd is not None:
190
190
  working_directory = os.path.join(self._cwd, hash)
191
191
  else:
192
- working_directory = os.path.abspath(hash)
192
+ working_directory = os.path.join(os.path.abspath("executorlib_cache"), hash)
193
193
  set_current_directory_in_environment()
194
194
  return queue_adapter.submit_job(
195
195
  command=" ".join(self.generate_command(command_lst=command_lst)),
@@ -242,8 +242,6 @@ def create_pysqa_block_allocation_scheduler(
242
242
  executor_kwargs["cwd"] = os.path.abspath(cache_directory)
243
243
  if cache_directory is not None:
244
244
  executor_kwargs["cache_directory"] = os.path.abspath(cache_directory)
245
- else:
246
- executor_kwargs["cache_directory"] = os.path.abspath(".")
247
245
  executor_kwargs["hostname_localhost"] = hostname_localhost
248
246
  executor_kwargs["log_obj_size"] = log_obj_size
249
247
  executor_kwargs["pmi_mode"] = pmi_mode
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: executorlib
3
- Version: 1.9.4
3
+ Version: 1.10.1
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
@@ -45,8 +45,9 @@ Classifier: Programming Language :: Python :: 3.10
45
45
  Classifier: Programming Language :: Python :: 3.11
46
46
  Classifier: Programming Language :: Python :: 3.12
47
47
  Classifier: Programming Language :: Python :: 3.13
48
+ Classifier: Programming Language :: Python :: 3.14
48
49
  Classifier: Topic :: Scientific/Engineering :: Physics
49
- Requires-Python: <3.14,>3.9
50
+ Requires-Python: <3.15,>3.9
50
51
  Requires-Dist: cloudpickle<=3.1.2,>=2.0.0
51
52
  Requires-Dist: pyzmq<=27.1.0,>=25.0.0
52
53
  Provides-Extra: all
@@ -56,12 +57,12 @@ Requires-Dist: mpi4py<=4.1.2,>=3.1.4; extra == 'all'
56
57
  Requires-Dist: networkx<=3.6.1,>=2.8.8; extra == 'all'
57
58
  Requires-Dist: pydantic<=2.13.4,>=2.5.3; extra == 'all'
58
59
  Requires-Dist: pygraphviz<=1.14,>=1.10; extra == 'all'
59
- Requires-Dist: pysqa==0.4.2; extra == 'all'
60
+ Requires-Dist: pysqa==0.4.3; extra == 'all'
60
61
  Provides-Extra: cache
61
62
  Requires-Dist: h5py<=3.16.0,>=3.6.0; extra == 'cache'
62
63
  Provides-Extra: cluster
63
64
  Requires-Dist: h5py<=3.16.0,>=3.6.0; extra == 'cluster'
64
- Requires-Dist: pysqa==0.4.2; extra == 'cluster'
65
+ Requires-Dist: pysqa==0.4.3; extra == 'cluster'
65
66
  Provides-Extra: graph
66
67
  Requires-Dist: networkx<=3.6.1,>=2.8.8; extra == 'graph'
67
68
  Requires-Dist: pygraphviz<=1.14,>=1.10; extra == 'graph'
@@ -218,6 +219,25 @@ given allocation. Even when [SLURM](https://slurm.schedmd.com) is used as primar
218
219
  recommended to use [SLURM with flux](https://executorlib.readthedocs.io/en/latest/3-hpc-job.html#slurm-with-flux)
219
220
  as hierarchical job scheduler within the allocations.
220
221
 
222
+ ## Which Executor should I use?
223
+ executorlib provides five `Executor` classes. They all share the same `submit()` / `map()` interface and only differ in
224
+ *where* the Python functions are executed and *how* the resources are requested. A common workflow is to develop and
225
+ test with the `SingleNodeExecutor` on a laptop and then switch to one of the HPC executors by changing only the class
226
+ name:
227
+
228
+ | Executor | Where it runs | Scheduler command | Best for |
229
+ |---|---|---|---|
230
+ | [`SingleNodeExecutor`](https://executorlib.readthedocs.io/en/latest/1-single-node.html) | laptop, workstation or single compute node | `subprocess` | developing and testing a workflow |
231
+ | [`SlurmClusterExecutor`](https://executorlib.readthedocs.io/en/latest/2-hpc-cluster.html#slurm) | HPC login node | `sbatch` (one job per function) | long-running functions that should outlive the Python session |
232
+ | [`SlurmJobExecutor`](https://executorlib.readthedocs.io/en/latest/3-hpc-job.html#slurm) | inside a SLURM allocation | `srun` (job steps) | many functions within one existing allocation |
233
+ | [`FluxClusterExecutor`](https://executorlib.readthedocs.io/en/latest/2-hpc-cluster.html#flux) | HPC login node or Flux instance | `flux submit` | long-running functions; disconnecting and reconnecting |
234
+ | [`FluxJobExecutor`](https://executorlib.readthedocs.io/en/latest/3-hpc-job.html#flux) | inside a Flux allocation | `flux run` | high-throughput execution of many short functions |
235
+
236
+ The **Cluster** executors submit each Python function as an individual job and communicate via the file system, so the
237
+ Python process which created the executor can be closed and the results reloaded later. The **Job** executors run inside
238
+ an existing allocation and communicate via sockets, which has lower overhead and is the better choice for many short
239
+ function calls.
240
+
221
241
  ## Documentation
222
242
  * [Installation](https://executorlib.readthedocs.io/en/latest/installation.html)
223
243
  * [Minimal](https://executorlib.readthedocs.io/en/latest/installation.html#minimal)
@@ -243,6 +263,9 @@ as hierarchical job scheduler within the allocations.
243
263
  * [HPC Cluster Executor](https://executorlib.readthedocs.io/en/latest/2-hpc-cluster.html)
244
264
  * [SLURM](https://executorlib.readthedocs.io/en/latest/2-hpc-cluster.html#slurm)
245
265
  * [Flux](https://executorlib.readthedocs.io/en/latest/2-hpc-cluster.html#flux)
266
+ * [Disconnecting and Reconnecting](https://executorlib.readthedocs.io/en/latest/2-hpc-cluster.html#disconnecting-and-reconnecting)
267
+ * [Combine both](https://executorlib.readthedocs.io/en/latest/2-hpc-cluster.html#combine-both)
268
+ * [Cleaning Cache](https://executorlib.readthedocs.io/en/latest/2-hpc-cluster.html#cleaning-cache)
246
269
  * [HPC Job Executor](https://executorlib.readthedocs.io/en/latest/3-hpc-job.html)
247
270
  * [SLURM](https://executorlib.readthedocs.io/en/latest/3-hpc-job.html#slurm)
248
271
  * [SLURM with Flux](https://executorlib.readthedocs.io/en/latest/3-hpc-job.html#slurm-with-flux)
@@ -250,6 +273,12 @@ as hierarchical job scheduler within the allocations.
250
273
  * [Application](https://executorlib.readthedocs.io/en/latest/application.html)
251
274
  * [GPAW](https://executorlib.readthedocs.io/en/latest/4-1-gpaw.html)
252
275
  * [Quantum Espresso](https://executorlib.readthedocs.io/en/latest/4-2-quantum-espresso.html)
276
+ * [Integration](https://executorlib.readthedocs.io/en/latest/coupling.html)
277
+ * [emcee](https://executorlib.readthedocs.io/en/latest/coupling.html#emcee)
278
+ * [pipefunc](https://executorlib.readthedocs.io/en/latest/coupling.html#pipefunc)
279
+ * [omp4py](https://executorlib.readthedocs.io/en/latest/coupling.html#omp4py)
280
+ * [pylammpsmpi](https://executorlib.readthedocs.io/en/latest/coupling.html#pylammpsmpi)
281
+ * [General Pattern](https://executorlib.readthedocs.io/en/latest/coupling.html#general-pattern)
253
282
  * [Trouble Shooting](https://executorlib.readthedocs.io/en/latest/trouble_shooting.html)
254
283
  * [Filesystem Usage](https://executorlib.readthedocs.io/en/latest/trouble_shooting.html#filesystem-usage)
255
284
  * [Firewall Issues](https://executorlib.readthedocs.io/en/latest/trouble_shooting.html#firewall-issues)
@@ -1,11 +1,11 @@
1
1
  executorlib/__init__.py,sha256=IY_DkT706LPIv2_iIe3whrQNGoDzaDFYBvXyUepoZpw,4780
2
- executorlib/_version.py,sha256=VdLE9NNjOWcm4_Kh_W9w_lFN3bh0oesrwyTL3nQnUKg,520
2
+ executorlib/_version.py,sha256=9cYIW_mnApkxjl7hrsLPCkpAtl6R-GXOqmSgy2KFfGA,522
3
3
  executorlib/api.py,sha256=F6ibDJnVcPGxxPe-UScFJHprWHiVsETGhgAvS1T-9ZI,1365
4
4
  executorlib/backend/__init__.py,sha256=2b_iwds4VUrJe92nKtQXkoGxkJiXeEDSlbvCRN_-de8,456
5
5
  executorlib/backend/cache_parallel.py,sha256=ldb2iYzrhcXJZ0LcH75FpTLO_6F51mleU9JGAilF00k,2020
6
6
  executorlib/backend/cache_serial.py,sha256=9T3bAxVivGxvzHnXmvysyEPP4sw--VCwXCn2Mdkt0-o,177
7
7
  executorlib/backend/interactive_parallel.py,sha256=HimGnWOdTXInC3o7W4wMUSTTlj6MsMPLJLkcNTaK_SQ,3869
8
- executorlib/backend/interactive_serial.py,sha256=NxlSX566rQM-pHiy2rQja2rr3lFwdnv0EvIyXk8H7co,2982
8
+ executorlib/backend/interactive_serial.py,sha256=ZV_VGcnCAk7N-VcoJKYEIG0OGUUwR4KFWoHG7MVBA3g,2998
9
9
  executorlib/executor/__init__.py,sha256=oR2ABLAMYV_TNs1eG-3-MAKHFS7OKB-1KOzCqKNbtWA,310
10
10
  executorlib/executor/base.py,sha256=UKJViNoshthAgF2I4FoK0nZT0FL7WgkrzWFYhRiU1H4,6957
11
11
  executorlib/executor/flux.py,sha256=g8K1GMfn9KMM4udj3LdmDMahavPBBCOusYVG36W1hAY,40779
@@ -15,7 +15,7 @@ executorlib/standalone/__init__.py,sha256=n_Q4NUFu35Fn0qlWIhmoC_FyUkmFGlWn1cNc_7
15
15
  executorlib/standalone/batched.py,sha256=o3TtsFJir8nP1O_NZFfW0Q78CoZAFgHMyroWlg520nE,1446
16
16
  executorlib/standalone/command.py,sha256=4Xndog84zJdku1ke1DwdUamkWvzRrMz-VDCi5cRXi0M,6548
17
17
  executorlib/standalone/error.py,sha256=aaMQoRsoLzLCbYT-E4LZxGM9pm_AhjMesRjVt0d_LDk,714
18
- executorlib/standalone/hdf.py,sha256=nE2mTH1U8O7sm2TPJkfRU0uEgWJOhLnYxI6yZord8Eo,7623
18
+ executorlib/standalone/hdf.py,sha256=dRePOCYXbPG_i__ASUcD4qs5AAU2fPbP5o_5ytwaOjw,7805
19
19
  executorlib/standalone/inputcheck.py,sha256=kSWUzqdMOhILYXW4Isumn1EGH3SegxPUMWRkUWfEleU,10041
20
20
  executorlib/standalone/queue.py,sha256=KFEBFQXGvcaf5qcuCjT5kaZg7ucWOTGOtrD96tIBlq0,589
21
21
  executorlib/standalone/scheduler.py,sha256=LhCuIdaw9BjrP3GerbHUIqwsvxERdtH5JQoeyAqASIU,2325
@@ -42,9 +42,9 @@ executorlib/task_scheduler/interactive/dependency_plot.py,sha256=iZBZ9UMDeYOMFjD
42
42
  executorlib/task_scheduler/interactive/onetoone.py,sha256=cTXgTXR9kKzzlx6EfGumMsEm7DUa7BD9JSeBpdPiupI,13312
43
43
  executorlib/task_scheduler/interactive/shared.py,sha256=-krntmZFOOE5U0HdFwuU8JZPqZQmPW4-cePDWuvkTgM,6305
44
44
  executorlib/task_scheduler/interactive/spawner_flux.py,sha256=M7CPWvzY7MDkplJ4awymh7WbMYwKsDPTKxA2Op9wfNo,7075
45
- executorlib/task_scheduler/interactive/spawner_pysqa.py,sha256=96NqUfoIBUFd7KjY02dpIL9ZoS_u5beRuNw_1FUKH6Q,10393
45
+ executorlib/task_scheduler/interactive/spawner_pysqa.py,sha256=i-E9MOK9_aiUigrrGFMLs_m0y3VhrEgu95_PXCOg-hg,10352
46
46
  executorlib/task_scheduler/interactive/spawner_slurm.py,sha256=K5mj63PE8FYbkw9WWm4uEjoA5q0HM42z1d2wjAmO5YA,3713
47
- executorlib-1.9.4.dist-info/METADATA,sha256=4augHmAbGQ-7H0r4Zh6vaFvTh-yTwZMSyuLVYsp7-Qo,18249
48
- executorlib-1.9.4.dist-info/WHEEL,sha256=mffPy8wBnZQn2VnJUU5jE99KsxaSfiyMHV9Yt0aLVxs,87
49
- executorlib-1.9.4.dist-info/licenses/LICENSE,sha256=NkrhccIxPXCbbvp_upyVojt7DNTwZIco3z9wsYpSLqU,1511
50
- executorlib-1.9.4.dist-info/RECORD,,
47
+ executorlib-1.10.1.dist-info/METADATA,sha256=cK6UBcUFueR_PY8sOJC9D6xJ0gBNTJ7oQyVSLlFi4A8,20966
48
+ executorlib-1.10.1.dist-info/WHEEL,sha256=mffPy8wBnZQn2VnJUU5jE99KsxaSfiyMHV9Yt0aLVxs,87
49
+ executorlib-1.10.1.dist-info/licenses/LICENSE,sha256=NkrhccIxPXCbbvp_upyVojt7DNTwZIco3z9wsYpSLqU,1511
50
+ executorlib-1.10.1.dist-info/RECORD,,