siliconcompiler 0.33.0__py3-none-any.whl → 0.33.2__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 (177) hide show
  1. siliconcompiler/_common.py +5 -0
  2. siliconcompiler/_metadata.py +1 -1
  3. siliconcompiler/apps/sc_install.py +7 -0
  4. siliconcompiler/apps/sc_remote.py +7 -2
  5. siliconcompiler/apps/utils/replay.py +5 -5
  6. siliconcompiler/core.py +38 -12
  7. siliconcompiler/data/templates/replay/replay.sh.j2 +18 -1
  8. siliconcompiler/metric.py +78 -0
  9. siliconcompiler/package/git.py +1 -1
  10. siliconcompiler/record.py +63 -7
  11. siliconcompiler/remote/client.py +57 -14
  12. siliconcompiler/remote/server.py +110 -60
  13. siliconcompiler/report/dashboard/cli/__init__.py +2 -0
  14. siliconcompiler/report/dashboard/cli/board.py +34 -31
  15. siliconcompiler/report/report.py +10 -5
  16. siliconcompiler/report/utils.py +12 -6
  17. siliconcompiler/scheduler/__init__.py +146 -976
  18. siliconcompiler/scheduler/run_node.py +12 -5
  19. siliconcompiler/scheduler/send_messages.py +9 -3
  20. siliconcompiler/scheduler/slurm.py +10 -43
  21. siliconcompiler/scheduler/taskscheduler.py +320 -0
  22. siliconcompiler/schema/baseschema.py +25 -4
  23. siliconcompiler/schema/journalingschema.py +4 -0
  24. siliconcompiler/schema/schema_cfg.py +3 -3
  25. siliconcompiler/tool.py +201 -32
  26. siliconcompiler/tools/_common/__init__.py +14 -11
  27. siliconcompiler/tools/_common/asic.py +5 -5
  28. siliconcompiler/tools/bluespec/convert.py +2 -1
  29. siliconcompiler/tools/builtin/_common.py +9 -2
  30. siliconcompiler/tools/builtin/concatenate.py +6 -2
  31. siliconcompiler/tools/builtin/minimum.py +7 -2
  32. siliconcompiler/tools/builtin/mux.py +7 -2
  33. siliconcompiler/tools/builtin/nop.py +7 -2
  34. siliconcompiler/tools/builtin/verify.py +7 -3
  35. siliconcompiler/tools/chisel/convert.py +10 -10
  36. siliconcompiler/tools/klayout/drc.py +2 -2
  37. siliconcompiler/tools/klayout/klayout_show.py +6 -6
  38. siliconcompiler/tools/klayout/klayout_utils.py +12 -12
  39. siliconcompiler/tools/netgen/count_lvs.py +2 -2
  40. siliconcompiler/tools/netgen/lvs.py +1 -1
  41. siliconcompiler/tools/openroad/_apr.py +2 -2
  42. siliconcompiler/tools/openroad/scripts/apr/sc_init_floorplan.tcl +1 -7
  43. siliconcompiler/tools/openroad/scripts/common/procs.tcl +18 -0
  44. siliconcompiler/tools/openroad/scripts/common/read_input_files.tcl +1 -7
  45. siliconcompiler/tools/opensta/scripts/sc_timing.tcl +10 -0
  46. siliconcompiler/tools/opensta/timing.py +11 -0
  47. siliconcompiler/tools/slang/__init__.py +6 -5
  48. siliconcompiler/tools/slang/elaborate.py +6 -6
  49. siliconcompiler/tools/slang/lint.py +1 -3
  50. siliconcompiler/tools/vpr/_xml_constraint.py +8 -8
  51. siliconcompiler/tools/yosys/prepareLib.py +2 -2
  52. siliconcompiler/tools/yosys/sc_synth_asic.tcl +43 -5
  53. siliconcompiler/tools/yosys/screenshot.py +1 -1
  54. siliconcompiler/tools/yosys/syn_asic.py +5 -5
  55. siliconcompiler/toolscripts/_tools.json +17 -10
  56. siliconcompiler/toolscripts/rhel8/install-chisel.sh +9 -2
  57. siliconcompiler/toolscripts/rhel8/install-icarus.sh +10 -3
  58. siliconcompiler/toolscripts/rhel8/install-klayout.sh +8 -1
  59. siliconcompiler/toolscripts/rhel8/install-magic.sh +9 -2
  60. siliconcompiler/toolscripts/rhel8/install-montage.sh +1 -1
  61. siliconcompiler/toolscripts/rhel8/install-netgen.sh +9 -2
  62. siliconcompiler/toolscripts/rhel8/install-slang.sh +11 -4
  63. siliconcompiler/toolscripts/rhel8/install-surelog.sh +9 -2
  64. siliconcompiler/toolscripts/rhel8/install-sv2v.sh +11 -4
  65. siliconcompiler/toolscripts/rhel8/install-verible.sh +11 -3
  66. siliconcompiler/toolscripts/rhel8/install-verilator.sh +10 -3
  67. siliconcompiler/toolscripts/rhel8/install-xyce.sh +15 -10
  68. siliconcompiler/toolscripts/rhel9/install-chisel.sh +9 -2
  69. siliconcompiler/toolscripts/rhel9/install-ghdl.sh +9 -2
  70. siliconcompiler/toolscripts/rhel9/install-gtkwave.sh +10 -3
  71. siliconcompiler/toolscripts/rhel9/install-icarus.sh +10 -3
  72. siliconcompiler/toolscripts/rhel9/install-klayout.sh +8 -1
  73. siliconcompiler/toolscripts/rhel9/install-magic.sh +9 -2
  74. siliconcompiler/toolscripts/rhel9/install-montage.sh +1 -1
  75. siliconcompiler/toolscripts/rhel9/install-netgen.sh +9 -2
  76. siliconcompiler/toolscripts/rhel9/install-openroad.sh +16 -3
  77. siliconcompiler/toolscripts/rhel9/install-opensta.sh +17 -5
  78. siliconcompiler/toolscripts/rhel9/install-slang.sh +11 -4
  79. siliconcompiler/toolscripts/rhel9/install-surelog.sh +9 -2
  80. siliconcompiler/toolscripts/rhel9/install-sv2v.sh +11 -4
  81. siliconcompiler/toolscripts/rhel9/install-verible.sh +11 -3
  82. siliconcompiler/toolscripts/rhel9/install-verilator.sh +10 -3
  83. siliconcompiler/toolscripts/rhel9/install-vpr.sh +9 -2
  84. siliconcompiler/toolscripts/rhel9/install-xdm.sh +10 -2
  85. siliconcompiler/toolscripts/rhel9/install-xyce.sh +15 -10
  86. siliconcompiler/toolscripts/rhel9/install-yosys-moosic.sh +9 -2
  87. siliconcompiler/toolscripts/rhel9/install-yosys-parmys.sh +10 -3
  88. siliconcompiler/toolscripts/rhel9/install-yosys-slang.sh +10 -2
  89. siliconcompiler/toolscripts/rhel9/install-yosys.sh +9 -2
  90. siliconcompiler/toolscripts/ubuntu20/install-bambu.sh +10 -2
  91. siliconcompiler/toolscripts/ubuntu20/install-bluespec.sh +10 -3
  92. siliconcompiler/toolscripts/ubuntu20/install-chisel.sh +9 -2
  93. siliconcompiler/toolscripts/ubuntu20/install-ghdl.sh +9 -2
  94. siliconcompiler/toolscripts/ubuntu20/install-gtkwave.sh +9 -2
  95. siliconcompiler/toolscripts/ubuntu20/install-icarus.sh +9 -2
  96. siliconcompiler/toolscripts/ubuntu20/install-icepack.sh +9 -2
  97. siliconcompiler/toolscripts/ubuntu20/install-klayout.sh +8 -1
  98. siliconcompiler/toolscripts/ubuntu20/install-magic.sh +9 -2
  99. siliconcompiler/toolscripts/ubuntu20/install-montage.sh +1 -1
  100. siliconcompiler/toolscripts/ubuntu20/install-netgen.sh +9 -2
  101. siliconcompiler/toolscripts/ubuntu20/install-nextpnr.sh +9 -2
  102. siliconcompiler/toolscripts/ubuntu20/install-openroad.sh +16 -3
  103. siliconcompiler/toolscripts/ubuntu20/install-opensta.sh +16 -5
  104. siliconcompiler/toolscripts/ubuntu20/install-slang.sh +11 -4
  105. siliconcompiler/toolscripts/ubuntu20/install-slurm.sh +9 -2
  106. siliconcompiler/toolscripts/ubuntu20/install-surelog.sh +10 -2
  107. siliconcompiler/toolscripts/ubuntu20/install-sv2v.sh +11 -4
  108. siliconcompiler/toolscripts/ubuntu20/install-verible.sh +11 -3
  109. siliconcompiler/toolscripts/ubuntu20/install-verilator.sh +9 -2
  110. siliconcompiler/toolscripts/ubuntu20/install-xdm.sh +10 -2
  111. siliconcompiler/toolscripts/ubuntu20/install-xyce.sh +13 -8
  112. siliconcompiler/toolscripts/ubuntu20/install-yosys-moosic.sh +9 -2
  113. siliconcompiler/toolscripts/ubuntu20/install-yosys.sh +9 -2
  114. siliconcompiler/toolscripts/ubuntu22/install-bambu.sh +10 -2
  115. siliconcompiler/toolscripts/ubuntu22/install-bluespec.sh +10 -3
  116. siliconcompiler/toolscripts/ubuntu22/install-chisel.sh +9 -2
  117. siliconcompiler/toolscripts/ubuntu22/install-ghdl.sh +9 -2
  118. siliconcompiler/toolscripts/ubuntu22/install-gtkwave.sh +9 -2
  119. siliconcompiler/toolscripts/ubuntu22/install-icarus.sh +9 -2
  120. siliconcompiler/toolscripts/ubuntu22/install-icepack.sh +9 -2
  121. siliconcompiler/toolscripts/ubuntu22/install-klayout.sh +12 -1
  122. siliconcompiler/toolscripts/ubuntu22/install-magic.sh +9 -2
  123. siliconcompiler/toolscripts/ubuntu22/install-montage.sh +1 -1
  124. siliconcompiler/toolscripts/ubuntu22/install-netgen.sh +9 -2
  125. siliconcompiler/toolscripts/ubuntu22/install-nextpnr.sh +9 -2
  126. siliconcompiler/toolscripts/ubuntu22/install-openroad.sh +16 -3
  127. siliconcompiler/toolscripts/ubuntu22/install-opensta.sh +17 -5
  128. siliconcompiler/toolscripts/ubuntu22/install-slang.sh +11 -4
  129. siliconcompiler/toolscripts/ubuntu22/install-slurm.sh +9 -2
  130. siliconcompiler/toolscripts/ubuntu22/install-surelog.sh +10 -2
  131. siliconcompiler/toolscripts/ubuntu22/install-sv2v.sh +11 -4
  132. siliconcompiler/toolscripts/ubuntu22/install-verible.sh +11 -3
  133. siliconcompiler/toolscripts/ubuntu22/install-verilator.sh +9 -2
  134. siliconcompiler/toolscripts/ubuntu22/install-vpr.sh +9 -2
  135. siliconcompiler/toolscripts/ubuntu22/install-xdm.sh +10 -2
  136. siliconcompiler/toolscripts/ubuntu22/install-xyce.sh +13 -8
  137. siliconcompiler/toolscripts/ubuntu22/install-yosys-moosic.sh +9 -2
  138. siliconcompiler/toolscripts/ubuntu22/install-yosys-parmys.sh +10 -3
  139. siliconcompiler/toolscripts/ubuntu22/install-yosys-slang.sh +10 -2
  140. siliconcompiler/toolscripts/ubuntu22/install-yosys.sh +9 -2
  141. siliconcompiler/toolscripts/ubuntu24/install-bambu.sh +12 -4
  142. siliconcompiler/toolscripts/ubuntu24/install-bluespec.sh +10 -3
  143. siliconcompiler/toolscripts/ubuntu24/install-chisel.sh +9 -2
  144. siliconcompiler/toolscripts/ubuntu24/install-ghdl.sh +9 -2
  145. siliconcompiler/toolscripts/ubuntu24/install-gtkwave.sh +9 -2
  146. siliconcompiler/toolscripts/ubuntu24/install-icarus.sh +9 -2
  147. siliconcompiler/toolscripts/ubuntu24/install-icepack.sh +9 -2
  148. siliconcompiler/toolscripts/ubuntu24/install-klayout.sh +12 -1
  149. siliconcompiler/toolscripts/ubuntu24/install-magic.sh +9 -2
  150. siliconcompiler/toolscripts/ubuntu24/install-montage.sh +1 -1
  151. siliconcompiler/toolscripts/ubuntu24/install-netgen.sh +9 -2
  152. siliconcompiler/toolscripts/ubuntu24/install-nextpnr.sh +9 -2
  153. siliconcompiler/toolscripts/ubuntu24/install-openroad.sh +16 -3
  154. siliconcompiler/toolscripts/ubuntu24/install-opensta.sh +17 -5
  155. siliconcompiler/toolscripts/ubuntu24/install-slang.sh +11 -4
  156. siliconcompiler/toolscripts/ubuntu24/install-slurm.sh +9 -2
  157. siliconcompiler/toolscripts/ubuntu24/install-surelog.sh +10 -2
  158. siliconcompiler/toolscripts/ubuntu24/install-sv2v.sh +11 -4
  159. siliconcompiler/toolscripts/ubuntu24/install-verible.sh +11 -3
  160. siliconcompiler/toolscripts/ubuntu24/install-verilator.sh +9 -2
  161. siliconcompiler/toolscripts/ubuntu24/install-vpr.sh +9 -2
  162. siliconcompiler/toolscripts/ubuntu24/install-xdm.sh +10 -2
  163. siliconcompiler/toolscripts/ubuntu24/install-xyce.sh +13 -8
  164. siliconcompiler/toolscripts/ubuntu24/install-yosys-moosic.sh +9 -2
  165. siliconcompiler/toolscripts/ubuntu24/install-yosys-parmys.sh +10 -3
  166. siliconcompiler/toolscripts/ubuntu24/install-yosys-slang.sh +10 -2
  167. siliconcompiler/toolscripts/ubuntu24/install-yosys.sh +9 -2
  168. siliconcompiler/utils/__init__.py +11 -0
  169. siliconcompiler/utils/flowgraph.py +6 -101
  170. siliconcompiler/utils/issue.py +15 -23
  171. siliconcompiler/utils/logging.py +2 -2
  172. {siliconcompiler-0.33.0.dist-info → siliconcompiler-0.33.2.dist-info}/METADATA +6 -5
  173. {siliconcompiler-0.33.0.dist-info → siliconcompiler-0.33.2.dist-info}/RECORD +177 -176
  174. {siliconcompiler-0.33.0.dist-info → siliconcompiler-0.33.2.dist-info}/WHEEL +1 -1
  175. {siliconcompiler-0.33.0.dist-info → siliconcompiler-0.33.2.dist-info}/entry_points.txt +0 -0
  176. {siliconcompiler-0.33.0.dist-info → siliconcompiler-0.33.2.dist-info}/licenses/LICENSE +0 -0
  177. {siliconcompiler-0.33.0.dist-info → siliconcompiler-0.33.2.dist-info}/top_level.txt +0 -0
