dv-flow-mgr 1.7.14886019138rc0__py3-none-any.whl → 1.8.14920283751rc0__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/__init__.py CHANGED
@@ -31,7 +31,7 @@ from .task_node_ctor_wrapper import task
31
31
  from .task_runner import TaskSetRunner
32
32
  from .task_listener_log import TaskListenerLog
33
33
 
34
- VERSION="1.7.0"
35
- SUFFIX="14886019138rc0"
34
+ VERSION="1.8.0"
35
+ SUFFIX="14920283751rc0"
36
36
  __version__="%s%s" % (VERSION, SUFFIX)
37
37
 
@@ -28,6 +28,7 @@ from ..task_data import SeverityE
28
28
  from ..task_graph_builder import TaskGraphBuilder
29
29
  from ..task_runner import TaskSetRunner
30
30
  from ..task_listener_log import TaskListenerLog
31
+ from ..task_listener_trace import TaskListenerTrace
31
32
 
32
33
 
33
34
  class CmdRun(object):
@@ -98,7 +99,14 @@ class CmdRun(object):
98
99
  if args.j != -1:
99
100
  runner.nproc = int(args.j)
100
101
 
102
+ if not os.path.isdir(os.path.join(rundir, "log")):
103
+ os.makedirs(os.path.join(rundir, "log"))
104
+
105
+ fp = open(os.path.join(rundir, "log", "%s.trace.json" % pkg.name), "w")
106
+ trace = TaskListenerTrace(fp)
107
+
101
108
  runner.add_listener(listener.event)
109
+ runner.add_listener(trace.event)
102
110
 
103
111
  tasks = []
104
112
 
@@ -110,6 +118,9 @@ class CmdRun(object):
110
118
 
111
119
  asyncio.run(runner.run(tasks))
112
120
 
121
+ trace.close()
122
+ fp.close()
123
+
113
124
  return runner.status
114
125
 
115
126
 
