GPU Coder でサポートされる MATLAB 言語機能
GPU Coder™ は、MATLAB® Coder™ でサポートされている多数の MATLAB 言語機能をサポートします。C/C++ コード生成でサポートされている MATLAB 言語機能を参照してください。ただし、制限モードでサポートされる機能もあれば、サポートされない機能もあります。以降の節では、GPU コード生成に影響を与える一部の重要な機能を紹介し、GPU Coder でサポートされない機能を一覧表示します。
一般的かつ重要な考慮事項は、可変サイズ行列のサポートです。この機能は CUDA® カーネルの作成方法に実際に影響する可能性があります。以下では、GPU コード生成の機能と考慮事項について説明します。
可変サイズ配列のコード生成
コード生成の場合、配列次元は "固定サイズ" または "可変サイズ" になります。コード ジェネレーターで配列のサイズを確認でき、実行時にその配列のサイズが変わらないことを確認できる場合、その次元は固定サイズです。配列のすべての次元が固定サイズである場合、その配列は "固定サイズ" 配列です。次の例では、Z
は固定サイズ配列です。
function Z = myfcn() Z = zeros(1,4); end
コード ジェネレーターで配列のサイズを確認できなかったり、コード ジェネレーターでそのサイズの変化が確認される場合、その次元は可変サイズです。1 つ以上の次元が可変サイズである場合、配列は "可変サイズ" 配列です。
可変サイズの次元は、"制限あり" か "制限なし" のどちらかになります。制限ありの次元には固定された上限サイズがあります。制限なしの次元には固定された上限サイズがありません。
次の例では、Z
の 2 番目の次元が制限ありの可変サイズです。これは 32 が上限になっています。
function s = myfcn(n) if (n > 0) Z = zeros(1,4); else Z = zeros(1,32); end s = length(Z);
次の例では、n
の値がコンパイル時に不明である場合、Z
の 2 番目の次元は制限なしになります。
function s = myfcn(n) Z = rand(1,n); s = sum(Z); end
可変サイズ配列を定義するには、以下を行います。
zeros
やones
などのコンストラクターを使用し、非定数サイズの値を指定します。変数を使用する前に、複数の定数サイズをその同じ変数に代入します。
ループを使用し、変数の次元を拡大します。
関数
coder.typeof
またはcoder.varsize
を使用して、変数のインスタンスが可変サイズになるように宣言します。たとえば、coder.typeof(1, [12,1],[true, false])
やcoder.varsize(1, [Inf,1], [true, false])
のようにします。
詳細については、コード生成のための可変サイズ データの定義を参照してください。
可変サイズ配列のサポートの有効化および無効化
コード生成の動作
制限ありの可変サイズ配列の場合、GPU Coder はこれらの制限ありの変数を GPU にマッピングし、CUDA カーネルが作成されます。可変サイズ配列の上限を指定するには、可変サイズ配列の上限の指定を参照してください。
非有界の可変サイズ配列と、DynamicMemoryAllocationThreshold
以上のサイズを持つ可変サイズ配列の場合、GPU Coder はこれらの変数を GPU にマッピングせず、カーネルが作成されません。コード ジェネレーターによってメモリが CPU ヒープに動的に割り当てられます。GPU Coder は、ビルド ログおよびコード生成レポート内において制限なしの変数に対する警告を発行します。
既定では、コード ジェネレーターは、2 GB をしきい値として、そのしきい値以上のサイズを持つ可変サイズ配列に動的メモリ割り当てを使用するように設定されています。これらの設定を変更するには、以下を行います。
構成オブジェクトで、
EnableDynamicMemoryAllocation
をtrue
に設定し、DynamicMemoryAllocationThreshold
を非負の整数値に設定します。GPU Coder アプリの [メモリ] 設定で、[動的メモリ割り当てを有効化] を選択し、[動的メモリ割り当てしきい値] を非負の整数に設定します。
コード生成レポート内の可変サイズ配列
コード生成レポートで [変数] タブの [サイズ] 列を確認することで、配列が固定サイズか可変サイズかを判断できます。
コロン (:) は、次元が可変サイズであることを示します。疑問符 (?) は、サイズが制限なしであることを示します。たとえば、1 x :? のサイズは、1 番目の次元のサイズが固定サイズ 1 であり、2 番目の次元のサイズが制限なしの可変サイズであることを示します。アスタリスク (*) は、コード ジェネレーターにより可変サイズ配列が生成されたが、その配列のサイズは実行中に変わらないことを示します。
コード生成の構造体定義
構造体の効率的なスタンドアロン コードを生成するには、MATLAB 環境でコードを実行するときの通常の方法とは異なる方法で構造体を定義および使用しなければなりません。コード生成では、構造体を配列に拡大する前に、まずその構造体のスカラー テンプレート バージョンを作成する必要があります。コード生成推定エンジンは、このスカラー値の型を配列の基本データ型として使用します。MATLAB 構造体のスタンドアロン コードを生成する場合、次の操作に制限されます。
関数
struct
を代入および使用して、構造体をローカル変数および永続変数として定義するドット表記を使用して構造体フィールドをインデックス付けする
基本関数またはエントリポイント関数の入力を構造体として定義する
構造体をローカル関数に渡す
詳細については、コード生成のための構造体の定義を参照してください。
メモ
GPU Coder では、struct の配列ではなく配列の struct を使用すると、より効率的なコードが生成されます。
例
この例では、コード生成に適するように構造体配列を使用する MATLAB 関数を作成する方法を説明します。まず、関数 struct
を使用して、基本要素を指定しなければなりません。
tempS = struct('a',0,'b',0); numE = 2000; AofS = repmat(tempS,numE,1);
MATLAB では、構造体配列を作成する場合、通常は処理を進めながらフィールドを追加していきます。この "動的" なスタイルの構造体作成はコード生成ではサポートされていません。その 1 つの理由は、MATLAB では、構造体配列の 2 つの異なる要素について別々の構造体フィールドを持つ可能性があることです。これは、より静的な型推論のアプローチと矛盾します。そのため、最初に基本的なスカラー要素を指定し、次にこの完全に指定された要素から構造体配列を拡大させなければなりません。この方法により、構造体配列の 2 つの要素が常に型 (フィールド) を共有することが保証されます。
for ind = 1:numE AofS(ind).a = rand; AofS(ind).b = rand; end
ここで、AofS
を入力として受け取るエントリポイント関数 mStructSupport
を定義できます。ローカル関数 arrayOp
は AofS.b
を 2 倍にして、その結果を AofS.a
に格納します。
function [V] = mStructSupport(AofS) V = arrayOp(AofS); end function AofS = arrayOp(AofS) n = numel(AofS); for i = 1:n AofS(i).a = AofS(i).b * 2; end end
GPU Coder アプリを使用したコード生成で説明されているいずれかの方法を使用して、この例の CUDA コードを生成できます。
サポートされていない機能
次の一覧には、現在サポートされていない機能を示しています。
メモリ整合性チェック。実行時チェックの制御を参照してください。
配列の範囲および次元チェック。
break
ステートメント。関数ハンドルは、別の関数内で定義されていて、エントリポイント パラメーターとして定義されていない場合のみサポート。
無名関数は、別の関数内で定義されていて、エントリポイント パラメーターとして定義されていない場合のみサポート。