@@ -1,6 +1,7 @@
1
1
  # Copyright 2020 Silicon Compiler Authors. All Rights Reserved.
2
2
 
3
3
  from aiohttp import web
4
+ import copy
4
5
  import threading
5
6
  import json
6
7
  import logging as log
@@ -12,7 +13,8 @@ import sys
12
13
  import fastjsonschema
13
14
  from pathlib import Path
14
15
  from fastjsonschema import JsonSchemaException
15
- import io
16
+
17
+ import os.path
16
18
 
17
19
  from siliconcompiler import Chip, Schema
18
20
  from siliconcompiler.schema import utils as schema_utils
@@ -20,8 +22,10 @@ from siliconcompiler._metadata import version as sc_version
20
22
  from siliconcompiler.schema import SCHEMA_VERSION as sc_schema_version
21
23
  from siliconcompiler.remote.schema import ServerSchema
22
24
  from siliconcompiler.remote import banner, JobStatus
23
- from siliconcompiler.scheduler.slurm import get_configuration_directory
24
- from siliconcompiler.utils.flowgraph import nodes_to_execute
25
+ from siliconcompiler import NodeStatus as SCNodeStatus
26
+ from siliconcompiler.remote import NodeStatus
27
+ from siliconcompiler.flowgraph import RuntimeFlowgraph
28
+ from siliconcompiler.scheduler.taskscheduler import TaskScheduler
25
29
 
