siliconcompiler 0.32.3__py3-none-any.whl → 0.33.1__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 (280) hide show
  1. siliconcompiler/__init__.py +19 -2
  2. siliconcompiler/_common.py +5 -0
  3. siliconcompiler/_metadata.py +1 -1
  4. siliconcompiler/apps/sc.py +2 -2
  5. siliconcompiler/apps/sc_install.py +10 -3
  6. siliconcompiler/apps/sc_issue.py +1 -1
  7. siliconcompiler/apps/sc_remote.py +10 -5
  8. siliconcompiler/apps/sc_show.py +2 -2
  9. siliconcompiler/apps/utils/replay.py +5 -3
  10. siliconcompiler/asic.py +120 -0
  11. siliconcompiler/checklist.py +150 -0
  12. siliconcompiler/core.py +299 -299
  13. siliconcompiler/flowgraph.py +803 -515
  14. siliconcompiler/fpga.py +84 -0
  15. siliconcompiler/metric.py +479 -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 +453 -0
  20. siliconcompiler/remote/client.py +15 -5
  21. siliconcompiler/remote/schema.py +116 -112
  22. siliconcompiler/remote/server.py +9 -6
  23. siliconcompiler/report/dashboard/cli/__init__.py +14 -721
  24. siliconcompiler/report/dashboard/cli/board.py +899 -0
  25. siliconcompiler/report/dashboard/web/__init__.py +10 -10
  26. siliconcompiler/report/dashboard/web/components/__init__.py +5 -4
  27. siliconcompiler/report/dashboard/web/components/flowgraph.py +3 -3
  28. siliconcompiler/report/dashboard/web/components/graph.py +6 -3
  29. siliconcompiler/report/dashboard/web/state.py +1 -1
  30. siliconcompiler/report/dashboard/web/utils/__init__.py +4 -3
  31. siliconcompiler/report/html_report.py +2 -3
  32. siliconcompiler/report/report.py +22 -11
  33. siliconcompiler/report/summary_image.py +1 -1
  34. siliconcompiler/report/summary_table.py +3 -3
  35. siliconcompiler/report/utils.py +21 -14
  36. siliconcompiler/scheduler/__init__.py +234 -1206
  37. siliconcompiler/scheduler/run_node.py +2 -1
  38. siliconcompiler/scheduler/send_messages.py +11 -5
  39. siliconcompiler/scheduler/slurm.py +11 -44
  40. siliconcompiler/scheduler/taskscheduler.py +320 -0
  41. siliconcompiler/schema/__init__.py +19 -2
  42. siliconcompiler/schema/baseschema.py +493 -0
  43. siliconcompiler/schema/cmdlineschema.py +250 -0
  44. siliconcompiler/{sphinx_ext → schema/docs}/__init__.py +3 -1
  45. siliconcompiler/{sphinx_ext → schema/docs}/dynamicgen.py +63 -81
  46. siliconcompiler/{sphinx_ext → schema/docs}/schemagen.py +73 -85
  47. siliconcompiler/{sphinx_ext → schema/docs}/utils.py +12 -13
  48. siliconcompiler/schema/editableschema.py +136 -0
  49. siliconcompiler/schema/journalingschema.py +238 -0
  50. siliconcompiler/schema/namedschema.py +41 -0
  51. siliconcompiler/schema/packageschema.py +101 -0
  52. siliconcompiler/schema/parameter.py +791 -0
  53. siliconcompiler/schema/parametertype.py +323 -0
  54. siliconcompiler/schema/parametervalue.py +736 -0
  55. siliconcompiler/schema/safeschema.py +37 -0
  56. siliconcompiler/schema/schema_cfg.py +109 -1789
  57. siliconcompiler/schema/utils.py +5 -68
  58. siliconcompiler/schema_obj.py +119 -0
  59. siliconcompiler/tool.py +1416 -0
  60. siliconcompiler/tools/_common/__init__.py +6 -10
  61. siliconcompiler/tools/_common/asic.py +5 -5
  62. siliconcompiler/tools/_common/sdc/sc_constraints.sdc +1 -1
  63. siliconcompiler/tools/bluespec/convert.py +9 -8
  64. siliconcompiler/tools/builtin/_common.py +9 -2
  65. siliconcompiler/tools/builtin/concatenate.py +7 -3
  66. siliconcompiler/tools/builtin/minimum.py +7 -2
  67. siliconcompiler/tools/builtin/mux.py +8 -2
  68. siliconcompiler/tools/builtin/nop.py +7 -2
  69. siliconcompiler/tools/builtin/verify.py +11 -5
  70. siliconcompiler/tools/chisel/convert.py +10 -10
  71. siliconcompiler/tools/genfasm/bitstream.py +3 -3
  72. siliconcompiler/tools/ghdl/convert.py +1 -1
  73. siliconcompiler/tools/icarus/compile.py +4 -4
  74. siliconcompiler/tools/icepack/bitstream.py +6 -1
  75. siliconcompiler/tools/klayout/convert_drc_db.py +5 -0
  76. siliconcompiler/tools/klayout/drc.py +2 -2
  77. siliconcompiler/tools/klayout/klayout_export.py +0 -1
  78. siliconcompiler/tools/klayout/klayout_show.py +6 -6
  79. siliconcompiler/tools/klayout/klayout_utils.py +15 -22
  80. siliconcompiler/tools/netgen/count_lvs.py +2 -2
  81. siliconcompiler/tools/netgen/lvs.py +1 -1
  82. siliconcompiler/tools/nextpnr/apr.py +6 -1
  83. siliconcompiler/tools/nextpnr/nextpnr.py +4 -4
  84. siliconcompiler/tools/openroad/_apr.py +15 -2
  85. siliconcompiler/tools/openroad/rdlroute.py +3 -3
  86. siliconcompiler/tools/openroad/scripts/apr/postamble.tcl +1 -1
  87. siliconcompiler/tools/openroad/scripts/apr/preamble.tcl +5 -5
  88. siliconcompiler/tools/openroad/scripts/apr/sc_antenna_repair.tcl +2 -2
  89. siliconcompiler/tools/openroad/scripts/apr/sc_clock_tree_synthesis.tcl +2 -2
  90. siliconcompiler/tools/openroad/scripts/apr/sc_detailed_placement.tcl +2 -2
  91. siliconcompiler/tools/openroad/scripts/apr/sc_detailed_route.tcl +2 -2
  92. siliconcompiler/tools/openroad/scripts/apr/sc_endcap_tapcell_insertion.tcl +2 -2
  93. siliconcompiler/tools/openroad/scripts/apr/sc_fillercell_insertion.tcl +2 -2
  94. siliconcompiler/tools/openroad/scripts/apr/sc_fillmetal_insertion.tcl +2 -2
  95. siliconcompiler/tools/openroad/scripts/apr/sc_global_placement.tcl +2 -2
  96. siliconcompiler/tools/openroad/scripts/apr/sc_global_route.tcl +2 -2
  97. siliconcompiler/tools/openroad/scripts/apr/sc_init_floorplan.tcl +3 -9
  98. siliconcompiler/tools/openroad/scripts/apr/sc_macro_placement.tcl +3 -3
  99. siliconcompiler/tools/openroad/scripts/apr/sc_metrics.tcl +2 -2
  100. siliconcompiler/tools/openroad/scripts/apr/sc_pin_placement.tcl +2 -2
  101. siliconcompiler/tools/openroad/scripts/apr/sc_power_grid.tcl +2 -2
  102. siliconcompiler/tools/openroad/scripts/apr/sc_repair_design.tcl +2 -2
  103. siliconcompiler/tools/openroad/scripts/apr/sc_repair_timing.tcl +2 -2
  104. siliconcompiler/tools/openroad/scripts/apr/sc_write_data.tcl +2 -2
  105. siliconcompiler/tools/openroad/scripts/common/procs.tcl +75 -1
  106. siliconcompiler/tools/openroad/scripts/common/read_input_files.tcl +1 -7
  107. siliconcompiler/tools/openroad/scripts/common/screenshot.tcl +2 -2
  108. siliconcompiler/tools/openroad/scripts/common/write_images.tcl +28 -3
  109. siliconcompiler/tools/openroad/scripts/sc_rcx.tcl +1 -1
  110. siliconcompiler/tools/openroad/scripts/sc_rdlroute.tcl +3 -3
  111. siliconcompiler/tools/openroad/scripts/sc_show.tcl +6 -6
  112. siliconcompiler/tools/opensta/scripts/sc_timing.tcl +10 -0
  113. siliconcompiler/tools/opensta/timing.py +11 -0
  114. siliconcompiler/tools/slang/__init__.py +13 -13
  115. siliconcompiler/tools/slang/elaborate.py +6 -6
  116. siliconcompiler/tools/slang/lint.py +1 -3
  117. siliconcompiler/tools/surelog/parse.py +4 -4
  118. siliconcompiler/tools/sv2v/convert.py +20 -3
  119. siliconcompiler/tools/verilator/compile.py +2 -2
  120. siliconcompiler/tools/verilator/verilator.py +3 -3
  121. siliconcompiler/tools/vpr/_xml_constraint.py +8 -8
  122. siliconcompiler/tools/vpr/place.py +1 -1
  123. siliconcompiler/tools/vpr/route.py +4 -4
  124. siliconcompiler/tools/vpr/screenshot.py +1 -1
  125. siliconcompiler/tools/vpr/show.py +5 -5
  126. siliconcompiler/tools/vpr/vpr.py +24 -24
  127. siliconcompiler/tools/xdm/convert.py +2 -2
  128. siliconcompiler/tools/xyce/simulate.py +1 -1
  129. siliconcompiler/tools/yosys/prepareLib.py +2 -2
  130. siliconcompiler/tools/yosys/sc_synth_asic.tcl +111 -63
  131. siliconcompiler/tools/yosys/screenshot.py +1 -1
  132. siliconcompiler/tools/yosys/syn_asic.py +7 -7
  133. siliconcompiler/toolscripts/_tools.json +12 -10
  134. siliconcompiler/toolscripts/rhel8/install-chisel.sh +9 -2
  135. siliconcompiler/toolscripts/rhel8/install-icarus.sh +10 -3
  136. siliconcompiler/toolscripts/rhel8/install-klayout.sh +8 -1
  137. siliconcompiler/toolscripts/rhel8/install-magic.sh +9 -2
  138. siliconcompiler/toolscripts/rhel8/install-montage.sh +1 -1
  139. siliconcompiler/toolscripts/rhel8/install-netgen.sh +9 -2
  140. siliconcompiler/toolscripts/rhel8/install-slang.sh +11 -4
  141. siliconcompiler/toolscripts/rhel8/install-surelog.sh +9 -2
  142. siliconcompiler/toolscripts/rhel8/install-sv2v.sh +11 -4
  143. siliconcompiler/toolscripts/rhel8/install-verible.sh +11 -3
  144. siliconcompiler/toolscripts/rhel8/install-verilator.sh +10 -3
  145. siliconcompiler/toolscripts/rhel8/install-xyce.sh +15 -10
  146. siliconcompiler/toolscripts/rhel9/install-chisel.sh +9 -2
  147. siliconcompiler/toolscripts/rhel9/install-ghdl.sh +9 -2
  148. siliconcompiler/toolscripts/rhel9/install-gtkwave.sh +10 -3
  149. siliconcompiler/toolscripts/rhel9/install-icarus.sh +10 -3
  150. siliconcompiler/toolscripts/rhel9/install-klayout.sh +8 -1
  151. siliconcompiler/toolscripts/rhel9/install-magic.sh +9 -2
  152. siliconcompiler/toolscripts/rhel9/install-montage.sh +1 -1
  153. siliconcompiler/toolscripts/rhel9/install-netgen.sh +9 -2
  154. siliconcompiler/toolscripts/rhel9/install-openroad.sh +16 -3
  155. siliconcompiler/toolscripts/rhel9/install-opensta.sh +17 -5
  156. siliconcompiler/toolscripts/rhel9/install-slang.sh +11 -4
  157. siliconcompiler/toolscripts/rhel9/install-surelog.sh +9 -2
  158. siliconcompiler/toolscripts/rhel9/install-sv2v.sh +11 -4
  159. siliconcompiler/toolscripts/rhel9/install-verible.sh +11 -3
  160. siliconcompiler/toolscripts/rhel9/install-verilator.sh +10 -3
  161. siliconcompiler/toolscripts/rhel9/install-vpr.sh +9 -2
  162. siliconcompiler/toolscripts/rhel9/install-xdm.sh +10 -2
  163. siliconcompiler/toolscripts/rhel9/install-xyce.sh +15 -10
  164. siliconcompiler/toolscripts/rhel9/install-yosys-moosic.sh +9 -2
  165. siliconcompiler/toolscripts/rhel9/install-yosys-parmys.sh +10 -3
  166. siliconcompiler/toolscripts/rhel9/install-yosys-slang.sh +10 -2
  167. siliconcompiler/toolscripts/rhel9/install-yosys.sh +9 -2
  168. siliconcompiler/toolscripts/ubuntu20/install-bambu.sh +10 -2
  169. siliconcompiler/toolscripts/ubuntu20/install-bluespec.sh +10 -3
  170. siliconcompiler/toolscripts/ubuntu20/install-chisel.sh +9 -2
  171. siliconcompiler/toolscripts/ubuntu20/install-ghdl.sh +9 -2
  172. siliconcompiler/toolscripts/ubuntu20/install-gtkwave.sh +9 -2
  173. siliconcompiler/toolscripts/ubuntu20/install-icarus.sh +9 -2
  174. siliconcompiler/toolscripts/ubuntu20/install-icepack.sh +9 -2
  175. siliconcompiler/toolscripts/ubuntu20/install-klayout.sh +8 -1
  176. siliconcompiler/toolscripts/ubuntu20/install-magic.sh +9 -2
  177. siliconcompiler/toolscripts/ubuntu20/install-montage.sh +1 -1
  178. siliconcompiler/toolscripts/ubuntu20/install-netgen.sh +9 -2
  179. siliconcompiler/toolscripts/ubuntu20/install-nextpnr.sh +9 -2
  180. siliconcompiler/toolscripts/ubuntu20/install-openroad.sh +16 -3
  181. siliconcompiler/toolscripts/ubuntu20/install-opensta.sh +16 -5
  182. siliconcompiler/toolscripts/ubuntu20/install-slang.sh +11 -4
  183. siliconcompiler/toolscripts/ubuntu20/install-slurm.sh +9 -2
  184. siliconcompiler/toolscripts/ubuntu20/install-surelog.sh +10 -2
  185. siliconcompiler/toolscripts/ubuntu20/install-sv2v.sh +11 -4
  186. siliconcompiler/toolscripts/ubuntu20/install-verible.sh +11 -3
  187. siliconcompiler/toolscripts/ubuntu20/install-verilator.sh +9 -2
  188. siliconcompiler/toolscripts/ubuntu20/install-xdm.sh +10 -2
  189. siliconcompiler/toolscripts/ubuntu20/install-xyce.sh +13 -8
  190. siliconcompiler/toolscripts/ubuntu20/install-yosys-moosic.sh +9 -2
  191. siliconcompiler/toolscripts/ubuntu20/install-yosys.sh +9 -2
  192. siliconcompiler/toolscripts/ubuntu22/install-bambu.sh +10 -2
  193. siliconcompiler/toolscripts/ubuntu22/install-bluespec.sh +10 -3
  194. siliconcompiler/toolscripts/ubuntu22/install-chisel.sh +9 -2
  195. siliconcompiler/toolscripts/ubuntu22/install-ghdl.sh +9 -2
  196. siliconcompiler/toolscripts/ubuntu22/install-gtkwave.sh +9 -2
  197. siliconcompiler/toolscripts/ubuntu22/install-icarus.sh +9 -2
  198. siliconcompiler/toolscripts/ubuntu22/install-icepack.sh +9 -2
  199. siliconcompiler/toolscripts/ubuntu22/install-klayout.sh +8 -1
  200. siliconcompiler/toolscripts/ubuntu22/install-magic.sh +9 -2
  201. siliconcompiler/toolscripts/ubuntu22/install-montage.sh +1 -1
  202. siliconcompiler/toolscripts/ubuntu22/install-netgen.sh +9 -2
  203. siliconcompiler/toolscripts/ubuntu22/install-nextpnr.sh +9 -2
  204. siliconcompiler/toolscripts/ubuntu22/install-openroad.sh +16 -3
  205. siliconcompiler/toolscripts/ubuntu22/install-opensta.sh +17 -5
  206. siliconcompiler/toolscripts/ubuntu22/install-slang.sh +11 -4
  207. siliconcompiler/toolscripts/ubuntu22/install-slurm.sh +9 -2
  208. siliconcompiler/toolscripts/ubuntu22/install-surelog.sh +10 -2
  209. siliconcompiler/toolscripts/ubuntu22/install-sv2v.sh +11 -4
  210. siliconcompiler/toolscripts/ubuntu22/install-verible.sh +11 -3
  211. siliconcompiler/toolscripts/ubuntu22/install-verilator.sh +9 -2
  212. siliconcompiler/toolscripts/ubuntu22/install-vpr.sh +9 -4
  213. siliconcompiler/toolscripts/ubuntu22/install-xdm.sh +10 -2
  214. siliconcompiler/toolscripts/ubuntu22/install-xyce.sh +13 -8
  215. siliconcompiler/toolscripts/ubuntu22/install-yosys-moosic.sh +9 -2
  216. siliconcompiler/toolscripts/ubuntu22/install-yosys-parmys.sh +10 -3
  217. siliconcompiler/toolscripts/ubuntu22/install-yosys-slang.sh +10 -2
  218. siliconcompiler/toolscripts/ubuntu22/install-yosys.sh +9 -2
  219. siliconcompiler/toolscripts/ubuntu24/install-bambu.sh +12 -4
  220. siliconcompiler/toolscripts/ubuntu24/install-bluespec.sh +10 -3
  221. siliconcompiler/toolscripts/ubuntu24/install-chisel.sh +9 -2
  222. siliconcompiler/toolscripts/ubuntu24/install-ghdl.sh +9 -2
  223. siliconcompiler/toolscripts/ubuntu24/install-gtkwave.sh +9 -2
  224. siliconcompiler/toolscripts/ubuntu24/install-icarus.sh +9 -2
  225. siliconcompiler/toolscripts/ubuntu24/install-icepack.sh +9 -2
  226. siliconcompiler/toolscripts/ubuntu24/install-klayout.sh +8 -1
  227. siliconcompiler/toolscripts/ubuntu24/install-magic.sh +9 -2
  228. siliconcompiler/toolscripts/ubuntu24/install-montage.sh +1 -1
  229. siliconcompiler/toolscripts/ubuntu24/install-netgen.sh +9 -2
  230. siliconcompiler/toolscripts/ubuntu24/install-nextpnr.sh +9 -2
  231. siliconcompiler/toolscripts/ubuntu24/install-openroad.sh +16 -3
  232. siliconcompiler/toolscripts/ubuntu24/install-opensta.sh +17 -5
  233. siliconcompiler/toolscripts/ubuntu24/install-slang.sh +11 -4
  234. siliconcompiler/toolscripts/ubuntu24/install-slurm.sh +9 -2
  235. siliconcompiler/toolscripts/ubuntu24/install-surelog.sh +10 -2
  236. siliconcompiler/toolscripts/ubuntu24/install-sv2v.sh +11 -4
  237. siliconcompiler/toolscripts/ubuntu24/install-verible.sh +11 -3
  238. siliconcompiler/toolscripts/ubuntu24/install-verilator.sh +9 -2
  239. siliconcompiler/toolscripts/ubuntu24/install-vpr.sh +9 -4
  240. siliconcompiler/toolscripts/ubuntu24/install-xdm.sh +10 -2
  241. siliconcompiler/toolscripts/ubuntu24/install-xyce.sh +13 -8
  242. siliconcompiler/toolscripts/ubuntu24/install-yosys-moosic.sh +9 -2
  243. siliconcompiler/toolscripts/ubuntu24/install-yosys-parmys.sh +10 -3
  244. siliconcompiler/toolscripts/ubuntu24/install-yosys-slang.sh +10 -2
  245. siliconcompiler/toolscripts/ubuntu24/install-yosys.sh +9 -2
  246. siliconcompiler/utils/__init__.py +19 -112
  247. siliconcompiler/utils/flowgraph.py +244 -0
  248. siliconcompiler/{issue.py → utils/issue.py} +18 -25
  249. siliconcompiler/utils/logging.py +3 -4
  250. {siliconcompiler-0.32.3.dist-info → siliconcompiler-0.33.1.dist-info}/METADATA +9 -8
  251. siliconcompiler-0.33.1.dist-info/RECORD +488 -0
  252. {siliconcompiler-0.32.3.dist-info → siliconcompiler-0.33.1.dist-info}/WHEEL +1 -1
  253. {siliconcompiler-0.32.3.dist-info → siliconcompiler-0.33.1.dist-info}/entry_points.txt +8 -8
  254. siliconcompiler/schema/schema_obj.py +0 -1936
  255. siliconcompiler/toolscripts/ubuntu20/install-vpr.sh +0 -29
  256. siliconcompiler/toolscripts/ubuntu20/install-yosys-parmys.sh +0 -61
  257. siliconcompiler-0.32.3.dist-info/RECORD +0 -470
  258. /siliconcompiler/{templates → data/templates}/__init__.py +0 -0
  259. /siliconcompiler/{templates → data/templates}/email/__init__.py +0 -0
  260. /siliconcompiler/{templates → data/templates}/email/general.j2 +0 -0
  261. /siliconcompiler/{templates → data/templates}/email/summary.j2 +0 -0
  262. /siliconcompiler/{templates → data/templates}/issue/README.txt +0 -0
  263. /siliconcompiler/{templates → data/templates}/issue/__init__.py +0 -0
  264. /siliconcompiler/{templates → data/templates}/issue/run.sh +0 -0
  265. /siliconcompiler/{templates → data/templates}/replay/replay.py.j2 +0 -0
  266. /siliconcompiler/{templates → data/templates}/replay/replay.sh.j2 +0 -0
  267. /siliconcompiler/{templates → data/templates}/replay/requirements.txt +0 -0
  268. /siliconcompiler/{templates → data/templates}/replay/setup.sh +0 -0
  269. /siliconcompiler/{templates → data/templates}/report/__init__.py +0 -0
  270. /siliconcompiler/{templates → data/templates}/report/bootstrap.min.css +0 -0
  271. /siliconcompiler/{templates → data/templates}/report/bootstrap.min.js +0 -0
  272. /siliconcompiler/{templates → data/templates}/report/bootstrap_LICENSE.md +0 -0
  273. /siliconcompiler/{templates → data/templates}/report/sc_report.j2 +0 -0
  274. /siliconcompiler/{templates → data/templates}/slurm/__init__.py +0 -0
  275. /siliconcompiler/{templates → data/templates}/slurm/run.sh +0 -0
  276. /siliconcompiler/{templates → data/templates}/tcl/__init__.py +0 -0
  277. /siliconcompiler/{templates → data/templates}/tcl/manifest.tcl.j2 +0 -0
  278. /siliconcompiler/{units.py → utils/units.py} +0 -0
  279. {siliconcompiler-0.32.3.dist-info → siliconcompiler-0.33.1.dist-info}/licenses/LICENSE +0 -0
  280. {siliconcompiler-0.32.3.dist-info → siliconcompiler-0.33.1.dist-info}/top_level.txt +0 -0
