siliconcompiler 0.32.2__py3-none-any.whl → 0.32.3__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/_metadata.py +3 -2
- siliconcompiler/core.py +52 -56
- siliconcompiler/issue.py +3 -1
- siliconcompiler/remote/client.py +55 -16
- siliconcompiler/report/__init__.py +3 -2
- siliconcompiler/report/dashboard/__init__.py +61 -170
- siliconcompiler/report/dashboard/cli/__init__.py +788 -0
- siliconcompiler/report/dashboard/web/__init__.py +196 -0
- siliconcompiler/report/dashboard/{components → web/components}/__init__.py +4 -4
- siliconcompiler/report/dashboard/{components → web/components}/graph.py +1 -1
- siliconcompiler/report/dashboard/{layouts → web/layouts}/__init__.py +3 -3
- siliconcompiler/report/dashboard/{layouts → web/layouts}/_common.py +1 -1
- siliconcompiler/report/dashboard/{layouts → web/layouts}/vertical_flowgraph.py +5 -5
- siliconcompiler/report/dashboard/{layouts → web/layouts}/vertical_flowgraph_node_tab.py +6 -6
- siliconcompiler/report/dashboard/{layouts → web/layouts}/vertical_flowgraph_sac_tabs.py +6 -6
- siliconcompiler/report/dashboard/{viewer.py → web/viewer.py} +4 -4
- siliconcompiler/scheduler/__init__.py +8 -6
- siliconcompiler/templates/replay/replay.sh.j2 +2 -2
- siliconcompiler/tools/_common/__init__.py +2 -0
- siliconcompiler/tools/openroad/_apr.py +4 -0
- siliconcompiler/tools/openroad/fillmetal_insertion.py +14 -14
- siliconcompiler/tools/openroad/scripts/apr/sc_antenna_repair.tcl +1 -1
- siliconcompiler/tools/openroad/scripts/apr/sc_clock_tree_synthesis.tcl +1 -1
- siliconcompiler/tools/openroad/scripts/apr/sc_detailed_placement.tcl +1 -1
- siliconcompiler/tools/openroad/scripts/apr/sc_detailed_route.tcl +1 -1
- siliconcompiler/tools/openroad/scripts/apr/sc_endcap_tapcell_insertion.tcl +1 -1
- siliconcompiler/tools/openroad/scripts/apr/sc_fillercell_insertion.tcl +1 -1
- siliconcompiler/tools/openroad/scripts/apr/sc_fillmetal_insertion.tcl +2 -2
- siliconcompiler/tools/openroad/scripts/apr/sc_global_placement.tcl +1 -1
- siliconcompiler/tools/openroad/scripts/apr/sc_global_route.tcl +1 -1
- siliconcompiler/tools/openroad/scripts/apr/sc_init_floorplan.tcl +1 -1
- siliconcompiler/tools/openroad/scripts/apr/sc_macro_placement.tcl +1 -1
- siliconcompiler/tools/openroad/scripts/apr/sc_metrics.tcl +1 -1
- siliconcompiler/tools/openroad/scripts/apr/sc_pin_placement.tcl +1 -1
- siliconcompiler/tools/openroad/scripts/apr/sc_power_grid.tcl +1 -1
- siliconcompiler/tools/openroad/scripts/apr/sc_repair_design.tcl +1 -1
- siliconcompiler/tools/openroad/scripts/apr/sc_repair_timing.tcl +2 -2
- siliconcompiler/tools/openroad/scripts/apr/sc_write_data.tcl +1 -1
- siliconcompiler/tools/openroad/scripts/common/procs.tcl +1 -1
- siliconcompiler/tools/openroad/scripts/common/reports.tcl +2 -2
- siliconcompiler/tools/openroad/scripts/sc_rcx.tcl +1 -1
- siliconcompiler/tools/openroad/scripts/sc_rdlroute.tcl +1 -1
- siliconcompiler/tools/openroad/scripts/sc_show.tcl +1 -1
- siliconcompiler/tools/opensta/__init__.py +1 -1
- siliconcompiler/tools/opensta/scripts/sc_check_library.tcl +1 -1
- siliconcompiler/tools/opensta/scripts/sc_procs.tcl +16 -0
- siliconcompiler/tools/opensta/scripts/sc_report_libraries.tcl +1 -1
- siliconcompiler/tools/opensta/scripts/sc_timing.tcl +35 -7
- siliconcompiler/tools/opensta/timing.py +6 -2
- siliconcompiler/tools/yosys/sc_synth_asic.tcl +36 -28
- siliconcompiler/tools/yosys/syn_asic.py +11 -2
- siliconcompiler/toolscripts/_tools.json +9 -4
- siliconcompiler/toolscripts/rhel8/install-chisel.sh +2 -0
- siliconcompiler/toolscripts/rhel8/install-icarus.sh +1 -0
- siliconcompiler/toolscripts/rhel8/install-klayout.sh +2 -0
- siliconcompiler/toolscripts/rhel8/install-magic.sh +1 -2
- siliconcompiler/toolscripts/rhel8/install-netgen.sh +1 -1
- siliconcompiler/toolscripts/rhel8/install-slang.sh +2 -0
- siliconcompiler/toolscripts/rhel8/install-surelog.sh +3 -1
- siliconcompiler/toolscripts/rhel8/install-sv2v.sh +1 -0
- siliconcompiler/toolscripts/rhel8/install-verible.sh +2 -0
- siliconcompiler/toolscripts/rhel8/install-verilator.sh +1 -0
- siliconcompiler/toolscripts/rhel8/install-xyce.sh +2 -0
- siliconcompiler/toolscripts/rhel9/install-chisel.sh +2 -0
- siliconcompiler/toolscripts/rhel9/install-ghdl.sh +1 -0
- siliconcompiler/toolscripts/rhel9/install-gtkwave.sh +1 -0
- siliconcompiler/toolscripts/rhel9/install-icarus.sh +1 -0
- siliconcompiler/toolscripts/rhel9/install-klayout.sh +2 -0
- siliconcompiler/toolscripts/rhel9/install-magic.sh +1 -2
- siliconcompiler/toolscripts/rhel9/install-netgen.sh +1 -1
- siliconcompiler/toolscripts/rhel9/install-openroad.sh +2 -0
- siliconcompiler/toolscripts/rhel9/install-opensta.sh +76 -0
- siliconcompiler/toolscripts/rhel9/install-slang.sh +3 -1
- siliconcompiler/toolscripts/rhel9/install-surelog.sh +2 -1
- siliconcompiler/toolscripts/rhel9/install-sv2v.sh +1 -0
- siliconcompiler/toolscripts/rhel9/install-verible.sh +2 -0
- siliconcompiler/toolscripts/rhel9/install-verilator.sh +1 -0
- siliconcompiler/toolscripts/rhel9/install-vpr.sh +2 -0
- siliconcompiler/toolscripts/rhel9/install-xdm.sh +2 -0
- siliconcompiler/toolscripts/rhel9/install-xyce.sh +2 -0
- siliconcompiler/toolscripts/rhel9/install-yosys-moosic.sh +2 -0
- siliconcompiler/toolscripts/rhel9/install-yosys-parmys.sh +2 -0
- siliconcompiler/toolscripts/rhel9/install-yosys-slang.sh +3 -1
- siliconcompiler/toolscripts/rhel9/install-yosys.sh +2 -0
- siliconcompiler/toolscripts/ubuntu20/install-bambu.sh +2 -0
- siliconcompiler/toolscripts/ubuntu20/install-bluespec.sh +2 -0
- siliconcompiler/toolscripts/ubuntu20/install-chisel.sh +2 -0
- siliconcompiler/toolscripts/ubuntu20/install-ghdl.sh +2 -0
- siliconcompiler/toolscripts/ubuntu20/install-gtkwave.sh +2 -0
- siliconcompiler/toolscripts/ubuntu20/install-icarus.sh +2 -0
- siliconcompiler/toolscripts/ubuntu20/install-icepack.sh +2 -0
- siliconcompiler/toolscripts/ubuntu20/install-klayout.sh +2 -0
- siliconcompiler/toolscripts/ubuntu20/install-magic.sh +2 -0
- siliconcompiler/toolscripts/ubuntu20/install-netgen.sh +2 -0
- siliconcompiler/toolscripts/ubuntu20/install-nextpnr.sh +1 -3
- siliconcompiler/toolscripts/ubuntu20/install-openroad.sh +2 -0
- siliconcompiler/toolscripts/ubuntu20/install-opensta.sh +72 -0
- siliconcompiler/toolscripts/ubuntu20/install-slang.sh +3 -1
- siliconcompiler/toolscripts/ubuntu20/install-slurm.sh +2 -0
- siliconcompiler/toolscripts/ubuntu20/install-surelog.sh +3 -1
- siliconcompiler/toolscripts/ubuntu20/install-sv2v.sh +1 -1
- siliconcompiler/toolscripts/ubuntu20/install-verible.sh +2 -0
- siliconcompiler/toolscripts/ubuntu20/install-verilator.sh +2 -0
- siliconcompiler/toolscripts/ubuntu20/install-vpr.sh +2 -0
- siliconcompiler/toolscripts/ubuntu20/install-xdm.sh +2 -0
- siliconcompiler/toolscripts/ubuntu20/install-xyce.sh +2 -0
- siliconcompiler/toolscripts/ubuntu20/install-yosys-moosic.sh +2 -0
- siliconcompiler/toolscripts/ubuntu20/install-yosys-parmys.sh +2 -0
- siliconcompiler/toolscripts/ubuntu20/install-yosys.sh +2 -0
- siliconcompiler/toolscripts/ubuntu22/install-bambu.sh +2 -0
- siliconcompiler/toolscripts/ubuntu22/install-bluespec.sh +2 -0
- siliconcompiler/toolscripts/ubuntu22/install-chisel.sh +2 -0
- siliconcompiler/toolscripts/ubuntu22/install-ghdl.sh +2 -0
- siliconcompiler/toolscripts/ubuntu22/install-gtkwave.sh +2 -0
- siliconcompiler/toolscripts/ubuntu22/install-icarus.sh +2 -0
- siliconcompiler/toolscripts/ubuntu22/install-icepack.sh +2 -0
- siliconcompiler/toolscripts/ubuntu22/install-klayout.sh +2 -0
- siliconcompiler/toolscripts/ubuntu22/install-magic.sh +2 -0
- siliconcompiler/toolscripts/ubuntu22/install-netgen.sh +2 -0
- siliconcompiler/toolscripts/ubuntu22/install-nextpnr.sh +1 -2
- siliconcompiler/toolscripts/ubuntu22/install-openroad.sh +2 -0
- siliconcompiler/toolscripts/ubuntu22/install-opensta.sh +72 -0
- siliconcompiler/toolscripts/ubuntu22/install-slang.sh +3 -1
- siliconcompiler/toolscripts/ubuntu22/install-slurm.sh +2 -0
- siliconcompiler/toolscripts/ubuntu22/install-surelog.sh +3 -1
- siliconcompiler/toolscripts/ubuntu22/install-sv2v.sh +1 -1
- siliconcompiler/toolscripts/ubuntu22/install-verible.sh +2 -0
- siliconcompiler/toolscripts/ubuntu22/install-verilator.sh +2 -0
- siliconcompiler/toolscripts/ubuntu22/install-vpr.sh +2 -0
- siliconcompiler/toolscripts/ubuntu22/install-xdm.sh +2 -0
- siliconcompiler/toolscripts/ubuntu22/install-xyce.sh +2 -0
- siliconcompiler/toolscripts/ubuntu22/install-yosys-moosic.sh +2 -0
- siliconcompiler/toolscripts/ubuntu22/install-yosys-parmys.sh +2 -0
- siliconcompiler/toolscripts/ubuntu22/install-yosys-slang.sh +3 -1
- siliconcompiler/toolscripts/ubuntu22/install-yosys.sh +2 -0
- siliconcompiler/toolscripts/ubuntu24/install-bambu.sh +2 -0
- siliconcompiler/toolscripts/ubuntu24/install-bluespec.sh +2 -0
- siliconcompiler/toolscripts/ubuntu24/install-chisel.sh +2 -0
- siliconcompiler/toolscripts/ubuntu24/install-ghdl.sh +2 -0
- siliconcompiler/toolscripts/ubuntu24/install-gtkwave.sh +2 -0
- siliconcompiler/toolscripts/ubuntu24/install-icarus.sh +2 -0
- siliconcompiler/toolscripts/ubuntu24/install-icepack.sh +2 -0
- siliconcompiler/toolscripts/ubuntu24/install-klayout.sh +2 -0
- siliconcompiler/toolscripts/ubuntu24/install-magic.sh +2 -0
- siliconcompiler/toolscripts/ubuntu24/install-netgen.sh +2 -0
- siliconcompiler/toolscripts/ubuntu24/install-nextpnr.sh +1 -3
- siliconcompiler/toolscripts/ubuntu24/install-openroad.sh +2 -0
- siliconcompiler/toolscripts/ubuntu24/install-opensta.sh +72 -0
- siliconcompiler/toolscripts/ubuntu24/install-slang.sh +3 -1
- siliconcompiler/toolscripts/ubuntu24/install-slurm.sh +2 -0
- siliconcompiler/toolscripts/ubuntu24/install-surelog.sh +3 -1
- siliconcompiler/toolscripts/ubuntu24/install-sv2v.sh +1 -1
- siliconcompiler/toolscripts/ubuntu24/install-verible.sh +2 -0
- siliconcompiler/toolscripts/ubuntu24/install-verilator.sh +2 -0
- siliconcompiler/toolscripts/ubuntu24/install-vpr.sh +2 -0
- siliconcompiler/toolscripts/ubuntu24/install-xdm.sh +2 -0
- siliconcompiler/toolscripts/ubuntu24/install-xyce.sh +2 -0
- siliconcompiler/toolscripts/ubuntu24/install-yosys-moosic.sh +2 -0
- siliconcompiler/toolscripts/ubuntu24/install-yosys-parmys.sh +2 -0
- siliconcompiler/toolscripts/ubuntu24/install-yosys-slang.sh +3 -1
- siliconcompiler/toolscripts/ubuntu24/install-yosys.sh +2 -0
- siliconcompiler/utils/logging.py +87 -33
- {siliconcompiler-0.32.2.dist-info → siliconcompiler-0.32.3.dist-info}/METADATA +5 -4
- {siliconcompiler-0.32.2.dist-info → siliconcompiler-0.32.3.dist-info}/RECORD +172 -166
- /siliconcompiler/report/dashboard/{components → web/components}/flowgraph.py +0 -0
- /siliconcompiler/report/dashboard/{state.py → web/state.py} +0 -0
- /siliconcompiler/report/dashboard/{utils → web/utils}/__init__.py +0 -0
- /siliconcompiler/report/dashboard/{utils → web/utils}/file_utils.py +0 -0
- {siliconcompiler-0.32.2.dist-info → siliconcompiler-0.32.3.dist-info}/WHEEL +0 -0
- {siliconcompiler-0.32.2.dist-info → siliconcompiler-0.32.3.dist-info}/entry_points.txt +0 -0
- {siliconcompiler-0.32.2.dist-info → siliconcompiler-0.32.3.dist-info}/licenses/LICENSE +0 -0
- {siliconcompiler-0.32.2.dist-info → siliconcompiler-0.32.3.dist-info}/top_level.txt +0 -0
siliconcompiler/_metadata.py
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# Version number following semver standard.
|
|
2
|
-
version = '0.32.
|
|
2
|
+
version = '0.32.3'
|
|
3
3
|
|
|
4
4
|
# Default server address for remote runs, if unspecified.
|
|
5
5
|
default_server = 'https://server.siliconcompiler.com'
|
|
@@ -21,7 +21,8 @@ authors = [
|
|
|
21
21
|
'Aulihan Teng',
|
|
22
22
|
'Peter Grossmann',
|
|
23
23
|
'Gabriel Aguirre',
|
|
24
|
-
'Martin Troiber'
|
|
24
|
+
'Martin Troiber',
|
|
25
|
+
'Ciprian Antoci'
|
|
25
26
|
]
|
|
26
27
|
|
|
27
28
|
# CLI entry banner autogenerated using pyfiglet.
|
siliconcompiler/core.py
CHANGED
|
@@ -17,16 +17,20 @@ import graphviz
|
|
|
17
17
|
import codecs
|
|
18
18
|
import copy
|
|
19
19
|
from inspect import getfullargspec
|
|
20
|
-
from siliconcompiler.remote import client
|
|
21
20
|
from siliconcompiler.schema import Schema, SCHEMA_VERSION
|
|
22
21
|
from siliconcompiler.schema import utils as schema_utils
|
|
23
22
|
from siliconcompiler import utils
|
|
24
|
-
from siliconcompiler.utils.logging import
|
|
23
|
+
from siliconcompiler.utils.logging import SCColorLoggerFormatter, \
|
|
24
|
+
SCLoggerFormatter, SCInRunLoggerFormatter, \
|
|
25
|
+
SCDebugLoggerFormatter, SCDebugInRunLoggerFormatter, \
|
|
26
|
+
SCBlankLoggerFormatter
|
|
25
27
|
from siliconcompiler import _metadata
|
|
26
28
|
from siliconcompiler import NodeStatus, SiliconCompilerError
|
|
27
29
|
from siliconcompiler.report import _show_summary_table
|
|
28
30
|
from siliconcompiler.report import _generate_summary_image, _open_summary_image
|
|
29
|
-
from siliconcompiler.report import
|
|
31
|
+
from siliconcompiler.report.dashboard.web import WebDashboard
|
|
32
|
+
from siliconcompiler.report.dashboard.cli import CliDashboard
|
|
33
|
+
from siliconcompiler.report.dashboard import DashboardType
|
|
30
34
|
from siliconcompiler import package as sc_package
|
|
31
35
|
import glob
|
|
32
36
|
from siliconcompiler.scheduler import run as sc_runner
|
|
@@ -238,62 +242,39 @@ class Chip:
|
|
|
238
242
|
self.logger._console = stream_handler
|
|
239
243
|
self.logger.addHandler(stream_handler)
|
|
240
244
|
|
|
241
|
-
self.logger._support_color =
|
|
245
|
+
self.logger._support_color = SCColorLoggerFormatter.supports_color(stream_handler)
|
|
242
246
|
|
|
243
247
|
self._init_logger_formats(loglevel=loglevel)
|
|
244
248
|
|
|
245
249
|
def _init_logger_formats(self, loglevel=None):
|
|
246
250
|
if not loglevel:
|
|
247
|
-
self.schema.get('option', 'loglevel',
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
max_index_len = min(max_index_len, max_column_width)
|
|
269
|
-
|
|
270
|
-
jobname = self.get('option', 'jobname')
|
|
271
|
-
|
|
272
|
-
step = self.logger._in_step
|
|
273
|
-
index = self.logger._in_index
|
|
274
|
-
|
|
275
|
-
if step is None:
|
|
276
|
-
step = '-' * max(max_step_len // 4, 1)
|
|
277
|
-
if index is None:
|
|
278
|
-
index = '-' * max(max_index_len // 4, 1)
|
|
279
|
-
|
|
280
|
-
log_format.append(utils.truncate_text(jobname, max_column_width))
|
|
281
|
-
log_format.append(f'{utils.truncate_text(step, max_step_len): <{max_step_len}}')
|
|
282
|
-
log_format.append(f'{utils.truncate_text(index, max_step_len): >{max_index_len}}')
|
|
283
|
-
|
|
284
|
-
log_formatprefix = "| "
|
|
285
|
-
if loglevel == "quiet":
|
|
286
|
-
log_format = []
|
|
287
|
-
log_formatprefix = ""
|
|
288
|
-
|
|
289
|
-
log_format.append('%(message)s')
|
|
290
|
-
stream_logformat = log_formatprefix + ' | '.join(log_format[1:])
|
|
251
|
+
loglevel = self.schema.get('option', 'loglevel',
|
|
252
|
+
step=self.logger._in_step, index=self.logger._in_index)
|
|
253
|
+
|
|
254
|
+
if loglevel == 'quiet':
|
|
255
|
+
base_format = SCBlankLoggerFormatter()
|
|
256
|
+
elif self.logger._in_run:
|
|
257
|
+
if loglevel == 'debug':
|
|
258
|
+
base_format = SCDebugInRunLoggerFormatter(
|
|
259
|
+
self,
|
|
260
|
+
self.get('option', 'jobname'),
|
|
261
|
+
self.logger._in_step, self.logger._in_index)
|
|
262
|
+
else:
|
|
263
|
+
base_format = SCInRunLoggerFormatter(
|
|
264
|
+
self,
|
|
265
|
+
self.get('option', 'jobname'),
|
|
266
|
+
self.logger._in_step, self.logger._in_index)
|
|
267
|
+
else:
|
|
268
|
+
if loglevel == 'debug':
|
|
269
|
+
base_format = SCDebugLoggerFormatter()
|
|
270
|
+
else:
|
|
271
|
+
base_format = SCLoggerFormatter()
|
|
291
272
|
|
|
292
273
|
for handler in self.logger.handlers.copy():
|
|
293
274
|
if handler == self.logger._console and self.logger._support_color:
|
|
294
|
-
formatter =
|
|
275
|
+
formatter = SCColorLoggerFormatter(base_format)
|
|
295
276
|
else:
|
|
296
|
-
formatter =
|
|
277
|
+
formatter = base_format
|
|
297
278
|
handler.setFormatter(formatter)
|
|
298
279
|
|
|
299
280
|
###########################################################################
|
|
@@ -2867,7 +2848,7 @@ class Chip:
|
|
|
2867
2848
|
return hashlist
|
|
2868
2849
|
|
|
2869
2850
|
###########################################################################
|
|
2870
|
-
def dashboard(self, wait=True, port=None, graph_chips=None):
|
|
2851
|
+
def dashboard(self, wait=True, port=None, graph_chips=None, type=DashboardType.WEB):
|
|
2871
2852
|
'''
|
|
2872
2853
|
Open a session of the dashboard.
|
|
2873
2854
|
|
|
@@ -2881,6 +2862,8 @@ class Chip:
|
|
|
2881
2862
|
dashboard to.
|
|
2882
2863
|
graph_chips (list): A list of dictionaries of the format
|
|
2883
2864
|
{'chip': chip object, 'name': chip name}
|
|
2865
|
+
type (enum): A string specifying what kind of dashboard to
|
|
2866
|
+
launch. Available options: 'cli', 'web'.
|
|
2884
2867
|
|
|
2885
2868
|
Examples:
|
|
2886
2869
|
>>> chip.dashboard()
|
|
@@ -2891,7 +2874,14 @@ class Chip:
|
|
|
2891
2874
|
self._dash.stop()
|
|
2892
2875
|
self._dash = None
|
|
2893
2876
|
|
|
2894
|
-
|
|
2877
|
+
# Select dashboard type
|
|
2878
|
+
type = DashboardType(type)
|
|
2879
|
+
if type == DashboardType.WEB:
|
|
2880
|
+
self._dash = WebDashboard(self, port=port, graph_chips=graph_chips)
|
|
2881
|
+
elif type == DashboardType.CLI:
|
|
2882
|
+
self._dash = CliDashboard(self)
|
|
2883
|
+
wait = False
|
|
2884
|
+
|
|
2895
2885
|
self._dash.open_dashboard()
|
|
2896
2886
|
|
|
2897
2887
|
if wait:
|
|
@@ -3017,7 +3007,7 @@ class Chip:
|
|
|
3017
3007
|
flow (str): Flow name
|
|
3018
3008
|
step (str): Step name
|
|
3019
3009
|
task (module/str): Task to associate with this node
|
|
3020
|
-
index (int): Step index
|
|
3010
|
+
index (int/str): Step index
|
|
3021
3011
|
|
|
3022
3012
|
Examples:
|
|
3023
3013
|
>>> import siliconcomiler.tools.openroad.place as place
|
|
@@ -3076,8 +3066,8 @@ class Chip:
|
|
|
3076
3066
|
flow (str): Name of flow
|
|
3077
3067
|
tail (str): Name of tail node
|
|
3078
3068
|
head (str): Name of head node
|
|
3079
|
-
tail_index (int): Index of tail node to connect
|
|
3080
|
-
head_index (int): Index of head node to connect
|
|
3069
|
+
tail_index (int/str): Index of tail node to connect
|
|
3070
|
+
head_index (int/str): Index of head node to connect
|
|
3081
3071
|
|
|
3082
3072
|
Examples:
|
|
3083
3073
|
>>> chip.edge('place', 'cts')
|
|
@@ -3107,7 +3097,7 @@ class Chip:
|
|
|
3107
3097
|
Args:
|
|
3108
3098
|
flow (str): Flow name
|
|
3109
3099
|
step (str): Step name
|
|
3110
|
-
index (int): Step index
|
|
3100
|
+
index (int/str): Step index
|
|
3111
3101
|
'''
|
|
3112
3102
|
|
|
3113
3103
|
if flow not in self.getkeys('flowgraph'):
|
|
@@ -3219,6 +3209,12 @@ class Chip:
|
|
|
3219
3209
|
raise e
|
|
3220
3210
|
self.logger.error(str(e))
|
|
3221
3211
|
return False
|
|
3212
|
+
finally:
|
|
3213
|
+
# Update dashboard if running
|
|
3214
|
+
if self._dash:
|
|
3215
|
+
self._dash.update_manifest()
|
|
3216
|
+
self._dash.end_of_run()
|
|
3217
|
+
|
|
3222
3218
|
return True
|
|
3223
3219
|
|
|
3224
3220
|
###########################################################################
|
siliconcompiler/issue.py
CHANGED
|
@@ -273,7 +273,9 @@ def generate_testcase(chip,
|
|
|
273
273
|
full_archive_path = os.path.join(archive_directory, archive_name)
|
|
274
274
|
full_archive_path = os.path.abspath(full_archive_path)
|
|
275
275
|
# Build archive
|
|
276
|
-
arch_base_dir = os.path.basename(archive_name)
|
|
276
|
+
arch_base_dir = os.path.basename(archive_name)
|
|
277
|
+
while arch_base_dir.lower().split('.')[-1] in ('gz', 'tar'):
|
|
278
|
+
arch_base_dir = '.'.join(arch_base_dir.split('.')[0:-1])
|
|
277
279
|
with tarfile.open(full_archive_path, "w:gz") as tar:
|
|
278
280
|
# Add individual files
|
|
279
281
|
add_files = [manifest_path,
|
siliconcompiler/remote/client.py
CHANGED
|
@@ -10,11 +10,12 @@ import tarfile
|
|
|
10
10
|
import tempfile
|
|
11
11
|
import multiprocessing
|
|
12
12
|
|
|
13
|
-
from siliconcompiler import utils, SiliconCompilerError
|
|
13
|
+
from siliconcompiler import utils, SiliconCompilerError, NodeStatus
|
|
14
14
|
from siliconcompiler import NodeStatus as SCNodeStatus
|
|
15
15
|
from siliconcompiler._metadata import default_server
|
|
16
16
|
from siliconcompiler.flowgraph import nodes_to_execute
|
|
17
17
|
from siliconcompiler.remote import JobStatus
|
|
18
|
+
from siliconcompiler.report.dashboard import DashboardType
|
|
18
19
|
|
|
19
20
|
# Step name to use while logging
|
|
20
21
|
remote_step_name = 'remote'
|
|
@@ -298,18 +299,19 @@ service, provided by SiliconCompiler, is not intended to process proprietary IP.
|
|
|
298
299
|
self.__logger.info(nodes_log)
|
|
299
300
|
|
|
300
301
|
def _report_job_status(self, info):
|
|
302
|
+
completed = []
|
|
303
|
+
starttimes = {}
|
|
304
|
+
|
|
301
305
|
if not info['busy']:
|
|
302
306
|
# Job is not running
|
|
303
|
-
return
|
|
307
|
+
return completed, starttimes, False
|
|
304
308
|
|
|
305
309
|
try:
|
|
306
310
|
# Decode response JSON, if possible.
|
|
307
311
|
job_info = json.loads(info['message'])
|
|
308
312
|
except json.JSONDecodeError as e:
|
|
309
313
|
self.__logger.warning(f"Job is still running: {e}")
|
|
310
|
-
return
|
|
311
|
-
|
|
312
|
-
completed = []
|
|
314
|
+
return completed, starttimes, True
|
|
313
315
|
|
|
314
316
|
nodes_to_log = {}
|
|
315
317
|
for node, node_info in job_info.items():
|
|
@@ -335,7 +337,16 @@ service, provided by SiliconCompiler, is not intended to process proprietary IP.
|
|
|
335
337
|
self.__log_node_status(stat, nodes)
|
|
336
338
|
|
|
337
339
|
# Running / in-progress flowgraph nodes should all be printed:
|
|
340
|
+
base_time = time.time()
|
|
338
341
|
for stat, nodes in nodes_to_log.items():
|
|
342
|
+
for node, node_info in nodes:
|
|
343
|
+
if 'elapsed_time' in node_info:
|
|
344
|
+
runtime = 0
|
|
345
|
+
for part in node_info['elapsed_time'].split(":"):
|
|
346
|
+
runtime = 60 * runtime + float(part)
|
|
347
|
+
starttimes[(self.__node_information[node]["step"],
|
|
348
|
+
self.__node_information[node]["index"])] = base_time - runtime
|
|
349
|
+
|
|
339
350
|
if SCNodeStatus.is_running(stat):
|
|
340
351
|
self.__logger.info(f' {stat.title()} ({len(nodes)}):')
|
|
341
352
|
for node, node_info in nodes:
|
|
@@ -349,7 +360,7 @@ service, provided by SiliconCompiler, is not intended to process proprietary IP.
|
|
|
349
360
|
if SCNodeStatus.is_waiting(stat):
|
|
350
361
|
self.__log_node_status(stat, nodes)
|
|
351
362
|
|
|
352
|
-
return completed, True
|
|
363
|
+
return completed, starttimes, True
|
|
353
364
|
|
|
354
365
|
def __check(self):
|
|
355
366
|
def post_action(url):
|
|
@@ -438,6 +449,9 @@ service, provided by SiliconCompiler, is not intended to process proprietary IP.
|
|
|
438
449
|
raise SiliconCompilerError('Cannot pass [arg,index] parameter into remote flow.',
|
|
439
450
|
chip=self.__chip)
|
|
440
451
|
|
|
452
|
+
if not self.__chip._dash:
|
|
453
|
+
self.__chip.dashboard(type=DashboardType.CLI)
|
|
454
|
+
|
|
441
455
|
# Only run the pre-process step if the job doesn't already have a remote ID.
|
|
442
456
|
if not remote_resume:
|
|
443
457
|
self.__run_preprocess()
|
|
@@ -450,10 +464,12 @@ service, provided by SiliconCompiler, is not intended to process proprietary IP.
|
|
|
450
464
|
self.__request_run()
|
|
451
465
|
|
|
452
466
|
# Run the main 'check_progress' loop to monitor job status until it finishes.
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
467
|
+
try:
|
|
468
|
+
self._run_loop()
|
|
469
|
+
finally:
|
|
470
|
+
# Restore logger
|
|
471
|
+
self.__chip._dash.end_of_run()
|
|
472
|
+
self.__chip._init_logger(in_run=True)
|
|
457
473
|
|
|
458
474
|
def __request_run(self):
|
|
459
475
|
'''
|
|
@@ -559,7 +575,7 @@ service, provided by SiliconCompiler, is not intended to process proprietary IP.
|
|
|
559
575
|
self.__logger.info(f'To cancel this job use: {cancel_cmd}')
|
|
560
576
|
raise SiliconCompilerError('Job canceled by user keyboard interrupt')
|
|
561
577
|
|
|
562
|
-
def __import_run_manifests(self):
|
|
578
|
+
def __import_run_manifests(self, starttimes):
|
|
563
579
|
changed = False
|
|
564
580
|
for _, node_info in self.__node_information.items():
|
|
565
581
|
if node_info["imported"]:
|
|
@@ -577,6 +593,16 @@ service, provided by SiliconCompiler, is not intended to process proprietary IP.
|
|
|
577
593
|
except: # noqa E722
|
|
578
594
|
# Import may fail if file is still getting written
|
|
579
595
|
pass
|
|
596
|
+
elif self.__chip.get('record', 'status',
|
|
597
|
+
step=node_info["step"], index=node_info["index"]) \
|
|
598
|
+
== NodeStatus.SKIPPED:
|
|
599
|
+
node_info["imported"] = True
|
|
600
|
+
changed = True
|
|
601
|
+
|
|
602
|
+
if changed and self.__chip._dash:
|
|
603
|
+
# Update dashboard if active
|
|
604
|
+
self.__chip._dash.update_manifest({"starttimes": starttimes})
|
|
605
|
+
|
|
580
606
|
return changed
|
|
581
607
|
|
|
582
608
|
def __ensure_run_loop_information(self):
|
|
@@ -605,17 +631,30 @@ service, provided by SiliconCompiler, is not intended to process proprietary IP.
|
|
|
605
631
|
# Check the job's progress periodically until it finishes.
|
|
606
632
|
running = True
|
|
607
633
|
|
|
634
|
+
starttimes = {}
|
|
635
|
+
|
|
608
636
|
while running:
|
|
609
|
-
|
|
610
|
-
|
|
637
|
+
sleepremaining = self.__check_interval
|
|
638
|
+
while any([nodeinfo["fetched"] and not nodeinfo["imported"]
|
|
639
|
+
for nodeinfo in self.__node_information.values()]):
|
|
640
|
+
self.__import_run_manifests(starttimes)
|
|
641
|
+
sleepremaining -= 1
|
|
642
|
+
if sleepremaining <= 0:
|
|
643
|
+
break
|
|
644
|
+
time.sleep(1)
|
|
645
|
+
if sleepremaining > 0:
|
|
646
|
+
time.sleep(sleepremaining)
|
|
611
647
|
|
|
612
648
|
# Check progress
|
|
613
649
|
job_info = self.check_job_status()
|
|
614
|
-
completed, running = self._report_job_status(job_info)
|
|
650
|
+
completed, new_starttimes, running = self._report_job_status(job_info)
|
|
651
|
+
|
|
652
|
+
# preserve old starttimes
|
|
653
|
+
starttimes = {**starttimes, **new_starttimes}
|
|
615
654
|
|
|
616
655
|
if self.__chip._dash:
|
|
617
656
|
# Update dashboard if active
|
|
618
|
-
self.__chip._dash.update_manifest()
|
|
657
|
+
self.__chip._dash.update_manifest({"starttimes": starttimes})
|
|
619
658
|
|
|
620
659
|
nodes_to_fetch = []
|
|
621
660
|
for node in completed:
|
|
@@ -648,7 +687,7 @@ service, provided by SiliconCompiler, is not intended to process proprietary IP.
|
|
|
648
687
|
self.__download_pool.join()
|
|
649
688
|
self.__download_pool = None
|
|
650
689
|
|
|
651
|
-
self.__import_run_manifests()
|
|
690
|
+
self.__import_run_manifests({})
|
|
652
691
|
|
|
653
692
|
def __schedule_fetch_result(self, node):
|
|
654
693
|
self.__node_information[node]["fetched"] = True
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
from .summary_image import _generate_summary_image, _open_summary_image
|
|
2
2
|
from .html_report import _generate_html_report, _open_html_report
|
|
3
3
|
from .summary_table import _show_summary_table
|
|
4
|
-
from .dashboard import
|
|
4
|
+
from .dashboard.web import WebDashboard
|
|
5
|
+
# from .dashboard import Dashboard
|
|
5
6
|
|
|
6
7
|
__all__ = [
|
|
7
8
|
"_generate_summary_image",
|
|
@@ -9,5 +10,5 @@ __all__ = [
|
|
|
9
10
|
"_generate_html_report",
|
|
10
11
|
"_open_html_report",
|
|
11
12
|
"_show_summary_table",
|
|
12
|
-
"
|
|
13
|
+
"WebDashboard"
|
|
13
14
|
]
|
|
@@ -1,190 +1,81 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import tempfile
|
|
4
|
-
import json
|
|
1
|
+
from abc import ABC, abstractmethod
|
|
2
|
+
from enum import Enum
|
|
5
3
|
|
|
6
|
-
import multiprocessing
|
|
7
|
-
import subprocess
|
|
8
|
-
import atexit
|
|
9
|
-
import shutil
|
|
10
|
-
import fasteners
|
|
11
|
-
import signal
|
|
12
|
-
import socketserver
|
|
13
4
|
|
|
14
|
-
|
|
5
|
+
class DashboardType(Enum):
|
|
6
|
+
WEB = 'web'
|
|
7
|
+
CLI = 'cli'
|
|
15
8
|
|
|
16
|
-
try:
|
|
17
|
-
from streamlit.web import bootstrap
|
|
18
|
-
from streamlit import config as _config
|
|
19
|
-
except ModuleNotFoundError:
|
|
20
|
-
bootstrap = None
|
|
21
|
-
_config = None
|
|
22
9
|
|
|
10
|
+
class AbstractDashboard(ABC):
|
|
11
|
+
"""
|
|
12
|
+
Abstract base class defining the interface for dashboard implementations.
|
|
13
|
+
Any concrete dashboard implementation should inherit from this class and
|
|
14
|
+
implement all abstract methods.
|
|
15
|
+
"""
|
|
23
16
|
|
|
24
|
-
|
|
25
|
-
|
|
17
|
+
@abstractmethod
|
|
18
|
+
def __init__(self, chip):
|
|
19
|
+
"""
|
|
20
|
+
Initialize the dashboard.
|
|
26
21
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
def __init__(self, chip, port=None, graph_chips=None):
|
|
33
|
-
if not bootstrap:
|
|
34
|
-
raise NotImplementedError('streamlit is not available')
|
|
35
|
-
|
|
36
|
-
if not port:
|
|
37
|
-
port = Dashboard.get_next_port()
|
|
38
|
-
if not port:
|
|
39
|
-
port = Dashboard.__port
|
|
40
|
-
|
|
41
|
-
self.__dashboard = None
|
|
42
|
-
self.__chip = chip
|
|
43
|
-
self.__directory = tempfile.mkdtemp(prefix='sc_dashboard_',
|
|
44
|
-
suffix=f'_{self.__chip.design}')
|
|
45
|
-
self.__manifest = os.path.join(self.__directory, 'manifest.json')
|
|
46
|
-
self.__manifest_lock = os.path.join(self.__directory, 'manifest.lock')
|
|
47
|
-
self.__port = port
|
|
48
|
-
dirname = os.path.dirname(__file__)
|
|
49
|
-
self.__streamlit_file = os.path.join(dirname, 'viewer.py')
|
|
50
|
-
|
|
51
|
-
self.__streamlit_args = [
|
|
52
|
-
("browser.gatherUsageStats", False),
|
|
53
|
-
("browser.serverPort", self.__port),
|
|
54
|
-
("logger.level", 'error'),
|
|
55
|
-
("runner.fastReruns", True),
|
|
56
|
-
("server.port", self.__port),
|
|
57
|
-
("client.toolbarMode", "viewer")
|
|
58
|
-
]
|
|
59
|
-
|
|
60
|
-
# pass in a json object called __graph_chips
|
|
61
|
-
# the key is the chip_name and value is the filepath
|
|
62
|
-
# if another argument is passed
|
|
63
|
-
|
|
64
|
-
# use of list is to preserve order
|
|
65
|
-
self.__graph_chips = []
|
|
66
|
-
graph_chips_config = []
|
|
67
|
-
if graph_chips:
|
|
68
|
-
for chip_object_and_name in graph_chips:
|
|
69
|
-
chip_file_path = \
|
|
70
|
-
os.path.join(self.__directory,
|
|
71
|
-
f"{chip_object_and_name['name']}.json")
|
|
72
|
-
self.__graph_chips.append({
|
|
73
|
-
'chip': chip_object_and_name['chip'],
|
|
74
|
-
'name': chip_file_path
|
|
75
|
-
})
|
|
76
|
-
graph_chips_config.append({
|
|
77
|
-
"path": chip_file_path,
|
|
78
|
-
"cwd": utils.get_chip_cwd(
|
|
79
|
-
chip_object_and_name['chip'],
|
|
80
|
-
chip_object_and_name['cfg_path'])
|
|
81
|
-
})
|
|
82
|
-
|
|
83
|
-
self.__config = {
|
|
84
|
-
"manifest": self.__manifest,
|
|
85
|
-
"lock": self.__manifest_lock,
|
|
86
|
-
"graph_chips": graph_chips_config
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
self.__sleep_time = 0.5
|
|
90
|
-
self.__signal_handler = None
|
|
91
|
-
|
|
92
|
-
self.__lock = fasteners.InterProcessLock(self.__manifest_lock)
|
|
93
|
-
|
|
94
|
-
atexit.register(self.__cleanup)
|
|
22
|
+
Args:
|
|
23
|
+
chip: The chip object to display in the dashboard
|
|
24
|
+
"""
|
|
25
|
+
self._chip = chip
|
|
95
26
|
|
|
27
|
+
@abstractmethod
|
|
96
28
|
def open_dashboard(self):
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
self.update_graph_manifests()
|
|
103
|
-
|
|
104
|
-
self.__dashboard = multiprocessing.Process(
|
|
105
|
-
target=self._run_streamlit_bootstrap)
|
|
106
|
-
|
|
107
|
-
self.__signal_handler = signal.signal(signal.SIGINT, Dashboard.__signal_handler)
|
|
108
|
-
|
|
109
|
-
self.__dashboard.start()
|
|
110
|
-
|
|
111
|
-
def update_manifest(self):
|
|
112
|
-
if not self.__manifest:
|
|
113
|
-
return
|
|
29
|
+
"""
|
|
30
|
+
Open and start the dashboard service.
|
|
31
|
+
"""
|
|
32
|
+
pass
|
|
114
33
|
|
|
115
|
-
|
|
116
|
-
|
|
34
|
+
@abstractmethod
|
|
35
|
+
def update_manifest(self, payload=None):
|
|
36
|
+
"""
|
|
37
|
+
Update the manifest file with the latest chip information.
|
|
117
38
|
|
|
118
|
-
|
|
119
|
-
|
|
39
|
+
Args:
|
|
40
|
+
payload (dict): Dictionary of metadata to pass along to dashboard.
|
|
41
|
+
{"starttimes" {<node>: time, ...}}
|
|
42
|
+
"""
|
|
43
|
+
pass
|
|
120
44
|
|
|
45
|
+
@abstractmethod
|
|
121
46
|
def update_graph_manifests(self):
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
def __get_config_file(self):
|
|
128
|
-
return os.path.join(self.__directory, 'config.json')
|
|
47
|
+
"""
|
|
48
|
+
Update the manifest files for all graph chips.
|
|
49
|
+
"""
|
|
50
|
+
pass
|
|
129
51
|
|
|
52
|
+
@abstractmethod
|
|
130
53
|
def is_running(self):
|
|
131
|
-
|
|
132
|
-
|
|
54
|
+
"""
|
|
55
|
+
Check if the dashboard is currently running.
|
|
133
56
|
|
|
134
|
-
|
|
135
|
-
|
|
57
|
+
Returns:
|
|
58
|
+
bool: True if the dashboard is running, False otherwise
|
|
59
|
+
"""
|
|
60
|
+
pass
|
|
136
61
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
62
|
+
@abstractmethod
|
|
63
|
+
def end_of_run(self):
|
|
64
|
+
"""
|
|
65
|
+
Announce that a run has completed
|
|
66
|
+
"""
|
|
67
|
+
pass
|
|
140
68
|
|
|
69
|
+
@abstractmethod
|
|
141
70
|
def stop(self):
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
self.__dashboard.terminate()
|
|
147
|
-
self._sleep()
|
|
148
|
-
|
|
149
|
-
if self.__signal_handler:
|
|
150
|
-
signal.signal(signal.SIGINT, self.__signal_handler)
|
|
151
|
-
|
|
152
|
-
self.__dashboard = None
|
|
153
|
-
self.__manifest = None
|
|
154
|
-
self.__signal_handler = None
|
|
71
|
+
"""
|
|
72
|
+
Stop the dashboard service if it's running.
|
|
73
|
+
"""
|
|
74
|
+
pass
|
|
155
75
|
|
|
76
|
+
@abstractmethod
|
|
156
77
|
def wait(self):
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
def _run_streamlit_bootstrap(self):
|
|
163
|
-
for config, val in self.__streamlit_args:
|
|
164
|
-
_config.set_option(config, val)
|
|
165
|
-
|
|
166
|
-
bootstrap.run(self.__streamlit_file,
|
|
167
|
-
False,
|
|
168
|
-
[self.__get_config_file()],
|
|
169
|
-
flag_options={})
|
|
170
|
-
|
|
171
|
-
def __run_streamlit_subproc(self):
|
|
172
|
-
cmd = ['streamlit', 'run',
|
|
173
|
-
self.__streamlit_file, self.__get_config_file()]
|
|
174
|
-
for config, val in self.__streamlit_args:
|
|
175
|
-
cmd.append(f'--{config}')
|
|
176
|
-
cmd.append(val)
|
|
177
|
-
|
|
178
|
-
subprocess.Popen(cmd)
|
|
179
|
-
|
|
180
|
-
def __cleanup(self):
|
|
181
|
-
self.stop()
|
|
182
|
-
|
|
183
|
-
if os.path.exists(self.__directory):
|
|
184
|
-
shutil.rmtree(self.__directory)
|
|
185
|
-
|
|
186
|
-
@staticmethod
|
|
187
|
-
def get_next_port():
|
|
188
|
-
with socketserver.TCPServer(("localhost", 0), None) as s:
|
|
189
|
-
return s.server_address[1]
|
|
190
|
-
return None
|
|
78
|
+
"""
|
|
79
|
+
Wait for the dashboard service to terminate.
|
|
80
|
+
"""
|
|
81
|
+
pass
|