dv-flow-mgr 0.0.1.12981364130a1__tar.gz → 0.0.1.13335470340a1__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 (83) hide show
  1. {dv_flow_mgr-0.0.1.12981364130a1 → dv_flow_mgr-0.0.1.13335470340a1}/PKG-INFO +1 -1
  2. dv_flow_mgr-0.0.1.13335470340a1/docs/KeyArchitecture.md +65 -0
  3. {dv_flow_mgr-0.0.1.12981364130a1 → dv_flow_mgr-0.0.1.13335470340a1}/docs/Roadmap.md +19 -2
  4. dv_flow_mgr-0.0.1.13335470340a1/docs/Steps.md +50 -0
  5. dv_flow_mgr-0.0.1.13335470340a1/docs/Usecases.md +49 -0
  6. {dv_flow_mgr-0.0.1.12981364130a1 → dv_flow_mgr-0.0.1.13335470340a1}/ivpm.yaml +2 -0
  7. {dv_flow_mgr-0.0.1.12981364130a1 → dv_flow_mgr-0.0.1.13335470340a1}/pyproject.toml +1 -1
  8. dv_flow_mgr-0.0.1.13335470340a1/src/dv_flow/mgr/expr_parser.py +38 -0
  9. {dv_flow_mgr-0.0.1.12981364130a1 → dv_flow_mgr-0.0.1.13335470340a1}/src/dv_flow/mgr/fragment_def.py +2 -0
  10. dv_flow_mgr-0.0.1.13335470340a1/src/dv_flow/mgr/out +12 -0
  11. {dv_flow_mgr-0.0.1.12981364130a1 → dv_flow_mgr-0.0.1.13335470340a1}/src/dv_flow/mgr/package.py +1 -0
  12. {dv_flow_mgr-0.0.1.12981364130a1 → dv_flow_mgr-0.0.1.13335470340a1}/src/dv_flow/mgr/package_def.py +41 -3
  13. dv_flow_mgr-0.0.1.13335470340a1/src/dv_flow/mgr/param_def.py +25 -0
  14. {dv_flow_mgr-0.0.1.12981364130a1 → dv_flow_mgr-0.0.1.13335470340a1}/src/dv_flow/mgr/std/fileset.py +7 -0
  15. dv_flow_mgr-0.0.1.13335470340a1/src/dv_flow/mgr/std/flow.dv +78 -0
  16. {dv_flow_mgr-0.0.1.12981364130a1 → dv_flow_mgr-0.0.1.13335470340a1}/src/dv_flow/mgr/task.py +1 -2
  17. {dv_flow_mgr-0.0.1.12981364130a1 → dv_flow_mgr-0.0.1.13335470340a1}/src/dv_flow/mgr/task_data.py +12 -14
  18. {dv_flow_mgr-0.0.1.12981364130a1 → dv_flow_mgr-0.0.1.13335470340a1}/src/dv_flow/mgr/task_def.py +4 -1
  19. dv_flow_mgr-0.0.1.13335470340a1/src/dv_flow/mgr/task_impl_data.py +17 -0
  20. dv_flow_mgr-0.0.1.13335470340a1/src/dv_flow/mgr/task_output.py +6 -0
  21. dv_flow_mgr-0.0.1.13335470340a1/src/dv_flow/mgr/type_def.py +10 -0
  22. {dv_flow_mgr-0.0.1.12981364130a1 → dv_flow_mgr-0.0.1.13335470340a1}/src/dv_flow_mgr.egg-info/PKG-INFO +1 -1
  23. {dv_flow_mgr-0.0.1.12981364130a1 → dv_flow_mgr-0.0.1.13335470340a1}/src/dv_flow_mgr.egg-info/SOURCES.txt +11 -0
  24. dv_flow_mgr-0.0.1.13335470340a1/tests/unit/data/fileset/test1/files2/file2_2.sv +0 -0
  25. {dv_flow_mgr-0.0.1.12981364130a1 → dv_flow_mgr-0.0.1.13335470340a1}/tests/unit/test_fileset.py +1 -1
  26. dv_flow_mgr-0.0.1.13335470340a1/tests/unit/test_parse.py +38 -0
  27. {dv_flow_mgr-0.0.1.12981364130a1 → dv_flow_mgr-0.0.1.13335470340a1}/tests/unit/test_smoke.py +55 -1
  28. dv_flow_mgr-0.0.1.12981364130a1/src/dv_flow/mgr/std/flow.dv +0 -30
  29. {dv_flow_mgr-0.0.1.12981364130a1 → dv_flow_mgr-0.0.1.13335470340a1}/.github/workflows/ci.yml +0 -0
  30. {dv_flow_mgr-0.0.1.12981364130a1 → dv_flow_mgr-0.0.1.13335470340a1}/.gitignore +0 -0
  31. {dv_flow_mgr-0.0.1.12981364130a1 → dv_flow_mgr-0.0.1.13335470340a1}/.vscode/settings.json +0 -0
  32. {dv_flow_mgr-0.0.1.12981364130a1 → dv_flow_mgr-0.0.1.13335470340a1}/LICENSE +0 -0
  33. {dv_flow_mgr-0.0.1.12981364130a1 → dv_flow_mgr-0.0.1.13335470340a1}/README.md +0 -0
  34. {dv_flow_mgr-0.0.1.12981364130a1 → dv_flow_mgr-0.0.1.13335470340a1}/docs/Makefile +0 -0
  35. {dv_flow_mgr-0.0.1.12981364130a1 → dv_flow_mgr-0.0.1.13335470340a1}/docs/Notes.md +0 -0
  36. {dv_flow_mgr-0.0.1.12981364130a1 → dv_flow_mgr-0.0.1.13335470340a1}/docs/Stages.md +0 -0
  37. {dv_flow_mgr-0.0.1.12981364130a1 → dv_flow_mgr-0.0.1.13335470340a1}/docs/TypesAndDefs.md +0 -0
  38. {dv_flow_mgr-0.0.1.12981364130a1 → dv_flow_mgr-0.0.1.13335470340a1}/docs/conf.py +0 -0
  39. {dv_flow_mgr-0.0.1.12981364130a1 → dv_flow_mgr-0.0.1.13335470340a1}/docs/index.rst +0 -0
  40. {dv_flow_mgr-0.0.1.12981364130a1 → dv_flow_mgr-0.0.1.13335470340a1}/docs/intro.rst +0 -0
  41. {dv_flow_mgr-0.0.1.12981364130a1 → dv_flow_mgr-0.0.1.13335470340a1}/docs/quickstart.rst +0 -0
  42. {dv_flow_mgr-0.0.1.12981364130a1 → dv_flow_mgr-0.0.1.13335470340a1}/docs/reference.rst +0 -0
  43. {dv_flow_mgr-0.0.1.12981364130a1 → dv_flow_mgr-0.0.1.13335470340a1}/setup.cfg +0 -0
  44. {dv_flow_mgr-0.0.1.12981364130a1 → dv_flow_mgr-0.0.1.13335470340a1}/src/dv_flow/mgr/__init__.py +0 -0
  45. {dv_flow_mgr-0.0.1.12981364130a1 → dv_flow_mgr-0.0.1.13335470340a1}/src/dv_flow/mgr/__main__.py +0 -0
  46. {dv_flow_mgr-0.0.1.12981364130a1 → dv_flow_mgr-0.0.1.13335470340a1}/src/dv_flow/mgr/cmds/cmd_run.py +0 -0
  47. {dv_flow_mgr-0.0.1.12981364130a1 → dv_flow_mgr-0.0.1.13335470340a1}/src/dv_flow/mgr/fileset.py +0 -0
  48. {dv_flow_mgr-0.0.1.12981364130a1 → dv_flow_mgr-0.0.1.13335470340a1}/src/dv_flow/mgr/package_import_spec.py +0 -0
  49. {dv_flow_mgr-0.0.1.12981364130a1 → dv_flow_mgr-0.0.1.13335470340a1}/src/dv_flow/mgr/pkg_rgy.py +0 -0
  50. {dv_flow_mgr-0.0.1.12981364130a1 → dv_flow_mgr-0.0.1.13335470340a1}/src/dv_flow/mgr/share/flow.json +0 -0
  51. {dv_flow_mgr-0.0.1.12981364130a1 → dv_flow_mgr-0.0.1.13335470340a1}/src/dv_flow/mgr/std/message.py +0 -0
  52. {dv_flow_mgr-0.0.1.12981364130a1 → dv_flow_mgr-0.0.1.13335470340a1}/src/dv_flow/mgr/std/task_null.py +0 -0
  53. {dv_flow_mgr-0.0.1.12981364130a1 → dv_flow_mgr-0.0.1.13335470340a1}/src/dv_flow/mgr/task_graph_builder.py +0 -0
  54. {dv_flow_mgr-0.0.1.12981364130a1 → dv_flow_mgr-0.0.1.13335470340a1}/src/dv_flow/mgr/task_graph_runner.py +0 -0
  55. {dv_flow_mgr-0.0.1.12981364130a1 → dv_flow_mgr-0.0.1.13335470340a1}/src/dv_flow/mgr/task_graph_runner_local.py +0 -0
  56. {dv_flow_mgr-0.0.1.12981364130a1 → dv_flow_mgr-0.0.1.13335470340a1}/src/dv_flow/mgr/task_memento.py +0 -0
  57. /dv_flow_mgr-0.0.1.12981364130a1/tests/unit/data/fileset/test1 copy/files1/file1_1.sv → /dv_flow_mgr-0.0.1.13335470340a1/src/dv_flow/mgr/type.py +0 -0
  58. {dv_flow_mgr-0.0.1.12981364130a1 → dv_flow_mgr-0.0.1.13335470340a1}/src/dv_flow/mgr/util.py +0 -0
  59. {dv_flow_mgr-0.0.1.12981364130a1 → dv_flow_mgr-0.0.1.13335470340a1}/src/dv_flow_mgr.egg-info/dependency_links.txt +0 -0
  60. {dv_flow_mgr-0.0.1.12981364130a1 → dv_flow_mgr-0.0.1.13335470340a1}/src/dv_flow_mgr.egg-info/entry_points.txt +0 -0
  61. {dv_flow_mgr-0.0.1.12981364130a1 → dv_flow_mgr-0.0.1.13335470340a1}/src/dv_flow_mgr.egg-info/requires.txt +0 -0
  62. {dv_flow_mgr-0.0.1.12981364130a1 → dv_flow_mgr-0.0.1.13335470340a1}/src/dv_flow_mgr.egg-info/top_level.txt +0 -0
  63. {dv_flow_mgr-0.0.1.12981364130a1 → dv_flow_mgr-0.0.1.13335470340a1}/tests/examples/example1/example1.flow +0 -0
  64. {dv_flow_mgr-0.0.1.12981364130a1 → dv_flow_mgr-0.0.1.13335470340a1}/tests/system/test_depends.py +0 -0
  65. {dv_flow_mgr-0.0.1.12981364130a1 → dv_flow_mgr-0.0.1.13335470340a1}/tests/system/test_pkg_discovery.py +0 -0
  66. {dv_flow_mgr-0.0.1.12981364130a1 → dv_flow_mgr-0.0.1.13335470340a1}/tests/system/test_stdlib.py +0 -0
  67. {dv_flow_mgr-0.0.1.12981364130a1 → dv_flow_mgr-0.0.1.13335470340a1}/tests/unit/__init__.py +0 -0
  68. /dv_flow_mgr-0.0.1.12981364130a1/tests/unit/data/fileset/test1/files1/file1_2.sv → /dv_flow_mgr-0.0.1.13335470340a1/tests/unit/data/fileset/test1/files1/file1_1.sv +0 -0
  69. /dv_flow_mgr-0.0.1.12981364130a1/tests/unit/data/fileset/test1/files2/file2_1.sv → /dv_flow_mgr-0.0.1.13335470340a1/tests/unit/data/fileset/test1/files1/file1_2.sv +0 -0
  70. /dv_flow_mgr-0.0.1.12981364130a1/tests/unit/data/fileset/test1/files2/file2_2.sv → /dv_flow_mgr-0.0.1.13335470340a1/tests/unit/data/fileset/test1/files2/file2_1.sv +0 -0
  71. {dv_flow_mgr-0.0.1.12981364130a1 → dv_flow_mgr-0.0.1.13335470340a1}/tests/unit/data/fileset/test1/flow.dv +0 -0
  72. {dv_flow_mgr-0.0.1.12981364130a1/tests/unit/data/fileset/test1 → dv_flow_mgr-0.0.1.13335470340a1/tests/unit/data/fileset/test1 copy}/files1/file1_1.sv +0 -0
  73. {dv_flow_mgr-0.0.1.12981364130a1 → dv_flow_mgr-0.0.1.13335470340a1}/tests/unit/data/fileset/test1 copy/files1/file1_2.sv +0 -0
  74. {dv_flow_mgr-0.0.1.12981364130a1 → dv_flow_mgr-0.0.1.13335470340a1}/tests/unit/data/fileset/test1 copy/files2/file2_1.sv +0 -0
  75. {dv_flow_mgr-0.0.1.12981364130a1 → dv_flow_mgr-0.0.1.13335470340a1}/tests/unit/data/fileset/test1 copy/files2/file2_2.sv +0 -0
  76. {dv_flow_mgr-0.0.1.12981364130a1 → dv_flow_mgr-0.0.1.13335470340a1}/tests/unit/data/fileset/test1 copy/test1.dfs +0 -0
  77. {dv_flow_mgr-0.0.1.12981364130a1 → dv_flow_mgr-0.0.1.13335470340a1}/tests/unit/data/proj1/proj1.dfs +0 -0
  78. {dv_flow_mgr-0.0.1.12981364130a1 → dv_flow_mgr-0.0.1.13335470340a1}/tests/unit/data/proj2/proj2.dfs +0 -0
  79. {dv_flow_mgr-0.0.1.12981364130a1 → dv_flow_mgr-0.0.1.13335470340a1}/tests/unit/data/proj3/proj3.dfs +0 -0
  80. {dv_flow_mgr-0.0.1.12981364130a1 → dv_flow_mgr-0.0.1.13335470340a1}/tests/unit/test_data_merge.py +0 -0
  81. {dv_flow_mgr-0.0.1.12981364130a1 → dv_flow_mgr-0.0.1.13335470340a1}/tests/unit/test_pyclass.py +0 -0
  82. {dv_flow_mgr-0.0.1.12981364130a1 → dv_flow_mgr-0.0.1.13335470340a1}/tests/unit/test_smoke copy.sav +0 -0
  83. {dv_flow_mgr-0.0.1.12981364130a1 → dv_flow_mgr-0.0.1.13335470340a1}/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.12981364130a1
