siliconcompiler 0.33.0__py3-none-any.whl → 0.33.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/_common.py +5 -0
- siliconcompiler/_metadata.py +1 -1
- siliconcompiler/apps/sc_install.py +7 -0
- siliconcompiler/apps/sc_remote.py +7 -2
- siliconcompiler/apps/utils/replay.py +5 -5
- siliconcompiler/core.py +38 -12
- siliconcompiler/data/templates/replay/replay.sh.j2 +18 -1
- siliconcompiler/metric.py +78 -0
- siliconcompiler/package/git.py +1 -1
- siliconcompiler/record.py +63 -7
- siliconcompiler/remote/client.py +57 -14
- siliconcompiler/remote/server.py +110 -60
- siliconcompiler/report/dashboard/cli/__init__.py +2 -0
- siliconcompiler/report/dashboard/cli/board.py +34 -31
- siliconcompiler/report/report.py +10 -5
- siliconcompiler/report/utils.py +12 -6
- siliconcompiler/scheduler/__init__.py +146 -976
- siliconcompiler/scheduler/run_node.py +12 -5
- siliconcompiler/scheduler/send_messages.py +9 -3
- siliconcompiler/scheduler/slurm.py +10 -43
- siliconcompiler/scheduler/taskscheduler.py +320 -0
- siliconcompiler/schema/baseschema.py +25 -4
- siliconcompiler/schema/journalingschema.py +4 -0
- siliconcompiler/schema/schema_cfg.py +3 -3
- siliconcompiler/tool.py +201 -32
- siliconcompiler/tools/_common/__init__.py +14 -11
- siliconcompiler/tools/_common/asic.py +5 -5
- siliconcompiler/tools/bluespec/convert.py +2 -1
- siliconcompiler/tools/builtin/_common.py +9 -2
- siliconcompiler/tools/builtin/concatenate.py +6 -2
- siliconcompiler/tools/builtin/minimum.py +7 -2
- siliconcompiler/tools/builtin/mux.py +7 -2
- siliconcompiler/tools/builtin/nop.py +7 -2
- siliconcompiler/tools/builtin/verify.py +7 -3
- siliconcompiler/tools/chisel/convert.py +10 -10
- siliconcompiler/tools/klayout/drc.py +2 -2
- siliconcompiler/tools/klayout/klayout_show.py +6 -6
- siliconcompiler/tools/klayout/klayout_utils.py +12 -12
- siliconcompiler/tools/netgen/count_lvs.py +2 -2
- siliconcompiler/tools/netgen/lvs.py +1 -1
- siliconcompiler/tools/openroad/_apr.py +2 -2
- siliconcompiler/tools/openroad/scripts/apr/sc_init_floorplan.tcl +1 -7
- siliconcompiler/tools/openroad/scripts/common/procs.tcl +18 -0
- siliconcompiler/tools/openroad/scripts/common/read_input_files.tcl +1 -7
- siliconcompiler/tools/opensta/scripts/sc_timing.tcl +10 -0
- siliconcompiler/tools/opensta/timing.py +11 -0
- siliconcompiler/tools/slang/__init__.py +6 -5
- siliconcompiler/tools/slang/elaborate.py +6 -6
- siliconcompiler/tools/slang/lint.py +1 -3
- siliconcompiler/tools/vpr/_xml_constraint.py +8 -8
- siliconcompiler/tools/yosys/prepareLib.py +2 -2
- siliconcompiler/tools/yosys/sc_synth_asic.tcl +43 -5
- siliconcompiler/tools/yosys/screenshot.py +1 -1
- siliconcompiler/tools/yosys/syn_asic.py +5 -5
- siliconcompiler/toolscripts/_tools.json +17 -10
- siliconcompiler/toolscripts/rhel8/install-chisel.sh +9 -2
- siliconcompiler/toolscripts/rhel8/install-icarus.sh +10 -3
- siliconcompiler/toolscripts/rhel8/install-klayout.sh +8 -1
- siliconcompiler/toolscripts/rhel8/install-magic.sh +9 -2
- siliconcompiler/toolscripts/rhel8/install-montage.sh +1 -1
- siliconcompiler/toolscripts/rhel8/install-netgen.sh +9 -2
- siliconcompiler/toolscripts/rhel8/install-slang.sh +11 -4
- siliconcompiler/toolscripts/rhel8/install-surelog.sh +9 -2
- siliconcompiler/toolscripts/rhel8/install-sv2v.sh +11 -4
- siliconcompiler/toolscripts/rhel8/install-verible.sh +11 -3
- siliconcompiler/toolscripts/rhel8/install-verilator.sh +10 -3
- siliconcompiler/toolscripts/rhel8/install-xyce.sh +15 -10
- siliconcompiler/toolscripts/rhel9/install-chisel.sh +9 -2
- siliconcompiler/toolscripts/rhel9/install-ghdl.sh +9 -2
- siliconcompiler/toolscripts/rhel9/install-gtkwave.sh +10 -3
- siliconcompiler/toolscripts/rhel9/install-icarus.sh +10 -3
- siliconcompiler/toolscripts/rhel9/install-klayout.sh +8 -1
- siliconcompiler/toolscripts/rhel9/install-magic.sh +9 -2
- siliconcompiler/toolscripts/rhel9/install-montage.sh +1 -1
- siliconcompiler/toolscripts/rhel9/install-netgen.sh +9 -2
- siliconcompiler/toolscripts/rhel9/install-openroad.sh +16 -3
- siliconcompiler/toolscripts/rhel9/install-opensta.sh +17 -5
- siliconcompiler/toolscripts/rhel9/install-slang.sh +11 -4
- siliconcompiler/toolscripts/rhel9/install-surelog.sh +9 -2
- siliconcompiler/toolscripts/rhel9/install-sv2v.sh +11 -4
- siliconcompiler/toolscripts/rhel9/install-verible.sh +11 -3
- siliconcompiler/toolscripts/rhel9/install-verilator.sh +10 -3
- siliconcompiler/toolscripts/rhel9/install-vpr.sh +9 -2
- siliconcompiler/toolscripts/rhel9/install-xdm.sh +10 -2
- siliconcompiler/toolscripts/rhel9/install-xyce.sh +15 -10
- siliconcompiler/toolscripts/rhel9/install-yosys-moosic.sh +9 -2
- siliconcompiler/toolscripts/rhel9/install-yosys-parmys.sh +10 -3
- siliconcompiler/toolscripts/rhel9/install-yosys-slang.sh +10 -2
- siliconcompiler/toolscripts/rhel9/install-yosys.sh +9 -2
- siliconcompiler/toolscripts/ubuntu20/install-bambu.sh +10 -2
- siliconcompiler/toolscripts/ubuntu20/install-bluespec.sh +10 -3
- siliconcompiler/toolscripts/ubuntu20/install-chisel.sh +9 -2
- siliconcompiler/toolscripts/ubuntu20/install-ghdl.sh +9 -2
- siliconcompiler/toolscripts/ubuntu20/install-gtkwave.sh +9 -2
- siliconcompiler/toolscripts/ubuntu20/install-icarus.sh +9 -2
- siliconcompiler/toolscripts/ubuntu20/install-icepack.sh +9 -2
- siliconcompiler/toolscripts/ubuntu20/install-klayout.sh +8 -1
- siliconcompiler/toolscripts/ubuntu20/install-magic.sh +9 -2
- siliconcompiler/toolscripts/ubuntu20/install-montage.sh +1 -1
- siliconcompiler/toolscripts/ubuntu20/install-netgen.sh +9 -2
- siliconcompiler/toolscripts/ubuntu20/install-nextpnr.sh +9 -2
- siliconcompiler/toolscripts/ubuntu20/install-openroad.sh +16 -3
- siliconcompiler/toolscripts/ubuntu20/install-opensta.sh +16 -5
- siliconcompiler/toolscripts/ubuntu20/install-slang.sh +11 -4
- siliconcompiler/toolscripts/ubuntu20/install-slurm.sh +9 -2
- siliconcompiler/toolscripts/ubuntu20/install-surelog.sh +10 -2
- siliconcompiler/toolscripts/ubuntu20/install-sv2v.sh +11 -4
- siliconcompiler/toolscripts/ubuntu20/install-verible.sh +11 -3
- siliconcompiler/toolscripts/ubuntu20/install-verilator.sh +9 -2
- siliconcompiler/toolscripts/ubuntu20/install-xdm.sh +10 -2
- siliconcompiler/toolscripts/ubuntu20/install-xyce.sh +13 -8
- siliconcompiler/toolscripts/ubuntu20/install-yosys-moosic.sh +9 -2
- siliconcompiler/toolscripts/ubuntu20/install-yosys.sh +9 -2
- siliconcompiler/toolscripts/ubuntu22/install-bambu.sh +10 -2
- siliconcompiler/toolscripts/ubuntu22/install-bluespec.sh +10 -3
- siliconcompiler/toolscripts/ubuntu22/install-chisel.sh +9 -2
- siliconcompiler/toolscripts/ubuntu22/install-ghdl.sh +9 -2
- siliconcompiler/toolscripts/ubuntu22/install-gtkwave.sh +9 -2
- siliconcompiler/toolscripts/ubuntu22/install-icarus.sh +9 -2
- siliconcompiler/toolscripts/ubuntu22/install-icepack.sh +9 -2
- siliconcompiler/toolscripts/ubuntu22/install-klayout.sh +12 -1
- siliconcompiler/toolscripts/ubuntu22/install-magic.sh +9 -2
- siliconcompiler/toolscripts/ubuntu22/install-montage.sh +1 -1
- siliconcompiler/toolscripts/ubuntu22/install-netgen.sh +9 -2
- siliconcompiler/toolscripts/ubuntu22/install-nextpnr.sh +9 -2
- siliconcompiler/toolscripts/ubuntu22/install-openroad.sh +16 -3
- siliconcompiler/toolscripts/ubuntu22/install-opensta.sh +17 -5
- siliconcompiler/toolscripts/ubuntu22/install-slang.sh +11 -4
- siliconcompiler/toolscripts/ubuntu22/install-slurm.sh +9 -2
- siliconcompiler/toolscripts/ubuntu22/install-surelog.sh +10 -2
- siliconcompiler/toolscripts/ubuntu22/install-sv2v.sh +11 -4
- siliconcompiler/toolscripts/ubuntu22/install-verible.sh +11 -3
- siliconcompiler/toolscripts/ubuntu22/install-verilator.sh +9 -2
- siliconcompiler/toolscripts/ubuntu22/install-vpr.sh +9 -2
- siliconcompiler/toolscripts/ubuntu22/install-xdm.sh +10 -2
- siliconcompiler/toolscripts/ubuntu22/install-xyce.sh +13 -8
- siliconcompiler/toolscripts/ubuntu22/install-yosys-moosic.sh +9 -2
- siliconcompiler/toolscripts/ubuntu22/install-yosys-parmys.sh +10 -3
- siliconcompiler/toolscripts/ubuntu22/install-yosys-slang.sh +10 -2
- siliconcompiler/toolscripts/ubuntu22/install-yosys.sh +9 -2
- siliconcompiler/toolscripts/ubuntu24/install-bambu.sh +12 -4
- siliconcompiler/toolscripts/ubuntu24/install-bluespec.sh +10 -3
- siliconcompiler/toolscripts/ubuntu24/install-chisel.sh +9 -2
- siliconcompiler/toolscripts/ubuntu24/install-ghdl.sh +9 -2
- siliconcompiler/toolscripts/ubuntu24/install-gtkwave.sh +9 -2
- siliconcompiler/toolscripts/ubuntu24/install-icarus.sh +9 -2
- siliconcompiler/toolscripts/ubuntu24/install-icepack.sh +9 -2
- siliconcompiler/toolscripts/ubuntu24/install-klayout.sh +12 -1
- siliconcompiler/toolscripts/ubuntu24/install-magic.sh +9 -2
- siliconcompiler/toolscripts/ubuntu24/install-montage.sh +1 -1
- siliconcompiler/toolscripts/ubuntu24/install-netgen.sh +9 -2
- siliconcompiler/toolscripts/ubuntu24/install-nextpnr.sh +9 -2
- siliconcompiler/toolscripts/ubuntu24/install-openroad.sh +16 -3
- siliconcompiler/toolscripts/ubuntu24/install-opensta.sh +17 -5
- siliconcompiler/toolscripts/ubuntu24/install-slang.sh +11 -4
- siliconcompiler/toolscripts/ubuntu24/install-slurm.sh +9 -2
- siliconcompiler/toolscripts/ubuntu24/install-surelog.sh +10 -2
- siliconcompiler/toolscripts/ubuntu24/install-sv2v.sh +11 -4
- siliconcompiler/toolscripts/ubuntu24/install-verible.sh +11 -3
- siliconcompiler/toolscripts/ubuntu24/install-verilator.sh +9 -2
- siliconcompiler/toolscripts/ubuntu24/install-vpr.sh +9 -2
- siliconcompiler/toolscripts/ubuntu24/install-xdm.sh +10 -2
- siliconcompiler/toolscripts/ubuntu24/install-xyce.sh +13 -8
- siliconcompiler/toolscripts/ubuntu24/install-yosys-moosic.sh +9 -2
- siliconcompiler/toolscripts/ubuntu24/install-yosys-parmys.sh +10 -3
- siliconcompiler/toolscripts/ubuntu24/install-yosys-slang.sh +10 -2
- siliconcompiler/toolscripts/ubuntu24/install-yosys.sh +9 -2
- siliconcompiler/utils/__init__.py +11 -0
- siliconcompiler/utils/flowgraph.py +6 -101
- siliconcompiler/utils/issue.py +15 -23
- siliconcompiler/utils/logging.py +2 -2
- {siliconcompiler-0.33.0.dist-info → siliconcompiler-0.33.2.dist-info}/METADATA +6 -5
- {siliconcompiler-0.33.0.dist-info → siliconcompiler-0.33.2.dist-info}/RECORD +177 -176
- {siliconcompiler-0.33.0.dist-info → siliconcompiler-0.33.2.dist-info}/WHEEL +1 -1
- {siliconcompiler-0.33.0.dist-info → siliconcompiler-0.33.2.dist-info}/entry_points.txt +0 -0
- {siliconcompiler-0.33.0.dist-info → siliconcompiler-0.33.2.dist-info}/licenses/LICENSE +0 -0
- {siliconcompiler-0.33.0.dist-info → siliconcompiler-0.33.2.dist-info}/top_level.txt +0 -0
siliconcompiler/_common.py
CHANGED
|
@@ -14,6 +14,7 @@ class NodeStatus():
|
|
|
14
14
|
SKIPPED = 'skipped'
|
|
15
15
|
TIMEOUT = 'timeout'
|
|
16
16
|
|
|
17
|
+
@staticmethod
|
|
17
18
|
def is_done(status):
|
|
18
19
|
return status in (
|
|
19
20
|
NodeStatus.SUCCESS,
|
|
@@ -22,23 +23,27 @@ class NodeStatus():
|
|
|
22
23
|
NodeStatus.TIMEOUT
|
|
23
24
|
)
|
|
24
25
|
|
|
26
|
+
@staticmethod
|
|
25
27
|
def is_running(status):
|
|
26
28
|
return status in (
|
|
27
29
|
NodeStatus.QUEUED,
|
|
28
30
|
NodeStatus.RUNNING
|
|
29
31
|
)
|
|
30
32
|
|
|
33
|
+
@staticmethod
|
|
31
34
|
def is_waiting(status):
|
|
32
35
|
return status in (
|
|
33
36
|
NodeStatus.PENDING,
|
|
34
37
|
)
|
|
35
38
|
|
|
39
|
+
@staticmethod
|
|
36
40
|
def is_success(status):
|
|
37
41
|
return status in (
|
|
38
42
|
NodeStatus.SUCCESS,
|
|
39
43
|
NodeStatus.SKIPPED
|
|
40
44
|
)
|
|
41
45
|
|
|
46
|
+
@staticmethod
|
|
42
47
|
def is_error(status):
|
|
43
48
|
return status in (
|
|
44
49
|
NodeStatus.ERROR,
|
siliconcompiler/_metadata.py
CHANGED
|
@@ -42,6 +42,13 @@ def install_tool(tool, script, build_dir, prefix):
|
|
|
42
42
|
# setup environment
|
|
43
43
|
env = os.environ.copy()
|
|
44
44
|
env["PREFIX"] = prefix
|
|
45
|
+
env["USE_SUDO_INSTALL"] = "no"
|
|
46
|
+
try:
|
|
47
|
+
os.makedirs(prefix, exist_ok=True)
|
|
48
|
+
except PermissionError:
|
|
49
|
+
env["USE_SUDO_INSTALL"] = "yes"
|
|
50
|
+
if not os.access(prefix, os.W_OK):
|
|
51
|
+
env["USE_SUDO_INSTALL"] = "yes"
|
|
45
52
|
|
|
46
53
|
# run
|
|
47
54
|
ret = subprocess.call(script, env=env, cwd=build_dir)
|
|
@@ -6,7 +6,7 @@ from siliconcompiler import Chip
|
|
|
6
6
|
from siliconcompiler import SiliconCompilerError
|
|
7
7
|
from siliconcompiler.remote.client import Client, ConfigureClient
|
|
8
8
|
from siliconcompiler.scheduler import _finalize_run
|
|
9
|
-
from siliconcompiler.
|
|
9
|
+
from siliconcompiler.flowgraph import RuntimeFlowgraph
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
def main():
|
|
@@ -170,7 +170,12 @@ To delete a job, use:
|
|
|
170
170
|
return 1
|
|
171
171
|
|
|
172
172
|
# Wrap up run
|
|
173
|
-
|
|
173
|
+
runtime = RuntimeFlowgraph(
|
|
174
|
+
chip.schema.get("flowgraph", flow, field='schema'),
|
|
175
|
+
from_steps=chip.get('option', 'from'),
|
|
176
|
+
to_steps=chip.get('option', 'to'),
|
|
177
|
+
prune_nodes=chip.get('option', 'prune'))
|
|
178
|
+
for step, index in runtime.get_nodes():
|
|
174
179
|
manifest = os.path.join(chip.getworkdir(step=step, index=index),
|
|
175
180
|
'outputs',
|
|
176
181
|
f'{chip.design}.pkg.json')
|
|
@@ -18,6 +18,7 @@ import siliconcompiler
|
|
|
18
18
|
from siliconcompiler.apps._common import UNSET_DESIGN
|
|
19
19
|
from siliconcompiler import SiliconCompilerError
|
|
20
20
|
from siliconcompiler import utils
|
|
21
|
+
from siliconcompiler.record import RecordTime
|
|
21
22
|
|
|
22
23
|
|
|
23
24
|
def make_bytes(data):
|
|
@@ -127,11 +128,10 @@ def main():
|
|
|
127
128
|
path = os.path.abspath(args['file'])
|
|
128
129
|
os.makedirs(os.path.dirname(path), exist_ok=True)
|
|
129
130
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
starttime = min(starttimes).strftime('%Y-%m-%d %H:%M:%S')
|
|
131
|
+
record_schema = chip.schema.get('history', jobname, 'record', field="schema")
|
|
132
|
+
starttime = datetime.fromtimestamp(
|
|
133
|
+
record_schema.get_earliest_time(RecordTime.START)).strftime(
|
|
134
|
+
'%Y-%m-%d %H:%M:%S')
|
|
135
135
|
|
|
136
136
|
with io.StringIO() as fd:
|
|
137
137
|
fd.write(utils.get_file_template('replay/requirements.txt').render(
|
siliconcompiler/core.py
CHANGED
|
@@ -37,10 +37,7 @@ from siliconcompiler.report.dashboard import DashboardType
|
|
|
37
37
|
from siliconcompiler import package as sc_package
|
|
38
38
|
import glob
|
|
39
39
|
from siliconcompiler.scheduler import run as sc_runner
|
|
40
|
-
from siliconcompiler.utils.flowgraph import
|
|
41
|
-
_get_pruned_node_inputs, \
|
|
42
|
-
_get_flowgraph_execution_order, _check_flowgraph_io, \
|
|
43
|
-
_get_flowgraph_information
|
|
40
|
+
from siliconcompiler.utils.flowgraph import _check_flowgraph_io, _get_flowgraph_information
|
|
44
41
|
from siliconcompiler.tools._common import get_tool_task
|
|
45
42
|
from types import FunctionType, ModuleType
|
|
46
43
|
from siliconcompiler.flowgraph import RuntimeFlowgraph
|
|
@@ -1622,11 +1619,26 @@ class Chip:
|
|
|
1622
1619
|
error = True
|
|
1623
1620
|
self.logger.error(f"flowgraph {flow} not defined.")
|
|
1624
1621
|
|
|
1625
|
-
|
|
1622
|
+
runtime = RuntimeFlowgraph(
|
|
1623
|
+
self.schema.get("flowgraph", flow, field='schema'),
|
|
1624
|
+
args=(self.get('arg', 'step'), self.get('arg', 'index')),
|
|
1625
|
+
from_steps=self.get('option', 'from'),
|
|
1626
|
+
to_steps=self.get('option', 'to'),
|
|
1627
|
+
prune_nodes=self.get('option', 'prune'))
|
|
1628
|
+
|
|
1629
|
+
nodes = [node for node in runtime.get_nodes()
|
|
1626
1630
|
if self.get('record', 'status', step=node[0], index=node[1])
|
|
1627
1631
|
!= NodeStatus.SKIPPED]
|
|
1632
|
+
flow_schema = self.schema.get("flowgraph", flow, field="schema")
|
|
1633
|
+
runtime_io = RuntimeFlowgraph(
|
|
1634
|
+
flow_schema,
|
|
1635
|
+
args=(self.get('arg', 'step'), self.get('arg', 'index')),
|
|
1636
|
+
from_steps=set([step for step, _ in flow_schema.get_entry_nodes()]),
|
|
1637
|
+
prune_nodes=self.get('option', 'prune'))
|
|
1638
|
+
|
|
1628
1639
|
for (step, index) in nodes:
|
|
1629
|
-
for in_step, in_index in
|
|
1640
|
+
for in_step, in_index in runtime_io.get_node_inputs(
|
|
1641
|
+
step, index, record=self.schema.get("record", field="schema")):
|
|
1630
1642
|
if (in_step, in_index) in nodes:
|
|
1631
1643
|
# we're gonna run this step, OK
|
|
1632
1644
|
continue
|
|
@@ -1717,7 +1729,11 @@ class Chip:
|
|
|
1717
1729
|
error = True
|
|
1718
1730
|
self.logger.error(f'No executable or run() function specified for {tool}/{task}')
|
|
1719
1731
|
|
|
1720
|
-
|
|
1732
|
+
runtime_full = RuntimeFlowgraph(
|
|
1733
|
+
self.schema.get("flowgraph", flow, field='schema'),
|
|
1734
|
+
to_steps=self.get('option', 'to'),
|
|
1735
|
+
prune_nodes=self.get('option', 'prune'))
|
|
1736
|
+
if not error and not _check_flowgraph_io(self, nodes=runtime_full.get_nodes()):
|
|
1721
1737
|
error = True
|
|
1722
1738
|
|
|
1723
1739
|
return not error
|
|
@@ -2748,7 +2764,13 @@ class Chip:
|
|
|
2748
2764
|
flow = self.get('option', 'flow')
|
|
2749
2765
|
flowgraph_nodes = [(step, index) for index in self.getkeys("flowgraph", flow, step)]
|
|
2750
2766
|
else:
|
|
2751
|
-
|
|
2767
|
+
flow = self.get('option', 'flow')
|
|
2768
|
+
runtime = RuntimeFlowgraph(
|
|
2769
|
+
self.schema.get("flowgraph", flow, field='schema'),
|
|
2770
|
+
from_steps=self.get('option', 'from'),
|
|
2771
|
+
to_steps=self.get('option', 'to'),
|
|
2772
|
+
prune_nodes=self.get('option', 'prune'))
|
|
2773
|
+
flowgraph_nodes = runtime.get_nodes()
|
|
2752
2774
|
|
|
2753
2775
|
if not archive_name:
|
|
2754
2776
|
if step and index:
|
|
@@ -3231,14 +3253,18 @@ class Chip:
|
|
|
3231
3253
|
search_nodes.append((sc_step, sc_index))
|
|
3232
3254
|
elif sc_step:
|
|
3233
3255
|
if flow is not None:
|
|
3234
|
-
|
|
3256
|
+
runtime = RuntimeFlowgraph(
|
|
3257
|
+
self.schema.get("flowgraph", flow, field='schema'),
|
|
3258
|
+
from_steps=self.get('option', 'from'),
|
|
3259
|
+
to_steps=self.get('option', 'to'),
|
|
3260
|
+
prune_nodes=self.get('option', 'prune'))
|
|
3261
|
+
for check_step, check_index in runtime.get_nodes():
|
|
3235
3262
|
if sc_step == check_step:
|
|
3236
3263
|
search_nodes.append((check_step, check_index))
|
|
3237
3264
|
else:
|
|
3238
3265
|
if flow is not None:
|
|
3239
|
-
for nodes in
|
|
3240
|
-
|
|
3241
|
-
reverse=True):
|
|
3266
|
+
for nodes in self.schema.get(
|
|
3267
|
+
"flowgraph", flow, field="schema").get_execution_order(reverse=True):
|
|
3242
3268
|
search_nodes.extend(nodes)
|
|
3243
3269
|
|
|
3244
3270
|
for ext in self._showtools.keys():
|
|
@@ -9,6 +9,7 @@ CD_WORK="{{ work_dir }}"
|
|
|
9
9
|
PRINT=""
|
|
10
10
|
CMDPREFIX=""
|
|
11
11
|
SKIPEXPORT=0
|
|
12
|
+
DONODE={{ node_only }}
|
|
12
13
|
while [[ $# -gt 0 ]]; do
|
|
13
14
|
case $1 in
|
|
14
15
|
--which)
|
|
@@ -40,6 +41,11 @@ while [[ $# -gt 0 ]]; do
|
|
|
40
41
|
shift
|
|
41
42
|
shift
|
|
42
43
|
;;
|
|
44
|
+
--node)
|
|
45
|
+
DONODE=1
|
|
46
|
+
shift
|
|
47
|
+
shift
|
|
48
|
+
;;
|
|
43
49
|
-h|--help)
|
|
44
50
|
echo "Usage: $0"
|
|
45
51
|
echo " Options:"
|
|
@@ -49,7 +55,8 @@ while [[ $# -gt 0 ]]; do
|
|
|
49
55
|
echo " --command print the execution command"
|
|
50
56
|
echo " --skipcd do not change directory into replay directory"
|
|
51
57
|
echo " --skipexports do not export environmental variables"
|
|
52
|
-
echo " --cmdprefix <cmd> prefix to add to the replay command, such as
|
|
58
|
+
echo " --cmdprefix <cmd> prefix to add to the replay command, such as dgb"
|
|
59
|
+
echo " --node execute entire node"
|
|
53
60
|
echo " -h,--help print this help"
|
|
54
61
|
exit 0
|
|
55
62
|
;;
|
|
@@ -87,6 +94,16 @@ case $PRINT in
|
|
|
87
94
|
;;
|
|
88
95
|
esac
|
|
89
96
|
|
|
97
|
+
if [ $DONODE == 1 ]; then
|
|
98
|
+
python3 -m siliconcompiler.scheduler.run_node \
|
|
99
|
+
-cfg "{{ cfg_file }}" \
|
|
100
|
+
-builddir "${PWD}/../../../../" \
|
|
101
|
+
-step "{{ step }}" \
|
|
102
|
+
-index "{{ index }}" \
|
|
103
|
+
-cwd "$PWD" \
|
|
104
|
+
-replay
|
|
105
|
+
{% if cmds|length > 0 %}else
|
|
90
106
|
# Command execution
|
|
91
107
|
$CMDPREFIX \{% for cmd in cmds %}
|
|
92
108
|
{% if not loop.first %} {% endif %}{{ cmd }}{% if not loop.last %} \{% endif %}{% endfor %}
|
|
109
|
+
{% endif %}fi
|
siliconcompiler/metric.py
CHANGED
|
@@ -3,6 +3,7 @@ from siliconcompiler.schema import EditableSchema, Parameter, PerNode, Scope
|
|
|
3
3
|
from siliconcompiler.schema.utils import trim
|
|
4
4
|
|
|
5
5
|
from siliconcompiler.utils.units import convert
|
|
6
|
+
from siliconcompiler.record import RecordTime
|
|
6
7
|
|
|
7
8
|
|
|
8
9
|
class MetricSchema(BaseSchema):
|
|
@@ -43,6 +44,83 @@ class MetricSchema(BaseSchema):
|
|
|
43
44
|
|
|
44
45
|
return self.set(metric, value, step=step, index=str(index))
|
|
45
46
|
|
|
47
|
+
def record_tasktime(self, step, index, record):
|
|
48
|
+
"""
|
|
49
|
+
Record the task time for this node
|
|
50
|
+
|
|
51
|
+
Args:
|
|
52
|
+
step (str): step to record
|
|
53
|
+
index (str/int): index to record
|
|
54
|
+
record (:class:`RecordSchema`): record to lookup data in
|
|
55
|
+
"""
|
|
56
|
+
start_time, end_time = [
|
|
57
|
+
record.get_recorded_time(step, index, RecordTime.START),
|
|
58
|
+
record.get_recorded_time(step, index, RecordTime.END)
|
|
59
|
+
]
|
|
60
|
+
|
|
61
|
+
if start_time is None or end_time is None:
|
|
62
|
+
return False
|
|
63
|
+
|
|
64
|
+
return self.record(step, index, "tasktime", end_time-start_time, unit="s")
|
|
65
|
+
|
|
66
|
+
def record_totaltime(self, step, index, flow, record):
|
|
67
|
+
"""
|
|
68
|
+
Record the total time for this node
|
|
69
|
+
|
|
70
|
+
Args:
|
|
71
|
+
step (str): step to record
|
|
72
|
+
index (str/int): index to record
|
|
73
|
+
flow (:class:`FlowgraphSchema`): flowgraph to lookup nodes in
|
|
74
|
+
record (:class:`RecordSchema`): record to lookup data in
|
|
75
|
+
"""
|
|
76
|
+
all_nodes = flow.get_nodes()
|
|
77
|
+
node_times = [
|
|
78
|
+
(record.get_recorded_time(*node, RecordTime.START),
|
|
79
|
+
record.get_recorded_time(*node, RecordTime.END)) for node in all_nodes
|
|
80
|
+
]
|
|
81
|
+
|
|
82
|
+
# Remove incomplete records
|
|
83
|
+
node_times = [times for times in node_times if times[0] is not None]
|
|
84
|
+
|
|
85
|
+
if len(node_times) == 0:
|
|
86
|
+
return False
|
|
87
|
+
|
|
88
|
+
node_end = record.get_recorded_time(step, index, RecordTime.END)
|
|
89
|
+
if node_end is None:
|
|
90
|
+
return False
|
|
91
|
+
|
|
92
|
+
node_times = sorted(node_times)
|
|
93
|
+
if len(node_times) > 1:
|
|
94
|
+
new_times = []
|
|
95
|
+
for n in range(len(node_times)):
|
|
96
|
+
if not new_times:
|
|
97
|
+
new_times.append(node_times[n])
|
|
98
|
+
continue
|
|
99
|
+
prev_start_time, prev_end_time = new_times[-1]
|
|
100
|
+
start_time, end_time = node_times[n]
|
|
101
|
+
|
|
102
|
+
new_start = min(prev_start_time, start_time)
|
|
103
|
+
|
|
104
|
+
if prev_end_time is None:
|
|
105
|
+
new_times[-1] = (new_start, end_time)
|
|
106
|
+
elif prev_end_time >= start_time:
|
|
107
|
+
if end_time is not None:
|
|
108
|
+
new_end = max(prev_end_time, end_time)
|
|
109
|
+
else:
|
|
110
|
+
new_end = prev_end_time
|
|
111
|
+
new_times[-1] = (new_start, new_end)
|
|
112
|
+
else:
|
|
113
|
+
new_times.append(node_times[n])
|
|
114
|
+
node_times = new_times
|
|
115
|
+
|
|
116
|
+
total_time = 0
|
|
117
|
+
for start_time, end_time in node_times:
|
|
118
|
+
if start_time > node_end:
|
|
119
|
+
continue
|
|
120
|
+
total_time += min(end_time, node_end) - start_time
|
|
121
|
+
|
|
122
|
+
return self.record(step, index, "totaltime", total_time, unit="s")
|
|
123
|
+
|
|
46
124
|
|
|
47
125
|
###########################################################################
|
|
48
126
|
# Metrics to Track
|
siliconcompiler/package/git.py
CHANGED
siliconcompiler/record.py
CHANGED
|
@@ -30,13 +30,25 @@ class RecordTool(Enum):
|
|
|
30
30
|
|
|
31
31
|
|
|
32
32
|
class RecordSchema(BaseSchema):
|
|
33
|
-
__TIMEFORMAT = "%Y-%m-%d %H:%M:%S"
|
|
33
|
+
__TIMEFORMAT = "%Y-%m-%d %H:%M:%S.%f"
|
|
34
34
|
|
|
35
35
|
def __init__(self):
|
|
36
36
|
super().__init__()
|
|
37
37
|
|
|
38
38
|
schema_record(self)
|
|
39
39
|
|
|
40
|
+
def _from_dict(self, manifest, keypath, version=None):
|
|
41
|
+
ret = super()._from_dict(manifest, keypath, version)
|
|
42
|
+
|
|
43
|
+
# Correct for change specification
|
|
44
|
+
if version and version < (0, 50, 4):
|
|
45
|
+
for timekey in RecordTime:
|
|
46
|
+
start_param = self.get(timekey.value, field=None)
|
|
47
|
+
for value, step, index in start_param.getvalues():
|
|
48
|
+
start_param.set(f"{value}.000000", step=step, index=index)
|
|
49
|
+
|
|
50
|
+
return ret
|
|
51
|
+
|
|
40
52
|
def clear(self, step, index, keep=None):
|
|
41
53
|
'''
|
|
42
54
|
Clear all saved metrics for a given step and index
|
|
@@ -259,7 +271,7 @@ class RecordSchema(BaseSchema):
|
|
|
259
271
|
|
|
260
272
|
def get_recorded_time(self, step, index, type):
|
|
261
273
|
'''
|
|
262
|
-
Returns the time recorded for a given record.
|
|
274
|
+
Returns the time recorded for a given record, or None if nothing is recorded.
|
|
263
275
|
|
|
264
276
|
Args:
|
|
265
277
|
step (str): Step name to associate.
|
|
@@ -267,10 +279,52 @@ class RecordSchema(BaseSchema):
|
|
|
267
279
|
type (:class:`RecordTime`): type of time to record
|
|
268
280
|
'''
|
|
269
281
|
type = RecordTime(type)
|
|
282
|
+
record_time = self.get(type.value, step=step, index=index)
|
|
283
|
+
if record_time is None:
|
|
284
|
+
return None
|
|
285
|
+
|
|
270
286
|
return datetime.strptime(
|
|
271
|
-
|
|
287
|
+
record_time+"+0000",
|
|
272
288
|
RecordSchema.__TIMEFORMAT+"%z").timestamp()
|
|
273
289
|
|
|
290
|
+
def get_earliest_time(self, type):
|
|
291
|
+
'''
|
|
292
|
+
Returns the earliest recorded time.
|
|
293
|
+
|
|
294
|
+
Args:
|
|
295
|
+
type (:class:`RecordTime`): type of time to record
|
|
296
|
+
'''
|
|
297
|
+
type = RecordTime(type)
|
|
298
|
+
record_param = self.get(type.value, field=None)
|
|
299
|
+
|
|
300
|
+
times = set()
|
|
301
|
+
for _, step, index in record_param.getvalues():
|
|
302
|
+
times.add(self.get_recorded_time(step, index, type))
|
|
303
|
+
|
|
304
|
+
if not times:
|
|
305
|
+
return None
|
|
306
|
+
|
|
307
|
+
return min(times)
|
|
308
|
+
|
|
309
|
+
def get_latest_time(self, type):
|
|
310
|
+
'''
|
|
311
|
+
Returns the last recorded time.
|
|
312
|
+
|
|
313
|
+
Args:
|
|
314
|
+
type (:class:`RecordTime`): type of time to record
|
|
315
|
+
'''
|
|
316
|
+
type = RecordTime(type)
|
|
317
|
+
record_param = self.get(type.value, field=None)
|
|
318
|
+
|
|
319
|
+
times = set()
|
|
320
|
+
for _, step, index in record_param.getvalues():
|
|
321
|
+
times.add(self.get_recorded_time(step, index, type))
|
|
322
|
+
|
|
323
|
+
if not times:
|
|
324
|
+
return None
|
|
325
|
+
|
|
326
|
+
return max(times)
|
|
327
|
+
|
|
274
328
|
def record_tool(self, step, index, info, type):
|
|
275
329
|
'''
|
|
276
330
|
Record information about the tool used during this record.
|
|
@@ -316,11 +370,13 @@ def schema_record(schema):
|
|
|
316
370
|
'x86_64',
|
|
317
371
|
'(x86_64, rv64imafdc)'],
|
|
318
372
|
'starttime': ['start time',
|
|
319
|
-
'\"2021-09-06 12:20:20\"',
|
|
320
|
-
'Time is
|
|
373
|
+
'\"2021-09-06 12:20:20.000000\"',
|
|
374
|
+
'Time is recorded with the format YYYY-MM-DD HR:MIN:SEC.MICROSEC for '
|
|
375
|
+
'UTC'],
|
|
321
376
|
'endtime': ['end time',
|
|
322
|
-
'\"2021-09-06 12:20:20\"',
|
|
323
|
-
'Time is
|
|
377
|
+
'\"2021-09-06 12:20:20.000000\"',
|
|
378
|
+
'Time is recorded with the format YYYY-MM-DD HR:MIN:SEC.MICROSEC for '
|
|
379
|
+
'UTC'],
|
|
324
380
|
'region': ['cloud region',
|
|
325
381
|
'\"US Gov Boston\"',
|
|
326
382
|
"""Recommended naming methodology:
|
siliconcompiler/remote/client.py
CHANGED
|
@@ -10,12 +10,15 @@ import tarfile
|
|
|
10
10
|
import tempfile
|
|
11
11
|
import multiprocessing
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
import os.path
|
|
14
|
+
|
|
15
|
+
from siliconcompiler import utils, SiliconCompilerError
|
|
14
16
|
from siliconcompiler import NodeStatus as SCNodeStatus
|
|
15
17
|
from siliconcompiler._metadata import default_server
|
|
16
|
-
from siliconcompiler.
|
|
17
|
-
from siliconcompiler.remote import JobStatus
|
|
18
|
+
from siliconcompiler.remote import JobStatus, NodeStatus
|
|
18
19
|
from siliconcompiler.report.dashboard import DashboardType
|
|
20
|
+
from siliconcompiler.flowgraph import RuntimeFlowgraph
|
|
21
|
+
from siliconcompiler.schema import JournalingSchema
|
|
19
22
|
|
|
20
23
|
# Step name to use while logging
|
|
21
24
|
remote_step_name = 'remote'
|
|
@@ -309,19 +312,29 @@ service, provided by SiliconCompiler, is not intended to process proprietary IP.
|
|
|
309
312
|
try:
|
|
310
313
|
# Decode response JSON, if possible.
|
|
311
314
|
job_info = json.loads(info['message'])
|
|
312
|
-
|
|
313
|
-
|
|
315
|
+
if "null" in job_info:
|
|
316
|
+
job_info[None] = job_info["null"]
|
|
317
|
+
del job_info["null"]
|
|
318
|
+
except json.JSONDecodeError:
|
|
319
|
+
self.__logger.warning(f"Job is still running: {info['message']}")
|
|
314
320
|
return completed, starttimes, True
|
|
315
321
|
|
|
316
322
|
nodes_to_log = {}
|
|
317
323
|
for node, node_info in job_info.items():
|
|
318
324
|
status = node_info['status']
|
|
319
|
-
|
|
325
|
+
|
|
326
|
+
if status == NodeStatus.UPLOADED:
|
|
327
|
+
status = SCNodeStatus.PENDING
|
|
320
328
|
|
|
321
329
|
if SCNodeStatus.is_done(status):
|
|
322
330
|
# collect completed
|
|
323
331
|
completed.append(node)
|
|
324
332
|
|
|
333
|
+
if not node:
|
|
334
|
+
continue
|
|
335
|
+
|
|
336
|
+
nodes_to_log.setdefault(status, []).append((node, node_info))
|
|
337
|
+
|
|
325
338
|
if self.__node_information and node in self.__node_information:
|
|
326
339
|
self.__chip.set('record', 'status', status,
|
|
327
340
|
step=self.__node_information[node]["step"],
|
|
@@ -579,6 +592,22 @@ service, provided by SiliconCompiler, is not intended to process proprietary IP.
|
|
|
579
592
|
raise SiliconCompilerError('Job canceled by user keyboard interrupt')
|
|
580
593
|
|
|
581
594
|
def __import_run_manifests(self, starttimes):
|
|
595
|
+
if not self.__setup_information_loaded:
|
|
596
|
+
if self.__setup_information_fetched:
|
|
597
|
+
manifest = os.path.join(self.__chip.getworkdir(), f'{self.__chip.design}.pkg.json')
|
|
598
|
+
if os.path.exists(manifest):
|
|
599
|
+
try:
|
|
600
|
+
JournalingSchema(self.__chip.schema).read_journal(manifest)
|
|
601
|
+
self.__setup_information_loaded = True
|
|
602
|
+
changed = True
|
|
603
|
+
except: # noqa E722
|
|
604
|
+
# Import may fail if file is still getting written
|
|
605
|
+
pass
|
|
606
|
+
|
|
607
|
+
if not self.__setup_information_loaded:
|
|
608
|
+
# Dont do anything until this has been loaded
|
|
609
|
+
return
|
|
610
|
+
|
|
582
611
|
changed = False
|
|
583
612
|
for _, node_info in self.__node_information.items():
|
|
584
613
|
if node_info["imported"]:
|
|
@@ -590,7 +619,7 @@ service, provided by SiliconCompiler, is not intended to process proprietary IP.
|
|
|
590
619
|
f'{self.__chip.design}.pkg.json')
|
|
591
620
|
if os.path.exists(manifest):
|
|
592
621
|
try:
|
|
593
|
-
self.__chip.schema.read_journal(manifest)
|
|
622
|
+
JournalingSchema(self.__chip.schema).read_journal(manifest)
|
|
594
623
|
node_info["imported"] = True
|
|
595
624
|
changed = True
|
|
596
625
|
except: # noqa E722
|
|
@@ -598,7 +627,7 @@ service, provided by SiliconCompiler, is not intended to process proprietary IP.
|
|
|
598
627
|
pass
|
|
599
628
|
elif self.__chip.get('record', 'status',
|
|
600
629
|
step=node_info["step"], index=node_info["index"]) \
|
|
601
|
-
==
|
|
630
|
+
== SCNodeStatus.SKIPPED:
|
|
602
631
|
node_info["imported"] = True
|
|
603
632
|
changed = True
|
|
604
633
|
|
|
@@ -617,8 +646,17 @@ service, provided by SiliconCompiler, is not intended to process proprietary IP.
|
|
|
617
646
|
check_info = self.__check()
|
|
618
647
|
self.__check_interval = check_info['progress_interval']
|
|
619
648
|
|
|
649
|
+
self.__setup_information_fetched = False
|
|
650
|
+
self.__setup_information_loaded = False
|
|
651
|
+
|
|
620
652
|
self.__node_information = {}
|
|
621
|
-
|
|
653
|
+
runtime = RuntimeFlowgraph(
|
|
654
|
+
self.__chip.schema.get("flowgraph", self.__chip.get('option', 'flow'), field='schema'),
|
|
655
|
+
from_steps=self.__chip.get('option', 'from'),
|
|
656
|
+
to_steps=self.__chip.get('option', 'to'),
|
|
657
|
+
prune_nodes=self.__chip.get('option', 'prune'))
|
|
658
|
+
|
|
659
|
+
for step, index in runtime.get_nodes():
|
|
622
660
|
done = SCNodeStatus.is_done(self.__chip.get('record', 'status', step=step, index=index))
|
|
623
661
|
node_info = {
|
|
624
662
|
"step": step,
|
|
@@ -659,6 +697,11 @@ service, provided by SiliconCompiler, is not intended to process proprietary IP.
|
|
|
659
697
|
# Update dashboard if active
|
|
660
698
|
self.__chip._dash.update_manifest({"starttimes": starttimes})
|
|
661
699
|
|
|
700
|
+
if None in completed:
|
|
701
|
+
completed.remove(None)
|
|
702
|
+
if not self.__setup_information_fetched:
|
|
703
|
+
self.__schedule_fetch_result(None)
|
|
704
|
+
|
|
662
705
|
nodes_to_fetch = []
|
|
663
706
|
for node in completed:
|
|
664
707
|
if not self.__node_information[node]["fetched"]:
|
|
@@ -674,7 +717,6 @@ service, provided by SiliconCompiler, is not intended to process proprietary IP.
|
|
|
674
717
|
for node, node_info in self.__node_information.items():
|
|
675
718
|
if not node_info["fetched"]:
|
|
676
719
|
self.__schedule_fetch_result(node)
|
|
677
|
-
self.__schedule_fetch_result(node)
|
|
678
720
|
|
|
679
721
|
self._finalize_loop()
|
|
680
722
|
|
|
@@ -693,11 +735,12 @@ service, provided by SiliconCompiler, is not intended to process proprietary IP.
|
|
|
693
735
|
self.__import_run_manifests({})
|
|
694
736
|
|
|
695
737
|
def __schedule_fetch_result(self, node):
|
|
696
|
-
|
|
738
|
+
if node:
|
|
739
|
+
self.__node_information[node]["fetched"] = True
|
|
740
|
+
self.__logger.info(f' {node}')
|
|
741
|
+
else:
|
|
742
|
+
self.__setup_information_fetched = True
|
|
697
743
|
self.__download_pool.apply_async(Client._fetch_result, (self, node))
|
|
698
|
-
if node is None:
|
|
699
|
-
node = 'final result'
|
|
700
|
-
self.__logger.info(f' {node}')
|
|
701
744
|
|
|
702
745
|
def _fetch_result(self, node):
|
|
703
746
|
'''
|