@@ -0,0 +1,160 @@
1
+ import dataclasses as dc
2
+ import json
3
+ import time
4
+ from typing import Dict, List, TextIO
5
+ from .task_node import TaskNode
6
+
7
+ @dc.dataclass
8
+ class TaskListenerTrace(object):
9
+ """Task listener that generates Google Trace Event Format output."""
10
+
11
+ fp: TextIO # File to write trace events to
12
+ _free_tids: List = dc.field(default_factory=list) # Pool of available thread IDs
13
+ _task_tid_map: Dict = dc.field(default_factory=dict) # Map of tasks to their assigned thread IDs
14
+ _next_tid: int = dc.field(default=1) # Next thread ID to assign if pool is empty
15
+ _next_flow_id: int = dc.field(default=1) # Counter for unique flow IDs
16
+ _events: List = dc.field(default_factory=list) # Store events in memory
17
+
18
+ def __post_init__(self):
19
+ # Add metadata event
20
+ self._events.append({
21
+ "name": "metadata",
22
+ "ph": "M",
23
+ "pid": 1,
24
+ "tid": 0,
25
+ "args": {
26
+ "name": "Task Execution",
27
+ "timeUnit": "us"
28
+ }
29
+ })
30
+
31
+ def close(self):
32
+ """Write the complete trace file and close it."""
33
+ trace = {
34
+ "traceEvents": self._events,
35
+ "displayTimeUnit": "ms" # Show times in milliseconds in the viewer
36
+ }
37
+ json.dump(trace, self.fp, indent=2)
38
+ self.fp.flush()
39
+
40
+ def _get_tid(self, task: TaskNode) -> int:
41
+ """Get a thread ID for a task, either from the pool or creating a new one."""
42
+ if task in self._task_tid_map:
43
+ return self._task_tid_map[task]
44
+
45
+ if len(self._free_tids) > 0:
46
+ tid = self._free_tids.pop()
47
+ else:
48
+ tid = self._next_tid
49
+ self._next_tid += 1
50
+
51
+ self._task_tid_map[task] = tid
52
+ return tid
53
+
54
+ def _release_tid(self, task: TaskNode):
55
+ """Return a task's thread ID to the pool."""
56
+ if task in self._task_tid_map:
57
+ tid = self._task_tid_map[task]
58
+ del self._task_tid_map[task]
59
+ self._free_tids.append(tid)
60
+
61
+ def event(self, task: TaskNode, reason: str):
62
+ """Record a task execution event.
63
+
64
+ Args:
65
+ task: The task that generated the event
66
+ reason: Either 'enter' or 'leave' marking start/end of task execution
67
+ """
68
+ # Get/create thread ID for this task
69
+ tid = self._get_tid(task)
70
+
71
+ # Map the event type
72
+ ph = 'B' if reason == 'enter' else 'E'
73
+
74
+ # Get current timestamp in microseconds
75
+ ts = int(time.time() * 1_000_000) if reason == "enter" else int(task.end.timestamp() * 1_000_000)
76
+
77
+ # Create the duration event
78
+ event = {
79
+ "name": task.name,
80
+ "cat": "task",
81
+ "ph": ph,
82
+ "pid": 1,
83
+ "tid": tid,
84
+ "ts": ts
85
+ }
86
+
87
+ # Store the duration event
88
+ self._events.append(event)
89
+
90
+ if reason == "enter":
91
+ # When a task starts, create flow events from all its dependencies
92
+ for need, _ in task.needs:
93
+ flow_id = self._next_flow_id
94
+ self._next_flow_id += 1
95
+
96
+ # # Add flow end event connecting to this task
97
+ # flow_end = {
98
+ # "name": f"{need.name} -> {task.name}",
99
+ # "cat": "flow",
100
+ # "ph": "e", # Flow end
101
+ # "pid": 1,
102
+ # "tid": tid, # Target task's thread
103
+ # "ts": ts,
104
+ # "id": flow_id,
105
+ # "bp": "e" # Connect to enclosing slice
106
+ # }
107
+ # self._events.append(flow_end)
108
+
109
+ # # Add flow start event from dependency
110
+ # flow_start = {
111
+ # "name": f"{need.name} -> {task.name}",
112
+ # "cat": "flow",
113
+ # "ph": "b", # Flow begin
114
+ # "pid": 1,
115
+ # "tid": self._task_tid_map.get(need, 0), # Source task's thread
116
+ # "ts": int(need.end.timestamp() * 1_000_000) if need.end else ts,
117
+ # "id": flow_id,
118
+ # "bp": "e" # Connect to enclosing slice
119
+ # }
120
+ # self._events.append(flow_start)
121
+
122
+ elif reason == 'leave':
123
+ # For completed tasks, emit flow start events
124
+ if task.result:
125
+ event["args"] = {
126
+ "status": task.result.status,
127
+ "changed": task.result.changed
128
+ }
129
+
130
+ # Find any tasks that depend on this one and create flow events
131
+ for dep_task, dep_tid in self._task_tid_map.items():
132
+ if any(need[0] is task for need in dep_task.needs):
133
+ # # Create flow start event
134
+ # flow = {
135
+ # "name": f"{task.name} -> {dep_task.name}",
136
+ # "cat": "flow",
137
+ # "ph": "s", # Flow start
138
+ # "pid": 1,
139
+ # "tid": tid, # Source task's thread
140
+ # "ts": ts, # Use task end time
141
+ # "id": self._next_flow_id,
142
+ # "bp": "e" # Connect to enclosing slice
143
+ # }
144
+ # self._events.append(flow)
145
+
146
+ # # Create flow end event
147
+ # flow_end = {
148
+ # "name": f"{task.name} -> {dep_task.name}",
149
+ # "cat": "flow",
150
+ # "ph": "f", # Flow finish
151
+ # "pid": 1,
152
+ # "tid": dep_tid, # Target task's thread
153
+ # "ts": ts, # Will be updated when target task starts
154
+ # "id": self._next_flow_id,
155
+ # "bp": "e" # Connect to enclosing slice
156
+ # }
157
+ # self._events.append(flow_end)
158
+ self._next_flow_id += 1
159
+
160
+ self._release_tid(task)
dv_flow/mgr/task_node.py CHANGED
@@ -24,6 +24,7 @@ import json
24
24
  import os