3
+ Version: 0.0.1.13335470340a1
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,65 @@
1
+
2
+ # Tasks
3
+ - A task has 0..N dependencies (references to tasks whose output
4
+ data must be available prior to execution of the task)
5
+ - The input data available to a task includes
6
+ - Output data from its dependencies
7
+ - Memento data from its prior execution (a memento is a record of task execution)
8
+ - Makes sense to include markers here
9
+ - Locally-specified data (ie task parameters)
10
+ - The core implementation of a task is invoked with a
11
+ consolidated set of data that is specified in the task definition.
12
+ - Example: select all FileSet that have kind systemVerilog, verilog, or VHDL
13
+ - The output of a task is comprised of (think of this as a filter?)
14
+ - Output data from its dependencies
15
+ - Memento data from the implementation, including marker information
16
+
17
+ # Types
18
+ - Types are named structures
19
+
20
+ # Task Parameters
21
+ - A task may have parameters. Parameters are singletons, and are
22
+ not extensible from outside.
23
+ - If a task needs to accept outside input, it must select that
24
+ by type from input parameter sets
25
+ - Direct parameters
26
+ - Task parameters are exposed to task implementation via a type with the task name
27
+ - Do we really need this?
28
+ - Using explicit types results in one extra layer of indirection
29
+ - Still may have to deal with ambiguity...
30
+
31
+ - name: RunSim
32
+ uses: SimRun
33
+ with:
34
+ - name: simargs
35
+ type:
36
+ list:
37
+ item: SimArgs
38
+ value: ${{ jq in.[]}}
39
+ - uses: SimArgs
40
+ with:
41
+ - append-list
42
+
43
+ So... Tasks do not have parameters.
44
+ - Tasks can inject parameter sets into the input set
45
+ - Tasks can control what emerges from the task
46
+
47
+ plusargs: .[] select(uses==SimArgs) |
48
+
49
+ # Cross-Task Dataflow
50
+ - Cross-task dataflow is comprised of a collection of typed objects
51
+ containing typed fields.
52
+ - Augmenting data is done by injecting new object instances into
53
+ the dataset. For example:
54
+ - The dataset contains an object for specifying simulation runtime
55
+ arguments. It contains a directive to append "+UVM_TEST=my_test"
56
+ to the arguments
57
+ - I add a new runtime-arguments object that contains a directive
58
+ to append "+debug" to the arguments
59
+ - The consumer will see [+UVM_TEST=my_test +debug]
60
+
61
+
62
+ # Data-Combination Rules
63
+ - In most cases, data must be flattened in order to use it. For example,
64
+
65
+ -
@@ -53,9 +53,10 @@ are evaluated.
53
53
 
