siliconcompiler 0.32.0__py3-none-any.whl → 0.32.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.
Files changed (62) hide show
  1. siliconcompiler/_metadata.py +1 -1
  2. siliconcompiler/apps/_common.py +23 -6
  3. siliconcompiler/apps/sc_dashboard.py +7 -1
  4. siliconcompiler/apps/sc_install.py +13 -5
  5. siliconcompiler/apps/sc_remote.py +2 -1
  6. siliconcompiler/apps/sc_show.py +6 -0
  7. siliconcompiler/core.py +34 -16
  8. siliconcompiler/fpgas/lattice_ice40.py +6 -16
  9. siliconcompiler/package/__init__.py +11 -55
  10. siliconcompiler/package/github.py +124 -0
  11. siliconcompiler/package/https.py +6 -0
  12. siliconcompiler/report/dashboard/components/__init__.py +2 -1
  13. siliconcompiler/report/dashboard/components/flowgraph.py +3 -0
  14. siliconcompiler/report/dashboard/utils/__init__.py +5 -2
  15. siliconcompiler/report/utils.py +3 -0
  16. siliconcompiler/scheduler/__init__.py +37 -8
  17. siliconcompiler/scheduler/docker_runner.py +2 -1
  18. siliconcompiler/schema/schema_obj.py +3 -2
  19. siliconcompiler/schema/utils.py +0 -3
  20. siliconcompiler/sphinx_ext/dynamicgen.py +11 -11
  21. siliconcompiler/targets/fpgaflow_demo.py +0 -2
  22. siliconcompiler/templates/tcl/manifest.tcl.j2 +4 -120
  23. siliconcompiler/tools/_common/tcl/sc_schema_access.tcl +126 -0
  24. siliconcompiler/tools/openroad/_apr.py +3 -0
  25. siliconcompiler/tools/openroad/scripts/apr/sc_repair_timing.tcl +53 -7
  26. siliconcompiler/tools/openroad/scripts/common/procs.tcl +19 -1
  27. siliconcompiler/tools/openroad/scripts/common/reports.tcl +16 -5
  28. siliconcompiler/tools/slang/__init__.py +7 -8
  29. siliconcompiler/tools/sv2v/sv2v.py +4 -1
  30. siliconcompiler/tools/yosys/__init__.py +4 -36
  31. siliconcompiler/tools/yosys/lec.py +3 -4
  32. siliconcompiler/tools/yosys/{syn_asic.tcl → sc_synth_asic.tcl} +79 -0
  33. siliconcompiler/tools/yosys/{syn_fpga.tcl → sc_synth_fpga.tcl} +78 -0
  34. siliconcompiler/tools/yosys/syn_asic.py +26 -10
  35. siliconcompiler/tools/yosys/syn_fpga.py +23 -16
  36. siliconcompiler/toolscripts/_tools.json +18 -9
  37. siliconcompiler/toolscripts/rhel9/install-gtkwave.sh +1 -1
  38. siliconcompiler/toolscripts/rhel9/install-vpr.sh +29 -0
  39. siliconcompiler/toolscripts/rhel9/install-yosys-parmys.sh +59 -0
  40. siliconcompiler/toolscripts/ubuntu20/install-yosys-parmys.sh +59 -0
  41. siliconcompiler/toolscripts/ubuntu22/install-bluespec.sh +25 -2
  42. siliconcompiler/toolscripts/ubuntu22/install-ghdl.sh +2 -2
  43. siliconcompiler/toolscripts/ubuntu22/install-yosys-parmys.sh +59 -0
  44. siliconcompiler/toolscripts/ubuntu24/install-ghdl.sh +2 -2
  45. siliconcompiler/toolscripts/ubuntu24/install-icarus.sh +2 -1
  46. siliconcompiler/toolscripts/ubuntu24/install-netgen.sh +1 -1
  47. siliconcompiler/toolscripts/ubuntu24/install-yosys-parmys.sh +59 -0
  48. siliconcompiler/utils/__init__.py +9 -15
  49. siliconcompiler/utils/logging.py +1 -1
  50. {siliconcompiler-0.32.0.dist-info → siliconcompiler-0.32.2.dist-info}/METADATA +12 -9
  51. {siliconcompiler-0.32.0.dist-info → siliconcompiler-0.32.2.dist-info}/RECORD +55 -55
  52. {siliconcompiler-0.32.0.dist-info → siliconcompiler-0.32.2.dist-info}/WHEEL +1 -1
  53. {siliconcompiler-0.32.0.dist-info → siliconcompiler-0.32.2.dist-info}/entry_points.txt +1 -0
  54. siliconcompiler/fpgas/vpr_example.py +0 -116
  55. siliconcompiler/tools/yosys/sc_syn.tcl +0 -87
  56. siliconcompiler/toolscripts/rhel8/install-ghdl.sh +0 -25
  57. siliconcompiler/toolscripts/rhel8/install-yosys-moosic.sh +0 -17
  58. siliconcompiler/toolscripts/rhel8/install-yosys-slang.sh +0 -22
  59. siliconcompiler/toolscripts/rhel8/install-yosys.sh +0 -23
  60. siliconcompiler/toolscripts/ubuntu20/install-yosys-slang.sh +0 -22
  61. {siliconcompiler-0.32.0.dist-info → siliconcompiler-0.32.2.dist-info/licenses}/LICENSE +0 -0
  62. {siliconcompiler-0.32.0.dist-info → siliconcompiler-0.32.2.dist-info}/top_level.txt +0 -0
