Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Slurm job scriptMatlab script

Serial batch job

Warnung

No parallelization at all, MATLAB is intended to run on a single core.
Please use the "serial" cluster of the Linux Cluster!



Codeblock
languagebash
titlematmul_serial.slurm
linenumberstrue
collapsetrue
#!/bin/bash
#SBATCH -o ./out/matlab_job.%j.%N.out
#SBATCH -e ./out/matlab_job.%j.%N.err
#SBATCH -D ./
#SBATCH -J matlab_serial_batch_job
#SBATCH --get-user-env
#SBATCH --export=NONE
#SBATCH --clusters=serial
#SBATCH --partition=serial_std
#SBATCH --nodes=1
#SBATCH --tasks-per-node=1
#SBATCH --cpus-per-task=1
#SBATCH --mem=10000
#SBATCH --time=0:30:00
# As needed, remove/adjust memory requirement "--mem" in MB

module load slurm_setup
module load matlab/R2019b-generic

# Example: matrix-matrix multiplication C = A*B
#          with A of size NROWA x NCOLA and
#          B of size NROWB x NCOLB
NROWA=1000
NCOLA=2000
NROWB=2000
NCOLB=5000

# Run MATLAB
# => Using option -r don't add file extension .m to the function call!
# => MATLAB commandline arguments are case-sensitive!
matlab -nodisplay -singleCompThread \
       -r "matmul_serial([$NROWA $NCOLA], [$NROWB $NCOLB]);"



Codeblock
languagetext
titlematmul_serial.m
linenumberstrue
collapsetrue
function [C, comptime] = matmul_serial(size_A, size_B)

%===============================================================================
% MATLAB EXAMPLE: SERIAL HELLO WORLD
%                 -> matrix-matrix multiplication C = A*B
%
% INPUT
%   size_A, size_B ... 2-element row vectors defining sizes of A and B
% OUTPUT
%   C ................ result
%   comptime ......... computation time (matrix product only)
%===============================================================================

%===============================================================================
% Check input
%===============================================================================
if nargin~=2
    error('Invalid number of input arguments!');
end
if size_A(2)~=size_B(1)
    error(sprintf('Dimension mismatch of A (%d columns) and B (%d rows)!',...
                  size_A(2), size_B(1)));
end

%===============================================================================
% Work
%===============================================================================
% Hello message from compute node
fprintf('Hello from MATLAB process PID=%d running on node %s!\n',...
        feature('getpid'),...
        strtrim(evalc('system(''hostname'');')));

% generate well-defined matrices
NA = prod(size_A);
NB = prod(size_B);
A = reshape( linspace( 1,NA, NA), size_A );
B = reshape( linspace(NB, 1, NB), size_B );

% compute
tic;
C = A*B;
comptime = toc;
fprintf('serial computation of matrix-matrix product:\n');
fprintf('\ttime = %.2f s\n', comptime);


Parallel job using multithreading

Warnung

MATLAB will run on a single compute node.
Please use the partition "cm2_tiny" in cluster "cm2_tiny"!



Codeblock
languagebash
titlematmul_mthread.slurm
linenumberstrue
collapsetrue
#!/bin/bash
#SBATCH -o ./out/matlab_job.%j.%N.out
#SBATCH -e ./out/matlab_job.%j.%N.err
#SBATCH -D ./
#SBATCH -J matlab_threading_batch_job
#SBATCH --get-user-env
#SBATCH --export=NONE
#SBATCH --clusters=cm2_tiny
#SBATCH --partition=cm2_tiny
#SBATCH --nodes=1
#SBATCH --tasks-per-node=1
#SBATCH --cpus-per-task=14
#SBATCH --time=00:30:00

module load slurm_setup
module load matlab/R2019b-generic

# Example: matrix-matrix multiplication C = A*B
#          with A of size NROWA x NCOLA and
#          B of size NROWB x NCOLB
NROWA=1000
NCOLA=2000
NROWB=2000
NCOLB=5000

# Run MATLAB
# => Using option -r don't add file extension .m to the function call!
# => MATLAB commandline arguments are case-sensitive!
matlab -nodisplay \
       -r "matmul_mthread([$NROWA $NCOLA], [$NROWB $NCOLB]);"



Codeblock
languagetext
titlematmul_mthread.m
linenumberstrue
collapsetrue
function [C, comptime] = parallel_mthread(size_A, size_B)

%===============================================================================
% MATLAB EXAMPLE: PARALLEL HELLO WORLD USING MULTITHREADING
%                 -> matrix-matrix multiplication C = A*B
%
% INPUT
%   size_A, size_B ... 2-element row vectors defining sizes of A and B
% OUTPUT
%   C ................ result
%   comptime ......... computation time (matrix product only)
%===============================================================================

%===============================================================================
% Check input
%===============================================================================
if nargin~=2
    error('Invalid number of input arguments!');
end
if size_A(2)~=size_B(1)
    error(sprintf('Dimension mismatch of A (%d columns) and B (%d rows)!',...
                  size_A(2), size_B(1)));
end

%===============================================================================
% Manage multithreading
%===============================================================================
% Get number of threads depending on job type (batch job or interactive job).
% In batch jobs 1 MATLAB task will use "nw" threads. 
%
% obtain number of threads from Slurm environment variables
cluster = getenv('SLURM_CLUSTER_NAME');
if strcmp(cluster, 'inter')
    % interactive job
    nw = str2num(getenv('SLURM_JOB_CPUS_PER_NODE'));
elseif strcmp(cluster, 'cm2_tiny') || ...
       strcmp(cluster, 'mpp3') || ...
       strcmp(cluster, 'ivymuc')
    % batch job
    nw = str2num(getenv('SLURM_CPUS_PER_TASK'));
else
    % default
    nw = 1;