54
54
  ## 1.0.0
55
55
  - Std
56
- - Null (combine dependencies, set variables). Implements tasks that do not specify 'uses'
56
+ * Null (combine dependencies, set variables). Implements tasks that do not specify 'uses'
57
57
  - Exec
58
- - FileSet
58
+ - Make
59
+ * FileSet
59
60
  - PyClass - implement a task as a Python class (load from a module)
60
61
 
61
62
  - HdlSim
@@ -112,3 +113,19 @@ are evaluated.
112
113
  - Extensible -- by users and organizations
113
114
  - Implementation independent (not tied to a specific implementation language)
114
115
 
116
+
117
+ # TODO
118
+ - Need some way to signal rough core consumption. Challenge is to complete
119
+ build as quickly as possible via coarse and fine-grained parallelism
120
+ - Parallelism tends to follow exponential curve. High parallelism early ; Low later
121
+ - Reasoning about curves may guide resource over-subscription
122
+ - Each task needs memory hints / requirements as well
123
+ - Dependency strategy for Exec/Make
124
+ - Specify dependency file created by task
125
+ - When the timestamp is updated, task is known to have been rebuilt
126
+ -
127
+
128
+ - Allow each task to emit a series of markers as part of the result
129
+ - Enables users to easily click on first N warnings/errors in each step
130
+ without needing to find and open a logfile
131
+ - Allow files to be attached as part of the result
@@ -0,0 +1,50 @@
1
+
2
+ # Tasks and Types
3
+ - Load type definitions from YAML
4
+ - Load task definitions from YAML
5
+
6
+ # Data Selection and Extraction
7
+ - Sort and select data
8
+ - Need to support expressions
9
+ -
10
+
11
+ # Task Implementation Source/Result Data
12
+
13
+ Source Data
14
+ - Task parameters
15
+ - Upstream-change indication
16
+ - Memento
17
+
18
+ Result Data
19
+ - List of output parameter sets
20
+ - Change indication
21
+ - Memento
22
+
23
+ # Data Combination
24
+ -
25
+
26
+ # Day in the Life
27
+ - Task Runner receives outputs from dependent tasks
28
+ - ORs input changed' input flags to determine 'changed' flag to pass to task
29
+ - Task Runner orders parameters using dependency information
30
+ - Task Runner evaluates task-parameter creation code. Uses input data in this process
31
+ - Creates object of appropriate type
32
+ - Evalutes base-up to assign and augment parameter values
33
+ - Retrieves memento (if available)
34
+ - Passes accumulated data to task
35
+ - changed
36
+ - parameters
37
+ -
38
+ - Receives output from task
39
+ - list of parameter sets
40
+ - changed
41
+ - memento
42
+ - list of markers
43
+ - Saves memento and markers for later inspection (central dir?)
44
+ - Sets 'self' as source of parameter sets
45
+ - Forms output data from
46
+ - changed
47
+ - list of parameter sets
48
+
49
+ # Creating Task Parameters
50
+ -
@@ -0,0 +1,49 @@
1
+
2
+ # Simple Initial Project Setup
3
+
4
+
5
+ # Reconfigure Project Build
6
+
7
+ # Global Configuration Data
8
+ Some configuration data is global in nature -- in other words,
9
+ it is relevant to multiple tools. Debug is one example. Enabling
10
+ a debug flow impacts multiple simulation tools, and may impact
11
+ how user-specified input behaves as well (eg adding +UVM_VERBOSITY)
12
+
13
+ # Configure Package Usage
14
+ I have a package that depends on UVM, as well as other packages (UVCs)
15
+ that depend on UVM. By default, the UVM library is provided as a
16
+ pre-compiled library (n simulators that support it). For "reasons",
17
+ I want to switch to using the pure-source version. My choice must
18
+ apply to all packages within my orbit -- in other words, having
19
+ my package depend on source UVM while the UVC depends on pre-compiled
20
+ will result in a conflict.
21
+
22
+ # Configure Project Toolchain
23
+ My package has external dependencies that may specify processing
24
+ in addition to sources (eg the UVM library specifies how to
25
+ precompile it). I need a way to configure the toolchain that the
26
+ external packages use the toolchain defined by my package.
27
+
28
+ # Inline Specification of Inputs
29
+ The simulation tool receives its inputs and controls via task data.
30
+ This provides flexibility, by allowing multiple tasks to contribute
31
+ command-line arguments. While I could create a new task to output
32
+ data that would add a command-line argument, I'd prefer to have
33
+ a more-direct way to do so -- a sort of inline injection of task
34
+ data that is combined with the task data of dependencies prior to
35
+ being presented to the implementation.
36
+
37
+
38
+ # Static Composition of Task Graphs (Introspection?)
39
+ I have a collection of test definitions. I want to take a selection
40
+ of them, connect my preferred simulation image, and run them.
41
+
42
+
43
+ # Static Composition of Task Graphs (Introspection)
44
+ I have collections of test definitions. I want to select tests that
45
+ have a specific attribute / tag value, connect my preferred
46
+ simulation image, and run them.
47
+
48
+
49
+
@@ -25,5 +25,7 @@ package:
25
25
  src: pypi
