siliconcompiler 0.28.4__py3-none-any.whl → 0.28.6__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/_metadata.py +1 -1
- siliconcompiler/apps/_common.py +88 -56
- siliconcompiler/apps/sc.py +33 -14
- siliconcompiler/apps/sc_dashboard.py +16 -9
- siliconcompiler/apps/sc_show.py +17 -15
- siliconcompiler/apps/utils/summarize.py +47 -0
- siliconcompiler/core.py +20 -12
- siliconcompiler/flows/drcflow.py +13 -0
- siliconcompiler/flows/interposerflow.py +17 -0
- siliconcompiler/libs/interposer.py +8 -0
- siliconcompiler/pdks/interposer.py +8 -0
- siliconcompiler/remote/schema.py +11 -1
- siliconcompiler/remote/server.py +7 -2
- siliconcompiler/report/dashboard/__init__.py +10 -3
- siliconcompiler/scheduler/__init__.py +93 -0
- siliconcompiler/schema/schema_cfg.py +15 -3
- siliconcompiler/schema/schema_obj.py +51 -1
- siliconcompiler/targets/interposer_demo.py +56 -0
- siliconcompiler/templates/tcl/manifest.tcl.j2 +2 -0
- siliconcompiler/tools/klayout/export.py +7 -4
- siliconcompiler/tools/klayout/klayout_export.py +3 -0
- siliconcompiler/tools/klayout/klayout_utils.py +8 -2
- siliconcompiler/tools/openroad/metrics.py +44 -0
- siliconcompiler/tools/openroad/openroad.py +3 -0
- siliconcompiler/tools/openroad/rdlroute.py +97 -0
- siliconcompiler/tools/openroad/scripts/sc_apr.tcl +20 -22
- siliconcompiler/tools/openroad/scripts/sc_metrics.tcl +0 -169
- siliconcompiler/tools/openroad/scripts/sc_rdlroute.tcl +184 -0
- siliconcompiler/tools/openroad/scripts/sc_report.tcl +170 -0
- siliconcompiler/tools/opensta/scripts/sc_report_libraries.tcl +11 -1
- siliconcompiler/tools/xyce/__init__.py +1 -1
- siliconcompiler/toolscripts/_tools.json +3 -4
- siliconcompiler/toolscripts/rhel8/install-xyce.sh +4 -5
- siliconcompiler/toolscripts/rhel9/install-xyce.sh +4 -5
- siliconcompiler/toolscripts/ubuntu20/install-xyce.sh +5 -5
- siliconcompiler/toolscripts/ubuntu22/install-xyce.sh +2 -2
- siliconcompiler/toolscripts/ubuntu24/install-xyce.sh +2 -2
- {siliconcompiler-0.28.4.dist-info → siliconcompiler-0.28.6.dist-info}/METADATA +14 -12
- {siliconcompiler-0.28.4.dist-info → siliconcompiler-0.28.6.dist-info}/RECORD +43 -33
- {siliconcompiler-0.28.4.dist-info → siliconcompiler-0.28.6.dist-info}/WHEEL +1 -1
- {siliconcompiler-0.28.4.dist-info → siliconcompiler-0.28.6.dist-info}/LICENSE +0 -0
- {siliconcompiler-0.28.4.dist-info → siliconcompiler-0.28.6.dist-info}/entry_points.txt +0 -0
- {siliconcompiler-0.28.4.dist-info → siliconcompiler-0.28.6.dist-info}/top_level.txt +0 -0
siliconcompiler/_metadata.py
CHANGED
siliconcompiler/apps/_common.py
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
|
-
import glob
|
|
2
1
|
import os
|
|
3
2
|
|
|
4
3
|
|
|
4
|
+
# TODO: this is a hack to get around design name requirement: since legal
|
|
5
|
+
# design names probably can't contain spaces, we can detect if it is unset.
|
|
6
|
+
UNSET_DESIGN = ' unset '
|
|
7
|
+
|
|
8
|
+
|
|
5
9
|
def manifest_switches():
|
|
6
10
|
'''
|
|
7
11
|
Returns a list of manifest switches that can be used
|
|
@@ -14,63 +18,91 @@ def manifest_switches():
|
|
|
14
18
|
'-jobname']
|
|
15
19
|
|
|
16
20
|
|
|
17
|
-
def
|
|
18
|
-
|
|
19
|
-
if (src_file is not None) and (not chip.get('option', 'cfg')):
|
|
20
|
-
if not os.path.exists(src_file):
|
|
21
|
-
chip.logger.error(f'{src_file} cannot be found.')
|
|
22
|
-
return False
|
|
23
|
-
# only autoload manifest if user doesn't supply manually
|
|
24
|
-
manifest = _get_manifest(os.path.dirname(src_file))
|
|
25
|
-
if not manifest:
|
|
26
|
-
design = os.path.splitext(os.path.basename(src_file))[0]
|
|
27
|
-
chip.logger.error(f'Unable to automatically find manifest for design {design}. '
|
|
28
|
-
'Please provide a manifest explicitly using -cfg.')
|
|
29
|
-
return False
|
|
30
|
-
elif not chip.get('option', 'cfg'):
|
|
31
|
-
manifest = _get_manifest_from_design(chip)
|
|
32
|
-
if not manifest:
|
|
33
|
-
chip.logger.error(f'Could not find manifest for {chip.design}')
|
|
34
|
-
return False
|
|
21
|
+
def _get_manifests(cwd):
|
|
22
|
+
manifests = {}
|
|
35
23
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
24
|
+
def get_dirs(cwd):
|
|
25
|
+
dirs = []
|
|
26
|
+
for dirname in os.listdir(cwd):
|
|
27
|
+
fullpath = os.path.join(cwd, dirname)
|
|
28
|
+
if os.path.isdir(fullpath):
|
|
29
|
+
dirs.append((dirname, fullpath))
|
|
30
|
+
return dirs
|
|
31
|
+
|
|
32
|
+
for _, buildpath in get_dirs(cwd):
|
|
33
|
+
for design, designdir in get_dirs(buildpath):
|
|
34
|
+
for jobname, jobdir in get_dirs(designdir):
|
|
35
|
+
manifest = os.path.join(jobdir, f'{design}.pkg.json')
|
|
36
|
+
if os.path.isfile(manifest):
|
|
37
|
+
manifests[(design, jobname, None, None)] = manifest
|
|
38
|
+
for step, stepdir in get_dirs(jobdir):
|
|
39
|
+
for index, indexdir in get_dirs(stepdir):
|
|
40
|
+
manifest = os.path.join(indexdir, 'outputs', f'{design}.pkg.json')
|
|
41
|
+
if os.path.isfile(manifest):
|
|
42
|
+
manifests[(design, jobname, step, index)] = manifest
|
|
43
|
+
else:
|
|
44
|
+
manifest = os.path.join(indexdir, 'inputs', f'{design}.pkg.json')
|
|
45
|
+
if os.path.isfile(manifest):
|
|
46
|
+
manifests[(design, jobname, step, index)] = manifest
|
|
47
|
+
|
|
48
|
+
organized_manifest = {}
|
|
49
|
+
for (design, job, step, index), manifest in manifests.items():
|
|
50
|
+
jobs = organized_manifest.setdefault(design, {})
|
|
51
|
+
jobs.setdefault(job, {})[step, index] = os.path.abspath(manifest)
|
|
52
|
+
|
|
53
|
+
return organized_manifest
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def pick_manifest_from_file(chip, src_file, all_manifests):
|
|
57
|
+
if src_file is None:
|
|
54
58
|
return None
|
|
55
|
-
return manifest
|
|
56
59
|
|
|
60
|
+
if not os.path.exists(src_file):
|
|
61
|
+
chip.logger.error(f'{src_file} cannot be found.')
|
|
62
|
+
return None
|
|
63
|
+
|
|
64
|
+
src_dir = os.path.abspath(os.path.dirname(src_file))
|
|
65
|
+
for _, jobs in all_manifests.items():
|
|
66
|
+
for _, nodes in jobs.items():
|
|
67
|
+
for manifest in nodes.values():
|
|
68
|
+
if src_dir == os.path.dirname(manifest):
|
|
69
|
+
return manifest
|
|
57
70
|
|
|
58
|
-
def _get_manifest_from_design(chip):
|
|
59
|
-
for jobname, step, index in [
|
|
60
|
-
(chip.get('option', 'jobname'),
|
|
61
|
-
chip.get('arg', 'step'),
|
|
62
|
-
chip.get('arg', 'index')),
|
|
63
|
-
(chip.get('option', 'jobname'),
|
|
64
|
-
None,
|
|
65
|
-
None),
|
|
66
|
-
(chip.schema.get_default('option', 'jobname'),
|
|
67
|
-
chip.get('arg', 'step'),
|
|
68
|
-
chip.get('arg', 'index')),
|
|
69
|
-
(chip.schema.get_default('option', 'jobname'),
|
|
70
|
-
None,
|
|
71
|
-
None)]:
|
|
72
|
-
manifest = _get_manifest(chip.getworkdir(jobname=jobname, step=step, index=index))
|
|
73
|
-
|
|
74
|
-
if manifest:
|
|
75
|
-
return manifest
|
|
76
71
|
return None
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def pick_manifest(chip, src_file=None):
|
|
75
|
+
all_manifests = _get_manifests(os.getcwd())
|
|
76
|
+
|
|
77
|
+
manifest = pick_manifest_from_file(chip, src_file, all_manifests)
|
|
78
|
+
if manifest:
|
|
79
|
+
return manifest
|
|
80
|
+
|
|
81
|
+
if chip.design == UNSET_DESIGN:
|
|
82
|
+
if len(all_manifests) == 1:
|
|
83
|
+
chip.set('design', list(all_manifests.keys())[0])
|
|
84
|
+
else:
|
|
85
|
+
chip.logger.error('Design name is not set')
|
|
86
|
+
return None
|
|
87
|
+
|
|
88
|
+
if chip.design not in all_manifests:
|
|
89
|
+
chip.logger.error(f'Could not find manifest for {chip.design}')
|
|
90
|
+
return None
|
|
91
|
+
|
|
92
|
+
if chip.get('option', 'jobname') not in all_manifests[chip.design] and \
|
|
93
|
+
len(all_manifests[chip.design]) != 1:
|
|
94
|
+
chip.logger.error(f'Could not determine jobname for {chip.design}')
|
|
95
|
+
return None
|
|
96
|
+
|
|
97
|
+
jobname = chip.get('option', 'jobname')
|
|
98
|
+
if chip.get('option', 'jobname') not in all_manifests[chip.design]:
|
|
99
|
+
jobname = list(all_manifests[chip.design].keys())[0]
|
|
100
|
+
|
|
101
|
+
if (None, None) in all_manifests[chip.design][jobname]:
|
|
102
|
+
manifest = all_manifests[chip.design][jobname][None, None]
|
|
103
|
+
else:
|
|
104
|
+
# pick newest manifest
|
|
105
|
+
manifest = list(sorted(all_manifests[chip.design][jobname].values(),
|
|
106
|
+
key=lambda file: os.stat(file).st_ctime))[-1]
|
|
107
|
+
|
|
108
|
+
return manifest
|
siliconcompiler/apps/sc.py
CHANGED
|
@@ -10,6 +10,37 @@ from siliconcompiler.targets import skywater130_demo
|
|
|
10
10
|
from siliconcompiler import SiliconCompilerError
|
|
11
11
|
|
|
12
12
|
|
|
13
|
+
def _infer_designname(chip):
|
|
14
|
+
topfile = None
|
|
15
|
+
sourcesets = chip.getkeys('input')
|
|
16
|
+
for sourceset in reversed(('rtl', 'hll')):
|
|
17
|
+
if sourceset in sourcesets:
|
|
18
|
+
sourcesets.remove(sourceset)
|
|
19
|
+
sourcesets.insert(0, sourceset)
|
|
20
|
+
for sourceset in sourcesets:
|
|
21
|
+
for filetype in chip.getkeys('input', sourceset):
|
|
22
|
+
all_vals = chip.schema._getvals('input', sourceset, filetype)
|
|
23
|
+
if all_vals:
|
|
24
|
+
# just look at first value
|
|
25
|
+
sources, _, _ = all_vals[0]
|
|
26
|
+
# grab first source
|
|
27
|
+
topfile = sources[0]
|
|
28
|
+
break
|
|
29
|
+
if topfile:
|
|
30
|
+
break
|
|
31
|
+
|
|
32
|
+
if not topfile:
|
|
33
|
+
return None
|
|
34
|
+
|
|
35
|
+
root = os.path.basename(topfile)
|
|
36
|
+
while True:
|
|
37
|
+
root, ext = os.path.splitext(root)
|
|
38
|
+
if not ext:
|
|
39
|
+
break
|
|
40
|
+
|
|
41
|
+
return root
|
|
42
|
+
|
|
43
|
+
|
|
13
44
|
###########################
|
|
14
45
|
def main():
|
|
15
46
|
progname = "sc"
|
|
@@ -50,24 +81,12 @@ def main():
|
|
|
50
81
|
|
|
51
82
|
# Set design if none specified
|
|
52
83
|
if chip.get('design') == UNSET_DESIGN:
|
|
53
|
-
|
|
54
|
-
for sourceset in ('rtl', 'hll'):
|
|
55
|
-
for filetype in chip.getkeys('input', sourceset):
|
|
56
|
-
all_vals = chip.schema._getvals('input', sourceset, filetype)
|
|
57
|
-
if all_vals:
|
|
58
|
-
# just look at first value
|
|
59
|
-
sources, _, _ = all_vals[0]
|
|
60
|
-
# grab first source
|
|
61
|
-
topfile = sources[0]
|
|
62
|
-
break
|
|
63
|
-
if topfile:
|
|
64
|
-
break
|
|
84
|
+
topmodule = _infer_designname(chip)
|
|
65
85
|
|
|
66
|
-
if not
|
|
86
|
+
if not topmodule:
|
|
67
87
|
chip.logger.error('Invalid arguments: either specify -design or provide sources.')
|
|
68
88
|
return 1
|
|
69
89
|
|
|
70
|
-
topmodule = os.path.splitext(os.path.basename(topfile))[0]
|
|
71
90
|
chip.set('design', topmodule)
|
|
72
91
|
|
|
73
92
|
# Set demo target if none specified
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import sys
|
|
3
3
|
import siliconcompiler
|
|
4
4
|
import os
|
|
5
|
-
from siliconcompiler.apps._common import
|
|
5
|
+
from siliconcompiler.apps._common import pick_manifest, manifest_switches, UNSET_DESIGN
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
def main():
|
|
@@ -11,9 +11,16 @@ def main():
|
|
|
11
11
|
-----------------------------------------------------------
|
|
12
12
|
SC app to open a dashboard for a given manifest.
|
|
13
13
|
|
|
14
|
-
To open:
|
|
14
|
+
To open and allow sc-dashboard to autoload manifest:
|
|
15
|
+
sc-dashboard
|
|
16
|
+
|
|
17
|
+
To open by specifying manifest:
|
|
15
18
|
sc-dashboard -cfg <path to manifest>
|
|
16
19
|
|
|
20
|
+
To open by specifying design and optionally jobname:
|
|
21
|
+
sc-dashboard -design <name>
|
|
22
|
+
sc-dashboard -design <name> -jobname <jobname>
|
|
23
|
+
|
|
17
24
|
To specify a different port than the default:
|
|
18
25
|
sc-dashboard -cfg <path to manifest> -port 10000
|
|
19
26
|
|
|
@@ -23,10 +30,6 @@ To include another chip object to compare to:
|
|
|
23
30
|
-----------------------------------------------------------
|
|
24
31
|
"""
|
|
25
32
|
|
|
26
|
-
# TODO: this is a hack to get around design name requirement: since legal
|
|
27
|
-
# design names probably can't contain spaces, we can detect if it is unset.
|
|
28
|
-
UNSET_DESIGN = ' unset '
|
|
29
|
-
|
|
30
33
|
# Create a base chip class.
|
|
31
34
|
chip = siliconcompiler.Chip(UNSET_DESIGN)
|
|
32
35
|
|
|
@@ -54,15 +57,19 @@ To include another chip object to compare to:
|
|
|
54
57
|
chip.logger.error(e)
|
|
55
58
|
return 1
|
|
56
59
|
|
|
60
|
+
if not chip.get('option', 'cfg'):
|
|
61
|
+
manifest = pick_manifest(chip)
|
|
62
|
+
|
|
63
|
+
if manifest:
|
|
64
|
+
chip.logger.info(f'Loading manifest: {manifest}')
|
|
65
|
+
chip.read_manifest(manifest)
|
|
66
|
+
|
|
57
67
|
# Error checking
|
|
58
68
|
design = chip.get('design')
|
|
59
69
|
if design == UNSET_DESIGN:
|
|
60
70
|
chip.logger.error('Design not loaded')
|
|
61
71
|
return 1
|
|
62
72
|
|
|
63
|
-
if not load_manifest(chip, None):
|
|
64
|
-
return 1
|
|
65
|
-
|
|
66
73
|
graph_chips = []
|
|
67
74
|
if switches['graph_cfg']:
|
|
68
75
|
for i, name_and_file_path in enumerate(switches['graph_cfg']):
|
siliconcompiler/apps/sc_show.py
CHANGED
|
@@ -3,7 +3,7 @@ import sys
|
|
|
3
3
|
import os
|
|
4
4
|
import siliconcompiler
|
|
5
5
|
from siliconcompiler.utils import get_default_iomap
|
|
6
|
-
from siliconcompiler.apps._common import
|
|
6
|
+
from siliconcompiler.apps._common import manifest_switches, pick_manifest, UNSET_DESIGN
|
|
7
7
|
from siliconcompiler.utils import get_file_ext
|
|
8
8
|
|
|
9
9
|
|
|
@@ -18,6 +18,9 @@ def main():
|
|
|
18
18
|
|
|
19
19
|
Examples:
|
|
20
20
|
|
|
21
|
+
sc-show
|
|
22
|
+
(displays build/adder/job0/write_gds/0/outputs/adder.gds)
|
|
23
|
+
|
|
21
24
|
sc-show -design adder
|
|
22
25
|
(displays build/adder/job0/write_gds/0/outputs/adder.gds)
|
|
23
26
|
|
|
@@ -40,10 +43,6 @@ def main():
|
|
|
40
43
|
(displays build/adder/job0/route/1/outputs/adder.def)
|
|
41
44
|
"""
|
|
42
45
|
|
|
43
|
-
# TODO: this is a hack to get around design name requirement: since legal
|
|
44
|
-
# design names probably can't contain spaces, we can detect if it is unset.
|
|
45
|
-
UNSET_DESIGN = ' unset '
|
|
46
|
-
|
|
47
46
|
# Create a base chip class.
|
|
48
47
|
chip = siliconcompiler.Chip(UNSET_DESIGN)
|
|
49
48
|
|
|
@@ -81,10 +80,6 @@ def main():
|
|
|
81
80
|
chip.logger.error(e)
|
|
82
81
|
return 1
|
|
83
82
|
|
|
84
|
-
# Error checking
|
|
85
|
-
design = chip.get('design')
|
|
86
|
-
design_set = design != UNSET_DESIGN
|
|
87
|
-
|
|
88
83
|
# Search input keys for files
|
|
89
84
|
input_mode = []
|
|
90
85
|
for fileset in chip.getkeys('input'):
|
|
@@ -92,11 +87,6 @@ def main():
|
|
|
92
87
|
if chip.schema._getvals('input', fileset, mode):
|
|
93
88
|
input_mode = [('input', fileset, mode)]
|
|
94
89
|
|
|
95
|
-
if not (design_set or input_mode):
|
|
96
|
-
chip.logger.error('Nothing to load: please define a target with '
|
|
97
|
-
'-cfg, -design, and/or inputs.')
|
|
98
|
-
return 1
|
|
99
|
-
|
|
100
90
|
filename = None
|
|
101
91
|
if input_mode:
|
|
102
92
|
check_ext = list(chip._showtools.keys())
|
|
@@ -115,7 +105,19 @@ def main():
|
|
|
115
105
|
|
|
116
106
|
filename = get_file_from_keys()
|
|
117
107
|
|
|
118
|
-
|
|
108
|
+
# Attempt to load a manifest
|
|
109
|
+
if not chip.get('option', 'cfg'):
|
|
110
|
+
manifest = pick_manifest(chip, src_file=filename)
|
|
111
|
+
if manifest:
|
|
112
|
+
chip.logger.info(f'Loading manifest: {manifest}')
|
|
113
|
+
chip.read_manifest(manifest)
|
|
114
|
+
|
|
115
|
+
# Error checking
|
|
116
|
+
design = chip.get('design')
|
|
117
|
+
design_set = design != UNSET_DESIGN
|
|
118
|
+
if not (design_set or input_mode):
|
|
119
|
+
chip.logger.error('Nothing to load: please define a target with '
|
|
120
|
+
'-cfg, -design, and/or inputs.')
|
|
119
121
|
return 1
|
|
120
122
|
|
|
121
123
|
# Read in file
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# Copyright 2024 Silicon Compiler Authors. All Rights Reserved.
|
|
2
|
+
|
|
3
|
+
# Standard Modules
|
|
4
|
+
import sys
|
|
5
|
+
|
|
6
|
+
import siliconcompiler
|
|
7
|
+
from siliconcompiler.apps._common import UNSET_DESIGN
|
|
8
|
+
from siliconcompiler import SiliconCompilerError
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
###########################
|
|
12
|
+
def main():
|
|
13
|
+
progname = "summarize"
|
|
14
|
+
description = """
|
|
15
|
+
------------------------------------------------------------
|
|
16
|
+
Utility script to print job summary from a manifest
|
|
17
|
+
------------------------------------------------------------
|
|
18
|
+
"""
|
|
19
|
+
# Create a base chip class.
|
|
20
|
+
chip = siliconcompiler.Chip(UNSET_DESIGN)
|
|
21
|
+
|
|
22
|
+
# Read command-line inputs and generate Chip objects to run the flow on.
|
|
23
|
+
try:
|
|
24
|
+
chip.create_cmdline(progname,
|
|
25
|
+
description=description,
|
|
26
|
+
switchlist=['-cfg',
|
|
27
|
+
'-loglevel'])
|
|
28
|
+
except SiliconCompilerError:
|
|
29
|
+
return 1
|
|
30
|
+
except Exception as e:
|
|
31
|
+
chip.logger.error(e)
|
|
32
|
+
return 1
|
|
33
|
+
|
|
34
|
+
design = chip.get('design')
|
|
35
|
+
if design == UNSET_DESIGN:
|
|
36
|
+
chip.logger.error('Design not loaded')
|
|
37
|
+
return 1
|
|
38
|
+
|
|
39
|
+
# Print Job Summary
|
|
40
|
+
chip.summary(generate_image=False, generate_html=False)
|
|
41
|
+
|
|
42
|
+
return 0
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
#########################
|
|
46
|
+
if __name__ == "__main__":
|
|
47
|
+
sys.exit(main())
|
siliconcompiler/core.py
CHANGED
|
@@ -399,7 +399,7 @@ class Chip:
|
|
|
399
399
|
self.set(*key, packages, field='package', step=step, index=index)
|
|
400
400
|
|
|
401
401
|
# Read in target if set
|
|
402
|
-
if "target" in extra_params:
|
|
402
|
+
if extra_params is not None and "target" in extra_params:
|
|
403
403
|
if extra_params["target"]:
|
|
404
404
|
# running target command
|
|
405
405
|
# Search order "{name}", and "siliconcompiler.targets.{name}"
|
|
@@ -416,7 +416,7 @@ class Chip:
|
|
|
416
416
|
self.use(modules[0])
|
|
417
417
|
extra_params["target"] = modules[0].__name__
|
|
418
418
|
|
|
419
|
-
if "use" in extra_params:
|
|
419
|
+
if extra_params is not None and "use" in extra_params:
|
|
420
420
|
if extra_params["use"]:
|
|
421
421
|
for use in extra_params["use"]:
|
|
422
422
|
mod = self._load_module(use)
|
|
@@ -437,19 +437,25 @@ class Chip:
|
|
|
437
437
|
if "-target" in additional_args:
|
|
438
438
|
raise ValueError('-target cannot be used as an additional argument')
|
|
439
439
|
|
|
440
|
-
|
|
441
|
-
"
|
|
442
|
-
|
|
443
|
-
|
|
440
|
+
if switchlist is None or '-target' in switchlist:
|
|
441
|
+
additional_args["-target"] = {
|
|
442
|
+
"help": "target to load",
|
|
443
|
+
"metavar": "<target>"
|
|
444
|
+
}
|
|
445
|
+
if switchlist:
|
|
446
|
+
switchlist.remove('-target')
|
|
444
447
|
|
|
445
448
|
if "-use" in additional_args:
|
|
446
449
|
raise ValueError('-use cannot be used as an additional argument')
|
|
447
450
|
|
|
448
|
-
|
|
449
|
-
"
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
451
|
+
if switchlist is None or '-use' in switchlist:
|
|
452
|
+
additional_args["-use"] = {
|
|
453
|
+
"action": "append",
|
|
454
|
+
"help": "modules to load",
|
|
455
|
+
"metavar": "<module>"
|
|
456
|
+
}
|
|
457
|
+
if switchlist:
|
|
458
|
+
switchlist.remove('-use')
|
|
453
459
|
|
|
454
460
|
try:
|
|
455
461
|
return self.schema.create_cmdline(
|
|
@@ -2123,7 +2129,9 @@ class Chip:
|
|
|
2123
2129
|
nonlocal graph_idx
|
|
2124
2130
|
|
|
2125
2131
|
for subgraph in graph_info["graphs"]:
|
|
2132
|
+
child_prefix = prefix
|
|
2126
2133
|
if get_node_count(graph_info["graphs"][subgraph]) > 1:
|
|
2134
|
+
child_prefix = f"{child_prefix}{subgraph}."
|
|
2127
2135
|
graph = graphviz.Digraph(name=f"cluster_{graph_idx}")
|
|
2128
2136
|
graph_idx += 1
|
|
2129
2137
|
|
|
@@ -2143,7 +2151,7 @@ class Chip:
|
|
|
2143
2151
|
else:
|
|
2144
2152
|
graph = parent
|
|
2145
2153
|
|
|
2146
|
-
build_graph(graph_info["graphs"][subgraph], graph,
|
|
2154
|
+
build_graph(graph_info["graphs"][subgraph], graph, child_prefix)
|
|
2147
2155
|
|
|
2148
2156
|
if graph is not parent:
|
|
2149
2157
|
parent.subgraph(graph)
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
from siliconcompiler import Flow
|
|
2
|
+
|
|
3
|
+
from siliconcompiler.tools.openroad import rdlroute
|
|
4
|
+
from siliconcompiler.tools.klayout import export
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def setup():
|
|
8
|
+
'''
|
|
9
|
+
A flow to perform RDL routing and generate a GDS
|
|
10
|
+
'''
|
|
11
|
+
flow = Flow('interposerflow')
|
|
12
|
+
flow.node('interposerflow', 'rdlroute', rdlroute)
|
|
13
|
+
flow.node('interposerflow', 'write_gds', export)
|
|
14
|
+
|
|
15
|
+
flow.edge('interposerflow', 'rdlroute', 'write_gds')
|
|
16
|
+
|
|
17
|
+
return flow
|
siliconcompiler/remote/schema.py
CHANGED
|
@@ -2,7 +2,7 @@ from siliconcompiler.schema.schema_cfg import scparam
|
|
|
2
2
|
from siliconcompiler.schema import Schema
|
|
3
3
|
|
|
4
4
|
|
|
5
|
-
SCHEMA_VERSION = '0.0.
|
|
5
|
+
SCHEMA_VERSION = '0.0.2'
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
def schema_cfg():
|
|
@@ -93,6 +93,16 @@ def schema_cfg():
|
|
|
93
93
|
schelp="""
|
|
94
94
|
Provides explicit control over the level of debug logging printed.""")
|
|
95
95
|
|
|
96
|
+
scparam(cfg, ['option', 'checkinterval'],
|
|
97
|
+
sctype='int',
|
|
98
|
+
defvalue=30,
|
|
99
|
+
shorthelp="Interval for client",
|
|
100
|
+
switch="-checkinterval <int>",
|
|
101
|
+
example=["cli: -checkinterval 10",
|
|
102
|
+
"api: chip.set('option', 'checkinterval', 10)"],
|
|
103
|
+
schelp="""
|
|
104
|
+
Interval between checks to announce to clients""")
|
|
105
|
+
|
|
96
106
|
return cfg
|
|
97
107
|
|
|
98
108
|
|
siliconcompiler/remote/server.py
CHANGED
|
@@ -239,7 +239,7 @@ class Server:
|
|
|
239
239
|
|
|
240
240
|
# Return a response to the client.
|
|
241
241
|
return web.json_response({'message': f"Starting job: {job_hash}",
|
|
242
|
-
'interval':
|
|
242
|
+
'interval': self.checkinterval,
|
|
243
243
|
'job_hash': job_hash})
|
|
244
244
|
|
|
245
245
|
####################
|
|
@@ -375,7 +375,7 @@ class Server:
|
|
|
375
375
|
'sc_schema': sc_schema_version,
|
|
376
376
|
'sc_server': Server.__version__,
|
|
377
377
|
},
|
|
378
|
-
'progress_interval':
|
|
378
|
+
'progress_interval': self.checkinterval
|
|
379
379
|
}
|
|
380
380
|
|
|
381
381
|
username = job_params['username']
|
|
@@ -490,6 +490,11 @@ class Server:
|
|
|
490
490
|
# Ensure that NFS mounting path is absolute.
|
|
491
491
|
return os.path.abspath(self.get('option', 'nfsmount'))
|
|
492
492
|
|
|
493
|
+
###################
|
|
494
|
+
@property
|
|
495
|
+
def checkinterval(self):
|
|
496
|
+
return self.get('option', 'checkinterval')
|
|
497
|
+
|
|
493
498
|
def get(self, *keypath, field='value'):
|
|
494
499
|
return self.schema.get(*keypath, field=field)
|
|
495
500
|
|
|
@@ -3,9 +3,6 @@ import time
|
|
|
3
3
|
import tempfile
|
|
4
4
|
import json
|
|
5
5
|
|
|
6
|
-
from streamlit.web import bootstrap
|
|
7
|
-
from streamlit import config as _config
|
|
8
|
-
|
|
9
6
|
import multiprocessing
|
|
10
7
|
import subprocess
|
|
11
8
|
import atexit
|
|
@@ -16,6 +13,13 @@ import socketserver
|
|
|
16
13
|
|
|
17
14
|
from siliconcompiler.report.dashboard import utils
|
|
18
15
|
|
|
16
|
+
try:
|
|
17
|
+
from streamlit.web import bootstrap
|
|
18
|
+
from streamlit import config as _config
|
|
19
|
+
except ModuleNotFoundError:
|
|
20
|
+
bootstrap = None
|
|
21
|
+
_config = None
|
|
22
|
+
|
|
19
23
|
|
|
20
24
|
class Dashboard():
|
|
21
25
|
__port = 8501
|
|
@@ -26,6 +30,9 @@ class Dashboard():
|
|
|
26
30
|
pass
|
|
27
31
|
|
|
28
32
|
def __init__(self, chip, port=None, graph_chips=None):
|
|
33
|
+
if not bootstrap:
|
|
34
|
+
raise NotImplementedError('streamlit is not available')
|
|
35
|
+
|
|
29
36
|
if not port:
|
|
30
37
|
port = Dashboard.get_next_port()
|
|
31
38
|
if not port:
|