slurm-script-generator 0.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,254 @@
1
+ import argparse
2
+ import json
3
+
4
+ import slurm_script_generator.sbatch_parser as sbatch_parser
5
+ from slurm_script_generator.sbatch import register_to_parser
6
+
7
+
8
+ def add_misc_options(parser):
9
+
10
+ parser.add_argument(
11
+ "--line-length",
12
+ dest="line_length",
13
+ type=int,
14
+ default=40,
15
+ metavar="LINE_LENGHT",
16
+ help="line length before start of comment",
17
+ )
18
+
19
+ parser.add_argument(
20
+ "--modules",
21
+ dest="modules",
22
+ type=str,
23
+ nargs="+",
24
+ default=[],
25
+ metavar="MODULES",
26
+ help="Modules to load (e.g., --modules mod1 mod2 mod3)",
27
+ )
28
+
29
+ parser.add_argument(
30
+ "--vars",
31
+ dest="vars",
32
+ type=str,
33
+ nargs="+",
34
+ default=[],
35
+ metavar="ENVIRONMENT_VARS",
36
+ help="Environment variables to export (e.g., --vars VAR1=a VAR2=b)",
37
+ )
38
+
39
+ parser.add_argument(
40
+ "--venv",
41
+ dest="venv",
42
+ type=str,
43
+ default=None,
44
+ metavar="VENV",
45
+ help="virtual environment to load with `source VENV/bin/activate`",
46
+ )
47
+
48
+ parser.add_argument(
49
+ "--printenv",
50
+ action="store_true",
51
+ dest="printenv",
52
+ help="print all environment variables",
53
+ )
54
+
55
+ parser.add_argument(
56
+ "--print-self",
57
+ action="store_true",
58
+ dest="printself",
59
+ help="print the batch script in the batch script",
60
+ )
61
+
62
+ parser.add_argument(
63
+ "--likwid",
64
+ action="store_true",
65
+ dest="likwid",
66
+ help="Set up likwid environment variables",
67
+ )
68
+
69
+ parser.add_argument(
70
+ "--input",
71
+ dest="input",
72
+ type=str,
73
+ default=None,
74
+ metavar="INPUT_PATH",
75
+ help="path to input json file",
76
+ )
77
+
78
+ parser.add_argument(
79
+ "--output",
80
+ dest="output",
81
+ type=str,
82
+ default=None,
83
+ metavar="OUTPUT_PATH",
84
+ help="json path to save slurm batch script to",
85
+ )
86
+
87
+ parser.add_argument(
88
+ "--export-json",
89
+ dest="export_json",
90
+ type=str,
91
+ default=None,
92
+ metavar="JSON_PATH",
93
+ help="path to export yaml for generating the slurm script to",
94
+ )
95
+ return parser
96
+
97
+
98
+ def add_line(line, comment="", line_length=40):
99
+ if len(line) > line_length:
100
+ return f"{line} # {comment}\n"
101
+ else:
102
+ return f"{line} {' ' * (line_length - len(line))}# {comment}\n"
103
+
104
+
105
+ def export_json(args_dict, path):
106
+ with open(path, "w") as f:
107
+ json.dump(args_dict, f)
108
+
109
+
110
+ def read_yaml(path):
111
+ with open(path, "r") as f:
112
+ return json.load(f)
113
+
114
+
115
+ def generate_script(args_dict, print_script=True):
116
+
117
+ line_length = args_dict.get("line_length", 60)
118
+
119
+ # Start generating the SLURM batch script
120
+ script = "#!/bin/bash\n"
121
+ script += "#" * (line_length + 2) + "\n"
122
+
123
+ for pragma in sbatch_parser.pragmas:
124
+ # print(f"{pragma.dest = } {list(args_dict.keys()) = }")
125
+ if pragma.dest in list(args_dict.keys()):
126
+ # print(f"{pragma.dest = }")
127
+ val = args_dict.get(pragma.dest)
128
+ if val not in [None, False]:
129
+ script += add_line(
130
+ f"#SBATCH --{pragma.sbatch_flag} {val}",
131
+ pragma.help,
132
+ line_length=line_length,
133
+ )
134
+ script += "#" * (line_length + 2) + "\n\n"
135
+
136
+ vars = args_dict.get("vars", [])
137
+ if len(vars) > 0:
138
+ for var in vars:
139
+ script += add_line(
140
+ f"export {var}",
141
+ "Set environment variable",
142
+ line_length=line_length,
143
+ )
144
+
145
+ if args_dict.get("printself", False):
146
+ script += add_line(
147
+ f"cat $0",
148
+ "print this batch script",
149
+ line_length=line_length,
150
+ )
151
+
152
+ # Load modules
153
+ if len(args_dict.get("modules", [])) > 0:
154
+ script += add_line(
155
+ "module purge",
156
+ "Purge modules",
157
+ line_length=line_length,
158
+ )
159
+ script += add_line(
160
+ f"module load {' '.join(args_dict.get('modules'))}",
161
+ "modules",
162
+ line_length=line_length,
163
+ )
164
+ script += add_line(
165
+ "module list",
166
+ "List loaded modules",
167
+ line_length=line_length,
168
+ )
169
+
170
+ if args_dict.get("venv", None) is not None:
171
+ script += add_line(
172
+ f"source {args_dict.get('venv')}/bin/activate",
173
+ "virtual environment",
174
+ line_length=line_length,
175
+ )
176
+
177
+ if args_dict.get("printenv", False):
178
+ script += add_line(
179
+ "printenv",
180
+ "print environment variables",
181
+ line_length=line_length,
182
+ )
183
+
184
+ if args_dict.get("likwid", False):
185
+ script += add_line(
186
+ "LIKWID_PREFIX=$(realpath $(dirname $(which likwid-topology))/..)",
187
+ "Set LIKWID prefix",
188
+ line_length=line_length,
189
+ )
190
+
191
+ script += add_line(
192
+ "export LD_LIBRARY_PATH=$LIKWID_PREFIX/lib",
193
+ "Set LD_LIBRARY_PATH for LIKWID",
194
+ line_length=line_length,
195
+ )
196
+
197
+ script += add_line(
198
+ "likwid-topology > likwid-topology.txt",
199
+ "Save LIKWID topology information",
200
+ line_length=line_length,
201
+ )
202
+ script += add_line(
203
+ "likwid-topology -g > likwid-topology-g.txt",
204
+ "Save graphical LIKWID topology information",
205
+ line_length=line_length,
206
+ )
207
+
208
+ script += "\n"
209
+ if args_dict.get("export_json", None) is not None:
210
+ path = args_dict.pop("export_json")
211
+ export_json(args_dict=args_dict, path=path)
212
+ if args_dict.get("output") is not None:
213
+ with open(args_dict.get("output"), "w") as f:
214
+ f.write(script)
215
+
216
+ if print_script:
217
+ print(script)
218
+
219
+ return script
220
+
221
+
222
+ def main():
223
+ parser = argparse.ArgumentParser(
224
+ description="Slurm job submission options",
225
+ formatter_class=argparse.ArgumentDefaultsHelpFormatter,
226
+ )
227
+
228
+ for p in sbatch_parser.pragmas:
229
+ register_to_parser(parser, p)
230
+
231
+ # slurm_options_dict = {}
232
+ # for action in parser._actions:
233
+ # slurm_options_dict[action.dest] = action.help
234
+
235
+ add_misc_options(parser=parser)
236
+
237
+ sbatch_args = parser.parse_args()
238
+
239
+ if sbatch_args.input is not None:
240
+ args_dict = read_yaml(sbatch_args.input)
241
+ else:
242
+ args_dict = {}
243
+ for arg in sbatch_args.__dict__:
244
+ val = sbatch_args.__dict__[arg]
245
+ if val is not None and val is not False:
246
+ if isinstance(val, list) and len(val) == 0:
247
+ continue
248
+ args_dict.update({arg: val})
249
+
250
+ generate_script(args_dict)
251
+
252
+
253
+ if __name__ == "__main__":
254
+ main()
@@ -0,0 +1,71 @@
1
+ from argparse import ArgumentParser
2
+ from dataclasses import dataclass, field
3
+ from typing import Any, Callable, List, Optional
4
+
5
+
6
+ @dataclass
7
+ class Flag:
8
+ name: str
9
+ help: str
10
+
11
+
12
+ @dataclass
13
+ class Pragma:
14
+ flags: List[Flag] # e.g. ['-A', '--account']
15
+ dest: str # e.g. 'account'
16
+ example: Optional[str] = None
17
+ help: Optional[str] = "" # e.g. 'charge job to specified account'
18
+ nargs: Optional[str] = None
19
+ const: Optional[int] = None
20
+ choices: Optional[list] = None
21
+ metavar: Optional[str] = None # e.g. 'NAME'
22
+ action: Optional[str] = None # e.g. 'store_true', 'store_false'
23
+ default: Optional[str] = None # Optional default value
24
+ type: Optional[Callable[[str], Any]] = str # e.g. str, int, float, etc.
25
+ env_var: Optional[str] = None # Environment variable
26
+
27
+ def add_argument_to_parser(self, parser: ArgumentParser):
28
+
29
+ kwargs = {
30
+ "dest": self.dest,
31
+ "type": self.type,
32
+ "default": self.default,
33
+ "help": self.help,
34
+ }
35
+ parser.add_argument(
36
+ self.flags[0].name,
37
+ **kwargs,
38
+ )
39
+
40
+ @property
41
+ def sbatch_flag(self):
42
+ return self.dest.replace("_", "-")
43
+
44
+
45
+ def register_to_parser(parser, pragma: Pragma):
46
+ kwargs = {"dest": pragma.dest, "help": pragma.help}
47
+ if pragma.metavar:
48
+ kwargs["metavar"] = pragma.metavar
49
+ if pragma.action:
50
+ kwargs["action"] = pragma.action
51
+ if pragma.default:
52
+ kwargs["default"] = pragma.default
53
+
54
+ parser.add_argument(*pragma.flags, **kwargs)
55
+
56
+
57
+ if __name__ == "__main__":
58
+ import argparse
59
+
60
+ parser = argparse.ArgumentParser(
61
+ description="Slurm job submission options",
62
+ formatter_class=argparse.ArgumentDefaultsHelpFormatter,
63
+ )
64
+
65
+ p = Pragma(flags=["--nodes"], dest="nodes", help="Number of nodes", type=str)
66
+
67
+ register_to_parser(parser, p)
68
+
69
+ sbatch_args = parser.parse_args()
70
+
71
+ print(p)
@@ -0,0 +1,572 @@
1
+ import argparse
2
+
3
+ from slurm_script_generator.sbatch import Pragma
4
+
5
+ pragmas = [
6
+ Pragma(
7
+ flags=["-A", "--account"],
8
+ dest="account",
9
+ metavar="NAME",
10
+ help="charge job to specified account",
11
+ example="myacct",
12
+ ),
13
+ Pragma(
14
+ flags=["-b", "--begin"],
15
+ dest="begin",
16
+ metavar="TIME",
17
+ help="defer job until HH:MM MM/DD/YY",
18
+ ),
19
+ Pragma(
20
+ flags=["--bell"],
21
+ dest="bell",
22
+ action="store_true",
23
+ help="ring the terminal bell when the job is allocated",
24
+ ),
25
+ Pragma(
26
+ flags=["--no-bell"],
27
+ dest="bell",
28
+ action="store_false",
29
+ help="do NOT ring the terminal bell",
30
+ ),
31
+ Pragma(
32
+ flags=["--bb"],
33
+ dest="burst_buffer",
34
+ metavar="SPEC",
35
+ help="burst buffer specifications",
36
+ ),
37
+ Pragma(
38
+ flags=["--bbf"],
39
+ dest="bb_file",
40
+ metavar="FILE_NAME",
41
+ help="burst buffer specification file",
42
+ ),
43
+ Pragma(
44
+ flags=["-c", "--cpus-per-task"],
45
+ dest="cpus_per_task",
46
+ type=int,
47
+ metavar="NCPUS",
48
+ help="number of cpus required per task",
49
+ example=16,
50
+ ),
51
+ Pragma(
52
+ flags=["--comment"],
53
+ dest="comment",
54
+ metavar="NAME",
55
+ help="arbitrary comment",
56
+ ),
57
+ Pragma(
58
+ flags=["--container"],
59
+ dest="container",
60
+ metavar="PATH",
61
+ help="Path to OCI container bundle",
62
+ ),
63
+ Pragma(
64
+ flags=["--container-id"],
65
+ dest="container_id",
66
+ metavar="ID",
67
+ help="OCI container ID",
68
+ ),
69
+ Pragma(
70
+ flags=["--cpu-freq"],
71
+ dest="cpu_freq",
72
+ metavar="MIN[-MAX[:GOV]]",
73
+ help="requested cpu frequency (and governor)",
74
+ ),
75
+ Pragma(
76
+ flags=["--delay-boot"],
77
+ dest="delay_boot",
78
+ type=int,
79
+ metavar="MINS",
80
+ help="delay boot for desired node features",
81
+ ),
82
+ Pragma(
83
+ flags=["-d", "--dependency"],
84
+ dest="dependency",
85
+ metavar="TYPE:JOBID[:TIME]",
86
+ help="defer job until condition on jobid is satisfied",
87
+ ),
88
+ Pragma(
89
+ flags=["--deadline"],
90
+ dest="deadline",
91
+ metavar="TIME",
92
+ help="remove the job if no ending possible before this deadline",
93
+ ),
94
+ Pragma(
95
+ flags=["-D", "--chdir"],
96
+ dest="chdir",
97
+ metavar="PATH",
98
+ help="change working directory",
99
+ ),
100
+ Pragma(
101
+ flags=["--get-user-env"],
102
+ dest="get_user_env",
103
+ action="store_true",
104
+ help="used by Moab. See srun man page",
105
+ ),
106
+ Pragma(
107
+ flags=["--gres"],
108
+ dest="gres",
109
+ metavar="LIST",
110
+ type=lambda s: s.split(","),
111
+ help="required generic resources",
112
+ ),
113
+ Pragma(
114
+ flags=["--gres-flags"],
115
+ dest="gres_flags",
116
+ metavar="OPTS",
117
+ help="flags related to GRES management",
118
+ ),
119
+ Pragma(
120
+ flags=["-H", "--hold"],
121
+ dest="hold",
122
+ action="store_true",
123
+ help="submit job in held state",
124
+ ),
125
+ Pragma(
126
+ flags=["-I", "--immediate"],
127
+ dest="immediate",
128
+ nargs="?",
129
+ const=0,
130
+ metavar="SECS",
131
+ type=int,
132
+ help='exit if resources not available in "secs"',
133
+ ),
134
+ Pragma(
135
+ flags=["-J", "--job-name"],
136
+ dest="job_name",
137
+ metavar="NAME",
138
+ help="name of job",
139
+ example="my_job",
140
+ ),
141
+ Pragma(
142
+ flags=["-k", "--no-kill"],
143
+ dest="no_kill",
144
+ action="store_true",
145
+ help="do not kill job on node failure",
146
+ ),
147
+ Pragma(
148
+ flags=["-K", "--kill-command"],
149
+ dest="kill_command",
150
+ nargs="?",
151
+ const="TERM",
152
+ metavar="SIGNAL",
153
+ help="signal to send terminating job",
154
+ ),
155
+ Pragma(
156
+ flags=["-L", "--licenses"],
157
+ dest="licenses",
158
+ metavar="NAMES",
159
+ type=lambda s: s.split(","),
160
+ help="required license, comma separated",
161
+ ),
162
+ Pragma(
163
+ flags=["-M", "--clusters"],
164
+ dest="clusters",
165
+ metavar="NAMES",
166
+ type=lambda s: s.split(","),
167
+ help="Comma separated list of clusters to issue commands to",
168
+ ),
169
+ Pragma(
170
+ flags=["-m", "--distribution"],
171
+ dest="distribution",
172
+ metavar="TYPE",
173
+ choices=["block", "cyclic", "arbitrary"],
174
+ help="distribution method for processes to nodes",
175
+ ),
176
+ Pragma(
177
+ flags=["--mail-type"],
178
+ dest="mail_type",
179
+ metavar="TYPE",
180
+ choices=["BEGIN", "END", "FAIL", "ALL"],
181
+ help="notify on state change",
182
+ example="ALL",
183
+ ),
184
+ Pragma(
185
+ flags=["--mail-user"],
186
+ dest="mail_user",
187
+ metavar="USER",
188
+ help="who to send email notification for job state changes",
189
+ example="example@email.com",
190
+ ),
191
+ Pragma(
192
+ flags=["--mcs-label"],
193
+ dest="mcs_label",
194
+ metavar="MCS",
195
+ help="mcs label if mcs plugin mcs/group is used",
196
+ ),
197
+ Pragma(
198
+ flags=["-n", "--ntasks"],
199
+ dest="ntasks",
200
+ type=int,
201
+ metavar="N",
202
+ help="number of processors required",
203
+ example=16,
204
+ ),
205
+ Pragma(
206
+ flags=["--nice"],
207
+ dest="nice",
208
+ type=int,
209
+ metavar="VALUE",
210
+ help="decrease scheduling priority by value",
211
+ example=1,
212
+ ),
213
+ Pragma(
214
+ flags=["-N", "--nodes"],
215
+ dest="nodes",
216
+ metavar="NODES",
217
+ help="number of nodes on which to run",
218
+ example=2,
219
+ ),
220
+ Pragma(
221
+ flags=["--ntasks-per-node"],
222
+ dest="ntasks_per_node",
223
+ type=int,
224
+ metavar="N",
225
+ help="number of tasks to invoke on each node",
226
+ example=16,
227
+ ),
228
+ Pragma(
229
+ flags=["--oom-kill-step"],
230
+ dest="oom_kill_step",
231
+ nargs="?",
232
+ const=1,
233
+ type=int,
234
+ metavar="0|1",
235
+ help="set the OOMKillStep behaviour",
236
+ ),
237
+ Pragma(
238
+ flags=["-O", "--overcommit"],
239
+ dest="overcommit",
240
+ action="store_true",
241
+ help="overcommit resources",
242
+ ),
243
+ Pragma(
244
+ flags=["--power"],
245
+ dest="power",
246
+ metavar="FLAGS",
247
+ help="power management options",
248
+ ),
249
+ Pragma(
250
+ flags=["--priority"],
251
+ dest="priority",
252
+ metavar="VALUE",
253
+ type=int,
254
+ help="set the priority of the job",
255
+ ),
256
+ Pragma(
257
+ flags=["--profile"],
258
+ dest="profile",
259
+ metavar="VALUE",
260
+ help="enable acct_gather_profile for detailed data",
261
+ ),
262
+ Pragma(
263
+ flags=["-p", "--partition"],
264
+ dest="partition",
265
+ metavar="PARTITION",
266
+ help="partition requested",
267
+ ),
268
+ Pragma(flags=["-q", "--qos"], dest="qos", metavar="QOS", help="quality of service"),
269
+ Pragma(
270
+ flags=["-Q", "--quiet"],
271
+ dest="quiet",
272
+ action="store_true",
273
+ help="quiet mode (suppress informational messages)",
274
+ ),
275
+ Pragma(
276
+ flags=["--reboot"],
277
+ dest="reboot",
278
+ action="store_true",
279
+ help="reboot compute nodes before starting job",
280
+ ),
281
+ Pragma(
282
+ flags=["-s", "--oversubscribe"],
283
+ dest="oversubscribe",
284
+ action="store_true",
285
+ help="oversubscribe resources with other jobs",
286
+ ),
287
+ Pragma(
288
+ flags=["--signal"],
289
+ dest="signal",
290
+ metavar="[R:]NUM[@TIME]",
291
+ help="send signal when time limit within time seconds",
292
+ ),
293
+ Pragma(
294
+ flags=["--spread-job"],
295
+ dest="spread_job",
296
+ action="store_true",
297
+ help="spread job across as many nodes as possible",
298
+ ),
299
+ Pragma(
300
+ flags=["--switches"],
301
+ dest="switches",
302
+ metavar="MAX_SWITCHES[@MAX_TIME]",
303
+ help="optimum switches and max time to wait for optimum",
304
+ ),
305
+ Pragma(
306
+ flags=["-S", "--core-spec"],
307
+ dest="core_spec",
308
+ metavar="CORES",
309
+ help="count of reserved cores",
310
+ ),
311
+ Pragma(
312
+ flags=["--thread-spec"],
313
+ dest="thread_spec",
314
+ metavar="THREADS",
315
+ help="count of reserved threads",
316
+ ),
317
+ Pragma(
318
+ flags=["-t", "--time"],
319
+ dest="time",
320
+ metavar="MINUTES",
321
+ type=int,
322
+ help="time limit",
323
+ example="00:45:00",
324
+ ),
325
+ Pragma(
326
+ flags=["--time-min"],
327
+ dest="time_min",
328
+ metavar="MINUTES",
329
+ type=int,
330
+ help="minimum time limit (if distinct)",
331
+ ),
332
+ Pragma(
333
+ flags=["--tres-bind"],
334
+ dest="tres_bind",
335
+ metavar="...",
336
+ help="task to tres binding options",
337
+ ),
338
+ Pragma(
339
+ flags=["--tres-per-task"],
340
+ dest="tres_per_task",
341
+ metavar="LIST",
342
+ type=lambda s: s.split(","),
343
+ help="list of tres required per task",
344
+ ),
345
+ Pragma(
346
+ flags=["--use-min-nodes"],
347
+ dest="use_min_nodes",
348
+ action="store_true",
349
+ help="if a range of node counts is given, prefer the smaller count",
350
+ ),
351
+ Pragma(
352
+ flags=["--wckey"], dest="wckey", metavar="WCKEY", help="wckey to run job under"
353
+ ),
354
+ Pragma(
355
+ flags=["--cluster-constraint"],
356
+ dest="cluster_constraint",
357
+ metavar="LIST",
358
+ type=lambda s: s.split(","),
359
+ help="specify a list of cluster constraints",
360
+ ),
361
+ Pragma(
362
+ flags=["--contiguous"],
363
+ dest="contiguous",
364
+ action="store_true",
365
+ help="demand a contiguous range of nodes",
366
+ ),
367
+ Pragma(
368
+ flags=["-C", "--constraint"],
369
+ dest="constraint",
370
+ metavar="LIST",
371
+ type=lambda s: s.split(","),
372
+ help="specify a list of constraints",
373
+ ),
374
+ Pragma(
375
+ flags=["-F", "--nodefile"],
376
+ dest="nodefile",
377
+ metavar="FILENAME",
378
+ help="request a specific list of hosts",
379
+ ),
380
+ Pragma(
381
+ flags=["--mem"],
382
+ dest="mem",
383
+ metavar="MB",
384
+ type=int,
385
+ help="minimum amount of real memory",
386
+ example="25GB",
387
+ ),
388
+ Pragma(
389
+ flags=["--mincpus"],
390
+ dest="mincpus",
391
+ metavar="N",
392
+ type=int,
393
+ help="minimum number of logical processors per node",
394
+ ),
395
+ Pragma(
396
+ flags=["--reservation"],
397
+ dest="reservation",
398
+ metavar="NAME",
399
+ help="allocate resources from named reservation",
400
+ ),
401
+ Pragma(
402
+ flags=["--tmp"],
403
+ dest="tmp",
404
+ metavar="MB",
405
+ type=int,
406
+ help="minimum amount of temporary disk",
407
+ ),
408
+ Pragma(
409
+ flags=["-w", "--nodelist"],
410
+ dest="nodelist",
411
+ nargs="+",
412
+ metavar="HOST",
413
+ help="request a specific list of hosts",
414
+ ),
415
+ Pragma(
416
+ flags=["-x", "--exclude"],
417
+ dest="exclude",
418
+ nargs="+",
419
+ metavar="HOST",
420
+ help="exclude a specific list of hosts",
421
+ ),
422
+ Pragma(
423
+ flags=["--exclusive-user"],
424
+ dest="exclusive_user",
425
+ action="store_true",
426
+ help="allocate nodes in exclusive mode for cpu consumable resource",
427
+ ),
428
+ Pragma(
429
+ flags=["--exclusive-mcs"],
430
+ dest="exclusive_mcs",
431
+ action="store_true",
432
+ help="allocate nodes in exclusive mode when mcs plugin is enabled",
433
+ ),
434
+ Pragma(
435
+ flags=["--mem-per-cpu"],
436
+ dest="mem_per_cpu",
437
+ metavar="MB",
438
+ type=int,
439
+ help="maximum amount of real memory per allocated cpu",
440
+ ),
441
+ Pragma(
442
+ flags=["--resv-ports"],
443
+ dest="resv_ports",
444
+ action="store_true",
445
+ help="reserve communication ports",
446
+ ),
447
+ Pragma(
448
+ flags=["--sockets-per-node"],
449
+ dest="sockets_per_node",
450
+ metavar="S",
451
+ type=int,
452
+ help="number of sockets per node to allocate",
453
+ ),
454
+ Pragma(
455
+ flags=["--cores-per-socket"],
456
+ dest="cores_per_socket",
457
+ metavar="C",
458
+ type=int,
459
+ help="number of cores per socket to allocate",
460
+ example=8,
461
+ ),
462
+ Pragma(
463
+ flags=["--threads-per-core"],
464
+ dest="threads_per_core",
465
+ metavar="T",
466
+ type=int,
467
+ help="number of threads per core to allocate",
468
+ example=4,
469
+ ),
470
+ Pragma(
471
+ flags=["-B", "--extra-node-info"],
472
+ dest="extra_node_info",
473
+ metavar="S[:C[:T]]",
474
+ help="combine request of sockets, cores and threads",
475
+ ),
476
+ Pragma(
477
+ flags=["--ntasks-per-core"],
478
+ dest="ntasks_per_core",
479
+ metavar="N",
480
+ type=int,
481
+ help="number of tasks to invoke on each core",
482
+ example=16,
483
+ ),
484
+ Pragma(
485
+ flags=["--ntasks-per-socket"],
486
+ dest="ntasks_per_socket",
487
+ metavar="N",
488
+ type=int,
489
+ help="number of tasks to invoke on each socket",
490
+ example=8,
491
+ ),
492
+ Pragma(
493
+ flags=["--hint"],
494
+ dest="hint",
495
+ metavar="HINT",
496
+ help="Bind tasks according to application hints",
497
+ ),
498
+ Pragma(
499
+ flags=["--mem-bind"],
500
+ dest="mem_bind",
501
+ metavar="BIND",
502
+ help="Bind memory to locality domains",
503
+ ),
504
+ Pragma(
505
+ flags=["--cpus-per-gpu"],
506
+ dest="cpus_per_gpu",
507
+ metavar="N",
508
+ type=int,
509
+ help="number of CPUs required per allocated GPU",
510
+ example=4,
511
+ ),
512
+ Pragma(
513
+ flags=["-G", "--gpus"],
514
+ dest="gpus",
515
+ metavar="N",
516
+ type=int,
517
+ help="count of GPUs required for the job",
518
+ example=32,
519
+ ),
520
+ Pragma(
521
+ flags=["--gpu-bind"],
522
+ dest="gpu_bind",
523
+ metavar="...",
524
+ help="task to gpu binding options",
525
+ ),
526
+ Pragma(
527
+ flags=["--gpu-freq"],
528
+ dest="gpu_freq",
529
+ metavar="...",
530
+ help="frequency and voltage of GPUs",
531
+ ),
532
+ Pragma(
533
+ flags=["--gpus-per-node"],
534
+ dest="gpus_per_node",
535
+ metavar="N",
536
+ type=int,
537
+ help="number of GPUs required per allocated node",
538
+ ),
539
+ Pragma(
540
+ flags=["--gpus-per-socket"],
541
+ dest="gpus_per_socket",
542
+ metavar="N",
543
+ type=int,
544
+ help="number of GPUs required per allocated socket",
545
+ ),
546
+ Pragma(
547
+ flags=["--gpus-per-task"],
548
+ dest="gpus_per_task",
549
+ metavar="N",
550
+ type=int,
551
+ help="number of GPUs required per spawned task",
552
+ ),
553
+ Pragma(
554
+ flags=["--mem-per-gpu"],
555
+ dest="mem_per_gpu",
556
+ type=str,
557
+ help="real memory required per allocated GPU",
558
+ example="8GB",
559
+ ),
560
+ Pragma(
561
+ flags=["--disable-stdout-job-summary"],
562
+ dest="disable_stdout_job_summary",
563
+ action="store_true",
564
+ help="disable job summary in stdout file for the job",
565
+ ),
566
+ Pragma(
567
+ flags=["--nvmps"],
568
+ dest="nvmps",
569
+ action="store_true",
570
+ help="launching NVIDIA MPS for job",
571
+ ),
572
+ ]
@@ -0,0 +1,240 @@
1
+ Metadata-Version: 2.4
2
+ Name: slurm-script-generator
3
+ Version: 0.1
4
+ Summary: Generate slurm scripts.
5
+ Author: Max
6
+ Project-URL: Source, https://github.com/max-models/slurm-script-generator
7
+ Keywords: python
8
+ Classifier: Development Status :: 3 - Alpha
9
+ Classifier: Programming Language :: Python :: 3 :: Only
10
+ Classifier: Programming Language :: Python :: 3.8
11
+ Classifier: Programming Language :: Python :: 3.9
12
+ Classifier: Programming Language :: Python :: 3.10
13
+ Classifier: Programming Language :: Python :: 3.11
14
+ Classifier: Programming Language :: Python :: 3.12
15
+ Classifier: Programming Language :: Python :: 3.13
16
+ Requires-Python: >=3.8
17
+ Description-Content-Type: text/markdown
18
+ Provides-Extra: dev
19
+ Requires-Dist: black; extra == "dev"
20
+ Requires-Dist: check-manifest; extra == "dev"
21
+ Requires-Dist: isort; extra == "dev"
22
+ Requires-Dist: pytest; extra == "dev"
23
+ Provides-Extra: test
24
+ Requires-Dist: coverage; extra == "test"
25
+
26
+ # Slurm script generator
27
+
28
+ ## Install
29
+
30
+ ```
31
+ pip install .
32
+ ```
33
+
34
+ ## Generate scripts
35
+
36
+ Generate a slurm script to `slurm_script.sh` with
37
+
38
+ ```bash
39
+ ❯ generate-slurm-script --nodes 1 --ntasks-per-node 16 --output slurm_script.sh
40
+ ❯ cat slurm_script.sh
41
+ #!/bin/bash
42
+ ##########################################
43
+ #SBATCH --nodes 1 # number of nodes on which to run
44
+ #SBATCH --ntasks_per_node 16 # number of tasks to invoke on each node
45
+ ##########################################
46
+ ```
47
+
48
+ To export the settings to a json file you can use `--export-json`:
49
+
50
+ ```bash
51
+ ❯ generate-slurm-script --nodes 2 --export-json setup.json
52
+ #!/bin/bash
53
+ ##########################################
54
+ #SBATCH --nodes 2 # number of nodes on which to run
55
+ ##########################################
56
+ ```
57
+
58
+ This json file can used as a basis for creating new scripts
59
+
60
+ ```bash
61
+ ❯ generate-slurm-script --input setup.json --ntasks-per-node 16
62
+ #!/bin/bash
63
+ ##########################################
64
+ #SBATCH --nodes 2 # number of nodes on which to run
65
+ #SBATCH --ntasks_per_node 16 # number of tasks to invoke on each node
66
+ ##########################################
67
+ ```
68
+
69
+ ### Add modules
70
+
71
+ Add modules with
72
+
73
+ ```bash
74
+ ❯ generate-slurm-script --modules gcc/13 openmpi/5.0
75
+ #!/bin/bash
76
+ ##########################################
77
+ ##########################################
78
+
79
+ module purge # Purge modules
80
+ module load gcc/13 openmpi/5.0 # modules
81
+ module list # List loaded modules
82
+ ```
83
+
84
+ ### Add virtual environment
85
+
86
+ ```bash
87
+ ❯ generate-slurm-script --nodes 1 --ntasks-per-node 16 --venv ~/virtual_envs/env
88
+ args_dict.get("modules") = None
89
+ #!/bin/bash
90
+ ##########################################
91
+ #SBATCH --nodes 1 # number of nodes on which to run
92
+ #SBATCH --ntasks_per_node 16 # number of tasks to invoke on each node
93
+ ##########################################
94
+
95
+ source /Users/max/virtual_envs/env/bin/activate # virtual environment
96
+ ```
97
+
98
+ ### Other
99
+
100
+ All optional arguments can be shown with
101
+
102
+ ```bash
103
+ ❯ generate-slurm-script -h
104
+ usage: generate-slurm-script [-h] [-A NAME] [-b TIME] [--bell] [--no-bell] [--bb SPEC] [--bbf FILE_NAME] [-c NCPUS] [--comment NAME] [--container PATH] [--container-id ID]
105
+ [--cpu-freq MIN[-MAX[:GOV]]] [--delay-boot MINS] [-d TYPE:JOBID[:TIME]] [--deadline TIME] [-D PATH] [--get-user-env] [--gres LIST]
106
+ [--gres-flags OPTS] [-H] [-I [SECS]] [-J NAME] [-k] [-K [SIGNAL]] [-L NAMES] [-M NAMES] [-m TYPE] [--mail-type TYPE] [--mail-user USER]
107
+ [--mcs-label MCS] [-n N] [--nice [VALUE]] [-N NODES] [--ntasks-per-node N] [--oom-kill-step [0|1]] [-O] [--power FLAGS] [--priority VALUE]
108
+ [--profile VALUE] [-p PARTITION] [-q QOS] [-Q] [--reboot] [-s] [--signal [R:]NUM[@TIME]] [--spread-job] [--switches MAX_SWITCHES[@MAX_TIME]]
109
+ [-S CORES] [--thread-spec THREADS] [-t MINUTES] [--time-min MINUTES] [--tres-bind ...] [--tres-per-task LIST] [--use-min-nodes] [--wckey WCKEY]
110
+ [--cluster-constraint LIST] [--contiguous] [-C LIST] [-F FILENAME] [--mem MB] [--mincpus N] [--reservation NAME] [--tmp MB] [-w HOST [HOST ...]]
111
+ [-x HOST [HOST ...]] [--exclusive-user] [--exclusive-mcs] [--mem-per-cpu MB] [--resv-ports] [--sockets-per-node S] [--cores-per-socket C]
112
+ [--threads-per-core T] [-B S[:C[:T]]] [--ntasks-per-core N] [--ntasks-per-socket N] [--hint HINT] [--mem-bind BIND] [--cpus-per-gpu N] [-G N]
113
+ [--gpu-bind ...] [--gpu-freq ...] [--gpus-per-node N] [--gpus-per-socket N] [--gpus-per-task N] [--mem-per-gpu MEM_PER_GPU]
114
+ [--disable-stdout-job-summary] [--nvmps] [--line-length LINE_LENGHT] [--modules MODULES [MODULES ...]] [--venv VENV] [--printenv] [--print-self]
115
+ [--likwid] [--input INPUT_PATH] [--output OUTPUT_PATH] [--export-json JSON_PATH]
116
+
117
+ Slurm job submission options
118
+
119
+ options:
120
+ -h, --help show this help message and exit
121
+ -A, --account NAME charge job to specified account (default: None)
122
+ -b, --begin TIME defer job until HH:MM MM/DD/YY (default: None)
123
+ --bell ring the terminal bell when the job is allocated (default: False)
124
+ --no-bell do NOT ring the terminal bell (default: True)
125
+ --bb SPEC burst buffer specifications (default: None)
126
+ --bbf FILE_NAME burst buffer specification file (default: None)
127
+ -c, --cpus-per-task NCPUS
128
+ number of cpus required per task (default: None)
129
+ --comment NAME arbitrary comment (default: None)
130
+ --container PATH Path to OCI container bundle (default: None)
131
+ --container-id ID OCI container ID (default: None)
132
+ --cpu-freq MIN[-MAX[:GOV]]
133
+ requested cpu frequency (and governor) (default: None)
134
+ --delay-boot MINS delay boot for desired node features (default: None)
135
+ -d, --dependency TYPE:JOBID[:TIME]
136
+ defer job until condition on jobid is satisfied (default: None)
137
+ --deadline TIME remove the job if no ending possible before this deadline (default: None)
138
+ -D, --chdir PATH change working directory (default: None)
139
+ --get-user-env used by Moab. See srun man page (default: False)
140
+ --gres LIST required generic resources (default: None)
141
+ --gres-flags OPTS flags related to GRES management (default: None)
142
+ -H, --hold submit job in held state (default: False)
143
+ -I, --immediate [SECS]
144
+ exit if resources not available in "secs" (default: None)
145
+ -J, --job-name NAME name of job (default: None)
146
+ -k, --no-kill do not kill job on node failure (default: False)
147
+ -K, --kill-command [SIGNAL]
148
+ signal to send terminating job (default: None)
149
+ -L, --licenses NAMES required license, comma separated (default: None)
150
+ -M, --clusters NAMES Comma separated list of clusters to issue commands to (default: None)
151
+ -m, --distribution TYPE
152
+ distribution method for processes to nodes (default: None)
153
+ --mail-type TYPE notify on state change (default: None)
154
+ --mail-user USER who to send email notification for job state changes (default: None)
155
+ --mcs-label MCS mcs label if mcs plugin mcs/group is used (default: None)
156
+ -n, --ntasks N number of processors required (default: None)
157
+ --nice [VALUE] decrease scheduling priority by value (default: None)
158
+ -N, --nodes NODES number of nodes on which to run (default: None)
159
+ --ntasks-per-node N number of tasks to invoke on each node (default: None)
160
+ --oom-kill-step [0|1]
161
+ set the OOMKillStep behaviour (default: None)
162
+ -O, --overcommit overcommit resources (default: False)
163
+ --power FLAGS power management options (default: None)
164
+ --priority VALUE set the priority of the job (default: None)
165
+ --profile VALUE enable acct_gather_profile for detailed data (default: None)
166
+ -p, --partition PARTITION
167
+ partition requested (default: None)
168
+ -q, --qos QOS quality of service (default: None)
169
+ -Q, --quiet quiet mode (suppress informational messages) (default: False)
170
+ --reboot reboot compute nodes before starting job (default: False)
171
+ -s, --oversubscribe oversubscribe resources with other jobs (default: False)
172
+ --signal [R:]NUM[@TIME]
173
+ send signal when time limit within time seconds (default: None)
174
+ --spread-job spread job across as many nodes as possible (default: False)
175
+ --switches MAX_SWITCHES[@MAX_TIME]
176
+ optimum switches and max time to wait for optimum (default: None)
177
+ -S, --core-spec CORES
178
+ count of reserved cores (default: None)
179
+ --thread-spec THREADS
180
+ count of reserved threads (default: None)
181
+ -t, --time MINUTES time limit (default: None)
182
+ --time-min MINUTES minimum time limit (if distinct) (default: None)
183
+ --tres-bind ... task to tres binding options (default: None)
184
+ --tres-per-task LIST list of tres required per task (default: None)
185
+ --use-min-nodes if a range of node counts is given, prefer the smaller count (default: False)
186
+ --wckey WCKEY wckey to run job under (default: None)
187
+ --cluster-constraint LIST
188
+ specify a list of cluster constraints (default: None)
189
+ --contiguous demand a contiguous range of nodes (default: False)
190
+ -C, --constraint LIST
191
+ specify a list of constraints (default: None)
192
+ -F, --nodefile FILENAME
193
+ request a specific list of hosts (default: None)
194
+ --mem MB minimum amount of real memory (default: None)
195
+ --mincpus N minimum number of logical processors per node (default: None)
196
+ --reservation NAME allocate resources from named reservation (default: None)
197
+ --tmp MB minimum amount of temporary disk (default: None)
198
+ -w, --nodelist HOST [HOST ...]
199
+ request a specific list of hosts (default: None)
200
+ -x, --exclude HOST [HOST ...]
201
+ exclude a specific list of hosts (default: None)
202
+ --exclusive-user allocate nodes in exclusive mode for cpu consumable resource (default: False)
203
+ --exclusive-mcs allocate nodes in exclusive mode when mcs plugin is enabled (default: False)
204
+ --mem-per-cpu MB maximum amount of real memory per allocated cpu (default: None)
205
+ --resv-ports reserve communication ports (default: False)
206
+ --sockets-per-node S number of sockets per node to allocate (default: None)
207
+ --cores-per-socket C number of cores per socket to allocate (default: None)
208
+ --threads-per-core T number of threads per core to allocate (default: None)
209
+ -B, --extra-node-info S[:C[:T]]
210
+ combine request of sockets, cores and threads (default: None)
211
+ --ntasks-per-core N number of tasks to invoke on each core (default: None)
212
+ --ntasks-per-socket N
213
+ number of tasks to invoke on each socket (default: None)
214
+ --hint HINT Bind tasks according to application hints (default: None)
215
+ --mem-bind BIND Bind memory to locality domains (default: None)
216
+ --cpus-per-gpu N number of CPUs required per allocated GPU (default: None)
217
+ -G, --gpus N count of GPUs required for the job (default: None)
218
+ --gpu-bind ... task to gpu binding options (default: None)
219
+ --gpu-freq ... frequency and voltage of GPUs (default: None)
220
+ --gpus-per-node N number of GPUs required per allocated node (default: None)
221
+ --gpus-per-socket N number of GPUs required per allocated socket (default: None)
222
+ --gpus-per-task N number of GPUs required per spawned task (default: None)
223
+ --mem-per-gpu MEM_PER_GPU
224
+ real memory required per allocated GPU (default: None)
225
+ --disable-stdout-job-summary
226
+ disable job summary in stdout file for the job (default: False)
227
+ --nvmps launching NVIDIA MPS for job (default: False)
228
+ --line-length LINE_LENGHT
229
+ line length before start of comment (default: 40)
230
+ --modules MODULES [MODULES ...]
231
+ Modules to load (e.g., --modules mod1 mod2 mod3) (default: [])
232
+ --venv VENV virtual environment to load with `source VENV/bin/activate` (default: None)
233
+ --printenv print all environment variables (default: False)
234
+ --print-self print the batch script in the batch script (default: False)
235
+ --likwid Set up likwid environment variables (default: False)
236
+ --input INPUT_PATH path to input json file (default: None)
237
+ --output OUTPUT_PATH json path to save slurm batch script to (default: None)
238
+ --export-json JSON_PATH
239
+ path to export yaml for generating the slurm script to (default: None)
240
+ ```
@@ -0,0 +1,8 @@
1
+ slurm_script_generator/main.py,sha256=MJ5DJ5QgFoko_B-D1UQHYh2JhG8wjuCglJ5RhXAhJJ4,6670
2
+ slurm_script_generator/sbatch.py,sha256=DcTuzyWkt7mXEcofQbM7ydajBJ4CdTTtGiPW-cQTJMs,1938
3
+ slurm_script_generator/sbatch_parser.py,sha256=BAtuooI5ARRMpIjNfhgGspDmLs9ngITGbQZNEsP0TBU,14699
4
+ slurm_script_generator-0.1.dist-info/METADATA,sha256=bj7GI7TVdWQwHUBIjvTQuwLeKAWVFRZokaBaECrp9rI,13072
5
+ slurm_script_generator-0.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
6
+ slurm_script_generator-0.1.dist-info/entry_points.txt,sha256=3hkDhrBEjwGBvRoUfVj2M3PVT_tqyvlgixg0EgmN1IM,75
7
+ slurm_script_generator-0.1.dist-info/top_level.txt,sha256=3ltSu_DVIP0Ot4g-cBH-fDyoSTwieTZWDeBuHTX2xuY,23
8
+ slurm_script_generator-0.1.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (80.9.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ generate-slurm-script = slurm_script_generator.main:main
@@ -0,0 +1 @@
1
+ slurm_script_generator