A simple Snakemake profile for Slurm without
--cluster-generic-*-cmd
The option --cluster-config
is removed in snakemake>8.0.0
, but it's still
possible to set default and rule-specific resources for submitting jobs to a
remote scheduler using a combination of
--default-resources
and the resources
field in individual rules. This
profile is a simplified alternative to the more comprehensive official Slurm
profile for Snakemake. For more background, this blog
post by Sichong Peng nicely explains this strategy for replacing
--cluster-config
.
Warning
The Slurm profile and documentation in this repository have been updated to only support Snakemake versions >= 8.0.0. This is because Snakemake 8 completely overhauled how it submits jobs to external clusters, which broke this and all the other existing profiles. If you plan to continue to use Snakemake 7, you can find the Snakemake 7 version of the docs in the v7 branch of this repository.
-
Only requires a single configuration file to get started submitting jobs to Slurm
-
Easily add or remove options to pass to
sbatch
-
Automatically saves the log files as
logs/{rule}/{rule}-{wildcards}-%j.out
, where{rule}
is the name of the rule,{wildcards}
is any wildcards passed to the rule, and%j
is the job number -
Automatically names jobs using the pattern
smk-{rule}-{wildcards}
-
Fast! It can quickly submit jobs and check their status because it doesn't invoke a Python script for these steps, which adds up when you have thousands of jobs (however, please see the section Use speed with caution)
-
No reliance on the now-removed option
--cluster-config
or hard-to-read command-line flags (--cluster-generic-*-cmd
) to customize job resources -
By default it relies on Snakemake's built-in ability to understand the job statuses PENDING, RUNNING, COMPLETING, and OUT_OF_MEMORY
-
(Optional, but recommended) You can pass a simple script (see
extras/
) to--cluster-generic-status-cmd
to additionally handle the job statuses TIMEOUT and CANCELED -
New Support for cluster-cancel feature introduced in Snakemake 7.0.0 (see
examples/cluster-cancel/
) -
New Full support for multi-cluster setups (using a custom status script requires Snakemake 7.1.1+). See the section Multiple clusters below
-
New Adaptable for use with AWS ParallelCluster. See Christian Brueffer's profile snakemake-aws-parallelcluster-slurm
-
If you use job grouping, then you can't dynamically name the jobs and log files based on the name of the rules. This doesn't prevent you from using this profile and benefiting from its other features, but it is less convenient. Also note that job grouping isn't easy to use in the first place, since it sums resources like
mem_mb
andthreads
, but that is a limitation of Snakemake itself, and not anything in particular with this profile UPDATE: As of Snakemake 7.11, there is improved support for managing the maximum resources requested when submitting a grouped job that executes multiple rules. It's still non-trivial, but now at least possible. See the example inexamples/job-grouping/
for a demonstration of how to use the new features -
Wildcards can't contain
/
if you want to use them in the name of the Slurm log file. This is a Slurm requirement (which makes sense, since it has to create a file on the filesystem). You'll either have to change how you manage the wildcards or remove the{wildcards}
from the pattern passed to--output
, e.g.--output=logs/{rule}/{rule}-%j.out
. Note that you can still submit wildcards containing/
to--job-name
-
Requires Snakemake version 8.0.0 or later (released 2023-12-20, see changelog). You can test this directly in your
Snakefile
withmin_version()
. If you require an older version of Snakemake, please see thev7
branch
-
Download the configuration file
config.v8+.yaml
to your Snakemake project. It has to be in a subdirectory, e.g.simple/
-
Open it in your favorite text editor and replace all the placeholders surrounded in angle brackets (
<>
) with the options you use to submit jobs on your cluster -
You can override any of the defaults by adding a
resources
field to a rule, e.g.rule much_memory: resources: mem_mb=64000
-
Invoke snakemake with the profile:
snakemake --profile simple/
See the directory examples/
for examples you can experiment with
on your cluster.
To pass an additional argument to sbatch
that will be fixed across all job
submissions, add it directly to the arguments passed to sbatch
in the field
cluster-generic-submit-cmd
. For example, to specify an account to use for all job submissions, you can add the --account
argument as shown below:
executor: cluster-generic
cluster-generic-submit-cmd:
mkdir -p logs/{rule} &&
sbatch
--partition={resources.partition}
--qos={resources.qos}
--cpus-per-task={threads}
--mem={resources.mem_mb}
--job-name=smk-{rule}-{wildcards}
--output=logs/{rule}/{rule}-{wildcards}-%j.out
--account=myaccount
To pass an additional argument to sbatch
that can vary across job submissions,
add it to the arguments passed to sbatch
in the field cluster
, list a
default value in the field default-resources
, and update any rules that
require a value different from the default.
For example, the config.v8+.yaml
below sets a default time of 1 hour, and the
example rule overrides this default for a total of 3 hours. Note that the quotes
around the default time specification are required, even though you don't need
quotes when specifying the default for either partition
or qos
.
executor: cluster-generic
cluster-generic-submit-cmd:
mkdir -p logs/{rule} &&
sbatch
--partition={resources.partition}
--qos={resources.qos}
--cpus-per-task={threads}
--mem={resources.mem_mb}
--job-name=smk-{rule}-{wildcards}
--output=logs/{rule}/{rule}-{wildcards}-%j.out
--time={resources.time}
default-resources:
- partition=<name-of-default-partition>
- qos=<name-of-quality-of-service>
- mem_mb=1000
- time="01:00:00"
# A rule in Snakefile
rule more_time:
resources:
time = "03:00:00"
Note that sbatch
accepts time defined using various formats. Above I used
hours:minutes:seconds
, but the simple slurm profile is agnostic to how you
choose to configure this. It's a good idea to be consistent across rules, but
it's not required. From Slurm 19.05.7:
A time limit of zero requests that no time limit be imposed. Acceptable time formats include "minutes", "minutes:seconds", "hours:minutes:seconds", "days-hours", "days-hours:minutes" and "days-hours:minutes:seconds".
Thus to instead use minutes
, you could achieve the same effect as above with:
executor: cluster-generic
cluster-generic-submit-cmd:
mkdir -p logs/{rule} &&
sbatch
--partition={resources.partition}
--qos={resources.qos}
--cpus-per-task={threads}
--mem={resources.mem_mb}
--job-name=smk-{rule}-{wildcards}
--output=logs/{rule}/{rule}-{wildcards}-%j.out
--time={resources.time}
default-resources:
- partition=<name-of-default-partition>
- qos=<name-of-quality-of-service>
- mem_mb=1000
- time=60
# A rule in Snakefile
rule more_time:
resources:
time = 180
See examples/time-integer/
and
examples/time-string/
for examples you can play with.
Note that specifying the time as a string requires a minimum Snakemake version
of 5.15.0.
By default, snakemake can monitor jobs submitted to slurm. I realized this when
reading this detailed blog post, in which the author
decided not to use the cluster-status.py
script provided by the official
Slurm profile. Thus if you don't find that your jobs are
silently failing often, then there's no need to worry about this extra
configuration step.
However, if you start to have jobs silently fail often, e.g. with status
TIMEOUT
for exceeding their time limit, then you can add a custom script to
monitor the job status with the option --cluster-generic-status-cmd
.
The directory extras/
contains multiple options for checking the
status of the jobs. You can choose which one you'd like to use:
-
status-sacct.py
- This is the example from the Snakemake documentation. It usessacct
to query the status of each job by its ID -
status-sacct.sh
- (recommended) This is a Bash translation of the example from the Snakemake documentation. The Python script is simply shell-ing out tosacct
, so running Bash directly removes the overhead of repeatedly starting Python each time you check a job -
status-scontrol.sh
- This is a Bash script that usesscontrol
to query the status of each job by its ID. Thescontrol
command is fromslurm-status.py
in the official profile. If your HPC cluster doesn't havesacct
configured, you can use this option -
status-sacct-multi.sh
- Support for multi-cluster setup (see section Multiple clusters)
To use one of these status scripts:
-
Download the script to your profile directory where
config.yaml
is located -
Make the script executable, e.g.
chmod +x status-sacct.sh
-
Add the field
cluster-generic-status-cmd
to yourconfig.yaml
, e.g.cluster-generic-status-cmd: status-sacct.sh
-
Add the flag
--parsable
to yoursbatch
command (requires Slurm version 14.03.0rc1 or later)
It's possible for Slurm to submit jobs to multiple different clusters. Below is my advice on how to configure this. However, I've worked with multiple HPC clusters running Slurm, and have never encountered this situation. Thus I'd appreciate any contributions to improve the documentation below.
-
If you have access to multiple clusters, but only need to submit jobs to the default cluster, then you shouldn't have to modify anything in this profile
-
If you want to always submit your jobs to a cluster other than the default, or use multiple clusters, then pass the option
--clusters
tosbatch
, e.g. to submit your jobs to either cluster "c1" or "c2"# config.v8+.yaml executor: cluster-generic cluster-generic-submit-cmd: mkdir -p logs/{rule} && sbatch --clusters=c1,c2
-
To set a default cluster and override it for specific rules, use
--default-resources
. For example, to run on "c1" by default but "c2" for a specific rule:# config.v8+.yaml executor: cluster-generic cluster-generic-submit-cmd: mkdir -p logs/{rule} && sbatch --clusters={resources.clusters} default-resources: - clusters=c1
# Snakefile rule different_cluster: resources: clusters="c2"
-
Using a custom cluster status script in a multi-cluster setup requires Snakemake 7.1.1+ (or Snakemake 8.0.0+ if you are using the new
--cluster-generic-*-cmd
flags). After you add the flag--parsable
tosbatch
, it will returnjobid;cluster_name
. I adaptedstatus-sacct.sh
to handle this situation. Please seeexamples/multi-cluster/
to try outstatus-sacct-multi.sh
A big benefit of the simplicity of this profile is the speed in which jobs can be submitted and their statuses checked. The official Slurm profile for Snakemake provides a lot of extra fine-grained control, but this is all defined in Python scripts, which then have to be invoked for each job submission and status check. I needed this speed for a pipeline that had an aggregation rule that needed to be run tens of thousands of times, and the run time for each job was under 10 seconds. In this situation, the job submission rate and status check rate were huge bottlenecks.
However, you should use this speed with caution! On a shared HPC cluster, many
users are making requests to the Slurm scheduler. If too many requests are made
at once, the performance will suffer for all users. If the rules in your
Snakemake pipeline take at least more than a few minutes to complete, then it's
overkill to constantly check the status of multiple jobs in a single second. In
other words, only increase max-jobs-per-second
and/or
max-status-checks-per-second
if either the submission rate or status checks to
confirm job completion are clear bottlenecks.
This is all boiler plate code. Please feel free to use it for whatever purpose
you like. No need to attribute or cite this repo, but of course it comes with no
warranties. To make it official, it's released under the CC0 license. See
LICENSE
for details.