Quick Links
On this page Related
| Description
The MATLAB Compiler can be used to create a stand-alone executable from a MATLAB application. This executable can then be run on Biowulf or your local machine without utilizing a MATLAB license. Note that you do not need to compile your Matlab code to submit it as a batch job.
The compiler can also be used to incorporate MATLAB-based algorithms into applications built using C/C++, .NET, Java, or Python. See the Mathworks documentation for details. Most MATLAB functions can be compiled, but a few cannot. Check this list to see if your code can be compiled.
IMPORTANT: (November 2021) Biowulf users now have access to unlimited Matlab licenses and all toolboxes A MATLAB program may produce different results after it has been compiled. Test your application again after compiling to be sure its behavior has not changed. See the articles listed under "Programming Considerations for Compiling MATLAB code" below to learn how to avoid these issues. Starting with Matlab R2021a (v910) we provide the MCR Runtime in compressed format (e.g., v910.tar.gz) only. We recommend users copy this compressed MCR to local disk (lscratch) and uncompress and use locally. |
Once MATLAB code has been compiled, it is run using the MATLAB Component Runtime (MCR). There are several versions of the MCR available on the systems. The MCR version must match the version of MATLAB that was used to compile the code. On our systems, the MCR is located in /usr/local/matlab-compiler
. Note that you do not need to compile your Matlab code to submit it as a batch job.
MATLAB to MCR mapping | ||
---|---|---|
MATLAB Version | MCR Version | R2021b | v911 | R2021a | v910 | R2020b | v99 | R2020a | v98 | R2019b | v97 |
R2019a | v96 | |
R2018b | v95 | R2018a | v94 |
R2017b | v93 | |
R2017a | v92 | |
R2016b | v91 | |
R2016a | v901 | |
R2015b | v90 | |
R2015a | v85 | |
R2014b | v84 | |
R2014a | v83 | |
R2013b | v82 | |
R2013a | v81 | |
R2012b | v80 | |
R2012a | v717 | |
R2011b | v716 | |
R2011a | v715 | |
R2010b | v714 | |
R2010a | v7.13 | |
R2009b | v711 |
back to top
Note that you do not need to compile your Matlab code to submit it as a batch job. Compilation involves loading the matlab module and executing one simple command. (user input in bold):
[user@biowulf ~]$ sinteractive [user@cn1234 ~]$ module load matlab/<ver> [user@cn1234 ~]$ mcc -m matlab_file.m [user@cn1234 ~]$ exit
Note that these and following mcc
commands can also be executed directly
from within MATLAB.
>> mcc -m matlab_file.m
Several new files are produced by the compilation process, so it may be best to
create a new directory in which to compile the executable. You may cd to that
directory and issue the mcc
command using the full path and file name of the .m
file to be compiled, or you may send the new files to the directory of your choice
using the -d
argument like so:
>> mcc -m -d /new/location matlab_file.m
Users who wish to run compiled MATLAB code on Biowulf are strongly encouraged to
add the singleCompThread
runtime flag to their mcc
command to ensure that
compiled MATLAB jobs run a single thread per core.
>> mcc -m -R singleCompThread matlab_file.m
Other options and runtime flags are available. Type help mcc
at the MATLAB
command prompt to see more. These options identical for mcc
.
The following demonstrates how to compile a .m
file and then call
the resulting executable.
In this example, the user copies the magicsquare.m
example file to a new directory
in their home space. They then compile it into an executable using mcc
.
Several files are generated including a binary executable version of magicsquare
and a
shell script that sets up runtime libraries to make it easier to run the
compiled executable (run_magicsquare.sh
). Finally, the binary is executed using
run_magicsquare.sh
with arguments providing the location of the (appropriate) MATLAB
MCR and the variable for generating the magic square (first 3, then 5).
magicsquare.m
contains the following code:
function m = magicsquare(n) %MAGICSQUARE generates a magic square matrix of the size specified % by the input parameter n. % Copyright 2003-2006 The MathWorks, Inc. if ischar(n) n=str2num(n); end m = magic(n); disp(m)
.m
file to a new directory in their home space.
[user@cn1234 ~]$ mkdir ~/matlab_compiler_test [user@cn1234 ~]$ cd ~/matlab_compiler_test [user@cn1234 ~/matlab_compiler_test]$ cp /usr/local/matlab64/extern/examples/compiler/magicsquare.m ./ [user@cn1234 ~/matlab_compiler_test]$ ls -l -r--r--r-- 1 user group 202 May 13 14:15 magicsquare.m
Then the user executes mcc
(here from within the shell) to compile the code.
[user@cn1234 ~/matlab_compiler_test]$ module load matlab/2018b #or different version with different MCR below [user@cn1234 ~/matlab_compiler_test]$ mcc -m -R singleCompThread magicsquare.m < M A T L A B (R) > Copyright 1984-2018 The MathWorks, Inc. R2018b (9.5.0.944444) 64-bit (glnxa64) August 28, 2018 For online documentation, see https://www.mathworks.com/support For product information, visit www.mathworks.com. [user@cn1234 ~/matlab_compiler_test]$ ls -l total 108 -rwxr--r-- 1 user group 88922 Dec 13 15:32 magicsquare -rw-r--r-- 1 user group 124 Jun 27 14:19 magicsquare.m -rw-r--r-- 1 user group 102 Dec 13 15:32 mccExcludedFiles.log -rw-r--r-- 1 user group 3546 Dec 13 15:32 readme.txt -rw-r--r-- 1 user group 6 Dec 13 15:32 requiredMCRProducts.txt -rwxr--r-- 1 user group 879 Dec 13 15:32 run_magicsquare.sh
The two new files magicsquare
and run_magicsquare.sh
are most
important for our purposes. Finally, the user runs the compiled code directly from the
shell by entering the path and name of the run_*.sh
shell script followed by the full
path to the correct MCR for the version of matlab used to compile followed by
the variable(s) needed by the compiled MATLAB function.
[user@cn1234 ~/matlab_compiler_test]$ ./run_magicsquare.sh /usr/local/matlab-compiler/v95 3 ------------------------------------------ Setting up environment variables --- LD_LIBRARY_PATH is .:/usr/local/matlab-compiler/v95/runtime/glnxa64:/usr/local/matlab-compiler/v95/bin/glnxa64:/usr/local/matlab-compiler/v95/sys/os/glnxa64:/usr/local/matlab-compiler/v95/sys/opengl/lib/glnxa64 m = 8 1 6 3 5 7 4 9 2 [user@cn1234 ~/matlab_compiler_test]$ ./run_magicsquare.sh /usr/local/matlab-compiler/v95 5 ------------------------------------------ Setting up environment variables --- LD_LIBRARY_PATH is .:/usr/local/matlab-compiler/v95/runtime/glnxa64:/usr/local/matlab-compiler/v95/bin/glnxa64:/usr/local/matlab-compiler/v95/sys/os/glnxa64:/usr/local/matlab-compiler/v95/sys/opengl/lib/glnxa64 m = 17 24 1 8 15 23 5 7 14 16 4 6 13 20 22 10 12 19 21 3 11 18 25 2 9
back to top
The in-house function called mcc2
(originally written to minimize license usage) has been deprecated. Biowulf users now have access to unlimited number of compiler licenses and should use the compiler command mcc
. mcc
's usage is identical to mcc2
.
[user@cn1234 ~]$ module load matlab
Within an interactive MATLAB session, mcc
resides in the compiler toolbox. This
function might not be visible to MATLAB if the toolbox cache is out of date. To test
this enter:
>> help mcc
The following error shows that the toolbox cache is out of date and MATLAB does not
recognize mcc2
.
mcc not found. Use the Help browser search field to search the documentation, or type "help help" for help command options, such as help for methods.
To correct this error, enter:
>> rehash toolbox
The previous command should now return a few lines of help for mcc2
.
>> help mcc
The change should persist across MATLAB sessions.
back to top
Open an sinteractive session on Biowulf and start up MATLAB. It is a good idea to test your MATLAB script before compilation by running it at the prompt.
Type deploytool
to start the Compiler GUI. In the window that appears, select (for the purposes of this example) 'Application Compiler' to get started. Of course, you can select 'Library Compiler' if you want to build a shared library. (See the Mathworks documentation for details.)
The Application Compiler window will appear on your screen
Select the plus sign beside 'Add main file' (highlighted in pink at the top) and in the resultant window, select the MATLAB file that you want to compile Add required files in the 'Files required for your application to run' section.
Click the 'Package' button, which is the green check button at the top right.
Once your build is complete, follow the instructions above or below on running your compiled code.
back to top
Note that you do not need to compile your Matlab code to submit it as a batch job. Set up a batch script along the following lines:
#!/bin/sh #SBATCH -J matjob # This file is my-mat-job.sh. # It assumes the code was compiled with MATLAB 2018b # see previous example cd ~/matlab_compiler_test \ && ./run_magicsquare.sh /usr/local/matlab-compiler/v95 5
Submit this job with:
[user@biowulf ~]$ sbatch my-mat-job.sh
The sbatch
command has many options available. If you need to allocate
more memory, cpus, or time for your job, want to run your job on another partition,
or you have other special requirements, check the manual pages with:
[user@biowulf ~]$ man sbatch
More info can also be found in the Biowulf User Guide under Job Submission.
back to top
The in-house swarm
program is an easy and powerful way to run many processes in parallel on the cluster, also known as a job array. Note that is is not necessary to compile your matlab code to be able to use swarm.
When running a job array, it helps to store the MATLAB runtime on the local file system (in /lscratch/$SLURM_JOB_ID) in order to relieve the central file system of the combined load of accessing the Matlab runtime tree from all of your subjobs.
In the following example, the MATLAB program magicsquare takes 1 parameter as input. Once the program has been compiled either on the command line or using the GUI, a swarm file can be set up along the following lines:
# This file is my-mat-jobs.swarm. # It assumes that the code was compiled with MATLAB 2018b tar -C /lscratch/$SLURM_JOB_ID -xf /usr/local/matlab-compiler/v95.tar.gz \ && cd ~/matlab_compiler_test \ && ./run_magicsquare.sh /lscratch/$SLURM_JOB_ID/v95 4 tar -C /lscratch/$SLURM_JOB_ID -xf /usr/local/matlab-compiler/v95.tar.gz \ && cd ~/matlab_compiler_test \ && ./run_magicsquare.sh /lscratch/$SLURM_JOB_ID/v95 2 tar -C /lscratch/$SLURM_JOB_ID -xf /usr/local/matlab-compiler/v95.tar.gz \ && cd ~/matlab_compiler_test \ && ./run_magicsquare.sh /lscratch/$SLURM_JOB_ID/v95 8 tar -C /lscratch/$SLURM_JOB_ID -xf /usr/local/matlab-compiler/v95.tar.gz \ && cd ~/matlab_compiler_test \ && ./run_magicsquare.sh /lscratch/$SLURM_JOB_ID/v93 5 tar -C /lscratch/$SLURM_JOB_ID -xf /usr/local/matlab-compiler/v93.tar.gz \ && cd ~/matlab_compiler_test \ && ./run_magicsquare.sh /lscratch/$SLURM_JOB_ID/v95 6 tar -C /lscratch/$SLURM_JOB_ID -xf /usr/local/matlab-compiler/v95.tar.gz \ && cd ~/matlab_compiler_test; \ && ./run_magicsquare.sh /lscratch/$SLURM_JOB_ID/v95 3
This swarm file can be submiited to the Biowulf cluster with:
[user@biowulf ~]$ swarm --gres lscratch:10 -f my-mat-jobs.swarm 138158
You typically would not want to write swarm files manually. Instead, you should write code that will generate swarm files for you. That way, if you decide to rerun your analysis with some new parameters or on some new files, it will be trivial to generate a new swarm file even if it contains thousands of commands. Here's some example MATLAB code that will generate the swarm file above.
% stick all the parameters in an array % (Note that they are strings) param_list = {'4' '2' '8' '5' '6' '3'}; % make a command on a new line for each parameter command_list = []; for ii = 1:length(param_list) command_list = [command_list ... 'tar -C /lscratch/$SLURM_JOB_ID -xf /usr/local/matlab-compiler/v95.tar.gz \\ \n'... ' && cd ~/matlab_compiler_test \\ \n'... ' && ./run_magicsquare.sh '... '/lscratch/$SLURM_JOB_ID/v95 '... param_list{ii}... '\n']; end % write the commands into a swarm file file_handle = fopen('my-mat-jobs.swarm','w+'); fprintf(file_handle,command_list); fclose(file_handle);
For more tips and tricks on automating the swarm submission process in MATLAB, see this recorded training session.
back to top
When a user executes compiled MATLAB code, MATLAB creates a hidden cache containing binaries,
links, scripts, etc. By default this cache will be located in a user's home directory (i.e.
~/.mcrCache9.0/
). Performance of the compiled MATLAB code can be poor if the
MCR cache directory is located on a network filesystem and a large number of parallel processes
attempt to access it simultaneously.
To address this issue the cache directory can be made local to each node in a
swarm. The location of the directory can be determined by setting the
MCR_CACHE_ROOT
environmental variable. Local scratch space should be requested
for this purpose in the swarm or sbatch command. See using local disk for more information.
The following command could be incorporated into the wrapper script generated by the matlab compiler:
export MCR_CACHE_ROOT=/lscratch/$SLURM_JOB_ID
Setting the directory to the value of $SLURM_JOB_ID is important to prevent multiple jobs running on the same nodes from interfering with one another. Otherwise, one job may attempt to read from a file in the cache while another file is overwriting it. This means the variable must be set after a job has initiated and been assigned a job id. (This approach will work with swarm because each subjob in a job array actually has a unique job id.)
If you don't want to manually edit the run_X.sh script generated by MATLAB upon compilation, another strategy would be to add this command to each line of you swarm file like so.
export MCR_CACHE_ROOT=/lscratch/$SLURM_JOB_ID; \ tar -C /lscratch/$SLURM_JOB_ID -xf /usr/local/matlab-compiler/v95.tar.gz \ && cd ~/matlab_compiler_test \ && ./run_magicsquare.sh /lscratch/$SLURM_JOB_ID/v95 4 export MCR_CACHE_ROOT=/lscratch/$SLURM_JOB_ID; \ tar -C /lscratch/$SLURM_JOB_ID -xf /usr/local/matlab-compiler/v95.tar.gz \ && cd ~/matlab_compiler_test \ && ./run_magicsquare.sh /lscratch/$SLURM_JOB_ID/v95 2 export MCR_CACHE_ROOT=/lscratch/$SLURM_JOB_ID; \ tar -C /lscratch/$SLURM_JOB_ID -xf /usr/local/matlab-compiler/v95.tar.gz \ && cd ~/matlab_compiler_test \ && ./run_magicsquare.sh /lscratch/$SLURM_JOB_ID/v95 8 export MCR_CACHE_ROOT=/lscratch/$SLURM_JOB_ID; \ tar -C /lscratch/$SLURM_JOB_ID -xf /usr/local/matlab-compiler/v95.tar.gz \ && cd ~/matlab_compiler_test \ && ./run_magicsquare.sh /lscratch/$SLURM_JOB_ID/v95 5 export MCR_CACHE_ROOT=/lscratch/$SLURM_JOB_ID; \ tar -C /lscratch/$SLURM_JOB_ID -xf /usr/local/matlab-compiler/v95.tar.gz \ && cd ~/matlab_compiler_test \ && ./run_magicsquare.sh /lscratch/$SLURM_JOB_ID/v95 3
Of course, these commands could be added automatically by a script that generates the swarm file as explained above.
Finally, you must remember to request the lscratch resource in your swarm command. For instance, the following command would allocate 10GB of local disk space for each job to use as the mcr cache and to hold the Matlab runtime. This should be more than enough.
[user@biowulf ~]$ swarm --gres=lscratch:10 -f my-mat-jobs.swarm
See this thread on MATLAB answers for more information.