experimaestro 2.0.0a4__py3-none-any.whl → 2.0.0a6__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.
Potentially problematic release.
This version of experimaestro might be problematic. Click here for more details.
- experimaestro/core/identifier.py +10 -5
- experimaestro/core/objects/config.py +18 -170
- experimaestro/core/objects/config_walk.py +1 -5
- experimaestro/core/objects.pyi +2 -6
- experimaestro/core/serializers.py +1 -8
- experimaestro/tests/test_dependencies.py +0 -6
- experimaestro/tests/test_identifier.py +77 -66
- experimaestro/tests/test_instance.py +0 -12
- experimaestro/tests/test_serializers.py +0 -59
- experimaestro/tests/test_tasks.py +0 -20
- {experimaestro-2.0.0a4.dist-info → experimaestro-2.0.0a6.dist-info}/METADATA +1 -1
- {experimaestro-2.0.0a4.dist-info → experimaestro-2.0.0a6.dist-info}/RECORD +15 -15
- {experimaestro-2.0.0a4.dist-info → experimaestro-2.0.0a6.dist-info}/WHEEL +0 -0
- {experimaestro-2.0.0a4.dist-info → experimaestro-2.0.0a6.dist-info}/entry_points.txt +0 -0
- {experimaestro-2.0.0a4.dist-info → experimaestro-2.0.0a6.dist-info}/licenses/LICENSE +0 -0
experimaestro/core/identifier.py
CHANGED
|
@@ -6,7 +6,7 @@ import logging
|
|
|
6
6
|
import os
|
|
7
7
|
import struct
|
|
8
8
|
from typing import Optional
|
|
9
|
-
from experimaestro.core.objects import Config
|
|
9
|
+
from experimaestro.core.objects import Config, ConfigMixin
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
class ConfigPath:
|
|
@@ -116,7 +116,7 @@ class IdentifierComputer:
|
|
|
116
116
|
CYCLE_REFERENCE = b"\x0b"
|
|
117
117
|
INIT_TASKS = b"\x0c"
|
|
118
118
|
|
|
119
|
-
def __init__(self, config: "
|
|
119
|
+
def __init__(self, config: "ConfigMixin", config_path: ConfigPath, *, version=None):
|
|
120
120
|
# Hasher for parameters
|
|
121
121
|
self._hasher = hashlib.sha256()
|
|
122
122
|
self.config = config
|
|
@@ -183,7 +183,7 @@ class IdentifierComputer:
|
|
|
183
183
|
self.update(value)
|
|
184
184
|
|
|
185
185
|
# Handles configurations
|
|
186
|
-
elif isinstance(value,
|
|
186
|
+
elif isinstance(value, ConfigMixin):
|
|
187
187
|
# Encodes the identifier
|
|
188
188
|
self._hashupdate(IdentifierComputer.OBJECT_ID)
|
|
189
189
|
|
|
@@ -273,12 +273,17 @@ class IdentifierComputer:
|
|
|
273
273
|
self._hashupdate(IdentifierComputer.NAME_ID)
|
|
274
274
|
self.update(argvalue)
|
|
275
275
|
|
|
276
|
+
# Add init tasks
|
|
277
|
+
if value.__xpm__.init_tasks:
|
|
278
|
+
self._hashupdate(IdentifierComputer.INIT_TASKS)
|
|
279
|
+
for init_task in value.__xpm__.init_tasks:
|
|
280
|
+
self.update(init_task)
|
|
276
281
|
else:
|
|
277
282
|
raise NotImplementedError("Cannot compute hash of type %s" % type(value))
|
|
278
283
|
|
|
279
284
|
@staticmethod
|
|
280
285
|
def compute(
|
|
281
|
-
config: "
|
|
286
|
+
config: "ConfigMixin", config_path: ConfigPath | None = None, version=None
|
|
282
287
|
) -> Identifier:
|
|
283
288
|
"""Compute the identifier for a configuration
|
|
284
289
|
|
|
@@ -290,7 +295,7 @@ class IdentifierComputer:
|
|
|
290
295
|
# Try to use the cached value first
|
|
291
296
|
# (if there are no loops)
|
|
292
297
|
if config.__xpm__._sealed:
|
|
293
|
-
identifier = config.__xpm__.
|
|
298
|
+
identifier = config.__xpm__._identifier
|
|
294
299
|
if identifier is not None and not identifier.has_loops:
|
|
295
300
|
return identifier
|
|
296
301
|
|
|
@@ -9,7 +9,6 @@ from experimaestro import taskglobals
|
|
|
9
9
|
|
|
10
10
|
from termcolor import cprint
|
|
11
11
|
from pathlib import Path
|
|
12
|
-
import hashlib
|
|
13
12
|
import logging
|
|
14
13
|
import io
|
|
15
14
|
from enum import Enum
|
|
@@ -20,7 +19,6 @@ from typing import (
|
|
|
20
19
|
Callable,
|
|
21
20
|
ClassVar,
|
|
22
21
|
Dict,
|
|
23
|
-
Iterator,
|
|
24
22
|
List,
|
|
25
23
|
Optional,
|
|
26
24
|
Set,
|
|
@@ -48,7 +46,6 @@ from .config_walk import ConfigWalk, ConfigWalkContext
|
|
|
48
46
|
from .config_utils import (
|
|
49
47
|
getqualattr,
|
|
50
48
|
add_to_path,
|
|
51
|
-
SealedError,
|
|
52
49
|
TaggedValue,
|
|
53
50
|
ObjectStore,
|
|
54
51
|
classproperty,
|
|
@@ -148,9 +145,6 @@ class ConfigInformation:
|
|
|
148
145
|
# This is used to check typevars coherence
|
|
149
146
|
self.concrete_typevars: Dict[TypeVar, type] = {}
|
|
150
147
|
|
|
151
|
-
# Lightweight tasks
|
|
152
|
-
self.pre_tasks: List["LightweightTask"] = []
|
|
153
|
-
|
|
154
148
|
# Initialization tasks
|
|
155
149
|
self.init_tasks: List["LightweightTask"] = []
|
|
156
150
|
|
|
@@ -159,11 +153,8 @@ class ConfigInformation:
|
|
|
159
153
|
|
|
160
154
|
# Cached information
|
|
161
155
|
|
|
162
|
-
self.
|
|
163
|
-
"""The
|
|
164
|
-
|
|
165
|
-
self._raw_identifier = None
|
|
166
|
-
"""The identifier without taking into account pre-tasks"""
|
|
156
|
+
self._identifier = None
|
|
157
|
+
"""The configuration identifier (cached when sealed)"""
|
|
167
158
|
|
|
168
159
|
self._validated = False
|
|
169
160
|
self._sealed = False
|
|
@@ -222,7 +213,7 @@ class ConfigInformation:
|
|
|
222
213
|
if value is None:
|
|
223
214
|
return False
|
|
224
215
|
|
|
225
|
-
if isinstance(value, (int, str, float, bool, Path)):
|
|
216
|
+
if isinstance(value, (int, str, float, bool, Enum, Path)):
|
|
226
217
|
return False
|
|
227
218
|
|
|
228
219
|
if isinstance(value, ConfigMixin):
|
|
@@ -237,7 +228,7 @@ class ConfigInformation:
|
|
|
237
228
|
for x in value.values()
|
|
238
229
|
)
|
|
239
230
|
|
|
240
|
-
|
|
231
|
+
return False
|
|
241
232
|
|
|
242
233
|
def set(self, k, v, bypass=False):
|
|
243
234
|
from experimaestro.generators import Generator
|
|
@@ -366,10 +357,6 @@ class ConfigInformation:
|
|
|
366
357
|
% (k, self.xpmtype, self._initinfo)
|
|
367
358
|
)
|
|
368
359
|
|
|
369
|
-
# Validate pre-tasks
|
|
370
|
-
for pre_task in self.pre_tasks:
|
|
371
|
-
pre_task.__xpm__.validate()
|
|
372
|
-
|
|
373
360
|
# Validate init tasks
|
|
374
361
|
for init_task in self.init_tasks:
|
|
375
362
|
init_task.__xpm__.validate()
|
|
@@ -465,90 +452,29 @@ class ConfigInformation:
|
|
|
465
452
|
context = ConfigWalkContext()
|
|
466
453
|
|
|
467
454
|
class Unsealer(ConfigWalk):
|
|
468
|
-
def preprocess(self, config:
|
|
455
|
+
def preprocess(self, config: ConfigMixin):
|
|
469
456
|
return config.__xpm__._sealed, config
|
|
470
457
|
|
|
471
|
-
def postprocess(self, stub, config:
|
|
458
|
+
def postprocess(self, stub, config: ConfigMixin, values):
|
|
472
459
|
config.__xpm__._sealed = False
|
|
473
460
|
config.__xpm__._identifier = None
|
|
474
461
|
|
|
475
462
|
Unsealer(context, recurse_task=True)(self.pyobject)
|
|
476
463
|
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
pre_tasks: Dict[int, "Config"] = {}
|
|
480
|
-
|
|
481
|
-
class PreTaskCollect(ConfigWalk):
|
|
482
|
-
def preprocess(self, config: Config):
|
|
483
|
-
# Do not cross tasks
|
|
484
|
-
return not isinstance(config.__xpm__, Task), config
|
|
485
|
-
|
|
486
|
-
def postprocess(self, stub, config: Config, values):
|
|
487
|
-
pre_tasks.update(
|
|
488
|
-
{id(pre_task): pre_task for pre_task in config.__xpm__.pre_tasks}
|
|
489
|
-
)
|
|
490
|
-
|
|
491
|
-
PreTaskCollect(context, recurse_task=True)(self.pyobject)
|
|
492
|
-
return pre_tasks.values()
|
|
493
|
-
|
|
494
|
-
def identifiers(self, only_raw: bool):
|
|
464
|
+
@property
|
|
465
|
+
def identifier(self):
|
|
495
466
|
"""Computes the unique identifier"""
|
|
496
|
-
from ..identifier import IdentifierComputer
|
|
497
|
-
|
|
498
|
-
raw_identifier = self._raw_identifier
|
|
499
|
-
full_identifier = self._full_identifier
|
|
467
|
+
from ..identifier import IdentifierComputer
|
|
500
468
|
|
|
501
469
|
# Computes raw identifier if needed
|
|
502
|
-
if
|
|
503
|
-
|
|
504
|
-
raw_identifier = IdentifierComputer.compute(self.pyobject)
|
|
505
|
-
if self._sealed:
|
|
506
|
-
self._raw_identifier = raw_identifier
|
|
507
|
-
|
|
508
|
-
if only_raw:
|
|
509
|
-
return raw_identifier, full_identifier
|
|
510
|
-
|
|
511
|
-
# OK, let's compute the full identifier
|
|
512
|
-
if full_identifier is None or not self._sealed:
|
|
513
|
-
# Compute the full identifier by including the pre-tasks
|
|
514
|
-
hasher = hashlib.sha256()
|
|
515
|
-
hasher.update(raw_identifier.all)
|
|
516
|
-
pre_tasks_ids = [
|
|
517
|
-
pre_task.__xpm__.raw_identifier.all
|
|
518
|
-
for pre_task in self.collect_pre_tasks()
|
|
519
|
-
]
|
|
520
|
-
for task_id in sorted(pre_tasks_ids):
|
|
521
|
-
hasher.update(task_id)
|
|
522
|
-
|
|
523
|
-
# Adds init tasks
|
|
524
|
-
if self.init_tasks:
|
|
525
|
-
hasher.update(IdentifierComputer.INIT_TASKS)
|
|
526
|
-
for init_task in self.init_tasks:
|
|
527
|
-
hasher.update(init_task.__xpm__.raw_identifier.all)
|
|
528
|
-
|
|
529
|
-
full_identifier = Identifier(hasher.digest())
|
|
530
|
-
full_identifier.has_loops = raw_identifier.has_loops
|
|
531
|
-
|
|
532
|
-
# Only cache the identifier if sealed
|
|
533
|
-
if self._sealed:
|
|
534
|
-
self._full_identifier = full_identifier
|
|
535
|
-
|
|
536
|
-
return raw_identifier, full_identifier
|
|
537
|
-
|
|
538
|
-
@property
|
|
539
|
-
def raw_identifier(self) -> "Identifier":
|
|
540
|
-
"""Computes the unique identifier (without task modifiers)"""
|
|
541
|
-
raw_identifier, _ = self.identifiers(True)
|
|
542
|
-
return raw_identifier
|
|
543
|
-
|
|
544
|
-
@property
|
|
545
|
-
def full_identifier(self) -> "Identifier":
|
|
546
|
-
"""Computes the unique identifier (with task modifiers)"""
|
|
547
|
-
_, full_identifier = self.identifiers(False)
|
|
548
|
-
return full_identifier
|
|
470
|
+
if self._identifier is not None:
|
|
471
|
+
return self._identifier
|
|
549
472
|
|
|
550
|
-
|
|
551
|
-
|
|
473
|
+
# Get the main identifier
|
|
474
|
+
identifier = IdentifierComputer.compute(self.pyobject)
|
|
475
|
+
if self._sealed:
|
|
476
|
+
self._identifier = identifier
|
|
477
|
+
return identifier
|
|
552
478
|
|
|
553
479
|
def dependency(self):
|
|
554
480
|
"""Returns a dependency"""
|
|
@@ -563,12 +489,6 @@ class ConfigInformation:
|
|
|
563
489
|
path: List[str],
|
|
564
490
|
taskids: Set[int],
|
|
565
491
|
):
|
|
566
|
-
# Add pre-tasks
|
|
567
|
-
for pre_task in self.pre_tasks:
|
|
568
|
-
pre_task.__xpm__.updatedependencies(
|
|
569
|
-
dependencies, path + ["__pre_tasks__"], taskids
|
|
570
|
-
)
|
|
571
|
-
|
|
572
492
|
# Add initialization tasks
|
|
573
493
|
for init_task in self.init_tasks:
|
|
574
494
|
init_task.__xpm__.updatedependencies(
|
|
@@ -841,9 +761,6 @@ class ConfigInformation:
|
|
|
841
761
|
if self.task is not None and self.task is not self:
|
|
842
762
|
ConfigInformation.__collect_objects__(self.task, objects, context)
|
|
843
763
|
|
|
844
|
-
# Serialize pre-tasks
|
|
845
|
-
ConfigInformation.__collect_objects__(self.pre_tasks, objects, context)
|
|
846
|
-
|
|
847
764
|
# Serialize initialization tasks
|
|
848
765
|
ConfigInformation.__collect_objects__(self.init_tasks, objects, context)
|
|
849
766
|
|
|
@@ -857,8 +774,6 @@ class ConfigInformation:
|
|
|
857
774
|
}
|
|
858
775
|
|
|
859
776
|
# Add pre/init tasks
|
|
860
|
-
if self.pre_tasks:
|
|
861
|
-
state_dict["pre-tasks"] = [id(pre_task) for pre_task in self.pre_tasks]
|
|
862
777
|
if self.init_tasks:
|
|
863
778
|
state_dict["init-tasks"] = [id(init_task) for init_task in self.init_tasks]
|
|
864
779
|
|
|
@@ -1191,12 +1106,6 @@ class ConfigInformation:
|
|
|
1191
1106
|
o.__post_init__()
|
|
1192
1107
|
|
|
1193
1108
|
else:
|
|
1194
|
-
# Sets pre-tasks
|
|
1195
|
-
o.__xpm__.pre_tasks = [
|
|
1196
|
-
objects[pre_task_id]
|
|
1197
|
-
for pre_task_id in definition.get("pre-tasks", [])
|
|
1198
|
-
]
|
|
1199
|
-
|
|
1200
1109
|
if task_id := definition.get("task", None):
|
|
1201
1110
|
o.__xpm__.task = objects[task_id]
|
|
1202
1111
|
|
|
@@ -1230,15 +1139,6 @@ class ConfigInformation:
|
|
|
1230
1139
|
|
|
1231
1140
|
# Run pre-task (or returns them)
|
|
1232
1141
|
if as_instance or return_tasks:
|
|
1233
|
-
# Collect pre-tasks (just once)
|
|
1234
|
-
completed_pretasks = set()
|
|
1235
|
-
pre_tasks = []
|
|
1236
|
-
for definition in definitions:
|
|
1237
|
-
for pre_task_id in definition.get("pre-tasks", []):
|
|
1238
|
-
if pre_task_id not in completed_pretasks:
|
|
1239
|
-
completed_pretasks.add(pre_task_id)
|
|
1240
|
-
pre_tasks.append(objects[pre_task_id])
|
|
1241
|
-
|
|
1242
1142
|
# Collect init tasks
|
|
1243
1143
|
init_tasks = []
|
|
1244
1144
|
for init_task_id in definitions[-1].get("init-tasks", []):
|
|
@@ -1246,14 +1146,11 @@ class ConfigInformation:
|
|
|
1246
1146
|
init_tasks.append(init_task)
|
|
1247
1147
|
|
|
1248
1148
|
if as_instance:
|
|
1249
|
-
for pre_task in pre_tasks:
|
|
1250
|
-
logger.info("Executing pre-task %s", type(pre_task))
|
|
1251
|
-
pre_task.execute()
|
|
1252
1149
|
for init_task in init_tasks:
|
|
1253
1150
|
logger.info("Executing init task %s", type(init_task))
|
|
1254
1151
|
init_task.execute()
|
|
1255
1152
|
else:
|
|
1256
|
-
return o,
|
|
1153
|
+
return o, init_tasks
|
|
1257
1154
|
|
|
1258
1155
|
return o
|
|
1259
1156
|
|
|
@@ -1261,7 +1158,6 @@ class ConfigInformation:
|
|
|
1261
1158
|
def __init__(self, context: ConfigWalkContext, *, objects: ObjectStore = None):
|
|
1262
1159
|
super().__init__(context)
|
|
1263
1160
|
self.objects = ObjectStore() if objects is None else objects
|
|
1264
|
-
self.pre_tasks = {}
|
|
1265
1161
|
|
|
1266
1162
|
def preprocess(self, config: "Config"):
|
|
1267
1163
|
if self.objects.is_constructed(id(config)):
|
|
@@ -1288,10 +1184,6 @@ class ConfigInformation:
|
|
|
1288
1184
|
# Call __post_init__
|
|
1289
1185
|
stub.__post_init__()
|
|
1290
1186
|
|
|
1291
|
-
# Gather pre-tasks
|
|
1292
|
-
for pre_task in config.__xpm__.pre_tasks:
|
|
1293
|
-
self.pre_tasks[id(pre_task)] = self.stub(pre_task)
|
|
1294
|
-
|
|
1295
1187
|
self.objects.set_constructed(id(config))
|
|
1296
1188
|
return stub
|
|
1297
1189
|
|
|
@@ -1305,10 +1197,6 @@ class ConfigInformation:
|
|
|
1305
1197
|
processor = ConfigInformation.FromPython(context, objects=objects)
|
|
1306
1198
|
last_object = processor(self.pyobject)
|
|
1307
1199
|
|
|
1308
|
-
# Execute pre-tasks
|
|
1309
|
-
for pre_task in processor.pre_tasks.values():
|
|
1310
|
-
pre_task.execute()
|
|
1311
|
-
|
|
1312
1200
|
return last_object
|
|
1313
1201
|
|
|
1314
1202
|
def add_dependencies(self, *dependencies):
|
|
@@ -1509,32 +1397,7 @@ class ConfigMixin:
|
|
|
1509
1397
|
attributes)"""
|
|
1510
1398
|
return clone(self)
|
|
1511
1399
|
|
|
1512
|
-
def
|
|
1513
|
-
assert all(
|
|
1514
|
-
[isinstance(task, ConfigMixin) for task in tasks]
|
|
1515
|
-
), "One of the parameters is not a configuration object"
|
|
1516
|
-
assert all(
|
|
1517
|
-
[isinstance(task, LightweightTask) for task in tasks]
|
|
1518
|
-
), "One of the pre-tasks are not lightweight tasks"
|
|
1519
|
-
if self.__xpm__._sealed:
|
|
1520
|
-
raise SealedError("Cannot add pre-tasks to a sealed configuration")
|
|
1521
|
-
self.__xpm__.pre_tasks.extend(tasks)
|
|
1522
|
-
return self
|
|
1523
|
-
|
|
1524
|
-
def add_pretasks_from(self, *configs: "Config"):
|
|
1525
|
-
assert all(
|
|
1526
|
-
[isinstance(config, ConfigMixin) for config in configs]
|
|
1527
|
-
), "One of the parameters is not a configuration object"
|
|
1528
|
-
for config in configs:
|
|
1529
|
-
self.add_pretasks(*config.__xpm__.pre_tasks)
|
|
1530
|
-
return self
|
|
1531
|
-
|
|
1532
|
-
@property
|
|
1533
|
-
def pre_tasks(self) -> List["LightweightTask"]:
|
|
1534
|
-
"""Access pre-tasks"""
|
|
1535
|
-
return self.__xpm__.pre_tasks
|
|
1536
|
-
|
|
1537
|
-
def copy_dependencies(self, other: "Config"):
|
|
1400
|
+
def copy_dependencies(self, other: "ConfigMixin"):
|
|
1538
1401
|
"""Add all the dependencies from other configuration"""
|
|
1539
1402
|
|
|
1540
1403
|
# Add task dependency
|
|
@@ -1600,27 +1463,12 @@ class Config:
|
|
|
1600
1463
|
def __identifier__(self) -> "Identifier":
|
|
1601
1464
|
return self.__xpm__.full_identifier
|
|
1602
1465
|
|
|
1603
|
-
def add_pretasks(self, *tasks: "LightweightTask"):
|
|
1604
|
-
"""Add pre-tasks"""
|
|
1605
|
-
raise AssertionError("This method can only be used during configuration")
|
|
1606
|
-
|
|
1607
|
-
def add_pretasks_from(self, *configs: "Config"):
|
|
1608
|
-
"""Add pre-tasks from the listed configurations"""
|
|
1609
|
-
raise AssertionError(
|
|
1610
|
-
"The 'add_pretasks_from' can only be used during configuration"
|
|
1611
|
-
)
|
|
1612
|
-
|
|
1613
1466
|
def copy_dependencies(self, other: "Config"):
|
|
1614
1467
|
"""Add pre-tasks from the listed configurations"""
|
|
1615
1468
|
raise AssertionError(
|
|
1616
1469
|
"The 'copy_dependencies' method can only be used during configuration"
|
|
1617
1470
|
)
|
|
1618
1471
|
|
|
1619
|
-
@property
|
|
1620
|
-
def pre_tasks(self) -> List["LightweightTask"]:
|
|
1621
|
-
"""Access pre-tasks"""
|
|
1622
|
-
raise AssertionError("Pre-tasks can be accessed only during configuration")
|
|
1623
|
-
|
|
1624
1472
|
def register_task_output(self, method, *args, **kwargs):
|
|
1625
1473
|
# Determine the path for this...
|
|
1626
1474
|
path = taskglobals.Env.instance().xpm_path / "task-outputs.jsonl"
|
|
@@ -109,11 +109,7 @@ class ConfigWalk:
|
|
|
109
109
|
else:
|
|
110
110
|
result[arg.name] = None
|
|
111
111
|
|
|
112
|
-
# Deals with
|
|
113
|
-
if info.pre_tasks:
|
|
114
|
-
with self.map("__pre_tasks__"):
|
|
115
|
-
self(info.pre_tasks)
|
|
116
|
-
|
|
112
|
+
# Deals with init tasks
|
|
117
113
|
if info.init_tasks:
|
|
118
114
|
with self.map("__init_tasks__"):
|
|
119
115
|
self(info.init_tasks)
|
experimaestro/core/objects.pyi
CHANGED
|
@@ -168,7 +168,7 @@ class ConfigMixin:
|
|
|
168
168
|
*,
|
|
169
169
|
workspace: Incomplete | None = ...,
|
|
170
170
|
launcher: Incomplete | None = ...,
|
|
171
|
-
run_mode: RunMode =
|
|
171
|
+
run_mode: RunMode = ...,
|
|
172
172
|
): ...
|
|
173
173
|
def stdout(self): ...
|
|
174
174
|
def stderr(self): ...
|
|
@@ -195,11 +195,7 @@ class Config:
|
|
|
195
195
|
def __post_init__(self) -> None: ...
|
|
196
196
|
def __json__(self): ...
|
|
197
197
|
def __identifier__(self) -> Identifier: ...
|
|
198
|
-
def add_pretasks(self, *tasks: "LightweightTask"): ...
|
|
199
|
-
def add_pretasks_from(self, configs: "Config"): ...
|
|
200
198
|
def copy_dependencies(self, other: "Config"): ...
|
|
201
|
-
@property
|
|
202
|
-
def pre_tasks(self) -> List["LightweightTask"]: ...
|
|
203
199
|
|
|
204
200
|
class LightweightTask(Config):
|
|
205
201
|
def execute(self) -> None: ...
|
|
@@ -213,7 +209,7 @@ class Task(LightweightTask):
|
|
|
213
209
|
workspace: Incomplete | None = ...,
|
|
214
210
|
launcher: Incomplete | None = ...,
|
|
215
211
|
run_mode: RunMode = ...,
|
|
216
|
-
init_tasks: List["LightweightTask"] = []
|
|
212
|
+
init_tasks: List["LightweightTask"] = [],
|
|
217
213
|
): ...
|
|
218
214
|
def task_outputs(self, dep: Callable[[Config], None]) -> Any: ...
|
|
219
215
|
|
|
@@ -1,10 +1,8 @@
|
|
|
1
|
-
from typing import List, TypeVar
|
|
2
|
-
from pathlib import Path
|
|
1
|
+
from typing import List, TypeVar
|
|
3
2
|
from experimaestro import Param
|
|
4
3
|
|
|
5
4
|
from .objects import Config, LightweightTask
|
|
6
5
|
from .arguments import DataPath
|
|
7
|
-
from experimaestro import copyconfig
|
|
8
6
|
|
|
9
7
|
|
|
10
8
|
class SerializationLWTask(LightweightTask):
|
|
@@ -39,8 +37,3 @@ class PathSerializationLWTask(SerializationLWTask):
|
|
|
39
37
|
|
|
40
38
|
path: DataPath
|
|
41
39
|
"""Path containing the data"""
|
|
42
|
-
|
|
43
|
-
@classmethod
|
|
44
|
-
def construct(cls, value: T, path: Path, dep: Callable[[Config], Any]) -> T:
|
|
45
|
-
value = copyconfig(value)
|
|
46
|
-
return value.add_pretasks(dep(cls(value=value, path=path)))
|
|
@@ -85,9 +85,3 @@ def test_dependencies_inner_task_output(xp):
|
|
|
85
85
|
a = task_a.submit()
|
|
86
86
|
b = Inner_TaskB.C(param_a=a).submit()
|
|
87
87
|
check_dependencies(b, task_a)
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
def test_dependencies_pre_task(xp):
|
|
91
|
-
a = TaskA.C().submit()
|
|
92
|
-
a2 = TaskA.C().add_pretasks(a).submit()
|
|
93
|
-
check_dependencies(a2, a)
|
|
@@ -68,19 +68,19 @@ def assert_notequal(a, b, message=""):
|
|
|
68
68
|
assert getidentifier(a) != getidentifier(b), message
|
|
69
69
|
|
|
70
70
|
|
|
71
|
-
def
|
|
71
|
+
def test_identifier_int():
|
|
72
72
|
assert_equal(A.C(a=1), A.C(a=1))
|
|
73
73
|
|
|
74
74
|
|
|
75
|
-
def
|
|
75
|
+
def test_identifier_different_type():
|
|
76
76
|
assert_notequal(A.C(a=1), B.C(a=1))
|
|
77
77
|
|
|
78
78
|
|
|
79
|
-
def
|
|
79
|
+
def test_identifier_order():
|
|
80
80
|
assert_equal(Values.C(value1=1, value2=2), Values.C(value2=2, value1=1))
|
|
81
81
|
|
|
82
82
|
|
|
83
|
-
def
|
|
83
|
+
def test_identifier_default():
|
|
84
84
|
assert_equal(C.C(a=1, b=2), C.C(b=2))
|
|
85
85
|
|
|
86
86
|
|
|
@@ -88,22 +88,22 @@ def test_identifier_default_field():
|
|
|
88
88
|
assert_equal(CField.C(a=1, b=2), CField.C(b=2))
|
|
89
89
|
|
|
90
90
|
|
|
91
|
-
def
|
|
91
|
+
def test_identifier_inner_eq():
|
|
92
92
|
assert_equal(D.C(a=A.C(a=1)), D.C(a=A.C(a=1)))
|
|
93
93
|
|
|
94
94
|
|
|
95
|
-
def
|
|
95
|
+
def test_identifier_float():
|
|
96
96
|
assert_equal(Float.C(value=1), Float.C(value=1))
|
|
97
97
|
|
|
98
98
|
|
|
99
|
-
def
|
|
99
|
+
def test_identifier_float2():
|
|
100
100
|
assert_equal(Float.C(value=1.0), Float.C(value=1))
|
|
101
101
|
|
|
102
102
|
|
|
103
103
|
# --- Argument name
|
|
104
104
|
|
|
105
105
|
|
|
106
|
-
def
|
|
106
|
+
def test_identifier_name():
|
|
107
107
|
"""The identifier fully determines the hash code"""
|
|
108
108
|
|
|
109
109
|
class Config0(Config):
|
|
@@ -125,7 +125,7 @@ def test_param_name():
|
|
|
125
125
|
# --- Test option
|
|
126
126
|
|
|
127
127
|
|
|
128
|
-
def
|
|
128
|
+
def test_identifier_option():
|
|
129
129
|
class OptionConfig(Config):
|
|
130
130
|
__xpmid__ = "test.identifier.option"
|
|
131
131
|
a: Param[int]
|
|
@@ -139,7 +139,7 @@ def test_param_option():
|
|
|
139
139
|
# --- Dictionnary
|
|
140
140
|
|
|
141
141
|
|
|
142
|
-
def
|
|
142
|
+
def test_identifier_dict():
|
|
143
143
|
"""Test identifiers of dictionary structures"""
|
|
144
144
|
|
|
145
145
|
class B(Config):
|
|
@@ -166,7 +166,7 @@ class TypeWithPath(Config):
|
|
|
166
166
|
path: Param[Path]
|
|
167
167
|
|
|
168
168
|
|
|
169
|
-
def
|
|
169
|
+
def test_identifier_path():
|
|
170
170
|
"""Path should be ignored"""
|
|
171
171
|
assert_equal(TypeWithPath.C(a=1, path="/a/b"), TypeWithPath.C(a=1, path="/c/d"))
|
|
172
172
|
assert_notequal(TypeWithPath.C(a=2, path="/a/b"), TypeWithPath.C(a=1, path="/c/d"))
|
|
@@ -175,7 +175,7 @@ def test_param_identifier_path():
|
|
|
175
175
|
# --- Test with added arguments
|
|
176
176
|
|
|
177
177
|
|
|
178
|
-
def
|
|
178
|
+
def test_identifier_pathoption():
|
|
179
179
|
"""Path arguments should be ignored"""
|
|
180
180
|
|
|
181
181
|
class A_with_path(Config):
|
|
@@ -190,7 +190,7 @@ def test_param_identifier_pathoption():
|
|
|
190
190
|
assert_equal(A_with_path.C(a=1), A_without_path.C(a=1))
|
|
191
191
|
|
|
192
192
|
|
|
193
|
-
def
|
|
193
|
+
def test_identifier_enum():
|
|
194
194
|
"""test enum parameters"""
|
|
195
195
|
from enum import Enum
|
|
196
196
|
|
|
@@ -205,7 +205,7 @@ def test_param_identifier_enum():
|
|
|
205
205
|
assert_equal(EnumConfig.C(a=EnumParam.FIRST), EnumConfig.C(a=EnumParam.FIRST))
|
|
206
206
|
|
|
207
207
|
|
|
208
|
-
def
|
|
208
|
+
def test_identifier_addnone():
|
|
209
209
|
"""Test the case of new parameter (with None default)"""
|
|
210
210
|
|
|
211
211
|
class B(Config):
|
|
@@ -222,7 +222,7 @@ def test_param_identifier_addnone():
|
|
|
222
222
|
assert_notequal(A_with_b.C(b=B.C(x=1)), A.C())
|
|
223
223
|
|
|
224
224
|
|
|
225
|
-
def
|
|
225
|
+
def test_identifier_defaultnew():
|
|
226
226
|
"""Path arguments should be ignored"""
|
|
227
227
|
|
|
228
228
|
class A_with_b(Config):
|
|
@@ -239,7 +239,7 @@ def test_param_defaultnew():
|
|
|
239
239
|
assert_equal(A_with_b.C(a=1), A.C(a=1))
|
|
240
240
|
|
|
241
241
|
|
|
242
|
-
def
|
|
242
|
+
def test_identifier_taskconfigidentifier():
|
|
243
243
|
"""Test whether the embedded task arguments make the configuration different"""
|
|
244
244
|
|
|
245
245
|
class MyConfig(Config):
|
|
@@ -261,7 +261,7 @@ def test_param_taskconfigidentifier():
|
|
|
261
261
|
)
|
|
262
262
|
|
|
263
263
|
|
|
264
|
-
def
|
|
264
|
+
def test_identifier_constant():
|
|
265
265
|
"""Test if constants are taken into account for signature computation"""
|
|
266
266
|
|
|
267
267
|
class A1(Config):
|
|
@@ -281,7 +281,7 @@ def test_param_constant():
|
|
|
281
281
|
assert_notequal(A1.C(), A2.C())
|
|
282
282
|
|
|
283
283
|
|
|
284
|
-
def
|
|
284
|
+
def test_identifier_deprecated_class():
|
|
285
285
|
"""Test that when submitting the task, the computed identifier is the one of
|
|
286
286
|
the new class"""
|
|
287
287
|
|
|
@@ -305,7 +305,7 @@ def test_param_identifier_deprecated_class():
|
|
|
305
305
|
)
|
|
306
306
|
|
|
307
307
|
|
|
308
|
-
def
|
|
308
|
+
def test_identifier_deprecated_attribute():
|
|
309
309
|
class Values(Config):
|
|
310
310
|
values: Param[List[int]] = []
|
|
311
311
|
|
|
@@ -320,7 +320,7 @@ class MetaA(Config):
|
|
|
320
320
|
x: Param[int]
|
|
321
321
|
|
|
322
322
|
|
|
323
|
-
def
|
|
323
|
+
def test_identifier_meta():
|
|
324
324
|
"""Test forced meta-parameter"""
|
|
325
325
|
|
|
326
326
|
class B(Config):
|
|
@@ -363,7 +363,7 @@ def test_param_identifier_meta():
|
|
|
363
363
|
)
|
|
364
364
|
|
|
365
365
|
|
|
366
|
-
def
|
|
366
|
+
def test_identifier_meta_default_dict():
|
|
367
367
|
class DictConfig(Config):
|
|
368
368
|
params: Param[Dict[str, MetaA]] = {}
|
|
369
369
|
|
|
@@ -379,7 +379,7 @@ def test_param_identifier_meta_default_dict():
|
|
|
379
379
|
)
|
|
380
380
|
|
|
381
381
|
|
|
382
|
-
def
|
|
382
|
+
def test_identifier_meta_default_array():
|
|
383
383
|
class ArrayConfigWithDefault(Config):
|
|
384
384
|
array: Param[List[MetaA]] = []
|
|
385
385
|
|
|
@@ -395,37 +395,7 @@ def test_param_identifier_meta_default_array():
|
|
|
395
395
|
)
|
|
396
396
|
|
|
397
397
|
|
|
398
|
-
def
|
|
399
|
-
class MyConfig(Config):
|
|
400
|
-
pass
|
|
401
|
-
|
|
402
|
-
class IdentifierPreLightTask(LightweightTask):
|
|
403
|
-
pass
|
|
404
|
-
|
|
405
|
-
class IdentifierPreTask(Task):
|
|
406
|
-
x: Param[MyConfig]
|
|
407
|
-
|
|
408
|
-
task = IdentifierPreTask.C(x=MyConfig.C()).submit(run_mode=RunMode.DRY_RUN)
|
|
409
|
-
task_with_pre = (
|
|
410
|
-
IdentifierPreTask.C(x=MyConfig.C())
|
|
411
|
-
.add_pretasks(IdentifierPreLightTask.C())
|
|
412
|
-
.submit(run_mode=RunMode.DRY_RUN)
|
|
413
|
-
)
|
|
414
|
-
task_with_pre_2 = (
|
|
415
|
-
IdentifierPreTask.C(x=MyConfig.C())
|
|
416
|
-
.add_pretasks(IdentifierPreLightTask.C())
|
|
417
|
-
.submit(run_mode=RunMode.DRY_RUN)
|
|
418
|
-
)
|
|
419
|
-
task_with_pre_3 = IdentifierPreTask.C(
|
|
420
|
-
x=MyConfig.C().add_pretasks(IdentifierPreLightTask.C())
|
|
421
|
-
).submit(run_mode=RunMode.DRY_RUN)
|
|
422
|
-
|
|
423
|
-
assert_notequal(task, task_with_pre, "No pre-task")
|
|
424
|
-
assert_equal(task_with_pre, task_with_pre_2, "Same parameters")
|
|
425
|
-
assert_equal(task_with_pre, task_with_pre_3, "Pre-tasks are order-less")
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
def test_param_identifier_init_task():
|
|
398
|
+
def test_identifier_init_task():
|
|
429
399
|
class MyConfig(Config):
|
|
430
400
|
pass
|
|
431
401
|
|
|
@@ -435,26 +405,67 @@ def test_param_identifier_init_task():
|
|
|
435
405
|
class IdentifierInitTask2(Task):
|
|
436
406
|
pass
|
|
437
407
|
|
|
438
|
-
class
|
|
408
|
+
class IdentifierTask(Task):
|
|
439
409
|
x: Param[MyConfig]
|
|
440
410
|
|
|
441
|
-
task =
|
|
442
|
-
task_with_pre =
|
|
411
|
+
task = IdentifierTask.C(x=MyConfig.C()).submit(run_mode=RunMode.DRY_RUN)
|
|
412
|
+
task_with_pre = IdentifierTask.C(x=MyConfig.C()).submit(
|
|
443
413
|
run_mode=RunMode.DRY_RUN,
|
|
444
414
|
init_tasks=[IdentifierInitTask.C(), IdentifierInitTask2.C()],
|
|
445
415
|
)
|
|
446
|
-
task_with_pre_2 =
|
|
416
|
+
task_with_pre_2 = IdentifierTask.C(x=MyConfig.C()).submit(
|
|
447
417
|
run_mode=RunMode.DRY_RUN,
|
|
448
418
|
init_tasks=[IdentifierInitTask.C(), IdentifierInitTask2.C()],
|
|
449
419
|
)
|
|
450
|
-
task_with_pre_3 =
|
|
420
|
+
task_with_pre_3 = IdentifierTask.C(x=MyConfig.C()).submit(
|
|
451
421
|
run_mode=RunMode.DRY_RUN,
|
|
452
422
|
init_tasks=[IdentifierInitTask2.C(), IdentifierInitTask.C()],
|
|
453
423
|
)
|
|
454
424
|
|
|
455
|
-
assert_notequal(task, task_with_pre, "
|
|
425
|
+
assert_notequal(task, task_with_pre, "Should be different with init-task")
|
|
456
426
|
assert_equal(task_with_pre, task_with_pre_2, "Same parameters")
|
|
457
|
-
assert_notequal(task_with_pre, task_with_pre_3, "
|
|
427
|
+
assert_notequal(task_with_pre, task_with_pre_3, "Other parameters")
|
|
428
|
+
|
|
429
|
+
|
|
430
|
+
def test_identifier_init_task_dep():
|
|
431
|
+
class Loader(LightweightTask):
|
|
432
|
+
param1: Param[float]
|
|
433
|
+
|
|
434
|
+
def execute(self):
|
|
435
|
+
pass
|
|
436
|
+
|
|
437
|
+
class FirstTask(Task):
|
|
438
|
+
def task_outputs(self, dep):
|
|
439
|
+
return dep(Loader.C(param1=1))
|
|
440
|
+
|
|
441
|
+
def execute(self):
|
|
442
|
+
pass
|
|
443
|
+
|
|
444
|
+
class SecondTask(Task):
|
|
445
|
+
param3: Param[int]
|
|
446
|
+
|
|
447
|
+
def execute(self):
|
|
448
|
+
pass
|
|
449
|
+
|
|
450
|
+
# Two identical tasks
|
|
451
|
+
task_a_1 = FirstTask.C()
|
|
452
|
+
task_a_2 = FirstTask.C()
|
|
453
|
+
assert_equal(task_a_1, task_a_2)
|
|
454
|
+
|
|
455
|
+
# We process them with two different init tasks
|
|
456
|
+
loader_1 = task_a_1.submit(
|
|
457
|
+
init_tasks=[Loader.C(param1=0.5)], run_mode=RunMode.DRY_RUN
|
|
458
|
+
)
|
|
459
|
+
loader_2 = task_a_2.submit(
|
|
460
|
+
init_tasks=[Loader.C(param1=5)], run_mode=RunMode.DRY_RUN
|
|
461
|
+
)
|
|
462
|
+
assert_notequal(loader_1, loader_2)
|
|
463
|
+
|
|
464
|
+
# Now, we process
|
|
465
|
+
c_1 = SecondTask.C(param3=2).submit(init_tasks=[loader_1], run_mode=RunMode.DRY_RUN)
|
|
466
|
+
|
|
467
|
+
c_2 = SecondTask.C(param3=2).submit(init_tasks=[loader_2], run_mode=RunMode.DRY_RUN)
|
|
468
|
+
assert_notequal(c_1, c_2)
|
|
458
469
|
|
|
459
470
|
|
|
460
471
|
# --- Check configuration reloads
|
|
@@ -472,7 +483,7 @@ def check_reload(config):
|
|
|
472
483
|
new_config = ConfigInformation.fromParameters(
|
|
473
484
|
data, as_instance=False, discard_id=True
|
|
474
485
|
)
|
|
475
|
-
assert new_config.__xpm__.
|
|
486
|
+
assert new_config.__xpm__._identifier is None
|
|
476
487
|
new_identifier = new_config.__xpm__.identifier.all
|
|
477
488
|
|
|
478
489
|
assert new_identifier == old_identifier
|
|
@@ -482,7 +493,7 @@ class IdentifierReloadConfig(Config):
|
|
|
482
493
|
id: Param[str]
|
|
483
494
|
|
|
484
495
|
|
|
485
|
-
def
|
|
496
|
+
def test_identifier_reload_config():
|
|
486
497
|
# Creates the configuration
|
|
487
498
|
check_reload(IdentifierReloadConfig.C(id="123"))
|
|
488
499
|
|
|
@@ -498,7 +509,7 @@ class IdentifierReloadDerived(Config):
|
|
|
498
509
|
task: Param[IdentifierReloadConfig]
|
|
499
510
|
|
|
500
511
|
|
|
501
|
-
def
|
|
512
|
+
def test_identifier_reload_taskoutput():
|
|
502
513
|
"""When using a task output, the identifier should not be different"""
|
|
503
514
|
|
|
504
515
|
# Creates the configuration
|
|
@@ -520,7 +531,7 @@ class IdentifierReloadTaskDerived(Config):
|
|
|
520
531
|
other: Param[IdentifierReloadTaskConfig]
|
|
521
532
|
|
|
522
533
|
|
|
523
|
-
def
|
|
534
|
+
def test_identifier_reload_task_direct():
|
|
524
535
|
"""When using a direct task output, the identifier should not be different"""
|
|
525
536
|
|
|
526
537
|
# Creates the configuration
|
|
@@ -531,7 +542,7 @@ def test_param_identifier_reload_task_direct():
|
|
|
531
542
|
check_reload(config)
|
|
532
543
|
|
|
533
544
|
|
|
534
|
-
def
|
|
545
|
+
def test_identifier_reload_meta():
|
|
535
546
|
"""Test identifier don't change when using meta"""
|
|
536
547
|
# Creates the configuration
|
|
537
548
|
task = IdentifierReloadTask.C(id="123").submit(run_mode=RunMode.DRY_RUN)
|
|
@@ -554,7 +565,7 @@ class LoopC(Config):
|
|
|
554
565
|
param_b: Param["LoopB"]
|
|
555
566
|
|
|
556
567
|
|
|
557
|
-
def
|
|
568
|
+
def test_identifier_loop():
|
|
558
569
|
c = LoopC.C()
|
|
559
570
|
b = LoopB.C(param_c=c)
|
|
560
571
|
a = LoopA.C(param_b=b)
|
|
@@ -46,18 +46,6 @@ class LoadModel(SerializationLWTask):
|
|
|
46
46
|
self.value.initialized = True
|
|
47
47
|
|
|
48
48
|
|
|
49
|
-
def test_instance_serialized():
|
|
50
|
-
model = Model.C()
|
|
51
|
-
model.add_pretasks(LoadModel.C(value=model))
|
|
52
|
-
trainer = Evaluator.C(model=model)
|
|
53
|
-
instance = trainer.instance()
|
|
54
|
-
|
|
55
|
-
assert isinstance(
|
|
56
|
-
instance.model, Model
|
|
57
|
-
), f"The model is not a Model but a {type(instance.model).__qualname__}"
|
|
58
|
-
assert instance.model.initialized, "The model was not initialized"
|
|
59
|
-
|
|
60
|
-
|
|
61
49
|
class ConfigWithOptional(Config):
|
|
62
50
|
x: Param[int] = 1
|
|
63
51
|
y: Param[Optional[int]]
|
|
@@ -1,71 +1,12 @@
|
|
|
1
1
|
from typing import Optional
|
|
2
2
|
from experimaestro import (
|
|
3
3
|
Config,
|
|
4
|
-
Task,
|
|
5
4
|
Param,
|
|
6
|
-
SerializationLWTask,
|
|
7
|
-
copyconfig,
|
|
8
5
|
state_dict,
|
|
9
6
|
from_state_dict,
|
|
10
7
|
)
|
|
11
8
|
from experimaestro.core.context import SerializationContext
|
|
12
9
|
from experimaestro.core.objects import ConfigMixin
|
|
13
|
-
from experimaestro.tests.utils import TemporaryExperiment
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
class SubModel(Config):
|
|
17
|
-
pass
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
class Model(Config):
|
|
21
|
-
submodel: Param[SubModel]
|
|
22
|
-
|
|
23
|
-
def __post_init__(self):
|
|
24
|
-
self.initialized = False
|
|
25
|
-
self.submodel.initialized = False
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
class LoadModel(SerializationLWTask):
|
|
29
|
-
def execute(self):
|
|
30
|
-
self.value.initialized = True
|
|
31
|
-
self.value.submodel.initialized = True
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
class Trainer(Task):
|
|
35
|
-
model: Param[Config]
|
|
36
|
-
|
|
37
|
-
def task_outputs(self, dep):
|
|
38
|
-
model = copyconfig(self.model)
|
|
39
|
-
return model.add_pretasks(dep(LoadModel.C(value=model)))
|
|
40
|
-
|
|
41
|
-
def execute(self):
|
|
42
|
-
assert not self.model.initialized, "Model not initialized"
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
class Evaluate(Task):
|
|
46
|
-
model: Param[Config]
|
|
47
|
-
is_submodel: Param[bool] = False
|
|
48
|
-
|
|
49
|
-
def execute(self):
|
|
50
|
-
assert self.model.initialized, "Model not initialized"
|
|
51
|
-
if self.is_submodel:
|
|
52
|
-
assert isinstance(self.model, SubModel)
|
|
53
|
-
else:
|
|
54
|
-
assert isinstance(self.model, Model)
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
def test_serializers_xp():
|
|
58
|
-
with TemporaryExperiment("serializers", maxwait=20, port=0):
|
|
59
|
-
model = Model.C(submodel=SubModel.C())
|
|
60
|
-
trained_model: Model = Trainer.C(model=model).submit()
|
|
61
|
-
|
|
62
|
-
# Use the model itself
|
|
63
|
-
Evaluate.C(model=trained_model).submit()
|
|
64
|
-
|
|
65
|
-
# Use a submodel
|
|
66
|
-
Evaluate.C(model=trained_model.submodel, is_submodel=True).add_pretasks_from(
|
|
67
|
-
trained_model
|
|
68
|
-
).submit()
|
|
69
10
|
|
|
70
11
|
|
|
71
12
|
class Object1(Config):
|
|
@@ -303,26 +303,6 @@ class MyLightweightTask(Task):
|
|
|
303
303
|
assert self.x.data == 1
|
|
304
304
|
|
|
305
305
|
|
|
306
|
-
def test_task_lightweight():
|
|
307
|
-
with TemporaryExperiment("lightweight", maxwait=20):
|
|
308
|
-
x = LightweightConfig.C()
|
|
309
|
-
lwtask = LightweightTask.C(x=x)
|
|
310
|
-
assert (
|
|
311
|
-
MyLightweightTask.C(x=x).add_pretasks(lwtask).submit().__xpm__.job.wait()
|
|
312
|
-
== JobState.DONE
|
|
313
|
-
), "Pre-tasks should be executed"
|
|
314
|
-
|
|
315
|
-
x_2 = LightweightConfig.C()
|
|
316
|
-
lwtask_2 = LightweightTask.C(x=x)
|
|
317
|
-
assert (
|
|
318
|
-
MyLightweightTask.C(x=x_2.add_pretasks(lwtask_2))
|
|
319
|
-
.add_pretasks(lwtask_2)
|
|
320
|
-
.submit()
|
|
321
|
-
.__xpm__.job.wait()
|
|
322
|
-
== JobState.DONE
|
|
323
|
-
), "Pre-tasks should be run just once"
|
|
324
|
-
|
|
325
|
-
|
|
326
306
|
def test_task_lightweight_init():
|
|
327
307
|
with TemporaryExperiment("lightweight_init", maxwait=20):
|
|
328
308
|
x = LightweightConfig.C()
|
|
@@ -16,14 +16,14 @@ experimaestro/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuF
|
|
|
16
16
|
experimaestro/core/arguments.py,sha256=gB0Kq9XL0_mYbm9WHL-mDx2tUGHI1pvsu1ahMaDxIY0,7170
|
|
17
17
|
experimaestro/core/callbacks.py,sha256=59JfeUgWcCCdIQ3pvh-xNnoRp9BX8f4iOAkgm16wBzE,1660
|
|
18
18
|
experimaestro/core/context.py,sha256=1tLmX7WcgEKSbGw77vfziTzS8KNsoZJ02JBWMBCqqOk,2606
|
|
19
|
-
experimaestro/core/identifier.py,sha256=
|
|
19
|
+
experimaestro/core/identifier.py,sha256=GmS3HtfLwirjoaVx6cZvLJL4r4546P0FFUSu2Nt0W9g,10812
|
|
20
20
|
experimaestro/core/objects/__init__.py,sha256=ucJY5e17QQ1Kc-GYXeL7g8GFj8rP0XB4g2vrl32uhxY,721
|
|
21
|
-
experimaestro/core/objects/config.py,sha256=
|
|
21
|
+
experimaestro/core/objects/config.py,sha256=Umw8wH_hL81OOqniMs9NErFjK-BOBlGfJ56PDFF8WzE,53142
|
|
22
22
|
experimaestro/core/objects/config_utils.py,sha256=ZLECGkeIWdzunm8vwWsQhvcSgV1e064BgXbLiZnxSEM,1288
|
|
23
|
-
experimaestro/core/objects/config_walk.py,sha256=
|
|
24
|
-
experimaestro/core/objects.pyi,sha256=
|
|
23
|
+
experimaestro/core/objects/config_walk.py,sha256=SYBrGuT7HV12no9mQd1HjnebiyygHyO-zq_TO1brUtc,4233
|
|
24
|
+
experimaestro/core/objects.pyi,sha256=Q1tq4F8LrExPm00E-P5aaygxMvViYZqhHvByo_TTZRE,6315
|
|
25
25
|
experimaestro/core/serialization.py,sha256=CSPEwOzlDsgAz6V2og-TgyU0RXDtzt_nXaoXFZleDZE,5775
|
|
26
|
-
experimaestro/core/serializers.py,sha256=
|
|
26
|
+
experimaestro/core/serializers.py,sha256=iOBuASEgD8dRKPnL16iOLBsM0GHChCJgjBd7LixFui4,919
|
|
27
27
|
experimaestro/core/types.py,sha256=aI-Qad27tkBFR5HyBCeeUwmZFIQif70__AR7enzpjvY,20938
|
|
28
28
|
experimaestro/core/utils.py,sha256=JfC3qGUS9b6FUHc2VxIYUI9ysNpXSQ1LjOBkjfZ8n7o,495
|
|
29
29
|
experimaestro/exceptions.py,sha256=cUy83WHM3GeynxmMk6QRr5xsnpqUAdAoc-m3KQVrE2o,44
|
|
@@ -122,24 +122,24 @@ experimaestro/tests/tasks/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJW
|
|
|
122
122
|
experimaestro/tests/tasks/all.py,sha256=OMkHsWZkErCmTajiNO7hNhvnk9eKzJC-VatWgabWlsI,1955
|
|
123
123
|
experimaestro/tests/tasks/foreign.py,sha256=uhXDOcWozkcm26ybbeEU9RElJpbhjC-zdzmlSKfPcdY,122
|
|
124
124
|
experimaestro/tests/test_checkers.py,sha256=e6Rv2TlePRY__VXs0vUb6a5Aw_KIq_cs4N86VhnYHtw,407
|
|
125
|
-
experimaestro/tests/test_dependencies.py,sha256=
|
|
125
|
+
experimaestro/tests/test_dependencies.py,sha256=LvpmMcfnRzQPzUIuFNCIQnJot8YBSxCA827xh9gYlq0,1890
|
|
126
126
|
experimaestro/tests/test_experiment.py,sha256=Nfevu_aMyX4c5xTjDHMeKXZWs2HMOhy96tsQlnF-IVs,1693
|
|
127
127
|
experimaestro/tests/test_file_progress.py,sha256=uNUUq-ptcnxu56zRvUUZ5EYM9ZIQbUmOU_LI0roMgSw,15119
|
|
128
128
|
experimaestro/tests/test_file_progress_integration.py,sha256=ejXASpdnpi6HUy569Q5Vx5F8SV_RDU-4o3yuQka6vS4,16751
|
|
129
129
|
experimaestro/tests/test_findlauncher.py,sha256=KPy8ow--NXS1KFCIpxrmEJFRvjo-v-PwlVHVyoVKLPg,3134
|
|
130
130
|
experimaestro/tests/test_forward.py,sha256=9y1zYm7hT_Lx5citxnK7n20cMZ2WJbsaEeY5irCZ9U4,735
|
|
131
131
|
experimaestro/tests/test_generators.py,sha256=R0UypTzxX0dPYvY4A_kozpLDHhGzQDNfLQyc0oRaSx8,2891
|
|
132
|
-
experimaestro/tests/test_identifier.py,sha256=
|
|
133
|
-
experimaestro/tests/test_instance.py,sha256=
|
|
132
|
+
experimaestro/tests/test_identifier.py,sha256=0uv7lsgLLzKHLinlq2J9yj9UyKG6ud1EYtxIyeXbyhE,14368
|
|
133
|
+
experimaestro/tests/test_instance.py,sha256=VFRvjy1OXGtGgkh__mf73KmJq4Lom7ppvBDkhE7rjTA,1325
|
|
134
134
|
experimaestro/tests/test_objects.py,sha256=hGku35h1qkNMIdgP_gWM7HeviaqW7jrZDffOsCJh-_Q,1787
|
|
135
135
|
experimaestro/tests/test_outputs.py,sha256=vilnECNfc-cyzDZjTvCgCSMesC7QwWTfhJtlOyM9kIM,797
|
|
136
136
|
experimaestro/tests/test_param.py,sha256=OW3uguPjy9U6f9BrLr8z4ieo88EH6da2zMho-FVwmKQ,7324
|
|
137
137
|
experimaestro/tests/test_progress.py,sha256=j-V65Adk9psBzMcSzlH7uSqDiLkYDd3Udpy1UCT8j2Y,7588
|
|
138
|
-
experimaestro/tests/test_serializers.py,sha256=
|
|
138
|
+
experimaestro/tests/test_serializers.py,sha256=dQkiuvHAQ1g-SCRCfOy977nQMWR7CFuBUud65N_vfiI,1248
|
|
139
139
|
experimaestro/tests/test_snippets.py,sha256=rojnyDjtmAMnSuDUj6Bv9XEgdP8oQf2nVc132JF8vsM,3081
|
|
140
140
|
experimaestro/tests/test_ssh.py,sha256=KS1NWltiXrJBSStY9d4mwrexeqgNGWmhxuAU_WLQDAU,1449
|
|
141
141
|
experimaestro/tests/test_tags.py,sha256=_FE0g1kCwrgy7AlLNmgYHol07lMk8Iyera60-gO2k-s,2886
|
|
142
|
-
experimaestro/tests/test_tasks.py,sha256=
|
|
142
|
+
experimaestro/tests/test_tasks.py,sha256=fr0e4X5xhzHtDUVyHU4wB00IXggWs-f5MzBBi_kHVZA,8895
|
|
143
143
|
experimaestro/tests/test_tokens.py,sha256=0PPVCBcYWzFqgCQEbJsNAZOIVZt4VVv2vu-W4sk0Ogg,7859
|
|
144
144
|
experimaestro/tests/test_types.py,sha256=Y76TvSv9euJqI6Zu14cnD8ldToWxts43yvGa7-HV2kA,1363
|
|
145
145
|
experimaestro/tests/test_validation.py,sha256=tinkXETcAGtgPIsmbioKSU00kGIV1YnniHTGDDcUOq8,4118
|
|
@@ -159,8 +159,8 @@ experimaestro/utils/multiprocessing.py,sha256=am3DkHP_kmWbpynbck2c9QystCUtPBoSAC
|
|
|
159
159
|
experimaestro/utils/resources.py,sha256=j-nvsTFwmgENMoVGOD2Ap-UD3WU85WkI0IgeSszMCX4,1328
|
|
160
160
|
experimaestro/utils/settings.py,sha256=jpFMqF0DLL4_P1xGal0zVR5cOrdD8O0Y2IOYvnRgN3k,793
|
|
161
161
|
experimaestro/xpmutils.py,sha256=S21eMbDYsHfvmZ1HmKpq5Pz5O-1HnCLYxKbyTBbASyQ,638
|
|
162
|
-
experimaestro-2.0.
|
|
163
|
-
experimaestro-2.0.
|
|
164
|
-
experimaestro-2.0.
|
|
165
|
-
experimaestro-2.0.
|
|
166
|
-
experimaestro-2.0.
|
|
162
|
+
experimaestro-2.0.0a6.dist-info/METADATA,sha256=OdsoYiYB38ga_dl_GBbZ8cFecIdsq2cks_DNLNh5IWo,5712
|
|
163
|
+
experimaestro-2.0.0a6.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
|
|
164
|
+
experimaestro-2.0.0a6.dist-info/entry_points.txt,sha256=TppTNiz5qm5xm1fhAcdLKdCLMrlL-eQggtCrCI00D9c,446
|
|
165
|
+
experimaestro-2.0.0a6.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
|
166
|
+
experimaestro-2.0.0a6.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|