Pass an Entry-Point Function Output as an Input - MATLAB & Simulink (original) (raw)
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 functionfoo1
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. Usecoder.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 calledmyConstuctor
:
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 thesquiggle
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
anduseConstructor
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. ForuseConstructor
, specify the input type as the output type from myConstructor
by usingcoder.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 foruseConstructor
, you must specify the input type by usingcoder.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. Usecoder.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
. Thecoder.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