MATLAB
MATLAB Parallel Computing
The university now has a campus license for MATLAB, which makes it possible to submit jobs from MATLAB to the cluster, and run jobs on multiple nodes. For all details, see the attached manual. Note that the functionality currently only works with MATLAB 2020b; if you want to submit jobs from your own workstation, make sure to use the same MATLAB version and install the set of scripts as described in the manual.
The examples that you will find below, do not use this functionality and show how to manually submit MATLAB jobs.
Single CPU
In order to run a simple MATLAB script on a single core, two files should be constructed. The first file is the MATLAB script (with the .m extension), which is here called matlab_example1.m
:
- matlab_example1.m
% Matrix multiplication example. A = [1,2,3;1,2,3;1,2,3]; B = [2,3,4;2,3,4;2,3,4]; % Multiplies matrix A with B 20 times. for i=1:20 A=A*B; end display(A)
The second file is the job script that is used to send the MATLAB job to the cluster. This file is called matlab_ex1.sh
and should look like:
- matlab_ex1.sh
#!/bin/bash #SBATCH --time=00:05:00 #SBATCH --nodes=1 #SBATCH --ntasks=1 #SBATCH --cpus-per-task=1 #SBATCH --job-name=matlab_example1 #SBATCH --output=matlab_example1.out #SBATCH --mem=1000 module purge module load MATLAB/2022b-r5 matlab -nodisplay -singleCompThread < matlab_example1.m
When both files are created and saved in the same directory, the following command can be used to submit the job from that directory:
sbatch matlab_ex1.sh
The job is now submitted, and the squeue
command can be used to check the status of the job:
squeue -u $USER
A file named matlab_example1.out
will also be created when the job starts running; open this file with a text viewer/editor to see the job output. If the file is empty, try again a bit later.
The expected output should be:
A = 1.0e+19 * 1.6210 2.4315 3.2420 1.6210 2.4315 3.2420 1.6210 2.4315 3.2420 >>
Multiple CPUs
The following example shows how multiple cores are used with MATLAB.
We use the following MATLAB script named matlab_parpool_example.m
:
- matlab_parpool_example.m
% This code creates a random 4x4 matrix with values between 0 and 10, n times. n = 4; % Should correspond to --cpus-per-task in the sbatch file. parpool('local', n); parfor i=1:n % Multithreaded part disp(round(rand(4)*10)); end
Then we need the following matlab_parpool_example.sh
script. Note that the –cpus-per-task
option is used to specify the number of cores.
- matlab_parpool_example.sh
#!/bin/bash #SBATCH --time=00:10:00 #SBATCH --nodes=1 #SBATCH --ntasks=1 #SBATCH --cpus-per-task=4 # Here we request 4 cores for this task. #SBATCH --job-name=matlab_parpool_example #SBATCH --output=matlab_parpool_example.out #SBATCH --mem=8000 module load MATLAB/2020b matlab -nodisplay < matlab_parpool_example.m
Then, by giving the following command, the job gets submitted:
sbatch matlab_parpool_example.sh
Note that starting a parallel pool takes some time, hence for this short example, it will not run faster than a serial execution of this example.
GPU
Here we show how to use a GPU on the cluster for your MATLAB script. Make sure that the partition is set to gpu
in the batch script. The Running jobs on GPUs page shows how other settings for the GPU are set. The batch script here is named gpuExampleMatlab.sh
and the MATLAB script mandelbrot.m
.
- gpuExampleMatlab.sh
#!/bin/bash #SBATCH --time=00:05:00 #SBATCH --partition=gpu #SBATCH --gres=gpu:1 #SBATCH --mem=1000 module load MATLAB/2020b matlab -nodisplay -r mandelbrot
The MATLAB script:
- mandelbrot.m
maxIterations = 5000; gridSize = 1000; xlim = [-0.748766713922161, -0.748766707771757]; ylim = [ 0.123640844894862, 0.123640851045266]; % Setup normal way. x = linspace( xlim(1), xlim(2), gridSize ); y = linspace( ylim(1), ylim(2), gridSize ); [xGrid,yGrid] = meshgrid( x, y ); z0 = xGrid + 1i*yGrid; count = ones( size(z0) ); % Calculate t = tic(); z = z0; for n = 0:maxIterations z = z.*z + z0; inside = abs( z )<=2; count = count + inside; end count = log( count ); % Show cpuTime = toc( t ); fig = gcf; fig.Position = [200 200 600 600]; imagesc( x, y, count ); axis image colormap( [jet();flipud( jet() );0 0 0] ); title( sprintf( '%1.2fsecs (without GPU)', cpuTime ) ); print -dpng CPU.png % Set up GPU x = gpuArray.linspace( xlim(1), xlim(2), gridSize ); y = gpuArray.linspace( ylim(1), ylim(2), gridSize ); [xGrid,yGrid] = meshgrid( x, y ); z0 = complex( xGrid, yGrid ); count = ones( size(z0), 'gpuArray' ); % Calculate t = tic(); z = z0; for n = 0:maxIterations z = z.*z + z0; inside = abs( z )<=2; count = count + inside; end count = log( count ); % Show count = gather( count ); % Fetch the data back from the GPU naiveGPUTime = toc( t ); imagesc( x, y, count ) axis image title( sprintf( '%1.3fsecs (naive GPU) = %1.1fx faster', ... naiveGPUTime, cpuTime/naiveGPUTime ) ) print -dpng GPU.png
Submitting this job can be done with the command: sbatch gpuExampleMatlab.sh
Running this job will result in two PNG files being created in the same directory. These images show the Mandelbrot fractals and the computing time on one CPU and the computing time on one GPU.