Main Content

Speed Up Matrix Operations in Code Generated from a MATLAB Function Block

To improve the execution speed of code generated for certain low-level vector and matrix operations (such as matrix multiplication) in a MATLAB Function block, specify that you want the code generator to produce BLAS calls. BLAS is a software library for low-level vector and matrix computations that has several highly optimized machine-specific implementations. The code generator uses the CBLAS C interface to BLAS. If you specify that you want to generate BLAS calls, and the input arrays for the matrix functions meet certain criteria, the code generator produces the BLAS calls. Otherwise, the code generator produces code for the matrix functions.

The code generator uses the BLAS library that you specify. Specify a BLAS library that is optimized for your execution environment.

Specify BLAS Library

To produce BLAS calls in generated code, you must have access to a BLAS callback class. A BLAS callback class specifies the BLAS library, the CBLAS header file, certain C data types the particular CBLAS interface uses and the compiler and linker options for the build process.

To indicate that you want to generate BLAS calls and use a specific BLAS library, specify the name of the BLAS callback class. In the Configuration Parameters dialog box, set Custom BLAS library callback to the name of the callback class.

Write BLAS Callback Class

To generate calls to a specific BLAS library in the generated code, write a BLAS callback class. Share the callback class with others who want to use this BLAS library for BLAS calls in standalone code.

The callback class must derive from the abstract class coder.BLASCallback. This example is an implementation of the callback class mklcallback for integration with the Intel MKL BLAS library on a Windows® platform.

classdef mklcallback < coder.BLASCallback
    methods (Static)
        function updateBuildInfo(buildInfo, ~)
            libPath = fullfile(pwd,'mkl','WIN','lib','intel64');
            libPriority = '';
            libPreCompiled = true;
            libLinkOnly = true;
            libs = {'mkl_intel_ilp64.lib' 'mkl_intel_thread.lib' 'mkl_core.lib'};
            buildInfo.addLinkObjects(libs, libPath, libPriority, libPreCompiled, ...
                                  libLinkOnly);
            buildInfo.addLinkObjects('libiomp5md.lib',fullfile(matlabroot,'bin', ...
                             'win64'), libPriority, libPreCompiled, libLinkOnly);
            buildInfo.addIncludePaths(fullfile(pwd,'mkl','WIN','include'));
            buildInfo.addDefines('-DMKL_ILP64');
        end
        function headerName = getHeaderFilename()
            headerName = 'mkl_cblas.h';
        end
        function intTypeName = getBLASIntTypeName()
            intTypeName = 'MKL_INT';
        end
    end
end

You must provide the getHeaderFilename, getBLASIntTypeName, and updateBuildInfo methods. The getHeaderFilename method returns the CBLAS header file name. If you are using a different BLAS library, replace mkl_cblas.h with the name of your CBLAS header file. The getBLASIntTypeName method returns the name of the integer data type that your CBLAS interface uses. If you are using a different BLAS library, replace MKL_INT with the name of the integer data type specific to your CBLAS interface. The updateBuildInfo method provides the information required for the build process to link to the BLAS library. Use code that is like the code in the example callback class to specify the location of header file, the full path name of the BLAS library, and the compiler and linker options. If you use the Intel MKL BLAS library, use the link line advisor to see which libraries and compiler options are recommended for your use case.

There are three other methods that are already implemented in coder.BLASCallback. These methods are getBLASDoubleComplexTypeName, getBLASSingleComplexTypeName, and useEnumNameRatherThanTypedef. By default, your callback class inherits these implementations from coder.BLASCallback. In certain situations, you must override these methods with your own definitions when you define your callback class.

The getBLASDoubleComplexTypeName method returns the type used for double-precision complex variables in the generated code. If your BLAS library takes a type other than double* and void* for double-precision complex array arguments, include this method in your callback class definition.

function doubleComplexTypeName = getBLASDoubleComplexTypeName()
doubleComplexTypeName = 'my_double_complex_type';
end

Replace my_double_complex_type with the type that your BLAS library takes for double-precision complex array arguments.

The getBLASSingleComplexTypeName method returns the type used for single-precision complex variables in the generated code. If your BLAS library takes a type other than float* and void* for single-precision complex array arguments, include this method in your callback class definition.

function singleComplexTypeName = getBLASSingleComplexTypeName()
doubleComplexTypeName = 'my_single_complex_type';
end

Replace my_single_complex_type with the type that your BLAS library takes for single-precision complex array arguments.

The useEnumNameRatherThanTypedef method returns false by default. If types for enumerations in your BLAS library include the enum keyword, redefine this method to return true in your callback class definition.

function p = useEnumNameRatherThanTypedef()
p = true;
end

An excerpt from generated C source code that includes the enum keyword is:

enum CBLAS_SIDE t;
enum CBLAS_UPLO b_t;
double temp;
enum CBLAS_TRANSPOSE c_t;
enum CBLAS_DIAG d_t;

Generate BLAS Calls by Specifying a BLAS Callback Class

This example shows how to generate code that calls BLAS functions in a specific BLAS library. The BLAS callback class useMyBLAS specifies the BLAS library that you want to use in this example.

  1. Create a Simulink® model.

  2. Add a MATLAB Function block to the model.

  3. In the MATLAB Function block, add code that calls a function for a basic matrix operation. For example, add the function myMultiply that multiplies two matrices A and B.

    function C = myMultiply(A,B) %#codegen
    C = A*B;
    end

  4. Add two Constant blocks to the left of the MATLAB Function block. Set their values to zeros(1000).

  5. Add an Outport block to the right of the MATLAB Function block.

  6. Connect the blocks.

    Simulink model that multiplies two matrices.

  7. In the Configuration Parameters dialog box, set Custom BLAS library callback to the name of the callback class useMyBLAS.

    The callback class must be on the MATLAB® path.

  8. Build the model.

    If A and B are large enough, the code generator produces a BLAS call for the matrix multiplication function.

Locate BLAS Library in Execution Environment

The BLAS library must be available in your execution environment. If your BLAS library is shared, use environment variables or linker options to specify the location of the BLAS library.

  • On a Windows platform, modify the PATH environment variable.

  • On a Linux® platform, modify the LD_LIBRARY_PATH environment variable or use the rpath linker option.

  • On a macOS platform, modify the DYLD_LIBRARY_PATH environment variable or use the rpath linker option.

To specify the rpath linker option, use the build information addLinkFlags method in the updateBuildInfo method of your BLAS callback class. For example, for a GCC compiler:

buildInfo.addLinkFlags(sprintf('-Wl,-rpath,"%s"',libPath));

Usage Notes and Limitations for OpenBLAS Library

If you generate code that includes calls to the OpenBLAS library functions, follow these guidelines and restrictions:

  • If you generate C++ code that includes calls to OpenBLAS library functions, compiling it with the -pedantic option produces warnings. To disable the -pedantic compiler option, include these lines in the updateBuildInfo method:

    if ctx.getTargetLang() == 'C++'
        buildInfo.addCompileFlags('-Wno-pedantic');
    end
  • OpenBLAS does not support the C89/C90 standard.

See Also

Related Topics

External Websites