hpcflow-new2 0.2.0a189__py3-none-any.whl → 0.2.0a199__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 +9 -6
- hpcflow/_version.py +1 -1
- hpcflow/app.py +1 -0
- hpcflow/data/scripts/bad_script.py +2 -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/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_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_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_hdf5_in_obj.py +1 -1
- hpcflow/data/scripts/main_script_test_hdf5_in_obj_2.py +12 -0
- hpcflow/data/scripts/main_script_test_hdf5_out_obj.py +1 -1
- hpcflow/data/scripts/main_script_test_json_out_FAIL.py +3 -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/script_exit_test.py +5 -0
- hpcflow/data/template_components/environments.yaml +1 -1
- hpcflow/sdk/__init__.py +26 -15
- hpcflow/sdk/app.py +2192 -768
- hpcflow/sdk/cli.py +506 -296
- hpcflow/sdk/cli_common.py +105 -7
- hpcflow/sdk/config/__init__.py +1 -1
- hpcflow/sdk/config/callbacks.py +115 -43
- hpcflow/sdk/config/cli.py +126 -103
- hpcflow/sdk/config/config.py +674 -318
- hpcflow/sdk/config/config_file.py +131 -95
- hpcflow/sdk/config/errors.py +125 -84
- hpcflow/sdk/config/types.py +148 -0
- hpcflow/sdk/core/__init__.py +25 -1
- hpcflow/sdk/core/actions.py +1771 -1059
- hpcflow/sdk/core/app_aware.py +24 -0
- hpcflow/sdk/core/cache.py +139 -79
- hpcflow/sdk/core/command_files.py +263 -287
- hpcflow/sdk/core/commands.py +145 -112
- hpcflow/sdk/core/element.py +828 -535
- hpcflow/sdk/core/enums.py +192 -0
- hpcflow/sdk/core/environment.py +74 -93
- hpcflow/sdk/core/errors.py +455 -52
- hpcflow/sdk/core/execute.py +207 -0
- hpcflow/sdk/core/json_like.py +540 -272
- hpcflow/sdk/core/loop.py +751 -347
- hpcflow/sdk/core/loop_cache.py +164 -47
- hpcflow/sdk/core/object_list.py +370 -207
- hpcflow/sdk/core/parameters.py +1100 -627
- hpcflow/sdk/core/rule.py +59 -41
- hpcflow/sdk/core/run_dir_files.py +21 -37
- hpcflow/sdk/core/skip_reason.py +7 -0
- hpcflow/sdk/core/task.py +1649 -1339
- hpcflow/sdk/core/task_schema.py +308 -196
- hpcflow/sdk/core/test_utils.py +191 -114
- hpcflow/sdk/core/types.py +440 -0
- hpcflow/sdk/core/utils.py +485 -309
- hpcflow/sdk/core/validation.py +82 -9
- hpcflow/sdk/core/workflow.py +2544 -1178
- hpcflow/sdk/core/zarr_io.py +98 -137
- hpcflow/sdk/data/workflow_spec_schema.yaml +2 -0
- hpcflow/sdk/demo/cli.py +53 -33
- hpcflow/sdk/helper/cli.py +18 -15
- hpcflow/sdk/helper/helper.py +75 -63
- hpcflow/sdk/helper/watcher.py +61 -28
- hpcflow/sdk/log.py +122 -71
- hpcflow/sdk/persistence/__init__.py +8 -31
- hpcflow/sdk/persistence/base.py +1360 -606
- hpcflow/sdk/persistence/defaults.py +6 -0
- hpcflow/sdk/persistence/discovery.py +38 -0
- hpcflow/sdk/persistence/json.py +568 -188
- hpcflow/sdk/persistence/pending.py +382 -179
- hpcflow/sdk/persistence/store_resource.py +39 -23
- hpcflow/sdk/persistence/types.py +318 -0
- hpcflow/sdk/persistence/utils.py +14 -11
- hpcflow/sdk/persistence/zarr.py +1337 -433
- hpcflow/sdk/runtime.py +44 -41
- hpcflow/sdk/submission/{jobscript_info.py → enums.py} +39 -12
- hpcflow/sdk/submission/jobscript.py +1651 -692
- hpcflow/sdk/submission/schedulers/__init__.py +167 -39
- hpcflow/sdk/submission/schedulers/direct.py +121 -81
- hpcflow/sdk/submission/schedulers/sge.py +170 -129
- hpcflow/sdk/submission/schedulers/slurm.py +291 -268
- hpcflow/sdk/submission/schedulers/utils.py +12 -2
- hpcflow/sdk/submission/shells/__init__.py +14 -15
- hpcflow/sdk/submission/shells/base.py +150 -29
- hpcflow/sdk/submission/shells/bash.py +283 -173
- hpcflow/sdk/submission/shells/os_version.py +31 -30
- hpcflow/sdk/submission/shells/powershell.py +228 -170
- hpcflow/sdk/submission/submission.py +1014 -335
- hpcflow/sdk/submission/types.py +140 -0
- hpcflow/sdk/typing.py +182 -12
- hpcflow/sdk/utils/arrays.py +71 -0
- hpcflow/sdk/utils/deferred_file.py +55 -0
- hpcflow/sdk/utils/hashing.py +16 -0
- hpcflow/sdk/utils/patches.py +12 -0
- hpcflow/sdk/utils/strings.py +33 -0
- hpcflow/tests/api/test_api.py +32 -0
- hpcflow/tests/conftest.py +27 -6
- hpcflow/tests/data/multi_path_sequences.yaml +29 -0
- hpcflow/tests/data/workflow_test_run_abort.yaml +34 -35
- hpcflow/tests/schedulers/sge/test_sge_submission.py +36 -0
- hpcflow/tests/schedulers/slurm/test_slurm_submission.py +5 -2
- hpcflow/tests/scripts/test_input_file_generators.py +282 -0
- hpcflow/tests/scripts/test_main_scripts.py +866 -85
- 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 +12 -4
- hpcflow/tests/unit/test_action.py +262 -75
- hpcflow/tests/unit/test_action_rule.py +9 -4
- hpcflow/tests/unit/test_app.py +33 -6
- hpcflow/tests/unit/test_cache.py +46 -0
- hpcflow/tests/unit/test_cli.py +134 -1
- hpcflow/tests/unit/test_command.py +71 -54
- hpcflow/tests/unit/test_config.py +142 -16
- hpcflow/tests/unit/test_config_file.py +21 -18
- hpcflow/tests/unit/test_element.py +58 -62
- hpcflow/tests/unit/test_element_iteration.py +50 -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_jobscript_unit.py +757 -0
- hpcflow/tests/unit/test_json_like.py +44 -35
- hpcflow/tests/unit/test_loop.py +1396 -84
- hpcflow/tests/unit/test_meta_task.py +325 -0
- hpcflow/tests/unit/test_multi_path_sequences.py +229 -0
- hpcflow/tests/unit/test_object_list.py +17 -12
- hpcflow/tests/unit/test_parameter.py +29 -7
- hpcflow/tests/unit/test_persistence.py +237 -42
- hpcflow/tests/unit/test_resources.py +20 -18
- hpcflow/tests/unit/test_run.py +117 -6
- hpcflow/tests/unit/test_run_directories.py +29 -0
- hpcflow/tests/unit/test_runtime.py +2 -1
- hpcflow/tests/unit/test_schema_input.py +23 -15
- hpcflow/tests/unit/test_shell.py +23 -2
- hpcflow/tests/unit/test_slurm.py +8 -7
- hpcflow/tests/unit/test_submission.py +38 -89
- 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/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/workflows/__init__.py +0 -0
- hpcflow/tests/workflows/test_directory_structure.py +31 -0
- hpcflow/tests/workflows/test_jobscript.py +334 -1
- 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 +160 -15
- hpcflow/tests/workflows/test_zip.py +18 -0
- hpcflow/viz_demo.ipynb +6587 -3
- {hpcflow_new2-0.2.0a189.dist-info → hpcflow_new2-0.2.0a199.dist-info}/METADATA +8 -4
- hpcflow_new2-0.2.0a199.dist-info/RECORD +221 -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.0a199.dist-info}/LICENSE +0 -0
- {hpcflow_new2-0.2.0a189.dist-info → hpcflow_new2-0.2.0a199.dist-info}/WHEEL +0 -0
- {hpcflow_new2-0.2.0a189.dist-info → hpcflow_new2-0.2.0a199.dist-info}/entry_points.txt +0 -0
hpcflow/sdk/core/loop_cache.py
CHANGED
@@ -2,14 +2,122 @@
|
|
2
2
|
Cache of loop statuses.
|
3
3
|
"""
|
4
4
|
|
5
|
+
from __future__ import annotations
|
5
6
|
from dataclasses import dataclass
|
6
7
|
from collections import defaultdict
|
7
|
-
from typing import
|
8
|
+
from typing import TYPE_CHECKING
|
9
|
+
from typing_extensions import Generic, TypeVar
|
8
10
|
|
9
|
-
from hpcflow.sdk import app
|
10
11
|
from hpcflow.sdk.core.utils import nth_key
|
11
12
|
from hpcflow.sdk.log import TimeIt
|
12
|
-
from hpcflow.sdk.core.cache import
|
13
|
+
from hpcflow.sdk.core.cache import ObjectCache
|
14
|
+
|
15
|
+
if TYPE_CHECKING:
|
16
|
+
from collections.abc import Mapping, Sequence
|
17
|
+
from typing_extensions import Self
|
18
|
+
from ..typing import DataIndex
|
19
|
+
from .loop import Loop
|
20
|
+
from .task import WorkflowTask
|
21
|
+
from .types import DependentDescriptor, ElementDescriptor
|
22
|
+
from .workflow import Workflow
|
23
|
+
|
24
|
+
K = TypeVar("K")
|
25
|
+
V = TypeVar("V")
|
26
|
+
|
27
|
+
|
28
|
+
class _LoopIndexError(TypeError):
|
29
|
+
"""
|
30
|
+
A type error special to loop indices.
|
31
|
+
"""
|
32
|
+
|
33
|
+
def __init__(self, loop_index: LoopIndex) -> None:
|
34
|
+
super().__init__(
|
35
|
+
f"{loop_index.__class__.__name__} does not support item assignment"
|
36
|
+
)
|
37
|
+
|
38
|
+
|
39
|
+
class LoopIndex(dict[K, V], Generic[K, V]):
|
40
|
+
"""
|
41
|
+
Hashable dict implementation, suitable for use as a key into
|
42
|
+
other dicts. Once used as a key, becomes immutable.
|
43
|
+
|
44
|
+
Example
|
45
|
+
-------
|
46
|
+
|
47
|
+
>>> h1 = LoopIndex({"apples": 1, "bananas":2})
|
48
|
+
>>> h2 = LoopIndex({"bananas": 3, "mangoes": 5})
|
49
|
+
>>> h1+h2
|
50
|
+
LoopIndex(apples=1, bananas=3, mangoes=5)
|
51
|
+
>>> d1 = {}
|
52
|
+
>>> d1[h1] = "salad"
|
53
|
+
>>> d1[h1]
|
54
|
+
'salad'
|
55
|
+
>>> d1[h2]
|
56
|
+
Traceback (most recent call last):
|
57
|
+
...
|
58
|
+
KeyError: LoopIndex(bananas=3, mangoes=5)
|
59
|
+
|
60
|
+
Notes
|
61
|
+
-----
|
62
|
+
* Based on answers from
|
63
|
+
http://stackoverflow.com/questions/1151658/python-hashable-dicts
|
64
|
+
* Assumes both keys and values are hashable. True in practice.
|
65
|
+
"""
|
66
|
+
|
67
|
+
def __init__(self, map: Mapping[K, V] | None = None) -> None:
|
68
|
+
"""
|
69
|
+
Make an instance from another dictionary.
|
70
|
+
This object will be mutable until it is used as a key.
|
71
|
+
"""
|
72
|
+
super().__init__(map or {})
|
73
|
+
self.__hash: int | None = None
|
74
|
+
|
75
|
+
def __repr__(self):
|
76
|
+
return f"""{self.__class__.__name__}({
|
77
|
+
', '.join(f'{k!r}={v!r}' for k, v in self.items())
|
78
|
+
})"""
|
79
|
+
|
80
|
+
def __hash__(self):
|
81
|
+
if self.__hash is None:
|
82
|
+
self.__hash = hash(frozenset(self.items()))
|
83
|
+
return self.__hash
|
84
|
+
|
85
|
+
def _validate_update(self) -> None:
|
86
|
+
if self.__hash is not None:
|
87
|
+
raise _LoopIndexError(self)
|
88
|
+
|
89
|
+
def __setitem__(self, key: K, value: V) -> None:
|
90
|
+
self._validate_update()
|
91
|
+
super().__setitem__(key, value)
|
92
|
+
|
93
|
+
def __delitem__(self, key: K) -> None:
|
94
|
+
self._validate_update()
|
95
|
+
super().__delitem__(key)
|
96
|
+
|
97
|
+
def clear(self) -> None:
|
98
|
+
self._validate_update()
|
99
|
+
super().clear()
|
100
|
+
|
101
|
+
def pop(self, *args, **kwargs) -> V:
|
102
|
+
self._validate_update()
|
103
|
+
return super().pop(*args, **kwargs)
|
104
|
+
|
105
|
+
def popitem(self) -> tuple[K, V]:
|
106
|
+
self._validate_update()
|
107
|
+
return super().popitem()
|
108
|
+
|
109
|
+
def setdefault(self, key: K, default: V) -> V:
|
110
|
+
self._validate_update()
|
111
|
+
return super().setdefault(key, default)
|
112
|
+
|
113
|
+
def update(self, *args, **kwargs) -> None:
|
114
|
+
self._validate_update()
|
115
|
+
super().update(*args, **kwargs)
|
116
|
+
|
117
|
+
def __add__(self, right: Mapping[K, V]) -> Self:
|
118
|
+
result = self.__class__(self)
|
119
|
+
result.update(right)
|
120
|
+
return result
|
13
121
|
|
14
122
|
|
15
123
|
@dataclass
|
@@ -40,97 +148,105 @@ class LoopCache:
|
|
40
148
|
task_iterations:
|
41
149
|
Keys are task insert IDs, values are list of all iteration IDs associated with
|
42
150
|
that task.
|
43
|
-
|
44
151
|
"""
|
45
152
|
|
46
153
|
#: Keys are element IDs, values are dicts whose keys are element IDs that depend on
|
47
154
|
#: the key element ID (via `Element.get_dependent_elements_recursively`), and whose
|
48
155
|
#: values are dicts with keys: `group_names`, which is a tuple of the string group
|
49
156
|
#: names associated with the dependent element's element set.
|
50
|
-
element_dependents:
|
157
|
+
element_dependents: dict[int, dict[int, DependentDescriptor]]
|
51
158
|
#: Keys are element IDs, values are dicts with keys: `input_statuses`,
|
52
159
|
#: `input_sources`, and `task_insert_ID`.
|
53
|
-
elements:
|
160
|
+
elements: dict[int, ElementDescriptor]
|
54
161
|
#: Keys are element IDs, values are data associated with the zeroth iteration of that
|
55
162
|
#: element, namely a tuple of iteration ID and `ElementIteration.data_idx`.
|
56
|
-
zeroth_iters:
|
163
|
+
zeroth_iters: dict[int, tuple[int, DataIndex]]
|
57
164
|
#: Keys are element IDs, values are data associated with all iterations of that
|
58
165
|
#: element, namely a dict whose keys are the iteration loop index as a tuple, and
|
59
166
|
#: whose values are data indices via `ElementIteration.get_data_idx()`.
|
60
|
-
data_idx:
|
167
|
+
data_idx: dict[int, dict[LoopIndex[str, int], DataIndex]]
|
61
168
|
#: Keys are iteration IDs, values are tuples of element ID and iteration index within
|
62
169
|
#: that element.
|
63
|
-
iterations:
|
170
|
+
iterations: dict[int, tuple[int, int]]
|
64
171
|
#: Keys are task insert IDs, values are list of all iteration IDs associated with
|
65
172
|
#: that task.
|
66
|
-
task_iterations:
|
173
|
+
task_iterations: dict[int, list[int]]
|
67
174
|
|
68
175
|
@TimeIt.decorator
|
69
|
-
def get_iter_IDs(self, loop:
|
176
|
+
def get_iter_IDs(self, loop: Loop) -> list[int]:
|
70
177
|
"""Retrieve a list of iteration IDs belonging to a given loop."""
|
71
|
-
return [
|
178
|
+
return [
|
179
|
+
i_id for t_id in loop.task_insert_IDs for i_id in self.task_iterations[t_id]
|
180
|
+
]
|
72
181
|
|
73
182
|
@TimeIt.decorator
|
74
|
-
def get_iter_loop_indices(self, iter_IDs:
|
183
|
+
def get_iter_loop_indices(self, iter_IDs: list[int]) -> Sequence[Mapping[str, int]]:
|
75
184
|
"""
|
76
185
|
Retrieve the mapping from element to loop index for each given iteration.
|
77
186
|
"""
|
78
|
-
iter_loop_idx = []
|
79
|
-
for
|
80
|
-
elem_id, idx = self.iterations[
|
81
|
-
iter_loop_idx.append(
|
187
|
+
iter_loop_idx: list[LoopIndex[str, int]] = []
|
188
|
+
for id_ in iter_IDs:
|
189
|
+
elem_id, idx = self.iterations[id_]
|
190
|
+
iter_loop_idx.append(nth_key(self.data_idx[elem_id], idx))
|
82
191
|
return iter_loop_idx
|
83
192
|
|
84
193
|
@TimeIt.decorator
|
85
|
-
def update_loop_indices(self, new_loop_name: str, iter_IDs:
|
194
|
+
def update_loop_indices(self, new_loop_name: str, iter_IDs: list[int]) -> None:
|
86
195
|
"""
|
87
196
|
Set the loop indices for a named loop to the given list of iteration IDs.
|
88
197
|
"""
|
89
|
-
elem_ids = {
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
new_item[tuple(sorted(new_k.items()))] = v
|
96
|
-
self.data_idx[i] = new_item
|
198
|
+
elem_ids = {e_ids[0] for k, e_ids in self.iterations.items() if k in iter_IDs}
|
199
|
+
new_loop_entry = {new_loop_name: 0}
|
200
|
+
for id_ in elem_ids:
|
201
|
+
self.data_idx[id_] = {
|
202
|
+
k + new_loop_entry: v for k, v in self.data_idx[id_].items()
|
203
|
+
}
|
97
204
|
|
98
205
|
@TimeIt.decorator
|
99
|
-
def add_iteration(
|
206
|
+
def add_iteration(
|
207
|
+
self,
|
208
|
+
iter_ID: int,
|
209
|
+
task_insert_ID: int,
|
210
|
+
element_ID: int,
|
211
|
+
loop_idx: LoopIndex[str, int],
|
212
|
+
data_idx: DataIndex,
|
213
|
+
):
|
100
214
|
"""Update the cache to include a newly added iteration."""
|
101
215
|
self.task_iterations[task_insert_ID].append(iter_ID)
|
102
216
|
new_iter_idx = len(self.data_idx[element_ID])
|
103
|
-
self.data_idx[element_ID][
|
217
|
+
self.data_idx[element_ID][loop_idx] = data_idx
|
104
218
|
self.iterations[iter_ID] = (element_ID, new_iter_idx)
|
105
219
|
|
106
220
|
@classmethod
|
107
221
|
@TimeIt.decorator
|
108
|
-
def build(cls, workflow:
|
222
|
+
def build(cls, workflow: Workflow, loops: list[Loop] | None = None) -> Self:
|
109
223
|
"""Build a cache of data for use in adding loops and iterations."""
|
110
224
|
|
111
|
-
deps_cache =
|
225
|
+
deps_cache = ObjectCache.build(workflow, dependencies=True, elements=True)
|
112
226
|
|
113
|
-
loops =
|
114
|
-
task_iIDs =
|
115
|
-
tasks = [
|
116
|
-
|
227
|
+
loops = [*workflow.template.loops, *(loops or ())]
|
228
|
+
task_iIDs = {t_id for loop in loops for t_id in loop.task_insert_IDs}
|
229
|
+
tasks: list[WorkflowTask] = [
|
230
|
+
workflow.tasks.get(insert_ID=t_id) for t_id in sorted(task_iIDs)
|
231
|
+
]
|
232
|
+
elem_deps: dict[int, dict[int, DependentDescriptor]] = {}
|
117
233
|
|
118
234
|
# keys: element IDs, values: dict with keys: tuple(loop_idx), values: data index
|
119
|
-
data_idx_cache = {}
|
235
|
+
data_idx_cache: dict[int, dict[LoopIndex[str, int], DataIndex]] = {}
|
120
236
|
|
121
237
|
# keys: iteration IDs, values: tuple of (element ID, integer index into values
|
122
238
|
# dict in `data_idx_cache` [accessed via `.keys()[index]`])
|
123
|
-
iters = {}
|
239
|
+
iters: dict[int, tuple[int, int]] = {}
|
124
240
|
|
125
241
|
# keys: element IDs, values: dict with keys: "input_statues", "input_sources",
|
126
242
|
# "task_insert_ID":
|
127
|
-
elements = {}
|
243
|
+
elements: dict[int, ElementDescriptor] = {}
|
128
244
|
|
129
|
-
zeroth_iters = {}
|
245
|
+
zeroth_iters: dict[int, tuple[int, DataIndex]] = {}
|
130
246
|
task_iterations = defaultdict(list)
|
131
247
|
for task in tasks:
|
132
|
-
for
|
133
|
-
element = deps_cache.elements[
|
248
|
+
for elem_id in task.element_IDs:
|
249
|
+
element = deps_cache.elements[elem_id]
|
134
250
|
inp_statuses = task.template.get_input_statuses(element.element_set)
|
135
251
|
elements[element.id_] = {
|
136
252
|
"input_statuses": inp_statuses,
|
@@ -138,28 +254,29 @@ class LoopCache:
|
|
138
254
|
"task_insert_ID": task.insert_ID,
|
139
255
|
}
|
140
256
|
elem_deps[element.id_] = {
|
141
|
-
|
257
|
+
de_id: {
|
142
258
|
"group_names": tuple(
|
143
|
-
|
259
|
+
grp.name
|
260
|
+
for grp in deps_cache.elements[de_id].element_set.groups
|
144
261
|
),
|
145
262
|
}
|
146
|
-
for
|
263
|
+
for de_id in deps_cache.elem_elem_dependents_rec[element.id_]
|
147
264
|
}
|
148
|
-
elem_iters = {}
|
265
|
+
elem_iters: dict[LoopIndex[str, int], DataIndex] = {}
|
149
266
|
for idx, iter_i in enumerate(element.iterations):
|
150
267
|
if idx == 0:
|
151
268
|
zeroth_iters[element.id_] = (iter_i.id_, iter_i.data_idx)
|
152
|
-
|
153
|
-
elem_iters[loop_idx_key] = iter_i.get_data_idx()
|
269
|
+
elem_iters[iter_i.loop_idx] = iter_i.get_data_idx()
|
154
270
|
task_iterations[task.insert_ID].append(iter_i.id_)
|
155
271
|
iters[iter_i.id_] = (element.id_, idx)
|
156
272
|
data_idx_cache[element.id_] = elem_iters
|
157
273
|
|
274
|
+
task_iterations.default_factory = None
|
158
275
|
return cls(
|
159
276
|
element_dependents=elem_deps,
|
160
277
|
elements=elements,
|
161
278
|
zeroth_iters=zeroth_iters,
|
162
279
|
data_idx=data_idx_cache,
|
163
280
|
iterations=iters,
|
164
|
-
task_iterations=
|
281
|
+
task_iterations=task_iterations,
|
165
282
|
)
|