end
% set threads
maxNumCompThreads(nw);

%===============================================================================
% Work
%===============================================================================
fprintf('Hello from MATLAB process PID=%d running on node %s!\n',...
        feature('getpid'),...
        strtrim(evalc('system(''hostname'');')));

% generate well-defined matrices
NA = prod(size_A);
NB = prod(size_B);
A = reshape( linspace( 1,NA, NA), size_A );
B = reshape( linspace(NB, 1, NB), size_B );

% compute
tic;
C = A*B;
comptime = toc;
fprintf('parallel computation (multithreading) of matrix-matrix product:\n');
fprintf('\tnumber of threads = %d\n', nw);
fprintf('\ttime = %.2f s\n', comptime);


Parallel batch job using Parallel Computing Toolbox (PCT)

Warnung

MATLAB will run on a single compute node.
Please use the partition "cm2_tiny" in cluster "cm2_tiny"!



Codeblock
languagebash
titlematmul_pct.slurm
linenumberstrue
collapsetrue
#!/bin/bash
#SBATCH -o ./out/matlab_job.%j.%N.out
#SBATCH -e ./out/matlab_job.%j.%N.err
#SBATCH -D ./
#SBATCH -J matlab_pct_batch_job
#SBATCH --get-user-env
#SBATCH --export=NONE
#SBATCH --clusters=cm2_tiny
#SBATCH --partition=cm2_tiny
#SBATCH --nodes=1
#SBATCH --tasks-per-node=4
#SBATCH --cpus-per-task=1
#SBATCH --time=00:30:00

# IMPORTANT
# Default settings of Intel MPI module may disrupt 
# functionality of Parallel-Computing-Toolbox!
# Do one of the following solutions:  
# (1) Unload module mpi.intel:
module rm mpi.intel
# (2) If Intel MPI module is mandatory, add next line
# export KMP_AFFINITY=granularity=thread,none

module load slurm_setup
module load matlab/R2019b-generic

# Example: matrix-matrix multiplication C = A*B
#          with A of size NROWA x NCOLA and
#          B of size NROWB x NCOLB
NROWA=1000
NCOLA=2000
NROWB=2000
NCOLB=5000

# Run MATLAB
# => Using option -r don't add file extension .m to the function call!
# => MATLAB commandline arguments are case-sensitive!
matlab -nodisplay -singleCompThread \
       -r "matmul_pct([$NROWA $NCOLA], [$NROWB $NCOLB]);"



Codeblock
languagetext
titlematmul_pct.m
linenumberstrue
collapsetrue
function [Cglob, comptime] = matmul_pct(size_A, size_B)

%===============================================================================
% MATLAB EXAMPLE: PARALLEL HELLO WORLD USING PCT TOOLBOX
%                 -> matrix-matrix multiplication C = A*B
%
% INPUT
%   size_A, size_B ... 2-element row vectors defining sizes of A and B
% OUTPUT
%   C ................ result
%   comptime ......... computation time (matrix product only)
%===============================================================================

%===============================================================================
% Check input
%===============================================================================
if nargin~=2
    error('Invalid number of input arguments!');
end
if size_A(2)~=size_B(1)
    error(sprintf('Dimension mismatch of A (%d columns) and B (%d rows)!',...
                  size_A(2), size_B(1)));
end

%===============================================================================
% Verify that no parallel pool is initialized by creating/deleting a dummy pool
%===============================================================================
if ~isempty(gcp('nocreate'))
    poolobj = gcp('nocreate');
    delete(poolobj);
end

%===============================================================================
% Start parallel pool
%===============================================================================
% Get number of workers depending on job type. Start parallel pool via "local"
% cluster object.
%
% obtain number of tasks from Slurm environment variables
cluster = getenv('SLURM_CLUSTER_NAME');
if strcmp(cluster, 'inter')
    % interactive job
    nw = str2num(getenv('SLURM_JOB_CPUS_PER_NODE'));
elseif strcmp(cluster, 'cm2_tiny') || ...
       strcmp(cluster, 'serial') || ...
       strcmp(cluster, 'mpp3') || ...
       strcmp(cluster, 'ivymuc')
    % batch job
    nw = str2num(getenv('SLURM_NTASKS'));
else
    % default
    nw = 1;
end

% disallow Threading
if maxNumCompThreads > 1
    maxNumCompThreads(1);
    warning('MultiThreading: number of threads has been set to 1!');
end

% create a local cluster object
pc = parcluster('local');
% set number of workers
pc.NumWorkers = nw;
% set the JobStorageLocation to SCRATCH (default: HOME -> not recommended)
pc.JobStorageLocation = strcat(getenv('SCRATCH'));
% start the parallel pool
poolobj = parpool(pc, nw);

%===============================================================================
% Work
%===============================================================================
spmd
    fprintf('Hello from MATLAB process PID=%d running on node %s!\n',...
            feature('getpid'),...
            getenv('HOSTNAME'));
end

% generate well-defined matrices
NA = prod(size_A);
NB = prod(size_B);
A = reshape( linspace( 1,NA, NA), size_A );
B = reshape( linspace(NB, 1, NB), size_B );

% distribute data to workers and do parallel computation
spmd
    Aloc = codistributed(A, codistributor2dbc([nw 1]));
    Bloc = codistributed(B, codistributor2dbc([1 nw]));
    tic;
    Cloc = Aloc*Bloc;
    t = toc;
end

comptime = max(cell2mat(t(:)));
fprintf('parallel computation (MPI) of matrix-matrix product:\n');
fprintf('\tnumber of tasks (MATLAB workers) = %d\n', nw);
fprintf('\ttime = %.2f s\n', comptime);

Cglob = gather(Cloc);

%===============================================================================
% Close parallel pool
%===============================================================================
delete(poolobj);


...