executorlib 1.8.1__tar.gz → 1.9.0__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 (51) hide show
  1. {executorlib-1.8.1 → executorlib-1.9.0}/PKG-INFO +6 -3
  2. {executorlib-1.8.1 → executorlib-1.9.0}/pyproject.toml +6 -2
  3. {executorlib-1.8.1 → executorlib-1.9.0}/src/executorlib/__init__.py +56 -3
  4. {executorlib-1.8.1 → executorlib-1.9.0}/src/executorlib/_version.py +2 -2
  5. {executorlib-1.8.1 → executorlib-1.9.0}/src/executorlib/api.py +2 -0
  6. {executorlib-1.8.1 → executorlib-1.9.0}/src/executorlib/backend/cache_parallel.py +4 -4
  7. {executorlib-1.8.1 → executorlib-1.9.0}/src/executorlib/executor/flux.py +148 -79
  8. {executorlib-1.8.1 → executorlib-1.9.0}/src/executorlib/executor/single.py +139 -67
  9. {executorlib-1.8.1 → executorlib-1.9.0}/src/executorlib/executor/slurm.py +136 -81
  10. {executorlib-1.8.1 → executorlib-1.9.0}/src/executorlib/standalone/command.py +4 -0
  11. {executorlib-1.8.1 → executorlib-1.9.0}/src/executorlib/standalone/hdf.py +58 -7
  12. {executorlib-1.8.1 → executorlib-1.9.0}/src/executorlib/standalone/inputcheck.py +7 -0
  13. executorlib-1.9.0/src/executorlib/standalone/validate.py +62 -0
  14. {executorlib-1.8.1 → executorlib-1.9.0}/src/executorlib/task_scheduler/base.py +12 -2
  15. {executorlib-1.8.1 → executorlib-1.9.0}/src/executorlib/task_scheduler/file/backend.py +2 -1
  16. {executorlib-1.8.1 → executorlib-1.9.0}/src/executorlib/task_scheduler/file/shared.py +143 -51
  17. {executorlib-1.8.1 → executorlib-1.9.0}/src/executorlib/task_scheduler/file/spawner_pysqa.py +31 -3
  18. {executorlib-1.8.1 → executorlib-1.9.0}/src/executorlib/task_scheduler/file/task_scheduler.py +20 -12
  19. {executorlib-1.8.1 → executorlib-1.9.0}/src/executorlib/task_scheduler/interactive/blockallocation.py +26 -3
  20. {executorlib-1.8.1 → executorlib-1.9.0}/src/executorlib/task_scheduler/interactive/dependency.py +21 -9
  21. {executorlib-1.8.1 → executorlib-1.9.0}/src/executorlib/task_scheduler/interactive/dependency_plot.py +3 -1
  22. {executorlib-1.8.1 → executorlib-1.9.0}/src/executorlib/task_scheduler/interactive/onetoone.py +6 -3
  23. {executorlib-1.8.1 → executorlib-1.9.0}/src/executorlib/task_scheduler/interactive/spawner_flux.py +7 -0
  24. {executorlib-1.8.1 → executorlib-1.9.0}/src/executorlib/task_scheduler/interactive/spawner_pysqa.py +22 -15
  25. {executorlib-1.8.1 → executorlib-1.9.0}/src/executorlib/task_scheduler/interactive/spawner_slurm.py +4 -0
  26. {executorlib-1.8.1 → executorlib-1.9.0}/.gitignore +0 -0
  27. {executorlib-1.8.1 → executorlib-1.9.0}/LICENSE +0 -0
  28. {executorlib-1.8.1 → executorlib-1.9.0}/README.md +0 -0
  29. {executorlib-1.8.1 → executorlib-1.9.0}/src/executorlib/backend/__init__.py +0 -0
  30. {executorlib-1.8.1 → executorlib-1.9.0}/src/executorlib/backend/cache_serial.py +0 -0
  31. {executorlib-1.8.1 → executorlib-1.9.0}/src/executorlib/backend/interactive_parallel.py +0 -0
  32. {executorlib-1.8.1 → executorlib-1.9.0}/src/executorlib/backend/interactive_serial.py +0 -0
  33. {executorlib-1.8.1 → executorlib-1.9.0}/src/executorlib/executor/__init__.py +0 -0
  34. {executorlib-1.8.1 → executorlib-1.9.0}/src/executorlib/executor/base.py +0 -0
  35. {executorlib-1.8.1 → executorlib-1.9.0}/src/executorlib/standalone/__init__.py +0 -0
  36. {executorlib-1.8.1 → executorlib-1.9.0}/src/executorlib/standalone/batched.py +0 -0
  37. {executorlib-1.8.1 → executorlib-1.9.0}/src/executorlib/standalone/error.py +0 -0
  38. {executorlib-1.8.1 → executorlib-1.9.0}/src/executorlib/standalone/interactive/__init__.py +0 -0
  39. {executorlib-1.8.1 → executorlib-1.9.0}/src/executorlib/standalone/interactive/arguments.py +0 -0
  40. {executorlib-1.8.1 → executorlib-1.9.0}/src/executorlib/standalone/interactive/backend.py +0 -0
  41. {executorlib-1.8.1 → executorlib-1.9.0}/src/executorlib/standalone/interactive/communication.py +0 -0
  42. {executorlib-1.8.1 → executorlib-1.9.0}/src/executorlib/standalone/interactive/spawner.py +0 -0
  43. {executorlib-1.8.1 → executorlib-1.9.0}/src/executorlib/standalone/queue.py +0 -0
  44. {executorlib-1.8.1 → executorlib-1.9.0}/src/executorlib/standalone/scheduler.py +0 -0
  45. {executorlib-1.8.1 → executorlib-1.9.0}/src/executorlib/standalone/select.py +0 -0
  46. {executorlib-1.8.1 → executorlib-1.9.0}/src/executorlib/standalone/serialize.py +0 -0
  47. {executorlib-1.8.1 → executorlib-1.9.0}/src/executorlib/task_scheduler/__init__.py +0 -0
  48. {executorlib-1.8.1 → executorlib-1.9.0}/src/executorlib/task_scheduler/file/__init__.py +0 -0
  49. {executorlib-1.8.1 → executorlib-1.9.0}/src/executorlib/task_scheduler/file/spawner_subprocess.py +0 -0
  50. {executorlib-1.8.1 → executorlib-1.9.0}/src/executorlib/task_scheduler/interactive/__init__.py +0 -0
  51. {executorlib-1.8.1 → executorlib-1.9.0}/src/executorlib/task_scheduler/interactive/shared.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: executorlib