26
30
 
27
31
  # Compile validation code for API request bodies.
@@ -81,7 +85,61 @@ class Server:
81
85
  self.schema = ServerSchema()
82
86
 
83
87
  # Set up a dictionary to track running jobs.
88
+ self.sc_jobs_lock = threading.Lock()
84
89
  self.sc_jobs = {}
90
+ self.sc_chip_lookup = {}
91
+
92
+ # Register callbacks
93
+ TaskScheduler.register_callback("pre_run", self.__run_start)
94
+ TaskScheduler.register_callback("pre_node", self.__node_start)
95
+ TaskScheduler.register_callback("post_node", self.__node_end)
96
+
97
+ def __run_start(self, chip):
98
+ flow = chip.get("option", "flow")
99
+ nodes = chip.schema.get("flowgraph", flow, field="schema").get_nodes()
100
+
101
+ with self.sc_jobs_lock:
102
+ job_hash = self.sc_chip_lookup[chip]["jobhash"]
103
+
104
+ start_tar = os.path.join(self.nfs_mount, job_hash, f'{job_hash}_None.tar.gz')
105
+ start_status = NodeStatus.SUCCESS
106
+ with tarfile.open(start_tar, "w:gz") as tf:
107
+ start_manifest = os.path.join(chip.getworkdir(), f"{chip.design}.pkg.json")
108
+ tf.add(start_manifest, arcname=os.path.relpath(start_manifest, self.nfs_mount))
109
+
110
+ with self.sc_jobs_lock:
111
+ job_name = self.sc_chip_lookup[chip]["name"]
112
+
113
+ self.sc_jobs[job_name][None]["status"] = start_status
114
+
115
+ for step, index in nodes:
116
+ name = f"{step}{index}"
117
+ if name not in self.sc_jobs[job_name]:
118
+ continue
119
+ self.sc_jobs[job_name][name]["status"] = \
120
+ chip.get('record', 'status', step=step, index=index)
121
+
122
+ def __node_start(self, chip, step, index):
123
+ with self.sc_jobs_lock:
124
+ job_name = self.sc_chip_lookup[chip]["name"]
125
+ self.sc_jobs[job_name][f"{step}{index}"]["status"] = NodeStatus.RUNNING
126
+
127
+ def __node_end(self, chip, step, index):
128
+ with self.sc_jobs_lock:
129
+ job_hash = self.sc_chip_lookup[chip]["jobhash"]
130
+ job_name = self.sc_chip_lookup[chip]["name"]
131
+
132
+ chip = copy.deepcopy(chip)
133
+ chip.cwd = os.path.join(chip.get('option', 'builddir'), '..')
134
+ with tarfile.open(os.path.join(self.nfs_mount,
135
+ job_hash,
136
+ f'{job_hash}_{step}{index}.tar.gz'),
137
+ mode='w:gz') as tf:
138
+ chip._archive_node(tf, step=step, index=index, include="*")
139
+
140
+ with self.sc_jobs_lock:
141
+ self.sc_jobs[job_name][f"{step}{index}"]["status"] = \
142
+ chip.get('record', 'status', step=step, index=index)
85
143
 
