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.
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 to
fiaccel
:
fiaccel -config cfg foo
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 DynamicMemoryAllocation
option:
Setting | Action |
---|---|
mexcfg.DynamicMemoryAllocation='Off'; | Dynamic memory allocation is disabled. All variable-size data is allocated statically on the stack. |
mexcfg.DynamicMemoryAllocation='AllVariableSizeArrays'; | Dynamic memory allocation is enabled for all variable-size arrays. All variable-size data is allocated dynamically on the heap. |
mexcfg.DynamicMemoryAllocation='Threshold'; | 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
Dynamic memory allocation threshold parameter.
Variable-size arrays whose size is less than this threshold are allocated on
the stack. |
Optionally, if you set Dynamic memory allocation
to
'Threshold'
, configure Dynamic memory allocation
threshold
to fine tune memory allocation.
Using the -config
option, pass the configuration object to
fiaccel
:
fiaccel -config mexcfg foo
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:
fiaccel -report foo -args {coder.typeof(0,[2 4],1)}
coder.typeof
to specify one variable-size input for
function foo
. 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.
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
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
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.
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.
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 of
B
in uniquetol
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 for
uniquetol
named uniquetol_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
is 1x:?
, indicating
that it is variable size with no upper bounds.
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.