Accelerate Code for Variable-Size Data
Variable-size data is data whose size might change at run time. MATLAB® supports bounded and unbounded variable-size data for code generation. Bounded variable-size data has fixed upper bounds. This data can be allocated statically on the stack or dynamically on the heap. Unbounded variable-size data does not have fixed upper bounds. This data must be allocated on the heap. By default, for MEX and C/C++ code generation, support for variable-size data is enabled and dynamic memory allocation is enabled for variable-size arrays whose size exceeds a configurable threshold.
Disable Support for Variable-Size Data
By default, for MEX and C/C++ code acceleration, support for variable-size data is enabled. You modify variable sizing settings at the command line.
Create a configuration object for code generation.
cfg = coder.mexconfig;
Set the
EnableVariableSizing
option:cfg.EnableVariableSizing = false;
Using the
-config
option, pass the configuration object tofiaccel
:fiaccel -config cfg foo
Control Dynamic Memory Allocation
By default, dynamic memory allocation is enabled for variable-size arrays whose size exceeds a configurable threshold. If you disable support for variable-size data, you also disable dynamic memory allocation. You can modify dynamic memory allocation settings at the command line.
Create a configuration object for code acceleration. For example, for a MEX function:
mexcfg = coder.mexconfig;
Set the
EnableDynamicMemoryAllocation
option:Setting Action mexcfg.EnableDynamicMemoryAllocation=false;
Dynamic memory allocation is disabled. All variable-size data is allocated statically on the stack. mexcfg.EnableDynamicMemoryAllocation=true;
Dynamic memory allocation is enabled for all variable-size arrays whose size (in bytes) is greater than or equal to the value specified using the DynamicMemoryAllocationThreshold
parameter. Variable-size arrays whose size is less than this threshold are allocated on the stack.Optionally, if you set
EnableDynamicMemoryAllocation
totrue
, configureDynamicMemoryAllocationThreshold
to fine tune memory allocation.Using the
-config
option, pass the configuration object tofiaccel
:fiaccel -config mexcfg foo
Accelerate Code for MATLAB Functions with Variable-Size Data
Here is a basic workflow that generates MEX code.
In the MATLAB Editor, add the compilation directive
%#codegen
at the top of your function.This directive:
Indicates that you intend to generate code for the MATLAB algorithm
Turns on checking in the MATLAB Code Analyzer to detect potential errors during code generation
Address issues detected by the Code Analyzer.
In some cases, the MATLAB Code Analyzer warns you when your code assigns data a fixed size but later grows the data, such as by assignment or concatenation in a loop. If that data is supposed to vary in size at run time, you can ignore these warnings.
Generate a MEX function using
fiaccel
. Use the following command-line options:-args {coder.typeof...}
if you have variable-size inputs-report
to generate a code generation report
For example:
This command usesfiaccel -report foo -args {coder.typeof(0,[2 4],1)}
coder.typeof
to specify one variable-size input for functionfoo
. The first argument,0
, indicates the input data type (double
) and complexity (real
). The second argument,[2 4]
, indicates the size, a matrix with two dimensions. The third argument,1
, indicates that the input is variable sized. The upper bound is 2 for the first dimension and 4 for the second dimension.Note
During compilation,
fiaccel
detects variables and structure fields that change size after you define them, and reports these occurrences as errors. In addition,fiaccel
performs a runtime check to generate errors when data exceeds upper bounds.Fix size mismatch errors:
Cause: How To Fix: For More Information: You try to change the size of data after its size has been locked. Declare the data to be variable sized. See Diagnosing and Fixing Size Mismatch Errors. Fix upper bounds errors
Cause: How To Fix: For More Information: MATLAB cannot determine or compute the upper bound Specify an upper bound. See Specify Upper Bounds for Variable-Size Arrays and Diagnosing and Fixing Size Mismatch Errors. MATLAB attempts to compute an upper bound for unbounded variable-size data. If the data is unbounded, enable dynamic memory allocation. See Control Dynamic Memory Allocation Generate C/C++ code using the
fiaccel
function.
Accelerate Code for a MATLAB Function That Expands a Vector in a Loop
About the MATLAB Function uniquetol
This example uses the function uniquetol
. This function returns in
vector B
a version of input vector A
, where the
elements are unique to within tolerance tol
of each other. In vector
B
,
abs
(B
(i
) -
B
(j
)) > tol
for all
i
and j
. Initially, assume input vector
A
can store up to 100 elements.
function B = uniquetol(A, tol) A = sort(A); B = A(1); k = 1; for i = 2:length(A) if abs(A(k) - A(i)) > tol B = [B A(i)]; k = i; end end
Step 1: Add Compilation Directive for Code Generation
Add the %#codegen
compilation directive at the top of the
function:
function B = uniquetol(A, tol) %#codegen A = sort(A); B = A(1); k = 1; for i = 2:length(A) if abs(A(k) - A(i)) > tol B = [B A(i)]; k = i; end end
Step 2: Address Issues Detected by the Code Analyzer
The Code Analyzer detects that variable B
might change size in the
for-
loop. It issues this
warning:
The variable 'B' appears to change size on every loop iteration. Consider preallocating for speed.
In this function, vector B
should expand in size as it adds values
from vector A
. Therefore, you can ignore this warning.
Step 3: Generate MEX Code
To generate MEX code, use the fiaccel
function.
Generate a MEX function for
uniquetol
:T = numerictype(1, 16, 15); fiaccel -report uniquetol -args {coder.typeof(fi(0,T),[1 100],1),coder.typeof(fi(0,T))}
What do these command-line options mean?
Executing this command generates a compiler error:
??? Size mismatch (size [1 x 1] ~= size [1 x 2]). The size to the left is the size of the left-hand side of the assignment.
Open the error report and select the Variables tab.
The error indicates a size mismatch between the left-hand side and right-hand side of
the assignment statement B = [B A(i)];
. The assignment B =
A(1)
establishes the size of B
as a fixed-size scalar (1 x
1). Therefore, the concatenation of [B A(i)]
creates a 1 x 2 vector.
Step 4: Fix the Size Mismatch Error
To fix this error, declare B
to be a variable-size vector.
Add this statement to the
uniquetol
function:coder.varsize('B');
It should appear before
B
is used (read). For example:function B = uniquetol(A, tol) %#codegen A = sort(A); coder.varsize('B'); B = A(1); k = 1; for i = 2:length(A) if abs(A(k) - A(i)) > tol B = [B A(i)]; k = i; end end
The function
coder.varsize
declares every instance ofB
inuniquetol
to be variable sized.Generate code again using the same command:
fiaccel -report uniquetol -args {coder.typeof(fi(0,T),[1 100],1),coder.typeof(fi(0,T))}
In the current folder,
fiaccel
generates a MEX function foruniquetol
nameduniquetol_mex
and provides a link to the code generation report.Click the View report link.
In the code generation report, select the Variables tab.
The size of variable
B
is1x:?
, indicating that it is variable size with no upper bounds.
Step 5: Compare Execution Speed of MEX Function to Original Code
Run the original MATLAB algorithm and MEX function with the same inputs for the same number of loop iterations and compare their execution speeds.
Create inputs of the correct class, complexity, and size to pass to the
uniquetol
MATLAB and MEX functions.x = fi(rand(1,90), T); tol = fi(0, T);
Run the original
uniquetol
function in a loop and time how long it takes to execute 10 iterations of the loop.tic; for k=1:10, b = uniquetol(x,tol); end; tSim=toc
Run the generated MEX function with the same inputs for the same number of loop iterations.
tic; for k=1:10, b = uniquetol_mex(x,tol); end; tSim_mex=toc
Compare the execution times.
r = tSim/tSim_mex
This example shows that generating a MEX function using
fiaccel
greatly accelerates the execution of the fixed-point algorithm.