dv-flow-mgr 0.0.1.13478128278a1__py3-none-any.whl → 0.0.1.13489806632a1__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.
@@ -0,0 +1,80 @@
1
+
2
+ import dataclasses as dc
3
+ import logging
4
+ from typing import Any, Callable, ClassVar, Dict, List
5
+ from .task_data import TaskDataInput, TaskDataOutput, TaskDataResult
6
+ from .task_params_ctor import TaskParamsCtor
7
+
8
+ @dc.dataclass
9
+ class TaskNode(object):
10
+ """Executable view of a task"""
11
+ # Ctor fields -- must specify on construction
12
+ name : str
13
+ srcdir : str
14
+ # This can be the resolved parameters
15
+ params : TaskParamsCtor
16
+
17
+ task : Callable[['TaskRunner','TaskDataInput'],'TaskDataResult']
18
+
19
+ # Runtime fields -- these get populated during execution
20
+ changed : bool = False
21
+ needs : List['TaskNode'] = dc.field(default_factory=list)
22
+ rundir : str = dc.field(default=None)
23
+ output : TaskDataOutput = dc.field(default=None)
24
+
25
+ _log : ClassVar = logging.getLogger("TaskNode")
26
+
27
+ def __hash__(self):
28
+ return id(self)
29
+
30
+ @staticmethod
31
+ def task(paramT):
32
+ def wrapper(T):
33
+ ctor = TaskNodeCtorWrapper(T.__name__, T, paramT)
34
+ return ctor
35
+ return wrapper
36
+
37
+ @dc.dataclass
38
+ class TaskNodeCtor(object):
39
+ """
40
+ Factory for a specific task type
41
+ - Produces a task parameters object, applying value-setting instructions
42
+ - Produces a TaskNode
43
+ """
44
+ name : str
45
+
46
+
47
+ def mkTaskNode(self, srcdir, params, name=None) -> TaskNode:
48
+ raise NotImplementedError("mkTaskNode in type %s" % str(type(self)))
49
+
50
+ def mkTaskParams(self, params : Dict) -> Any:
51
+ raise NotImplementedError("mkTaskParams in type %s" % str(type(self)))
52
+
53
+ @dc.dataclass
54
+ class TaskNodeCtorWrapper(TaskNodeCtor):
55
+ T : Any
56
+ paramT : Any
57
+
58
+ def __call__(self,
59
+ srcdir,
60
+ name=None,
61
+ params=None,
62
+ needs=None,
63
+ **kwargs):
64
+ """Convenience method for direct creation of tasks"""
65
+ if params is None:
66
+ params = self.mkTaskParams(kwargs)
67
+
68
+ node = self.mkTaskNode(srcdir, params, name)
69
+ if needs is not None:
70
+ node.needs.extend(needs)
71
+ return node
72
+
73
+ def mkTaskNode(self, srcdir, params, name=None) -> TaskNode:
74
+ node = TaskNode(name, srcdir, params, self.T)
75
+ return node
76
+
77
+ def mkTaskParams(self, params : Dict) -> Any:
78
+ obj = self.paramT()
79
+ # TODO: apply user-specified params
80
+ return obj
@@ -1,6 +1,9 @@
1
+ import asyncio
1
2
  import dataclasses as dc
2
- from .task_data import TaskDataInput, TaskDataResult
3
- from typing import Any, Callable, List, Tuple
3
+ from toposort import toposort
4
+ from typing import Any, Callable, List, Tuple, Union
5
+ from .task_data import TaskDataInput, TaskDataOutput, TaskDataResult
6
+ from .task_node import TaskNode
4
7
 
5
8
  @dc.dataclass
6
9
  class TaskRunner(object):
@@ -19,6 +22,98 @@ class TaskRunner(object):
19
22
  memento : Any = None) -> 'TaskDataResult':
20
23
  pass
21
24
 
