MEX Function Generation at the Command Line

Learning Objectives

In this tutorial, you will learn how to:

  • Automatically generate a MEX function from your MATLAB® code.

  • Define function input properties at the command line.

  • Specify the upper bounds of variable-size data.

  • Specify variable-size inputs.

  • Generate a code generation report that you can use to debug your MATLAB code and verify that it is suitable for code generation.

Tutorial Prerequisites

What You Need to Know

To complete this tutorial, you should have basic familiarity with MATLAB software.

Required Products

To complete this tutorial, you must install the following products:

  • MATLAB

  • MATLAB Coder™

  • C compiler

    For most platforms, a default compiler is supplied with MATLAB.

    MATLAB Coder automatically locates and uses a supported installed compiler. For the current list of supported compilers, see Supported and Compatible Compilers on the MathWorks® website.

    You can use mex -setup to change the default compiler. See Change Default Compiler.

For instructions on installing MathWorks products, refer to the installation documentation. If you have installed MATLAB and want to check which other MathWorks products are installed, enter ver in the MATLAB Command Window.

Example: Euclidean Minimum Distance

Description

The Euclidean distance between points p and q is the length of the line segment pq¯. In Cartesian coordinates, if p=(p1,p2,...,pn) and q=(q1,q2,...,qn) are two points in Euclidean n-space, then the distance from p to q is given by:

d(p,q)=pq=(p1q1)2+(p2q2)2+...+(pnqn)2=i=1n(piqi)2

In one dimension, the distance between two points, x1 and x2, on a line is simply the absolute value of the difference between the two points:

(x2x1)2=|x2x1|

In two dimensions, the distance between p=(p1,p2) and q=(q1,q2) is: (p1q1)2+(p2q2)2

The example for this tutorial computes the minimum Euclidean distance between a column vector x and a collection of column vectors in the codebook matrix cb. The function has three output variables:

  • y, the vector in cb with the minimum distance to x

  • idx, the index of the column vector in cb corresponding to the closest vector

  • distance, the distance between x and y

Algorithm

This algorithm computes the minimum Euclidean distance between a column vector x and a collection of column vectors in the codebook matrix cb. The algorithm computes the minimum distance to x and finds the column vector in cb that is closest to x. It outputs this column vector, y, its index, idx, in cb, and distance, the distance between x and y.

The function signature for the algorithm is:

function [y,idx,distance] = euclidean(x,cb)

The minimum distance is initially set to the first element of cb.

idx=1;
distance=norm(x-cb(:,1));

The minimum distance calculation is performed in the for-loop.

for index=2:size(cb,2)
    d=norm(x-cb(:,index));
    if d < distance
        distance=d;
        idx=index;
    end
end

The output y is set to the minimum distance vector.

y=cb(:,idx);

Files for the Tutorial

About the Tutorial Files

The tutorial uses the following files:

  • Example MATLAB code files for each step of the tutorial.

    Throughout this tutorial, you work with MATLAB files that contain a simple Euclidean distance algorithm.

  • Build scripts that you use to compile your function code.

  • Test files that:

    • Perform the preprocessing functions, for example, setting up input data.

    • Call the specified Euclidean function.

    • Perform the post-processing functions, for example, plotting the distances.

  • A MAT-file that contains example input data.

Location of Files

The tutorial files are available in the following folder: docroot\toolbox\coder\examples\euclidean. To run the tutorial, you must copy these files to a local folder. For instructions, see Copying Files Locally.

Names and Descriptions of Files

TypeNameDescription
Function code euclidean01.mBaseline MATLAB implementation of Euclidean minimum distance algorithm including plot functions.
euclidean02.mVersion of the original algorithm with the %#codegen directive.
euclidean03.mVersion of the original algorithm without plotting functions.
euclidean04.mModified algorithm that uses assert to specify the upper bounds of variable N.
Build scriptbuild01.mBuild script for euclidean03.m.
build02.mBuild script for euclidean03.m specifying two-dimensional inputs.
build03.mBuild script for euclidean03.m specifying variable-size inputs.
build04.mBuild script for euclidean04.m.
Test script test01.mInitial version of test script, includes plot functions. Tests euclidean03 MEX function.
test02.mTests the three-dimensional euclidean03 MEX function with two-dimensional inputs.
test03.mTests the two-dimensional euclidean04 MEX function with two-dimensional inputs.
test04.mTests euclidean03_varsize MEX function with two-dimensional and three-dimensional inputs.
test05.mTests euclidean04 MEX function specifying how many elements of each input to process.
MAT-fileeuclidean.matContains the input data used by the algorithm.

