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.
Files changed (59) hide show
  1. siliconcompiler/__init__.py +2 -0
  2. siliconcompiler/_metadata.py +1 -1
  3. siliconcompiler/apps/sc_issue.py +5 -3
  4. siliconcompiler/apps/sc_remote.py +0 -17
  5. siliconcompiler/apps/utils/replay.py +5 -5
  6. siliconcompiler/checklist.py +1 -1
  7. siliconcompiler/core.py +39 -48
  8. siliconcompiler/data/templates/replay/replay.sh.j2 +18 -1
  9. siliconcompiler/dependencyschema.py +392 -0
  10. siliconcompiler/design.py +664 -0
  11. siliconcompiler/flowgraph.py +32 -1
  12. siliconcompiler/metric.py +19 -0
  13. siliconcompiler/package/__init__.py +383 -223
  14. siliconcompiler/package/git.py +75 -77
  15. siliconcompiler/package/github.py +70 -97
  16. siliconcompiler/package/https.py +77 -93
  17. siliconcompiler/packageschema.py +260 -0
  18. siliconcompiler/pdk.py +2 -2
  19. siliconcompiler/record.py +57 -5
  20. siliconcompiler/remote/client.py +61 -13
  21. siliconcompiler/remote/server.py +109 -64
  22. siliconcompiler/report/dashboard/cli/board.py +1 -2
  23. siliconcompiler/scheduler/__init__.py +3 -1375
  24. siliconcompiler/scheduler/docker.py +268 -0
  25. siliconcompiler/scheduler/run_node.py +20 -19
  26. siliconcompiler/scheduler/scheduler.py +308 -0
  27. siliconcompiler/scheduler/schedulernode.py +934 -0
  28. siliconcompiler/scheduler/slurm.py +147 -163
  29. siliconcompiler/scheduler/taskscheduler.py +39 -52
  30. siliconcompiler/schema/__init__.py +3 -3
  31. siliconcompiler/schema/baseschema.py +256 -11
  32. siliconcompiler/schema/editableschema.py +4 -0
  33. siliconcompiler/schema/journal.py +210 -0
  34. siliconcompiler/schema/namedschema.py +31 -2
  35. siliconcompiler/schema/parameter.py +14 -1
  36. siliconcompiler/schema/parametervalue.py +1 -34
  37. siliconcompiler/schema/schema_cfg.py +211 -350
  38. siliconcompiler/tool.py +139 -37
  39. siliconcompiler/tools/_common/__init__.py +14 -11
  40. siliconcompiler/tools/builtin/concatenate.py +2 -2
  41. siliconcompiler/tools/builtin/verify.py +1 -2
  42. siliconcompiler/tools/openroad/scripts/common/procs.tcl +27 -25
  43. siliconcompiler/tools/slang/__init__.py +3 -2
  44. siliconcompiler/tools/vpr/route.py +69 -0
  45. siliconcompiler/tools/yosys/sc_synth_asic.tcl +0 -4
  46. siliconcompiler/toolscripts/_tools.json +13 -8
  47. siliconcompiler/toolscripts/ubuntu22/install-klayout.sh +4 -0
  48. siliconcompiler/toolscripts/ubuntu24/install-klayout.sh +4 -0
  49. siliconcompiler/utils/__init__.py +2 -23
  50. siliconcompiler/utils/flowgraph.py +5 -5
  51. siliconcompiler/utils/logging.py +2 -1
  52. {siliconcompiler-0.33.1.dist-info → siliconcompiler-0.34.0.dist-info}/METADATA +8 -6
  53. {siliconcompiler-0.33.1.dist-info → siliconcompiler-0.34.0.dist-info}/RECORD +57 -52
  54. {siliconcompiler-0.33.1.dist-info → siliconcompiler-0.34.0.dist-info}/WHEEL +1 -1
  55. siliconcompiler/scheduler/docker_runner.py +0 -254
  56. siliconcompiler/schema/journalingschema.py +0 -238
  57. {siliconcompiler-0.33.1.dist-info → siliconcompiler-0.34.0.dist-info}/entry_points.txt +0 -0
  58. {siliconcompiler-0.33.1.dist-info → siliconcompiler-0.34.0.dist-info}/licenses/LICENSE +0 -0
  59. {siliconcompiler-0.33.1.dist-info → siliconcompiler-0.34.0.dist-info}/top_level.txt +0 -0
