siliconcompiler 0.34.1__py3-none-any.whl → 0.34.3__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 (129) hide show
  1. siliconcompiler/__init__.py +23 -4
  2. siliconcompiler/__main__.py +1 -7
  3. siliconcompiler/_metadata.py +1 -1
  4. siliconcompiler/apps/_common.py +104 -23
  5. siliconcompiler/apps/sc.py +4 -8
  6. siliconcompiler/apps/sc_dashboard.py +6 -4
  7. siliconcompiler/apps/sc_install.py +10 -6
  8. siliconcompiler/apps/sc_issue.py +7 -5
  9. siliconcompiler/apps/sc_remote.py +1 -1
  10. siliconcompiler/apps/sc_server.py +9 -14
  11. siliconcompiler/apps/sc_show.py +7 -6
  12. siliconcompiler/apps/smake.py +130 -94
  13. siliconcompiler/apps/utils/replay.py +4 -7
  14. siliconcompiler/apps/utils/summarize.py +3 -5
  15. siliconcompiler/asic.py +420 -0
  16. siliconcompiler/checklist.py +25 -2
  17. siliconcompiler/cmdlineschema.py +534 -0
  18. siliconcompiler/constraints/__init__.py +17 -0
  19. siliconcompiler/constraints/asic_component.py +378 -0
  20. siliconcompiler/constraints/asic_floorplan.py +449 -0
  21. siliconcompiler/constraints/asic_pins.py +489 -0
  22. siliconcompiler/constraints/asic_timing.py +517 -0
  23. siliconcompiler/core.py +10 -35
  24. siliconcompiler/data/templates/tcl/manifest.tcl.j2 +8 -0
  25. siliconcompiler/dependencyschema.py +96 -202
  26. siliconcompiler/design.py +327 -241
  27. siliconcompiler/filesetschema.py +250 -0
  28. siliconcompiler/flowgraph.py +298 -106
  29. siliconcompiler/fpga.py +124 -1
  30. siliconcompiler/library.py +331 -0
  31. siliconcompiler/metric.py +327 -92
  32. siliconcompiler/metrics/__init__.py +7 -0
  33. siliconcompiler/metrics/asic.py +245 -0
  34. siliconcompiler/metrics/fpga.py +220 -0
  35. siliconcompiler/package/__init__.py +391 -67
  36. siliconcompiler/package/git.py +92 -16
  37. siliconcompiler/package/github.py +114 -22
  38. siliconcompiler/package/https.py +79 -16
  39. siliconcompiler/packageschema.py +341 -16
  40. siliconcompiler/pathschema.py +255 -0
  41. siliconcompiler/pdk.py +566 -1
  42. siliconcompiler/project.py +1460 -0
  43. siliconcompiler/record.py +38 -1
  44. siliconcompiler/remote/__init__.py +5 -2
  45. siliconcompiler/remote/client.py +11 -6
  46. siliconcompiler/remote/schema.py +5 -23
  47. siliconcompiler/remote/server.py +41 -54
  48. siliconcompiler/report/__init__.py +3 -3
  49. siliconcompiler/report/dashboard/__init__.py +48 -14
  50. siliconcompiler/report/dashboard/cli/__init__.py +99 -21
  51. siliconcompiler/report/dashboard/cli/board.py +364 -179
  52. siliconcompiler/report/dashboard/web/__init__.py +90 -12
  53. siliconcompiler/report/dashboard/web/components/__init__.py +219 -240
  54. siliconcompiler/report/dashboard/web/components/flowgraph.py +49 -26
  55. siliconcompiler/report/dashboard/web/components/graph.py +139 -100
  56. siliconcompiler/report/dashboard/web/layouts/__init__.py +29 -1
  57. siliconcompiler/report/dashboard/web/layouts/_common.py +38 -2
  58. siliconcompiler/report/dashboard/web/layouts/vertical_flowgraph.py +39 -26
  59. siliconcompiler/report/dashboard/web/layouts/vertical_flowgraph_node_tab.py +50 -50
  60. siliconcompiler/report/dashboard/web/layouts/vertical_flowgraph_sac_tabs.py +49 -46
  61. siliconcompiler/report/dashboard/web/state.py +141 -14
  62. siliconcompiler/report/dashboard/web/utils/__init__.py +79 -16
  63. siliconcompiler/report/dashboard/web/utils/file_utils.py +74 -11
  64. siliconcompiler/report/dashboard/web/viewer.py +25 -1
  65. siliconcompiler/report/report.py +5 -2
  66. siliconcompiler/report/summary_image.py +29 -11
  67. siliconcompiler/scheduler/__init__.py +9 -1
  68. siliconcompiler/scheduler/docker.py +81 -4
  69. siliconcompiler/scheduler/run_node.py +37 -20
  70. siliconcompiler/scheduler/scheduler.py +211 -36
  71. siliconcompiler/scheduler/schedulernode.py +394 -60
  72. siliconcompiler/scheduler/send_messages.py +77 -29
  73. siliconcompiler/scheduler/slurm.py +76 -12
  74. siliconcompiler/scheduler/taskscheduler.py +142 -21
  75. siliconcompiler/schema/__init__.py +0 -4
  76. siliconcompiler/schema/baseschema.py +338 -59
  77. siliconcompiler/schema/editableschema.py +14 -6
  78. siliconcompiler/schema/journal.py +28 -17
  79. siliconcompiler/schema/namedschema.py +22 -14
  80. siliconcompiler/schema/parameter.py +89 -28
  81. siliconcompiler/schema/parametertype.py +2 -0
  82. siliconcompiler/schema/parametervalue.py +258 -15
  83. siliconcompiler/schema/safeschema.py +25 -2
  84. siliconcompiler/schema/schema_cfg.py +23 -19
  85. siliconcompiler/schema/utils.py +2 -2
  86. siliconcompiler/schema_obj.py +24 -5
  87. siliconcompiler/tool.py +1131 -265
  88. siliconcompiler/tools/bambu/__init__.py +41 -0
  89. siliconcompiler/tools/builtin/concatenate.py +2 -2
  90. siliconcompiler/tools/builtin/minimum.py +2 -1
  91. siliconcompiler/tools/builtin/mux.py +2 -1
  92. siliconcompiler/tools/builtin/nop.py +2 -1
  93. siliconcompiler/tools/builtin/verify.py +2 -1
  94. siliconcompiler/tools/klayout/__init__.py +95 -0
  95. siliconcompiler/tools/openroad/__init__.py +289 -0
  96. siliconcompiler/tools/openroad/scripts/apr/preamble.tcl +3 -0
  97. siliconcompiler/tools/openroad/scripts/apr/sc_detailed_route.tcl +7 -2
  98. siliconcompiler/tools/openroad/scripts/apr/sc_global_route.tcl +8 -4
  99. siliconcompiler/tools/openroad/scripts/apr/sc_init_floorplan.tcl +9 -5
  100. siliconcompiler/tools/openroad/scripts/common/write_images.tcl +5 -1
  101. siliconcompiler/tools/slang/__init__.py +1 -1
  102. siliconcompiler/tools/slang/elaborate.py +2 -1
  103. siliconcompiler/tools/vivado/scripts/sc_run.tcl +1 -1
  104. siliconcompiler/tools/vivado/scripts/sc_syn_fpga.tcl +8 -1
  105. siliconcompiler/tools/vivado/syn_fpga.py +6 -0
  106. siliconcompiler/tools/vivado/vivado.py +35 -2
  107. siliconcompiler/tools/vpr/__init__.py +150 -0
  108. siliconcompiler/tools/yosys/__init__.py +369 -1
  109. siliconcompiler/tools/yosys/scripts/procs.tcl +0 -1
  110. siliconcompiler/toolscripts/_tools.json +5 -10
  111. siliconcompiler/utils/__init__.py +66 -0
  112. siliconcompiler/utils/flowgraph.py +2 -2
  113. siliconcompiler/utils/issue.py +2 -1
  114. siliconcompiler/utils/logging.py +14 -0
  115. siliconcompiler/utils/multiprocessing.py +256 -0
  116. siliconcompiler/utils/showtools.py +10 -0
  117. {siliconcompiler-0.34.1.dist-info → siliconcompiler-0.34.3.dist-info}/METADATA +6 -6
  118. {siliconcompiler-0.34.1.dist-info → siliconcompiler-0.34.3.dist-info}/RECORD +122 -115
  119. {siliconcompiler-0.34.1.dist-info → siliconcompiler-0.34.3.dist-info}/entry_points.txt +3 -0
  120. siliconcompiler/schema/cmdlineschema.py +0 -250
  121. siliconcompiler/schema/packageschema.py +0 -101
  122. siliconcompiler/toolscripts/rhel8/install-slang.sh +0 -40
  123. siliconcompiler/toolscripts/rhel9/install-slang.sh +0 -40
  124. siliconcompiler/toolscripts/ubuntu20/install-slang.sh +0 -47
  125. siliconcompiler/toolscripts/ubuntu22/install-slang.sh +0 -37
  126. siliconcompiler/toolscripts/ubuntu24/install-slang.sh +0 -37
  127. {siliconcompiler-0.34.1.dist-info → siliconcompiler-0.34.3.dist-info}/WHEEL +0 -0
  128. {siliconcompiler-0.34.1.dist-info → siliconcompiler-0.34.3.dist-info}/licenses/LICENSE +0 -0
  129. {siliconcompiler-0.34.1.dist-info → siliconcompiler-0.34.3.dist-info}/top_level.txt +0 -0