26
26
  - name: sphinxcontrib-mermaid
27
27
  src: pypi
28
+ - name: jq
29
+ src: pypi
28
30
 
29
31
 
@@ -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.12981364130a1"
8
+ version = "0.0.1.13335470340a1"
9
9
  dependencies = [
10
10
  'pydantic',
11
11
  'pyyaml',
@@ -0,0 +1,38 @@
1
+ import dataclasses as dc
2
+ import enum
3
+
4
+ class TokenKind(enum.Enum):
5
+ ID = enum.auto()
6
+
7
+ @dc.dataclass
8
+ class Expr(object):
9
+ kind : TokenKind = TokenKind.ID
10
+
11
+ class ExprId(Expr):
12
+ id : str
13
+
14
+ def __post_init__(self):
15
+ self.kind = TokenKind.ID
16
+
17
+ class ExprPipe(Expr):
18
+ lhs : Expr
19
+ rhs : Expr
20
+
21
+ def __post_init__(self):
22
+ self.kind = TokenKind.ID
23
+
24
+
25
+
26
+ class ExprParser(object):
27
+
28
+ def __init__(self, input):
29
+ self.input = input
30
+
31
+ def __iter__(self):
32
+ return self
33
+
34
+ def __next__(self):
35
+
36
+ self.expr = expr
37
+ self.tokens = []
38
+ self.pos = 0
@@ -26,11 +26,13 @@ from typing import Any, Dict, List, Union
26
26
  from .package import Package
27
27
  from .package_import_spec import PackageImportSpec
28
28
  from .task_def import TaskDef
29
+ from .type_def import TypeDef
29
30
 
30
31
  class FragmentDef(BaseModel):
31
32
  tasks : List[TaskDef] = dc.Field(default_factory=list)
32
33
  imports : List[Union[str,PackageImportSpec]] = dc.Field(default_factory=list, alias="imports")
33
34
  fragments: List[str] = dc.Field(default_factory=list)
35
+ types : List[TypeDef] = dc.Field(default_factory=list)
34
36
 
35
37
  basedir : str = None
36
38
 
@@ -0,0 +1,12 @@
1
+ __main__.py
2
+ flow.py
3
+ package.py
4
+ package_def.py
5
+ package_import_spec.py
6
+ parameters.py
7
+ pkg_rgy.py
8
+ task.py
9
+ task_graph_builder.py
10
+ task_graph_runner.py
11
+ util.py
12
+
@@ -31,6 +31,7 @@ class Package(object):
31
31
  # Package holds constructors for tasks
32
32
  # - Dict holds the default parameters for the task
33
33
  tasks : Dict[str,TaskCtor] = dc.field(default_factory=dict)
34
+ types : Dict[str,Any] = dc.field(default_factory=dict)
34
35
  _log : ClassVar = logging.getLogger("Package")
35
36
 
36
37
  def getTaskCtor(self, name : str) -> TaskCtor:
@@ -19,6 +19,7 @@
19
19
  #* Author:
20
20
  #*
21
21
  #****************************************************************************
22
+ import io
22
23
  import os
23
24
  import json
24
25
  import yaml
@@ -35,6 +36,7 @@ from .package_import_spec import PackageImportSpec, PackageSpec
35
36
  from .task import TaskCtor, TaskCtorProxy, TaskCtorCls, TaskCtorParam, TaskCtorParamCls
36
37
  from .task_def import TaskDef, TaskSpec
37
38
  from .std.task_null import TaskNull
39
+ from .type_def import TypeDef
38
40
 
39
41
 
40
42
  class PackageDef(BaseModel):
@@ -44,6 +46,7 @@ class PackageDef(BaseModel):
44
46
  tasks : List[TaskDef] = dc.Field(default_factory=list)
45
47
  imports : List[PackageImportSpec] = dc.Field(default_factory=list)
46
48
  fragments: List[str] = dc.Field(default_factory=list)
49
+ types : List[TypeDef] = dc.Field(default_factory=list)
47
50
 
48
51
  fragment_l : List['FragmentDef'] = dc.Field(default_factory=list, exclude=True)
49
52
 
@@ -119,6 +122,7 @@ class PackageDef(BaseModel):
119
122
  return ctor_t
120
123
 
121
124
  def handleParams(self, task, ctor_t):
125
+ self._log.debug("--> handleParams %s params=%s" % (task.name, str(task.params)))
122
126
 
123
127
  if task.params is not None and len(task.params) > 0:
124
128
  decl_params = False
@@ -131,7 +135,8 @@ class PackageDef(BaseModel):
131
135
  # ctor_t.params.update(task.params)
132
136
 
133
137
  for value in task.params.values():
134
- if "type" in value:
138
+ self._log.debug("value: %s" % str(value))
139
+ if type(value) == dict and "type" in value.keys():
135
140
  decl_params = True
136
141
  break
137
142
 
@@ -143,6 +148,7 @@ class PackageDef(BaseModel):
143
148
  field_m[fname] = (info.annotation, info.default)
144
149
 
145
150
  if decl_params:
151
+ self._log.debug("Type declares new parameters")
146
152
  # We need to combine base parameters with new parameters
147
153
  ptype_m = {
148
154
  "str" : str,
@@ -160,6 +166,7 @@ class PackageDef(BaseModel):
160
166
  }
161
167
  for p in task.params.keys():
162
168
  param = task.params[p]
169
+ self._log.debug("param: %s" % str(param))
163
170
  if type(param) == dict and "type" in param.keys():
164
171
  ptype_s = param["type"]
165
172
  if ptype_s not in ptype_m.keys():
@@ -191,6 +198,7 @@ class PackageDef(BaseModel):
191
198
  uses=ctor_t,
192
199
  params_ctor=param_t)