25
+ @dc.dataclass
26
+ class TaskSetRunner(TaskRunner):
27
+ nproc : int = 8
28
+
29
+ async def run(self, task : Union[TaskNode,List[TaskNode]]):
30
+ # First, build a depedency map
31
+ tasks = task if isinstance(task, list) else [task]
32
+ dep_m = {}
33
+ for t in tasks:
34
+ self._buildDepMap(dep_m, t)
35
+
36
+ print("dep_m: %s" % str(dep_m))
37
+
38
+ order = list(toposort(dep_m))
39
+
40
+ active_task_l = []
41
+ done_task_s = set()
42
+ for active_s in order:
43
+ done = True
44
+ for t in active_s:
45
+ while len(active_task_l) >= self.nproc and t not in done_task_s:
46
+ # Wait for at least one job to complete
47
+ done, pending = await asyncio.wait(at[1] for at in active_task_l)
48
+ for d in done:
49
+ for i in range(len(active_task_l)):
50
+ if active_task_l[i][1] == d:
51
+ tt = active_task_l[i][0]
52
+ done_task_s.add(tt)
53
+ active_task_l.pop(i)
54
+ break
55
+ if t not in done_task_s:
56
+ coro = asyncio.Task(self.do_run(t))
57
+ active_task_l.append((t, coro))
58
+
59
+ # Now, wait for tasks to complete
60
+ if len(active_task_l):
61
+ coros = list(at[1] for at in active_task_l)
62
+ res = await asyncio.gather(*coros)
63
+
64
+
65
+ pass
66
+
67
+ async def do_run(self,
68
+ task : 'TaskNode',
69
+ memento : Any = None) -> 'TaskDataResult':
70
+ changed = False
71
+ for dep in task.needs:
72
+ changed |= dep.changed
73
+
74
+ # TODO: create an evaluator for substituting param values
75
+ eval = None
76
+
77
+ for field in dc.fields(task.params):
78
+ print("Field: %s" % field.name)
79
+
80
+ input = TaskDataInput(
81
+ changed=changed,
82
+ srcdir=task.srcdir,
83
+ rundir=self.rundir,
84
+ params=task.params,
85
+ memento=memento)
86
+
87
+ # TODO: notify of task start
88
+ ret : TaskDataResult = await task.task(self, input)
89
+ # TODO: notify of task complete
90
+
91
+ # Store the result
92
+ task.output = TaskDataOutput(
93
+ changed=ret.changed,
94
+ output=ret.output.copy())
95
+
96
+ # # By definition, none of this have run, since we just ran
97
+ # for dep in task.dependents:
98
+ # is_sat = True
99
+ # for need in dep.needs:
100
+ # if need.output is None:
101
+ # is_sat = False
102
+ # break
103
+
104
+ # if is_sat:
105
+ # # TODO: queue task for evaluation
106
+ # pass
107
+ # TODO:
108
+
109
+ return ret
110
+
111
+ def _buildDepMap(self, dep_m, task : TaskNode):
112
+ if task not in dep_m.keys():
113
+ dep_m[task] = set(task.needs)
114
+ for need in task.needs:
115
+ self._buildDepMap(dep_m, need)
116
+
22
117
  @dc.dataclass
23
118
  class SingleTaskRunner(TaskRunner):
24
119
 
@@ -32,15 +127,36 @@ class SingleTaskRunner(TaskRunner):
32
127
  # TODO: create an evaluator for substituting param values
33
128
  eval = None
34
129
 
35
- params = task.params.mk(eval)
130
+ for field in dc.fields(task.params):
131
+ print("Field: %s" % field.name)
36
132
 
37
133
  input = TaskDataInput(
38
134
  changed=changed,
39
135
  srcdir=task.srcdir,
40
136
  rundir=self.rundir,
41
- params=params,
137
+ params=task.params,
42
138
  memento=memento)
43
-
44
- ret = await task.run(self, input)
139
+
140
+ # TODO: notify of task start
141
+ ret : TaskDataResult = await task.task(self, input)
142
+ # TODO: notify of task complete
143
+
144
+ # Store the result
145
+ task.output = TaskDataOutput(
146
+ changed=ret.changed,
147
+ output=ret.output.copy())
148
+
149
+ # # By definition, none of this have run, since we just ran
150
+ # for dep in task.dependents:
151
+ # is_sat = True
152
+ # for need in dep.needs:
153
+ # if need.output is None:
154
+ # is_sat = False
155
+ # break
156
+
157
+ # if is_sat:
158
+ # # TODO: queue task for evaluation
159
+ # pass
160
+ # TODO:
45
161
 
46
162
  return ret
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: dv-flow-mgr
3
- Version: 0.0.1.13478128278a1
3
+ Version: 0.0.1.13489806632a1
4
4
  Summary: DV Flow Manager is a build system for silicon design
5
5
  Author-email: Matthew Ballance <matt.ballance@gmail.com>
6
6
  License: Apache License
