hpcflow-new2 0.2.0a189__py3-none-any.whl → 0.2.0a190__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/__pyinstaller/hook-hpcflow.py +8 -6
- hpcflow/_version.py +1 -1
- hpcflow/app.py +1 -0
- hpcflow/data/scripts/main_script_test_hdf5_in_obj.py +1 -1
- hpcflow/data/scripts/main_script_test_hdf5_out_obj.py +1 -1
- hpcflow/sdk/__init__.py +21 -15
- hpcflow/sdk/app.py +2133 -770
- hpcflow/sdk/cli.py +281 -250
- hpcflow/sdk/cli_common.py +6 -2
- hpcflow/sdk/config/__init__.py +1 -1
- hpcflow/sdk/config/callbacks.py +77 -42
- hpcflow/sdk/config/cli.py +126 -103
- hpcflow/sdk/config/config.py +578 -311
- hpcflow/sdk/config/config_file.py +131 -95
- hpcflow/sdk/config/errors.py +112 -85
- hpcflow/sdk/config/types.py +145 -0
- hpcflow/sdk/core/actions.py +1054 -994
- hpcflow/sdk/core/app_aware.py +24 -0
- hpcflow/sdk/core/cache.py +81 -63
- hpcflow/sdk/core/command_files.py +275 -185
- hpcflow/sdk/core/commands.py +111 -107
- hpcflow/sdk/core/element.py +724 -503
- hpcflow/sdk/core/enums.py +192 -0
- hpcflow/sdk/core/environment.py +74 -93
- hpcflow/sdk/core/errors.py +398 -51
- hpcflow/sdk/core/json_like.py +540 -272
- hpcflow/sdk/core/loop.py +380 -334
- hpcflow/sdk/core/loop_cache.py +160 -43
- hpcflow/sdk/core/object_list.py +370 -207
- hpcflow/sdk/core/parameters.py +728 -600
- hpcflow/sdk/core/rule.py +59 -41
- hpcflow/sdk/core/run_dir_files.py +33 -22
- hpcflow/sdk/core/task.py +1546 -1325
- hpcflow/sdk/core/task_schema.py +240 -196
- hpcflow/sdk/core/test_utils.py +126 -88
- hpcflow/sdk/core/types.py +387 -0
- hpcflow/sdk/core/utils.py +410 -305
- hpcflow/sdk/core/validation.py +82 -9
- hpcflow/sdk/core/workflow.py +1192 -1028
- hpcflow/sdk/core/zarr_io.py +98 -137
- hpcflow/sdk/demo/cli.py +46 -33
- hpcflow/sdk/helper/cli.py +18 -16
- hpcflow/sdk/helper/helper.py +75 -63
- hpcflow/sdk/helper/watcher.py +61 -28
- hpcflow/sdk/log.py +83 -59
- hpcflow/sdk/persistence/__init__.py +8 -31
- hpcflow/sdk/persistence/base.py +988 -586
- hpcflow/sdk/persistence/defaults.py +6 -0
- hpcflow/sdk/persistence/discovery.py +38 -0
- hpcflow/sdk/persistence/json.py +408 -153
- hpcflow/sdk/persistence/pending.py +158 -123
- hpcflow/sdk/persistence/store_resource.py +37 -22
- hpcflow/sdk/persistence/types.py +307 -0
- hpcflow/sdk/persistence/utils.py +14 -11
- hpcflow/sdk/persistence/zarr.py +477 -420
- hpcflow/sdk/runtime.py +44 -41
- hpcflow/sdk/submission/{jobscript_info.py → enums.py} +39 -12
- hpcflow/sdk/submission/jobscript.py +444 -404
- hpcflow/sdk/submission/schedulers/__init__.py +133 -40
- hpcflow/sdk/submission/schedulers/direct.py +97 -71
- hpcflow/sdk/submission/schedulers/sge.py +132 -126
- hpcflow/sdk/submission/schedulers/slurm.py +263 -268
- hpcflow/sdk/submission/schedulers/utils.py +7 -2
- hpcflow/sdk/submission/shells/__init__.py +14 -15
- hpcflow/sdk/submission/shells/base.py +102 -29
- hpcflow/sdk/submission/shells/bash.py +72 -55
- hpcflow/sdk/submission/shells/os_version.py +31 -30
- hpcflow/sdk/submission/shells/powershell.py +37 -29
- hpcflow/sdk/submission/submission.py +203 -257
- hpcflow/sdk/submission/types.py +143 -0
- hpcflow/sdk/typing.py +163 -12
- hpcflow/tests/conftest.py +8 -6
- hpcflow/tests/schedulers/slurm/test_slurm_submission.py +5 -2
- hpcflow/tests/scripts/test_main_scripts.py +60 -30
- hpcflow/tests/shells/wsl/test_wsl_submission.py +6 -4
- hpcflow/tests/unit/test_action.py +86 -75
- hpcflow/tests/unit/test_action_rule.py +9 -4
- hpcflow/tests/unit/test_app.py +13 -6
- hpcflow/tests/unit/test_cli.py +1 -1
- hpcflow/tests/unit/test_command.py +71 -54
- hpcflow/tests/unit/test_config.py +20 -15
- hpcflow/tests/unit/test_config_file.py +21 -18
- hpcflow/tests/unit/test_element.py +58 -62
- hpcflow/tests/unit/test_element_iteration.py +3 -1
- hpcflow/tests/unit/test_element_set.py +29 -19
- hpcflow/tests/unit/test_group.py +4 -2
- hpcflow/tests/unit/test_input_source.py +116 -93
- hpcflow/tests/unit/test_input_value.py +29 -24
- hpcflow/tests/unit/test_json_like.py +44 -35
- hpcflow/tests/unit/test_loop.py +65 -58
- hpcflow/tests/unit/test_object_list.py +17 -12
- hpcflow/tests/unit/test_parameter.py +16 -7
- hpcflow/tests/unit/test_persistence.py +48 -35
- hpcflow/tests/unit/test_resources.py +20 -18
- hpcflow/tests/unit/test_run.py +8 -3
- hpcflow/tests/unit/test_runtime.py +2 -1
- hpcflow/tests/unit/test_schema_input.py +23 -15
- hpcflow/tests/unit/test_shell.py +3 -2
- hpcflow/tests/unit/test_slurm.py +8 -7
- hpcflow/tests/unit/test_submission.py +39 -19
- hpcflow/tests/unit/test_task.py +352 -247
- hpcflow/tests/unit/test_task_schema.py +33 -20
- hpcflow/tests/unit/test_utils.py +9 -11
- hpcflow/tests/unit/test_value_sequence.py +15 -12
- hpcflow/tests/unit/test_workflow.py +114 -83
- hpcflow/tests/unit/test_workflow_template.py +0 -1
- hpcflow/tests/workflows/test_jobscript.py +2 -1
- hpcflow/tests/workflows/test_workflows.py +18 -13
- {hpcflow_new2-0.2.0a189.dist-info → hpcflow_new2-0.2.0a190.dist-info}/METADATA +2 -1
- hpcflow_new2-0.2.0a190.dist-info/RECORD +165 -0
- hpcflow/sdk/core/parallel.py +0 -21
- hpcflow_new2-0.2.0a189.dist-info/RECORD +0 -158
- {hpcflow_new2-0.2.0a189.dist-info → hpcflow_new2-0.2.0a190.dist-info}/LICENSE +0 -0
- {hpcflow_new2-0.2.0a189.dist-info → hpcflow_new2-0.2.0a190.dist-info}/WHEEL +0 -0
- {hpcflow_new2-0.2.0a189.dist-info → hpcflow_new2-0.2.0a190.dist-info}/entry_points.txt +0 -0
@@ -0,0 +1,387 @@
|
|
1
|
+
"""
|
2
|
+
Types to support the core SDK.
|
3
|
+
"""
|
4
|
+
from __future__ import annotations
|
5
|
+
from typing import Any, Literal, Protocol, TYPE_CHECKING
|
6
|
+
from typing_extensions import NotRequired, TypeAlias, TypedDict
|
7
|
+
|
8
|
+
if TYPE_CHECKING:
|
9
|
+
from collections.abc import Mapping, Sequence
|
10
|
+
from datetime import datetime, timedelta
|
11
|
+
import numpy as np
|
12
|
+
from valida.conditions import ConditionLike # type: ignore
|
13
|
+
from .actions import ActionScope
|
14
|
+
from .command_files import FileSpec
|
15
|
+
from .enums import ParallelMode, ParameterPropagationMode
|
16
|
+
from .object_list import ResourceList
|
17
|
+
from .parameters import (
|
18
|
+
InputSource,
|
19
|
+
InputValue,
|
20
|
+
Parameter,
|
21
|
+
ResourceSpec,
|
22
|
+
)
|
23
|
+
from .task import InputStatus
|
24
|
+
from ..persistence.types import ParamSource
|
25
|
+
|
26
|
+
|
27
|
+
class ParameterDependence(TypedDict):
|
28
|
+
"""
|
29
|
+
Dependency descriptor for a parameter.
|
30
|
+
"""
|
31
|
+
|
32
|
+
#: The input file writers that can use the parameter.
|
33
|
+
input_file_writers: list[FileSpec]
|
34
|
+
#: The commands that can use the parameter.
|
35
|
+
commands: list[int]
|
36
|
+
|
37
|
+
|
38
|
+
class ScriptData(TypedDict, total=False):
|
39
|
+
"""
|
40
|
+
Descriptor for data relating to a script.
|
41
|
+
"""
|
42
|
+
|
43
|
+
#: The format of the data.
|
44
|
+
format: str
|
45
|
+
#: Whether the data is required for all iterations.
|
46
|
+
all_iterations: NotRequired[bool]
|
47
|
+
|
48
|
+
|
49
|
+
class JobscriptSubmissionFailureArgs(TypedDict):
|
50
|
+
"""
|
51
|
+
Arguments that can be expanded to create a
|
52
|
+
:class:`JobscriptSubmissionFailure`.
|
53
|
+
"""
|
54
|
+
|
55
|
+
#: The command that was submitted.
|
56
|
+
submit_cmd: list[str]
|
57
|
+
#: The jobscript index.
|
58
|
+
js_idx: int
|
59
|
+
#: The jobscript path.
|
60
|
+
js_path: str
|
61
|
+
#: Where to write stdout.
|
62
|
+
stdout: NotRequired[str]
|
63
|
+
#: Where to write stderr.
|
64
|
+
stderr: NotRequired[str]
|
65
|
+
#: The exception from the exec of the subprocess.
|
66
|
+
subprocess_exc: NotRequired[Exception]
|
67
|
+
#: The exception from parsing the job ID.
|
68
|
+
job_ID_parse_exc: NotRequired[Exception]
|
69
|
+
|
70
|
+
|
71
|
+
class ElementDescriptor(TypedDict):
|
72
|
+
"""
|
73
|
+
Descriptor for elements.
|
74
|
+
"""
|
75
|
+
|
76
|
+
#: The statuses of inputs.
|
77
|
+
input_statuses: Mapping[str, InputStatus]
|
78
|
+
#: The sources of inputs.
|
79
|
+
input_sources: Mapping[str, InputSource]
|
80
|
+
#: The insertion ID.
|
81
|
+
task_insert_ID: int
|
82
|
+
|
83
|
+
|
84
|
+
class _DependentDescriptor(TypedDict):
|
85
|
+
#: The names of groups of dependents.
|
86
|
+
group_names: tuple[str, ...]
|
87
|
+
|
88
|
+
|
89
|
+
class DependentDescriptor(_DependentDescriptor, total=False):
|
90
|
+
"""
|
91
|
+
Descriptor for dependents.
|
92
|
+
"""
|
93
|
+
|
94
|
+
|
95
|
+
class IterableParam(TypedDict):
|
96
|
+
"""
|
97
|
+
The type of the descriptor for an iterable parameter.
|
98
|
+
"""
|
99
|
+
|
100
|
+
#: Identifier for the input task supplying the parameter.
|
101
|
+
input_task: int
|
102
|
+
#: Identifiers for the output tasks consuming the parameter.
|
103
|
+
output_tasks: list[int]
|
104
|
+
|
105
|
+
|
106
|
+
#: Type of an address.
|
107
|
+
Address: TypeAlias = "list[int | float | str]"
|
108
|
+
#: Type of something numeric.
|
109
|
+
Numeric: TypeAlias = "int | float | np.number"
|
110
|
+
|
111
|
+
|
112
|
+
class LabelInfo(TypedDict):
|
113
|
+
"""
|
114
|
+
Information about a label.
|
115
|
+
"""
|
116
|
+
|
117
|
+
#: The label propagation mode, if known.
|
118
|
+
propagation_mode: NotRequired[ParameterPropagationMode]
|
119
|
+
#: The group containing the label, if known.
|
120
|
+
group: NotRequired[str]
|
121
|
+
#: The default value for the label, if known.
|
122
|
+
default_value: NotRequired[InputValue]
|
123
|
+
|
124
|
+
|
125
|
+
class LabellingDescriptor(TypedDict):
|
126
|
+
"""
|
127
|
+
Descriptor for a labelling.
|
128
|
+
"""
|
129
|
+
|
130
|
+
#: The type with the label.
|
131
|
+
labelled_type: str
|
132
|
+
#: The propagation mode for the label.
|
133
|
+
propagation_mode: ParameterPropagationMode
|
134
|
+
#: The group containing the label.
|
135
|
+
group: str | None
|
136
|
+
#: The default value for the label, if known.
|
137
|
+
default_value: NotRequired[InputValue]
|
138
|
+
|
139
|
+
|
140
|
+
class ResourceSpecArgs(TypedDict):
|
141
|
+
"""
|
142
|
+
Supported keyword arguments for a ResourceSpec.
|
143
|
+
"""
|
144
|
+
|
145
|
+
#: Which scope does this apply to.
|
146
|
+
scope: NotRequired[ActionScope | str]
|
147
|
+
#: Which scratch space to use.
|
148
|
+
scratch: NotRequired[str]
|
149
|
+
#: Which parallel mode to use.
|
150
|
+
parallel_mode: NotRequired[str | ParallelMode]
|
151
|
+
#: How many cores to request.
|
152
|
+
num_cores: NotRequired[int]
|
153
|
+
#: How many cores per compute node to request.
|
154
|
+
num_cores_per_node: NotRequired[int]
|
155
|
+
#: How many threads to request.
|
156
|
+
num_threads: NotRequired[int]
|
157
|
+
#: How many compute nodes to request.
|
158
|
+
num_nodes: NotRequired[int]
|
159
|
+
#: Which scheduler to use.
|
160
|
+
scheduler: NotRequired[str]
|
161
|
+
#: Which system shell to use.
|
162
|
+
shell: NotRequired[str]
|
163
|
+
#: Whether to use array jobs.
|
164
|
+
use_job_array: NotRequired[bool]
|
165
|
+
#: If using array jobs, up to how many items should be in the job array.
|
166
|
+
max_array_items: NotRequired[int]
|
167
|
+
#: How long to run for.
|
168
|
+
time_limit: NotRequired[str | timedelta]
|
169
|
+
#: Additional arguments to pass to the scheduler.
|
170
|
+
scheduler_args: NotRequired[dict[str, Any]]
|
171
|
+
#: Additional arguments to pass to the shell.
|
172
|
+
shell_args: NotRequired[dict[str, Any]]
|
173
|
+
#: Which OS to use.
|
174
|
+
os_name: NotRequired[str]
|
175
|
+
#: Which execution environments to use.
|
176
|
+
environments: NotRequired[dict[str, dict[str, Any]]]
|
177
|
+
#: Which SGE parallel environment to request.
|
178
|
+
SGE_parallel_env: NotRequired[str]
|
179
|
+
#: Which SLURM partition to request.
|
180
|
+
SLURM_partition: NotRequired[str]
|
181
|
+
#: How many SLURM tasks to request.
|
182
|
+
SLURM_num_tasks: NotRequired[str]
|
183
|
+
#: How many SLURM tasks per compute node to request.
|
184
|
+
SLURM_num_tasks_per_node: NotRequired[str]
|
185
|
+
#: How many compute nodes to request.
|
186
|
+
SLURM_num_nodes: NotRequired[str]
|
187
|
+
#: How many CPU cores to ask for per SLURM task.
|
188
|
+
SLURM_num_cpus_per_task: NotRequired[str]
|
189
|
+
|
190
|
+
|
191
|
+
# Used in declaration of Resources below
|
192
|
+
_R: TypeAlias = "ResourceSpec | ResourceSpecArgs | dict"
|
193
|
+
#: The type of things we can normalise to a :py:class:`ResourceList`.
|
194
|
+
Resources: TypeAlias = "_R | ResourceList | None | Sequence[_R]"
|
195
|
+
|
196
|
+
|
197
|
+
class SchemaInputKwargs(TypedDict):
|
198
|
+
"""
|
199
|
+
Just used when deep copying `SchemaInput`.
|
200
|
+
"""
|
201
|
+
|
202
|
+
#: The parameter.
|
203
|
+
parameter: Parameter | str
|
204
|
+
#: Whether this is multiple.
|
205
|
+
multiple: bool
|
206
|
+
#: The labels.
|
207
|
+
labels: dict[str, LabelInfo] | None
|
208
|
+
|
209
|
+
|
210
|
+
class RuleArgs(TypedDict):
|
211
|
+
"""
|
212
|
+
The keyword arguments that may be used to create a Rule.
|
213
|
+
"""
|
214
|
+
|
215
|
+
#: If present, check this attribute exists.
|
216
|
+
check_exists: NotRequired[str]
|
217
|
+
#: If present, check this attribute does *not* exist.
|
218
|
+
check_missing: NotRequired[str]
|
219
|
+
#: Where to look up the attribute to check.
|
220
|
+
#: If not present, determined by context.
|
221
|
+
path: NotRequired[str]
|
222
|
+
#: If present, a general condition to check (or kwargs used to generate one).
|
223
|
+
condition: NotRequired[dict[str, Any] | ConditionLike]
|
224
|
+
#: If present, a cast to apply prior to running the general check.
|
225
|
+
cast: NotRequired[str]
|
226
|
+
#: Optional descriptive text.
|
227
|
+
doc: NotRequired[str]
|
228
|
+
|
229
|
+
|
230
|
+
class ActParameterDependence(TypedDict):
|
231
|
+
"""
|
232
|
+
Action parameter dependency descriptor.
|
233
|
+
"""
|
234
|
+
|
235
|
+
#: The input file writers that produce the parameter.
|
236
|
+
input_file_writers: list[tuple[int, FileSpec]]
|
237
|
+
#: The commands that produce the parameter.
|
238
|
+
commands: list[tuple[int, int]]
|
239
|
+
|
240
|
+
|
241
|
+
#: A relevant path when applying an update.
|
242
|
+
RelevantPath: TypeAlias = "ParentPath | UpdatePath | SiblingPath"
|
243
|
+
|
244
|
+
|
245
|
+
class RepeatsDescriptor(TypedDict):
|
246
|
+
"""
|
247
|
+
Descriptor for repeats.
|
248
|
+
"""
|
249
|
+
|
250
|
+
#: Name of the repeat.
|
251
|
+
name: str
|
252
|
+
#: The repeat count.
|
253
|
+
number: int
|
254
|
+
#: The nesting order. Normally an integer; non-integer values have special meanings.
|
255
|
+
nesting_order: float
|
256
|
+
|
257
|
+
|
258
|
+
class MultiplicityDescriptor(TypedDict):
|
259
|
+
"""
|
260
|
+
Descriptor for multiplicities.
|
261
|
+
"""
|
262
|
+
|
263
|
+
#: The size of the multiplicity.
|
264
|
+
multiplicity: int
|
265
|
+
#: The nesting order. Normally an integer; non-integer values have special meanings.
|
266
|
+
nesting_order: float
|
267
|
+
#: The path to the multiplicity.
|
268
|
+
path: str
|
269
|
+
|
270
|
+
|
271
|
+
class ParentPath(TypedDict):
|
272
|
+
"""
|
273
|
+
A `RelevantPath` that is a path to a parent.
|
274
|
+
"""
|
275
|
+
|
276
|
+
#: Type ID.
|
277
|
+
type: Literal["parent"]
|
278
|
+
relative_path: Sequence[str]
|
279
|
+
|
280
|
+
|
281
|
+
class UpdatePath(TypedDict):
|
282
|
+
"""
|
283
|
+
A `RelevantPath` that is a path to an update.
|
284
|
+
"""
|
285
|
+
|
286
|
+
#: Type ID.
|
287
|
+
type: Literal["update"]
|
288
|
+
update_path: Sequence[str]
|
289
|
+
|
290
|
+
|
291
|
+
class SiblingPath(TypedDict):
|
292
|
+
"""
|
293
|
+
A `RelevantPath` that is a path to a sibling.
|
294
|
+
"""
|
295
|
+
|
296
|
+
#: Type ID.
|
297
|
+
type: Literal["sibling"]
|
298
|
+
|
299
|
+
|
300
|
+
class RelevantData(TypedDict):
|
301
|
+
"""
|
302
|
+
Data relevant to performing an update.
|
303
|
+
"""
|
304
|
+
|
305
|
+
#: The data to set.
|
306
|
+
data: list[Any] | Any
|
307
|
+
#: Which method to use for handling the data, if any.
|
308
|
+
value_class_method: list[str | None] | str | None
|
309
|
+
#: Whether the value is set.
|
310
|
+
is_set: bool | list[bool]
|
311
|
+
#: Whether the value is multiple.
|
312
|
+
is_multi: bool
|
313
|
+
|
314
|
+
|
315
|
+
class CreationInfo(TypedDict):
|
316
|
+
"""
|
317
|
+
Descriptor for creation information about a workflow.
|
318
|
+
"""
|
319
|
+
|
320
|
+
#: Description of information about the application.
|
321
|
+
app_info: dict[str, Any]
|
322
|
+
#: When the workflow was created.
|
323
|
+
create_time: datetime
|
324
|
+
#: Unique identifier for the workflow.
|
325
|
+
id: str
|
326
|
+
|
327
|
+
|
328
|
+
class WorkflowTemplateTaskData(TypedDict):
|
329
|
+
"""
|
330
|
+
Descriptor for information about tasks described in a workflow template.
|
331
|
+
"""
|
332
|
+
|
333
|
+
#: The schema, if known.
|
334
|
+
schema: NotRequired[Any | list[Any]]
|
335
|
+
#: The element sets, if known.
|
336
|
+
element_sets: NotRequired[list["WorkflowTemplateTaskData"]]
|
337
|
+
#: The output labels, if known.
|
338
|
+
output_labels: NotRequired[list[str]]
|
339
|
+
|
340
|
+
|
341
|
+
class Pending(TypedDict):
|
342
|
+
"""
|
343
|
+
Pending update information. Internal use only.
|
344
|
+
"""
|
345
|
+
|
346
|
+
#: Template components to update.
|
347
|
+
template_components: dict[str, list[int]]
|
348
|
+
#: Tasks to update.
|
349
|
+
tasks: list[int]
|
350
|
+
#: Loops to update.
|
351
|
+
loops: list[int]
|
352
|
+
#: Submissions to update.
|
353
|
+
submissions: list[int]
|
354
|
+
|
355
|
+
|
356
|
+
class AbstractFileSystem(Protocol):
|
357
|
+
"""
|
358
|
+
Type constraints for an abstract file system.
|
359
|
+
"""
|
360
|
+
|
361
|
+
# Because a dependency is not fully typed...
|
362
|
+
def exists(self, path: str) -> bool:
|
363
|
+
"""Test if a path points to a file or directory that exists."""
|
364
|
+
|
365
|
+
def rename(self, from_: str, to: str, *, recursive: bool = False) -> None:
|
366
|
+
"""Rename a file or directory."""
|
367
|
+
|
368
|
+
def rm(self, path: str, *, recursive: bool = False) -> None:
|
369
|
+
"""Delete a file or directory."""
|
370
|
+
|
371
|
+
def glob(self, pattern: str) -> list[str]:
|
372
|
+
"""List files in a directory that match a pattern."""
|
373
|
+
|
374
|
+
|
375
|
+
class ResourcePersistingWorkflow(Protocol):
|
376
|
+
"""
|
377
|
+
An object to pass to :py:meth:`ResourceSpec.make_persistent` that handles
|
378
|
+
persisting resources.
|
379
|
+
"""
|
380
|
+
|
381
|
+
def _add_parameter_data(self, data: Any, source: ParamSource) -> int:
|
382
|
+
...
|
383
|
+
|
384
|
+
def check_parameters_exist(self, id_lst: int | list[int]) -> bool:
|
385
|
+
"""
|
386
|
+
Check if all the parameters exist.
|
387
|
+
"""
|