set.seed(20140219)
Y <- rnorm(5000, rep(c(1, 5, 10, 25, 50), rep(1000, 5)))
Y <- Y[sample(5000)]
G <- rep(1:100, rep(50, 100))
dofor <- function(x, y = Y, g = G) {
for (i in unique(g)) mean(y[g == i])
}
dotapp <- function(x, y = Y, g = G) {
tapply(y, g, function(z) mean(z))
}
repfn <- function(f, n = 100, cmp = FALSE) {
tm0 <- Sys.time()
if (cmp == TRUE)
f <- cmpfun(f)
replicate(n, f(0))
tm1 <- Sys.time()
(tm1 - tm0)/n
}
bench <- c(forLoop = repfn(dofor), tapply = repfn(dotapp))
bench/min(bench)
## forLoop tapply
## 3.167 1.000
compiler
package pre-installed.cmpfun
require(compiler)
bench <- c(bench,
forComp=repfn(dofor,cmp=TRUE),
forPreComp=repfn(cmpfun(dofor)),
tappComp=repfn(dotapp,cmp=TRUE)
)
bench/min(bench)
## forLoop tapply forComp forPreComp tappComp
## 3.167 1.000 3.132 3.081 1.032
fun <- function(x, y = Y, g = G) {
a <- 1:5000 * g
b <- y - 32
ab <- tcrossprod(a, b)
for (i in 1:5000) {
ab[i, i] <- g[i]%%3
}
for (i in 1:5000) {
ab[i, 1] <- a[i] - b[i]
ab[1, i] <- b[i] - a[i]
}
}
bench2 <- c(repfn(fun), repfn(fun, cmp = TRUE))
bench2/min(bench2)
## [1] 1.243 1.000
repfn
..Renviron
file in your home directory.R_COMPILE_PKGS=TRUE
R_ENABLE_JIT=3
snow
library.require(snow)
cl <- makeCluster(4)
dotappClus <- function(x) {
parLapply(cl, split(Y, G), mean)
}
repfnClus <- function(f, n = 100) {
tm0 <- Sys.time()
parSapply(cl, integer(n), f, y = Y, g = G)
tm1 <- Sys.time()
(tm1 - tm0)/n
}
bench <- c(bench, tappClus1 = repfn(dotappClus), tappClus2 = repfnClus(dotapp),
forClus = repfnClus(dofor))
stopCluster(cl)
bench/min(bench)
## forLoop tapply forComp forPreComp tappComp tappClus1
## 6.635 2.095 6.561 6.454 2.162 2.387
## tappClus2 forClus
## 1.000 2.800
snowfall
, doParallel
require(doParallel, quietly = TRUE)
cl <- makeCluster(4)
registerDoParallel(cl)
invisible({
t0 <- Sys.time()
foreach(i = 1:100) %dopar% dotapp(0)
t1 <- Sys.time()
})
stopCluster(cl)
bench <- c(bench, tappForEach = (t1 - t0)/100)
bench/min(bench)
## forLoop tapply forComp forPreComp tappComp tappClus1
## 6.635 2.095 6.561 6.454 2.162 2.387
## tappClus2 forClus tappForEach
## 1.000 2.800 2.033
Conceptually, it's trivial to parallelize chains in MCMC.
For JAGS, there is a package available, dclone
(for data cloning) that includes helpful functions to run chains in parallel.
Check the documentation, but it looks pretty easy. parJagsModel
and parCodaSamples
This package should take care of instantiating each pRNG with sufficiently different seeds.
For stan, you don't get much help. Do your parallelism in such a way that you get a list of stanfit
objects, then combine them with the helper function sflist2stanfit
.
So you could do something like:
parSapply(cl, function(i) stan(fit = f1, seed = seed, chains = 1, chain_id = i,
refresh = -1))
There are examples in the R documentation for sflist2stanfit
, so check that out.
By iterating the chainid, and having a consistent seed, stan should ensure that you get different pRNG sequences.
\home\ddd281\bin
(my "home" directory)~\bin
cd \home\ddd281
mkdir \home\ddd281\FolderName
ls -l ~\bin
\home\ddd281
- 5GB limit per user.
\scratch\ddd281
- This is the "working directory" for running jobs. It has a 5TB limit per user.
\archive\ddd281
- This is longer-term storage. It is backed up, and begins with an allocation of 2TB/user. Faculty sponsors can request more.mv src dst
to move file src
to dst
(can also function as a "rename")cp src dst
to copy file src
to dst
rm src
to remove (delete) src
-r
flag to them.rsync
to move files to and from the cluster, but you can also use WinSCP or gFTP or similar program.rsync -azvr src dst
- There are some funky things with trailing slashes. (read the manpage)hpctunnel
active, first, and then you can log onto the individual clusters to transfer files.ls -l | wc -l
lists the files in a directory, and then sends that output to the next command.wc -l
counts the lines in the input. So the combined command counts the number of files in a folder.ls -l > out.file
ls -l | wc -l >> out.file
&>
or &>>
(to redirect both stdout and stderr)2>
(1>
)vim
, nano
, emacs
, etc (personal preference, but vim
is the best)echo "This is a line ot text." > out.file
sed
) to do simple search and replace using regular expressions.cat out.file | sed "s/ot /of /" > out.file
fixes our typo..sh
#!\usr\bin\env bash
on the first linechmod +x scriptname.sh
./scriptname.sh
or sh scriptname.sh
$1
(for the 1st argument) and so on.VAR=24
and recalled with $VAR
$PATH
is your "search path" which lists (in order) where the shell will search for executable files.export PATH=/home/ddd281/bin:$PATH
nyuhpc_update.sh
#! /usr/bin/env bash
set -e
if [ "`ps aux |grep hpctunnel|wc -l`" -lt "2" ] ; then
echo "Need to have HPC's SSH tunnel active. Run ssh hpctunnel"
exit 0;
fi
if [ "$1" != "pdfs" ]; then
rsync -avzr --exclude '*.pdf' --delete cpp/ bowery:~/ocr_files/
exit 0;
fi
rsync -azvr --delete cpp/ bowery:~/ocr_files/
exit 0;
~/.ssh/config
file (create if it doesn't exit)ssh hpctunnel
and then login. Then, in a new terminal, you can connect to the cluster you want with ssh usq
, ssh bowery
, ssh cardiac1
ddd281@hpc.es.its.nyu.edu
, login, and then you can simply ssh usq
(or whichever cluster)Host hpctunnel
HostName hpc.es.its.nyu.edu
LocalForward 8020 usq.es.its.nyu.edu:22
LocalForward 8021 bowery.es.its.nyu.edu:22
LocalForward 8022 cardiac1.es.its.nyu.edu:22
User NetID
Host usq
HostName localhost
Port 8020
ForwardX11 yes
User NetID
Host bowery
HostName localhost
Port 8021
ForwardX11 yes
User NetID
Host cardiac1
HostName localhost
Port 8022
ForwardX11 yes
User NetID
Rscript filename.R
stata -b do filename
or stata < filename.do > filename.log
set processors X
where X is the number of cores to use../my_program
qsub -I -q interactive -l nodes=1:ppn=8,walltime=04:00:00
#PBS -V
#PBS -S /bin/bash
#PBS -N ocr-2014-02-19
#PBS -l nodes=1:ppn=1,walltime=10:00:00
#PBS -l mem=1GB
#PBS -q s48
#PBS -M ddd281@nyu.edu
#PBS -m bea
#PBS -w /scratch/ddd281/ocr_wd/
#PBS -e localhost:${PBS_O_WORKDIR}/pbs_files/${PBS_JOBNAME}.e${PBS_JOBID}
#PBS -o localhost:${PBS_O_WORKDIR}/pbs_files/${PBS_JOBNAME}.o${PBS_JOBID}
#PBS -V
- exports environment variables from current session to the job's sessionPBS -S /bin/bash
- which shell to use. No need to change this.#PBS -N ocr-2014-02-19
- a name for the job. This will be used in emails, and in naming some logfiles.#PBS -l nodes=1:ppn=1,walltime=10:00:00
nodes=1
- tells the scheduler how many nodes to allocate to the jobppn=1
- how many processors per node?walltime=10:00:00
- how much time to allocate to this job (and NO longer)#PBS -l mem=1GB
- how much memory to allocate to this job (and NO longer)#PBS -q s48
- which queue should this job be placed in?#PBS -M ddd281@nyu.edu
- NYU email#PBS -m bea
- email me on begin, aborts, ends#PBS -w /scratch/ddd281/ocr_wd/
- sets the working directory for the job#PBS -e localhost:${PBS_O_WORKDIR}/pbs_files/${PBS_JOBNAME}.e${PBS_JOBID}
- location to redirect stderr#PBS -o localhost:${PBS_O_WORKDIR}/pbs_files/${PBS_JOBNAME}.o${PBS_JOBID}
- location to redirect stdoutman qsub
for much more information on options.qsub
to submit a job (pbs script)showq | grep ddd281
to view your jobs in the queueqdel 1234
to delete job number 1234qstat 1234
to see status report on job 1234module avail
r/intel/3.0.1
module show r
for more info (for instance, where binaries are stored, etc)module load r/intel/3.0.1
module
command is available:source /etc/profile.d/env-modules.sh
hpc.R
args <- commandArgs(trailingOnly = TRUE)
if(length(args)!=2) stop(paste0("Not the right number of arguments!",args))
args <- as.double(args)
load("s_africa_data.Rdata")
require(cvTools)
require(topicmodels)
cvLDA <- function(Ntopics,K=5) {
folds<-cvFolds(nrow(dtm),K,1)
perplex <- rep(NA,K)
llk <- rep(NA,K)
for(i in unique(folds$which)){
which.test <- folds$subsets[folds$which==i]
which.train <- {1:nrow(dtm)}[-which.test]
dtm.train <- dtm[which.train,]
dtm.test <- dtm[which.test,]
lda.fit <- LDA(dtm.train,Ntopics)
perplex[i] <- perplexity(lda.fit,dtm.test)
llk[i] <- logLik(lda.fit)
}
perplex <- mean(perplex)
perpSD <- sd(perplex)
llk <- mean(llk)
llkSD <- sd(llk)
return(c(K=Ntopics,perplexity=perplex,perpSD=perpSD,logLik=llk,logLikSD=llkSD))
}
Topics.to.Est <- seq(args[1],args[2])
cv.out <- t(sapply(Topics.to.Est,cvLDA))
name<-paste0("cv.out.",min(Topics.to.Est),".",max(Topics.to.Est))
assign(name,cv.out)
save(list=name,file=paste0(name,".Rdata"))
ldacv.pbs
#!/bin/bash
#PBS -V
#PBS -S /bin/bash
#PBS -N ldacv-INSERTMIN-INSERTMAX
#PBS -l nodes=1:ppn=1,walltime=12:00:00
#PBS -l mem=8GB
#PBS -q s48
#PBS -M ddd281@nyu.edu
#PBS -m bea
#PBS -e localhost:${PBS_O_WORKDIR}/pbs_files/${PBS_JOBNAME}.e${PBS_JOBID}
#PBS -o localhost:${PBS_O_WORKDIR}/pbs_files/${PBS_JOBNAME}.o${PBS_JOBID}
set -e
OLDDIR=`pwd`
cd /scratch/ddd281/ldacv
module load gsl/intel/1.15
/home/ddd281/local/bin/Rscript --vanilla hpc.R INSERTMIN INSERTMAX
cd $OLDDIR
exit 0;
start_ldacv.sh
./start_ldacv.sh 50 50
./start_ldacv.sh 10 13
#!/bin/bash
set -e
cat ldacv.pbs | sed "s/INSERTMIN/$1/g" | sed "s/INSERTMAX/$2/g" > ldacv.${1}-${2}.pbs
qsub ldacv.${1}-${2}.pbs
rm ldacv.${1}-${2}.pbs
files <- dir()
files <- files[grep("cv.out", files)]
cv.out <- NULL
for (f in files) {
load(f)
vr <- strsplit(f, ".", fixed = TRUE)[[1]]
vr <- paste(vr[-length(vr)], collapse = ".")
cv.out <- rbind(cv.out, get(vr))
rm(list = vr)
}
cv.out <- cv.out[order(cv.out[, "K"]), ]
save(cv.out, file = "ldacv_all.Rdata")
snow
) would only be more complicated and error prone#PBS -l nodes=<N/12>:ppn=12
...
cd directory_for_job1
mpiexec -comm none -n 1 $executable arguments_for_job1 > output 2> error &
...
cd directory_for_jobN
mpiexec -comm none -n 1 $executable arguments_for_jobN > output 2> error &
wait
set -e
at the start of shell scripts! This will make it quit immediately upon encountering an error../configure
make && make install
--prefix=/home/ddd281/local
to configure
make && make install
as normal. This will install R to the appropriate directory.module load gcc/4.7.3
(on bowery, versions may be different, so check module avail
)\home\ddd281\local\bin
to your PATH, or you can just call R with \home\ddd281\local\bin\Rscript
module load intel/11.1.046
icc
/ icpc
/ etc-O2 -fPIC -align -Zp8 -axP -unroll -xP -ip
-shared-intel
to get my C++ to compile properly.