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.
- siliconcompiler/__init__.py +23 -4
- siliconcompiler/__main__.py +1 -7
- siliconcompiler/_metadata.py +1 -1
- siliconcompiler/apps/_common.py +104 -23
- siliconcompiler/apps/sc.py +4 -8
- siliconcompiler/apps/sc_dashboard.py +6 -4
- siliconcompiler/apps/sc_install.py +10 -6
- siliconcompiler/apps/sc_issue.py +7 -5
- siliconcompiler/apps/sc_remote.py +1 -1
- siliconcompiler/apps/sc_server.py +9 -14
- siliconcompiler/apps/sc_show.py +7 -6
- siliconcompiler/apps/smake.py +130 -94
- siliconcompiler/apps/utils/replay.py +4 -7
- siliconcompiler/apps/utils/summarize.py +3 -5
- siliconcompiler/asic.py +420 -0
- siliconcompiler/checklist.py +25 -2
- siliconcompiler/cmdlineschema.py +534 -0
- siliconcompiler/constraints/__init__.py +17 -0
- siliconcompiler/constraints/asic_component.py +378 -0
- siliconcompiler/constraints/asic_floorplan.py +449 -0
- siliconcompiler/constraints/asic_pins.py +489 -0
- siliconcompiler/constraints/asic_timing.py +517 -0
- siliconcompiler/core.py +10 -35
- siliconcompiler/data/templates/tcl/manifest.tcl.j2 +8 -0
- siliconcompiler/dependencyschema.py +96 -202
- siliconcompiler/design.py +327 -241
- siliconcompiler/filesetschema.py +250 -0
- siliconcompiler/flowgraph.py +298 -106
- siliconcompiler/fpga.py +124 -1
- siliconcompiler/library.py +331 -0
- siliconcompiler/metric.py +327 -92
- siliconcompiler/metrics/__init__.py +7 -0
- siliconcompiler/metrics/asic.py +245 -0
- siliconcompiler/metrics/fpga.py +220 -0
- siliconcompiler/package/__init__.py +391 -67
- siliconcompiler/package/git.py +92 -16
- siliconcompiler/package/github.py +114 -22
- siliconcompiler/package/https.py +79 -16
- siliconcompiler/packageschema.py +341 -16
- siliconcompiler/pathschema.py +255 -0
- siliconcompiler/pdk.py +566 -1
- siliconcompiler/project.py +1460 -0
- siliconcompiler/record.py +38 -1
- siliconcompiler/remote/__init__.py +5 -2
- siliconcompiler/remote/client.py +11 -6
- siliconcompiler/remote/schema.py +5 -23
- siliconcompiler/remote/server.py +41 -54
- siliconcompiler/report/__init__.py +3 -3
- siliconcompiler/report/dashboard/__init__.py +48 -14
- siliconcompiler/report/dashboard/cli/__init__.py +99 -21
- siliconcompiler/report/dashboard/cli/board.py +364 -179
- siliconcompiler/report/dashboard/web/__init__.py +90 -12
- siliconcompiler/report/dashboard/web/components/__init__.py +219 -240
- siliconcompiler/report/dashboard/web/components/flowgraph.py +49 -26
- siliconcompiler/report/dashboard/web/components/graph.py +139 -100
- siliconcompiler/report/dashboard/web/layouts/__init__.py +29 -1
- siliconcompiler/report/dashboard/web/layouts/_common.py +38 -2
- siliconcompiler/report/dashboard/web/layouts/vertical_flowgraph.py +39 -26
- siliconcompiler/report/dashboard/web/layouts/vertical_flowgraph_node_tab.py +50 -50
- siliconcompiler/report/dashboard/web/layouts/vertical_flowgraph_sac_tabs.py +49 -46
- siliconcompiler/report/dashboard/web/state.py +141 -14
- siliconcompiler/report/dashboard/web/utils/__init__.py +79 -16
- siliconcompiler/report/dashboard/web/utils/file_utils.py +74 -11
- siliconcompiler/report/dashboard/web/viewer.py +25 -1
- siliconcompiler/report/report.py +5 -2
- siliconcompiler/report/summary_image.py +29 -11
- siliconcompiler/scheduler/__init__.py +9 -1
- siliconcompiler/scheduler/docker.py +81 -4
- siliconcompiler/scheduler/run_node.py +37 -20
- siliconcompiler/scheduler/scheduler.py +211 -36
- siliconcompiler/scheduler/schedulernode.py +394 -60
- siliconcompiler/scheduler/send_messages.py +77 -29
- siliconcompiler/scheduler/slurm.py +76 -12
- siliconcompiler/scheduler/taskscheduler.py +142 -21
- siliconcompiler/schema/__init__.py +0 -4
- siliconcompiler/schema/baseschema.py +338 -59
- siliconcompiler/schema/editableschema.py +14 -6
- siliconcompiler/schema/journal.py +28 -17
- siliconcompiler/schema/namedschema.py +22 -14
- siliconcompiler/schema/parameter.py +89 -28
- siliconcompiler/schema/parametertype.py +2 -0
- siliconcompiler/schema/parametervalue.py +258 -15
- siliconcompiler/schema/safeschema.py +25 -2
- siliconcompiler/schema/schema_cfg.py +23 -19
- siliconcompiler/schema/utils.py +2 -2
- siliconcompiler/schema_obj.py +24 -5
- siliconcompiler/tool.py +1131 -265
- siliconcompiler/tools/bambu/__init__.py +41 -0
- siliconcompiler/tools/builtin/concatenate.py +2 -2
- siliconcompiler/tools/builtin/minimum.py +2 -1
- siliconcompiler/tools/builtin/mux.py +2 -1
- siliconcompiler/tools/builtin/nop.py +2 -1
- siliconcompiler/tools/builtin/verify.py +2 -1
- siliconcompiler/tools/klayout/__init__.py +95 -0
- siliconcompiler/tools/openroad/__init__.py +289 -0
- siliconcompiler/tools/openroad/scripts/apr/preamble.tcl +3 -0
- siliconcompiler/tools/openroad/scripts/apr/sc_detailed_route.tcl +7 -2
- siliconcompiler/tools/openroad/scripts/apr/sc_global_route.tcl +8 -4
- siliconcompiler/tools/openroad/scripts/apr/sc_init_floorplan.tcl +9 -5
- siliconcompiler/tools/openroad/scripts/common/write_images.tcl +5 -1
- siliconcompiler/tools/slang/__init__.py +1 -1
- siliconcompiler/tools/slang/elaborate.py +2 -1
- siliconcompiler/tools/vivado/scripts/sc_run.tcl +1 -1
- siliconcompiler/tools/vivado/scripts/sc_syn_fpga.tcl +8 -1
- siliconcompiler/tools/vivado/syn_fpga.py +6 -0
- siliconcompiler/tools/vivado/vivado.py +35 -2
- siliconcompiler/tools/vpr/__init__.py +150 -0
- siliconcompiler/tools/yosys/__init__.py +369 -1
- siliconcompiler/tools/yosys/scripts/procs.tcl +0 -1
- siliconcompiler/toolscripts/_tools.json +5 -10
- siliconcompiler/utils/__init__.py +66 -0
- siliconcompiler/utils/flowgraph.py +2 -2
- siliconcompiler/utils/issue.py +2 -1
- siliconcompiler/utils/logging.py +14 -0
- siliconcompiler/utils/multiprocessing.py +256 -0
- siliconcompiler/utils/showtools.py +10 -0
- {siliconcompiler-0.34.1.dist-info → siliconcompiler-0.34.3.dist-info}/METADATA +6 -6
- {siliconcompiler-0.34.1.dist-info → siliconcompiler-0.34.3.dist-info}/RECORD +122 -115
- {siliconcompiler-0.34.1.dist-info → siliconcompiler-0.34.3.dist-info}/entry_points.txt +3 -0
- siliconcompiler/schema/cmdlineschema.py +0 -250
- siliconcompiler/schema/packageschema.py +0 -101
- siliconcompiler/toolscripts/rhel8/install-slang.sh +0 -40
- siliconcompiler/toolscripts/rhel9/install-slang.sh +0 -40
- siliconcompiler/toolscripts/ubuntu20/install-slang.sh +0 -47
- siliconcompiler/toolscripts/ubuntu22/install-slang.sh +0 -37
- siliconcompiler/toolscripts/ubuntu24/install-slang.sh +0 -37
- {siliconcompiler-0.34.1.dist-info → siliconcompiler-0.34.3.dist-info}/WHEEL +0 -0
- {siliconcompiler-0.34.1.dist-info → siliconcompiler-0.34.3.dist-info}/licenses/LICENSE +0 -0
- {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
|
]
|
siliconcompiler/remote/client.py
CHANGED
|
@@ -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.
|
|
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.
|
|
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)
|
siliconcompiler/remote/schema.py
CHANGED
|
@@ -1,13 +1,11 @@
|
|
|
1
|
-
from siliconcompiler.schema import BaseSchema
|
|
2
|
-
from siliconcompiler.
|
|
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.
|
|
5
|
+
SCHEMA_VERSION = '0.0.3'
|
|
8
6
|
|
|
9
7
|
|
|
10
|
-
class ServerSchema(
|
|
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='
|
|
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(
|
siliconcompiler/remote/server.py
CHANGED
|
@@ -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
|
|
4
|
+
import fastjsonschema
|
|
6
5
|
import json
|
|
7
|
-
import logging
|
|
6
|
+
import logging
|
|
8
7
|
import os
|
|
9
8
|
import shutil
|
|
10
|
-
import uuid
|
|
11
|
-
import tarfile
|
|
12
9
|
import sys
|
|
13
|
-
import
|
|
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
|
|
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
|
-
|
|
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
|
|
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 =
|
|
79
|
-
handler =
|
|
80
|
-
formatter =
|
|
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
|
|
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
|
-
|
|
14
|
-
|
|
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
|
-
|
|
34
|
+
Initializes the dashboard with a reference to the chip object.
|
|
21
35
|
|
|
22
36
|
Args:
|
|
23
|
-
chip: The chip object
|
|
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
|
-
|
|
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
|
-
|
|
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):
|
|
41
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|