Tutorial Steps

Copying Files Locally

Copy the tutorial files to a local solutions folder and create a local working folder:

  1. Create a local solutions folder, for example, c:\coder\euclidean\solutions.

  2. Change to the docroot\toolbox\coder\examples folder. At the MATLAB command prompt, enter:

    cd(fullfile(docroot, 'toolbox', 'coder', 'examples')) 

  3. Copy the contents of the euclidean subfolder to your local solutions folder, specifying the full pathname of the solutions folder:

    copyfile('euclidean', 'solutions')
    Your solutions folder now contains a complete set of solutions for the tutorial. If you do not want to perform the steps for each task in the tutorial, you can view the solutions to see how the code should look.

  4. Create a local work folder, for example, c:\coder\euclidean\work.

  5. Copy the following files from your solutions folder to your work folder.

    • euclidean01.m

    • euclidean.mat

    • Build files build01.m through build04.m

    • Test scripts test01.m through test05.m

    Your work folder now contains the files that you need to get started with the tutorial.

Running the Original MATLAB Code

In this tutorial, you work with a MATLAB function that implements the Euclidean distance minimizing algorithm. You make the MATLAB version of this algorithm suitable for code generation and test the resulting MEX function to validate the functionality of the modified code. As you work through the tutorial, you refine the design of the algorithm to accept variable-size inputs.

Before generating a MEX function, run the original MATLAB function to see how the Euclidean distance minimizing algorithm works.

  1. Set your MATLAB current folder to the work folder that contains your files for this tutorial.

    cd work
    work is the full path name of the work folder containing your files. For more information, see Files and Folders that MATLAB Accesses.

  2. Load the euclidean.mat file into your MATLAB workspace.

    load euclidean.mat
    Your MATLAB workspace now contains:

    • A matrix x containing 40000 three-dimensional vectors.

    • A matrix cb containing 216 three-dimensional vectors.

    The Euclidean algorithm minimizes the distance between a column vector, x1, taken from matrix x, and the column vectors in the codebook matrix cb. It outputs the column vector in cb that is closest to x1.

  3. Create a single input vector x1 from the matrix x.

    x1=x(:,1)

    The result is the first vector from x:

    x1 =
    
        0.8568
        0.7455
        0.3835
  4. Use the Euclidean algorithm to find the vector in codebook matrix cb that is closest to x1. At the MATLAB command prompt, enter:

    [y, idx, distance]=euclidean01(x1,cb)

    The Euclidean algorithm runs and plots the lines from x1 to each vector in cb.

    After completing the algorithm, it outputs the coordinates of the point y, which is the vector in cb closest to x1, together with the index idx of x1 in cb, and the distance, distance, between y and x1.

    y =
        0.8000
        0.8000
        0.4000
    
    idx =
       171
    
    distance =
        0.0804

    The algorithm computes that the point y=0.8000, 0.8000, 0.4000, the 171st vector in cb, is closest to point x1. The distance between y and x1 is 0.0804.

Where to Go Next.  Before continuing with the tutorial, you must set up your C compiler as detailed in Setting Up Your C Compiler.

Setting Up Your C Compiler

MATLAB Coder automatically locates and uses a supported installed compiler. For the current list of supported compilers, see Supported and Compatible Compilers on the MathWorks website.

You can use mex -setup to change the default compiler. See Change Default Compiler.

Considerations for Making Your Code Compliant

Designing for Code Generation.  Before generating code, you must prepare your MATLAB code for code generation. The first step is to eliminate unsupported constructs.

Checking for Issues at Design Time.  There are two tools that help you detect code generation issues at design time: the code analyzer and the code generation readiness tool.

You use the code analyzer in the MATLAB Editor to check for code issues at design time, minimizing compilation errors. The code analyzer continuously checks your code as you enter it. It reports problems and recommends modifications to maximize performance and maintainability.

To use the code analyzer to identify warnings and errors specific to MATLAB for code generation, you must add the %#codegen directive (or pragma) to your MATLAB file. A complete list of MATLAB for Code Generation code analyzer messages is available in the MATLAB Code Analyzer preferences. See Running the Code Analyzer Report for more details.

    Note:   The code analyzer might not detect all MATLAB for code generation issues. After eliminating errors or warnings that the code analyzer detects, compile your code with MATLAB Coder to determine if the code has other compliance issues.

The code generation readiness tool screens MATLAB code for features and functions that are not supported for code generation. The tool provides a report that lists the source files that contain unsupported features and functions and an indication of how much work is required to make the MATLAB code suitable for code generation.