25
25
  import sys
26
26
  import dataclasses as dc
27
+ import datetime
27
28
  import pydantic.dataclasses as pdc
28
29
  import logging
29
30
  import toposort
@@ -55,8 +56,8 @@ class TaskNode(object):
55
56
  rundir : List[str] = dc.field(default=None)
56
57
  output : TaskDataOutput = dc.field(default=None)
57
58
  result : TaskDataResult = dc.field(default=None)
58
- start : float = dc.field(default=None)
59
- end : float = dc.field(default=None)
59
+ start : datetime.datetime = dc.field(default=None)
60
+ end : datetime.datetime = dc.field(default=None)
60
61
  save_exec_data : bool = dc.field(default=True)
61
62
  iff : bool = dc.field(default=True)
62
63
  parent : 'TaskNode' = dc.field(default=None)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dv-flow-mgr
3
- Version: 1.7.14886019138rc0
3
+ Version: 1.8.14920283751rc0
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
@@ -1,4 +1,4 @@
1
- dv_flow/mgr/__init__.py,sha256=IGdCSIE1H9oiKxdBHCoep36ZQbA0PNZeiF-QVlXh3gQ,1315
1
+ dv_flow/mgr/__init__.py,sha256=NUUQLnpk4-yjT3DaUH9ugThEF8n1nqhlzLs6YW9zLHU,1315
2
2
  dv_flow/mgr/__main__.py,sha256=BogNdBkXhgg05E8_IumNkVoag6WwvfbpiI8346oOtPo,3844
3
3
  dv_flow/mgr/cond_def.py,sha256=2ZkzPusqVkN1fFMTvkDl9O_OJLPdD_cK3xzX9J75RMw,343
4
4
  dv_flow/mgr/config.py,sha256=b2MVlVVNB0psk8x4bQRAYshkpNJrtyMtV1Ymhmx9AfM,137
@@ -37,7 +37,8 @@ dv_flow/mgr/task_def.py,sha256=8NPwtTROfWDkMqcO9mKXV4dw0sC4mCMmnsNuv8uTdTY,5094
37
37
  dv_flow/mgr/task_graph_builder.py,sha256=q7BS7OLYkS6uZwQLvo6P_CtJkhIvPal_tXLZHgUuLpU,28172
38
38
  dv_flow/mgr/task_graph_dot_writer.py,sha256=qK4Imy9o2_F1aKoU1tJ-qoBHslq2BhSMbdjAUPfpN7I,6009
39
39
  dv_flow/mgr/task_listener_log.py,sha256=Ai-6X5BOoGsaNTgnlXEW0-czrjJm7__ShNK501CUmko,4337
40
- dv_flow/mgr/task_node.py,sha256=3L1qqwisV_qRdbUdRG25uzcsO57T2Z7fbvXYF87Ta1U,5191
40
+ dv_flow/mgr/task_listener_trace.py,sha256=76Fqb7hiAT2GH8_-_bMRAl6T2lrTly6sP1Zis6BG3wU,6192
41
+ dv_flow/mgr/task_node.py,sha256=OC3rkeRSFv9wmgkMZ_7eJu7nuXGJcwW_b6FGQM-w7AU,5231
41
42
  dv_flow/mgr/task_node_compound.py,sha256=0biBPT_2SpCPJL7DFaFY27_K7kNxJ1taIut3Fv12HXk,3347
42
43
  dv_flow/mgr/task_node_ctor.py,sha256=YsoVMX5WbpbzcHvEK7ps_ZRV-J7MZ3F8NNozQw7vbog,4418
43
44
  dv_flow/mgr/task_node_ctor_compound.py,sha256=290JdcTnL3b3Gv7s_wRLjdM02ezKhc9QnxZE0mv72i8,4379
@@ -56,7 +57,7 @@ dv_flow/mgr/type.py,sha256=hoJTatlPC0yOazKSWduK-5CfY38RPkc6qXFzOCcVSdM,723
56
57
  dv_flow/mgr/type_def.py,sha256=4sge3PibO1jDnS0cXdX0PiurcKbDA3kT6rb4DGIKwEM,1176
