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,449 @@
1
+ # Copyright 2025 Silicon Compiler Authors. All Rights Reserved.
2
+
3
+ import distro
4
+ import getpass
5
+ import platform
6
+ import psutil
7
+ import shlex
8
+ import socket
9
+
10
+ from datetime import datetime, timezone
11
+ from enum import Enum
12
+
13
+ from siliconcompiler.schema import BaseSchema
14
+ from siliconcompiler.schema import EditableSchema, Parameter, PerNode, Scope
15
+ from siliconcompiler.schema.utils import trim
16
+
17
+ from siliconcompiler import _metadata
18
+
19
+
20
+ class RecordTime(Enum):
21
+ START = "starttime"
22
+ END = "endtime"
23
+
24
+
25
+ class RecordTool(Enum):
26
+ EXITCODE = "toolexitcode"
27
+ VERSION = "toolversion"
28
+ PATH = "toolpath"
29
+ ARGS = "toolargs"
30
+
31
+
32
+ class RecordSchema(BaseSchema):
33
+ __TIMEFORMAT = "%Y-%m-%d %H:%M:%S"
34
+
35
+ def __init__(self):
36
+ super().__init__()
37
+
38
+ schema_record(self)
39
+
40
+ def clear(self, step, index, keep=None):
41
+ '''
42
+ Clear all saved metrics for a given step and index
43
+
44
+ Args:
45
+ step (str): Step name to clear.
46
+ index (str): Index name to clear.
47
+ keep (list of str): list of records to keep.
48
+ '''
49
+
50
+ if not keep:
51
+ keep = []
52
+
53
+ for record in self.getkeys():
54
+ if record in keep:
55
+ continue
56
+ param = self.get(record, field=None)
57
+
58
+ if param.get(field='pernode').is_never():
59
+ param.unset()
60
+ else:
61
+ param.unset(step=step, index=index)
62
+
63
+ def record_python_packages(self):
64
+ '''
65
+ Record the python packages currently available in the environment.
66
+ '''
67
+ try:
68
+ from pip._internal.operations.freeze import freeze
69
+ except: # noqa E722
70
+ freeze = None
71
+
72
+ if freeze:
73
+ # clear record
74
+ self.set('pythonpackage', [])
75
+
76
+ for pkg in freeze():
77
+ self.add('pythonpackage', pkg)
78
+
79
+ def record_version(self, step, index):
80
+ '''
81
+ Records the versions for SiliconCompiler and python.
82
+
83
+ Args:
84
+ step (str): Step name to associate.
85
+ index (str): Index name to associate.
86
+ '''
87
+ self.set('scversion', _metadata.version, step=step, index=index)
88
+ self.set('pythonversion', platform.python_version(), step=step, index=index)
89
+
90
+ @staticmethod
91
+ def get_cloud_information():
92
+ '''
93
+ Return information about the cloud environment.
94
+
95
+ Return format: {
96
+ "region": str
97
+ }
98
+ '''
99
+ # TODO: add logic to figure out if we're running on a remote cluster and
100
+ # extract the region in a provider-specific way.
101
+ return {"region": "local"}
102
+
103
+ @staticmethod
104
+ def get_ip_information():
105
+ '''
106
+ Return information about the ip and mac address of this machine.
107
+
108
+ Return format: {
109
+ "ip": str,
110
+ "mac": str
111
+ }
112
+ '''
113
+ try:
114
+ for interface, addrs in psutil.net_if_addrs().items():
115
+ if interface == 'lo':
116
+ # don't consider loopback device
117
+ continue
118
+
119
+ if not addrs:
120
+ # skip missing addrs
121
+ continue
122
+
123
+ use_addr = False
124
+ for addr in addrs:
125
+ if addr.family == socket.AF_INET:
126
+ if not addr.address.startswith('127.'):
127
+ use_addr = True
128
+ break
129
+ if addr.family == socket.AF_INET6:
130
+ if addr.address != "::1":
131
+ use_addr = True
132
+ break
133
+
134
+ if use_addr:
135
+ ipaddr = None
136
+ macaddr = None
137
+ for addr in addrs:
138
+ if not ipaddr and addr.family == socket.AF_INET:
139
+ ipaddr = addr.address
140
+ if not ipaddr and addr.family == socket.AF_INET6:
141
+ ipaddr = addr.address
142
+ if not macaddr and addr.family == psutil.AF_LINK:
143
+ macaddr = addr.address
144
+
145
+ return {"ip": ipaddr, "mac": macaddr}
146
+ except: # noqa E722
147
+ pass
148
+
149
+ return {"ip": None, "mac": None}
150
+
151
+ @staticmethod
152
+ def get_machine_information():
153
+ '''
154
+ Return information about the machine.
155
+
156
+ Return format: {
157
+ "machine": str,
158
+ "system": str,
159
+ "distro": str,
160
+ "osversion": str,
161
+ "kernelversion": str,
162
+ "arch": str
163
+ }
164
+ '''
165
+ system = platform.system()
166
+ if system == 'Darwin':
167
+ lower_sys_name = 'macos'
168
+ else:
169
+ lower_sys_name = system.lower()
170
+
171
+ if system == 'Linux':
172
+ distro_name = distro.id()
173
+ else:
174
+ distro_name = None
175
+
176
+ if system == 'Darwin':
177
+ osversion, _, _ = platform.mac_ver()
178
+ elif system == 'Linux':
179
+ osversion = distro.version()
180
+ else:
181
+ osversion = platform.release()
182
+
183
+ kernelversion = None
184
+ if system == 'Linux':
185
+ kernelversion = platform.release()
186
+ elif system == 'Windows':
187
+ kernelversion = platform.version()
188
+ elif system == 'Darwin':
189
+ kernelversion = platform.release()
190
+
191
+ return {'name': platform.node(),
192
+ 'system': lower_sys_name,
193
+ 'distro': distro_name,
194
+ 'osversion': osversion,
195
+ 'kernelversion': kernelversion,
196
+ 'arch': platform.machine()}
197
+
198
+ @staticmethod
199
+ def get_user_information():
200
+ '''
201
+ Return information about the user.
202
+
203
+ Return format: {"username": str}
204
+ '''
205
+ return {'username': getpass.getuser()}
206
+
207
+ def record_userinformation(self, step, index):
208
+ '''
209
+ Records information about the current machine and user.
210
+ Uses information from :meth:`get_machine_information`, :meth:`get_user_information`,
211
+ :meth:`get_cloud_information`, and :meth:`get_ip_information`.
212
+
213
+ Args:
214
+ step (str): Step name to associate.
215
+ index (str): Index name to associate.
216
+ '''
217
+ machine_info = RecordSchema.get_machine_information()
218
+ user_info = RecordSchema.get_user_information()
219
+ cloud_info = RecordSchema.get_cloud_information()
220
+ ip_information = RecordSchema.get_ip_information()
221
+
222
+ self.set('platform', machine_info['system'], step=step, index=index)
223
+ if machine_info['distro']:
224
+ self.set('distro', machine_info['distro'], step=step, index=index)
225
+ self.set('osversion', machine_info['osversion'], step=step, index=index)
226
+ if machine_info['kernelversion']:
227
+ self.set('kernelversion', machine_info['kernelversion'], step=step, index=index)
228
+ self.set('arch', machine_info['arch'], step=step, index=index)
229
+ self.set('machine', machine_info['name'], step=step, index=index)
230
+ self.set('userid', user_info['username'], step=step, index=index)
231
+ self.set('region', cloud_info['region'], step=step, index=index)
232
+
233
+ if ip_information['ip']:
234
+ self.set('ipaddr', ip_information['ip'], step=step, index=index)
235
+ if ip_information['mac']:
236
+ self.set('macaddr', ip_information['mac'], step=step, index=index)
237
+
238
+ def record_time(self, step, index, type):
239
+ '''
240
+ Record the time of the record.
241
+
242
+ Returns:
243
+ time recorded.
244
+
245
+ Args:
246
+ step (str): Step name to associate.
247
+ index (str): Index name to associate.
248
+ type (:class:`RecordTime`): type of time to record
249
+ '''
250
+ type = RecordTime(type)
251
+
252
+ now = datetime.now(timezone.utc)
253
+
254
+ self.set(type.value,
255
+ now.strftime(RecordSchema.__TIMEFORMAT),
256
+ step=step, index=index)
257
+
258
+ return now.timestamp()
259
+
260
+ def get_recorded_time(self, step, index, type):
261
+ '''
262
+ Returns the time recorded for a given record.
263
+
264
+ Args:
265
+ step (str): Step name to associate.
266
+ index (str): Index name to associate.
267
+ type (:class:`RecordTime`): type of time to record
268
+ '''
269
+ type = RecordTime(type)
270
+ return datetime.strptime(
271
+ self.get(type.value, step=step, index=index)+"+0000",
272
+ RecordSchema.__TIMEFORMAT+"%z").timestamp()
273
+
274
+ def record_tool(self, step, index, info, type):
275
+ '''
276
+ Record information about the tool used during this record.
277
+
278
+ Args:
279
+ step (str): Step name to associate.
280
+ index (str): Index name to associate.
281
+ info (any): Information to record.
282
+ type (:class:`RecordTool`): type of tool information being recorded
283
+ '''
284
+ if type == RecordTool.ARGS:
285
+ info = shlex.join(info)
286
+ self.set(type.value, info, step=step, index=index)
287
+
288
+
289
+ ###########################################################################
290
+ # Run Record
291
+ ###########################################################################
292
+ def schema_record(schema):
293
+ schema = EditableSchema(schema)
294
+ records = {'userid': ['userid',
295
+ 'wiley',
296
+ ''],
297
+ 'publickey': ['public key',
298
+ '<key>',
299
+ ''],
300
+ 'machine': ['machine name',
301
+ 'carbon',
302
+ '(myhost, localhost, ...'],
303
+ 'macaddr': ['MAC address',
304
+ '<addr>',
305
+ ''],
306
+ 'ipaddr': ['IP address',
307
+ '<addr>',
308
+ ''],
309
+ 'platform': ['platform name',
310
+ 'linux',
311
+ '(linux, windows, freebsd)'],
312
+ 'distro': ['distro name',
313
+ 'ubuntu',
314
+ '(ubuntu, redhat, centos)'],
315
+ 'arch': ['hardware architecture',
316
+ 'x86_64',
317
+ '(x86_64, rv64imafdc)'],
318
+ 'starttime': ['start time',
319
+ '\"2021-09-06 12:20:20\"',
320
+ 'Time is reported in the ISO 8601 format YYYY-MM-DD HR:MIN:SEC'],
321
+ 'endtime': ['end time',
322
+ '\"2021-09-06 12:20:20\"',
323
+ 'Time is reported in the ISO 8601 format YYYY-MM-DD HR:MIN:SEC'],
324
+ 'region': ['cloud region',
325
+ '\"US Gov Boston\"',
326
+ """Recommended naming methodology:
327
+
328
+ * local: node is the local machine
329
+ * onprem: node in on-premises IT infrastructure
330
+ * public: generic public cloud
331
+ * govcloud: generic US government cloud
332
+ * <region>: cloud and entity specific region string name
333
+ """],
334
+ 'scversion': ['software version',
335
+ '1.0',
336
+ """Version number for the SiliconCompiler software."""],
337
+ 'toolversion': ['tool version',
338
+ '1.0',
339
+ """The tool version captured corresponds to the 'tool'
340
+ parameter within the 'tool' dictionary."""],
341
+ 'toolpath': ['tool path',
342
+ '/usr/bin/openroad',
343
+ """Full path to tool executable used to run this
344
+ task."""],
345
+ 'toolargs': ['tool CLI arguments',
346
+ '\"-I include/ foo.v\"',
347
+ 'Arguments passed to tool via CLI.'],
348
+ 'pythonversion': ['Python version',
349
+ '3.12.3',
350
+ """Version of python used to run this task."""],
351
+ 'osversion': ['O/S version',
352
+ '20.04.1-Ubuntu',
353
+ """Since there is not standard version system for operating
354
+ systems, extracting information from is platform dependent.
355
+ For Linux based operating systems, the 'osversion' is the
356
+ version of the distro."""],
357
+ 'kernelversion': ['O/S kernel version',
358
+ '5.11.0-34-generic',
359
+ """Used for platforms that support a distinction
360
+ between os kernels and os distributions."""]}
361
+
362
+ for key, (shorthelp, example, longhelp) in records.items():
363
+ schema.insert(
364
+ key,
365
+ Parameter(
366
+ "str",
367
+ scope=Scope.JOB,
368
+ shorthelp=f"Record: {shorthelp}",
369
+ switch=f"-record_{key} 'step index <str>'",
370
+ example=[
371
+ f"cli: -record_{key} 'dfm 0 {example}'",
372
+ f"api: chip.set('record', '{key}', '{example}', step='dfm', index=0)"],
373
+ pernode=PerNode.REQUIRED,
374
+ help=f'Record tracking the {shorthelp} per step and index basis.'
375
+ f'{" " + trim(longhelp) if longhelp else ""}'
376
+ ))
377
+
378
+ schema.insert(
379
+ "toolexitcode",
380
+ Parameter(
381
+ "int",
382
+ scope=Scope.JOB,
383
+ shorthelp="Record: tool exit code",
384
+ switch="-record_toolexitcode 'step index <int>'",
385
+ example=[
386
+ "cli: -record_toolexitcode 'dfm 0 0'",
387
+ "api: chip.set('record', 'toolexitcode', 0, step='dfm', index=0)"],
388
+ pernode=PerNode.REQUIRED,
389
+ help='Record tracking the tool exit code per step and index basis.'
390
+ ))
391
+
392
+ # Non-per-node records.
393
+ schema.insert(
394
+ "remoteid",
395
+ Parameter(
396
+ "str",
397
+ scope=Scope.JOB,
398
+ shorthelp="Record: remote job ID",
399
+ switch="-record_remoteid '<str>'",
400
+ example=[
401
+ "cli: -record_remoteid '0123456789abcdeffedcba9876543210'",
402
+ "api: chip.set('record', 'remoteid', '0123456789abcdeffedcba9876543210')"],
403
+ help='Record tracking the job ID for a remote run.'
404
+ ))
405
+
406
+ schema.insert(
407
+ "pythonpackage",
408
+ Parameter(
409
+ "[str]",
410
+ scope=Scope.JOB,
411
+ shorthelp="Record: python packages",
412
+ switch="-record_pythonpackage '<str>'",
413
+ example=[
414
+ "cli: -record_pythonpackage 'siliconcompiler==0.28.0'",
415
+ "api: chip.set('record', 'pythonpackage', 'siliconcompiler==0.28.0')"],
416
+ help='Record tracking for the python packages installed.'
417
+ ))
418
+
419
+ # flowgraph status
420
+ schema.insert(
421
+ "status",
422
+ Parameter(
423
+ "<pending,queued,running,success,error,skipped,timeout>", # sync with NodeStatus
424
+ pernode=PerNode.REQUIRED,
425
+ scope=Scope.JOB,
426
+ shorthelp="Record: node execution status",
427
+ switch="-record_status 'step index <str>'",
428
+ example=[
429
+ "cli: -record_status 'syn 0 success'",
430
+ "api: chip.set('record', 'status', 'success', step='syn', index='0')"],
431
+ help="""Record tracking for the status of a node."""
432
+ ))
433
+
434
+ # flowgraph select
435
+ schema.insert(
436
+ "inputnode",
437
+ Parameter(
438
+ "[(str,str)]",
439
+ pernode=PerNode.REQUIRED,
440
+ scope=Scope.JOB,
441
+ shorthelp="Record: node inputs",
442
+ switch="-record_inputnode 'step index <(str,str)>'",
443
+ example=[
444
+ "cli: -record_inputnode 'cts 0 (place,42)'",
445
+ "api: chip.set('record', 'inputnode', ('place', '42'), step='syn', index='0')"],
446
+ help=trim("""
447
+ List of selected inputs for the current step/index specified as
448
+ (in_step, in_index) tuple.""")
449
+ ))
@@ -10,11 +10,12 @@ import tarfile
10
10
  import tempfile