You can access the code generation readiness tool in the following ways:

  • In the current folder browser — by right-clicking a MATLAB file

  • At the command line — by using the coder.screener function.

  • In a project — when you add a MATLAB file to a project, if MATLAB Coder detects code generation issues, it provides a link to the code generation readiness report.

Checking for Issues at Code Generation Time.  You can use codegen to check for issues at code generation time. codegen checks that your MATLAB code is suitable for code generation.

When codegen detects errors or warnings, it automatically generates an error report that describes the issues and provides links to the offending MATLAB code. For more information, see Code Generation Reports.

After code generation, codegen generates a MEX function that you can use to test your implementation in MATLAB.

Checking for Issues at Run Time.  You can use codegen to generate a MEX function and check for issues at run time. In simulation, the code generated for your MATLAB functions includes the run-time checks. Disabling run-time checks and extrinsic calls usually results in streamlined generated code and faster simulation. You control run-time checks using the MEX configuration object, coder.MexCodeConfig. For more information, see Control Run-Time Checks.

If you encounter run-time errors in your MATLAB functions, a run-time stack appears automatically in the MATLAB Command Window. See Debug Run-Time Errors.

Where to Go Next.  The next section of the tutorial, Making Your Code Suitable for Code Generation, shows you how to use the MATLAB code analyzer and codegen to make your code suitable for code generation.

Making the MATLAB Code Suitable for Code Generation

Making Your Code Suitable for Code Generation.  To begin the process of making your MATLAB code suitable for code generation, you work with the euclidean01.m file. This file is a MATLAB version of a three-dimensional Euclidean example that plots the distances between an input vector x and each of the vectors in the codebook matrix cb. It determines which vector in cb is closest to x, and outputs this vector, its position in cb, and the distance to y.

  1. In your work folder, open euclidean01.m in the MATLAB Editor.

    edit euclidean01.m

    The file opens. The code analyzer message indicator in the top right corner of the MATLAB Editor is green, which indicates that the code analyzer has not detected errors, warnings, or opportunities for improvement in the code.

  2. Turn on code generation error checking by adding the %#codegen compilation directive after the function declaration.

    function [ y, idx, distance ] = ...
      euclidean01( x, cb )  %#codegen
    The code analyzer message indicator remains green, indicating that it has not detected code generation issues.

    For more information on using the code analyzer, see Running the Code Analyzer Report.

  3. Change the function name to euclidean02 and save the file as euclidean02.m in the current folder.

    You are now ready to compile your code using codegen, which checks that your code is suitable for code generation. After code generation, codegen generates a MEX function that you can test in MATLAB.

     Best Practice — Preserving Your Code

Generating a MEX Function Using codegen

About codegen.  You generate MEX functions using codegen, a function that compiles MATLAB code to a MEX function. codegen also checks that your MATLAB code is suitable for code generation.

Using codegen.  Because C uses static typing, codegen must determine the properties of all variables in the MATLAB files at compile time. Therefore, you must specify the properties of all function inputs at the same time as you compile the file with codegen. To compile euclidean02.m, you must specify the size of the input vector x and the codebook matrix cb.

  1. Compile the euclidean02.m file.

    codegen -report euclidean02.m -args {x(:,1), cb}

    • By default, codegen generates a MEX function named euclidean02_mex in the current folder. You can compare the results of running the MEX function with the results of running the original MATLAB code.

    • The -args option instructs codegen to compile the file euclidean02.m by using the sample input parameters x(:,1) and cb.

    • The -report option instructs codegen to produce a code generation report.

  2. At the MATLAB command prompt, click the link to the code generation report. View the MATLAB code for the plot_distances function.

MATLAB Coder treats common MATLAB visualization functions as extrinsic. It does not generate code for these functions. Instead, for a MEX function, it generates code to run the function in MATLAB. These functions include line, grid, clf, axis, and pause. The report highlights extrinsic functions. If a function is not supported for code generation, and is not treated as extrinsic, you must explicitly declare that the function is extrinsic by using coder.extrinsic. See Extrinsic Functions.

You are ready to begin the next task in this tutorial, Validating the MEX Function.

Validating the MEX Function

Test the MEX function that you generated in Generating a MEX Function Using codegen to verify that it provides the same functionality as the original MATLAB code. You run the MEX function with the same inputs that you used in Running the Original MATLAB Code.