193
200
  else: # no new parameters declared
201
+ self._log.debug("Type only overrides existing parameters")
194
202
  for p in task.params.keys():
195
203
  param = task.params[p]
196
204
  if p not in field_m.keys():
@@ -203,12 +211,15 @@ class PackageDef(BaseModel):
203
211
  raise Exception("No value specified for param %s: %s" % (
204
212
  p, str(param)))
205
213
  field_m[p] = (field_m[p][0], value)
206
- ctor_t.params[p] = value
214
+ self._log.debug("Set param=%s to %s" % (p, str(value)))
215
+ ctor_t.params[p] = value
216
+
217
+ self._log.debug("<-- handleParams %s" % task.name)
207
218
 
208
219
  return ctor_t
209
220
 
210
221
  def mkTaskCtor(self, session, task, srcdir, tasks_m) -> TaskCtor:
211
- self._log.debug("--> %s::mkTaskCtor %s" % (self.name, task.name))
222
+ self._log.debug("--> %s::mkTaskCtor %s (srcdir: %s)" % (self.name, task.name, srcdir))
212
223
  ctor_t : TaskCtor = None
213
224
 
214
225
  # Determine the implementation constructor first
@@ -261,6 +272,7 @@ class PackageDef(BaseModel):
261
272
  srcdir=srcdir)
262
273
 
263
274
  ctor_t = self.handleParams(task, ctor_t)
275
+ ctor_t.depends.extend(task.depends)
264
276
 
