siliconcompiler 0.32.2__py3-none-any.whl → 0.33.0__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 (277) hide show
  1. siliconcompiler/__init__.py +19 -2
  2. siliconcompiler/_metadata.py +3 -2
  3. siliconcompiler/apps/sc.py +2 -2
  4. siliconcompiler/apps/sc_install.py +3 -3
  5. siliconcompiler/apps/sc_issue.py +1 -1
  6. siliconcompiler/apps/sc_remote.py +4 -4
  7. siliconcompiler/apps/sc_show.py +2 -2
  8. siliconcompiler/apps/utils/replay.py +5 -3
  9. siliconcompiler/asic.py +120 -0
  10. siliconcompiler/checklist.py +150 -0
  11. siliconcompiler/core.py +319 -345
  12. siliconcompiler/{templates → data/templates}/replay/replay.sh.j2 +2 -2
  13. siliconcompiler/flowgraph.py +803 -515
  14. siliconcompiler/fpga.py +84 -0
  15. siliconcompiler/metric.py +420 -0
  16. siliconcompiler/optimizer/vizier.py +2 -3
  17. siliconcompiler/package/__init__.py +29 -6
  18. siliconcompiler/pdk.py +415 -0
  19. siliconcompiler/record.py +449 -0
  20. siliconcompiler/remote/client.py +61 -19
  21. siliconcompiler/remote/schema.py +116 -112
  22. siliconcompiler/remote/server.py +3 -5
  23. siliconcompiler/report/__init__.py +3 -2
  24. siliconcompiler/report/dashboard/__init__.py +61 -170
  25. siliconcompiler/report/dashboard/cli/__init__.py +79 -0
  26. siliconcompiler/report/dashboard/cli/board.py +895 -0
  27. siliconcompiler/report/dashboard/web/__init__.py +196 -0
  28. siliconcompiler/report/dashboard/{components → web/components}/__init__.py +9 -8
  29. siliconcompiler/report/dashboard/{components → web/components}/flowgraph.py +3 -3
  30. siliconcompiler/report/dashboard/{components → web/components}/graph.py +7 -4
  31. siliconcompiler/report/dashboard/{layouts → web/layouts}/__init__.py +3 -3
  32. siliconcompiler/report/dashboard/{layouts → web/layouts}/_common.py +1 -1
  33. siliconcompiler/report/dashboard/{layouts → web/layouts}/vertical_flowgraph.py +5 -5
  34. siliconcompiler/report/dashboard/{layouts → web/layouts}/vertical_flowgraph_node_tab.py +6 -6
  35. siliconcompiler/report/dashboard/{layouts → web/layouts}/vertical_flowgraph_sac_tabs.py +6 -6
  36. siliconcompiler/report/dashboard/{state.py → web/state.py} +1 -1
  37. siliconcompiler/report/dashboard/{utils → web/utils}/__init__.py +4 -3
  38. siliconcompiler/report/dashboard/{viewer.py → web/viewer.py} +4 -4
  39. siliconcompiler/report/html_report.py +2 -3
  40. siliconcompiler/report/report.py +13 -7
  41. siliconcompiler/report/summary_image.py +1 -1
  42. siliconcompiler/report/summary_table.py +3 -3
  43. siliconcompiler/report/utils.py +11 -10
  44. siliconcompiler/scheduler/__init__.py +153 -286
  45. siliconcompiler/scheduler/run_node.py +2 -1
  46. siliconcompiler/scheduler/send_messages.py +4 -4
  47. siliconcompiler/scheduler/slurm.py +2 -2
  48. siliconcompiler/schema/__init__.py +19 -2
  49. siliconcompiler/schema/baseschema.py +493 -0
  50. siliconcompiler/schema/cmdlineschema.py +250 -0
  51. siliconcompiler/{sphinx_ext → schema/docs}/__init__.py +3 -1
  52. siliconcompiler/{sphinx_ext → schema/docs}/dynamicgen.py +63 -81
  53. siliconcompiler/{sphinx_ext → schema/docs}/schemagen.py +73 -85
  54. siliconcompiler/{sphinx_ext → schema/docs}/utils.py +12 -13
  55. siliconcompiler/schema/editableschema.py +136 -0
  56. siliconcompiler/schema/journalingschema.py +238 -0
  57. siliconcompiler/schema/namedschema.py +41 -0
  58. siliconcompiler/schema/packageschema.py +101 -0
  59. siliconcompiler/schema/parameter.py +791 -0
  60. siliconcompiler/schema/parametertype.py +323 -0
  61. siliconcompiler/schema/parametervalue.py +736 -0
  62. siliconcompiler/schema/safeschema.py +37 -0
  63. siliconcompiler/schema/schema_cfg.py +109 -1789
  64. siliconcompiler/schema/utils.py +5 -68
  65. siliconcompiler/schema_obj.py +119 -0
  66. siliconcompiler/tool.py +1308 -0
  67. siliconcompiler/tools/_common/__init__.py +8 -10
  68. siliconcompiler/tools/_common/sdc/sc_constraints.sdc +1 -1
  69. siliconcompiler/tools/bluespec/convert.py +7 -7
  70. siliconcompiler/tools/builtin/_common.py +1 -1
  71. siliconcompiler/tools/builtin/concatenate.py +2 -2
  72. siliconcompiler/tools/builtin/minimum.py +1 -1
  73. siliconcompiler/tools/builtin/mux.py +2 -1
  74. siliconcompiler/tools/builtin/nop.py +1 -1
  75. siliconcompiler/tools/builtin/verify.py +6 -4
  76. siliconcompiler/tools/chisel/convert.py +4 -4
  77. siliconcompiler/tools/genfasm/bitstream.py +3 -3
  78. siliconcompiler/tools/ghdl/convert.py +1 -1
  79. siliconcompiler/tools/icarus/compile.py +4 -4
  80. siliconcompiler/tools/icepack/bitstream.py +6 -1
  81. siliconcompiler/tools/klayout/convert_drc_db.py +5 -0
  82. siliconcompiler/tools/klayout/klayout_export.py +0 -1
  83. siliconcompiler/tools/klayout/klayout_utils.py +3 -10
  84. siliconcompiler/tools/nextpnr/apr.py +6 -1
  85. siliconcompiler/tools/nextpnr/nextpnr.py +4 -4
  86. siliconcompiler/tools/openroad/_apr.py +17 -0
  87. siliconcompiler/tools/openroad/fillmetal_insertion.py +14 -14
  88. siliconcompiler/tools/openroad/rdlroute.py +3 -3
  89. siliconcompiler/tools/openroad/scripts/apr/postamble.tcl +1 -1
  90. siliconcompiler/tools/openroad/scripts/apr/preamble.tcl +5 -5
  91. siliconcompiler/tools/openroad/scripts/apr/sc_antenna_repair.tcl +3 -3
  92. siliconcompiler/tools/openroad/scripts/apr/sc_clock_tree_synthesis.tcl +3 -3
  93. siliconcompiler/tools/openroad/scripts/apr/sc_detailed_placement.tcl +3 -3
  94. siliconcompiler/tools/openroad/scripts/apr/sc_detailed_route.tcl +3 -3
  95. siliconcompiler/tools/openroad/scripts/apr/sc_endcap_tapcell_insertion.tcl +3 -3
  96. siliconcompiler/tools/openroad/scripts/apr/sc_fillercell_insertion.tcl +3 -3
  97. siliconcompiler/tools/openroad/scripts/apr/sc_fillmetal_insertion.tcl +4 -4
  98. siliconcompiler/tools/openroad/scripts/apr/sc_global_placement.tcl +3 -3
  99. siliconcompiler/tools/openroad/scripts/apr/sc_global_route.tcl +3 -3
  100. siliconcompiler/tools/openroad/scripts/apr/sc_init_floorplan.tcl +3 -3
  101. siliconcompiler/tools/openroad/scripts/apr/sc_macro_placement.tcl +4 -4
  102. siliconcompiler/tools/openroad/scripts/apr/sc_metrics.tcl +3 -3
  103. siliconcompiler/tools/openroad/scripts/apr/sc_pin_placement.tcl +3 -3
  104. siliconcompiler/tools/openroad/scripts/apr/sc_power_grid.tcl +3 -3
  105. siliconcompiler/tools/openroad/scripts/apr/sc_repair_design.tcl +3 -3
  106. siliconcompiler/tools/openroad/scripts/apr/sc_repair_timing.tcl +4 -4
  107. siliconcompiler/tools/openroad/scripts/apr/sc_write_data.tcl +3 -3
  108. siliconcompiler/tools/openroad/scripts/common/procs.tcl +58 -2
  109. siliconcompiler/tools/openroad/scripts/common/reports.tcl +2 -2
  110. siliconcompiler/tools/openroad/scripts/common/screenshot.tcl +2 -2
  111. siliconcompiler/tools/openroad/scripts/common/write_images.tcl +28 -3
  112. siliconcompiler/tools/openroad/scripts/sc_rcx.tcl +2 -2
  113. siliconcompiler/tools/openroad/scripts/sc_rdlroute.tcl +4 -4
  114. siliconcompiler/tools/openroad/scripts/sc_show.tcl +7 -7
  115. siliconcompiler/tools/opensta/__init__.py +1 -1
  116. siliconcompiler/tools/opensta/scripts/sc_check_library.tcl +1 -1
  117. siliconcompiler/tools/opensta/scripts/sc_procs.tcl +16 -0
  118. siliconcompiler/tools/opensta/scripts/sc_report_libraries.tcl +1 -1
  119. siliconcompiler/tools/opensta/scripts/sc_timing.tcl +35 -7
  120. siliconcompiler/tools/opensta/timing.py +6 -2
  121. siliconcompiler/tools/slang/__init__.py +10 -10
  122. siliconcompiler/tools/surelog/parse.py +4 -4
  123. siliconcompiler/tools/sv2v/convert.py +20 -3
  124. siliconcompiler/tools/verilator/compile.py +2 -2
  125. siliconcompiler/tools/verilator/verilator.py +3 -3
  126. siliconcompiler/tools/vpr/place.py +1 -1
  127. siliconcompiler/tools/vpr/route.py +4 -4
  128. siliconcompiler/tools/vpr/screenshot.py +1 -1
  129. siliconcompiler/tools/vpr/show.py +5 -5
  130. siliconcompiler/tools/vpr/vpr.py +24 -24
  131. siliconcompiler/tools/xdm/convert.py +2 -2
  132. siliconcompiler/tools/xyce/simulate.py +1 -1
  133. siliconcompiler/tools/yosys/sc_synth_asic.tcl +104 -90
  134. siliconcompiler/tools/yosys/syn_asic.py +13 -4
  135. siliconcompiler/toolscripts/_tools.json +12 -7
  136. siliconcompiler/toolscripts/rhel8/install-chisel.sh +2 -0
  137. siliconcompiler/toolscripts/rhel8/install-icarus.sh +1 -0
  138. siliconcompiler/toolscripts/rhel8/install-klayout.sh +2 -0
  139. siliconcompiler/toolscripts/rhel8/install-magic.sh +1 -2
  140. siliconcompiler/toolscripts/rhel8/install-netgen.sh +1 -1
  141. siliconcompiler/toolscripts/rhel8/install-slang.sh +2 -0
  142. siliconcompiler/toolscripts/rhel8/install-surelog.sh +3 -1
  143. siliconcompiler/toolscripts/rhel8/install-sv2v.sh +1 -0
  144. siliconcompiler/toolscripts/rhel8/install-verible.sh +2 -0
  145. siliconcompiler/toolscripts/rhel8/install-verilator.sh +1 -0
  146. siliconcompiler/toolscripts/rhel8/install-xyce.sh +2 -0
  147. siliconcompiler/toolscripts/rhel9/install-chisel.sh +2 -0
  148. siliconcompiler/toolscripts/rhel9/install-ghdl.sh +1 -0
  149. siliconcompiler/toolscripts/rhel9/install-gtkwave.sh +1 -0
  150. siliconcompiler/toolscripts/rhel9/install-icarus.sh +1 -0
  151. siliconcompiler/toolscripts/rhel9/install-klayout.sh +2 -0
  152. siliconcompiler/toolscripts/rhel9/install-magic.sh +1 -2
  153. siliconcompiler/toolscripts/rhel9/install-netgen.sh +1 -1
  154. siliconcompiler/toolscripts/rhel9/install-openroad.sh +2 -0
  155. siliconcompiler/toolscripts/rhel9/install-opensta.sh +76 -0
  156. siliconcompiler/toolscripts/rhel9/install-slang.sh +3 -1
  157. siliconcompiler/toolscripts/rhel9/install-surelog.sh +2 -1
  158. siliconcompiler/toolscripts/rhel9/install-sv2v.sh +1 -0
  159. siliconcompiler/toolscripts/rhel9/install-verible.sh +2 -0
  160. siliconcompiler/toolscripts/rhel9/install-verilator.sh +1 -0
  161. siliconcompiler/toolscripts/rhel9/install-vpr.sh +2 -0
  162. siliconcompiler/toolscripts/rhel9/install-xdm.sh +2 -0
  163. siliconcompiler/toolscripts/rhel9/install-xyce.sh +2 -0
  164. siliconcompiler/toolscripts/rhel9/install-yosys-moosic.sh +2 -0
  165. siliconcompiler/toolscripts/rhel9/install-yosys-parmys.sh +2 -0
  166. siliconcompiler/toolscripts/rhel9/install-yosys-slang.sh +3 -1
  167. siliconcompiler/toolscripts/rhel9/install-yosys.sh +2 -0
  168. siliconcompiler/toolscripts/ubuntu20/install-bambu.sh +2 -0
  169. siliconcompiler/toolscripts/ubuntu20/install-bluespec.sh +2 -0
  170. siliconcompiler/toolscripts/ubuntu20/install-chisel.sh +2 -0
  171. siliconcompiler/toolscripts/ubuntu20/install-ghdl.sh +2 -0
  172. siliconcompiler/toolscripts/ubuntu20/install-gtkwave.sh +2 -0
  173. siliconcompiler/toolscripts/ubuntu20/install-icarus.sh +2 -0
  174. siliconcompiler/toolscripts/ubuntu20/install-icepack.sh +2 -0
  175. siliconcompiler/toolscripts/ubuntu20/install-klayout.sh +2 -0
  176. siliconcompiler/toolscripts/ubuntu20/install-magic.sh +2 -0
  177. siliconcompiler/toolscripts/ubuntu20/install-netgen.sh +2 -0
  178. siliconcompiler/toolscripts/ubuntu20/install-nextpnr.sh +1 -3
  179. siliconcompiler/toolscripts/ubuntu20/install-openroad.sh +2 -0
  180. siliconcompiler/toolscripts/ubuntu20/install-opensta.sh +72 -0
  181. siliconcompiler/toolscripts/ubuntu20/install-slang.sh +3 -1
  182. siliconcompiler/toolscripts/ubuntu20/install-slurm.sh +2 -0
  183. siliconcompiler/toolscripts/ubuntu20/install-surelog.sh +3 -1
  184. siliconcompiler/toolscripts/ubuntu20/install-sv2v.sh +1 -1
  185. siliconcompiler/toolscripts/ubuntu20/install-verible.sh +2 -0
  186. siliconcompiler/toolscripts/ubuntu20/install-verilator.sh +2 -0
  187. siliconcompiler/toolscripts/ubuntu20/install-xdm.sh +2 -0
  188. siliconcompiler/toolscripts/ubuntu20/install-xyce.sh +2 -0
  189. siliconcompiler/toolscripts/ubuntu20/install-yosys-moosic.sh +2 -0
  190. siliconcompiler/toolscripts/ubuntu20/install-yosys.sh +2 -0
  191. siliconcompiler/toolscripts/ubuntu22/install-bambu.sh +2 -0
  192. siliconcompiler/toolscripts/ubuntu22/install-bluespec.sh +2 -0
  193. siliconcompiler/toolscripts/ubuntu22/install-chisel.sh +2 -0
  194. siliconcompiler/toolscripts/ubuntu22/install-ghdl.sh +2 -0
  195. siliconcompiler/toolscripts/ubuntu22/install-gtkwave.sh +2 -0
  196. siliconcompiler/toolscripts/ubuntu22/install-icarus.sh +2 -0
  197. siliconcompiler/toolscripts/ubuntu22/install-icepack.sh +2 -0
  198. siliconcompiler/toolscripts/ubuntu22/install-klayout.sh +2 -0
  199. siliconcompiler/toolscripts/ubuntu22/install-magic.sh +2 -0
  200. siliconcompiler/toolscripts/ubuntu22/install-netgen.sh +2 -0
  201. siliconcompiler/toolscripts/ubuntu22/install-nextpnr.sh +1 -2
  202. siliconcompiler/toolscripts/ubuntu22/install-openroad.sh +2 -0
  203. siliconcompiler/toolscripts/ubuntu22/install-opensta.sh +72 -0
  204. siliconcompiler/toolscripts/ubuntu22/install-slang.sh +3 -1
  205. siliconcompiler/toolscripts/ubuntu22/install-slurm.sh +2 -0
  206. siliconcompiler/toolscripts/ubuntu22/install-surelog.sh +3 -1
  207. siliconcompiler/toolscripts/ubuntu22/install-sv2v.sh +1 -1
  208. siliconcompiler/toolscripts/ubuntu22/install-verible.sh +2 -0
  209. siliconcompiler/toolscripts/ubuntu22/install-verilator.sh +2 -0
  210. siliconcompiler/toolscripts/ubuntu22/install-vpr.sh +2 -2
  211. siliconcompiler/toolscripts/ubuntu22/install-xdm.sh +2 -0
  212. siliconcompiler/toolscripts/ubuntu22/install-xyce.sh +2 -0
  213. siliconcompiler/toolscripts/ubuntu22/install-yosys-moosic.sh +2 -0
  214. siliconcompiler/toolscripts/ubuntu22/install-yosys-parmys.sh +2 -0
  215. siliconcompiler/toolscripts/ubuntu22/install-yosys-slang.sh +3 -1
  216. siliconcompiler/toolscripts/ubuntu22/install-yosys.sh +2 -0
  217. siliconcompiler/toolscripts/ubuntu24/install-bambu.sh +2 -0
  218. siliconcompiler/toolscripts/ubuntu24/install-bluespec.sh +2 -0
  219. siliconcompiler/toolscripts/ubuntu24/install-chisel.sh +2 -0
  220. siliconcompiler/toolscripts/ubuntu24/install-ghdl.sh +2 -0
  221. siliconcompiler/toolscripts/ubuntu24/install-gtkwave.sh +2 -0
  222. siliconcompiler/toolscripts/ubuntu24/install-icarus.sh +2 -0
  223. siliconcompiler/toolscripts/ubuntu24/install-icepack.sh +2 -0
  224. siliconcompiler/toolscripts/ubuntu24/install-klayout.sh +2 -0
  225. siliconcompiler/toolscripts/ubuntu24/install-magic.sh +2 -0
  226. siliconcompiler/toolscripts/ubuntu24/install-netgen.sh +2 -0
  227. siliconcompiler/toolscripts/ubuntu24/install-nextpnr.sh +1 -3
  228. siliconcompiler/toolscripts/ubuntu24/install-openroad.sh +2 -0
  229. siliconcompiler/toolscripts/ubuntu24/install-opensta.sh +72 -0
  230. siliconcompiler/toolscripts/ubuntu24/install-slang.sh +3 -1
  231. siliconcompiler/toolscripts/ubuntu24/install-slurm.sh +2 -0
  232. siliconcompiler/toolscripts/ubuntu24/install-surelog.sh +3 -1
  233. siliconcompiler/toolscripts/ubuntu24/install-sv2v.sh +1 -1
  234. siliconcompiler/toolscripts/ubuntu24/install-verible.sh +2 -0
  235. siliconcompiler/toolscripts/ubuntu24/install-verilator.sh +2 -0
  236. siliconcompiler/toolscripts/ubuntu24/install-vpr.sh +2 -2
  237. siliconcompiler/toolscripts/ubuntu24/install-xdm.sh +2 -0
  238. siliconcompiler/toolscripts/ubuntu24/install-xyce.sh +2 -0
  239. siliconcompiler/toolscripts/ubuntu24/install-yosys-moosic.sh +2 -0
  240. siliconcompiler/toolscripts/ubuntu24/install-yosys-parmys.sh +2 -0
  241. siliconcompiler/toolscripts/ubuntu24/install-yosys-slang.sh +3 -1
  242. siliconcompiler/toolscripts/ubuntu24/install-yosys.sh +2 -0
  243. siliconcompiler/utils/__init__.py +8 -112
  244. siliconcompiler/utils/flowgraph.py +339 -0
  245. siliconcompiler/{issue.py → utils/issue.py} +7 -4
  246. siliconcompiler/utils/logging.py +86 -33
  247. {siliconcompiler-0.32.2.dist-info → siliconcompiler-0.33.0.dist-info}/METADATA +10 -8
  248. siliconcompiler-0.33.0.dist-info/RECORD +487 -0
  249. {siliconcompiler-0.32.2.dist-info → siliconcompiler-0.33.0.dist-info}/WHEEL +1 -1
  250. {siliconcompiler-0.32.2.dist-info → siliconcompiler-0.33.0.dist-info}/entry_points.txt +8 -8
  251. siliconcompiler/schema/schema_obj.py +0 -1936
  252. siliconcompiler/toolscripts/ubuntu20/install-vpr.sh +0 -27
  253. siliconcompiler/toolscripts/ubuntu20/install-yosys-parmys.sh +0 -59
  254. siliconcompiler-0.32.2.dist-info/RECORD +0 -464
  255. /siliconcompiler/{templates → data/templates}/__init__.py +0 -0
  256. /siliconcompiler/{templates → data/templates}/email/__init__.py +0 -0
  257. /siliconcompiler/{templates → data/templates}/email/general.j2 +0 -0
  258. /siliconcompiler/{templates → data/templates}/email/summary.j2 +0 -0
  259. /siliconcompiler/{templates → data/templates}/issue/README.txt +0 -0
  260. /siliconcompiler/{templates → data/templates}/issue/__init__.py +0 -0
  261. /siliconcompiler/{templates → data/templates}/issue/run.sh +0 -0
  262. /siliconcompiler/{templates → data/templates}/replay/replay.py.j2 +0 -0
  263. /siliconcompiler/{templates → data/templates}/replay/requirements.txt +0 -0
  264. /siliconcompiler/{templates → data/templates}/replay/setup.sh +0 -0
  265. /siliconcompiler/{templates → data/templates}/report/__init__.py +0 -0
  266. /siliconcompiler/{templates → data/templates}/report/bootstrap.min.css +0 -0
  267. /siliconcompiler/{templates → data/templates}/report/bootstrap.min.js +0 -0
  268. /siliconcompiler/{templates → data/templates}/report/bootstrap_LICENSE.md +0 -0
  269. /siliconcompiler/{templates → data/templates}/report/sc_report.j2 +0 -0
  270. /siliconcompiler/{templates → data/templates}/slurm/__init__.py +0 -0
  271. /siliconcompiler/{templates → data/templates}/slurm/run.sh +0 -0
  272. /siliconcompiler/{templates → data/templates}/tcl/__init__.py +0 -0
  273. /siliconcompiler/{templates → data/templates}/tcl/manifest.tcl.j2 +0 -0
  274. /siliconcompiler/report/dashboard/{utils → web/utils}/file_utils.py +0 -0
  275. /siliconcompiler/{units.py → utils/units.py} +0 -0
  276. {siliconcompiler-0.32.2.dist-info → siliconcompiler-0.33.0.dist-info}/licenses/LICENSE +0 -0
  277. {siliconcompiler-0.32.2.dist-info → siliconcompiler-0.33.0.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
+
18
+ class WebDashboard(AbstractDashboard):
19
+ __port = 8501
20
+
21
+ @staticmethod
22
+ def __signal_handler(signal, frame):
23
+ # used to avoid issues during shutdown
24
+ pass
25
+
26
+ def __init__(self, chip, port=None, graph_chips=None):
27
+ try:
28
+ from streamlit.web import bootstrap # noqa: F401
29
+ except ModuleNotFoundError:
30
+ raise NotImplementedError('streamlit is not available')
31
+
32
+ super().__init__(chip)
33
+
34
+ if not port:
35
+ port = WebDashboard.get_next_port()
36
+ if not port:
37
+ port = WebDashboard.__port
38
+
39
+ self.__dashboard = None
40
+ self.__chip = chip
41
+ self.__directory = tempfile.mkdtemp(prefix='sc_dashboard_',
42
+ suffix=f'_{self.__chip.design}')
43
+ self.__manifest = os.path.join(self.__directory, 'manifest.json')
44
+ self.__manifest_lock = os.path.join(self.__directory, 'manifest.lock')
45
+ self.__port = port
46
+ dirname = os.path.dirname(__file__)
47
+ self.__streamlit_file = os.path.join(dirname, 'viewer.py')
48
+
49
+ self.__streamlit_args = [
50
+ ("browser.gatherUsageStats", False),
51
+ ("browser.serverPort", self.__port),
52
+ ("logger.level", 'error'),
53
+ ("runner.fastReruns", True),
54
+ ("server.port", self.__port),
55
+ ("client.toolbarMode", "viewer")
56
+ ]
57
+ if "PYTEST_CURRENT_TEST" in os.environ:
58
+ self.__streamlit_args.append(("server.headless", True))
59
+
60
+ # pass in a json object called __graph_chips
61
+ # the key is the chip_name and value is the filepath
62
+ # if another argument is passed
63
+
64
+ # use of list is to preserve order
65
+ self.__graph_chips = []
66
+ graph_chips_config = []
67
+ if graph_chips:
68
+ for chip_object_and_name in graph_chips:
69
+ chip_file_path = \
70
+ os.path.join(self.__directory,
71
+ f"{chip_object_and_name['name']}.json")
72
+ self.__graph_chips.append({
73
+ 'chip': chip_object_and_name['chip'],
74
+ 'name': chip_file_path
75
+ })
76
+ graph_chips_config.append({
77
+ "path": chip_file_path,
78
+ "cwd": utils.get_chip_cwd(
79
+ chip_object_and_name['chip'],
80
+ chip_object_and_name['cfg_path'])
81
+ })
82
+
83
+ self.__config = {
84
+ "manifest": self.__manifest,
85
+ "lock": self.__manifest_lock,
86
+ "graph_chips": graph_chips_config
87
+ }
88
+
89
+ self.__sleep_time = 0.5
90
+ self.__signal_handler = None
91
+
92
+ self.__lock = fasteners.InterProcessLock(self.__manifest_lock)
93
+
94
+ atexit.register(self.__cleanup)
95
+
96
+ def open_dashboard(self):
97
+ with open(self.__get_config_file(), 'w') as f:
98
+ json.dump(self.__config, f, indent=4)
99
+
100
+ self.update_manifest()
101
+
102
+ self.update_graph_manifests()
103
+
104
+ self.__dashboard = multiprocessing.Process(
105
+ target=self._run_streamlit_bootstrap)
106
+
107
+ self.__signal_handler = signal.signal(signal.SIGINT, WebDashboard.__signal_handler)
108
+
109
+ self.__dashboard.start()
110
+
111
+ def update_manifest(self, payload=None):
112
+ if not self.__manifest:
113
+ return
114
+
115
+ new_file = f"{self.__manifest}.new.json"
116
+ self.__chip.write_manifest(new_file)
117
+
118
+ with self.__lock:
119
+ shutil.move(new_file, self.__manifest)
120
+
121
+ def update_graph_manifests(self):
122
+ for chip_object_and_name in self.__graph_chips:
123
+ chip = chip_object_and_name['chip']
124
+ file_path = chip_object_and_name['name']
125
+ chip.write_manifest(file_path)
126
+
127
+ def __get_config_file(self):
128
+ return os.path.join(self.__directory, 'config.json')
129
+
130
+ def is_running(self):
131
+ if self.__dashboard is None:
132
+ return False
133
+
134
+ if self.__dashboard.is_alive():
135
+ return True
136
+
137
+ self.__dashboard = None
138
+ self.__manifest = None
139
+ return False
140
+
141
+ def end_of_run(self):
142
+ pass
143
+
144
+ def stop(self):
145
+ if not self.is_running():
146
+ return
147
+
148
+ while self.__dashboard.is_alive():
149
+ self.__dashboard.terminate()
150
+ self._sleep()
151
+
152
+ if self.__signal_handler:
153
+ signal.signal(signal.SIGINT, self.__signal_handler)
154
+
155
+ self.__dashboard = None
156
+ self.__manifest = None
157
+ self.__signal_handler = None
158
+
159
+ def wait(self):
160
+ self.__dashboard.join()
161
+
162
+ def _sleep(self):
163
+ time.sleep(self.__sleep_time)
164
+
165
+ def _run_streamlit_bootstrap(self):
166
+ from streamlit.web import bootstrap
167
+ from streamlit import config as _config
168
+
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
@@ -1,7 +1,6 @@
1
1
  import base64
2
2
  import json
3
3
  import os
4
- import pandas
5
4
 
6
5
  import streamlit
7
6
  from streamlit_agraph import agraph
@@ -14,10 +13,10 @@ from siliconcompiler import __version__ as sc_version
14
13
  from siliconcompiler import utils
15
14
  from siliconcompiler.report import report
16
15
 
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
16
+ from siliconcompiler.report.dashboard.web import state
17
+ from siliconcompiler.report.dashboard.web import layouts
18
+ from siliconcompiler.report.dashboard.web.utils import file_utils
19
+ from siliconcompiler.report.dashboard.web.components import flowgraph
21
20
 
22
21
 
23
22
  SC_ABOUT = [
@@ -302,7 +301,7 @@ def manifest_viewer(
302
301
  if streamlit.checkbox(
303
302
  'Raw manifest',
304
303
  help='Click here to see the manifest before it was made more readable'):
305
- manifest_to_show = chip.schema.cfg
304
+ manifest_to_show = chip.schema.getdict()
306
305
  else:
307
306
  manifest_to_show = report.make_manifest(chip)
308
307
 
@@ -327,7 +326,7 @@ def manifest_viewer(
327
326
  streamlit.download_button(
328
327
  label='Download',
329
328
  file_name='manifest.json',
330
- data=json.dumps(chip.schema.cfg, indent=2),
329
+ data=json.dumps(chip.schema.getdict(), indent=2),
331
330
  mime="application/json",
332
331
  use_container_width=True)
333
332
 
@@ -491,6 +490,8 @@ def node_file_tree_viewer(chip, step, index):
491
490
 
492
491
 
493
492
  def node_viewer(chip, step, index, metric_dataframe, height=None):
493
+ from pandas import DataFrame
494
+
494
495
  metrics_col, records_col, logs_and_reports_col = streamlit.columns(3, gap='small')
495
496
 
496
497
  node_name = f'{step}{index}'
@@ -507,7 +508,7 @@ def node_viewer(chip, step, index, metric_dataframe, height=None):
507
508
  nodes = {}
508
509
  nodes[step + index] = report.get_flowgraph_nodes(chip, step, index)
509
510
  streamlit.dataframe(
510
- pandas.DataFrame.from_dict(nodes),
511
+ DataFrame.from_dict(nodes),
511
512
  use_container_width=True,
512
513
  height=height)
513
514
  with logs_and_reports_col:
@@ -1,5 +1,4 @@
1
1
  from siliconcompiler.report import report
2
- from siliconcompiler.flowgraph import _get_flowgraph_exit_nodes, _get_flowgraph_entry_nodes
3
2
  from siliconcompiler.tools._common import get_tool_task
4
3
  from siliconcompiler import NodeStatus
5
4
 
@@ -45,8 +44,9 @@ def get_nodes_and_edges(chip):
45
44
  node_dependencies = report.get_flowgraph_edges(chip)
46
45
  successful_path = report.get_flowgraph_path(chip)
47
46
 
48
- entry_exit_nodes = _get_flowgraph_entry_nodes(chip, chip.get('option', 'flow')) + \
49
- _get_flowgraph_exit_nodes(chip, chip.get('option', 'flow'))
47
+ flow = chip.get('option', 'flow')
48
+ entry_exit_nodes = chip.schema.get("flowgraph", flow, field="schema").get_entry_nodes() + \
49
+ chip.schema.get("flowgraph", flow, field="schema").get_exit_nodes()
50
50
 
51
51
  for step, index in node_dependencies:
52
52
  # Build node
@@ -1,11 +1,10 @@
1
1
  import altair
2
2
  import math
3
- import pandas
4
3
  import streamlit
5
4
 
6
5
  from siliconcompiler.report import report
7
6
 
8
- from siliconcompiler.report.dashboard import state
7
+ from siliconcompiler.report.dashboard.web import state
9
8
 
10
9
 
11
10
  def _get_report_chips():
@@ -20,9 +19,11 @@ def job_selector():
20
19
  Displays a dataframe that can be edited to select specific jobs to include
21
20
  in the analysis.
22
21
  """
22
+ from pandas import DataFrame
23
+
23
24
  jobs = state.get_chips()
24
25
 
25
- all_jobs = pandas.DataFrame({
26
+ all_jobs = DataFrame({
26
27
  'job names': jobs,
27
28
  'selected jobs': [True] * len(jobs)
28
29
  })
@@ -114,6 +115,8 @@ def settings(metrics, nodes, graph_number):
114
115
 
115
116
 
116
117
  def graph(metrics, nodes, node_to_step_index_map, graph_number):
118
+ from pandas import DataFrame
119
+
117
120
  metric, selected_nodes, log_scale, transpose, chart_type = \
118
121
  settings(metrics, nodes, graph_number)
119
122
 
@@ -167,7 +170,7 @@ def graph(metrics, nodes, node_to_step_index_map, graph_number):
167
170
 
168
171
  color = color_label
169
172
 
170
- alt_chart = altair.Chart(pandas.DataFrame(filtered_data).dropna(), height=500)
173
+ alt_chart = altair.Chart(DataFrame(filtered_data).dropna(), height=500)
171
174
 
172
175
  if chart_type == 'line':
173
176
  chart_mark = alt_chart.mark_line(point=True)
@@ -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
 
@@ -58,7 +58,7 @@ def update_manifest():
58
58
 
59
59
  for history in chip.getkeys('history'):
60
60
  history_chip = Chip(design='')
61
- history_chip.schema.cfg = chip.getdict('history', history)
61
+ history_chip.schema = chip.schema.history(history).copy()
62
62
  history_chip.set('design', chip.design)
63
63
  add_chip(history, history_chip)
64
64
 
@@ -1,5 +1,4 @@
1
1
  from siliconcompiler import NodeStatus
2
- from siliconcompiler.flowgraph import _get_flowgraph_nodes
3
2
 
4
3
  from pathlib import Path
5
4
 
@@ -25,7 +24,8 @@ def make_node_to_step_index_map(chip, metric_dataframe):
25
24
  '''
26
25
  node_to_step_index_map = {}
27
26
  if chip.get('option', 'flow'):
28
- for step, index in _get_flowgraph_nodes(chip, chip.get('option', 'flow')):
27
+ for step, index in chip.schema.get("flowgraph", chip.get('option', 'flow'),
28
+ field="schema").get_nodes():
29
29
  node_to_step_index_map[f'{step}{index}'] = (step, index)
30
30
 
31
31
  # concatenate step and index
@@ -57,7 +57,8 @@ def make_metric_to_metric_unit_map(metric_dataframe):
57
57
  def is_running(chip):
58
58
  if not chip.get('option', 'flow'):
59
59
  return False
60
- for step, index in _get_flowgraph_nodes(chip, chip.get('option', 'flow')):
60
+ for step, index in chip.schema.get("flowgraph", chip.get('option', 'flow'),
61
+ field="schema").get_nodes():
61
62
  state = chip.get('record', 'status', step=step, index=index)
62
63
  if not NodeStatus.is_done(state):
63
64
  return True
@@ -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
 
@@ -21,8 +21,7 @@ def _generate_html_report(chip, flow, flowgraph_nodes, results_html):
21
21
  del flowgraph_nodes[index]
22
22
 
23
23
  schema = chip.schema.copy()
24
- schema.prune()
25
- pruned_cfg = schema.cfg
24
+ pruned_cfg = schema.getdict()
26
25
  if 'history' in pruned_cfg:
27
26
  del pruned_cfg['history']
28
27
  if 'library' in pruned_cfg:
@@ -51,7 +50,7 @@ def _generate_html_report(chip, flow, flowgraph_nodes, results_html):
51
50
  metrics=metrics,
52
51
  metrics_unit=metrics_unit,
53
52
  reports=reports,
54
- manifest=chip.schema.cfg,
53
+ manifest=chip.schema.getdict(),
55
54
  pruned_cfg=pruned_cfg,
56
55
  metric_keys=metrics_to_show,
57
56
  img_data=img_data,
@@ -1,10 +1,9 @@
1
1
  import fnmatch
2
- import pandas
3
2
  import os
4
3
  from siliconcompiler import Schema
5
- from siliconcompiler.schema.utils import PerNode
4
+ from siliconcompiler.schema import PerNode
6
5
  from siliconcompiler.report import utils
7
- from siliconcompiler.flowgraph import nodes_to_execute
6
+ from siliconcompiler.utils.flowgraph import nodes_to_execute
8
7
  from siliconcompiler.tools._common import get_tool_task
9
8
 
10
9
 
@@ -22,10 +21,12 @@ def make_metric_dataframe(chip):
22
21
  >>> make_metric_dataframe(chip)
23
22
  Returns pandas dataframe of tracked metrics.
24
23
  '''
24
+ from pandas import DataFrame
25
+
25
26
  nodes, errors, metrics, metrics_unit, metrics_to_show, reports = utils._collect_data(chip)
26
27
  # converts from 2d dictionary to pandas DataFrame, transposes so
27
28
  # orientation is correct, and filters based on the metrics we track
28
- data = (pandas.DataFrame.from_dict(metrics, orient='index').transpose())
29
+ data = (DataFrame.from_dict(metrics, orient='index').transpose())
29
30
  data = data.loc[metrics_to_show]
30
31
  # include metrics_unit
31
32
  data.index = data.index.map(lambda x: (x, metrics_unit[x]))
@@ -106,6 +107,11 @@ def make_manifest_helper(manifest_subsect, modified_manifest_subsect):
106
107
  'default' nodes.
107
108
  '''
108
109
 
110
+ def _is_leaf(cfg):
111
+ # 'shorthelp' chosen arbitrarily: any mandatory field with a consistent
112
+ # type would work.
113
+ return 'shorthelp' in cfg and isinstance(cfg['shorthelp'], str)
114
+
109
115
  def build_leaf(manifest_subsect):
110
116
  if PerNode(manifest_subsect['pernode']) == PerNode.NEVER:
111
117
  if Schema.GLOBAL_KEY in manifest_subsect['node'] and \
@@ -132,7 +138,7 @@ def make_manifest_helper(manifest_subsect, modified_manifest_subsect):
132
138
  node_values[step + index] = value
133
139
  return node_values
134
140
 
135
- if Schema._is_leaf(manifest_subsect):
141
+ if _is_leaf(manifest_subsect):
136
142
  if PerNode(manifest_subsect['pernode']) == PerNode.NEVER:
137
143
  if Schema.GLOBAL_KEY in manifest_subsect['node']:
138
144
  value = manifest_subsect['node'][Schema.GLOBAL_KEY][Schema.GLOBAL_KEY]['value']
@@ -157,7 +163,7 @@ def make_manifest_helper(manifest_subsect, modified_manifest_subsect):
157
163
 
158
164
  for key, key_dict in manifest_subsect.items():
159
165
  if key != 'default':
160
- if Schema._is_leaf(key_dict):
166
+ if _is_leaf(key_dict):
161
167
  modified_manifest_subsect[key] = build_leaf(key_dict)
162
168
  else:
163
169
  modified_manifest_subsect[key] = {}
@@ -175,7 +181,7 @@ def make_manifest(chip):
175
181
  >>> make_manifest(chip)
176
182
  Returns tree/json of manifest.
177
183
  '''
178
- manifest = chip.schema.cfg
184
+ manifest = chip.schema.getdict()
179
185
  modified_manifest = {}
180
186
  make_manifest_helper(manifest, modified_manifest)
181
187
  return modified_manifest
@@ -2,7 +2,7 @@ import os
2
2
  import string
3
3
  from PIL import Image, ImageFont, ImageDraw
4
4
 
5
- from siliconcompiler import units
5
+ from siliconcompiler.utils import units
6
6
  from siliconcompiler.report.utils import _find_summary_image, _find_summary_metrics
7
7
 
8
8
 
@@ -1,4 +1,3 @@
1
- import pandas
2
1
  import shutil
3
2
 
4
3
  from siliconcompiler.report.utils import _collect_data, _get_flowgraph_path
@@ -10,6 +9,7 @@ def _show_summary_table(chip, flow, flowgraph_nodes, show_all_indices):
10
9
  '''
11
10
  Prints the end of run summary table
12
11
  '''
12
+ from pandas import DataFrame
13
13
 
14
14
  # Display data
15
15
  column_width = 15
@@ -85,7 +85,7 @@ def _show_summary_table(chip, flow, flowgraph_nodes, show_all_indices):
85
85
  info_list.append(f"partname : {fpga_partname}")
86
86
 
87
87
  libraries = set()
88
- for val, step, index in chip.schema._getvals('asic', 'logiclib'):
88
+ for val, step, index in chip.schema.get('asic', 'logiclib', field=None).getvalues():
89
89
  if not step or (step, index) in flowgraph_nodes:
90
90
  libraries.update(val)
91
91
  if libraries:
@@ -96,7 +96,7 @@ def _show_summary_table(chip, flow, flowgraph_nodes, show_all_indices):
96
96
  print("-" * max_line_width)
97
97
  print(info, "\n")
98
98
 
99
- df = pandas.DataFrame(data, row_labels, column_labels)
99
+ df = DataFrame(data, row_labels, column_labels)
100
100
  if not df.empty:
101
101
  print(df.to_string(line_width=max_line_width, col_space=2))
102
102
  else:
@@ -1,9 +1,11 @@
1
1
  from siliconcompiler import NodeStatus
2
- from siliconcompiler import units
3
- from siliconcompiler.flowgraph import _get_flowgraph_execution_order, _get_flowgraph_exit_nodes, \
2
+ from siliconcompiler.utils import units
3
+ from siliconcompiler.utils.flowgraph import _get_flowgraph_execution_order, \
4
4
  nodes_to_execute
5
5
  from siliconcompiler.tools._common import get_tool_task
6
6
 
7
+ from siliconcompiler.flowgraph import RuntimeFlowgraph
8
+
7
9
 
8
10
  def _find_summary_image(chip, ext='png'):
9
11
  for nodes in reversed(_get_flowgraph_execution_order(chip, chip.get('option', 'flow'))):
@@ -26,9 +28,7 @@ def _find_summary_metrics(chip, metrics_map):
26
28
 
27
29
  data = chip.get('metric', metric, step=step, index=index)
28
30
  if data is not None:
29
- unit = None
30
- if chip.schema.has_field('metric', metric, 'unit'):
31
- unit = chip.get('metric', metric, field='unit')
31
+ unit = chip.get('metric', metric, field='unit')
32
32
  if formatter:
33
33
  metrics[name] = formatter(data, unit)
34
34
  else:
@@ -44,7 +44,7 @@ def _collect_data(chip, flow=None, flowgraph_nodes=None, format_as_string=True):
44
44
  return [], {}, {}, {}, [], {}
45
45
 
46
46
  if not flowgraph_nodes:
47
- flowgraph_nodes = nodes_to_execute(chip)
47
+ flowgraph_nodes = list(nodes_to_execute(chip))
48
48
  # only report tool based steps functions
49
49
  for (step, index) in list(flowgraph_nodes):
50
50
  tool, task = get_tool_task(chip, step, '0', flow=flow)
@@ -79,9 +79,7 @@ def _collect_data(chip, flow=None, flowgraph_nodes=None, format_as_string=True):
79
79
  for metric in chip.getkeys('metric'):
80
80
 
81
81
  # Get the unit associated with the metric
82
- metric_unit = None
83
- if chip.schema.has_field('metric', metric, 'unit'):
84
- metric_unit = chip.get('metric', metric, field='unit')
82
+ metric_unit = chip.get('metric', metric, field='unit')
85
83
  metric_type = chip.get('metric', metric, field='type')
86
84
 
87
85
  show_metric = False
@@ -143,7 +141,10 @@ def _get_flowgraph_path(chip, flow, nodes_to_execute, only_include_successful=Fa
143
141
  to_search = []
144
142
  # Start search with any successful leaf nodes.
145
143
  flowgraph_steps = list(map(lambda node: node[0], nodes_to_execute))
146
- end_nodes = _get_flowgraph_exit_nodes(chip, flow, steps=flowgraph_steps)
144
+ runtime = RuntimeFlowgraph(chip.schema.get("flowgraph", flow, field='schema'),
145
+ from_steps=flowgraph_steps,
146
+ to_steps=flowgraph_steps)
147
+ end_nodes = runtime.get_exit_nodes()
147
148
  for node in end_nodes:
148
149
  if only_include_successful:
149
150
  if NodeStatus.is_success(chip.get('record', 'status', step=node[0], index=node[1])):