# MATLAB

There are two main ways of using MATLAB on Compute Canada clusters.

- Running MATLAB directly

This approach requires you to have access to a MATLAB license. You may either:

- Bring your own license, which involves using a license you already have access to, typically owned by your institution, faculty, department or lab.
- Run MATLAB on Cedar or Béluga, both of which have a license available for any student, professor or academic researcher.

- Running a compiled MATLAB application

This method requires compiling your code into a binary using the MATLAB compiler (`mcc`). You can then run that binary executable using the appropriate MATLAB Runtime.

More details about these approaches are provided below.

## Contents

# Bringing your own license

Compute Canada is a hosting provider for MATLAB. This means that we have MATLAB installed on our clusters and can allow you to access an institutional license to run computations on our infrastructure. For any questions regarding usage of your license outside of your campus, we encourage you to contact the system administrator at your institution or MathWorks account manager.

Accessing your campus license for MATLAB from a Compute Canada cluster requires some technical configuration. Firstly, you should create a file similar to the following example,

**File :**matlab.lic

```
# MATLAB license passcode file
SERVER <ip address> ANY <port>
USE_SERVER
```

and put it in the directory `$HOME/.licenses/`, where the IP address and port number correspond to the values for your campus license server. Next you will need to ensure that the license server on your campus is reachable by our compute nodes. This will require our technical team to get in touch with the technical people managing your license software. For some campuses, this has already been done. If so, when you load the MATLAB module and try a test such as the one below, it should find a license automatically. If this is not the case, please write to technical support, so that we can arrange this for you.

Test your license arrangement:

[name@cluster ~]$ module load matlab/2018a [name@cluster ~]$ matlab -nodisplay -nojvm -r "fprintf('%s\n', license()); exit" < M A T L A B (R) > Copyright 1984-2018 The MathWorks, Inc. R2018a (9.4.0.813654) 64-bit (glnxa64) February 23, 2018 For online documentation, see http://www.mathworks.com/support For product information, visit www.mathworks.com. 987654 [name@cluster ~]$

If any license number is printed, you're okay.

# Prepare your `.matlab` folder

Because the home directory is accessible in read-only mode on some clusters' compute nodes, users should create a `.matlab` symbolic link that makes sure MATLAB profile and job data will be written to the scratch space instead:

[name@cluster ~]$ cd $HOME [name@cluster ~]$ if [ -d ".matlab" ]; then mv .matlab scratch/ else mkdir -p scratch/.matlab fi && ln -sn scratch/.matlab .matlab

# Running a MATLAB code

**Important:** Any MATLAB calculation larger than a short test job of, say, 5 minutes, must be submitted to the scheduler. For instructions on using the scheduler, please see the Running jobs page.

Consider the following example code:

**File :**cosplot.m

```
function cosplot()
% MATLAB file example to approximate a sawtooth
% with a truncated Fourier expansion.
nterms=5;
fourbypi=4.0/pi;
np=100;
y(1:np)=pi/2.0;
x(1:np)=linspace(-2.0*pi,2*pi,np);
for k=1:nterms
twokm=2*k-1;
y=y-fourbypi*cos(twokm*x)/twokm^2;
end
plot(x,y)
print -dpsc matlab_test_plot.ps
quit
end
```

Here is a simple SLURM script that you can use to run `cosplot.m`

:

**File :**matlab_slurm.sl

```
#!/bin/bash -l
#SBATCH --job-name=matlab_test
#SBATCH --account=def-someprof # adjust this to match the accounting group you are using to submit jobs
#SBATCH --time=0-03:00 # adjust this to match the walltime of your job
#SBATCH --nodes=1
#SBATCH --ntasks=1
#SBATCH --cpus-per-task=1 # adjust this if you are using parallel commands
#SBATCH --mem=4000 # adjust this according to your the memory requirement per node you need
#SBATCH --mail-user=you@youruniversity.ca # adjust this to match your email address
#SBATCH --mail-type=ALL
# Choose a version of MATLAB by loading a module:
module load matlab/2018a
# Remove -singleCompThread below if you are using parallel commands:
srun matlab -nodisplay -singleCompThread -r "cosplot"
```