siliconcompiler/record.py CHANGED
@@ -18,11 +18,17 @@ from siliconcompiler import _metadata
18
18
 
19
19
 
20
20
  class RecordTime(Enum):
21
+ """
22
+ Enumeration of time record types.
23
+ """
21
24
  START = "starttime"
22
25
  END = "endtime"
23
26
 
24
27
 
25
28
  class RecordTool(Enum):
29
+ """
30
+ Enumeration of tool record types.
31
+ """
26
32
  EXITCODE = "toolexitcode"
27
33
  VERSION = "toolversion"
28
34
  PATH = "toolpath"
@@ -30,14 +36,31 @@ class RecordTool(Enum):
30
36
 
31
37
 
32
38
  class RecordSchema(BaseSchema):
39
+ """
40
+ A class for managing run record data.
41
+ """
33
42
  __TIMEFORMAT = "%Y-%m-%d %H:%M:%S.%f"
34
43
 
35
44
  def __init__(self):
45
+ """
46
+ Initializes the RecordSchema object.
47
+ """
36
48
  super().__init__()
37
49
 
38
50
  schema_record(self)
39
51
 
40
52
  def _from_dict(self, manifest, keypath, version=None):
53
+ """
54
+ Constructs a schema from a dictionary.
55
+
56
+ Args:
57
+ manifest (dict): Dictionary to construct from.
58
+ keypath (list): List of keys representing the path to the current dictionary.
59
+ version (str, optional): Version of the manifest. Defaults to None.
60
+
61
+ Returns:
62
+ dict: The constructed dictionary.
63
+ """
41
64
  ret = super()._from_dict(manifest, keypath, version)
