Skip to content
Snippets Groups Projects
Commit 1f662b23 authored by Pavel Gajdušek's avatar Pavel Gajdušek
Browse files

mdlint, edited tabulators

parent 64ebed9a
No related branches found
No related tags found
6 merge requests!368Update prace.md to document the change from qprace to qprod as the default...,!367Update prace.md to document the change from qprace to qprod as the default...,!366Update prace.md to document the change from qprace to qprod as the default...,!323extended-acls-storage-section,!196Master,!161Gajdusek cleaning
...@@ -92,26 +92,26 @@ r1i0n17$ matlab & ...@@ -92,26 +92,26 @@ r1i0n17$ matlab &
To run matlab in batch mode, write an matlab script, then write a bash jobscript and execute via the qsub command. By default, matlab will execute one matlab worker instance per allocated core. To run matlab in batch mode, write an matlab script, then write a bash jobscript and execute via the qsub command. By default, matlab will execute one matlab worker instance per allocated core.
```bash ```bash
#!/bin/bash #!/bin/bash
#PBS -A PROJECT ID #PBS -A PROJECT ID
#PBS -q qprod #PBS -q qprod
#PBS -l select=1:ncpus=16:mpiprocs=16:ompthreads=1 #PBS -l select=1:ncpus=16:mpiprocs=16:ompthreads=1
# change to shared scratch directory # change to shared scratch directory
SCR=/scratch/work/user/$USER/$PBS_JOBID SCR=/scratch/work/user/$USER/$PBS_JOBID
mkdir -p $SCR ; cd $SCR || exit mkdir -p $SCR ; cd $SCR || exit
# copy input file to scratch # copy input file to scratch
cp $PBS_O_WORKDIR/matlabcode.m . cp $PBS_O_WORKDIR/matlabcode.m .
# load modules # load modules
module load MATLAB/2015a-EDU module load MATLAB/2015a-EDU
# execute the calculation # execute the calculation
matlab -nodisplay -r matlabcode > output.out matlab -nodisplay -r matlabcode > output.out
# copy output file to home # copy output file to home
cp output.out $PBS_O_WORKDIR/. cp output.out $PBS_O_WORKDIR/.
``` ```
This script may be submitted directly to the PBS workload manager via the qsub command. The inputs and matlab script are in matlabcode.m file, outputs in output.out file. Note the missing .m extension in the matlab -r matlabcodefile call, **the .m must not be included**. Note that the **shared /scratch must be used**. Further, it is **important to include quit** statement at the end of the matlabcode.m script. This script may be submitted directly to the PBS workload manager via the qsub command. The inputs and matlab script are in matlabcode.m file, outputs in output.out file. Note the missing .m extension in the matlab -r matlabcodefile call, **the .m must not be included**. Note that the **shared /scratch must be used**. Further, it is **important to include quit** statement at the end of the matlabcode.m script.
...@@ -138,40 +138,40 @@ This script creates scheduler object "cluster" of type "local" that starts worke ...@@ -138,40 +138,40 @@ This script creates scheduler object "cluster" of type "local" that starts worke
The last step is to start matlabpool with "cluster" object and correct number of workers. We have 24 cores per node, so we start 24 workers. The last step is to start matlabpool with "cluster" object and correct number of workers. We have 24 cores per node, so we start 24 workers.
```console ```console
parpool(cluster,16); parpool(cluster,16);
... parallel code ... ... parallel code ...
parpool close parpool close
``` ```
The complete example showing how to use Distributed Computing Toolbox in local mode is shown here. The complete example showing how to use Distributed Computing Toolbox in local mode is shown here.
```console ```console
cluster = parcluster('local'); cluster = parcluster('local');
cluster cluster
parpool(cluster,24); parpool(cluster,24);
n=2000; n=2000;
W = rand(n,n); W = rand(n,n);
W = distributed(W); W = distributed(W);
x = (1:n)'; x = (1:n)';
x = distributed(x); x = distributed(x);
spmd spmd
[~, name] = system('hostname') [~, name] = system('hostname')
T = W*x; % Calculation performed on labs, in parallel. T = W*x; % Calculation performed on labs, in parallel.
% T and W are both codistributed arrays here. % T and W are both codistributed arrays here.
end end
T; T;
whos % T and W are both distributed arrays here. whos % T and W are both distributed arrays here.
parpool close parpool close
quit quit
``` ```
You can copy and paste the example in a .m file and execute. Note that the parpool size should correspond to **total number of cores** available on allocated nodes. You can copy and paste the example in a .m file and execute. Note that the parpool size should correspond to **total number of cores** available on allocated nodes.
...@@ -183,29 +183,29 @@ This mode uses PBS scheduler to launch the parallel pool. It uses the SalomonPBS ...@@ -183,29 +183,29 @@ This mode uses PBS scheduler to launch the parallel pool. It uses the SalomonPBS
This is an example of m-script using PBS mode: This is an example of m-script using PBS mode:
```console ```console
cluster = parcluster('SalomonPBSPro'); cluster = parcluster('SalomonPBSPro');
set(cluster, 'SubmitArguments', '-A OPEN-0-0'); set(cluster, 'SubmitArguments', '-A OPEN-0-0');
set(cluster, 'ResourceTemplate', '-q qprod -l select=10:ncpus=16'); set(cluster, 'ResourceTemplate', '-q qprod -l select=10:ncpus=16');
set(cluster, 'NumWorkers', 160); set(cluster, 'NumWorkers', 160);
pool = parpool(cluster, 160); pool = parpool(cluster, 160);
n=2000; n=2000;
W = rand(n,n); W = rand(n,n);
W = distributed(W); W = distributed(W);
x = (1:n)'; x = (1:n)';
x = distributed(x); x = distributed(x);
spmd spmd
[~, name] = system('hostname') [~, name] = system('hostname')
T = W*x; % Calculation performed on labs, in parallel. T = W*x; % Calculation performed on labs, in parallel.
% T and W are both codistributed arrays here. % T and W are both codistributed arrays here.
end end
whos % T and W are both distributed arrays here. whos % T and W are both distributed arrays here.
% shut down parallel pool % shut down parallel pool
delete(pool) delete(pool)
``` ```
Note that we first construct a cluster object using the imported profile, then set some important options, namely: SubmitArguments, where you need to specify accounting id, and ResourceTemplate, where you need to specify number of nodes to run the job. Note that we first construct a cluster object using the imported profile, then set some important options, namely: SubmitArguments, where you need to specify accounting id, and ResourceTemplate, where you need to specify number of nodes to run the job.
...@@ -224,28 +224,28 @@ For this method, you need to use SalomonDirect profile, import it using [the sam ...@@ -224,28 +224,28 @@ For this method, you need to use SalomonDirect profile, import it using [the sam
This is an example of m-script using direct mode: This is an example of m-script using direct mode:
```console ```console
parallel.importProfile('/apps/all/MATLAB/2015a-EDU/SalomonDirect.settings') parallel.importProfile('/apps/all/MATLAB/2015a-EDU/SalomonDirect.settings')
cluster = parcluster('SalomonDirect'); cluster = parcluster('SalomonDirect');
set(cluster, 'NumWorkers', 48); set(cluster, 'NumWorkers', 48);
pool = parpool(cluster, 48); pool = parpool(cluster, 48);
n=2000; n=2000;
W = rand(n,n); W = rand(n,n);
W = distributed(W); W = distributed(W);
x = (1:n)'; x = (1:n)';
x = distributed(x); x = distributed(x);
spmd spmd
[~, name] = system('hostname') [~, name] = system('hostname')
T = W*x; % Calculation performed on labs, in parallel. T = W*x; % Calculation performed on labs, in parallel.
% T and W are both codistributed arrays here. % T and W are both codistributed arrays here.
end end
whos % T and W are both distributed arrays here. whos % T and W are both distributed arrays here.
% shut down parallel pool % shut down parallel pool
delete(pool) delete(pool)
``` ```
### Non-Interactive Session and Licenses ### Non-Interactive Session and Licenses
......
...@@ -29,25 +29,25 @@ $ octave ...@@ -29,25 +29,25 @@ $ octave
To run octave in batch mode, write an octave script, then write a bash jobscript and execute via the qsub command. By default, octave will use 16 threads when running MKL kernels. To run octave in batch mode, write an octave script, then write a bash jobscript and execute via the qsub command. By default, octave will use 16 threads when running MKL kernels.
```bash ```bash
#!/bin/bash #!/bin/bash
# change to local scratch directory # change to local scratch directory
cd /lscratch/$PBS_JOBID || exit cd /lscratch/$PBS_JOBID || exit
# copy input file to scratch # copy input file to scratch
cp $PBS_O_WORKDIR/octcode.m . cp $PBS_O_WORKDIR/octcode.m .
# load octave module # load octave module
module load octave module load octave
# execute the calculation # execute the calculation
octave -q --eval octcode > output.out octave -q --eval octcode > output.out
# copy output file to home # copy output file to home
cp output.out $PBS_O_WORKDIR/. cp output.out $PBS_O_WORKDIR/.
#exit #exit
exit exit
``` ```
This script may be submitted directly to the PBS workload manager via the qsub command. The inputs are in octcode.m file, outputs in output.out file. See the single node jobscript example in the [Job execution section](../../job-submission-and-execution/). This script may be submitted directly to the PBS workload manager via the qsub command. The inputs are in octcode.m file, outputs in output.out file. See the single node jobscript example in the [Job execution section](../../job-submission-and-execution/).
......
...@@ -45,25 +45,25 @@ To run R in batch mode, write an R script, then write a bash jobscript and execu ...@@ -45,25 +45,25 @@ To run R in batch mode, write an R script, then write a bash jobscript and execu
Example jobscript: Example jobscript:
```bash ```bash
#!/bin/bash #!/bin/bash
# change to local scratch directory # change to local scratch directory
cd /lscratch/$PBS_JOBID || exit cd /lscratch/$PBS_JOBID || exit
# copy input file to scratch # copy input file to scratch
cp $PBS_O_WORKDIR/rscript.R . cp $PBS_O_WORKDIR/rscript.R .
# load R module # load R module
module load R module load R
# execute the calculation # execute the calculation
R CMD BATCH rscript.R routput.out R CMD BATCH rscript.R routput.out
# copy output file to home # copy output file to home
cp routput.out $PBS_O_WORKDIR/. cp routput.out $PBS_O_WORKDIR/.
#exit #exit
exit exit
``` ```
This script may be submitted directly to the PBS workload manager via the qsub command. The inputs are in rscript.R file, outputs in routput.out file. See the single node jobscript example in the [Job execution section](../../job-submission-and-execution/). This script may be submitted directly to the PBS workload manager via the qsub command. The inputs are in rscript.R file, outputs in routput.out file. See the single node jobscript example in the [Job execution section](../../job-submission-and-execution/).
...@@ -105,35 +105,35 @@ The forking is the most simple to use. Forking family of functions provide paral ...@@ -105,35 +105,35 @@ The forking is the most simple to use. Forking family of functions provide paral
Forking example: Forking example:
```r ```r
library(parallel) library(parallel)
#integrand function #integrand function
f <- function(i,h) { f <- function(i,h) {
x <- h*(i-0.5) x <- h*(i-0.5)
return (4/(1 + x*x)) return (4/(1 + x*x))
} }
#initialize #initialize
size <- detectCores() size <- detectCores()
while (TRUE) while (TRUE)
{ {
#read number of intervals #read number of intervals
cat("Enter the number of intervals: (0 quits) ") cat("Enter the number of intervals: (0 quits) ")
fp<-file("stdin"); n<-scan(fp,nmax=1); close(fp) fp<-file("stdin"); n<-scan(fp,nmax=1); close(fp)
if(n<=0) break if(n<=0) break
#run the calculation #run the calculation
n <- max(n,size) n <- max(n,size)
h <- 1.0/n h <- 1.0/n
i <- seq(1,n); i <- seq(1,n);
pi3 <- h*sum(simplify2array(mclapply(i,f,h,mc.cores=size))); pi3 <- h*sum(simplify2array(mclapply(i,f,h,mc.cores=size)));
#print results #print results
cat(sprintf("Value of PI %16.14f, diff= %16.14fn",pi3,pi3-pi)) cat(sprintf("Value of PI %16.14f, diff= %16.14fn",pi3,pi3-pi))
} }
``` ```
The above example is the classic parallel example for calculating the number π. Note the **detectCores()** and **mclapply()** functions. Execute the example as: The above example is the classic parallel example for calculating the number π. Note the **detectCores()** and **mclapply()** functions. Execute the example as:
...@@ -169,47 +169,47 @@ Static Rmpi programs are executed via mpiexec, as any other MPI programs. Number ...@@ -169,47 +169,47 @@ Static Rmpi programs are executed via mpiexec, as any other MPI programs. Number
Static Rmpi example: Static Rmpi example:
```r ```r
library(Rmpi) library(Rmpi)
#integrand function #integrand function
f <- function(i,h) { f <- function(i,h) {
x <- h*(i-0.5) x <- h*(i-0.5)
return (4/(1 + x*x)) return (4/(1 + x*x))
} }
#initialize #initialize
invisible(mpi.comm.dup(0,1)) invisible(mpi.comm.dup(0,1))
rank <- mpi.comm.rank() rank <- mpi.comm.rank()
size <- mpi.comm.size() size <- mpi.comm.size()
n<-0 n<-0
while (TRUE) while (TRUE)
{ {
#read number of intervals #read number of intervals
if (rank==0) { if (rank==0) {
cat("Enter the number of intervals: (0 quits) ") cat("Enter the number of intervals: (0 quits) ")
fp<-file("stdin"); n<-scan(fp,nmax=1); close(fp) fp<-file("stdin"); n<-scan(fp,nmax=1); close(fp)
} }
#broadcat the intervals #broadcat the intervals
n <- mpi.bcast(as.integer(n),type=1) n <- mpi.bcast(as.integer(n),type=1)
if(n<=0) break if(n<=0) break
#run the calculation #run the calculation
n <- max(n,size) n <- max(n,size)
h <- 1.0/n h <- 1.0/n
i <- seq(rank+1,n,size); i <- seq(rank+1,n,size);
mypi <- h*sum(sapply(i,f,h)); mypi <- h*sum(sapply(i,f,h));
pi3 <- mpi.reduce(mypi) pi3 <- mpi.reduce(mypi)
#print results #print results
if (rank==0) cat(sprintf("Value of PI %16.14f, diff= %16.14fn",pi3,pi3-pi)) if (rank==0) cat(sprintf("Value of PI %16.14f, diff= %16.14fn",pi3,pi3-pi))
} }
mpi.quit() mpi.quit()
``` ```
The above is the static MPI example for calculating the number π. Note the **library(Rmpi)** and **mpi.comm.dup()** function calls. The above is the static MPI example for calculating the number π. Note the **library(Rmpi)** and **mpi.comm.dup()** function calls.
...@@ -227,61 +227,61 @@ Dynamic Rmpi programs are executed by calling the R directly. openmpi module mus ...@@ -227,61 +227,61 @@ Dynamic Rmpi programs are executed by calling the R directly. openmpi module mus
Dynamic Rmpi example: Dynamic Rmpi example:
```r ```r
#integrand function #integrand function
f <- function(i,h) { f <- function(i,h) {
x <- h*(i-0.5) x <- h*(i-0.5)
return (4/(1 + x*x)) return (4/(1 + x*x))
} }
#the worker function #the worker function
workerpi <- function() workerpi <- function()
{ {
#initialize #initialize
rank <- mpi.comm.rank() rank <- mpi.comm.rank()
size <- mpi.comm.size() size <- mpi.comm.size()
n<-0 n<-0
while (TRUE) while (TRUE)
{ {
#read number of intervals #read number of intervals
if (rank==0) { if (rank==0) {
cat("Enter the number of intervals: (0 quits) ") cat("Enter the number of intervals: (0 quits) ")
fp<-file("stdin"); n<-scan(fp,nmax=1); close(fp) fp<-file("stdin"); n<-scan(fp,nmax=1); close(fp)
} }
#broadcat the intervals #broadcat the intervals
n <- mpi.bcast(as.integer(n),type=1) n <- mpi.bcast(as.integer(n),type=1)
if(n<=0) break if(n<=0) break
#run the calculation #run the calculation
n <- max(n,size) n <- max(n,size)
h <- 1.0/n h <- 1.0/n
i <- seq(rank+1,n,size); i <- seq(rank+1,n,size);
mypi <- h*sum(sapply(i,f,h)); mypi <- h*sum(sapply(i,f,h));
pi3 <- mpi.reduce(mypi) pi3 <- mpi.reduce(mypi)
#print results #print results
if (rank==0) cat(sprintf("Value of PI %16.14f, diff= %16.14fn",pi3,pi3-pi)) if (rank==0) cat(sprintf("Value of PI %16.14f, diff= %16.14fn",pi3,pi3-pi))
} }
} }
#main #main
library(Rmpi) library(Rmpi)
cat("Enter the number of slaves: ") cat("Enter the number of slaves: ")
fp<-file("stdin"); ns<-scan(fp,nmax=1); close(fp) fp<-file("stdin"); ns<-scan(fp,nmax=1); close(fp)
mpi.spawn.Rslaves(nslaves=ns) mpi.spawn.Rslaves(nslaves=ns)
mpi.bcast.Robj2slave(f) mpi.bcast.Robj2slave(f)
mpi.bcast.Robj2slave(workerpi) mpi.bcast.Robj2slave(workerpi)
mpi.bcast.cmd(workerpi()) mpi.bcast.cmd(workerpi())
workerpi() workerpi()
mpi.quit() mpi.quit()
``` ```
The above example is the dynamic MPI example for calculating the number π. Both master and slave processes carry out the calculation. Note the mpi.spawn.Rslaves(), mpi.bcast.Robj2slave()** and the mpi.bcast.cmd()** function calls. The above example is the dynamic MPI example for calculating the number π. Both master and slave processes carry out the calculation. Note the mpi.spawn.Rslaves(), mpi.bcast.Robj2slave()** and the mpi.bcast.cmd()** function calls.
...@@ -304,51 +304,51 @@ Execution is identical to other dynamic Rmpi programs. ...@@ -304,51 +304,51 @@ Execution is identical to other dynamic Rmpi programs.
mpi.apply Rmpi example: mpi.apply Rmpi example:
```r ```r
#integrand function #integrand function
f <- function(i,h) { f <- function(i,h) {
x <- h*(i-0.5) x <- h*(i-0.5)
return (4/(1 + x*x)) return (4/(1 + x*x))
} }
#the worker function #the worker function
workerpi <- function(rank,size,n) workerpi <- function(rank,size,n)
{ {
#run the calculation #run the calculation
n <- max(n,size) n <- max(n,size)
h <- 1.0/n h <- 1.0/n
i <- seq(rank,n,size); i <- seq(rank,n,size);
mypi <- h*sum(sapply(i,f,h)); mypi <- h*sum(sapply(i,f,h));
return(mypi) return(mypi)
} }
#main #main
library(Rmpi) library(Rmpi)
cat("Enter the number of slaves: ") cat("Enter the number of slaves: ")
fp<-file("stdin"); ns<-scan(fp,nmax=1); close(fp) fp<-file("stdin"); ns<-scan(fp,nmax=1); close(fp)
mpi.spawn.Rslaves(nslaves=ns) mpi.spawn.Rslaves(nslaves=ns)
mpi.bcast.Robj2slave(f) mpi.bcast.Robj2slave(f)
mpi.bcast.Robj2slave(workerpi) mpi.bcast.Robj2slave(workerpi)
while (TRUE) while (TRUE)
{ {
#read number of intervals #read number of intervals
cat("Enter the number of intervals: (0 quits) ") cat("Enter the number of intervals: (0 quits) ")
fp<-file("stdin"); n<-scan(fp,nmax=1); close(fp) fp<-file("stdin"); n<-scan(fp,nmax=1); close(fp)
if(n<=0) break if(n<=0) break
#run workerpi #run workerpi
i=seq(1,2*ns) i=seq(1,2*ns)
pi3=sum(mpi.parSapply(i,workerpi,2*ns,n)) pi3=sum(mpi.parSapply(i,workerpi,2*ns,n))
#print results #print results
cat(sprintf("Value of PI %16.14f, diff= %16.14fn",pi3,pi3-pi)) cat(sprintf("Value of PI %16.14f, diff= %16.14fn",pi3,pi3-pi))
} }
mpi.quit() mpi.quit()
``` ```
The above is the mpi.apply MPI example for calculating the number π. Only the slave processes carry out the calculation. Note the **mpi.parSapply()**, function call. The package parallel [example](r/#package-parallel)[above](r/#package-parallel) may be trivially adapted (for much better performance) to this structure using the mclapply() in place of mpi.parSapply(). The above is the mpi.apply MPI example for calculating the number π. Only the slave processes carry out the calculation. Note the **mpi.parSapply()**, function call. The package parallel [example](r/#package-parallel)[above](r/#package-parallel) may be trivially adapted (for much better performance) to this structure using the mclapply() in place of mpi.parSapply().
...@@ -370,30 +370,30 @@ The R parallel jobs are executed via the PBS queue system exactly as any other p ...@@ -370,30 +370,30 @@ The R parallel jobs are executed via the PBS queue system exactly as any other p
Example jobscript for [static Rmpi](r/#static-rmpi) parallel R execution, running 1 process per core: Example jobscript for [static Rmpi](r/#static-rmpi) parallel R execution, running 1 process per core:
```bash ```bash
#!/bin/bash #!/bin/bash
#PBS -q qprod #PBS -q qprod
#PBS -N Rjob #PBS -N Rjob
#PBS -l select=100:ncpus=16:mpiprocs=16:ompthreads=1 #PBS -l select=100:ncpus=16:mpiprocs=16:ompthreads=1
# change to scratch directory # change to scratch directory
SCRDIR=/scratch/$USER/myjob SCRDIR=/scratch/$USER/myjob
cd $SCRDIR || exit cd $SCRDIR || exit
# copy input file to scratch # copy input file to scratch
cp $PBS_O_WORKDIR/rscript.R . cp $PBS_O_WORKDIR/rscript.R .
# load R and openmpi module # load R and openmpi module
module load R module load R
module load openmpi module load openmpi
# execute the calculation # execute the calculation
mpiexec -bycore -bind-to-core R --slave --no-save --no-restore -f rscript.R mpiexec -bycore -bind-to-core R --slave --no-save --no-restore -f rscript.R
# copy output file to home # copy output file to home
cp routput.out $PBS_O_WORKDIR/. cp routput.out $PBS_O_WORKDIR/.
#exit #exit
exit exit
``` ```
For more information about jobscript and MPI execution refer to the [Job submission](../../job-submission-and-execution/) and general [MPI](../mpi/mpi/) sections. For more information about jobscript and MPI execution refer to the [Job submission](../../job-submission-and-execution/) and general [MPI](../mpi/mpi/) sections.
...@@ -50,11 +50,11 @@ Delete previously used file mpiLibConf.m, we have observed crashes when using In ...@@ -50,11 +50,11 @@ Delete previously used file mpiLibConf.m, we have observed crashes when using In
To use Distributed Computing, you first need to setup a parallel profile. We have provided the profile for you, you can either import it in MATLAB command line: To use Distributed Computing, you first need to setup a parallel profile. We have provided the profile for you, you can either import it in MATLAB command line:
```console ```console
> parallel.importProfile('/apps/all/MATLAB/2015b-EDU/SalomonPBSPro.settings') > parallel.importProfile('/apps/all/MATLAB/2015b-EDU/SalomonPBSPro.settings')
ans = ans =
SalomonPBSPro SalomonPBSPro
``` ```
Or in the GUI, go to tab HOME -> Parallel -> Manage Cluster Profiles..., click Import and navigate to : Or in the GUI, go to tab HOME -> Parallel -> Manage Cluster Profiles..., click Import and navigate to :
...@@ -79,8 +79,8 @@ The second part of the command shows how to request all necessary licenses. In t ...@@ -79,8 +79,8 @@ The second part of the command shows how to request all necessary licenses. In t
Once the access to compute nodes is granted by PBS, user can load following modules and start Matlab: Once the access to compute nodes is granted by PBS, user can load following modules and start Matlab:
```console ```console
r1i0n17$ ml MATLAB/2015a-EDU r1i0n17$ ml MATLAB/2015a-EDU
r1i0n17$ matlab & r1i0n17$ matlab &
``` ```
### Parallel Matlab Batch Job in Local Mode ### Parallel Matlab Batch Job in Local Mode
...@@ -88,26 +88,26 @@ Once the access to compute nodes is granted by PBS, user can load following modu ...@@ -88,26 +88,26 @@ Once the access to compute nodes is granted by PBS, user can load following modu
To run matlab in batch mode, write an matlab script, then write a bash jobscript and execute via the qsub command. By default, matlab will execute one matlab worker instance per allocated core. To run matlab in batch mode, write an matlab script, then write a bash jobscript and execute via the qsub command. By default, matlab will execute one matlab worker instance per allocated core.
```bash ```bash
#!/bin/bash #!/bin/bash
#PBS -A PROJECT ID #PBS -A PROJECT ID
#PBS -q qprod #PBS -q qprod
#PBS -l select=1:ncpus=24:mpiprocs=24:ompthreads=1 #PBS -l select=1:ncpus=24:mpiprocs=24:ompthreads=1
# change to shared scratch directory # change to shared scratch directory
SCR=/scratch/work/user/$USER/$PBS_JOBID SCR=/scratch/work/user/$USER/$PBS_JOBID
mkdir -p $SCR ; cd $SCR || exit mkdir -p $SCR ; cd $SCR || exit
# copy input file to scratch # copy input file to scratch
cp $PBS_O_WORKDIR/matlabcode.m . cp $PBS_O_WORKDIR/matlabcode.m .
# load modules # load modules
module load MATLAB/2015a-EDU module load MATLAB/2015a-EDU
# execute the calculation # execute the calculation
matlab -nodisplay -r matlabcode > output.out matlab -nodisplay -r matlabcode > output.out
# copy output file to home # copy output file to home
cp output.out $PBS_O_WORKDIR/. cp output.out $PBS_O_WORKDIR/.
``` ```
This script may be submitted directly to the PBS workload manager via the qsub command. The inputs and matlab script are in matlabcode.m file, outputs in output.out file. Note the missing .m extension in the matlab -r matlabcodefile call, **the .m must not be included**. Note that the **shared /scratch must be used**. Further, it is **important to include quit** statement at the end of the matlabcode.m script. This script may be submitted directly to the PBS workload manager via the qsub command. The inputs and matlab script are in matlabcode.m file, outputs in output.out file. Note the missing .m extension in the matlab -r matlabcodefile call, **the .m must not be included**. Note that the **shared /scratch must be used**. Further, it is **important to include quit** statement at the end of the matlabcode.m script.
...@@ -123,7 +123,7 @@ $ qsub ./jobscript ...@@ -123,7 +123,7 @@ $ qsub ./jobscript
The last part of the configuration is done directly in the user Matlab script before Distributed Computing Toolbox is started. The last part of the configuration is done directly in the user Matlab script before Distributed Computing Toolbox is started.
```console ```console
cluster = parcluster('local') cluster = parcluster('local')
``` ```
This script creates scheduler object "cluster" of type "local" that starts workers locally. This script creates scheduler object "cluster" of type "local" that starts workers locally.
...@@ -134,40 +134,40 @@ This script creates scheduler object "cluster" of type "local" that starts worke ...@@ -134,40 +134,40 @@ This script creates scheduler object "cluster" of type "local" that starts worke
The last step is to start matlabpool with "cluster" object and correct number of workers. We have 24 cores per node, so we start 24 workers. The last step is to start matlabpool with "cluster" object and correct number of workers. We have 24 cores per node, so we start 24 workers.
```console ```console
parpool(cluster,24); parpool(cluster,24);
... parallel code ... ... parallel code ...
parpool close parpool close
``` ```
The complete example showing how to use Distributed Computing Toolbox in local mode is shown here. The complete example showing how to use Distributed Computing Toolbox in local mode is shown here.
```console ```console
cluster = parcluster('local'); cluster = parcluster('local');
cluster cluster
parpool(cluster,24); parpool(cluster,24);
n=2000; n=2000;
W = rand(n,n); W = rand(n,n);
W = distributed(W); W = distributed(W);
x = (1:n)'; x = (1:n)';
x = distributed(x); x = distributed(x);
spmd spmd
[~, name] = system('hostname') [~, name] = system('hostname')
T = W*x; % Calculation performed on labs, in parallel. T = W*x; % Calculation performed on labs, in parallel.
% T and W are both codistributed arrays here. % T and W are both codistributed arrays here.
end end
T; T;
whos % T and W are both distributed arrays here. whos % T and W are both distributed arrays here.
parpool close parpool close
quit quit
``` ```
You can copy and paste the example in a .m file and execute. Note that the parpool size should correspond to **total number of cores** available on allocated nodes. You can copy and paste the example in a .m file and execute. Note that the parpool size should correspond to **total number of cores** available on allocated nodes.
...@@ -179,29 +179,29 @@ This mode uses PBS scheduler to launch the parallel pool. It uses the SalomonPBS ...@@ -179,29 +179,29 @@ This mode uses PBS scheduler to launch the parallel pool. It uses the SalomonPBS
This is an example of m-script using PBS mode: This is an example of m-script using PBS mode:
```console ```console
cluster = parcluster('SalomonPBSPro'); cluster = parcluster('SalomonPBSPro');
set(cluster, 'SubmitArguments', '-A OPEN-0-0'); set(cluster, 'SubmitArguments', '-A OPEN-0-0');
set(cluster, 'ResourceTemplate', '-q qprod -l select=10:ncpus=24'); set(cluster, 'ResourceTemplate', '-q qprod -l select=10:ncpus=24');
set(cluster, 'NumWorkers', 240); set(cluster, 'NumWorkers', 240);
pool = parpool(cluster,240); pool = parpool(cluster,240);
n=2000; n=2000;
W = rand(n,n); W = rand(n,n);
W = distributed(W); W = distributed(W);
x = (1:n)'; x = (1:n)';
x = distributed(x); x = distributed(x);
spmd spmd
[~, name] = system('hostname') [~, name] = system('hostname')
T = W*x; % Calculation performed on labs, in parallel. T = W*x; % Calculation performed on labs, in parallel.
% T and W are both codistributed arrays here. % T and W are both codistributed arrays here.
end end
whos % T and W are both distributed arrays here. whos % T and W are both distributed arrays here.
% shut down parallel pool % shut down parallel pool
delete(pool) delete(pool)
``` ```
Note that we first construct a cluster object using the imported profile, then set some important options, namely : SubmitArguments, where you need to specify accounting id, and ResourceTemplate, where you need to specify number of nodes to run the job. Note that we first construct a cluster object using the imported profile, then set some important options, namely : SubmitArguments, where you need to specify accounting id, and ResourceTemplate, where you need to specify number of nodes to run the job.
...@@ -220,28 +220,28 @@ For this method, you need to use SalomonDirect profile, import it using [the sam ...@@ -220,28 +220,28 @@ For this method, you need to use SalomonDirect profile, import it using [the sam
This is an example of m-script using direct mode: This is an example of m-script using direct mode:
```console ```console
parallel.importProfile('/apps/all/MATLAB/2015b-EDU/SalomonDirect.settings') parallel.importProfile('/apps/all/MATLAB/2015b-EDU/SalomonDirect.settings')
cluster = parcluster('SalomonDirect'); cluster = parcluster('SalomonDirect');
set(cluster, 'NumWorkers', 48); set(cluster, 'NumWorkers', 48);
pool = parpool(cluster, 48); pool = parpool(cluster, 48);
n=2000; n=2000;
W = rand(n,n); W = rand(n,n);
W = distributed(W); W = distributed(W);
x = (1:n)'; x = (1:n)';
x = distributed(x); x = distributed(x);
spmd spmd
[~, name] = system('hostname') [~, name] = system('hostname')
T = W*x; % Calculation performed on labs, in parallel. T = W*x; % Calculation performed on labs, in parallel.
% T and W are both codistributed arrays here. % T and W are both codistributed arrays here.
end end
whos % T and W are both distributed arrays here. whos % T and W are both distributed arrays here.
% shut down parallel pool % shut down parallel pool
delete(pool) delete(pool)
``` ```
### Non-Interactive Session and Licenses ### Non-Interactive Session and Licenses
......
...@@ -166,47 +166,47 @@ Static Rmpi programs are executed via mpiexec, as any other MPI programs. Number ...@@ -166,47 +166,47 @@ Static Rmpi programs are executed via mpiexec, as any other MPI programs. Number
Static Rmpi example: Static Rmpi example:
```r ```r
library(Rmpi) library(Rmpi)
#integrand function #integrand function
f <- function(i,h) { f <- function(i,h) {
x <- h*(i-0.5) x <- h*(i-0.5)
return (4/(1 + x*x)) return (4/(1 + x*x))
} }
#initialize #initialize
invisible(mpi.comm.dup(0,1)) invisible(mpi.comm.dup(0,1))
rank <- mpi.comm.rank() rank <- mpi.comm.rank()
size <- mpi.comm.size() size <- mpi.comm.size()
n<-0 n<-0
while (TRUE) while (TRUE)
{ {
#read number of intervals #read number of intervals
if (rank==0) { if (rank==0) {
cat("Enter the number of intervals: (0 quits) ") cat("Enter the number of intervals: (0 quits) ")
fp<-file("stdin"); n<-scan(fp,nmax=1); close(fp) fp<-file("stdin"); n<-scan(fp,nmax=1); close(fp)
} }
#broadcat the intervals #broadcat the intervals
n <- mpi.bcast(as.integer(n),type=1) n <- mpi.bcast(as.integer(n),type=1)
if(n<=0) break if(n<=0) break
#run the calculation #run the calculation
n <- max(n,size) n <- max(n,size)
h <- 1.0/n h <- 1.0/n
i <- seq(rank+1,n,size); i <- seq(rank+1,n,size);
mypi <- h*sum(sapply(i,f,h)); mypi <- h*sum(sapply(i,f,h));
pi3 <- mpi.reduce(mypi) pi3 <- mpi.reduce(mypi)
#print results #print results
if (rank==0) cat(sprintf("Value of PI %16.14f, diff= %16.14fn",pi3,pi3-pi)) if (rank==0) cat(sprintf("Value of PI %16.14f, diff= %16.14fn",pi3,pi3-pi))
} }
mpi.quit() mpi.quit()
``` ```
The above is the static MPI example for calculating the number π. Note the **library(Rmpi)** and **mpi.comm.dup()** function calls. Execute the example as: The above is the static MPI example for calculating the number π. Note the **library(Rmpi)** and **mpi.comm.dup()** function calls. Execute the example as:
...@@ -222,61 +222,61 @@ Dynamic Rmpi programs are executed by calling the R directly. OpenMPI module mus ...@@ -222,61 +222,61 @@ Dynamic Rmpi programs are executed by calling the R directly. OpenMPI module mus
Dynamic Rmpi example: Dynamic Rmpi example:
```r ```r
#integrand function #integrand function
f <- function(i,h) { f <- function(i,h) {
x <- h*(i-0.5) x <- h*(i-0.5)
return (4/(1 + x*x)) return (4/(1 + x*x))
} }
#the worker function #the worker function
workerpi <- function() workerpi <- function()
{ {
#initialize #initialize
rank <- mpi.comm.rank() rank <- mpi.comm.rank()
size <- mpi.comm.size() size <- mpi.comm.size()
n<-0 n<-0
while (TRUE) while (TRUE)
{ {
#read number of intervals #read number of intervals
if (rank==0) { if (rank==0) {
cat("Enter the number of intervals: (0 quits) ") cat("Enter the number of intervals: (0 quits) ")
fp<-file("stdin"); n<-scan(fp,nmax=1); close(fp) fp<-file("stdin"); n<-scan(fp,nmax=1); close(fp)
} }
#broadcat the intervals #broadcat the intervals
n <- mpi.bcast(as.integer(n),type=1) n <- mpi.bcast(as.integer(n),type=1)
if(n<=0) break if(n<=0) break
#run the calculation #run the calculation
n <- max(n,size) n <- max(n,size)
h <- 1.0/n h <- 1.0/n
i <- seq(rank+1,n,size); i <- seq(rank+1,n,size);
mypi <- h*sum(sapply(i,f,h)); mypi <- h*sum(sapply(i,f,h));
pi3 <- mpi.reduce(mypi) pi3 <- mpi.reduce(mypi)
#print results #print results
if (rank==0) cat(sprintf("Value of PI %16.14f, diff= %16.14fn",pi3,pi3-pi)) if (rank==0) cat(sprintf("Value of PI %16.14f, diff= %16.14fn",pi3,pi3-pi))
} }
} }
#main #main
library(Rmpi) library(Rmpi)
cat("Enter the number of slaves: ") cat("Enter the number of slaves: ")
fp<-file("stdin"); ns<-scan(fp,nmax=1); close(fp) fp<-file("stdin"); ns<-scan(fp,nmax=1); close(fp)
mpi.spawn.Rslaves(nslaves=ns) mpi.spawn.Rslaves(nslaves=ns)
mpi.bcast.Robj2slave(f) mpi.bcast.Robj2slave(f)
mpi.bcast.Robj2slave(workerpi) mpi.bcast.Robj2slave(workerpi)
mpi.bcast.cmd(workerpi()) mpi.bcast.cmd(workerpi())
workerpi() workerpi()
mpi.quit() mpi.quit()
``` ```
The above example is the dynamic MPI example for calculating the number π. Both master and slave processes carry out the calculation. Note the mpi.spawn.Rslaves(), mpi.bcast.Robj2slave()** and the mpi.bcast.cmd()** function calls. The above example is the dynamic MPI example for calculating the number π. Both master and slave processes carry out the calculation. Note the mpi.spawn.Rslaves(), mpi.bcast.Robj2slave()** and the mpi.bcast.cmd()** function calls.
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment