hpcflow-new2 0.2.0a179__py3-none-any.whl → 0.2.0a181__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.
- hpcflow/_version.py +1 -1
- hpcflow/data/demo_data_manifest/__init__.py +3 -0
- hpcflow/sdk/__init__.py +4 -1
- hpcflow/sdk/app.py +160 -15
- hpcflow/sdk/cli.py +14 -0
- hpcflow/sdk/cli_common.py +83 -0
- hpcflow/sdk/config/__init__.py +4 -0
- hpcflow/sdk/config/callbacks.py +25 -2
- hpcflow/sdk/config/cli.py +4 -1
- hpcflow/sdk/config/config.py +188 -14
- hpcflow/sdk/config/config_file.py +91 -3
- hpcflow/sdk/config/errors.py +33 -0
- hpcflow/sdk/core/__init__.py +2 -0
- hpcflow/sdk/core/actions.py +492 -35
- hpcflow/sdk/core/cache.py +22 -0
- hpcflow/sdk/core/command_files.py +221 -5
- hpcflow/sdk/core/commands.py +57 -0
- hpcflow/sdk/core/element.py +407 -8
- hpcflow/sdk/core/environment.py +92 -0
- hpcflow/sdk/core/errors.py +245 -61
- hpcflow/sdk/core/json_like.py +72 -14
- hpcflow/sdk/core/loop.py +122 -21
- hpcflow/sdk/core/loop_cache.py +34 -9
- hpcflow/sdk/core/object_list.py +172 -26
- hpcflow/sdk/core/parallel.py +14 -0
- hpcflow/sdk/core/parameters.py +478 -25
- hpcflow/sdk/core/rule.py +31 -1
- hpcflow/sdk/core/run_dir_files.py +12 -2
- hpcflow/sdk/core/task.py +407 -80
- hpcflow/sdk/core/task_schema.py +70 -9
- hpcflow/sdk/core/test_utils.py +35 -0
- hpcflow/sdk/core/utils.py +101 -4
- hpcflow/sdk/core/validation.py +13 -1
- hpcflow/sdk/core/workflow.py +316 -96
- hpcflow/sdk/core/zarr_io.py +23 -0
- hpcflow/sdk/data/__init__.py +13 -0
- hpcflow/sdk/demo/__init__.py +3 -0
- hpcflow/sdk/helper/__init__.py +3 -0
- hpcflow/sdk/helper/cli.py +9 -0
- hpcflow/sdk/helper/helper.py +28 -0
- hpcflow/sdk/helper/watcher.py +33 -0
- hpcflow/sdk/log.py +40 -0
- hpcflow/sdk/persistence/__init__.py +14 -4
- hpcflow/sdk/persistence/base.py +289 -23
- hpcflow/sdk/persistence/json.py +29 -0
- hpcflow/sdk/persistence/pending.py +217 -107
- hpcflow/sdk/persistence/store_resource.py +58 -2
- hpcflow/sdk/persistence/utils.py +8 -0
- hpcflow/sdk/persistence/zarr.py +68 -1
- hpcflow/sdk/runtime.py +52 -10
- hpcflow/sdk/submission/__init__.py +3 -0
- hpcflow/sdk/submission/jobscript.py +198 -9
- hpcflow/sdk/submission/jobscript_info.py +13 -0
- hpcflow/sdk/submission/schedulers/__init__.py +60 -0
- hpcflow/sdk/submission/schedulers/direct.py +53 -0
- hpcflow/sdk/submission/schedulers/sge.py +45 -7
- hpcflow/sdk/submission/schedulers/slurm.py +45 -8
- hpcflow/sdk/submission/schedulers/utils.py +4 -0
- hpcflow/sdk/submission/shells/__init__.py +11 -1
- hpcflow/sdk/submission/shells/base.py +32 -1
- hpcflow/sdk/submission/shells/bash.py +36 -1
- hpcflow/sdk/submission/shells/os_version.py +18 -6
- hpcflow/sdk/submission/shells/powershell.py +22 -0
- hpcflow/sdk/submission/submission.py +88 -3
- hpcflow/sdk/typing.py +10 -1
- {hpcflow_new2-0.2.0a179.dist-info → hpcflow_new2-0.2.0a181.dist-info}/METADATA +3 -3
- {hpcflow_new2-0.2.0a179.dist-info → hpcflow_new2-0.2.0a181.dist-info}/RECORD +70 -70
- {hpcflow_new2-0.2.0a179.dist-info → hpcflow_new2-0.2.0a181.dist-info}/LICENSE +0 -0
- {hpcflow_new2-0.2.0a179.dist-info → hpcflow_new2-0.2.0a181.dist-info}/WHEEL +0 -0
- {hpcflow_new2-0.2.0a179.dist-info → hpcflow_new2-0.2.0a181.dist-info}/entry_points.txt +0 -0
hpcflow/sdk/persistence/base.py
CHANGED
@@ -1,4 +1,8 @@
|
|
1
|
-
|
1
|
+
"""
|
2
|
+
Base persistence models.
|
3
|
+
|
4
|
+
Store* classes represent the element-metadata in the store, in a store-agnostic way.
|
5
|
+
"""
|
2
6
|
from __future__ import annotations
|
3
7
|
from abc import ABC
|
4
8
|
|
@@ -50,46 +54,81 @@ PARAM_DATA_NOT_SET = 0
|
|
50
54
|
|
51
55
|
|
52
56
|
def update_param_source_dict(source, update):
|
57
|
+
"""
|
58
|
+
Combine two dicts into a new dict that is ordered on its keys.
|
59
|
+
"""
|
53
60
|
return dict(sorted({**source, **update}.items()))
|
54
61
|
|
55
62
|
|
56
63
|
@dataclass
|
57
64
|
class PersistentStoreFeatures:
|
58
|
-
"""
|
65
|
+
"""
|
66
|
+
Represents the features provided by a persistent store.
|
59
67
|
|
60
68
|
Parameters
|
61
69
|
----------
|
62
|
-
create
|
70
|
+
create:
|
63
71
|
If True, a new workflow can be created using this store.
|
64
|
-
edit
|
72
|
+
edit:
|
65
73
|
If True, the workflow can be modified.
|
66
|
-
jobscript_parallelism
|
74
|
+
jobscript_parallelism:
|
67
75
|
If True, the store supports workflows running multiple independent jobscripts
|
68
76
|
simultaneously.
|
69
|
-
EAR_parallelism
|
77
|
+
EAR_parallelism:
|
70
78
|
If True, the store supports workflows running multiple EARs simultaneously.
|
71
|
-
schedulers
|
72
|
-
If True, the store supports submitting workflows to a scheduler
|
73
|
-
submission
|
79
|
+
schedulers:
|
80
|
+
If True, the store supports submitting workflows to a scheduler.
|
81
|
+
submission:
|
74
82
|
If True, the store supports submission. If False, the store can be considered to
|
75
83
|
be an archive, which would need transforming to another store type before
|
76
84
|
submission.
|
77
85
|
"""
|
78
86
|
|
87
|
+
#: Whether a new workflow can be created using this store.
|
79
88
|
create: bool = False
|
89
|
+
#: Whether the workflow can be modified.
|
80
90
|
edit: bool = False
|
91
|
+
#: Whetherthe store supports workflows running multiple independent jobscripts
|
92
|
+
#: simultaneously.
|
81
93
|
jobscript_parallelism: bool = False
|
94
|
+
#: Whether the store supports workflows running multiple EARs simultaneously.
|
82
95
|
EAR_parallelism: bool = False
|
96
|
+
#: Whether the store supports submitting workflows to a scheduler.
|
83
97
|
schedulers: bool = False
|
98
|
+
#: Whether the store supports submission. If not, the store can be considered to
|
99
|
+
#: be an archive, which would need transforming to another store type before
|
100
|
+
#: submission.
|
84
101
|
submission: bool = False
|
85
102
|
|
86
103
|
|
87
104
|
@dataclass
|
88
105
|
class StoreTask:
|
106
|
+
"""
|
107
|
+
Represents a task in a persistent store.
|
108
|
+
|
109
|
+
Parameters
|
110
|
+
----------
|
111
|
+
id_:
|
112
|
+
The ID of the task.
|
113
|
+
index:
|
114
|
+
The index of the task within its workflow.
|
115
|
+
is_pending:
|
116
|
+
Whether the task has changes not yet persisted.
|
117
|
+
element_IDs:
|
118
|
+
The IDs of elements in the task.
|
119
|
+
task_template:
|
120
|
+
Description of the template for the task.
|
121
|
+
"""
|
122
|
+
|
123
|
+
#: The ID of the task.
|
89
124
|
id_: int
|
125
|
+
#: The index of the task within its workflow.
|
90
126
|
index: int
|
127
|
+
#: Whether the task has changes not yet persisted.
|
91
128
|
is_pending: bool
|
129
|
+
#: The IDs of elements in the task.
|
92
130
|
element_IDs: List[int]
|
131
|
+
#: Description of the template for the task.
|
93
132
|
task_template: Optional[Dict] = None
|
94
133
|
|
95
134
|
def encode(self) -> Tuple[int, Dict, Dict]:
|
@@ -124,21 +163,43 @@ class StoreTask:
|
|
124
163
|
@dataclass
|
125
164
|
class StoreElement:
|
126
165
|
"""
|
166
|
+
Represents an element in a persistent store.
|
167
|
+
|
127
168
|
Parameters
|
128
169
|
----------
|
129
|
-
|
170
|
+
id_:
|
171
|
+
The ID of the element.
|
172
|
+
is_pending:
|
173
|
+
Whether the element has changes not yet persisted.
|
174
|
+
index:
|
130
175
|
Index of the element within its parent task.
|
131
|
-
|
176
|
+
es_idx:
|
177
|
+
Index of the element set containing this element.
|
178
|
+
seq_idx:
|
179
|
+
Value sequence index map.
|
180
|
+
src_idx:
|
181
|
+
Data source index map.
|
182
|
+
task_ID:
|
183
|
+
ID of the task that contains this element.
|
184
|
+
iteration_IDs:
|
132
185
|
IDs of element-iterations that belong to this element.
|
133
186
|
"""
|
134
187
|
|
188
|
+
#: The ID of the element.
|
135
189
|
id_: int
|
190
|
+
#: Whether the element has changes not yet persisted.
|
136
191
|
is_pending: bool
|
192
|
+
#: Index of the element within its parent task.
|
137
193
|
index: int
|
194
|
+
#: Index of the element set containing this element.
|
138
195
|
es_idx: int
|
196
|
+
#: Value sequence index map.
|
139
197
|
seq_idx: Dict[str, int]
|
198
|
+
#: Data source index map.
|
140
199
|
src_idx: Dict[str, int]
|
200
|
+
#: ID of the task that contains this element.
|
141
201
|
task_ID: int
|
202
|
+
#: IDs of element-iterations that belong to this element.
|
142
203
|
iteration_IDs: List[int]
|
143
204
|
|
144
205
|
def encode(self) -> Dict:
|
@@ -185,24 +246,45 @@ class StoreElement:
|
|
185
246
|
@dataclass
|
186
247
|
class StoreElementIter:
|
187
248
|
"""
|
249
|
+
Represents an element iteration in a persistent store.
|
250
|
+
|
188
251
|
Parameters
|
189
252
|
----------
|
190
|
-
|
253
|
+
id_:
|
254
|
+
The ID of this element iteration.
|
255
|
+
is_pending:
|
256
|
+
Whether the element iteration has changes not yet persisted.
|
257
|
+
element_ID:
|
258
|
+
Which element is an iteration for.
|
259
|
+
EARs_initialised:
|
260
|
+
Whether EARs have been initialised for this element iteration.
|
261
|
+
EAR_IDs:
|
262
|
+
Maps task schema action indices to EARs by ID.
|
263
|
+
data_idx:
|
191
264
|
Overall data index for the element-iteration, which maps parameter names to
|
192
265
|
parameter data indices.
|
193
|
-
|
194
|
-
Maps task schema action indices to EARs by ID.
|
195
|
-
schema_parameters
|
266
|
+
schema_parameters:
|
196
267
|
List of parameters defined by the associated task schema.
|
268
|
+
loop_idx:
|
269
|
+
What loops are being handled here and where they're up to.
|
197
270
|
"""
|
198
271
|
|
272
|
+
#: The ID of this element iteration.
|
199
273
|
id_: int
|
274
|
+
#: Whether the element iteration has changes not yet persisted.
|
200
275
|
is_pending: bool
|
276
|
+
#: Which element is an iteration for.
|
201
277
|
element_ID: int
|
278
|
+
#: Whether EARs have been initialised for this element iteration.
|
202
279
|
EARs_initialised: bool
|
280
|
+
#: Maps task schema action indices to EARs by ID.
|
203
281
|
EAR_IDs: Dict[int, List[int]]
|
282
|
+
#: Overall data index for the element-iteration, which maps parameter names to
|
283
|
+
#: parameter data indices.
|
204
284
|
data_idx: Dict[str, int]
|
285
|
+
#: List of parameters defined by the associated task schema.
|
205
286
|
schema_parameters: List[str]
|
287
|
+
#: What loops are being handled here and where they're up to.
|
206
288
|
loop_idx: Dict[str, int] = field(default_factory=dict)
|
207
289
|
|
208
290
|
def encode(self) -> Dict:
|
@@ -296,31 +378,75 @@ class StoreElementIter:
|
|
296
378
|
@dataclass
|
297
379
|
class StoreEAR:
|
298
380
|
"""
|
381
|
+
Represents an element action run in a persistent store.
|
382
|
+
|
299
383
|
Parameters
|
300
384
|
----------
|
301
|
-
|
385
|
+
id_:
|
386
|
+
The ID of this element action run.
|
387
|
+
is_pending:
|
388
|
+
Whether the element action run has changes not yet persisted.
|
389
|
+
elem_iter_ID:
|
390
|
+
What element iteration owns this EAR.
|
391
|
+
action_idx:
|
392
|
+
The task schema action associated with this EAR.
|
393
|
+
commands_idx:
|
394
|
+
The indices of the commands in the EAR.
|
395
|
+
data_idx:
|
302
396
|
Maps parameter names within this EAR to parameter data indices.
|
303
|
-
|
397
|
+
submission_idx:
|
398
|
+
Which submission contained this EAR, if known.
|
399
|
+
skip:
|
400
|
+
Whether to skip this EAR.
|
401
|
+
success:
|
402
|
+
Whether this EAR was successful, if known.
|
403
|
+
start_time:
|
404
|
+
When this EAR started, if known.
|
405
|
+
end_time:
|
406
|
+
When this EAR finished, if known.
|
407
|
+
snapshot_start:
|
408
|
+
Snapshot of files at EAR start, if recorded.
|
409
|
+
snapshot_end:
|
410
|
+
Snapshot of files at EAR end, if recorded.
|
411
|
+
exit_code:
|
412
|
+
The exit code of the underlying executable, if known.
|
413
|
+
metadata:
|
304
414
|
Metadata concerning e.g. the state of the EAR.
|
305
|
-
|
306
|
-
|
415
|
+
run_hostname:
|
416
|
+
Where this EAR was submitted to run, if known.
|
307
417
|
"""
|
308
418
|
|
419
|
+
#: The ID of this element action run.
|
309
420
|
id_: int
|
421
|
+
#: Whether the element action run has changes not yet persisted.
|
310
422
|
is_pending: bool
|
423
|
+
#: What element iteration owns this EAR.
|
311
424
|
elem_iter_ID: int
|
425
|
+
#: The task schema action associated with this EAR.
|
312
426
|
action_idx: int
|
427
|
+
#: The indices of the commands in the EAR.
|
313
428
|
commands_idx: List[int]
|
429
|
+
#: Maps parameter names within this EAR to parameter data indices.
|
314
430
|
data_idx: Dict[str, int]
|
431
|
+
#: Which submission contained this EAR, if known.
|
315
432
|
submission_idx: Optional[int] = None
|
433
|
+
#: Whether to skip this EAR.
|
316
434
|
skip: Optional[bool] = False
|
435
|
+
#: Whether this EAR was successful, if known.
|
317
436
|
success: Optional[bool] = None
|
437
|
+
#: When this EAR started, if known.
|
318
438
|
start_time: Optional[datetime] = None
|
439
|
+
#: When this EAR finished, if known.
|
319
440
|
end_time: Optional[datetime] = None
|
441
|
+
#: Snapshot of files at EAR start, if recorded.
|
320
442
|
snapshot_start: Optional[Dict] = None
|
443
|
+
#: Snapshot of files at EAR end, if recorded.
|
321
444
|
snapshot_end: Optional[Dict] = None
|
445
|
+
#: The exit code of the underlying executable, if known.
|
322
446
|
exit_code: Optional[int] = None
|
447
|
+
#: Metadata concerning e.g. the state of the EAR.
|
323
448
|
metadata: Dict[str, Any] = None
|
449
|
+
#: Where this EAR was submitted to run, if known.
|
324
450
|
run_hostname: Optional[str] = None
|
325
451
|
|
326
452
|
@staticmethod
|
@@ -434,11 +560,36 @@ class StoreEAR:
|
|
434
560
|
|
435
561
|
@dataclass
|
436
562
|
class StoreParameter:
|
563
|
+
"""
|
564
|
+
Represents a parameter in a persistent store.
|
565
|
+
|
566
|
+
Parameters
|
567
|
+
----------
|
568
|
+
id_:
|
569
|
+
The ID of this parameter.
|
570
|
+
is_pending:
|
571
|
+
Whether the parameter has changes not yet persisted.
|
572
|
+
is_set:
|
573
|
+
Whether the parameter is set.
|
574
|
+
data:
|
575
|
+
Description of the value of the parameter.
|
576
|
+
file:
|
577
|
+
Description of the file this parameter represents.
|
578
|
+
source:
|
579
|
+
Description of where this parameter originated.
|
580
|
+
"""
|
581
|
+
|
582
|
+
#: The ID of this parameter.
|
437
583
|
id_: int
|
584
|
+
#: Whether the parameter has changes not yet persisted.
|
438
585
|
is_pending: bool
|
586
|
+
#: Whether the parameter is set.
|
439
587
|
is_set: bool
|
588
|
+
#: Description of the value of the parameter.
|
440
589
|
data: Any
|
590
|
+
#: Description of the file this parameter represents.
|
441
591
|
file: Dict
|
592
|
+
#: Description of where this parameter originated.
|
442
593
|
source: Dict
|
443
594
|
|
444
595
|
_encoders = {}
|
@@ -647,6 +798,21 @@ class StoreParameter:
|
|
647
798
|
|
648
799
|
|
649
800
|
class PersistentStore(ABC):
|
801
|
+
"""
|
802
|
+
An abstract class representing a persistent workflow store.
|
803
|
+
|
804
|
+
Parameters
|
805
|
+
----------
|
806
|
+
app: App
|
807
|
+
The main hpcflow core.
|
808
|
+
workflow: ~hpcflow.app.Workflow
|
809
|
+
The workflow being persisted.
|
810
|
+
path: pathlib.Path
|
811
|
+
Where to hold the store.
|
812
|
+
fs: fsspec.AbstractFileSystem
|
813
|
+
Optionally, information about how to access the store.
|
814
|
+
"""
|
815
|
+
|
650
816
|
_store_task_cls = StoreTask
|
651
817
|
_store_elem_cls = StoreElement
|
652
818
|
_store_iter_cls = StoreElementIter
|
@@ -672,14 +838,23 @@ class PersistentStore(ABC):
|
|
672
838
|
|
673
839
|
@property
|
674
840
|
def logger(self):
|
841
|
+
"""
|
842
|
+
The logger to use.
|
843
|
+
"""
|
675
844
|
return self.app.persistence_logger
|
676
845
|
|
677
846
|
@property
|
678
847
|
def ts_fmt(self) -> str:
|
848
|
+
"""
|
849
|
+
The format for timestamps.
|
850
|
+
"""
|
679
851
|
return self.workflow.ts_fmt
|
680
852
|
|
681
853
|
@property
|
682
854
|
def has_pending(self):
|
855
|
+
"""
|
856
|
+
Whether there are any pending changes.
|
857
|
+
"""
|
683
858
|
return bool(self._pending)
|
684
859
|
|
685
860
|
@property
|
@@ -689,6 +864,9 @@ class PersistentStore(ABC):
|
|
689
864
|
|
690
865
|
@property
|
691
866
|
def use_cache(self):
|
867
|
+
"""
|
868
|
+
Whether to use a cache.
|
869
|
+
"""
|
692
870
|
return self._use_cache
|
693
871
|
|
694
872
|
@property
|
@@ -914,6 +1092,9 @@ class PersistentStore(ABC):
|
|
914
1092
|
self._pending.commit_all()
|
915
1093
|
|
916
1094
|
def add_template_components(self, temp_comps: Dict, save: bool = True) -> None:
|
1095
|
+
"""
|
1096
|
+
Add template components to the workflow.
|
1097
|
+
"""
|
917
1098
|
all_tc = self.get_template_components()
|
918
1099
|
for name, dat in temp_comps.items():
|
919
1100
|
if name in all_tc:
|
@@ -976,6 +1157,9 @@ class PersistentStore(ABC):
|
|
976
1157
|
self.save()
|
977
1158
|
|
978
1159
|
def add_element_set(self, task_id: int, es_js: Dict, save: bool = True):
|
1160
|
+
"""
|
1161
|
+
Add an element set to a task.
|
1162
|
+
"""
|
979
1163
|
self._pending.add_element_sets[task_id].append(es_js)
|
980
1164
|
if save:
|
981
1165
|
self.save()
|
@@ -1058,6 +1242,9 @@ class PersistentStore(ABC):
|
|
1058
1242
|
def add_submission_part(
|
1059
1243
|
self, sub_idx: int, dt_str: str, submitted_js_idx: List[int], save: bool = True
|
1060
1244
|
):
|
1245
|
+
"""
|
1246
|
+
Add a submission part.
|
1247
|
+
"""
|
1061
1248
|
self._pending.add_submission_parts[sub_idx][dt_str] = submitted_js_idx
|
1062
1249
|
if save:
|
1063
1250
|
self.save()
|
@@ -1066,11 +1253,17 @@ class PersistentStore(ABC):
|
|
1066
1253
|
def set_EAR_submission_index(
|
1067
1254
|
self, EAR_ID: int, sub_idx: int, save: bool = True
|
1068
1255
|
) -> None:
|
1256
|
+
"""
|
1257
|
+
Set the submission index for an element action run.
|
1258
|
+
"""
|
1069
1259
|
self._pending.set_EAR_submission_indices[EAR_ID] = sub_idx
|
1070
1260
|
if save:
|
1071
1261
|
self.save()
|
1072
1262
|
|
1073
1263
|
def set_EAR_start(self, EAR_ID: int, save: bool = True) -> datetime:
|
1264
|
+
"""
|
1265
|
+
Mark an element action run as started.
|
1266
|
+
"""
|
1074
1267
|
dt = datetime.utcnow()
|
1075
1268
|
ss_js = self.app.RunDirAppFiles.take_snapshot()
|
1076
1269
|
run_hostname = socket.gethostname()
|
@@ -1082,6 +1275,9 @@ class PersistentStore(ABC):
|
|
1082
1275
|
def set_EAR_end(
|
1083
1276
|
self, EAR_ID: int, exit_code: int, success: bool, save: bool = True
|
1084
1277
|
) -> datetime:
|
1278
|
+
"""
|
1279
|
+
Mark an element action run as finished.
|
1280
|
+
"""
|
1085
1281
|
# TODO: save output files
|
1086
1282
|
dt = datetime.utcnow()
|
1087
1283
|
ss_js = self.app.RunDirAppFiles.take_snapshot()
|
@@ -1091,11 +1287,17 @@ class PersistentStore(ABC):
|
|
1091
1287
|
return dt
|
1092
1288
|
|
1093
1289
|
def set_EAR_skip(self, EAR_ID: int, save: bool = True) -> None:
|
1290
|
+
"""
|
1291
|
+
Mark an element action run as skipped.
|
1292
|
+
"""
|
1094
1293
|
self._pending.set_EAR_skips.append(EAR_ID)
|
1095
1294
|
if save:
|
1096
1295
|
self.save()
|
1097
1296
|
|
1098
1297
|
def set_EARs_initialised(self, iter_ID: int, save: bool = True) -> None:
|
1298
|
+
"""
|
1299
|
+
Mark an element action run as initialised.
|
1300
|
+
"""
|
1099
1301
|
self._pending.set_EARs_initialised.append(iter_ID)
|
1100
1302
|
if save:
|
1101
1303
|
self.save()
|
@@ -1116,6 +1318,9 @@ class PersistentStore(ABC):
|
|
1116
1318
|
process_ID: Optional[int] = None,
|
1117
1319
|
save: bool = True,
|
1118
1320
|
):
|
1321
|
+
"""
|
1322
|
+
Set the metadata for a job script.
|
1323
|
+
"""
|
1119
1324
|
if version_info:
|
1120
1325
|
self._pending.set_js_metadata[sub_idx][js_idx]["version_info"] = version_info
|
1121
1326
|
if submit_time:
|
@@ -1229,6 +1434,9 @@ class PersistentStore(ABC):
|
|
1229
1434
|
clean_up: bool = False,
|
1230
1435
|
save: bool = True,
|
1231
1436
|
):
|
1437
|
+
"""
|
1438
|
+
Set details of a file, including whether it is associated with a parameter.
|
1439
|
+
"""
|
1232
1440
|
self.logger.debug(f"Setting new file")
|
1233
1441
|
file_param_dat = self._prepare_set_file(
|
1234
1442
|
store_contents=store_contents,
|
@@ -1255,6 +1463,9 @@ class PersistentStore(ABC):
|
|
1255
1463
|
filename: str = None,
|
1256
1464
|
save: bool = True,
|
1257
1465
|
):
|
1466
|
+
"""
|
1467
|
+
Add a file that will be associated with a parameter.
|
1468
|
+
"""
|
1258
1469
|
self.logger.debug(f"Adding new file")
|
1259
1470
|
file_param_dat = self._prepare_set_file(
|
1260
1471
|
store_contents=store_contents,
|
@@ -1291,14 +1502,23 @@ class PersistentStore(ABC):
|
|
1291
1502
|
fp.write(dat["contents"])
|
1292
1503
|
|
1293
1504
|
def add_set_parameter(self, data: Any, source: Dict, save: bool = True) -> int:
|
1505
|
+
"""
|
1506
|
+
Add a parameter that is set to a value.
|
1507
|
+
"""
|
1294
1508
|
return self._add_parameter(data=data, is_set=True, source=source, save=save)
|
1295
1509
|
|
1296
1510
|
def add_unset_parameter(self, source: Dict, save: bool = True) -> int:
|
1511
|
+
"""
|
1512
|
+
Add a parameter that is not set to any value.
|
1513
|
+
"""
|
1297
1514
|
return self._add_parameter(data=None, is_set=False, source=source, save=save)
|
1298
1515
|
|
1299
1516
|
def set_parameter_value(
|
1300
1517
|
self, param_id: int, value: Any, is_file: bool = False, save: bool = True
|
1301
1518
|
):
|
1519
|
+
"""
|
1520
|
+
Set the value of a parameter.
|
1521
|
+
"""
|
1302
1522
|
self.logger.debug(
|
1303
1523
|
f"Setting store parameter ID {param_id} value with type: {type(value)!r})."
|
1304
1524
|
)
|
@@ -1310,6 +1530,9 @@ class PersistentStore(ABC):
|
|
1310
1530
|
def update_param_source(
|
1311
1531
|
self, param_sources: Dict[int, Dict], save: bool = True
|
1312
1532
|
) -> None:
|
1533
|
+
"""
|
1534
|
+
Set the source of a parameter.
|
1535
|
+
"""
|
1313
1536
|
self.logger.debug(f"Updating parameter sources with {param_sources!r}.")
|
1314
1537
|
self._pending.update_param_sources.update(param_sources)
|
1315
1538
|
if save:
|
@@ -1318,6 +1541,9 @@ class PersistentStore(ABC):
|
|
1318
1541
|
def update_loop_num_iters(
|
1319
1542
|
self, index: int, num_added_iters: int, save: bool = True
|
1320
1543
|
) -> None:
|
1544
|
+
"""
|
1545
|
+
Add iterations to a loop.
|
1546
|
+
"""
|
1321
1547
|
self.logger.debug(
|
1322
1548
|
f"Updating loop {index!r} num added iterations to {num_added_iters!r}."
|
1323
1549
|
)
|
@@ -1333,6 +1559,9 @@ class PersistentStore(ABC):
|
|
1333
1559
|
parents: List[str],
|
1334
1560
|
save: bool = True,
|
1335
1561
|
) -> None:
|
1562
|
+
"""
|
1563
|
+
Set the parents of a loop.
|
1564
|
+
"""
|
1336
1565
|
self.logger.debug(
|
1337
1566
|
f"Updating loop {index!r} parents to {parents!r}, and num added iterations "
|
1338
1567
|
f"to {num_added_iters}."
|
@@ -1355,6 +1584,9 @@ class PersistentStore(ABC):
|
|
1355
1584
|
return tc
|
1356
1585
|
|
1357
1586
|
def get_template(self) -> Dict:
|
1587
|
+
"""
|
1588
|
+
Get the workflow template.
|
1589
|
+
"""
|
1358
1590
|
return self._get_persistent_template()
|
1359
1591
|
|
1360
1592
|
def _get_task_id_to_idx_map(self) -> Dict[int, int]:
|
@@ -1362,6 +1594,9 @@ class PersistentStore(ABC):
|
|
1362
1594
|
|
1363
1595
|
@TimeIt.decorator
|
1364
1596
|
def get_task(self, task_idx: int) -> AnySTask:
|
1597
|
+
"""
|
1598
|
+
Get a task.
|
1599
|
+
"""
|
1365
1600
|
return self.get_tasks()[task_idx]
|
1366
1601
|
|
1367
1602
|
def _process_retrieved_tasks(self, tasks: List[AnySTask]) -> List[AnySTask]:
|
@@ -1394,6 +1629,9 @@ class PersistentStore(ABC):
|
|
1394
1629
|
return loops_new
|
1395
1630
|
|
1396
1631
|
def get_tasks_by_IDs(self, id_lst: Iterable[int]) -> List[AnySTask]:
|
1632
|
+
"""
|
1633
|
+
Get tasks with the given IDs.
|
1634
|
+
"""
|
1397
1635
|
# separate pending and persistent IDs:
|
1398
1636
|
id_set = set(id_lst)
|
1399
1637
|
all_pending = set(self._pending.add_tasks)
|
@@ -1461,6 +1699,9 @@ class PersistentStore(ABC):
|
|
1461
1699
|
|
1462
1700
|
@TimeIt.decorator
|
1463
1701
|
def get_submissions_by_ID(self, id_lst: Iterable[int]) -> Dict[int, Dict]:
|
1702
|
+
"""
|
1703
|
+
Get submissions with the given IDs.
|
1704
|
+
"""
|
1464
1705
|
# separate pending and persistent IDs:
|
1465
1706
|
id_set = set(id_lst)
|
1466
1707
|
all_pending = set(self._pending.add_submissions)
|
@@ -1477,6 +1718,9 @@ class PersistentStore(ABC):
|
|
1477
1718
|
|
1478
1719
|
@TimeIt.decorator
|
1479
1720
|
def get_elements(self, id_lst: Iterable[int]) -> List[AnySElement]:
|
1721
|
+
"""
|
1722
|
+
Get elements with the given IDs.
|
1723
|
+
"""
|
1480
1724
|
self.logger.debug(f"PersistentStore.get_elements: id_lst={id_lst!r}")
|
1481
1725
|
|
1482
1726
|
# separate pending and persistent IDs:
|
@@ -1504,6 +1748,9 @@ class PersistentStore(ABC):
|
|
1504
1748
|
|
1505
1749
|
@TimeIt.decorator
|
1506
1750
|
def get_element_iterations(self, id_lst: Iterable[int]) -> List[AnySElementIter]:
|
1751
|
+
"""
|
1752
|
+
Get element iterations with the given IDs.
|
1753
|
+
"""
|
1507
1754
|
self.logger.debug(f"PersistentStore.get_element_iterations: id_lst={id_lst!r}")
|
1508
1755
|
|
1509
1756
|
# separate pending and persistent IDs:
|
@@ -1540,6 +1787,9 @@ class PersistentStore(ABC):
|
|
1540
1787
|
|
1541
1788
|
@TimeIt.decorator
|
1542
1789
|
def get_EARs(self, id_lst: Iterable[int]) -> List[AnySEAR]:
|
1790
|
+
"""
|
1791
|
+
Get element action runs with the given IDs.
|
1792
|
+
"""
|
1543
1793
|
self.logger.debug(f"PersistentStore.get_EARs: id_lst={id_lst!r}")
|
1544
1794
|
|
1545
1795
|
# separate pending and persistent IDs:
|
@@ -1624,6 +1874,9 @@ class PersistentStore(ABC):
|
|
1624
1874
|
return self._get_cached_persistent_items(id_lst, self.parameter_cache)
|
1625
1875
|
|
1626
1876
|
def get_EAR_skipped(self, EAR_ID: int) -> bool:
|
1877
|
+
"""
|
1878
|
+
Whether the element action run with the given ID was skipped.
|
1879
|
+
"""
|
1627
1880
|
self.logger.debug(f"PersistentStore.get_EAR_skipped: EAR_ID={EAR_ID!r}")
|
1628
1881
|
return self.get_EARs([EAR_ID])[0].skip
|
1629
1882
|
|
@@ -1634,11 +1887,17 @@ class PersistentStore(ABC):
|
|
1634
1887
|
**kwargs: Dict,
|
1635
1888
|
) -> List[AnySParameter]:
|
1636
1889
|
"""
|
1890
|
+
Get parameters with the given IDs.
|
1891
|
+
|
1637
1892
|
Parameters
|
1638
1893
|
----------
|
1639
|
-
|
1640
|
-
|
1641
|
-
|
1894
|
+
id_lst:
|
1895
|
+
The IDs of the parameters to get.
|
1896
|
+
|
1897
|
+
Keyword Arguments
|
1898
|
+
-----------------
|
1899
|
+
dataset_copy: bool
|
1900
|
+
For Zarr stores only. If True, copy arrays as NumPy arrays.
|
1642
1901
|
"""
|
1643
1902
|
# separate pending and persistent IDs:
|
1644
1903
|
id_set = set(id_lst)
|
@@ -1656,6 +1915,9 @@ class PersistentStore(ABC):
|
|
1656
1915
|
|
1657
1916
|
@TimeIt.decorator
|
1658
1917
|
def get_parameter_set_statuses(self, id_lst: Iterable[int]) -> List[bool]:
|
1918
|
+
"""
|
1919
|
+
Get whether the parameters with the given IDs are set.
|
1920
|
+
"""
|
1659
1921
|
# separate pending and persistent IDs:
|
1660
1922
|
id_set = set(id_lst)
|
1661
1923
|
all_pending = set(self._pending.add_parameters)
|
@@ -1670,6 +1932,9 @@ class PersistentStore(ABC):
|
|
1670
1932
|
|
1671
1933
|
@TimeIt.decorator
|
1672
1934
|
def get_parameter_sources(self, id_lst: Iterable[int]) -> List[Dict]:
|
1935
|
+
"""
|
1936
|
+
Get the sources of the parameters with the given IDs.
|
1937
|
+
"""
|
1673
1938
|
# separate pending and persistent IDs:
|
1674
1939
|
id_set = set(id_lst)
|
1675
1940
|
all_pending = set(self._pending.add_parameters)
|
@@ -1698,7 +1963,8 @@ class PersistentStore(ABC):
|
|
1698
1963
|
task_id,
|
1699
1964
|
idx_lst: Optional[Iterable[int]] = None,
|
1700
1965
|
) -> List[Dict]:
|
1701
|
-
"""
|
1966
|
+
"""
|
1967
|
+
Get element data by an indices within a given task.
|
1702
1968
|
|
1703
1969
|
Element iterations and EARs belonging to the elements are included.
|
1704
1970
|
|