42
65
 
43
66
  # Correct for change specification
@@ -51,7 +74,7 @@ class RecordSchema(BaseSchema):
51
74
 
52
75
  def clear(self, step, index, keep=None):
53
76
  '''
54
- Clear all saved metrics for a given step and index
77
+ Clear all saved metrics for a given step and index.
55
78
 
56
79
  Args:
57
80
  step (str): Step name to clear.
@@ -339,11 +362,25 @@ class RecordSchema(BaseSchema):
339
362
  info = shlex.join(info)
340
363
  self.set(type.value, info, step=step, index=index)
341
364
 
365
+ @classmethod
366
+ def _getdict_type(cls) -> str:
367
+ """
368
+ Returns the meta data for getdict
369
+ """
370
+
371
+ return RecordSchema.__name__
372
+
342
373
 
343
374
  ###########################################################################
344
375
  # Run Record
345
376
  ###########################################################################
346
377
  def schema_record(schema):
378
+ """
379
+ Adds record schema parameters to the given schema.
380
+
381
+ Args:
382
+ schema (EditableSchema): The schema to modify.
383
+ """
347
384
  schema = EditableSchema(schema)
348
385
  records = {'userid': ['userid',
349
386
  'wiley',
@@ -36,12 +36,15 @@ class JobStatus():
36
36
  UNKNOWN = "unknown"
37
37
 
38
38
 
39
- from siliconcompiler.remote.client import Client, ConfigureClient # noqa E402
39
+ from siliconcompiler.remote.client import Client, ConfigureClient, ClientScheduler # noqa E402
40
+ from siliconcompiler.remote.server import Server # noqa E402
40
41
 
41
42
 
42
43
  __all__ = [
43
44
  "NodeStatus",
44
45
  "JobStatus",
45
46
  "Client",
46
- "ConfigureClient"
47
+ "ConfigureClient",
48
+ "ClientScheduler",
49
+ "Server"
47
50
  ]
@@ -1,34 +1,37 @@
1
1
  # Copyright 2020 Silicon Compiler Authors. All Rights Reserved.
2
2
 
3
3
  import json
4
+ import multiprocessing
4
5
  import os
5
6
  import requests
6
7
  import shutil
7
8
  import time
8
- import urllib.parse
9
9
  import tarfile
10
10
  import tempfile
11
- import multiprocessing
12
11
 
13
12
  import os.path
13
+ import urllib.parse
14
14
 
15
15
  from siliconcompiler import utils, SiliconCompilerError
16
16
  from siliconcompiler import NodeStatus as SCNodeStatus
17
+
17
18
  from siliconcompiler._metadata import default_server
18
- from siliconcompiler.remote import JobStatus, NodeStatus
19
- from siliconcompiler.report.dashboard import DashboardType
20
19
  from siliconcompiler.flowgraph import RuntimeFlowgraph
21
- from siliconcompiler.scheduler.scheduler import Scheduler
20
+ from siliconcompiler.report.dashboard import DashboardType
21
+ from siliconcompiler.scheduler import Scheduler
22
22
  from siliconcompiler.schema import Journal
23
+
23
24
  from siliconcompiler.utils.logging import get_console_formatter
24
25
 
26
+ from siliconcompiler.remote import JobStatus, NodeStatus
27
+
25
28
  # Step name to use while logging
26
29
  remote_step_name = 'remote'
27
30
 
28
31
 
29
32
  class ClientScheduler(Scheduler):
30
33
  def run_core(self):
31
- Client(self._Scheduler__chip).run()
34
+ Client(self.project).run()
32
35
 
33
36
  def configure_nodes(self):
34
37
  return
@@ -732,6 +735,8 @@ service, provided by SiliconCompiler, is not intended to process proprietary IP.
732
735
 
733
736
  # Done: try to fetch any node results which still haven't been retrieved.
734
737
  self.__logger.info('Remote job completed! Retrieving final results...')
738
+ if not self.__setup_information_fetched:
739
+ self.__schedule_fetch_result(None)
735
740
  for node, node_info in self.__node_information.items():
736
741
  if not node_info["fetched"]:
737
742
  self.__schedule_fetch_result(node)
@@ -1,13 +1,11 @@
1
- from siliconcompiler.schema import BaseSchema
2
- from siliconcompiler.schema import CommandLineSchema
3
- from siliconcompiler.schema import EditableSchema
4
- from siliconcompiler.schema import Parameter, Scope
1
+ from siliconcompiler.schema import BaseSchema, EditableSchema, Parameter, Scope
2
+ from siliconcompiler.cmdlineschema import CommandLineSchema
5
3
 
6
4
 
7
- SCHEMA_VERSION = '0.0.2'
5
+ SCHEMA_VERSION = '0.0.3'
8
6
 
9
7
 
10
- class ServerSchema(BaseSchema, CommandLineSchema):
8
+ class ServerSchema(CommandLineSchema, BaseSchema):
11
9
  def __init__(self):
12
10
  super().__init__()
13
11
 
@@ -57,7 +55,7 @@ class ServerSchema(BaseSchema, CommandLineSchema):
57
55
  Parameter(
58
56
  'dir',
59
57
  scope=Scope.GLOBAL,
60
- defvalue='/nfs/sc_compute',
58
+ defvalue='./sc_compute',
61
59
  require='all',
62
60
  shorthelp="Directory of mounted shared NFS storage.",
63
61
  switch="-nfsmount <dir>",
@@ -78,22 +76,6 @@ class ServerSchema(BaseSchema, CommandLineSchema):
78
76
  "api: server.set('option', 'auth', True)"],
79
77
  help="""Flag determining whether to enable authenticated and encrypted jobs."""))
80
78
 
81
- schema.insert(
82
- 'option', 'cfg',
83
- Parameter(
84
- '[file]',
85
- scope=Scope.JOB,
86
- shorthelp="Configuration manifest",
87
- switch="-cfg <file>",
88
- example=["cli: -cfg mypdk.json",
89
- "api: chip.set('option', 'cfg', 'mypdk.json')"],
90
- help="""
91
- List of filepaths to JSON formatted schema configuration
92
- manifests. The files are read in automatically when using the
93
- command line application. In Python programs, JSON manifests
94
- can be merged into the current working manifest using the
95
- read_manifest() method."""))
96
-
97
79
  schema.insert(
98
80
  'option', 'loglevel',
99
81
  Parameter(
@@ -1,31 +1,35 @@
1
1
  # Copyright 2020 Silicon Compiler Authors. All Rights Reserved.
2
2
 
3
- from aiohttp import web
4
3
  import copy
5
- import threading
4
+ import fastjsonschema
6
5
  import json
7
- import logging as log
6
+ import logging
8
7
  import os
9
8
  import shutil
10
- import uuid
11
- import tarfile
12
9
  import sys
13
- import fastjsonschema
10
+ import tarfile
11
+ import threading
12
+ import uuid
13
+
14
+ from aiohttp import web
14
15
  from pathlib import Path
15
16
  from fastjsonschema import JsonSchemaException
16
17
 
17
18
  import os.path
18
19
 
19
20
  from siliconcompiler import Chip, Schema
20
- from siliconcompiler.schema import utils as schema_utils
21
+ from siliconcompiler import NodeStatus as SCNodeStatus
21
22
  from siliconcompiler._metadata import version as sc_version
23
+
24
+ from siliconcompiler.schema import utils as schema_utils
22
25
  from siliconcompiler.schema import SCHEMA_VERSION as sc_schema_version
23
- from siliconcompiler.remote.schema import ServerSchema
24
- from siliconcompiler.remote import banner, JobStatus
25
- from siliconcompiler import NodeStatus as SCNodeStatus
26
- from siliconcompiler.remote import NodeStatus
26
+
27
27
  from siliconcompiler.flowgraph import RuntimeFlowgraph
28
- from siliconcompiler.scheduler.taskscheduler import TaskScheduler
28
+ from siliconcompiler.scheduler import SchedulerNode
29
+ from siliconcompiler.scheduler import TaskScheduler
30
+
31
+ from siliconcompiler.remote import JobStatus, NodeStatus
32
+ from siliconcompiler.remote.schema import ServerSchema
29
33
 
30
34
 
31
35
  # Compile validation code for API request bodies.
@@ -57,7 +61,7 @@ with open(api_dir / 'get_results.json') as schema:
57
61
  validate_get_results = fastjsonschema.compile(json.loads(schema.read()))
58
62
 
59
63
 
60
- class Server:
64
+ class Server(ServerSchema):
61
65
  """
62
66
  The core class for the siliconcompiler 'gateway' server, which can run
63
67
  locally or on a remote host. Its job is to process requests for
@@ -74,26 +78,21 @@ class Server:
74
78
  Init method for Server object
75
79
  '''
