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.
Files changed (251) hide show
  1. siliconcompiler/__init__.py +24 -0
  2. siliconcompiler/__main__.py +12 -0
  3. siliconcompiler/_common.py +49 -0
  4. siliconcompiler/_metadata.py +36 -0
  5. siliconcompiler/apps/__init__.py +0 -0
  6. siliconcompiler/apps/_common.py +76 -0
  7. siliconcompiler/apps/sc.py +92 -0
  8. siliconcompiler/apps/sc_dashboard.py +94 -0
  9. siliconcompiler/apps/sc_issue.py +178 -0
  10. siliconcompiler/apps/sc_remote.py +199 -0
  11. siliconcompiler/apps/sc_server.py +39 -0
  12. siliconcompiler/apps/sc_show.py +142 -0
  13. siliconcompiler/apps/smake.py +232 -0
  14. siliconcompiler/checklists/__init__.py +0 -0
  15. siliconcompiler/checklists/oh_tapeout.py +41 -0
  16. siliconcompiler/core.py +3221 -0
  17. siliconcompiler/data/RobotoMono/LICENSE.txt +202 -0
  18. siliconcompiler/data/RobotoMono/RobotoMono-Regular.ttf +0 -0
  19. siliconcompiler/data/heartbeat.v +18 -0
  20. siliconcompiler/data/logo.png +0 -0
  21. siliconcompiler/flowgraph.py +570 -0
  22. siliconcompiler/flows/__init__.py +0 -0
  23. siliconcompiler/flows/_common.py +67 -0
  24. siliconcompiler/flows/asicflow.py +180 -0
  25. siliconcompiler/flows/asictopflow.py +38 -0
  26. siliconcompiler/flows/dvflow.py +86 -0
  27. siliconcompiler/flows/fpgaflow.py +202 -0
  28. siliconcompiler/flows/generate_openroad_rcx.py +66 -0
  29. siliconcompiler/flows/lintflow.py +35 -0
  30. siliconcompiler/flows/screenshotflow.py +51 -0
  31. siliconcompiler/flows/showflow.py +59 -0
  32. siliconcompiler/flows/signoffflow.py +53 -0
  33. siliconcompiler/flows/synflow.py +128 -0
  34. siliconcompiler/fpgas/__init__.py +0 -0
  35. siliconcompiler/fpgas/lattice_ice40.py +42 -0
  36. siliconcompiler/fpgas/vpr_example.py +109 -0
  37. siliconcompiler/issue.py +300 -0
  38. siliconcompiler/libs/__init__.py +0 -0
  39. siliconcompiler/libs/asap7sc7p5t.py +8 -0
  40. siliconcompiler/libs/gf180mcu.py +8 -0
  41. siliconcompiler/libs/nangate45.py +8 -0
  42. siliconcompiler/libs/sky130hd.py +8 -0
  43. siliconcompiler/libs/sky130io.py +8 -0
  44. siliconcompiler/package.py +412 -0
  45. siliconcompiler/pdks/__init__.py +0 -0
  46. siliconcompiler/pdks/asap7.py +8 -0
  47. siliconcompiler/pdks/freepdk45.py +8 -0
  48. siliconcompiler/pdks/gf180.py +8 -0
  49. siliconcompiler/pdks/skywater130.py +8 -0
  50. siliconcompiler/remote/__init__.py +36 -0
  51. siliconcompiler/remote/client.py +891 -0
  52. siliconcompiler/remote/schema.py +106 -0
  53. siliconcompiler/remote/server.py +507 -0
  54. siliconcompiler/remote/server_schema/requests/cancel_job.json +51 -0
  55. siliconcompiler/remote/server_schema/requests/check_progress.json +61 -0
  56. siliconcompiler/remote/server_schema/requests/check_server.json +38 -0
  57. siliconcompiler/remote/server_schema/requests/delete_job.json +51 -0
  58. siliconcompiler/remote/server_schema/requests/get_results.json +48 -0
  59. siliconcompiler/remote/server_schema/requests/remote_run.json +40 -0
  60. siliconcompiler/remote/server_schema/responses/cancel_job.json +18 -0
  61. siliconcompiler/remote/server_schema/responses/check_progress.json +30 -0
  62. siliconcompiler/remote/server_schema/responses/check_server.json +32 -0
  63. siliconcompiler/remote/server_schema/responses/delete_job.json +18 -0
  64. siliconcompiler/remote/server_schema/responses/get_results.json +21 -0
  65. siliconcompiler/remote/server_schema/responses/remote_run.json +25 -0
  66. siliconcompiler/report/__init__.py +13 -0
  67. siliconcompiler/report/html_report.py +74 -0
  68. siliconcompiler/report/report.py +355 -0
  69. siliconcompiler/report/streamlit_report.py +137 -0
  70. siliconcompiler/report/streamlit_viewer.py +944 -0
  71. siliconcompiler/report/summary_image.py +117 -0
  72. siliconcompiler/report/summary_table.py +105 -0
  73. siliconcompiler/report/utils.py +163 -0
  74. siliconcompiler/scheduler/__init__.py +2092 -0
  75. siliconcompiler/scheduler/docker_runner.py +253 -0
  76. siliconcompiler/scheduler/run_node.py +138 -0
  77. siliconcompiler/scheduler/send_messages.py +178 -0
  78. siliconcompiler/scheduler/slurm.py +208 -0
  79. siliconcompiler/scheduler/validation/email_credentials.json +54 -0
  80. siliconcompiler/schema/__init__.py +7 -0
  81. siliconcompiler/schema/schema_cfg.py +4014 -0
  82. siliconcompiler/schema/schema_obj.py +1841 -0
  83. siliconcompiler/schema/utils.py +93 -0
  84. siliconcompiler/sphinx_ext/__init__.py +0 -0
  85. siliconcompiler/sphinx_ext/dynamicgen.py +1006 -0
  86. siliconcompiler/sphinx_ext/schemagen.py +221 -0
  87. siliconcompiler/sphinx_ext/utils.py +166 -0
  88. siliconcompiler/targets/__init__.py +0 -0
  89. siliconcompiler/targets/asap7_demo.py +68 -0
  90. siliconcompiler/targets/asic_demo.py +38 -0
  91. siliconcompiler/targets/fpgaflow_demo.py +47 -0
  92. siliconcompiler/targets/freepdk45_demo.py +59 -0
  93. siliconcompiler/targets/gf180_demo.py +77 -0
  94. siliconcompiler/targets/skywater130_demo.py +70 -0
  95. siliconcompiler/templates/email/general.j2 +66 -0
  96. siliconcompiler/templates/email/summary.j2 +43 -0
  97. siliconcompiler/templates/issue/README.txt +26 -0
  98. siliconcompiler/templates/issue/run.sh +6 -0
  99. siliconcompiler/templates/report/bootstrap.min.css +7 -0
  100. siliconcompiler/templates/report/bootstrap.min.js +7 -0
  101. siliconcompiler/templates/report/bootstrap_LICENSE.md +24 -0
  102. siliconcompiler/templates/report/sc_report.j2 +427 -0
  103. siliconcompiler/templates/slurm/run.sh +9 -0
  104. siliconcompiler/templates/tcl/manifest.tcl.j2 +137 -0
  105. siliconcompiler/tools/__init__.py +0 -0
  106. siliconcompiler/tools/_common/__init__.py +432 -0
  107. siliconcompiler/tools/_common/asic.py +115 -0
  108. siliconcompiler/tools/_common/sdc/sc_constraints.sdc +76 -0
  109. siliconcompiler/tools/_common/tcl/sc_pin_constraints.tcl +63 -0
  110. siliconcompiler/tools/bambu/bambu.py +32 -0
  111. siliconcompiler/tools/bambu/convert.py +77 -0
  112. siliconcompiler/tools/bluespec/bluespec.py +40 -0
  113. siliconcompiler/tools/bluespec/convert.py +103 -0
  114. siliconcompiler/tools/builtin/_common.py +155 -0
  115. siliconcompiler/tools/builtin/builtin.py +26 -0
  116. siliconcompiler/tools/builtin/concatenate.py +85 -0
  117. siliconcompiler/tools/builtin/join.py +27 -0
  118. siliconcompiler/tools/builtin/maximum.py +46 -0
  119. siliconcompiler/tools/builtin/minimum.py +57 -0
  120. siliconcompiler/tools/builtin/mux.py +70 -0
  121. siliconcompiler/tools/builtin/nop.py +38 -0
  122. siliconcompiler/tools/builtin/verify.py +83 -0
  123. siliconcompiler/tools/chisel/SCDriver.scala +10 -0
  124. siliconcompiler/tools/chisel/build.sbt +27 -0
  125. siliconcompiler/tools/chisel/chisel.py +37 -0
  126. siliconcompiler/tools/chisel/convert.py +140 -0
  127. siliconcompiler/tools/execute/exec_input.py +41 -0
  128. siliconcompiler/tools/execute/execute.py +17 -0
  129. siliconcompiler/tools/genfasm/bitstream.py +61 -0
  130. siliconcompiler/tools/genfasm/genfasm.py +40 -0
  131. siliconcompiler/tools/ghdl/convert.py +87 -0
  132. siliconcompiler/tools/ghdl/ghdl.py +41 -0
  133. siliconcompiler/tools/icarus/compile.py +87 -0
  134. siliconcompiler/tools/icarus/icarus.py +36 -0
  135. siliconcompiler/tools/icepack/bitstream.py +20 -0
  136. siliconcompiler/tools/icepack/icepack.py +43 -0
  137. siliconcompiler/tools/klayout/export.py +117 -0
  138. siliconcompiler/tools/klayout/klayout.py +119 -0
  139. siliconcompiler/tools/klayout/klayout_export.py +205 -0
  140. siliconcompiler/tools/klayout/klayout_operations.py +363 -0
  141. siliconcompiler/tools/klayout/klayout_show.py +242 -0
  142. siliconcompiler/tools/klayout/klayout_utils.py +176 -0
  143. siliconcompiler/tools/klayout/operations.py +194 -0
  144. siliconcompiler/tools/klayout/screenshot.py +98 -0
  145. siliconcompiler/tools/klayout/show.py +101 -0
  146. siliconcompiler/tools/magic/drc.py +49 -0
  147. siliconcompiler/tools/magic/extspice.py +19 -0
  148. siliconcompiler/tools/magic/magic.py +85 -0
  149. siliconcompiler/tools/magic/sc_drc.tcl +96 -0
  150. siliconcompiler/tools/magic/sc_extspice.tcl +54 -0
  151. siliconcompiler/tools/magic/sc_magic.tcl +47 -0
  152. siliconcompiler/tools/montage/montage.py +30 -0
  153. siliconcompiler/tools/montage/tile.py +66 -0
  154. siliconcompiler/tools/netgen/count_lvs.py +132 -0
  155. siliconcompiler/tools/netgen/lvs.py +90 -0
  156. siliconcompiler/tools/netgen/netgen.py +36 -0
  157. siliconcompiler/tools/netgen/sc_lvs.tcl +46 -0
  158. siliconcompiler/tools/nextpnr/apr.py +24 -0
  159. siliconcompiler/tools/nextpnr/nextpnr.py +59 -0
  160. siliconcompiler/tools/openfpgaloader/openfpgaloader.py +39 -0
  161. siliconcompiler/tools/openroad/__init__.py +0 -0
  162. siliconcompiler/tools/openroad/cts.py +45 -0
  163. siliconcompiler/tools/openroad/dfm.py +66 -0
  164. siliconcompiler/tools/openroad/export.py +131 -0
  165. siliconcompiler/tools/openroad/floorplan.py +70 -0
  166. siliconcompiler/tools/openroad/openroad.py +977 -0
  167. siliconcompiler/tools/openroad/physyn.py +27 -0
  168. siliconcompiler/tools/openroad/place.py +41 -0
  169. siliconcompiler/tools/openroad/rcx_bench.py +95 -0
  170. siliconcompiler/tools/openroad/rcx_extract.py +34 -0
  171. siliconcompiler/tools/openroad/route.py +45 -0
  172. siliconcompiler/tools/openroad/screenshot.py +60 -0
  173. siliconcompiler/tools/openroad/scripts/sc_apr.tcl +499 -0
  174. siliconcompiler/tools/openroad/scripts/sc_cts.tcl +64 -0
  175. siliconcompiler/tools/openroad/scripts/sc_dfm.tcl +20 -0
  176. siliconcompiler/tools/openroad/scripts/sc_export.tcl +98 -0
  177. siliconcompiler/tools/openroad/scripts/sc_floorplan.tcl +413 -0
  178. siliconcompiler/tools/openroad/scripts/sc_metrics.tcl +158 -0
  179. siliconcompiler/tools/openroad/scripts/sc_physyn.tcl +7 -0
  180. siliconcompiler/tools/openroad/scripts/sc_place.tcl +84 -0
  181. siliconcompiler/tools/openroad/scripts/sc_procs.tcl +423 -0
  182. siliconcompiler/tools/openroad/scripts/sc_rcx.tcl +63 -0
  183. siliconcompiler/tools/openroad/scripts/sc_rcx_bench.tcl +20 -0
  184. siliconcompiler/tools/openroad/scripts/sc_rcx_extract.tcl +12 -0
  185. siliconcompiler/tools/openroad/scripts/sc_route.tcl +133 -0
  186. siliconcompiler/tools/openroad/scripts/sc_screenshot.tcl +21 -0
  187. siliconcompiler/tools/openroad/scripts/sc_write.tcl +5 -0
  188. siliconcompiler/tools/openroad/scripts/sc_write_images.tcl +361 -0
  189. siliconcompiler/tools/openroad/show.py +94 -0
  190. siliconcompiler/tools/openroad/templates/pex.tcl +8 -0
  191. siliconcompiler/tools/opensta/__init__.py +101 -0
  192. siliconcompiler/tools/opensta/report_libraries.py +28 -0
  193. siliconcompiler/tools/opensta/scripts/sc_procs.tcl +47 -0
  194. siliconcompiler/tools/opensta/scripts/sc_report_libraries.tcl +74 -0
  195. siliconcompiler/tools/opensta/scripts/sc_timing.tcl +268 -0
  196. siliconcompiler/tools/opensta/timing.py +214 -0
  197. siliconcompiler/tools/slang/__init__.py +49 -0
  198. siliconcompiler/tools/slang/lint.py +101 -0
  199. siliconcompiler/tools/surelog/__init__.py +123 -0
  200. siliconcompiler/tools/surelog/parse.py +183 -0
  201. siliconcompiler/tools/surelog/templates/output.v +7 -0
  202. siliconcompiler/tools/sv2v/convert.py +46 -0
  203. siliconcompiler/tools/sv2v/sv2v.py +37 -0
  204. siliconcompiler/tools/template/template.py +125 -0
  205. siliconcompiler/tools/verilator/compile.py +139 -0
  206. siliconcompiler/tools/verilator/lint.py +19 -0
  207. siliconcompiler/tools/verilator/parse.py +27 -0
  208. siliconcompiler/tools/verilator/verilator.py +172 -0
  209. siliconcompiler/tools/vivado/__init__.py +7 -0
  210. siliconcompiler/tools/vivado/bitstream.py +21 -0
  211. siliconcompiler/tools/vivado/place.py +21 -0
  212. siliconcompiler/tools/vivado/route.py +21 -0
  213. siliconcompiler/tools/vivado/scripts/sc_bitstream.tcl +6 -0
  214. siliconcompiler/tools/vivado/scripts/sc_place.tcl +2 -0
  215. siliconcompiler/tools/vivado/scripts/sc_route.tcl +4 -0
  216. siliconcompiler/tools/vivado/scripts/sc_run.tcl +45 -0
  217. siliconcompiler/tools/vivado/scripts/sc_syn_fpga.tcl +25 -0
  218. siliconcompiler/tools/vivado/syn_fpga.py +20 -0
  219. siliconcompiler/tools/vivado/vivado.py +147 -0
  220. siliconcompiler/tools/vpr/_json_constraint.py +63 -0
  221. siliconcompiler/tools/vpr/_xml_constraint.py +109 -0
  222. siliconcompiler/tools/vpr/place.py +137 -0
  223. siliconcompiler/tools/vpr/route.py +124 -0
  224. siliconcompiler/tools/vpr/screenshot.py +54 -0
  225. siliconcompiler/tools/vpr/show.py +88 -0
  226. siliconcompiler/tools/vpr/vpr.py +357 -0
  227. siliconcompiler/tools/xyce/xyce.py +36 -0
  228. siliconcompiler/tools/yosys/lec.py +56 -0
  229. siliconcompiler/tools/yosys/prepareLib.py +59 -0
  230. siliconcompiler/tools/yosys/sc_lec.tcl +84 -0
  231. siliconcompiler/tools/yosys/sc_syn.tcl +79 -0
  232. siliconcompiler/tools/yosys/syn_asic.py +565 -0
  233. siliconcompiler/tools/yosys/syn_asic.tcl +377 -0
  234. siliconcompiler/tools/yosys/syn_asic_fpga_shared.tcl +31 -0
  235. siliconcompiler/tools/yosys/syn_fpga.py +146 -0
  236. siliconcompiler/tools/yosys/syn_fpga.tcl +233 -0
  237. siliconcompiler/tools/yosys/syn_strategies.tcl +81 -0
  238. siliconcompiler/tools/yosys/techmaps/lcu_kogge_stone.v +39 -0
  239. siliconcompiler/tools/yosys/templates/abc.const +2 -0
  240. siliconcompiler/tools/yosys/yosys.py +147 -0
  241. siliconcompiler/units.py +259 -0
  242. siliconcompiler/use.py +177 -0
  243. siliconcompiler/utils/__init__.py +423 -0
  244. siliconcompiler/utils/asic.py +158 -0
  245. siliconcompiler/utils/showtools.py +25 -0
  246. siliconcompiler-0.26.5.dist-info/LICENSE +190 -0
  247. siliconcompiler-0.26.5.dist-info/METADATA +195 -0
  248. siliconcompiler-0.26.5.dist-info/RECORD +251 -0
  249. siliconcompiler-0.26.5.dist-info/WHEEL +5 -0
  250. siliconcompiler-0.26.5.dist-info/entry_points.txt +12 -0
  251. 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
+ }
@@ -0,0 +1,7 @@
1
+ from .schema_cfg import SCHEMA_VERSION
2
+ from .schema_obj import Schema
3
+
4
+ __all__ = [
5
+ "SCHEMA_VERSION",
6
+ "Schema"
7
+ ]