3
- Version: 1.8.1
3
+ Version: 1.9.0
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
@@ -54,13 +54,14 @@ Requires-Dist: h5py<=3.15.1,>=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
58
  Requires-Dist: pygraphviz<=1.14,>=1.10; extra == 'all'
58
- Requires-Dist: pysqa==0.3.4; extra == 'all'
59
+ Requires-Dist: pysqa==0.3.5; extra == 'all'
59
60
  Provides-Extra: cache
60
61
  Requires-Dist: h5py<=3.15.1,>=3.6.0; extra == 'cache'
61
62
  Provides-Extra: cluster
62
63
  Requires-Dist: h5py<=3.15.1,>=3.6.0; extra == 'cluster'
63
- Requires-Dist: pysqa==0.3.4; extra == 'cluster'
64
+ Requires-Dist: pysqa==0.3.5; extra == 'cluster'
64
65
  Provides-Extra: graph
65
66
  Requires-Dist: networkx<=3.6.1,>=2.8.8; extra == 'graph'
66
67
  Requires-Dist: pygraphviz<=1.14,>=1.10; extra == 'graph'
@@ -70,6 +71,8 @@ Requires-Dist: networkx<=3.6.1,>=2.8.8; extra == 'graphnotebook'
70
71
  Requires-Dist: pygraphviz<=1.14,>=1.10; extra == 'graphnotebook'
71
72
  Provides-Extra: mpi
72
73
  Requires-Dist: mpi4py<=4.1.1,>=3.1.4; extra == 'mpi'
74
+ Provides-Extra: validation
75
+ Requires-Dist: pydantic<=2.12.5,>=2.5.3; extra == 'validation'
73
76
  Description-Content-Type: text/markdown
74
77
 
75
78
  # executorlib
@@ -52,13 +52,17 @@ graphnotebook = [
52
52
  ]
53
53
  mpi = ["mpi4py>=3.1.4,<=4.1.1"]
54
54
  cluster = [
55
- "pysqa==0.3.4",
55
+ "pysqa==0.3.5",
56
56
  "h5py>=3.6.0,<=3.15.1",
57
57
  ]