@@ -93,7 +93,8 @@ def main():
93
93
  chip.set('record', 'remoteid', args.remoteid)
94
94
 
95
95
  if args.unset_scheduler:
96
- for vals, step, index in chip.schema._getvals('option', 'scheduler', 'name'):
96
+ for vals, step, index in chip.schema.get('option', 'scheduler', 'name',
97
+ field=None).getvalues():
97
98
  chip.unset('option', 'scheduler', 'name', step=step, index=index)
98
99
 
99
100
  # Init logger to ensure consistent view
@@ -6,12 +6,12 @@ from email.mime.application import MIMEApplication
6
6
  import json
7
7
  import os
8
8
  from siliconcompiler import sc_open
9
- from siliconcompiler.schema import Schema
9
+ from siliconcompiler import Schema
10
10
  from siliconcompiler.report import utils as report_utils
11
11
  import fastjsonschema
12
12
  from pathlib import Path
13
- from siliconcompiler.flowgraph import get_executed_nodes
14
13
  import uuid
14
+ from siliconcompiler.flowgraph import RuntimeFlowgraph
15
15
 
16
16
 
17
17
  # Compile validation code for API request bodies.
@@ -25,7 +25,7 @@ with open(api_dir / 'email_credentials.json') as schema:
25
25
  def __load_config(chip):
