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.
- siliconcompiler/_common.py +5 -0
- siliconcompiler/_metadata.py +1 -1
- siliconcompiler/apps/sc_install.py +7 -0
- siliconcompiler/apps/sc_remote.py +7 -2
- siliconcompiler/apps/utils/replay.py +5 -5
- siliconcompiler/core.py +38 -12
- siliconcompiler/data/templates/replay/replay.sh.j2 +18 -1
- siliconcompiler/metric.py +78 -0
- siliconcompiler/package/git.py +1 -1
- siliconcompiler/record.py +63 -7
- siliconcompiler/remote/client.py +57 -14
- siliconcompiler/remote/server.py +110 -60
- siliconcompiler/report/dashboard/cli/__init__.py +2 -0
- siliconcompiler/report/dashboard/cli/board.py +34 -31
- siliconcompiler/report/report.py +10 -5
- siliconcompiler/report/utils.py +12 -6
- siliconcompiler/scheduler/__init__.py +146 -976
- siliconcompiler/scheduler/run_node.py +12 -5
- siliconcompiler/scheduler/send_messages.py +9 -3
- siliconcompiler/scheduler/slurm.py +10 -43
- siliconcompiler/scheduler/taskscheduler.py +320 -0
- siliconcompiler/schema/baseschema.py +25 -4
- siliconcompiler/schema/journalingschema.py +4 -0
- siliconcompiler/schema/schema_cfg.py +3 -3
- siliconcompiler/tool.py +201 -32
- siliconcompiler/tools/_common/__init__.py +14 -11
- siliconcompiler/tools/_common/asic.py +5 -5
- siliconcompiler/tools/bluespec/convert.py +2 -1
- siliconcompiler/tools/builtin/_common.py +9 -2
- siliconcompiler/tools/builtin/concatenate.py +6 -2
- siliconcompiler/tools/builtin/minimum.py +7 -2
- siliconcompiler/tools/builtin/mux.py +7 -2
- siliconcompiler/tools/builtin/nop.py +7 -2
- siliconcompiler/tools/builtin/verify.py +7 -3
- siliconcompiler/tools/chisel/convert.py +10 -10
- siliconcompiler/tools/klayout/drc.py +2 -2
- siliconcompiler/tools/klayout/klayout_show.py +6 -6
- siliconcompiler/tools/klayout/klayout_utils.py +12 -12
- siliconcompiler/tools/netgen/count_lvs.py +2 -2
- siliconcompiler/tools/netgen/lvs.py +1 -1
- siliconcompiler/tools/openroad/_apr.py +2 -2
- siliconcompiler/tools/openroad/scripts/apr/sc_init_floorplan.tcl +1 -7
- siliconcompiler/tools/openroad/scripts/common/procs.tcl +18 -0
- siliconcompiler/tools/openroad/scripts/common/read_input_files.tcl +1 -7
- siliconcompiler/tools/opensta/scripts/sc_timing.tcl +10 -0
- siliconcompiler/tools/opensta/timing.py +11 -0
- siliconcompiler/tools/slang/__init__.py +6 -5
- siliconcompiler/tools/slang/elaborate.py +6 -6
- siliconcompiler/tools/slang/lint.py +1 -3
- siliconcompiler/tools/vpr/_xml_constraint.py +8 -8
- siliconcompiler/tools/yosys/prepareLib.py +2 -2
- siliconcompiler/tools/yosys/sc_synth_asic.tcl +43 -5
- siliconcompiler/tools/yosys/screenshot.py +1 -1
- siliconcompiler/tools/yosys/syn_asic.py +5 -5
- siliconcompiler/toolscripts/_tools.json +17 -10
- siliconcompiler/toolscripts/rhel8/install-chisel.sh +9 -2
- siliconcompiler/toolscripts/rhel8/install-icarus.sh +10 -3
- siliconcompiler/toolscripts/rhel8/install-klayout.sh +8 -1
- siliconcompiler/toolscripts/rhel8/install-magic.sh +9 -2
- siliconcompiler/toolscripts/rhel8/install-montage.sh +1 -1
- siliconcompiler/toolscripts/rhel8/install-netgen.sh +9 -2
- siliconcompiler/toolscripts/rhel8/install-slang.sh +11 -4
- siliconcompiler/toolscripts/rhel8/install-surelog.sh +9 -2
- siliconcompiler/toolscripts/rhel8/install-sv2v.sh +11 -4
- siliconcompiler/toolscripts/rhel8/install-verible.sh +11 -3
- siliconcompiler/toolscripts/rhel8/install-verilator.sh +10 -3
- siliconcompiler/toolscripts/rhel8/install-xyce.sh +15 -10
- siliconcompiler/toolscripts/rhel9/install-chisel.sh +9 -2
- siliconcompiler/toolscripts/rhel9/install-ghdl.sh +9 -2
- siliconcompiler/toolscripts/rhel9/install-gtkwave.sh +10 -3
- siliconcompiler/toolscripts/rhel9/install-icarus.sh +10 -3
- siliconcompiler/toolscripts/rhel9/install-klayout.sh +8 -1
- siliconcompiler/toolscripts/rhel9/install-magic.sh +9 -2
- siliconcompiler/toolscripts/rhel9/install-montage.sh +1 -1
- siliconcompiler/toolscripts/rhel9/install-netgen.sh +9 -2
- siliconcompiler/toolscripts/rhel9/install-openroad.sh +16 -3
- siliconcompiler/toolscripts/rhel9/install-opensta.sh +17 -5
- siliconcompiler/toolscripts/rhel9/install-slang.sh +11 -4
- siliconcompiler/toolscripts/rhel9/install-surelog.sh +9 -2
- siliconcompiler/toolscripts/rhel9/install-sv2v.sh +11 -4
- siliconcompiler/toolscripts/rhel9/install-verible.sh +11 -3
- siliconcompiler/toolscripts/rhel9/install-verilator.sh +10 -3
- siliconcompiler/toolscripts/rhel9/install-vpr.sh +9 -2
- siliconcompiler/toolscripts/rhel9/install-xdm.sh +10 -2
- siliconcompiler/toolscripts/rhel9/install-xyce.sh +15 -10
- siliconcompiler/toolscripts/rhel9/install-yosys-moosic.sh +9 -2
- siliconcompiler/toolscripts/rhel9/install-yosys-parmys.sh +10 -3
- siliconcompiler/toolscripts/rhel9/install-yosys-slang.sh +10 -2
- siliconcompiler/toolscripts/rhel9/install-yosys.sh +9 -2
- siliconcompiler/toolscripts/ubuntu20/install-bambu.sh +10 -2
- siliconcompiler/toolscripts/ubuntu20/install-bluespec.sh +10 -3
- siliconcompiler/toolscripts/ubuntu20/install-chisel.sh +9 -2
- siliconcompiler/toolscripts/ubuntu20/install-ghdl.sh +9 -2
- siliconcompiler/toolscripts/ubuntu20/install-gtkwave.sh +9 -2
- siliconcompiler/toolscripts/ubuntu20/install-icarus.sh +9 -2
- siliconcompiler/toolscripts/ubuntu20/install-icepack.sh +9 -2
- siliconcompiler/toolscripts/ubuntu20/install-klayout.sh +8 -1
- siliconcompiler/toolscripts/ubuntu20/install-magic.sh +9 -2
- siliconcompiler/toolscripts/ubuntu20/install-montage.sh +1 -1
- siliconcompiler/toolscripts/ubuntu20/install-netgen.sh +9 -2
- siliconcompiler/toolscripts/ubuntu20/install-nextpnr.sh +9 -2
- siliconcompiler/toolscripts/ubuntu20/install-openroad.sh +16 -3
- siliconcompiler/toolscripts/ubuntu20/install-opensta.sh +16 -5
- siliconcompiler/toolscripts/ubuntu20/install-slang.sh +11 -4
- siliconcompiler/toolscripts/ubuntu20/install-slurm.sh +9 -2
- siliconcompiler/toolscripts/ubuntu20/install-surelog.sh +10 -2
- siliconcompiler/toolscripts/ubuntu20/install-sv2v.sh +11 -4
- siliconcompiler/toolscripts/ubuntu20/install-verible.sh +11 -3
- siliconcompiler/toolscripts/ubuntu20/install-verilator.sh +9 -2
- siliconcompiler/toolscripts/ubuntu20/install-xdm.sh +10 -2
- siliconcompiler/toolscripts/ubuntu20/install-xyce.sh +13 -8
- siliconcompiler/toolscripts/ubuntu20/install-yosys-moosic.sh +9 -2
- siliconcompiler/toolscripts/ubuntu20/install-yosys.sh +9 -2
- siliconcompiler/toolscripts/ubuntu22/install-bambu.sh +10 -2
- siliconcompiler/toolscripts/ubuntu22/install-bluespec.sh +10 -3
- siliconcompiler/toolscripts/ubuntu22/install-chisel.sh +9 -2
- siliconcompiler/toolscripts/ubuntu22/install-ghdl.sh +9 -2
- siliconcompiler/toolscripts/ubuntu22/install-gtkwave.sh +9 -2
- siliconcompiler/toolscripts/ubuntu22/install-icarus.sh +9 -2
- siliconcompiler/toolscripts/ubuntu22/install-icepack.sh +9 -2
- siliconcompiler/toolscripts/ubuntu22/install-klayout.sh +12 -1
- siliconcompiler/toolscripts/ubuntu22/install-magic.sh +9 -2
- siliconcompiler/toolscripts/ubuntu22/install-montage.sh +1 -1
- siliconcompiler/toolscripts/ubuntu22/install-netgen.sh +9 -2
- siliconcompiler/toolscripts/ubuntu22/install-nextpnr.sh +9 -2
- siliconcompiler/toolscripts/ubuntu22/install-openroad.sh +16 -3
- siliconcompiler/toolscripts/ubuntu22/install-opensta.sh +17 -5
- siliconcompiler/toolscripts/ubuntu22/install-slang.sh +11 -4
- siliconcompiler/toolscripts/ubuntu22/install-slurm.sh +9 -2
- siliconcompiler/toolscripts/ubuntu22/install-surelog.sh +10 -2
- siliconcompiler/toolscripts/ubuntu22/install-sv2v.sh +11 -4
- siliconcompiler/toolscripts/ubuntu22/install-verible.sh +11 -3
- siliconcompiler/toolscripts/ubuntu22/install-verilator.sh +9 -2
- siliconcompiler/toolscripts/ubuntu22/install-vpr.sh +9 -2
- siliconcompiler/toolscripts/ubuntu22/install-xdm.sh +10 -2
- siliconcompiler/toolscripts/ubuntu22/install-xyce.sh +13 -8
- siliconcompiler/toolscripts/ubuntu22/install-yosys-moosic.sh +9 -2
- siliconcompiler/toolscripts/ubuntu22/install-yosys-parmys.sh +10 -3
- siliconcompiler/toolscripts/ubuntu22/install-yosys-slang.sh +10 -2
- siliconcompiler/toolscripts/ubuntu22/install-yosys.sh +9 -2
- siliconcompiler/toolscripts/ubuntu24/install-bambu.sh +12 -4
- siliconcompiler/toolscripts/ubuntu24/install-bluespec.sh +10 -3
- siliconcompiler/toolscripts/ubuntu24/install-chisel.sh +9 -2
- siliconcompiler/toolscripts/ubuntu24/install-ghdl.sh +9 -2
- siliconcompiler/toolscripts/ubuntu24/install-gtkwave.sh +9 -2
- siliconcompiler/toolscripts/ubuntu24/install-icarus.sh +9 -2
- siliconcompiler/toolscripts/ubuntu24/install-icepack.sh +9 -2
- siliconcompiler/toolscripts/ubuntu24/install-klayout.sh +12 -1
- siliconcompiler/toolscripts/ubuntu24/install-magic.sh +9 -2
- siliconcompiler/toolscripts/ubuntu24/install-montage.sh +1 -1
- siliconcompiler/toolscripts/ubuntu24/install-netgen.sh +9 -2
- siliconcompiler/toolscripts/ubuntu24/install-nextpnr.sh +9 -2
- siliconcompiler/toolscripts/ubuntu24/install-openroad.sh +16 -3
- siliconcompiler/toolscripts/ubuntu24/install-opensta.sh +17 -5
- siliconcompiler/toolscripts/ubuntu24/install-slang.sh +11 -4
- siliconcompiler/toolscripts/ubuntu24/install-slurm.sh +9 -2
- siliconcompiler/toolscripts/ubuntu24/install-surelog.sh +10 -2
- siliconcompiler/toolscripts/ubuntu24/install-sv2v.sh +11 -4
- siliconcompiler/toolscripts/ubuntu24/install-verible.sh +11 -3
- siliconcompiler/toolscripts/ubuntu24/install-verilator.sh +9 -2
- siliconcompiler/toolscripts/ubuntu24/install-vpr.sh +9 -2
- siliconcompiler/toolscripts/ubuntu24/install-xdm.sh +10 -2
- siliconcompiler/toolscripts/ubuntu24/install-xyce.sh +13 -8
- siliconcompiler/toolscripts/ubuntu24/install-yosys-moosic.sh +9 -2
- siliconcompiler/toolscripts/ubuntu24/install-yosys-parmys.sh +10 -3
- siliconcompiler/toolscripts/ubuntu24/install-yosys-slang.sh +10 -2
- siliconcompiler/toolscripts/ubuntu24/install-yosys.sh +9 -2
- siliconcompiler/utils/__init__.py +11 -0
- siliconcompiler/utils/flowgraph.py +6 -101
- siliconcompiler/utils/issue.py +15 -23
- siliconcompiler/utils/logging.py +2 -2
- {siliconcompiler-0.33.0.dist-info → siliconcompiler-0.33.2.dist-info}/METADATA +6 -5
- {siliconcompiler-0.33.0.dist-info → siliconcompiler-0.33.2.dist-info}/RECORD +177 -176
- {siliconcompiler-0.33.0.dist-info → siliconcompiler-0.33.2.dist-info}/WHEEL +1 -1
- {siliconcompiler-0.33.0.dist-info → siliconcompiler-0.33.2.dist-info}/entry_points.txt +0 -0
- {siliconcompiler-0.33.0.dist-info → siliconcompiler-0.33.2.dist-info}/licenses/LICENSE +0 -0
- {siliconcompiler-0.33.0.dist-info → siliconcompiler-0.33.2.dist-info}/top_level.txt +0 -0
siliconcompiler/remote/server.py
CHANGED
|
@@ -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
|
-
|
|
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
|
|
24
|
-
from siliconcompiler.
|
|
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
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
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
|
-
|
|
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
|
-
|
|
304
|
-
|
|
305
|
-
|
|
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
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
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.
|
|
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.
|
|
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):
|
|
@@ -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
|
-
|
|
341
|
-
|
|
342
|
-
|
|
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
|
-
|
|
347
|
-
|
|
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
|
-
|
|
602
|
-
|
|
603
|
-
|
|
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
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
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')
|
siliconcompiler/report/report.py
CHANGED
|
@@ -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
|
-
|
|
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
|
|
293
|
-
if isinstance(manifest[
|
|
294
|
-
acc += get_total_manifest_key_count(manifest[
|
|
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
|
|
siliconcompiler/report/utils.py
CHANGED
|
@@ -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(
|
|
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(
|
|
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
|
-
|
|
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
|
|
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:
|