11
11
  import multiprocessing
12
12
 
13
- from siliconcompiler import utils, SiliconCompilerError
13
+ from siliconcompiler import utils, SiliconCompilerError, NodeStatus
14
14
  from siliconcompiler import NodeStatus as SCNodeStatus
15
15
  from siliconcompiler._metadata import default_server
16
- from siliconcompiler.flowgraph import nodes_to_execute
16
+ from siliconcompiler.utils.flowgraph import nodes_to_execute
17
17
  from siliconcompiler.remote import JobStatus
18
+ from siliconcompiler.report.dashboard import DashboardType
18
19
 
19
20
  # Step name to use while logging
20
21
  remote_step_name = 'remote'
@@ -298,18 +299,19 @@ service, provided by SiliconCompiler, is not intended to process proprietary IP.
298
299
  self.__logger.info(nodes_log)
299
300
 
300
301
  def _report_job_status(self, info):
302
+ completed = []
303
+ starttimes = {}
304
+
301
305
  if not info['busy']:
302
306
  # Job is not running
303
- return [], False
307
+ return completed, starttimes, False
304
308
 
305
309
  try:
306
310
  # Decode response JSON, if possible.
307
311
  job_info = json.loads(info['message'])
308
312
  except json.JSONDecodeError as e:
309
313
  self.__logger.warning(f"Job is still running: {e}")
