siliconcompiler 0.33.2__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.
Files changed (104) hide show
  1. siliconcompiler/__init__.py +2 -0
  2. siliconcompiler/_metadata.py +1 -1
  3. siliconcompiler/apps/_common.py +1 -1
  4. siliconcompiler/apps/sc.py +1 -1
  5. siliconcompiler/apps/sc_issue.py +6 -4
  6. siliconcompiler/apps/sc_remote.py +3 -20
  7. siliconcompiler/apps/sc_show.py +2 -2
  8. siliconcompiler/apps/utils/replay.py +4 -4
  9. siliconcompiler/checklist.py +202 -1
  10. siliconcompiler/core.py +62 -293
  11. siliconcompiler/data/templates/email/general.j2 +3 -3
  12. siliconcompiler/data/templates/email/summary.j2 +1 -1
  13. siliconcompiler/data/templates/issue/README.txt +1 -1
  14. siliconcompiler/data/templates/report/sc_report.j2 +7 -7
  15. siliconcompiler/dependencyschema.py +392 -0
  16. siliconcompiler/design.py +758 -0
  17. siliconcompiler/flowgraph.py +79 -13
  18. siliconcompiler/optimizer/vizier.py +2 -2
  19. siliconcompiler/package/__init__.py +383 -223
  20. siliconcompiler/package/git.py +75 -77
  21. siliconcompiler/package/github.py +70 -97
  22. siliconcompiler/package/https.py +77 -93
  23. siliconcompiler/packageschema.py +260 -0
  24. siliconcompiler/pdk.py +5 -5
  25. siliconcompiler/remote/client.py +33 -15
  26. siliconcompiler/remote/server.py +2 -2
  27. siliconcompiler/report/dashboard/cli/__init__.py +6 -6
  28. siliconcompiler/report/dashboard/cli/board.py +4 -4
  29. siliconcompiler/report/dashboard/web/components/__init__.py +5 -5
  30. siliconcompiler/report/dashboard/web/components/flowgraph.py +4 -4
  31. siliconcompiler/report/dashboard/web/components/graph.py +2 -2
  32. siliconcompiler/report/dashboard/web/state.py +1 -1
  33. siliconcompiler/report/dashboard/web/utils/__init__.py +5 -5
  34. siliconcompiler/report/html_report.py +1 -1
  35. siliconcompiler/report/report.py +4 -4
  36. siliconcompiler/report/summary_table.py +2 -2
  37. siliconcompiler/report/utils.py +5 -5
  38. siliconcompiler/scheduler/__init__.py +3 -1382
  39. siliconcompiler/scheduler/docker.py +263 -0
  40. siliconcompiler/scheduler/run_node.py +10 -21
  41. siliconcompiler/scheduler/scheduler.py +311 -0
  42. siliconcompiler/scheduler/schedulernode.py +944 -0
  43. siliconcompiler/scheduler/send_messages.py +3 -3
  44. siliconcompiler/scheduler/slurm.py +149 -163
  45. siliconcompiler/scheduler/taskscheduler.py +45 -57
  46. siliconcompiler/schema/__init__.py +3 -3
  47. siliconcompiler/schema/baseschema.py +234 -11
  48. siliconcompiler/schema/editableschema.py +4 -0
  49. siliconcompiler/schema/journal.py +210 -0
  50. siliconcompiler/schema/namedschema.py +55 -2
  51. siliconcompiler/schema/parameter.py +14 -1
  52. siliconcompiler/schema/parametervalue.py +1 -34
  53. siliconcompiler/schema/schema_cfg.py +210 -349
  54. siliconcompiler/tool.py +412 -148
  55. siliconcompiler/tools/__init__.py +2 -0
  56. siliconcompiler/tools/builtin/_common.py +5 -5
  57. siliconcompiler/tools/builtin/concatenate.py +7 -7
  58. siliconcompiler/tools/builtin/minimum.py +4 -4
  59. siliconcompiler/tools/builtin/mux.py +4 -4
  60. siliconcompiler/tools/builtin/nop.py +4 -4
  61. siliconcompiler/tools/builtin/verify.py +8 -9
  62. siliconcompiler/tools/execute/exec_input.py +1 -1
  63. siliconcompiler/tools/genfasm/genfasm.py +1 -6
  64. siliconcompiler/tools/openroad/_apr.py +5 -1
  65. siliconcompiler/tools/openroad/antenna_repair.py +1 -1
  66. siliconcompiler/tools/openroad/macro_placement.py +1 -1
  67. siliconcompiler/tools/openroad/power_grid.py +1 -1
  68. siliconcompiler/tools/openroad/scripts/common/procs.tcl +32 -25
  69. siliconcompiler/tools/opensta/timing.py +26 -3
  70. siliconcompiler/tools/slang/__init__.py +2 -2
  71. siliconcompiler/tools/surfer/__init__.py +0 -0
  72. siliconcompiler/tools/surfer/show.py +53 -0
  73. siliconcompiler/tools/surfer/surfer.py +30 -0
  74. siliconcompiler/tools/vpr/route.py +82 -0
  75. siliconcompiler/tools/vpr/vpr.py +23 -6
  76. siliconcompiler/tools/yosys/__init__.py +1 -1
  77. siliconcompiler/tools/yosys/scripts/procs.tcl +143 -0
  78. siliconcompiler/tools/yosys/{sc_synth_asic.tcl → scripts/sc_synth_asic.tcl} +4 -0
  79. siliconcompiler/tools/yosys/{sc_synth_fpga.tcl → scripts/sc_synth_fpga.tcl} +24 -77
  80. siliconcompiler/tools/yosys/syn_fpga.py +14 -0
  81. siliconcompiler/toolscripts/_tools.json +9 -13
  82. siliconcompiler/toolscripts/rhel9/install-vpr.sh +0 -2
  83. siliconcompiler/toolscripts/ubuntu22/install-surfer.sh +33 -0
  84. siliconcompiler/toolscripts/ubuntu24/install-surfer.sh +33 -0
  85. siliconcompiler/utils/__init__.py +4 -24
  86. siliconcompiler/utils/flowgraph.py +29 -28
  87. siliconcompiler/utils/issue.py +23 -29
  88. siliconcompiler/utils/logging.py +37 -7
  89. siliconcompiler/utils/showtools.py +6 -1
  90. {siliconcompiler-0.33.2.dist-info → siliconcompiler-0.34.1.dist-info}/METADATA +16 -25
  91. {siliconcompiler-0.33.2.dist-info → siliconcompiler-0.34.1.dist-info}/RECORD +98 -91
  92. siliconcompiler/scheduler/docker_runner.py +0 -254
  93. siliconcompiler/schema/journalingschema.py +0 -242
  94. siliconcompiler/tools/yosys/procs.tcl +0 -71
  95. siliconcompiler/toolscripts/rhel9/install-yosys-parmys.sh +0 -68
  96. siliconcompiler/toolscripts/ubuntu22/install-yosys-parmys.sh +0 -68
  97. siliconcompiler/toolscripts/ubuntu24/install-yosys-parmys.sh +0 -68
  98. /siliconcompiler/tools/yosys/{sc_lec.tcl → scripts/sc_lec.tcl} +0 -0
  99. /siliconcompiler/tools/yosys/{sc_screenshot.tcl → scripts/sc_screenshot.tcl} +0 -0
  100. /siliconcompiler/tools/yosys/{syn_strategies.tcl → scripts/syn_strategies.tcl} +0 -0
  101. {siliconcompiler-0.33.2.dist-info → siliconcompiler-0.34.1.dist-info}/WHEEL +0 -0
  102. {siliconcompiler-0.33.2.dist-info → siliconcompiler-0.34.1.dist-info}/entry_points.txt +0 -0
  103. {siliconcompiler-0.33.2.dist-info → siliconcompiler-0.34.1.dist-info}/licenses/LICENSE +0 -0
  104. {siliconcompiler-0.33.2.dist-info → siliconcompiler-0.34.1.dist-info}/top_level.txt +0 -0
