dv-flow-mgr 0.0.1.13478128278a1__tar.gz → 0.0.1.13489806632a1__tar.gz

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 (96) hide show
  1. {dv_flow_mgr-0.0.1.13478128278a1 → dv_flow_mgr-0.0.1.13489806632a1}/PKG-INFO +1 -1
  2. dv_flow_mgr-0.0.1.13489806632a1/docs/Tasks.md +19 -0
  3. {dv_flow_mgr-0.0.1.13478128278a1 → dv_flow_mgr-0.0.1.13489806632a1}/pyproject.toml +1 -1
  4. dv_flow_mgr-0.0.1.13489806632a1/src/dv_flow/mgr/task_node.py +80 -0
  5. dv_flow_mgr-0.0.1.13489806632a1/src/dv_flow/mgr/task_runner.py +162 -0
  6. {dv_flow_mgr-0.0.1.13478128278a1 → dv_flow_mgr-0.0.1.13489806632a1}/src/dv_flow_mgr.egg-info/PKG-INFO +1 -1
  7. {dv_flow_mgr-0.0.1.13478128278a1 → dv_flow_mgr-0.0.1.13489806632a1}/src/dv_flow_mgr.egg-info/SOURCES.txt +2 -0
  8. dv_flow_mgr-0.0.1.13489806632a1/tests/unit/test_pytask_smoke.py +96 -0
  9. dv_flow_mgr-0.0.1.13478128278a1/src/dv_flow/mgr/task_runner.py +0 -46
  10. dv_flow_mgr-0.0.1.13478128278a1/tests/unit/test_pytask_smoke.py +0 -59
  11. {dv_flow_mgr-0.0.1.13478128278a1 → dv_flow_mgr-0.0.1.13489806632a1}/.github/workflows/ci.yml +0 -0
  12. {dv_flow_mgr-0.0.1.13478128278a1 → dv_flow_mgr-0.0.1.13489806632a1}/.gitignore +0 -0
  13. {dv_flow_mgr-0.0.1.13478128278a1 → dv_flow_mgr-0.0.1.13489806632a1}/.vscode/settings.json +0 -0
  14. {dv_flow_mgr-0.0.1.13478128278a1 → dv_flow_mgr-0.0.1.13489806632a1}/LICENSE +0 -0
  15. {dv_flow_mgr-0.0.1.13478128278a1 → dv_flow_mgr-0.0.1.13489806632a1}/README.md +0 -0
  16. {dv_flow_mgr-0.0.1.13478128278a1 → dv_flow_mgr-0.0.1.13489806632a1}/docs/KeyArchitecture.md +0 -0
  17. {dv_flow_mgr-0.0.1.13478128278a1 → dv_flow_mgr-0.0.1.13489806632a1}/docs/Makefile +0 -0
  18. {dv_flow_mgr-0.0.1.13478128278a1 → dv_flow_mgr-0.0.1.13489806632a1}/docs/Notes.md +0 -0
  19. {dv_flow_mgr-0.0.1.13478128278a1 → dv_flow_mgr-0.0.1.13489806632a1}/docs/Roadmap.md +0 -0
  20. {dv_flow_mgr-0.0.1.13478128278a1 → dv_flow_mgr-0.0.1.13489806632a1}/docs/RundirLayout.md +0 -0
  21. {dv_flow_mgr-0.0.1.13478128278a1 → dv_flow_mgr-0.0.1.13489806632a1}/docs/Stages.md +0 -0
  22. {dv_flow_mgr-0.0.1.13478128278a1 → dv_flow_mgr-0.0.1.13489806632a1}/docs/Steps.md +0 -0
  23. {dv_flow_mgr-0.0.1.13478128278a1 → dv_flow_mgr-0.0.1.13489806632a1}/docs/TypesAndDefs.md +0 -0
  24. {dv_flow_mgr-0.0.1.13478128278a1 → dv_flow_mgr-0.0.1.13489806632a1}/docs/Usecases.md +0 -0
  25. {dv_flow_mgr-0.0.1.13478128278a1 → dv_flow_mgr-0.0.1.13489806632a1}/docs/conf.py +0 -0
  26. {dv_flow_mgr-0.0.1.13478128278a1 → dv_flow_mgr-0.0.1.13489806632a1}/docs/index.rst +0 -0
  27. {dv_flow_mgr-0.0.1.13478128278a1 → dv_flow_mgr-0.0.1.13489806632a1}/docs/intro.rst +0 -0
  28. {dv_flow_mgr-0.0.1.13478128278a1 → dv_flow_mgr-0.0.1.13489806632a1}/docs/quickstart.rst +0 -0
  29. {dv_flow_mgr-0.0.1.13478128278a1 → dv_flow_mgr-0.0.1.13489806632a1}/docs/reference.rst +0 -0
  30. {dv_flow_mgr-0.0.1.13478128278a1 → dv_flow_mgr-0.0.1.13489806632a1}/ivpm.yaml +0 -0
  31. {dv_flow_mgr-0.0.1.13478128278a1 → dv_flow_mgr-0.0.1.13489806632a1}/setup.cfg +0 -0
  32. {dv_flow_mgr-0.0.1.13478128278a1 → dv_flow_mgr-0.0.1.13489806632a1}/src/dv_flow/mgr/__init__.py +0 -0
  33. {dv_flow_mgr-0.0.1.13478128278a1 → dv_flow_mgr-0.0.1.13489806632a1}/src/dv_flow/mgr/__main__.py +0 -0
  34. {dv_flow_mgr-0.0.1.13478128278a1 → dv_flow_mgr-0.0.1.13489806632a1}/src/dv_flow/mgr/cmds/cmd_run.py +0 -0
  35. {dv_flow_mgr-0.0.1.13478128278a1 → dv_flow_mgr-0.0.1.13489806632a1}/src/dv_flow/mgr/expr_eval.py +0 -0
  36. {dv_flow_mgr-0.0.1.13478128278a1 → dv_flow_mgr-0.0.1.13489806632a1}/src/dv_flow/mgr/expr_parser.py +0 -0
  37. {dv_flow_mgr-0.0.1.13478128278a1 → dv_flow_mgr-0.0.1.13489806632a1}/src/dv_flow/mgr/fileset.py +0 -0
  38. {dv_flow_mgr-0.0.1.13478128278a1 → dv_flow_mgr-0.0.1.13489806632a1}/src/dv_flow/mgr/fragment_def.py +0 -0
  39. {dv_flow_mgr-0.0.1.13478128278a1 → dv_flow_mgr-0.0.1.13489806632a1}/src/dv_flow/mgr/out +0 -0
  40. {dv_flow_mgr-0.0.1.13478128278a1 → dv_flow_mgr-0.0.1.13489806632a1}/src/dv_flow/mgr/package.py +0 -0
  41. {dv_flow_mgr-0.0.1.13478128278a1 → dv_flow_mgr-0.0.1.13489806632a1}/src/dv_flow/mgr/package_def.py +0 -0
  42. {dv_flow_mgr-0.0.1.13478128278a1 → dv_flow_mgr-0.0.1.13489806632a1}/src/dv_flow/mgr/package_import_spec.py +0 -0
  43. {dv_flow_mgr-0.0.1.13478128278a1 → dv_flow_mgr-0.0.1.13489806632a1}/src/dv_flow/mgr/param_def.py +0 -0
  44. {dv_flow_mgr-0.0.1.13478128278a1 → dv_flow_mgr-0.0.1.13489806632a1}/src/dv_flow/mgr/parsetab.py +0 -0
  45. {dv_flow_mgr-0.0.1.13478128278a1 → dv_flow_mgr-0.0.1.13489806632a1}/src/dv_flow/mgr/pkg_rgy.py +0 -0
  46. {dv_flow_mgr-0.0.1.13478128278a1 → dv_flow_mgr-0.0.1.13489806632a1}/src/dv_flow/mgr/share/flow.json +0 -0
  47. {dv_flow_mgr-0.0.1.13478128278a1 → dv_flow_mgr-0.0.1.13489806632a1}/src/dv_flow/mgr/std/fileset.py +0 -0
  48. {dv_flow_mgr-0.0.1.13478128278a1 → dv_flow_mgr-0.0.1.13489806632a1}/src/dv_flow/mgr/std/flow.dv +0 -0
  49. {dv_flow_mgr-0.0.1.13478128278a1 → dv_flow_mgr-0.0.1.13489806632a1}/src/dv_flow/mgr/std/message.py +0 -0
  50. {dv_flow_mgr-0.0.1.13478128278a1 → dv_flow_mgr-0.0.1.13489806632a1}/src/dv_flow/mgr/std/task_null.py +0 -0
  51. {dv_flow_mgr-0.0.1.13478128278a1 → dv_flow_mgr-0.0.1.13489806632a1}/src/dv_flow/mgr/task.py +0 -0
  52. {dv_flow_mgr-0.0.1.13478128278a1 → dv_flow_mgr-0.0.1.13489806632a1}/src/dv_flow/mgr/task_ctor.py +0 -0
  53. {dv_flow_mgr-0.0.1.13478128278a1 → dv_flow_mgr-0.0.1.13489806632a1}/src/dv_flow/mgr/task_data.py +0 -0
  54. {dv_flow_mgr-0.0.1.13478128278a1 → dv_flow_mgr-0.0.1.13489806632a1}/src/dv_flow/mgr/task_def.py +0 -0
  55. {dv_flow_mgr-0.0.1.13478128278a1 → dv_flow_mgr-0.0.1.13489806632a1}/src/dv_flow/mgr/task_exec_data.py +0 -0
  56. {dv_flow_mgr-0.0.1.13478128278a1 → dv_flow_mgr-0.0.1.13489806632a1}/src/dv_flow/mgr/task_graph_builder.py +0 -0
  57. {dv_flow_mgr-0.0.1.13478128278a1 → dv_flow_mgr-0.0.1.13489806632a1}/src/dv_flow/mgr/task_graph_runner.py +0 -0
  58. {dv_flow_mgr-0.0.1.13478128278a1 → dv_flow_mgr-0.0.1.13489806632a1}/src/dv_flow/mgr/task_graph_runner_local.py +0 -0
  59. {dv_flow_mgr-0.0.1.13478128278a1 → dv_flow_mgr-0.0.1.13489806632a1}/src/dv_flow/mgr/task_impl_data.py +0 -0
  60. {dv_flow_mgr-0.0.1.13478128278a1 → dv_flow_mgr-0.0.1.13489806632a1}/src/dv_flow/mgr/task_memento.py +0 -0
  61. {dv_flow_mgr-0.0.1.13478128278a1 → dv_flow_mgr-0.0.1.13489806632a1}/src/dv_flow/mgr/task_output.py +0 -0
  62. {dv_flow_mgr-0.0.1.13478128278a1 → dv_flow_mgr-0.0.1.13489806632a1}/src/dv_flow/mgr/task_params_ctor.py +0 -0
  63. {dv_flow_mgr-0.0.1.13478128278a1 → dv_flow_mgr-0.0.1.13489806632a1}/src/dv_flow/mgr/type.py +0 -0
  64. {dv_flow_mgr-0.0.1.13478128278a1 → dv_flow_mgr-0.0.1.13489806632a1}/src/dv_flow/mgr/type_def.py +0 -0
  65. {dv_flow_mgr-0.0.1.13478128278a1 → dv_flow_mgr-0.0.1.13489806632a1}/src/dv_flow/mgr/util.py +0 -0
  66. {dv_flow_mgr-0.0.1.13478128278a1 → dv_flow_mgr-0.0.1.13489806632a1}/src/dv_flow_mgr.egg-info/dependency_links.txt +0 -0
  67. {dv_flow_mgr-0.0.1.13478128278a1 → dv_flow_mgr-0.0.1.13489806632a1}/src/dv_flow_mgr.egg-info/entry_points.txt +0 -0
  68. {dv_flow_mgr-0.0.1.13478128278a1 → dv_flow_mgr-0.0.1.13489806632a1}/src/dv_flow_mgr.egg-info/requires.txt +0 -0
  69. {dv_flow_mgr-0.0.1.13478128278a1 → dv_flow_mgr-0.0.1.13489806632a1}/src/dv_flow_mgr.egg-info/top_level.txt +0 -0
  70. {dv_flow_mgr-0.0.1.13478128278a1 → dv_flow_mgr-0.0.1.13489806632a1}/tests/examples/example1/example1.flow +0 -0
  71. {dv_flow_mgr-0.0.1.13478128278a1 → dv_flow_mgr-0.0.1.13489806632a1}/tests/system/test_depends.py +0 -0
  72. {dv_flow_mgr-0.0.1.13478128278a1 → dv_flow_mgr-0.0.1.13489806632a1}/tests/system/test_pkg_discovery.py +0 -0
  73. {dv_flow_mgr-0.0.1.13478128278a1 → dv_flow_mgr-0.0.1.13489806632a1}/tests/system/test_stdlib.py +0 -0
  74. {dv_flow_mgr-0.0.1.13478128278a1 → dv_flow_mgr-0.0.1.13489806632a1}/tests/unit/__init__.py +0 -0
  75. {dv_flow_mgr-0.0.1.13478128278a1 → dv_flow_mgr-0.0.1.13489806632a1}/tests/unit/data/fileset/test1/files1/file1_1.sv +0 -0
  76. {dv_flow_mgr-0.0.1.13478128278a1 → dv_flow_mgr-0.0.1.13489806632a1}/tests/unit/data/fileset/test1/files1/file1_2.sv +0 -0
  77. {dv_flow_mgr-0.0.1.13478128278a1 → dv_flow_mgr-0.0.1.13489806632a1}/tests/unit/data/fileset/test1/files2/file2_1.sv +0 -0
  78. {dv_flow_mgr-0.0.1.13478128278a1 → dv_flow_mgr-0.0.1.13489806632a1}/tests/unit/data/fileset/test1/files2/file2_2.sv +0 -0
  79. {dv_flow_mgr-0.0.1.13478128278a1 → dv_flow_mgr-0.0.1.13489806632a1}/tests/unit/data/fileset/test1/flow.dv +0 -0
  80. {dv_flow_mgr-0.0.1.13478128278a1 → dv_flow_mgr-0.0.1.13489806632a1}/tests/unit/data/fileset/test1 copy/files1/file1_1.sv +0 -0
  81. {dv_flow_mgr-0.0.1.13478128278a1 → dv_flow_mgr-0.0.1.13489806632a1}/tests/unit/data/fileset/test1 copy/files1/file1_2.sv +0 -0
  82. {dv_flow_mgr-0.0.1.13478128278a1 → dv_flow_mgr-0.0.1.13489806632a1}/tests/unit/data/fileset/test1 copy/files2/file2_1.sv +0 -0
  83. {dv_flow_mgr-0.0.1.13478128278a1 → dv_flow_mgr-0.0.1.13489806632a1}/tests/unit/data/fileset/test1 copy/files2/file2_2.sv +0 -0
  84. {dv_flow_mgr-0.0.1.13478128278a1 → dv_flow_mgr-0.0.1.13489806632a1}/tests/unit/data/fileset/test1 copy/test1.dfs +0 -0
  85. {dv_flow_mgr-0.0.1.13478128278a1 → dv_flow_mgr-0.0.1.13489806632a1}/tests/unit/data/proj1/proj1.dfs +0 -0
  86. {dv_flow_mgr-0.0.1.13478128278a1 → dv_flow_mgr-0.0.1.13489806632a1}/tests/unit/data/proj2/proj2.dfs +0 -0
  87. {dv_flow_mgr-0.0.1.13478128278a1 → dv_flow_mgr-0.0.1.13489806632a1}/tests/unit/data/proj3/proj3.dfs +0 -0
  88. {dv_flow_mgr-0.0.1.13478128278a1 → dv_flow_mgr-0.0.1.13489806632a1}/tests/unit/test_data_merge.py +0 -0
  89. {dv_flow_mgr-0.0.1.13478128278a1 → dv_flow_mgr-0.0.1.13489806632a1}/tests/unit/test_expr_eval.py +0 -0
  90. {dv_flow_mgr-0.0.1.13478128278a1 → dv_flow_mgr-0.0.1.13489806632a1}/tests/unit/test_expr_parser.py +0 -0
  91. {dv_flow_mgr-0.0.1.13478128278a1 → dv_flow_mgr-0.0.1.13489806632a1}/tests/unit/test_fileset.py +0 -0
  92. {dv_flow_mgr-0.0.1.13478128278a1 → dv_flow_mgr-0.0.1.13489806632a1}/tests/unit/test_parse.py +0 -0
  93. {dv_flow_mgr-0.0.1.13478128278a1 → dv_flow_mgr-0.0.1.13489806632a1}/tests/unit/test_pyclass.py +0 -0
  94. {dv_flow_mgr-0.0.1.13478128278a1 → dv_flow_mgr-0.0.1.13489806632a1}/tests/unit/test_smoke copy.sav +0 -0
  95. {dv_flow_mgr-0.0.1.13478128278a1 → dv_flow_mgr-0.0.1.13489806632a1}/tests/unit/test_smoke.py +0 -0
  96. {dv_flow_mgr-0.0.1.13478128278a1 → dv_flow_mgr-0.0.1.13489806632a1}/tests/unit/test_stdlib.py +0 -0
