executorlib 1.10.2__py3-none-any.whl → 1.10.3__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/__init__.py CHANGED
@@ -44,6 +44,35 @@ def get_cache_data(cache_directory: str) -> list[dict]:
44
44
  return get_cache_data(cache_directory=cache_directory)
45
45
 
46
46
 
47
+ def get_cache_data_queue(
48
+ cache_directory: str,
49
+ queue_type: Optional[str] = None,
50
+ config_directory: Optional[str] = None,
51
+ ) -> list[dict]:
52
+ """
53
+ Collect all HDF5 files in the cache directory and check their status in the queue system
54
+
55
+ Args:
56
+ cache_directory (str): The directory to store cache files.
57
+ queue_type (str, optional): The type of the queue system ["slurm", "flux"].
58
+ config_directory (str, optional): The directory containing the configuration for the queue system.
59
+
60
+ Returns:
61
+ list[dict]: List of dictionaries each representing on of the HDF5 files in the
62
+ cache directory with their status in the queue system.
63
+ """
64
+ from executorlib.standalone.hdf import get_cache_data
65
+ from executorlib.task_scheduler.file.spawner_pysqa import (
66
+ get_queue_system_cache_data,
67
+ )
68
+
69
+ return get_queue_system_cache_data(
70
+ cache_dict=get_cache_data(cache_directory=cache_directory),
71
+ queue_type=queue_type,
72
+ config_directory=config_directory,
73
+ )
74
+
75
+
47
76
  def get_future_from_cache(
48
77
  cache_directory: str,
49
78
  cache_key: str,
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.10.2'
22
- __version_tuple__ = version_tuple = (1, 10, 2)
21
+ __version__ = version = '1.10.3'
22
+ __version_tuple__ = version_tuple = (1, 10, 3)
23
23
 
24
24
  __commit_id__ = commit_id = None
@@ -150,9 +150,11 @@ class SocketInterface:
150
150
  """
151
151
  result = None
152
152
  if self._spawner.poll():
153
- result = self.send_and_receive_dict(
153
+ output = self.send_and_receive_dict(
154
154
  input_dict={"shutdown": True, "wait": wait}
155
- )["result"]
155
+ )
156
+ if "result" in output:
157
+ result = output["result"]
156
158
  self._spawner.shutdown(wait=wait)
157
159
  self._reset_socket()
158
160
  return result
@@ -34,7 +34,7 @@ def serialize_funct(
34
34
  fn_kwargs: Optional[dict] = None,
35
35
  resource_dict: Optional[dict] = None,
36
36
  cache_key: Optional[str] = None,
37
- ) -> tuple[str, dict]:
37
+ ) -> tuple[str, dict, Optional[Exception]]:
38
38
  """
39
39
  Serialize a function and its arguments and keyword arguments into an HDF5 file.
40
40
 
@@ -56,7 +56,8 @@ def serialize_funct(
56
56
  overwritten by setting the cache_key.
57
57
 
58
58
  Returns:
59
- Tuple[str, dict]: A tuple containing the task key and the serialized data.
59
+ Tuple[str, dict, Optional[Exception]]: A tuple containing the task key, the serialized data and an
60
+ exception if the serialization failed.
60
61
 
61
62
  """
62
63
  if fn_args is None:
@@ -68,21 +69,25 @@ def serialize_funct(
68
69
  if cache_key is not None:
69
70
  task_key = cache_key
70
71
  else:
71
- binary_all = cloudpickle.dumps(
72
- {
73
- "fn": fn,
74
- "args": fn_args,
75
- "kwargs": fn_kwargs,
76
- }
77
- )
78
- task_key = _get_function_name(fn=fn) + _get_hash(binary=binary_all)
72
+ try:
73
+ binary_all = cloudpickle.dumps(
74
+ {
75
+ "fn": fn,
76
+ "args": fn_args,
77
+ "kwargs": fn_kwargs,
78
+ }
79
+ )
80
+ except Exception as e:
81
+ return "", {}, e
82
+ else:
83
+ task_key = _get_function_name(fn=fn) + _get_hash(binary=binary_all)
79
84
  data = {
80
85
  "fn": fn,
81
86
  "args": fn_args,
82
87
  "kwargs": fn_kwargs,
83
88
  "resource_dict": resource_dict,
84
89
  }
85
- return task_key, data
90
+ return task_key, data, None
86
91
 
87
92
 
88
93
  def _get_hash(binary: bytes) -> str:
@@ -129,7 +129,7 @@ def execute_tasks_h5(
129
129
  executor_kwargs=executor_kwargs,
130
130
  )
131
131
  )
132
- task_key, data_dict = serialize_funct(
132
+ task_key, data_dict, serialize_exception = serialize_funct(
133
133
  fn=task_dict["fn"],
134
134
  fn_args=task_args,
135
135
  fn_kwargs=task_kwargs,
@@ -137,7 +137,9 @@ def execute_tasks_h5(
137
137
  cache_key=cache_key,
138
138
  )
139
139
  data_dict["error_log_file"] = error_log_file
140
- if task_key not in memory_dict:
140
+ if serialize_exception is not None:
141
+ task_dict["future"].set_exception(serialize_exception)
142
+ elif task_key not in memory_dict:
141
143
  if os.path.join(
142
144
  cache_directory, task_key + "_o.h5"
143
145
  ) not in get_cache_files(cache_directory=cache_directory):
@@ -156,25 +158,31 @@ def execute_tasks_h5(
156
158
  )
157
159
  )
158
160
  task_dependent_lst = []
159
- process_dict[task_key] = execute_function(
160
- command=get_cache_execute_command(
161
+ try:
162
+ process_dict[task_key] = execute_function(
163
+ command=get_cache_execute_command(
164
+ file_name=file_name,
165
+ cores=task_resource_dict["cores"],
166
+ backend=backend,
167
+ exclusive=task_resource_dict.get("exclusive", False),
168
+ openmpi_oversubscribe=task_resource_dict.get(
169
+ "openmpi_oversubscribe", False
170
+ ),
171
+ pmi_mode=pmi_mode,
172
+ ),
161
173
  file_name=file_name,
162
- cores=task_resource_dict["cores"],
174
+ data_dict=data_dict,
175
+ task_dependent_lst=task_dependent_lst,
176
+ resource_dict=task_resource_dict,
177
+ config_directory=pysqa_config_directory,
163
178
  backend=backend,
164
- exclusive=task_resource_dict.get("exclusive", False),
165
- openmpi_oversubscribe=task_resource_dict.get(
166
- "openmpi_oversubscribe", False
167
- ),
168
- pmi_mode=pmi_mode,
169
- ),
170
- file_name=file_name,
171
- data_dict=data_dict,
172
- task_dependent_lst=task_dependent_lst,
173
- resource_dict=task_resource_dict,
174
- config_directory=pysqa_config_directory,
175
- backend=backend,
176
- cache_directory=cache_directory,
177
- )
179
+ cache_directory=cache_directory,
180
+ )
181
+ except Exception as e:
182
+ task_dict["future"].set_exception(e)
183
+ memory_dict[task_key] = task_dict["future"]
184
+ future_queue.task_done()
185
+ continue
178
186
  file_name = os.path.join(cache_directory, task_key + "_o.h5")
179
187
  file_name_dict[task_key] = file_name
180
188
  queue_id = get_queue_id(file_name=file_name)
@@ -2,6 +2,7 @@ import os
2
2
  from subprocess import CalledProcessError
3
3
  from typing import Optional
4
4
 
5
+ from pandas import DataFrame
5
6
  from pysqa import QueueAdapter
6
7
 
7
8
  from executorlib.standalone.command_pysqa import pysqa_execute_command, pysqa_terminate
@@ -154,3 +155,58 @@ def terminate_task_in_cache(
154
155
  backend=backend,
155
156
  )
156
157
  os.remove(file_name)
158
+
159
+
160
+ def get_queue_system_cache_data(
161
+ cache_dict: list[dict],
162
+ queue_type: Optional[str] = None,
163
+ config_directory: Optional[str] = None,
164
+ ) -> list[dict]:
165
+ """
166
+ Get the status of the queue system.
167
+
168
+ Args:
169
+ cache_dict (list[dict]): List of dictionaries each representing on of the HDF5 files in the cache directory.
170
+ queue_type (str, optional): The type of the queue system ["slurm", "flux"].
171
+ config_directory (str, optional): The directory containing the configuration for the queue system.
172
+
173
+ Returns:
174
+ cache_dict (list[dict]): List of dictionaries each representing on of the HDF5 files in the cache directory.
175
+ """
176
+ return _merge_cache_with_queue_status(
177
+ cache_dict=cache_dict,
178
+ dataframe=QueueAdapter(
179
+ directory=config_directory,
180
+ queue_type=queue_type,
181
+ ).get_queue_status(),
182
+ )
183
+
184
+
185
+ def _merge_cache_with_queue_status(
186
+ cache_dict: list[dict], dataframe: DataFrame
187
+ ) -> list[dict]:
188
+ """
189
+ Merge the cache data with the queue status.
190
+
191
+ Args:
192
+ cache_dict (list[dict]): List of dictionaries each representing on of the HDF5 files in the cache directory.
193
+ dataframe (DataFrame): DataFrame containing the status of the queue system.
194
+
195
+ Returns:
196
+ cache_dict (list[dict]): List of dictionaries each representing on of the HDF5 files in the cache directory.
197
+ """
198
+ cache_updated_dict = []
199
+ for row in cache_dict:
200
+ if "output" in row and row["output"]:
201
+ row["status"] = "finished"
202
+ elif "queue_id" in row and row["queue_id"] in dataframe["jobid"].values:
203
+ row["status"] = dataframe[dataframe["jobid"] == row["queue_id"]][
204
+ "status"
205
+ ].values[-1]
206
+ elif "queue_id" not in row:
207
+ row["status"] = "running"
208
+ else:
209
+ row["status"] = "aborted"
210
+ cache_updated_dict.append(row)
211
+
212
+ return cache_updated_dict
@@ -80,35 +80,37 @@ class BlockAllocationTaskScheduler(TaskSchedulerBase):
80
80
  executor_kwargs["restart_limit"] = restart_limit
81
81
  self._process_kwargs = executor_kwargs
82
82
  self._max_workers = max_workers
83
- self_id = random.getrandbits(128)
84
- self._self_id = self_id
83
+ self._self_id = random.getrandbits(128)
85
84
  _interrupt_bootup_dict[self._self_id] = False
86
- alive_workers = [max_workers]
87
- alive_workers_lock = Lock()
88
- bootup_events = [Event() for _ in range(self._max_workers)]
89
- bootup_events[0].set()
85
+ self._alive_workers = [max_workers]
86
+ self._alive_workers_lock = Lock()
87
+ self._bootup_events = [Event() for _ in range(self._max_workers)]
88
+ self._bootup_events[0].set()
90
89
  self._set_process(
91
90
  process=[
92
91
  Thread(
93
92
  target=_execute_multiple_tasks,
94
- kwargs=executor_kwargs
95
- | {
96
- "worker_id": worker_id,
97
- "stop_function": lambda: _interrupt_bootup_dict[self_id],
98
- "bootup_event": bootup_events[worker_id],
99
- "next_bootup_event": (
100
- bootup_events[worker_id + 1]
101
- if worker_id + 1 < self._max_workers
102
- else None
103
- ),
104
- "alive_workers": alive_workers,
105
- "alive_workers_lock": alive_workers_lock,
106
- },
93
+ kwargs=self._worker_kwargs(worker_id),
107
94
  )
108
95
  for worker_id in range(self._max_workers)
109
96
  ],
110
97
  )
111
98
 
99
+ def _worker_kwargs(self, worker_id: int) -> dict:
100
+ self_id = self._self_id
101
+ return self._process_kwargs | {
102
+ "worker_id": worker_id,
103
+ "stop_function": lambda: _interrupt_bootup_dict[self_id],
104
+ "bootup_event": self._bootup_events[worker_id],
105
+ "next_bootup_event": (
106
+ self._bootup_events[worker_id + 1]
107
+ if worker_id + 1 < len(self._bootup_events)
108
+ else None
109
+ ),
110
+ "alive_workers": self._alive_workers,
111
+ "alive_workers_lock": self._alive_workers_lock,
112
+ }
113
+
112
114
  @property
113
115
  def max_workers(self) -> int:
114
116
  return self._max_workers
@@ -126,12 +128,20 @@ class BlockAllocationTaskScheduler(TaskSchedulerBase):
126
128
  process for process in self._process if process.is_alive()
127
129
  ]
128
130
  elif self._max_workers < max_workers:
131
+ old_max_workers = self._max_workers
132
+ self._bootup_events.extend(
133
+ Event() for _ in range(max_workers - old_max_workers)
134
+ )
135
+ for idx in range(old_max_workers, max_workers):
136
+ self._bootup_events[idx].set()
137
+ with self._alive_workers_lock:
138
+ self._alive_workers[0] += max_workers - old_max_workers
129
139
  new_process_lst = [
130
140
  Thread(
131
141
  target=_execute_multiple_tasks,
132
- kwargs=self._process_kwargs,
142
+ kwargs=self._worker_kwargs(worker_id),
133
143
  )
134
- for _ in range(max_workers - self._max_workers)
144
+ for worker_id in range(old_max_workers, max_workers)
135
145
  ]
136
146
  for process_instance in new_process_lst:
137
147
  process_instance.start()
@@ -101,13 +101,17 @@ def _execute_task_without_cache(
101
101
  Returns:
102
102
  bool: True if the task was submitted successfully, False otherwise.
103
103
  """
104
- output = interface.send_and_receive_dict(input_dict=task_dict)
105
- if "result" in output:
106
- future_obj.set_result(output["result"])
107
- elif isinstance(output["error"], ExecutorlibSocketError):
108
- return False
104
+ try:
105
+ output = interface.send_and_receive_dict(input_dict=task_dict)
106
+ except Exception as e:
107
+ future_obj.set_exception(exception=e)
109
108
  else:
110
- future_obj.set_exception(exception=output["error"])
109
+ if "result" in output:
110
+ future_obj.set_result(output["result"])
111
+ elif isinstance(output["error"], ExecutorlibSocketError):
112
+ return False
113
+ else:
114
+ future_obj.set_exception(exception=output["error"])
111
115
  return True
112
116
 
113
117
 
@@ -132,27 +136,34 @@ def _execute_task_with_cache(
132
136
  """
133
137
  from executorlib.standalone.hdf import dump, get_cache_files, get_output
134
138
 
135
- task_key, data_dict = serialize_funct(
139
+ task_key, data_dict, serialize_exception = serialize_funct(
136
140
  fn=task_dict["fn"],
137
141
  fn_args=task_dict["args"],
138
142
  fn_kwargs=task_dict["kwargs"],
139
143
  resource_dict=task_dict.get("resource_dict", {}),
140
144
  cache_key=cache_key,
141
145
  )
142
- file_name = os.path.abspath(os.path.join(cache_directory, task_key + "_o.h5"))
143
- if file_name not in get_cache_files(cache_directory=cache_directory):
144
- time_start = time.time()
145
- output = interface.send_and_receive_dict(input_dict=task_dict)
146
- if "result" in output:
147
- data_dict["output"] = output["result"]
148
- data_dict["runtime"] = time.time() - time_start
149
- dump(file_name=file_name, data_dict=data_dict)
150
- future_obj.set_result(output["result"])
151
- elif isinstance(output["error"], ExecutorlibSocketError):
152
- return False
153
- else:
154
- future_obj.set_exception(exception=output["error"])
146
+ if serialize_exception is not None:
147
+ future_obj.set_exception(exception=serialize_exception)
155
148
  else:
156
- _, _, result = get_output(file_name=file_name)
157
- future_obj.set_result(result)
149
+ file_name = os.path.abspath(os.path.join(cache_directory, task_key + "_o.h5"))
150
+ if file_name not in get_cache_files(cache_directory=cache_directory):
151
+ time_start = time.time()
152
+ try:
153
+ output = interface.send_and_receive_dict(input_dict=task_dict)
154
+ except Exception as e:
155
+ future_obj.set_exception(exception=e)
156
+ return True
157
+ if "result" in output:
158
+ data_dict["output"] = output["result"]
159
+ data_dict["runtime"] = time.time() - time_start
160
+ dump(file_name=file_name, data_dict=data_dict)
161
+ future_obj.set_result(output["result"])
162
+ elif isinstance(output["error"], ExecutorlibSocketError):
163
+ return False
164
+ else:
165
+ future_obj.set_exception(exception=output["error"])
166
+ else:
167
+ _, _, result = get_output(file_name=file_name)
168
+ future_obj.set_result(result)
158
169
  return True
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.4
1
+ Metadata-Version: 2.5
2
2
  Name: executorlib
3
- Version: 1.10.2
3
+ Version: 1.10.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
@@ -49,31 +49,31 @@ Classifier: Programming Language :: Python :: 3.14
49
49
  Classifier: Topic :: Scientific/Engineering :: Physics
50
50
  Requires-Python: <3.15,>3.9
51
51
  Requires-Dist: cloudpickle<=3.1.2,>=2.0.0
52
- Requires-Dist: pyzmq<=27.1.0,>=25.0.0
52
+ Requires-Dist: pyzmq<=27.2.0,>=25.0.0
53
53
  Provides-Extra: all
54
54
  Requires-Dist: h5py<=3.16.0,>=3.6.0; extra == 'all'
55
55
  Requires-Dist: ipython<=9.9.0,>=7.33.0; extra == 'all'
56
56
  Requires-Dist: mpi4py<=4.1.2,>=3.1.4; extra == 'all'
57
57
  Requires-Dist: networkx<=3.6.1,>=2.8.8; extra == 'all'
58
- Requires-Dist: pydantic<=2.13.4,>=2.5.3; extra == 'all'
59
- Requires-Dist: pygraphviz<=1.14,>=1.10; extra == 'all'
60
- Requires-Dist: pysqa==0.4.4; extra == 'all'
58
+ Requires-Dist: pydantic<=2.13.5,>=2.5.3; extra == 'all'
59
+ Requires-Dist: pygraphviz<=2.0.1,>=1.10; extra == 'all'
60
+ Requires-Dist: pysqa==1.0.0; extra == 'all'
61
61
  Provides-Extra: cache
62
62
  Requires-Dist: h5py<=3.16.0,>=3.6.0; extra == 'cache'
63
63
  Provides-Extra: cluster
64
64
  Requires-Dist: h5py<=3.16.0,>=3.6.0; extra == 'cluster'
65
- Requires-Dist: pysqa==0.4.4; extra == 'cluster'
65
+ Requires-Dist: pysqa==1.0.0; extra == 'cluster'
66
66
  Provides-Extra: graph
67
67
  Requires-Dist: networkx<=3.6.1,>=2.8.8; extra == 'graph'
68
- Requires-Dist: pygraphviz<=1.14,>=1.10; extra == 'graph'
68
+ Requires-Dist: pygraphviz<=2.0.1,>=1.10; extra == 'graph'
69
69
  Provides-Extra: graphnotebook
70
70
  Requires-Dist: ipython<=9.9.0,>=7.33.0; extra == 'graphnotebook'
71
71
  Requires-Dist: networkx<=3.6.1,>=2.8.8; extra == 'graphnotebook'
72
- Requires-Dist: pygraphviz<=1.14,>=1.10; extra == 'graphnotebook'
72
+ Requires-Dist: pygraphviz<=2.0.1,>=1.10; extra == 'graphnotebook'
73
73
  Provides-Extra: mpi
74
74
  Requires-Dist: mpi4py<=4.1.2,>=3.1.4; extra == 'mpi'
75
75
  Provides-Extra: validation
76
- Requires-Dist: pydantic<=2.13.4,>=2.5.3; extra == 'validation'
76
+ Requires-Dist: pydantic<=2.13.5,>=2.5.3; extra == 'validation'
77
77
  Description-Content-Type: text/markdown
78
78
 
79
79
  # executorlib
@@ -1,5 +1,5 @@
1
- executorlib/__init__.py,sha256=IY_DkT706LPIv2_iIe3whrQNGoDzaDFYBvXyUepoZpw,4780
2
- executorlib/_version.py,sha256=aubWhgSag2TvKOWdccSUKUZIISdFObmOxMDtFhqzXC0,522
1
+ executorlib/__init__.py,sha256=Xj1QeplikK6_6BFifidkFWPcTDzDM-XEV74RjXJU5KY,5841
2
+ executorlib/_version.py,sha256=jvpQUuRyrfcKdP3sIxjj1JLsvJpVHjBDuHss7asmwlI,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
@@ -20,31 +20,31 @@ executorlib/standalone/hdf.py,sha256=dRePOCYXbPG_i__ASUcD4qs5AAU2fPbP5o_5ytwaOjw
20
20
  executorlib/standalone/inputcheck.py,sha256=kSWUzqdMOhILYXW4Isumn1EGH3SegxPUMWRkUWfEleU,10041
21
21
  executorlib/standalone/queue.py,sha256=KFEBFQXGvcaf5qcuCjT5kaZg7ucWOTGOtrD96tIBlq0,589
22
22
  executorlib/standalone/select.py,sha256=FUSXYbhoc_uP_vPji8L4PcK4b2Gwcai7rXZ5dKRVjZM,3061
23
- executorlib/standalone/serialize.py,sha256=7DxcuCYZVqLf8wa7EXsN-_8fSpUJqyQ-5G6NT863SgM,4716
23
+ executorlib/standalone/serialize.py,sha256=NdFdwF8xrIPPbYpBRQY3d5-n2yQSG6H41EDEr2Ojkes,4972
24
24
  executorlib/standalone/validate.py,sha256=hHG32xomLhbqnqd6Vn4AO05bQ7B3WZ1rngTkMsODwwk,4430
25
25
  executorlib/standalone/interactive/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
26
26
  executorlib/standalone/interactive/arguments.py,sha256=iaVXf7Wq9MUOu3WeYSi2t-f8Si_pyAPyykcnq8bf8cY,3239
27
27
  executorlib/standalone/interactive/backend.py,sha256=gGgcvER8w75bM_p1uplSsr6yCtBBlOS_6wR1iQNsntc,3006
28
- executorlib/standalone/interactive/communication.py,sha256=ctiVWkc7g1mfsYHJSJzg29nAvaEkJopXpajBmOpJOIc,10400
28
+ executorlib/standalone/interactive/communication.py,sha256=hmv6APOu1RMScn5RIkoXH4-CZAI9QUkDwd-eq1NEabI,10467
29
29
  executorlib/standalone/interactive/spawner.py,sha256=4TEPL4iI_rF25kOaW-eqY74jK93LFZ05cYOHUjIuo4M,6384
30
30
  executorlib/task_scheduler/__init__.py,sha256=-sw60rfnEvwFiOAONFHpE3izPA9CPtp5cQ7vRetw2Mw,249
31
31
  executorlib/task_scheduler/base.py,sha256=A9nQb8FYKbZGjQP1G5ccT75ODbEqqiM0OVybHAxjqzE,9718
32
32
  executorlib/task_scheduler/file/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
33
33
  executorlib/task_scheduler/file/backend.py,sha256=tojXcYytAsfABugsOMfkx9oAh01do_DcSneVldMfeK0,2876
34
- executorlib/task_scheduler/file/shared.py,sha256=uJECqjLr_Mq9AQdVOAkEdN-gS2dryfwufmtrcgMs02M,24719
35
- executorlib/task_scheduler/file/spawner_pysqa.py,sha256=z6kEsyVnCFmpLmVlHL2LxumAgDU0t0zvo59snMv0sMw,6021
34
+ executorlib/task_scheduler/file/shared.py,sha256=WABgsQFKhrl7n50-pjmcQwWRioxCwn9abOXufZdO6BY,25216
35
+ executorlib/task_scheduler/file/spawner_pysqa.py,sha256=jpE7eKGlE-OpzMM7ly7U--IQViMQ72vHnWve6fHXcwM,7991
36
36
  executorlib/task_scheduler/file/spawner_subprocess.py,sha256=yMc4nHRUghgdR0ehihE2CYsaTn1RspRI3ddhIhkTgDw,3086
37
37
  executorlib/task_scheduler/file/task_scheduler.py,sha256=gfEpNVJ9u87_yaDYZ86kHt_mAEXfOqBwvxX4IlpKt6o,6170
38
38
  executorlib/task_scheduler/interactive/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
39
- executorlib/task_scheduler/interactive/blockallocation.py,sha256=hsKTDScVxzLJ4sHhAWIoMjRxZxX2zzpO4r_z-7ksV_s,17705
39
+ executorlib/task_scheduler/interactive/blockallocation.py,sha256=CRU0b_HtOBxNTxGEuZ4BSf4qcszGd7RijO66yzGjlMo,18161
40
40
  executorlib/task_scheduler/interactive/dependency.py,sha256=zQMfI6AjeUv3A1qyPzFah2BKYGWgGLRyEIdZ0XTjq1M,15222
41
41
  executorlib/task_scheduler/interactive/dependency_plot.py,sha256=iZBZ9UMDeYOMFjD2-kYOxOdKeodj7TuyshI4HbH4XCU,11788
42
42
  executorlib/task_scheduler/interactive/onetoone.py,sha256=cTXgTXR9kKzzlx6EfGumMsEm7DUa7BD9JSeBpdPiupI,13312
43
- executorlib/task_scheduler/interactive/shared.py,sha256=tGlhIsqOfkO7QwNmr3I71M8DFT3NNXHwyUoZ_BrjfWQ,6263
43
+ executorlib/task_scheduler/interactive/shared.py,sha256=Lr9R63f0kBl4g64E0vRl3xMvnYlNypoIx5ADYSQ2RdE,6720
44
44
  executorlib/task_scheduler/interactive/spawner_flux.py,sha256=M7CPWvzY7MDkplJ4awymh7WbMYwKsDPTKxA2Op9wfNo,7075
45
45
  executorlib/task_scheduler/interactive/spawner_pysqa.py,sha256=jQB8PQAH9cBo_ofpxHTzydg0ghwSOP51CtVL96YH_fc,10346
46
46
  executorlib/task_scheduler/interactive/spawner_slurm.py,sha256=K5mj63PE8FYbkw9WWm4uEjoA5q0HM42z1d2wjAmO5YA,3713
47
- executorlib-1.10.2.dist-info/METADATA,sha256=xt32x11FToSi84-Knrpr2Rx4OIUUBfWth9c7xSPf0Es,20966
48
- executorlib-1.10.2.dist-info/WHEEL,sha256=lCkmxWfQsSc9CfIClYeavTdQeEX2toPqufh9gI35EQA,87
49
- executorlib-1.10.2.dist-info/licenses/LICENSE,sha256=NkrhccIxPXCbbvp_upyVojt7DNTwZIco3z9wsYpSLqU,1511
50
- executorlib-1.10.2.dist-info/RECORD,,
47
+ executorlib-1.10.3.dist-info/METADATA,sha256=GzUIqIQXzO-lYw9hTDEAIjFTHYFV-R_b3ZoN87yUozA,20969
48
+ executorlib-1.10.3.dist-info/WHEEL,sha256=zOwg4jB6zX2kU910N-cMawjivD6tO8NEWvE12je1bVk,87
49
+ executorlib-1.10.3.dist-info/licenses/LICENSE,sha256=NkrhccIxPXCbbvp_upyVojt7DNTwZIco3z9wsYpSLqU,1511
50
+ executorlib-1.10.3.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: hatchling 1.31.0
2
+ Generator: hatchling 1.32.0
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any