dv-flow-mgr 0.0.1.13824531439a1__py3-none-any.whl → 0.0.1.13862522550a1__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.
- dv_flow/mgr/pkg_rgy.py +7 -0
- dv_flow/mgr/std/create_file.py +61 -0
- dv_flow/mgr/std/flow.dv +16 -0
- dv_flow/mgr/task_graph_builder.py +28 -1
- dv_flow/mgr/task_node.py +33 -25
- dv_flow/mgr/task_runner.py +5 -1
- {dv_flow_mgr-0.0.1.13824531439a1.dist-info → dv_flow_mgr-0.0.1.13862522550a1.dist-info}/METADATA +1 -1
- {dv_flow_mgr-0.0.1.13824531439a1.dist-info → dv_flow_mgr-0.0.1.13862522550a1.dist-info}/RECORD +12 -11
- {dv_flow_mgr-0.0.1.13824531439a1.dist-info → dv_flow_mgr-0.0.1.13862522550a1.dist-info}/LICENSE +0 -0
- {dv_flow_mgr-0.0.1.13824531439a1.dist-info → dv_flow_mgr-0.0.1.13862522550a1.dist-info}/WHEEL +0 -0
- {dv_flow_mgr-0.0.1.13824531439a1.dist-info → dv_flow_mgr-0.0.1.13862522550a1.dist-info}/entry_points.txt +0 -0
- {dv_flow_mgr-0.0.1.13824531439a1.dist-info → dv_flow_mgr-0.0.1.13862522550a1.dist-info}/top_level.txt +0 -0
dv_flow/mgr/pkg_rgy.py
CHANGED
@@ -32,6 +32,13 @@ class PkgRgy(object):
|
|
32
32
|
self._pkgpath = []
|
33
33
|
self._pkg_m : Dict[str, Tuple[str,PackageDef]] = {}
|
34
34
|
self._log = logging.getLogger(type(self).__name__)
|
35
|
+
self._override_m : Dict[str,str] = {}
|
36
|
+
|
37
|
+
def addOverride(self, key, value):
|
38
|
+
self._override_m[key] = value
|
39
|
+
|
40
|
+
def getOverrides(self):
|
41
|
+
return self._override_m
|
35
42
|
|
36
43
|
def hasPackage(self, name, search_path=True):
|
37
44
|
if name in self._pkg_m.keys():
|
@@ -0,0 +1,61 @@
|
|
1
|
+
import os
|
2
|
+
import hashlib
|
3
|
+
import logging
|
4
|
+
import pydantic.dataclasses as dc
|
5
|
+
from pydantic import BaseModel
|
6
|
+
from typing import ClassVar, List, Tuple
|
7
|
+
from dv_flow.mgr import TaskDataResult
|
8
|
+
from dv_flow.mgr import FileSet as _FileSet
|
9
|
+
|
10
|
+
class TaskCreateFileMemento(BaseModel):
|
11
|
+
name : str = ""
|
12
|
+
hash : str = ""
|
13
|
+
|
14
|
+
_log = logging.getLogger("CreateFile")
|
15
|
+
|
16
|
+
async def CreateFile(runner, input) -> TaskDataResult:
|
17
|
+
_log.debug("CreateFile run: %s: rundir=%s, type=%s filename=%s content=%s" % (
|
18
|
+
input.name,
|
19
|
+
input.rundir,
|
20
|
+
input.params.type, input.params.filename, input.params.content))
|
21
|
+
|
22
|
+
#
|
23
|
+
try:
|
24
|
+
ex_memento = TaskCreateFileMemento(**input.memento) if input.memento is not None else None
|
25
|
+
except Exception as e:
|
26
|
+
_log.error("Failed to load memento: %s" % str(e))
|
27
|
+
ex_memento = None
|
28
|
+
memento = TaskCreateFileMemento()
|
29
|
+
|
30
|
+
_log.debug("ex_memento: %s" % str(ex_memento))
|
31
|
+
_log.debug("params: %s" % str(input.params))
|
32
|
+
|
33
|
+
changed = (input.changed or ex_memento is None)
|
34
|
+
|
35
|
+
if not changed and ex_memento is not None:
|
36
|
+
if ex_memento.name != input.params.filename:
|
37
|
+
changed = True
|
38
|
+
else:
|
39
|
+
new_hash = hashlib.md5(input.params.content.encode()).hexdigest()
|
40
|
+
changed = ex_memento.hash != new_hash
|
41
|
+
|
42
|
+
if changed:
|
43
|
+
filename = os.path.join(input.rundir, input.params.filename)
|
44
|
+
os.makedirs(os.path.dirname(filename), exist_ok=True)
|
45
|
+
|
46
|
+
with open(filename, "w") as fp:
|
47
|
+
fp.write(input.params.content)
|
48
|
+
|
49
|
+
fs = _FileSet(
|
50
|
+
filetype=input.params.type,
|
51
|
+
src=input.name,
|
52
|
+
basedir=input.rundir,
|
53
|
+
files=[input.params.filename])
|
54
|
+
|
55
|
+
_log.debug("<-- FileSet(%s) changed=%s" % (input.name, changed))
|
56
|
+
|
57
|
+
return TaskDataResult(
|
58
|
+
memento=memento,
|
59
|
+
changed=changed,
|
60
|
+
output=[fs]
|
61
|
+
)
|
dv_flow/mgr/std/flow.dv
CHANGED
@@ -29,6 +29,22 @@ package:
|
|
29
29
|
exclude:
|
30
30
|
type: str
|
31
31
|
value: ""
|
32
|
+
- name: CreateFile
|
33
|
+
pytask: dv_flow.mgr.std.create_file.CreateFile
|
34
|
+
passthrough: true
|
35
|
+
doc: |
|
36
|
+
Creates one or more files in the run directory from
|
37
|
+
literal content in the .dv file. Outputs a fileset
|
38
|
+
referencing all the created files.
|
39
|
+
with:
|
40
|
+
type:
|
41
|
+
desc: Content-type to use for the fileset
|
42
|
+
type: str
|
43
|
+
value: ""
|
44
|
+
filename:
|
45
|
+
type: str
|
46
|
+
content:
|
47
|
+
type: str
|
32
48
|
- name: Exec
|
33
49
|
pytask: dv_flow.mgr.std.exec.Exec
|
34
50
|
with:
|
@@ -39,16 +39,20 @@ class TaskGraphBuilder(object):
|
|
39
39
|
_pkg_m : Dict[PackageSpec,Package] = dc.field(default_factory=dict)
|
40
40
|
_pkg_spec_s : List[PackageDef] = dc.field(default_factory=list)
|
41
41
|
_task_m : Dict['TaskSpec',Task] = dc.field(default_factory=dict)
|
42
|
+
_override_m : Dict[str,str] = dc.field(default_factory=dict)
|
42
43
|
_logger : logging.Logger = None
|
43
44
|
|
44
45
|
def __post_init__(self):
|
45
46
|
if self.pkg_rgy is None:
|
46
47
|
self.pkg_rgy = PkgRgy.inst().copy()
|
47
48
|
|
49
|
+
# Initialize the overrides from the global registry
|
50
|
+
self._override_m.update(self.pkg_rgy.getOverrides())
|
51
|
+
|
48
52
|
self._logger = logging.getLogger(type(self).__name__)
|
49
|
-
self._logger.debug("TaskGraphBuilder: root_pkg: %s" % str(self.root_pkg))
|
50
53
|
|
51
54
|
if self.root_pkg is not None:
|
55
|
+
self._logger.debug("TaskGraphBuilder: root_pkg: %s" % str(self.root_pkg))
|
52
56
|
|
53
57
|
# Register package definitions found during loading
|
54
58
|
visited = set()
|
@@ -61,6 +65,14 @@ class TaskGraphBuilder(object):
|
|
61
65
|
# Allows us to find ourselves
|
62
66
|
self._pkg_m[PackageSpec(self.root_pkg.name)] = pkg
|
63
67
|
|
68
|
+
def loadPkg(self, pkgfile : str):
|
69
|
+
pkg = PackageDef.load(pkgfile)
|
70
|
+
visited = set()
|
71
|
+
self._registerPackages(pkg, visited)
|
72
|
+
|
73
|
+
def addOverride(self, key : str, val : str):
|
74
|
+
self._override_m[key] = val
|
75
|
+
|
64
76
|
def _registerPackages(self, pkg : PackageDef, visited):
|
65
77
|
self._logger.debug("Packages: %s" % str(pkg))
|
66
78
|
if pkg.name not in visited:
|
@@ -210,6 +222,21 @@ class TaskGraphBuilder(object):
|
|
210
222
|
|
211
223
|
def mkTaskNode(self, task_t, name=None, srcdir=None, needs=None, **kwargs):
|
212
224
|
self._logger.debug("--> mkTaskNode: %s" % task_t)
|
225
|
+
|
226
|
+
if task_t in self._override_m.keys():
|
227
|
+
self._logger.debug("Overriding task %s with %s" % (task_t, self._override_m[task_t]))
|
228
|
+
task_t = self._override_m[task_t]
|
229
|
+
else:
|
230
|
+
dot_idx = task_t.rfind(".")
|
231
|
+
if dot_idx != -1:
|
232
|
+
pkg = task_t[0:dot_idx]
|
233
|
+
tname = task_t[dot_idx+1:]
|
234
|
+
|
235
|
+
if pkg in self._override_m.keys():
|
236
|
+
self._logger.debug("Overriding package %s with %s" % (pkg, self._override_m[pkg]))
|
237
|
+
task_t = self._override_m[pkg] + "." + tname
|
238
|
+
|
239
|
+
|
213
240
|
ctor = self.getTaskCtor(task_t)
|
214
241
|
self._logger.debug("ctor: %s" % ctor.name)
|
215
242
|
params = ctor.mkTaskParams(kwargs)
|
dv_flow/mgr/task_node.py
CHANGED
@@ -58,8 +58,8 @@ class TaskNode(object):
|
|
58
58
|
if subdep not in dep_m.keys():
|
59
59
|
dep_m[subdep] = []
|
60
60
|
dep_m[subdep].extend(need.output.dep_m[subdep])
|
61
|
+
self._log.debug("input dep_m: %s %s" % (self.name, str(dep_m)))
|
61
62
|
|
62
|
-
self._log.debug("input dep_m: %s" % str(dep_m))
|
63
63
|
sorted = toposort.toposort(dep_m)
|
64
64
|
|
65
65
|
in_params_m = {}
|
@@ -127,10 +127,12 @@ class TaskNode(object):
|
|
127
127
|
|
128
128
|
self._log.debug("output[1]: %s" % str(output))
|
129
129
|
|
130
|
+
# Pass-through all dependencies
|
131
|
+
# Add an entry for ourselves
|
132
|
+
dep_m[self.name] = list(need.name for need in self.needs)
|
133
|
+
|
130
134
|
if self.passthrough:
|
131
135
|
self._log.debug("passthrough: %s" % self.name)
|
132
|
-
# Add an entry for ourselves
|
133
|
-
dep_m[self.name] = list(need.name for need in self.needs)
|
134
136
|
|
135
137
|
if self.consumes is None and len(self.consumes):
|
136
138
|
self._log.debug("Propagating all input parameters to output")
|
@@ -167,11 +169,11 @@ class TaskNode(object):
|
|
167
169
|
else:
|
168
170
|
self._log.debug("non-passthrough: %s (only local outputs propagated)" % self.name)
|
169
171
|
# empty dependency map
|
170
|
-
dep_m = {
|
171
|
-
self.name : []
|
172
|
-
}
|
172
|
+
# dep_m = {
|
173
|
+
# self.name : []
|
174
|
+
# }
|
173
175
|
|
174
|
-
self._log.debug("output dep_m: %s" % str(dep_m))
|
176
|
+
self._log.debug("output dep_m: %s %s" % (self.name, str(dep_m)))
|
175
177
|
self._log.debug("output[2]: %s" % str(output))
|
176
178
|
|
177
179
|
# Store the result
|
@@ -187,6 +189,30 @@ class TaskNode(object):
|
|
187
189
|
|
188
190
|
def __hash__(self):
|
189
191
|
return id(self)
|
192
|
+
|
193
|
+
def _matches(self, params, consumes):
|
194
|
+
"""Determines if a parameter set matches a set of consumed parameters"""
|
195
|
+
self._log.debug("--> _matches: %s params=%s consumes=%s" % (
|
196
|
+
self.name, str(params), str(consumes)))
|
197
|
+
consumed = False
|
198
|
+
for c in consumes:
|
199
|
+
# All matching attribute keys must have same value
|
200
|
+
match = False
|
201
|
+
for k,v in c.items():
|
202
|
+
self._log.debug("k,v: %s,%s - hasattr=%s" % (k,v, hasattr(params, k)))
|
203
|
+
if hasattr(params, k):
|
204
|
+
self._log.debug("getattr=%s v=%s" % (getattr(params, k), v))
|
205
|
+
if getattr(params, k) == v:
|
206
|
+
match = True
|
207
|
+
else:
|
208
|
+
match = False
|
209
|
+
break
|
210
|
+
if match:
|
211
|
+
consumed = True
|
212
|
+
break
|
213
|
+
self._log.debug("<-- _matches: %s %s" % (self.name, consumed))
|
214
|
+
return consumed
|
215
|
+
|
190
216
|
|
191
217
|
|
192
218
|
@dc.dataclass
|
@@ -353,24 +379,6 @@ class TaskNodeCtorWrapper(TaskNodeCtor):
|
|
353
379
|
setattr(obj, key, value)
|
354
380
|
return obj
|
355
381
|
|
356
|
-
def _matches(self, params, consumes):
|
357
|
-
"""Determines if a parameter set matches a set of consumed parameters"""
|
358
|
-
consumed = False
|
359
|
-
for c in consumes:
|
360
|
-
# All matching attribute keys must have same value
|
361
|
-
match = False
|
362
|
-
for k,v in c.items():
|
363
|
-
if hasattr(params, k):
|
364
|
-
if getattr(params, k) != v:
|
365
|
-
match = True
|
366
|
-
else:
|
367
|
-
match = False
|
368
|
-
break
|
369
|
-
if match:
|
370
|
-
consumed = True
|
371
|
-
break
|
372
|
-
return consumed
|
373
|
-
|
374
382
|
def task(paramT,passthrough=False,consumes=None):
|
375
383
|
"""Decorator to wrap a task method as a TaskNodeCtor"""
|
376
384
|
def wrapper(T):
|
dv_flow/mgr/task_runner.py
CHANGED
@@ -38,13 +38,17 @@ class TaskRunner(object):
|
|
38
38
|
|
39
39
|
@dc.dataclass
|
40
40
|
class TaskSetRunner(TaskRunner):
|
41
|
-
nproc : int =
|
41
|
+
nproc : int = -1
|
42
42
|
status : int = 0
|
43
43
|
|
44
44
|
_anon_tid : int = 1
|
45
45
|
|
46
46
|
_log : ClassVar = logging.getLogger("TaskSetRunner")
|
47
47
|
|
48
|
+
def __post_init__(self):
|
49
|
+
if self.nproc == -1:
|
50
|
+
self.nproc = os.cpu_count()
|
51
|
+
|
48
52
|
async def run(self, task : Union[TaskNode,List[TaskNode]]):
|
49
53
|
# Ensure that the rundir exists or can be created
|
50
54
|
|
{dv_flow_mgr-0.0.1.13824531439a1.dist-info → dv_flow_mgr-0.0.1.13862522550a1.dist-info}/RECORD
RENAMED
@@ -13,35 +13,36 @@ dv_flow/mgr/param.py,sha256=3BY-ucig6JRw73FhjyJQL-vpd57qhAzixgZ8I5FoUpw,553
|
|
13
13
|
dv_flow/mgr/param_def.py,sha256=gLua-EQiY8V2CFX-2svLRIlrs8PEeGh4-EPtn4a2Mng,712
|
14
14
|
dv_flow/mgr/param_ref_eval.py,sha256=U8QhDf1n_9bLnExdc1oQamq5-pOUXrFalOX4oyR9UoM,1138
|
15
15
|
dv_flow/mgr/parsetab.py,sha256=I-p3nC60t9jiNtPhKyl_sE92SiP96zJLnNdydcLy33g,3780
|
16
|
-
dv_flow/mgr/pkg_rgy.py,sha256=
|
16
|
+
dv_flow/mgr/pkg_rgy.py,sha256=UGQvBYUbAiabiBk8lKxknpk-yAOVfgeQzTB180iG9h4,5332
|
17
17
|
dv_flow/mgr/task.py,sha256=kLQSvnVwj9ROIDtxq8lLu-4mJizTxOqvUeogmgN6QAA,5976
|
18
18
|
dv_flow/mgr/task_ctor.py,sha256=hlfl-UVvyjzLFN6D0Oel9eBs0xUQPqCX7gQ0uEHoL7o,1382
|
19
19
|
dv_flow/mgr/task_data.py,sha256=m3W7k-xv09ZyhpP2gg33CLOhBLyQDJS2mlG35yOZjZQ,11432
|
20
20
|
dv_flow/mgr/task_def.py,sha256=Wmh78mQLAiHXlpD2KCvFxTWtnjjwgct8fEm8gelCg1c,1987
|
21
21
|
dv_flow/mgr/task_exec_data.py,sha256=aT__kmVmNxqnS_GbTRS1vrYgKiv8cH-HUSmRb6YYKsI,640
|
22
|
-
dv_flow/mgr/task_graph_builder.py,sha256=
|
22
|
+
dv_flow/mgr/task_graph_builder.py,sha256=a9g_2WYlxqD_3R9wa7QDKxA5lqQozGskb8afg8ArP1Y,10101
|
23
23
|
dv_flow/mgr/task_graph_runner.py,sha256=jUGI49QvxUCfQoKQDDk2psbeapIcCg72qNOW1JipHzM,2182
|
24
24
|
dv_flow/mgr/task_graph_runner_local.py,sha256=OrydPwtQ8E7hYWvSXx0h7lI3nfUNFyklULhsyMwz9dA,4687
|
25
25
|
dv_flow/mgr/task_impl_data.py,sha256=bFPijoKrh9x7fZN2DsvRJp0UHo-gGM0VjtDQISyfhFk,321
|
26
26
|
dv_flow/mgr/task_listener_log.py,sha256=d4GQcT3n_0Dq-XWQP-WNJIhuxvw948RbFPSiJ6X1_eI,2683
|
27
27
|
dv_flow/mgr/task_memento.py,sha256=C7VTQpBhDEoYuDmE6YTM-6TLMLnqHp6Y0Vat1aTgtCs,1096
|
28
|
-
dv_flow/mgr/task_node.py,sha256=
|
28
|
+
dv_flow/mgr/task_node.py,sha256=I1wbq-EpuZZ94R42rtBSQRnk-2Yf6ZQhctsxjn2Vbus,14228
|
29
29
|
dv_flow/mgr/task_output.py,sha256=dkJhhNRFGFQSkVsw_bGirK0_0ghTxBYq1LjRMZCVWnA,245
|
30
30
|
dv_flow/mgr/task_params_ctor.py,sha256=aXgB8o9xFPjaEjGW_xYkEC0N0apzGzGUPDj7g2ZLvus,1112
|
31
|
-
dv_flow/mgr/task_runner.py,sha256=
|
31
|
+
dv_flow/mgr/task_runner.py,sha256=NFGAAlOKMeXkWQtSX3YcZ6RMPn5xlZ92R6q57xPpueg,7922
|
32
32
|
dv_flow/mgr/type.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
33
33
|
dv_flow/mgr/type_def.py,sha256=KdhuNlfw-NKU-4VZFCnMPyj775yEB7cpr5tz73a9yuQ,259
|
34
34
|
dv_flow/mgr/util.py,sha256=06eVyURF4ga-s8C9Sd3ZSDebwO4QS0XXaB8xADVbWRc,1437
|
35
35
|
dv_flow/mgr/cmds/cmd_run.py,sha256=w1KdnS5Skg4RH1xTB1RZP7gAElZMNcRuOhz3G98n9uk,2467
|
36
36
|
dv_flow/mgr/share/flow.json,sha256=lNmZex9NXkYbyb2aZseQfUOkV9CMyfH0iLODEI7EPBw,5096
|
37
|
+
dv_flow/mgr/std/create_file.py,sha256=gPNasXwjg3NSIc2QhMp-UlBW1r5dRDLt6pluFTJhfek,1886
|
37
38
|
dv_flow/mgr/std/exec.py,sha256=ETx9xSxhdCD_iw6pcmhrafDCJ-41AneyEAPwQf3q-3w,452
|
38
39
|
dv_flow/mgr/std/fileset.py,sha256=nW5Cg4IyCs-ccKKsIxA5W5aZvaluFk6LXDyFh9Jixcs,3076
|
39
|
-
dv_flow/mgr/std/flow.dv,sha256=
|
40
|
+
dv_flow/mgr/std/flow.dv,sha256=CcQOvSfT0JgsaNf7dH8gfbG8lPvQQXw9W9gqrT52Pw0,2025
|
40
41
|
dv_flow/mgr/std/message.py,sha256=T8Ye44784rD6CT2qIAP5SD7sKPdAlGMFimc4IaPCxxE,200
|
41
42
|
dv_flow/mgr/std/task_null.py,sha256=UKwUnqwFPBY8BO44ZAPcgehQB59kHZFa1qyZc1TwUqE,196
|
42
|
-
dv_flow_mgr-0.0.1.
|
43
|
-
dv_flow_mgr-0.0.1.
|
44
|
-
dv_flow_mgr-0.0.1.
|
45
|
-
dv_flow_mgr-0.0.1.
|
46
|
-
dv_flow_mgr-0.0.1.
|
47
|
-
dv_flow_mgr-0.0.1.
|
43
|
+
dv_flow_mgr-0.0.1.13862522550a1.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
44
|
+
dv_flow_mgr-0.0.1.13862522550a1.dist-info/METADATA,sha256=B8h8L4Nr9ywSDxAGO4ElhZg4cIHndSyJCmNRMJGP4d4,13314
|
45
|
+
dv_flow_mgr-0.0.1.13862522550a1.dist-info/WHEEL,sha256=52BFRY2Up02UkjOa29eZOS2VxUrpPORXg1pkohGGUS8,91
|
46
|
+
dv_flow_mgr-0.0.1.13862522550a1.dist-info/entry_points.txt,sha256=1roy8wAFM48LabOvr6jiOw0MUs-qE8X3Vf8YykPazxk,50
|
47
|
+
dv_flow_mgr-0.0.1.13862522550a1.dist-info/top_level.txt,sha256=amfVTkggzYPtWwLqNmRukfz1Buu0pGS2SrYBBLhXm04,8
|
48
|
+
dv_flow_mgr-0.0.1.13862522550a1.dist-info/RECORD,,
|
{dv_flow_mgr-0.0.1.13824531439a1.dist-info → dv_flow_mgr-0.0.1.13862522550a1.dist-info}/LICENSE
RENAMED
File without changes
|
{dv_flow_mgr-0.0.1.13824531439a1.dist-info → dv_flow_mgr-0.0.1.13862522550a1.dist-info}/WHEEL
RENAMED
File without changes
|
File without changes
|
File without changes
|