76
80
 
81
+ super().__init__()
82
+
77
83
  # Initialize logger
78
- self.logger = log.getLogger(f'sc_server_{id(self)}')
79
- handler = log.StreamHandler(stream=sys.stdout)
80
- formatter = log.Formatter('%(asctime)s | %(levelname)-8s | %(message)s')
84
+ self.logger = logging.getLogger(f'sc_server_{uuid.uuid4().hex}')
85
+ handler = logging.StreamHandler(stream=sys.stdout)
86
+ formatter = logging.Formatter('%(asctime)s | %(levelname)-8s | %(message)s')
81
87
  handler.setFormatter(formatter)
82
88
  self.logger.addHandler(handler)
83
89
  self.logger.setLevel(schema_utils.translate_loglevel(loglevel))
84
90
 
85
- self.schema = ServerSchema()
86
-
87
91
  # Set up a dictionary to track running jobs.
88
92
  self.sc_jobs_lock = threading.Lock()
89
93
  self.sc_jobs = {}
90
94
  self.sc_chip_lookup = {}
91
95
 
92
- # Register callbacks
93
- TaskScheduler.register_callback("pre_run", self.__run_start)
94
- TaskScheduler.register_callback("pre_node", self.__node_start)
95
- TaskScheduler.register_callback("post_node", self.__node_end)
96
-
97
96
  def __run_start(self, chip):
