If you run MATLAB single- or multi-processor 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. The executable runs without MATLAB or license. Demonstrated below is a complete standalone example: how to compile; how to run interactive and batch jobs. To receive a copy, see Download Standalone Example.
How to build a standalone executable (on the SCC)
- 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 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.
>> mcc -mv -o myExecR2013a myStandalone.m myApp.m % . . .
-mvproduces a standalone and shows actions taken
-o myExecR2013aspecifies the executable name. Though not required, “R2013a” indicates MATLAB release used for compilation.
myApp.mplays the role of your main program. The standalone procedure supports most toolboxes.
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
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.mis an optional application-dependent wrapper and is a command function. Note that, because
myApp.mtakes two input parameters — by design rather than mandatory —
myStandalone.mretains the same 2 run time input. You might want to verify that
myStandalone.mworks before compiling
>> myStandalone 2000 4 % parfor i=1:2000 on 4 cores
The following may be necessary to help
myStandalone.mfind files it needs . . .
>> addpath codes2compile % your m-files folder
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
-R -singleCompThread) may be required.
Compiling your code to generate a standalone is only the first of two steps you need to take. The second step is to set the
LD_LIBRARY_PATH environment variable to tell the system where to find the MATLAB Compiler Runtime library, or MCR. On the SCC, you can append the shell command files
mybash.txt to your respective
.bashrc shell scripts in your home directory
- For tcsh shell users:
scc1% cat mycsh.txt >> ~/.cshrc <-- appends commands to ~/.cshrc scc1% source ~/.cshrc <-- make shell effective immediately
- For bash shell users:
scc1$ cat mybash.txt >> ~/.bashrc <-- appends commands to ~/.bashrc scc1$ source ~/.bashrc <-- make shell effective immediately
To run standalone interactively on the SCC
scc1$ ./myExecR2013a 2000 4
To run a standalone batch job on the SCC
The standalone generated above can be used as is for interactive applications. For batch processing however, additional runtime flags (
-R) may be required. Let's say that you submitted a single-core batch job on the SCC. This job is dispatched to an available node (think of each node as a multicore desktop) at runtime. MATLAB's multithreading utility may decide to take advantage of multicore on your code's behalf (it has no knowledge of your asking for 1 core through the batch scheduler). When that happens, the batch scheduler aborts your job for using more cores than committed. To prevent core over usage, you can compile your application with
>> mcc -mv -o myExecR2013a myStandalone.m myApp.m ... -R -singleCompThread -R -nodisplay
The -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.
scc1$ qsub ./run_standalone_job
#!/bin/csh # SGE script for MATLAB standalone (generated with mcc) # Usage: # scc1$ qsub ./run_standalone_job # n = 100 # scc1$ qsub -t 100-300:200 ./run_standalone_job # n=100,300 # # Specify SGE batch scheduler options # Merge output and error files in one #$ -j y # Send email to SCC userID when job finished or aborted #$ -m ae # Request 4 cores from omp queue (example needs multicores) # For serial apps, prepend the line below with another # #$ -pe omp 4 # set default value for n; override with qsub -v or -t at runtime #$ -v n=100 echo "\n\n********************************************" echo "* This job runs on $HOSTNAME" echo "********************************************\n\n" set NODENAME = `echo $HOSTNAME | sed 's/.scc.bu.edu//'` # Running MATLAB standalone results in creation of a cache folder in home dir # This may cause runtime issues. Below is a workaround. echo tmpdir is $TMPDIR setenv MCR_CACHE_ROOT $TMPDIR echo "\n\n********************************************" echo "* Created local scratch folder /net/$NODENAME$TMPDIR" echo "********************************************\n\n" unsetenv DISPLAY # Output to screen go to your ?.o$JOB_ID file if $?SGE_TASK_ID then @ n = $SGE_TASK_ID; endif @ nprocs = $NSLOTS; # -pe omp 4 ==> NSLOTS = 4 # this standalone example expects n (parfor i=1:n) & nprocs (cores) myExecR2014b $n $nprocs
To run a single batch job, this script uses n=100 with 4 cores to compute the sum of the arithmetic sequence: s = 1 + 2 + 3 + . . . + n
To submit multiple batch jobs with
qsub, see Notes.
How to generate and run standalone on other systems
Generally, the above instructions are applicable to other situations; you can generate standalone on one Linux (or Windows, Macs) platform with MATLAB installed and run it on another Linux (or Windows, Macs) machine without an installed MATLAB. On the SCC, since MATLAB — and hence MCR — is available, only a couple of environment variables need to be set to help the executable find the necessary MATLAB library. To run the standalone on a system without MATLAB, an MCR library, freely downloadable from the Mathworks, will be needed.