310
- return [], True
311
-
312
- completed = []
314
+ return completed, starttimes, True
313
315
 
314
316
  nodes_to_log = {}
315
317
  for node, node_info in job_info.items():
@@ -335,7 +337,16 @@ service, provided by SiliconCompiler, is not intended to process proprietary IP.
335
337
  self.__log_node_status(stat, nodes)
336
338
 
337
339
  # Running / in-progress flowgraph nodes should all be printed:
340
+ base_time = time.time()
338
341
  for stat, nodes in nodes_to_log.items():
342
+ for node, node_info in nodes:
343
+ if 'elapsed_time' in node_info:
344
+ runtime = 0
345
+ for part in node_info['elapsed_time'].split(":"):
346
+ runtime = 60 * runtime + float(part)
347
+ starttimes[(self.__node_information[node]["step"],
348
+ self.__node_information[node]["index"])] = base_time - runtime
349
+
339
350
  if SCNodeStatus.is_running(stat):
340
351
  self.__logger.info(f' {stat.title()} ({len(nodes)}):')
341
352
  for node, node_info in nodes:
@@ -349,7 +360,7 @@ service, provided by SiliconCompiler, is not intended to process proprietary IP.
349
360
  if SCNodeStatus.is_waiting(stat):
350
361
  self.__log_node_status(stat, nodes)