@@ -1,5 +1,5 @@
1
1
  # Version number following semver standard.
2
- version = '0.32.0'
2
+ version = '0.32.2'
3
3
 
4
4
  # Default server address for remote runs, if unspecified.
5
5
  default_server = 'https://server.siliconcompiler.com'
@@ -98,11 +98,28 @@ def pick_manifest(chip, src_file=None):
98
98
  if chip.get('option', 'jobname') not in all_manifests[chip.design]:
99
99
  jobname = list(all_manifests[chip.design].keys())[0]
100
100
 
101
+ step, index = chip.get('arg', 'step'), chip.get('arg', 'index')
102
+ if step and not index:
103
+ all_nodes = list(all_manifests[chip.design][jobname].keys())
104
+ try:
105
+ all_nodes.remove((None, None))
106
+ except ValueError:
107
+ pass
108
+ for found_step, found_index in sorted(all_nodes):
109
+ if found_step == step:
110
+ index = found_index
111
+ if index is None:
112
+ index = '0'
113
+ if step and index:
114
+ if (step, index) in all_manifests[chip.design][jobname]:
115
+ return all_manifests[chip.design][jobname][(step, index)]
116
+ else:
117
+ chip.logger.error(f'{step}{index} is not a valid node.')
118
+ return None
119
+
101
120
  if (None, None) in all_manifests[chip.design][jobname]:
102
- manifest = all_manifests[chip.design][jobname][None, None]
103
- else:
104
- # pick newest manifest
105
- manifest = list(sorted(all_manifests[chip.design][jobname].values(),
106
- key=lambda file: os.stat(file).st_ctime))[-1]
121
+ return all_manifests[chip.design][jobname][None, None]
107
122
 
108
- return manifest
123
+ # pick newest manifest
124
+ return list(sorted(all_manifests[chip.design][jobname].values(),
125
+ key=lambda file: os.stat(file).st_ctime))[-1]
@@ -63,6 +63,8 @@ To include another chip object to compare to:
63
63
  if manifest:
64
64
  chip.logger.info(f'Loading manifest: {manifest}')
65
65
  chip.read_manifest(manifest)
66
+ else:
67
+ manifest = chip.get('option', 'cfg')
66
68
 
67
69
  # Error checking
68
70
  design = chip.get('design')
@@ -70,6 +72,10 @@ To include another chip object to compare to:
70
72
  chip.logger.error('Design not loaded')
71
73
  return 1
72
74
 
75
+ if not manifest:
76
+ chip.logger.error('Unable to determine job manifest')
77
+ return 2
78
+
73
79
  graph_chips = []
74
80
  if switches['graph_cfg']:
75
81
  for i, name_and_file_path in enumerate(switches['graph_cfg']):