58
+ validation = [
59
+ "pydantic>=2.5.3,<=2.12.5",
60
+ ]
58
61
  all = [
59
62
  "mpi4py>=3.1.4,<=4.1.1",
60
- "pysqa==0.3.4",
63
+ "pysqa==0.3.5",
61
64
  "h5py>=3.6.0,<=3.15.1",
65
+ "pydantic>=2.5.3,<=2.12.5",
62
66
  "pygraphviz>=1.10,<=1.14",
63
67
  "networkx>=2.8.8,<=3.6.1",
64
68
  "ipython>=7.33.0,<=9.9.0",
@@ -12,6 +12,7 @@ Finally, the get_cache_data() function allows users to cache the content of thei
12
12
  pandas.DataFrame.
13
13
  """
14
14
 
15
+ from concurrent.futures import Future
15
16
  from typing import Optional
16
17
 
17
18
  import executorlib._version
@@ -43,9 +44,35 @@ def get_cache_data(cache_directory: str) -> list[dict]:
43
44
  return get_cache_data(cache_directory=cache_directory)
44
45
 
45
46
 
47
+ def get_future_from_cache(
48
+ cache_directory: str,
49
+ cache_key: str,
50
+ ) -> Future:
51
+ """
52
+ Reload future from HDF5 file in cache directory with the given cache key. The function checks if the output file
53
+ exists, if not it checks for the input file. If neither of them exist, it raises a FileNotFoundError. If the output
54
+ file exists, it loads the output and sets it as the result of the future. If only the input file exists, it checks
55
+ if the execution is finished and if there was an error. If there was no error, it sets the output as the result of
56
+ the future, otherwise it raises the error.
57
+
58
+ Args:
59
+ cache_directory (str): The directory to store cache files.
60
+ cache_key (str): The key of the cache file to be reloaded.
61
+
62
+ Returns:
63
+ Future: Future object containing the result of the execution of the python function.
64
+ """
65
+ from executorlib.standalone.hdf import get_future_from_cache
66
+
67
+ return get_future_from_cache(
68
+ cache_directory=cache_directory,
69
+ cache_key=cache_key,
70
+ )
71
+
72
+
46
73
  def terminate_tasks_in_cache(
47
74
  cache_directory: str,
48
- config_directory: Optional[str] = None,
75
+ pysqa_config_directory: Optional[str] = None,
49
76
  backend: Optional[str] = None,
50
77
  ):
51
78
  """
@@ -53,20 +80,46 @@ def terminate_tasks_in_cache(
53
80
 
54
81
  Args:
55
82
  cache_directory (str): The directory to store cache files.
56
- config_directory (str, optional): path to the config directory.
83
+ pysqa_config_directory (str, optional): path to the pysqa config directory.
57
84
  backend (str, optional): name of the backend used to spawn tasks ["slurm", "flux"].
58
85
  """
59
86
  from executorlib.task_scheduler.file.spawner_pysqa import terminate_tasks_in_cache
60
87
 
61
88
  return terminate_tasks_in_cache(
62
89
  cache_directory=cache_directory,
63
- config_directory=config_directory,
90
+ pysqa_config_directory=pysqa_config_directory,
91
+ backend=backend,
92
+ )
93
+
94
+
95
+ def terminate_task_in_cache(
96
+ cache_directory: str,
97
+ cache_key: str,
98
+ pysqa_config_directory: Optional[str] = None,
99
+ backend: Optional[str] = None,
100
+ ):
101
+ """
102
+ Delete a specific job stored in the cache directory from the queuing system
103
+
104
+ Args:
105
+ cache_directory (str): The directory to store cache files.
106
+ cache_key (str): The key of the cache file to be deleted.
107
+ pysqa_config_directory (str, optional): path to the pysqa config directory.
108
+ backend (str, optional): name of the backend used to spawn tasks ["slurm", "flux"].
109
+ """
110
+ from executorlib.task_scheduler.file.spawner_pysqa import terminate_task_in_cache
111
+
112
+ return terminate_task_in_cache(
113
+ cache_directory=cache_directory,
114
+ cache_key=cache_key,
115
+ pysqa_config_directory=pysqa_config_directory,
64
116
  backend=backend,
65
117
  )
66
118
 
67
119
 
68
120
  __all__: list[str] = [
69
121
  "get_cache_data",
122
+ "get_future_from_cache",
70
123
  "get_item_from_future",
71
124
  "split_future",
72
125
  "terminate_tasks_in_cache",
@@ -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.8.1'
32
- __version_tuple__ = version_tuple = (1, 8, 1)
31
+ __version__ = version = '1.9.0'
32
+ __version_tuple__ = version_tuple = (1, 9, 0)
33
33
 
34
34
  __commit_id__ = commit_id = None
@@ -8,6 +8,7 @@ functionality is considered internal and might change during minor releases.
8
8
  from executorlib.executor.single import TestClusterExecutor
9
9
  from executorlib.standalone.command import get_command_path
10
10
  from executorlib.standalone.interactive.communication import (
11
+ ExecutorlibSocketError,
11
12
  SocketInterface,
12
13
  interface_bootup,
13
14
  interface_connect,
@@ -32,4 +33,5 @@ __all__: list[str] = [
32
33
  "MpiExecSpawner",
33
34
  "SocketInterface",
34
35
  "SubprocessSpawner",
36
+ "ExecutorlibSocketError",
35
37
  ]
@@ -39,11 +39,11 @@ def main() -> None:
39
39
 
40
40
  time_start = time.time()
41
41
  apply_dict = {}
42
- if mpi_rank_zero:
43
- apply_dict = backend_load_file(file_name=file_name)
44
- apply_dict = MPI.COMM_WORLD.bcast(apply_dict, root=0)
45
- output = apply_dict["fn"].__call__(*apply_dict["args"], **apply_dict["kwargs"])
46
42
  try:
43
+ if mpi_rank_zero:
44
+ apply_dict = backend_load_file(file_name=file_name)
45
+ apply_dict = MPI.COMM_WORLD.bcast(apply_dict, root=0)
46
+ output = apply_dict["fn"].__call__(*apply_dict["args"], **apply_dict["kwargs"])
47
47
  result = (
48
48
  MPI.COMM_WORLD.gather(output, root=0) if mpi_size_larger_one else output
49
49
  )