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,25 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Utility base class for making classes aware of the overall application context.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
from typing import TYPE_CHECKING
|
|
7
|
+
|
|
8
|
+
if TYPE_CHECKING:
|
|
9
|
+
from typing import ClassVar
|
|
10
|
+
from ..app import BaseApp
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class AppAware:
|
|
14
|
+
"""
|
|
15
|
+
A base class that marks its subclasses as aware of the application.
|
|
16
|
+
|
|
17
|
+
Attributes
|
|
18
|
+
----------
|
|
19
|
+
_app: BaseApp
|
|
20
|
+
A class attribute that holds the application instance.
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
__slots__: ClassVar[tuple[str, ...]] = ()
|
|
24
|
+
_app: ClassVar[BaseApp]
|
|
25
|
+
_app_attr: ClassVar[str] = "_app"
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Dependency resolution cache.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
from collections import defaultdict
|
|
7
|
+
from dataclasses import dataclass
|
|
8
|
+
from itertools import chain
|
|
9
|
+
from typing import TYPE_CHECKING
|
|
10
|
+
|
|
11
|
+
from hpcflow.sdk.log import TimeIt
|
|
12
|
+
|
|
13
|
+
if TYPE_CHECKING:
|
|
14
|
+
from collections.abc import Sequence
|
|
15
|
+
from typing_extensions import Self
|
|
16
|
+
from .element import Element, ElementIteration
|
|
17
|
+
from .actions import ElementActionRun
|
|
18
|
+
from .workflow import Workflow
|
|
19
|
+
from ..persistence.base import StoreEAR, StoreElement, StoreElementIter
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
@dataclass
|
|
23
|
+
class ObjectCache:
|
|
24
|
+
"""Class to bulk-retrieve and store elements, iterations, runs and their various
|
|
25
|
+
dependencies."""
|
|
26
|
+
|
|
27
|
+
#: The elements of the workflow that this cache was built from.
|
|
28
|
+
elements: list[Element] | None = None
|
|
29
|
+
#: The iterations of the workflow that this cache was built from.
|
|
30
|
+
iterations: list[ElementIteration] | None = None
|
|
31
|
+
#: The runs of the workflow that this cache was built from.
|
|
32
|
+
runs: list[ElementActionRun] | None = None
|
|
33
|
+
|
|
34
|
+
#: What EARs (by ID) a given EAR depends on.
|
|
35
|
+
run_dependencies: dict[int, set[int]] | None = None
|
|
36
|
+
#: What EARs (by ID) are depending on a given EAR.
|
|
37
|
+
run_dependents: dict[int, set[int]] | None = None
|
|
38
|
+
#: What EARs (by ID) a given iteration depends on.
|
|
39
|
+
iter_run_dependencies: dict[int, set[int]] | None = None
|
|
40
|
+
#: What iterations (by ID) a given iteration depends on.
|
|
41
|
+
iter_iter_dependencies: dict[int, set[int]] | None = None
|
|
42
|
+
#: What iterations (by ID) a given element depends on.
|
|
43
|
+
elem_iter_dependencies: dict[int, set[int]] | None = None
|
|
44
|
+
#: What elements (by ID) a given element depends on.
|
|
45
|
+
elem_elem_dependencies: dict[int, set[int]] | None = None
|
|
46
|
+
#: What elements (by ID) are depending on a given element.
|
|
47
|
+
elem_elem_dependents: dict[int, set[int]] | None = None
|
|
48
|
+
#: Transitive closure of :py:attr:`elem_elem_dependents`.
|
|
49
|
+
elem_elem_dependents_rec: dict[int, set[int]] | None = None
|
|
50
|
+
|
|
51
|
+
@classmethod
|
|
52
|
+
@TimeIt.decorator
|
|
53
|
+
def build(
|
|
54
|
+
cls,
|
|
55
|
+
workflow: Workflow,
|
|
56
|
+
dependencies: bool = False,
|
|
57
|
+
elements: bool = False,
|
|
58
|
+
iterations: bool = False,
|
|
59
|
+
runs: bool = False,
|
|
60
|
+
):
|
|
61
|
+
"""
|
|
62
|
+
Build a cache instance.
|
|
63
|
+
|
|
64
|
+
Parameters
|
|
65
|
+
----------
|
|
66
|
+
workflow: ~hpcflow.app.Workflow
|
|
67
|
+
The workflow to build the cache from.
|
|
68
|
+
dependencies
|
|
69
|
+
If True, calculate dependencies.
|
|
70
|
+
elements
|
|
71
|
+
If True, include elements in the cache.
|
|
72
|
+
iterations
|
|
73
|
+
If True, include iterations in the cache.
|
|
74
|
+
runs
|
|
75
|
+
If True, include runs in the cache.
|
|
76
|
+
|
|
77
|
+
"""
|
|
78
|
+
kwargs = {}
|
|
79
|
+
if dependencies:
|
|
80
|
+
kwargs.update(cls._get_dependencies(workflow))
|
|
81
|
+
|
|
82
|
+
if elements:
|
|
83
|
+
kwargs["elements"] = workflow.get_all_elements()
|
|
84
|
+
|
|
85
|
+
if iterations:
|
|
86
|
+
kwargs["iterations"] = workflow.get_all_element_iterations()
|
|
87
|
+
|
|
88
|
+
if runs:
|
|
89
|
+
kwargs["runs"] = workflow.get_all_EARs()
|
|
90
|
+
|
|
91
|
+
return cls(**kwargs)
|
|
92
|
+
|
|
93
|
+
@classmethod
|
|
94
|
+
@TimeIt.decorator
|
|
95
|
+
def _get_dependencies(cls, workflow: Workflow):
|
|
96
|
+
def _get_recursive_deps(elem_id: int, seen_ids: list[int] | None = None):
|
|
97
|
+
if seen_ids is None:
|
|
98
|
+
seen_ids = [elem_id]
|
|
99
|
+
elif elem_id in seen_ids:
|
|
100
|
+
# stop recursion
|
|
101
|
+
return set()
|
|
102
|
+
else:
|
|
103
|
+
seen_ids.append(elem_id)
|
|
104
|
+
return set(elem_elem_dependents[elem_id]).union(
|
|
105
|
+
[
|
|
106
|
+
j
|
|
107
|
+
for i in elem_elem_dependents[elem_id]
|
|
108
|
+
for j in _get_recursive_deps(i, seen_ids)
|
|
109
|
+
if j != elem_id
|
|
110
|
+
]
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
num_iters = workflow.num_element_iterations
|
|
114
|
+
num_elems = workflow.num_elements
|
|
115
|
+
num_runs = workflow.num_EARs
|
|
116
|
+
|
|
117
|
+
all_store_runs: Sequence[StoreEAR] = workflow._store.get_EARs(range(num_runs))
|
|
118
|
+
all_store_iters: Sequence[StoreElementIter] = (
|
|
119
|
+
workflow._store.get_element_iterations(range(num_iters))
|
|
120
|
+
)
|
|
121
|
+
all_store_elements: Sequence[StoreElement] = workflow._store.get_elements(
|
|
122
|
+
range(num_elems)
|
|
123
|
+
)
|
|
124
|
+
all_param_sources = workflow.get_all_parameter_sources()
|
|
125
|
+
all_data_idx = (
|
|
126
|
+
{
|
|
127
|
+
k: v if isinstance(v, list) else [v]
|
|
128
|
+
for k, v in store_ear.data_idx.items()
|
|
129
|
+
if not k.startswith("repeats.")
|
|
130
|
+
}
|
|
131
|
+
for store_ear in all_store_runs
|
|
132
|
+
)
|
|
133
|
+
|
|
134
|
+
# run dependencies and dependents
|
|
135
|
+
run_dependencies: dict[int, set[int]] = {}
|
|
136
|
+
run_dependents: defaultdict[int, set[int]] = defaultdict(set)
|
|
137
|
+
for idx, dict_i in enumerate(all_data_idx):
|
|
138
|
+
run_i_sources = set(
|
|
139
|
+
run_k
|
|
140
|
+
for dat_idx_k in chain.from_iterable(dict_i.values())
|
|
141
|
+
if (run_k := all_param_sources[dat_idx_k].get("EAR_ID")) is not None
|
|
142
|
+
and run_k != idx
|
|
143
|
+
)
|
|
144
|
+
run_dependencies[idx] = run_i_sources
|
|
145
|
+
for m in run_i_sources:
|
|
146
|
+
run_dependents[m].add(idx)
|
|
147
|
+
|
|
148
|
+
# add missing and downgrade to dict:
|
|
149
|
+
for run_idx in range(num_runs):
|
|
150
|
+
run_dependents[run_idx]
|
|
151
|
+
run_dependents.default_factory = None
|
|
152
|
+
|
|
153
|
+
# iteration dependencies
|
|
154
|
+
all_iter_run_IDs = {
|
|
155
|
+
iter_.id_: tuple(chain.from_iterable((iter_.EAR_IDs or {}).values()))
|
|
156
|
+
for iter_ in all_store_iters
|
|
157
|
+
}
|
|
158
|
+
# for each iteration, which runs does it depend on?
|
|
159
|
+
iter_run_dependencies = {
|
|
160
|
+
k: set(j for idx in v for j in run_dependencies[idx])
|
|
161
|
+
for k, v in all_iter_run_IDs.items()
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
# for each run, which iteration does it belong to?
|
|
165
|
+
all_run_iter_IDs = {
|
|
166
|
+
run_ID: iter_ID
|
|
167
|
+
for iter_ID, run_IDs in all_iter_run_IDs.items()
|
|
168
|
+
for run_ID in run_IDs
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
# for each iteration, which iterations does it depend on?
|
|
172
|
+
iter_iter_dependencies = {
|
|
173
|
+
k: set(all_run_iter_IDs[i] for i in v)
|
|
174
|
+
for k, v in iter_run_dependencies.items()
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
all_elem_iter_IDs = {el.id_: el.iteration_IDs for el in all_store_elements}
|
|
178
|
+
|
|
179
|
+
elem_iter_dependencies = {
|
|
180
|
+
elem_ID: set(j for i in iter_IDs for j in iter_iter_dependencies[i])
|
|
181
|
+
for elem_ID, iter_IDs in all_elem_iter_IDs.items()
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
# for each iteration, which element does it belong to?
|
|
185
|
+
all_iter_elem_IDs = {
|
|
186
|
+
iter_ID: elem_ID
|
|
187
|
+
for elem_ID, iter_IDs in all_elem_iter_IDs.items()
|
|
188
|
+
for iter_ID in iter_IDs
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
# element dependencies
|
|
192
|
+
elem_elem_dependencies = {
|
|
193
|
+
k: set(all_iter_elem_IDs[i] for i in dep_set)
|
|
194
|
+
for k, dep_set in elem_iter_dependencies.items()
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
# for each element, which elements depend on it (directly)?
|
|
198
|
+
elem_elem_dependents: defaultdict[int, set[int]] = defaultdict(set)
|
|
199
|
+
for k, dep_set in elem_elem_dependencies.items():
|
|
200
|
+
for i in dep_set:
|
|
201
|
+
elem_elem_dependents[i].add(k)
|
|
202
|
+
|
|
203
|
+
# for each element, which elements depend on it (recursively)?
|
|
204
|
+
elem_elem_dependents_rec: defaultdict[int, set[int]] = defaultdict(set)
|
|
205
|
+
for i in list(elem_elem_dependents):
|
|
206
|
+
elem_elem_dependents_rec[i] = _get_recursive_deps(i)
|
|
207
|
+
|
|
208
|
+
# add missing keys and downgrade to dict:
|
|
209
|
+
for elem_idx in range(num_elems):
|
|
210
|
+
elem_elem_dependents[elem_idx]
|
|
211
|
+
elem_elem_dependents_rec[elem_idx]
|
|
212
|
+
elem_elem_dependents.default_factory = None
|
|
213
|
+
elem_elem_dependents_rec.default_factory = None
|
|
214
|
+
|
|
215
|
+
return dict(
|
|
216
|
+
run_dependencies=run_dependencies,
|
|
217
|
+
run_dependents=run_dependents,
|
|
218
|
+
iter_run_dependencies=iter_run_dependencies,
|
|
219
|
+
iter_iter_dependencies=iter_iter_dependencies,
|
|
220
|
+
elem_iter_dependencies=elem_iter_dependencies,
|
|
221
|
+
elem_elem_dependencies=elem_elem_dependencies,
|
|
222
|
+
elem_elem_dependents=elem_elem_dependents,
|
|
223
|
+
elem_elem_dependents_rec=elem_elem_dependents_rec,
|
|
224
|
+
)
|