@@ -86,7 +92,7 @@ To include another chip object to compare to:
86
92
  raise ValueError(('graph_cfg accepts a max of 2 values, you supplied'
87
93
  f' {args} in "-graph_cfg {name_and_file_path}"'))
88
94
  if not os.path.isfile(file_path):
89
- raise ValueError(f'not a valid file path : {file_path}')
95
+ raise ValueError(f'not a valid file path: {file_path}')
90
96
  graph_chip = siliconcompiler.core.Chip(design='')
91
97
  graph_chip.read_manifest(file_path)
92
98
  graph_chips.append({
@@ -139,8 +139,8 @@ def _get_tools_list():
139
139
 
140
140
  def _recommended_tool_groups(tools):
141
141
  groups = {
142
- "asic": {"surelog", "sv2v", "yosys", "openroad", "klayout"},
143
- "fpga": {"surelog", "sv2v", "yosys", "vpr"},
142
+ "asic": {"sv2v", "yosys", "openroad", "klayout"},
143
+ "fpga": {"sv2v", "yosys", "vpr"},
144
144
  "digital-simulation": {"verilator", "icarus", "gtkwave"},
145
145
  "analog-simulation": {"xyce"}
146
146
  }
@@ -162,7 +162,13 @@ class HelpFormatter(argparse.ArgumentDefaultsHelpFormatter, argparse.RawDescript
162
162
 
163
163
  def main():
164
164
  progname = "sc-install"
165
- description = """
165
+
166
+ tools = _get_tools_list()
167
+ group_desc = "\n".join(
168
+ [f" {grp}: {', '.join(grp_tools)}"
169
+ for grp, grp_tools in _recommended_tool_groups(tools).items()])
170
+
171
+ description = f"""
166
172
  -----------------------------------------------------------
167
173
  SC app install supported tools.
168
174
 
@@ -187,14 +193,16 @@ To show the install script:
187
193
  To system debugging information (this should only be used to debug):
188
194
  sc-install -debug_machine
189
195
  -----------------------------------------------------------
196
+ Tool groups:
197
+ {group_desc}
198
+ -----------------------------------------------------------
190
199
  """
200
+
191
201
  parser = argparse.ArgumentParser(
192
202
  prog=progname,
193
203
  description=description,
194
204
  formatter_class=HelpFormatter)
195
205
 
196
- tools = _get_tools_list()
197
-
198
206
  if _get_os_name() is None:
199
207
  print("Unsupported operating system", file=sys.stderr)
200
208
  print_machine_info()
@@ -97,8 +97,9 @@ To delete a job, use:
97
97
  chip.logger.error(f'Error: {", ".join(["-"+e for e in exclusive])} are mutually exclusive')
98
98
  return 1
99
99
  chip_cfg = chip.get('option', 'cfg')
100
- if chip_cfg and not any([args[arg] for arg in cfg_only]):
100
+ if not chip_cfg and any([args[arg] for arg in cfg_only]):
101
101
  chip.logger.error(f'Error: -cfg is required for {", ".join(["-"+e for e in cfg_only])}')
102
+ return 2
102
103
  if any([args[arg] for arg in cfg_only]) and args['server']:
103
104
  chip.logger.error('Error: -server cannot be specified with '
104
105
  f'{", ".join(["-"+e for e in cfg_only])}')
@@ -111,6 +111,8 @@ def main():
111
111
  if manifest:
112
112
  chip.logger.info(f'Loading manifest: {manifest}')
113
113
  chip.read_manifest(manifest)
114
+ else:
115
+ manifest = chip.get('option', 'cfg')
114
116
 
115
117
  # Error checking
116
118
  design = chip.get('design')
@@ -120,6 +122,10 @@ def main():
120
122
  '-cfg, -design, and/or inputs.')
121
123
  return 1
122
124
 
125
+ if not manifest:
126
+ chip.logger.error('Unable to determine job manifest')
127
+ return 2
128
+
123
129
  # Read in file
124
130
  if filename:
125
131
  chip.logger.info(f"Displaying {filename}")
siliconcompiler/core.py CHANGED
@@ -203,13 +203,11 @@ class Chip:
203
203
 
204
204
  def _add_file_logger(self, filename):
205
205
  # Add a file handler for logging
206
- logformat = self.logger.handlers[0].formatter
207
-
208
206
  file_handler = logging.FileHandler(filename)
209
- file_handler.setFormatter(logformat)
210
-
211
207
  self.logger.addHandler(file_handler)
212
208
 
209
+ self._init_logger_formats()
210
+
213
211
  return file_handler
214
212
 
215
213
  ###########################################################################
@@ -227,13 +225,35 @@ class Chip:
227
225
  else:
228
226
  in_run = False
229
227
 
228
+ # Save in run flag
229
+ self.logger._in_run = in_run
230
+ self.logger._in_step = step
231
+ self.logger._in_index = index
232
+
233
+ self.logger.setLevel(schema_utils.translate_loglevel(loglevel))
234
+
235
+ if not self.logger.hasHandlers():
236
+ stream_handler = logging.StreamHandler(stream=sys.stdout)
237
+ # Save console handler
238
+ self.logger._console = stream_handler
239
+ self.logger.addHandler(stream_handler)
240
+
241
+ self.logger._support_color = ColorStreamFormatter.supports_color(stream_handler)
242
+
243
+ self._init_logger_formats(loglevel=loglevel)
244
+
245
+ def _init_logger_formats(self, loglevel=None):
246
+ if not loglevel:
247
+ self.schema.get('option', 'loglevel',
248
+ step=self.logger._in_step, index=self.logger._in_index)
249
+
230
250
  level_format = '%(levelname)-7s'
231
251
  log_format = [level_format]
232
252
  if loglevel == 'debug':
233
253
  log_format.append('%(funcName)-10s')
234
254
  log_format.append('%(lineno)-4s')
235
255
 
236
- if in_run:
256
+ if self.logger._in_run:
237
257
  max_column_width = 20
238
258
  # Figure out how wide to make step and index fields
239
259
  max_step_len = 1
@@ -249,6 +269,9 @@ class Chip:
249
269
 
250
270
  jobname = self.get('option', 'jobname')
251
271
 
272
+ step = self.logger._in_step
273
+ index = self.logger._in_index
274
+
252
275
  if step is None:
253
276
  step = '-' * max(max_step_len // 4, 1)
254
277
  if index is None:
@@ -266,19 +289,13 @@ class Chip:
266
289
  log_format.append('%(message)s')
267
290
  stream_logformat = log_formatprefix + ' | '.join(log_format[1:])
268
291
 
269
- if not self.logger.hasHandlers():
270
- stream_handler = logging.StreamHandler(stream=sys.stdout)
271
- self.logger.addHandler(stream_handler)
272
-
273
- for handler in self.logger.handlers:
274
- if ColorStreamFormatter.supports_color(handler):
292
+ for handler in self.logger.handlers.copy():
293
+ if handler == self.logger._console and self.logger._support_color:
275
294
  formatter = ColorStreamFormatter(log_formatprefix, level_format, stream_logformat)
276
295
  else:
277
296
  formatter = LoggerFormatter(log_formatprefix, level_format, stream_logformat)
278
297
  handler.setFormatter(formatter)
279
298
 
280
- self.logger.setLevel(schema_utils.translate_loglevel(loglevel))
281
-
282
299
  ###########################################################################
283
300
  def _init_codecs(self):
284
301
  # Custom error handlers used to provide warnings when invalid characters
@@ -3239,9 +3256,10 @@ class Chip:
3239
3256
  if sc_step and sc_index:
3240
3257
  search_nodes.append((sc_step, sc_index))
3241
3258
  elif sc_step:
3242
- for check_step, check_index in nodes_to_execute(self, flow):
3243
- if sc_step == check_step:
3244
- search_nodes.append((check_step, check_index))
3259
+ if flow is not None:
3260
+ for check_step, check_index in nodes_to_execute(self, flow):
3261
+ if sc_step == check_step:
3262
+ search_nodes.append((check_step, check_index))
3245
3263
  else:
3246
3264
  if flow is not None:
3247
3265
  for nodes in _get_flowgraph_execution_order(self,
@@ -1,5 +1,4 @@
1
- import siliconcompiler
2
- from siliconcompiler.utils import register_sc_data_source
1
+ from siliconcompiler import Chip, FPGA
3
2
 
4
3
 
5
4
  ####################################################
@@ -13,22 +12,13 @@ def setup():
13
12
  yosys + nextpnr
14
13
  '''
15
14
 
16
- vendor = 'lattice'
17
-
18
- lut_size = '4'
19
-
20
15
  all_fpgas = []
21
16
 
22
- all_part_names = [
23
- "ice40up5k-sg48",
24
- ]
25
-
26
- for part_name in all_part_names:
27
- fpga = siliconcompiler.FPGA(part_name, package='siliconcompiler_data')
28
- register_sc_data_source(fpga)
17
+ for part_name in ("ice40up5k-sg48",):
18
+ fpga = FPGA(part_name)
29
19
 
30
- fpga.set('fpga', part_name, 'vendor', vendor)
31
- fpga.set('fpga', part_name, 'lutsize', lut_size)
20
+ fpga.set('fpga', part_name, 'vendor', 'lattice')
21
+ fpga.set('fpga', part_name, 'lutsize', 4)
32
22
 
33
23
  all_fpgas.append(fpga)
34
24
 
@@ -37,5 +27,5 @@ def setup():
37
27
 
38
28
  #########################
39
29
  if __name__ == "__main__":
40
- for fpga in setup(siliconcompiler.Chip('<fpga>')):
30
+ for fpga in setup(Chip('<fpga>')):
41
31
  fpga.write_manifest(f'{fpga.design}.json')
@@ -10,9 +10,6 @@ import functools
10
10
  import time
11
11
  from pathlib import Path
12
12
 
13
- from github import Github
14
- import github.Auth
15
-
16
13
  from siliconcompiler.utils import get_plugins
17
14
 
18
15
 
@@ -219,58 +216,6 @@ def register_python_data_source(chip,
219
216
  ref=ref)
220
217
 
221
218
 
222
- def register_private_github_data_source(chip,
223
- package_name,
224
- repository,
225
- release,
226
- artifact):
227
- gh = Github(auth=github.Auth.Token(__get_github_auth_token(package_name)))
228
- repo = gh.get_repo(repository)
229
-
230
- if not release:
231
- release = repo.get_latest_release().tag_name
232
-
233
- url = None
234
- for repo_release in repo.get_releases():
235
- if repo_release.tag_name == release:
236
- for asset in repo_release.assets:
237
- if asset.name == artifact:
238
- url = asset.url
239
-
240
- if not url:
241
- raise ValueError(f'Unable to find release asset: {repository}/{release}/{artifact}')
242
-
243
- chip.register_source(
244
- package_name,
245
- path=url,
246
- ref=release)
247
-
248
-
249
- def __get_github_auth_token(package_name):
250
- token_name = package_name.upper()
251
- for tok in ('#', '$', '&', '-', '=', '!', '/'):
252
- token_name = token_name.replace(tok, '')
253
-
254
- search_env = (
255
- f'GITHUB_{token_name}_TOKEN',
256
- 'GITHUB_TOKEN',
257
- 'GIT_TOKEN'
258
- )
259
-
260
- token = None
261
- for env in search_env:
262
- token = os.environ.get(env, None)
263
-
264
- if token:
265
- break
266
-
267
- if not token:
268
- raise ValueError('Unable to determine authorization token for GitHub, '
269
- f'please set one of the following environmental variables: {search_env}')
270
-
271
- return token
272
-
273
-
274
219
  @functools.lru_cache(maxsize=1)
275
220
  def __get_python_module_mapping():
276
221
  mapping = {}
@@ -298,3 +243,14 @@ def __get_python_module_mapping():
298
243
  mapping.setdefault(module, []).append(dist_name)
299
244
 
300
245
  return mapping
246
+
247
+
248
+ def register_private_github_data_source(chip,
249
+ package_name,
250
+ repository,
251
+ release,
252
+ artifact):
253
+ chip.register_source(
254
+ package_name,
255
+ path=f"github+private://{repository}/{release}/{artifact}",
256
+ ref=release)
@@ -0,0 +1,124 @@
1
+ import os
2
+ from fasteners import InterProcessLock
3
+ from github import Github, Auth
4
+ from github.GithubException import UnknownObjectException
5
+ from urllib.parse import urlparse
6
+ from siliconcompiler.package import get_download_cache_path
7
+ from siliconcompiler.package import aquire_data_lock, release_data_lock
8
+ from siliconcompiler.package.https import _http_resolver
9
+
10
+
11
+ def get_resolver(url):
12
+ if url.scheme in ("github",):
13
+ return github_any_resolver
14
+ if url.scheme in ("github+private",):
15
+ return github_private_resolver
16
+ return None
17
+
18
+
19
+ def github_any_resolver(chip, package, path, ref, url, fetch):
20
+ data_path, data_path_lock = get_download_cache_path(chip, package, ref)
21
+
22
+ if not fetch:
23
+ return data_path, False
24
+
25
+ # Acquire lock
26
+ data_lock = InterProcessLock(data_path_lock)
27
+ aquire_data_lock(data_path, data_lock)
28
+
29
+ if os.path.exists(data_path):
30
+ release_data_lock(data_lock)
31
+ return data_path, False
32
+
33
+ try:
34
+ return _github_resolver(chip, package, path, ref, url, data_lock)
35
+ except UnknownObjectException:
36
+ return github_private_resolver(chip, package, path, ref, url, fetch, data_lock=data_lock)
37
+
38
+
39
+ def github_private_resolver(chip, package, path, ref, url, fetch, data_lock=None):
40
+ data_path, data_path_lock = get_download_cache_path(chip, package, ref)
41
+
42
+ if not fetch:
43
+ return data_path, False
44
+
45
+ if not data_lock:
46
+ # Acquire lock
47
+ data_lock = InterProcessLock(data_path_lock)
48
+ aquire_data_lock(data_path, data_lock)
49
+
50
+ if os.path.exists(data_path):
51
+ release_data_lock(data_lock)
52
+ return data_path, False
53
+
54
+ gh = Github(auth=Auth.Token(__get_github_auth_token(package)))
55
+
56
+ return _github_resolver(chip, package, path, ref, url, data_lock, gh=gh)
57
+
58
+
59
+ def _github_resolver(chip, package, path, ref, url, data_lock, gh=None):
60
+ if not gh:
61
+ gh = Github()
62
+
63
+ url_parts = (url.netloc, *url.path.split("/")[1:])
64
+
65
+ if len(url_parts) != 4:
66
+ raise ValueError(
67
+ f"{path} is not in the proper form: <owner>/<repository>/<version>/<artifact>")
68
+
69
+ repository = "/".join(url_parts[0:2])
70
+ release = url_parts[2]
71
+ artifact = url_parts[3]
72
+
73
+ release_url = __get_release_url(gh, repository, release, artifact)
74
+
75
+ return _http_resolver(chip, package, release_url, ref, urlparse(release_url), data_lock)
76
+
77
+
78
+ def __get_release_url(gh, repository, release, artifact):
79
+ if artifact == f"{release}.zip":
80
+ return f"https://github.com/{repository}/archive/refs/tags/{release}.zip"
81
+ if artifact == f"{release}.tar.gz":
82
+ return f"https://github.com/{repository}/archive/refs/tags/{release}.tar.gz"
83
+
84
+ repo = gh.get_repo(repository)
85
+
86
+ if not release:
87
+ release = repo.get_latest_release().tag_name
88
+
89
+ url = None
90
+ for repo_release in repo.get_releases():
91
+ if repo_release.tag_name == release:
92
+ for asset in repo_release.assets:
93
+ if asset.name == artifact:
94
+ url = asset.url
95
+
96
+ if not url:
97
+ raise ValueError(f'Unable to find release asset: {repository}/{release}/{artifact}')
98
+
99
+ return url
100
+
101
+
102
+ def __get_github_auth_token(package_name):
103
+ token_name = package_name.upper()
104
+ for tok in ('#', '$', '&', '-', '=', '!', '/'):
105
+ token_name = token_name.replace(tok, '')
106
+
107
+ search_env = (
108
+ f'GITHUB_{token_name}_TOKEN',
109
+ 'GITHUB_TOKEN',
110
+ 'GIT_TOKEN'
111
+ )
112
+
113
+ token = None
114
+ for env in search_env:
115
+ token = os.environ.get(env, None)
116
+
117
+ if token:
118
+ break
119
+
120
+ if not token:
121
+ raise ValueError('Unable to determine authorization token for GitHub, '
122
+ f'please set one of the following environmental variables: {search_env}')
123
+
124
+ return token
@@ -35,6 +35,12 @@ def http_resolver(chip, package, path, ref, url, fetch):
35
35
  release_data_lock(data_lock)
36
36
  return data_path, False
37
37
 
38
+ return _http_resolver(chip, package, path, ref, url, data_lock)
39
+
40
+
41
+ def _http_resolver(chip, package, path, ref, url, data_lock):
42
+ data_path, _ = get_download_cache_path(chip, package, ref)
43
+
38
44
  extract_from_url(chip, package, path, ref, url, data_path)
39
45
 
40
46
  release_data_lock(data_lock)
@@ -9,6 +9,7 @@ import streamlit_antd_components as sac
9
9
 
10
10
  from PIL import Image
11
11
 
12
+ import siliconcompiler
12
13
  from siliconcompiler import __version__ as sc_version
13
14
  from siliconcompiler import utils
14
15
  from siliconcompiler.report import report
@@ -31,7 +32,7 @@ SC_MENU = {
31
32
  "Report a Bug":
32
33
  '''https://github.com/siliconcompiler/siliconcompiler/issues''',
33
34
  "About": "\n\n".join(SC_ABOUT)}
34
- SC_DATA_ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..', '..', 'data'))
35
+ SC_DATA_ROOT = os.path.abspath(os.path.join(os.path.dirname(siliconcompiler.__file__), 'data'))
35
36
  SC_LOGO_PATH = os.path.join(SC_DATA_ROOT, 'logo.png')
36
37
  SC_FONT_PATH = os.path.join(SC_DATA_ROOT, 'RobotoMono', 'RobotoMono-Regular.ttf')
37
38
 
@@ -34,6 +34,9 @@ def get_nodes_and_edges(chip):
34
34
  nodes = []
35
35
  edges = []
36
36
 
37
+ if not chip.get('option', 'flow'):
38
+ return nodes, edges
39
+
37
40
  default_node_border_width = 1
38
41
  successful_path_node_width = 3
39
42
  default_edge_width = 3
@@ -24,8 +24,9 @@ def make_node_to_step_index_map(chip, metric_dataframe):
24
24
  nodes of the selected chip
25
25
  '''
26
26
  node_to_step_index_map = {}
27
- for step, index in _get_flowgraph_nodes(chip, chip.get('option', 'flow')):
28
- node_to_step_index_map[f'{step}{index}'] = (step, index)
27
+ if chip.get('option', 'flow'):
28
+ for step, index in _get_flowgraph_nodes(chip, chip.get('option', 'flow')):
29
+ node_to_step_index_map[f'{step}{index}'] = (step, index)
29
30
 
30
31
  # concatenate step and index
31
32
  metric_dataframe.columns = metric_dataframe.columns.map(lambda x: f'{x[0]}{x[1]}')
@@ -54,6 +55,8 @@ def make_metric_to_metric_unit_map(metric_dataframe):
54
55
 
55
56
 
56
57
  def is_running(chip):
58
+ if not chip.get('option', 'flow'):
59
+ return False
57
60
  for step, index in _get_flowgraph_nodes(chip, chip.get('option', 'flow')):
58
61
  state = chip.get('record', 'status', step=step, index=index)
59
62
  if not NodeStatus.is_done(state):
@@ -40,6 +40,9 @@ def _find_summary_metrics(chip, metrics_map):
40
40
  def _collect_data(chip, flow=None, flowgraph_nodes=None, format_as_string=True):
41
41
  if not flow:
42
42
  flow = chip.get('option', 'flow')
43
+ if not flow:
44
+ return [], {}, {}, {}, [], {}
45
+
43
46
  if not flowgraph_nodes:
44
47
  flowgraph_nodes = nodes_to_execute(chip)
45
48
  # only report tool based steps functions