@@ -1,4 +1,5 @@
1
1
  import inspect
2
+ import importlib
2
3
 
3
4
  from siliconcompiler import Schema
4
5
  from siliconcompiler.schema import BaseSchema, NamedSchema
@@ -10,7 +11,8 @@ from siliconcompiler import NodeStatus
10
11
 
11
12
  class FlowgraphSchema(NamedSchema):
12
13
  def __init__(self, name=None):
13
- super().__init__(name=name)
14
+ super().__init__()
15
+ self.set_name(name)
14
16
 
15
17
  schema = EditableSchema(self)
16
18
  schema.insert("default", "default", FlowgraphNodeSchema())
@@ -30,6 +32,8 @@ class FlowgraphSchema(NamedSchema):
30
32
 
31
33
  self.__cache_node_outputs = None
32
34
 
35
+ self.__cache_tasks = None
36
+
33
37
  def node(self, step, task, index=0):
34
38
  '''
35
39
  Creates a flowgraph node.
@@ -79,6 +83,11 @@ class FlowgraphSchema(NamedSchema):
79
83
  raise ValueError(f"{task} is not a valid task, it must be associated with "
80
84
  "a tool '<tool>.<task>'.")
81
85
 
86
+ if '/' in step:
87
+ raise ValueError(f"{step} is not a valid step, it cannot contain '/'")
88
+ if '/' in index:
89
+ raise ValueError(f"{index} is not a valid index, it cannot contain '/'")
90
+
82
91
  tool_name, task_name = task_parts[-2:]
83
92
 
84
93
  # bind tool to node
@@ -114,7 +123,7 @@ class FlowgraphSchema(NamedSchema):
114
123
 
115
124
  for step, index in [(head, head_index), (tail, tail_index)]:
116
125
  if not self.valid(step, index):
117
- raise ValueError(f"{step}{index} is not a defined node in {self.name()}.")
126
+ raise ValueError(f"{step}/{index} is not a defined node in {self.name()}.")
118
127
 
119
128
  tail_node = (tail, tail_index)
120
129
  if tail_node in self.get(head, head_index, 'input'):
@@ -167,6 +176,37 @@ class FlowgraphSchema(NamedSchema):
167
176
 
168
177
  self.__clear_cache()
169
178
 
179
+ def insert_node(self, step, task, before_step, index=0, before_index=0):
180
+ '''
181
+ Insert a new node after the specified node
182
+
183
+ Args:
184
+ step (str): Step name
185
+ index (int/str): Step index
186
+ task (module/str): Task to associate with this node
187
+ before_step (str): name of step to insert task after
188
+ before_index (int/str): index of step to insert task after
189
+ '''
190
+
191
+ index = str(index)
192
+ before_index = str(before_index)
193
+
194
+ if (before_step, before_index) not in self.get_nodes():
195
+ raise ValueError(f'{before_step}/{before_index} is not a valid node in {self.name()}')
196
+
197
+ # add the node
198
+ self.node(step, task, index=index)
199
+
200
+ # rewire
201
+ for istep, iindex in self.get_node_outputs(before_step, before_index):
202
+ inputs = self.get(istep, iindex, "input")
203
+ inputs.remove((before_step, before_index))
204
+ self.set(istep, iindex, "input", inputs)
205
+ self.add(istep, iindex, "input", (step, index))
206
+ self.set(step, index, "input", [(before_step, before_index)])
207
+
208
+ self.__clear_cache()
209
+
170
210
  ###########################################################################
171
211
  def graph(self, subflow, name=None):
172
212
  '''
