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
siliconcompiler/metric.py
CHANGED
|
@@ -1,38 +1,144 @@
|
|
|
1
|
+
import shutil
|
|
2
|
+
import sys
|
|
3
|
+
|
|
4
|
+
from typing import List, Tuple, TextIO
|
|
5
|
+
|
|
1
6
|
from siliconcompiler.schema import BaseSchema
|
|
2
7
|
from siliconcompiler.schema import EditableSchema, Parameter, PerNode, Scope
|
|
3
8
|
from siliconcompiler.schema.utils import trim
|
|
4
9
|
|
|
5
|
-
from siliconcompiler.utils
|
|
10
|
+
from siliconcompiler.utils import truncate_text, units
|
|
6
11
|
from siliconcompiler.record import RecordTime
|
|
7
12
|
|
|
8
13
|
|
|
9
14
|
class MetricSchema(BaseSchema):
|
|
15
|
+
'''
|
|
16
|
+
Schema for storing and accessing metrics collected during a run.
|
|
17
|
+
|
|
18
|
+
This class provides a structured way to define, record, and report
|
|
19
|
+
various metrics such as runtime, memory usage, and design quality
|
|
20
|
+
indicators for each step of a compilation flow.
|
|
21
|
+
'''
|
|
22
|
+
|
|
10
23
|
def __init__(self):
|
|
24
|
+
'''Initializes the MetricSchema.'''
|
|
11
25
|
super().__init__()
|
|
12
26
|
|
|
13
|
-
|
|
27
|
+
schema = EditableSchema(self)
|
|
28
|
+
|
|
29
|
+
for item, description in [
|
|
30
|
+
('errors', 'errors'),
|
|
31
|
+
('warnings', 'warnings')]:
|
|
32
|
+
schema.insert(
|
|
33
|
+
item,
|
|
34
|
+
Parameter(
|
|
35
|
+
'int',
|
|
36
|
+
scope=Scope.JOB,
|
|
37
|
+
shorthelp=f"Metric: total {item}",
|
|
38
|
+
switch=f"-metric_{item} 'step index <int>'",
|
|
39
|
+
example=[
|
|
40
|
+
f"cli: -metric_{item} 'dfm 0 0'",
|
|
41
|
+
f"api: chip.set('metric', '{item}', 0, step='dfm', index=0)"],
|
|
42
|
+
pernode=PerNode.REQUIRED,
|
|
43
|
+
help=trim(f"""Metric tracking the total number of {description} on a
|
|
44
|
+
per step and index basis.""")))
|
|
45
|
+
|
|
46
|
+
schema.insert(
|
|
47
|
+
'memory',
|
|
48
|
+
Parameter(
|
|
49
|
+
'float',
|
|
50
|
+
unit='B',
|
|
51
|
+
scope=Scope.JOB,
|
|
52
|
+
shorthelp="Metric: memory",
|
|
53
|
+
switch="-metric_memory 'step index <float>'",
|
|
54
|
+
example=[
|
|
55
|
+
"cli: -metric_memory 'dfm 0 10e9'",
|
|
56
|
+
"api: chip.set('metric', 'memory', 10e9, step='dfm', index=0)"],
|
|
57
|
+
pernode=PerNode.REQUIRED,
|
|
58
|
+
help=trim("""
|
|
59
|
+
Metric tracking total peak program memory footprint on a per
|
|
60
|
+
step and index basis.""")))
|
|
61
|
+
|
|
62
|
+
schema.insert(
|
|
63
|
+
'exetime',
|
|
64
|
+
Parameter(
|
|
65
|
+
'float',
|
|
66
|
+
unit='s',
|
|
67
|
+
scope=Scope.JOB,
|
|
68
|
+
shorthelp="Metric: exetime",
|
|
69
|
+
switch="-metric_exetime 'step index <float>'",
|
|
70
|
+
example=[
|
|
71
|
+
"cli: -metric_exetime 'dfm 0 10.0'",
|
|
72
|
+
"api: chip.set('metric', 'exetime', 10.0, step='dfm', index=0)"],
|
|
73
|
+
pernode=PerNode.REQUIRED,
|
|
74
|
+
help=trim("""
|
|
75
|
+
Metric tracking time spent by the EDA executable :keypath:`tool,<tool>,exe` on a
|
|
76
|
+
per step and index basis. It does not include the SiliconCompiler
|
|
77
|
+
runtime overhead or time waiting for I/O operations and
|
|
78
|
+
inter-processor communication to complete.""")))
|
|
79
|
+
|
|
80
|
+
schema.insert(
|
|
81
|
+
'tasktime',
|
|
82
|
+
Parameter(
|
|
83
|
+
'float',
|
|
84
|
+
unit='s',
|
|
85
|
+
scope=Scope.JOB,
|
|
86
|
+
shorthelp="Metric: tasktime",
|
|
87
|
+
switch="-metric_tasktime 'step index <float>'",
|
|
88
|
+
example=[
|
|
89
|
+
"cli: -metric_tasktime 'dfm 0 10.0'",
|
|
90
|
+
"api: chip.set('metric', 'tasktime', 10.0, step='dfm', index=0)"],
|
|
91
|
+
pernode=PerNode.REQUIRED,
|
|
92
|
+
help=trim("""
|
|
93
|
+
Metric tracking the total amount of time spent on a task from
|
|
94
|
+
beginning to end, including data transfers and pre/post
|
|
95
|
+
processing.""")))
|
|
96
|
+
|
|
97
|
+
schema.insert(
|
|
98
|
+
'totaltime',
|
|
99
|
+
Parameter(
|
|
100
|
+
'float',
|
|
101
|
+
unit='s',
|
|
102
|
+
scope=Scope.JOB,
|
|
103
|
+
shorthelp="Metric: totaltime",
|
|
104
|
+
switch="-metric_totaltime 'step index <float>'",
|
|
105
|
+
example=[
|
|
106
|
+
"cli: -metric_totaltime 'dfm 0 10.0'",
|
|
107
|
+
"api: chip.set('metric', 'totaltime', 10.0, step='dfm', index=0)"],
|
|
108
|
+
pernode=PerNode.REQUIRED,
|
|
109
|
+
help=trim("""
|
|
110
|
+
Metric tracking the total amount of time spent from the beginning
|
|
111
|
+
of the run up to and including the current step and index.""")))
|
|
14
112
|
|
|
15
113
|
def clear(self, step, index):
|
|
16
114
|
'''
|
|
17
|
-
|
|
115
|
+
Clears all saved metrics for a given step and index.
|
|
18
116
|
|
|
19
117
|
Args:
|
|
20
|
-
step (str):
|
|
21
|
-
index (str
|
|
118
|
+
step (str): The step name to clear metrics for.
|
|
119
|
+
index (str or int): The index to clear metrics for.
|
|
22
120
|
'''
|
|
23
121
|
for metric in self.getkeys():
|
|
24
122
|
self.unset(metric, step=step, index=str(index))
|
|
25
123
|
|
|
26
124
|
def record(self, step, index, metric, value, unit=None):
|
|
27
125
|
"""
|
|
28
|
-
|
|
126
|
+
Records a metric value for a specific step and index.
|
|
127
|
+
|
|
128
|
+
This method handles unit conversion if the metric is defined with a
|
|
129
|
+
unit in the schema.
|
|
29
130
|
|
|
30
131
|
Args:
|
|
31
|
-
step (str): step to record
|
|
32
|
-
index (str
|
|
33
|
-
metric (str): name of metric
|
|
34
|
-
value (int
|
|
35
|
-
unit (str): unit
|
|
132
|
+
step (str): The step to record the metric for.
|
|
133
|
+
index (str or int): The index to record the metric for.
|
|
134
|
+
metric (str): The name of the metric to record.
|
|
135
|
+
value (int or float): The value of the metric.
|
|
136
|
+
unit (str, optional): The unit of the provided value. If the schema
|
|
137
|
+
defines a unit for this metric, the value will be converted.
|
|
138
|
+
Defaults to None.
|
|
139
|
+
|
|
140
|
+
Returns:
|
|
141
|
+
The recorded value after any unit conversion.
|
|
36
142
|
"""
|
|
37
143
|
metric_unit = self.get(metric, field='unit')
|
|
38
144
|
|
|
@@ -40,18 +146,21 @@ class MetricSchema(BaseSchema):
|
|
|
40
146
|
raise ValueError(f"{metric} does not have a unit, but {unit} was supplied")
|
|
41
147
|
|
|
42
148
|
if metric_unit:
|
|
43
|
-
value = convert(value, from_unit=unit, to_unit=metric_unit)
|
|
149
|
+
value = units.convert(value, from_unit=unit, to_unit=metric_unit)
|
|
44
150
|
|
|
45
151
|
return self.set(metric, value, step=step, index=str(index))
|
|
46
152
|
|
|
47
153
|
def record_tasktime(self, step, index, record):
|
|
48
154
|
"""
|
|
49
|
-
|
|
155
|
+
Records the task time for a given node based on start and end times.
|
|
50
156
|
|
|
51
157
|
Args:
|
|
52
|
-
step (str): step
|
|
53
|
-
index (str
|
|
54
|
-
record (
|
|
158
|
+
step (str): The step of the node.
|
|
159
|
+
index (str or int): The index of the node.
|
|
160
|
+
record (RecordSchema): The record schema containing timing data.
|
|
161
|
+
|
|
162
|
+
Returns:
|
|
163
|
+
bool: True if the time was successfully recorded, False otherwise.
|
|
55
164
|
"""
|
|
56
165
|
start_time, end_time = [
|
|
57
166
|
record.get_recorded_time(step, index, RecordTime.START),
|
|
@@ -65,13 +174,19 @@ class MetricSchema(BaseSchema):
|
|
|
65
174
|
|
|
66
175
|
def record_totaltime(self, step, index, flow, record):
|
|
67
176
|
"""
|
|
68
|
-
|
|
177
|
+
Records the cumulative total time up to the end of a given node.
|
|
178
|
+
|
|
179
|
+
This method calculates the total wall-clock time by summing the
|
|
180
|
+
durations of all previously executed parallel tasks.
|
|
69
181
|
|
|
70
182
|
Args:
|
|
71
|
-
step (str): step
|
|
72
|
-
index (str
|
|
73
|
-
flow (
|
|
74
|
-
record (
|
|
183
|
+
step (str): The step of the node.
|
|
184
|
+
index (str or int): The index of the node.
|
|
185
|
+
flow (FlowgraphSchema): The flowgraph containing the nodes.
|
|
186
|
+
record (RecordSchema): The record schema containing timing data.
|
|
187
|
+
|
|
188
|
+
Returns:
|
|
189
|
+
bool: True if the time was successfully recorded, False otherwise.
|
|
75
190
|
"""
|
|
76
191
|
all_nodes = flow.get_nodes()
|
|
77
192
|
node_times = [
|
|
@@ -121,16 +236,203 @@ class MetricSchema(BaseSchema):
|
|
|
121
236
|
|
|
122
237
|
return self.record(step, index, "totaltime", total_time, unit="s")
|
|
123
238
|
|
|
239
|
+
def get_formatted_metric(self, metric: str, step: str, index: str) -> str:
|
|
240
|
+
'''
|
|
241
|
+
Retrieves and formats a metric for display.
|
|
242
|
+
|
|
243
|
+
Handles special formatting for memory (binary units), time, and adds
|
|
244
|
+
SI suffixes for other float values.
|
|
245
|
+
|
|
246
|
+
Args:
|
|
247
|
+
metric (str): The name of the metric to format.
|
|
248
|
+
step (str): The step of the metric.
|
|
249
|
+
index (str): The index of the metric.
|
|
250
|
+
|
|
251
|
+
Returns:
|
|
252
|
+
str: The formatted, human-readable metric value as a string.
|
|
253
|
+
'''
|
|
254
|
+
if metric == 'memory':
|
|
255
|
+
return units.format_binary(self.get(metric, step=step, index=index),
|
|
256
|
+
self.get(metric, field="unit"))
|
|
257
|
+
elif metric in ['exetime', 'tasktime', 'totaltime']:
|
|
258
|
+
return units.format_time(self.get(metric, step=step, index=index))
|
|
259
|
+
elif self.get(metric, field="type") == 'int':
|
|
260
|
+
return str(self.get(metric, step=step, index=index))
|
|
261
|
+
else:
|
|
262
|
+
return units.format_si(self.get(metric, step=step, index=index),
|
|
263
|
+
self.get(metric, field="unit"))
|
|
264
|
+
|
|
265
|
+
def summary_table(self,
|
|
266
|
+
nodes: List[Tuple[str, str]] = None,
|
|
267
|
+
column_width: int = 15,
|
|
268
|
+
formatted: bool = True,
|
|
269
|
+
trim_empty_metrics: bool = True):
|
|
270
|
+
'''
|
|
271
|
+
Generates a summary of metrics as a pandas DataFrame.
|
|
272
|
+
|
|
273
|
+
Args:
|
|
274
|
+
nodes (List[Tuple[str, str]], optional): A list of (step, index)
|
|
275
|
+
tuples to include in the summary. If None, all nodes with
|
|
276
|
+
metrics are included. Defaults to None.
|
|
277
|
+
column_width (int, optional): The width for each column.
|
|
278
|
+
Defaults to 15.
|
|
279
|
+
formatted (bool, optional): If True, metric values are formatted
|
|
280
|
+
for human readability. Defaults to True.
|
|
281
|
+
trim_empty_metrics (bool, optional): If True, metrics that have no
|
|
282
|
+
value for any of the specified nodes are excluded.
|
|
283
|
+
Defaults to True.
|
|
284
|
+
|
|
285
|
+
Returns:
|
|
286
|
+
pandas.DataFrame: A DataFrame containing the metric summary.
|
|
287
|
+
'''
|
|
288
|
+
from pandas import DataFrame
|
|
289
|
+
|
|
290
|
+
if not nodes:
|
|
291
|
+
nodes = set()
|
|
292
|
+
for metric in self.getkeys():
|
|
293
|
+
for value, step, index in self.get(metric, field=None).getvalues():
|
|
294
|
+
nodes.add((step, index))
|
|
295
|
+
nodes = list(sorted(nodes))
|
|
296
|
+
|
|
297
|
+
row_labels = list(self.getkeys())
|
|
298
|
+
sort_map = {metric: 0 for metric in row_labels}
|
|
299
|
+
sort_map["errors"] = -2
|
|
300
|
+
sort_map["warnings"] = -1
|
|
301
|
+
sort_map["memory"] = 1
|
|
302
|
+
sort_map["exetime"] = 2
|
|
303
|
+
sort_map["tasktime"] = 3
|
|
304
|
+
sort_map["totaltime"] = 4
|
|
305
|
+
row_labels = sorted(row_labels, key=lambda row: sort_map[row])
|
|
306
|
+
|
|
307
|
+
if trim_empty_metrics:
|
|
308
|
+
for metric in self.getkeys():
|
|
309
|
+
data = []
|
|
310
|
+
for step, index in nodes:
|
|
311
|
+
data.append(self.get(metric, step=step, index=index))
|
|
312
|
+
if all([dat is None for dat in data]):
|
|
313
|
+
row_labels.remove(metric)
|
|
314
|
+
|
|
315
|
+
if 'totaltime' in row_labels:
|
|
316
|
+
if not any([self.get('totaltime', step=step, index=index) is None
|
|
317
|
+
for step, index in nodes]):
|
|
318
|
+
nodes.sort(
|
|
319
|
+
key=lambda node: self.get('totaltime', step=node[0], index=node[1]))
|
|
320
|
+
|
|
321
|
+
# trim labels to column width
|
|
322
|
+
column_labels = ["unit"]
|
|
323
|
+
labels = [f'{step}/{index}' for step, index in nodes]
|
|
324
|
+
if labels:
|
|
325
|
+
column_width = min([column_width, max([len(label) for label in labels])])
|
|
326
|
+
|
|
327
|
+
for label in labels:
|
|
328
|
+
column_labels.append(truncate_text(label, column_width).center(column_width))
|
|
329
|
+
|
|
330
|
+
if formatted:
|
|
331
|
+
none_value = "---".center(column_width)
|
|
332
|
+
else:
|
|
333
|
+
none_value = None
|
|
334
|
+
|
|
335
|
+
data = []
|
|
336
|
+
for metric in row_labels:
|
|
337
|
+
row = [self.get(metric, field="unit") or ""]
|
|
338
|
+
for step, index in nodes:
|
|
339
|
+
value = self.get(metric, step=step, index=index)
|
|
340
|
+
if value is None:
|
|
341
|
+
value = none_value
|
|
342
|
+
else:
|
|
343
|
+
if formatted:
|
|
344
|
+
value = self.get_formatted_metric(metric, step=step, index=index)
|
|
345
|
+
value = value.center(column_width)
|
|
346
|
+
else:
|
|
347
|
+
value = self.get(metric, step=step, index=index)
|
|
348
|
+
row.append(value)
|
|
349
|
+
data.append(row)
|
|
350
|
+
|
|
351
|
+
return DataFrame(data, row_labels, column_labels)
|
|
352
|
+
|
|
353
|
+
def summary(self,
|
|
354
|
+
headers: List[Tuple[str, str]],
|
|
355
|
+
nodes: List[Tuple[str, str]] = None,
|
|
356
|
+
column_width: int = 15,
|
|
357
|
+
fd: TextIO = None) -> None:
|
|
358
|
+
'''
|
|
359
|
+
Prints a formatted summary of metrics to a file descriptor.
|
|
360
|
+
|
|
361
|
+
Args:
|
|
362
|
+
headers (List[Tuple[str, str]]): A list of (title, value) tuples
|
|
363
|
+
to print in the header section of the summary.
|
|
364
|
+
nodes (List[Tuple[str, str]], optional): A list of (step, index)
|
|
365
|
+
tuples to include. Defaults to all nodes.
|
|
366
|
+
column_width (int, optional): The width for each column in the table.
|
|
367
|
+
Defaults to 15.
|
|
368
|
+
fd (TextIO, optional): The file descriptor to write to.
|
|
369
|
+
Defaults to `sys.stdout`.
|
|
370
|
+
'''
|
|
371
|
+
header = []
|
|
372
|
+
headers.insert(0, ("SUMMARY", None))
|
|
373
|
+
if headers:
|
|
374
|
+
max_header = max([len(title) for title, _ in headers])
|
|
375
|
+
for title, value in headers:
|
|
376
|
+
if value is None:
|
|
377
|
+
header.append(f"{title:<{max_header}} :")
|
|
378
|
+
else:
|
|
379
|
+
header.append(f"{title:<{max_header}} : {value}")
|
|
380
|
+
|
|
381
|
+
max_line_width = max(4 * column_width, int(0.95*shutil.get_terminal_size().columns))
|
|
382
|
+
data = self.summary_table(nodes=nodes, column_width=column_width)
|
|
383
|
+
|
|
384
|
+
if not fd:
|
|
385
|
+
fd = sys.stdout
|
|
386
|
+
|
|
387
|
+
print("-" * max_line_width, file=fd)
|
|
388
|
+
print("\n".join(header), file=fd)
|
|
389
|
+
print(file=fd)
|
|
390
|
+
if data.empty:
|
|
391
|
+
print(" No metrics to display!", file=fd)
|
|
392
|
+
else:
|
|
393
|
+
print(data.to_string(line_width=max_line_width, col_space=3), file=fd)
|
|
394
|
+
print("-" * max_line_width, file=fd)
|
|
395
|
+
|
|
396
|
+
@classmethod
|
|
397
|
+
def _getdict_type(cls) -> str:
|
|
398
|
+
"""
|
|
399
|
+
Returns the metadata type for `getdict` serialization.
|
|
400
|
+
"""
|
|
401
|
+
|
|
402
|
+
return MetricSchema.__name__
|
|
403
|
+
|
|
404
|
+
|
|
405
|
+
class MetricSchemaTmp(MetricSchema):
|
|
406
|
+
'''
|
|
407
|
+
A temporary schema containing a wide range of common ASIC and FPGA metrics.
|
|
408
|
+
|
|
409
|
+
This class extends the base `MetricSchema` with numerous metrics related to
|
|
410
|
+
design rules, area, timing, power, and physical implementation details.
|
|
411
|
+
'''
|
|
412
|
+
|
|
413
|
+
def __init__(self):
|
|
414
|
+
'''Initializes the MetricSchemaTmp.'''
|
|
415
|
+
super().__init__()
|
|
416
|
+
|
|
417
|
+
schema_metric_tmp(self)
|
|
418
|
+
|
|
124
419
|
|
|
125
420
|
###########################################################################
|
|
126
421
|
# Metrics to Track
|
|
127
422
|
###########################################################################
|
|
128
|
-
def
|
|
423
|
+
def schema_metric_tmp(schema):
|
|
424
|
+
'''
|
|
425
|
+
Defines a temporary, extended set of metrics in the provided schema.
|
|
426
|
+
|
|
427
|
+
This function populates a schema with a comprehensive list of metrics
|
|
428
|
+
commonly used in ASIC and FPGA design flows.
|
|
429
|
+
|
|
430
|
+
Args:
|
|
431
|
+
schema (Schema): The schema object to configure.
|
|
432
|
+
'''
|
|
129
433
|
schema = EditableSchema(schema)
|
|
130
434
|
|
|
131
|
-
metrics = {'
|
|
132
|
-
'warnings': 'warnings',
|
|
133
|
-
'drvs': 'design rule violations',
|
|
435
|
+
metrics = {'drvs': 'design rule violations',
|
|
134
436
|
'drcs': 'physical design rule violations',
|
|
135
437
|
'unconstrained': 'unconstrained timing paths'}
|
|
136
438
|
|
|
@@ -429,70 +731,3 @@ def schema_metric(schema):
|
|
|
429
731
|
congested design. To analyze where the congestion is occurring
|
|
430
732
|
inspect the router log files for detailed per metal overflow
|
|
431
733
|
reporting and open up the design to find routing hotspots.""")))
|
|
432
|
-
|
|
433
|
-
schema.insert(
|
|
434
|
-
'memory',
|
|
435
|
-
Parameter(
|
|
436
|
-
'float',
|
|
437
|
-
unit='B',
|
|
438
|
-
scope=Scope.JOB,
|
|
439
|
-
shorthelp="Metric: memory",
|
|
440
|
-
switch="-metric_memory 'step index <float>'",
|
|
441
|
-
example=[
|
|
442
|
-
"cli: -metric_memory 'dfm 0 10e9'",
|
|
443
|
-
"api: chip.set('metric', 'memory', 10e9, step='dfm', index=0)"],
|
|
444
|
-
pernode=PerNode.REQUIRED,
|
|
445
|
-
help=trim("""
|
|
446
|
-
Metric tracking total peak program memory footprint on a per
|
|
447
|
-
step and index basis.""")))
|
|
448
|
-
|
|
449
|
-
schema.insert(
|
|
450
|
-
'exetime',
|
|
451
|
-
Parameter(
|
|
452
|
-
'float',
|
|
453
|
-
unit='s',
|
|
454
|
-
scope=Scope.JOB,
|
|
455
|
-
shorthelp="Metric: exetime",
|
|
456
|
-
switch="-metric_exetime 'step index <float>'",
|
|
457
|
-
example=[
|
|
458
|
-
"cli: -metric_exetime 'dfm 0 10.0'",
|
|
459
|
-
"api: chip.set('metric', 'exetime', 10.0, step='dfm', index=0)"],
|
|
460
|
-
pernode=PerNode.REQUIRED,
|
|
461
|
-
help=trim("""
|
|
462
|
-
Metric tracking time spent by the EDA executable :keypath:`tool,<tool>,exe` on a
|
|
463
|
-
per step and index basis. It does not include the SiliconCompiler
|
|
464
|
-
runtime overhead or time waiting for I/O operations and
|
|
465
|
-
inter-processor communication to complete.""")))
|
|
466
|
-
|
|
467
|
-
schema.insert(
|
|
468
|
-
'tasktime',
|
|
469
|
-
Parameter(
|
|
470
|
-
'float',
|
|
471
|
-
unit='s',
|
|
472
|
-
scope=Scope.JOB,
|
|
473
|
-
shorthelp="Metric: tasktime",
|
|
474
|
-
switch="-metric_tasktime 'step index <float>'",
|
|
475
|
-
example=[
|
|
476
|
-
"cli: -metric_tasktime 'dfm 0 10.0'",
|
|
477
|
-
"api: chip.set('metric', 'tasktime', 10.0, step='dfm', index=0)"],
|
|
478
|
-
pernode=PerNode.REQUIRED,
|
|
479
|
-
help=trim("""
|
|
480
|
-
Metric tracking the total amount of time spent on a task from
|
|
481
|
-
beginning to end, including data transfers and pre/post
|
|
482
|
-
processing.""")))
|
|
483
|
-
|
|
484
|
-
schema.insert(
|
|
485
|
-
'totaltime',
|
|
486
|
-
Parameter(
|
|
487
|
-
'float',
|
|
488
|
-
unit='s',
|
|
489
|
-
scope=Scope.JOB,
|
|
490
|
-
shorthelp="Metric: totaltime",
|
|
491
|
-
switch="-metric_totaltime 'step index <float>'",
|
|
492
|
-
example=[
|
|
493
|
-
"cli: -metric_totaltime 'dfm 0 10.0'",
|
|
494
|
-
"api: chip.set('metric', 'totaltime', 10.0, step='dfm', index=0)"],
|
|
495
|
-
pernode=PerNode.REQUIRED,
|
|
496
|
-
help=trim("""
|
|
497
|
-
Metric tracking the total amount of time spent from the beginning
|
|
498
|
-
of the run up to and including the current step and index.""")))
|