Speed Up Matrix Operations in Generated Standalone Code by Using BLAS Calls
To improve the execution speed of code generated for certain low-level vector and matrix operations (such as matrix multiplication) in standalone code, specify that you want MATLAB® Coder™ to generate 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.
For BLAS calls in standalone code, MATLAB Coder uses the BLAS library that you specify. Specify a BLAS library that is optimized for your execution environment.
MathWorks® provides a collection of BLAS and LAPACK callback classes for various platforms. You can download these callback classes from this GitHub repository.
For more information on how to use these callbacks to generate code, see Speed Up of Standalone Generated Code Using Preconfigured BLAS and LAPACK Callbacks.
Specify BLAS Library
To generate BLAS calls in standalone 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 that the particular CBLAS interface uses, and the compiler and linker options for the build process. Do one of the following:
At the command line, set the code configuration object property
CustomBLASCallbackto the name of the callback class.In the MATLAB Coder app, 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.
Write a MATLAB function that calls a function for a basic matrix operation. For example, write a function
myMultiplythat multiplies two matricesAandB.function C = myMultiply(A,B) %#codegen C = A*B; end
Define a code configuration object for a static library, dynamically linked library, or executable program. For example, define a configuration object for a dynamically linked library on a Windows platform.
cfg = coder.config('dll');Specify the BLAS callback class
useMyBLAS.cfg.CustomBLASCallback = 'useMyBLAS';The callback class must be on the MATLAB path.
Generate code. Specify that the inputs
AandBare 1000-by-1000 arrays of doubles.codegen myMultiply -args {zeros(1000),zeros(1000)} -config cfg -report
If
AandBare 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
rpathlinker option.On a macOS platform, modify the DYLD_LIBRARY_PATH environment variable or use the
rpathlinker 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
-pedanticoption produces warnings. To disable the-pedanticcompiler option, include these lines in theupdateBuildInfomethod:if ctx.getTargetLang() == 'C++' buildInfo.addCompileFlags('-Wno-pedantic'); end
OpenBLAS does not support the C89/C90 standard.
See Also
Topics
External Websites
- https://netlib.org/blas/
- https://netlib.org/blas/faq.html#_5_a_id_are_optimized_blas_libraries_available_where_can_i_find_vendor_supplied_blas_a_are_optimized_blas_libraries_available_where_can_i_find_optimized_blas_libraries
- https://www.intel.com/content/www/us/en/resources-documentation/developer.html