siliconcompiler 0.34.0__py3-none-any.whl → 0.34.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- siliconcompiler/__init__.py +14 -2
- siliconcompiler/_metadata.py +1 -1
- siliconcompiler/apps/_common.py +1 -1
- siliconcompiler/apps/sc.py +1 -1
- siliconcompiler/apps/sc_issue.py +1 -1
- siliconcompiler/apps/sc_remote.py +3 -3
- siliconcompiler/apps/sc_show.py +3 -3
- siliconcompiler/apps/utils/replay.py +4 -4
- siliconcompiler/checklist.py +203 -2
- 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 +31 -249
- siliconcompiler/data/templates/email/general.j2 +3 -3
- siliconcompiler/data/templates/email/summary.j2 +1 -1
- siliconcompiler/data/templates/issue/README.txt +1 -1
- siliconcompiler/data/templates/report/sc_report.j2 +7 -7
- siliconcompiler/dependencyschema.py +10 -174
- siliconcompiler/design.py +325 -114
- siliconcompiler/flowgraph.py +63 -15
- siliconcompiler/library.py +133 -0
- siliconcompiler/metric.py +94 -72
- siliconcompiler/metrics/__init__.py +7 -0
- siliconcompiler/metrics/asic.py +245 -0
- siliconcompiler/metrics/fpga.py +220 -0
- siliconcompiler/optimizer/vizier.py +2 -2
- siliconcompiler/package/__init__.py +138 -35
- siliconcompiler/package/github.py +6 -10
- siliconcompiler/packageschema.py +256 -12
- siliconcompiler/pathschema.py +226 -0
- siliconcompiler/pdk.py +5 -5
- siliconcompiler/project.py +459 -0
- siliconcompiler/remote/client.py +18 -12
- siliconcompiler/remote/server.py +2 -2
- siliconcompiler/report/dashboard/cli/__init__.py +6 -6
- siliconcompiler/report/dashboard/cli/board.py +3 -3
- siliconcompiler/report/dashboard/web/components/__init__.py +5 -5
- siliconcompiler/report/dashboard/web/components/flowgraph.py +4 -4
- siliconcompiler/report/dashboard/web/components/graph.py +2 -2
- siliconcompiler/report/dashboard/web/state.py +1 -1
- siliconcompiler/report/dashboard/web/utils/__init__.py +5 -5
- siliconcompiler/report/html_report.py +1 -1
- siliconcompiler/report/report.py +4 -4
- siliconcompiler/report/summary_table.py +2 -2
- siliconcompiler/report/utils.py +5 -5
- siliconcompiler/scheduler/docker.py +4 -10
- siliconcompiler/scheduler/run_node.py +4 -8
- siliconcompiler/scheduler/scheduler.py +18 -24
- siliconcompiler/scheduler/schedulernode.py +161 -143
- siliconcompiler/scheduler/send_messages.py +3 -3
- siliconcompiler/scheduler/slurm.py +5 -3
- siliconcompiler/scheduler/taskscheduler.py +10 -8
- siliconcompiler/schema/__init__.py +0 -2
- siliconcompiler/schema/baseschema.py +148 -26
- siliconcompiler/schema/editableschema.py +14 -6
- siliconcompiler/schema/journal.py +23 -15
- siliconcompiler/schema/namedschema.py +30 -4
- siliconcompiler/schema/parameter.py +34 -19
- siliconcompiler/schema/parametertype.py +2 -0
- siliconcompiler/schema/parametervalue.py +198 -15
- siliconcompiler/schema/schema_cfg.py +18 -14
- siliconcompiler/schema_obj.py +5 -3
- siliconcompiler/tool.py +591 -179
- siliconcompiler/tools/__init__.py +2 -0
- siliconcompiler/tools/builtin/_common.py +5 -5
- siliconcompiler/tools/builtin/concatenate.py +5 -5
- siliconcompiler/tools/builtin/minimum.py +4 -4
- siliconcompiler/tools/builtin/mux.py +4 -4
- siliconcompiler/tools/builtin/nop.py +4 -4
- siliconcompiler/tools/builtin/verify.py +7 -7
- siliconcompiler/tools/execute/exec_input.py +1 -1
- siliconcompiler/tools/genfasm/genfasm.py +1 -6
- siliconcompiler/tools/openroad/_apr.py +5 -1
- siliconcompiler/tools/openroad/antenna_repair.py +1 -1
- siliconcompiler/tools/openroad/macro_placement.py +1 -1
- siliconcompiler/tools/openroad/power_grid.py +1 -1
- siliconcompiler/tools/openroad/scripts/common/procs.tcl +5 -0
- siliconcompiler/tools/opensta/timing.py +26 -3
- siliconcompiler/tools/slang/__init__.py +2 -2
- siliconcompiler/tools/surfer/__init__.py +0 -0
- siliconcompiler/tools/surfer/show.py +53 -0
- siliconcompiler/tools/surfer/surfer.py +30 -0
- siliconcompiler/tools/vpr/route.py +27 -14
- siliconcompiler/tools/vpr/vpr.py +23 -6
- siliconcompiler/tools/yosys/__init__.py +1 -1
- siliconcompiler/tools/yosys/scripts/procs.tcl +143 -0
- siliconcompiler/tools/yosys/{sc_synth_asic.tcl → scripts/sc_synth_asic.tcl} +4 -0
- siliconcompiler/tools/yosys/{sc_synth_fpga.tcl → scripts/sc_synth_fpga.tcl} +24 -77
- siliconcompiler/tools/yosys/syn_fpga.py +14 -0
- siliconcompiler/toolscripts/_tools.json +9 -13
- siliconcompiler/toolscripts/rhel9/install-vpr.sh +0 -2
- siliconcompiler/toolscripts/ubuntu22/install-surfer.sh +33 -0
- siliconcompiler/toolscripts/ubuntu24/install-surfer.sh +33 -0
- siliconcompiler/utils/__init__.py +2 -1
- siliconcompiler/utils/flowgraph.py +24 -23
- siliconcompiler/utils/issue.py +23 -29
- siliconcompiler/utils/logging.py +35 -6
- siliconcompiler/utils/showtools.py +6 -1
- {siliconcompiler-0.34.0.dist-info → siliconcompiler-0.34.2.dist-info}/METADATA +15 -25
- {siliconcompiler-0.34.0.dist-info → siliconcompiler-0.34.2.dist-info}/RECORD +109 -97
- siliconcompiler/schema/packageschema.py +0 -101
- siliconcompiler/tools/yosys/procs.tcl +0 -71
- siliconcompiler/toolscripts/rhel9/install-yosys-parmys.sh +0 -68
- siliconcompiler/toolscripts/ubuntu22/install-yosys-parmys.sh +0 -68
- siliconcompiler/toolscripts/ubuntu24/install-yosys-parmys.sh +0 -68
- /siliconcompiler/tools/yosys/{sc_lec.tcl → scripts/sc_lec.tcl} +0 -0
- /siliconcompiler/tools/yosys/{sc_screenshot.tcl → scripts/sc_screenshot.tcl} +0 -0
- /siliconcompiler/tools/yosys/{syn_strategies.tcl → scripts/syn_strategies.tcl} +0 -0
- {siliconcompiler-0.34.0.dist-info → siliconcompiler-0.34.2.dist-info}/WHEEL +0 -0
- {siliconcompiler-0.34.0.dist-info → siliconcompiler-0.34.2.dist-info}/entry_points.txt +0 -0
- {siliconcompiler-0.34.0.dist-info → siliconcompiler-0.34.2.dist-info}/licenses/LICENSE +0 -0
- {siliconcompiler-0.34.0.dist-info → siliconcompiler-0.34.2.dist-info}/top_level.txt +0 -0
siliconcompiler/core.py
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
# Copyright 2020 Silicon Compiler Authors. All Rights Reserved.
|
|
2
2
|
|
|
3
|
+
import copy
|
|
3
4
|
import tarfile
|
|
4
5
|
import os
|
|
5
6
|
import pathlib
|
|
@@ -13,7 +14,6 @@ import shutil
|
|
|
13
14
|
import importlib
|
|
14
15
|
import textwrap
|
|
15
16
|
import graphviz
|
|
16
|
-
import codecs
|
|
17
17
|
import csv
|
|
18
18
|
import yaml
|
|
19
19
|
from inspect import getfullargspec
|
|
@@ -23,10 +23,7 @@ from siliconcompiler.schema.parametertype import NodeType
|
|
|
23
23
|
from siliconcompiler.schema.parametervalue import FileNodeValue
|
|
24
24
|
from siliconcompiler.schema import utils as schema_utils
|
|
25
25
|
from siliconcompiler import utils
|
|
26
|
-
from siliconcompiler.utils.logging import
|
|
27
|
-
SCLoggerFormatter, SCInRunLoggerFormatter, \
|
|
28
|
-
SCDebugLoggerFormatter, SCDebugInRunLoggerFormatter, \
|
|
29
|
-
SCBlankLoggerFormatter
|
|
26
|
+
from siliconcompiler.utils.logging import get_console_formatter, SCLoggerFormatter
|
|
30
27
|
from siliconcompiler import _metadata
|
|
31
28
|
from siliconcompiler import NodeStatus, SiliconCompilerError
|
|
32
29
|
from siliconcompiler.report import _show_summary_table
|
|
@@ -40,6 +37,7 @@ from siliconcompiler.utils.flowgraph import _check_flowgraph_io, _get_flowgraph_
|
|
|
40
37
|
from siliconcompiler.tools._common import get_tool_task
|
|
41
38
|
from types import FunctionType, ModuleType
|
|
42
39
|
from siliconcompiler.flowgraph import RuntimeFlowgraph
|
|
40
|
+
from siliconcompiler.package import Resolver
|
|
43
41
|
|
|
44
42
|
|
|
45
43
|
class Chip:
|
|
@@ -62,6 +60,8 @@ class Chip:
|
|
|
62
60
|
self.scversion = _metadata.version
|
|
63
61
|
self.schemaversion = SCHEMA_VERSION
|
|
64
62
|
|
|
63
|
+
Resolver.reset_cache(self)
|
|
64
|
+
|
|
65
65
|
# Local variables
|
|
66
66
|
self.scroot = os.path.dirname(os.path.abspath(__file__))
|
|
67
67
|
self._error = False
|
|
@@ -72,14 +72,13 @@ class Chip:
|
|
|
72
72
|
"SiliconCompiler must be run from a directory that exists. "
|
|
73
73
|
"If you are sure that your working directory is valid, try running `cd $(pwd)`.")
|
|
74
74
|
|
|
75
|
-
|
|
76
|
-
# by each spawned (as opposed to forked) subprocess
|
|
77
|
-
self._init_codecs()
|
|
78
|
-
|
|
79
|
-
self._init_logger()
|
|
75
|
+
self.__init_logger()
|
|
80
76
|
|
|
81
77
|
self.schema = Schema(logger=self.logger)
|
|
82
78
|
|
|
79
|
+
# Setup console formatting
|
|
80
|
+
self._logger_console.setFormatter(get_console_formatter(self, False, None, None))
|
|
81
|
+
|
|
83
82
|
self.register_source('siliconcompiler',
|
|
84
83
|
'python://siliconcompiler')
|
|
85
84
|
|
|
@@ -205,96 +204,21 @@ class Chip:
|
|
|
205
204
|
else:
|
|
206
205
|
return module
|
|
207
206
|
|
|
208
|
-
def _add_file_logger(self, filename):
|
|
209
|
-
# Add a file handler for logging
|
|
210
|
-
file_handler = logging.FileHandler(filename)
|
|
211
|
-
self.logger.addHandler(file_handler)
|
|
212
|
-
|
|
213
|
-
self._init_logger_formats()
|
|
214
|
-
|
|
215
|
-
return file_handler
|
|
216
|
-
|
|
217
207
|
###########################################################################
|
|
218
|
-
def
|
|
219
|
-
|
|
208
|
+
def __init_logger(self):
|
|
220
209
|
# Check if the logger exists and create
|
|
221
210
|
if not hasattr(self, 'logger') or not self.logger:
|
|
222
211
|
self.logger = logging.getLogger(f'sc_{id(self)}')
|
|
223
212
|
|
|
224
213
|
self.logger.propagate = False
|
|
225
214
|
|
|
226
|
-
|
|
227
|
-
if hasattr(self, 'schema'):
|
|
228
|
-
loglevel = self.schema.get('option', 'loglevel', step=step, index=index)
|
|
229
|
-
else:
|
|
230
|
-
in_run = False
|
|
231
|
-
|
|
232
|
-
# Save in run flag
|
|
233
|
-
self.logger._in_run = in_run
|
|
234
|
-
self.logger._in_step = step
|
|
235
|
-
self.logger._in_index = index
|
|
236
|
-
|
|
237
|
-
self.logger.setLevel(schema_utils.translate_loglevel(loglevel))
|
|
238
|
-
|
|
239
|
-
if not self.logger.hasHandlers():
|
|
240
|
-
stream_handler = logging.StreamHandler(stream=sys.stdout)
|
|
241
|
-
# Save console handler
|
|
242
|
-
self.logger._console = stream_handler
|
|
243
|
-
self.logger.addHandler(stream_handler)
|
|
244
|
-
|
|
245
|
-
self.logger._support_color = SCColorLoggerFormatter.supports_color(stream_handler)
|
|
246
|
-
|
|
247
|
-
self._init_logger_formats(loglevel=loglevel)
|
|
248
|
-
|
|
249
|
-
def _init_logger_formats(self, loglevel=None):
|
|
250
|
-
if not loglevel:
|
|
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()
|
|
215
|
+
self.logger.setLevel(logging.INFO)
|
|
272
216
|
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
handler.setFormatter(formatter)
|
|
279
|
-
|
|
280
|
-
###########################################################################
|
|
281
|
-
def _init_codecs(self):
|
|
282
|
-
# Custom error handlers used to provide warnings when invalid characters
|
|
283
|
-
# are encountered in a file for a given encoding. The names
|
|
284
|
-
# 'replace_with_warning' and 'ignore_with_warning' are supplied to
|
|
285
|
-
# open() via the 'errors' kwarg.
|
|
286
|
-
|
|
287
|
-
# Warning message/behavior for invalid characters while running tool
|
|
288
|
-
def display_error_handler(e):
|
|
289
|
-
self.logger.warning('Invalid character in tool output, displaying as �')
|
|
290
|
-
return codecs.replace_errors(e)
|
|
291
|
-
codecs.register_error('replace_with_warning', display_error_handler)
|
|
292
|
-
|
|
293
|
-
# Warning message/behavior for invalid characters while processing log
|
|
294
|
-
def log_error_handler(e):
|
|
295
|
-
self.logger.warning('Ignoring invalid character found while reading log')
|
|
296
|
-
return codecs.ignore_errors(e)
|
|
297
|
-
codecs.register_error('ignore_with_warning', log_error_handler)
|
|
217
|
+
stream_handler = logging.StreamHandler(stream=sys.stdout)
|
|
218
|
+
stream_handler.setFormatter(SCLoggerFormatter())
|
|
219
|
+
# Save console handler
|
|
220
|
+
self._logger_console = stream_handler
|
|
221
|
+
self.logger.addHandler(stream_handler)
|
|
298
222
|
|
|
299
223
|
###########################################################################
|
|
300
224
|
def create_cmdline(self,
|
|
@@ -1557,12 +1481,9 @@ class Chip:
|
|
|
1557
1481
|
if keypath[-2:] == ('option', 'builddir'):
|
|
1558
1482
|
ignore_keys.append(keypath)
|
|
1559
1483
|
|
|
1560
|
-
package_map = self.get("package", field="schema").get_resolvers()
|
|
1561
|
-
|
|
1562
1484
|
return self.schema.check_filepaths(
|
|
1563
1485
|
ignore_keys=ignore_keys,
|
|
1564
1486
|
logger=self.logger,
|
|
1565
|
-
packages=package_map,
|
|
1566
1487
|
collection_dir=self._getcollectdir(),
|
|
1567
1488
|
cwd=self.cwd)
|
|
1568
1489
|
|
|
@@ -1631,7 +1552,7 @@ class Chip:
|
|
|
1631
1552
|
NodeStatus.SUCCESS:
|
|
1632
1553
|
# this task has already completed successfully, OK
|
|
1633
1554
|
continue
|
|
1634
|
-
self.logger.error(f'{step}{index} relies on {in_step}{in_index}, '
|
|
1555
|
+
self.logger.error(f'{step}/{index} relies on {in_step}/{in_index}, '
|
|
1635
1556
|
'but this task has not been run and is not in the '
|
|
1636
1557
|
'current nodes to execute.')
|
|
1637
1558
|
error = True
|
|
@@ -1676,12 +1597,12 @@ class Chip:
|
|
|
1676
1597
|
if not self._get_tool_module(step, index, flow=flow, error=False):
|
|
1677
1598
|
error = True
|
|
1678
1599
|
self.logger.error(f"Tool module {tool_name} could not be found or "
|
|
1679
|
-
f"loaded for {step}{index}.")
|
|
1600
|
+
f"loaded for {step}/{index}.")
|
|
1680
1601
|
if not self._get_task_module(step, index, flow=flow, error=False):
|
|
1681
1602
|
error = True
|
|
1682
1603
|
task_module = self.get('flowgraph', flow, step, index, 'taskmodule')
|
|
1683
1604
|
self.logger.error(f"Task module {task_module} for {tool_name}/{task_name} "
|
|
1684
|
-
f"could not be found or loaded for {step}{index}.")
|
|
1605
|
+
f"could not be found or loaded for {step}/{index}.")
|
|
1685
1606
|
|
|
1686
1607
|
# 5. Check per tool parameter requirements (when tool exists)
|
|
1687
1608
|
for (step, index) in nodes:
|
|
@@ -1911,156 +1832,13 @@ class Chip:
|
|
|
1911
1832
|
>>> status = chip.check_checklist('iso9000', 'd000')
|
|
1912
1833
|
Returns status.
|
|
1913
1834
|
'''
|
|
1914
|
-
error = False
|
|
1915
|
-
|
|
1916
|
-
self.logger.info(f'Checking checklist {standard}')
|
|
1917
|
-
|
|
1918
1835
|
if standard not in self.getkeys('checklist'):
|
|
1919
1836
|
self.logger.error(f'{standard} has not been loaded.')
|
|
1920
1837
|
return False
|
|
1921
1838
|
|
|
1922
|
-
|
|
1923
|
-
items =
|
|
1924
|
-
|
|
1925
|
-
# these tasks are recorded by SC so there are no reports
|
|
1926
|
-
metrics_without_reports = (
|
|
1927
|
-
'tasktime',
|
|
1928
|
-
'totaltime',
|
|
1929
|
-
'exetime',
|
|
1930
|
-
'memory')
|
|
1931
|
-
|
|
1932
|
-
for item in items:
|
|
1933
|
-
if item not in self.getkeys('checklist', standard):
|
|
1934
|
-
self.logger.error(f'{item} is not a check in {standard}.')
|
|
1935
|
-
error = True
|
|
1936
|
-
continue
|
|
1937
|
-
|
|
1938
|
-
allow_missing_reports = True
|
|
1939
|
-
|
|
1940
|
-
has_check = False
|
|
1941
|
-
|
|
1942
|
-
all_criteria = self.get('checklist', standard, item, 'criteria')
|
|
1943
|
-
for criteria in all_criteria:
|
|
1944
|
-
m = re.match(r'^(\w+)\s*([\>\=\<]+)\s*([+\-]?\d+(\.\d+)?(e[+\-]?\d+)?)$',
|
|
1945
|
-
criteria.strip())
|
|
1946
|
-
if not m:
|
|
1947
|
-
self.error(f"Illegal checklist criteria: {criteria}")
|
|
1948
|
-
return False
|
|
1949
|
-
elif m.group(1) not in self.getkeys('metric'):
|
|
1950
|
-
self.error(f"Criteria must use legal metrics only: {criteria}")
|
|
1951
|
-
return False
|
|
1952
|
-
|
|
1953
|
-
metric = m.group(1)
|
|
1954
|
-
op = m.group(2)
|
|
1955
|
-
if self.get('metric', metric, field='type') == 'int':
|
|
1956
|
-
goal = int(m.group(3))
|
|
1957
|
-
number_format = 'd'
|
|
1958
|
-
else:
|
|
1959
|
-
goal = float(m.group(3))
|
|
1960
|
-
|
|
1961
|
-
if goal == 0.0 or (abs(goal) > 1e-3 and abs(goal) < 1e5):
|
|
1962
|
-
number_format = '.3f'
|
|
1963
|
-
else:
|
|
1964
|
-
number_format = '.3e'
|
|
1965
|
-
|
|
1966
|
-
if metric not in metrics_without_reports:
|
|
1967
|
-
allow_missing_reports = False
|
|
1968
|
-
|
|
1969
|
-
tasks = self.get('checklist', standard, item, 'task')
|
|
1970
|
-
for job, step, index in tasks:
|
|
1971
|
-
if job not in self.getkeys('history'):
|
|
1972
|
-
self.error(f'{job} not found in history')
|
|
1973
|
-
|
|
1974
|
-
flow = self.get('option', 'flow', job=job)
|
|
1975
|
-
|
|
1976
|
-
if step not in self.getkeys('flowgraph', flow, job=job):
|
|
1977
|
-
self.error(f'{step} not found in flowgraph')
|
|
1978
|
-
|
|
1979
|
-
if index not in self.getkeys('flowgraph', flow, step, job=job):
|
|
1980
|
-
self.error(f'{step}{index} not found in flowgraph')
|
|
1981
|
-
|
|
1982
|
-
if self.get('record', 'status', step=step, index=index, job=job) == \
|
|
1983
|
-
NodeStatus.SKIPPED:
|
|
1984
|
-
if verbose:
|
|
1985
|
-
self.logger.warning(f'{step}{index} was skipped')
|
|
1986
|
-
continue
|
|
1987
|
-
|
|
1988
|
-
has_check = True
|
|
1989
|
-
|
|
1990
|
-
# Automated checks
|
|
1991
|
-
flow = self.get('option', 'flow', job=job)
|
|
1992
|
-
tool = self.get('flowgraph', flow, step, index, 'tool', job=job)
|
|
1993
|
-
task = self.get('flowgraph', flow, step, index, 'task', job=job)
|
|
1994
|
-
|
|
1995
|
-
value = self.get('metric', metric, job=job, step=step, index=index)
|
|
1996
|
-
criteria_ok = utils.safecompare(self, value, op, goal)
|
|
1997
|
-
if metric in self.getkeys('checklist', standard, item, 'waiver'):
|
|
1998
|
-
waivers = self.get('checklist', standard, item, 'waiver', metric)
|
|
1999
|
-
else:
|
|
2000
|
-
waivers = []
|
|
2001
|
-
|
|
2002
|
-
criteria_str = f'{metric}{op}{goal:{number_format}}'
|
|
2003
|
-
compare_str = f'{value:{number_format}}{op}{goal:{number_format}}'
|
|
2004
|
-
step_desc = f'job {job} with step {step}{index} and task {tool}/{task}'
|
|
2005
|
-
if not criteria_ok and waivers:
|
|
2006
|
-
self.logger.warning(f'{item} criteria {criteria_str} ({compare_str}) unmet '
|
|
2007
|
-
f'by {step_desc}, but found waivers.')
|
|
2008
|
-
elif not criteria_ok:
|
|
2009
|
-
self.logger.error(f'{item} criteria {criteria_str} ({compare_str}) unmet '
|
|
2010
|
-
f'by {step_desc}.')
|
|
2011
|
-
error = True
|
|
2012
|
-
elif verbose and criteria_ok:
|
|
2013
|
-
self.logger.info(f'{item} criteria {criteria_str} met by {step_desc}.')
|
|
2014
|
-
|
|
2015
|
-
has_reports = \
|
|
2016
|
-
self.valid('tool', tool, 'task', task, 'report', metric, job=job) and \
|
|
2017
|
-
self.get('tool', tool, 'task', task, 'report', metric, job=job,
|
|
2018
|
-
step=step, index=index)
|
|
2019
|
-
|
|
2020
|
-
if allow_missing_reports and not has_reports:
|
|
2021
|
-
# No reports available and it is allowed
|
|
2022
|
-
continue
|
|
2023
|
-
|
|
2024
|
-
reports = []
|
|
2025
|
-
try:
|
|
2026
|
-
if has_reports:
|
|
2027
|
-
reports = self.find_files('tool', tool, 'task', task, 'report', metric,
|
|
2028
|
-
job=job,
|
|
2029
|
-
step=step, index=index,
|
|
2030
|
-
missing_ok=not require_reports)
|
|
2031
|
-
except SiliconCompilerError:
|
|
2032
|
-
reports = []
|
|
2033
|
-
continue
|
|
2034
|
-
|
|
2035
|
-
if require_reports and not reports:
|
|
2036
|
-
self.logger.error(f'No EDA reports generated for metric {metric} in '
|
|
2037
|
-
f'{step_desc}')
|
|
2038
|
-
error = True
|
|
2039
|
-
|
|
2040
|
-
for report in reports:
|
|
2041
|
-
if not report:
|
|
2042
|
-
continue
|
|
2043
|
-
|
|
2044
|
-
report = os.path.relpath(report, self.cwd)
|
|
2045
|
-
if report not in self.get('checklist', standard, item, 'report'):
|
|
2046
|
-
self.add('checklist', standard, item, 'report', report)
|
|
2047
|
-
|
|
2048
|
-
if has_check:
|
|
2049
|
-
if require_reports and \
|
|
2050
|
-
not allow_missing_reports and \
|
|
2051
|
-
not self.get('checklist', standard, item, 'report'):
|
|
2052
|
-
# TODO: validate that report exists?
|
|
2053
|
-
self.logger.error(f'No report documenting item {item}')
|
|
2054
|
-
error = True
|
|
2055
|
-
|
|
2056
|
-
if check_ok and not self.get('checklist', standard, item, 'ok'):
|
|
2057
|
-
self.logger.error(f"Item {item} 'ok' field not checked")
|
|
2058
|
-
error = True
|
|
2059
|
-
|
|
2060
|
-
if not error:
|
|
2061
|
-
self.logger.info('Check succeeded!')
|
|
2062
|
-
|
|
2063
|
-
return not error
|
|
1839
|
+
return self.get("checklist", standard, field="schema").check(
|
|
1840
|
+
items=items, check_ok=check_ok, require_reports=require_reports
|
|
1841
|
+
)
|
|
2064
1842
|
|
|
2065
1843
|
###########################################################################
|
|
2066
1844
|
def __import_library(self, libname, library, job=None, clobber=True, keep_input=True):
|
|
@@ -2673,7 +2451,7 @@ class Chip:
|
|
|
2673
2451
|
###########################################################################
|
|
2674
2452
|
def _archive_node(self, tar, step, index, include=None, verbose=True):
|
|
2675
2453
|
if verbose:
|
|
2676
|
-
self.logger.info(f'Archiving {step}{index}...')
|
|
2454
|
+
self.logger.info(f'Archiving {step}/{index}...')
|
|
2677
2455
|
|
|
2678
2456
|
basedir = self.getworkdir(step=step, index=index)
|
|
2679
2457
|
|
|
@@ -2682,7 +2460,7 @@ class Chip:
|
|
|
2682
2460
|
|
|
2683
2461
|
if not os.path.isdir(basedir):
|
|
2684
2462
|
if self.get('record', 'status', step=step, index=index) != NodeStatus.SKIPPED:
|
|
2685
|
-
self.logger.error(f'Unable to archive {step}{index} due to missing node directory')
|
|
2463
|
+
self.logger.error(f'Unable to archive {step}/{index} due to missing node directory')
|
|
2686
2464
|
return
|
|
2687
2465
|
|
|
2688
2466
|
if include:
|
|
@@ -2756,7 +2534,7 @@ class Chip:
|
|
|
2756
2534
|
|
|
2757
2535
|
if not archive_name:
|
|
2758
2536
|
if step and index:
|
|
2759
|
-
archive_name = f"{design}_{jobname}_{step}{index}.tgz"
|
|
2537
|
+
archive_name = f"{design}_{jobname}_{step}_{index}.tgz"
|
|
2760
2538
|
elif step:
|
|
2761
2539
|
archive_name = f"{design}_{jobname}_{step}.tgz"
|
|
2762
2540
|
else:
|
|
@@ -3322,7 +3100,7 @@ class Chip:
|
|
|
3322
3100
|
self.unset('option', 'prune')
|
|
3323
3101
|
self.unset('option', 'from')
|
|
3324
3102
|
# build new job name
|
|
3325
|
-
self.set('option', 'jobname', f'_{taskname}_{sc_job}_{sc_step}{sc_index}', clobber=True)
|
|
3103
|
+
self.set('option', 'jobname', f'_{taskname}_{sc_job}_{sc_step}_{sc_index}', clobber=True)
|
|
3326
3104
|
|
|
3327
3105
|
# Setup in step/index variables
|
|
3328
3106
|
for step, index in self.get("flowgraph", "showflow", field="schema").get_nodes():
|
|
@@ -3451,6 +3229,7 @@ class Chip:
|
|
|
3451
3229
|
# We have to remove the chip's logger before serializing the object
|
|
3452
3230
|
# since the logger object is not serializable.
|
|
3453
3231
|
del attributes['logger']
|
|
3232
|
+
del attributes['_logger_console']
|
|
3454
3233
|
return attributes
|
|
3455
3234
|
|
|
3456
3235
|
#######################################
|
|
@@ -3458,4 +3237,7 @@ class Chip:
|
|
|
3458
3237
|
self.__dict__ = state
|
|
3459
3238
|
|
|
3460
3239
|
# Reinitialize logger on restore
|
|
3461
|
-
self.
|
|
3240
|
+
self.__init_logger()
|
|
3241
|
+
|
|
3242
|
+
def copy(self):
|
|
3243
|
+
return copy.deepcopy(self)
|
|
@@ -9,11 +9,11 @@
|
|
|
9
9
|
</head>
|
|
10
10
|
|
|
11
11
|
<body>
|
|
12
|
-
<h2>Node Summary: "{{ step }}{{ index }}"</h2>
|
|
12
|
+
<h2>Node Summary: "{{ step }}/{{ index }}"</h2>
|
|
13
13
|
<span>
|
|
14
14
|
<p><b>Design</b>: {{ design }}</p>
|
|
15
15
|
<p><b>Job</b>: {{ job }}</p>
|
|
16
|
-
<p><b>Node</b>: {{ step }}{{ index }}</p>
|
|
16
|
+
<p><b>Node</b>: {{ step }}/{{ index }}</p>
|
|
17
17
|
<p><b>Status</b>: {{ status }}</p>
|
|
18
18
|
</span>
|
|
19
19
|
<span>
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
<th>Metrics</th>
|
|
37
37
|
<th>units</th>
|
|
38
38
|
{% for step, index in nodes %}
|
|
39
|
-
<th align="center">{{ step }}{{ index }}</th>
|
|
39
|
+
<th align="center">{{ step }}/{{ index }}</th>
|
|
40
40
|
{% endfor %}
|
|
41
41
|
</tr>
|
|
42
42
|
{% for metric in metric_keys %}
|
|
@@ -13,7 +13,7 @@ Schema: {{ version['schema'] }}
|
|
|
13
13
|
Testcase built: {{ date }}
|
|
14
14
|
Tool: {{ run['tool'] }} {% if run['toolversion'] %}{{ run['toolversion'] }}{% endif %}
|
|
15
15
|
Task: {{ run['task'] }}
|
|
16
|
-
Node: {{ run['step'] }}{{ run['index'] }}
|
|
16
|
+
Node: {{ run['step'] }}/{{ run['index'] }}
|
|
17
17
|
|
|
18
18
|
** Python **
|
|
19
19
|
Version: {{ python['version'] }}
|
|
@@ -271,12 +271,12 @@
|
|
|
271
271
|
{% for metric in metric_keys %}
|
|
272
272
|
{% for step, index in nodes %}
|
|
273
273
|
{% if reports[step, index][metric] %}
|
|
274
|
-
var sim_log_btn = document.getElementById("{{ step }}{{ index }}_{{ metric }}_metlink");
|
|
274
|
+
var sim_log_btn = document.getElementById("{{ step }}_{{ index }}_{{ metric }}_metlink");
|
|
275
275
|
sim_log_btn.addEventListener('click', () => {
|
|
276
276
|
log_link = "{{ step }}/{{ index }}/{{ reports[step, index][metric][0] }}";
|
|
277
277
|
window.open(log_link, "_blank");
|
|
278
278
|
});
|
|
279
|
-
var sim_log_btn = document.getElementById("{{ step }}{{ index }}_{{ metric }}_ddmetlink");
|
|
279
|
+
var sim_log_btn = document.getElementById("{{ step }}_{{ index }}_{{ metric }}_ddmetlink");
|
|
280
280
|
sim_log_btn.addEventListener('click', () => {
|
|
281
281
|
log_link = "{{ step }}/{{ index }}/{{ reports[step, index][metric][0] }}";
|
|
282
282
|
window.open(log_link, "_blank");
|
|
@@ -333,7 +333,7 @@
|
|
|
333
333
|
<th>-</th>
|
|
334
334
|
<th>units</th>
|
|
335
335
|
{% for step, index in nodes %}
|
|
336
|
-
<th>{{ step }}{{ index }}</th>
|
|
336
|
+
<th>{{ step }}/{{ index }}</th>
|
|
337
337
|
{% endfor %}
|
|
338
338
|
</tr>
|
|
339
339
|
{% for metric in metric_keys %}
|
|
@@ -372,12 +372,12 @@
|
|
|
372
372
|
<h2>Metrics for {{ design }} Tasks</h2>
|
|
373
373
|
{% for step, index in nodes %}
|
|
374
374
|
<div>
|
|
375
|
-
<a class="btn btn-success" data-bs-toggle="collapse" href="#{{ step }}{{ index }}_dropdown_div", role="button", aria-controls="{{ step }}{{ index }}_dropdown_div">
|
|
376
|
-
Toggle {{ step }}{{ index }} Metrics
|
|
375
|
+
<a class="btn btn-success" data-bs-toggle="collapse" href="#{{ step }}_{{ index }}_dropdown_div", role="button", aria-controls="{{ step }}_{{ index }}_dropdown_div">
|
|
376
|
+
Toggle {{ step }}/{{ index }} Metrics
|
|
377
377
|
</a>
|
|
378
378
|
</div>
|
|
379
|
-
<div id="{{ step }}{{ index }}_dropdown_div" class="collapse">
|
|
380
|
-
<table id="{{ step }}{{ index }}_metrics_table" class="table table-dark table-striped table-bordered">
|
|
379
|
+
<div id="{{ step }}_{{ index }}_dropdown_div" class="collapse">
|
|
380
|
+
<table id="{{ step }}_{{ index }}_metrics_table" class="table table-dark table-striped table-bordered">
|
|
381
381
|
<tr>
|
|
382
382
|
{% for metric in metric_keys %}
|
|
383
383
|
<th>{{ metric }}</th>
|