98
97
  flow = chip.get("option", "flow")
99
98
  nodes = chip.get("flowgraph", flow, field="schema").get_nodes()
@@ -135,15 +134,19 @@ class Server:
135
134
  job_hash,
136
135
  f'{job_hash}_{step}{index}.tar.gz'),
137
136
  mode='w:gz') as tf:
138
- chip._archive_node(tf, step=step, index=index, include="*")
137
+ SchedulerNode(chip, step, index).archive(tf, include="*")
139
138
 
140
139
  with self.sc_jobs_lock:
141
140
  self.sc_jobs[job_name][f"{step}{index}"]["status"] = \
142
141
  chip.get('record', 'status', step=step, index=index)
143
142
 
144
143
  def run(self):
144
+ if not os.path.exists(self.nfs_mount):
145
+ os.makedirs(self.nfs_mount, exist_ok=True)
145
146
  if not os.path.exists(self.nfs_mount):
146
147
  raise FileNotFoundError(f'{self.nfs_mount} could not be found.')
148
+ with open(os.path.join(self.nfs_mount, ".gitignore"), "w") as f:
149
+ f.write("*")
147
150
 
148
151
  self.logger.info(f"Running in: {self.nfs_mount}")
149
152
  # If authentication is enabled, try connecting to the SQLite3 database.