265
277
  self._log.debug("<-- %s::mkTaskCtor %s" % (self.name, task.name))
266
278
  return ctor_t
@@ -305,6 +317,32 @@ class PackageDef(BaseModel):
305
317
  file_s.pop()
306
318
 
307
319
  return pkg
320
+
321
+ @staticmethod
322
+ def loads(data, exp_pkg_name=None):
323
+ return PackageDef._loadPkgDefS(data, exp_pkg_name)
324
+ pass
325
+
326
+ @staticmethod
327
+ def _loadPkgDefS(data, exp_pkg_name):
328
+ ret = None
329
+ doc = yaml.load(io.StringIO(data), Loader=yaml.FullLoader)
330
+ if "package" not in doc.keys():
331
+ raise Exception("Missing 'package' key in %s" % root)
332
+ pkg = PackageDef(**(doc["package"]))
333
+ pkg.basedir = None
334
+
335
+ # for t in pkg.tasks:
336
+ # t.basedir = os.path.dirname(root)
337
+
338
+ if exp_pkg_name is not None:
339
+ if exp_pkg_name != pkg.name:
340
+ raise Exception("Package name mismatch: %s != %s" % (exp_pkg_name, pkg.name))
341
+
342
+ if len(pkg.fragments) > 0:
343
+ raise Exception("Cannot load a package-def with fragments from a string")
344
+
345
+ return pkg
308
346
 
309
347
  @staticmethod
310
348
  def _loadFragmentSpec(pkg, spec, file_s):
@@ -0,0 +1,25 @@
1
+
2
+ from typing import Any, List, Union
3
+ from pydantic import BaseModel, Field
4
+
5
+ class ListType(BaseModel):
6
+ item : Union[str, 'ComplexType']
7
+
8
+ class MapType(BaseModel):
9
+ key : Union[str, 'ComplexType']
10
+ item : Union[str, 'ComplexType']
11
+
12
+ class ComplexType(BaseModel):
13
+ list : Union[ListType, None] = None
14
+ map : Union[MapType, None] = None
15
+
16
+ class ParamDef(BaseModel):
17
+ name : str
18
+ doc : str = None
19
+ type : Union[str, 'ComplexType'] = None
20
+ value : Union[Any, None] = None
21
+ append : Union[Any, None] = None
22
+ prepend : Union[Any, None] = None
23
+ path_append : Union[Any, None] = Field(alias="path-append", default=None)
24
+ path_prepend : Union[Any, None] = Field(alias="path-prepend", default=None)
25
+
@@ -26,6 +26,9 @@ class FileSet(Task):
26
26
  ex_memento = self.getMemento(TaskFileSetMemento)
27
27
  memento = TaskFileSetMemento()
28
28
 
29
+ self._log.debug("ex_memento: %s" % str(ex_memento))
30
+ self._log.debug("params: %s" % str(self.params))
31
+
29
32
  if self.params is not None:
30
33
  glob_root = os.path.join(self.srcdir, self.params.base)
31
34
  glob_root = glob_root.strip()
@@ -33,6 +36,8 @@ class FileSet(Task):
33
36
  if glob_root[-1] == '/' or glob_root == '\\':
34
37
  glob_root = glob_root[:-1]
35
38
 
39
+ self._log.debug("glob_root: %s" % glob_root)
40
+
36
41
  fs = _FileSet(
37
42
  src=self.name,
38
43
  type=self.params.type,
@@ -45,6 +50,8 @@ class FileSet(Task):
45
50
  for pattern in self.params.include:
46
51
  included_files.extend(glob.glob(os.path.join(glob_root, pattern), recursive=False))
47
52
 
53
+ self._log.debug("included_files: %s" % str(included_files))
54
+
48
55
  for file in included_files:
49
56
  if not any(glob.fnmatch.fnmatch(file, os.path.join(glob_root, pattern)) for pattern in self.params.exclude):
50
57
  memento.files.append((file, os.path.getmtime(os.path.join(glob_root, file))))
@@ -0,0 +1,78 @@
1
+
2
+ package:
3
+ name: std
4
+
5
+ tasks:
6
+ - name: Message
7
+ pyclass: dv_flow.mgr.std.message.Message
8
+ with:
9
+ msg:
10
+ type: str
11
+ value: ""
12
+ - name: FileSet
13
+ pyclass: dv_flow.mgr.std.fileset.FileSet
14
+ with:
15
+ base:
16
+ type: str
17
+ value: ""
18
+ type:
19
+ type: str
20
+ value: ""
21
+ include:
22
+ type: str
23
+ value: ""
24
+ exclude:
25
+ type: str
26
+ value: ""
27
+ # - name: Exec
28
+ # pyclass: dv_flow.mgr.std.exec.Exec
29
+ # with: {}
30
+ types:
31
+ # - name: TaskDataItem
32
+ # doc: |
33
+ # Base type for a data element produced by a task.
34
+ # TaskDataItem is never used directly
35
+ # with:
36
+ # - name: kind
37
+ # type: str
38
+ # kind: metadata
39
+ # doc: |
40
+ # Kind of data item
41
+ # - name: src
42
+ # type: str
43
+ # kind: metadata
44
+ # doc: |
45
+ # Name of the task that produced this item
46
+ # - name: id
47
+ # type: str
48
+ # kind: metadata
49
+ # doc: |
50
+ # Unique identiifer
51
+
52
+ - name: Env
53
+ doc: |
54
+ Environment variables
55
+ with:
56
+ - name: doc
57
+
58
+ - name: FileSet
59
+ uses: TaskDataItem
60
+ with:
61
+ - name: kind
62
+ value: "FileSet"
63
+ - name: base
64
+ type: str
65
+ - name: fileType
66
+ type: str
67
+ - name: files
68
+ type:
69
+ list:
70
+ item:
71
+ type: str
72
+
73
+ # type:
74
+ # list: (str,int)
75
+ # - complex type
76
+ # type:
77
+ # object:
78
+ #
@@ -123,7 +123,7 @@ class TaskCtorCls(TaskCtor):
123
123
  _log : ClassVar = logging.getLogger("TaskCtorCls")
124
124
 
125
125
  def mkTask(self, name : str, depends, rundir, srcdir=None, params=None):
126
- self._log.debug("--> %s::mkTask (%s)" % (self.name, str(self.task_ctor)))
126
+ self._log.debug("--> %s::mkTask (%s) srcdir=%s" % (self.name, str(self.task_ctor), srcdir))
127
127
 
128
128
  if srcdir is None:
129
129
  srcdir = self.srcdir
@@ -137,7 +137,6 @@ class TaskCtorCls(TaskCtor):
137
137
  rundir=rundir,
138
138
  srcdir=srcdir,
139
139
  params=params)
