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
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"openroad": {
|
|
3
3
|
"git-url": "https://github.com/The-OpenROAD-Project/OpenROAD.git",
|
|
4
|
-
"git-commit": "
|
|
4
|
+
"git-commit": "be6d32d0c093e8e5f0545067f48509c60fbde1dc",
|
|
5
5
|
"docker-cmds": [
|
|
6
6
|
"# Remove OR-Tools files",
|
|
7
7
|
"RUN rm -f $SC_PREFIX/Makefile $SC_PREFIX/README.md",
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
},
|
|
18
18
|
"opensta": {
|
|
19
19
|
"git-url": "https://github.com/parallaxsw/OpenSTA.git",
|
|
20
|
-
"git-commit": "
|
|
20
|
+
"git-commit": "82fd625199d25dbe6ca25db9b62417caad358bb9",
|
|
21
21
|
"auto-update": true
|
|
22
22
|
},
|
|
23
23
|
"netgen": {
|
|
@@ -60,7 +60,7 @@
|
|
|
60
60
|
},
|
|
61
61
|
"verilator": {
|
|
62
62
|
"git-url": "https://github.com/verilator/verilator.git",
|
|
63
|
-
"git-commit": "v5.
|
|
63
|
+
"git-commit": "v5.038",
|
|
64
64
|
"auto-update": true
|
|
65
65
|
},
|
|
66
66
|
"bambu": {
|
|
@@ -101,7 +101,7 @@
|
|
|
101
101
|
},
|
|
102
102
|
"yosys": {
|
|
103
103
|
"git-url": "https://github.com/YosysHQ/yosys.git",
|
|
104
|
-
"git-commit": "v0.
|
|
104
|
+
"git-commit": "v0.56",
|
|
105
105
|
"version-prefix": "",
|
|
106
106
|
"auto-update": true
|
|
107
107
|
},
|
|
@@ -139,11 +139,6 @@
|
|
|
139
139
|
"git-url": "https://github.com/chipsalliance/verible.git",
|
|
140
140
|
"auto-update": false
|
|
141
141
|
},
|
|
142
|
-
"slang": {
|
|
143
|
-
"git-commit": "v8.1",
|
|
144
|
-
"git-url": "https://github.com/MikePopoloski/slang.git",
|
|
145
|
-
"auto-update": true
|
|
146
|
-
},
|
|
147
142
|
"gtkwave": {
|
|
148
143
|
"git-commit": "v3.3.116",
|
|
149
144
|
"git-url": "https://github.com/gtkwave/gtkwave.git",
|
|
@@ -151,7 +146,7 @@
|
|
|
151
146
|
},
|
|
152
147
|
"yosys-slang": {
|
|
153
148
|
"git-url": "https://github.com/povik/yosys-slang.git",
|
|
154
|
-
"git-commit": "
|
|
149
|
+
"git-commit": "e0b5a4c2b8360479a408bc30f57871f3b0b814ff",
|
|
155
150
|
"docker-depends": "yosys",
|
|
156
151
|
"auto-update": true
|
|
157
152
|
},
|
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
import contextlib
|
|
2
2
|
import os
|
|
3
3
|
import re
|
|
4
|
+
import pathlib
|
|
4
5
|
import psutil
|
|
5
6
|
import shutil
|
|
7
|
+
import stat
|
|
6
8
|
import traceback
|
|
9
|
+
|
|
7
10
|
from io import StringIO
|
|
8
11
|
from pathlib import Path
|
|
9
12
|
from jinja2 import Environment, FileSystemLoader
|
|
13
|
+
|
|
10
14
|
from siliconcompiler.schema.parametervalue import PathNodeValue
|
|
11
15
|
|
|
12
16
|
import sys
|
|
@@ -405,3 +409,65 @@ def print_traceback(logger, exception):
|
|
|
405
409
|
logger.error("Backtrace:")
|
|
406
410
|
for line in trace.getvalue().splitlines():
|
|
407
411
|
logger.error(line)
|
|
412
|
+
|
|
413
|
+
|
|
414
|
+
class FilterDirectories:
|
|
415
|
+
def __init__(self, project):
|
|
416
|
+
self.file_count = 0
|
|
417
|
+
self.directory_file_limit = None
|
|
418
|
+
self.abspath = None
|
|
419
|
+
self.project = project
|
|
420
|
+
|
|
421
|
+
@property
|
|
422
|
+
def logger(self):
|
|
423
|
+
return self.project.logger
|
|
424
|
+
|
|
425
|
+
@property
|
|
426
|
+
def builddir(self):
|
|
427
|
+
return self.project._getbuilddir()
|
|
428
|
+
|
|
429
|
+
def filter(self, path, files):
|
|
430
|
+
if pathlib.Path(path) == pathlib.Path.home():
|
|
431
|
+
# refuse to collect home directory
|
|
432
|
+
self.logger.error(f'Cannot collect user home directory: {path}')
|
|
433
|
+
return files
|
|
434
|
+
|
|
435
|
+
if pathlib.Path(path) == pathlib.Path(self.builddir):
|
|
436
|
+
# refuse to collect build directory
|
|
437
|
+
self.logger.error(f'Cannot collect build directory: {path}')
|
|
438
|
+
return files
|
|
439
|
+
|
|
440
|
+
# do not collect hidden files
|
|
441
|
+
hidden_files = []
|
|
442
|
+
# filter out hidden files (unix)
|
|
443
|
+
hidden_files.extend([f for f in files if f.startswith('.')])
|
|
444
|
+
# filter out hidden files (windows)
|
|
445
|
+
try:
|
|
446
|
+
if hasattr(os.stat_result, 'st_file_attributes'):
|
|
447
|
+
hidden_files.extend([
|
|
448
|
+
f for f in files
|
|
449
|
+
if bool(os.stat(os.path.join(path, f)).st_file_attributes &
|
|
450
|
+
stat.FILE_ATTRIBUTE_HIDDEN)
|
|
451
|
+
])
|
|
452
|
+
except: # noqa 722
|
|
453
|
+
pass
|
|
454
|
+
# filter out hidden files (macos)
|
|
455
|
+
try:
|
|
456
|
+
if hasattr(os.stat_result, 'st_reparse_tag'):
|
|
457
|
+
hidden_files.extend([
|
|
458
|
+
f for f in files
|
|
459
|
+
if bool(os.stat(os.path.join(path, f)).st_reparse_tag &
|
|
460
|
+
stat.UF_HIDDEN)
|
|
461
|
+
])
|
|
462
|
+
except: # noqa 722
|
|
463
|
+
pass
|
|
464
|
+
|
|
465
|
+
self.file_count += len(files) - len(hidden_files)
|
|
466
|
+
|
|
467
|
+
if self.directory_file_limit and \
|
|
468
|
+
self.file_count > self.directory_file_limit:
|
|
469
|
+
self.logger.error(f'File collection from {self.abspath} exceeds '
|
|
470
|
+
f'{self.directory_file_limit} files')
|
|
471
|
+
return files
|
|
472
|
+
|
|
473
|
+
return hidden_files
|
|
@@ -4,7 +4,7 @@ from siliconcompiler import NodeStatus
|
|
|
4
4
|
from siliconcompiler.tools._common import input_file_node_name, get_tool_task
|
|
5
5
|
|
|
6
6
|
from siliconcompiler.flowgraph import RuntimeFlowgraph
|
|
7
|
-
from siliconcompiler.scheduler
|
|
7
|
+
from siliconcompiler.scheduler import SchedulerNode
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
###########################################################################
|
|
@@ -65,7 +65,7 @@ def _check_flowgraph_io(chip, nodes=None):
|
|
|
65
65
|
in_tool, in_task = get_tool_task(chip, in_step, in_index, flow=flow)
|
|
66
66
|
task_class = chip.get("tool", in_tool, "task", in_task, field="schema")
|
|
67
67
|
|
|
68
|
-
with task_class.runtime(chip,
|
|
68
|
+
with task_class.runtime(SchedulerNode(chip, in_step, in_index)) as task:
|
|
69
69
|
inputs = task.get_output_files()
|
|
70
70
|
|
|
71
71
|
for inp in inputs:
|
siliconcompiler/utils/issue.py
CHANGED
|
@@ -10,6 +10,7 @@ from datetime import datetime
|
|
|
10
10
|
from siliconcompiler.utils import get_file_template
|
|
11
11
|
from siliconcompiler.tools._common import get_tool_task
|
|
12
12
|
from siliconcompiler import RecordSchema
|
|
13
|
+
from siliconcompiler.scheduler import SchedulerNode
|
|
13
14
|
|
|
14
15
|
|
|
15
16
|
def generate_testcase(chip,
|
|
@@ -154,7 +155,7 @@ def generate_testcase(chip,
|
|
|
154
155
|
|
|
155
156
|
task_class = chip.get("tool", tool, "task", task, field="schema")
|
|
156
157
|
|
|
157
|
-
with task_class.runtime(chip, step
|
|
158
|
+
with task_class.runtime(SchedulerNode(chip, step, index), relpath=new_work_dir) as task:
|
|
158
159
|
# Rewrite replay.sh
|
|
159
160
|
prev_quiet = chip.get('option', 'quiet', step=step, index=index)
|
|
160
161
|
chip.set('option', 'quiet', True, step=step, index=index)
|
siliconcompiler/utils/logging.py
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import logging
|
|
2
|
+
import re
|
|
2
3
|
import sys
|
|
4
|
+
|
|
3
5
|
from siliconcompiler import utils
|
|
4
6
|
|
|
5
7
|
|
|
@@ -8,6 +10,18 @@ class SCBlankLoggerFormatter(logging.Formatter):
|
|
|
8
10
|
super().__init__("%(message)s")
|
|
9
11
|
|
|
10
12
|
|
|
13
|
+
class SCBlankColorlessLoggerFormatter(logging.Formatter):
|
|
14
|
+
def __init__(self):
|
|
15
|
+
super().__init__("%(message)s")
|
|
16
|
+
|
|
17
|
+
self.__rm = re.compile(u"\u001b\\[(\\d+)m")
|
|
18
|
+
|
|
19
|
+
def format(self, record):
|
|
20
|
+
msg = super().format(record)
|
|
21
|
+
|
|
22
|
+
return self.__rm.sub("", msg)
|
|
23
|
+
|
|
24
|
+
|
|
11
25
|
class SCDebugLoggerFormatter(logging.Formatter):
|
|
12
26
|
def __init__(self):
|
|
13
27
|
super().__init__(
|
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
import atexit
|
|
2
|
+
import logging
|
|
3
|
+
import multiprocessing
|
|
4
|
+
import tempfile
|
|
5
|
+
import os.path
|
|
6
|
+
from datetime import datetime
|
|
7
|
+
|
|
8
|
+
from siliconcompiler.report.dashboard.cli.board import Board
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class _ManagerSingleton(type):
|
|
12
|
+
"""
|
|
13
|
+
A metaclass to enforce the singleton pattern on any class that uses it.
|
|
14
|
+
|
|
15
|
+
This ensures that only one instance of the target class is ever created
|
|
16
|
+
within the application's lifecycle. It uses a lock to make the
|
|
17
|
+
instantiation process thread-safe.
|
|
18
|
+
|
|
19
|
+
Attributes:
|
|
20
|
+
_instances (dict): A dictionary to store singleton instances, mapping
|
|
21
|
+
class objects to their single instance.
|
|
22
|
+
_lock (multiprocessing.Lock): A lock to prevent race conditions during
|
|
23
|
+
the first instantiation.
|
|
24
|
+
"""
|
|
25
|
+
_instances = {}
|
|
26
|
+
_lock = multiprocessing.Lock()
|
|
27
|
+
|
|
28
|
+
@staticmethod
|
|
29
|
+
def has_cls(cls):
|
|
30
|
+
"""
|
|
31
|
+
Checks if a singleton instance exists for the given class.
|
|
32
|
+
|
|
33
|
+
Args:
|
|
34
|
+
cls (type): The class to check.
|
|
35
|
+
|
|
36
|
+
Returns:
|
|
37
|
+
bool: True if an instance exists, False otherwise.
|
|
38
|
+
"""
|
|
39
|
+
return cls in _ManagerSingleton._instances
|
|
40
|
+
|
|
41
|
+
@staticmethod
|
|
42
|
+
def remove_cls(cls):
|
|
43
|
+
"""
|
|
44
|
+
Removes a class's singleton instance from the registry.
|
|
45
|
+
|
|
46
|
+
This is useful for cleanup, especially in testing scenarios where
|
|
47
|
+
a fresh instance is needed.
|
|
48
|
+
|
|
49
|
+
Args:
|
|
50
|
+
cls (type): The class whose instance should be removed.
|
|
51
|
+
"""
|
|
52
|
+
if not _ManagerSingleton.has_cls(cls):
|
|
53
|
+
return
|
|
54
|
+
|
|
55
|
+
with _ManagerSingleton._lock:
|
|
56
|
+
if cls in _ManagerSingleton._instances:
|
|
57
|
+
del _ManagerSingleton._instances[cls]
|
|
58
|
+
|
|
59
|
+
def __call__(cls, *args, **kwargs):
|
|
60
|
+
"""
|
|
61
|
+
Handles the instantiation of the class using a double-checked lock.
|
|
62
|
+
|
|
63
|
+
If an instance of the class does not already exist, it creates one
|
|
64
|
+
and stores it. Subsequent calls will return the existing instance.
|
|
65
|
+
A special '_init_singleton' method is called on the first creation.
|
|
66
|
+
"""
|
|
67
|
+
if not _ManagerSingleton.has_cls(cls):
|
|
68
|
+
with _ManagerSingleton._lock:
|
|
69
|
+
if cls not in _ManagerSingleton._instances:
|
|
70
|
+
instance = super(_ManagerSingleton, cls).__call__(*args, **kwargs)
|
|
71
|
+
_ManagerSingleton._instances[cls] = instance
|
|
72
|
+
# Custom initializer for the singleton instance
|
|
73
|
+
instance._init_singleton()
|
|
74
|
+
return _ManagerSingleton._instances[cls]
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
class MPManager(metaclass=_ManagerSingleton):
|
|
78
|
+
"""
|
|
79
|
+
A singleton manager for handling multiprocessing resources in SiliconCompiler.
|
|
80
|
+
|
|
81
|
+
This class provides centralized, thread-safe access to shared resources
|
|
82
|
+
like a logger, a multiprocessing.Manager, and a dashboard Board instance.
|
|
83
|
+
It is designed to be instantiated once and accessed globally.
|
|
84
|
+
"""
|
|
85
|
+
__ENABLE_LOGGER: bool = True
|
|
86
|
+
|
|
87
|
+
def __init__(self):
|
|
88
|
+
"""
|
|
89
|
+
Initializes the MPManager.
|
|
90
|
+
|
|
91
|
+
Note: The actual setup logic is in _init_singleton, which is called
|
|
92
|
+
automatically by the _ManagerSingleton metaclass upon first instantiation.
|
|
93
|
+
"""
|
|
94
|
+
pass
|
|
95
|
+
|
|
96
|
+
def _init_singleton(self):
|
|
97
|
+
"""
|
|
98
|
+
Performs the one-time initialization of the singleton instance.
|
|
99
|
+
|
|
100
|
+
This method sets up the start time, error flag, logger,
|
|
101
|
+
multiprocessing manager, and registers the cleanup function (`stop`)
|
|
102
|
+
to be called on program exit.
|
|
103
|
+
"""
|
|
104
|
+
self.__start = datetime.now()
|
|
105
|
+
self.__error = False
|
|
106
|
+
|
|
107
|
+
# Parent logger setup
|
|
108
|
+
now_file = self.__start.strftime("%Y-%m-%d-%H-%M-%S-%f")
|
|
109
|
+
self.__logfile = os.path.join(tempfile.gettempdir(),
|
|
110
|
+
"siliconcompiler",
|
|
111
|
+
f"{now_file}_{id(self)}.log")
|
|
112
|
+
self._init_logger()
|
|
113
|
+
|
|
114
|
+
# Manager to handle shared data between processes
|
|
115
|
+
self.__manager = multiprocessing.Manager()
|
|
116
|
+
|
|
117
|
+
# Dashboard singleton setup
|
|
118
|
+
self.__board_lock = self.__manager.Lock()
|
|
119
|
+
self.__board = None
|
|
120
|
+
|
|
121
|
+
# Register cleanup function to run at exit
|
|
122
|
+
atexit.register(MPManager.stop)
|
|
123
|
+
|
|
124
|
+
def _init_logger(self):
|
|
125
|
+
"""
|
|
126
|
+
Initializes the logging configuration for SiliconCompiler.
|
|
127
|
+
|
|
128
|
+
It sets up a root logger named "siliconcompiler" and adds a file
|
|
129
|
+
handler to log messages to a temporary file. The log level is
|
|
130
|
+
initially set to INFO to capture the start time and then raised
|
|
131
|
+
to WARNING.
|
|
132
|
+
"""
|
|
133
|
+
# Root logger for the application
|
|
134
|
+
self.__logger = logging.getLogger("siliconcompiler")
|
|
135
|
+
self.__logger.propagate = False
|
|
136
|
+
|
|
137
|
+
if self.__ENABLE_LOGGER:
|
|
138
|
+
self.__logger.setLevel(logging.INFO)
|
|
139
|
+
try:
|
|
140
|
+
os.makedirs(os.path.dirname(self.__logfile), exist_ok=True)
|
|
141
|
+
|
|
142
|
+
handler = logging.FileHandler(self.__logfile)
|
|
143
|
+
handler.setFormatter(logging.Formatter(
|
|
144
|
+
'%(asctime)s | %(name)s | %(levelname)s | %(message)s'))
|
|
145
|
+
handler.setLevel(logging.INFO)
|
|
146
|
+
|
|
147
|
+
self.__logger.addHandler(handler)
|
|
148
|
+
|
|
149
|
+
now_print = self.__start.strftime("%Y-%m-%d %H:%M:%S.%f")
|
|
150
|
+
self.__logger.info(f"Log started at {now_print}")
|
|
151
|
+
|
|
152
|
+
# Reduce logging level after initial message
|
|
153
|
+
handler.setLevel(logging.WARNING)
|
|
154
|
+
except Exception:
|
|
155
|
+
# Fails silently if logging can't be set up
|
|
156
|
+
pass
|
|
157
|
+
|
|
158
|
+
@staticmethod
|
|
159
|
+
def stop():
|
|
160
|
+
"""
|
|
161
|
+
Cleans up all managed resources as a static method.
|
|
162
|
+
|
|
163
|
+
This method is registered with atexit to run on script termination.
|
|
164
|
+
It closes logger handlers, deletes the log file if no errors occurred,
|
|
165
|
+
stops the dashboard service, shuts down the multiprocessing manager,
|
|
166
|
+
and finally removes the singleton instance from the registry.
|
|
167
|
+
"""
|
|
168
|
+
if not _ManagerSingleton.has_cls(MPManager):
|
|
169
|
+
return
|
|
170
|
+
|
|
171
|
+
manager = MPManager()
|
|
172
|
+
|
|
173
|
+
# Remove all logger handlers to release file locks
|
|
174
|
+
for handler in list(manager.__logger.handlers):
|
|
175
|
+
manager.__logger.removeHandler(handler)
|
|
176
|
+
handler.close()
|
|
177
|
+
|
|
178
|
+
# Remove the log file if the run was successful
|
|
179
|
+
if not manager.__error:
|
|
180
|
+
try:
|
|
181
|
+
os.remove(manager.__logfile)
|
|
182
|
+
except: # noqa E722
|
|
183
|
+
pass
|
|
184
|
+
|
|
185
|
+
# Stop the dashboard service if it's running
|
|
186
|
+
if manager.__board:
|
|
187
|
+
with manager.__board_lock:
|
|
188
|
+
if manager.__board:
|
|
189
|
+
manager.__board.stop()
|
|
190
|
+
manager.__board = None
|
|
191
|
+
|
|
192
|
+
# Shut down the multiprocessing manager
|
|
193
|
+
manager.__manager.shutdown()
|
|
194
|
+
|
|
195
|
+
# Unregister cleanup function to prevent it from being called again
|
|
196
|
+
atexit.unregister(MPManager.stop)
|
|
197
|
+
|
|
198
|
+
# Delete singleton instance to allow for re-initialization
|
|
199
|
+
_ManagerSingleton.remove_cls(MPManager)
|
|
200
|
+
|
|
201
|
+
@staticmethod
|
|
202
|
+
def error(msg: str = None):
|
|
203
|
+
"""
|
|
204
|
+
Logs an error and flags the session as having an error.
|
|
205
|
+
|
|
206
|
+
This prevents the log file from being deleted upon exit, preserving it
|
|
207
|
+
for debugging.
|
|
208
|
+
|
|
209
|
+
Args:
|
|
210
|
+
msg (str, optional): The error message to log. Defaults to None.
|
|
211
|
+
"""
|
|
212
|
+
manager = MPManager()
|
|
213
|
+
if msg:
|
|
214
|
+
manager.logger().error(f"Error: {msg}")
|
|
215
|
+
else:
|
|
216
|
+
manager.logger().error("Error occurred")
|
|
217
|
+
manager.__error = True
|
|
218
|
+
|
|
219
|
+
@staticmethod
|
|
220
|
+
def get_manager():
|
|
221
|
+
"""
|
|
222
|
+
Provides access to the shared multiprocessing.Manager instance.
|
|
223
|
+
|
|
224
|
+
Returns:
|
|
225
|
+
multiprocessing.Manager: The singleton manager instance.
|
|
226
|
+
"""
|
|
227
|
+
return MPManager().__manager
|
|
228
|
+
|
|
229
|
+
@staticmethod
|
|
230
|
+
def get_dashboard() -> Board:
|
|
231
|
+
"""
|
|
232
|
+
Lazily initializes and returns the singleton dashboard Board instance.
|
|
233
|
+
|
|
234
|
+
This method ensures that the Board is only created when first requested
|
|
235
|
+
and that its initialization is thread-safe.
|
|
236
|
+
|
|
237
|
+
Returns:
|
|
238
|
+
Board: The singleton dashboard Board instance.
|
|
239
|
+
"""
|
|
240
|
+
manager = MPManager()
|
|
241
|
+
if not manager.__board:
|
|
242
|
+
with manager.__board_lock:
|
|
243
|
+
# Double-check locking to ensure thread safety
|
|
244
|
+
if not manager.__board:
|
|
245
|
+
manager.__board = Board(manager.__manager)
|
|
246
|
+
return manager.__board
|
|
247
|
+
|
|
248
|
+
@staticmethod
|
|
249
|
+
def logger() -> logging.Logger:
|
|
250
|
+
"""
|
|
251
|
+
Provides access to the shared logger instance.
|
|
252
|
+
|
|
253
|
+
Returns:
|
|
254
|
+
logging.Logger: The singleton logger instance.
|
|
255
|
+
"""
|
|
256
|
+
return MPManager().__logger
|
|
@@ -44,3 +44,13 @@ def setup(chip):
|
|
|
44
44
|
chip.register_showtool('dot', graphviz_screenshot)
|
|
45
45
|
chip.register_showtool('xdot', graphviz_show)
|
|
46
46
|
chip.register_showtool('xdot', graphviz_screenshot)
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def showtasks():
|
|
50
|
+
from siliconcompiler import ShowTaskSchema, ScreenshotTaskSchema
|
|
51
|
+
|
|
52
|
+
from siliconcompiler.tools.openroad.show import ShowTask as OpenROADShow
|
|
53
|
+
from siliconcompiler.tools.openroad.screenshot import ScreenshotTask as OpenROADScreenshot
|
|
54
|
+
|
|
55
|
+
ShowTaskSchema.register_task(OpenROADShow)
|
|
56
|
+
ScreenshotTaskSchema.register_task(OpenROADScreenshot)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: siliconcompiler
|
|
3
|
-
Version: 0.34.
|
|
3
|
+
Version: 0.34.3
|
|
4
4
|
Summary: A compiler framework that automates translation from source code to silicon.
|
|
5
5
|
Author-email: Andreas Olofsson <andreas.d.olofsson@gmail.com>
|
|
6
6
|
License: Apache License 2.0
|
|
@@ -34,16 +34,16 @@ Requires-Dist: distro==1.9.0
|
|
|
34
34
|
Requires-Dist: packaging<25,>=21.3
|
|
35
35
|
Requires-Dist: psutil>=5.8.0
|
|
36
36
|
Requires-Dist: Pillow==11.3.0
|
|
37
|
-
Requires-Dist: GitPython
|
|
37
|
+
Requires-Dist: GitPython<3.2,>=3.1.44
|
|
38
38
|
Requires-Dist: lambdapdk>=0.1.47
|
|
39
|
-
Requires-Dist: PyGithub==2.
|
|
39
|
+
Requires-Dist: PyGithub==2.7.0
|
|
40
40
|
Requires-Dist: urllib3>=1.26.0
|
|
41
41
|
Requires-Dist: fasteners==0.19
|
|
42
42
|
Requires-Dist: fastjsonschema==2.21.1
|
|
43
43
|
Requires-Dist: docker==7.1.0
|
|
44
44
|
Requires-Dist: importlib_metadata; python_version < "3.10"
|
|
45
|
-
Requires-Dist: orjson
|
|
46
|
-
Requires-Dist: pyslang==
|
|
45
|
+
Requires-Dist: orjson<4,>=3.11.0
|
|
46
|
+
Requires-Dist: pyslang==9.0.0
|
|
47
47
|
Requires-Dist: streamlit==1.46.1; python_full_version != "3.9.7"
|
|
48
48
|
Requires-Dist: streamlit_agraph==0.0.45; python_full_version != "3.9.7"
|
|
49
49
|
Requires-Dist: streamlit-antd-components==0.3.2; python_full_version != "3.9.7"
|
|
@@ -54,7 +54,7 @@ Provides-Extra: test
|
|
|
54
54
|
Requires-Dist: pytest==8.4.1; extra == "test"
|
|
55
55
|
Requires-Dist: pytest-xdist==3.8.0; extra == "test"
|
|
56
56
|
Requires-Dist: pytest-timeout==2.4.0; extra == "test"
|
|
57
|
-
Requires-Dist: pytest-asyncio==1.
|
|
57
|
+
Requires-Dist: pytest-asyncio==1.1.0; extra == "test"
|
|
58
58
|
Requires-Dist: pytest-cov==6.2.1; extra == "test"
|
|
59
59
|
Requires-Dist: responses==0.25.7; extra == "test"
|
|
60
60
|
Requires-Dist: PyVirtualDisplay==3.0; extra == "test"
|