Running the Generated MEX Function  

  1. Create a single input vector x1 from the matrix x.

    x1=x(:,1)

    The result is the first vector in x:

    x1 =
        0.8568
        0.7455
        0.3835
  2. Use the MEX function euclidean02_mex to find the vector in codebook matrix cb that is closest to x1.

    [y, idx, distance] = euclidean02_mex(x1,cb)

    The MEX function runs and plots the lines from x1 to each vector in cb. After completing the algorithm, it outputs the coordinates of the point y, which is the vector in cb closest to x1, together with the index idx of y in cb, and the distance, distance, between y and x1.

    y =
        0.8000
        0.8000
        0.4000
    
    idx =
       171
    
    distance =
        0.0804

    The plots and outputs are identical to those generated with the original MATLAB function. The MEX function euclidean02_mex is functionally equivalent to the original MATLAB code in euclidean01.m.

Using Build and Test Scripts

In Check for Run-Time Issues, you generated a MEX function for your MATLAB code by calling codegen from the MATLAB command line. In this part of the tutorial, you use a build script to generate your MEX function and a test script to test it. The first step is to modify the code in euclidean02.m to move the plotting function to a separate test script.

 Why Use Build Scripts?

 Why Use Test Scripts?

Modifying the Code to Remove the Plot Function.  In the file euclidean02.m:

  1. Delete the call to plot_distances.

  2. Delete the local function plot_distances.

  3. Change the function name to euclidean03 and save the file as euclidean03.m in the current folder.

 Contents of euclidean03.m

Using the Build Script build01.m.  Next you use the build script build01.m that compiles euclidean03.m using codegen. Use the -report option, which instructs codegen to generate a code generation report that you can use to debug your MATLAB code and verify that it is suitable for code generation.

 Best Practice — Generating a Code Generation Report

 Contents of Build File build01.m

At the MATLAB command prompt, enter:

build01
codegen runs and generates a MEX function euclidean03_mex in the current folder.

You are ready to test the MEX function euclidean03_mex.

Using the Test Script test01.m.  You use the test script test01.m to test the MEX function euclidean03_mex.

The test script:

  • Loads the test data from the file euclidean.mat.

  • Runs the original MATLAB file euclidean03.m and plots the distances.

  • Runs the MEX function euclidean03_mex and plots the distances.

 Contents of Test Script test01.m

Running the Test Script.  At the MATLAB command prompt, enter:

test01

The test file runs, plots the lines from x1 to each vector in cb, and outputs:

Running MATLAB function euclidean03
y = 0.8         0.8         0.4
idx = 171
distance = 0.080374
Running MEX function euclidean03_mex
y = 0.8         0.8         0.4
idx = 171
distance = 0.080374
The outputs for the original MATLAB code and the MEX function are identical.

You are now ready to begin the next task in this tutorial, Modifying the Algorithm to Accept Variable-Size Inputs.

Modifying the Algorithm to Accept Variable-Size Inputs

Why Modify the Algorithm?.  The algorithm you have used so far in this tutorial is suitable only to process inputs whose dimensions match the dimensions of the example inputs provided using the -args option. In this part of the tutorial, you run euclidean03_mex to see that it does not accept two-dimensional inputs. You then recompile your code using two-dimensional example inputs and test the resulting MEX function with the two-dimensional inputs.

About the Build and Test Scripts  

 Contents of test02.m

 Contents of build02.m

 Contents of test03.m

Running the Build and Test Scripts  

  1. Run the test script test02.m to test euclidean03x with two-dimensional inputs.

    test02

    MATLAB reports an error indicating that the MEX function does not accept two-dimensional variables for the input cb.

     MATLAB expression 'x' is not of the correct size: 
    expected [3x1] found [2x1].
    
    Error in ==> euclidean03

    To process two-dimensional inputs, you must recompile your code providing two-dimensional example inputs.

  2. Run the build file build02.m to recompile euclidean03.m with two-dimensional inputs.

    build02
    codegen compiles the file and generates a MEX function euclidean03_2d in the current folder.

  3. Run the test file test03.m to run the resulting MEX function euclidean03_2d with two-dimensional inputs.

    At the MATLAB command prompt, enter:

    test03
    This time, the MEX function runs and outputs the vector y in matrix cb that is closest to x2d in two dimensions.
    Running new 2-D version of MEX function
    y = 0         0.4
    idx = 3
    distance = 0.053094

This part of the tutorial demonstrates how to create MEX functions to handle inputs with different dimensions. Using this approach, you would need a library of MEX functions, each one suitable only for inputs with specified data types, dimensions, and complexity. Alternatively, you can modify your code to accept variable-size inputs. To learn how, see Specifying Variable-Size Inputs.

Specifying Variable-Size Inputs.  The original MATLAB function is suitable for many different size inputs. To provide this same flexibility in your generated C code, use coder.typeof with the codegen -args command-line option.

