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)

For batch processing, you may need to generate a separate standalone to include runtime requirements.

Requisites:

  • 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 double in 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.

Compilation:

>> mcc -mv -o myExecR2013a myStandalone.m myApp.m    % . . . 
  • -mv produces a standalone and shows actions taken
  • -o myExecR2013a specifies the executable name. Though not required, “R2013a” indicates MATLAB release used for compilation.
  • myApp.m plays the role of your main program. The standalone procedure supports most toolboxes.

    myApp.m

    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.m must 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. You might want to verify that myStandalone.m works before compiling
    >> myStandalone 2000 4   % parfor i=1:2000 on 4 cores

    The following may be necessary to help myStandalone.m find files it needs . . .

    >> addpath codes2compile   % your m-files folder

    myStandalone.m

    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

  • Check out Research Computing’s Standalone Made Easy compiling tool.
  • For batch processing, mcc runtime option (e.g., -R -singleCompThread) may be required.
  • Recompiling required whenever changes are made to one or more m-files.
  • How does a standalone find MATLAB runtime library

    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 mycsh.txt and mybash.txt to your respective .cshrc and .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
    The above procedure needs only be performed once as long as the standalones are compiled with the same MATLAB release (default or via module). On the other hand, the Run Standalone With Script method may be more appropriate if your standalones are compiled with multiple MATLAB releases.

    How to run a standalone executable

    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

    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.