@@ -21,9 +21,10 @@ dv_flow/mgr/task_graph_runner.py,sha256=jUGI49QvxUCfQoKQDDk2psbeapIcCg72qNOW1Jip
21
21
  dv_flow/mgr/task_graph_runner_local.py,sha256=OrydPwtQ8E7hYWvSXx0h7lI3nfUNFyklULhsyMwz9dA,4687
22
22
  dv_flow/mgr/task_impl_data.py,sha256=bFPijoKrh9x7fZN2DsvRJp0UHo-gGM0VjtDQISyfhFk,321
23
23
  dv_flow/mgr/task_memento.py,sha256=C7VTQpBhDEoYuDmE6YTM-6TLMLnqHp6Y0Vat1aTgtCs,1096
24
+ dv_flow/mgr/task_node.py,sha256=wcvxdtrRNwPwV494DerrB79PFYAv6bPdWZDvRGQ0V6Q,2318
24
25
  dv_flow/mgr/task_output.py,sha256=l-W-FvVo6YDah1RQS-I9N0KUtB3vp-kl7lxIdmNz0l4,178
25
26
  dv_flow/mgr/task_params_ctor.py,sha256=aXgB8o9xFPjaEjGW_xYkEC0N0apzGzGUPDj7g2ZLvus,1112
26
- dv_flow/mgr/task_runner.py,sha256=XrVYZ13qIbGDkLgDT-NAq_qd2plCqVjHKEe25MD-7xE,1272
27
+ dv_flow/mgr/task_runner.py,sha256=5vCKM2UFxdHB9OslUVIx5Ipc0r04Cizvrc2YSKGMqqI,5055
27
28
  dv_flow/mgr/type.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
28
29
  dv_flow/mgr/type_def.py,sha256=KdhuNlfw-NKU-4VZFCnMPyj775yEB7cpr5tz73a9yuQ,259
29
30
  dv_flow/mgr/util.py,sha256=06eVyURF4ga-s8C9Sd3ZSDebwO4QS0XXaB8xADVbWRc,1437
@@ -33,9 +34,9 @@ dv_flow/mgr/std/fileset.py,sha256=uP7bGntRq-Tn5_GEFnt0_J_OAmfvep3GlCwCuE8by4o,27
33
34
  dv_flow/mgr/std/flow.dv,sha256=j9wLrF3Ghh1ZLbJxmk7WiNiRYUYEer-8CCUA5hsgtfk,1409
34
35
  dv_flow/mgr/std/message.py,sha256=BPTHnEMD4tBufQ9LvsS9Sa_0xjaJATbBpwqosWslvVA,193
35
36
  dv_flow/mgr/std/task_null.py,sha256=KObmjG_4D08GJ1k6neqKIQrFY72Sj0jLnwXxEkq5HA0,321
36
- dv_flow_mgr-0.0.1.13478128278a1.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
37
- dv_flow_mgr-0.0.1.13478128278a1.dist-info/METADATA,sha256=HCQCME5rxfNs5HNZ0WmoQtIQMTWNtZzkGrfwhXoO09I,13276
38
- dv_flow_mgr-0.0.1.13478128278a1.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
39
- dv_flow_mgr-0.0.1.13478128278a1.dist-info/entry_points.txt,sha256=1roy8wAFM48LabOvr6jiOw0MUs-qE8X3Vf8YykPazxk,50
40
- dv_flow_mgr-0.0.1.13478128278a1.dist-info/top_level.txt,sha256=amfVTkggzYPtWwLqNmRukfz1Buu0pGS2SrYBBLhXm04,8
41
- dv_flow_mgr-0.0.1.13478128278a1.dist-info/RECORD,,
37
+ dv_flow_mgr-0.0.1.13489806632a1.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
38
+ dv_flow_mgr-0.0.1.13489806632a1.dist-info/METADATA,sha256=iGQC00bCbcchWcesU4kXOBNBn-ggHWurn1YqLBKB610,13276
39
+ dv_flow_mgr-0.0.1.13489806632a1.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
40
+ dv_flow_mgr-0.0.1.13489806632a1.dist-info/entry_points.txt,sha256=1roy8wAFM48LabOvr6jiOw0MUs-qE8X3Vf8YykPazxk,50
41
+ dv_flow_mgr-0.0.1.13489806632a1.dist-info/top_level.txt,sha256=amfVTkggzYPtWwLqNmRukfz1Buu0pGS2SrYBBLhXm04,8
42
+ dv_flow_mgr-0.0.1.13489806632a1.dist-info/RECORD,,