@@ -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
@@ -0,0 +1,19 @@
1
+
2
+ A task graph is composed of task nodes. A task is defined as the combination
3
+ of:
4
+ - behavior
5
+ - parameters data structure
6
+ - rules/process for specifying parameter values
7
+
8
+ Task behavior must:
9
+ - accept input data composed of:
10
+ - parameter data structure with values populated
11
+ - change notification
12
+ - (optional) meta-data
13
+ - produce result data composed of:
14
+ - list of parameter sets
15
+ - change notification
16
+ - (optional) meta-data
17
+ - (optional) markers
18
+ - execution status
19
+
@@ -5,7 +5,7 @@ build-backend = "setuptools.build_meta"
5
5
 
6
6
  [project]
7
7
  name = "dv-flow-mgr"
8
- version = "0.0.1.13478128278a1"
8
+ version = "0.0.1.13489806632a1"
9
9
  dependencies = [
10
10
  'pydantic',
11
11
  'pyyaml',
@@ -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
@@ -0,0 +1,162 @@
1
+ import asyncio
2
+ import dataclasses as dc
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
7
+
8
+ @dc.dataclass
9
+ class TaskRunner(object):
10
+ rundir : str
11
+
12
+ # List of [Listener:Callable[Task],Recurisve:bool]
13
+ listeners : List[Tuple[Callable['Task','Reason'], bool]] = dc.field(default_factory=list)
14
+
15
+ async def do_run(self,
16
+ task : 'Task',
17
+ memento : Any = None) -> 'TaskDataResult':
18
+ return await self.run(task, memento)
19
+
20
+ async def run(self,
21
+ task : 'Task',
22
+ memento : Any = None) -> 'TaskDataResult':
23
+ pass
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
+
117
+ @dc.dataclass
118
+ class SingleTaskRunner(TaskRunner):
119
+
120
+ async def run(self,
121
+ task : 'Task',
122
+ memento : Any = None) -> 'TaskDataResult':
123
+ changed = False
124
+ for dep in task.needs:
125
+ changed |= dep.changed
126
+
127
+ # TODO: create an evaluator for substituting param values
128
+ eval = None
129
+
130
+ for field in dc.fields(task.params):
131
+ print("Field: %s" % field.name)
132
+
133
+ input = TaskDataInput(
134
+ changed=changed,
135
+ srcdir=task.srcdir,
136
+ rundir=self.rundir,
137
+ params=task.params,
138
+ memento=memento)
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:
161
+
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
@@ -12,6 +12,7 @@ docs/Roadmap.md
12
12
  docs/RundirLayout.md
13
13
  docs/Stages.md
14
14
  docs/Steps.md
15
+ docs/Tasks.md
15
16
  docs/TypesAndDefs.md
16
17
  docs/Usecases.md
17
18
  docs/conf.py
@@ -42,6 +43,7 @@ src/dv_flow/mgr/task_graph_runner.py
42
43
  src/dv_flow/mgr/task_graph_runner_local.py
43
44
  src/dv_flow/mgr/task_impl_data.py
44
45
  src/dv_flow/mgr/task_memento.py
46
+ src/dv_flow/mgr/task_node.py
45
47
  src/dv_flow/mgr/task_output.py
46
48
  src/dv_flow/mgr/task_params_ctor.py
47
49
  src/dv_flow/mgr/task_runner.py
@@ -0,0 +1,96 @@
1
+ import asyncio
2
+ import pytest
3
+ import dataclasses as dc
4
+ from dv_flow.mgr.task import Task
5
+ from dv_flow.mgr.task_data import TaskDataResult, TaskMarker
6
+ from dv_flow.mgr.task_node import task as t_decorator
7
+ from dv_flow.mgr.task_runner import SingleTaskRunner, TaskSetRunner
8
+
9
+
10
+ def test_smoke_1(tmpdir):
11
+
12
+ @dc.dataclass
13
+ class Params(object):
14
+ p1 : str = None
15
+
16
+ called = False
17
+
18
+ @t_decorator(Params)
19
+ async def MyTask(runner, input):
20
+ nonlocal called
21
+ called = True
22
+ print("Hello from run")
23
+ return TaskDataResult()
24
+
25
+ task = MyTask("srcdir", p1="p1")
26
+ runner = SingleTaskRunner("rundir")
27
+
28
+ result = asyncio.run(runner.run(task))
29
+
30
+ assert called
31
+
32
+ def test_smoke_2(tmpdir):
33
+
34
+ @dc.dataclass
35
+ class Params(object):
36
+ p1 : str = None
37
+
38
+ called = False
39
+ @Task.ctor(Params)
40
+ class MyTask(Task):
41
+ async def run(self, runner, input):
42
+ nonlocal called
43
+ called = True
44
+ print("Hello from run")
45
+ return TaskDataResult(
46
+ markers=[TaskMarker(msg="testing", severity="info")]
47
+ )
48
+
49
+ task = MyTask.mkTask("task1", "srcdir", MyTask.mkParams(
50
+ p1="p1"
51
+ ))
52
+ runner = SingleTaskRunner("rundir")
53
+
54
+ result = asyncio.run(runner.run(task))
55
+
56
+ assert called
57
+ assert result is not None
58
+ assert len(result.markers) == 1
59
+
60
+ def test_smoke_3(tmpdir):
61
+
62
+ @dc.dataclass
63
+ class Params(object):
64
+ p1 : str = None
65
+
66
+ called = False
67
+
68
+ @t_decorator(Params)
69
+ async def MyTask1(runner, input):
70
+ nonlocal called
71
+ called = True
72
+ print("Hello from run1 (%s)" % input.params.p1)
73
+ return TaskDataResult()
74
+
75
+ @t_decorator(Params)
76
+ async def MyTask2(runner, input):
77
+ nonlocal called
78
+ called = True
79
+ print("Hello from run2 (%s)" % input.params.p1)
80
+ return TaskDataResult()
81
+
82
+ @t_decorator(Params)
83
+ async def MyTask3(runner, input):
84
+ nonlocal called
85
+ called = True
86
+ print("Hello from run3 (%s)" % input.params.p1)
87
+ return TaskDataResult()
88
+
89
+ task1 = MyTask1("srcdir", p1="1")
90
+ task2 = MyTask2("srcdir", p1="2")
91
+ task3 = MyTask3("srcdir", p1="2", needs=[task1, task2])
92
+ runner = TaskSetRunner("rundir")
93
+
94
+ result = asyncio.run(runner.run(task3))
95
+
96
+ assert called
@@ -1,46 +0,0 @@
1
- import dataclasses as dc
2
- from .task_data import TaskDataInput, TaskDataResult
3
- from typing import Any, Callable, List, Tuple
4
-
5
- @dc.dataclass
6
- class TaskRunner(object):
7
- rundir : str
8
-
9
- # List of [Listener:Callable[Task],Recurisve:bool]
10
- listeners : List[Tuple[Callable['Task','Reason'], bool]] = dc.field(default_factory=list)
11
-
12
- async def do_run(self,
13
- task : 'Task',
14
- memento : Any = None) -> 'TaskDataResult':
15
- return await self.run(task, memento)
16
-
17
- async def run(self,
18
- task : 'Task',
19
- memento : Any = None) -> 'TaskDataResult':
20
- pass
21
-
22
- @dc.dataclass
23
- class SingleTaskRunner(TaskRunner):
24
-
25
- async def run(self,
26
- task : 'Task',
27
- memento : Any = None) -> 'TaskDataResult':
28
- changed = False
29
- for dep in task.needs:
30
- changed |= dep.changed
31
-
32
- # TODO: create an evaluator for substituting param values
33
- eval = None
34
-
35
- params = task.params.mk(eval)
36
-
37
- input = TaskDataInput(
38
- changed=changed,
39
- srcdir=task.srcdir,
40
- rundir=self.rundir,
41
- params=params,
42
- memento=memento)
43
-
44
- ret = await task.run(self, input)
45
-
46
- return ret
@@ -1,59 +0,0 @@
1
- import asyncio
2
- import pytest
3
- import dataclasses as dc
4
- from dv_flow.mgr.task import Task
5
- from dv_flow.mgr.task_data import TaskDataResult, TaskMarker
6
- from dv_flow.mgr.task_runner import SingleTaskRunner
7
-
8
-
9
- def test_smoke_1(tmpdir):
10
-
11
- @dc.dataclass
12
- class Params(object):
13
- p1 : str
14
-
15
- called = False
16
- @Task.ctor(Params)
17
- class MyTask(Task):
18
- async def run(self, runner, input):
19
- nonlocal called
20
- called = True
21
- print("Hello from run")
22
- pass
23
-
24
- task = MyTask("task1", "srcdir", MyTask.mkParams("p1"))
25
- runner = SingleTaskRunner("rundir")
26
-
27
- result = asyncio.run(runner.run(task))
28
-
29
- assert called
30
-
31
- def test_smoke_2(tmpdir):
32
-
33
- @dc.dataclass
34
- class Params(object):
35
- p1 : str = None
36
-
37
- called = False
38
- @Task.ctor(Params)
39
- class MyTask(Task):
40
- async def run(self, runner, input):
41
- nonlocal called
42
- called = True
43
- print("Hello from run")
44
- return TaskDataResult(
45
- markers=[TaskMarker(msg="testing", severity="info")]
46
- )
47
-
48
- task = MyTask.mkTask("task1", "srcdir", MyTask.mkParams(
49
- p1="p1"
50
- ))
51
- runner = SingleTaskRunner("rundir")
52
-
53
- result = asyncio.run(runner.run(task))
54
-
55
- assert called
56
- assert result is not None
57
- assert len(result.markers) == 1
58
-
59
-