Pass an Entry-Point Function Output as an Input
When you generate code for multiple entry-point functions, you must specify the input
types for each function. Using coder.OutputType
, you can pass the output type of one function as the input type
to another function. For example, to use the type of the second output from a function
foo1
as the input type to a function foo2
,
enter:
codegen foo1 -args {7, 42} foo2 -args {coder.OutputType('foo1',2)}
You can also use coder.OutputType
to facilitate the process of
partitioning, componentizing, or extending your code base. For example, when your
MATLAB® code uses or accepts a complicated, aggregate data type, consider creating a
separate constructor function that creates that data type. Then, generate code for multiple
entry-point functions, using coder.OutputType
to pass the output type from
the constructor to your other entry-point functions.
For more information on using multiple entry-point functions, see Generate Code for Multiple Entry-Point Functions.
Pass an Entry-Point Function Output as an Input to Another Entry-Point Function
The coder.OutputType
function provides a way to chain together
entry-point functions that use the same data types. Use
coder.OutputType
to:
Simplify the input type specification process. When an existing entry-point function creates or defines a data type, you can reuse that definition for the input to a different entry-point function.
Synchronize and align data between entry-point functions. When you use
coder.OutputType
to pass a data type, there is only a single source for the type definition, and that definition is used by both functions.
To understand these advantages, compare two cases where you generate code with and
without using coder.OutputType
.
Example: Reuse a Nested Structure Output Type as an Input Type
Suppose that you have a complicated data type that is important to your code base. You have multiple entry-point functions that rely on this data type for input, output, and internal computation. You require the interfaces between the generated function code to use the same type definition.
For the purposes of this example, suppose that the data type is a nested
structure, with a variable-size array stored in the lowest-level property. You want
to name this structure type squiggle
in the generated code. In
MATLAB, you write a constructing function for the data type called
myConstuctor
:
function [out] = myConstructor(a, b) % create a variable-sized array with upper bounds of 100-by-100 coder.varsize('myStruct.f1.f2.f3.f4', [100 100], [1 1]); % define the nested structure type myStruct = struct('f1', struct('f2', struct('f3', struct('f4', zeros(a,b) )))); % specify the name of the structure and one of its fields coder.cstructname(myStruct.f1.f2.f3,'squiggle_f3'); coder.cstructname(myStruct,'squiggle'); out = myStruct;
You write a second function, useConstructor
, that takes the
squiggle
type as input, performs addition, and pushes
additional columns on to the end of the data.
function x = useConstructor(x, n) xz = x.f1.f2.f3.f4; b = zeros(size(xz,1),1); for i = 1:n xz = [(xz + pi), b]; end x.f1.f2.f3.f4 = xz;
To generate code for myConstructor
and
useConstructor
and treat them as multiple entry-point
functions, you must specify the input types for both functions. Specify the input
types for myConstructor
by using two integers. For
useConstructor
, specify the input type as the output type
from myConstructor
by using
coder.OutputType
:
v = coder.OutputType('myConstructor'); codegen myConstructor -args {5,1} useConstructor -args {v,3} -report -config:lib
In the generated code, the function interfaces are aligned. The two entry-point
functions use the same type definition for squiggle
. You can use
the generated code for the constructor to create an input type for the generated
code for useConstructor
.
Example: Manually Define an Input Type Without Using coder.OutputType
If you do not use coder.OutputType
to define the input type for
useConstructor
, you must specify the input type by using
coder.typeof
and coder.StructType
class properties:
% MATLAB type definition for squiggle myStruct = struct('f1', struct('f2', struct('f3', struct('f4', zeros(2) )))); t = coder.typeof(myStruct); t.Fields.f1.Fields.f2.Fields.f3.Fields.f4 = coder.typeof(zeros(2), [100 100], [1 1]); t.Fields.f1.Fields.f2.Fields.f3.TypeName = 'squiggle_f3'; t.TypeName = 'squiggle';
To generate static library code, enter:
codegen myConstructor -args {5,1} useConstructor -args {t,3} -report -config:lib
As in the first example, the function interfaces are aligned. However, creating
and maintaining the type definition for squiggle
is
labor-intensive. Changes that you make to the type definition must be replicated in
two places: the myConstructor
function and the current workspace
variable t
. These changes can fall out of synchronization,
particularly when working with complicated type definitions. Use
coder.OutputType
to assist in your development process.
Use coder.OutputType
to Facilitate Code Componentization
If your MATLAB code uses large, complicated, or aggregate type definitions, you can
separate your code into different entry-point function components (such as a constructor
and an operator) and use coder.OutputType
to pass the type definition
between them. The coder.OutputType
function enables you to
ensure a matching interface between the different
entry-point functions.
Example: Create a Constructor and Use coder.OutputType
to Pass the Output Type
Consider the function useSparse
that performs an operation on a
sparse matrix input.
function out = useSparse(in) %#codegen out = in*2;
If you generate code for useSparse
, you must manually construct
the appropriate input type in C/C++. To automate
and simplify the type construction, write a constructor for the sparse
matrix.
function A = makeSparse(i,j,v,m,n) %#codegen A = sparse(i,j,v,m,n);
To generate code, use coder.OutputType
to pass the output from
the constructor as the input to useSparse
. Define your input
argument as a 3-by-5 matrix.
t = coder.OutputType('makeSparse'); S = round(rand(3,5)); [m,n] = size(S); [i,j,v] = find(S); i = coder.typeof(i,[inf 1]); % allow number of nonzero entries to vary codegen makeSparse -args {i,i,i,m,n} useSparse -args {t} -report
Using the generated C/C++ code, you can call makeSparse
to
generate the input to useSparse
. The
coder.OutputType
function makes it easy to create and align the
interface for separate entry-point functions that belong to a common code
base.
See Also
coder.StructType
| coder.typeof
| coder.varsize
| coder.cstructname
| coder.OutputType