|
| 1 | +#' Batchtools futures for LSF, OpenLava, SGE, Slurm, TORQUE etc. |
| 2 | +#' |
| 3 | +#' Batchtools futures for LSF, OpenLava, SGE, Slurm, TORQUE etc. are |
| 4 | +#' asynchronous multiprocess futures that will be evaluated on a compute |
| 5 | +#' cluster via a job scheduler. |
| 6 | +#' |
| 7 | +#' @inheritParams BatchtoolsFutureBackend |
| 8 | +#' |
| 9 | +#' @param template (optional) A batchtools template file or a template string |
| 10 | +#' (in \pkg{brew} format). If not specified, it is left to the |
| 11 | +#' \pkg{batchtools} package to locate such file using its search rules. |
| 12 | +#' |
| 13 | +#' @param type (character string) Type of job scheduler. |
| 14 | +#' |
| 15 | +#' @param \ldots Additional arguments passed to [BatchtoolsFutureBackend()]. |
| 16 | +#' |
| 17 | +#' @return An object of class `BatchtoolsFutureBackend`. |
| 18 | +#' |
| 19 | +#' @details |
| 20 | +#' These type of batchtools futures rely on batchtools backends set |
| 21 | +#' up using the following \pkg{batchtools} functions: |
| 22 | +#' |
| 23 | +#' * [batchtools::makeClusterFunctionsLSF()] for |
| 24 | +#' [Load Sharing Facility (LSF)](https://en.wikipedia.org/wiki/Platform_LSF) |
| 25 | +#' * [batchtools::makeClusterFunctionsOpenLava()] for |
| 26 | +#' [OpenLava](https://en.wikipedia.org/wiki/OpenLava) |
| 27 | +#' * [batchtools::makeClusterFunctionsSGE()] for |
| 28 | +#' [Sun/Oracle Grid Engine (SGE)](https://en.wikipedia.org/wiki/Oracle_Grid_Engine) |
| 29 | +#' * [batchtools::makeClusterFunctionsSlurm()] for |
| 30 | +#' [Slurm](https://en.wikipedia.org/wiki/Slurm_Workload_Manager) |
| 31 | +#' * [batchtools::makeClusterFunctionsTORQUE()] for |
| 32 | +#' [TORQUE](https://en.wikipedia.org/wiki/TORQUE) / PBS |
| 33 | +#' |
| 34 | +#' @aliases BatchtoolsLsfFutureBackend BatchtoolsOpenLavaFutureBackend BatchtoolsSGEFutureBackend BatchtoolsSlurmFutureBackend BatchtoolsTorqueFutureBackend |
| 35 | +#' @aliases batchtools_lsf batchtools_openlava batchtools_sge batchtools_torque |
| 36 | +#' |
| 37 | +#' @importFrom batchtools makeClusterFunctionsLSF |
| 38 | +#' @importFrom batchtools makeClusterFunctionsOpenLava |
| 39 | +#' @importFrom batchtools makeClusterFunctionsSGE |
| 40 | +#' @importFrom batchtools makeClusterFunctionsSlurm |
| 41 | +#' @importFrom batchtools makeClusterFunctionsTORQUE |
| 42 | +#' @export |
| 43 | +BatchtoolsTemplateFutureBackend <- function(..., template = NULL, type = c("lsf", "openlava", "sge", "slurm", "torque")) { |
| 44 | + assert_no_positional_args_but_first() |
| 45 | + type <- match.arg(type) |
| 46 | + |
| 47 | + |
| 48 | + dotdotdot <- list(...) |
| 49 | + |
| 50 | + make_cfs <- switch(type, |
| 51 | + lsf = makeClusterFunctionsLSF, |
| 52 | + openlava = makeClusterFunctionsOpenLava, |
| 53 | + sge = makeClusterFunctionsSGE, |
| 54 | + slurm = makeClusterFunctionsSlurm, |
| 55 | + torque = makeClusterFunctionsTORQUE |
| 56 | + ) |
| 57 | + |
| 58 | + make_cfs_formals <- formals(make_cfs) |
| 59 | + |
| 60 | + ## Get the default template? |
| 61 | + if (is.null(template)) { |
| 62 | + template <- make_cfs_formals$template |
| 63 | + } |
| 64 | + |
| 65 | + stop_if_not(is.character(template), length(template) == 1L, |
| 66 | + !is.na(template), nzchar(template)) |
| 67 | + |
| 68 | + template <- find_template_file(template) |
| 69 | + |
| 70 | + keep <- which(names(dotdotdot) %in% names(make_cfs_formals)) |
| 71 | + args <- c(list(template = template), dotdotdot[keep]) |
| 72 | + cluster.functions <- do.call(make_cfs, args = args) |
| 73 | + attr(cluster.functions, "template") <- template |
| 74 | + |
| 75 | + ## Drop used '...' arguments |
| 76 | + if (length(keep) > 0) dotdotdot <- dotdotdot[-keep] |
| 77 | + |
| 78 | + args <- dotdotdot |
| 79 | + args[["cluster.functions"]] <- cluster.functions |
| 80 | + |
| 81 | + core <- do.call(BatchtoolsMultiprocessFutureBackend, args = args) |
| 82 | + |
| 83 | + core[["futureClasses"]] <- c("BatchtoolsTemplateFuture", "BatchtoolsMultiprocessFuture", core[["futureClasses"]]) |
| 84 | + core <- structure(core, class = c("BatchtoolsTemplateFutureBackend", class(core))) |
| 85 | + core |
| 86 | +} |
| 87 | + |
| 88 | + |
| 89 | +#' @export |
| 90 | +BatchtoolsSlurmFutureBackend <- function(...) { |
| 91 | + core <- BatchtoolsTemplateFutureBackend(..., type = "slurm") |
| 92 | + core[["futureClasses"]] <- c("BatchtoolsSlurmFuture", core[["futureClasses"]]) |
| 93 | + core <- structure(core, class = c("BatchtoolsSlurmFutureBackend", class(core))) |
| 94 | + core |
| 95 | +} |
| 96 | + |
| 97 | + |
| 98 | +#' A batchtools slurm backend resolves futures in parallel via a Slurm job scheduler |
| 99 | +#' |
| 100 | +#' @inheritParams BatchtoolsFutureBackend |
| 101 | +#' @inheritParams BatchtoolsTemplateFutureBackend |
| 102 | +#' |
| 103 | +#' @param template (optional) Name of job-script template to be searched |
| 104 | +#' for by [batchtools::findTemplateFile()]. If not found, it defaults to |
| 105 | +#' the `templates/slurm.tmpl` part of this package (see below). |
| 106 | +#' |
| 107 | +#' @param \ldots Not used. |
| 108 | +#' |
| 109 | +#' @details |
| 110 | +#' Batchtools slurm futures use \pkg{batchtools} cluster functions |
| 111 | +#' created by [batchtools::makeClusterFunctionsSlurm()], which requires |
| 112 | +#' that Slurm commands `sbatch`, `squeue`, and `scancel` are installed on |
| 113 | +#' the current machine. |
| 114 | +#' |
| 115 | +#' The default template script `templates/slurm.tmpl` can be found in: |
| 116 | +#' |
| 117 | +#' ```r |
| 118 | +#' system.file("templates", "slurm.tmpl", package = "future.batchtools") |
| 119 | +#' ``` |
| 120 | +#' |
| 121 | +#' and comprise: |
| 122 | +#' |
| 123 | +#' `r paste(c("\x60\x60\x60bash", readLines("inst/templates/slurm.tmpl"), "\x60\x60\x60"), collapse = "\n")` |
| 124 | +#' |
| 125 | +#' @examplesIf interactive() |
| 126 | +#' # Limit runtime to 3 minutes and memory to 200 MiB per future |
| 127 | +#' plan(batchtools_slurm, resources = list(time = "00:03:00", mem = "200M")) |
| 128 | +#' |
| 129 | +#' message("Main process ID: ", Sys.getpid()) |
| 130 | +#' |
| 131 | +#' f <- future(Sys.getpid()) |
| 132 | +#' pid <- value(f) |
| 133 | +#' message("Worker process ID: ", pid) |
| 134 | +#' |
| 135 | +#' @export |
| 136 | +batchtools_slurm <- function(...) { |
| 137 | + stop("INTERNAL ERROR: The future.batchtools::batchtools_slurm() must never be called directly") |
| 138 | +} |
| 139 | +class(batchtools_slurm) <- c( |
| 140 | + "batchtools_slurm", "batchtools_template", |
| 141 | + "batchtools_multiprocess", "batchtools", |
| 142 | + "multiprocess", "future", "function" |
| 143 | +) |
| 144 | +attr(batchtools_slurm, "tweakable") <- c( |
| 145 | + "workers", |
| 146 | + "finalize", |
| 147 | + ## Arguments to batchtools::makeClusterFunctionsSlurm() |
| 148 | + "array.jobs", "nodename", "scheduler.latency", "fs.latency" |
| 149 | +) |
| 150 | +attr(batchtools_slurm, "init") <- TRUE |
| 151 | +attr(batchtools_slurm, "factory") <- BatchtoolsSlurmFutureBackend |
0 commit comments