coder.typeof(a,b,1) specifies a variable-size input with the same class and complexity as a and same size and upper bounds as the size vector b. For more information, see Specify Variable-Size Inputs at the Command Line.

  1. Compile this code using the build file build03.m. This build file uses coder.typeof to specify variable-size inputs to the euclidean03 function.

    build03

    codegen compiles the file without warnings or errors and generates a MEX function euclidean03_varsizex in the current folder.

     Contents of build03.m

  2. Run the resulting MEX function with two-dimensional and then three-dimensional inputs using the test file test04.m.

    At the MATLAB command prompt, enter:

    test04

    The test file runs and outputs:

    Running euclidean03_varsizex with 2-D inputs
    y  = 0         0.4
    idx = 3
    distance = 0.053094
    Running euclidean04_varsizex with 3-D inputs
    y = 0.6         0.8         0.2
    idx = 134
    distance = 0.053631
    You have created an algorithm that accepts variable-size inputs.

     Contents of test04.m

Specifying Upper Bounds for Local Variables

In this part of the tutorial, you modify the algorithm to compute only the distance between the first N elements of a given vector x and the first N elements of every column vector in the matrix cb.

To modify the Euclidean minimum distance algorithm, euclidean03.m, to accommodate changes in dimensions over which to compute the distances:

  1. Provide a new input parameter, N, to specify the number of elements to consider. The new function signature is:

    function [y,idx,distance] = euclidean03(x,cb,N) 

  2. Specify an upper bound for the variable N using assert. Add this line after the function declaration.

    assert(N<=3);

    The value of the upper bound must correspond to the maximum number of dimensions of matrix cb. If you do not specify an upper bound, an array bounds error occurs if you run the MEX function with a value for N that exceeds the number of dimensions of matrix cb. For more information, see Specifying Upper Bounds for Variable-Size Data.

  3. Modify the line of code that calculates the initial distance to use N. Replace the line:

    distance=norm(x-cb(:,1));
    with:
    distance=norm(x(1:N)-cb(1:N,1));

  4. Modify the line of code that calculates each successive distance to use N. Replace the line:

    d=norm(x-cb(:,index));
    with:
    d=norm(x(1:N)-cb(1:N,index)); 

  5. Change the function name to euclidean04 and save the file as euclidean04.m in the current folder.

     Contents of euclidean04.m

  6. Compile this code using the build file build04.m.

    At the MATLAB command prompt, enter:

    build04

    codegen compiles the file without warnings or errors and generates a MEX function euclidean04x in the current folder.

     Contents of build04.m

  7. Run the resulting MEX function to process the first two elements of the inputs x and cb , then to process all three elements of these inputs. Use the test file test05.m.

    At the MATLAB command prompt, enter:

    test05

    The test file runs and outputs:

    Running euclidean04_mex for first two elements of inputs x and cb
    y = 0.8         0.8           0
    idx = 169
    distance = 0.078672
    Running eucidean04_mex for three elements of inputs x and cb
    y = 0.8         0.8         0.4
    idx = 171
    distance = 0.080374

     Contents of test05.m

Key Points to Remember

  • Back up your MATLAB code before you modify it.

  • Decide on a naming convention for your files and save interim versions frequently. For example, this tutorial uses a two-digit suffix to differentiate the various versions of the filter algorithm.

  • Use build scripts to build your files.

  • Use test scripts to separate the pre- and post-processing from the core algorithm.

  • Use the -args option to specify input parameters at the command line.

  • Use the MATLAB assert function to specify the upper bounds of variable-size data.

  • Use the -report option to create a code generation report.

  • Use coder.typeof(a,b,1) to specify variable-size inputs.

Where to Learn More

Next Steps

To...See...

Learn how to generate C code from your MATLAB code

C Code Generation at the Command Line

Learn how to integrate your MATLAB code with Simulink® models

Track Object Using MATLAB Code

Learn more about using code generation from MATLAB

MATLAB Programming for Code Generation

Use variable-size data

Variable-Size Data Definition for Code Generation

Speed up fixed-point MATLAB code

fiaccel

Integrate custom C code into MATLAB code and generate embeddable code

External Code Integration

Integrate custom C code into a MATLAB function

coder.ceval

Generate HDL from MATLAB code

www.mathworks.com/products/slhdlcoder

Product Help

MathWorks product documentation is available online from the Help menu on the MATLAB desktop.

MathWorks Online

For additional information and support, visit the MATLAB Coder page on the MathWorks website at:

www.mathworks.com/products/featured/matlab-coder

Was this topic helpful?