siliconcompiler 0.26.5__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 +24 -0
- siliconcompiler/__main__.py +12 -0
- siliconcompiler/_common.py +49 -0
- siliconcompiler/_metadata.py +36 -0
- siliconcompiler/apps/__init__.py +0 -0
- siliconcompiler/apps/_common.py +76 -0
- siliconcompiler/apps/sc.py +92 -0
- siliconcompiler/apps/sc_dashboard.py +94 -0
- siliconcompiler/apps/sc_issue.py +178 -0
- siliconcompiler/apps/sc_remote.py +199 -0
- siliconcompiler/apps/sc_server.py +39 -0
- siliconcompiler/apps/sc_show.py +142 -0
- siliconcompiler/apps/smake.py +232 -0
- siliconcompiler/checklists/__init__.py +0 -0
- siliconcompiler/checklists/oh_tapeout.py +41 -0
- siliconcompiler/core.py +3221 -0
- siliconcompiler/data/RobotoMono/LICENSE.txt +202 -0
- siliconcompiler/data/RobotoMono/RobotoMono-Regular.ttf +0 -0
- siliconcompiler/data/heartbeat.v +18 -0
- siliconcompiler/data/logo.png +0 -0
- siliconcompiler/flowgraph.py +570 -0
- siliconcompiler/flows/__init__.py +0 -0
- siliconcompiler/flows/_common.py +67 -0
- siliconcompiler/flows/asicflow.py +180 -0
- siliconcompiler/flows/asictopflow.py +38 -0
- siliconcompiler/flows/dvflow.py +86 -0
- siliconcompiler/flows/fpgaflow.py +202 -0
- siliconcompiler/flows/generate_openroad_rcx.py +66 -0
- siliconcompiler/flows/lintflow.py +35 -0
- siliconcompiler/flows/screenshotflow.py +51 -0
- siliconcompiler/flows/showflow.py +59 -0
- siliconcompiler/flows/signoffflow.py +53 -0
- siliconcompiler/flows/synflow.py +128 -0
- siliconcompiler/fpgas/__init__.py +0 -0
- siliconcompiler/fpgas/lattice_ice40.py +42 -0
- siliconcompiler/fpgas/vpr_example.py +109 -0
- siliconcompiler/issue.py +300 -0
- siliconcompiler/libs/__init__.py +0 -0
- siliconcompiler/libs/asap7sc7p5t.py +8 -0
- siliconcompiler/libs/gf180mcu.py +8 -0
- siliconcompiler/libs/nangate45.py +8 -0
- siliconcompiler/libs/sky130hd.py +8 -0
- siliconcompiler/libs/sky130io.py +8 -0
- siliconcompiler/package.py +412 -0
- siliconcompiler/pdks/__init__.py +0 -0
- siliconcompiler/pdks/asap7.py +8 -0
- siliconcompiler/pdks/freepdk45.py +8 -0
- siliconcompiler/pdks/gf180.py +8 -0
- siliconcompiler/pdks/skywater130.py +8 -0
- siliconcompiler/remote/__init__.py +36 -0
- siliconcompiler/remote/client.py +891 -0
- siliconcompiler/remote/schema.py +106 -0
- siliconcompiler/remote/server.py +507 -0
- siliconcompiler/remote/server_schema/requests/cancel_job.json +51 -0
- siliconcompiler/remote/server_schema/requests/check_progress.json +61 -0
- siliconcompiler/remote/server_schema/requests/check_server.json +38 -0
- siliconcompiler/remote/server_schema/requests/delete_job.json +51 -0
- siliconcompiler/remote/server_schema/requests/get_results.json +48 -0
- siliconcompiler/remote/server_schema/requests/remote_run.json +40 -0
- siliconcompiler/remote/server_schema/responses/cancel_job.json +18 -0
- siliconcompiler/remote/server_schema/responses/check_progress.json +30 -0
- siliconcompiler/remote/server_schema/responses/check_server.json +32 -0
- siliconcompiler/remote/server_schema/responses/delete_job.json +18 -0
- siliconcompiler/remote/server_schema/responses/get_results.json +21 -0
- siliconcompiler/remote/server_schema/responses/remote_run.json +25 -0
- siliconcompiler/report/__init__.py +13 -0
- siliconcompiler/report/html_report.py +74 -0
- siliconcompiler/report/report.py +355 -0
- siliconcompiler/report/streamlit_report.py +137 -0
- siliconcompiler/report/streamlit_viewer.py +944 -0
- siliconcompiler/report/summary_image.py +117 -0
- siliconcompiler/report/summary_table.py +105 -0
- siliconcompiler/report/utils.py +163 -0
- siliconcompiler/scheduler/__init__.py +2092 -0
- siliconcompiler/scheduler/docker_runner.py +253 -0
- siliconcompiler/scheduler/run_node.py +138 -0
- siliconcompiler/scheduler/send_messages.py +178 -0
- siliconcompiler/scheduler/slurm.py +208 -0
- siliconcompiler/scheduler/validation/email_credentials.json +54 -0
- siliconcompiler/schema/__init__.py +7 -0
- siliconcompiler/schema/schema_cfg.py +4014 -0
- siliconcompiler/schema/schema_obj.py +1841 -0
- siliconcompiler/schema/utils.py +93 -0
- siliconcompiler/sphinx_ext/__init__.py +0 -0
- siliconcompiler/sphinx_ext/dynamicgen.py +1006 -0
- siliconcompiler/sphinx_ext/schemagen.py +221 -0
- siliconcompiler/sphinx_ext/utils.py +166 -0
- siliconcompiler/targets/__init__.py +0 -0
- siliconcompiler/targets/asap7_demo.py +68 -0
- siliconcompiler/targets/asic_demo.py +38 -0
- siliconcompiler/targets/fpgaflow_demo.py +47 -0
- siliconcompiler/targets/freepdk45_demo.py +59 -0
- siliconcompiler/targets/gf180_demo.py +77 -0
- siliconcompiler/targets/skywater130_demo.py +70 -0
- siliconcompiler/templates/email/general.j2 +66 -0
- siliconcompiler/templates/email/summary.j2 +43 -0
- siliconcompiler/templates/issue/README.txt +26 -0
- siliconcompiler/templates/issue/run.sh +6 -0
- siliconcompiler/templates/report/bootstrap.min.css +7 -0
- siliconcompiler/templates/report/bootstrap.min.js +7 -0
- siliconcompiler/templates/report/bootstrap_LICENSE.md +24 -0
- siliconcompiler/templates/report/sc_report.j2 +427 -0
- siliconcompiler/templates/slurm/run.sh +9 -0
- siliconcompiler/templates/tcl/manifest.tcl.j2 +137 -0
- siliconcompiler/tools/__init__.py +0 -0
- siliconcompiler/tools/_common/__init__.py +432 -0
- siliconcompiler/tools/_common/asic.py +115 -0
- siliconcompiler/tools/_common/sdc/sc_constraints.sdc +76 -0
- siliconcompiler/tools/_common/tcl/sc_pin_constraints.tcl +63 -0
- siliconcompiler/tools/bambu/bambu.py +32 -0
- siliconcompiler/tools/bambu/convert.py +77 -0
- siliconcompiler/tools/bluespec/bluespec.py +40 -0
- siliconcompiler/tools/bluespec/convert.py +103 -0
- siliconcompiler/tools/builtin/_common.py +155 -0
- siliconcompiler/tools/builtin/builtin.py +26 -0
- siliconcompiler/tools/builtin/concatenate.py +85 -0
- siliconcompiler/tools/builtin/join.py +27 -0
- siliconcompiler/tools/builtin/maximum.py +46 -0
- siliconcompiler/tools/builtin/minimum.py +57 -0
- siliconcompiler/tools/builtin/mux.py +70 -0
- siliconcompiler/tools/builtin/nop.py +38 -0
- siliconcompiler/tools/builtin/verify.py +83 -0
- siliconcompiler/tools/chisel/SCDriver.scala +10 -0
- siliconcompiler/tools/chisel/build.sbt +27 -0
- siliconcompiler/tools/chisel/chisel.py +37 -0
- siliconcompiler/tools/chisel/convert.py +140 -0
- siliconcompiler/tools/execute/exec_input.py +41 -0
- siliconcompiler/tools/execute/execute.py +17 -0
- siliconcompiler/tools/genfasm/bitstream.py +61 -0
- siliconcompiler/tools/genfasm/genfasm.py +40 -0
- siliconcompiler/tools/ghdl/convert.py +87 -0
- siliconcompiler/tools/ghdl/ghdl.py +41 -0
- siliconcompiler/tools/icarus/compile.py +87 -0
- siliconcompiler/tools/icarus/icarus.py +36 -0
- siliconcompiler/tools/icepack/bitstream.py +20 -0
- siliconcompiler/tools/icepack/icepack.py +43 -0
- siliconcompiler/tools/klayout/export.py +117 -0
- siliconcompiler/tools/klayout/klayout.py +119 -0
- siliconcompiler/tools/klayout/klayout_export.py +205 -0
- siliconcompiler/tools/klayout/klayout_operations.py +363 -0
- siliconcompiler/tools/klayout/klayout_show.py +242 -0
- siliconcompiler/tools/klayout/klayout_utils.py +176 -0
- siliconcompiler/tools/klayout/operations.py +194 -0
- siliconcompiler/tools/klayout/screenshot.py +98 -0
- siliconcompiler/tools/klayout/show.py +101 -0
- siliconcompiler/tools/magic/drc.py +49 -0
- siliconcompiler/tools/magic/extspice.py +19 -0
- siliconcompiler/tools/magic/magic.py +85 -0
- siliconcompiler/tools/magic/sc_drc.tcl +96 -0
- siliconcompiler/tools/magic/sc_extspice.tcl +54 -0
- siliconcompiler/tools/magic/sc_magic.tcl +47 -0
- siliconcompiler/tools/montage/montage.py +30 -0
- siliconcompiler/tools/montage/tile.py +66 -0
- siliconcompiler/tools/netgen/count_lvs.py +132 -0
- siliconcompiler/tools/netgen/lvs.py +90 -0
- siliconcompiler/tools/netgen/netgen.py +36 -0
- siliconcompiler/tools/netgen/sc_lvs.tcl +46 -0
- siliconcompiler/tools/nextpnr/apr.py +24 -0
- siliconcompiler/tools/nextpnr/nextpnr.py +59 -0
- siliconcompiler/tools/openfpgaloader/openfpgaloader.py +39 -0
- siliconcompiler/tools/openroad/__init__.py +0 -0
- siliconcompiler/tools/openroad/cts.py +45 -0
- siliconcompiler/tools/openroad/dfm.py +66 -0
- siliconcompiler/tools/openroad/export.py +131 -0
- siliconcompiler/tools/openroad/floorplan.py +70 -0
- siliconcompiler/tools/openroad/openroad.py +977 -0
- siliconcompiler/tools/openroad/physyn.py +27 -0
- siliconcompiler/tools/openroad/place.py +41 -0
- siliconcompiler/tools/openroad/rcx_bench.py +95 -0
- siliconcompiler/tools/openroad/rcx_extract.py +34 -0
- siliconcompiler/tools/openroad/route.py +45 -0
- siliconcompiler/tools/openroad/screenshot.py +60 -0
- siliconcompiler/tools/openroad/scripts/sc_apr.tcl +499 -0
- siliconcompiler/tools/openroad/scripts/sc_cts.tcl +64 -0
- siliconcompiler/tools/openroad/scripts/sc_dfm.tcl +20 -0
- siliconcompiler/tools/openroad/scripts/sc_export.tcl +98 -0
- siliconcompiler/tools/openroad/scripts/sc_floorplan.tcl +413 -0
- siliconcompiler/tools/openroad/scripts/sc_metrics.tcl +158 -0
- siliconcompiler/tools/openroad/scripts/sc_physyn.tcl +7 -0
- siliconcompiler/tools/openroad/scripts/sc_place.tcl +84 -0
- siliconcompiler/tools/openroad/scripts/sc_procs.tcl +423 -0
- siliconcompiler/tools/openroad/scripts/sc_rcx.tcl +63 -0
- siliconcompiler/tools/openroad/scripts/sc_rcx_bench.tcl +20 -0
- siliconcompiler/tools/openroad/scripts/sc_rcx_extract.tcl +12 -0
- siliconcompiler/tools/openroad/scripts/sc_route.tcl +133 -0
- siliconcompiler/tools/openroad/scripts/sc_screenshot.tcl +21 -0
- siliconcompiler/tools/openroad/scripts/sc_write.tcl +5 -0
- siliconcompiler/tools/openroad/scripts/sc_write_images.tcl +361 -0
- siliconcompiler/tools/openroad/show.py +94 -0
- siliconcompiler/tools/openroad/templates/pex.tcl +8 -0
- siliconcompiler/tools/opensta/__init__.py +101 -0
- siliconcompiler/tools/opensta/report_libraries.py +28 -0
- siliconcompiler/tools/opensta/scripts/sc_procs.tcl +47 -0
- siliconcompiler/tools/opensta/scripts/sc_report_libraries.tcl +74 -0
- siliconcompiler/tools/opensta/scripts/sc_timing.tcl +268 -0
- siliconcompiler/tools/opensta/timing.py +214 -0
- siliconcompiler/tools/slang/__init__.py +49 -0
- siliconcompiler/tools/slang/lint.py +101 -0
- siliconcompiler/tools/surelog/__init__.py +123 -0
- siliconcompiler/tools/surelog/parse.py +183 -0
- siliconcompiler/tools/surelog/templates/output.v +7 -0
- siliconcompiler/tools/sv2v/convert.py +46 -0
- siliconcompiler/tools/sv2v/sv2v.py +37 -0
- siliconcompiler/tools/template/template.py +125 -0
- siliconcompiler/tools/verilator/compile.py +139 -0
- siliconcompiler/tools/verilator/lint.py +19 -0
- siliconcompiler/tools/verilator/parse.py +27 -0
- siliconcompiler/tools/verilator/verilator.py +172 -0
- siliconcompiler/tools/vivado/__init__.py +7 -0
- siliconcompiler/tools/vivado/bitstream.py +21 -0
- siliconcompiler/tools/vivado/place.py +21 -0
- siliconcompiler/tools/vivado/route.py +21 -0
- siliconcompiler/tools/vivado/scripts/sc_bitstream.tcl +6 -0
- siliconcompiler/tools/vivado/scripts/sc_place.tcl +2 -0
- siliconcompiler/tools/vivado/scripts/sc_route.tcl +4 -0
- siliconcompiler/tools/vivado/scripts/sc_run.tcl +45 -0
- siliconcompiler/tools/vivado/scripts/sc_syn_fpga.tcl +25 -0
- siliconcompiler/tools/vivado/syn_fpga.py +20 -0
- siliconcompiler/tools/vivado/vivado.py +147 -0
- siliconcompiler/tools/vpr/_json_constraint.py +63 -0
- siliconcompiler/tools/vpr/_xml_constraint.py +109 -0
- siliconcompiler/tools/vpr/place.py +137 -0
- siliconcompiler/tools/vpr/route.py +124 -0
- siliconcompiler/tools/vpr/screenshot.py +54 -0
- siliconcompiler/tools/vpr/show.py +88 -0
- siliconcompiler/tools/vpr/vpr.py +357 -0
- siliconcompiler/tools/xyce/xyce.py +36 -0
- siliconcompiler/tools/yosys/lec.py +56 -0
- siliconcompiler/tools/yosys/prepareLib.py +59 -0
- siliconcompiler/tools/yosys/sc_lec.tcl +84 -0
- siliconcompiler/tools/yosys/sc_syn.tcl +79 -0
- siliconcompiler/tools/yosys/syn_asic.py +565 -0
- siliconcompiler/tools/yosys/syn_asic.tcl +377 -0
- siliconcompiler/tools/yosys/syn_asic_fpga_shared.tcl +31 -0
- siliconcompiler/tools/yosys/syn_fpga.py +146 -0
- siliconcompiler/tools/yosys/syn_fpga.tcl +233 -0
- siliconcompiler/tools/yosys/syn_strategies.tcl +81 -0
- siliconcompiler/tools/yosys/techmaps/lcu_kogge_stone.v +39 -0
- siliconcompiler/tools/yosys/templates/abc.const +2 -0
- siliconcompiler/tools/yosys/yosys.py +147 -0
- siliconcompiler/units.py +259 -0
- siliconcompiler/use.py +177 -0
- siliconcompiler/utils/__init__.py +423 -0
- siliconcompiler/utils/asic.py +158 -0
- siliconcompiler/utils/showtools.py +25 -0
- siliconcompiler-0.26.5.dist-info/LICENSE +190 -0
- siliconcompiler-0.26.5.dist-info/METADATA +195 -0
- siliconcompiler-0.26.5.dist-info/RECORD +251 -0
- siliconcompiler-0.26.5.dist-info/WHEEL +5 -0
- siliconcompiler-0.26.5.dist-info/entry_points.txt +12 -0
- siliconcompiler-0.26.5.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import shlex
|
|
3
|
+
import subprocess
|
|
4
|
+
import stat
|
|
5
|
+
import time
|
|
6
|
+
import uuid
|
|
7
|
+
import json
|
|
8
|
+
import shutil
|
|
9
|
+
from siliconcompiler import utils, SiliconCompilerError
|
|
10
|
+
from siliconcompiler.flowgraph import nodes_to_execute, _get_flowgraph_entry_nodes
|
|
11
|
+
from siliconcompiler.package import get_cache_path
|
|
12
|
+
|
|
13
|
+
# Full list of Slurm states, split into 'active' and 'inactive' categories.
|
|
14
|
+
# Many of these do not apply to a minimal configuration, but we'll track them all.
|
|
15
|
+
# https://slurm.schedmd.com/squeue.html#SECTION_JOB-STATE-CODES
|
|
16
|
+
SLURM_ACTIVE_STATES = [
|
|
17
|
+
'RUNNING',
|
|
18
|
+
'PENDING',
|
|
19
|
+
'CONFIGURING',
|
|
20
|
+
'COMPLETING',
|
|
21
|
+
'SIGNALING',
|
|
22
|
+
'STAGE_OUT',
|
|
23
|
+
'RESIZING',
|
|
24
|
+
'REQUEUED',
|
|
25
|
+
]
|
|
26
|
+
SLURM_INACTIVE_STATES = [
|
|
27
|
+
'BOOT_FAIL',
|
|
28
|
+
'CANCELLED',
|
|
29
|
+
'COMPLETED',
|
|
30
|
+
'DEADLINE',
|
|
31
|
+
'FAILED',
|
|
32
|
+
'NODE_FAIL',
|
|
33
|
+
'OUT_OF_MEMORY',
|
|
34
|
+
'PREEMPTED',
|
|
35
|
+
'RESV_DEL_HOLD',
|
|
36
|
+
'REQUEUE_FED',
|
|
37
|
+
'REQUEUE_HOLD',
|
|
38
|
+
'REVOKED',
|
|
39
|
+
'SPECIAL_EXIT',
|
|
40
|
+
'STOPPED',
|
|
41
|
+
'SUSPENDED',
|
|
42
|
+
'TIMEOUT',
|
|
43
|
+
]
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
###########################################################################
|
|
47
|
+
def get_configuration_directory(chip):
|
|
48
|
+
'''
|
|
49
|
+
Helper function to get the configuration directory for the scheduler
|
|
50
|
+
'''
|
|
51
|
+
|
|
52
|
+
return f'{chip.getworkdir()}/configs'
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def init(chip):
|
|
56
|
+
if os.path.exists(chip._getcollectdir()):
|
|
57
|
+
# nothing to do
|
|
58
|
+
return
|
|
59
|
+
|
|
60
|
+
collect = False
|
|
61
|
+
flow = chip.get('option', 'flow')
|
|
62
|
+
entry_nodes = _get_flowgraph_entry_nodes(chip, flow)
|
|
63
|
+
for (step, index) in nodes_to_execute(chip, flow):
|
|
64
|
+
if (step, index) in entry_nodes:
|
|
65
|
+
collect = True
|
|
66
|
+
|
|
67
|
+
if collect:
|
|
68
|
+
chip.collect()
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
###########################################################################
|
|
72
|
+
def _defernode(chip, step, index, replay):
|
|
73
|
+
'''
|
|
74
|
+
Helper method to run an individual step on a slurm cluster.
|
|
75
|
+
|
|
76
|
+
Blocks until the compute node
|
|
77
|
+
finishes processing this step, and it sets the active/error bits.
|
|
78
|
+
'''
|
|
79
|
+
|
|
80
|
+
# Determine which HPC job scheduler being used.
|
|
81
|
+
scheduler_type = chip.get('option', 'scheduler', 'name', step=step, index=index)
|
|
82
|
+
|
|
83
|
+
if scheduler_type != 'slurm':
|
|
84
|
+
raise ValueError(f'{scheduler_type} is not a supported scheduler')
|
|
85
|
+
|
|
86
|
+
if not check_slurm():
|
|
87
|
+
raise SiliconCompilerError('slurm is not available or installed on this machine', chip=chip)
|
|
88
|
+
|
|
89
|
+
# Determine which cluster parititon to use. (Default value can be overridden on per-step basis)
|
|
90
|
+
partition = chip.get('option', 'scheduler', 'queue', step=step, index=index)
|
|
91
|
+
if not partition:
|
|
92
|
+
partition = _get_slurm_partition()
|
|
93
|
+
|
|
94
|
+
# Get the temporary UID associated with this job run.
|
|
95
|
+
job_hash = chip.get('record', 'remoteid')
|
|
96
|
+
if not job_hash:
|
|
97
|
+
# Generate a new uuid since it was not set
|
|
98
|
+
job_hash = uuid.uuid4().hex
|
|
99
|
+
|
|
100
|
+
job_name = f'{job_hash}_{step}{index}'
|
|
101
|
+
|
|
102
|
+
# Write out the current schema for the compute node to pick up.
|
|
103
|
+
cfg_dir = get_configuration_directory(chip)
|
|
104
|
+
cfg_file = f'{cfg_dir}/{step}{index}.json'
|
|
105
|
+
log_file = f'{cfg_dir}/{step}{index}.log'
|
|
106
|
+
script_file = f'{cfg_dir}/{step}{index}.sh'
|
|
107
|
+
os.makedirs(cfg_dir, exist_ok=True)
|
|
108
|
+
|
|
109
|
+
chip.set('option', 'scheduler', 'name', None, step=step, index=index)
|
|
110
|
+
chip.write_manifest(cfg_file)
|
|
111
|
+
|
|
112
|
+
# Allow user-defined compute node execution script if it already exists on the filesystem.
|
|
113
|
+
# Otherwise, create a minimal script to run the task using the SiliconCompiler CLI.
|
|
114
|
+
if not os.path.isfile(script_file):
|
|
115
|
+
with open(script_file, 'w') as sf:
|
|
116
|
+
sf.write(utils.get_file_template('slurm/run.sh').render(
|
|
117
|
+
cfg_file=shlex.quote(cfg_file),
|
|
118
|
+
build_dir=shlex.quote(chip.get("option", "builddir")),
|
|
119
|
+
step=shlex.quote(step),
|
|
120
|
+
index=shlex.quote(index),
|
|
121
|
+
cachedir=shlex.quote(get_cache_path(chip))
|
|
122
|
+
))
|
|
123
|
+
|
|
124
|
+
# This is Python for: `chmod +x [script_path]`
|
|
125
|
+
os.chmod(script_file,
|
|
126
|
+
os.stat(script_file).st_mode | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH)
|
|
127
|
+
|
|
128
|
+
schedule_cmd = ['sbatch',
|
|
129
|
+
'--exclusive',
|
|
130
|
+
'--partition', partition,
|
|
131
|
+
'--chdir', chip.cwd,
|
|
132
|
+
'--job-name', job_name,
|
|
133
|
+
'--output', log_file]
|
|
134
|
+
|
|
135
|
+
# Only delay the starting time if the 'defer' Schema option is specified.
|
|
136
|
+
defer_time = chip.get('option', 'scheduler', 'defer', step=step, index=index)
|
|
137
|
+
if defer_time:
|
|
138
|
+
schedule_cmd.extend(['--begin', defer_time])
|
|
139
|
+
|
|
140
|
+
schedule_cmd.append(script_file)
|
|
141
|
+
|
|
142
|
+
# Run the 'srun' command, and track its output.
|
|
143
|
+
# TODO: output should be fed to log, and stdout if quiet = False
|
|
144
|
+
step_result = subprocess.Popen(schedule_cmd,
|
|
145
|
+
stdout=subprocess.PIPE,
|
|
146
|
+
stderr=subprocess.STDOUT)
|
|
147
|
+
|
|
148
|
+
# Wait for the subprocess call to complete. It should already be done,
|
|
149
|
+
# as it has closed its output stream. But if we don't call '.wait()',
|
|
150
|
+
# the '.returncode' value will not be set correctly.
|
|
151
|
+
step_result.wait()
|
|
152
|
+
result_msg = step_result.stdout.read().decode()
|
|
153
|
+
sbatch_id = result_msg.split(' ')[-1].strip()
|
|
154
|
+
retcode = 0
|
|
155
|
+
|
|
156
|
+
while True:
|
|
157
|
+
# Return early with an error if the batch ID is not an integer.
|
|
158
|
+
if not sbatch_id.isdigit():
|
|
159
|
+
retcode = 1
|
|
160
|
+
break
|
|
161
|
+
|
|
162
|
+
# Rate-limit the status checks to once every few seconds.
|
|
163
|
+
time.sleep(3.0)
|
|
164
|
+
|
|
165
|
+
# Check whether the job is still running.
|
|
166
|
+
jobcheck = subprocess.run(['scontrol', 'show', 'job', sbatch_id],
|
|
167
|
+
stdout=subprocess.PIPE,
|
|
168
|
+
stderr=subprocess.STDOUT)
|
|
169
|
+
jobout = jobcheck.stdout.decode()
|
|
170
|
+
|
|
171
|
+
# Jobs have a number of potential states that they can be in if they
|
|
172
|
+
# are still active in the Slurm scheduler.
|
|
173
|
+
if [state for state in SLURM_ACTIVE_STATES if state in jobout]:
|
|
174
|
+
pass
|
|
175
|
+
# 'COMPLETED' is a special case indicating successful job termination.
|
|
176
|
+
elif 'COMPLETED' in jobout:
|
|
177
|
+
break
|
|
178
|
+
elif 'Invalid job id specified' in jobout:
|
|
179
|
+
# May have already completed and been purged from active list.
|
|
180
|
+
break
|
|
181
|
+
# Jobs have a number of potential states that they can be in if they
|
|
182
|
+
# did not terminate successfully.
|
|
183
|
+
elif [state for state in SLURM_INACTIVE_STATES if state in jobout]:
|
|
184
|
+
# FAILED, TIMEOUT, etc.
|
|
185
|
+
retcode = 1
|
|
186
|
+
break
|
|
187
|
+
|
|
188
|
+
if retcode > 0:
|
|
189
|
+
chip.logger.error(f'srun command for {step} failed.')
|
|
190
|
+
chip.logger.error(f'srun output for {step}: {jobout}')
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
def _get_slurm_partition():
|
|
194
|
+
partitions = subprocess.run(['sinfo', '--json'],
|
|
195
|
+
stdout=subprocess.PIPE,
|
|
196
|
+
stderr=subprocess.STDOUT)
|
|
197
|
+
|
|
198
|
+
if partitions.returncode != 0:
|
|
199
|
+
raise RuntimeError('Unable to determine partitions in slurm')
|
|
200
|
+
|
|
201
|
+
sinfo = json.loads(partitions.stdout.decode())
|
|
202
|
+
|
|
203
|
+
# Return the first listed partition
|
|
204
|
+
return sinfo['nodes'][0]['partitions'][0]
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
def check_slurm():
|
|
208
|
+
return shutil.which('sinfo') is not None
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
{
|
|
2
|
+
"title": "Email credentials",
|
|
3
|
+
"description": "Schema describing parameters needed to log into an email server to send messages.",
|
|
4
|
+
|
|
5
|
+
"type": "object",
|
|
6
|
+
"additionalProperties": false,
|
|
7
|
+
"properties": {
|
|
8
|
+
"username": {
|
|
9
|
+
"title": "Username",
|
|
10
|
+
"description": "Username on email server",
|
|
11
|
+
"examples": ["my_user@xyz.com", "account1234"],
|
|
12
|
+
|
|
13
|
+
"type": "string",
|
|
14
|
+
"pattern": "^.*$"
|
|
15
|
+
},
|
|
16
|
+
"password": {
|
|
17
|
+
"title": "Password",
|
|
18
|
+
"description": "Password on email server",
|
|
19
|
+
"examples": ["mysecret", "password1234"],
|
|
20
|
+
|
|
21
|
+
"type": "string",
|
|
22
|
+
"pattern": "^.*$"
|
|
23
|
+
},
|
|
24
|
+
"from": {
|
|
25
|
+
"title": "Username to use as source of emails",
|
|
26
|
+
"description": "Username/email to use as the source of the emails, if not provided the first recipient of the emails will be listed as from.",
|
|
27
|
+
"examples": ["my_user@xyz.com", "account1234@nop.xyz"],
|
|
28
|
+
|
|
29
|
+
"type": "string",
|
|
30
|
+
"pattern": "^.*$"
|
|
31
|
+
},
|
|
32
|
+
"server": {
|
|
33
|
+
"title": "Server address",
|
|
34
|
+
"description": "Address for the SMTP server",
|
|
35
|
+
"examples": ["smtp.xyz.com"],
|
|
36
|
+
"type": "string"
|
|
37
|
+
},
|
|
38
|
+
"port": {
|
|
39
|
+
"title": "Server port",
|
|
40
|
+
"description": "Port number for the SMTP server",
|
|
41
|
+
"examples": [25],
|
|
42
|
+
"type": "integer"
|
|
43
|
+
},
|
|
44
|
+
"ssl": {
|
|
45
|
+
"title": "Use SSL",
|
|
46
|
+
"description": "Flag to indicate that SSL should be used.",
|
|
47
|
+
"examples": [true],
|
|
48
|
+
"type": "boolean",
|
|
49
|
+
"default": true
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
|
|
53
|
+
"required": ["username", "password", "server", "port"]
|
|
54
|
+
}
|