If you run MATLAB jobs routinely, you may have had the experience of denied MATLAB access or having your MATLAB batch jobs killed due to unavailable MATLAB licenses. This can be avoided if you compile your MATLAB application into an executable with the MATLAB
mcc compiler. A standalone executable runs without using a MATLAB license, and has several other benefits.
Benefits of standalone executables
- Broader distribution: Extend the reach of your program to users who lack a MATLAB license.
- Access reliability: Standalone executables never fail due to license availability.
- Embarrassingly parallel applications: Hundreds or thousands of independent runs are common for many applications. Using a standalone makes it possible to run these tasks concurrently — e.g. on the SCC cluster — without running into licensing issues.
- Hide source code for intellectual property protection
To be compatible with the MATLAB
mcc compiler, your program must meet a few requirements. The most important of these are listed below.
- The starting, or “main,” program must be a function — with or without returning output. The standalone, regardless, will not return any output. You can use either the original main or you create a command function wrapper as the new “main” which in turn calls the original main. For many, a wrapper may be more appealing as it enables the original program to be kept completely separate from the corresponding standalone program.
- All runtime input parameters are always passed to the standalone as strings. Any passed string parameter intended as
doublein the code must be converted with
str2double. Your wrapper will perform data type conversions (if any) and pass them to the original main for further processing.
scc1% module load matlab/2016a scc1% mcc -mv -o myExecR2016a myStandalone.m myApp.m
-mvproduces a standalone and shows actions taken
-o myExecR2016aspecifies the executable name. Though not required, “R2016a” suffix in the output name indicates MATLAB release used for compilation.
Running Standalone executable interactively
scc1% qrsh -pe omp 4 scc-pi4% module load mcr/9.0.1_2016a scc-pi4% mcr ./myExecR2016a 2000 4 scc-pi4% exit
Submit a job
Example batch script to submit a standalone MATLAB executable
#!/bin/bash -l # SGE script for MATLAB standalone # Usage: # scc1$ qsub run_standalone_job # # Merge output and error files in one #$ -j y # Send email when job finished or aborted #$ -m ae # Request 4 cores #$ -pe omp 4 module load mcr/9.0.1_2016a mcr ./myExecR2016a 2000 4
Example Source Files
function s = myApp(n, nslots) % function s = myApp(n, nslots) % Purpose: runs basic MATLAB commands to simulate user code for a standalone demo % n: size of arithmetic sequence [1+2+3+ . . . +n] % nslots: number of processors in parallel computing % Compute with the Parallel Computing Toolbox fprintf(1,'\n Test the parallel computing toolbox . . . . .\n'); fprintf(1,'Parfor will be used to compute the sum of the arithmetic sequence\n'); fprintf(1,'s = 1 + 2 + 3 + . . . + n = n(n+1)/2\n\n'); fprintf(1,'Will use %d threads for parfor operations.\n', nslots); %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Especially important for running multiple batch jobs % Without this procedure, some batch jobs may fail % redirects ~/.matlab PCT temp files to system's TMPDIR on compute % node to avoid inter-node (compute node <--> login node) I/O myCluster = parcluster('local'); % cores on compute node are "local" if getenv('ENVIRONMENT') % true if this is a batch job myCluster.JobStorageLocation = getenv('TMPDIR') % points to TMPDIR end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% parpool(myCluster, nslots); % MATLAB R2014a or newer %matlabpool(myCluster, nslots); % MATLAB R2013b or older % REPLACE BELOW EXAMPLE WITH YOUR APP % This example uses parfor to compute arithmetic sequence sum s = 0; % initialize sequence sum s parfor i=1:n s = s + i; % s = 1 + 2 + 3 + . . . + n end %matlabpool close; % close parallel pool for R2013 or older delete(gcp) % close parallel pool for R2014a or newer fprintf(1,'\n\n Iteration count n = %d\n', n); fprintf(1,'\nComputed s = %d ; Expected s = %d \n\n', s, n*(n+1)/2); end % end of function% end of function
myStandalone wrapper script
function myStandalone(n, nprocs) % function myStandalone(n, nprocs) % Purpose: this optionally serves as the front m-file % to your app so your app remain unchanged. % n: size of arithmetic sequence [1+2+3+ . . . +n] % nprocs: # of procs [ (matlabpool('local', nprocs) ] % Standalone Main Program Rules % a) It must be a function, and it must not have output % >> myStandalone 2000 4 % command syntax % >> myStandalone(2000, 4) % function syntax % b) The standalone runs in command syntax only % scc1$ ./myExecR2013a 2000 4 % c) Commandline input (if any) are passed as strings % Must be converted to double for used as double % In command syntax, both n and nprocs are strings if ischar(n) == 1 disp('n needs conversion') n = str2double(n); % convert string to double end if ischar(nprocs) == 1 disp('nprocs needs conversion') nprocs = str2double(nprocs); % convert string end % Call user app, myApp (script or function m-file) s = myApp(n, nprocs); % Handle the output (s) as intended disp(['Sum of Arithmetic sequence 1+2+3+...+n = ' num2str(s)]) if isdeployed % in standalone mode . . . exit; else close all end end % end of function
- All supportive user m-files must be included for compilation.
- Consult the Restrictions and Limitations section for unsupported commands and toolboxes.
- If a wrapper is not used,
myApp.mmust be a command function.
myStandalone.m is an optional application-dependent wrapper and is a command function. Note that, because
myApp.m takes two input parameters — by design rather than mandatory —
myStandalone.m retains the same 2 run time input.
The following command might need to be added into your matlab script to help
myStandalone.m find files it needs:
>> addpath my/script/dir % your m-files folder
- Recompiling required whenever changes are made to one or more m-files.
- For batch processing, mcc runtime option (e.g.,
-R -singleCompThread) may be required if you run a single threaded job.
scc1% mcc -mv -o myExec myStandalone.m myApp.m -R -singleCompThread -R -nodisplay
- -R -singleCompThread turns off multithreading while -R -nodisplay disables graphics display.
- The standalone built with these runtime switches will always run with single thread and will not display graphics — in batch or interactive.