生成された関数インターフェイスにおける動的割り当ての C++ 配列の使用
ほとんどの場合、配列を受け取るか配列を返す MATLAB® 関数のコードを生成すると、生成された CUDA® 関数のインターフェイスでも配列が使用されます。コンパイル時に配列サイズが不明な場合や、配列の境界が事前定義されたしきい値を超える場合、生成される配列のメモリは動的に割り当てられます。
既定では、動的に割り当てられる配列は、生成コードで C スタイルの emxArray データ構造を使用して実装されます。または、動的に割り当てられる配列を、生成コードで coder::gpu_array と呼ばれるクラス テンプレートとして実装できます。coder::gpu_array には、emxArray スタイルのデータ構造と比べて次のようないくつかの利点があります。
生成コードが例外安全になる。
生成コードが読みやすくなる。
入力データの初期化と出力データの操作が容易になり、C++ との統合が向上する。
coder::gpu_arrayは MATLAB 付属のヘッダー ファイルで定義されているため、生成コードよりも前にインターフェイスのコードを記述できる。
生成された CUDA C++ 関数と統合するカスタム CUDA コードで動的割り当ての配列を使用するにあたっては、coder::gpu_array テンプレートの使用方法を学習してください。
インターフェイス世代の変更
既定では、生成される CUDA コードは C スタイルの emxArray データ構造を使用して、動的に割り当てられる配列を実装します。代わりに、動的に割り当てられる配列を実装するために、coder::gpu_array テンプレートを使用する CUDA コードを生成することもできます。coder::gpu_array テンプレートを生成するには、次のいずれかを実行します。
コード構成オブジェクト (
coder.MexCodeConfig、coder.CodeConfig、またはcoder.EmbeddedCodeConfig) で、DynamicMemoryAllocationInterfaceパラメーターを'C++'に設定。GPU Coder™ アプリの設定の [メモリ] タブで、[動的メモリ割り当てインターフェイス] を
[C++ の coder::array を使用]に設定。
coder::gpu_array クラス テンプレートの使用
MATLAB 関数の CUDA コードを生成すると、コード ジェネレーターによって、ビルド フォルダーにヘッダー ファイル coder_gpu_array.h と coder::array.h が生成されます。coder_gpu_array.h ヘッダー ファイルには、名前空間 coder のクラス テンプレート gpu_array の定義および関数テンプレート arrayCopyCpuToGpu と arrayCopyGpuToCpu の定義が含まれています。coder::gpu_array テンプレートは、動的に割り当てられる配列を生成コードに実装します。このテンプレート用の宣言は次のとおりです。
template <typename T, int32_T N> class gpu_array
T 型の要素が格納され、N 個の次元をもちます。たとえば、カスタム CUDA コードで int32_T 型の要素を含む 2 次元動的配列 myArray を宣言するには、次を使用します。coder::gpu_array<int32_T, 2> myArray
関数テンプレート arrayCopyCpuToGpu および arrayCopyGpuToCpu は、CPU のメモリと GPU のメモリの間のデータ転送を実装します。CPU では、動的に割り当てられる配列が coder::array テンプレートを使用して実装されます。カスタム コードで動的配列を作成して操作するために使用する API の詳細については、生成された関数インターフェイスでの動的に割り当てられた C++ 配列の使用を参照してください。
生成コード (カスタム main 関数など) と統合するカスタム CUDA コードで動的割り当ての配列を使用するには、カスタム .cu ファイルに coder_gpu_array.h と coder_array.h のヘッダー ファイルを含めます。
可変サイズの数値配列を受け入れて返す C++ コードの生成
この例では、生成されたサンプル main 関数をカスタマイズして、プロジェクトで coder::gpu_array と coder::array のクラス テンプレートを使用する方法を示します。
目標は、int32_T の要素の配列を受け入れて返すことができる xTest1 用の CUDA 実行可能ファイルを生成することです。配列の最初の次元を大きさ 1 にし、2 番目の次元を無制限にします。
配列
Xを受け入れ、スカラーAをその各要素に追加し、結果の配列Yを返す MATLAB 関数xTest1を定義します。function Y = xTest1(X, A) Y = X; for i = 1:numel(X) Y(i) = X(i) + A; end
xTest1の初期ソース コードを生成し、xTest1.hをコード生成フォルダーから現在のフォルダーに移動します。以下のコマンドを使用します。cfg = coder.gpuConfig('lib'); cfg.DynamicMemoryAllocationInterface = 'C++'; cfg.GenerateReport = true; inputs = {coder.typeof(int32(0), [1 inf]), int32(0)}; codegen -config cfg -args inputs xTest1.m
生成コード内の
xTest1の関数プロトタイプは次のようになります。extern void xTest1(const coder::array<int, 2U> &X, int A, coder::array<int, 2U> &Y);上記の関数プロトタイプと互換性のある入力配列と出力配列を提供することにより、この生成コードと接続します。
現在の作業フォルダーにあるファイル
xTest1_main.cuで CUDA main 関数を定義します。この main 関数には、それぞれ
coder::gpu_arrayとcoder::arrayのクラス テンプレート定義を含むヘッダー ファイルcoder_gpu_array.hとcoder_array.hが含まれます。main 関数は次のアクションを実行します。myArrayとmyResultをint32_Tの要素の 2 次元coder::array動的配列として宣言。set_sizeメソッドを使用して、myArrayの 2 つの次元のサイズを1と100に動的に設定。myResult.sizeを使用して、myResultのサイズ ベクトルにアクセス。
#include<iostream> #include<coder_array.h> #include<xTest1.h> int main(int argc, char *argv[]) { static_cast<void>(argc); static_cast<void>(argv); // Instantiate the input variable by using coder::array template coder::array<int32_T, 2> myArray; // Allocate initial memory for the array myArray.set_size(1, 100); // Access array with standard C++ indexing for (int i = 0; i < myArray.size(1); i++) { myArray[i] = i; } // Instantiate the result variable by using coder::array template coder::array<int32_T, 2> myResult; // Pass the input and result arrays to the generated function xTest1(myArray, 1000, myResult); for (int i = 0; i < myResult.size(1); i++) { if (i > 0) std::cout << " "; std::cout << myResult[i]; if (((i+1) % 10) == 0) std::cout << std::endl; } std::cout << std::endl; return 0; }次のスクリプトを実行してコードを生成します。
cfg = coder.gpuConfig('exe'); cfg.DynamicMemoryAllocationInterface = 'C++'; cfg.GenerateReport = true; cfg.CustomSource = 'xTest1_main.cu'; cfg.CustomInclude = '.'; codegen -config cfg -args inputs xTest1_main.cu xTest1.m
コード ジェネレーターは、現在の作業フォルダーに実行可能ファイル
xTest1を生成します。以下のコマンドを使用して実行可能ファイルを実行します。if ispc !xtest1.exe else !./xTest1 end
1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099
制限
coder::gpu_arrayを使用する CUDA コードを生成するには、GPU メモリ割り当てモードをdiscreteに設定しなければなりません。GPU Coder アプリの設定でメモリ割り当てモードを変更するには、[GPU コード] セクションで [Malloc モード] パラメーターを使用します。コマンド ライン インターフェイスを使用する場合、
MallocModeビルド構成プロパティを使用し、それを'discrete'または'unified'に設定します。GPU Coder は Simulink® で
coder::gpu_arrayをサポートしません。