idmtools 0.0.0.dev0__py3-none-any.whl → 0.0.2__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.
- idmtools/__init__.py +27 -8
- idmtools/analysis/__init__.py +5 -0
- idmtools/analysis/add_analyzer.py +89 -0
- idmtools/analysis/analyze_manager.py +490 -0
- idmtools/analysis/csv_analyzer.py +103 -0
- idmtools/analysis/download_analyzer.py +96 -0
- idmtools/analysis/map_worker_entry.py +100 -0
- idmtools/analysis/platform_analysis_bootstrap.py +94 -0
- idmtools/analysis/platform_anaylsis.py +291 -0
- idmtools/analysis/tags_analyzer.py +93 -0
- idmtools/assets/__init__.py +9 -0
- idmtools/assets/asset.py +453 -0
- idmtools/assets/asset_collection.py +514 -0
- idmtools/assets/content_handlers.py +19 -0
- idmtools/assets/errors.py +23 -0
- idmtools/assets/file_list.py +191 -0
- idmtools/builders/__init__.py +11 -0
- idmtools/builders/arm_simulation_builder.py +152 -0
- idmtools/builders/csv_simulation_builder.py +76 -0
- idmtools/builders/simulation_builder.py +348 -0
- idmtools/builders/sweep_arm.py +109 -0
- idmtools/builders/yaml_simulation_builder.py +82 -0
- idmtools/config/__init__.py +7 -0
- idmtools/config/idm_config_parser.py +486 -0
- idmtools/core/__init__.py +10 -0
- idmtools/core/cache_enabled.py +114 -0
- idmtools/core/context.py +68 -0
- idmtools/core/docker_task.py +207 -0
- idmtools/core/enums.py +51 -0
- idmtools/core/exceptions.py +91 -0
- idmtools/core/experiment_factory.py +71 -0
- idmtools/core/id_file.py +70 -0
- idmtools/core/interfaces/__init__.py +5 -0
- idmtools/core/interfaces/entity_container.py +64 -0
- idmtools/core/interfaces/iassets_enabled.py +58 -0
- idmtools/core/interfaces/ientity.py +331 -0
- idmtools/core/interfaces/iitem.py +206 -0
- idmtools/core/interfaces/imetadata_operations.py +89 -0
- idmtools/core/interfaces/inamed_entity.py +17 -0
- idmtools/core/interfaces/irunnable_entity.py +159 -0
- idmtools/core/logging.py +387 -0
- idmtools/core/platform_factory.py +316 -0
- idmtools/core/system_information.py +104 -0
- idmtools/core/task_factory.py +145 -0
- idmtools/entities/__init__.py +10 -0
- idmtools/entities/command_line.py +229 -0
- idmtools/entities/command_task.py +155 -0
- idmtools/entities/experiment.py +787 -0
- idmtools/entities/generic_workitem.py +43 -0
- idmtools/entities/ianalyzer.py +163 -0
- idmtools/entities/iplatform.py +1106 -0
- idmtools/entities/iplatform_default.py +39 -0
- idmtools/entities/iplatform_ops/__init__.py +5 -0
- idmtools/entities/iplatform_ops/iplatform_asset_collection_operations.py +148 -0
- idmtools/entities/iplatform_ops/iplatform_experiment_operations.py +415 -0
- idmtools/entities/iplatform_ops/iplatform_simulation_operations.py +315 -0
- idmtools/entities/iplatform_ops/iplatform_suite_operations.py +322 -0
- idmtools/entities/iplatform_ops/iplatform_workflowitem_operations.py +301 -0
- idmtools/entities/iplatform_ops/utils.py +185 -0
- idmtools/entities/itask.py +316 -0
- idmtools/entities/iworkflow_item.py +167 -0
- idmtools/entities/platform_requirements.py +20 -0
- idmtools/entities/relation_type.py +14 -0
- idmtools/entities/simulation.py +255 -0
- idmtools/entities/suite.py +188 -0
- idmtools/entities/task_proxy.py +37 -0
- idmtools/entities/templated_simulation.py +325 -0
- idmtools/frozen/frozen_dict.py +71 -0
- idmtools/frozen/frozen_list.py +66 -0
- idmtools/frozen/frozen_set.py +86 -0
- idmtools/frozen/frozen_tuple.py +18 -0
- idmtools/frozen/frozen_utils.py +179 -0
- idmtools/frozen/ifrozen.py +66 -0
- idmtools/plugins/__init__.py +5 -0
- idmtools/plugins/git_commit.py +117 -0
- idmtools/registry/__init__.py +4 -0
- idmtools/registry/experiment_specification.py +105 -0
- idmtools/registry/functions.py +28 -0
- idmtools/registry/hook_specs.py +132 -0
- idmtools/registry/master_plugin_registry.py +51 -0
- idmtools/registry/platform_specification.py +138 -0
- idmtools/registry/plugin_specification.py +129 -0
- idmtools/registry/task_specification.py +104 -0
- idmtools/registry/utils.py +119 -0
- idmtools/services/__init__.py +5 -0
- idmtools/services/ipersistance_service.py +135 -0
- idmtools/services/platforms.py +13 -0
- idmtools/utils/__init__.py +5 -0
- idmtools/utils/caller.py +24 -0
- idmtools/utils/collections.py +246 -0
- idmtools/utils/command_line.py +45 -0
- idmtools/utils/decorators.py +300 -0
- idmtools/utils/display/__init__.py +22 -0
- idmtools/utils/display/displays.py +181 -0
- idmtools/utils/display/settings.py +25 -0
- idmtools/utils/dropbox_location.py +30 -0
- idmtools/utils/entities.py +127 -0
- idmtools/utils/file.py +72 -0
- idmtools/utils/file_parser.py +151 -0
- idmtools/utils/filter_simulations.py +182 -0
- idmtools/utils/filters/__init__.py +5 -0
- idmtools/utils/filters/asset_filters.py +88 -0
- idmtools/utils/general.py +286 -0
- idmtools/utils/gitrepo.py +336 -0
- idmtools/utils/hashing.py +239 -0
- idmtools/utils/info.py +124 -0
- idmtools/utils/json.py +82 -0
- idmtools/utils/language.py +107 -0
- idmtools/utils/local_os.py +40 -0
- idmtools/utils/time.py +22 -0
- idmtools-0.0.2.dist-info/METADATA +120 -0
- idmtools-0.0.2.dist-info/RECORD +116 -0
- idmtools-0.0.2.dist-info/entry_points.txt +9 -0
- idmtools-0.0.2.dist-info/licenses/LICENSE.TXT +3 -0
- idmtools-0.0.0.dev0.dist-info/METADATA +0 -41
- idmtools-0.0.0.dev0.dist-info/RECORD +0 -5
- {idmtools-0.0.0.dev0.dist-info → idmtools-0.0.2.dist-info}/WHEEL +0 -0
- {idmtools-0.0.0.dev0.dist-info → idmtools-0.0.2.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Defines our ITask interface.
|
|
3
|
+
|
|
4
|
+
Copyright 2021, Bill & Melinda Gates Foundation. All rights reserved.
|
|
5
|
+
"""
|
|
6
|
+
import copy
|
|
7
|
+
from abc import ABCMeta, abstractmethod
|
|
8
|
+
from dataclasses import dataclass, field, fields
|
|
9
|
+
from logging import getLogger
|
|
10
|
+
from typing import Set, NoReturn, Union, Callable, List, TYPE_CHECKING, Dict
|
|
11
|
+
from idmtools.assets import AssetCollection
|
|
12
|
+
from idmtools.entities.command_line import CommandLine
|
|
13
|
+
from idmtools.entities.platform_requirements import PlatformRequirements
|
|
14
|
+
from idmtools.utils.hashing import ignore_fields_in_dataclass_on_pickle
|
|
15
|
+
from inspect import signature
|
|
16
|
+
|
|
17
|
+
logger = getLogger(__name__)
|
|
18
|
+
# Tasks can be allocated multiple ways
|
|
19
|
+
# They can be used in Experiments as the description of the item to run within a Simulation
|
|
20
|
+
# They can also be used in Workflows to run items
|
|
21
|
+
# When used in experiments, it is triggered in the steps
|
|
22
|
+
# 1. Create Suite(If Suite)
|
|
23
|
+
# a) Pre-Creation hooks
|
|
24
|
+
|
|
25
|
+
if TYPE_CHECKING: # pragma: no cover
|
|
26
|
+
from idmtools.entities.iplatform import IPlatform
|
|
27
|
+
from idmtools.entities.simulation import Simulation
|
|
28
|
+
from idmtools.entities.iworkflow_item import IWorkflowItem # noqa: F401
|
|
29
|
+
|
|
30
|
+
TTaskParent = Union['Simulation', 'IWorkflowItem'] # noqa: F821
|
|
31
|
+
TTaskHook = Callable[[TTaskParent, 'IPlatform'], NoReturn]
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
@dataclass
|
|
35
|
+
class ITask(metaclass=ABCMeta):
|
|
36
|
+
"""
|
|
37
|
+
ITask represents a task to be ran on a remote system.
|
|
38
|
+
|
|
39
|
+
A Task should provide all the files and command needed to run remotely.
|
|
40
|
+
"""
|
|
41
|
+
#: The Command to run
|
|
42
|
+
command: Union[str, CommandLine] = field(default=None, metadata={"md": True})
|
|
43
|
+
#: List of requirements needed by the task to run on an execution platform. This is stuff like Windows, Linux, GPU
|
|
44
|
+
# etc
|
|
45
|
+
platform_requirements: Set[PlatformRequirements] = field(default_factory=set)
|
|
46
|
+
|
|
47
|
+
#: We provide hooks as list to allow more user scripting extensibility
|
|
48
|
+
__pre_creation_hooks: List[TTaskHook] = field(default_factory=list)
|
|
49
|
+
__post_creation_hooks: List[TTaskHook] = field(default_factory=list)
|
|
50
|
+
# This is optional experiment assets
|
|
51
|
+
# That means that users can explicitly define experiment level assets when using a Experiment builders
|
|
52
|
+
#: Common(Experiment-level) assets
|
|
53
|
+
common_assets: AssetCollection = field(default_factory=AssetCollection)
|
|
54
|
+
#: Transient(Simulation-level) assets
|
|
55
|
+
transient_assets: AssetCollection = field(default_factory=AssetCollection)
|
|
56
|
+
|
|
57
|
+
def __post_init__(self):
|
|
58
|
+
"""
|
|
59
|
+
Post Creation.
|
|
60
|
+
|
|
61
|
+
Returns:
|
|
62
|
+
None
|
|
63
|
+
"""
|
|
64
|
+
self.__pre_creation_hooks = []
|
|
65
|
+
self.__post_creation_hooks = []
|
|
66
|
+
|
|
67
|
+
@property
|
|
68
|
+
def command(self): # noqa: F811
|
|
69
|
+
"""
|
|
70
|
+
Get the command line.
|
|
71
|
+
|
|
72
|
+
Returns:
|
|
73
|
+
Commnad Line
|
|
74
|
+
"""
|
|
75
|
+
return self._command
|
|
76
|
+
|
|
77
|
+
@command.setter
|
|
78
|
+
def command(self, value: Union[str, CommandLine]):
|
|
79
|
+
"""
|
|
80
|
+
Set the command on the Task.
|
|
81
|
+
|
|
82
|
+
Command to be a string or CommandLine object. If it is a string, it will be converted to CommandLine
|
|
83
|
+
|
|
84
|
+
Args:
|
|
85
|
+
value: Value to set
|
|
86
|
+
|
|
87
|
+
Returns:
|
|
88
|
+
None
|
|
89
|
+
"""
|
|
90
|
+
if isinstance(value, property):
|
|
91
|
+
self._command = None
|
|
92
|
+
elif isinstance(value, str):
|
|
93
|
+
self._command = CommandLine.from_string(value)
|
|
94
|
+
else:
|
|
95
|
+
self._command = value
|
|
96
|
+
|
|
97
|
+
@property
|
|
98
|
+
def metadata_fields(self):
|
|
99
|
+
"""
|
|
100
|
+
Collect all metadata fields.
|
|
101
|
+
|
|
102
|
+
Returns: set of metadata filed names
|
|
103
|
+
"""
|
|
104
|
+
return set(f.name for f in fields(self) if "md" in f.metadata and f.metadata["md"])
|
|
105
|
+
|
|
106
|
+
def add_pre_creation_hook(self, hook: TTaskHook):
|
|
107
|
+
"""
|
|
108
|
+
Called before a simulation is created on a platform. Each hook receives either a Simulation or WorkflowTask.
|
|
109
|
+
|
|
110
|
+
Args:
|
|
111
|
+
hook: Function to call on event
|
|
112
|
+
|
|
113
|
+
Returns:
|
|
114
|
+
None
|
|
115
|
+
"""
|
|
116
|
+
if len(signature(hook).parameters) != 2:
|
|
117
|
+
raise ValueError("Pre creation hooks should have 2 arguments. The first argument will be the item, the second the platform")
|
|
118
|
+
self.__pre_creation_hooks.append(hook)
|
|
119
|
+
|
|
120
|
+
def add_post_creation_hook(self, hook: TTaskHook):
|
|
121
|
+
"""
|
|
122
|
+
Called after a simulation has been created on a platform. Each hook receives either a Simulation or WorkflowTask.
|
|
123
|
+
|
|
124
|
+
Args:
|
|
125
|
+
hook: Function to call on event
|
|
126
|
+
|
|
127
|
+
Returns:
|
|
128
|
+
None
|
|
129
|
+
"""
|
|
130
|
+
if len(signature(hook).parameters) != 2:
|
|
131
|
+
raise ValueError("Post creation hooks should have 2 arguments. The first argument will be the item, the second the platform")
|
|
132
|
+
self.__post_creation_hooks.append(hook)
|
|
133
|
+
|
|
134
|
+
def add_platform_requirement(self, requirement: Union[PlatformRequirements, str]) -> NoReturn:
|
|
135
|
+
"""
|
|
136
|
+
Adds a platform requirements to a task.
|
|
137
|
+
|
|
138
|
+
Args:
|
|
139
|
+
requirement: Requirement to add task
|
|
140
|
+
|
|
141
|
+
Returns:
|
|
142
|
+
None
|
|
143
|
+
"""
|
|
144
|
+
if isinstance(requirement, str):
|
|
145
|
+
requirement = PlatformRequirements[requirement.lower()]
|
|
146
|
+
self.platform_requirements.add(requirement)
|
|
147
|
+
|
|
148
|
+
def pre_creation(self, parent: Union['Simulation', 'IWorkflowItem'], platform: 'IPlatform'): # noqa: F821
|
|
149
|
+
"""
|
|
150
|
+
Optional Hook called at the time of creation of task. Can be used to setup simulation and experiment level hooks.
|
|
151
|
+
|
|
152
|
+
Args:
|
|
153
|
+
parent: Parent of Item
|
|
154
|
+
platform: Platform executing the task. Useful for querying platform before execution
|
|
155
|
+
|
|
156
|
+
Returns:
|
|
157
|
+
None
|
|
158
|
+
"""
|
|
159
|
+
if self.command is None:
|
|
160
|
+
logger.error('Command is not defined')
|
|
161
|
+
raise ValueError("Command is required for on task when preparing an experiment")
|
|
162
|
+
if platform.is_windows_platform(parent):
|
|
163
|
+
self.command.is_windows = True
|
|
164
|
+
[hook(parent, platform) for hook in self.__pre_creation_hooks]
|
|
165
|
+
|
|
166
|
+
def post_creation(self, parent: Union['Simulation', 'IWorkflowItem'], platform: 'IPlatform'): # noqa: F821
|
|
167
|
+
"""
|
|
168
|
+
Optional Hook called at the after creation task. Can be used to setup simulation and experiment level hooks.
|
|
169
|
+
|
|
170
|
+
Args:
|
|
171
|
+
parent: Parent of Item
|
|
172
|
+
platform: Platform executing the task. Useful for querying platform before execution
|
|
173
|
+
|
|
174
|
+
Returns:
|
|
175
|
+
None
|
|
176
|
+
"""
|
|
177
|
+
[hook(parent, platform) for hook in self.__post_creation_hooks]
|
|
178
|
+
|
|
179
|
+
@abstractmethod
|
|
180
|
+
def gather_common_assets(self) -> AssetCollection:
|
|
181
|
+
"""
|
|
182
|
+
Function called at runtime to gather all assets in the collection.
|
|
183
|
+
"""
|
|
184
|
+
pass
|
|
185
|
+
|
|
186
|
+
@abstractmethod
|
|
187
|
+
def gather_transient_assets(self) -> AssetCollection:
|
|
188
|
+
"""
|
|
189
|
+
Function called at runtime to gather all assets in the collection.
|
|
190
|
+
"""
|
|
191
|
+
pass
|
|
192
|
+
|
|
193
|
+
def gather_all_assets(self) -> AssetCollection:
|
|
194
|
+
"""
|
|
195
|
+
Collect all common and transient assets.
|
|
196
|
+
|
|
197
|
+
Returns: new AssetCollection
|
|
198
|
+
"""
|
|
199
|
+
return self.gather_common_assets() + self.gather_transient_assets()
|
|
200
|
+
|
|
201
|
+
def copy_simulation(self, base_simulation: 'Simulation') -> 'Simulation':
|
|
202
|
+
"""
|
|
203
|
+
Called when copying a simulation for batching. Override you your task has specific concerns when copying simulations.
|
|
204
|
+
"""
|
|
205
|
+
new_simulation = copy.deepcopy(base_simulation)
|
|
206
|
+
return new_simulation
|
|
207
|
+
|
|
208
|
+
def reload_from_simulation(self, simulation: 'Simulation'):
|
|
209
|
+
"""
|
|
210
|
+
Optional hook that is called when loading simulations from a platform.
|
|
211
|
+
"""
|
|
212
|
+
raise NotImplementedError("Reloading task from a simulation is not supported")
|
|
213
|
+
|
|
214
|
+
def to_simulation(self):
|
|
215
|
+
"""
|
|
216
|
+
Convert task to simulation.
|
|
217
|
+
|
|
218
|
+
Returns: new simulation
|
|
219
|
+
"""
|
|
220
|
+
from idmtools.entities.simulation import Simulation
|
|
221
|
+
s = Simulation()
|
|
222
|
+
s.task = self
|
|
223
|
+
return s
|
|
224
|
+
|
|
225
|
+
def __repr__(self):
|
|
226
|
+
"""
|
|
227
|
+
Representation as a string.
|
|
228
|
+
|
|
229
|
+
Returns:
|
|
230
|
+
Represetnation as string
|
|
231
|
+
"""
|
|
232
|
+
return f"<{self.__class__.__name__}"
|
|
233
|
+
|
|
234
|
+
def pre_getstate(self):
|
|
235
|
+
"""
|
|
236
|
+
Return default values for :meth:`~idmtools.interfaces.ientity.pickle_ignore_fields`.
|
|
237
|
+
|
|
238
|
+
Call before pickling.
|
|
239
|
+
|
|
240
|
+
Returns: dict
|
|
241
|
+
"""
|
|
242
|
+
pass
|
|
243
|
+
|
|
244
|
+
def post_setstate(self):
|
|
245
|
+
"""Post load from pickle."""
|
|
246
|
+
pass
|
|
247
|
+
|
|
248
|
+
@property
|
|
249
|
+
def pickle_ignore_fields(self):
|
|
250
|
+
"""
|
|
251
|
+
Pickle ignore fields.
|
|
252
|
+
|
|
253
|
+
Returns:
|
|
254
|
+
List of fields to ignore
|
|
255
|
+
"""
|
|
256
|
+
return set(f.name for f in fields(self) if "pickle_ignore" in f.metadata and f.metadata["pickle_ignore"])
|
|
257
|
+
|
|
258
|
+
def __getstate__(self):
|
|
259
|
+
"""
|
|
260
|
+
Ignore the fields in pickle_ignore_fields during pickling.
|
|
261
|
+
|
|
262
|
+
Returns: fields set after removing ignored fields
|
|
263
|
+
"""
|
|
264
|
+
return ignore_fields_in_dataclass_on_pickle(self)
|
|
265
|
+
|
|
266
|
+
def __setstate__(self, state):
|
|
267
|
+
"""
|
|
268
|
+
Add ignored fields back since they don't exist in the pickle.
|
|
269
|
+
"""
|
|
270
|
+
self.__dict__.update(state)
|
|
271
|
+
|
|
272
|
+
def __deepcopy__(self, memo):
|
|
273
|
+
"""
|
|
274
|
+
Deepcopy of a task.
|
|
275
|
+
|
|
276
|
+
Args:
|
|
277
|
+
memo: Object to deepcopy
|
|
278
|
+
|
|
279
|
+
Returns:
|
|
280
|
+
Deep copied item
|
|
281
|
+
"""
|
|
282
|
+
cls = self.__class__
|
|
283
|
+
result = cls.__new__(cls)
|
|
284
|
+
memo[id(self)] = result
|
|
285
|
+
for k, v in self.__dict__.items():
|
|
286
|
+
if k not in ['_task_log', 'common_assets']:
|
|
287
|
+
setattr(result, k, copy.deepcopy(v, memo))
|
|
288
|
+
elif k == 'common_assets':
|
|
289
|
+
setattr(result, k, v)
|
|
290
|
+
return result
|
|
291
|
+
|
|
292
|
+
def to_dict(self) -> Dict:
|
|
293
|
+
"""
|
|
294
|
+
Select metadata fields and make a new dict.
|
|
295
|
+
|
|
296
|
+
Returns: dict
|
|
297
|
+
"""
|
|
298
|
+
from idmtools.core.context import get_current_platform
|
|
299
|
+
|
|
300
|
+
result = dict()
|
|
301
|
+
metadata_fields = self.metadata_fields
|
|
302
|
+
platform = get_current_platform()
|
|
303
|
+
for f in fields(self):
|
|
304
|
+
if not f.name.startswith("_") and f.name not in ['parent']:
|
|
305
|
+
try:
|
|
306
|
+
from idmtools_platform_comps.comps_platform import COMPSPlatform
|
|
307
|
+
if isinstance(platform, COMPSPlatform):
|
|
308
|
+
if f.name in metadata_fields:
|
|
309
|
+
result[f.name] = getattr(self, f.name)
|
|
310
|
+
else:
|
|
311
|
+
result[f.name] = f.default
|
|
312
|
+
else:
|
|
313
|
+
result[f.name] = getattr(self, f.name)
|
|
314
|
+
except ImportError:
|
|
315
|
+
result[f.name] = getattr(self, f.name)
|
|
316
|
+
return result
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Defines our IWorkflowItem interface.
|
|
3
|
+
|
|
4
|
+
Copyright 2021, Bill & Melinda Gates Foundation. All rights reserved.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import warnings
|
|
8
|
+
from abc import ABC
|
|
9
|
+
from dataclasses import dataclass, field, fields, InitVar
|
|
10
|
+
from typing import NoReturn, Dict, Any, TYPE_CHECKING
|
|
11
|
+
from idmtools.assets import AssetCollection
|
|
12
|
+
from idmtools.assets.file_list import FileList
|
|
13
|
+
from idmtools.core import ItemType
|
|
14
|
+
from idmtools.core.interfaces.iassets_enabled import IAssetsEnabled
|
|
15
|
+
from idmtools.core.interfaces.inamed_entity import INamedEntity
|
|
16
|
+
from idmtools.core.interfaces.irunnable_entity import IRunnableEntity
|
|
17
|
+
from idmtools.entities.itask import ITask
|
|
18
|
+
|
|
19
|
+
if TYPE_CHECKING: # pragma: no cover
|
|
20
|
+
from idmtools.entities.iplatform import IPlatform
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
@dataclass
|
|
24
|
+
class IWorkflowItem(IAssetsEnabled, INamedEntity, IRunnableEntity, ABC):
|
|
25
|
+
"""
|
|
26
|
+
Interface of idmtools work item.
|
|
27
|
+
"""
|
|
28
|
+
|
|
29
|
+
#: Name of the workflow step
|
|
30
|
+
name: str = field(default=None)
|
|
31
|
+
|
|
32
|
+
#: Legacy name for workflow items
|
|
33
|
+
item_name: InitVar[str] = None
|
|
34
|
+
#: Legacy name. Set assets now
|
|
35
|
+
asset_collection_id: InitVar[str] = None
|
|
36
|
+
#: Tags associated with the work item
|
|
37
|
+
tags: Dict[str, Any] = field(default_factory=lambda: {})
|
|
38
|
+
#: Common Assets for the workitem
|
|
39
|
+
transient_assets: AssetCollection = field(default_factory=AssetCollection)
|
|
40
|
+
#: Legacy var. Going forward use assets
|
|
41
|
+
asset_files: InitVar[FileList] = None
|
|
42
|
+
#: Legacy var. Going forward use assets
|
|
43
|
+
user_files: InitVar[FileList] = None
|
|
44
|
+
# Task for object. All workflow items must implement by 1.7.0
|
|
45
|
+
task: ITask = field(default=None)
|
|
46
|
+
|
|
47
|
+
related_experiments: list = field(default_factory=list)
|
|
48
|
+
related_simulations: list = field(default_factory=list)
|
|
49
|
+
related_suites: list = field(default_factory=list)
|
|
50
|
+
related_work_items: list = field(default_factory=list)
|
|
51
|
+
related_asset_collections: list = field(default_factory=list)
|
|
52
|
+
work_item_type: str = field(default=None)
|
|
53
|
+
|
|
54
|
+
item_type: 'ItemType' = field(default=ItemType.WORKFLOW_ITEM, compare=False, init=False)
|
|
55
|
+
|
|
56
|
+
def __post_init__(self, item_name: str, asset_collection_id: str, asset_files: FileList, user_files: FileList):
|
|
57
|
+
"""
|
|
58
|
+
Constructor.
|
|
59
|
+
|
|
60
|
+
Args:
|
|
61
|
+
item_name: Item name
|
|
62
|
+
asset_collection_id: AssetCollectionId
|
|
63
|
+
asset_files: AssetFiles
|
|
64
|
+
user_files: UserFiles
|
|
65
|
+
|
|
66
|
+
Returns:
|
|
67
|
+
None
|
|
68
|
+
"""
|
|
69
|
+
if item_name is not None and not isinstance(item_name, property):
|
|
70
|
+
self.name = item_name
|
|
71
|
+
|
|
72
|
+
if user_files and not isinstance(user_files, property):
|
|
73
|
+
# user property since it can convert file lists
|
|
74
|
+
self.user_files = user_files
|
|
75
|
+
|
|
76
|
+
if asset_files and not isinstance(asset_files, property):
|
|
77
|
+
# user property since it can convert file lists
|
|
78
|
+
self.asset_files = asset_files
|
|
79
|
+
|
|
80
|
+
if asset_collection_id and not isinstance(asset_collection_id, property):
|
|
81
|
+
# user property since it will inform user of changes
|
|
82
|
+
self.asset_collection_id = asset_collection_id
|
|
83
|
+
|
|
84
|
+
if self.task is None:
|
|
85
|
+
warnings.warn("In 1.7.0, all work items require a Task")
|
|
86
|
+
|
|
87
|
+
self.tags = self.tags or dict()
|
|
88
|
+
|
|
89
|
+
def __repr__(self):
|
|
90
|
+
"""
|
|
91
|
+
String representation of workflow items.
|
|
92
|
+
"""
|
|
93
|
+
return f"<WorkItem {self.uid}>"
|
|
94
|
+
|
|
95
|
+
def gather_assets(self) -> NoReturn:
|
|
96
|
+
"""
|
|
97
|
+
Function called at runtime to gather all assets in the collection.
|
|
98
|
+
"""
|
|
99
|
+
pass
|
|
100
|
+
|
|
101
|
+
def add_file(self, af):
|
|
102
|
+
"""
|
|
103
|
+
Methods used to add new file.
|
|
104
|
+
|
|
105
|
+
Args:
|
|
106
|
+
af: file to add
|
|
107
|
+
|
|
108
|
+
Returns: None
|
|
109
|
+
"""
|
|
110
|
+
self.user_files.add_asset_file(af)
|
|
111
|
+
|
|
112
|
+
def clear_user_files(self):
|
|
113
|
+
"""
|
|
114
|
+
Clear all existing user files.
|
|
115
|
+
|
|
116
|
+
Returns: None
|
|
117
|
+
"""
|
|
118
|
+
self.transient_assets.clear()
|
|
119
|
+
|
|
120
|
+
def pre_creation(self, platform: 'IPlatform') -> None:
|
|
121
|
+
"""
|
|
122
|
+
Called before the actual creation of the entity.
|
|
123
|
+
"""
|
|
124
|
+
if self.name is None:
|
|
125
|
+
raise ValueError("Name is required")
|
|
126
|
+
files_to_be_removed = ('comps_log.log', 'idmtools.log')
|
|
127
|
+
super().pre_creation(platform)
|
|
128
|
+
if self.task:
|
|
129
|
+
self.task.pre_creation(self, platform)
|
|
130
|
+
self.assets.add_assets(self.task.common_assets)
|
|
131
|
+
self.transient_assets.add_assets(self.task.transient_assets)
|
|
132
|
+
self.transient_assets.files = [f for f in self.transient_assets.assets if f.filename.lower() not in files_to_be_removed]
|
|
133
|
+
|
|
134
|
+
def __check_for_platform(self, platform: 'IPlatform'): # noqa: F821
|
|
135
|
+
"""
|
|
136
|
+
Check for platform. If platform is non, we try to load the current platform instead.
|
|
137
|
+
|
|
138
|
+
Args:
|
|
139
|
+
platform: Platform that can be pre-defined.
|
|
140
|
+
|
|
141
|
+
Returns:
|
|
142
|
+
None
|
|
143
|
+
|
|
144
|
+
Raises:
|
|
145
|
+
ValueError - If platform cannot be found
|
|
146
|
+
"""
|
|
147
|
+
from idmtools.core.context import CURRENT_PLATFORM
|
|
148
|
+
if platform is not None:
|
|
149
|
+
self.platform = platform
|
|
150
|
+
if self.platform is None:
|
|
151
|
+
if CURRENT_PLATFORM is None:
|
|
152
|
+
raise ValueError("Platform is required to run item")
|
|
153
|
+
self.platform = CURRENT_PLATFORM
|
|
154
|
+
|
|
155
|
+
def to_dict(self) -> Dict:
|
|
156
|
+
"""
|
|
157
|
+
Convert IWorkflowItem to a dictionary.
|
|
158
|
+
|
|
159
|
+
Returns:
|
|
160
|
+
Dictionary of WorkflowItem
|
|
161
|
+
"""
|
|
162
|
+
result = dict()
|
|
163
|
+
for f in fields(self):
|
|
164
|
+
if not f.name.startswith("_") and f.name not in ['parent']:
|
|
165
|
+
result[f.name] = getattr(self, f.name)
|
|
166
|
+
result['_uid'] = self.uid
|
|
167
|
+
return result
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Defines our PlatformRequirements enum.
|
|
3
|
+
|
|
4
|
+
Copyright 2021, Bill & Melinda Gates Foundation. All rights reserved.
|
|
5
|
+
"""
|
|
6
|
+
from enum import Enum
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class PlatformRequirements(Enum):
|
|
10
|
+
"""
|
|
11
|
+
Defines possible requirements a task could need from a platform.
|
|
12
|
+
"""
|
|
13
|
+
SHELL = "shell" # Shell commands like ls -al
|
|
14
|
+
NativeBinary = "NativeBinary" # Run a user-provided binary
|
|
15
|
+
LINUX = "Linux" # Linux only binaries
|
|
16
|
+
WINDOWS = "windows" # windows only binaries
|
|
17
|
+
GPU = "gpu" # GPU support
|
|
18
|
+
PYTHON = "python" # Python(on host) commands
|
|
19
|
+
DOCKER = "docker" # Can you run docker commands
|
|
20
|
+
SINGULARITY = "singularity"
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Defines our RelationType enum.
|
|
3
|
+
|
|
4
|
+
Copyright 2021, Bill & Melinda Gates Foundation. All rights reserved.
|
|
5
|
+
"""
|
|
6
|
+
from enum import Enum
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class RelationType(Enum):
|
|
10
|
+
"""
|
|
11
|
+
An enumeration representing the type of relationship for related entities.
|
|
12
|
+
"""
|
|
13
|
+
DependsOn = 0
|
|
14
|
+
Created = 1
|