57
58
  dv_flow/mgr/yaml_srcinfo_loader.py,sha256=29BNRiB8Hj1FepkrLtdjHSv5U_85Q432gBeeK80nKEA,1606
58
59
  dv_flow/mgr/cmds/cmd_graph.py,sha256=yg5KbNrGvm3dySiI0Qei_pMWZkOE9GtEyaQ4IdNVmoE,2852
59
- dv_flow/mgr/cmds/cmd_run.py,sha256=J53JJnUPn9yLDFHFv_DJdnZR2qMvbhsGWY8APHoVtWE,3707
60
+ dv_flow/mgr/cmds/cmd_run.py,sha256=SsCZXwutJW1XT5iXtJqvdeg6p6HEa86V5hELNKuaWgA,4082
60
61
  dv_flow/mgr/cmds/cmd_show.py,sha256=JOIFaVXt8YCf9bKXfq6qzV5wQdxdLHqE-yCj0ecGREs,3755
61
62
  dv_flow/mgr/share/flow.json,sha256=lNmZex9NXkYbyb2aZseQfUOkV9CMyfH0iLODEI7EPBw,5096
62
63
  dv_flow/mgr/std/create_file.py,sha256=SEpKTQdiY32002C7b4kYfAiK9v_xajixOJU5WftW75I,2957
@@ -73,9 +74,9 @@ dv_flow/mgr/util/util.py,sha256=BO7iqP_c9ttmXkojq7nKDN-g8wl1_Pco9k-KnrXxjwE,1889
73
74
  dv_flow/mgr/util/cmds/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
74
75
  dv_flow/mgr/util/cmds/cmd_schema.py,sha256=IJzZdxCSEgIQ79LpYiM7UqJ9RJ-7yraqmBN2XVgAgXA,1752
75
76
  dv_flow/mgr/util/cmds/cmd_workspace.py,sha256=egmaIXpe5L-TePwmcfisfrG6tdiTUWSjqa9Za5WChVs,890
76
- dv_flow_mgr-1.7.14886019138rc0.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
77
- dv_flow_mgr-1.7.14886019138rc0.dist-info/METADATA,sha256=BdTQJ9Wt87mId9RnZiwCzqIYuHtedmHd8zGNmMykNDc,13335
78
- dv_flow_mgr-1.7.14886019138rc0.dist-info/WHEEL,sha256=0CuiUZ_p9E4cD6NyLD6UG80LBXYyiSYZOKDm5lp32xk,91
79
- dv_flow_mgr-1.7.14886019138rc0.dist-info/entry_points.txt,sha256=1roy8wAFM48LabOvr6jiOw0MUs-qE8X3Vf8YykPazxk,50
80
- dv_flow_mgr-1.7.14886019138rc0.dist-info/top_level.txt,sha256=amfVTkggzYPtWwLqNmRukfz1Buu0pGS2SrYBBLhXm04,8
81
- dv_flow_mgr-1.7.14886019138rc0.dist-info/RECORD,,
77
+ dv_flow_mgr-1.8.14920283751rc0.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
78
+ dv_flow_mgr-1.8.14920283751rc0.dist-info/METADATA,sha256=CeTzqO-0eYhSYkg9hMV97sS0lr_W_2gulAFrOH5wy_4,13335
79
+ dv_flow_mgr-1.8.14920283751rc0.dist-info/WHEEL,sha256=0CuiUZ_p9E4cD6NyLD6UG80LBXYyiSYZOKDm5lp32xk,91
80
+ dv_flow_mgr-1.8.14920283751rc0.dist-info/entry_points.txt,sha256=1roy8wAFM48LabOvr6jiOw0MUs-qE8X3Vf8YykPazxk,50
81
+ dv_flow_mgr-1.8.14920283751rc0.dist-info/top_level.txt,sha256=amfVTkggzYPtWwLqNmRukfz1Buu0pGS2SrYBBLhXm04,8
82
+ dv_flow_mgr-1.8.14920283751rc0.dist-info/RECORD,,