351
362
 
352
- return completed, True
363
+ return completed, starttimes, True
353
364
 
354
365
  def __check(self):
355
366
  def post_action(url):
@@ -438,6 +449,9 @@ service, provided by SiliconCompiler, is not intended to process proprietary IP.
438
449
  raise SiliconCompilerError('Cannot pass [arg,index] parameter into remote flow.',
439
450
  chip=self.__chip)
440
451
 
452
+ if not self.__chip._dash:
453
+ self.__chip.dashboard(type=DashboardType.CLI)
454
+
441
455
  # Only run the pre-process step if the job doesn't already have a remote ID.
442
456
  if not remote_resume:
443
457
  self.__run_preprocess()
@@ -450,10 +464,12 @@ service, provided by SiliconCompiler, is not intended to process proprietary IP.
450
464
  self.__request_run()
451
465
 
452
466
  # Run the main 'check_progress' loop to monitor job status until it finishes.
453
- self._run_loop()
454
-
455
- # Restore logger
456
- self.__chip._init_logger(in_run=True)
467
+ try:
468
+ self._run_loop()
469
+ finally:
470
+ # Restore logger
471
+ self.__chip._dash.end_of_run()
472
+ self.__chip._init_logger(in_run=True)
457
473
 
458
474
  def __request_run(self):