@@ -357,7 +397,7 @@ class FlowgraphSchema(NamedSchema):
357
397
  index = str(index)
358
398
 
359
399
  if (step, index) not in self.get_nodes():
360
- raise ValueError(f"{step}{index} is not a valid node")
400
+ raise ValueError(f"{step}/{index} is not a valid node")
361
401
 
362
402
  if self.__cache_node_outputs is not None:
363
403
  return self.__cache_node_outputs[(step, index)]
@@ -433,15 +473,15 @@ class FlowgraphSchema(NamedSchema):
433
473
  if input_nodes.count(node) > 1:
434
474
  in_step, in_index = node
435
475
  if logger:
436
- logger.error(f'Duplicate edge from {in_step}{in_index} to '
437
- f'{step}{index} in the {self.name()} flowgraph')
476
+ logger.error(f'Duplicate edge from {in_step}/{in_index} to '
477
+ f'{step}/{index} in the {self.name()} flowgraph')
438
478
  error = True
439
479
 
440
480
  diff_nodes = check_nodes.difference(self.get_nodes())
441
481
  if diff_nodes:
442
482
  if logger:
443
483
  for step, index in diff_nodes:
444
- logger.error(f'{step}{index} is missing in the {self.name()} flowgraph')
484
+ logger.error(f'{step}/{index} is missing in the {self.name()} flowgraph')
445
485
  error = True
446
486
 
447
487
  # Detect missing definitions
@@ -449,7 +489,7 @@ class FlowgraphSchema(NamedSchema):
449
489
  for item in ('tool', 'task', 'taskmodule'):
450
490
  if not self.get(step, index, item):
451
491
  if logger:
