siliconcompiler 0.34.2__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 +12 -5
- 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 +6 -5
- 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/asic_component.py +2 -2
- siliconcompiler/constraints/asic_pins.py +2 -2
- siliconcompiler/constraints/asic_timing.py +3 -3
- siliconcompiler/core.py +7 -32
- siliconcompiler/data/templates/tcl/manifest.tcl.j2 +8 -0
- siliconcompiler/dependencyschema.py +89 -31
- siliconcompiler/design.py +176 -207
- siliconcompiler/filesetschema.py +250 -0
- siliconcompiler/flowgraph.py +274 -95
- siliconcompiler/fpga.py +124 -1
- siliconcompiler/library.py +218 -20
- siliconcompiler/metric.py +233 -20
- siliconcompiler/package/__init__.py +271 -50
- siliconcompiler/package/git.py +92 -16
- siliconcompiler/package/github.py +108 -12
- siliconcompiler/package/https.py +79 -16
- siliconcompiler/packageschema.py +88 -7
- siliconcompiler/pathschema.py +31 -2
- siliconcompiler/pdk.py +566 -1
- siliconcompiler/project.py +1095 -94
- 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 +79 -1
- siliconcompiler/scheduler/run_node.py +35 -19
- siliconcompiler/scheduler/scheduler.py +208 -24
- siliconcompiler/scheduler/schedulernode.py +372 -46
- siliconcompiler/scheduler/send_messages.py +77 -29
- siliconcompiler/scheduler/slurm.py +76 -12
- siliconcompiler/scheduler/taskscheduler.py +140 -20
- siliconcompiler/schema/__init__.py +0 -2
- siliconcompiler/schema/baseschema.py +194 -38
- siliconcompiler/schema/journal.py +7 -4
- siliconcompiler/schema/namedschema.py +16 -10
- siliconcompiler/schema/parameter.py +55 -9
- siliconcompiler/schema/parametervalue.py +60 -0
- siliconcompiler/schema/safeschema.py +25 -2
- siliconcompiler/schema/schema_cfg.py +5 -5
- siliconcompiler/schema/utils.py +2 -2
- siliconcompiler/schema_obj.py +20 -3
- siliconcompiler/tool.py +979 -302
- 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.2.dist-info → siliconcompiler-0.34.3.dist-info}/METADATA +5 -5
- {siliconcompiler-0.34.2.dist-info → siliconcompiler-0.34.3.dist-info}/RECORD +115 -118
- {siliconcompiler-0.34.2.dist-info → siliconcompiler-0.34.3.dist-info}/entry_points.txt +3 -0
- siliconcompiler/schema/cmdlineschema.py +0 -250
- 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.2.dist-info → siliconcompiler-0.34.3.dist-info}/WHEEL +0 -0
- {siliconcompiler-0.34.2.dist-info → siliconcompiler-0.34.3.dist-info}/licenses/LICENSE +0 -0
- {siliconcompiler-0.34.2.dist-info → siliconcompiler-0.34.3.dist-info}/top_level.txt +0 -0
siliconcompiler/report/report.py
CHANGED
|
@@ -110,7 +110,7 @@ def make_manifest_helper(manifest_subsect, modified_manifest_subsect):
|
|
|
110
110
|
def _is_leaf(cfg):
|
|
111
111
|
# 'shorthelp' chosen arbitrarily: any mandatory field with a consistent
|
|
112
112
|
# type would work.
|
|
113
|
-
return '
|
|
113
|
+
return 'type' in cfg and isinstance(cfg['type'], str)
|
|
114
114
|
|
|
115
115
|
def build_leaf(manifest_subsect):
|
|
116
116
|
if PerNode(manifest_subsect['pernode']) == PerNode.NEVER:
|
|
@@ -161,7 +161,10 @@ def make_manifest_helper(manifest_subsect, modified_manifest_subsect):
|
|
|
161
161
|
else:
|
|
162
162
|
modified_manifest_subsect[step + index] = value
|
|
163
163
|
|
|
164
|
-
for key, key_dict in manifest_subsect.items():
|
|
164
|
+
for key, key_dict in sorted(manifest_subsect.items(), key=lambda k: k[0]):
|
|
165
|
+
if key == "__meta__" or key == "__journal__":
|
|
166
|
+
continue
|
|
167
|
+
|
|
165
168
|
if key != 'default':
|
|
166
169
|
if _is_leaf(key_dict):
|
|
167
170
|
modified_manifest_subsect[key] = build_leaf(key_dict)
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
import os
|
|
2
2
|
import string
|
|
3
|
+
|
|
4
|
+
import os.path
|
|
5
|
+
|
|
3
6
|
from PIL import Image, ImageFont, ImageDraw
|
|
4
7
|
|
|
8
|
+
import siliconcompiler
|
|
5
9
|
from siliconcompiler.utils import units
|
|
6
10
|
from siliconcompiler.report.utils import _find_summary_image, _find_summary_metrics
|
|
7
11
|
|
|
@@ -12,10 +16,6 @@ def _generate_summary_image(chip, output_path):
|
|
|
12
16
|
featuring a layout thumbnail and several metrics.
|
|
13
17
|
'''
|
|
14
18
|
|
|
15
|
-
img_path = _find_summary_image(chip)
|
|
16
|
-
if not img_path:
|
|
17
|
-
return
|
|
18
|
-
|
|
19
19
|
# Extract metrics for display
|
|
20
20
|
metrics = {
|
|
21
21
|
'Chip': chip.design,
|
|
@@ -46,14 +46,31 @@ def _generate_summary_image(chip, output_path):
|
|
|
46
46
|
'LUTs': ('luts', None),
|
|
47
47
|
'Fmax': ('fmax', format_freq)}))
|
|
48
48
|
|
|
49
|
-
|
|
49
|
+
info = []
|
|
50
|
+
for metric, value in metrics.items():
|
|
51
|
+
info.append((metric, value))
|
|
52
|
+
|
|
53
|
+
generate_summary_image(chip, output_path, info)
|
|
50
54
|
|
|
55
|
+
|
|
56
|
+
def generate_summary_image(project, output_path, info):
|
|
57
|
+
'''
|
|
58
|
+
Takes a layout screenshot and generates a design summary image
|
|
59
|
+
featuring a layout thumbnail and several metrics.
|
|
60
|
+
'''
|
|
61
|
+
|
|
62
|
+
img_path = _find_summary_image(project)
|
|
63
|
+
if not img_path:
|
|
64
|
+
return
|
|
65
|
+
|
|
66
|
+
# Generate design
|
|
51
67
|
WIDTH = 1024
|
|
52
68
|
BORDER = 32
|
|
53
69
|
LINE_SPACING = 8
|
|
54
70
|
TEXT_INDENT = 16
|
|
55
71
|
|
|
56
|
-
FONT_PATH = os.path.join(
|
|
72
|
+
FONT_PATH = os.path.join(os.path.dirname(siliconcompiler.__file__),
|
|
73
|
+
'data', 'RobotoMono', 'RobotoMono-Regular.ttf')
|
|
57
74
|
FONT_SIZE = 40
|
|
58
75
|
|
|
59
76
|
# matches dark gray background color configured in klayout_show.py
|
|
@@ -82,8 +99,9 @@ def _generate_summary_image(chip, output_path):
|
|
|
82
99
|
text = []
|
|
83
100
|
x = BORDER + TEXT_INDENT
|
|
84
101
|
y = thumbnail_height + 2 * BORDER
|
|
85
|
-
for
|
|
86
|
-
|
|
102
|
+
max_title_len = max([len(title) for title, _ in info])
|
|
103
|
+
for title, value in info:
|
|
104
|
+
line = f'{title:<{max_title_len}}: {value}'
|
|
87
105
|
|
|
88
106
|
# shorten line till it fits
|
|
89
107
|
cropped_line = line
|
|
@@ -94,8 +112,8 @@ def _generate_summary_image(chip, output_path):
|
|
|
94
112
|
cropped_line = cropped_line[:-1]
|
|
95
113
|
|
|
96
114
|
if cropped_line != line:
|
|
97
|
-
|
|
98
|
-
|
|
115
|
+
project.logger.warning(f'Cropped {line} to {cropped_line} to fit in design summary '
|
|
116
|
+
'image')
|
|
99
117
|
|
|
100
118
|
# Stash line to write and coords to write it at
|
|
101
119
|
text.append(((x, y), cropped_line))
|
|
@@ -110,7 +128,7 @@ def _generate_summary_image(chip, output_path):
|
|
|
110
128
|
draw.text(coords, line, TEXT_COLOR, font=font)
|
|
111
129
|
|
|
112
130
|
design_summary.save(output_path)
|
|
113
|
-
|
|
131
|
+
project.logger.info(f'Generated summary image at {output_path}')
|
|
114
132
|
|
|
115
133
|
|
|
116
134
|
def _open_summary_image(image):
|
|
@@ -1,5 +1,13 @@
|
|
|
1
|
+
from siliconcompiler.scheduler.schedulernode import SchedulerNode
|
|
2
|
+
from siliconcompiler.scheduler.slurm import SlurmSchedulerNode
|
|
3
|
+
from siliconcompiler.scheduler.docker import DockerSchedulerNode
|
|
1
4
|
from siliconcompiler.scheduler.taskscheduler import TaskScheduler
|
|
5
|
+
from siliconcompiler.scheduler.scheduler import Scheduler
|
|
2
6
|
|
|
3
7
|
__all__ = [
|
|
4
|
-
"
|
|
8
|
+
"Scheduler",
|
|
9
|
+
"SchedulerNode",
|
|
10
|
+
"TaskScheduler",
|
|
11
|
+
"DockerSchedulerNode",
|
|
12
|
+
"SlurmSchedulerNode"
|
|
5
13
|
]
|
|
@@ -7,10 +7,25 @@ from pathlib import Path
|
|
|
7
7
|
|
|
8
8
|
from siliconcompiler.package import RemoteResolver
|
|
9
9
|
from siliconcompiler.utils import default_email_credentials_file
|
|
10
|
-
from siliconcompiler.scheduler
|
|
10
|
+
from siliconcompiler.scheduler import SchedulerNode
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
def get_image(chip, step, index):
|
|
14
|
+
"""Determines the Docker image to use for a given node.
|
|
15
|
+
|
|
16
|
+
The image is selected based on the following priority:
|
|
17
|
+
1. The value of ['option', 'scheduler', 'queue'] specific to the step/index.
|
|
18
|
+
2. The value of the 'SC_DOCKER_IMAGE' environment variable.
|
|
19
|
+
3. A default image name constructed as 'ghcr.io/siliconcompiler/sc_runner:v<version>'.
|
|
20
|
+
|
|
21
|
+
Args:
|
|
22
|
+
chip (Chip): The Chip object.
|
|
23
|
+
step (str): The step name of the node.
|
|
24
|
+
index (str): The index of the node.
|
|
25
|
+
|
|
26
|
+
Returns:
|
|
27
|
+
str: The name of the Docker image to use.
|
|
28
|
+
"""
|
|
14
29
|
from siliconcompiler import __version__
|
|
15
30
|
|
|
16
31
|
queue = chip.get('option', 'scheduler', 'queue', step=step, index=index)
|
|
@@ -23,6 +38,27 @@ def get_image(chip, step, index):
|
|
|
23
38
|
|
|
24
39
|
|
|
25
40
|
def get_volumes_directories(chip, cache_dir, workdir, step, index):
|
|
41
|
+
"""
|
|
42
|
+
Identifies and categorizes all host directories that need to be mounted
|
|
43
|
+
into the Docker container.
|
|
44
|
+
|
|
45
|
+
This function scans the chip schema for all file and directory paths,
|
|
46
|
+
collects them, and then prunes the list to a minimal set of parent
|
|
47
|
+
directories to mount. It then separates these directories into read-write
|
|
48
|
+
(RW) and read-only (RO) sets.
|
|
49
|
+
|
|
50
|
+
Args:
|
|
51
|
+
chip (Chip): The Chip object.
|
|
52
|
+
cache_dir (str): The path to the cache directory.
|
|
53
|
+
workdir (str): The path to the node's working directory.
|
|
54
|
+
step (str): The step name of the current node.
|
|
55
|
+
index (str): The index of the current node.
|
|
56
|
+
|
|
57
|
+
Returns:
|
|
58
|
+
tuple: A tuple containing two sets: (rw_volumes, ro_volumes).
|
|
59
|
+
`rw_volumes` is a set of Path objects for read-write directories.
|
|
60
|
+
`ro_volumes` is a set of Path objects for read-only directories.
|
|
61
|
+
"""
|
|
26
62
|
all_dirs = set()
|
|
27
63
|
# Collect files
|
|
28
64
|
for key in chip.allkeys():
|
|
@@ -89,17 +125,46 @@ def get_volumes_directories(chip, cache_dir, workdir, step, index):
|
|
|
89
125
|
|
|
90
126
|
|
|
91
127
|
class DockerSchedulerNode(SchedulerNode):
|
|
128
|
+
"""A SchedulerNode implementation for running tasks in a Docker container.
|
|
129
|
+
|
|
130
|
+
This class extends the base SchedulerNode to handle the specifics of
|
|
131
|
+
running a compilation step inside a Docker container. It uses the `docker-py`
|
|
132
|
+
library to manage the container lifecycle, including pulling the image,
|
|
133
|
+
|
|
134
|
+
mounting volumes, and executing the command.
|
|
135
|
+
"""
|
|
136
|
+
|
|
92
137
|
def __init__(self, chip, step, index, replay=False):
|
|
138
|
+
"""Initializes a DockerSchedulerNode.
|
|
139
|
+
|
|
140
|
+
Args:
|
|
141
|
+
chip (Chip): The parent Chip object.
|
|
142
|
+
step (str): The step name in the flowgraph.
|
|
143
|
+
index (str): The index for the step.
|
|
144
|
+
replay (bool): If True, sets up the node to replay a previous run.
|
|
145
|
+
"""
|
|
93
146
|
super().__init__(chip, step, index, replay=replay)
|
|
94
147
|
|
|
95
148
|
self.__queue = get_image(self.chip, self.step, self.index)
|
|
96
149
|
|
|
97
150
|
@property
|
|
98
151
|
def queue(self):
|
|
152
|
+
"""str: The Docker image name to be used for the container."""
|
|
99
153
|
return self.__queue
|
|
100
154
|
|
|
101
155
|
@staticmethod
|
|
102
156
|
def init(chip):
|
|
157
|
+
"""
|
|
158
|
+
A static pre-processing hook for the Docker scheduler.
|
|
159
|
+
|
|
160
|
+
On Windows, this method forces all file/directory parameters to be
|
|
161
|
+
copied rather than linked, which avoids issues with differing
|
|
162
|
+
filesystem types between the host and the Linux-based container.
|
|
163
|
+
It then triggers `chip.collect()` to ensure all files are staged.
|
|
164
|
+
|
|
165
|
+
Args:
|
|
166
|
+
chip (Chip): The Chip object to perform pre-processing on.
|
|
167
|
+
"""
|
|
103
168
|
if sys.platform == 'win32':
|
|
104
169
|
# this avoids the issue of different file system types
|
|
105
170
|
chip.logger.error('Setting copy field to true for docker run on Windows')
|
|
@@ -112,6 +177,19 @@ class DockerSchedulerNode(SchedulerNode):
|
|
|
112
177
|
chip.collect()
|
|
113
178
|
|
|
114
179
|
def run(self):
|
|
180
|
+
"""
|
|
181
|
+
Runs the node's task inside a Docker container.
|
|
182
|
+
|
|
183
|
+
This method orchestrates the entire process:
|
|
184
|
+
1. Connects to the Docker daemon.
|
|
185
|
+
2. Pulls the required Docker image if it's not present locally.
|
|
186
|
+
3. Determines and prepares all necessary volume mounts.
|
|
187
|
+
4. Creates and starts a detached Docker container.
|
|
188
|
+
5. Writes the current manifest to a file accessible by the container.
|
|
189
|
+
6. Executes the `sc-node` command inside the container.
|
|
190
|
+
7. Streams the container's log output to the console.
|
|
191
|
+
8. Halts on error and ensures the container is stopped upon completion.
|
|
192
|
+
"""
|
|
115
193
|
self._init_run_logger()
|
|
116
194
|
|
|
117
195
|
try:
|
|
@@ -1,4 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
A command-line utility to execute a single node (step and index) from a
|
|
4
|
+
SiliconCompiler flowgraph.
|
|
5
|
+
|
|
6
|
+
This script is designed to be called by a scheduler (like Slurm, Docker, or
|
|
7
|
+
a local process manager) to run a specific task in isolation. It takes all
|
|
8
|
+
necessary configuration information via command-line arguments, sets up a
|
|
9
|
+
Chip object, and executes the specified node's `run()` method.
|
|
10
|
+
"""
|
|
2
11
|
|
|
3
12
|
import argparse
|
|
4
13
|
import os
|
|
@@ -8,19 +17,22 @@ import os.path
|
|
|
8
17
|
|
|
9
18
|
from siliconcompiler import Chip, Schema
|
|
10
19
|
from siliconcompiler.package import Resolver
|
|
11
|
-
from siliconcompiler.scheduler
|
|
20
|
+
from siliconcompiler.scheduler import SchedulerNode
|
|
12
21
|
from siliconcompiler import __version__
|
|
13
22
|
|
|
14
23
|
|
|
15
24
|
##########################
|
|
16
25
|
def main():
|
|
26
|
+
"""The main entry point for the run_node script."""
|
|
17
27
|
schema = Schema()
|
|
18
28
|
|
|
19
|
-
#
|
|
29
|
+
# Set up a minimal argument parser, as we don't need the full
|
|
30
|
+
# Chip.cmdline() functionality which includes extra logger setup.
|
|
20
31
|
parser = argparse.ArgumentParser(prog='run_node',
|
|
21
32
|
formatter_class=argparse.RawDescriptionHelpFormatter,
|
|
22
33
|
description='Script to run a single node in an SC flowgraph')
|
|
23
34
|
|
|
35
|
+
# Define command-line arguments
|
|
24
36
|
parser.add_argument('-version',
|
|
25
37
|
action='version',
|
|
26
38
|
version=__version__)
|
|
@@ -75,16 +87,17 @@ def main():
|
|
|
75
87
|
help='Running as replay')
|
|
76
88
|
args = parser.parse_args()
|
|
77
89
|
|
|
78
|
-
# Change to working directory
|
|
79
|
-
#
|
|
80
|
-
#
|
|
90
|
+
# Change to the specified working directory. This is crucial for remote
|
|
91
|
+
# runners (like Docker) where paths inside the environment are different
|
|
92
|
+
# from the host.
|
|
81
93
|
os.chdir(os.path.abspath(args.cwd))
|
|
82
94
|
|
|
83
95
|
# Create the Chip object.
|
|
84
96
|
chip = Chip('<design>')
|
|
97
|
+
# Load the configuration from the manifest provided.
|
|
85
98
|
chip.read_manifest(args.cfg)
|
|
86
99
|
|
|
87
|
-
#
|
|
100
|
+
# Configure the chip object based on command-line arguments.
|
|
88
101
|
chip.set('arg', 'step', args.step)
|
|
89
102
|
chip.set('arg', 'index', args.index)
|
|
90
103
|
chip.set('option', 'builddir', os.path.abspath(args.builddir))
|
|
@@ -95,40 +108,42 @@ def main():
|
|
|
95
108
|
if args.remoteid:
|
|
96
109
|
chip.set('record', 'remoteid', args.remoteid)
|
|
97
110
|
|
|
111
|
+
# If running in a container/remote machine, we unset the scheduler to
|
|
112
|
+
# prevent a recursive scheduling loop.
|
|
98
113
|
if args.unset_scheduler:
|
|
99
114
|
for _, step, index in chip.get('option', 'scheduler', 'name',
|
|
100
115
|
field=None).getvalues():
|
|
101
116
|
chip.unset('option', 'scheduler', 'name', step=step, index=index)
|
|
102
117
|
|
|
118
|
+
# Pre-populate the package cache if a map is provided.
|
|
103
119
|
if args.cachemap:
|
|
104
120
|
for cachepair in args.cachemap:
|
|
105
121
|
package, path = cachepair.split(':')
|
|
106
122
|
Resolver.set_cache(chip, package, path)
|
|
107
123
|
|
|
108
|
-
#
|
|
124
|
+
# Ensure all package caches are populated before running the node.
|
|
109
125
|
for resolver in chip.get('package', field='schema').get_resolvers().values():
|
|
110
126
|
resolver()
|
|
111
127
|
|
|
112
|
-
#
|
|
128
|
+
# Instantiate the SchedulerNode for the specified step and index.
|
|
113
129
|
error = True
|
|
130
|
+
node = SchedulerNode(
|
|
131
|
+
chip,
|
|
132
|
+
args.step,
|
|
133
|
+
args.index,
|
|
134
|
+
replay=args.replay)
|
|
114
135
|
try:
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
args.index,
|
|
118
|
-
replay=args.replay).run()
|
|
136
|
+
# Execute the node's run() method.
|
|
137
|
+
node.run()
|
|
119
138
|
error = False
|
|
120
|
-
|
|
121
139
|
finally:
|
|
140
|
+
# Archive results upon completion, regardless of success or failure.
|
|
122
141
|
if args.archive:
|
|
123
|
-
# Archive the results.
|
|
124
142
|
with tarfile.open(args.archive,
|
|
125
143
|
mode='w:gz') as tf:
|
|
126
|
-
|
|
127
|
-
step=args.step,
|
|
128
|
-
index=args.index,
|
|
129
|
-
include=args.include)
|
|
144
|
+
node.archive(tf, include=args.include)
|
|
130
145
|
|
|
131
|
-
# Return
|
|
146
|
+
# Return a non-zero exit code on error.
|
|
132
147
|
if error:
|
|
133
148
|
return 1
|
|
134
149
|
return 0
|
|
@@ -136,4 +151,5 @@ def main():
|
|
|
136
151
|
|
|
137
152
|
##########################
|
|
138
153
|
if __name__ == "__main__":
|
|
154
|
+
# This makes the script executable.
|
|
139
155
|
sys.exit(main())
|