The snowfall package offers some convenient routines for performing parallel computations using R. There are a couple of steps that need to be taken to use this package efficiently on the UB CCR cluster. These steps are described below and an example is available on CCR storage in the "/util/academic/R/snowfall-example" directory. Users may wish to copy the "slurm-snowfall-example" and "MySnowfallScript.R" files from this directory and edit them (e.g. using vimemacs, or gedit) as needed for their application. SLURM scripts can be submitted to the scheduler using the "sbatch" command.

1. Create a SLURM job script for launching the snowfall .R code as a batch job. The SLURM script should pass the number of processors and the node list as command line arguments to the .R code. Further, using "R CMD BATCH" to run the .R code is suggested instead of Rscript.  For example, consider the following SLURM script:  

#SBATCH --time=1:00:00
#SBATCH --nodes=3
#SBATCH --cpus-per-task=1
#SBATCH --tasks-per-node=8
#SBATCH --mail-type=END
#SBATCH --output=snowfall.out
#SBATCH --error=snowfall.err
#SBATCH --exclusive

tic=`date +%s`
echo "Start Time = "`date`

echo "working directory = "$SLURM_SUBMIT_DIR
module load R
module list
ulimit -s unlimited

# count the number of processors
np=`srun hostname -s | wc -l`

# generate nodelist
nodelist=`srun hostname -s | sort | tr '\n' ' '`

echo "Launching snowfall script using R"
# MySnowfallScript.R for this example is located here:
#   /util/R/snowfall-example
# It takes as arguments the number of processors (np)
# and a space-separated list of node names (nodelist)

R CMD BATCH --no-save --no-restore "--args $np $nodelist" MySnowfallScript.R

echo "All Done!"

echo "End Time = "`date`
toc=`date +%s`

elapsedTime=`expr $toc - $tic`
echo "Elapsed Time = $elapsedTime seconds" 


2. The .R code should extract the command line arguments provided by the SLURM script and pass them along to the sfInit() function. For example, consider the following snippet of R code:

# --------------------------------------
# extract command line args.
# arg 1 = number of cpus
# args 2 through N  = list of hostnames
# --------------------------------------
args = commandArgs(trailingOnly = TRUE);
ncpus = args[1];

# ------------------------------------------------------------------------
# initialize parallel mode using sockets and command-line args
# ------------------------------------------------------------------------
sfInit( parallel=TRUE, cpus=ncpus , type="SOCK", socketHosts=c(args[-1]));