452
- logger.error(f'{step}{index} is missing a {item} definition in the '
492
+ logger.error(f'{step}/{index} is missing a {item} definition in the '
453
493
  f'{self.name()} flowgraph')
454
494
  error = True
455
495
 
@@ -459,11 +499,37 @@ class FlowgraphSchema(NamedSchema):
459
499
  if loop_path:
460
500
  error = True
461
501
  if logger:
462
- loop_path = [f"{step}{index}" for step, index in loop_path]
502
+ loop_path = [f"{step}/{index}" for step, index in loop_path]
463
503
  logger.error(f"{' -> '.join(loop_path)} forms a loop in {self.name()}")
464
504
 
465
505
  return not error
466
506
 
507
+ def get_task_module(self, step, index):
508
+ """
509
+ Returns the module for a given task
510
+
511
+ Args:
512
+ step (str): Step name
513
+ index (int/str): Step index
514
+ """
515
+
516
+ index = str(index)
517
+
518
+ if (step, index) not in self.get_nodes():
519
+ raise ValueError(f"{step}/{index} is not a valid node in {self.name()}.")
520
+
521
+ taskmodule = self.get(step, index, 'taskmodule')
522
+
523
+ # Create cache
524
+ if self.__cache_tasks is None:
525
+ self.__cache_tasks = {}
526
+
527
+ if taskmodule in self.__cache_tasks:
528
+ return self.__cache_tasks[taskmodule]
529
+
530
+ self.__cache_tasks[taskmodule] = importlib.import_module(taskmodule)
531
+ return self.__cache_tasks[taskmodule]
532
+
467
533
 
468
534
  class RuntimeFlowgraph:
469
535
  '''
@@ -618,13 +684,13 @@ class RuntimeFlowgraph:
618
684
  index = str(index)
619
685
 
620
686
  if (step, index) not in self.get_nodes():
621
- raise ValueError(f"{step}{index} is not a valid node")
687
+ raise ValueError(f"{step}/{index} is not a valid node")
622
688
 
623
689
  return tuple(sorted(self.__walk_graph((step, str(index)), reverse=False)))
624
690
 
625
691
  def get_node_inputs(self, step, index, record=None):
626
692
  if (step, index) not in self.get_nodes():
627
- raise ValueError(f"{step}{index} is not a valid node")
693
+ raise ValueError(f"{step}/{index} is not a valid node")
628
694
 
629
695
  if record is None:
630
696
  inputs = set()
@@ -691,7 +757,7 @@ class RuntimeFlowgraph:
691
757
  # Check for undefined prunes
692
758
  for step, index in sorted(prune_nodes.difference(flow.get_nodes())):
693
759
  if logger:
694
- logger.error(f'{step}{index} is not defined in the {flow.name()} flowgraph')
760
+ logger.error(f'{step}/{index} is not defined in the {flow.name()} flowgraph')
695
761
  error = True
696
762
 
697
763
  if not error:
@@ -732,9 +798,9 @@ class RuntimeFlowgraph:
732
798
  if entrynode in runtime.__walk_graph(exitnode):
733
799
  found = True
734
800
  if not found:
735
- exits = ",".join([f"{step}{index}"
801
+ exits = ",".join([f"{step}/{index}"
736
802
  for step, index in runtime.get_exit_nodes()])
737
- missing.append(f'no path from {entrynode[0]}{entrynode[1]} to {exits} '
803
+ missing.append(f'no path from {entrynode[0]}/{entrynode[1]} to {exits} '
738
804
  f'in the {flow.name()} flowgraph')
739
805
  if found:
740
806
  found_any = True
@@ -157,7 +157,7 @@ class VizierOptimizier(Optimizer):
157
157
  chip.graph(flow, org_flow, name=graph_name)
158
158
 
159
159
  # Complete nodes
160
- nodes = chip.schema.get("flowgraph", org_flow, field="schema").get_nodes()
160
+ nodes = chip.get("flowgraph", org_flow, field="schema").get_nodes()
161
161
  for step, _ in list(nodes):
162
162
  nodes.append((step, None))
163
163
  nodes = set(nodes)
@@ -167,7 +167,7 @@ class VizierOptimizier(Optimizer):
167
167
  if key[0] == 'history':
168
168
  continue
169
169
 
170
- for value, step, index in chip.schema.get(*key, field=None).getvalues():
170
+ for value, step, index in chip.get(*key, field=None).getvalues():
171
171
  node = (step, index)
172
172
 
173
173
  if node in nodes: