hpcflow 0.1.15__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 -461
- 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.15.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 -490
- hpcflow/archive/archive.py +0 -307
- hpcflow/archive/cloud/cloud.py +0 -45
- hpcflow/archive/cloud/errors.py +0 -9
- hpcflow/archive/cloud/providers/dropbox.py +0 -427
- hpcflow/archive/errors.py +0 -5
- hpcflow/base_db.py +0 -4
- hpcflow/config.py +0 -233
- 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 -2595
- hpcflow/nesting.py +0 -9
- hpcflow/profiles.py +0 -455
- hpcflow/project.py +0 -81
- hpcflow/scheduler.py +0 -322
- hpcflow/utils.py +0 -103
- hpcflow/validation.py +0 -166
- hpcflow/variables.py +0 -543
- hpcflow-0.1.15.dist-info/METADATA +0 -168
- hpcflow-0.1.15.dist-info/RECORD +0 -45
- hpcflow-0.1.15.dist-info/entry_points.txt +0 -8
- hpcflow-0.1.15.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,272 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Miscellaneous configuration-related errors.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
from typing import Any, TYPE_CHECKING
|
|
7
|
+
|
|
8
|
+
if TYPE_CHECKING:
|
|
9
|
+
from collections.abc import Sequence, Iterable
|
|
10
|
+
from .types import ConfigMetadata
|
|
11
|
+
from ..typing import PathLike
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class ConfigError(Exception):
|
|
15
|
+
"""
|
|
16
|
+
Raised when a valid configuration can not be associated with the current
|
|
17
|
+
invocation.
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class IncompatibleConfigError(ConfigError):
|
|
22
|
+
"""
|
|
23
|
+
Raised when the config file is from an incompatible version of the app.
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class ConfigUnknownItemError(ConfigError):
|
|
28
|
+
"""
|
|
29
|
+
Raised when the configuration contains an unknown item.
|
|
30
|
+
"""
|
|
31
|
+
|
|
32
|
+
def __init__(self, name: str, message: str = ""):
|
|
33
|
+
super().__init__(
|
|
34
|
+
message
|
|
35
|
+
or (
|
|
36
|
+
f"Specified name {name!r} is not a valid meta-data or configurable "
|
|
37
|
+
f"configuration item."
|
|
38
|
+
)
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
class ConfigUnknownOverrideError(ConfigError):
|
|
43
|
+
"""
|
|
44
|
+
Raised when the configuration override contains an unknown item.
|
|
45
|
+
"""
|
|
46
|
+
|
|
47
|
+
def __init__(self, name: str, message: str = ""):
|
|
48
|
+
super().__init__(
|
|
49
|
+
message
|
|
50
|
+
or (
|
|
51
|
+
f"Specified configuration override {name!r} is not a valid configurable item."
|
|
52
|
+
)
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
class ConfigNonConfigurableError(ConfigError):
|
|
57
|
+
"""
|
|
58
|
+
Raised when the configuration contains an item that can't be configured.
|
|
59
|
+
"""
|
|
60
|
+
|
|
61
|
+
def __init__(self, name: str | Iterable[str], message: str | None = None):
|
|
62
|
+
if not message:
|
|
63
|
+
if not isinstance(name, str):
|
|
64
|
+
names_str = ", ".join(f"{i!r}" for i in name)
|
|
65
|
+
msg = f"Specified names {names_str} are not configurable items."
|
|
66
|
+
else:
|
|
67
|
+
msg = f"Specified name {name!r} is not a configurable item."
|
|
68
|
+
self.message = message or msg
|
|
69
|
+
super().__init__(self.message)
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
class ConfigItemAlreadyUnsetError(ConfigError):
|
|
73
|
+
"""
|
|
74
|
+
Raised when the configuration tries to unset an unset item.
|
|
75
|
+
"""
|
|
76
|
+
|
|
77
|
+
def __init__(self, name: str, message: str = ""):
|
|
78
|
+
super().__init__(message or f"Configuration item {name!r} is already not set.")
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
class ConfigFileValidationError(ConfigError):
|
|
82
|
+
"""
|
|
83
|
+
Raised when the configuration file fails validation.
|
|
84
|
+
"""
|
|
85
|
+
|
|
86
|
+
def __init__(self, msg: str) -> None:
|
|
87
|
+
super().__init__(msg)
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
class ConfigItemCallbackError(ConfigError):
|
|
91
|
+
"""
|
|
92
|
+
Raised when a configuration callback errors.
|
|
93
|
+
"""
|
|
94
|
+
|
|
95
|
+
def __init__(self, name: str, callback: Any, err: Any, message: str = ""):
|
|
96
|
+
super().__init__(
|
|
97
|
+
message
|
|
98
|
+
or (
|
|
99
|
+
f"Callback function {callback.__name__!r} for configuration item {name!r} "
|
|
100
|
+
f"failed with exception: \n\n{str(err)}"
|
|
101
|
+
)
|
|
102
|
+
)
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
class ConfigFileInvocationIncompatibleError(ConfigError):
|
|
106
|
+
"""Raised when, given the run time information of the invocation, no compatible
|
|
107
|
+
configuration can be found in the config file."""
|
|
108
|
+
|
|
109
|
+
def __init__(self, message: str | None = ""):
|
|
110
|
+
super().__init__(
|
|
111
|
+
message or ("No config could be found that matches the current invocation.")
|
|
112
|
+
)
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
class ConfigFileInvocationUnknownMatchKey(ConfigError):
|
|
116
|
+
"""
|
|
117
|
+
Raised when the configuration contains an invalid match key.
|
|
118
|
+
"""
|
|
119
|
+
|
|
120
|
+
def __init__(self, match_key: str, message: str = ""):
|
|
121
|
+
self.match_key = match_key
|
|
122
|
+
super().__init__(
|
|
123
|
+
message
|
|
124
|
+
or (
|
|
125
|
+
f"Specified match key ({match_key!r}) is not a valid run time info "
|
|
126
|
+
f"attribute."
|
|
127
|
+
)
|
|
128
|
+
)
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
class ConfigInvocationKeyNotFoundError(ConfigError):
|
|
132
|
+
"""Raised when a configuration invocation key is passed but it is not a valid key."""
|
|
133
|
+
|
|
134
|
+
def __init__(
|
|
135
|
+
self, invoc_key: str, file_path: PathLike, available_keys: Sequence[str]
|
|
136
|
+
):
|
|
137
|
+
self.invoc_key = invoc_key
|
|
138
|
+
self.file_path = file_path
|
|
139
|
+
self.available_keys = available_keys
|
|
140
|
+
super().__init__(
|
|
141
|
+
f"Invocation key {self.invoc_key!r} does not exist in configuration file. "
|
|
142
|
+
f"Available keys in configuration file {str(self.file_path)!r} are "
|
|
143
|
+
f"{self.available_keys!r}."
|
|
144
|
+
)
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
class ConfigValidationError(ConfigError):
|
|
148
|
+
"""Raised when the matching config data is invalid."""
|
|
149
|
+
|
|
150
|
+
def __init__(self, message: str, meta_data: ConfigMetadata | None = None):
|
|
151
|
+
self.meta_data = meta_data
|
|
152
|
+
super().__init__(message + (f"config {self.meta_data}\n" if meta_data else ""))
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
class ConfigDefaultValidationError(ConfigError):
|
|
156
|
+
"""Raised when the specified default configuration in the `ConfigOptions` object is
|
|
157
|
+
invalid."""
|
|
158
|
+
|
|
159
|
+
def __init__(self, validation_err: Any, message: str = ""):
|
|
160
|
+
super().__init__(
|
|
161
|
+
message
|
|
162
|
+
or (
|
|
163
|
+
f"The default configuration specified in the `ConfigOptions` object is "
|
|
164
|
+
f"invalid.\n\n{validation_err}"
|
|
165
|
+
)
|
|
166
|
+
)
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
class ConfigChangeInvalidError(ConfigError):
|
|
170
|
+
"""Raised when trying to set an invalid key in the Config."""
|
|
171
|
+
|
|
172
|
+
def __init__(self, name: str, message: str = ""):
|
|
173
|
+
super().__init__(
|
|
174
|
+
message
|
|
175
|
+
or (
|
|
176
|
+
f"Cannot modify value for invalid config item {name!r}. Use the `config list`"
|
|
177
|
+
f" sub-command to list all configurable items."
|
|
178
|
+
)
|
|
179
|
+
)
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
class ConfigChangeInvalidJSONError(ConfigError):
|
|
183
|
+
"""Raised when attempting to set a config key using an invalid JSON string."""
|
|
184
|
+
|
|
185
|
+
def __init__(self, name: str, json_str: str, err: Any, message: str = ""):
|
|
186
|
+
super().__init__(
|
|
187
|
+
message
|
|
188
|
+
or (
|
|
189
|
+
f"The config file has not been modified. Invalid JSON string for config item "
|
|
190
|
+
f"{name!r}. {json_str!r}\n\n{err!r}"
|
|
191
|
+
)
|
|
192
|
+
)
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
class ConfigChangeValidationError(ConfigError):
|
|
196
|
+
"""Raised when a change to the configurable data would invalidate the config."""
|
|
197
|
+
|
|
198
|
+
def __init__(self, name: str, validation_err: Any, message: str = ""):
|
|
199
|
+
super().__init__(
|
|
200
|
+
message
|
|
201
|
+
or (
|
|
202
|
+
f"The configuration has not been modified. Requested modification to item "
|
|
203
|
+
f"{name!r} would invalidate the config in the following way."
|
|
204
|
+
f"\n\n{validation_err}"
|
|
205
|
+
)
|
|
206
|
+
)
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
class ConfigChangeFileUpdateError(ConfigError):
|
|
210
|
+
"""Raised when the updating of the config YAML file fails."""
|
|
211
|
+
|
|
212
|
+
def __init__(self, names: Sequence[str], err, message: str = ""):
|
|
213
|
+
super().__init__(
|
|
214
|
+
message
|
|
215
|
+
or (
|
|
216
|
+
f"Failed to update the config file for modification of config items {names!r}."
|
|
217
|
+
f"\n\n{err!r}"
|
|
218
|
+
)
|
|
219
|
+
)
|
|
220
|
+
|
|
221
|
+
|
|
222
|
+
class ConfigChangeTypeInvalidError(ConfigError):
|
|
223
|
+
"""Raised when trying to modify a config item using a list operation, when the config
|
|
224
|
+
item is not a list."""
|
|
225
|
+
|
|
226
|
+
def __init__(self, name: str, typ: type, message: str = ""):
|
|
227
|
+
super().__init__(
|
|
228
|
+
message
|
|
229
|
+
or (
|
|
230
|
+
f"The configuration has not been modified. The config item {name!r} has type "
|
|
231
|
+
f"{typ!r} and so cannot be modified in that way."
|
|
232
|
+
)
|
|
233
|
+
)
|
|
234
|
+
|
|
235
|
+
|
|
236
|
+
class ConfigChangePopIndexError(ConfigError):
|
|
237
|
+
"""Raised when trying to pop an item from a config item with an invalid index."""
|
|
238
|
+
|
|
239
|
+
def __init__(self, name: str, length: int, index: int, message: str = ""):
|
|
240
|
+
super().__init__(
|
|
241
|
+
message
|
|
242
|
+
or (
|
|
243
|
+
f"The configuration has not been modified. The config item {name!r} has length "
|
|
244
|
+
f"{length!r} and so cannot be popped with index {index}."
|
|
245
|
+
)
|
|
246
|
+
)
|
|
247
|
+
|
|
248
|
+
|
|
249
|
+
class MissingTaskSchemaFileError(ConfigError):
|
|
250
|
+
"""Raised when a task schema file specified in the config file does not exist."""
|
|
251
|
+
|
|
252
|
+
def __init__(self, file_name: str, err: Any, message: str = ""):
|
|
253
|
+
super().__init__(
|
|
254
|
+
message or (f"The task schema file {file_name!r} cannot be found. \n{err!s}")
|
|
255
|
+
)
|
|
256
|
+
|
|
257
|
+
|
|
258
|
+
class MissingEnvironmentFileError(ConfigError):
|
|
259
|
+
"""Raised when an environment file specified in the config file does not exist."""
|
|
260
|
+
|
|
261
|
+
def __init__(self, file_name: str, err: Any, message: str = ""):
|
|
262
|
+
super().__init__(
|
|
263
|
+
message or (f"The environment file {file_name!r} cannot be found. \n{err!s}")
|
|
264
|
+
)
|
|
265
|
+
|
|
266
|
+
|
|
267
|
+
class ConfigReadOnlyError(ConfigError):
|
|
268
|
+
pass
|
|
269
|
+
|
|
270
|
+
|
|
271
|
+
class UnknownMetaTaskConstitutiveSchema(ValueError):
|
|
272
|
+
pass
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Types used in configuration.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
from typing import TYPE_CHECKING
|
|
7
|
+
from typing_extensions import TypeAlias, TypedDict, TypeVar
|
|
8
|
+
|
|
9
|
+
if TYPE_CHECKING:
|
|
10
|
+
from collections.abc import Callable, Sequence
|
|
11
|
+
from pathlib import Path
|
|
12
|
+
from typing import Any
|
|
13
|
+
from typing_extensions import NotRequired
|
|
14
|
+
from .config import Config
|
|
15
|
+
from ..core.validation import Schema
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
T = TypeVar("T")
|
|
19
|
+
#: Type of a getter callback.
|
|
20
|
+
GetterCallback: TypeAlias = "Callable[[Config, T], T]"
|
|
21
|
+
#: Type of a setter callback.
|
|
22
|
+
SetterCallback: TypeAlias = "Callable[[Config, T], Any]"
|
|
23
|
+
#: Type of a unsetter callback.
|
|
24
|
+
UnsetterCallback: TypeAlias = "Callable[[Config], None]"
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class SGEParallelEnvsDescriptor(TypedDict):
|
|
28
|
+
"""
|
|
29
|
+
SGE parallel environment descriptor.
|
|
30
|
+
"""
|
|
31
|
+
|
|
32
|
+
#: Number of supported cores.
|
|
33
|
+
num_cores: list[int]
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class SLURMPartitionsDescriptor(TypedDict):
|
|
37
|
+
"""
|
|
38
|
+
SLURM partition descriptor.
|
|
39
|
+
"""
|
|
40
|
+
|
|
41
|
+
#: Number of supported cores.
|
|
42
|
+
num_cores: NotRequired[list[int]]
|
|
43
|
+
#: Number of cores per node.
|
|
44
|
+
num_cores_per_node: NotRequired[list[int]]
|
|
45
|
+
#: Number of supported nodes.
|
|
46
|
+
num_nodes: NotRequired[list[int]]
|
|
47
|
+
#: Possible parallel modes.
|
|
48
|
+
parallel_modes: NotRequired[list[str]]
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
class SchedulerConfigDescriptor(TypedDict):
|
|
52
|
+
"""
|
|
53
|
+
Scheduler configuration descriptor.
|
|
54
|
+
"""
|
|
55
|
+
|
|
56
|
+
#: Default values.
|
|
57
|
+
defaults: dict[str, Any]
|
|
58
|
+
#: SGE parallel environments, by name.
|
|
59
|
+
parallel_environments: NotRequired[dict[str, SGEParallelEnvsDescriptor]]
|
|
60
|
+
#: SLURM partitions, by name.
|
|
61
|
+
partitions: NotRequired[dict[str, SLURMPartitionsDescriptor]]
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
class ShellConfigDescriptor(TypedDict):
|
|
65
|
+
"""
|
|
66
|
+
Shell configuration descriptor.
|
|
67
|
+
"""
|
|
68
|
+
|
|
69
|
+
#: Default values.
|
|
70
|
+
defaults: dict[str, Any]
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
class ConfigDescriptor(TypedDict):
|
|
74
|
+
"""
|
|
75
|
+
Configuration descriptor.
|
|
76
|
+
"""
|
|
77
|
+
|
|
78
|
+
#: Execution machine.
|
|
79
|
+
machine: NotRequired[str]
|
|
80
|
+
#: Where to log.
|
|
81
|
+
log_file_path: NotRequired[str]
|
|
82
|
+
#: Where to find execution environments.
|
|
83
|
+
environment_sources: NotRequired[list[str]]
|
|
84
|
+
#: Where to find task schemas.
|
|
85
|
+
task_schema_sources: NotRequired[list[str]]
|
|
86
|
+
#: Where to find command files.
|
|
87
|
+
command_file_sources: NotRequired[list[str]]
|
|
88
|
+
#: Where to find parameter implementations.
|
|
89
|
+
parameter_sources: NotRequired[list[str]]
|
|
90
|
+
#: Default scheduler.
|
|
91
|
+
default_scheduler: NotRequired[str]
|
|
92
|
+
#: Default shell.
|
|
93
|
+
default_shell: NotRequired[str]
|
|
94
|
+
#: Supported schedulers.
|
|
95
|
+
schedulers: NotRequired[dict[str, SchedulerConfigDescriptor]]
|
|
96
|
+
#: Supported shells.
|
|
97
|
+
shells: NotRequired[dict[str, ShellConfigDescriptor]]
|
|
98
|
+
#: User affiliations
|
|
99
|
+
user_affiliations: NotRequired[list[str]]
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
class InvocationDescriptor(TypedDict):
|
|
103
|
+
"""
|
|
104
|
+
Invocation descriptor.
|
|
105
|
+
"""
|
|
106
|
+
|
|
107
|
+
#: Used to set up the environment.
|
|
108
|
+
environment_setup: str | None
|
|
109
|
+
#: setting to apply if matched.
|
|
110
|
+
match: dict[str, str | list[str]]
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
class DefaultConfiguration(TypedDict):
|
|
114
|
+
"""
|
|
115
|
+
The default configuration.
|
|
116
|
+
"""
|
|
117
|
+
|
|
118
|
+
#: Default invocation.
|
|
119
|
+
invocation: InvocationDescriptor
|
|
120
|
+
#: Default configuration.
|
|
121
|
+
config: ConfigDescriptor
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
#: A configuration dictionary.
|
|
125
|
+
ConfigDict: TypeAlias = "dict[str, dict[str, DefaultConfiguration]]"
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
class ConfigMetadata(TypedDict):
|
|
129
|
+
"""
|
|
130
|
+
Metadata supported by the :class:`Config` class.
|
|
131
|
+
"""
|
|
132
|
+
|
|
133
|
+
#: Location of directory containing the config file.
|
|
134
|
+
config_directory: Path
|
|
135
|
+
#: Name of the config file.
|
|
136
|
+
config_file_name: str
|
|
137
|
+
#: Full path to the config file.
|
|
138
|
+
config_file_path: Path
|
|
139
|
+
#: The contents of the config file.
|
|
140
|
+
config_file_contents: str
|
|
141
|
+
#: The key identifying the config section within the config file.
|
|
142
|
+
config_key: str
|
|
143
|
+
#: Schemas that apply to the config.
|
|
144
|
+
config_schemas: Sequence[Schema]
|
|
145
|
+
#: The user that invoked things.
|
|
146
|
+
invoking_user_id: str
|
|
147
|
+
#: The user hosting things.
|
|
148
|
+
host_user_id: str
|
|
149
|
+
#: Path to file holding description of :attr:``host_user_id``.
|
|
150
|
+
host_user_id_file_path: Path
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"""Core programmatic models for hpcflow.
|
|
2
|
+
|
|
3
|
+
EAR abort exit code is set to 64. EAR skipped exit code is set to 65.
|
|
4
|
+
|
|
5
|
+
References
|
|
6
|
+
----------
|
|
7
|
+
https://tldp.org/LDP/abs/html/exitcodes.html
|
|
8
|
+
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
import numpy as np
|
|
12
|
+
|
|
13
|
+
#: Formats supported for templates.
|
|
14
|
+
ALL_TEMPLATE_FORMATS = ("yaml", "json")
|
|
15
|
+
#: The exit code used by an EAR when it aborts.
|
|
16
|
+
ABORT_EXIT_CODE = 64
|
|
17
|
+
SKIPPED_EXIT_CODE = 65
|
|
18
|
+
NO_COMMANDS_EXIT_CODE = 66
|
|
19
|
+
RUN_DIR_ARR_DTYPE = [
|
|
20
|
+
("task_insert_ID", np.uint8),
|
|
21
|
+
("element_idx", np.uint32),
|
|
22
|
+
("iteration_idx", np.uint32),
|
|
23
|
+
("action_idx", np.uint8),
|
|
24
|
+
("run_idx", np.uint8),
|
|
25
|
+
("element_depth", np.uint8),
|
|
26
|
+
("iteration_depth", np.uint8),
|
|
27
|
+
]
|
|
28
|
+
_uint8_max = np.iinfo(np.uint8).max
|
|
29
|
+
_uint32_max = np.iinfo(np.uint32).max
|
|
30
|
+
RUN_DIR_ARR_FILL = (
|
|
31
|
+
_uint8_max,
|
|
32
|
+
_uint32_max,
|
|
33
|
+
_uint32_max,
|
|
34
|
+
_uint8_max,
|
|
35
|
+
_uint8_max,
|
|
36
|
+
_uint8_max,
|
|
37
|
+
_uint8_max,
|
|
38
|
+
)
|