140
- ret.srcdir = self.srcdir
141
140
 
142
141
  # Update parameters on the way back
143
142
  self.applyParams(ret.params)
@@ -48,26 +48,22 @@ class TaskDataParam(BaseModel):
48
48
  kind : TaskDataParamKindE
49
49
  ops : List[TaskDataParamOp] = dc.Field(default_factory=list)
50
50
 
51
+ class TaskDataItem(BaseModel):
52
+ type : str
53
+ src : str
54
+ id : str
55
+
51
56
  class TaskData(BaseModel):
52
57
  src : str = None
53
- params : Dict[str,TaskDataParam] = dc.Field(default_factory=dict)
54
58
  deps : Dict[str,Set[str]] = dc.Field(default_factory=dict)
55
- filesets : List[FileSet] = dc.Field(default_factory=list)
56
59
  changed : bool = False
60
+ data : List[TaskDataItem] = dc.Field(default_factory=list)
57
61
 
58
62
  _log : ClassVar = logging.getLogger("TaskData")
59
63
 
60
- def hasParam(self, name: str) -> bool:
61
- return name in self.params
62
-
63
- def getParam(self, name: str) -> Any:
64
- return self.params[name]
65
-
66
- def setParam(self, name: str, value: Any):
67
- self.params[name] = value
68
-
69
- def addFileSet(self, fs : FileSet):
70
- self.filesets.append(fs)
64
+ def addData(self, item : TaskDataItem):
65
+ item.src = self.src
66
+ self.data.append(item)
71
67
 
72
68
  def getFileSets(self, type=None, order=True) -> List[FileSet]:
73
69
  ret = []
@@ -77,8 +73,10 @@ class TaskData(BaseModel):
77
73
  if order:
78
74
  # The deps map specifies task dependencies
79
75
 
76
+ filesets = filter(lambda x: x.type == "std.FileSet", self.data)
77
+
80
78
  candidate_fs = []
81
- for fs in self.filesets:
79
+ for fs in filesets:
82
80
  self._log.debug("fs: %s" % str(fs))
83
81
  if type is None or fs.type in type:
84
82
  candidate_fs.append(fs)
@@ -22,7 +22,9 @@
22
22
  import pydantic.dataclasses as dc
23
23
  from pydantic import BaseModel
24
24
  from typing import Any, Dict, List, Union, Tuple
25
+ from .param_def import ParamDef
25
26
  from .task import Task
27
+ from .task_output import TaskOutput
26
28
 
27
29
  @dc.dataclass
28
30
  class TaskSpec(object):
@@ -37,7 +39,8 @@ class TaskDef(BaseModel):
37
39
  desc : str = dc.Field(default="")
38
40
  doc : str = dc.Field(default="")
39
41
  depends : List[Union[str,TaskSpec]] = dc.Field(default_factory=list, alias="needs")
40
- params: Dict[str,Any] = dc.Field(default_factory=dict, alias="with")
42
+ params: List[ParamDef] = dc.Field(default_factory=list, alias="with")
43
+ out: List[TaskOutput] = dc.Field(default_factory=list)
41
44
 
42
45
  def copy(self) -> 'TaskDef':
