coder.const - Fold expressions into constants in generated code - MATLAB (original) (raw)
Fold expressions into constants in generated code
Syntax
Description
[out](#bt1ikuf-out) = coder.const([expression](#bt1ikuf-expression))
evaluates expression
and replaces out
with the result of the evaluation in generated code.
[[out1,...,outN](#bt1ikuf-out1outN)] = coder.const([handle](#bt1ikuf-handle),[arg1,...,argN](#bt1ikuf-arg1argN))
evaluates the multi-output function having handle handle
. It then replaces out1,...,outN
with the results of the evaluation in the generated code. To learn about the behavior of coder.const
whenhandle
accepts zero inputs and returns zero or one outputs, see Tips.
Examples
Fold Function Calls into Constants in Generated Code
This example shows how to specify constants in generated code usingcoder.const
. The code generator folds an expression or a function call in a coder.const
statement into a constant in generated code. Because the generated code does not have to evaluate the expression or call the function every time, this optimization reduces the execution time of the generated code.
Write a function AddShift
that takes an input Shift
and adds it to the elements of a vector. The vector consists of the square of the first 10 natural numbers. AddShift
generates this vector.
function y = AddShift(Shift) %#codegen y = (1:10).^2+Shift;
Generate code for AddShift
using the codegen
command. Open the Code Generation Report.
codegen -config:lib -launchreport AddShift -args 0
The code generator produces code for creating the vector. It adds Shift
to each element of the vector during vector creation. The definition of AddShift
in generated code looks as follows:
void AddShift(double Shift, double y[10]) { int k; for (k = 0; k < 10; k++) { y[k] = (double)((1 + k) * (1 + k)) + Shift; } }
Replace the expression (1:10).^2
withcoder.const((1:10).^2)
, and then generate code forAddShift
again using the codegen
command. Open the Code Generation Report.
codegen -config:lib -launchreport AddShift -args 0
The code generator creates the vector containing the squares of the first 10 natural numbers. In the generated code, it adds Shift
to each element of this vector. The definition of AddShift
in generated code looks as follows:
void AddShift(double Shift, double y[10]) { int i; static const signed char iv[10] = { 1, 4, 9, 16, 25, 36, 49, 64, 81, 100 };
for (i = 0; i < 10; i++) { y[i] = (double)iv[i] + Shift; } }
Create Lookup Table in Generated Code
This example shows how to fold a user-written function into a constant in generated code.
Write a function getsine
that takes an input index
and returns the element referred to by index
from a lookup table of sines. The function getsine
creates the lookup table using another function gettable
.
function y = getsine(index) %#codegen assert(isa(index, 'int32')); persistent tbl; if isempty(tbl) tbl = gettable(1024); end y = tbl(index);
function y = gettable(n) y = zeros(1,n); for i = 1:n y(i) = sin((i-1)/(2pin)); end
Generate code for getsine
using an argument of type int32
. Open the Code Generation Report.
codegen -config:lib -launchreport getsine -args int32(0)
The generated code contains instructions for creating the lookup table.
Replace the statement:
with:
tbl = coder.const(gettable(1024));
Generate code for getsine
using an argument of type int32
. Open the Code Generation Report.
The generated code contains the lookup table itself. coder.const
forces the expression gettable(1024)
to be evaluated during code generation. The generated code does not contain instructions for the evaluation. The generated code contains the result of the evaluation itself.
Specify Constants in Generated Code Using Multi-Output Function
This example shows how to specify constants in generated code using a multi-output function in a coder.const
statement.
Write a function MultiplyConst
that takes an input factor
and multiplies every element of two vectors vec1
and vec2
with factor
. The function generates vec1
and vec2
using another function EvalConsts
.
function [y1,y2] = MultiplyConst(factor) %#codegen [vec1,vec2]=EvalConsts(pi.*(1./2.^(1:10)),2); y1=vec1.*factor; y2=vec2.*factor;
function [f1,f2]=EvalConsts(z,n) f1=z.^(2n)/factorial(2n); f2=z.^(2n+1)/factorial(2n+1);
Generate code for MultiplyConst
using the codegen
command. Open the Code Generation Report.
codegen -config:lib -launchreport MultiplyConst -args 0
The code generator produces code for creating the vectors.
Replace the statement
[vec1,vec2]=EvalConsts(pi.*(1./2.^(1:10)),2);
with
[vec1,vec2]=coder.const(@EvalConsts,pi.*(1./2.^(1:10)),2);
Generate code for MultiplyConst
using the codegen
command. Open the Code Generation Report.
codegen -config:lib -launchreport MultiplyConst -args 0
The code generator does not generate code for creating the vectors. Instead, it calculates the vectors and specifies the calculated vectors in generated code.
Read Constants by Processing XML File
This example shows how to call an extrinsic function using coder.const
.
Write an XML file MyParams.xml
containing the following statements:
Save MyParams.xml
in the current folder.
Write a MATLAB® function xml2struct
that reads an XML file. The function identifies the XML tag param
inside another tag params
.
After identifying param
, the function assigns the value of its attribute name
to the field name of a structure s
. The function also assigns the value of attribute value
to the value of the field.
function s = xml2struct(file)
s = struct();
doc = xmlread(file);
els = doc.getElementsByTagName('params');
for i = 0:els.getLength-1
it = els.item(i);
ps = it.getElementsByTagName('param');
for j = 0:ps.getLength-1
param = ps.item(j);
paramName = char(param.getAttribute('name'));
paramValue = char(param.getAttribute('value'));
paramValue = evalin('base', paramValue);
s.(paramName) = paramValue;
end
end
Save xml2struct
in the current folder.
Write a MATLAB function MyFunc
that reads the XML file MyParams.xml
into a structure s
using the function xml2struct
. Declare xml2struct
as extrinsic using coder.extrinsic
and call it in a coder.const
statement.
function y = MyFunc(u) %#codegen assert(isa(u, 'double')); coder.extrinsic('xml2struct'); s = coder.const(xml2struct('MyParams.xml')); y = s.hello + s.world + u;
Generate code for MyFunc
using the codegen
command. Open the Code Generation Report.
codegen -config:dll -launchreport MyFunc -args 0
The code generator executes the call to xml2struct
during code generation. It replaces the structure fields s.hello
and s.world
with the values 17 and 42 in generated code.
Input Arguments
expression
— MATLAB expression or user-written function
expression with constants | single-output function with constant arguments
MATLAB expression or user-defined single-output function.
The expression must have compile-time constants only. The function must take constant arguments only. For instance, the following code leads to a code generation error, because x
is not a compile-time constant.
function y=func(x) y=coder.const(log10(x));
To fix the error, assign x
to a constant in the MATLAB code. Alternatively, during code generation, you can use coder.Constant
to define input type as follows:
codegen -config:lib func -args coder.Constant(10)
Example: 2*pi
, factorial(10)
handle
— Function handle
function handle
Handle to built-in or user-written function.
Example: @log
, @sin
Data Types: function_handle
arg1,...,argN
— Arguments to the function with handle handle
function arguments that are constants
Arguments to the function with handle handle
.
The arguments must be compile-time constants. For instance, the following code leads to a code generation error, because x
and y
are not compile-time constants.
function y=func(x,y) y=coder.const(@nchoosek,x,y);
To fix the error, assign x
and y
to constants in the MATLAB code. Alternatively, during code generation, you can use coder.Constant
to define input type as follows:
codegen -config:lib func -args {coder.Constant(10),coder.Constant(2)}
Output Arguments
out
— Value of expression
value of the evaluated expression
Value of expression
. In the generated code, MATLAB Coder™ replaces occurrences of out
with the value of expression
.
out1,...,outN
— Outputs of the function with handle handle
values of the outputs of the function with handle handle
Outputs of the function with handle handle
. MATLAB Coder evaluates the function and replaces occurrences ofout1,...,outN
with constants in the generated code.
Limitations
- You cannot use
coder.const
on dictionaries, dictionary keys, or dictionary values.
Tips
- When possible, the code generator constant-folds expressions automatically. Typically, automatic constant-folding occurs for expressions with scalars only. Use
coder.const
when the code generator does not constant-fold expressions on its own. - When constant-folding computationally intensive function calls, to reduce code generation time, make the function call extrinsic. The extrinsic function call causes evaluation of the function call by MATLAB instead of by the code generator. For example:
function j = fcn(z)
zTable = coder.const(0:0.01:100);
jTable = coder.const(feval('besselj',3,zTable));
j = interp1(zTable,jTable,z);
end
See Use coder.const with Extrinsic Function Calls. - If
coder.const
is unable to constant-fold a function call, try to force constant-folding by making the function call extrinsic. The extrinsic function call causes evaluation of the function call by MATLAB instead of by the code generator. For example:
function yi = fcn(xi)
y = coder.const(feval('rand',1,100));
yi = interp1(y,xi);
end
See Use coder.const with Extrinsic Function Calls. - Suppose that you call
coder.const
on a function handle with zero inputs and zero or one outputs. For example:
In such situations, the code generator does not evaluatefcn
, and setsout
to the function handle@fcn
itself. To force the evaluation offcn
in this special case, call the function explicitly inside thecoder.const
command. For example:
out = coder.const(fcn());
Extended Capabilities
C/C++ Code Generation
Generate C and C++ code using MATLAB® Coder™.
GPU Code Generation
Generate CUDA® code for NVIDIA® GPUs using GPU Coder™.
Version History
Introduced in R2013b