459
475
  '''
@@ -488,7 +504,7 @@ service, provided by SiliconCompiler, is not intended to process proprietary IP.
488
504
  # Redirected POST requests are translated to GETs. This is actually
489
505
  # part of the HTTP spec, so we need to manually follow the trail.
490
506
  post_params = {
491
- 'chip_cfg': self.__chip.schema.cfg,
507
+ 'chip_cfg': self.__chip.schema.getdict(),
492
508
  'params': self.__get_post_params(include_job_id=True)
493
509
  }
494
510
 
@@ -530,8 +546,11 @@ service, provided by SiliconCompiler, is not intended to process proprietary IP.
530
546
  key_type = self.__chip.get(*key, field='type')
531
547
 
532
548
  if 'dir' in key_type or 'file' in key_type:
533
- for _, step, index in self.__chip.schema._getvals(*key, return_defvalue=False):
549
+ for _, step, index in self.__chip.schema.get(*key, field=None).getvalues(
550
+ return_defvalue=False):
534
551
  packages = self.__chip.get(*key, field='package', step=step, index=index)
552
+ if not isinstance(packages, list):
553
+ packages = [packages]
535
554
  force_copy = False
536
555
  for package in packages:
537
556
  if not package:
@@ -559,7 +578,7 @@ service, provided by SiliconCompiler, is not intended to process proprietary IP.
559
578
  self.__logger.info(f'To cancel this job use: {cancel_cmd}')
560
579
  raise SiliconCompilerError('Job canceled by user keyboard interrupt')
561
580
 
562
- def __import_run_manifests(self):
581
+ def __import_run_manifests(self, starttimes):
563
582
  changed = False
564
583
  for _, node_info in self.__node_information.items():
565
584
  if node_info["imported"]:
@@ -577,6 +596,16 @@ service, provided by SiliconCompiler, is not intended to process proprietary IP.
577
596
  except: # noqa E722
578
597
  # Import may fail if file is still getting written
579
598
  pass
599
+ elif self.__chip.get('record', 'status',
600
+ step=node_info["step"], index=node_info["index"]) \
601
+ == NodeStatus.SKIPPED:
602
+ node_info["imported"] = True
603
+ changed = True
604
+
605
+ if changed and self.__chip._dash:
606
+ # Update dashboard if active
607
+ self.__chip._dash.update_manifest({"starttimes": starttimes})
608
+
580
609
  return changed
581
610
 
582
611
  def __ensure_run_loop_information(self):
@@ -605,17 +634,30 @@ service, provided by SiliconCompiler, is not intended to process proprietary IP.
605
634
  # Check the job's progress periodically until it finishes.
606
635
  running = True
607
636
 
637
+ starttimes = {}
638
+
608
639
  while running:
609
- time.sleep(self.__check_interval)
610
- self.__import_run_manifests()
640
+ sleepremaining = self.__check_interval
641
+ while any([nodeinfo["fetched"] and not nodeinfo["imported"]
642
+ for nodeinfo in self.__node_information.values()]):
643
+ self.__import_run_manifests(starttimes)
644
+ sleepremaining -= 1
645
+ if sleepremaining <= 0:
646
+ break
647
+ time.sleep(1)
648
+ if sleepremaining > 0:
649
+ time.sleep(sleepremaining)
611
650
 
612
651
  # Check progress
613
652
  job_info = self.check_job_status()
614
- completed, running = self._report_job_status(job_info)
653
+ completed, new_starttimes, running = self._report_job_status(job_info)
654
+
655
+ # preserve old starttimes
656
+ starttimes = {**starttimes, **new_starttimes}
615
657
 
616
658
  if self.__chip._dash:
617
659
  # Update dashboard if active
618
- self.__chip._dash.update_manifest()
660
+ self.__chip._dash.update_manifest({"starttimes": starttimes})
619
661
 
620
662
  nodes_to_fetch = []
621
663
  for node in completed:
@@ -648,7 +690,7 @@ service, provided by SiliconCompiler, is not intended to process proprietary IP.
648
690
  self.__download_pool.join()
649
691
  self.__download_pool = None
650
692
 
651
- self.__import_run_manifests()
693
+ self.__import_run_manifests({})
652
694
 
653
695
  def __schedule_fetch_result(self, node):
654
696
  self.__node_information[node]["fetched"] = True