Submit the job using `sbatch`:

`[name@server ~]$ sbatch matlab_slurm.sl`

Do not use the `-singleCompThread`

option if you request
more than one core with `--cpus-per-task`

.
You should also ensure that the size of your MATLAB parpool
matches the number of cores you are requesting.

Each time you run MATLAB it will create a file like `java.log.12345`

unless you supply the `-nojvm`

option.
However, using `-nojvm`

may interfere with certain plotting functions.
For further information on the command line options `-nodisplay`

, `-singleCompThread`

,
`-nojvm`

, and `-r`

,
see MATLAB (Linux) on the MathWorks web site.

# Running multiple parallel MATLAB jobs simultaneously

There is a known issue when two (or more) parallel MATLAB jobs are initializing their `parpool`

simultaneously : multiple MATLAB instances are trying to read and write to the same `.dat`

file in the `$HOME/.matlab/local_cluster_jobs/R*`

folder, which corrupts the local parallel profile used by other MATLAB jobs. To fix the corrupted profile: delete the `local_cluster_jobs`

folder when no job is running.

There are two main definitive solutions:

- Making sure only one MATLAB job at a time will start its
`parpool`

. There are many possible technical solutions, but none is perfect: using lock files (which may be left "locked" by failed jobs), using random delays (which may be equal or almost equal, and still cause the corruption), using always increasing delays (which are wasting compute time), or using SLURM options (i.e.`--begin`

or`--dependency=after:JOBID`

) to control the start time (which increases the wait time in queue). - Making sure each MATLAB job will create a local parallel profile in a unique location on the file system.

In your MATLAB code:

**File :**parallel_main.m

```
% Create a "local" cluster object
local_cluster = parcluster('local')
% Modify the JobStorageLocation to $SLURM_TMPDIR
local_cluster.JobStorageLocation = getenv('SLURM_TMPDIR')
% Start the parallel pool
parpool(local_cluster);
```

Reference:

- MATLAB Parallel Computing Toolbox simultaneous job problem
- ... from multiple MATLAB sessions that use a shared preference directory

# Using the MATLAB Compiler Runtime libraries

**Important:** Like any other intensive job, you must always run MCR code within a job that you will have submitted to the scheduler. For instructions on using the scheduler, please see the Running jobs page.

You can also compile your code using the MATLAB compiler, included among the Compute Canada-hosted modules. See documentation for the Compiler at the MathWorks website. At the moment, mcc is only provided for versions 2014a and 2018a (but the default is 2017a). This means you should probably start with

`[name@server ~]$ module load matlab/2018a`

unless you're on Cedar, where this version is provided by default (through /opt/software/bin).

To compile the `cosplot.m`

example given above, you would use the command

`[name@yourserver ~]$ mcc -m -R -nodisplay cosplot.m`

This will produce a binary named `cosplot`, as well as a wrapper script. To run the binary on Compute Canada servers, you will only require the binary. The wrapper script, named `run_cosplot.sh`, will not work as is on our servers, because MATLAB assumes that some libraries can be found in specific locations. Instead, we provide a different wrapper script, called `run_mcr_binary.sh` which sets the correct paths.

On one of our servers, load an MCR module corresponding to the MATLAB version you used to build the executable:

`[name@server ~]$ module load mcr/R2018a`

Run the following command:

`[name@server ~]$ setrpaths.sh --path cosplot`

then, in your submission script (**not on the login nodes**), use your binary as so:
`run_mcr_binary.sh cosplot`

You will only need to run the `setrpaths.sh` command once for each compiled binary. The `run_mcr_binary.sh` will instruct you to run it if it detects that it has not been done.