siliconcompiler 0.34.1__py3-none-any.whl → 0.34.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/__init__.py +23 -4
- siliconcompiler/__main__.py +1 -7
- siliconcompiler/_metadata.py +1 -1
- siliconcompiler/apps/_common.py +104 -23
- siliconcompiler/apps/sc.py +4 -8
- siliconcompiler/apps/sc_dashboard.py +6 -4
- siliconcompiler/apps/sc_install.py +10 -6
- siliconcompiler/apps/sc_issue.py +7 -5
- siliconcompiler/apps/sc_remote.py +1 -1
- siliconcompiler/apps/sc_server.py +9 -14
- siliconcompiler/apps/sc_show.py +7 -6
- siliconcompiler/apps/smake.py +130 -94
- siliconcompiler/apps/utils/replay.py +4 -7
- siliconcompiler/apps/utils/summarize.py +3 -5
- siliconcompiler/asic.py +420 -0
- siliconcompiler/checklist.py +25 -2
- siliconcompiler/cmdlineschema.py +534 -0
- siliconcompiler/constraints/__init__.py +17 -0
- siliconcompiler/constraints/asic_component.py +378 -0
- siliconcompiler/constraints/asic_floorplan.py +449 -0
- siliconcompiler/constraints/asic_pins.py +489 -0
- siliconcompiler/constraints/asic_timing.py +517 -0
- siliconcompiler/core.py +10 -35
- siliconcompiler/data/templates/tcl/manifest.tcl.j2 +8 -0
- siliconcompiler/dependencyschema.py +96 -202
- siliconcompiler/design.py +327 -241
- siliconcompiler/filesetschema.py +250 -0
- siliconcompiler/flowgraph.py +298 -106
- siliconcompiler/fpga.py +124 -1
- siliconcompiler/library.py +331 -0
- siliconcompiler/metric.py +327 -92
- siliconcompiler/metrics/__init__.py +7 -0
- siliconcompiler/metrics/asic.py +245 -0
- siliconcompiler/metrics/fpga.py +220 -0
- siliconcompiler/package/__init__.py +391 -67
- siliconcompiler/package/git.py +92 -16
- siliconcompiler/package/github.py +114 -22
- siliconcompiler/package/https.py +79 -16
- siliconcompiler/packageschema.py +341 -16
- siliconcompiler/pathschema.py +255 -0
- siliconcompiler/pdk.py +566 -1
- siliconcompiler/project.py +1460 -0
- siliconcompiler/record.py +38 -1
- siliconcompiler/remote/__init__.py +5 -2
- siliconcompiler/remote/client.py +11 -6
- siliconcompiler/remote/schema.py +5 -23
- siliconcompiler/remote/server.py +41 -54
- siliconcompiler/report/__init__.py +3 -3
- siliconcompiler/report/dashboard/__init__.py +48 -14
- siliconcompiler/report/dashboard/cli/__init__.py +99 -21
- siliconcompiler/report/dashboard/cli/board.py +364 -179
- siliconcompiler/report/dashboard/web/__init__.py +90 -12
- siliconcompiler/report/dashboard/web/components/__init__.py +219 -240
- siliconcompiler/report/dashboard/web/components/flowgraph.py +49 -26
- siliconcompiler/report/dashboard/web/components/graph.py +139 -100
- siliconcompiler/report/dashboard/web/layouts/__init__.py +29 -1
- siliconcompiler/report/dashboard/web/layouts/_common.py +38 -2
- siliconcompiler/report/dashboard/web/layouts/vertical_flowgraph.py +39 -26
- siliconcompiler/report/dashboard/web/layouts/vertical_flowgraph_node_tab.py +50 -50
- siliconcompiler/report/dashboard/web/layouts/vertical_flowgraph_sac_tabs.py +49 -46
- siliconcompiler/report/dashboard/web/state.py +141 -14
- siliconcompiler/report/dashboard/web/utils/__init__.py +79 -16
- siliconcompiler/report/dashboard/web/utils/file_utils.py +74 -11
- siliconcompiler/report/dashboard/web/viewer.py +25 -1
- siliconcompiler/report/report.py +5 -2
- siliconcompiler/report/summary_image.py +29 -11
- siliconcompiler/scheduler/__init__.py +9 -1
- siliconcompiler/scheduler/docker.py +81 -4
- siliconcompiler/scheduler/run_node.py +37 -20
- siliconcompiler/scheduler/scheduler.py +211 -36
- siliconcompiler/scheduler/schedulernode.py +394 -60
- siliconcompiler/scheduler/send_messages.py +77 -29
- siliconcompiler/scheduler/slurm.py +76 -12
- siliconcompiler/scheduler/taskscheduler.py +142 -21
- siliconcompiler/schema/__init__.py +0 -4
- siliconcompiler/schema/baseschema.py +338 -59
- siliconcompiler/schema/editableschema.py +14 -6
- siliconcompiler/schema/journal.py +28 -17
- siliconcompiler/schema/namedschema.py +22 -14
- siliconcompiler/schema/parameter.py +89 -28
- siliconcompiler/schema/parametertype.py +2 -0
- siliconcompiler/schema/parametervalue.py +258 -15
- siliconcompiler/schema/safeschema.py +25 -2
- siliconcompiler/schema/schema_cfg.py +23 -19
- siliconcompiler/schema/utils.py +2 -2
- siliconcompiler/schema_obj.py +24 -5
- siliconcompiler/tool.py +1131 -265
- siliconcompiler/tools/bambu/__init__.py +41 -0
- siliconcompiler/tools/builtin/concatenate.py +2 -2
- siliconcompiler/tools/builtin/minimum.py +2 -1
- siliconcompiler/tools/builtin/mux.py +2 -1
- siliconcompiler/tools/builtin/nop.py +2 -1
- siliconcompiler/tools/builtin/verify.py +2 -1
- siliconcompiler/tools/klayout/__init__.py +95 -0
- siliconcompiler/tools/openroad/__init__.py +289 -0
- siliconcompiler/tools/openroad/scripts/apr/preamble.tcl +3 -0
- siliconcompiler/tools/openroad/scripts/apr/sc_detailed_route.tcl +7 -2
- siliconcompiler/tools/openroad/scripts/apr/sc_global_route.tcl +8 -4
- siliconcompiler/tools/openroad/scripts/apr/sc_init_floorplan.tcl +9 -5
- siliconcompiler/tools/openroad/scripts/common/write_images.tcl +5 -1
- siliconcompiler/tools/slang/__init__.py +1 -1
- siliconcompiler/tools/slang/elaborate.py +2 -1
- siliconcompiler/tools/vivado/scripts/sc_run.tcl +1 -1
- siliconcompiler/tools/vivado/scripts/sc_syn_fpga.tcl +8 -1
- siliconcompiler/tools/vivado/syn_fpga.py +6 -0
- siliconcompiler/tools/vivado/vivado.py +35 -2
- siliconcompiler/tools/vpr/__init__.py +150 -0
- siliconcompiler/tools/yosys/__init__.py +369 -1
- siliconcompiler/tools/yosys/scripts/procs.tcl +0 -1
- siliconcompiler/toolscripts/_tools.json +5 -10
- siliconcompiler/utils/__init__.py +66 -0
- siliconcompiler/utils/flowgraph.py +2 -2
- siliconcompiler/utils/issue.py +2 -1
- siliconcompiler/utils/logging.py +14 -0
- siliconcompiler/utils/multiprocessing.py +256 -0
- siliconcompiler/utils/showtools.py +10 -0
- {siliconcompiler-0.34.1.dist-info → siliconcompiler-0.34.3.dist-info}/METADATA +6 -6
- {siliconcompiler-0.34.1.dist-info → siliconcompiler-0.34.3.dist-info}/RECORD +122 -115
- {siliconcompiler-0.34.1.dist-info → siliconcompiler-0.34.3.dist-info}/entry_points.txt +3 -0
- siliconcompiler/schema/cmdlineschema.py +0 -250
- siliconcompiler/schema/packageschema.py +0 -101
- siliconcompiler/toolscripts/rhel8/install-slang.sh +0 -40
- siliconcompiler/toolscripts/rhel9/install-slang.sh +0 -40
- siliconcompiler/toolscripts/ubuntu20/install-slang.sh +0 -47
- siliconcompiler/toolscripts/ubuntu22/install-slang.sh +0 -37
- siliconcompiler/toolscripts/ubuntu24/install-slang.sh +0 -37
- {siliconcompiler-0.34.1.dist-info → siliconcompiler-0.34.3.dist-info}/WHEEL +0 -0
- {siliconcompiler-0.34.1.dist-info → siliconcompiler-0.34.3.dist-info}/licenses/LICENSE +0 -0
- {siliconcompiler-0.34.1.dist-info → siliconcompiler-0.34.3.dist-info}/top_level.txt +0 -0
|
@@ -16,18 +16,37 @@ from siliconcompiler.report.dashboard.web import utils
|
|
|
16
16
|
|
|
17
17
|
|
|
18
18
|
class WebDashboard(AbstractDashboard):
|
|
19
|
+
"""
|
|
20
|
+
A web-based dashboard for SiliconCompiler that uses the Streamlit framework.
|
|
21
|
+
|
|
22
|
+
This class launches a Streamlit server in a separate process to provide a
|
|
23
|
+
real-time, interactive web UI for monitoring a chip's compilation flow.
|
|
24
|
+
It manages a temporary directory for passing manifests and configuration
|
|
25
|
+
between the main SC process and the Streamlit dashboard process.
|
|
26
|
+
|
|
27
|
+
Args:
|
|
28
|
+
chip (Chip): The main chip object to display.
|
|
29
|
+
port (int, optional): The port to run the Streamlit server on. If not
|
|
30
|
+
provided, it will search for an available port.
|
|
31
|
+
graph_chips (list, optional): A list of other chip objects to include
|
|
32
|
+
for comparison or display in the dashboard.
|
|
33
|
+
"""
|
|
19
34
|
__port = 8501
|
|
20
35
|
|
|
21
36
|
@staticmethod
|
|
22
37
|
def __signal_handler(signal, frame):
|
|
38
|
+
"""A no-op signal handler to gracefully manage shutdown."""
|
|
23
39
|
# used to avoid issues during shutdown
|
|
24
40
|
pass
|
|
25
41
|
|
|
26
42
|
def __init__(self, chip, port=None, graph_chips=None):
|
|
43
|
+
"""
|
|
44
|
+
Initializes the WebDashboard.
|
|
45
|
+
"""
|
|
27
46
|
try:
|
|
28
47
|
from streamlit.web import bootstrap # noqa: F401
|
|
29
48
|
except ModuleNotFoundError:
|
|
30
|
-
raise NotImplementedError('streamlit is not available')
|
|
49
|
+
raise NotImplementedError('streamlit is not available for dashboard')
|
|
31
50
|
|
|
32
51
|
super().__init__(chip)
|
|
33
52
|
|
|
@@ -46,6 +65,7 @@ class WebDashboard(AbstractDashboard):
|
|
|
46
65
|
dirname = os.path.dirname(__file__)
|
|
47
66
|
self.__streamlit_file = os.path.join(dirname, 'viewer.py')
|
|
48
67
|
|
|
68
|
+
# Configure Streamlit server options
|
|
49
69
|
self.__streamlit_args = [
|
|
50
70
|
("browser.gatherUsageStats", False),
|
|
51
71
|
("browser.serverPort", self.__port),
|
|
@@ -57,11 +77,7 @@ class WebDashboard(AbstractDashboard):
|
|
|
57
77
|
if "PYTEST_CURRENT_TEST" in os.environ:
|
|
58
78
|
self.__streamlit_args.append(("server.headless", True))
|
|
59
79
|
|
|
60
|
-
#
|
|
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
|
|
80
|
+
# Prepare configuration for any additional chips to be displayed
|
|
65
81
|
self.__graph_chips = []
|
|
66
82
|
graph_chips_config = []
|
|
67
83
|
if graph_chips:
|
|
@@ -80,6 +96,7 @@ class WebDashboard(AbstractDashboard):
|
|
|
80
96
|
chip_object_and_name['cfg_path'])
|
|
81
97
|
})
|
|
82
98
|
|
|
99
|
+
# Final configuration object to be passed to the Streamlit process
|
|
83
100
|
self.__config = {
|
|
84
101
|
"manifest": self.__manifest,
|
|
85
102
|
"lock": self.__manifest_lock,
|
|
@@ -91,27 +108,43 @@ class WebDashboard(AbstractDashboard):
|
|
|
91
108
|
|
|
92
109
|
self.__lock = fasteners.InterProcessLock(self.__manifest_lock)
|
|
93
110
|
|
|
111
|
+
# Ensure cleanup is called on exit
|
|
94
112
|
atexit.register(self.__cleanup)
|
|
95
113
|
|
|
96
114
|
def open_dashboard(self):
|
|
115
|
+
"""
|
|
116
|
+
Starts the Streamlit dashboard server in a new process.
|
|
117
|
+
|
|
118
|
+
This method writes the necessary configuration and manifests, then
|
|
119
|
+
launches the Streamlit bootstrap function in a separate process.
|
|
120
|
+
"""
|
|
121
|
+
# Write the configuration file for the Streamlit app to read
|
|
97
122
|
with open(self.__get_config_file(), 'w') as f:
|
|
98
123
|
json.dump(self.__config, f, indent=4)
|
|
99
124
|
|
|
100
125
|
self.update_manifest()
|
|
101
|
-
|
|
102
126
|
self.update_graph_manifests()
|
|
103
127
|
|
|
128
|
+
# Launch Streamlit in a separate process
|
|
104
129
|
self.__dashboard = multiprocessing.Process(
|
|
105
130
|
target=self._run_streamlit_bootstrap)
|
|
106
131
|
|
|
132
|
+
# Temporarily override the SIGINT handler for graceful shutdown
|
|
107
133
|
self.__signal_handler = signal.signal(signal.SIGINT, WebDashboard.__signal_handler)
|
|
108
134
|
|
|
109
135
|
self.__dashboard.start()
|
|
110
136
|
|
|
111
137
|
def update_manifest(self, payload=None):
|
|
138
|
+
"""
|
|
139
|
+
Writes the main chip's manifest to the shared temporary directory.
|
|
140
|
+
|
|
141
|
+
This method is the primary way data is passed from the main process
|
|
142
|
+
to the dashboard process. It uses a file lock to prevent race conditions.
|
|
143
|
+
"""
|
|
112
144
|
if not self.__manifest:
|
|
113
145
|
return
|
|
114
146
|
|
|
147
|
+
# Write to a new file and then move it to be atomic
|
|
115
148
|
new_file = f"{self.__manifest}.new.json"
|
|
116
149
|
self.__chip.write_manifest(new_file)
|
|
117
150
|
|
|
@@ -119,71 +152,108 @@ class WebDashboard(AbstractDashboard):
|
|
|
119
152
|
shutil.move(new_file, self.__manifest)
|
|
120
153
|
|
|
121
154
|
def update_graph_manifests(self):
|
|
155
|
+
"""
|
|
156
|
+
Writes the manifests for all additional graph chips to the shared directory.
|
|
157
|
+
"""
|
|
122
158
|
for chip_object_and_name in self.__graph_chips:
|
|
123
159
|
chip = chip_object_and_name['chip']
|
|
124
160
|
file_path = chip_object_and_name['name']
|
|
125
161
|
chip.write_manifest(file_path)
|
|
126
162
|
|
|
127
163
|
def __get_config_file(self):
|
|
164
|
+
"""Returns the path to the dashboard's JSON configuration file."""
|
|
128
165
|
return os.path.join(self.__directory, 'config.json')
|
|
129
166
|
|
|
130
167
|
def is_running(self):
|
|
168
|
+
"""
|
|
169
|
+
Checks if the dashboard server process is currently running.
|
|
170
|
+
|
|
171
|
+
Returns:
|
|
172
|
+
bool: True if the dashboard is running, False otherwise.
|
|
173
|
+
"""
|
|
131
174
|
if self.__dashboard is None:
|
|
132
175
|
return False
|
|
133
176
|
|
|
134
177
|
if self.__dashboard.is_alive():
|
|
135
178
|
return True
|
|
136
179
|
|
|
180
|
+
# Process is no longer alive, so clean up
|
|
137
181
|
self.__dashboard = None
|
|
138
182
|
self.__manifest = None
|
|
139
183
|
return False
|
|
140
184
|
|
|
141
185
|
def end_of_run(self):
|
|
186
|
+
"""A placeholder method to fulfill the AbstractDashboard interface."""
|
|
142
187
|
pass
|
|
143
188
|
|
|
144
189
|
def stop(self):
|
|
190
|
+
"""
|
|
191
|
+
Stops the dashboard server process.
|
|
192
|
+
"""
|
|
145
193
|
if not self.is_running():
|
|
146
194
|
return
|
|
147
195
|
|
|
196
|
+
# Terminate the process
|
|
148
197
|
while self.__dashboard.is_alive():
|
|
149
198
|
self.__dashboard.terminate()
|
|
150
199
|
self._sleep()
|
|
151
200
|
|
|
201
|
+
# Restore the original signal handler
|
|
152
202
|
if self.__signal_handler:
|
|
153
203
|
signal.signal(signal.SIGINT, self.__signal_handler)
|
|
154
204
|
|
|
205
|
+
# Clean up state
|
|
155
206
|
self.__dashboard = None
|
|
156
207
|
self.__manifest = None
|
|
157
208
|
self.__signal_handler = None
|
|
158
209
|
|
|
159
210
|
def wait(self):
|
|
160
|
-
|
|
211
|
+
"""
|
|
212
|
+
Waits for the dashboard server process to terminate.
|
|
213
|
+
"""
|
|
214
|
+
if self.is_running():
|
|
215
|
+
self.__dashboard.join()
|
|
161
216
|
|
|
162
217
|
def _sleep(self):
|
|
218
|
+
"""Pauses execution for a short duration."""
|
|
163
219
|
time.sleep(self.__sleep_time)
|
|
164
220
|
|
|
165
221
|
def _run_streamlit_bootstrap(self):
|
|
222
|
+
"""
|
|
223
|
+
The target function for the multiprocessing.Process.
|
|
224
|
+
|
|
225
|
+
This function configures and runs the Streamlit application.
|
|
226
|
+
"""
|
|
166
227
|
from streamlit.web import bootstrap
|
|
167
228
|
from streamlit import config as _config
|
|
168
229
|
|
|
230
|
+
# Set all configured Streamlit options
|
|
169
231
|
for config, val in self.__streamlit_args:
|
|
170
232
|
_config.set_option(config, val)
|
|
171
233
|
|
|
234
|
+
# Run the Streamlit script
|
|
172
235
|
bootstrap.run(self.__streamlit_file,
|
|
173
236
|
False,
|
|
174
237
|
[self.__get_config_file()],
|
|
175
238
|
flag_options={})
|
|
176
239
|
|
|
177
240
|
def __run_streamlit_subproc(self):
|
|
241
|
+
"""
|
|
242
|
+
An alternative (unused) method to run Streamlit using a subprocess.
|
|
243
|
+
"""
|
|
178
244
|
cmd = ['streamlit', 'run',
|
|
179
245
|
self.__streamlit_file, self.__get_config_file()]
|
|
180
246
|
for config, val in self.__streamlit_args:
|
|
181
247
|
cmd.append(f'--{config}')
|
|
182
|
-
cmd.append(val)
|
|
248
|
+
cmd.append(str(val))
|
|
183
249
|
|
|
184
250
|
subprocess.Popen(cmd)
|
|
185
251
|
|
|
186
252
|
def __cleanup(self):
|
|
253
|
+
"""
|
|
254
|
+
Cleans up resources by stopping the dashboard and removing the temp directory.
|
|
255
|
+
This method is registered with atexit to be called on program exit.
|
|
256
|
+
"""
|
|
187
257
|
self.stop()
|
|
188
258
|
|
|
189
259
|
if os.path.exists(self.__directory):
|
|
@@ -191,6 +261,14 @@ class WebDashboard(AbstractDashboard):
|
|
|
191
261
|
|
|
192
262
|
@staticmethod
|
|
193
263
|
def get_next_port():
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
264
|
+
"""
|
|
265
|
+
Finds an available TCP port on the local machine.
|
|
266
|
+
|
|
267
|
+
Returns:
|
|
268
|
+
int or None: An available port number, or None if one cannot be found.
|
|
269
|
+
"""
|
|
270
|
+
try:
|
|
271
|
+
with socketserver.TCPServer(("localhost", 0), None) as s:
|
|
272
|
+
return s.server_address[1]
|
|
273
|
+
except OSError:
|
|
274
|
+
return None
|