% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/availableWorkers.R
\name{availableWorkers}
\alias{availableWorkers}
\title{Get Set of Available Workers}
\usage{
availableWorkers(
  constraints = NULL,
  methods = getOption2("parallelly.availableWorkers.methods", c("mc.cores",
    "BiocParallel", "_R_CHECK_LIMIT_CORES_", "Bioconductor", "LSF", "PJM", "PBS", "SGE",
    "Slurm", "custom", "cgroups.cpuset", "cgroups.cpuquota", "cgroups2.cpu.max", "nproc",
    "system", "fallback")),
  na.rm = TRUE,
  logical = getOption2("parallelly.availableCores.logical", TRUE),
  default = getOption2("parallelly.localhost.hostname", "localhost"),
  which = c("auto", "min", "max", "all")
)
}
\arguments{
\item{constraints}{An optional character specifying under what
constraints ("purposes") we are requesting the values.
Using \code{constraints = "connections"}, will append \code{"connections"} to
the \code{methods} argument.}

\item{methods}{A character vector specifying how to infer the number
of available cores.}

\item{na.rm}{If TRUE, only non-missing settings are considered/returned.}

\item{logical}{Passed as-is to \code{\link[=availableCores]{availableCores()}}.}

\item{default}{The default set of workers.}

\item{which}{A character specifying which set / sets to return.
If \code{"auto"} (default), the first non-empty set found.
If \code{"min"}, the minimum value is returned.
If \code{"max"}, the maximum value is returned (be careful!)
If \code{"all"}, all values are returned.}
}
\value{
Return a character vector of workers, which typically consists
of names of machines / compute nodes, but may also be IP numbers.
}
\description{
Get Set of Available Workers
}
\details{
The default set of workers for each method is
\code{rep("localhost", times = availableCores(methods = method, logical = logical))},
which means that each will at least use as many parallel workers on the
current machine that \code{\link[=availableCores]{availableCores()}} allows for that method.

In addition, the following settings ("methods") are also acknowledged:
\itemize{
\item \code{"LSF"} -
Query LSF/OpenLava environment variable \env{LSB_HOSTS}.

\item \code{"PJM"} -
Query Fujitsu Technical Computing Suite (that we choose to shorten
as "PJM") the hostname file given by environment variable
\env{PJM_O_NODEINF}.
The \env{PJM_O_NODEINF} file lists the hostnames of the nodes allotted.
This function returns those hostnames each repeated \code{availableCores()}
times, where \code{availableCores()} reflects \env{PJM_VNODE_CORE}.
For example, for \verb{pjsub -L vnode=2 -L vnode-core=8 hello.sh}, the
\env{PJM_O_NODEINF} file gives two hostnames, and \env{PJM_VNODE_CORE}
gives eight cores per host, resulting in a character vector of 16
hostnames (for two unique hostnames).

\item \code{"PBS"} -
Query TORQUE/PBS environment variable \env{PBS_NODEFILE}.
If this is set and specifies an existing file, then the set
of workers is read from that file, where one worker (node)
is given per line.
An example of a job submission that results in this is
\verb{qsub -l nodes=4:ppn=2}, which requests four nodes each
with two cores.

\item \code{"SGE"} -
Query Sun Grid Engine/Oracle Grid Engine/Son of Grid Engine (SGE)
and Univa Grid Engine (UGE) environment variable \env{PE_HOSTFILE}.
An example of a job submission that results in this is
\verb{qsub -pe mpi 8} (or \verb{qsub -pe ompi 8}), which
requests eight cores on a any number of machines.

\item \code{"Slurm"} -
Query Slurm environment variable \env{SLURM_JOB_NODELIST} (fallback
to legacy \env{SLURM_NODELIST}) and parse set of nodes.
Then query Slurm environment variable \env{SLURM_JOB_CPUS_PER_NODE}
(fallback \env{SLURM_TASKS_PER_NODE}) to infer how many CPU cores
Slurm have allotted to each of the nodes.  If \env{SLURM_CPUS_PER_TASK}
is set, which is always a scalar, then that is respected too, i.e.
if it is smaller, then that is used for all nodes.
For example, if \code{SLURM_NODELIST="n1,n[03-05]"} (expands to
\code{c("n1", "n03", "n04", "n05")}) and \code{SLURM_JOB_CPUS_PER_NODE="2(x2),3,2"}
(expands to \code{c(2, 2, 3, 2)}), then
\code{c("n1", "n1", "n03", "n03", "n04", "n04", "n04", "n05", "n05")} is
returned.  If in addition, \code{SLURM_CPUS_PER_TASK=1}, which can happen
depending on hyperthreading configurations on the Slurm cluster, then
\code{c("n1", "n03", "n04", "n05")} is returned.

\item \code{"custom"} -
If option
\code{\link[=parallelly.options]{parallelly.availableWorkers.custom}}
is set and a function,
then this function will be called (without arguments) and it's value
will be coerced to a character vector, which will be interpreted as
hostnames of available workers.
It is safe for this custom function to call \code{availableWorkers()}; if
done, the custom function will \emph{not} be recursively called.
}
}
\section{Known limitations}{

\code{availableWorkers(methods = "Slurm")} will expand \env{SLURM_JOB_NODELIST}
using \command{scontrol show hostnames "$SLURM_JOB_NODELIST"}, if available.
If not available, then it attempts to parse the compressed nodelist based
on a best-guess understanding on what the possible syntax may be.
One known limitation is that "multi-dimensional" ranges are not supported,
e.g. \code{"a[1-2]b[3-4]"} is expanded by \command{scontrol} to
\code{c("a1b3", "a1b4", "a2b3", "a2b4")}.  If \command{scontrol} is not
available, then any components that failed to be parsed are dropped with
an informative warning message.  If no components could be parsed, then
the result of \code{methods = "Slurm"} will be empty.
}

\examples{
message(paste("Available workers:",
        paste(sQuote(availableWorkers()), collapse = ", ")))

\dontrun{
options(mc.cores = 2L)
message(paste("Available workers:",
        paste(sQuote(availableWorkers()), collapse = ", ")))
}

\dontrun{
## Always use two workers on host 'n1' and one on host 'n2'
options(parallelly.availableWorkers.custom = function() {
  c("n1", "n1", "n2")
})
message(paste("Available workers:",
        paste(sQuote(availableWorkers()), collapse = ", ")))
}

\dontrun{
## A 50\% random subset of the available workers.
## Note that it is safe to call availableWorkers() here.
options(parallelly.availableWorkers.custom = function() {
  workers <- parallelly::availableWorkers()
  sample(workers, size = 0.50 * length(workers))
})
message(paste("Available workers:",
        paste(sQuote(availableWorkers()), collapse = ", ")))
}

}
\seealso{
To get the number of available workers on the current machine,
see \code{\link[=availableCores]{availableCores()}}.
}