43
46
  ret = TaskDef(
@@ -0,0 +1,17 @@
1
+
2
+ from pydantic import BaseModel
3
+ from typing import Any, ClassVar, Dict, Set, List, Tuple
4
+
5
+ class TaskImplParams(BaseModel):
6
+ pass
7
+
8
+ class TaskImplSourceData(BaseModel):
9
+ params : Any
10
+ changed : bool
11
+ memento : Any
12
+
13
+ class TaskImplResultData(BaseModel):
14
+ data : List[Any]
15
+ changed : bool
16
+ memento : Any
17
+
@@ -0,0 +1,6 @@
1
+ from pydantic import BaseModel, Field
2
+ from typing import Any, List
3
+
4
+ class TaskOutput(BaseModel):
5
+ type : str
6
+ params : List[Any] = Field(default_factory=list, alias="with")
@@ -0,0 +1,10 @@
1
+
2
+ from typing import List, Union
3
+ from pydantic import BaseModel, Field
4
+ from .param_def import ParamDef
5
+
6
+ class TypeDef(BaseModel):
7
+ name : str
8
+ uses : str = None
9
+ doc : str = None
10
+ fields : List[ParamDef] = Field(alias="with", default_factory=list)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: dv-flow-mgr
3
- Version: 0.0.1.12981364130a1
3
+ Version: 0.0.1.13335470340a1
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
@@ -5,11 +5,14 @@ ivpm.yaml
5
5
  pyproject.toml
6
6
  .github/workflows/ci.yml
7
7
  .vscode/settings.json
8
+ docs/KeyArchitecture.md
8
9
  docs/Makefile
9
10
  docs/Notes.md
10
11
  docs/Roadmap.md
11
12
  docs/Stages.md
13
+ docs/Steps.md
12
14
  docs/TypesAndDefs.md
15
+ docs/Usecases.md
13
16
  docs/conf.py
14
17
  docs/index.rst
15
18
  docs/intro.rst
@@ -17,11 +20,14 @@ docs/quickstart.rst
17
20
  docs/reference.rst
18
21
  src/dv_flow/mgr/__init__.py
19
22
  src/dv_flow/mgr/__main__.py
23
+ src/dv_flow/mgr/expr_parser.py
20
24
  src/dv_flow/mgr/fileset.py
21
25
  src/dv_flow/mgr/fragment_def.py
26
+ src/dv_flow/mgr/out
22
27
  src/dv_flow/mgr/package.py
23
28
  src/dv_flow/mgr/package_def.py
24
29
  src/dv_flow/mgr/package_import_spec.py
30
+ src/dv_flow/mgr/param_def.py
25
31
  src/dv_flow/mgr/pkg_rgy.py
26
32
  src/dv_flow/mgr/task.py
27
33
  src/dv_flow/mgr/task_data.py
@@ -29,7 +35,11 @@ src/dv_flow/mgr/task_def.py
29
35
  src/dv_flow/mgr/task_graph_builder.py
30
36
  src/dv_flow/mgr/task_graph_runner.py
31
37
  src/dv_flow/mgr/task_graph_runner_local.py
38
+ src/dv_flow/mgr/task_impl_data.py
32
39
  src/dv_flow/mgr/task_memento.py
40
+ src/dv_flow/mgr/task_output.py
41
+ src/dv_flow/mgr/type.py
42
+ src/dv_flow/mgr/type_def.py
33
43
  src/dv_flow/mgr/util.py
34
44
  src/dv_flow/mgr/cmds/cmd_run.py
35
45
  src/dv_flow/mgr/share/flow.json
@@ -50,6 +60,7 @@ tests/system/test_stdlib.py
50
60
  tests/unit/__init__.py
51
61
  tests/unit/test_data_merge.py
52
62
  tests/unit/test_fileset.py
63
+ tests/unit/test_parse.py
53
64
  tests/unit/test_pyclass.py
54
65
  tests/unit/test_smoke copy.sav
55
66
  tests/unit/test_smoke.py
@@ -39,7 +39,7 @@ def test_fileset_1(tmpdir):
39
39
  out = asyncio.run(runner.run(task))
40
40
  assert out.changed == False
41
41
 
42
- # Now, add a files
42
+ # Now, add a file
43
43
  with open(os.path.join(tmpdir, "test1", "files1", "file1_3.sv"), "w") as f:
44
44
  f.write("// file1_3.sv\n")
45
45
 
@@ -0,0 +1,38 @@
1
+ import io
2
+ import pytest
3
+ import yaml
4
+
5
+ from dv_flow.mgr.type_def import TypeDef
6
+
7
+ def test_typedef_1():
8
+ flow_dv = """
9
+ package:
10
+ name: abc
11
+ types:
12
+ - name: T1
13
+ with:
14
+ - name: F1
15
+ doc: "Field 1"
16
+ type: str
17
+ - name: F2
18
+ type:
19
+ list:
20
+ item: str
21
+ - name: F3
22
+ type:
23
+ map:
24
+ key: str
25
+ item:
26
+ list:
27
+ item: str
28
+ """
29
+
30
+ data = yaml.load(io.StringIO(flow_dv), yaml.FullLoader)
31
+
32
+ typedef = data["package"]["types"][0]
33
+ td = TypeDef(**typedef)
34
+
35
+ print("td=" + str(td))
36
+
37
+
38
+
@@ -3,12 +3,66 @@ import io
3
3
  import os
4
4
  import dataclasses as dc
5
5
  import pytest
6
+ import jq
6
7
  from typing import List
7
8
  import yaml
8
- from dv_flow.mgr import FileSet, PackageDef, TaskData
9
+ from dv_flow.mgr import FileSet, PackageDef, TaskData, TaskGraphBuilder
9
10
  from pydantic import BaseModel
10
11
  from shutil import copytree
11
12
 
13
+ def test_smoke_1():
14
+ flowdv = """
15
+ package:
16
+ name: my_pkg
17
+
18
+ tasks:
19
+ - name: entry
20
+ with:
21
+ - name: p1
22
+ type: int
23
+ - name: p2
24
+ type: int
25
+ """
26
+
27
+ pkg_def = PackageDef.loads(flowdv)
28
+ builder = TaskGraphBuilder(pkg_def, os.getcwd())
29
+ task = builder.mkTaskGraph("my_pkg.entry")
30
+
31
+ def test_jq():
32
+ data = [
33
+ {
34
+ "type": "FileSet",
35
+ "kind": "systemVerilogSource"
36
+ },
37
+ {
38
+ "type": "FileSet",
39
+ "kind": "vhdlSource"
40
+ },
41
+ {
42
+ "type": "FileSet",
43
+ "kind": "verilogSource"
44
+ }
45
+ ]
46
+
47
+ result = jq.compile(""".[] |
48
+ select(
49
+ .kind == "systemVerilogSource"
50
+ or .kind == "verilogSource")
51
+ """).input(data).all()
52
+ value = """
53
+ with:
54
+ - name: files
55
+ list-append: |
56
+ ${{
57
+ in | jq('.[] | select(
58
+ .kind == "systemVerilogSource"
59
+ or .kind == "verilogSource")')
60
+ }}
61
+ """
62
+ print("result: %s" % str(result))
63
+
64
+
65
+
12
66
  # def test_smoke():
13
67
  # file = """
14
68
  # package:
@@ -1,30 +0,0 @@
1
-
2
- package:
3
- name: std
4
-
5
- tasks:
6
- - name: Message
7
- pyclass: dv_flow.mgr.std.message.Message
8
- with:
9
- msg:
10
- type: str
11
- value: ""
12
- - name: FileSet
13
- pyclass: dv_flow.mgr.std.fileset.FileSet
14
- with:
15
- base:
16
- type: str
17
- value: ""
18
- type:
19
- type: str
20
- value: ""
21
- include:
22
- type: str
23
- value: ""
24
- exclude:
25
- type: str
26
- value: ""
27
- # - name: Exec
28
- # pyclass: dv_flow.mgr.std.exec.Exec
29
- # with: {}
30
-