siliconcompiler 0.33.1__py3-none-any.whl → 0.34.0__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 +2 -0
- siliconcompiler/_metadata.py +1 -1
- siliconcompiler/apps/sc_issue.py +5 -3
- siliconcompiler/apps/sc_remote.py +0 -17
- siliconcompiler/apps/utils/replay.py +5 -5
- siliconcompiler/checklist.py +1 -1
- siliconcompiler/core.py +39 -48
- siliconcompiler/data/templates/replay/replay.sh.j2 +18 -1
- siliconcompiler/dependencyschema.py +392 -0
- siliconcompiler/design.py +664 -0
- siliconcompiler/flowgraph.py +32 -1
- siliconcompiler/metric.py +19 -0
- siliconcompiler/package/__init__.py +383 -223
- siliconcompiler/package/git.py +75 -77
- siliconcompiler/package/github.py +70 -97
- siliconcompiler/package/https.py +77 -93
- siliconcompiler/packageschema.py +260 -0
- siliconcompiler/pdk.py +2 -2
- siliconcompiler/record.py +57 -5
- siliconcompiler/remote/client.py +61 -13
- siliconcompiler/remote/server.py +109 -64
- siliconcompiler/report/dashboard/cli/board.py +1 -2
- siliconcompiler/scheduler/__init__.py +3 -1375
- siliconcompiler/scheduler/docker.py +268 -0
- siliconcompiler/scheduler/run_node.py +20 -19
- siliconcompiler/scheduler/scheduler.py +308 -0
- siliconcompiler/scheduler/schedulernode.py +934 -0
- siliconcompiler/scheduler/slurm.py +147 -163
- siliconcompiler/scheduler/taskscheduler.py +39 -52
- siliconcompiler/schema/__init__.py +3 -3
- siliconcompiler/schema/baseschema.py +256 -11
- siliconcompiler/schema/editableschema.py +4 -0
- siliconcompiler/schema/journal.py +210 -0
- siliconcompiler/schema/namedschema.py +31 -2
- siliconcompiler/schema/parameter.py +14 -1
- siliconcompiler/schema/parametervalue.py +1 -34
- siliconcompiler/schema/schema_cfg.py +211 -350
- siliconcompiler/tool.py +139 -37
- siliconcompiler/tools/_common/__init__.py +14 -11
- siliconcompiler/tools/builtin/concatenate.py +2 -2
- siliconcompiler/tools/builtin/verify.py +1 -2
- siliconcompiler/tools/openroad/scripts/common/procs.tcl +27 -25
- siliconcompiler/tools/slang/__init__.py +3 -2
- siliconcompiler/tools/vpr/route.py +69 -0
- siliconcompiler/tools/yosys/sc_synth_asic.tcl +0 -4
- siliconcompiler/toolscripts/_tools.json +13 -8
- siliconcompiler/toolscripts/ubuntu22/install-klayout.sh +4 -0
- siliconcompiler/toolscripts/ubuntu24/install-klayout.sh +4 -0
- siliconcompiler/utils/__init__.py +2 -23
- siliconcompiler/utils/flowgraph.py +5 -5
- siliconcompiler/utils/logging.py +2 -1
- {siliconcompiler-0.33.1.dist-info → siliconcompiler-0.34.0.dist-info}/METADATA +8 -6
- {siliconcompiler-0.33.1.dist-info → siliconcompiler-0.34.0.dist-info}/RECORD +57 -52
- {siliconcompiler-0.33.1.dist-info → siliconcompiler-0.34.0.dist-info}/WHEEL +1 -1
- siliconcompiler/scheduler/docker_runner.py +0 -254
- siliconcompiler/schema/journalingschema.py +0 -238
- {siliconcompiler-0.33.1.dist-info → siliconcompiler-0.34.0.dist-info}/entry_points.txt +0 -0
- {siliconcompiler-0.33.1.dist-info → siliconcompiler-0.34.0.dist-info}/licenses/LICENSE +0 -0
- {siliconcompiler-0.33.1.dist-info → siliconcompiler-0.34.0.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
import os
|
|
2
|
+
|
|
3
|
+
import os.path
|
|
4
|
+
|
|
5
|
+
from siliconcompiler.schema import BaseSchema
|
|
6
|
+
from siliconcompiler.schema import EditableSchema, Parameter, Scope
|
|
7
|
+
from siliconcompiler.schema.utils import trim
|
|
8
|
+
from siliconcompiler.package import Resolver
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class PackageSchema(BaseSchema):
|
|
12
|
+
def __init__(self):
|
|
13
|
+
super().__init__()
|
|
14
|
+
|
|
15
|
+
schema_package(self)
|
|
16
|
+
|
|
17
|
+
self.__cache = {}
|
|
18
|
+
|
|
19
|
+
def register(self, name, path, ref=None, clobber=True):
|
|
20
|
+
"""
|
|
21
|
+
Registers a package by its name with the source path and reference
|
|
22
|
+
|
|
23
|
+
Registered package sources are stored in the package section of the schema.
|
|
24
|
+
|
|
25
|
+
Args:
|
|
26
|
+
name (str): Package name
|
|
27
|
+
path (str): Path to the sources, can be file, git url, archive url
|
|
28
|
+
ref (str): Reference of the sources, can be commitid, branch name, tag
|
|
29
|
+
clobber (bool): Overwrite existing
|
|
30
|
+
|
|
31
|
+
Examples:
|
|
32
|
+
>>> schema.register('siliconcompiler_data',
|
|
33
|
+
'git+https://github.com/siliconcompiler/siliconcompiler',
|
|
34
|
+
'cd328131bafd361787f9137a6ffed999d64c8c30')
|
|
35
|
+
"""
|
|
36
|
+
|
|
37
|
+
# If this is a file, get the directory for this
|
|
38
|
+
if os.path.isfile(path):
|
|
39
|
+
path = os.path.dirname(os.path.abspath(path))
|
|
40
|
+
elif os.path.isdir(path):
|
|
41
|
+
path = os.path.abspath(path)
|
|
42
|
+
|
|
43
|
+
success = False
|
|
44
|
+
if self.set('source', name, 'path', path, clobber=clobber):
|
|
45
|
+
success = True
|
|
46
|
+
if success and ref:
|
|
47
|
+
success = False
|
|
48
|
+
if self.set('source', name, 'ref', ref, clobber=clobber):
|
|
49
|
+
success = True
|
|
50
|
+
return success
|
|
51
|
+
|
|
52
|
+
def get_resolver(self, package):
|
|
53
|
+
'''
|
|
54
|
+
Returns a specific resolver
|
|
55
|
+
|
|
56
|
+
Args:
|
|
57
|
+
package (str): name of package
|
|
58
|
+
'''
|
|
59
|
+
resolver_cls = Resolver.find_resolver(self.get("source", package, "path"))
|
|
60
|
+
resolver = resolver_cls(package, self._parent(root=True),
|
|
61
|
+
self.get("source", package, "path"),
|
|
62
|
+
self.get("source", package, "ref"))
|
|
63
|
+
resolver.set_cache(self.__cache)
|
|
64
|
+
return resolver
|
|
65
|
+
|
|
66
|
+
def get_resolvers(self):
|
|
67
|
+
'''
|
|
68
|
+
Returns a dictionary of packages with their resolver method.
|
|
69
|
+
'''
|
|
70
|
+
resolvers = {}
|
|
71
|
+
for package in self.getkeys("source"):
|
|
72
|
+
resolvers[package] = self.get_resolver(package).get_path
|
|
73
|
+
|
|
74
|
+
return resolvers
|
|
75
|
+
|
|
76
|
+
def _set_cache(self, package, path):
|
|
77
|
+
self.__cache[package] = path
|
|
78
|
+
|
|
79
|
+
def get_path_cache(self):
|
|
80
|
+
return self.__cache.copy()
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
############################################
|
|
84
|
+
# Package information
|
|
85
|
+
############################################
|
|
86
|
+
def schema_package(schema):
|
|
87
|
+
schema = EditableSchema(schema)
|
|
88
|
+
|
|
89
|
+
schema.insert(
|
|
90
|
+
'version',
|
|
91
|
+
Parameter(
|
|
92
|
+
'str',
|
|
93
|
+
scope=Scope.GLOBAL,
|
|
94
|
+
shorthelp="Package: version",
|
|
95
|
+
switch="-package_version <str>",
|
|
96
|
+
example=[
|
|
97
|
+
"cli: -package_version 1.0",
|
|
98
|
+
"api: chip.set('package', 'version', '1.0')"],
|
|
99
|
+
help=trim("""Package version. Can be a branch, tag, commit hash,
|
|
100
|
+
or a semver compatible version.""")))
|
|
101
|
+
|
|
102
|
+
schema.insert(
|
|
103
|
+
'description',
|
|
104
|
+
Parameter(
|
|
105
|
+
'str',
|
|
106
|
+
scope=Scope.GLOBAL,
|
|
107
|
+
shorthelp="Package: description",
|
|
108
|
+
switch="-package_description <str>",
|
|
109
|
+
example=[
|
|
110
|
+
"cli: -package_description 'Yet another cpu'",
|
|
111
|
+
"api: chip.set('package', 'description', 'Yet another cpu')"],
|
|
112
|
+
help=trim("""Package short one line description for package
|
|
113
|
+
managers and summary reports.""")))
|
|
114
|
+
|
|
115
|
+
schema.insert(
|
|
116
|
+
'keyword',
|
|
117
|
+
Parameter(
|
|
118
|
+
'str',
|
|
119
|
+
scope=Scope.GLOBAL,
|
|
120
|
+
shorthelp="Package: keyword",
|
|
121
|
+
switch="-package_keyword <str>",
|
|
122
|
+
example=[
|
|
123
|
+
"cli: -package_keyword cpu",
|
|
124
|
+
"api: chip.set('package', 'keyword', 'cpu')"],
|
|
125
|
+
help=trim("""Package keyword(s) used to characterize package.""")))
|
|
126
|
+
schema.insert(
|
|
127
|
+
'doc', 'homepage',
|
|
128
|
+
Parameter(
|
|
129
|
+
'str',
|
|
130
|
+
scope=Scope.GLOBAL,
|
|
131
|
+
shorthelp="Package: documentation homepage",
|
|
132
|
+
switch="-package_doc_homepage <str>",
|
|
133
|
+
example=[
|
|
134
|
+
"cli: -package_doc_homepage index.html",
|
|
135
|
+
"api: chip.set('package', 'doc', 'homepage', 'index.html')"],
|
|
136
|
+
help=trim("""
|
|
137
|
+
Package documentation homepage. Filepath to design docs homepage.
|
|
138
|
+
Complex designs can can include a long non standard list of
|
|
139
|
+
documents dependent. A single html entry point can be used to
|
|
140
|
+
present an organized documentation dashboard to the designer.""")))
|
|
141
|
+
|
|
142
|
+
doctypes = ['datasheet',
|
|
143
|
+
'reference',
|
|
144
|
+
'userguide',
|
|
145
|
+
'quickstart',
|
|
146
|
+
'releasenotes',
|
|
147
|
+
'testplan',
|
|
148
|
+
'signoff',
|
|
149
|
+
'tutorial']
|
|
150
|
+
|
|
151
|
+
for item in doctypes:
|
|
152
|
+
schema.insert(
|
|
153
|
+
'doc', item,
|
|
154
|
+
Parameter(
|
|
155
|
+
'[file]',
|
|
156
|
+
scope=Scope.GLOBAL,
|
|
157
|
+
shorthelp=f"Package: {item} document",
|
|
158
|
+
switch=f"-package_doc_{item} <file>",
|
|
159
|
+
example=[
|
|
160
|
+
f"cli: -package_doc_{item} {item}.pdf",
|
|
161
|
+
f"api: chip.set('package', 'doc', '{item}', '{item}.pdf')"],
|
|
162
|
+
help=trim(f"""Package list of {item} documents.""")))
|
|
163
|
+
|
|
164
|
+
schema.insert(
|
|
165
|
+
'license',
|
|
166
|
+
Parameter(
|
|
167
|
+
'[str]',
|
|
168
|
+
scope=Scope.GLOBAL,
|
|
169
|
+
shorthelp="Package: license identifiers",
|
|
170
|
+
switch="-package_license <str>",
|
|
171
|
+
example=[
|
|
172
|
+
"cli: -package_license 'Apache-2.0'",
|
|
173
|
+
"api: chip.set('package', 'license', 'Apache-2.0')"],
|
|
174
|
+
help=trim("""Package list of SPDX license identifiers.""")))
|
|
175
|
+
|
|
176
|
+
schema.insert(
|
|
177
|
+
'licensefile',
|
|
178
|
+
Parameter(
|
|
179
|
+
'[file]',
|
|
180
|
+
scope=Scope.GLOBAL,
|
|
181
|
+
shorthelp="Package: license files",
|
|
182
|
+
switch="-package_licensefile <file>",
|
|
183
|
+
example=[
|
|
184
|
+
"cli: -package_licensefile './LICENSE'",
|
|
185
|
+
"api: chip.set('package', 'licensefile', './LICENSE')"],
|
|
186
|
+
help=trim("""Package list of license files for to be
|
|
187
|
+
applied in cases when a SPDX identifier is not available.
|
|
188
|
+
(eg. proprietary licenses).""")))
|
|
189
|
+
|
|
190
|
+
schema.insert(
|
|
191
|
+
'organization',
|
|
192
|
+
Parameter(
|
|
193
|
+
'[str]',
|
|
194
|
+
scope=Scope.GLOBAL,
|
|
195
|
+
shorthelp="Package: sponsoring organization",
|
|
196
|
+
switch="-package_organization <str>",
|
|
197
|
+
example=[
|
|
198
|
+
"cli: -package_organization 'humanity'",
|
|
199
|
+
"api: chip.set('package', 'organization', 'humanity')"],
|
|
200
|
+
help=trim("""Package sponsoring organization. The field can be left
|
|
201
|
+
blank if not applicable.""")))
|
|
202
|
+
|
|
203
|
+
record = ['name',
|
|
204
|
+
'email',
|
|
205
|
+
'username',
|
|
206
|
+
'location',
|
|
207
|
+
'organization',
|
|
208
|
+
'publickey']
|
|
209
|
+
|
|
210
|
+
for item in record:
|
|
211
|
+
schema.insert(
|
|
212
|
+
'author', 'default', item,
|
|
213
|
+
Parameter(
|
|
214
|
+
'str',
|
|
215
|
+
scope=Scope.GLOBAL,
|
|
216
|
+
shorthelp=f"Package: author {item}",
|
|
217
|
+
switch=f"-package_author_{item} 'userid <str>'",
|
|
218
|
+
example=[
|
|
219
|
+
f"cli: -package_author_{item} 'wiley wiley@acme.com'",
|
|
220
|
+
f"api: chip.set('package', 'author', 'wiley', '{item}', 'wiley@acme.com')"],
|
|
221
|
+
help=trim(f"""Package author {item} provided with full name as key and
|
|
222
|
+
{item} as value.""")))
|
|
223
|
+
|
|
224
|
+
schema.insert(
|
|
225
|
+
'source', 'default', 'path',
|
|
226
|
+
Parameter(
|
|
227
|
+
'str',
|
|
228
|
+
scope=Scope.GLOBAL,
|
|
229
|
+
shorthelp="Package: data source path",
|
|
230
|
+
switch="-package_source_path 'source <str>'",
|
|
231
|
+
example=[
|
|
232
|
+
"cli: -package_source_path "
|
|
233
|
+
"'freepdk45_data ssh://git@github.com/siliconcompiler/freepdk45/'",
|
|
234
|
+
"api: chip.set('package', 'source', "
|
|
235
|
+
"'freepdk45_data', 'path', 'ssh://git@github.com/siliconcompiler/freepdk45/')"],
|
|
236
|
+
help=trim("""
|
|
237
|
+
Package data source path, allowed paths:
|
|
238
|
+
|
|
239
|
+
* /path/on/network/drive
|
|
240
|
+
* file:///path/on/network/drive
|
|
241
|
+
* git+https://github.com/xyz/xyz
|
|
242
|
+
* git://github.com/xyz/xyz
|
|
243
|
+
* git+ssh://github.com/xyz/xyz
|
|
244
|
+
* ssh://github.com/xyz/xyz
|
|
245
|
+
* https://github.com/xyz/xyz/archive
|
|
246
|
+
* https://zeroasic.com/xyz.tar.gz
|
|
247
|
+
* python://siliconcompiler
|
|
248
|
+
""")))
|
|
249
|
+
|
|
250
|
+
schema.insert(
|
|
251
|
+
'source', 'default', 'ref',
|
|
252
|
+
Parameter(
|
|
253
|
+
'str',
|
|
254
|
+
scope=Scope.GLOBAL,
|
|
255
|
+
shorthelp="Package: data source reference",
|
|
256
|
+
switch="-package_source_ref 'source <str>'",
|
|
257
|
+
example=[
|
|
258
|
+
"cli: -package_source_ref 'freepdk45_data 07ec4aa'",
|
|
259
|
+
"api: chip.set('package', 'source', 'freepdk45_data', 'ref', '07ec4aa')"],
|
|
260
|
+
help=trim("""Package data source reference""")))
|
siliconcompiler/pdk.py
CHANGED
|
@@ -4,8 +4,8 @@ from siliconcompiler.schema.utils import trim
|
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
class PDKSchema(NamedSchema, PackageSchema):
|
|
7
|
-
def __init__(self, name
|
|
8
|
-
NamedSchema.__init__(self, name
|
|
7
|
+
def __init__(self, name, package=None):
|
|
8
|
+
NamedSchema.__init__(self, name)
|
|
9
9
|
PackageSchema.__init__(self, package=package)
|
|
10
10
|
|
|
11
11
|
schema_pdk(self)
|
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
|
|
@@ -275,6 +287,44 @@ class RecordSchema(BaseSchema):
|
|
|
275
287
|
record_time+"+0000",
|
|
276
288
|
RecordSchema.__TIMEFORMAT+"%z").timestamp()
|
|
277
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
|
+
|
|
278
328
|
def record_tool(self, step, index, info, type):
|
|
279
329
|
'''
|
|
280
330
|
Record information about the tool used during this record.
|
|
@@ -320,11 +370,13 @@ def schema_record(schema):
|
|
|
320
370
|
'x86_64',
|
|
321
371
|
'(x86_64, rv64imafdc)'],
|
|
322
372
|
'starttime': ['start time',
|
|
323
|
-
'\"2021-09-06 12:20:20\"',
|
|
324
|
-
'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'],
|
|
325
376
|
'endtime': ['end time',
|
|
326
|
-
'\"2021-09-06 12:20:20\"',
|
|
327
|
-
'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'],
|
|
328
380
|
'region': ['cloud region',
|
|
329
381
|
'\"US Gov Boston\"',
|
|
330
382
|
"""Recommended naming methodology:
|
siliconcompiler/remote/client.py
CHANGED
|
@@ -10,18 +10,32 @@ 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.remote import JobStatus
|
|
18
|
+
from siliconcompiler.remote import JobStatus, NodeStatus
|
|
17
19
|
from siliconcompiler.report.dashboard import DashboardType
|
|
18
20
|
from siliconcompiler.flowgraph import RuntimeFlowgraph
|
|
19
|
-
from siliconcompiler.
|
|
21
|
+
from siliconcompiler.scheduler.scheduler import Scheduler
|
|
22
|
+
from siliconcompiler.schema import Journal
|
|
20
23
|
|
|
21
24
|
# Step name to use while logging
|
|
22
25
|
remote_step_name = 'remote'
|
|
23
26
|
|
|
24
27
|
|
|
28
|
+
class ClientScheduler(Scheduler):
|
|
29
|
+
def run_core(self):
|
|
30
|
+
Client(self._Scheduler__chip).run()
|
|
31
|
+
|
|
32
|
+
def configure_nodes(self):
|
|
33
|
+
return
|
|
34
|
+
|
|
35
|
+
def check_manifest(self):
|
|
36
|
+
return True
|
|
37
|
+
|
|
38
|
+
|
|
25
39
|
class Client():
|
|
26
40
|
# Step name to use while logging
|
|
27
41
|
STEP_NAME = "remote"
|
|
@@ -310,19 +324,29 @@ service, provided by SiliconCompiler, is not intended to process proprietary IP.
|
|
|
310
324
|
try:
|
|
311
325
|
# Decode response JSON, if possible.
|
|
312
326
|
job_info = json.loads(info['message'])
|
|
313
|
-
|
|
314
|
-
|
|
327
|
+
if "null" in job_info:
|
|
328
|
+
job_info[None] = job_info["null"]
|
|
329
|
+
del job_info["null"]
|
|
330
|
+
except json.JSONDecodeError:
|
|
331
|
+
self.__logger.warning(f"Job is still running: {info['message']}")
|
|
315
332
|
return completed, starttimes, True
|
|
316
333
|
|
|
317
334
|
nodes_to_log = {}
|
|
318
335
|
for node, node_info in job_info.items():
|
|
319
336
|
status = node_info['status']
|
|
320
|
-
|
|
337
|
+
|
|
338
|
+
if status == NodeStatus.UPLOADED:
|
|
339
|
+
status = SCNodeStatus.PENDING
|
|
321
340
|
|
|
322
341
|
if SCNodeStatus.is_done(status):
|
|
323
342
|
# collect completed
|
|
324
343
|
completed.append(node)
|
|
325
344
|
|
|
345
|
+
if not node:
|
|
346
|
+
continue
|
|
347
|
+
|
|
348
|
+
nodes_to_log.setdefault(status, []).append((node, node_info))
|
|
349
|
+
|
|
326
350
|
if self.__node_information and node in self.__node_information:
|
|
327
351
|
self.__chip.set('record', 'status', status,
|
|
328
352
|
step=self.__node_information[node]["step"],
|
|
@@ -580,6 +604,22 @@ service, provided by SiliconCompiler, is not intended to process proprietary IP.
|
|
|
580
604
|
raise SiliconCompilerError('Job canceled by user keyboard interrupt')
|
|
581
605
|
|
|
582
606
|
def __import_run_manifests(self, starttimes):
|
|
607
|
+
if not self.__setup_information_loaded:
|
|
608
|
+
if self.__setup_information_fetched:
|
|
609
|
+
manifest = os.path.join(self.__chip.getworkdir(), f'{self.__chip.design}.pkg.json')
|
|
610
|
+
if os.path.exists(manifest):
|
|
611
|
+
try:
|
|
612
|
+
Journal.replay_file(self.__chip.schema, manifest)
|
|
613
|
+
self.__setup_information_loaded = True
|
|
614
|
+
changed = True
|
|
615
|
+
except: # noqa E722
|
|
616
|
+
# Import may fail if file is still getting written
|
|
617
|
+
pass
|
|
618
|
+
|
|
619
|
+
if not self.__setup_information_loaded:
|
|
620
|
+
# Dont do anything until this has been loaded
|
|
621
|
+
return
|
|
622
|
+
|
|
583
623
|
changed = False
|
|
584
624
|
for _, node_info in self.__node_information.items():
|
|
585
625
|
if node_info["imported"]:
|
|
@@ -591,7 +631,7 @@ service, provided by SiliconCompiler, is not intended to process proprietary IP.
|
|
|
591
631
|
f'{self.__chip.design}.pkg.json')
|
|
592
632
|
if os.path.exists(manifest):
|
|
593
633
|
try:
|
|
594
|
-
|
|
634
|
+
Journal.replay_file(self.__chip.schema, manifest)
|
|
595
635
|
node_info["imported"] = True
|
|
596
636
|
changed = True
|
|
597
637
|
except: # noqa E722
|
|
@@ -599,7 +639,7 @@ service, provided by SiliconCompiler, is not intended to process proprietary IP.
|
|
|
599
639
|
pass
|
|
600
640
|
elif self.__chip.get('record', 'status',
|
|
601
641
|
step=node_info["step"], index=node_info["index"]) \
|
|
602
|
-
==
|
|
642
|
+
== SCNodeStatus.SKIPPED:
|
|
603
643
|
node_info["imported"] = True
|
|
604
644
|
changed = True
|
|
605
645
|
|
|
@@ -618,6 +658,9 @@ service, provided by SiliconCompiler, is not intended to process proprietary IP.
|
|
|
618
658
|
check_info = self.__check()
|
|
619
659
|
self.__check_interval = check_info['progress_interval']
|
|
620
660
|
|
|
661
|
+
self.__setup_information_fetched = False
|
|
662
|
+
self.__setup_information_loaded = False
|
|
663
|
+
|
|
621
664
|
self.__node_information = {}
|
|
622
665
|
runtime = RuntimeFlowgraph(
|
|
623
666
|
self.__chip.schema.get("flowgraph", self.__chip.get('option', 'flow'), field='schema'),
|
|
@@ -666,6 +709,11 @@ service, provided by SiliconCompiler, is not intended to process proprietary IP.
|
|
|
666
709
|
# Update dashboard if active
|
|
667
710
|
self.__chip._dash.update_manifest({"starttimes": starttimes})
|
|
668
711
|
|
|
712
|
+
if None in completed:
|
|
713
|
+
completed.remove(None)
|
|
714
|
+
if not self.__setup_information_fetched:
|
|
715
|
+
self.__schedule_fetch_result(None)
|
|
716
|
+
|
|
669
717
|
nodes_to_fetch = []
|
|
670
718
|
for node in completed:
|
|
671
719
|
if not self.__node_information[node]["fetched"]:
|
|
@@ -681,7 +729,6 @@ service, provided by SiliconCompiler, is not intended to process proprietary IP.
|
|
|
681
729
|
for node, node_info in self.__node_information.items():
|
|
682
730
|
if not node_info["fetched"]:
|
|
683
731
|
self.__schedule_fetch_result(node)
|
|
684
|
-
self.__schedule_fetch_result(node)
|
|
685
732
|
|
|
686
733
|
self._finalize_loop()
|
|
687
734
|
|
|
@@ -700,11 +747,12 @@ service, provided by SiliconCompiler, is not intended to process proprietary IP.
|
|
|
700
747
|
self.__import_run_manifests({})
|
|
701
748
|
|
|
702
749
|
def __schedule_fetch_result(self, node):
|
|
703
|
-
|
|
750
|
+
if node:
|
|
751
|
+
self.__node_information[node]["fetched"] = True
|
|
752
|
+
self.__logger.info(f' {node}')
|
|
753
|
+
else:
|
|
754
|
+
self.__setup_information_fetched = True
|
|
704
755
|
self.__download_pool.apply_async(Client._fetch_result, (self, node))
|
|
705
|
-
if node is None:
|
|
706
|
-
node = 'final result'
|
|
707
|
-
self.__logger.info(f' {node}')
|
|
708
756
|
|
|
709
757
|
def _fetch_result(self, node):
|
|
710
758
|
'''
|