@@ -3,6 +3,7 @@ from siliconcompiler._common import NodeStatus, SiliconCompilerError
3
3
  from siliconcompiler.utils import sc_open
4
4
  from siliconcompiler.schema_obj import SchemaTmp as Schema
5
5
 
6
+ from siliconcompiler.design import DesignSchema
6
7
  from siliconcompiler.record import RecordSchema
7
8
  from siliconcompiler.metric import MetricSchema
8
9
  from siliconcompiler.pdk import PDKSchema
@@ -30,6 +31,7 @@ __all__ = [
30
31
  "Checklist",
31
32
  "Schema",
32
33
  "sc_open",
34
+ "DesignSchema",
33
35
  "RecordSchema",
34
36
  "MetricSchema",
35
37
  "PDKSchema",
@@ -1,5 +1,5 @@
1
1
  # Version number following semver standard.
2
- version = '0.33.1'
2
+ version = '0.34.0'
3
3
 
4
4
  # Default server address for remote runs, if unspecified.
5
5
  default_server = 'https://server.siliconcompiler.com'
@@ -4,7 +4,7 @@ import os
4
4
  import siliconcompiler
5
5
  import tarfile
6
6
  import json
7
- from siliconcompiler.scheduler import _runtask, _executenode
7
+ from siliconcompiler.scheduler.schedulernode import SchedulerNode
8
8
  from siliconcompiler.utils.issue import generate_testcase
9
9
  from siliconcompiler.tools._common import get_tool_task
10
10
 
@@ -153,8 +153,10 @@ To run a testcase, use:
153
153
  # Run task
154
154
  # Rerun setup task, assumed to be running in its own thread so
155
155
  # multiprocess is not needed
156
- flow = chip.get('option', 'flow')
157
- _runtask(chip, flow, step, index, _executenode, replay=True)
156
+ SchedulerNode(chip,
157
+ step,
158
+ index,
159
+ replay=True).run()
158
160
 
159
161
  return 0
160
162
 
@@ -1,12 +1,9 @@
1
1
  # Copyright 2023 Silicon Compiler Authors. All Rights Reserved.
2
- import os
3
2
  import sys
4
3
 
5
4
  from siliconcompiler import Chip
6
5
  from siliconcompiler import SiliconCompilerError
7
6
  from siliconcompiler.remote.client import Client, ConfigureClient
8
- from siliconcompiler.scheduler import _finalize_run
9
- from siliconcompiler.flowgraph import RuntimeFlowgraph
10
7
 
11
8
 
12
9
  def main():
@@ -169,20 +166,6 @@ To delete a job, use:
169
166
  chip.logger.error(f'{e}')
170
167
  return 1
171
168
 
172
- # Wrap up run
173
- runtime = RuntimeFlowgraph(
174
- chip.schema.get("flowgraph", flow, field='schema'),
175
- from_steps=chip.get('option', 'from'),
176
- to_steps=chip.get('option', 'to'),
177
- prune_nodes=chip.get('option', 'prune'))
178
- for step, index in runtime.get_nodes():
179
- manifest = os.path.join(chip.getworkdir(step=step, index=index),
180
- 'outputs',
181
- f'{chip.design}.pkg.json')
182
- if os.path.exists(manifest):
183
- chip.schema.read_journal(manifest)
184
- _finalize_run(chip)
185
-
186
169
  # Summarize the run.
187
170
  chip.summary()
188
171
 
@@ -18,6 +18,7 @@ import siliconcompiler
18
18
  from siliconcompiler.apps._common import UNSET_DESIGN
19
19
  from siliconcompiler import SiliconCompilerError
20
20
  from siliconcompiler import utils
21
+ from siliconcompiler.record import RecordTime
21
22
 
22
23
 
23
24
  def make_bytes(data):
@@ -127,11 +128,10 @@ def main():
127
128
  path = os.path.abspath(args['file'])
128
129
  os.makedirs(os.path.dirname(path), exist_ok=True)
129
130
 
130
- starttimes = set()
131
- for starttime, step, index in chip.schema.get('history', jobname, 'record', 'starttime',
132
- field=None).getvalues():
133
- starttimes.add(datetime.strptime(starttime, '%Y-%m-%d %H:%M:%S'))
134
- starttime = min(starttimes).strftime('%Y-%m-%d %H:%M:%S')
131
+ record_schema = chip.schema.get('history', jobname, 'record', field="schema")
132
+ starttime = datetime.fromtimestamp(
133
+ record_schema.get_earliest_time(RecordTime.START)).strftime(
134
+ '%Y-%m-%d %H:%M:%S')
135
135
 
136
136
  with io.StringIO() as fd:
137
137
  fd.write(utils.get_file_template('replay/requirements.txt').render(
@@ -4,7 +4,7 @@ from siliconcompiler.schema.utils import trim
4
4
 
5
5
 
6
6
  class ChecklistSchema(NamedSchema):
7
- def __init__(self, name=None):
7
+ def __init__(self, name):
8
8
  super().__init__(name=name)
9
9
 
10
10
  schema_checklist(self)
siliconcompiler/core.py CHANGED
@@ -18,9 +18,9 @@ import csv
18
18
  import yaml
19
19
  from inspect import getfullargspec
20
20
  from siliconcompiler import Schema
21
- from siliconcompiler.schema import SCHEMA_VERSION, PerNode, JournalingSchema, EditableSchema
21
+ from siliconcompiler.schema import SCHEMA_VERSION, PerNode, Journal, EditableSchema
22
22
  from siliconcompiler.schema.parametertype import NodeType
23
- from siliconcompiler.schema.parametervalue import FileNodeValue, PathNodeValue
23
+ from siliconcompiler.schema.parametervalue import FileNodeValue
24
24
  from siliconcompiler.schema import utils as schema_utils
25
25
  from siliconcompiler import utils
26
26
  from siliconcompiler.utils.logging import SCColorLoggerFormatter, \
@@ -34,9 +34,8 @@ from siliconcompiler.report import _generate_summary_image, _open_summary_image
34
34
  from siliconcompiler.report.dashboard.web import WebDashboard
35
35
  from siliconcompiler.report.dashboard.cli import CliDashboard
36
36
  from siliconcompiler.report.dashboard import DashboardType
37
- from siliconcompiler import package as sc_package
38
37
  import glob
39
- from siliconcompiler.scheduler import run as sc_runner
38
+ from siliconcompiler.scheduler.scheduler import Scheduler
40
39
  from siliconcompiler.utils.flowgraph import _check_flowgraph_io, _get_flowgraph_information
41
40
  from siliconcompiler.tools._common import get_tool_task
42
41
  from types import FunctionType, ModuleType
@@ -1102,7 +1101,8 @@ class Chip:
1102
1101
  '''
1103
1102
 
1104
1103
  if package:
1105
- filename = os.path.join(sc_package.path(self, package), filename)
1104
+ resolvers = self.get("package", field="schema").get_resolvers()
1105
+ filename = os.path.join(resolvers[package](), filename)
1106
1106
 
1107
1107
  if not os.path.isfile(filename):
1108
1108
  raise FileNotFoundError(filename)
@@ -1110,10 +1110,16 @@ class Chip:
1110
1110
  package_name = f'flist-{os.path.basename(filename)}'
1111
1111
  package_dir = os.path.dirname(os.path.abspath(filename))
1112
1112
 
1113
- env_vars = utils.get_env_vars(self, None, None)
1114
-
1115
1113
  def __make_path(rel, path):
1116
- path = PathNodeValue.resolve_env_vars(path, envvars=env_vars)
1114
+ env_save = os.environ.copy()
1115
+ schema_env = {}
1116
+ for env in self.getkeys('option', 'env'):
1117
+ schema_env[env] = self.get('option', 'env', env)
1118
+ os.environ.update(schema_env)
1119
+ path = os.path.expandvars(path)
1120
+ path = os.path.expanduser(path)
1121
+ os.environ.clear()
1122
+ os.environ.update(env_save)
1117
1123
  if os.path.isabs(path):
1118
1124
  if path.startswith(rel):
1119
1125
  return os.path.relpath(path, rel), package_name
@@ -1380,18 +1386,17 @@ class Chip:
1380
1386
  else:
1381
1387
  search_paths = [self.cwd]
1382
1388
 
1383
- env_vars = utils.get_env_vars(self, step, index)
1389
+ resolvers = self.get("package", field="schema").get_resolvers()
1384
1390
  for (dependency, path) in zip(dependencies, paths):
1385
1391
  faux_param = FileNodeValue()
1386
1392
  faux_param.set(path)
1387
1393
  try:
1388
1394
  if dependency:
1389
1395
  faux_param.set(dependency, field='package')
1390
- faux_search = [os.path.abspath(os.path.join(sc_package.path(self, dependency)))]
1396
+ faux_search = [resolvers[dependency]()]
1391
1397
  else:
1392
1398
  faux_search = search_paths
1393
1399
  resolved = faux_param.resolve_path(
1394
- envvars=env_vars,
1395
1400
  search=faux_search,
1396
1401
  collection_dir=collection_dir)
1397
1402
  except FileNotFoundError:
@@ -1547,39 +1552,19 @@ class Chip:
1547
1552
  True if all file paths are valid, otherwise False.
1548
1553
  '''
1549
1554
 
1550
- allkeys = self.allkeys()
1551
- error = False
1552
- for keypath in allkeys:
1553
- paramtype = self.get(*keypath, field='type')
1554
- is_file = 'file' in paramtype
1555
- is_dir = 'dir' in paramtype
1556
- is_list = paramtype.startswith('[')
1557
-
1558
- if is_file or is_dir:
1559
- if keypath[-2:] == ('option', 'builddir'):
1560
- # Skip ['option', 'builddir'] since it will get created by run() if it doesn't
1561
- # exist
1562
- continue
1563
-
1564
- for check_files, step, index in self.schema.get(*keypath, field=None).getvalues():
1565
- if not check_files:
1566
- continue
1555
+ ignore_keys = []
1556
+ for keypath in self.allkeys():
1557
+ if keypath[-2:] == ('option', 'builddir'):
1558
+ ignore_keys.append(keypath)
1567
1559
 
1568
- if not is_list:
1569
- check_files = [check_files]
1570
-
1571
- for idx, check_file in enumerate(check_files):
1572
- found_file = self.__find_files(*keypath,
1573
- missing_ok=True,
1574
- step=step, index=index,
1575
- list_index=idx)
1576
- if is_list:
1577
- found_file = found_file[0]
1578
- if not found_file:
1579
- self.logger.error(f"Parameter {keypath} path {check_file} is invalid")
1580
- error = True
1560
+ package_map = self.get("package", field="schema").get_resolvers()
1581
1561
 
1582
- return not error
1562
+ return self.schema.check_filepaths(
1563
+ ignore_keys=ignore_keys,
1564
+ logger=self.logger,
1565
+ packages=package_map,
1566
+ collection_dir=self._getcollectdir(),
1567
+ cwd=self.cwd)
1583
1568
 
1584
1569
  ###########################################################################
1585
1570
  def check_manifest(self):
@@ -1729,7 +1714,11 @@ class Chip:
1729
1714
  error = True
1730
1715
  self.logger.error(f'No executable or run() function specified for {tool}/{task}')
1731
1716
 
1732
- if not error and not _check_flowgraph_io(self, nodes=nodes):
1717
+ runtime_full = RuntimeFlowgraph(
1718
+ self.schema.get("flowgraph", flow, field='schema'),
1719
+ to_steps=self.get('option', 'to'),
1720
+ prune_nodes=self.get('option', 'prune'))
1721
+ if not error and not _check_flowgraph_io(self, nodes=runtime_full.get_nodes()):
1733
1722
  error = True
1734
1723
 
1735
1724
  return not error
@@ -1792,10 +1781,7 @@ class Chip:
1792
1781
  schema.write_manifest(filepath)
1793
1782
  return
1794
1783
 
1795
- tcl_record = False
1796
- if isinstance(schema, JournalingSchema):
1797
- tcl_record = "get" in schema.get_journaling_types()
1798
- schema = schema.get_base_schema()
1784
+ tcl_record = "get" in Journal.access(schema).get_types()
1799
1785
 
1800
1786
  is_csv = re.search(r'(\.csv)(\.gz)*$', filepath)
1801
1787
 
@@ -3197,9 +3183,14 @@ class Chip:
3197
3183
  >>> run()
3198
3184
  Runs the execution flow defined by the flowgraph dictionary.
3199
3185
  '''
3186
+ from siliconcompiler.remote.client import ClientScheduler
3200
3187
 
3201
3188
  try:
3202
- sc_runner(self)
3189
+ if self.get('option', 'remote'):
3190
+ scheduler = ClientScheduler(self)
3191
+ else:
3192
+ scheduler = Scheduler(self)
3193
+ scheduler.run()
3203
3194
  except Exception as e:
3204
3195
  if raise_exception:
3205
3196
  raise e
@@ -9,6 +9,7 @@ CD_WORK="{{ work_dir }}"
9
9
  PRINT=""
10
10
  CMDPREFIX=""
11
11
  SKIPEXPORT=0
12
+ DONODE={{ node_only }}
12
13
  while [[ $# -gt 0 ]]; do
13
14
  case $1 in
14
15
  --which)
@@ -40,6 +41,11 @@ while [[ $# -gt 0 ]]; do
40
41
  shift
41
42
  shift
42
43
  ;;
44
+ --node)
45
+ DONODE=1
46
+ shift
47
+ shift
48
+ ;;
43
49
  -h|--help)
44
50
  echo "Usage: $0"
45
51
  echo " Options:"
@@ -49,7 +55,8 @@ while [[ $# -gt 0 ]]; do
49
55
  echo " --command print the execution command"
50
56
  echo " --skipcd do not change directory into replay directory"
51
57
  echo " --skipexports do not export environmental variables"
52
- echo " --cmdprefix <cmd> prefix to add to the replay command, such as gdb"
58
+ echo " --cmdprefix <cmd> prefix to add to the replay command, such as dgb"
59
+ echo " --node execute entire node"
53
60
  echo " -h,--help print this help"
54
61
  exit 0
55
62
  ;;
@@ -87,6 +94,16 @@ case $PRINT in
87
94
  ;;
88
95
  esac
89
96
 
97
+ if [ $DONODE == 1 ]; then
98
+ python3 -m siliconcompiler.scheduler.run_node \
99
+ -cfg "{{ cfg_file }}" \
100
+ -builddir "${PWD}/../../../../" \
101
+ -step "{{ step }}" \
102
+ -index "{{ index }}" \
103
+ -cwd "$PWD" \
104
+ -replay
105
+ {% if cmds|length > 0 %}else
90
106
  # Command execution
91
107
  $CMDPREFIX \{% for cmd in cmds %}
92
108
  {% if not loop.first %} {% endif %}{{ cmd }}{% if not loop.last %} \{% endif %}{% endfor %}
109
+ {% endif %}fi