26
26
  path = default_email_credentials_file()
27
27
  if not os.path.exists(path):
28
- chip.logger.warn(f'Email credentials are not available: {path}')
28
+ chip.logger.warning(f'Email credentials are not available: {path}')
29
29
  return {}
30
30
 
31
31
  with open(path) as f:
@@ -91,9 +91,15 @@ def send(chip, msg_type, step, index):
91
91
  filename=os.path.basename(layout_img))
92
92
  msg.attach(img_attach)
93
93
 
94
- nodes_to_execute = get_executed_nodes(chip, flow)
94
+ runtime = RuntimeFlowgraph(
95
+ chip.schema.get("flowgraph", flow, field='schema'),
96
+ from_steps=chip.get('option', 'from'),
97
+ to_steps=chip.get('option', 'to'),
98
+ prune_nodes=chip.get('option', 'prune'))
99
+
95
100
  nodes, errors, metrics, metrics_unit, metrics_to_show, _ = \
96
- report_utils._collect_data(chip, flow=flow, flowgraph_nodes=nodes_to_execute)
101
+ report_utils._collect_data(chip, flow=flow,
102
+ flowgraph_nodes=runtime.get_nodes())
97
103
 
98
104
  text_msg = get_file_template('email/summary.j2').render(
99
105
  design=chip.design,
@@ -2,13 +2,12 @@ import os
2
2
  import shlex
3
3
  import subprocess
4
4
  import stat
5
- import time
6
5
  import uuid
7
6
  import json
8
7
  import shutil
9
8
  from siliconcompiler import utils, SiliconCompilerError
10
- from siliconcompiler.flowgraph import nodes_to_execute, _get_flowgraph_entry_nodes
11
9
  from siliconcompiler.package import get_cache_path
10
+ from siliconcompiler.flowgraph import RuntimeFlowgraph
12
11
 
13
12
  # Full list of Slurm states, split into 'active' and 'inactive' categories.
14
13
  # Many of these do not apply to a minimal configuration, but we'll track them all.
@@ -59,8 +58,15 @@ def init(chip):
59
58
 
60
59
  collect = False
61
60
  flow = chip.get('option', 'flow')
62
- entry_nodes = _get_flowgraph_entry_nodes(chip, flow)
63
- for (step, index) in nodes_to_execute(chip, flow):
61
+ entry_nodes = chip.schema.get("flowgraph", flow, field="schema").get_entry_nodes()
62
+
63
+ runtime = RuntimeFlowgraph(
64
+ chip.schema.get("flowgraph", flow, field='schema'),
65
+ from_steps=chip.get('option', 'from'),
66
+ to_steps=chip.get('option', 'to'),
67
+ prune_nodes=chip.get('option', 'prune'))
68
+
69
+ for (step, index) in runtime.get_nodes():
64
70
  if (step, index) in entry_nodes:
65
71
  collect = True
66
72
 
@@ -125,7 +131,7 @@ def _defernode(chip, step, index, replay):
125
131
  os.chmod(script_file,
126
132
  os.stat(script_file).st_mode | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH)
127
133
 
128
- schedule_cmd = ['sbatch',
134
+ schedule_cmd = ['srun',
129
135
  '--exclusive',
130
136
  '--partition', partition,
131
137
  '--chdir', chip.cwd,
@@ -149,45 +155,6 @@ def _defernode(chip, step, index, replay):
149
155
  # as it has closed its output stream. But if we don't call '.wait()',
150
156
  # the '.returncode' value will not be set correctly.
151
157
  step_result.wait()
152
- result_msg = step_result.stdout.read().decode()
153
- sbatch_id = result_msg.split(' ')[-1].strip()
154
- retcode = 0
155
-
156
- while True:
157
- # Return early with an error if the batch ID is not an integer.
158
- if not sbatch_id.isdigit():
159
- retcode = 1
160
- break
161
-
162
- # Rate-limit the status checks to once every few seconds.
163
- time.sleep(3.0)
164
-
165
- # Check whether the job is still running.
166
- jobcheck = subprocess.run(['scontrol', 'show', 'job', sbatch_id],
167
- stdout=subprocess.PIPE,
168
- stderr=subprocess.STDOUT)
169
- jobout = jobcheck.stdout.decode()
170
-
171
- # Jobs have a number of potential states that they can be in if they
172
- # are still active in the Slurm scheduler.
173
- if [state for state in SLURM_ACTIVE_STATES if state in jobout]:
174
- pass
175
- # 'COMPLETED' is a special case indicating successful job termination.
176
- elif 'COMPLETED' in jobout:
177
- break
178
- elif 'Invalid job id specified' in jobout:
179
- # May have already completed and been purged from active list.
180
- break
181
- # Jobs have a number of potential states that they can be in if they
182
- # did not terminate successfully.
183
- elif [state for state in SLURM_INACTIVE_STATES if state in jobout]:
184
- # FAILED, TIMEOUT, etc.
185
- retcode = 1
186
- break
187
-
188
- if retcode > 0:
189
- chip.logger.error(f'srun command for {step} failed.')
190
- chip.logger.error(f'srun output for {step}: {jobout}')
191
158
 
192
159
 
193
160
  def _get_slurm_partition():
@@ -0,0 +1,320 @@
1
+ import multiprocessing
2
+ import sys
3
+ import time
4
+
5
+ import os.path
6
+
7
+ from logging.handlers import QueueListener
8
+
9
+ from siliconcompiler import NodeStatus
10
+ from siliconcompiler import SiliconCompilerError
11
+ from siliconcompiler import utils
12
+ from siliconcompiler.flowgraph import RuntimeFlowgraph
13
+
14
+ from siliconcompiler.schema import JournalingSchema
15
+
16
+ from siliconcompiler.scheduler import slurm
17
+ from siliconcompiler.scheduler import docker_runner
18
+ from siliconcompiler.tools._common import get_tool_task
19
+ from siliconcompiler.utils.logging import SCBlankLoggerFormatter
20
+
21
+
22
+ class TaskScheduler:
23
+ __callbacks = {
24
+ "pre_run": lambda chip: None,
25
+ "pre_node": lambda chip, step, index: None,
26
+ "post_node": lambda chip, step, index: None,
27
+ "post_run": lambda chip: None,
28
+ }
29
+
30
+ @staticmethod
31
+ def register_callback(hook, func):
32
+ if hook not in TaskScheduler.__callbacks:
33
+ raise ValueError(f"{hook} is not a valid callback")
34
+ TaskScheduler.__callbacks[hook] = func
35
+
36
+ def __init__(self, chip):
37
+ self.__chip = chip
38
+ self.__logger = self.__chip.logger
39
+ self.__schema = self.__chip.schema
40
+ self.__flow = self.__schema.get("flowgraph", self.__chip.get('option', 'flow'),
41
+ field="schema")
42
+ self.__record = self.__schema.get("record", field="schema")
43
+ self.__dashboard = chip._dash
44
+
45
+ self.__max_cores = utils.get_cores(chip)
46
+ self.__max_threads = utils.get_cores(chip)
47
+ self.__max_parallel_run = self.__chip.get('option', 'scheduler', 'maxnodes')
48
+ if not self.__max_parallel_run:
49
+ self.__max_parallel_run = utils.get_cores(chip)
50
+ # clip max parallel jobs to 1 <= jobs <= max_cores
51
+ self.__max_parallel_run = max(1, min(self.__max_parallel_run, self.__max_cores))
52
+
53
+ self.__log_queue = multiprocessing.Queue(-1)
54
+
55
+ self.__nodes = {}
56
+ self.__startTimes = {}
57
+ self.__dwellTime = 0.1
58
+
59
+ self.__create_nodes()
60
+
61
+ def __create_nodes(self):
62
+ from siliconcompiler.scheduler import _executenode, _runtask
63
+
64
+ runtime = RuntimeFlowgraph(
65
+ self.__flow,
66
+ from_steps=set([step for step, _ in self.__flow.get_entry_nodes()]),
67
+ prune_nodes=self.__chip.get('option', 'prune'))
68
+
69
+ init_funcs = set()
70
+
71
+ runtime_flow = RuntimeFlowgraph(
72
+ self.__flow,
73
+ from_steps=self.__chip.get('option', 'from'),
74
+ to_steps=self.__chip.get('option', 'to'),
75
+ prune_nodes=self.__chip.get('option', 'prune'))
76
+
77
+ for step, index in runtime_flow.get_nodes():
78
+ if self.__record.get('status', step=step, index=index) != NodeStatus.PENDING:
79
+ continue
80
+
81
+ tool_name, task_name = get_tool_task(self.__chip, step, index)
82
+ threads = self.__chip.get('tool', tool_name, 'task', task_name, 'threads',
83
+ step=step, index=index)
84
+ if not threads:
85
+ threads = self.__max_threads
86
+ threads = max(1, min(threads, self.__max_threads))
87
+
88
+ task = {
89
+ "name": f"{step}{index}",
90
+ "inputs": runtime.get_node_inputs(step, index, record=self.__record),
91
+ "proc": None,
92
+ "child_pipe": None,
93
+ "parent_pipe": None,
94
+ "local": False,
95
+ "tool": tool_name,
96
+ "task": task_name,
97
+ "threads": threads,
98
+ "running": False,
99
+ "manifest": os.path.join(self.__chip.getworkdir(step=step, index=index),
100
+ 'outputs',
101
+ f'{self.__chip.design}.pkg.json')
102
+ }
103
+
104
+ exec_func = _executenode
105
+
106
+ node_scheduler = self.__chip.get('option', 'scheduler', 'name', step=step, index=index)
107
+ if node_scheduler == 'slurm':
108
+ # Defer job to compute node
109
+ # If the job is configured to run on a cluster, collect the schema
110
+ # and send it to a compute node for deferred execution.
111
+ init_funcs.add(slurm.init)
112
+ exec_func = slurm._defernode
113
+ elif node_scheduler == 'docker':
114
+ # Run job in docker
115
+ init_funcs.add(docker_runner.init)
116
+ exec_func = docker_runner.run
117
+ task["local"] = True
118
+ else:
119
+ task["local"] = True
120
+
121
+ task["parent_pipe"], task["child_pipe"] = multiprocessing.Pipe()
122
+ task["proc"] = multiprocessing.Process(
123
+ target=_runtask,
124
+ args=(self.__chip, self.__flow.name(), step, index, exec_func),
125
+ kwargs={"pipe": task["child_pipe"],
126
+ "queue": self.__log_queue})
127
+
128
+ self.__nodes[(step, index)] = task
129
+
130
+ # Call preprocessing for schedulers
131
+ for init_func in init_funcs:
132
+ init_func(self.__chip)
133
+
134
+ def run(self):
135
+ # Call this in case this was invoked without __main__
136
+ multiprocessing.freeze_support()
137
+
138
+ # Handle logs across threads
139
+ log_listener = QueueListener(self.__log_queue, self.__logger._console)
140
+ console_format = self.__logger._console.formatter
141
+ self.__logger._console.setFormatter(SCBlankLoggerFormatter())
142
+ log_listener.start()
143
+
144
+ # Update dashboard before run begins
145
+ if self.__dashboard:
146
+ self.__dashboard.update_manifest()
147
+
148
+ TaskScheduler.__callbacks["pre_run"](self.__chip)
149
+
150
+ try:
151
+ self.__run_loop()
152
+ except KeyboardInterrupt:
153
+ # exit immediately
154
+ log_listener.stop()
155
+ sys.exit(0)
156
+
157
+ TaskScheduler.__callbacks["post_run"](self.__chip)
158
+
159
+ # Cleanup logger
160
+ log_listener.stop()
161
+ self.__logger._console.setFormatter(console_format)
162
+
163
+ def __run_loop(self):
164
+ self.__startTimes = {None: time.time()}
165
+
166
+ while len(self.get_nodes_waiting_to_run()) > 0 or len(self.get_running_nodes()) > 0:
167
+ changed = self.__process_completed_nodes()
168
+ changed |= self.__lanuch_nodes()
169
+
170
+ if changed and self.__dashboard:
171
+ # Update dashboard if the manifest changed
172
+ self.__dashboard.update_manifest(payload={"starttimes": self.__startTimes})
173
+
174
+ running_nodes = self.get_running_nodes()
175
+
176
+ # Check for situation where we have stuff left to run but don't
177
+ # have any nodes running. This shouldn't happen, but we will get
178
+ # stuck in an infinite loop if it does, so we want to break out
179
+ # with an explicit error.
180
+ if len(self.get_nodes_waiting_to_run()) > 0 and len(running_nodes) == 0:
181
+ raise SiliconCompilerError(
182
+ 'Nodes left to run, but no running nodes. From/to may be invalid.',
183
+ chip=self.__chip)
184
+
185
+ if len(running_nodes) == 1:
186
+ # if there is only one node running, just join the thread
187
+ self.__nodes[running_nodes[0]]["proc"].join()
188
+ elif len(running_nodes) > 1:
189
+ # if there are more than 1, join the first with a timeout
190
+ self.__nodes[running_nodes[0]]["proc"].join(timeout=self.__dwellTime)
191
+
192
+ def get_nodes(self):
193
+ return sorted(self.__nodes.keys())
194
+
195
+ def get_running_nodes(self):
196
+ nodes = []
197
+ for node, info in self.__nodes.items():
198
+ if info["running"]:
199
+ nodes.append(node)
200
+ return sorted(nodes)
201
+
202
+ def get_nodes_waiting_to_run(self):
203
+ nodes = []
204
+ for node, info in self.__nodes.items():
205
+ if not info["running"] and info["proc"]:
206
+ nodes.append(node)
207
+ return sorted(nodes)
208
+
209
+ def __process_completed_nodes(self):
210
+ changed = False
211
+ for node in self.get_running_nodes():
212
+ info = self.__nodes[node]
213
+
214
+ if not info["proc"].is_alive():
215
+ manifest = info["manifest"]
216
+
217
+ self.__logger.debug(f'{info["name"]} is complete merging: {manifest}')
218
+
219
+ if os.path.exists(manifest):
220
+ JournalingSchema(self.__schema).read_journal(manifest)
221
+
222
+ if info["parent_pipe"] and info["parent_pipe"].poll(1):
223
+ try:
224
+ packages = info["parent_pipe"].recv()
225
+ if isinstance(packages, dict):
226
+ self.__chip._packages.update(packages)
227
+ except: # noqa E722
228
+ pass
229
+
230
+ step, index = node
231
+ if info["proc"].exitcode > 0:
232
+ status = NodeStatus.ERROR
233
+ else:
234
+ status = self.__record.get('status', step=step, index=index)
235
+ if not status or status == NodeStatus.PENDING:
236
+ status = NodeStatus.ERROR
237
+
238
+ self.__record.set('status', status, step=step, index=index)
239
+
240
+ info["running"] = False
241
+ info["proc"] = None
242
+
243
+ changed = True
244
+
245
+ TaskScheduler.__callbacks['post_node'](self.__chip, step, index)
246
+
247
+ return changed
248
+
249
+ def __allow_start(self, node):
250
+ info = self.__nodes[node]
251
+
252
+ if not info["local"]:
253
+ # using a different scheduler, so allow
254
+ return True
255
+
256
+ running_nodes = self.get_running_nodes()
257
+
258
+ if len(running_nodes) >= self.__max_parallel_run:
259
+ # exceeding machine resources
260
+ return False
261
+
262
+ current_threads = sum([self.__nodes[run_node]["threads"] for run_node in running_nodes])
263
+
264
+ if info["threads"] + current_threads > self.__max_cores:
265
+ # delay until there are enough core available
266
+ return False
267
+
268
+ # allow
269
+ return True
270
+
271
+ def __lanuch_nodes(self):
272
+ changed = False
273
+ for node in self.get_nodes_waiting_to_run():
274
+ # TODO: breakpoint logic:
275
+ # if node is breakpoint, then don't launch while len(running_nodes) > 0
276
+
277
+ info = self.__nodes[node]
278
+ step, index = node
279
+
280
+ ready = True
281
+ inputs = []
282
+ for in_step, in_index in info["inputs"]:
283
+ in_status = self.__record.get('status', step=in_step, index=in_index)
284
+ inputs.append(in_status)
285
+
286
+ if not NodeStatus.is_done(in_status):
287
+ ready = False
288
+ break
289
+ if NodeStatus.is_error(in_status) and info["tool"] != "builtin":
290
+ # Fail if any dependency failed for non-builtin task
291
+ self.__record.set("status", NodeStatus.ERROR, step=step, index=index)
292
+
293
+ # Fail if no dependency successfully finished for builtin task
294
+ if inputs:
295
+ any_success = any([status == NodeStatus.SUCCESS for status in inputs])
296
+ else:
297
+ any_success = True
298
+ if ready and info["tool"] == "builtin" and not any_success:
299
+ self.__record.set("status", NodeStatus.ERROR, step=step, index=index)
300
+
301
+ if self.__record.get('status', step=step, index=index) == NodeStatus.ERROR:
302
+ info["proc"] = None
303
+ continue
304
+
305
+ # If there are no dependencies left, launch this node and
306
+ # remove from nodes_to_run.
307
+ if ready and self.__allow_start(node):
308
+ self.__logger.debug(f'Launching {info["name"]}')
309
+
310
+ TaskScheduler.__callbacks['pre_node'](self.__chip, step, index)
311
+
312
+ self.__record.set('status', NodeStatus.RUNNING, step=step, index=index)
313
+ self.__startTimes[node] = time.time()
314
+ changed = True
315
+
316
+ # Start the process
317
+ info["running"] = True
318
+ info["proc"].start()
319
+
320
+ return changed
@@ -1,7 +1,24 @@
1
+ from .parameter import Parameter, Scope, PerNode
2
+ from .safeschema import SafeSchema
3
+ from .editableschema import EditableSchema
4
+ from .baseschema import BaseSchema
5
+ from .cmdlineschema import CommandLineSchema
6
+ from .journalingschema import JournalingSchema
7
+ from .namedschema import NamedSchema
8
+ from .packageschema import PackageSchema
9
+
1
10
  from .schema_cfg import SCHEMA_VERSION
2
- from .schema_obj import Schema
3
11
 
4
12
  __all__ = [
5
13
  "SCHEMA_VERSION",
6
- "Schema"
14
+ "BaseSchema",
15
+ "SafeSchema",
16
+ "EditableSchema",
17
+ "CommandLineSchema",
18
+ "JournalingSchema",
19
+ "NamedSchema",
20
+ "PackageSchema",
21
+ "Parameter",
22
+ "Scope",
23
+ "PerNode"
7
24
  ]