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.
Files changed (118) hide show
  1. idmtools/__init__.py +27 -8
  2. idmtools/analysis/__init__.py +5 -0
  3. idmtools/analysis/add_analyzer.py +89 -0
  4. idmtools/analysis/analyze_manager.py +490 -0
  5. idmtools/analysis/csv_analyzer.py +103 -0
  6. idmtools/analysis/download_analyzer.py +96 -0
  7. idmtools/analysis/map_worker_entry.py +100 -0
  8. idmtools/analysis/platform_analysis_bootstrap.py +94 -0
  9. idmtools/analysis/platform_anaylsis.py +291 -0
  10. idmtools/analysis/tags_analyzer.py +93 -0
  11. idmtools/assets/__init__.py +9 -0
  12. idmtools/assets/asset.py +453 -0
  13. idmtools/assets/asset_collection.py +514 -0
  14. idmtools/assets/content_handlers.py +19 -0
  15. idmtools/assets/errors.py +23 -0
  16. idmtools/assets/file_list.py +191 -0
  17. idmtools/builders/__init__.py +11 -0
  18. idmtools/builders/arm_simulation_builder.py +152 -0
  19. idmtools/builders/csv_simulation_builder.py +76 -0
  20. idmtools/builders/simulation_builder.py +348 -0
  21. idmtools/builders/sweep_arm.py +109 -0
  22. idmtools/builders/yaml_simulation_builder.py +82 -0
  23. idmtools/config/__init__.py +7 -0
  24. idmtools/config/idm_config_parser.py +486 -0
  25. idmtools/core/__init__.py +10 -0
  26. idmtools/core/cache_enabled.py +114 -0
  27. idmtools/core/context.py +68 -0
  28. idmtools/core/docker_task.py +207 -0
  29. idmtools/core/enums.py +51 -0
  30. idmtools/core/exceptions.py +91 -0
  31. idmtools/core/experiment_factory.py +71 -0
  32. idmtools/core/id_file.py +70 -0
  33. idmtools/core/interfaces/__init__.py +5 -0
  34. idmtools/core/interfaces/entity_container.py +64 -0
  35. idmtools/core/interfaces/iassets_enabled.py +58 -0
  36. idmtools/core/interfaces/ientity.py +331 -0
  37. idmtools/core/interfaces/iitem.py +206 -0
  38. idmtools/core/interfaces/imetadata_operations.py +89 -0
  39. idmtools/core/interfaces/inamed_entity.py +17 -0
  40. idmtools/core/interfaces/irunnable_entity.py +159 -0
  41. idmtools/core/logging.py +387 -0
  42. idmtools/core/platform_factory.py +316 -0
  43. idmtools/core/system_information.py +104 -0
  44. idmtools/core/task_factory.py +145 -0
  45. idmtools/entities/__init__.py +10 -0
  46. idmtools/entities/command_line.py +229 -0
  47. idmtools/entities/command_task.py +155 -0
  48. idmtools/entities/experiment.py +787 -0
  49. idmtools/entities/generic_workitem.py +43 -0
  50. idmtools/entities/ianalyzer.py +163 -0
  51. idmtools/entities/iplatform.py +1106 -0
  52. idmtools/entities/iplatform_default.py +39 -0
  53. idmtools/entities/iplatform_ops/__init__.py +5 -0
  54. idmtools/entities/iplatform_ops/iplatform_asset_collection_operations.py +148 -0
  55. idmtools/entities/iplatform_ops/iplatform_experiment_operations.py +415 -0
  56. idmtools/entities/iplatform_ops/iplatform_simulation_operations.py +315 -0
  57. idmtools/entities/iplatform_ops/iplatform_suite_operations.py +322 -0
  58. idmtools/entities/iplatform_ops/iplatform_workflowitem_operations.py +301 -0
  59. idmtools/entities/iplatform_ops/utils.py +185 -0
  60. idmtools/entities/itask.py +316 -0
  61. idmtools/entities/iworkflow_item.py +167 -0
  62. idmtools/entities/platform_requirements.py +20 -0
  63. idmtools/entities/relation_type.py +14 -0
  64. idmtools/entities/simulation.py +255 -0
  65. idmtools/entities/suite.py +188 -0
  66. idmtools/entities/task_proxy.py +37 -0
  67. idmtools/entities/templated_simulation.py +325 -0
  68. idmtools/frozen/frozen_dict.py +71 -0
  69. idmtools/frozen/frozen_list.py +66 -0
  70. idmtools/frozen/frozen_set.py +86 -0
  71. idmtools/frozen/frozen_tuple.py +18 -0
  72. idmtools/frozen/frozen_utils.py +179 -0
  73. idmtools/frozen/ifrozen.py +66 -0
  74. idmtools/plugins/__init__.py +5 -0
  75. idmtools/plugins/git_commit.py +117 -0
  76. idmtools/registry/__init__.py +4 -0
  77. idmtools/registry/experiment_specification.py +105 -0
  78. idmtools/registry/functions.py +28 -0
  79. idmtools/registry/hook_specs.py +132 -0
  80. idmtools/registry/master_plugin_registry.py +51 -0
  81. idmtools/registry/platform_specification.py +138 -0
  82. idmtools/registry/plugin_specification.py +129 -0
  83. idmtools/registry/task_specification.py +104 -0
  84. idmtools/registry/utils.py +119 -0
  85. idmtools/services/__init__.py +5 -0
  86. idmtools/services/ipersistance_service.py +135 -0
  87. idmtools/services/platforms.py +13 -0
  88. idmtools/utils/__init__.py +5 -0
  89. idmtools/utils/caller.py +24 -0
  90. idmtools/utils/collections.py +246 -0
  91. idmtools/utils/command_line.py +45 -0
  92. idmtools/utils/decorators.py +300 -0
  93. idmtools/utils/display/__init__.py +22 -0
  94. idmtools/utils/display/displays.py +181 -0
  95. idmtools/utils/display/settings.py +25 -0
  96. idmtools/utils/dropbox_location.py +30 -0
  97. idmtools/utils/entities.py +127 -0
  98. idmtools/utils/file.py +72 -0
  99. idmtools/utils/file_parser.py +151 -0
  100. idmtools/utils/filter_simulations.py +182 -0
  101. idmtools/utils/filters/__init__.py +5 -0
  102. idmtools/utils/filters/asset_filters.py +88 -0
  103. idmtools/utils/general.py +286 -0
  104. idmtools/utils/gitrepo.py +336 -0
  105. idmtools/utils/hashing.py +239 -0
  106. idmtools/utils/info.py +124 -0
  107. idmtools/utils/json.py +82 -0
  108. idmtools/utils/language.py +107 -0
  109. idmtools/utils/local_os.py +40 -0
  110. idmtools/utils/time.py +22 -0
  111. idmtools-0.0.2.dist-info/METADATA +120 -0
  112. idmtools-0.0.2.dist-info/RECORD +116 -0
  113. idmtools-0.0.2.dist-info/entry_points.txt +9 -0
  114. idmtools-0.0.2.dist-info/licenses/LICENSE.TXT +3 -0
  115. idmtools-0.0.0.dev0.dist-info/METADATA +0 -41
  116. idmtools-0.0.0.dev0.dist-info/RECORD +0 -5
  117. {idmtools-0.0.0.dev0.dist-info → idmtools-0.0.2.dist-info}/WHEEL +0 -0
  118. {idmtools-0.0.0.dev0.dist-info → idmtools-0.0.2.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,255 @@
1
+ """
2
+ Defines our Simulation object.
3
+
4
+ The simulation object can be thought as a metadata object. It represents a configuration of a remote job execution metadata.
5
+ All simulations have a task. Optionally that have assets. All simulations should belong to an Experiment.
6
+
7
+ Copyright 2021, Bill & Melinda Gates Foundation. All rights reserved.
8
+ """
9
+ from dataclasses import dataclass, field, fields
10
+ from logging import getLogger, DEBUG
11
+ from typing import List, Union, Mapping, Any, Type, TypeVar, Dict, TYPE_CHECKING
12
+ from idmtools.assets import AssetCollection, Asset
13
+ from idmtools.core import ItemType, NoTaskFound
14
+ from idmtools.core.enums import EntityStatus
15
+ from idmtools.core.interfaces.iassets_enabled import IAssetsEnabled
16
+ from idmtools.core.interfaces.iitem import IItem
17
+ from idmtools.core.interfaces.inamed_entity import INamedEntity
18
+ from idmtools.entities.task_proxy import TaskProxy
19
+ from idmtools.utils.language import get_qualified_class_name_from_obj
20
+
21
+ if TYPE_CHECKING: # pragma: no cover
22
+ from idmtools.entities.itask import ITask
23
+ from idmtools.entities.iplatform import IPlatform
24
+ from idmtools.entities.experiment import Experiment
25
+
26
+ logger = getLogger(__name__)
27
+ user_logger = getLogger('user')
28
+
29
+
30
+ @dataclass
31
+ class Simulation(IAssetsEnabled, INamedEntity):
32
+ """
33
+ Class that represents a generic simulation.
34
+
35
+ This class needs to be implemented for each model type with specifics.
36
+ """
37
+ #: Experiment ID
38
+ experiment_id: str = field(default=None)
39
+ #: Task representing the configuration of the command to be executed
40
+ task: 'ITask' = field(default=None) # noqa: F821
41
+ #: Item Type. Should not be changed from Simulation
42
+ item_type: ItemType = field(default=ItemType.SIMULATION, compare=False)
43
+ #: Control whether we should replace the task with a proxy after creation
44
+ __replace_task_with_proxy: bool = field(default=True, init=False, compare=False)
45
+ #: Ensure we don't gather assets twice
46
+ __assets_gathered: bool = field(default=False)
47
+ #: Extra arguments to pass on creation to platform
48
+ _platform_kwargs: dict = field(default_factory=dict)
49
+
50
+ @property
51
+ def experiment(self) -> 'Experiment': # noqa: F821
52
+ """
53
+ Get experiment parent.
54
+
55
+ Returns:
56
+ Parent Experiment
57
+ """
58
+ return self.parent
59
+
60
+ @experiment.setter
61
+ def experiment(self, experiment: 'Experiment'): # noqa: F821
62
+ """
63
+ Set the parent experiment.
64
+
65
+ Args:
66
+ experiment: Experiment to set as parent.
67
+
68
+ Returns:
69
+ None
70
+ """
71
+ self.parent = experiment
72
+
73
+ @property
74
+ def parent(self):
75
+ """
76
+ Return parent object for item.
77
+
78
+ Returns:
79
+ Parent entity if set
80
+ """
81
+ if not self._parent:
82
+ self.parent_id = self.parent_id or self.experiment_id
83
+ if not self.parent_id:
84
+ return None
85
+ if not self.platform:
86
+ from idmtools.core import NoPlatformException
87
+ raise NoPlatformException("The object has no platform set...")
88
+ exp = self.platform.get_item(self.parent_id, ItemType.EXPERIMENT, force=True)
89
+ self._parent = exp
90
+ self.parent_id = self.suite_id = exp.id
91
+
92
+ return self._parent
93
+
94
+ @parent.setter
95
+ def parent(self, parent: 'Experiment'):
96
+ """
97
+ Sets the parent object for Entity.
98
+
99
+ Args:
100
+ parent: Parent object
101
+
102
+ Returns:
103
+ None
104
+ """
105
+ if parent is not None:
106
+ self._parent = parent
107
+ self.parent_id = self.suite_id = parent.id
108
+ else:
109
+ self._parent = self.parent_id = self.experiment_id = None
110
+
111
+ def __repr__(self):
112
+ """
113
+ String representation of simulation.
114
+ """
115
+ return f"<Simulation: {self.uid} - Exp_id: {self.parent_id}>"
116
+
117
+ def __hash__(self):
118
+ """
119
+ Hash of simulation(id).
120
+
121
+ Returns:
122
+ Hash of simulation
123
+ """
124
+ return id(self.uid)
125
+
126
+ def pre_creation(self, platform: 'IPlatform'):
127
+ """
128
+
129
+ Runs before a simulation is created server side.
130
+
131
+ Args:
132
+ platform: Platform the item is being executed on
133
+
134
+ Returns:
135
+ None
136
+ """
137
+ # skip the IItem created function
138
+ IItem.pre_creation(self, platform)
139
+ if self.task is None:
140
+ msg = 'Task is required for simulations'
141
+ user_logger.error(msg)
142
+ raise NoTaskFound(msg)
143
+
144
+ if logger.isEnabledFor(DEBUG):
145
+ logger.debug('Calling task pre creation')
146
+ self.task.pre_creation(self, platform)
147
+
148
+ self.gather_assets()
149
+
150
+ if self.__class__ is not Simulation:
151
+ # Add a tag to keep the Simulation class name
152
+ sn = get_qualified_class_name_from_obj(self)
153
+ if logger.isEnabledFor(DEBUG):
154
+ logger.debug(f'Setting Simulation Tag "simulation_type" to "{sn}"')
155
+ self.tags["simulation_type"] = sn
156
+
157
+ def post_creation(self, platform: 'IPlatform') -> None:
158
+ """
159
+ Called after a simulation is created.
160
+
161
+ Args:
162
+ platform: Platform simulation is being executed on
163
+
164
+ Returns:
165
+ None
166
+ """
167
+ if logger.isEnabledFor(DEBUG):
168
+ logger.debug('Calling task post creation')
169
+ if self.task is not None and not isinstance(self.task, TaskProxy):
170
+ self.task.post_creation(self, self.platform)
171
+
172
+ IItem.post_creation(self, platform)
173
+ if self.__replace_task_with_proxy or (self.parent and self.parent._Experiment__replace_task_with_proxy):
174
+ if logger.isEnabledFor(DEBUG):
175
+ logger.debug('Replacing task with proxy')
176
+ self.task = TaskProxy.from_task(self.task)
177
+ if self.status is None:
178
+ self.status = EntityStatus.CREATED
179
+ self.platform = platform
180
+
181
+ def pre_getstate(self):
182
+ """
183
+ Return default values for :meth:`pickle_ignore_fields`. Call before pickling.
184
+ """
185
+ from idmtools.assets import AssetCollection
186
+ from idmtools.core.interfaces.entity_container import EntityContainer
187
+ return {"assets": AssetCollection(), "simulations": EntityContainer()}
188
+
189
+ def gather_assets(self):
190
+ """
191
+ Gather all the assets for the simulation.
192
+ """
193
+ if not self.__assets_gathered:
194
+ self.task.gather_transient_assets()
195
+ self.assets.add_assets(self.task.transient_assets, fail_on_duplicate=False)
196
+ self.__assets_gathered = True
197
+
198
+ @classmethod
199
+ def from_task(cls, task: 'ITask', tags: Dict[str, Any] = None, # noqa E821
200
+ asset_collection: AssetCollection = None):
201
+ """
202
+ Create a simulation from a task.
203
+
204
+ Args:
205
+ task: Task to create from
206
+ tags: Tags to create on the simulation
207
+ asset_collection: Simulation Assets
208
+
209
+ Returns:
210
+ Simulation using the parameters provided
211
+ """
212
+ return Simulation(task=task, tags=dict() if tags is None else tags,
213
+ assets=asset_collection if asset_collection else AssetCollection())
214
+
215
+ def list_static_assets(self, platform: 'IPlatform' = None, **kwargs) -> List[Asset]:
216
+ """
217
+ List assets that have been uploaded to a server already.
218
+
219
+ Args:
220
+ platform: Optional platform to load assets list from
221
+ **kwargs:
222
+
223
+ Returns:
224
+ List of assets
225
+
226
+ Raises:
227
+ ValueError - If you try to list an assets for an simulation that hasn't been created/loaded from a remote platform.
228
+ """
229
+ if self.id is None:
230
+ raise ValueError("You can only list static assets on an existing experiment")
231
+ p = super()._check_for_platform_from_context(platform)
232
+ return p._simulations.list_assets(self, **kwargs)
233
+
234
+ def to_dict(self) -> Dict:
235
+ """
236
+ Do a lightweight conversation to json.
237
+
238
+ Returns:
239
+ Dict representing json of object
240
+ """
241
+ result = dict()
242
+ for f in fields(self):
243
+ if not f.name.startswith("_") and f.name not in ['parent']:
244
+ result[f.name] = getattr(self, f.name)
245
+ result['_uid'] = self.uid
246
+ result['task'] = self.task.to_dict() if self.task else None
247
+ return result
248
+
249
+
250
+ # TODO Rename to T simulation once old simulation is one
251
+ TTSimulation = TypeVar("TTSimulation", bound=Simulation)
252
+ TTSimulationClass = Type[TTSimulation]
253
+ TTSimulationBatch = List[TTSimulation]
254
+ TTAllSimulationData = Mapping[TTSimulation, Any]
255
+ TTSimulationList = List[Union[TTSimulation, str]]
@@ -0,0 +1,188 @@
1
+ """
2
+ Defines our Suite object.
3
+
4
+ The Suite object can be thought as a metadata object. It represents a container object for Experiments. All Suites should have one or more experiments.
5
+
6
+ Copyright 2021, Bill & Melinda Gates Foundation. All rights reserved.
7
+ """
8
+ from typing import NoReturn, Type, TYPE_CHECKING, Dict, List
9
+ from abc import ABC
10
+ from dataclasses import dataclass, field, fields
11
+ from idmtools.core.interfaces.iitem import IItem
12
+ from idmtools.core.interfaces.inamed_entity import INamedEntity
13
+ from idmtools.core import ItemType, EntityContainer
14
+ from idmtools.core.interfaces.irunnable_entity import IRunnableEntity
15
+
16
+ if TYPE_CHECKING: # pragma: no cover
17
+ from idmtools.entities.iplatform import IPlatform
18
+ from idmtools.entities.experiment import Experiment
19
+
20
+
21
+ @dataclass(repr=False)
22
+ class Suite(INamedEntity, ABC, IRunnableEntity):
23
+ """
24
+ Class that represents a generic suite (a collection of experiments).
25
+
26
+ Args:
27
+ experiments: The child items of this suite.
28
+ """
29
+ experiments: EntityContainer = field(
30
+ default_factory=lambda: EntityContainer(),
31
+ compare=False,
32
+ metadata={"pickle_ignore": True}
33
+ )
34
+
35
+ item_type: ItemType = field(default=ItemType.SUITE, compare=False, init=False)
36
+ description: str = field(default=None, compare=False)
37
+
38
+ def __post_init__(self):
39
+ """
40
+ Initialize Suite.
41
+ """
42
+ self.experiments = EntityContainer()
43
+
44
+ def add_experiment(self, experiment: 'Experiment') -> 'NoReturn': # noqa: F821
45
+ """
46
+ Add an experiment to the suite.
47
+
48
+ Args:
49
+ experiment: the experiment to be linked to suite
50
+ """
51
+ # Link the suite to the experiment. Assumes the experiment suite setter adds the experiment to the suite.
52
+ experiment._parent = self
53
+ experiment.parent_id = experiment.suite_id = self.id
54
+
55
+ ids = [exp.uid for exp in self.experiments]
56
+ if experiment.uid in ids:
57
+ return
58
+
59
+ # add experiment
60
+ self.experiments.append(experiment)
61
+
62
+ # clear possible directory cache for Experiment and Simulation
63
+ experiment.clear_directory_cache()
64
+
65
+ def display(self):
66
+ """
67
+ Display workflowitem.
68
+
69
+ Returns:
70
+ None
71
+ """
72
+ from idmtools.utils.display import display, suite_table_display
73
+ display(self, suite_table_display)
74
+
75
+ def pre_creation(self, platform: 'IPlatform'):
76
+ """
77
+ Pre Creation of IWorkflowItem.
78
+
79
+ Args:
80
+ platform: Platform we are creating item on
81
+
82
+ Returns:
83
+ None
84
+ """
85
+ IItem.pre_creation(self, platform)
86
+
87
+ def post_creation(self, platform: 'IPlatform'):
88
+ """
89
+ Post Creation of IWorkflowItem.
90
+
91
+ Args:
92
+ platform: Platform
93
+
94
+ Returns:
95
+ None
96
+ """
97
+ IItem.post_creation(self, platform)
98
+
99
+ def __repr__(self):
100
+ """
101
+ String representation of suite.
102
+ """
103
+ count = len(self.experiments) if self.experiments is not None else 0
104
+ return f"<Suite {self.uid} - {count} experiments>"
105
+
106
+ @property
107
+ def done(self):
108
+ """
109
+ Return if a suite has finished executing.
110
+
111
+ Returns:
112
+ True if all experiments have ran, False otherwise
113
+ """
114
+ return all([s.done for s in self.experiments])
115
+
116
+ @property
117
+ def succeeded(self) -> bool:
118
+ """
119
+ Return if a suite has succeeded. A suite is succeeded when all experiments have succeeded.
120
+
121
+ Returns:
122
+ True if all experiments have succeeded, False otherwise
123
+ """
124
+ return all([s.succeeded for s in self.experiments])
125
+
126
+ def to_dict(self) -> Dict:
127
+ """
128
+ Converts suite to a dictionary.
129
+
130
+ Returns:
131
+ Dictionary of suite.
132
+ """
133
+ result = dict()
134
+ for f in fields(self):
135
+ if not f.name.startswith("_") and f.name not in ['parent']:
136
+ result[f.name] = getattr(self, f.name)
137
+ result['_uid'] = self.uid
138
+ return result
139
+
140
+ def get_experiments(self) -> EntityContainer:
141
+ """
142
+ Retrieve the experiments associated with this suite from the platform.
143
+ Returns:
144
+ EntityContainer: A container of Experiment objects belonging to this suite.
145
+ """
146
+ experiments = self.experiments
147
+ if not experiments:
148
+ experiments = self.platform.get_children(self.id, ItemType.SUITE, force=True)
149
+ return experiments
150
+
151
+ def get_simulations_by_tags(self, tags=None, status=None, entity_type=False, skip_sims=None, max_simulations=None,
152
+ **kwargs) -> Dict[str, List[str]]:
153
+ """
154
+ Retrieve simulation ids or simulation objects with matching tags across all experiments in the suite.
155
+ This method filters simulations based on the provided tags, skipping specified simulations,
156
+ and limiting the number of results if `max_simulations` is set. The return type can be
157
+ either a dictionary of simulation IDs or simulation objects, depending on the `entity_type` flag.
158
+ Args:
159
+ status:
160
+ tags (dict, optional): A simulation's tags to filter by.
161
+ status (EntityStatus, Optional): Simulation status.
162
+ entity_type (bool, optional): If True, return simulation objects; otherwise, return simulation IDs. Defaults to False.
163
+ skip_sims (List[str], optional): A list of simulation IDs to exclude from the results.
164
+ max_simulations (int, optional): The maximum number of simulations to return per experiment.
165
+ **kwargs: Additional filter parameters.
166
+ Returns:
167
+ Dict[str, List[str]]: A dictionary where the keys are experiment IDs and the values are lists of
168
+ simulation IDs or simulation objects, depending on the `entity_type` flag.
169
+ """
170
+ experiments = self.get_experiments()
171
+ sims = {}
172
+ for experiment in experiments:
173
+ sims[experiment.id] = experiment.get_simulations_by_tags(tags=tags, status=status, entity_type=entity_type,
174
+ skip_sims=skip_sims,
175
+ max_simulations=max_simulations, **kwargs)
176
+ return sims
177
+
178
+ def __setstate__(self, state):
179
+ """
180
+ Add ignored fields back since they don't exist in the pickle.
181
+ """
182
+ # First call parent's __setstate__ to restore base attributes
183
+ super().__setstate__(state)
184
+ # Restore the pickle fields with values requested
185
+ self.experiments = EntityContainer()
186
+
187
+
188
+ ISuiteClass = Type[Suite]
@@ -0,0 +1,37 @@
1
+ """
2
+ Defines our TaskProxy object.
3
+
4
+ The TaskProxy object is mean to reduce the memory requirements of large simulation sets/configurations after provisioning. Instead of keeping the full original object in memory,
5
+ the object is replaced with a proxy object with minimal information needed to work with the task.
6
+
7
+ Copyright 2021, Bill & Melinda Gates Foundation. All rights reserved.
8
+ """
9
+ from typing import Union
10
+ from dataclasses import dataclass, field
11
+ from idmtools.entities import CommandLine
12
+
13
+
14
+ @dataclass
15
+ class TaskProxy:
16
+ """
17
+ This class is used to reduce the memory footprint of tasks after a simulation has been provisioned.
18
+ """
19
+ command: Union[str, CommandLine] = field(default=None)
20
+ is_docker: bool = False
21
+ is_gpu: bool = False
22
+
23
+ @staticmethod
24
+ def from_task(task: 'ITask'): # noqa: F821
25
+ """
26
+ Create a task proxy from a task.
27
+
28
+ Args:
29
+ task: Task to proxy
30
+
31
+ Returns:
32
+ TaskProxy of task
33
+ """
34
+ from idmtools.core.docker_task import DockerTask
35
+ is_docker = isinstance(task, DockerTask)
36
+ item = TaskProxy(command=task.command, is_docker=is_docker, is_gpu=is_docker and task.use_nvidia_run)
37
+ return item