siliconcompiler 0.28.1__py3-none-any.whl → 0.28.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.
Files changed (140) hide show
  1. siliconcompiler/_common.py +12 -0
  2. siliconcompiler/_metadata.py +1 -1
  3. siliconcompiler/apps/sc_dashboard.py +5 -1
  4. siliconcompiler/apps/sc_install.py +240 -0
  5. siliconcompiler/apps/sc_remote.py +1 -1
  6. siliconcompiler/core.py +54 -13
  7. siliconcompiler/remote/client.py +41 -10
  8. siliconcompiler/report/__init__.py +1 -1
  9. siliconcompiler/report/{streamlit_report.py → dashboard/__init__.py} +47 -10
  10. siliconcompiler/report/dashboard/components/__init__.py +534 -0
  11. siliconcompiler/report/dashboard/components/flowgraph.py +114 -0
  12. siliconcompiler/report/dashboard/components/graph.py +208 -0
  13. siliconcompiler/report/dashboard/layouts/__init__.py +20 -0
  14. siliconcompiler/report/dashboard/layouts/_common.py +43 -0
  15. siliconcompiler/report/dashboard/layouts/vertical_flowgraph.py +95 -0
  16. siliconcompiler/report/dashboard/layouts/vertical_flowgraph_node_tab.py +114 -0
  17. siliconcompiler/report/dashboard/layouts/vertical_flowgraph_sac_tabs.py +107 -0
  18. siliconcompiler/report/dashboard/state.py +215 -0
  19. siliconcompiler/report/dashboard/utils/__init__.py +73 -0
  20. siliconcompiler/report/dashboard/utils/file_utils.py +120 -0
  21. siliconcompiler/report/dashboard/viewer.py +36 -0
  22. siliconcompiler/report/report.py +22 -4
  23. siliconcompiler/scheduler/__init__.py +43 -6
  24. siliconcompiler/schema/schema_obj.py +4 -2
  25. siliconcompiler/tools/_common/tcl/sc_pin_constraints.tcl +6 -5
  26. siliconcompiler/tools/openroad/floorplan.py +5 -0
  27. siliconcompiler/tools/openroad/openroad.py +12 -3
  28. siliconcompiler/tools/openroad/scripts/sc_cts.tcl +18 -13
  29. siliconcompiler/tools/openroad/scripts/sc_floorplan.tcl +6 -1
  30. siliconcompiler/tools/openroad/scripts/sc_metrics.tcl +1 -1
  31. siliconcompiler/tools/openroad/scripts/sc_procs.tcl +44 -16
  32. siliconcompiler/tools/openroad/scripts/sc_route.tcl +1 -1
  33. siliconcompiler/tools/openroad/scripts/sc_write_images.tcl +10 -10
  34. siliconcompiler/tools/opensta/scripts/sc_procs.tcl +3 -3
  35. siliconcompiler/tools/yosys/syn_asic.tcl +1 -1
  36. siliconcompiler/toolscripts/_tools.json +136 -0
  37. siliconcompiler/toolscripts/_tools.py +222 -0
  38. siliconcompiler/toolscripts/rhel8/install-chisel.sh +26 -0
  39. siliconcompiler/toolscripts/rhel8/install-ghdl.sh +25 -0
  40. siliconcompiler/toolscripts/rhel8/install-icarus.sh +40 -0
  41. siliconcompiler/toolscripts/rhel8/install-klayout.sh +17 -0
  42. siliconcompiler/toolscripts/rhel8/install-magic.sh +26 -0
  43. siliconcompiler/toolscripts/rhel8/install-montage.sh +5 -0
  44. siliconcompiler/toolscripts/rhel8/install-netgen.sh +25 -0
  45. siliconcompiler/toolscripts/rhel8/install-openroad.sh +31 -0
  46. siliconcompiler/toolscripts/rhel8/install-slang.sh +31 -0
  47. siliconcompiler/toolscripts/rhel8/install-surelog.sh +32 -0
  48. siliconcompiler/toolscripts/rhel8/install-sv2v.sh +27 -0
  49. siliconcompiler/toolscripts/rhel8/install-verible.sh +24 -0
  50. siliconcompiler/toolscripts/rhel8/install-verilator.sh +40 -0
  51. siliconcompiler/toolscripts/rhel8/install-xyce.sh +64 -0
  52. siliconcompiler/toolscripts/rhel8/install-yosys.sh +23 -0
  53. siliconcompiler/toolscripts/rhel9/install-chisel.sh +26 -0
  54. siliconcompiler/toolscripts/rhel9/install-ghdl.sh +25 -0
  55. siliconcompiler/toolscripts/rhel9/install-icarus.sh +40 -0
  56. siliconcompiler/toolscripts/rhel9/install-klayout.sh +17 -0
  57. siliconcompiler/toolscripts/rhel9/install-magic.sh +26 -0
  58. siliconcompiler/toolscripts/rhel9/install-montage.sh +5 -0
  59. siliconcompiler/toolscripts/rhel9/install-netgen.sh +25 -0
  60. siliconcompiler/toolscripts/rhel9/install-slang.sh +31 -0
  61. siliconcompiler/toolscripts/rhel9/install-surelog.sh +32 -0
  62. siliconcompiler/toolscripts/rhel9/install-sv2v.sh +27 -0
  63. siliconcompiler/toolscripts/rhel9/install-verible.sh +24 -0
  64. siliconcompiler/toolscripts/rhel9/install-verilator.sh +40 -0
  65. siliconcompiler/toolscripts/rhel9/install-xdm.sh +43 -0
  66. siliconcompiler/toolscripts/rhel9/install-xyce.sh +64 -0
  67. siliconcompiler/toolscripts/rhel9/install-yosys.sh +23 -0
  68. siliconcompiler/toolscripts/ubuntu20/install-bambu.sh +49 -0
  69. siliconcompiler/toolscripts/ubuntu20/install-bluespec.sh +35 -0
  70. siliconcompiler/toolscripts/ubuntu20/install-chisel.sh +26 -0
  71. siliconcompiler/toolscripts/ubuntu20/install-ghdl.sh +25 -0
  72. siliconcompiler/toolscripts/ubuntu20/install-icarus.sh +25 -0
  73. siliconcompiler/toolscripts/ubuntu20/install-icepack.sh +22 -0
  74. siliconcompiler/toolscripts/ubuntu20/install-klayout.sh +29 -0
  75. siliconcompiler/toolscripts/ubuntu20/install-magic.sh +24 -0
  76. siliconcompiler/toolscripts/ubuntu20/install-montage.sh +5 -0
  77. siliconcompiler/toolscripts/ubuntu20/install-netgen.sh +24 -0
  78. siliconcompiler/toolscripts/ubuntu20/install-nextpnr.sh +32 -0
  79. siliconcompiler/toolscripts/ubuntu20/install-openroad.sh +31 -0
  80. siliconcompiler/toolscripts/ubuntu20/install-slang.sh +38 -0
  81. siliconcompiler/toolscripts/ubuntu20/install-slurm.sh +32 -0
  82. siliconcompiler/toolscripts/ubuntu20/install-surelog.sh +30 -0
  83. siliconcompiler/toolscripts/ubuntu20/install-sv2v.sh +26 -0
  84. siliconcompiler/toolscripts/ubuntu20/install-verible.sh +24 -0
  85. siliconcompiler/toolscripts/ubuntu20/install-verilator.sh +34 -0
  86. siliconcompiler/toolscripts/ubuntu20/install-vpr.sh +27 -0
  87. siliconcompiler/toolscripts/ubuntu20/install-xdm.sh +40 -0
  88. siliconcompiler/toolscripts/ubuntu20/install-xyce.sh +65 -0
  89. siliconcompiler/toolscripts/ubuntu20/install-yosys.sh +24 -0
  90. siliconcompiler/toolscripts/ubuntu22/install-bambu.sh +49 -0
  91. siliconcompiler/toolscripts/ubuntu22/install-bluespec.sh +35 -0
  92. siliconcompiler/toolscripts/ubuntu22/install-chisel.sh +26 -0
  93. siliconcompiler/toolscripts/ubuntu22/install-ghdl.sh +25 -0
  94. siliconcompiler/toolscripts/ubuntu22/install-icarus.sh +25 -0
  95. siliconcompiler/toolscripts/ubuntu22/install-icepack.sh +22 -0
  96. siliconcompiler/toolscripts/ubuntu22/install-klayout.sh +29 -0
  97. siliconcompiler/toolscripts/ubuntu22/install-magic.sh +24 -0
  98. siliconcompiler/toolscripts/ubuntu22/install-montage.sh +5 -0
  99. siliconcompiler/toolscripts/ubuntu22/install-netgen.sh +24 -0
  100. siliconcompiler/toolscripts/ubuntu22/install-nextpnr.sh +32 -0
  101. siliconcompiler/toolscripts/ubuntu22/install-openroad.sh +31 -0
  102. siliconcompiler/toolscripts/ubuntu22/install-slang.sh +28 -0
  103. siliconcompiler/toolscripts/ubuntu22/install-slurm.sh +32 -0
  104. siliconcompiler/toolscripts/ubuntu22/install-surelog.sh +25 -0
  105. siliconcompiler/toolscripts/ubuntu22/install-sv2v.sh +26 -0
  106. siliconcompiler/toolscripts/ubuntu22/install-verible.sh +24 -0
  107. siliconcompiler/toolscripts/ubuntu22/install-verilator.sh +34 -0
  108. siliconcompiler/toolscripts/ubuntu22/install-vpr.sh +27 -0
  109. siliconcompiler/toolscripts/ubuntu22/install-xdm.sh +40 -0
  110. siliconcompiler/toolscripts/ubuntu22/install-xyce.sh +65 -0
  111. siliconcompiler/toolscripts/ubuntu22/install-yosys.sh +24 -0
  112. siliconcompiler/toolscripts/ubuntu24/install-bambu.sh +49 -0
  113. siliconcompiler/toolscripts/ubuntu24/install-bluespec.sh +35 -0
  114. siliconcompiler/toolscripts/ubuntu24/install-chisel.sh +26 -0
  115. siliconcompiler/toolscripts/ubuntu24/install-ghdl.sh +25 -0
  116. siliconcompiler/toolscripts/ubuntu24/install-icarus.sh +25 -0
  117. siliconcompiler/toolscripts/ubuntu24/install-icepack.sh +22 -0
  118. siliconcompiler/toolscripts/ubuntu24/install-klayout.sh +31 -0
  119. siliconcompiler/toolscripts/ubuntu24/install-magic.sh +24 -0
  120. siliconcompiler/toolscripts/ubuntu24/install-montage.sh +5 -0
  121. siliconcompiler/toolscripts/ubuntu24/install-netgen.sh +24 -0
  122. siliconcompiler/toolscripts/ubuntu24/install-nextpnr.sh +32 -0
  123. siliconcompiler/toolscripts/ubuntu24/install-openroad.sh +31 -0
  124. siliconcompiler/toolscripts/ubuntu24/install-slang.sh +28 -0
  125. siliconcompiler/toolscripts/ubuntu24/install-slurm.sh +32 -0
  126. siliconcompiler/toolscripts/ubuntu24/install-surelog.sh +25 -0
  127. siliconcompiler/toolscripts/ubuntu24/install-sv2v.sh +26 -0
  128. siliconcompiler/toolscripts/ubuntu24/install-verible.sh +24 -0
  129. siliconcompiler/toolscripts/ubuntu24/install-verilator.sh +34 -0
  130. siliconcompiler/toolscripts/ubuntu24/install-vpr.sh +27 -0
  131. siliconcompiler/toolscripts/ubuntu24/install-xdm.sh +40 -0
  132. siliconcompiler/toolscripts/ubuntu24/install-xyce.sh +65 -0
  133. siliconcompiler/toolscripts/ubuntu24/install-yosys.sh +24 -0
  134. {siliconcompiler-0.28.1.dist-info → siliconcompiler-0.28.3.dist-info}/METADATA +7 -6
  135. {siliconcompiler-0.28.1.dist-info → siliconcompiler-0.28.3.dist-info}/RECORD +139 -29
  136. {siliconcompiler-0.28.1.dist-info → siliconcompiler-0.28.3.dist-info}/entry_points.txt +1 -0
  137. siliconcompiler/report/streamlit_viewer.py +0 -944
  138. {siliconcompiler-0.28.1.dist-info → siliconcompiler-0.28.3.dist-info}/LICENSE +0 -0
  139. {siliconcompiler-0.28.1.dist-info → siliconcompiler-0.28.3.dist-info}/WHEEL +0 -0
  140. {siliconcompiler-0.28.1.dist-info → siliconcompiler-0.28.3.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,215 @@
1
+ import argparse
2
+ import json
3
+ import os
4
+ import streamlit
5
+ import streamlit_javascript
6
+ import fasteners
7
+
8
+ from siliconcompiler import Chip
9
+
10
+
11
+ DISPLAY_FLOWGRAPH = "show_flowgraph"
12
+ SELECTED_JOB = "selected_job"
13
+ SELECTED_NODE = "selected_node"
14
+ # This is needed until the graph supports setting a selected node
15
+ SELECTED_FLOWGRAPH_NODE = "selected_flowgraph_node"
16
+ SELECTED_SELECTOR_NODE = "selected_selector_node"
17
+ NODE_SOURCE = "node_source"
18
+ SELECTED_FILE = "selected_file"
19
+ LOADED_CHIPS = "loaded_chips"
20
+ UI_WIDTH = "ui_width"
21
+ MANIFEST_FILE = "manifest_file"
22
+ MANIFEST_LOCK = "manifest_lock"
23
+ MANIFEST_TIME = "manifest_time"
24
+ IS_RUNNING = "is_flow_running"
25
+ GRAPH_JOBS = "graph_jobs"
26
+ APP_LAYOUT = "app_layout"
27
+ APP_RERUN = "app_rerun"
28
+ APP_RUNNING_REFRESH = "app_running_refresh"
29
+ APP_STOPPED_REFRESH = "app_stopped_refresh"
30
+ MAX_DICT_ITEMS_TO_SHOW = "max_dict_items"
31
+ MAX_FILE_LINES_TO_SHOW = "max_file_lines"
32
+ SELECT_TAB = "select_tab"
33
+ TAB_INDEX = "tab-index"
34
+ TAB_STATE = "tab-state"
35
+
36
+ _DEBUG = False
37
+ DEVELOPER = False
38
+
39
+
40
+ def _add_default(key, value):
41
+ if key not in streamlit.session_state:
42
+ streamlit.session_state[key] = value
43
+
44
+
45
+ def update_manifest():
46
+ file_time = os.stat(get_key(MANIFEST_FILE)).st_mtime
47
+
48
+ if get_key(MANIFEST_TIME) != file_time:
49
+ chip = Chip(design='')
50
+
51
+ with get_key(MANIFEST_LOCK):
52
+ chip.read_manifest(get_key(MANIFEST_FILE))
53
+ set_key(MANIFEST_TIME, file_time)
54
+ debug_print("Read manifest", get_key(MANIFEST_FILE))
55
+
56
+ add_chip("default", chip)
57
+
58
+ for history in chip.getkeys('history'):
59
+ history_chip = Chip(design='')
60
+ history_chip.schema.cfg = chip.getdict('history', history)
61
+ history_chip.set('design', chip.design)
62
+ add_chip(history, history_chip)
63
+
64
+ return True
65
+ return False
66
+
67
+
68
+ def init():
69
+ _add_default(DISPLAY_FLOWGRAPH, True)
70
+ _add_default(SELECTED_JOB, None)
71
+ _add_default(SELECTED_NODE, None)
72
+ _add_default(SELECTED_FLOWGRAPH_NODE, None)
73
+ _add_default(SELECTED_SELECTOR_NODE, None)
74
+ _add_default(NODE_SOURCE, None)
75
+ _add_default(SELECTED_FILE, None)
76
+ _add_default(LOADED_CHIPS, {})
77
+ _add_default(MANIFEST_FILE, None)
78
+ _add_default(MANIFEST_LOCK, None)
79
+ _add_default(MANIFEST_TIME, None)
80
+ _add_default(IS_RUNNING, False)
81
+ _add_default(GRAPH_JOBS, None)
82
+ _add_default(UI_WIDTH, None)
83
+ _add_default(APP_LAYOUT, "vertical_flowgraph")
84
+ _add_default(APP_RERUN, None)
85
+ _add_default(APP_RUNNING_REFRESH, 2 * 1000)
86
+ _add_default(APP_STOPPED_REFRESH, 30 * 1000)
87
+ _add_default(MAX_DICT_ITEMS_TO_SHOW, 100)
88
+ _add_default(MAX_FILE_LINES_TO_SHOW, 100)
89
+ _add_default(SELECT_TAB, None)
90
+ _add_default(TAB_INDEX, 0)
91
+
92
+ parser = argparse.ArgumentParser('dashboard')
93
+ parser.add_argument('cfg', nargs='?')
94
+ args = parser.parse_args()
95
+
96
+ if not args.cfg:
97
+ raise ValueError('configuration not provided')
98
+
99
+ if not get_key(LOADED_CHIPS):
100
+ # First time through
101
+
102
+ with open(args.cfg, 'r') as f:
103
+ config = json.load(f)
104
+
105
+ set_key(MANIFEST_FILE, config["manifest"])
106
+ set_key(MANIFEST_LOCK, fasteners.InterProcessLock(config["lock"]))
107
+
108
+ update_manifest()
109
+ chip = get_chip("default")
110
+ for graph_info in config['graph_chips']:
111
+ file_path = graph_info['path']
112
+ graph_chip = Chip(design='')
113
+ graph_chip.read_manifest(file_path)
114
+ graph_chip.unset('arg', 'step')
115
+ graph_chip.unset('arg', 'index')
116
+
117
+ if graph_info['cwd']:
118
+ graph_chip.cwd = graph_info['cwd']
119
+
120
+ add_chip(os.path.basename(file_path), graph_chip)
121
+
122
+ chip_step = chip.get('arg', 'step')
123
+ chip_index = chip.get('arg', 'index')
124
+
125
+ if chip_step and chip_index:
126
+ set_key(SELECTED_NODE, f'{chip_step}{chip_index}')
127
+
128
+ chip = get_chip("default")
129
+ chip.unset('arg', 'step')
130
+ chip.unset('arg', 'index')
131
+
132
+ if not get_key(SELECTED_JOB):
133
+ set_key(SELECTED_JOB, "default")
134
+
135
+
136
+ def setup():
137
+ with streamlit.empty():
138
+ # get width
139
+ set_key(UI_WIDTH, streamlit_javascript.st_javascript("window.innerWidth"))
140
+ # replace with a empty container to avoid adding a gap at the top
141
+ streamlit.empty()
142
+
143
+ set_key(NODE_SOURCE, None)
144
+
145
+
146
+ def get_chip(job=None):
147
+ if not job:
148
+ job = get_key(SELECTED_JOB)
149
+ return get_key(LOADED_CHIPS)[job]
150
+
151
+
152
+ def add_chip(name, chip):
153
+ streamlit.session_state[LOADED_CHIPS][name] = chip
154
+
155
+
156
+ def get_chips():
157
+ chips = list(get_key(LOADED_CHIPS).keys())
158
+ chips.remove('default')
159
+ chips.insert(0, 'default')
160
+ return chips
161
+
162
+
163
+ def get_selected_node():
164
+ if get_key(NODE_SOURCE) == "flowgraph":
165
+ return get_key(SELECTED_FLOWGRAPH_NODE)
166
+
167
+ if get_key(NODE_SOURCE) == "selector":
168
+ return get_key(SELECTED_SELECTOR_NODE)
169
+
170
+ return get_key(SELECTED_NODE)
171
+
172
+
173
+ def get_key(key):
174
+ return streamlit.session_state[key]
175
+
176
+
177
+ def set_key(key, value):
178
+ changed = value != streamlit.session_state[key]
179
+ if changed:
180
+ debug_print("set_key()", key, "changed", streamlit.session_state[key], "->", value)
181
+ streamlit.session_state[key] = value
182
+ return True
183
+ return False
184
+
185
+
186
+ def del_key(key):
187
+ debug_print("del_key()", key)
188
+ if key in streamlit.session_state:
189
+ del streamlit.session_state[key]
190
+
191
+
192
+ def compute_component_size(minimum, requested_px):
193
+ ui_width = get_key(UI_WIDTH)
194
+
195
+ if ui_width > 0:
196
+ return min(requested_px / ui_width, minimum)
197
+
198
+ return minimum
199
+
200
+
201
+ def debug_print(*args):
202
+ if not _DEBUG:
203
+ return
204
+
205
+ print(*args)
206
+
207
+
208
+ def debug_print_state():
209
+ if not _DEBUG:
210
+ return
211
+
212
+ for n, key in enumerate(sorted(streamlit.session_state.keys())):
213
+ value = streamlit.session_state[key]
214
+ print("state", n, key, type(value), value)
215
+ print()
@@ -0,0 +1,73 @@
1
+ from siliconcompiler import NodeStatus
2
+ from siliconcompiler.flowgraph import _get_flowgraph_nodes
3
+
4
+ from pathlib import Path
5
+
6
+
7
+ def get_chip_cwd(chip, manifest):
8
+ build_dir = Path(chip.get('option', 'builddir'))
9
+
10
+ manifest_path = Path(manifest)
11
+ for path in manifest_path.parents:
12
+ if build_dir.name == path.name:
13
+ return str(path.parent)
14
+
15
+ return None
16
+
17
+
18
+ def make_node_to_step_index_map(chip, metric_dataframe):
19
+ '''
20
+ Returns a map from the name of a node to the associated step, index pair.
21
+
22
+ Args:
23
+ metric_dataframe (pandas.DataFrame) : A dataframe full of all metrics and all
24
+ nodes of the selected chip
25
+ '''
26
+ node_to_step_index_map = {}
27
+ for step, index in _get_flowgraph_nodes(chip, chip.get('option', 'flow')):
28
+ node_to_step_index_map[f'{step}{index}'] = (step, index)
29
+
30
+ # concatenate step and index
31
+ metric_dataframe.columns = metric_dataframe.columns.map(lambda x: f'{x[0]}{x[1]}')
32
+ return node_to_step_index_map, metric_dataframe
33
+
34
+
35
+ def make_metric_to_metric_unit_map(metric_dataframe):
36
+ '''
37
+ Returns a map from the name of a metric to the associated metric and unit in
38
+ the form f'{x[0]} ({x[1]})'
39
+
40
+ Args:
41
+ metric_dataframe (pandas.DataFrame) : A dataframe full of all metrics and all
42
+ nodes of the selected chip.
43
+ '''
44
+ metric_to_metric_unit_map = {}
45
+ for metric, unit in metric_dataframe.index.tolist():
46
+ if unit != '':
47
+ metric_to_metric_unit_map[f'{metric} ({unit})'] = metric
48
+ else:
49
+ metric_to_metric_unit_map[metric] = metric
50
+ # concatenate metric and unit
51
+ metric_dataframe.index = metric_dataframe.index.map(lambda x: f'{x[0]} ({x[1]})'
52
+ if x[1] else x[0])
53
+ return metric_to_metric_unit_map, metric_dataframe
54
+
55
+
56
+ def is_running(chip):
57
+ for step, index in _get_flowgraph_nodes(chip, chip.get('option', 'flow')):
58
+ state = chip.get('record', 'status', step=step, index=index)
59
+ if not NodeStatus.is_done(state):
60
+ return True
61
+ return False
62
+
63
+
64
+ def generate_metric_dataframe(chip):
65
+ from siliconcompiler.report import report
66
+
67
+ metric_dataframe = report.make_metric_dataframe(chip)
68
+ node_to_step_index_map, metric_dataframe = \
69
+ make_node_to_step_index_map(chip, metric_dataframe)
70
+ metric_to_metric_unit_map, metric_dataframe = \
71
+ make_metric_to_metric_unit_map(metric_dataframe)
72
+
73
+ return metric_dataframe, node_to_step_index_map, metric_to_metric_unit_map
@@ -0,0 +1,120 @@
1
+ import gzip
2
+ import os
3
+ from siliconcompiler import utils, sc_open
4
+
5
+
6
+ def is_file_is_binary(path, compressed):
7
+ # Read first chunk and check for non characters
8
+ try:
9
+ if compressed:
10
+ with gzip.open(path, 'rt') as f:
11
+ f.read(8196)
12
+ else:
13
+ with open(path, "r") as f:
14
+ f.read(8196)
15
+ except UnicodeDecodeError:
16
+ return True
17
+ return False
18
+
19
+
20
+ def read_file(path, max_lines):
21
+ _, compressed_file_extension = os.path.splitext(path.lower())
22
+ file_info = []
23
+ honor_max_file = max_lines is not None
24
+
25
+ def read_file(fid):
26
+ for line in fid:
27
+ file_info.append(line.rstrip())
28
+ if honor_max_file and len(file_info) >= max_lines:
29
+ file_info.append('... truncated ...')
30
+ return
31
+
32
+ is_compressed = compressed_file_extension == '.gz'
33
+ if is_file_is_binary(path, is_compressed):
34
+ return "Binary file"
35
+
36
+ if is_compressed:
37
+ with gzip.open(path, 'rt') as fid:
38
+ read_file(fid)
39
+ else:
40
+ with sc_open(path) as fid:
41
+ read_file(fid)
42
+ return "\n".join(file_info)
43
+
44
+
45
+ def get_file_type(ext):
46
+ if ext in ("v", "vh", "sv", "svh", "vg"):
47
+ return "verilog"
48
+ if ext in ("vhdl", "vhd"):
49
+ return "vhdl"
50
+ if ext in ("tcl", "sdc", "xdc"):
51
+ return "tcl"
52
+ if ext in ("c", "cpp", "cc", "h"):
53
+ return "cpp"
54
+ if ext in ("csv",):
55
+ return "csv"
56
+ if ext in ("md",):
57
+ return "markdown"
58
+ if ext in ("sh",):
59
+ return "bash"
60
+ return "log"
61
+
62
+
63
+ def get_file_icon(file):
64
+ if not file:
65
+ return 'file'
66
+ ext = utils.get_file_ext(file)
67
+ file_type = get_file_type(ext)
68
+ if file.endswith('.pkg.json'):
69
+ return 'boxes'
70
+ elif ext in ('png', 'jpg', 'jpeg'):
71
+ return 'file-image'
72
+ elif ext == 'json':
73
+ return 'file-json'
74
+ elif file_type in ('verilog', 'tcl', 'vhdl', 'cpp', 'bash'):
75
+ return 'file-code'
76
+ elif ext in ('log', 'rpt', 'drc', 'warnings', 'errors'):
77
+ return 'file-text'
78
+ return 'file'
79
+
80
+
81
+ def convert_filepaths_to_select_tree(logs_and_reports):
82
+ """
83
+ Converts the logs_and_reports found to the structure
84
+ required by streamlit_tree_select. Success is predicated on the order of
85
+ logs_and_reports outlined in report.get_files.
86
+
87
+ Args:
88
+ logs_and_reports (list) : A list of 3-tuples with order of a path name,
89
+ folder in the..., and files in the....
90
+ """
91
+ if not logs_and_reports:
92
+ return []
93
+
94
+ all_files = {}
95
+ for path_name, folders, files in logs_and_reports:
96
+ all_files[path_name] = {
97
+ 'files': list(files),
98
+ 'folders': list(folders)
99
+ }
100
+
101
+ def organize_node(base_folder):
102
+ nodes = []
103
+
104
+ for folder in all_files[base_folder]['folders']:
105
+ path = os.path.join(base_folder, folder)
106
+ nodes.append({
107
+ 'value': path,
108
+ 'label': folder,
109
+ 'children': organize_node(path)
110
+ })
111
+ for file in all_files[base_folder]['files']:
112
+ nodes.append({
113
+ 'value': os.path.join(base_folder, file),
114
+ 'label': file
115
+ })
116
+
117
+ return nodes
118
+
119
+ starting_path_name = logs_and_reports[0][0]
120
+ return organize_node(starting_path_name)
@@ -0,0 +1,36 @@
1
+ import streamlit
2
+
3
+ from siliconcompiler.report.dashboard import components
4
+ from siliconcompiler.report.dashboard import layouts
5
+ from siliconcompiler.report.dashboard import state
6
+ from siliconcompiler.report.dashboard import utils
7
+
8
+ import streamlit_autorefresh
9
+
10
+
11
+ if __name__ == "__main__":
12
+ # opened by running command in siliconcompiler/apps/sc_dashboard.py
13
+ state.init()
14
+
15
+ components.setup_page()
16
+ state.setup()
17
+
18
+ layout = layouts.get_layout(state.get_key(state.APP_LAYOUT))
19
+ layout()
20
+
21
+ reload = False
22
+ if state.get_key(state.SELECTED_JOB) == 'default':
23
+ reload = state.set_key(state.IS_RUNNING, utils.is_running(state.get_chip()))
24
+
25
+ if state.get_key(state.IS_RUNNING):
26
+ update_interval = state.get_key(state.APP_RUNNING_REFRESH)
27
+ else:
28
+ update_interval = state.get_key(state.APP_STOPPED_REFRESH)
29
+
30
+ streamlit_autorefresh.st_autorefresh(interval=update_interval)
31
+
32
+ state.debug_print_state()
33
+
34
+ if reload or state.update_manifest() or state.get_key(state.APP_RERUN):
35
+ state.set_key(state.APP_RERUN, None)
36
+ streamlit.rerun()
@@ -1,3 +1,4 @@
1
+ import fnmatch
1
2
  import pandas
2
3
  import os
3
4
  from siliconcompiler import Schema
@@ -104,7 +105,8 @@ def make_manifest_helper(manifest_subsect, modified_manifest_subsect):
104
105
 
105
106
  def build_leaf(manifest_subsect):
106
107
  if manifest_subsect['pernode'] == 'never':
107
- if Schema.GLOBAL_KEY in manifest_subsect['node']:
108
+ if Schema.GLOBAL_KEY in manifest_subsect['node'] and \
109
+ Schema.GLOBAL_KEY in manifest_subsect['node'][Schema.GLOBAL_KEY]:
108
110
  value = manifest_subsect['node'][Schema.GLOBAL_KEY][Schema.GLOBAL_KEY]['value']
109
111
  else:
110
112
  value = manifest_subsect['node']['default']['default']['value']
@@ -201,7 +203,7 @@ def search_manifest_keys(manifest, key):
201
203
  '''
202
204
  filtered_manifest = {}
203
205
  for dict_key in manifest:
204
- if key in dict_key:
206
+ if fnmatch.fnmatch(dict_key, key):
205
207
  filtered_manifest[dict_key] = manifest[dict_key]
206
208
  elif isinstance(manifest[dict_key], dict):
207
209
  result = search_manifest_keys(manifest[dict_key], key)
@@ -225,8 +227,16 @@ def search_manifest_values(manifest, value):
225
227
  result = search_manifest_values(manifest[key], value)
226
228
  if result: # result is non-empty
227
229
  filtered_manifest[key] = result
228
- elif isinstance(manifest[key], str) and value in manifest[key]:
229
- filtered_manifest[key] = manifest[key]
230
+ else:
231
+ if manifest[key] is None:
232
+ continue
233
+
234
+ if isinstance(manifest[key], (list, tuple)):
235
+ if fnmatch.filter([str(v) for v in manifest[key]], value):
236
+ filtered_manifest[key] = manifest[key]
237
+ else:
238
+ if fnmatch.fnmatch(str(manifest[key]), value):
239
+ filtered_manifest[key] = manifest[key]
230
240
  return filtered_manifest
231
241
 
232
242
 
@@ -251,8 +261,12 @@ def search_manifest(manifest, key_search=None, value_search=None):
251
261
  '''
252
262
  return_manifest = manifest
253
263
  if key_search:
264
+ if '*' not in key_search or '?' not in key_search:
265
+ key_search = f'*{key_search}*'
254
266
  return_manifest = search_manifest_keys(return_manifest, key_search)
255
267
  if value_search:
268
+ if '*' not in value_search or '?' not in value_search:
269
+ value_search = f'*{value_search}*'
256
270
  return_manifest = search_manifest_values(return_manifest, value_search)
257
271
  return return_manifest
258
272
 
@@ -286,7 +300,11 @@ def get_metrics_source(chip, step, index):
286
300
  '''
287
301
  file_to_metric = {}
288
302
  tool, task = get_tool_task(chip, step, index)
303
+ if not chip.valid('tool', tool, 'task', task, 'report'):
304
+ return file_to_metric
305
+
289
306
  metrics = chip.getkeys('tool', tool, 'task', task, 'report')
307
+
290
308
  for metric in metrics:
291
309
  sources = chip.get('tool', tool, 'task', task, 'report', metric, step=step, index=index)
292
310
  for source in sources:
@@ -134,6 +134,10 @@ def _finalize_run(chip, environment):
134
134
  filepath = os.path.join(chip.getworkdir(), f"{chip.design}.pkg.json")
135
135
  chip.write_manifest(filepath)
136
136
 
137
+ # Update dashboard
138
+ if chip._dash:
139
+ chip._dash.update_manifest()
140
+
137
141
  send_messages.send(chip, 'summary', None, None)
138
142
 
139
143
 
@@ -278,6 +282,11 @@ def _local_process(chip, flow):
278
282
  processes = {}
279
283
  local_processes = []
280
284
  _prepare_nodes(chip, nodes_to_run, processes, local_processes, flow)
285
+
286
+ # Update dashboard before run begins
287
+ if chip._dash:
288
+ chip._dash.update_manifest()
289
+
281
290
  try:
282
291
  _launch_nodes(chip, nodes_to_run, processes, local_processes)
283
292
  except KeyboardInterrupt:
@@ -985,6 +994,8 @@ def _check_logfile(chip, step, index, quiet=False, run_func=None):
985
994
  Check log file (must be after post-process)
986
995
  '''
987
996
  if run_func is None:
997
+ tool, task = get_tool_task(chip, step, index)
998
+
988
999
  log_file = os.path.join(chip.getworkdir(step=step, index=index), f'{step}.log')
989
1000
  matches = check_logfile(chip, step=step, index=index,
990
1001
  display=not quiet,
@@ -994,13 +1005,27 @@ def _check_logfile(chip, step, index, quiet=False, run_func=None):
994
1005
  if errors is None:
995
1006
  errors = 0
996
1007
  errors += matches['errors']
997
- record_metric(chip, step, index, 'errors', errors, f'{step}.log')
1008
+
1009
+ sources = [f'{step}.log']
1010
+ if chip.valid('tool', tool, 'task', task, 'regex', 'errors'):
1011
+ if chip.get('tool', tool, 'task', task, 'regex', 'errors',
1012
+ step=step, index=index):
1013
+ sources.append(f'{step}.errors')
1014
+
1015
+ record_metric(chip, step, index, 'errors', errors, sources)
998
1016
  if 'warnings' in matches:
999
1017
  warnings = chip.get('metric', 'warnings', step=step, index=index)
1000
1018
  if warnings is None:
1001
1019
  warnings = 0
1002
1020
  warnings += matches['warnings']
1003
- record_metric(chip, step, index, 'warnings', warnings, f'{step}.log')
1021
+
1022
+ sources = [f'{step}.log']
1023
+ if chip.valid('tool', tool, 'task', task, 'regex', 'warnings'):
1024
+ if chip.get('tool', tool, 'task', task, 'regex', 'warnings',
1025
+ step=step, index=index):
1026
+ sources.append(f'{step}.warnings')
1027
+
1028
+ record_metric(chip, step, index, 'warnings', warnings, sources)
1004
1029
 
1005
1030
 
1006
1031
  def _executenode(chip, step, index, replay):
@@ -1354,16 +1379,16 @@ def _prepare_nodes(chip, nodes_to_run, processes, local_processes, flow):
1354
1379
  def _check_node_dependencies(chip, node, deps, deps_was_successful):
1355
1380
  had_deps = len(deps) > 0
1356
1381
  step, index = node
1357
- tool, task = get_tool_task(chip, step, index)
1382
+ tool, _ = get_tool_task(chip, step, index)
1358
1383
 
1359
1384
  # Clear any nodes that have finished from dependency list.
1360
1385
  for in_step, in_index in list(deps):
1361
1386
  in_status = chip.get('record', 'status', step=in_step, index=in_index)
1362
- if in_status != NodeStatus.PENDING:
1387
+ if NodeStatus.is_done(in_status):
1363
1388
  deps.remove((in_step, in_index))
1364
1389
  if in_status == NodeStatus.SUCCESS:
1365
1390
  deps_was_successful[node] = True
1366
- if in_status == NodeStatus.ERROR:
1391
+ if NodeStatus.is_error(in_status):
1367
1392
  # Fail if any dependency failed for non-builtin task
1368
1393
  if tool != 'builtin':
1369
1394
  deps.clear()
@@ -1418,7 +1443,7 @@ def _launch_nodes(chip, nodes_to_run, processes, local_processes):
1418
1443
  _get_callback('pre_run')(chip)
1419
1444
 
1420
1445
  while len(nodes_to_run) > 0 or len(running_nodes) > 0:
1421
- _process_completed_nodes(chip, processes, running_nodes)
1446
+ changed = _process_completed_nodes(chip, processes, running_nodes)
1422
1447
 
1423
1448
  # Check for new nodes that can be launched.
1424
1449
  for node, deps in list(nodes_to_run.items()):
@@ -1440,6 +1465,9 @@ def _launch_nodes(chip, nodes_to_run, processes, local_processes):
1440
1465
  if _get_callback('pre_node'):
1441
1466
  _get_callback('pre_node')(chip, *node)
1442
1467
 
1468
+ chip.set('record', 'status', NodeStatus.RUNNING, step=node[0], index=node[1])
1469
+ changed = True
1470
+
1443
1471
  processes[node].start()
1444
1472
  del nodes_to_run[node]
1445
1473
  running_nodes[node] = requested_threads
@@ -1452,11 +1480,16 @@ def _launch_nodes(chip, nodes_to_run, processes, local_processes):
1452
1480
  raise SiliconCompilerError(
1453
1481
  'Nodes left to run, but no running nodes. From/to may be invalid.', chip=chip)
1454
1482
 
1483
+ if chip._dash and changed:
1484
+ # Update dashboard if the manifest changed
1485
+ chip._dash.update_manifest()
1486
+
1455
1487
  # TODO: exponential back-off with max?
1456
1488
  time.sleep(0.1)
1457
1489
 
1458
1490
 
1459
1491
  def _process_completed_nodes(chip, processes, running_nodes):
1492
+ changed = False
1460
1493
  for node in list(running_nodes.keys()):
1461
1494
  if not processes[node].is_alive():
1462
1495
  step, index = node
@@ -1477,9 +1510,13 @@ def _process_completed_nodes(chip, processes, running_nodes):
1477
1510
 
1478
1511
  chip.set('record', 'status', status, step=step, index=index)
1479
1512
 
1513
+ changed = True
1514
+
1480
1515
  if _get_callback('post_node'):
1481
1516
  _get_callback('post_node')(chip, *node)
1482
1517
 
1518
+ return changed
1519
+
1483
1520
 
1484
1521
  def _check_nodes_status(chip, flow):
1485
1522
  def success(node):
@@ -628,7 +628,7 @@ class Schema:
628
628
  return copy.deepcopy(cfg)
629
629
 
630
630
  ###########################################################################
631
- def valid(self, *args, default_valid=False, job=None):
631
+ def valid(self, *args, default_valid=False, job=None, check_complete=False):
632
632
  """
633
633
  Checks validity of a keypath.
634
634
 
@@ -653,7 +653,9 @@ class Schema:
653
653
  cfg = cfg[default]
654
654
  else:
655
655
  return False
656
- return Schema._is_leaf(cfg)
656
+ if check_complete:
657
+ return Schema._is_leaf(cfg)
658
+ return True
657
659
 
658
660
  ##########################################################################
659
661
  def has_field(self, *args):
@@ -1,8 +1,9 @@
1
- proc sc_collect_pin_constraints { \
2
- placement_pins_arg \
3
- ordered_pins_arg \
4
- sc_side_layer_func \
5
- { print_func puts } } {
1
+ proc sc_collect_pin_constraints {
2
+ placement_pins_arg
3
+ ordered_pins_arg
4
+ sc_side_layer_func
5
+ { print_func puts }
6
+ } {
6
7
  upvar 1 $placement_pins_arg placement_pins
7
8
  upvar 1 $ordered_pins_arg ordered_pins
8
9
 
@@ -1,4 +1,5 @@
1
1
  from siliconcompiler.tools._common import input_provides, add_common_file, get_tool_task
2
+ from siliconcompiler.tools._common.asic import set_tool_task_var
2
3
  from siliconcompiler.tools.openroad.openroad import setup as setup_tool
3
4
  from siliconcompiler.tools.openroad.openroad import build_pex_corners
4
5
  from siliconcompiler.tools.openroad.openroad import post_process as or_post_process
@@ -46,6 +47,10 @@ def setup(chip):
46
47
  'script to insert the padring',
47
48
  field='help')
48
49
 
50
+ set_tool_task_var(chip, param_key='remove_synth_buffers',
51
+ default_value=True,
52
+ schelp='remove buffers inserted by synthesis')
53
+
49
54
  snap = chip.get('tool', tool, 'task', task, 'var', 'ifp_snap_strategy',
50
55
  step=step, index=index)[0]
51
56
  snaps_allowed = ('none', 'site', 'manufacturing_grid')