siliconcompiler 0.34.0__py3-none-any.whl → 0.34.1__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 +1 -1
- siliconcompiler/apps/sc.py +1 -1
- siliconcompiler/apps/sc_issue.py +1 -1
- siliconcompiler/apps/sc_remote.py +3 -3
- siliconcompiler/apps/sc_show.py +2 -2
- siliconcompiler/apps/utils/replay.py +4 -4
- siliconcompiler/checklist.py +203 -2
- siliconcompiler/core.py +28 -246
- siliconcompiler/data/templates/email/general.j2 +3 -3
- siliconcompiler/data/templates/email/summary.j2 +1 -1
- siliconcompiler/data/templates/issue/README.txt +1 -1
- siliconcompiler/data/templates/report/sc_report.j2 +7 -7
- siliconcompiler/design.py +148 -54
- siliconcompiler/flowgraph.py +50 -15
- siliconcompiler/optimizer/vizier.py +2 -2
- siliconcompiler/pdk.py +5 -5
- siliconcompiler/remote/client.py +18 -12
- siliconcompiler/remote/server.py +2 -2
- siliconcompiler/report/dashboard/cli/__init__.py +6 -6
- siliconcompiler/report/dashboard/cli/board.py +3 -3
- siliconcompiler/report/dashboard/web/components/__init__.py +5 -5
- siliconcompiler/report/dashboard/web/components/flowgraph.py +4 -4
- siliconcompiler/report/dashboard/web/components/graph.py +2 -2
- siliconcompiler/report/dashboard/web/state.py +1 -1
- siliconcompiler/report/dashboard/web/utils/__init__.py +5 -5
- siliconcompiler/report/html_report.py +1 -1
- siliconcompiler/report/report.py +4 -4
- siliconcompiler/report/summary_table.py +2 -2
- siliconcompiler/report/utils.py +5 -5
- siliconcompiler/scheduler/docker.py +3 -8
- siliconcompiler/scheduler/run_node.py +2 -7
- siliconcompiler/scheduler/scheduler.py +14 -11
- siliconcompiler/scheduler/schedulernode.py +136 -126
- siliconcompiler/scheduler/send_messages.py +3 -3
- siliconcompiler/scheduler/slurm.py +5 -3
- siliconcompiler/scheduler/taskscheduler.py +8 -7
- siliconcompiler/schema/baseschema.py +1 -2
- siliconcompiler/schema/namedschema.py +26 -2
- siliconcompiler/tool.py +398 -175
- siliconcompiler/tools/__init__.py +2 -0
- siliconcompiler/tools/builtin/_common.py +5 -5
- siliconcompiler/tools/builtin/concatenate.py +5 -5
- siliconcompiler/tools/builtin/minimum.py +4 -4
- siliconcompiler/tools/builtin/mux.py +4 -4
- siliconcompiler/tools/builtin/nop.py +4 -4
- siliconcompiler/tools/builtin/verify.py +7 -7
- siliconcompiler/tools/execute/exec_input.py +1 -1
- siliconcompiler/tools/genfasm/genfasm.py +1 -6
- siliconcompiler/tools/openroad/_apr.py +5 -1
- siliconcompiler/tools/openroad/antenna_repair.py +1 -1
- siliconcompiler/tools/openroad/macro_placement.py +1 -1
- siliconcompiler/tools/openroad/power_grid.py +1 -1
- siliconcompiler/tools/openroad/scripts/common/procs.tcl +5 -0
- siliconcompiler/tools/opensta/timing.py +26 -3
- siliconcompiler/tools/slang/__init__.py +2 -2
- siliconcompiler/tools/surfer/__init__.py +0 -0
- siliconcompiler/tools/surfer/show.py +53 -0
- siliconcompiler/tools/surfer/surfer.py +30 -0
- siliconcompiler/tools/vpr/route.py +27 -14
- siliconcompiler/tools/vpr/vpr.py +23 -6
- siliconcompiler/tools/yosys/__init__.py +1 -1
- siliconcompiler/tools/yosys/scripts/procs.tcl +143 -0
- siliconcompiler/tools/yosys/{sc_synth_asic.tcl → scripts/sc_synth_asic.tcl} +4 -0
- siliconcompiler/tools/yosys/{sc_synth_fpga.tcl → scripts/sc_synth_fpga.tcl} +24 -77
- siliconcompiler/tools/yosys/syn_fpga.py +14 -0
- siliconcompiler/toolscripts/_tools.json +8 -12
- siliconcompiler/toolscripts/rhel9/install-vpr.sh +0 -2
- siliconcompiler/toolscripts/ubuntu22/install-surfer.sh +33 -0
- siliconcompiler/toolscripts/ubuntu24/install-surfer.sh +33 -0
- siliconcompiler/utils/__init__.py +2 -1
- siliconcompiler/utils/flowgraph.py +24 -23
- siliconcompiler/utils/issue.py +23 -29
- siliconcompiler/utils/logging.py +35 -6
- siliconcompiler/utils/showtools.py +6 -1
- {siliconcompiler-0.34.0.dist-info → siliconcompiler-0.34.1.dist-info}/METADATA +15 -25
- {siliconcompiler-0.34.0.dist-info → siliconcompiler-0.34.1.dist-info}/RECORD +84 -82
- siliconcompiler/tools/yosys/procs.tcl +0 -71
- siliconcompiler/toolscripts/rhel9/install-yosys-parmys.sh +0 -68
- siliconcompiler/toolscripts/ubuntu22/install-yosys-parmys.sh +0 -68
- siliconcompiler/toolscripts/ubuntu24/install-yosys-parmys.sh +0 -68
- /siliconcompiler/tools/yosys/{sc_lec.tcl → scripts/sc_lec.tcl} +0 -0
- /siliconcompiler/tools/yosys/{sc_screenshot.tcl → scripts/sc_screenshot.tcl} +0 -0
- /siliconcompiler/tools/yosys/{syn_strategies.tcl → scripts/syn_strategies.tcl} +0 -0
- {siliconcompiler-0.34.0.dist-info → siliconcompiler-0.34.1.dist-info}/WHEEL +0 -0
- {siliconcompiler-0.34.0.dist-info → siliconcompiler-0.34.1.dist-info}/entry_points.txt +0 -0
- {siliconcompiler-0.34.0.dist-info → siliconcompiler-0.34.1.dist-info}/licenses/LICENSE +0 -0
- {siliconcompiler-0.34.0.dist-info → siliconcompiler-0.34.1.dist-info}/top_level.txt +0 -0
siliconcompiler/tool.py
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import contextlib
|
|
2
|
+
import copy
|
|
3
|
+
import csv
|
|
4
|
+
import gzip
|
|
2
5
|
import logging
|
|
3
6
|
import os
|
|
4
7
|
import psutil
|
|
@@ -8,6 +11,7 @@ import shutil
|
|
|
8
11
|
import subprocess
|
|
9
12
|
import sys
|
|
10
13
|
import time
|
|
14
|
+
import yaml
|
|
11
15
|
|
|
12
16
|
try:
|
|
13
17
|
import resource
|
|
@@ -25,12 +29,14 @@ import os.path
|
|
|
25
29
|
from packaging.version import Version, InvalidVersion
|
|
26
30
|
from packaging.specifiers import SpecifierSet, InvalidSpecifier
|
|
27
31
|
|
|
28
|
-
from siliconcompiler.schema import NamedSchema
|
|
32
|
+
from siliconcompiler.schema import NamedSchema, Journal
|
|
29
33
|
from siliconcompiler.schema import EditableSchema, Parameter, PerNode, Scope
|
|
34
|
+
from siliconcompiler.schema.parametertype import NodeType
|
|
30
35
|
from siliconcompiler.schema.utils import trim
|
|
31
36
|
|
|
32
|
-
from siliconcompiler import utils
|
|
37
|
+
from siliconcompiler import utils, NodeStatus
|
|
33
38
|
from siliconcompiler import sc_open
|
|
39
|
+
from siliconcompiler import Schema
|
|
34
40
|
|
|
35
41
|
from siliconcompiler.record import RecordTool
|
|
36
42
|
from siliconcompiler.flowgraph import RuntimeFlowgraph
|
|
@@ -61,37 +67,6 @@ class TaskExecutableNotFound(TaskError):
|
|
|
61
67
|
|
|
62
68
|
|
|
63
69
|
class TaskSchema(NamedSchema):
|
|
64
|
-
def __init__(self, name):
|
|
65
|
-
super().__init__(name)
|
|
66
|
-
|
|
67
|
-
schema_task(self)
|
|
68
|
-
|
|
69
|
-
def add_parameter(self, name, type, help, defvalue=None):
|
|
70
|
-
'''
|
|
71
|
-
Adds a parameter to the task definition.
|
|
72
|
-
|
|
73
|
-
Args:
|
|
74
|
-
name (str): name of parameter
|
|
75
|
-
type (str): schema type of the parameter
|
|
76
|
-
help (str): help string for this parameter
|
|
77
|
-
defvalue (any): default value for the parameter
|
|
78
|
-
'''
|
|
79
|
-
help = trim(help)
|
|
80
|
-
param = Parameter(
|
|
81
|
-
type,
|
|
82
|
-
defvalue=defvalue,
|
|
83
|
-
scope=Scope.JOB,
|
|
84
|
-
pernode=PerNode.OPTIONAL,
|
|
85
|
-
shorthelp=help,
|
|
86
|
-
help=help
|
|
87
|
-
)
|
|
88
|
-
|
|
89
|
-
EditableSchema(self).insert("var", name, param)
|
|
90
|
-
|
|
91
|
-
return param
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
class ToolSchema(NamedSchema):
|
|
95
70
|
__parse_version_check_str = r"""
|
|
96
71
|
(?P<operator>(==|!=|<=|>=|<|>|~=))
|
|
97
72
|
\s*
|
|
@@ -107,17 +82,28 @@ class ToolSchema(NamedSchema):
|
|
|
107
82
|
r"^\s*" + __parse_version_check_str + r"\s*$",
|
|
108
83
|
re.VERBOSE | re.IGNORECASE)
|
|
109
84
|
|
|
110
|
-
def __init__(self, name):
|
|
111
|
-
super().__init__(
|
|
85
|
+
def __init__(self, name=None):
|
|
86
|
+
super().__init__()
|
|
87
|
+
self.set_name(name)
|
|
112
88
|
|
|
113
|
-
|
|
89
|
+
schema_task(self)
|
|
114
90
|
|
|
115
|
-
|
|
116
|
-
|
|
91
|
+
self.__set_runtime(None)
|
|
92
|
+
|
|
93
|
+
@contextlib.contextmanager
|
|
94
|
+
def runtime(self, chip, step=None, index=None, relpath=None):
|
|
95
|
+
'''
|
|
96
|
+
Sets the runtime information needed to properly execute a task.
|
|
97
|
+
Note: unstable API
|
|
117
98
|
|
|
118
|
-
|
|
99
|
+
Args:
|
|
100
|
+
chip (:class:`Chip`): root schema for the runtime information
|
|
101
|
+
'''
|
|
102
|
+
obj_copy = copy.copy(self)
|
|
103
|
+
obj_copy.__set_runtime(chip, step=step, index=index, relpath=relpath)
|
|
104
|
+
yield obj_copy
|
|
119
105
|
|
|
120
|
-
def
|
|
106
|
+
def __set_runtime(self, chip, step=None, index=None, relpath=None):
|
|
121
107
|
'''
|
|
122
108
|
Sets the runtime information needed to properly execute a task.
|
|
123
109
|
Note: unstable API
|
|
@@ -128,22 +114,30 @@ class ToolSchema(NamedSchema):
|
|
|
128
114
|
self.__chip = None
|
|
129
115
|
self.__schema_full = None
|
|
130
116
|
self.__logger = None
|
|
117
|
+
self.__design_name = None
|
|
118
|
+
self.__design_top = None
|
|
119
|
+
self.__cwd = None
|
|
120
|
+
self.__relpath = relpath
|
|
131
121
|
if chip:
|
|
132
122
|
self.__chip = chip
|
|
133
123
|
self.__schema_full = chip.schema
|
|
134
124
|
self.__logger = chip.logger
|
|
125
|
+
self.__design_name = chip.design
|
|
126
|
+
self.__design_top = chip.top()
|
|
127
|
+
self.__cwd = chip.cwd
|
|
135
128
|
|
|
136
129
|
self.__step = step
|
|
137
130
|
self.__index = index
|
|
138
|
-
self.__tool = None
|
|
139
|
-
self.__task = None
|
|
140
131
|
|
|
141
132
|
self.__schema_record = None
|
|
142
133
|
self.__schema_metric = None
|
|
143
134
|
self.__schema_flow = None
|
|
135
|
+
self.__schema_flow_runtime = None
|
|
136
|
+
self.__schema_tool = None
|
|
144
137
|
if self.__schema_full:
|
|
145
138
|
self.__schema_record = self.__schema_full.get("record", field="schema")
|
|
146
139
|
self.__schema_metric = self.__schema_full.get("metric", field="schema")
|
|
140
|
+
self.__schema_tool = self._parent()._parent()
|
|
147
141
|
|
|
148
142
|
if not self.__step:
|
|
149
143
|
self.__step = self.__schema_full.get('arg', 'step')
|
|
@@ -157,8 +151,11 @@ class ToolSchema(NamedSchema):
|
|
|
157
151
|
if not flow:
|
|
158
152
|
raise RuntimeError("flow not specified")
|
|
159
153
|
self.__schema_flow = self.__schema_full.get("flowgraph", flow, field="schema")
|
|
160
|
-
|
|
161
|
-
self.
|
|
154
|
+
|
|
155
|
+
self.__schema_flow_runtime = RuntimeFlowgraph(
|
|
156
|
+
self.__schema_flow,
|
|
157
|
+
from_steps=set([step for step, _ in self.__schema_flow.get_entry_nodes()]),
|
|
158
|
+
prune_nodes=self.__schema_full.get('option', 'prune'))
|
|
162
159
|
|
|
163
160
|
def node(self):
|
|
164
161
|
'''
|
|
@@ -171,10 +168,10 @@ class ToolSchema(NamedSchema):
|
|
|
171
168
|
def tool(self):
|
|
172
169
|
'''
|
|
173
170
|
Returns:
|
|
174
|
-
|
|
171
|
+
tool name
|
|
175
172
|
'''
|
|
176
173
|
|
|
177
|
-
|
|
174
|
+
raise NotImplementedError("tool name must be implemented by the child class")
|
|
178
175
|
|
|
179
176
|
def task(self):
|
|
180
177
|
'''
|
|
@@ -182,7 +179,7 @@ class ToolSchema(NamedSchema):
|
|
|
182
179
|
task name
|
|
183
180
|
'''
|
|
184
181
|
|
|
185
|
-
|
|
182
|
+
raise NotImplementedError("task name must be implemented by the child class")
|
|
186
183
|
|
|
187
184
|
def logger(self):
|
|
188
185
|
'''
|
|
@@ -209,6 +206,10 @@ class ToolSchema(NamedSchema):
|
|
|
209
206
|
return self.__schema_metric
|
|
210
207
|
elif type == "flow":
|
|
211
208
|
return self.__schema_flow
|
|
209
|
+
elif type == "runtimeflow":
|
|
210
|
+
return self.__schema_flow_runtime
|
|
211
|
+
elif type == "tool":
|
|
212
|
+
return self.__schema_tool
|
|
212
213
|
else:
|
|
213
214
|
raise ValueError(f"{type} is not a schema section")
|
|
214
215
|
|
|
@@ -223,7 +224,7 @@ class ToolSchema(NamedSchema):
|
|
|
223
224
|
path to executable, or None if not specified
|
|
224
225
|
'''
|
|
225
226
|
|
|
226
|
-
exe = self.get('exe')
|
|
227
|
+
exe = self.schema("tool").get('exe')
|
|
227
228
|
|
|
228
229
|
if exe is None:
|
|
229
230
|
return None
|
|
@@ -250,7 +251,7 @@ class ToolSchema(NamedSchema):
|
|
|
250
251
|
version determined by :meth:`.parse_version`.
|
|
251
252
|
'''
|
|
252
253
|
|
|
253
|
-
veropt = self.get('vswitch')
|
|
254
|
+
veropt = self.schema("tool").get('vswitch')
|
|
254
255
|
if not veropt:
|
|
255
256
|
return None
|
|
256
257
|
|
|
@@ -263,7 +264,8 @@ class ToolSchema(NamedSchema):
|
|
|
263
264
|
cmdlist = [exe]
|
|
264
265
|
cmdlist.extend(veropt)
|
|
265
266
|
|
|
266
|
-
self.__logger.debug(f'Running {self.
|
|
267
|
+
self.__logger.debug(f'Running {self.tool()}/{self.task()} version check: '
|
|
268
|
+
f'{" ".join(cmdlist)}')
|
|
267
269
|
|
|
268
270
|
proc = subprocess.run(cmdlist,
|
|
269
271
|
stdin=subprocess.DEVNULL,
|
|
@@ -278,9 +280,11 @@ class ToolSchema(NamedSchema):
|
|
|
278
280
|
try:
|
|
279
281
|
version = self.parse_version(proc.stdout)
|
|
280
282
|
except NotImplementedError:
|
|
281
|
-
raise NotImplementedError(f'{self.
|
|
283
|
+
raise NotImplementedError(f'{self.tool()}/{self.task()} does not implement '
|
|
284
|
+
'parse_version()')
|
|
282
285
|
except Exception as e:
|
|
283
|
-
self.__logger.error(f'{self.
|
|
286
|
+
self.__logger.error(f'{self.tool()}/{self.task()} failed to parse version string: '
|
|
287
|
+
f'{proc.stdout}')
|
|
284
288
|
raise e from None
|
|
285
289
|
|
|
286
290
|
self.__logger.info(f"Tool '{exe_base}' found with version '{version}' "
|
|
@@ -301,7 +305,7 @@ class ToolSchema(NamedSchema):
|
|
|
301
305
|
|
|
302
306
|
'''
|
|
303
307
|
|
|
304
|
-
spec_sets = self.get('version', step=self.__step, index=self.__index)
|
|
308
|
+
spec_sets = self.schema("tool").get('version', step=self.__step, index=self.__index)
|
|
305
309
|
if not spec_sets:
|
|
306
310
|
# No requirement so always true
|
|
307
311
|
return True
|
|
@@ -310,7 +314,7 @@ class ToolSchema(NamedSchema):
|
|
|
310
314
|
split_specs = [s.strip() for s in spec_set.split(",") if s.strip()]
|
|
311
315
|
specs_list = []
|
|
312
316
|
for spec in split_specs:
|
|
313
|
-
match = re.match(
|
|
317
|
+
match = re.match(TaskSchema.__parse_version_check, spec)
|
|
314
318
|
if match is None:
|
|
315
319
|
self.__logger.warning(f'Invalid version specifier {spec}. '
|
|
316
320
|
f'Defaulting to =={spec}.')
|
|
@@ -324,15 +328,15 @@ class ToolSchema(NamedSchema):
|
|
|
324
328
|
try:
|
|
325
329
|
normalized_version = self.normalize_version(reported_version)
|
|
326
330
|
except Exception as e:
|
|
327
|
-
self.__logger.error(f'Unable to normalize version for {self.
|
|
331
|
+
self.__logger.error(f'Unable to normalize version for {self.tool()}/{self.task()}: '
|
|
328
332
|
f'{reported_version}')
|
|
329
333
|
raise e from None
|
|
330
334
|
|
|
331
335
|
try:
|
|
332
336
|
version = Version(normalized_version)
|
|
333
337
|
except InvalidVersion:
|
|
334
|
-
self.__logger.error(f'Version {normalized_version} reported by
|
|
335
|
-
'not match standard.')
|
|
338
|
+
self.__logger.error(f'Version {normalized_version} reported by '
|
|
339
|
+
f'{self.tool()}/{self.task()} does not match standard.')
|
|
336
340
|
return False
|
|
337
341
|
|
|
338
342
|
try:
|
|
@@ -340,7 +344,8 @@ class ToolSchema(NamedSchema):
|
|
|
340
344
|
f'{op}{self.normalize_version(ver)}' for op, ver in specs_list]
|
|
341
345
|
normalized_specs = ','.join(normalized_spec_list)
|
|
342
346
|
except Exception as e:
|
|
343
|
-
self.__logger.error(f'Unable to normalize versions for
|
|
347
|
+
self.__logger.error(f'Unable to normalize versions for '
|
|
348
|
+
f'{self.tool()}/{self.task()}: '
|
|
344
349
|
f'{",".join([f"{op}{ver}" for op, ver in specs_list])}')
|
|
345
350
|
raise e from None
|
|
346
351
|
|
|
@@ -355,7 +360,8 @@ class ToolSchema(NamedSchema):
|
|
|
355
360
|
return True
|
|
356
361
|
|
|
357
362
|
allowedstr = '; '.join(spec_sets)
|
|
358
|
-
self.__logger.error(f"Version check failed for {self.
|
|
363
|
+
self.__logger.error(f"Version check failed for {self.tool()}/{self.task()}. "
|
|
364
|
+
"Check installation.")
|
|
359
365
|
self.__logger.error(f"Found version {reported_version}, "
|
|
360
366
|
f"did not satisfy any version specifier set {allowedstr}.")
|
|
361
367
|
return False
|
|
@@ -377,16 +383,17 @@ class ToolSchema(NamedSchema):
|
|
|
377
383
|
envvars[env] = self.__schema_full.get('option', 'env', env)
|
|
378
384
|
|
|
379
385
|
# Add tool specific vars
|
|
380
|
-
for lic_env in self.getkeys('licenseserver'):
|
|
381
|
-
license_file = self.get('licenseserver', lic_env,
|
|
386
|
+
for lic_env in self.schema("tool").getkeys('licenseserver'):
|
|
387
|
+
license_file = self.schema("tool").get('licenseserver', lic_env,
|
|
388
|
+
step=self.__step, index=self.__index)
|
|
382
389
|
if license_file:
|
|
383
390
|
envvars[lic_env] = ':'.join(license_file)
|
|
384
391
|
|
|
385
392
|
if include_path:
|
|
386
|
-
path = self.find_files(
|
|
393
|
+
path = self.schema("tool").find_files(
|
|
387
394
|
"path", step=self.__step, index=self.__index,
|
|
388
|
-
packages=self.
|
|
389
|
-
cwd=self.
|
|
395
|
+
packages=self.schema().get("package", field="schema").get_resolvers(),
|
|
396
|
+
cwd=self.__cwd,
|
|
390
397
|
missing_ok=True)
|
|
391
398
|
|
|
392
399
|
envvars["PATH"] = os.getenv("PATH", os.defpath)
|
|
@@ -401,9 +408,8 @@ class ToolSchema(NamedSchema):
|
|
|
401
408
|
envvars[var] = val
|
|
402
409
|
|
|
403
410
|
# Add task specific vars
|
|
404
|
-
for env in self.getkeys(
|
|
405
|
-
envvars[env] = self.get(
|
|
406
|
-
step=self.__step, index=self.__index)
|
|
411
|
+
for env in self.getkeys("env"):
|
|
412
|
+
envvars[env] = self.get("env", env)
|
|
407
413
|
|
|
408
414
|
return envvars
|
|
409
415
|
|
|
@@ -417,9 +423,19 @@ class ToolSchema(NamedSchema):
|
|
|
417
423
|
|
|
418
424
|
cmdargs = []
|
|
419
425
|
try:
|
|
420
|
-
|
|
426
|
+
if self.__relpath:
|
|
427
|
+
args = []
|
|
428
|
+
for arg in self.runtime_options():
|
|
429
|
+
if os.path.isabs(arg) and os.path.exists(arg):
|
|
430
|
+
args.append(os.path.relpath(arg, self.__relpath))
|
|
431
|
+
else:
|
|
432
|
+
args.append(arg)
|
|
433
|
+
else:
|
|
434
|
+
args = self.runtime_options()
|
|
435
|
+
|
|
436
|
+
cmdargs.extend(args)
|
|
421
437
|
except Exception as e:
|
|
422
|
-
self.__logger.error(f'Failed to get runtime options for {self.
|
|
438
|
+
self.__logger.error(f'Failed to get runtime options for {self.tool()}/{self.task()}')
|
|
423
439
|
raise e from None
|
|
424
440
|
|
|
425
441
|
# Cleanup args
|
|
@@ -440,13 +456,13 @@ class ToolSchema(NamedSchema):
|
|
|
440
456
|
replay_opts["work_dir"] = workdir
|
|
441
457
|
replay_opts["exports"] = self.get_runtime_environmental_variables(include_path=include_path)
|
|
442
458
|
|
|
443
|
-
replay_opts["executable"] = self.get('exe')
|
|
459
|
+
replay_opts["executable"] = self.schema("tool").get('exe')
|
|
444
460
|
replay_opts["step"] = self.__step
|
|
445
461
|
replay_opts["index"] = self.__index
|
|
446
|
-
replay_opts["cfg_file"] = f"inputs/{self.
|
|
462
|
+
replay_opts["cfg_file"] = f"inputs/{self.__design_name}.pkg.json"
|
|
447
463
|
replay_opts["node_only"] = 0 if replay_opts["executable"] else 1
|
|
448
464
|
|
|
449
|
-
vswitch = self.get('vswitch')
|
|
465
|
+
vswitch = self.schema("tool").get('vswitch')
|
|
450
466
|
if vswitch:
|
|
451
467
|
replay_opts["version_flag"] = shlex.join(vswitch)
|
|
452
468
|
|
|
@@ -503,6 +519,66 @@ class ToolSchema(NamedSchema):
|
|
|
503
519
|
os.makedirs(os.path.join(workdir, 'outputs'), exist_ok=True)
|
|
504
520
|
os.makedirs(os.path.join(workdir, 'reports'), exist_ok=True)
|
|
505
521
|
|
|
522
|
+
def __write_yaml_manifest(self, fout, manifest):
|
|
523
|
+
class YamlIndentDumper(yaml.Dumper):
|
|
524
|
+
def increase_indent(self, flow=False, indentless=False):
|
|
525
|
+
return super().increase_indent(flow=flow, indentless=indentless)
|
|
526
|
+
|
|
527
|
+
fout.write(yaml.dump(manifest.getdict(), Dumper=YamlIndentDumper,
|
|
528
|
+
default_flow_style=False))
|
|
529
|
+
|
|
530
|
+
def __write_tcl_manifest(self, fout, manifest):
|
|
531
|
+
template = utils.get_file_template('tcl/manifest.tcl.j2')
|
|
532
|
+
tcl_set_cmds = []
|
|
533
|
+
for key in sorted(manifest.allkeys()):
|
|
534
|
+
# print out all non default values
|
|
535
|
+
if 'default' in key:
|
|
536
|
+
continue
|
|
537
|
+
|
|
538
|
+
param = manifest.get(*key, field=None)
|
|
539
|
+
|
|
540
|
+
# create a TCL dict
|
|
541
|
+
keystr = ' '.join([NodeType.to_tcl(keypart, 'str') for keypart in key])
|
|
542
|
+
|
|
543
|
+
valstr = param.gettcl(step=self.__step, index=self.__index)
|
|
544
|
+
if valstr is None:
|
|
545
|
+
continue
|
|
546
|
+
|
|
547
|
+
# Ensure empty values get something
|
|
548
|
+
if valstr == '':
|
|
549
|
+
valstr = '{}'
|
|
550
|
+
|
|
551
|
+
tcl_set_cmds.append(f"dict set sc_cfg {keystr} {valstr}")
|
|
552
|
+
|
|
553
|
+
if template:
|
|
554
|
+
fout.write(template.render(manifest_dict='\n'.join(tcl_set_cmds),
|
|
555
|
+
scroot=os.path.abspath(
|
|
556
|
+
os.path.join(os.path.dirname(__file__))),
|
|
557
|
+
record_access="get" in Journal.access(self).get_types(),
|
|
558
|
+
record_access_id=Schema._RECORD_ACCESS_IDENTIFIER))
|
|
559
|
+
else:
|
|
560
|
+
for cmd in tcl_set_cmds:
|
|
561
|
+
fout.write(cmd + '\n')
|
|
562
|
+
fout.write('\n')
|
|
563
|
+
|
|
564
|
+
def __write_csv_manifest(self, fout, manifest):
|
|
565
|
+
csvwriter = csv.writer(fout)
|
|
566
|
+
csvwriter.writerow(['Keypath', 'Value'])
|
|
567
|
+
|
|
568
|
+
for key in sorted(manifest.allkeys()):
|
|
569
|
+
keypath = ','.join(key)
|
|
570
|
+
param = manifest.get(*key, field=None)
|
|
571
|
+
if param.get(field="pernode").is_never():
|
|
572
|
+
value = param.get()
|
|
573
|
+
else:
|
|
574
|
+
value = param.get(step=self.__step, index=self.__index)
|
|
575
|
+
|
|
576
|
+
if isinstance(value, (set, list)):
|
|
577
|
+
for item in value:
|
|
578
|
+
csvwriter.writerow([keypath, item])
|
|
579
|
+
else:
|
|
580
|
+
csvwriter.writerow([keypath, value])
|
|
581
|
+
|
|
506
582
|
def write_task_manifest(self, directory, backup=True):
|
|
507
583
|
'''
|
|
508
584
|
Write the manifest needed for the task
|
|
@@ -512,7 +588,7 @@ class ToolSchema(NamedSchema):
|
|
|
512
588
|
backup (bool): if True and an existing manifest is found a backup is kept.
|
|
513
589
|
'''
|
|
514
590
|
|
|
515
|
-
suffix = self.get('format')
|
|
591
|
+
suffix = self.schema("tool").get('format')
|
|
516
592
|
if not suffix:
|
|
517
593
|
return
|
|
518
594
|
|
|
@@ -521,8 +597,65 @@ class ToolSchema(NamedSchema):
|
|
|
521
597
|
if backup and os.path.exists(manifest_path):
|
|
522
598
|
shutil.copyfile(manifest_path, f'{manifest_path}.bak')
|
|
523
599
|
|
|
524
|
-
#
|
|
525
|
-
self.
|
|
600
|
+
# Generate abs paths
|
|
601
|
+
schema = self.__abspath_schema()
|
|
602
|
+
|
|
603
|
+
if re.search(r'\.json(\.gz)?$', manifest_path):
|
|
604
|
+
schema.write_manifest(manifest_path)
|
|
605
|
+
else:
|
|
606
|
+
try:
|
|
607
|
+
# format specific dumping
|
|
608
|
+
if manifest_path.endswith('.gz'):
|
|
609
|
+
fout = gzip.open(manifest_path, 'wt', encoding='UTF-8')
|
|
610
|
+
elif re.search(r'\.csv$', manifest_path):
|
|
611
|
+
# Files written using csv library should be opened with newline=''
|
|
612
|
+
# https://docs.python.org/3/library/csv.html#id3
|
|
613
|
+
fout = open(manifest_path, 'w', newline='')
|
|
614
|
+
else:
|
|
615
|
+
fout = open(manifest_path, 'w')
|
|
616
|
+
|
|
617
|
+
if re.search(r'(\.yaml|\.yml)(\.gz)?$', manifest_path):
|
|
618
|
+
self.__write_yaml_manifest(fout, schema)
|
|
619
|
+
elif re.search(r'\.tcl(\.gz)?$', manifest_path):
|
|
620
|
+
self.__write_tcl_manifest(fout, schema)
|
|
621
|
+
elif re.search(r'\.csv(\.gz)?$', manifest_path):
|
|
622
|
+
self.__write_csv_manifest(fout, schema)
|
|
623
|
+
else:
|
|
624
|
+
raise ValueError(f"{manifest_path} is not a recognized path type")
|
|
625
|
+
finally:
|
|
626
|
+
fout.close()
|
|
627
|
+
|
|
628
|
+
def __abspath_schema(self):
|
|
629
|
+
root = self.schema()
|
|
630
|
+
schema = root.copy()
|
|
631
|
+
|
|
632
|
+
strict = root.get("option", "strict")
|
|
633
|
+
root.set("option", "strict", False)
|
|
634
|
+
|
|
635
|
+
for keypath in root.allkeys():
|
|
636
|
+
paramtype = schema.get(*keypath, field='type')
|
|
637
|
+
if 'file' not in paramtype and 'dir' not in paramtype:
|
|
638
|
+
# only do something if type is file or dir
|
|
639
|
+
continue
|
|
640
|
+
|
|
641
|
+
for value, step, index in root.get(*keypath, field=None).getvalues():
|
|
642
|
+
if not value:
|
|
643
|
+
continue
|
|
644
|
+
abspaths = root.find_files(*keypath, missing_ok=True, step=step, index=index)
|
|
645
|
+
if isinstance(abspaths, (set, list)) and None in abspaths:
|
|
646
|
+
# Lists may not contain None
|
|
647
|
+
schema.set(*keypath, [], step=step, index=index)
|
|
648
|
+
else:
|
|
649
|
+
if self.__relpath:
|
|
650
|
+
if isinstance(abspaths, (set, list)):
|
|
651
|
+
abspaths = [os.path.relpath(path, self.__relpath) for path in abspaths]
|
|
652
|
+
else:
|
|
653
|
+
abspaths = os.path.relpath(abspaths, self.__relpath)
|
|
654
|
+
schema.set(*keypath, abspaths, step=step, index=index)
|
|
655
|
+
|
|
656
|
+
root.set("option", "strict", strict)
|
|
657
|
+
|
|
658
|
+
return schema
|
|
526
659
|
|
|
527
660
|
def __get_io_file(self, io_type):
|
|
528
661
|
'''
|
|
@@ -531,10 +664,8 @@ class ToolSchema(NamedSchema):
|
|
|
531
664
|
Args:
|
|
532
665
|
io_type (str): name of io type
|
|
533
666
|
'''
|
|
534
|
-
suffix = self.get(
|
|
535
|
-
|
|
536
|
-
destination = self.get('task', self.__task, io_type, 'destination',
|
|
537
|
-
step=self.__step, index=self.__index)
|
|
667
|
+
suffix = self.get(io_type, "suffix")
|
|
668
|
+
destination = self.get(io_type, "destination")
|
|
538
669
|
|
|
539
670
|
io_file = None
|
|
540
671
|
io_log = False
|
|
@@ -542,7 +673,7 @@ class ToolSchema(NamedSchema):
|
|
|
542
673
|
io_file = f"{self.__step}.{suffix}"
|
|
543
674
|
io_log = True
|
|
544
675
|
elif destination == 'output':
|
|
545
|
-
io_file = os.path.join('outputs', f"{self.
|
|
676
|
+
io_file = os.path.join('outputs', f"{self.__design_top}.{suffix}")
|
|
546
677
|
elif destination == 'none':
|
|
547
678
|
io_file = os.devnull
|
|
548
679
|
|
|
@@ -581,13 +712,13 @@ class ToolSchema(NamedSchema):
|
|
|
581
712
|
TERMINATE_TIMEOUT = 5
|
|
582
713
|
|
|
583
714
|
terminate_process(proc.pid, timeout=TERMINATE_TIMEOUT)
|
|
584
|
-
self.__logger.info(f'Waiting for {self.
|
|
715
|
+
self.__logger.info(f'Waiting for {self.tool()}/{self.task()} to exit...')
|
|
585
716
|
try:
|
|
586
717
|
proc.wait(timeout=TERMINATE_TIMEOUT)
|
|
587
718
|
except subprocess.TimeoutExpired:
|
|
588
719
|
if proc.poll() is None:
|
|
589
|
-
self.__logger.warning(f'{self.
|
|
590
|
-
'seconds. Terminating...')
|
|
720
|
+
self.__logger.warning(f'{self.tool()}/{self.task()} did not exit within '
|
|
721
|
+
f'{TERMINATE_TIMEOUT} seconds. Terminating...')
|
|
591
722
|
terminate_process(proc.pid, timeout=TERMINATE_TIMEOUT)
|
|
592
723
|
|
|
593
724
|
def run_task(self, workdir, quiet, loglevel, breakpoint, nice, timeout):
|
|
@@ -658,7 +789,7 @@ class ToolSchema(NamedSchema):
|
|
|
658
789
|
contextlib.redirect_stdout(stdout_writer):
|
|
659
790
|
retcode = self.run()
|
|
660
791
|
except Exception as e:
|
|
661
|
-
self.__logger.error(f'Failed in run() for {self.
|
|
792
|
+
self.__logger.error(f'Failed in run() for {self.tool()}/{self.task()}: {e}')
|
|
662
793
|
utils.print_traceback(self.__logger, e)
|
|
663
794
|
raise e
|
|
664
795
|
finally:
|
|
@@ -706,9 +837,9 @@ class ToolSchema(NamedSchema):
|
|
|
706
837
|
retcode = pty.spawn([exe, *cmdlist], read)
|
|
707
838
|
else:
|
|
708
839
|
with open(stdout_file, 'w') as stdout_writer, \
|
|
709
|
-
open(stdout_file, 'r', errors='
|
|
840
|
+
open(stdout_file, 'r', errors='replace') as stdout_reader, \
|
|
710
841
|
open(stderr_file, 'w') as stderr_writer, \
|
|
711
|
-
open(stderr_file, 'r', errors='
|
|
842
|
+
open(stderr_file, 'r', errors='replace') as stderr_reader:
|
|
712
843
|
# if STDOUT and STDERR are to be redirected to the same file,
|
|
713
844
|
# use a single writer
|
|
714
845
|
if stderr_file == stdout_file:
|
|
@@ -805,7 +936,7 @@ class ToolSchema(NamedSchema):
|
|
|
805
936
|
|
|
806
937
|
# Remove runtime information
|
|
807
938
|
for key in list(state.keys()):
|
|
808
|
-
if key.startswith("
|
|
939
|
+
if key.startswith("_TaskSchema__"):
|
|
809
940
|
del state[key]
|
|
810
941
|
|
|
811
942
|
return state
|
|
@@ -814,10 +945,101 @@ class ToolSchema(NamedSchema):
|
|
|
814
945
|
self.__dict__ = state
|
|
815
946
|
|
|
816
947
|
# Reinit runtime information
|
|
817
|
-
self.
|
|
948
|
+
self.__set_runtime(None)
|
|
818
949
|
|
|
819
950
|
def get_output_files(self):
|
|
820
|
-
return set(self.get("
|
|
951
|
+
return set(self.get("output"))
|
|
952
|
+
|
|
953
|
+
def get_files_from_input_nodes(self):
|
|
954
|
+
"""
|
|
955
|
+
Returns a dictionary of files with the node they originated from
|
|
956
|
+
"""
|
|
957
|
+
|
|
958
|
+
nodes = self.schema("runtimeflow").get_nodes()
|
|
959
|
+
|
|
960
|
+
inputs = {}
|
|
961
|
+
for in_step, in_index in self.schema("flow").get(*self.node(), 'input'):
|
|
962
|
+
if (in_step, in_index) not in nodes:
|
|
963
|
+
# node has been pruned so will not provide anything
|
|
964
|
+
continue
|
|
965
|
+
|
|
966
|
+
in_tool = self.schema("flow").get(in_step, in_index, "tool")
|
|
967
|
+
in_task = self.schema("flow").get(in_step, in_index, "task")
|
|
968
|
+
|
|
969
|
+
task_obj = self.schema().get("tool", in_tool, "task", in_task, field="schema")
|
|
970
|
+
|
|
971
|
+
if self.schema("record").get('status', step=in_step, index=in_index) == \
|
|
972
|
+
NodeStatus.SKIPPED:
|
|
973
|
+
with task_obj.runtime(self.__chip, step=in_step, index=in_index) as task:
|
|
974
|
+
for file, nodes in task.get_files_from_input_nodes().items():
|
|
975
|
+
inputs.setdefault(file, []).extend(nodes)
|
|
976
|
+
continue
|
|
977
|
+
|
|
978
|
+
for output in NamedSchema.get(task_obj, "output", step=in_step, index=in_index):
|
|
979
|
+
inputs.setdefault(output, []).append((in_step, in_index))
|
|
980
|
+
|
|
981
|
+
return inputs
|
|
982
|
+
|
|
983
|
+
def compute_input_file_node_name(self, filename, step, index):
|
|
984
|
+
"""
|
|
985
|
+
Generate a unique name for in input file based on the originating node.
|
|
986
|
+
|
|
987
|
+
Args:
|
|
988
|
+
filename (str): name of inputfile
|
|
989
|
+
step (str): Step name
|
|
990
|
+
index (str): Index name
|
|
991
|
+
"""
|
|
992
|
+
|
|
993
|
+
_, file_type = os.path.splitext(filename)
|
|
994
|
+
|
|
995
|
+
if file_type:
|
|
996
|
+
base = filename
|
|
997
|
+
total_ext = []
|
|
998
|
+
while file_type:
|
|
999
|
+
base, file_type = os.path.splitext(base)
|
|
1000
|
+
total_ext.append(file_type)
|
|
1001
|
+
|
|
1002
|
+
total_ext.reverse()
|
|
1003
|
+
|
|
1004
|
+
return f'{base}.{step}{index}{"".join(total_ext)}'
|
|
1005
|
+
else:
|
|
1006
|
+
return f'{filename}.{step}{index}'
|
|
1007
|
+
|
|
1008
|
+
def add_parameter(self, name, type, help, defvalue=None):
|
|
1009
|
+
'''
|
|
1010
|
+
Adds a parameter to the task definition.
|
|
1011
|
+
|
|
1012
|
+
Args:
|
|
1013
|
+
name (str): name of parameter
|
|
1014
|
+
type (str): schema type of the parameter
|
|
1015
|
+
help (str): help string for this parameter
|
|
1016
|
+
defvalue (any): default value for the parameter
|
|
1017
|
+
'''
|
|
1018
|
+
help = trim(help)
|
|
1019
|
+
param = Parameter(
|
|
1020
|
+
type,
|
|
1021
|
+
defvalue=defvalue,
|
|
1022
|
+
scope=Scope.JOB,
|
|
1023
|
+
pernode=PerNode.OPTIONAL,
|
|
1024
|
+
shorthelp=help,
|
|
1025
|
+
help=help
|
|
1026
|
+
)
|
|
1027
|
+
|
|
1028
|
+
EditableSchema(self).insert("var", name, param)
|
|
1029
|
+
|
|
1030
|
+
return param
|
|
1031
|
+
|
|
1032
|
+
###############################################################
|
|
1033
|
+
def get(self, *keypath, field='value'):
|
|
1034
|
+
return super().get(*keypath, field=field,
|
|
1035
|
+
step=self.__step, index=self.__index)
|
|
1036
|
+
|
|
1037
|
+
def set(self, *args, field='value', clobber=True):
|
|
1038
|
+
return super().set(*args, field=field, clobber=clobber,
|
|
1039
|
+
step=self.__step, index=self.__index)
|
|
1040
|
+
|
|
1041
|
+
def add(self, *args, field='value'):
|
|
1042
|
+
return super().add(*args, field=field, step=self.__step, index=self.__index)
|
|
821
1043
|
|
|
822
1044
|
###############################################################
|
|
823
1045
|
def parse_version(self, stdout):
|
|
@@ -830,24 +1052,18 @@ class ToolSchema(NamedSchema):
|
|
|
830
1052
|
pass
|
|
831
1053
|
|
|
832
1054
|
def select_input_nodes(self):
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
flow,
|
|
836
|
-
from_steps=set([step for step, _ in flow.get_entry_nodes()]),
|
|
837
|
-
prune_nodes=self.__chip.get('option', 'prune'))
|
|
838
|
-
|
|
839
|
-
return runtime.get_node_inputs(self.__step, self.__index, record=self.schema("record"))
|
|
1055
|
+
return self.schema("runtimeflow").get_node_inputs(
|
|
1056
|
+
self.__step, self.__index, record=self.schema("record"))
|
|
840
1057
|
|
|
841
1058
|
def pre_process(self):
|
|
842
1059
|
pass
|
|
843
1060
|
|
|
844
1061
|
def runtime_options(self):
|
|
845
1062
|
cmdargs = []
|
|
846
|
-
cmdargs.extend(self.get(
|
|
847
|
-
step=self.__step, index=self.__index))
|
|
1063
|
+
cmdargs.extend(self.get("option"))
|
|
848
1064
|
|
|
849
1065
|
# Add scripts files / TODO:
|
|
850
|
-
scripts = self.__chip.find_files('tool', self.
|
|
1066
|
+
scripts = self.__chip.find_files('tool', self.tool(), 'task', self.task(), 'script',
|
|
851
1067
|
step=self.__step, index=self.__index)
|
|
852
1068
|
|
|
853
1069
|
cmdargs.extend(scripts)
|
|
@@ -861,12 +1077,33 @@ class ToolSchema(NamedSchema):
|
|
|
861
1077
|
pass
|
|
862
1078
|
|
|
863
1079
|
|
|
1080
|
+
class ToolSchema(NamedSchema):
|
|
1081
|
+
def __init__(self, name=None):
|
|
1082
|
+
super().__init__()
|
|
1083
|
+
self.set_name(name)
|
|
1084
|
+
|
|
1085
|
+
schema_tool(self)
|
|
1086
|
+
|
|
1087
|
+
schema = EditableSchema(self)
|
|
1088
|
+
schema.insert("task", "default", TaskSchema(None))
|
|
1089
|
+
|
|
1090
|
+
|
|
864
1091
|
###########################################################################
|
|
865
1092
|
# Migration helper
|
|
866
1093
|
###########################################################################
|
|
867
|
-
class ToolSchemaTmp(
|
|
1094
|
+
class ToolSchemaTmp(NamedSchema):
|
|
1095
|
+
def __init__(self):
|
|
1096
|
+
super().__init__()
|
|
1097
|
+
|
|
1098
|
+
schema_tool(self)
|
|
1099
|
+
|
|
1100
|
+
schema = EditableSchema(self)
|
|
1101
|
+
schema.insert("task", "default", TaskSchemaTmp())
|
|
1102
|
+
|
|
1103
|
+
|
|
1104
|
+
class TaskSchemaTmp(TaskSchema):
|
|
868
1105
|
def __init__(self):
|
|
869
|
-
super().__init__(
|
|
1106
|
+
super().__init__()
|
|
870
1107
|
|
|
871
1108
|
def __module_func(self, name, modules):
|
|
872
1109
|
for module in modules:
|
|
@@ -877,103 +1114,101 @@ class ToolSchemaTmp(ToolSchema):
|
|
|
877
1114
|
|
|
878
1115
|
def __tool_task_modules(self):
|
|
879
1116
|
step, index = self.node()
|
|
880
|
-
flow = self.
|
|
1117
|
+
flow = self._TaskSchema__chip.get('option', 'flow')
|
|
881
1118
|
return \
|
|
882
|
-
self.
|
|
883
|
-
self.
|
|
1119
|
+
self._TaskSchema__chip._get_tool_module(step, index, flow=flow), \
|
|
1120
|
+
self._TaskSchema__chip._get_task_module(step, index, flow=flow)
|
|
1121
|
+
|
|
1122
|
+
@contextlib.contextmanager
|
|
1123
|
+
def __in_step_index(self):
|
|
1124
|
+
prev_step, prev_index = self._TaskSchema__chip.get('arg', 'step'), \
|
|
1125
|
+
self._TaskSchema__chip.get('arg', 'index')
|
|
1126
|
+
step, index = self.node()
|
|
1127
|
+
self._TaskSchema__chip.set('arg', 'step', step)
|
|
1128
|
+
self._TaskSchema__chip.set('arg', 'index', index)
|
|
1129
|
+
yield
|
|
1130
|
+
self._TaskSchema__chip.set('arg', 'step', prev_step)
|
|
1131
|
+
self._TaskSchema__chip.set('arg', 'index', prev_index)
|
|
1132
|
+
|
|
1133
|
+
def tool(self):
|
|
1134
|
+
return self.schema("flow").get(*self.node(), 'tool')
|
|
1135
|
+
|
|
1136
|
+
def task(self):
|
|
1137
|
+
return self.schema("flow").get(*self.node(), 'task')
|
|
1138
|
+
|
|
1139
|
+
def get_exe(self):
|
|
1140
|
+
if self.tool() == "execute" and self.task() == "exec_input":
|
|
1141
|
+
return self.schema("tool").get("exe")
|
|
1142
|
+
return super().get_exe()
|
|
1143
|
+
|
|
1144
|
+
def schema(self, type=None):
|
|
1145
|
+
if type is None:
|
|
1146
|
+
return self._TaskSchema__chip
|
|
1147
|
+
return super().schema(type)
|
|
884
1148
|
|
|
885
1149
|
def get_output_files(self):
|
|
886
1150
|
_, task = self.__tool_task_modules()
|
|
887
1151
|
method = self.__module_func("_gather_outputs", [task])
|
|
888
1152
|
if method:
|
|
889
|
-
return method(self.
|
|
890
|
-
return
|
|
1153
|
+
return method(self._TaskSchema__chip, *self.node())
|
|
1154
|
+
return TaskSchema.get_output_files(self)
|
|
891
1155
|
|
|
892
1156
|
def parse_version(self, stdout):
|
|
893
1157
|
tool, _ = self.__tool_task_modules()
|
|
894
1158
|
method = self.__module_func("parse_version", [tool])
|
|
895
1159
|
if method:
|
|
896
1160
|
return method(stdout)
|
|
897
|
-
return
|
|
1161
|
+
return TaskSchema.parse_version(self, stdout)
|
|
898
1162
|
|
|
899
1163
|
def normalize_version(self, version):
|
|
900
1164
|
tool, _ = self.__tool_task_modules()
|
|
901
1165
|
method = self.__module_func("normalize_version", [tool])
|
|
902
1166
|
if method:
|
|
903
1167
|
return method(version)
|
|
904
|
-
return
|
|
1168
|
+
return TaskSchema.normalize_version(self, version)
|
|
905
1169
|
|
|
906
1170
|
def generate_replay_script(self, filepath, workdir, include_path=True):
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
self._ToolSchema__chip.set('arg', 'step', step)
|
|
911
|
-
self._ToolSchema__chip.set('arg', 'index', index)
|
|
912
|
-
ret = ToolSchema.generate_replay_script(self, filepath, workdir, include_path=include_path)
|
|
913
|
-
self._ToolSchema__chip.set('arg', 'step', prev_step)
|
|
914
|
-
self._ToolSchema__chip.set('arg', 'index', prev_index)
|
|
1171
|
+
with self.__in_step_index():
|
|
1172
|
+
ret = TaskSchema.generate_replay_script(self, filepath, workdir,
|
|
1173
|
+
include_path=include_path)
|
|
915
1174
|
return ret
|
|
916
1175
|
|
|
917
1176
|
def setup(self):
|
|
918
1177
|
_, task = self.__tool_task_modules()
|
|
919
1178
|
method = self.__module_func("setup", [task])
|
|
920
1179
|
if method:
|
|
921
|
-
|
|
922
|
-
self.
|
|
923
|
-
step, index = self.node()
|
|
924
|
-
self._ToolSchema__chip.set('arg', 'step', step)
|
|
925
|
-
self._ToolSchema__chip.set('arg', 'index', index)
|
|
926
|
-
ret = method(self._ToolSchema__chip)
|
|
927
|
-
self._ToolSchema__chip.set('arg', 'step', prev_step)
|
|
928
|
-
self._ToolSchema__chip.set('arg', 'index', prev_index)
|
|
1180
|
+
with self.__in_step_index():
|
|
1181
|
+
ret = method(self._TaskSchema__chip)
|
|
929
1182
|
return ret
|
|
930
|
-
return
|
|
1183
|
+
return TaskSchema.setup(self)
|
|
931
1184
|
|
|
932
1185
|
def select_input_nodes(self):
|
|
933
1186
|
_, task = self.__tool_task_modules()
|
|
934
1187
|
method = self.__module_func("_select_inputs", [task])
|
|
935
1188
|
if method:
|
|
936
|
-
|
|
937
|
-
self.
|
|
938
|
-
step, index = self.node()
|
|
939
|
-
self._ToolSchema__chip.set('arg', 'step', step)
|
|
940
|
-
self._ToolSchema__chip.set('arg', 'index', index)
|
|
941
|
-
ret = method(self._ToolSchema__chip, *self.node())
|
|
942
|
-
self._ToolSchema__chip.set('arg', 'step', prev_step)
|
|
943
|
-
self._ToolSchema__chip.set('arg', 'index', prev_index)
|
|
1189
|
+
with self.__in_step_index():
|
|
1190
|
+
ret = method(self._TaskSchema__chip, *self.node())
|
|
944
1191
|
return ret
|
|
945
|
-
return
|
|
1192
|
+
return TaskSchema.select_input_nodes(self)
|
|
946
1193
|
|
|
947
1194
|
def pre_process(self):
|
|
948
1195
|
_, task = self.__tool_task_modules()
|
|
949
1196
|
method = self.__module_func("pre_process", [task])
|
|
950
1197
|
if method:
|
|
951
|
-
|
|
952
|
-
self.
|
|
953
|
-
step, index = self.node()
|
|
954
|
-
self._ToolSchema__chip.set('arg', 'step', step)
|
|
955
|
-
self._ToolSchema__chip.set('arg', 'index', index)
|
|
956
|
-
ret = method(self._ToolSchema__chip)
|
|
957
|
-
self._ToolSchema__chip.set('arg', 'step', prev_step)
|
|
958
|
-
self._ToolSchema__chip.set('arg', 'index', prev_index)
|
|
1198
|
+
with self.__in_step_index():
|
|
1199
|
+
ret = method(self._TaskSchema__chip)
|
|
959
1200
|
return ret
|
|
960
|
-
return
|
|
1201
|
+
return TaskSchema.pre_process(self)
|
|
961
1202
|
|
|
962
1203
|
def runtime_options(self):
|
|
963
1204
|
tool, task = self.__tool_task_modules()
|
|
964
1205
|
method = self.__module_func("runtime_options", [task, tool])
|
|
965
1206
|
if method:
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
self._ToolSchema__chip.set('arg', 'step', step)
|
|
970
|
-
self._ToolSchema__chip.set('arg', 'index', index)
|
|
971
|
-
ret = ToolSchema.runtime_options(self)
|
|
972
|
-
ret.extend(method(self._ToolSchema__chip))
|
|
973
|
-
self._ToolSchema__chip.set('arg', 'step', prev_step)
|
|
974
|
-
self._ToolSchema__chip.set('arg', 'index', prev_index)
|
|
1207
|
+
with self.__in_step_index():
|
|
1208
|
+
ret = TaskSchema.runtime_options(self)
|
|
1209
|
+
ret.extend(method(self._TaskSchema__chip))
|
|
975
1210
|
return ret
|
|
976
|
-
return
|
|
1211
|
+
return TaskSchema.runtime_options(self)
|
|
977
1212
|
|
|
978
1213
|
def run(self):
|
|
979
1214
|
_, task = self.__tool_task_modules()
|
|
@@ -981,38 +1216,26 @@ class ToolSchemaTmp(ToolSchema):
|
|
|
981
1216
|
if method:
|
|
982
1217
|
# Handle logger stdout suppression if quiet
|
|
983
1218
|
step, index = self.node()
|
|
984
|
-
stdout_handler_level = self.
|
|
985
|
-
if self.
|
|
986
|
-
self.
|
|
1219
|
+
stdout_handler_level = self._TaskSchema__chip._logger_console.level
|
|
1220
|
+
if self._TaskSchema__chip.get('option', 'quiet', step=step, index=index):
|
|
1221
|
+
self._TaskSchema__chip._logger_console.setLevel(logging.CRITICAL)
|
|
987
1222
|
|
|
988
|
-
|
|
989
|
-
self.
|
|
990
|
-
step, index = self.node()
|
|
991
|
-
self._ToolSchema__chip.set('arg', 'step', step)
|
|
992
|
-
self._ToolSchema__chip.set('arg', 'index', index)
|
|
993
|
-
retcode = method(self._ToolSchema__chip)
|
|
994
|
-
self._ToolSchema__chip.set('arg', 'step', prev_step)
|
|
995
|
-
self._ToolSchema__chip.set('arg', 'index', prev_index)
|
|
1223
|
+
with self.__in_step_index():
|
|
1224
|
+
retcode = method(self._TaskSchema__chip)
|
|
996
1225
|
|
|
997
|
-
self.
|
|
1226
|
+
self._TaskSchema__chip._logger_console.setLevel(stdout_handler_level)
|
|
998
1227
|
|
|
999
1228
|
return retcode
|
|
1000
|
-
return
|
|
1229
|
+
return TaskSchema.run(self)
|
|
1001
1230
|
|
|
1002
1231
|
def post_process(self):
|
|
1003
1232
|
_, task = self.__tool_task_modules()
|
|
1004
1233
|
method = self.__module_func("post_process", [task])
|
|
1005
1234
|
if method:
|
|
1006
|
-
|
|
1007
|
-
self.
|
|
1008
|
-
step, index = self.node()
|
|
1009
|
-
self._ToolSchema__chip.set('arg', 'step', step)
|
|
1010
|
-
self._ToolSchema__chip.set('arg', 'index', index)
|
|
1011
|
-
ret = method(self._ToolSchema__chip)
|
|
1012
|
-
self._ToolSchema__chip.set('arg', 'step', prev_step)
|
|
1013
|
-
self._ToolSchema__chip.set('arg', 'index', prev_index)
|
|
1235
|
+
with self.__in_step_index():
|
|
1236
|
+
ret = method(self._TaskSchema__chip)
|
|
1014
1237
|
return ret
|
|
1015
|
-
return
|
|
1238
|
+
return TaskSchema.post_process(self)
|
|
1016
1239
|
|
|
1017
1240
|
|
|
1018
1241
|
###########################################################################
|