@@ -176,6 +179,11 @@ class Server:
176
179
  "file in the server's working directory. "
177
180
  "(User : Key) mappings were not imported.")
178
181
 
182
+ # Register callbacks
183
+ TaskScheduler.register_callback("pre_run", self.__run_start)
184
+ TaskScheduler.register_callback("pre_node", self.__node_start)
185
+ TaskScheduler.register_callback("post_node", self.__node_end)
186
+
179
187
  # Create a minimal web server to process the 'remote_run' API call.
180
188
  self.app = web.Application()
181
189
  self.app.add_routes([
@@ -194,21 +202,6 @@ class Server:
194
202
  # Start the async server.
195
203
  web.run_app(self.app, port=self.get('option', 'port'))
196
204
 
197
- def create_cmdline(self, progname, description=None, switchlist=None, additional_args=None):
198
- def print_banner():
199
- print(banner)
200
- print("Version:", Server.__version__, "\n")
201
- print("-" * 80)
202
-
203
- return self.schema.create_cmdline(
204
- progname=progname,
205
- description=description,
206
- switchlist=switchlist,
207
- additional_args=additional_args,
208
- version=Server.__version__,
209
- print_banner=print_banner,
210
- logger=self.logger)
211
-
212
205
  ####################
213
206
  async def handle_remote_run(self, request):
214
207
  '''
@@ -284,6 +277,15 @@ class Server:
284
277
  # Remove 'remote' JSON config value to run locally on compute node.
285
278
  chip.set('option', 'remote', False)
286
279
 
280
+ # Mark as nodisplay since it is a remote run
281
+ chip.set('option', 'nodisplay', True)
282
+
283
+ # Mark as quite to make server logging easier
284
+ chip.set('option', 'quiet', True)
285
+
286
+ # Log job received
287
+ self.logger.info(f"Received job: {job_hash}")
288
+
287
289
  # Run the job with the configured clustering option. (Non-blocking)
288
290
  job_proc = threading.Thread(target=self.remote_sc,
289
291
  args=[
@@ -543,18 +545,3 @@ class Server:
543
545
  @property
544
546
  def checkinterval(self):
545
547
  return self.get('option', 'checkinterval')
546
-
547
- def get(self, *keypath, field='value'):
548
- return self.schema.get(*keypath, field=field)
549
-
550
- def set(self, *args, field='value', clobber=True):
551
- keypath = args[:-1]
552
- value = args[-1]
553
-
554
- if keypath == ['option', 'loglevel'] and field == 'value':
555
- self.logger.setLevel(schema_utils.translate_loglevel(value))
556
-
557
- self.schema.set(*keypath, value, field=field, clobber=clobber)
558
-
559
- def write_configuration(self, filepath):
560
- self.schema.write_manifest(filepath)
@@ -1,8 +1,7 @@
1
- from .summary_image import _generate_summary_image, _open_summary_image
1
+ from .summary_image import _generate_summary_image, _open_summary_image, generate_summary_image
2
2
  from .html_report import _generate_html_report, _open_html_report
3
3
  from .summary_table import _show_summary_table
4
4
  from .dashboard.web import WebDashboard
5
- # from .dashboard import Dashboard
6
5
 
7
6
  __all__ = [
8
7
  "_generate_summary_image",
@@ -10,5 +9,6 @@ __all__ = [
10
9
  "_generate_html_report",
11
10
  "_open_html_report",
12
11
  "_show_summary_table",
13
- "WebDashboard"
12
+ "WebDashboard",
13
+ "generate_summary_image"
14
14
  ]
@@ -3,6 +3,16 @@ from enum import Enum
3
3
 
4
4
 
5
5
  class DashboardType(Enum):
6
+ """
7
+ An enumeration to represent the available types of dashboards.
8
+
9
+ This allows for a standardized way to specify whether to launch a
10
+ web-based dashboard or a command-line interface (CLI) dashboard.
11
+
12
+ Attributes:
13
+ WEB: Represents a web-based dashboard.
14
+ CLI: Represents a command-line interface dashboard.
15
+ """
6
16
  WEB = 'web'
7
17
  CLI = 'cli'
8
18
 
@@ -10,72 +20,96 @@ class DashboardType(Enum):
10
20
  class AbstractDashboard(ABC):
11
21
  """
12
22
  Abstract base class defining the interface for dashboard implementations.
13
- Any concrete dashboard implementation should inherit from this class and
14
- implement all abstract methods.
23
+
24
+ This class establishes a contract for all concrete dashboard classes,
25
+ such as `CliDashboard` or a future `WebDashboard`. It ensures that any
26
+ dashboard implementation will have a consistent set of methods for
27
+ starting, stopping, and updating its state, regardless of its specific
28
+ rendering technology (e.g., terminal UI or web browser).
15
29
  """
16
30
 
17
31
  @abstractmethod
18
32
  def __init__(self, chip):
19
33
  """
20
- Initialize the dashboard.
34
+ Initializes the dashboard with a reference to the chip object.
21
35
 
22
36
  Args:
23
- chip: The chip object to display in the dashboard
37
+ chip: The SiliconCompiler chip object whose data will be displayed
38
+ by the dashboard.
24
39
  """
25
40
  self._chip = chip
26
41
 
27
42
  @abstractmethod
28
43
  def open_dashboard(self):
29
44
  """
30
- Open and start the dashboard service.
45
+ Opens and starts the dashboard service.
46
+
47
+ This method should handle all setup required to make the dashboard
48
+ visible and active, such as starting a rendering thread or a web server.
31
49
  """
32
50
  pass
33
51
 
34
52
  @abstractmethod
35
53
  def update_manifest(self, payload=None):
36
54
  """
37
- Update the manifest file with the latest chip information.
55
+ Updates the dashboard with the latest information from the chip's manifest.
56
+
57
+ This method is the primary mechanism for pushing new data to the
58
+ dashboard as the compilation flow progresses.
38
59
 
39
60
  Args:
40
- payload (dict): Dictionary of metadata to pass along to dashboard.
41
- {"starttimes" {<node>: time, ...}}
61
+ payload (dict, optional): A dictionary of metadata to pass to the
62
+ dashboard. A common use is to provide node start times, e.g.,
63
+ `{"starttimes": {<node_tuple>: time, ...}}`. Defaults to None.
42
64
  """
43
65
  pass
44
66
 
45
67
  @abstractmethod
46
68
  def update_graph_manifests(self):
47
69
  """
48
- Update the manifest files for all graph chips.
70
+ Updates the manifest files for all associated graph chips.
71
+
72
+ This is intended for scenarios where a dashboard might need to display
73
+ data from multiple, related chip objects (e.g., in a multi-job run).
49
74
  """
50
75
  pass
51
76
 
52
77
  @abstractmethod
53
78
  def is_running(self):
54
79
  """
55
- Check if the dashboard is currently running.
80
+ Checks if the dashboard service is currently active.
56
81
 
57
82
  Returns:
58
- bool: True if the dashboard is running, False otherwise
83
+ bool: True if the dashboard is running, False otherwise.
59
84
  """
60
85
  pass
61
86
 
62
87
  @abstractmethod
63
88
  def end_of_run(self):
64
89
  """
65
- Announce that a run has completed
90
+ Notifies the dashboard that a compilation run has completed.
91
+
92
+ This allows the dashboard to perform any final updates or cleanup
93
+ actions, such as displaying a final summary.
66
94
  """
67
95
  pass
68
96
 
69
97
  @abstractmethod
70
98
  def stop(self):
71
99
  """
72
- Stop the dashboard service if it's running.
100
+ Stops the dashboard service if it's running.
101
+
102
+ This method should gracefully shut down any background processes,
103
+ threads, or servers associated with the dashboard.
73
104
  """
74
105
  pass
75
106
 
76
107
  @abstractmethod
77
108
  def wait(self):
78
109
  """
79
- Wait for the dashboard service to terminate.
110
+ Waits for the dashboard service to terminate.
111
+
112
+ This is a blocking call that should not return until the dashboard
113
+ has fully shut down. It is useful for ensuring a clean exit.
80
114
  """
81
115
  pass