snakemake-executor-plugin-slurm 0.15.0__py3-none-any.whl → 1.0.0__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.
Potentially problematic release.
This version of snakemake-executor-plugin-slurm might be problematic. Click here for more details.
- snakemake_executor_plugin_slurm/__init__.py +16 -7
- snakemake_executor_plugin_slurm/utils.py +62 -0
- {snakemake_executor_plugin_slurm-0.15.0.dist-info → snakemake_executor_plugin_slurm-1.0.0.dist-info}/METADATA +3 -2
- snakemake_executor_plugin_slurm-1.0.0.dist-info/RECORD +6 -0
- {snakemake_executor_plugin_slurm-0.15.0.dist-info → snakemake_executor_plugin_slurm-1.0.0.dist-info}/WHEEL +1 -1
- snakemake_executor_plugin_slurm-0.15.0.dist-info/RECORD +0 -6
- {snakemake_executor_plugin_slurm-0.15.0.dist-info → snakemake_executor_plugin_slurm-1.0.0.dist-info}/LICENSE +0 -0
|
@@ -26,9 +26,9 @@ from snakemake_interface_executor_plugins.jobs import (
|
|
|
26
26
|
JobExecutorInterface,
|
|
27
27
|
)
|
|
28
28
|
from snakemake_interface_common.exceptions import WorkflowError
|
|
29
|
-
from snakemake_executor_plugin_slurm_jobstep import
|
|
29
|
+
from snakemake_executor_plugin_slurm_jobstep import get_cpu_setting
|
|
30
30
|
|
|
31
|
-
from .utils import delete_slurm_environment, delete_empty_dirs
|
|
31
|
+
from .utils import delete_slurm_environment, delete_empty_dirs, set_gres_string
|
|
32
32
|
|
|
33
33
|
|
|
34
34
|
@dataclass
|
|
@@ -180,7 +180,9 @@ class Executor(RemoteExecutor):
|
|
|
180
180
|
group_or_rule = f"group_{job.name}" if job.is_group() else f"rule_{job.name}"
|
|
181
181
|
|
|
182
182
|
try:
|
|
183
|
-
wildcard_str =
|
|
183
|
+
wildcard_str = (
|
|
184
|
+
"_".join(job.wildcards).replace("/", "_") if job.wildcards else ""
|
|
185
|
+
)
|
|
184
186
|
except AttributeError:
|
|
185
187
|
wildcard_str = ""
|
|
186
188
|
|
|
@@ -208,7 +210,7 @@ class Executor(RemoteExecutor):
|
|
|
208
210
|
f"--job-name {self.run_uuid} "
|
|
209
211
|
f"--output '{slurm_logfile}' "
|
|
210
212
|
f"--export=ALL "
|
|
211
|
-
f"--comment {comment_str}"
|
|
213
|
+
f"--comment '{comment_str}'"
|
|
212
214
|
)
|
|
213
215
|
|
|
214
216
|
call += self.get_account_arg(job)
|
|
@@ -217,6 +219,8 @@ class Executor(RemoteExecutor):
|
|
|
217
219
|
if self.workflow.executor_settings.requeue:
|
|
218
220
|
call += " --requeue"
|
|
219
221
|
|
|
222
|
+
call += set_gres_string(job)
|
|
223
|
+
|
|
220
224
|
if job.resources.get("clusters"):
|
|
221
225
|
call += f" --clusters {job.resources.clusters}"
|
|
222
226
|
|
|
@@ -247,7 +251,11 @@ class Executor(RemoteExecutor):
|
|
|
247
251
|
|
|
248
252
|
# fixes #40 - set ntasks regardless of mpi, because
|
|
249
253
|
# SLURM v22.05 will require it for all jobs
|
|
250
|
-
|
|
254
|
+
gpu_job = job.resources.get("gpu") or "gpu" in job.resources.get("gres", "")
|
|
255
|
+
if gpu_job:
|
|
256
|
+
call += f" --ntasks-per-gpu={job.resources.get('tasks', 1)}"
|
|
257
|
+
else:
|
|
258
|
+
call += f" --ntasks={job.resources.get('tasks', 1)}"
|
|
251
259
|
# MPI job
|
|
252
260
|
if job.resources.get("mpi", False):
|
|
253
261
|
if not job.resources.get("tasks_per_node") and not job.resources.get(
|
|
@@ -259,8 +267,9 @@ class Executor(RemoteExecutor):
|
|
|
259
267
|
"Probably not what you want."
|
|
260
268
|
)
|
|
261
269
|
|
|
262
|
-
|
|
263
|
-
|
|
270
|
+
# we need to set cpus-per-task OR cpus-per-gpu, the function
|
|
271
|
+
# will return a string with the corresponding value
|
|
272
|
+
call += f" {get_cpu_setting(job, gpu_job)}"
|
|
264
273
|
if job.resources.get("slurm_extra"):
|
|
265
274
|
self.check_slurm_extra(job)
|
|
266
275
|
call += f" {job.resources.slurm_extra}"
|
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
# utility functions for the SLURM executor plugin
|
|
2
2
|
|
|
3
3
|
import os
|
|
4
|
+
import re
|
|
4
5
|
from pathlib import Path
|
|
5
6
|
|
|
7
|
+
from snakemake_interface_executor_plugins.jobs import (
|
|
8
|
+
JobExecutorInterface,
|
|
9
|
+
)
|
|
10
|
+
from snakemake_interface_common.exceptions import WorkflowError
|
|
11
|
+
|
|
6
12
|
|
|
7
13
|
def delete_slurm_environment():
|
|
8
14
|
"""
|
|
@@ -40,3 +46,59 @@ def delete_empty_dirs(path: Path) -> None:
|
|
|
40
46
|
except (OSError, FileNotFoundError) as e:
|
|
41
47
|
# Provide more context in the error message
|
|
42
48
|
raise OSError(f"Failed to remove empty directory {path}: {e}") from e
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def set_gres_string(job: JobExecutorInterface) -> str:
|
|
52
|
+
"""
|
|
53
|
+
Function to set the gres string for the SLURM job
|
|
54
|
+
based on the resources requested in the job.
|
|
55
|
+
"""
|
|
56
|
+
# generic resources (GRES) arguments can be of type
|
|
57
|
+
# "string:int" or "string:string:int"
|
|
58
|
+
gres_re = re.compile(r"^[a-zA-Z0-9_]+(:[a-zA-Z0-9_]+)?:\d+$")
|
|
59
|
+
# gpu model arguments can be of type "string"
|
|
60
|
+
gpu_model_re = re.compile(r"^[a-zA-Z0-9_]+$")
|
|
61
|
+
# The Snakemake resources can be only be of type "int",
|
|
62
|
+
# hence no further regex is needed.
|
|
63
|
+
|
|
64
|
+
gpu_string = None
|
|
65
|
+
if job.resources.get("gpu"):
|
|
66
|
+
gpu_string = str(job.resources.get("gpu"))
|
|
67
|
+
|
|
68
|
+
gpu_model = None
|
|
69
|
+
if job.resources.get("gpu_model"):
|
|
70
|
+
gpu_model = job.resources.get("gpu_model")
|
|
71
|
+
|
|
72
|
+
# ensure that gres is not set, if gpu and gpu_model are set
|
|
73
|
+
if job.resources.get("gres") and gpu_string:
|
|
74
|
+
raise WorkflowError(
|
|
75
|
+
"GRES and GPU are set. Please only set one of them.", rule=job.rule
|
|
76
|
+
)
|
|
77
|
+
elif not job.resources.get("gres") and not gpu_model and not gpu_string:
|
|
78
|
+
return ""
|
|
79
|
+
|
|
80
|
+
if job.resources.get("gres"):
|
|
81
|
+
# Validate GRES format (e.g., "gpu:1", "gpu:tesla:2")
|
|
82
|
+
gres = job.resources.gres
|
|
83
|
+
if not gres_re.match(gres):
|
|
84
|
+
raise WorkflowError(
|
|
85
|
+
f"Invalid GRES format: {gres}. Expected format: "
|
|
86
|
+
"'<name>:<number>' or '<name>:<type>:<number>' "
|
|
87
|
+
"(e.g., 'gpu:1' or 'gpu:tesla:2')"
|
|
88
|
+
)
|
|
89
|
+
return f" --gres={job.resources.gres}"
|
|
90
|
+
|
|
91
|
+
if gpu_model and gpu_string:
|
|
92
|
+
# validate GPU model format
|
|
93
|
+
if not gpu_model_re.match(gpu_model):
|
|
94
|
+
raise WorkflowError(
|
|
95
|
+
f"Invalid GPU model format: {gpu_model}."
|
|
96
|
+
" Expected format: '<name>' (e.g., 'tesla')"
|
|
97
|
+
)
|
|
98
|
+
return f" --gpus={gpu_model}:{gpu_string}"
|
|
99
|
+
elif gpu_model and not gpu_string:
|
|
100
|
+
raise WorkflowError("GPU model is set, but no GPU number is given")
|
|
101
|
+
elif gpu_string:
|
|
102
|
+
# we assume here, that the validator ensures that the 'gpu_string'
|
|
103
|
+
# is an integer
|
|
104
|
+
return f" --gpus={gpu_string}"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: snakemake-executor-plugin-slurm
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 1.0.0
|
|
4
4
|
Summary: A Snakemake executor plugin for submitting jobs to a SLURM cluster.
|
|
5
5
|
License: MIT
|
|
6
6
|
Keywords: snakemake,plugin,executor,cluster,slurm
|
|
@@ -12,7 +12,7 @@ Classifier: Programming Language :: Python :: 3
|
|
|
12
12
|
Classifier: Programming Language :: Python :: 3.11
|
|
13
13
|
Classifier: Programming Language :: Python :: 3.12
|
|
14
14
|
Classifier: Programming Language :: Python :: 3.13
|
|
15
|
-
Requires-Dist: snakemake-executor-plugin-slurm-jobstep (>=0.
|
|
15
|
+
Requires-Dist: snakemake-executor-plugin-slurm-jobstep (>=0.3.0,<0.4.0)
|
|
16
16
|
Requires-Dist: snakemake-interface-common (>=1.13.0,<2.0.0)
|
|
17
17
|
Requires-Dist: snakemake-interface-executor-plugins (>=9.1.1,<10.0.0)
|
|
18
18
|
Requires-Dist: throttler (>=1.2.2,<2.0.0)
|
|
@@ -25,3 +25,4 @@ Description-Content-Type: text/markdown
|
|
|
25
25
|
[](https://gitpod.io/#https://github.com/snakemake/snakemake-executor-plugin-slurm)
|
|
26
26
|
|
|
27
27
|
For documentation, see the [Snakemake plugin catalog](https://snakemake.github.io/snakemake-plugin-catalog/plugins/executor/slurm.html).
|
|
28
|
+
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
snakemake_executor_plugin_slurm/__init__.py,sha256=Bpro_L6Ca3kjnYXbpjpDKWFYE-fgZCW0sW41claGpp4,30090
|
|
2
|
+
snakemake_executor_plugin_slurm/utils.py,sha256=ZzXiXFDVLs15PLJnDP0eq98fNCtzlLbhtT03ec8Ou34,3578
|
|
3
|
+
snakemake_executor_plugin_slurm-1.0.0.dist-info/LICENSE,sha256=YVc4xTLWMqGfFL36120k7rzXtsT6e4RkJsh68VVn12s,1076
|
|
4
|
+
snakemake_executor_plugin_slurm-1.0.0.dist-info/METADATA,sha256=3wsaiJjVQrZXR5rcgtSqCU-HMWesfEqwtECI8COdeq0,1360
|
|
5
|
+
snakemake_executor_plugin_slurm-1.0.0.dist-info/WHEEL,sha256=XbeZDeTWKc1w7CSIyre5aMDU_-PohRwTQceYnisIYYY,88
|
|
6
|
+
snakemake_executor_plugin_slurm-1.0.0.dist-info/RECORD,,
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
snakemake_executor_plugin_slurm/__init__.py,sha256=FftjPVxYHcMNFvjq63D5xrlCZHNYBDNOEynfsoD5v1s,29670
|
|
2
|
-
snakemake_executor_plugin_slurm/utils.py,sha256=JOpQaUviGz6SORrMUsVDrSHc0lH6qX_SM0eUjVbWgp0,1282
|
|
3
|
-
snakemake_executor_plugin_slurm-0.15.0.dist-info/LICENSE,sha256=YVc4xTLWMqGfFL36120k7rzXtsT6e4RkJsh68VVn12s,1076
|
|
4
|
-
snakemake_executor_plugin_slurm-0.15.0.dist-info/METADATA,sha256=3swzWD9uoemx6bXSrpEEVEeKkDiBEJm_Q-mTED35UsA,1360
|
|
5
|
-
snakemake_executor_plugin_slurm-0.15.0.dist-info/WHEEL,sha256=IYZQI976HJqqOpQU6PHkJ8fb3tMNBFjg-Cn-pwAbaFM,88
|
|
6
|
-
snakemake_executor_plugin_slurm-0.15.0.dist-info/RECORD,,
|
|
File without changes
|