86
144
  def run(self):
87
145
  if not os.path.exists(self.nfs_mount):
@@ -226,9 +284,6 @@ class Server:
226
284
  # Remove 'remote' JSON config value to run locally on compute node.
227
285
  chip.set('option', 'remote', False)
228
286
 
229
- # Write JSON config to shared compute storage.
230
- os.makedirs(os.path.join(job_root, 'configs'), exist_ok=True)
231
-
232
287
  # Run the job with the configured clustering option. (Non-blocking)
233
288
  job_proc = threading.Thread(target=self.remote_sc,
234
289
  args=[
@@ -258,31 +313,13 @@ class Server:
258
313
  job_hash = job_params['job_hash']
259
314
  node = job_params['node'] if 'node' in job_params else None
260
315
 
261
- resp = web.StreamResponse(
262
- status=200,
263
- reason='OK',
264
- headers={
265
- 'Content-Type': 'application/x-tar',
266
- 'Content-Disposition': f'attachment; filename="{job_hash}_{node}.tar.gz"'
267
- },
268
- )
269
- await resp.prepare(request)
270
-
271
316
  zipfn = os.path.join(self.nfs_mount, job_hash, f'{job_hash}_{node}.tar.gz')
272
- if not node:
273
- with tarfile.open(zipfn, 'w:gz') as tar:
274
- text = "Done"
275
- metadata_file = io.BytesIO(text.encode('ascii'))
276
- tarinfo = tarfile.TarInfo(f'{job_hash}/done')
277
- tarinfo.size = metadata_file.getbuffer().nbytes
278
- tar.addfile(tarinfo=tarinfo, fileobj=metadata_file)
279
-
280
- with open(zipfn, 'rb') as zipf:
281
- await resp.write(zipf.read())
317
+ if not os.path.exists(zipfn):
318
+ return web.json_response(
319
+ {'message': 'Could not find results for the requested job/node.'},
320
+ status=404)
282
321
 
283
- await resp.write_eof()
284
-
285
- return resp
322
+ return web.FileResponse(zipfn)
286
323
 
287
324
  ####################
288
325
  async def handle_delete_job(self, request):
@@ -300,9 +337,10 @@ class Server:
300
337
  job_hash = job_params['job_hash']
301
338
 
302
339
  # Determine if the job is running.
303
- for job in self.sc_jobs:
304
- if job_hash in job:
305
- return self.__response("Error: job is still running.", status=400)
340
+ with self.sc_jobs_lock:
341
+ for job in self.sc_jobs:
342
+ if job_hash in job:
343
+ return self.__response("Error: job is still running.", status=400)
306
344
 
307
345
  # Delete job hash directory, only if it exists.
308
346
  # TODO: This assumes no malicious input.
@@ -342,16 +380,17 @@ class Server:
342
380
 
343
381
  # Determine if the job is running.
344
382
  # TODO: Return information about individual flowgraph nodes.
345
- if jobname in self.sc_jobs:
346
- resp = {
347
- 'status': JobStatus.RUNNING,
348
- 'message': 'Job is currently running on the server.',
349
- }
350
- else:
351
- resp = {
352
- 'status': JobStatus.COMPLETED,
353
- 'message': 'Job has no running steps.',
354
- }
383
+ with self.sc_jobs_lock:
384
+ if jobname in self.sc_jobs:
385
+ resp = {
386
+ 'status': JobStatus.RUNNING,
387
+ 'message': self.sc_jobs[jobname],
388
+ }
389
+ else:
390
+ resp = {
391
+ 'status': JobStatus.COMPLETED,
392
+ 'message': 'Job has no running steps.',
393
+ }
355
394
  return web.json_response(resp)
356
395
 
357
396
  ####################
@@ -402,18 +441,39 @@ class Server:
402
441
  # Assemble core job parameters.
403
442
  job_hash = chip.get('record', 'remoteid')
404
443
 
444
+ runtime = RuntimeFlowgraph(
445
+ chip.schema.get("flowgraph", chip.get('option', 'flow'), field='schema'),
446
+ from_steps=chip.get('option', 'from'),
447
+ to_steps=chip.get('option', 'to'),
448
+ prune_nodes=chip.get('option', 'prune'))
449
+
450
+ nodes = {}
451
+ nodes[None] = {
452
+ "status": SCNodeStatus.PENDING
453
+ }
454
+ for step, index in runtime.get_nodes():
455
+ status = chip.get('record', 'status', step=step, index=index)
456
+ if not status:
457
+ status = SCNodeStatus.PENDING
458
+ if SCNodeStatus.is_done(status):
459
+ status = NodeStatus.UPLOADED
460
+ nodes[f"{step}{index}"] = {
461
+ "status": status
462
+ }
463
+
405
464
  # Mark the job run as busy.
406
465
  sc_job_name = self.job_name(username, job_hash)
407
- self.sc_jobs[sc_job_name] = 'busy'
466
+ with self.sc_jobs_lock:
467
+ self.sc_chip_lookup[chip] = {
468
+ "name": sc_job_name,
469
+ "jobhash": job_hash
470
+ }
471
+ self.sc_jobs[sc_job_name] = nodes
408
472
 
409
473
  build_dir = os.path.join(self.nfs_mount, job_hash)
410
474
  chip.set('option', 'builddir', build_dir)
411
475
  chip.set('option', 'remote', False)
412
476
 
413
- job_cfg_dir = get_configuration_directory(chip)
414
- os.makedirs(job_cfg_dir, exist_ok=True)
415
- chip.write_manifest(f"{job_cfg_dir}/chip{chip.get('option', 'jobname')}.json")
416
-
417
477
  if self.get('option', 'cluster') == 'slurm':
418
478
  # Run the job with slurm clustering.
419
479
  chip.set('option', 'scheduler', 'name', 'slurm')
@@ -421,20 +481,10 @@ class Server:
421
481
  # Run the job.
422
482
  chip.run()
423
483
 
424
- # Archive each task.
425
- for (step, index) in nodes_to_execute(chip):
426
- chip.cwd = os.path.join(chip.get('option', 'builddir'), '..')
427
- tf = tarfile.open(os.path.join(self.nfs_mount,
428
- job_hash,
429
- f'{job_hash}_{step}{index}.tar.gz'),
430
- mode='w:gz')
431
- chip._archive_node(tf, step=step, index=index)
432
- tf.close()
433
-
434
- # (Email notifications can be sent here using your preferred API)
435
-
436
484
  # Mark the job hash as being done.
437
- self.sc_jobs.pop(sc_job_name)
485
+ with self.sc_jobs_lock:
486
+ self.sc_jobs.pop(sc_job_name)
487
+ self.sc_chip_lookup.pop(chip)
438
488
 
439
489
  ####################
440
490
  def __auth_password(self, username, password):
@@ -66,6 +66,8 @@ class CliDashboard(AbstractDashboard):
66
66
  """
67
67
  self._dashboard.end_of_run(self._chip)
68
68
 
69
+ self._dashboard.stop()
70
+
69
71
  # Restore logger
70
72
  if self.__logger_console:
71
73
  self._logger.removeHandler(self._dashboard._log_handler)
@@ -22,6 +22,8 @@ from siliconcompiler import SiliconCompilerError, NodeStatus
22
22
  from siliconcompiler.utils.logging import SCColorLoggerFormatter
23
23
  from siliconcompiler.flowgraph import RuntimeFlowgraph
24
24
 
25
+ import atexit
26
+
25
27
 
26
28
  class LogBufferHandler(logging.Handler):
27
29
  def __init__(self, sync_queue, n=50, event=None):
@@ -246,6 +248,15 @@ class Board(metaclass=BoardSingleton):
246
248
 
247
249
  def _init_singleton(self):
248
250
  self._console = Console(theme=Board.__theme)
251
+
252
+ self.live = Live(
253
+ console=self._console,
254
+ screen=False,
255
+ auto_refresh=True,
256
+ )
257
+
258
+ atexit.register(self._stop_on_exit)
259
+
249
260
  self._active = self._console.is_terminal
250
261
  if not self._active:
251
262
  self._console = None
@@ -279,6 +290,9 @@ class Board(metaclass=BoardSingleton):
279
290
 
280
291
  self._metrics = ("warnings", "errors")
281
292
 
293
+ def _stop_on_exit(self):
294
+ self.stop()
295
+
282
296
  def open_dashboard(self):
283
297
  """Starts the dashboard rendering thread if it is not already running."""
284
298
 
@@ -289,7 +303,7 @@ class Board(metaclass=BoardSingleton):
289
303
  self._update_render_data(None)
290
304
 
291
305
  with self._job_data_lock:
292
- if not self._render_thread:
306
+ if not self._render_thread or not self._render_thread.is_alive():
293
307
  self._render_thread = threading.Thread(target=self._render, daemon=True)
294
308
  self._render_event.clear()
295
309
  self._render_stop_event.clear()
@@ -328,7 +342,6 @@ class Board(metaclass=BoardSingleton):
328
342
  return
329
343
 
330
344
  self._update_render_data(chip, complete=True)
331
- self.stop()
332
345
 
333
346
  def stop(self):
334
347
  """
@@ -337,18 +350,20 @@ class Board(metaclass=BoardSingleton):
337
350
  if not self.is_running():
338
351
  return
339
352
 
340
- # check for running jobs
341
- with self._job_data_lock:
342
- if self._job_data:
343
- if any([not job.complete for job in self._job_data.values()]):
344
- return
353
+ if self._job_data:
354
+ if any([not job.complete for job in self._job_data.values()]):
355
+ return
345
356
 
346
- self._render_stop_event.set()
347
- self._render_event.set()
357
+ self._render_stop_event.set()
358
+ self._render_event.set()
348
359
 
349
360
  # Wait for rendering to finish
350
361
  self.wait()
351
362
 
363
+ # Restore terminal
364
+ self.live.stop()
365
+ self._console.show_cursor()
366
+
352
367
  def wait(self):
353
368
  """Waits for the dashboard rendering thread to finish."""
354
369
  if not self.is_running():
@@ -595,18 +610,11 @@ class Board(metaclass=BoardSingleton):
595
610
  # Catch any multiprocessing errors
596
611
  return True
597
612
 
598
- live = None
599
613
  try:
600
614
  update_data()
601
- live = Live(
602
- self._get_rendable(),
603
- console=self._console,
604
- screen=False,
605
- # transient=True,
606
- auto_refresh=True,
607
- # refresh_per_second=60,
608
- )
609
- live.start()
615
+
616
+ if not self.live.is_started:
617
+ self.live.start(refresh=True)
610
618
 
611
619
  while not check_stop_event():
612
620
  try:
@@ -620,18 +628,14 @@ class Board(metaclass=BoardSingleton):
620
628
  break
621
629
 
622
630
  update_data()
623
- live.update(self._get_rendable(), refresh=True)
631
+ self.live.update(self._get_rendable(), refresh=True)
632
+
624
633
  finally:
625
- try:
626
- update_data()
627
- if live:
628
- live.update(self._get_rendable(), refresh=True)
629
- live.stop()
630
- else:
631
- self._console.print(self._get_rendable())
632
- finally:
633
- # Restore the prompt
634
- print("\033[?25h", end="")
634
+ update_data()
635
+ if self.live:
636
+ self.live.update(self._get_rendable(), refresh=True)
637
+ else:
638
+ self._console.print(self._get_rendable())
635
639
 
636
640
  def _update_layout(self):
637
641
  with self._render_data_lock:
@@ -747,7 +751,6 @@ class Board(metaclass=BoardSingleton):
747
751
 
748
752
  runtime_flow = RuntimeFlowgraph(
749
753
  chip.schema.get("flowgraph", flow, field='schema'),
750
- args=(chip.get('arg', 'step'), chip.get('arg', 'index')),
751
754
  to_steps=chip.get('option', 'to'),
752
755
  prune_nodes=chip.get('option', 'prune'))
753
756
  record = chip.schema.get("record", field='schema')
@@ -3,8 +3,8 @@ import os
3
3
  from siliconcompiler import Schema
4
4
  from siliconcompiler.schema import PerNode
5
5
  from siliconcompiler.report import utils
6
- from siliconcompiler.utils.flowgraph import nodes_to_execute
7
6
  from siliconcompiler.tools._common import get_tool_task
7
+ from siliconcompiler.flowgraph import RuntimeFlowgraph
8
8
 
9
9
 
10
10
  def make_metric_dataframe(chip):
@@ -199,7 +199,12 @@ def get_flowgraph_path(chip):
199
199
  Returns the "winning" path for that job.
200
200
  '''
201
201
  flow = chip.get('option', 'flow')
202
- return utils._get_flowgraph_path(chip, flow, nodes_to_execute(chip))
202
+ runtime = RuntimeFlowgraph(
203
+ chip.schema.get("flowgraph", flow, field='schema'),
204
+ from_steps=chip.get('option', 'from'),
205
+ to_steps=chip.get('option', 'to'),
206
+ prune_nodes=chip.get('option', 'prune'))
207
+ return utils._get_flowgraph_path(chip, flow, runtime.get_nodes())
203
208
 
204
209
 
205
210
  def search_manifest_keys(manifest, key):
@@ -289,9 +294,9 @@ def get_total_manifest_key_count(manifest):
289
294
  acc (int) : An accumulator of the current number of folders and files.
290
295
  '''
291
296
  acc = len(manifest)
292
- for dictKeys in manifest:
293
- if isinstance(manifest[dictKeys], dict):
294
- acc += get_total_manifest_key_count(manifest[dictKeys])
297
+ for key in manifest:
298
+ if isinstance(manifest[key], dict):
299
+ acc += get_total_manifest_key_count(manifest[key])
295
300
  return acc
296
301
 
297
302
 
@@ -1,14 +1,13 @@
1
1
  from siliconcompiler import NodeStatus
2
2
  from siliconcompiler.utils import units
3
- from siliconcompiler.utils.flowgraph import _get_flowgraph_execution_order, \
4
- nodes_to_execute
5
3
  from siliconcompiler.tools._common import get_tool_task
6
4
 
7
5
  from siliconcompiler.flowgraph import RuntimeFlowgraph
8
6
 
9
7
 
10
8
  def _find_summary_image(chip, ext='png'):
11
- for nodes in reversed(_get_flowgraph_execution_order(chip, chip.get('option', 'flow'))):
9
+ for nodes in reversed(chip.schema.get(
10
+ "flowgraph", chip.get('option', 'flow'), field="schema").get_execution_order()):
12
11
  for step, index in nodes:
13
12
  layout_img = chip.find_result(ext, step=step, index=index)
14
13
  if layout_img:
@@ -18,7 +17,8 @@ def _find_summary_image(chip, ext='png'):
18
17
 
19
18
  def _find_summary_metrics(chip, metrics_map):
20
19
  metrics = {}
21
- for nodes in reversed(_get_flowgraph_execution_order(chip, chip.get('option', 'flow'))):
20
+ for nodes in reversed(chip.schema.get(
21
+ "flowgraph", chip.get('option', 'flow'), field="schema").get_execution_order()):
22
22
  for step, index in nodes:
23
23
  for name, metric_info in metrics_map.items():
24
24
  if name in metrics:
@@ -44,7 +44,13 @@ 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 = list(nodes_to_execute(chip))
47
+ runtime = RuntimeFlowgraph(
48
+ chip.schema.get("flowgraph", flow, field='schema'),
49
+ from_steps=chip.get('option', 'from'),
50
+ to_steps=chip.get('option', 'to'),
51
+ prune_nodes=chip.get('option', 'prune'))
52
+
53
+ flowgraph_nodes = list(runtime.get_nodes())
48
54
  # only report tool based steps functions
49
55
  for (step, index) in list(flowgraph_nodes):
50
56
  tool, task = get_tool_task(chip, step, '0', flow=flow)
@@ -64,7 +70,7 @@ def _collect_data(chip, flow=None, flowgraph_nodes=None, format_as_string=True):
64
70
  reports = {}
65
71
 
66
72
  # Build ordered list of nodes in flowgraph
67
- for level_nodes in _get_flowgraph_execution_order(chip, flow):
73
+ for level_nodes in chip.schema.get("flowgraph", flow, field="schema").get_execution_order():
68
74
  nodes.extend(sorted(level_nodes))
69
75
  nodes = [node for node in nodes if node in flowgraph_nodes]
70
76
  for (step, index) in nodes: