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.
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
CustomBLASCallback
to 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
myMultiply
that multiplies two matricesA
andB
.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
A
andB
are 1000-by-1000 arrays of doubles.codegen myMultiply -args {zeros(1000),zeros(1000)} -config cfg -report
If
A
andB
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 theupdateBuildInfo
method:if ctx.getTargetLang() == 'C++' buildInfo.addCompileFlags('-Wno-pedantic'); end
OpenBLAS does not support the C89/C90 standard.
See Also
Related 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