View source: R/batchtools_slurm.R
| batchtools_slurm | R Documentation |
A batchtools Slurm backend resolves futures in parallel via a Slurm job scheduler
batchtools_slurm(
...,
template = "slurm",
scheduler.latency = 1,
fs.latency = 65,
resources = list(),
delete = getOption("future.batchtools.delete", "on-success"),
workers = getOption("future.batchtools.workers", default = 100L)
)
template |
(optional) Name of job-script template to be searched
for by |
scheduler.latency |
[ |
fs.latency |
[ |
resources |
(optional) A named list passed to the batchtools
job-script template as variable
|
delete |
Controls if and when the batchtools job registry folder is
deleted.
If |
workers |
The maximum number of workers the batchtools backend may
use at any time, which for HPC schedulers corresponds to the maximum number
of queued jobs. The default is
|
... |
Not used. |
Batchtools Slurm futures use batchtools cluster functions
created by makeClusterFunctionsSlurm2(), which are used
to interact with the Slurm job scheduler. This requires that Slurm
commands sbatch, squeue, sacct, and scancel are available on
the current machine.
The default template script templates/slurm.tmpl can be found in:
system.file("templates", "slurm.tmpl", package = "future.batchtools")
and comprises:
#!/bin/bash
######################################################################
# A batchtools launch script template for Slurm
#
# Author: Henrik Bengtsson
######################################################################
## Job name
#SBATCH --job-name=<%= job.name %>
## Direct streams to logfile
#SBATCH --output=<%= log.file %>
## Resources needed
<%
## Should scheduler "details" be seen?
details <- isTRUE(resources[["details"]])
resources[["details"]] <- NULL
## Shell "startup" code to evaluate
startup <- resources[["startup"]]
resources[["startup"]] <- NULL
## Shell "shutdown" code to evaluate
shutdown <- resources[["shutdown"]]
resources[["shutdown"]] <- NULL
## Environment modules specifications
modules <- resources[["modules"]]
resources[["modules"]] <- NULL
## Environment variables to be set
envs <- resources[["envs"]]
if (length(envs) > 0) {
stopifnot(is.character(envs), !is.null(names(envs)))
}
resources[["envs"]] <- NULL
## Custom "Rscript" command and Rscript arguments
rscript <- resources[["rscript"]]
if (is.null(rscript)) {
rscript <- "Rscript"
} else if (length(rscript) == 0 || !nzchar(rscript)[1]) {
stop("Argument 'resources' specifies an empty 'rscript' field")
}
resources[["rscript"]] <- NULL
rscript_args <- resources[["rscript_args"]]
resources[["rscript_args"]] <- NULL
rscript_call <- paste(c(rscript, rscript_args), collapse = " ")
## As-is resource specifications
job_declarations <- resources[["asis"]]
resources[["asis"]] <- NULL
## Remaining resources are assumed to be of type '<key>=<value>'
opts <- unlist(resources, use.names = TRUE)
opts <- sprintf("%s=%s", names(opts), opts)
job_declarations <- sprintf("#SBATCH %s", c(job_declarations, sprintf("--%s", opts)))
writeLines(job_declarations)
%>
## Bash settings
set -e # exit on error
set -u # error on unset variables
set -o pipefail # fail a pipeline if any command fails
trap 'echo "ERROR: future.batchtools job script failed on line $LINENO" >&2; exit 1' ERR
<% if (length(job_declarations) > 0) {
writeLines(c(
"echo 'Job submission declarations:'",
sprintf("echo '%s'", job_declarations),
"echo"
))
} %>
<% if (details) { %>
if command -v scontrol > /dev/null; then
echo "Job information:"
scontrol show job "${SLURM_JOB_ID}"
echo
fi
<% } %>
<% if (length(startup) > 0) {
writeLines(startup)
} %>
<% if (length(modules) > 0) {
writeLines(c(
"echo 'Load environment modules:'",
sprintf("echo '- modules: %s'", paste(modules, collapse = ", ")),
sprintf("module load %s", paste(modules, collapse = " ")),
"module list"
))
} %>
<% if (length(envs) > 0) {
writeLines(c(
sprintf("echo 'Setting environment variables: [n=%d]'", length(envs)),
sprintf("echo ' - %s=%s'", names(envs), shQuote(envs)),
sprintf("export %s=%s", names(envs), shQuote(envs))
))
} %>
echo "Session information:"
echo "- timestamp: $(date +"%Y-%m-%d %H:%M:%S%z")"
echo "- hostname: $(hostname)"
echo "- Rscript call: <%= rscript_call %>"
if ! command -v <%= rscript[1] %> &> /dev/null; then
>&2 echo "ERROR: Argument 'resources' specifies a non-existing 'Rscript' launch command: <%= rscript[1] %>. Maybe you need to specify which environment modules to load in the 'resources' argument, e.g. 'plan(future.batchtools::batchtools_slurm, resources = list(modules = c(\"r\")))'. The search PATH for '<%= rscript[1] %>' was ${PATH}"
exit 1
fi
echo "- Rscript version: $(<%= paste(rscript, collapse = " ") %> --version)"
echo "- R_LIBS_USER=${R_LIBS_USER:-<not set>}"
echo "- R_LIBS_SITE=${R_LIBS_SITE:-<not set>}"
echo "- R_LIBS=${R_LIBS:-<not set>}"
echo "- Rscript library paths: $(<%= rscript_call %> -e "cat(shQuote(.libPaths()), sep = ' ')")"
echo
## Launch R and evaluate the batchtools R job
echo "Calling 'batchtools::doJobCollection()' ..."
echo "- job name: '<%= job.name %>'"
echo "- job log file: '<%= log.file %>'"
echo "- job uri: '<%= uri %>'"
<%= rscript_call %> -e 'batchtools::doJobCollection("<%= uri %>")'
res=$?
echo " - exit code: ${res}"
echo "Calling 'batchtools::doJobCollection()' ... done"
echo
<% if (details) { %>
if command -v sstat > /dev/null; then
echo "Job summary:"
sstat --format="JobID,AveCPU,MaxRSS,MaxPages,MaxDiskRead,MaxDiskWrite" --allsteps --jobs="${SLURM_JOB_ID}"
fi
<% } %>
<% if (length(shutdown) > 0) {
writeLines(shutdown)
} %>
echo "End time: $(date +"%Y-%m-%d %H:%M:%S%z")"
## Relay the exit code from Rscript
exit "${res}"
This template and the built-in makeClusterFunctionsSlurm2()
have been verified to work on a few different Slurm HPC clusters;
Slurm 21.08.4, Rocky Linux 8, NFS global filesystem, UCSF C4 HPC environment (June 2026)
Slurm 22.05.10, Rocky Linux 9, Lustre global filesystem (September 2025)
Slurm 22.05.11, Rocky Linux 8, NFS global filesystem (September 2025)
Slurm 23.11.4, Ubuntu 24.04 LTS, NFS global filesystem, UC Berkeley SCF HPC environment (June 2026)
Slurm 24.11.3, AlmaLinux 9, Lustre global filesystem (September 2025)*
Slurm 24.11.5, Rocky Linux 9, VAST global filesystem, UCSF CoreHPC environment (June 2026)
(*) Verified with future.batchtools 0.20.0, which used
batchtools::makeClusterFunctionsSlurm() since superseeded by
makeClusterFunctionsSlurm2().
Nothing.
library(future)
# Limit runtime to 10 minutes and memory to 400 MiB per future,
# request a parallel environment with four slots on a single host.
# Submit to the 'freecycle' partition. Load environment modules 'r' and
# 'jags'. Report on job details at startup and at the end of the job.
plan(future.batchtools::batchtools_slurm, resources = list(
time = "00:10:00", mem = "400M",
nodes = 1, ntasks = 4, "cpus-per-task" = 1,
partition = "freecycle",
modules = c("r", "jags"),
details = TRUE
))
f <- future({
data.frame(
hostname = Sys.info()[["nodename"]],
os = Sys.info()[["sysname"]],
osVersion = utils::osVersion,
cores = unname(parallelly::availableCores())
)
})
info <- value(f)
print(info)
# As above, but use R from the Rocker 'r-base' Linux container;
#
# mkdir -p ~/lxc
# apptainer build ~/lxc/rocker_r-base.sif docker://rocker/r-base
#
# Example assumes that 'future.batchtools' has already been installed in
# the container to the 'R_LIBS_USER' package folder living on the host;
#
# R_LIBS_USER=~/R/rocker-%p-library/%v ~/lxc/rocker_r-base.sif
# ...
# > chooseCRANmirror(ind = 1)
# > install.packages("future.batchtools")
#
plan(future.batchtools::batchtools_slurm, resources = list(
time = "00:10:00", mem = "400M",
nodes = 1, ntasks = 4, "cpus-per-task" = 1,
partition = "freecycle",
details = TRUE,
envs = c(R_LIBS_USER = "~/R/rocker-%p-library/%v"),
rscript = c("apptainer", "exec", "~/lxc/rocker_r-base.sif", "Rscript")
))
f <- future({
data.frame(
hostname = Sys.info()[["nodename"]],
os = Sys.info()[["sysname"]],
osVersion = utils::osVersion,
cores = unname(parallelly::availableCores()),
modules = Sys.getenv("LOADEDMODULES")
)
})
info <- value(f)
print(info)
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.