Main Content

入力としてのエントリポイント関数出力の受け渡し

複数のエントリポイント関数のコードを生成するには、各関数の入力の型を指定しなければなりません。coder.OutputType を使用して、1 つの関数の出力の型を別の関数の入力の型として渡すことができます。たとえば、関数 foo1 からの 2 番目の出力の型を関数 foo2 への入力型として使用するには、次のように入力します。

codegen foo1 -args {7, 42} foo2 -args {coder.OutputType('foo1',2)} 

また、coder.OutputType を使用して、コード ベースを分割、コンポーネント化、または拡張するプロセスを容易にすることもできます。たとえば、MATLAB® コードで複雑な集約データ型が使用されているか、受け入れている場合、そのデータ型を作成する別々のコンストラクター関数の作成を検討してください。次に、コンストラクターからの出力型を他のエントリポイント関数に渡す coder.OutputType を使用して、複数のエントリポイント関数のコードを生成します。

複数のエントリポイント関数の使用の詳細については、複数のエントリポイント関数のためのコード生成を参照してください。

エントリポイント関数の出力を別のエントリポイント関数への入力として渡す

関数 coder.OutputType は、同じデータ型を使用するエントリポイント関数を連結する方法を提供します。coder.OutputType を使用して次を行います。

  • 入力の型指定プロセスを簡略化する。既存のエントリポイント関数がデータ型を作成または定義するときに、その定義を別のエントリポイント関数への入力に再利用できます。

  • エントリポイント関数間でデータを同期および調整する。coder.OutputType を使用してデータ型を渡す場合、型定義には単一のソースしかなく、その定義は両方の関数によって使用されます。

これらのメリットを理解するために、coder.OutputType を使用する場合と、使用しない場合の 2 つのコード生成を比較します。

例: 入れ子にされた構造体の出力型を入力型として再利用

コード ベースにとって重要な、複雑なデータ型があるとします。入力、出力、および内部計算でこのデータ型に依存している複数のエントリポイント関数があります。同じ型定義を使用するには、生成された関数コード間のインターフェイスが必要です。

この例の目的上、データ型は入れ子にされた構造体であり、可変サイズの配列が最下位のレベルのプロパティに格納されているとします。生成されたコードのこの構造体型 squiggle に名前を付けます。MATLAB で、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;

2 番目の関数 useConstructor を記述します。この関数は、squiggle 型を入力として取り、加算を実行し、データの最後に追加列をプッシュします。

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;

myConstructor および useConstructor 用のコードを生成し、それらを複数のエントリポイント関数として扱うには、両方の関数の入力型を指定しなければなりません。2 つの整数を使用して、myConstructor の入力型を指定します。useConstructor の場合、coder.OutputType を使用して入力型を myConstructor からの出力型として指定します。

v = coder.OutputType('myConstructor');
codegen myConstructor -args {5,1} useConstructor -args {v,3} -report -config:lib

生成されたコードでは、関数インターフェイスが合わせられています。2 つのエントリポイント関数は、squiggle に対して同じ型定義を使用します。コンストラクターの生成コードを使用して、useConstructor の生成コードの入力型を作成できます。

例: coder.OutputType を使用せずに入力型を手動で定義

coder.OutputType を使用せずに useConstructor の入力型を定義する場合は、coder.typeof および coder.StructType クラスのプロパティを使用して入力型を指定しなければなりません。

% 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';

スタティック ライブラリ コードを生成するには、次を入力します。

codegen myConstructor -args {5,1} useConstructor -args {t,3} -report -config:lib

最初の例と同じように、関数インターフェイスが合わせられます。ただし、squiggle の型定義を作成および維持することは非常に労力を要します。型定義に対して行う変更は、2 つの場所、つまり関数 myConstructor と現在のワークスペース変数 t で複製されなければなりません。これらの変更は、特に複雑な型定義を使用している場合に、同期がとれなくなる可能性があります。coder.OutputType を使用して開発プロセスをサポートします。

coder.OutputType を使用してコードのコンポーネント化を容易にする

MATLAB コードが、大きく、複雑な、または集約型の定義を使用する場合、コードを別のエントリポイント関数のコンポーネント (コンストラクターや演算子など) に分割し、coder.OutputType を使用してそれらの間で型定義を渡すことができます。関数 coder.OutputType を使用すると、さまざまなエントリポイント関数間で必ずインターフェイスを一致させることができます。

例: コンストラクターを作成し、coder.OutputType を使用して出力型を渡す

スパース行列入力に対して演算を実行する関数 useSparse について考えます。

function out = useSparse(in)
%#codegen
out = in*2;

useSparse のコードを生成する場合、適切な入力型を C/C++ で手動で作成しなければなりません。型の構築を自動化および簡略化するには、スパース行列用のコンストラクターを記述します。

function A = makeSparse(i,j,v,m,n)
%#codegen
A = sparse(i,j,v,m,n);

コードを生成するには、coder.OutputType を使用してコンストラクターからの出力を useSparse への入力として渡します。入力引数を 3 行 5 列の行列として定義します。

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

生成された C/C++ コードを使用して、makeSparse を呼び出して useSparse への入力を生成できます。関数 coder.OutputType を使用すると、共通のコード ベースに属する別々のエントリポイント関数のインターフェイスを簡単に作成し、合わせることができます。

参考

| | | |

関連するトピック