hpcflow 0.1.9__py3-none-any.whl → 0.2.0a271__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/__init__.py +2 -11
- hpcflow/__pyinstaller/__init__.py +5 -0
- hpcflow/__pyinstaller/hook-hpcflow.py +40 -0
- hpcflow/_version.py +1 -1
- hpcflow/app.py +43 -0
- hpcflow/cli.py +2 -462
- hpcflow/data/demo_data_manifest/__init__.py +3 -0
- hpcflow/data/demo_data_manifest/demo_data_manifest.json +6 -0
- hpcflow/data/jinja_templates/test/test_template.txt +8 -0
- hpcflow/data/programs/hello_world/README.md +1 -0
- hpcflow/data/programs/hello_world/hello_world.c +87 -0
- hpcflow/data/programs/hello_world/linux/hello_world +0 -0
- hpcflow/data/programs/hello_world/macos/hello_world +0 -0
- hpcflow/data/programs/hello_world/win/hello_world.exe +0 -0
- hpcflow/data/scripts/__init__.py +1 -0
- hpcflow/data/scripts/bad_script.py +2 -0
- hpcflow/data/scripts/demo_task_1_generate_t1_infile_1.py +8 -0
- hpcflow/data/scripts/demo_task_1_generate_t1_infile_2.py +8 -0
- hpcflow/data/scripts/demo_task_1_parse_p3.py +7 -0
- hpcflow/data/scripts/do_nothing.py +2 -0
- hpcflow/data/scripts/env_specifier_test/input_file_generator_pass_env_spec.py +4 -0
- hpcflow/data/scripts/env_specifier_test/main_script_test_pass_env_spec.py +8 -0
- hpcflow/data/scripts/env_specifier_test/output_file_parser_pass_env_spec.py +4 -0
- hpcflow/data/scripts/env_specifier_test/v1/input_file_generator_basic.py +4 -0
- hpcflow/data/scripts/env_specifier_test/v1/main_script_test_direct_in_direct_out.py +7 -0
- hpcflow/data/scripts/env_specifier_test/v1/output_file_parser_basic.py +4 -0
- hpcflow/data/scripts/env_specifier_test/v2/main_script_test_direct_in_direct_out.py +7 -0
- hpcflow/data/scripts/generate_t1_file_01.py +7 -0
- hpcflow/data/scripts/import_future_script.py +7 -0
- hpcflow/data/scripts/input_file_generator_basic.py +3 -0
- hpcflow/data/scripts/input_file_generator_basic_FAIL.py +3 -0
- hpcflow/data/scripts/input_file_generator_test_stdout_stderr.py +8 -0
- hpcflow/data/scripts/main_script_test_direct_in.py +3 -0
- hpcflow/data/scripts/main_script_test_direct_in_direct_out.py +6 -0
- hpcflow/data/scripts/main_script_test_direct_in_direct_out_2.py +6 -0
- hpcflow/data/scripts/main_script_test_direct_in_direct_out_2_fail_allowed.py +6 -0
- hpcflow/data/scripts/main_script_test_direct_in_direct_out_2_fail_allowed_group.py +7 -0
- hpcflow/data/scripts/main_script_test_direct_in_direct_out_3.py +6 -0
- hpcflow/data/scripts/main_script_test_direct_in_direct_out_all_iters_test.py +15 -0
- hpcflow/data/scripts/main_script_test_direct_in_direct_out_env_spec.py +7 -0
- hpcflow/data/scripts/main_script_test_direct_in_direct_out_labels.py +8 -0
- hpcflow/data/scripts/main_script_test_direct_in_group_direct_out_3.py +6 -0
- hpcflow/data/scripts/main_script_test_direct_in_group_one_fail_direct_out_3.py +6 -0
- hpcflow/data/scripts/main_script_test_direct_sub_param_in_direct_out.py +6 -0
- hpcflow/data/scripts/main_script_test_hdf5_in_obj.py +12 -0
- hpcflow/data/scripts/main_script_test_hdf5_in_obj_2.py +12 -0
- hpcflow/data/scripts/main_script_test_hdf5_in_obj_group.py +12 -0
- hpcflow/data/scripts/main_script_test_hdf5_out_obj.py +11 -0
- hpcflow/data/scripts/main_script_test_json_and_direct_in_json_out.py +14 -0
- hpcflow/data/scripts/main_script_test_json_in_json_and_direct_out.py +17 -0
- hpcflow/data/scripts/main_script_test_json_in_json_out.py +14 -0
- hpcflow/data/scripts/main_script_test_json_in_json_out_labels.py +16 -0
- hpcflow/data/scripts/main_script_test_json_in_obj.py +12 -0
- hpcflow/data/scripts/main_script_test_json_out_FAIL.py +3 -0
- hpcflow/data/scripts/main_script_test_json_out_obj.py +10 -0
- hpcflow/data/scripts/main_script_test_json_sub_param_in_json_out_labels.py +16 -0
- hpcflow/data/scripts/main_script_test_shell_env_vars.py +12 -0
- hpcflow/data/scripts/main_script_test_std_out_std_err.py +6 -0
- hpcflow/data/scripts/output_file_parser_basic.py +3 -0
- hpcflow/data/scripts/output_file_parser_basic_FAIL.py +7 -0
- hpcflow/data/scripts/output_file_parser_test_stdout_stderr.py +8 -0
- hpcflow/data/scripts/parse_t1_file_01.py +4 -0
- hpcflow/data/scripts/script_exit_test.py +5 -0
- hpcflow/data/template_components/__init__.py +1 -0
- hpcflow/data/template_components/command_files.yaml +26 -0
- hpcflow/data/template_components/environments.yaml +13 -0
- hpcflow/data/template_components/parameters.yaml +14 -0
- hpcflow/data/template_components/task_schemas.yaml +139 -0
- hpcflow/data/workflows/workflow_1.yaml +5 -0
- hpcflow/examples.ipynb +1037 -0
- hpcflow/sdk/__init__.py +149 -0
- hpcflow/sdk/app.py +4266 -0
- hpcflow/sdk/cli.py +1479 -0
- hpcflow/sdk/cli_common.py +385 -0
- hpcflow/sdk/config/__init__.py +5 -0
- hpcflow/sdk/config/callbacks.py +246 -0
- hpcflow/sdk/config/cli.py +388 -0
- hpcflow/sdk/config/config.py +1410 -0
- hpcflow/sdk/config/config_file.py +501 -0
- hpcflow/sdk/config/errors.py +272 -0
- hpcflow/sdk/config/types.py +150 -0
- hpcflow/sdk/core/__init__.py +38 -0
- hpcflow/sdk/core/actions.py +3857 -0
- hpcflow/sdk/core/app_aware.py +25 -0
- hpcflow/sdk/core/cache.py +224 -0
- hpcflow/sdk/core/command_files.py +814 -0
- hpcflow/sdk/core/commands.py +424 -0
- hpcflow/sdk/core/element.py +2071 -0
- hpcflow/sdk/core/enums.py +221 -0
- hpcflow/sdk/core/environment.py +256 -0
- hpcflow/sdk/core/errors.py +1043 -0
- hpcflow/sdk/core/execute.py +207 -0
- hpcflow/sdk/core/json_like.py +809 -0
- hpcflow/sdk/core/loop.py +1320 -0
- hpcflow/sdk/core/loop_cache.py +282 -0
- hpcflow/sdk/core/object_list.py +933 -0
- hpcflow/sdk/core/parameters.py +3371 -0
- hpcflow/sdk/core/rule.py +196 -0
- hpcflow/sdk/core/run_dir_files.py +57 -0
- hpcflow/sdk/core/skip_reason.py +7 -0
- hpcflow/sdk/core/task.py +3792 -0
- hpcflow/sdk/core/task_schema.py +993 -0
- hpcflow/sdk/core/test_utils.py +538 -0
- hpcflow/sdk/core/types.py +447 -0
- hpcflow/sdk/core/utils.py +1207 -0
- hpcflow/sdk/core/validation.py +87 -0
- hpcflow/sdk/core/values.py +477 -0
- hpcflow/sdk/core/workflow.py +4820 -0
- hpcflow/sdk/core/zarr_io.py +206 -0
- hpcflow/sdk/data/__init__.py +13 -0
- hpcflow/sdk/data/config_file_schema.yaml +34 -0
- hpcflow/sdk/data/config_schema.yaml +260 -0
- hpcflow/sdk/data/environments_spec_schema.yaml +21 -0
- hpcflow/sdk/data/files_spec_schema.yaml +5 -0
- hpcflow/sdk/data/parameters_spec_schema.yaml +7 -0
- hpcflow/sdk/data/task_schema_spec_schema.yaml +3 -0
- hpcflow/sdk/data/workflow_spec_schema.yaml +22 -0
- hpcflow/sdk/demo/__init__.py +3 -0
- hpcflow/sdk/demo/cli.py +242 -0
- hpcflow/sdk/helper/__init__.py +3 -0
- hpcflow/sdk/helper/cli.py +137 -0
- hpcflow/sdk/helper/helper.py +300 -0
- hpcflow/sdk/helper/watcher.py +192 -0
- hpcflow/sdk/log.py +288 -0
- hpcflow/sdk/persistence/__init__.py +18 -0
- hpcflow/sdk/persistence/base.py +2817 -0
- hpcflow/sdk/persistence/defaults.py +6 -0
- hpcflow/sdk/persistence/discovery.py +39 -0
- hpcflow/sdk/persistence/json.py +954 -0
- hpcflow/sdk/persistence/pending.py +948 -0
- hpcflow/sdk/persistence/store_resource.py +203 -0
- hpcflow/sdk/persistence/types.py +309 -0
- hpcflow/sdk/persistence/utils.py +73 -0
- hpcflow/sdk/persistence/zarr.py +2388 -0
- hpcflow/sdk/runtime.py +320 -0
- hpcflow/sdk/submission/__init__.py +3 -0
- hpcflow/sdk/submission/enums.py +70 -0
- hpcflow/sdk/submission/jobscript.py +2379 -0
- hpcflow/sdk/submission/schedulers/__init__.py +281 -0
- hpcflow/sdk/submission/schedulers/direct.py +233 -0
- hpcflow/sdk/submission/schedulers/sge.py +376 -0
- hpcflow/sdk/submission/schedulers/slurm.py +598 -0
- hpcflow/sdk/submission/schedulers/utils.py +25 -0
- hpcflow/sdk/submission/shells/__init__.py +52 -0
- hpcflow/sdk/submission/shells/base.py +229 -0
- hpcflow/sdk/submission/shells/bash.py +504 -0
- hpcflow/sdk/submission/shells/os_version.py +115 -0
- hpcflow/sdk/submission/shells/powershell.py +352 -0
- hpcflow/sdk/submission/submission.py +1402 -0
- hpcflow/sdk/submission/types.py +140 -0
- hpcflow/sdk/typing.py +194 -0
- hpcflow/sdk/utils/arrays.py +69 -0
- hpcflow/sdk/utils/deferred_file.py +55 -0
- hpcflow/sdk/utils/hashing.py +16 -0
- hpcflow/sdk/utils/patches.py +31 -0
- hpcflow/sdk/utils/strings.py +69 -0
- hpcflow/tests/api/test_api.py +32 -0
- hpcflow/tests/conftest.py +123 -0
- hpcflow/tests/data/__init__.py +0 -0
- hpcflow/tests/data/benchmark_N_elements.yaml +6 -0
- hpcflow/tests/data/benchmark_script_runner.yaml +26 -0
- hpcflow/tests/data/multi_path_sequences.yaml +29 -0
- hpcflow/tests/data/workflow_1.json +10 -0
- hpcflow/tests/data/workflow_1.yaml +5 -0
- hpcflow/tests/data/workflow_1_slurm.yaml +8 -0
- hpcflow/tests/data/workflow_1_wsl.yaml +8 -0
- hpcflow/tests/data/workflow_test_run_abort.yaml +42 -0
- hpcflow/tests/jinja_templates/test_jinja_templates.py +161 -0
- hpcflow/tests/programs/test_programs.py +180 -0
- hpcflow/tests/schedulers/direct_linux/test_direct_linux_submission.py +12 -0
- hpcflow/tests/schedulers/sge/test_sge_submission.py +36 -0
- hpcflow/tests/schedulers/slurm/test_slurm_submission.py +14 -0
- hpcflow/tests/scripts/test_input_file_generators.py +282 -0
- hpcflow/tests/scripts/test_main_scripts.py +1361 -0
- hpcflow/tests/scripts/test_non_snippet_script.py +46 -0
- hpcflow/tests/scripts/test_ouput_file_parsers.py +353 -0
- hpcflow/tests/shells/wsl/test_wsl_submission.py +14 -0
- hpcflow/tests/unit/test_action.py +1066 -0
- hpcflow/tests/unit/test_action_rule.py +24 -0
- hpcflow/tests/unit/test_app.py +132 -0
- hpcflow/tests/unit/test_cache.py +46 -0
- hpcflow/tests/unit/test_cli.py +172 -0
- hpcflow/tests/unit/test_command.py +377 -0
- hpcflow/tests/unit/test_config.py +195 -0
- hpcflow/tests/unit/test_config_file.py +162 -0
- hpcflow/tests/unit/test_element.py +666 -0
- hpcflow/tests/unit/test_element_iteration.py +88 -0
- hpcflow/tests/unit/test_element_set.py +158 -0
- hpcflow/tests/unit/test_group.py +115 -0
- hpcflow/tests/unit/test_input_source.py +1479 -0
- hpcflow/tests/unit/test_input_value.py +398 -0
- hpcflow/tests/unit/test_jobscript_unit.py +757 -0
- hpcflow/tests/unit/test_json_like.py +1247 -0
- hpcflow/tests/unit/test_loop.py +2674 -0
- hpcflow/tests/unit/test_meta_task.py +325 -0
- hpcflow/tests/unit/test_multi_path_sequences.py +259 -0
- hpcflow/tests/unit/test_object_list.py +116 -0
- hpcflow/tests/unit/test_parameter.py +243 -0
- hpcflow/tests/unit/test_persistence.py +664 -0
- hpcflow/tests/unit/test_resources.py +243 -0
- hpcflow/tests/unit/test_run.py +286 -0
- hpcflow/tests/unit/test_run_directories.py +29 -0
- hpcflow/tests/unit/test_runtime.py +9 -0
- hpcflow/tests/unit/test_schema_input.py +372 -0
- hpcflow/tests/unit/test_shell.py +129 -0
- hpcflow/tests/unit/test_slurm.py +39 -0
- hpcflow/tests/unit/test_submission.py +502 -0
- hpcflow/tests/unit/test_task.py +2560 -0
- hpcflow/tests/unit/test_task_schema.py +182 -0
- hpcflow/tests/unit/test_utils.py +616 -0
- hpcflow/tests/unit/test_value_sequence.py +549 -0
- hpcflow/tests/unit/test_values.py +91 -0
- hpcflow/tests/unit/test_workflow.py +827 -0
- hpcflow/tests/unit/test_workflow_template.py +186 -0
- hpcflow/tests/unit/utils/test_arrays.py +40 -0
- hpcflow/tests/unit/utils/test_deferred_file_writer.py +34 -0
- hpcflow/tests/unit/utils/test_hashing.py +65 -0
- hpcflow/tests/unit/utils/test_patches.py +5 -0
- hpcflow/tests/unit/utils/test_redirect_std.py +50 -0
- hpcflow/tests/unit/utils/test_strings.py +97 -0
- hpcflow/tests/workflows/__init__.py +0 -0
- hpcflow/tests/workflows/test_directory_structure.py +31 -0
- hpcflow/tests/workflows/test_jobscript.py +355 -0
- hpcflow/tests/workflows/test_run_status.py +198 -0
- hpcflow/tests/workflows/test_skip_downstream.py +696 -0
- hpcflow/tests/workflows/test_submission.py +140 -0
- hpcflow/tests/workflows/test_workflows.py +564 -0
- hpcflow/tests/workflows/test_zip.py +18 -0
- hpcflow/viz_demo.ipynb +6794 -0
- hpcflow-0.2.0a271.dist-info/LICENSE +375 -0
- hpcflow-0.2.0a271.dist-info/METADATA +65 -0
- hpcflow-0.2.0a271.dist-info/RECORD +237 -0
- {hpcflow-0.1.9.dist-info → hpcflow-0.2.0a271.dist-info}/WHEEL +4 -5
- hpcflow-0.2.0a271.dist-info/entry_points.txt +6 -0
- hpcflow/api.py +0 -458
- hpcflow/archive/archive.py +0 -308
- hpcflow/archive/cloud/cloud.py +0 -47
- hpcflow/archive/cloud/errors.py +0 -9
- hpcflow/archive/cloud/providers/dropbox.py +0 -432
- hpcflow/archive/errors.py +0 -5
- hpcflow/base_db.py +0 -4
- hpcflow/config.py +0 -232
- hpcflow/copytree.py +0 -66
- hpcflow/data/examples/_config.yml +0 -14
- hpcflow/data/examples/damask/demo/1.run.yml +0 -4
- hpcflow/data/examples/damask/demo/2.process.yml +0 -29
- hpcflow/data/examples/damask/demo/geom.geom +0 -2052
- hpcflow/data/examples/damask/demo/load.load +0 -1
- hpcflow/data/examples/damask/demo/material.config +0 -185
- hpcflow/data/examples/damask/inputs/geom.geom +0 -2052
- hpcflow/data/examples/damask/inputs/load.load +0 -1
- hpcflow/data/examples/damask/inputs/material.config +0 -185
- hpcflow/data/examples/damask/profiles/_variable_lookup.yml +0 -21
- hpcflow/data/examples/damask/profiles/damask.yml +0 -4
- hpcflow/data/examples/damask/profiles/damask_process.yml +0 -8
- hpcflow/data/examples/damask/profiles/damask_run.yml +0 -5
- hpcflow/data/examples/damask/profiles/default.yml +0 -6
- hpcflow/data/examples/thinking.yml +0 -177
- hpcflow/errors.py +0 -2
- hpcflow/init_db.py +0 -37
- hpcflow/models.py +0 -2549
- hpcflow/nesting.py +0 -9
- hpcflow/profiles.py +0 -455
- hpcflow/project.py +0 -81
- hpcflow/scheduler.py +0 -323
- hpcflow/utils.py +0 -103
- hpcflow/validation.py +0 -167
- hpcflow/variables.py +0 -544
- hpcflow-0.1.9.dist-info/METADATA +0 -168
- hpcflow-0.1.9.dist-info/RECORD +0 -45
- hpcflow-0.1.9.dist-info/entry_points.txt +0 -8
- hpcflow-0.1.9.dist-info/top_level.txt +0 -1
- /hpcflow/{archive → data/jinja_templates}/__init__.py +0 -0
- /hpcflow/{archive/cloud → data/programs}/__init__.py +0 -0
- /hpcflow/{archive/cloud/providers → data/workflows}/__init__.py +0 -0
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Utilities for working with Zarr.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
from typing import Any
|
|
7
|
+
from typing_extensions import Self
|
|
8
|
+
|
|
9
|
+
import zarr # type: ignore
|
|
10
|
+
import numpy as np
|
|
11
|
+
|
|
12
|
+
from hpcflow.sdk.core.utils import get_in_container, get_relative_path, set_in_container
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
#: The basic types that Zarr can handle directly with no special action.
|
|
16
|
+
PRIMITIVES: tuple[type, ...] = (
|
|
17
|
+
int,
|
|
18
|
+
float,
|
|
19
|
+
str,
|
|
20
|
+
type(None),
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
#: Maximum nesting depth for encoding.
|
|
24
|
+
MAX_DEPTH = 50
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def zarr_encode(data, zarr_group: zarr.Group, is_pending_add: bool, is_set: bool):
|
|
28
|
+
"""
|
|
29
|
+
Encode data into a zarr group.
|
|
30
|
+
"""
|
|
31
|
+
|
|
32
|
+
encoded: list[dict] = []
|
|
33
|
+
|
|
34
|
+
def encode(obj: Any, path: list) -> Any:
|
|
35
|
+
if len(path) > MAX_DEPTH:
|
|
36
|
+
raise RuntimeError("I'm in too deep!")
|
|
37
|
+
|
|
38
|
+
if isinstance(obj, ZarrEncodable):
|
|
39
|
+
return encode(obj.to_dict(), path)
|
|
40
|
+
elif isinstance(obj, (list, tuple, set)):
|
|
41
|
+
out = (encode(item, [*path, idx]) for idx, item in enumerate(obj))
|
|
42
|
+
if isinstance(obj, tuple):
|
|
43
|
+
return tuple(out)
|
|
44
|
+
elif isinstance(obj, set):
|
|
45
|
+
return set(out)
|
|
46
|
+
else:
|
|
47
|
+
return list(out)
|
|
48
|
+
elif isinstance(obj, dict):
|
|
49
|
+
return {
|
|
50
|
+
dct_key: encode(dct_val, [*path, dct_key])
|
|
51
|
+
for dct_key, dct_val in obj.items()
|
|
52
|
+
}
|
|
53
|
+
elif isinstance(obj, PRIMITIVES):
|
|
54
|
+
return obj
|
|
55
|
+
elif isinstance(obj, np.ndarray):
|
|
56
|
+
new_name = str(max((int(i) + 1 for i in zarr_group.keys()), default=0))
|
|
57
|
+
zarr_group.create_dataset(name=new_name, data=obj)
|
|
58
|
+
encoded.append(
|
|
59
|
+
{
|
|
60
|
+
"path": path,
|
|
61
|
+
"dataset": new_name,
|
|
62
|
+
}
|
|
63
|
+
)
|
|
64
|
+
return None
|
|
65
|
+
else:
|
|
66
|
+
raise ValueError(f"unserializable type: {type(obj)}")
|
|
67
|
+
|
|
68
|
+
zarr_group.attrs["data"] = encode(data, [])
|
|
69
|
+
zarr_group.attrs["encoded"] = encoded
|
|
70
|
+
zarr_group.attrs["is_set"] = is_set
|
|
71
|
+
if is_pending_add:
|
|
72
|
+
zarr_group.attrs["is_pending_add"] = is_pending_add
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
# TODO: need to separate so this func doesn't need matflow
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def _zarr_encode_NEW(
|
|
79
|
+
obj: Any,
|
|
80
|
+
root_group: zarr.Group,
|
|
81
|
+
arr_path: str,
|
|
82
|
+
) -> tuple[Any, list[list]]:
|
|
83
|
+
"""
|
|
84
|
+
Save arbitrarily-nested Python-primitive, `ZarrEncodable` and numpy array objects into
|
|
85
|
+
Zarr.
|
|
86
|
+
|
|
87
|
+
Parameters
|
|
88
|
+
----------
|
|
89
|
+
obj:
|
|
90
|
+
Object to encode.
|
|
91
|
+
root_group:
|
|
92
|
+
Parent Zarr group into which new Zarr arrays will be added (at `arr_path`).
|
|
93
|
+
arr_path:
|
|
94
|
+
Path relative to `root_group` into which new Zarr arrays will be added.
|
|
95
|
+
|
|
96
|
+
Returns
|
|
97
|
+
-------
|
|
98
|
+
data
|
|
99
|
+
The encoded data.
|
|
100
|
+
arr_lookup
|
|
101
|
+
How to look up where to rebuild Numpy arrays.
|
|
102
|
+
"""
|
|
103
|
+
|
|
104
|
+
arr_lookup: list[list] = []
|
|
105
|
+
|
|
106
|
+
def encode(obj: Any, path: list) -> Any:
|
|
107
|
+
if len(path) > MAX_DEPTH:
|
|
108
|
+
raise RuntimeError("I'm in too deep!")
|
|
109
|
+
|
|
110
|
+
if isinstance(obj, ZarrEncodable):
|
|
111
|
+
return encode(obj.to_dict(), path)
|
|
112
|
+
elif isinstance(obj, (list, tuple, set)):
|
|
113
|
+
items = (encode(item, [*path, idx]) for idx, item in enumerate(obj))
|
|
114
|
+
if isinstance(obj, tuple):
|
|
115
|
+
return tuple(items)
|
|
116
|
+
elif isinstance(obj, set):
|
|
117
|
+
return set(items)
|
|
118
|
+
else:
|
|
119
|
+
return list(items)
|
|
120
|
+
elif isinstance(obj, dict):
|
|
121
|
+
return {key: encode(val, [*path, key]) for key, val in obj.items()}
|
|
122
|
+
elif isinstance(obj, PRIMITIVES):
|
|
123
|
+
return obj
|
|
124
|
+
elif isinstance(obj, np.ndarray):
|
|
125
|
+
# Might need to generate new group:
|
|
126
|
+
param_arr_group = root_group.require_group(arr_path)
|
|
127
|
+
new_idx = max((int(i) + 1 for i in param_arr_group.keys()), default=0)
|
|
128
|
+
param_arr_group.create_dataset(name=f"arr_{new_idx}", data=obj)
|
|
129
|
+
arr_lookup.append([path, new_idx])
|
|
130
|
+
return None
|
|
131
|
+
else:
|
|
132
|
+
raise ValueError(f"unserializable type: {type(obj)}")
|
|
133
|
+
|
|
134
|
+
return encode(obj, []), arr_lookup
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
def zarr_decode(
|
|
138
|
+
param_data: None | dict,
|
|
139
|
+
arr_group: zarr.Group,
|
|
140
|
+
path: list | None = None,
|
|
141
|
+
dataset_copy: bool = False,
|
|
142
|
+
):
|
|
143
|
+
"""
|
|
144
|
+
Decode data from a zarr group.
|
|
145
|
+
"""
|
|
146
|
+
if param_data is None:
|
|
147
|
+
return None
|
|
148
|
+
|
|
149
|
+
path = path or []
|
|
150
|
+
|
|
151
|
+
data = get_in_container(param_data["data"], path)
|
|
152
|
+
# data = copy.deepcopy(data) # TODO: why did we copy?
|
|
153
|
+
|
|
154
|
+
for arr_path, arr_idx in param_data["arr_lookup"]:
|
|
155
|
+
try:
|
|
156
|
+
rel_path = get_relative_path(arr_path, path)
|
|
157
|
+
except ValueError:
|
|
158
|
+
continue
|
|
159
|
+
|
|
160
|
+
dataset = arr_group.get(f"arr_{arr_idx}")
|
|
161
|
+
|
|
162
|
+
if dataset_copy:
|
|
163
|
+
dataset = dataset[:]
|
|
164
|
+
|
|
165
|
+
if rel_path:
|
|
166
|
+
set_in_container(data, rel_path, dataset)
|
|
167
|
+
else:
|
|
168
|
+
data = dataset
|
|
169
|
+
|
|
170
|
+
return data
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
class ZarrEncodable:
|
|
174
|
+
"""
|
|
175
|
+
Base class of data that can be converted to and from zarr form.
|
|
176
|
+
"""
|
|
177
|
+
|
|
178
|
+
_typ = None
|
|
179
|
+
|
|
180
|
+
def to_dict(self) -> dict[str, Any]:
|
|
181
|
+
"""
|
|
182
|
+
Convert this object to a dict.
|
|
183
|
+
"""
|
|
184
|
+
if hasattr(self, "__dict__"):
|
|
185
|
+
return dict(self.__dict__)
|
|
186
|
+
elif hasattr(self, "__slots__"):
|
|
187
|
+
return {k: getattr(self, k) for k in self.__slots__}
|
|
188
|
+
else:
|
|
189
|
+
# Should be unreachable
|
|
190
|
+
return {}
|
|
191
|
+
|
|
192
|
+
def to_zarr(self, zarr_group: zarr.Group):
|
|
193
|
+
"""
|
|
194
|
+
Save this object into the given zarr group.
|
|
195
|
+
"""
|
|
196
|
+
zarr_encode(self.to_dict(), zarr_group, is_pending_add=False, is_set=False)
|
|
197
|
+
|
|
198
|
+
@classmethod
|
|
199
|
+
def from_zarr(cls, zarr_group: zarr.Group, dataset_copy: bool = False) -> Self:
|
|
200
|
+
"""
|
|
201
|
+
Read an instance of this class from the given zarr group.
|
|
202
|
+
"""
|
|
203
|
+
# FIXME: Do the read of the data!
|
|
204
|
+
param_data = None
|
|
205
|
+
data = zarr_decode(param_data, zarr_group, dataset_copy=dataset_copy)
|
|
206
|
+
return cls(**data)
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"""
|
|
2
|
+
YAML schemas.
|
|
3
|
+
|
|
4
|
+
Contents:
|
|
5
|
+
|
|
6
|
+
* ``config_file_schema.yaml`` – Schema for configuration selection files.
|
|
7
|
+
* ``config_schema.yaml`` – Schema for configuration files.
|
|
8
|
+
* ``environments_spec_schema.yaml`` – Schema for execution environment definition files.
|
|
9
|
+
* ``files_spec_schema.yaml`` – Schema for input/output specification files.
|
|
10
|
+
* ``parameters_spec_schema.yaml`` – Schema for parameter specification files.
|
|
11
|
+
* ``task_schema_spec_schema.yaml`` – Schema for task template specification files.
|
|
12
|
+
* ``workflow_spec_schema.yaml`` – Schema for workflow files.
|
|
13
|
+
"""
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
rules:
|
|
2
|
+
- path: []
|
|
3
|
+
condition:
|
|
4
|
+
and:
|
|
5
|
+
- value.required_keys:
|
|
6
|
+
- configs
|
|
7
|
+
- value.allowed_keys:
|
|
8
|
+
- configs
|
|
9
|
+
|
|
10
|
+
- path: [configs]
|
|
11
|
+
doc: >
|
|
12
|
+
A mapping of string config "invocation keys" to configuration settings.
|
|
13
|
+
condition:
|
|
14
|
+
and:
|
|
15
|
+
- value.type.equal_to: dict
|
|
16
|
+
- value.keys_is_instance: [str]
|
|
17
|
+
|
|
18
|
+
- path: [configs, { type: map_value }]
|
|
19
|
+
condition:
|
|
20
|
+
and:
|
|
21
|
+
- value.type.equal_to: dict
|
|
22
|
+
- value.required_keys:
|
|
23
|
+
- invocation
|
|
24
|
+
- config
|
|
25
|
+
|
|
26
|
+
- path: [configs, { type: map_value }, invocation]
|
|
27
|
+
condition:
|
|
28
|
+
value.allowed_keys:
|
|
29
|
+
- environment_setup
|
|
30
|
+
- match
|
|
31
|
+
|
|
32
|
+
- path: [configs, { type: map_value }, invocation, match]
|
|
33
|
+
condition:
|
|
34
|
+
value.type.equal_to: dict
|
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
rules:
|
|
2
|
+
- path: []
|
|
3
|
+
condition:
|
|
4
|
+
value.allowed_keys:
|
|
5
|
+
- machine
|
|
6
|
+
- user_name
|
|
7
|
+
- user_orcid
|
|
8
|
+
- user_affiliations
|
|
9
|
+
- linux_release_file
|
|
10
|
+
- log_file_path
|
|
11
|
+
- log_file_level
|
|
12
|
+
- log_console_level
|
|
13
|
+
- task_schema_sources
|
|
14
|
+
- parameter_sources
|
|
15
|
+
- command_file_sources
|
|
16
|
+
- environment_sources
|
|
17
|
+
- default_scheduler
|
|
18
|
+
- default_shell
|
|
19
|
+
- schedulers
|
|
20
|
+
- shells
|
|
21
|
+
- demo_data_dir
|
|
22
|
+
- demo_data_manifest_file
|
|
23
|
+
- default_workflow_path
|
|
24
|
+
- workflow_name_use_dir
|
|
25
|
+
- workflow_name_add_timestamp
|
|
26
|
+
- path: []
|
|
27
|
+
condition:
|
|
28
|
+
value.required_keys:
|
|
29
|
+
- machine
|
|
30
|
+
- task_schema_sources
|
|
31
|
+
- parameter_sources
|
|
32
|
+
- command_file_sources
|
|
33
|
+
- environment_sources
|
|
34
|
+
- default_scheduler
|
|
35
|
+
- default_shell
|
|
36
|
+
- schedulers
|
|
37
|
+
- path: []
|
|
38
|
+
condition:
|
|
39
|
+
value.forbidden_keys:
|
|
40
|
+
- config_directory # Config metadata
|
|
41
|
+
- config_file_name # Config metadata
|
|
42
|
+
- config_file_path # Config metadata
|
|
43
|
+
- config_file_contents # Config metadata
|
|
44
|
+
- config_key # Config metadata
|
|
45
|
+
- config_schemas # Config metadata
|
|
46
|
+
- invoking_user_id # Config metadata
|
|
47
|
+
- host_user_id # Config metadata
|
|
48
|
+
- host_user_id_file_path # Config metadata
|
|
49
|
+
- config_callback # Config method
|
|
50
|
+
- get_all # Config method
|
|
51
|
+
- get # Config method
|
|
52
|
+
- set # Config method
|
|
53
|
+
- _set # Config method
|
|
54
|
+
- unset # Config method
|
|
55
|
+
- save # Config method
|
|
56
|
+
- reload # Config method
|
|
57
|
+
|
|
58
|
+
- path: [machine]
|
|
59
|
+
doc: >
|
|
60
|
+
A label that references the current machine. By default, this uses the return from
|
|
61
|
+
the Python function `socket.gethostname()`.
|
|
62
|
+
condition:
|
|
63
|
+
value.type.equal_to: str
|
|
64
|
+
|
|
65
|
+
- path: [user_name]
|
|
66
|
+
condition:
|
|
67
|
+
value.type.equal_to: str
|
|
68
|
+
|
|
69
|
+
- path: [user_orcid]
|
|
70
|
+
condition:
|
|
71
|
+
value.type.equal_to: str
|
|
72
|
+
|
|
73
|
+
- path: [user_affiliations]
|
|
74
|
+
condition:
|
|
75
|
+
value.type.equal_to: list
|
|
76
|
+
|
|
77
|
+
- path: [user_affiliations, { type: list_value }]
|
|
78
|
+
condition:
|
|
79
|
+
value.is_instance: [str]
|
|
80
|
+
|
|
81
|
+
- path: [linux_release_file]
|
|
82
|
+
condition:
|
|
83
|
+
value.type.equal_to: str
|
|
84
|
+
|
|
85
|
+
- path: [log_file_path]
|
|
86
|
+
doc:
|
|
87
|
+
- >
|
|
88
|
+
File path to the app log file. The variables `<<app_name>>` and `<<app_version>>`
|
|
89
|
+
are available to be used in this option, which resolve to the app name and version,
|
|
90
|
+
respectively.
|
|
91
|
+
- >
|
|
92
|
+
The file path may be nested in non-existent directories, in which case
|
|
93
|
+
those directories will be generated. If specified as a relative path, the path will
|
|
94
|
+
be resolved relative to the config directory (the directory that contains the config
|
|
95
|
+
file).
|
|
96
|
+
condition:
|
|
97
|
+
value.is_instance: [str, path]
|
|
98
|
+
|
|
99
|
+
- path: [log_file_level]
|
|
100
|
+
condition:
|
|
101
|
+
and:
|
|
102
|
+
- value.type.equal_to: str
|
|
103
|
+
- value.in: [notset, debug, info, warning, error, critical]
|
|
104
|
+
|
|
105
|
+
- path: [log_console_level]
|
|
106
|
+
condition:
|
|
107
|
+
and:
|
|
108
|
+
- value.type.equal_to: str
|
|
109
|
+
- value.in: [notset, debug, info, warning, error, critical]
|
|
110
|
+
|
|
111
|
+
- path: [task_schema_sources]
|
|
112
|
+
condition:
|
|
113
|
+
value.type.equal_to: list
|
|
114
|
+
|
|
115
|
+
- path: [environment_sources]
|
|
116
|
+
condition:
|
|
117
|
+
value.type.equal_to: list
|
|
118
|
+
|
|
119
|
+
- path: [parameter_sources]
|
|
120
|
+
condition:
|
|
121
|
+
value.type.equal_to: list
|
|
122
|
+
|
|
123
|
+
- path: [command_file_sources]
|
|
124
|
+
condition:
|
|
125
|
+
value.type.equal_to: list
|
|
126
|
+
|
|
127
|
+
- path: [task_schema_sources, { type: list_value }]
|
|
128
|
+
condition:
|
|
129
|
+
value.is_instance: [str, path]
|
|
130
|
+
|
|
131
|
+
- path: [environment_sources, { type: list_value }]
|
|
132
|
+
condition:
|
|
133
|
+
value.is_instance: [str, path]
|
|
134
|
+
|
|
135
|
+
- path: [parameter_sources, { type: list_value }]
|
|
136
|
+
condition:
|
|
137
|
+
value.is_instance: [str, path]
|
|
138
|
+
|
|
139
|
+
- path: [command_file_sources, { type: list_value }]
|
|
140
|
+
condition:
|
|
141
|
+
value.is_instance: [str, path]
|
|
142
|
+
|
|
143
|
+
- path: [default_scheduler]
|
|
144
|
+
condition:
|
|
145
|
+
value.in: [direct, sge, slurm]
|
|
146
|
+
|
|
147
|
+
- path: [default_shell]
|
|
148
|
+
condition:
|
|
149
|
+
value.in: [powershell, bash, wsl, wsl+bash]
|
|
150
|
+
|
|
151
|
+
- path: [schedulers]
|
|
152
|
+
condition:
|
|
153
|
+
value.allowed_keys: [direct, direct_posix, sge, slurm]
|
|
154
|
+
|
|
155
|
+
- path: [schedulers, { type: map_value }]
|
|
156
|
+
condition:
|
|
157
|
+
value.allowed_keys: [defaults, parallel_environments, partitions] # TODO split these up based on scheduler type
|
|
158
|
+
|
|
159
|
+
- path: [schedulers, { type: map_value }, defaults]
|
|
160
|
+
condition:
|
|
161
|
+
value.allowed_keys: # TODO: split these up based on scheduler type
|
|
162
|
+
- shebang_executable
|
|
163
|
+
- directives # TODO: only actually allowed in `QueuedScheduler` sub-classes
|
|
164
|
+
- options # deprecated, replaced by directives
|
|
165
|
+
- submit_cmd
|
|
166
|
+
- show_cmd
|
|
167
|
+
- del_cmd
|
|
168
|
+
- js_cmd
|
|
169
|
+
- array_switch
|
|
170
|
+
- array_item_var
|
|
171
|
+
- cwd_switch
|
|
172
|
+
|
|
173
|
+
- path: [schedulers, sge]
|
|
174
|
+
condition:
|
|
175
|
+
value.type.equal_to: dict
|
|
176
|
+
|
|
177
|
+
- path: [schedulers, sge, parallel_environments]
|
|
178
|
+
condition:
|
|
179
|
+
value.type.equal_to: dict
|
|
180
|
+
|
|
181
|
+
- path: [schedulers, sge, parallel_environments, { type: map_value }]
|
|
182
|
+
condition:
|
|
183
|
+
and:
|
|
184
|
+
- value.allowed_keys:
|
|
185
|
+
- num_cores
|
|
186
|
+
- num_nodes
|
|
187
|
+
- parallel_modes
|
|
188
|
+
- value.required_keys:
|
|
189
|
+
- num_cores
|
|
190
|
+
|
|
191
|
+
- path: [schedulers, slurm]
|
|
192
|
+
condition:
|
|
193
|
+
value.type.equal_to: dict
|
|
194
|
+
|
|
195
|
+
- path: [schedulers, slurm, partitions]
|
|
196
|
+
condition:
|
|
197
|
+
value.type.equal_to: dict
|
|
198
|
+
|
|
199
|
+
- path: [schedulers, slurm, partitions, { type: map_value }]
|
|
200
|
+
condition:
|
|
201
|
+
and:
|
|
202
|
+
- value.allowed_keys:
|
|
203
|
+
- num_cores
|
|
204
|
+
- num_nodes
|
|
205
|
+
- num_cores_per_node
|
|
206
|
+
- parallel_modes
|
|
207
|
+
- value.required_keys:
|
|
208
|
+
- num_cores
|
|
209
|
+
|
|
210
|
+
- path: [shells]
|
|
211
|
+
condition:
|
|
212
|
+
value.allowed_keys: [powershell, bash, wsl, wsl+bash]
|
|
213
|
+
|
|
214
|
+
- path: [shells, { type: map_value }]
|
|
215
|
+
condition:
|
|
216
|
+
value.allowed_keys: [defaults]
|
|
217
|
+
|
|
218
|
+
- path: [shells, { type: map_value }, defaults]
|
|
219
|
+
condition:
|
|
220
|
+
value.allowed_keys:
|
|
221
|
+
- executable
|
|
222
|
+
- executable_args
|
|
223
|
+
- os_args
|
|
224
|
+
- WSL_executable
|
|
225
|
+
- WSL_distribution
|
|
226
|
+
- WSL_user
|
|
227
|
+
|
|
228
|
+
- path: [demo_data_dir]
|
|
229
|
+
doc: >
|
|
230
|
+
If provided, this will be used as the path to the directory containing demo data
|
|
231
|
+
files. This can be a local path or an fsspec URL.
|
|
232
|
+
condition:
|
|
233
|
+
value.is_instance: [str, path]
|
|
234
|
+
|
|
235
|
+
- path: [demo_data_manifest_file]
|
|
236
|
+
doc: >
|
|
237
|
+
If provided, this will be used as the path to the manifest for the built-in example
|
|
238
|
+
data files. It should point to a JSON file whose top-level keys are example data
|
|
239
|
+
file names. Each value should be an empty map/dict or a map like: `{"in_zip": "text_file.zip"}`,
|
|
240
|
+
where `text_file.zip` is the name of a zip archive that contains the example data
|
|
241
|
+
file. This can be a local path or an fsspec URL.
|
|
242
|
+
condition:
|
|
243
|
+
value.is_instance: [str, path]
|
|
244
|
+
|
|
245
|
+
- path: [default_workflow_path]
|
|
246
|
+
doc: Default directory path in which new workflows will be generated.
|
|
247
|
+
condition:
|
|
248
|
+
value.is_instance: [str, path]
|
|
249
|
+
|
|
250
|
+
- path: [workflow_name_add_timestamp]
|
|
251
|
+
doc: By default, whether to suffix the workflow name with a date-timestamp.
|
|
252
|
+
condition:
|
|
253
|
+
value.is_instance: [bool]
|
|
254
|
+
|
|
255
|
+
- path: [workflow_name_add_timestamp]
|
|
256
|
+
doc: >
|
|
257
|
+
By default, whether to use a directory named according to the workflow name, and
|
|
258
|
+
a separate child directory named according to the date-timestamp if present.
|
|
259
|
+
condition:
|
|
260
|
+
value.is_instance: [bool]
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
rules:
|
|
2
|
+
- path: []
|
|
3
|
+
condition:
|
|
4
|
+
{
|
|
5
|
+
value.allowed_keys: [name, setup, executables, specifiers, doc, _hash_value],
|
|
6
|
+
}
|
|
7
|
+
- path: [setup]
|
|
8
|
+
condition:
|
|
9
|
+
or:
|
|
10
|
+
- value.type.equal_to: str
|
|
11
|
+
- value.null: null
|
|
12
|
+
- path: [executables]
|
|
13
|
+
condition: { value.type.equal_to: list }
|
|
14
|
+
- path: [executables, { type: list_value }]
|
|
15
|
+
condition: { value.allowed_keys: [label, instances] }
|
|
16
|
+
- path: [executables, { type: list_value }, instances]
|
|
17
|
+
condition: { value.type.equal_to: list }
|
|
18
|
+
- path: [executables, { type: list_value }, instances, { type: list_value }]
|
|
19
|
+
condition: { value.type.equal_to: dict }
|
|
20
|
+
- path: [executables, { type: list_value }, instances, { type: list_value }]
|
|
21
|
+
condition: { value.allowed_keys: [command, num_cores, parallel_mode] }
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
rules:
|
|
2
|
+
- path: []
|
|
3
|
+
condition:
|
|
4
|
+
value.allowed_keys:
|
|
5
|
+
- doc
|
|
6
|
+
- name
|
|
7
|
+
- source_file
|
|
8
|
+
- resources
|
|
9
|
+
- config
|
|
10
|
+
- environments
|
|
11
|
+
- env_presets
|
|
12
|
+
- template_components
|
|
13
|
+
- tasks
|
|
14
|
+
- meta_tasks
|
|
15
|
+
- loops
|
|
16
|
+
- store_kwargs
|
|
17
|
+
- merge_resources
|
|
18
|
+
- merge_envs
|
|
19
|
+
- workflow
|
|
20
|
+
|
|
21
|
+
- path: [tasks]
|
|
22
|
+
condition: { value.type.equal_to: list }
|