siliconcompiler 0.32.1__py3-none-any.whl → 0.32.3__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.
Files changed (187) hide show
  1. siliconcompiler/_metadata.py +3 -2
  2. siliconcompiler/apps/sc_install.py +13 -5
  3. siliconcompiler/apps/sc_remote.py +2 -1
  4. siliconcompiler/core.py +68 -55
  5. siliconcompiler/issue.py +3 -1
  6. siliconcompiler/remote/client.py +55 -16
  7. siliconcompiler/report/__init__.py +3 -2
  8. siliconcompiler/report/dashboard/__init__.py +61 -170
  9. siliconcompiler/report/dashboard/cli/__init__.py +788 -0
  10. siliconcompiler/report/dashboard/web/__init__.py +196 -0
  11. siliconcompiler/report/dashboard/{components → web/components}/__init__.py +4 -4
  12. siliconcompiler/report/dashboard/{components → web/components}/graph.py +1 -1
  13. siliconcompiler/report/dashboard/{layouts → web/layouts}/__init__.py +3 -3
  14. siliconcompiler/report/dashboard/{layouts → web/layouts}/_common.py +1 -1
  15. siliconcompiler/report/dashboard/{layouts → web/layouts}/vertical_flowgraph.py +5 -5
  16. siliconcompiler/report/dashboard/{layouts → web/layouts}/vertical_flowgraph_node_tab.py +6 -6
  17. siliconcompiler/report/dashboard/{layouts → web/layouts}/vertical_flowgraph_sac_tabs.py +6 -6
  18. siliconcompiler/report/dashboard/{viewer.py → web/viewer.py} +4 -4
  19. siliconcompiler/scheduler/__init__.py +44 -13
  20. siliconcompiler/scheduler/docker_runner.py +2 -1
  21. siliconcompiler/sphinx_ext/dynamicgen.py +11 -11
  22. siliconcompiler/templates/replay/replay.sh.j2 +2 -2
  23. siliconcompiler/templates/tcl/manifest.tcl.j2 +4 -120
  24. siliconcompiler/tools/_common/__init__.py +2 -0
  25. siliconcompiler/tools/_common/tcl/sc_schema_access.tcl +126 -0
  26. siliconcompiler/tools/openroad/_apr.py +7 -0
  27. siliconcompiler/tools/openroad/fillmetal_insertion.py +14 -14
  28. siliconcompiler/tools/openroad/scripts/apr/sc_antenna_repair.tcl +1 -1
  29. siliconcompiler/tools/openroad/scripts/apr/sc_clock_tree_synthesis.tcl +1 -1
  30. siliconcompiler/tools/openroad/scripts/apr/sc_detailed_placement.tcl +1 -1
  31. siliconcompiler/tools/openroad/scripts/apr/sc_detailed_route.tcl +1 -1
  32. siliconcompiler/tools/openroad/scripts/apr/sc_endcap_tapcell_insertion.tcl +1 -1
  33. siliconcompiler/tools/openroad/scripts/apr/sc_fillercell_insertion.tcl +1 -1
  34. siliconcompiler/tools/openroad/scripts/apr/sc_fillmetal_insertion.tcl +2 -2
  35. siliconcompiler/tools/openroad/scripts/apr/sc_global_placement.tcl +1 -1
  36. siliconcompiler/tools/openroad/scripts/apr/sc_global_route.tcl +1 -1
  37. siliconcompiler/tools/openroad/scripts/apr/sc_init_floorplan.tcl +1 -1
  38. siliconcompiler/tools/openroad/scripts/apr/sc_macro_placement.tcl +1 -1
  39. siliconcompiler/tools/openroad/scripts/apr/sc_metrics.tcl +1 -1
  40. siliconcompiler/tools/openroad/scripts/apr/sc_pin_placement.tcl +1 -1
  41. siliconcompiler/tools/openroad/scripts/apr/sc_power_grid.tcl +1 -1
  42. siliconcompiler/tools/openroad/scripts/apr/sc_repair_design.tcl +1 -1
  43. siliconcompiler/tools/openroad/scripts/apr/sc_repair_timing.tcl +54 -8
  44. siliconcompiler/tools/openroad/scripts/apr/sc_write_data.tcl +1 -1
  45. siliconcompiler/tools/openroad/scripts/common/procs.tcl +19 -1
  46. siliconcompiler/tools/openroad/scripts/common/reports.tcl +18 -7
  47. siliconcompiler/tools/openroad/scripts/sc_rcx.tcl +1 -1
  48. siliconcompiler/tools/openroad/scripts/sc_rdlroute.tcl +1 -1
  49. siliconcompiler/tools/openroad/scripts/sc_show.tcl +1 -1
  50. siliconcompiler/tools/opensta/__init__.py +1 -1
  51. siliconcompiler/tools/opensta/scripts/sc_check_library.tcl +1 -1
  52. siliconcompiler/tools/opensta/scripts/sc_procs.tcl +16 -0
  53. siliconcompiler/tools/opensta/scripts/sc_report_libraries.tcl +1 -1
  54. siliconcompiler/tools/opensta/scripts/sc_timing.tcl +35 -7
  55. siliconcompiler/tools/opensta/timing.py +6 -2
  56. siliconcompiler/tools/slang/__init__.py +7 -8
  57. siliconcompiler/tools/sv2v/sv2v.py +4 -1
  58. siliconcompiler/tools/yosys/__init__.py +4 -36
  59. siliconcompiler/tools/yosys/lec.py +3 -4
  60. siliconcompiler/tools/yosys/{syn_asic.tcl → sc_synth_asic.tcl} +87 -0
  61. siliconcompiler/tools/yosys/{syn_fpga.tcl → sc_synth_fpga.tcl} +78 -0
  62. siliconcompiler/tools/yosys/syn_asic.py +36 -11
  63. siliconcompiler/tools/yosys/syn_fpga.py +23 -16
  64. siliconcompiler/toolscripts/_tools.json +23 -9
  65. siliconcompiler/toolscripts/rhel8/install-chisel.sh +2 -0
  66. siliconcompiler/toolscripts/rhel8/install-icarus.sh +1 -0
  67. siliconcompiler/toolscripts/rhel8/install-klayout.sh +2 -0
  68. siliconcompiler/toolscripts/rhel8/install-magic.sh +1 -2
  69. siliconcompiler/toolscripts/rhel8/install-netgen.sh +1 -1
  70. siliconcompiler/toolscripts/rhel8/install-slang.sh +2 -0
  71. siliconcompiler/toolscripts/rhel8/install-surelog.sh +3 -1
  72. siliconcompiler/toolscripts/rhel8/install-sv2v.sh +1 -0
  73. siliconcompiler/toolscripts/rhel8/install-verible.sh +2 -0
  74. siliconcompiler/toolscripts/rhel8/install-verilator.sh +1 -0
  75. siliconcompiler/toolscripts/rhel8/install-xyce.sh +2 -0
  76. siliconcompiler/toolscripts/rhel9/install-chisel.sh +2 -0
  77. siliconcompiler/toolscripts/rhel9/install-ghdl.sh +1 -0
  78. siliconcompiler/toolscripts/rhel9/install-gtkwave.sh +2 -1
  79. siliconcompiler/toolscripts/rhel9/install-icarus.sh +1 -0
  80. siliconcompiler/toolscripts/rhel9/install-klayout.sh +2 -0
  81. siliconcompiler/toolscripts/rhel9/install-magic.sh +1 -2
  82. siliconcompiler/toolscripts/rhel9/install-netgen.sh +1 -1
  83. siliconcompiler/toolscripts/rhel9/install-openroad.sh +2 -0
  84. siliconcompiler/toolscripts/rhel9/install-opensta.sh +76 -0
  85. siliconcompiler/toolscripts/rhel9/install-slang.sh +3 -1
  86. siliconcompiler/toolscripts/rhel9/install-surelog.sh +2 -1
  87. siliconcompiler/toolscripts/rhel9/install-sv2v.sh +1 -0
  88. siliconcompiler/toolscripts/rhel9/install-verible.sh +2 -0
  89. siliconcompiler/toolscripts/rhel9/install-verilator.sh +1 -0
  90. siliconcompiler/toolscripts/rhel9/install-vpr.sh +31 -0
  91. siliconcompiler/toolscripts/rhel9/install-xdm.sh +2 -0
  92. siliconcompiler/toolscripts/rhel9/install-xyce.sh +2 -0
  93. siliconcompiler/toolscripts/rhel9/install-yosys-moosic.sh +2 -0
  94. siliconcompiler/toolscripts/rhel9/install-yosys-parmys.sh +61 -0
  95. siliconcompiler/toolscripts/rhel9/install-yosys-slang.sh +3 -1
  96. siliconcompiler/toolscripts/rhel9/install-yosys.sh +2 -0
  97. siliconcompiler/toolscripts/ubuntu20/install-bambu.sh +2 -0
  98. siliconcompiler/toolscripts/ubuntu20/install-bluespec.sh +2 -0
  99. siliconcompiler/toolscripts/ubuntu20/install-chisel.sh +2 -0
  100. siliconcompiler/toolscripts/ubuntu20/install-ghdl.sh +2 -0
  101. siliconcompiler/toolscripts/ubuntu20/install-gtkwave.sh +2 -0
  102. siliconcompiler/toolscripts/ubuntu20/install-icarus.sh +2 -0
  103. siliconcompiler/toolscripts/ubuntu20/install-icepack.sh +2 -0
  104. siliconcompiler/toolscripts/ubuntu20/install-klayout.sh +2 -0
  105. siliconcompiler/toolscripts/ubuntu20/install-magic.sh +2 -0
  106. siliconcompiler/toolscripts/ubuntu20/install-netgen.sh +2 -0
  107. siliconcompiler/toolscripts/ubuntu20/install-nextpnr.sh +1 -3
  108. siliconcompiler/toolscripts/ubuntu20/install-openroad.sh +2 -0
  109. siliconcompiler/toolscripts/ubuntu20/install-opensta.sh +72 -0
  110. siliconcompiler/toolscripts/ubuntu20/install-slang.sh +3 -1
  111. siliconcompiler/toolscripts/ubuntu20/install-slurm.sh +2 -0
  112. siliconcompiler/toolscripts/ubuntu20/install-surelog.sh +3 -1
  113. siliconcompiler/toolscripts/ubuntu20/install-sv2v.sh +1 -1
  114. siliconcompiler/toolscripts/ubuntu20/install-verible.sh +2 -0
  115. siliconcompiler/toolscripts/ubuntu20/install-verilator.sh +2 -0
  116. siliconcompiler/toolscripts/ubuntu20/install-vpr.sh +2 -0
  117. siliconcompiler/toolscripts/ubuntu20/install-xdm.sh +2 -0
  118. siliconcompiler/toolscripts/ubuntu20/install-xyce.sh +2 -0
  119. siliconcompiler/toolscripts/ubuntu20/install-yosys-moosic.sh +2 -0
  120. siliconcompiler/toolscripts/ubuntu20/install-yosys-parmys.sh +61 -0
  121. siliconcompiler/toolscripts/ubuntu20/install-yosys.sh +2 -0
  122. siliconcompiler/toolscripts/ubuntu22/install-bambu.sh +2 -0
  123. siliconcompiler/toolscripts/ubuntu22/install-bluespec.sh +27 -2
  124. siliconcompiler/toolscripts/ubuntu22/install-chisel.sh +2 -0
  125. siliconcompiler/toolscripts/ubuntu22/install-ghdl.sh +4 -2
  126. siliconcompiler/toolscripts/ubuntu22/install-gtkwave.sh +2 -0
  127. siliconcompiler/toolscripts/ubuntu22/install-icarus.sh +2 -0
  128. siliconcompiler/toolscripts/ubuntu22/install-icepack.sh +2 -0
  129. siliconcompiler/toolscripts/ubuntu22/install-klayout.sh +2 -0
  130. siliconcompiler/toolscripts/ubuntu22/install-magic.sh +2 -0
  131. siliconcompiler/toolscripts/ubuntu22/install-netgen.sh +2 -0
  132. siliconcompiler/toolscripts/ubuntu22/install-nextpnr.sh +1 -2
  133. siliconcompiler/toolscripts/ubuntu22/install-openroad.sh +2 -0
  134. siliconcompiler/toolscripts/ubuntu22/install-opensta.sh +72 -0
  135. siliconcompiler/toolscripts/ubuntu22/install-slang.sh +3 -1
  136. siliconcompiler/toolscripts/ubuntu22/install-slurm.sh +2 -0
  137. siliconcompiler/toolscripts/ubuntu22/install-surelog.sh +3 -1
  138. siliconcompiler/toolscripts/ubuntu22/install-sv2v.sh +1 -1
  139. siliconcompiler/toolscripts/ubuntu22/install-verible.sh +2 -0
  140. siliconcompiler/toolscripts/ubuntu22/install-verilator.sh +2 -0
  141. siliconcompiler/toolscripts/ubuntu22/install-vpr.sh +2 -0
  142. siliconcompiler/toolscripts/ubuntu22/install-xdm.sh +2 -0
  143. siliconcompiler/toolscripts/ubuntu22/install-xyce.sh +2 -0
  144. siliconcompiler/toolscripts/ubuntu22/install-yosys-moosic.sh +2 -0
  145. siliconcompiler/toolscripts/ubuntu22/install-yosys-parmys.sh +61 -0
  146. siliconcompiler/toolscripts/ubuntu22/install-yosys-slang.sh +3 -1
  147. siliconcompiler/toolscripts/ubuntu22/install-yosys.sh +2 -0
  148. siliconcompiler/toolscripts/ubuntu24/install-bambu.sh +2 -0
  149. siliconcompiler/toolscripts/ubuntu24/install-bluespec.sh +2 -0
  150. siliconcompiler/toolscripts/ubuntu24/install-chisel.sh +2 -0
  151. siliconcompiler/toolscripts/ubuntu24/install-ghdl.sh +4 -2
  152. siliconcompiler/toolscripts/ubuntu24/install-gtkwave.sh +2 -0
  153. siliconcompiler/toolscripts/ubuntu24/install-icarus.sh +2 -0
  154. siliconcompiler/toolscripts/ubuntu24/install-icepack.sh +2 -0
  155. siliconcompiler/toolscripts/ubuntu24/install-klayout.sh +2 -0
  156. siliconcompiler/toolscripts/ubuntu24/install-magic.sh +2 -0
  157. siliconcompiler/toolscripts/ubuntu24/install-netgen.sh +2 -0
  158. siliconcompiler/toolscripts/ubuntu24/install-nextpnr.sh +1 -3
  159. siliconcompiler/toolscripts/ubuntu24/install-openroad.sh +2 -0
  160. siliconcompiler/toolscripts/ubuntu24/install-opensta.sh +72 -0
  161. siliconcompiler/toolscripts/ubuntu24/install-slang.sh +3 -1
  162. siliconcompiler/toolscripts/ubuntu24/install-slurm.sh +2 -0
  163. siliconcompiler/toolscripts/ubuntu24/install-surelog.sh +3 -1
  164. siliconcompiler/toolscripts/ubuntu24/install-sv2v.sh +1 -1
  165. siliconcompiler/toolscripts/ubuntu24/install-verible.sh +2 -0
  166. siliconcompiler/toolscripts/ubuntu24/install-verilator.sh +2 -0
  167. siliconcompiler/toolscripts/ubuntu24/install-vpr.sh +2 -0
  168. siliconcompiler/toolscripts/ubuntu24/install-xdm.sh +2 -0
  169. siliconcompiler/toolscripts/ubuntu24/install-xyce.sh +2 -0
  170. siliconcompiler/toolscripts/ubuntu24/install-yosys-moosic.sh +2 -0
  171. siliconcompiler/toolscripts/ubuntu24/install-yosys-parmys.sh +61 -0
  172. siliconcompiler/toolscripts/ubuntu24/install-yosys-slang.sh +3 -1
  173. siliconcompiler/toolscripts/ubuntu24/install-yosys.sh +2 -0
  174. siliconcompiler/utils/__init__.py +4 -1
  175. siliconcompiler/utils/logging.py +88 -34
  176. {siliconcompiler-0.32.1.dist-info → siliconcompiler-0.32.3.dist-info}/METADATA +14 -10
  177. {siliconcompiler-0.32.1.dist-info → siliconcompiler-0.32.3.dist-info}/RECORD +185 -175
  178. {siliconcompiler-0.32.1.dist-info → siliconcompiler-0.32.3.dist-info}/WHEEL +1 -1
  179. siliconcompiler/tools/yosys/sc_syn.tcl +0 -87
  180. siliconcompiler/toolscripts/ubuntu20/install-yosys-slang.sh +0 -22
  181. /siliconcompiler/report/dashboard/{components → web/components}/flowgraph.py +0 -0
  182. /siliconcompiler/report/dashboard/{state.py → web/state.py} +0 -0
  183. /siliconcompiler/report/dashboard/{utils → web/utils}/__init__.py +0 -0
  184. /siliconcompiler/report/dashboard/{utils → web/utils}/file_utils.py +0 -0
  185. {siliconcompiler-0.32.1.dist-info → siliconcompiler-0.32.3.dist-info}/entry_points.txt +0 -0
  186. {siliconcompiler-0.32.1.dist-info → siliconcompiler-0.32.3.dist-info/licenses}/LICENSE +0 -0
  187. {siliconcompiler-0.32.1.dist-info → siliconcompiler-0.32.3.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,196 @@
1
+ import os
2
+ import time
3
+ import tempfile
4
+ import json
5
+
6
+ import multiprocessing
7
+ import subprocess
8
+ import atexit
9
+ import shutil
10
+ import fasteners
11
+ import signal
12
+ import socketserver
13
+
14
+ from siliconcompiler.report.dashboard import AbstractDashboard
15
+ from siliconcompiler.report.dashboard.web import utils
16
+
17
+ try:
18
+ from streamlit.web import bootstrap
19
+ from streamlit import config as _config
20
+ except ModuleNotFoundError:
21
+ bootstrap = None
22
+ _config = None
23
+
24
+
25
+ class WebDashboard(AbstractDashboard):
26
+ __port = 8501
27
+
28
+ @staticmethod
29
+ def __signal_handler(signal, frame):
30
+ # used to avoid issues during shutdown
31
+ pass
32
+
33
+ def __init__(self, chip, port=None, graph_chips=None):
34
+ super().__init__(chip)
35
+
36
+ if not bootstrap:
37
+ raise NotImplementedError('streamlit is not available')
38
+
39
+ if not port:
40
+ port = WebDashboard.get_next_port()
41
+ if not port:
42
+ port = WebDashboard.__port
43
+
44
+ self.__dashboard = None
45
+ self.__chip = chip
46
+ self.__directory = tempfile.mkdtemp(prefix='sc_dashboard_',
47
+ suffix=f'_{self.__chip.design}')
48
+ self.__manifest = os.path.join(self.__directory, 'manifest.json')
49
+ self.__manifest_lock = os.path.join(self.__directory, 'manifest.lock')
50
+ self.__port = port
51
+ dirname = os.path.dirname(__file__)
52
+ self.__streamlit_file = os.path.join(dirname, 'viewer.py')
53
+
54
+ self.__streamlit_args = [
55
+ ("browser.gatherUsageStats", False),
56
+ ("browser.serverPort", self.__port),
57
+ ("logger.level", 'error'),
58
+ ("runner.fastReruns", True),
59
+ ("server.port", self.__port),
60
+ ("client.toolbarMode", "viewer")
61
+ ]
62
+
63
+ # pass in a json object called __graph_chips
64
+ # the key is the chip_name and value is the filepath
65
+ # if another argument is passed
66
+
67
+ # use of list is to preserve order
68
+ self.__graph_chips = []
69
+ graph_chips_config = []
70
+ if graph_chips:
71
+ for chip_object_and_name in graph_chips:
72
+ chip_file_path = \
73
+ os.path.join(self.__directory,
74
+ f"{chip_object_and_name['name']}.json")
75
+ self.__graph_chips.append({
76
+ 'chip': chip_object_and_name['chip'],
77
+ 'name': chip_file_path
78
+ })
79
+ graph_chips_config.append({
80
+ "path": chip_file_path,
81
+ "cwd": utils.get_chip_cwd(
82
+ chip_object_and_name['chip'],
83
+ chip_object_and_name['cfg_path'])
84
+ })
85
+
86
+ self.__config = {
87
+ "manifest": self.__manifest,
88
+ "lock": self.__manifest_lock,
89
+ "graph_chips": graph_chips_config
90
+ }
91
+
92
+ self.__sleep_time = 0.5
93
+ self.__signal_handler = None
94
+
95
+ self.__lock = fasteners.InterProcessLock(self.__manifest_lock)
96
+
97
+ atexit.register(self.__cleanup)
98
+
99
+ def open_dashboard(self):
100
+ with open(self.__get_config_file(), 'w') as f:
101
+ json.dump(self.__config, f, indent=4)
102
+
103
+ self.update_manifest()
104
+
105
+ self.update_graph_manifests()
106
+
107
+ self.__dashboard = multiprocessing.Process(
108
+ target=self._run_streamlit_bootstrap)
109
+
110
+ self.__signal_handler = signal.signal(signal.SIGINT, WebDashboard.__signal_handler)
111
+
112
+ self.__dashboard.start()
113
+
114
+ def update_manifest(self, payload=None):
115
+ if not self.__manifest:
116
+ return
117
+
118
+ new_file = f"{self.__manifest}.new.json"
119
+ self.__chip.write_manifest(new_file)
120
+
121
+ with self.__lock:
122
+ shutil.move(new_file, self.__manifest)
123
+
124
+ def update_graph_manifests(self):
125
+ for chip_object_and_name in self.__graph_chips:
126
+ chip = chip_object_and_name['chip']
127
+ file_path = chip_object_and_name['name']
128
+ chip.write_manifest(file_path)
129
+
130
+ def __get_config_file(self):
131
+ return os.path.join(self.__directory, 'config.json')
132
+
133
+ def is_running(self):
134
+ if self.__dashboard is None:
135
+ return False
136
+
137
+ if self.__dashboard.is_alive():
138
+ return True
139
+
140
+ self.__dashboard = None
141
+ self.__manifest = None
142
+ return False
143
+
144
+ def end_of_run(self):
145
+ pass
146
+
147
+ def stop(self):
148
+ if not self.is_running():
149
+ return
150
+
151
+ while self.__dashboard.is_alive():
152
+ self.__dashboard.terminate()
153
+ self._sleep()
154
+
155
+ if self.__signal_handler:
156
+ signal.signal(signal.SIGINT, self.__signal_handler)
157
+
158
+ self.__dashboard = None
159
+ self.__manifest = None
160
+ self.__signal_handler = None
161
+
162
+ def wait(self):
163
+ self.__dashboard.join()
164
+
165
+ def _sleep(self):
166
+ time.sleep(self.__sleep_time)
167
+
168
+ def _run_streamlit_bootstrap(self):
169
+ for config, val in self.__streamlit_args:
170
+ _config.set_option(config, val)
171
+
172
+ bootstrap.run(self.__streamlit_file,
173
+ False,
174
+ [self.__get_config_file()],
175
+ flag_options={})
176
+
177
+ def __run_streamlit_subproc(self):
178
+ cmd = ['streamlit', 'run',
179
+ self.__streamlit_file, self.__get_config_file()]
180
+ for config, val in self.__streamlit_args:
181
+ cmd.append(f'--{config}')
182
+ cmd.append(val)
183
+
184
+ subprocess.Popen(cmd)
185
+
186
+ def __cleanup(self):
187
+ self.stop()
188
+
189
+ if os.path.exists(self.__directory):
190
+ shutil.rmtree(self.__directory)
191
+
192
+ @staticmethod
193
+ def get_next_port():
194
+ with socketserver.TCPServer(("localhost", 0), None) as s:
195
+ return s.server_address[1]
196
+ return None
@@ -14,10 +14,10 @@ from siliconcompiler import __version__ as sc_version
14
14
  from siliconcompiler import utils
15
15
  from siliconcompiler.report import report
16
16
 
17
- from siliconcompiler.report.dashboard import state
18
- from siliconcompiler.report.dashboard import layouts
19
- from siliconcompiler.report.dashboard.utils import file_utils
20
- from siliconcompiler.report.dashboard.components import flowgraph
17
+ from siliconcompiler.report.dashboard.web import state
18
+ from siliconcompiler.report.dashboard.web import layouts
19
+ from siliconcompiler.report.dashboard.web.utils import file_utils
20
+ from siliconcompiler.report.dashboard.web.components import flowgraph
21
21
 
22
22
 
23
23
  SC_ABOUT = [
@@ -5,7 +5,7 @@ import streamlit
5
5
 
6
6
  from siliconcompiler.report import report
7
7
 
8
- from siliconcompiler.report.dashboard import state
8
+ from siliconcompiler.report.dashboard.web import state
9
9
 
10
10
 
11
11
  def _get_report_chips():
@@ -1,6 +1,6 @@
1
- from siliconcompiler.report.dashboard.layouts import vertical_flowgraph
2
- from siliconcompiler.report.dashboard.layouts import vertical_flowgraph_sac_tabs
3
- from siliconcompiler.report.dashboard.layouts import vertical_flowgraph_node_tab
1
+ from siliconcompiler.report.dashboard.web.layouts import vertical_flowgraph
2
+ from siliconcompiler.report.dashboard.web.layouts import vertical_flowgraph_sac_tabs
3
+ from siliconcompiler.report.dashboard.web.layouts import vertical_flowgraph_node_tab
4
4
 
5
5
  __LAYOUTS = {
6
6
  "vertical_flowgraph": vertical_flowgraph.layout,
@@ -1,6 +1,6 @@
1
1
  import streamlit_antd_components as sac
2
2
 
3
- from siliconcompiler.report.dashboard import state
3
+ from siliconcompiler.report.dashboard.web import state
4
4
 
5
5
 
6
6
  def check_rerun():
@@ -1,11 +1,11 @@
1
1
  import os
2
2
  import streamlit
3
3
 
4
- from siliconcompiler.report.dashboard import components
5
- from siliconcompiler.report.dashboard.components import graph
6
- from siliconcompiler.report.dashboard import state
7
- from siliconcompiler.report.dashboard import utils
8
- from siliconcompiler.report.dashboard.layouts import _common
4
+ from siliconcompiler.report.dashboard.web import components
5
+ from siliconcompiler.report.dashboard.web.components import graph
6
+ from siliconcompiler.report.dashboard.web import state
7
+ from siliconcompiler.report.dashboard.web import utils
8
+ from siliconcompiler.report.dashboard.web.layouts import _common
9
9
 
10
10
 
11
11
  def layout():
@@ -1,12 +1,12 @@
1
1
  import os
2
2
  import streamlit
3
3
 
4
- from siliconcompiler.report.dashboard import components
5
- from siliconcompiler.report.dashboard.components import graph
6
- from siliconcompiler.report.dashboard import state
7
- from siliconcompiler.report.dashboard import utils
8
- from siliconcompiler.report.dashboard.utils import file_utils
9
- from siliconcompiler.report.dashboard.layouts import _common
4
+ from siliconcompiler.report.dashboard.web import components
5
+ from siliconcompiler.report.dashboard.web.components import graph
6
+ from siliconcompiler.report.dashboard.web import state
7
+ from siliconcompiler.report.dashboard.web import utils
8
+ from siliconcompiler.report.dashboard.web.utils import file_utils
9
+ from siliconcompiler.report.dashboard.web.layouts import _common
10
10
  import streamlit_antd_components as sac
11
11
 
12
12
 
@@ -1,12 +1,12 @@
1
1
  import os
2
2
  import streamlit
3
3
 
4
- from siliconcompiler.report.dashboard import components
5
- from siliconcompiler.report.dashboard.components import graph
6
- from siliconcompiler.report.dashboard import state
7
- from siliconcompiler.report.dashboard import utils
8
- from siliconcompiler.report.dashboard.utils import file_utils
9
- from siliconcompiler.report.dashboard.layouts import _common
4
+ from siliconcompiler.report.dashboard.web import components
5
+ from siliconcompiler.report.dashboard.web.components import graph
6
+ from siliconcompiler.report.dashboard.web import state
7
+ from siliconcompiler.report.dashboard.web import utils
8
+ from siliconcompiler.report.dashboard.web.utils import file_utils
9
+ from siliconcompiler.report.dashboard.web.layouts import _common
10
10
  import streamlit_antd_components as sac
11
11
 
12
12
 
@@ -1,9 +1,9 @@
1
1
  import streamlit
2
2
 
3
- from siliconcompiler.report.dashboard import components
4
- from siliconcompiler.report.dashboard import layouts
5
- from siliconcompiler.report.dashboard import state
6
- from siliconcompiler.report.dashboard import utils
3
+ from siliconcompiler.report.dashboard.web import components
4
+ from siliconcompiler.report.dashboard.web import layouts
5
+ from siliconcompiler.report.dashboard.web import state
6
+ from siliconcompiler.report.dashboard.web import utils
7
7
 
8
8
  import streamlit_autorefresh
9
9
 
@@ -2,6 +2,7 @@ import contextlib
2
2
  import distro
3
3
  import getpass
4
4
  import multiprocessing
5
+ import logging
5
6
  import os
6
7
  import platform
7
8
  import psutil
@@ -17,6 +18,7 @@ import packaging.specifiers
17
18
  from io import StringIO
18
19
  import traceback
19
20
  from datetime import datetime
21
+ from logging.handlers import QueueHandler, QueueListener
20
22
  from siliconcompiler import sc_open
21
23
  from siliconcompiler import utils
22
24
  from siliconcompiler import _metadata
@@ -29,6 +31,7 @@ from siliconcompiler.flowgraph import _get_flowgraph_nodes, _get_flowgraph_execu
29
31
  _get_pruned_node_inputs, _get_flowgraph_entry_nodes, \
30
32
  _unreachable_steps_to_execute, _nodes_to_execute, \
31
33
  get_nodes_from, nodes_to_execute, _check_flowgraph
34
+ from siliconcompiler.utils.logging import SCBlankLoggerFormatter
32
35
  from siliconcompiler.tools._common import input_file_node_name
33
36
  import lambdapdk
34
37
  from siliconcompiler.tools._common import get_tool_task, record_metric
@@ -85,6 +88,8 @@ def run(chip):
85
88
 
86
89
  # Re-init logger to include run info after setting up flowgraph.
87
90
  chip._init_logger(in_run=True)
91
+ if chip._dash and not chip._dash.is_running():
92
+ chip._dash.open_dashboard()
88
93
 
89
94
  # Check if flowgraph is complete and valid
90
95
  flow = chip.get('option', 'flow')
@@ -128,10 +133,6 @@ def _finalize_run(chip):
128
133
  filepath = os.path.join(chip.getworkdir(), f"{chip.design}.pkg.json")
129
134
  chip.write_manifest(filepath)
130
135
 
131
- # Update dashboard
132
- if chip._dash:
133
- chip._dash.update_manifest()
134
-
135
136
  send_messages.send(chip, 'summary', None, None)
136
137
 
137
138
 
@@ -275,7 +276,12 @@ def _local_process(chip, flow):
275
276
  nodes_to_run = {}
276
277
  processes = {}
277
278
  local_processes = []
278
- _prepare_nodes(chip, nodes_to_run, processes, local_processes, flow)
279
+ log_queue = _prepare_nodes(chip, nodes_to_run, processes, local_processes, flow)
280
+
281
+ # Handle logs across threads
282
+ log_listener = QueueListener(log_queue, chip.logger._console)
283
+ chip.logger._console.setFormatter(SCBlankLoggerFormatter())
284
+ log_listener.start()
279
285
 
280
286
  # Update dashboard before run begins
281
287
  if chip._dash:
@@ -285,6 +291,7 @@ def _local_process(chip, flow):
285
291
  _launch_nodes(chip, nodes_to_run, processes, local_processes)
286
292
  except KeyboardInterrupt:
287
293
  # exit immediately
294
+ log_listener.stop()
288
295
  sys.exit(0)
289
296
 
290
297
  if _get_callback('post_run'):
@@ -292,6 +299,10 @@ def _local_process(chip, flow):
292
299
 
293
300
  _check_nodes_status(chip, flow)
294
301
 
302
+ # Cleanup logger
303
+ log_listener.stop()
304
+ chip._init_logger_formats()
305
+
295
306
 
296
307
  def __is_posix():
297
308
  return sys.platform != 'win32'
@@ -421,7 +432,7 @@ def _check_version(chip, reported_version, tool, step, index):
421
432
 
422
433
 
423
434
  ###########################################################################
424
- def _runtask(chip, flow, step, index, exec_func, pipe=None, replay=False):
435
+ def _runtask(chip, flow, step, index, exec_func, pipe=None, queue=None, replay=False):
425
436
  '''
426
437
  Private per node run method called by run().
427
438
 
@@ -437,6 +448,11 @@ def _runtask(chip, flow, step, index, exec_func, pipe=None, replay=False):
437
448
  chip._init_codecs()
438
449
 
439
450
  chip._init_logger(step, index, in_run=True)
451
+ if queue:
452
+ chip.logger.removeHandler(chip.logger._console)
453
+ chip.logger._console = QueueHandler(queue)
454
+ chip.logger.addHandler(chip.logger._console)
455
+ chip._init_logger_formats()
440
456
 
441
457
  chip.set('arg', 'step', step, clobber=True)
442
458
  chip.set('arg', 'index', index, clobber=True)
@@ -541,13 +557,12 @@ def _select_inputs(chip, step, index, trial=False):
541
557
  '_select_inputs',
542
558
  None)
543
559
  if select_inputs:
544
- log_handlers = None
560
+ log_level = chip.logger.level
545
561
  if trial:
546
- log_handlers = chip.logger.handlers.copy()
547
- chip.logger.handlers.clear()
562
+ chip.logger.setLevel(logging.CRITICAL)
548
563
  sel_inputs = select_inputs(chip, step, index)
549
- if log_handlers:
550
- chip.logger.handlers = log_handlers
564
+ if trial:
565
+ chip.logger.setLevel(log_level)
551
566
  else:
552
567
  sel_inputs = _get_pruned_node_inputs(chip, flow, (step, index))
553
568
 
@@ -862,9 +877,16 @@ def _run_executable_or_builtin(chip, step, index, version, toolpath, workdir, ru
862
877
  stderr_writer.close()
863
878
  stderr_writer = sys.stdout
864
879
 
880
+ # Handle logger stdout suppression if quiet
881
+ stdout_handler_level = chip.logger._console.level
882
+ if chip.get('option', 'quiet', step=step, index=index):
883
+ chip.logger._console.setLevel(logging.CRITICAL)
884
+
865
885
  with contextlib.redirect_stderr(stderr_writer), \
866
886
  contextlib.redirect_stdout(stdout_writer):
867
887
  retcode = run_func(chip)
888
+
889
+ chip.logger._console.setLevel(stdout_handler_level)
868
890
  except Exception as e:
869
891
  chip.logger.error(f'Failed in run() for {tool}/{task}: {e}')
870
892
  retcode = 1 # default to non-zero
@@ -1491,6 +1513,9 @@ def _prepare_nodes(chip, nodes_to_run, processes, local_processes, flow):
1491
1513
  # Call this in case this was invoked without __main__
1492
1514
  multiprocessing.freeze_support()
1493
1515
 
1516
+ # Log queue for logging messages
1517
+ log_queue = multiprocessing.Queue(-1)
1518
+
1494
1519
  init_funcs = set()
1495
1520
  for (step, index) in nodes_to_execute(chip, flow):
1496
1521
  node = (step, index)
@@ -1525,13 +1550,16 @@ def _prepare_nodes(chip, nodes_to_run, processes, local_processes, flow):
1525
1550
  process["proc"] = multiprocessing.Process(
1526
1551
  target=_runtask,
1527
1552
  args=(chip, flow, step, index, exec_func),
1528
- kwargs={"pipe": process["child_pipe"]})
1553
+ kwargs={"pipe": process["child_pipe"],
1554
+ "queue": log_queue})
1529
1555
 
1530
1556
  processes[node] = process
1531
1557
 
1532
1558
  for init_func in init_funcs:
1533
1559
  init_func(chip)
1534
1560
 
1561
+ return log_queue
1562
+
1535
1563
 
1536
1564
  def _check_node_dependencies(chip, node, deps, deps_was_successful):
1537
1565
  had_deps = len(deps) > 0
@@ -1600,6 +1628,8 @@ def _launch_nodes(chip, nodes_to_run, processes, local_processes):
1600
1628
  if _get_callback('pre_run'):
1601
1629
  _get_callback('pre_run')(chip)
1602
1630
 
1631
+ start_times = {None: time.time()}
1632
+
1603
1633
  while len(nodes_to_run) > 0 or len(running_nodes) > 0:
1604
1634
  changed = _process_completed_nodes(chip, processes, running_nodes)
1605
1635
 
@@ -1624,6 +1654,7 @@ def _launch_nodes(chip, nodes_to_run, processes, local_processes):
1624
1654
  _get_callback('pre_node')(chip, *node)
1625
1655
 
1626
1656
  chip.set('record', 'status', NodeStatus.RUNNING, step=node[0], index=node[1])
1657
+ start_times[node] = time.time()
1627
1658
  changed = True
1628
1659
 
1629
1660
  processes[node]["proc"].start()
@@ -1640,7 +1671,7 @@ def _launch_nodes(chip, nodes_to_run, processes, local_processes):
1640
1671
 
1641
1672
  if chip._dash and changed:
1642
1673
  # Update dashboard if the manifest changed
1643
- chip._dash.update_manifest()
1674
+ chip._dash.update_manifest(payload={"starttimes": start_times})
1644
1675
 
1645
1676
  if len(running_nodes) == 1:
1646
1677
  # if there is only one node running, just join the thread
@@ -115,7 +115,8 @@ def run(chip, step, index, replay):
115
115
  start_cwd = os.getcwd()
116
116
 
117
117
  # Remove handlers from logger
118
- chip.logger.handlers.clear()
118
+ for handler in chip.logger.handlers.copy():
119
+ chip.logger.removeHandler(handler)
119
120
 
120
121
  # Reinit logger
121
122
  chip._init_logger(step=step, index=index, in_run=True)
@@ -325,7 +325,7 @@ class DynamicGen(SphinxDirective):
325
325
 
326
326
  return True
327
327
 
328
- def _document_free_params(self, cfg, type, key_path, reference_prefix, s):
328
+ def _document_free_params(self, cfg, type, key_path, reference_prefix, s, show_type=False):
329
329
  if type in cfg:
330
330
  cfg = cfg[type]
331
331
  else:
@@ -337,8 +337,12 @@ class DynamicGen(SphinxDirective):
337
337
  type_heading = "Files"
338
338
  elif type == "dir":
339
339
  type_heading = "Directories"
340
+ else:
341
+ raise ValueError(type)
340
342
 
341
343
  table = [[strong('Parameters'), strong('Help')]]
344
+ if show_type:
345
+ table[0].insert(1, strong('Type'))
342
346
  for key, params in cfg.items():
343
347
  if key == "default":
344
348
  continue
@@ -346,7 +350,10 @@ class DynamicGen(SphinxDirective):
346
350
  key_node = nodes.paragraph()
347
351
  key_node += keypath(key_path + [key], self.env.docname,
348
352
  key_text=["...", f"'{type}'", f"'{key}'"])
349
- table.append([key_node, para(params["help"])])
353
+ entry = [key_node, para(params["help"])]
354
+ if show_type:
355
+ entry.insert(1, code(params["type"]))
356
+ table.append(entry)
350
357
 
351
358
  if len(table) > 1:
352
359
  s += build_section(type_heading, self.get_ref(*reference_prefix, type))
@@ -710,14 +717,6 @@ class ToolGen(DynamicGen):
710
717
  self.__tool = None
711
718
  self.__task = None
712
719
 
713
- # Annotate the target used for default values
714
- if chip.valid('option', 'target') and chip.get('option', 'target'):
715
- p = docutils.nodes.inline('')
716
- target = chip.get('option', 'target').split('.')[-1]
717
- targetid = get_ref_id(DynamicGen.get_ref_key(TargetGen.REF_PREFIX, target))
718
- self.parse_rst(f"Built using target: :ref:`{target}<{targetid}>`", p)
719
- s += p
720
-
721
720
  try:
722
721
  task_setup(chip)
723
722
 
@@ -780,7 +779,8 @@ class ToolGen(DynamicGen):
780
779
 
781
780
  def document_free_params(self, cfg, reference_prefix, s):
782
781
  key_path = ['tool', '<tool>', 'task', '<task>']
783
- self._document_free_params(cfg, 'var', key_path + ['var'], reference_prefix, s)
782
+ self._document_free_params(cfg, 'var', key_path + ['var'], reference_prefix, s,
783
+ show_type=True)
784
784
  self._document_free_params(cfg, 'file', key_path + ['file'], reference_prefix, s)
785
785
  self._document_free_params(cfg, 'dir', key_path + ['dir'], reference_prefix, s)
786
786
 
@@ -60,10 +60,10 @@ while [[ $# -gt 0 ]]; do
60
60
  esac
61
61
  done
62
62
 
63
- if [ $SKIPEXPORT == 0 ]; then
63
+ {% if exports|length > 0 %}if [ $SKIPEXPORT == 0 ]; then
64
64
  # Environmental variables{% for key, value in exports.items() %}
65
65
  export {{ key }}="{{ value }}"{% endfor %}
66
- fi
66
+ fi{% endif %}
67
67
 
68
68
  # Switch to the working directory
69
69
  cd "$CD_WORK"