GPU Coder アプリを使用したコード生成
CUDA® カーネルを作成する最も簡単な方法は、coder.gpu.kernelfun
プラグマを "基本" MATLAB® 関数に配置することです。基本関数は、"最上位" 関数または "エントリポイント" 関数とも呼ばれます。GPU Coder™ は kernelfun
プラグマを検出すると、この関数内のすべての計算を並列化し、その計算を GPU にマッピングしようとします。GPU カーネルの詳細については、GPU プログラミングのパラダイムを参照してください。
学習目標
このチュートリアルでは、次の方法を学びます。
kernelfun
プラグマを使用した CUDA コード生成のための MATLAB コードの準備。GPU Coder プロジェクトの作成と設定。
関数入力のプロパティの定義。
コード生成の準備状態と実行時の問題のチェック。
コード生成のプロパティの指定。
GPU Coder アプリを使用した CUDA コードの生成。
チュートリアルの前提条件
このチュートリアルには、次の製品が必要です。
MATLAB
MATLAB Coder™
GPU Coder
C++ コンパイラ
CUDA 対応 NVIDIA® GPU
CUDA Toolkit およびドライバー
コンパイラおよびライブラリの環境変数。詳細については、環境変数を参照してください。
例:マンデルブロ集合
説明
マンデルブロ集合とは、下記の方程式で定義された軌跡が k→∞ のときに有限の範囲内にとどまる値 z0 で構成された複素平面の領域です。
マンデルブロ集合の全体的な幾何形状を図に示しています。この図には、集合の境界の外側周辺における詳しい構造を十分に示すための解像度がありません。拡大率を上げていくと、マンデルブロ集合の詳細な境界が示され、そこでは徐々に細かくなりながら細部が繰り返されていることがわかります。
アルゴリズム
このチュートリアルでは、メインのカージオイドとその左側にある p/q 球状部との谷間にある、マンデルブロ集合の大きく拡大された部分を指定する一連の範囲を選択します。これらの 2 つの範囲間に、実数部 (x) と虚数部 (y) の 1000 x 1000 のグリッドを作成します。次に、マンデルブロ アルゴリズムを各グリッド位置で反復します。500 回の反復回数で、完全な解像度のイメージがレンダリングされます。
maxIterations = 500; gridSize = 1000; xlim = [-0.748766713922161,-0.748766707771757]; ylim = [0.123640844894862,0.123640851045266];
このチュートリアルでは、CPU で実行される標準の MATLAB コマンドを使ったマンデルブロ集合の実装を使用します。この計算はすべての場所が同時に更新されるようにベクトル化されています。
チュートリアル ファイル
次のコード行を使用して mandelbrot_count.m
という MATLAB 関数を作成します。このコードは、マンデルブロ集合のベースライン ベクトル化済みの MATLAB 実装です。これは、グリッドのすべての点 (xGrid,yGrid)
について、方程式で定義された軌跡の原点からの距離が 2
になる反復インデックス count
を計算します。次に、count
の自然対数を返します。これはマンデルブロ集合の色分けされたプロットを生成するために使用されます。このチュートリアルでは後ほど、コード生成に適するようにこのファイルを変更します。
function count = mandelbrot_count(maxIterations,xGrid,yGrid) % mandelbrot computation z0 = xGrid + 1i*yGrid; count = ones(size(z0)); z = z0; for n = 0:maxIterations z = z.*z + z0; inside = abs(z)<=2; count = count + inside; end count = log(count);
次のコード行を使用して mandelbrot_test.m
という MATLAB スクリプトを作成します。このスクリプトは、xlim
と ylim
で指定した範囲間に実数部 (x) と虚数部 (y) の 1000 x 1000 のグリッドを生成します。また、関数 mandelbrot_count
を呼び出して、結果のマンデルブロ集合をプロットします。
maxIterations = 500; gridSize = 1000; xlim = [-0.748766713922161,-0.748766707771757]; ylim = [0.123640844894862,0.123640851045266]; x = linspace(xlim(1),xlim(2),gridSize); y = linspace(ylim(1),ylim(2),gridSize); [xGrid,yGrid] = meshgrid(x,y); %% Mandelbrot computation in MATLAB count = mandelbrot_count(maxIterations,xGrid,yGrid); % Show figure(1) imagesc(x,y,count); colormap([jet();flipud(jet());0 0 0]); axis off title('Mandelbrot set with MATLAB');
元の MATLAB コードの実行
マンデルブロの例の実行
MATLAB バージョンのマンデルブロ集合アルゴリズムをコード生成に適したものにする前に、元のコードの機能をテストできます。
現在の MATLAB 作業フォルダーを
mandelbrot_count.m
とmandelbrot_test.m
が含まれた場所に変更します。GPU Coder はこのフォルダーに生成コードを配置します。このフォルダーに対する完全なアクセス権がない場合は現在の作業フォルダーを変更してください。mandelbrot_test
スクリプトを実行します。
テスト スクリプトが実行され、変数 xlim
および ylim
により設定された境界内のマンデルブロの幾何形状が表示されます。
コード生成用の MATLAB コードの準備
GPU Coder でコードを生成する前に、元の MATLAB コードにおけるコーディングの問題をチェックします。
設計時の問題の確認
設計時にコード生成の問題を検出するのに役立つ次の 2 つのツールがあります。
コード アナライザー ツール
コード生成の準備状態ツール
コード アナライザーは、MATLAB エディターに組み込まれたツールであり、入力されたコードを継続的にチェックします。コード アナライザーは問題を報告し、コードのパフォーマンスと保守性を最大化するための変更を提案します。MATLAB コードからのコード生成に固有の警告とエラーを識別するには、%#codegen
命令を MATLAB ファイルに追加します。詳細については、コード アナライザー基本設定を参照してください。
メモ
コード アナライザーは、コード生成の問題をすべて検出するわけではありません。コード アナライザーで検出されたエラーや警告を取り除いた後、コードに他のコンプライアンスの問題があるかどうかを確認するには、GPU Coder を使用してコードをコンパイルします。
コード生成の準備状態ツールは、コード生成でサポートされていない機能と関数について、MATLAB コードをスクリーニングします。このツールで提供されるレポートには、MATLAB コードをコード生成に適したものにするための問題と推奨事項が一覧表示されます。コード生成の準備状態ツールには次の方法でアクセスできます。
[現在のフォルダー] ブラウザーで、エントリポイント関数を含む MATLAB ファイルを右クリックします。
コマンド ラインで、
-gpu
フラグを付けて関数coder.screener
を使用します。GPU Coder アプリで、エントリポイント ファイルを指定した後、コード アナライザーおよびコード生成の準備状態ツールを実行します。
コード生成時の問題の確認
GPU Coder を使用して、コード生成時の問題をチェックできます。GPU Coder によりエラーまたは警告が検出されると、問題の説明と、問題のある MATLAB コードへのリンクが用意されたエラー レポートが生成されます。詳細については、コード生成レポートを参照してください。
コード生成に適した MATLAB コードの作成
MATLAB コードをコード生成に適したものにするプロセスを始める前に、ファイル mandelbrot_count.m
を使用します。
MATLAB の現在のフォルダーを、このチュートリアル用のファイルが含まれた作業フォルダーに設定します。
MATLAB エディターで、
mandelbrot_count.m
を開きます。MATLAB エディターの右上隅にあるコード アナライザー メッセージ インジケーターは緑色になっています。アナライザーは、コード内にエラー、警告、および改善機会を検出しませんでした。関数宣言の後ろに
%#codegen
命令を追加して、コード生成に固有のエラー チェックをオンにします。function count = mandelbrot_count(maxIterations,xGrid,yGrid) %#codegen
コード アナライザー メッセージ インジケーターは緑色のままです。これはコード生成の問題が検出されていないことを示します。
関数
mandelbrot_count
を CUDA カーネルにマッピングするには、元の MATLAB コードを変更し、関数の本体にcoder.gpu.kernelfun
プラグマを配置します。function count = mandelbrot_count(maxIterations,xGrid,yGrid) %#codegen % Add kernelfun pragma to trigger kernel creation coder.gpu.kernelfun; % mandelbrot computation z0 = xGrid + 1i*yGrid; count = ones(size(z0)); z = z0; for n = 0:maxIterations z = z.*z + z0; inside = abs(z)<=2; count = count + inside; end count = log(count);
coder.gpu.kernelfun
プラグマを使用すると、GPU Coder は関数mandelbrot_count
の計算を GPU にマッピングしようとします。ファイルを保存します。GPU Coder アプリを使用してコードをコンパイルする準備が整いました。
GPU Coder アプリを使用したコード生成
GPU Coder アプリを開く
MATLAB ツールストリップの [アプリ] タブにある [コード生成] で、GPU Coder アプリ アイコンをクリックします。また、MATLAB コマンド ウィンドウで「gpucoder
」と入力してもアプリを開くことができます。[ソース ファイルの選択] ページが開きます。
ソース ファイルの選択
[ソース ファイルの選択] ページで、"基本" 関数
mandelbrot_count
の名前を入力または選択します。基本関数は、"最上位" 関数または "エントリポイント" 関数とも呼ばれます。アプリによって、mandelbrot_count.prj
という既定の名前が付いたプロジェクトが現在のフォルダーに作成されます。[次へ] をクリックして [入力の型を定義] 手順に進みます。アプリにより、コーディング問題とコード生成の準備状態について関数が解析されます。アプリで問題が特定された場合は、[コード生成の準備状態の確認] ページが開き、そこで問題を確認および修正できます。この例では、アプリは問題を検出しないため、[入力の型を定義] ページが開きます。
入力の型を定義
コード ジェネレーターはコンパイル時に MATLAB ファイル内のすべての変数のデータ型を決定しなければなりません。そのため、すべての入力変数のデータ型を指定する必要があります。入力データ型は次の 2 つの方法で指定できます。
プロジェクトのエントリポイント関数を呼び出すテスト ファイルを指定。GPU Coder アプリはテスト ファイルを実行することで入力引数の型を推測できます。
入力の型を直接入力。
入力仕様の詳細については、入力仕様を参照してください。
この例では、入力 maxIterations
、xGrid
、および yGrid
のプロパティを定義するために、テスト ファイル mandelbrot_test.m
を指定します。
テスト ファイル
mandelbrot_test.m
を入力または選択します。[入力の型の自動定義] をクリックします。
テスト ファイル
mandelbrot_test.m
は、想定される入力の型を使用してエントリポイント関数mandelbrot_count.m
を呼び出します。アプリは入力maxIterations
がdouble(1x1)
であり、入力xGrid
およびyGrid
がdouble(1000x1000)
であると推測します。[次へ] をクリックして [実行時の問題の確認] 手順に進みます。
実行時の問題の確認
[実行時の問題の確認] 手順では、エントリポイント関数から MEX ファイルが生成され、MEX 関数を実行して、問題が報告されます。この手順はオプションです。ただし、この手順を実行することをお勧めします。この手順を使用して、生成された GPU コードでの診断が難しい欠陥を検出および修正できます。
この時点で、GPU Coder によって GPU 固有のチェックを実行するオプションが提供されます。このオプションを選択すると、GPU Coder は、エントリポイント関数から CUDA コードと MEX ファイルを生成し、MEX 関数を実行して、問題を報告します。以下は GPU 固有の実行時チェックの一部です。
レジスタ スピルのチェック。
スタック サイズの適合性チェック。
メモ
コード内に存在する特定の MATLAB コンストラクトが原因で、[実行時の問題の確認] で CPU 固有のチェックに失敗しても、GPU 固有のチェックはパスする場合があります。
[実行時の問題の確認] ダイアログ ボックスを開くには、[問題の確認] 矢印をクリックします。
[実行時の問題の確認] ダイアログ ボックスで、テスト ファイルを指定するか、入力例を使用してエントリポイント関数を呼び出すコードを入力します。この例では、入力の型を定義するために使用したテスト ファイル
mandelbrot_test.m
を使用します。GPU 固有のチェックを有効にするには、[GPU] オプション ボタンを選択します。[問題の確認] をクリックします。
アプリによって MEX 関数が生成されます。
mandelbrot_count
の呼び出しと生成された MEX の呼び出しを置き換えて、テスト スクリプトmandelbrot_test
が実行されます。MEX 関数の生成時または実行時にアプリにより問題が検出された場合は、警告およびエラー メッセージが表示されます。これらのメッセージをクリックすると、問題のあるコードに移動して、その問題を修正できます。この例では、アプリは問題を検出しません。MEX 関数には元の関数mandelbrot_count
と同じ機能があります。メモ
コード内に存在する特定の MATLAB コンストラクトが原因で、[実行時の問題の確認] で CPU 固有のチェックに失敗しても、GPU 固有のチェックはパスする場合があります。
[次へ] をクリックして [コード生成] 手順に進みます。
CUDA コードの生成
[生成] ダイアログ ボックスを開くには、[生成] 矢印をクリックします。
[生成] ダイアログ ボックスで、GPU Coder で実行するビルドのタイプを選択できます。利用可能なオプションを次の表に示します。
ビルド タイプ 説明 ソース コード
外部プロジェクトと統合される CUDA ソース コード。
MEX
MATLAB 内で実行するコンパイル済みコード。
スタティック ライブラリ
外部プロジェクトとの静的なリンクに使用されるバイナリ ライブラリ。
ダイナミック ライブラリ
外部プロジェクトとの動的なリンクに使用されるバイナリ ライブラリ。
実行可能ファイル
スタンドアロン プログラム (CUDA のカスタムのメイン ファイルが必要)。
このチュートリアルでは、[ビルド タイプ] を
[MEX(.mex)]
に設定します。MEX 出力を生成することにより、生成された CUDA コードの正確性を MATLAB 内からチェックできます。MEX ビルド タイプに、[ツールチェーン] や [ハードウェア ボード] のような追加設定は不要です。また、ソース コードのみを生成するオプションは提供されません。環境変数が適切に設定されている限り、GPU Coder は利用可能な CUDA ツールチェーンを自動的に選択できます。詳細オプションを表示するには、[詳細設定]、[GPU コード] を選択します。[コンパイラ フラグ] オプションに、
--fmad=false
を追加します。このフラグは、nvcc
に渡すと、浮動小数点積和演算 (FMAD) 最適化を無効にするようにこのコンパイラに指示します。このオプションは、CPU と GPU のアーキテクチャの違いが原因で生成コードで数値の不一致が生じることを防ぐために設定します。詳細については、CPU と GPU の数値の差を参照してください。[生成] をクリックします。
GPU Coder は MEX 実行可能ファイル
mandelbrot_count_mex
を作業フォルダーに生成します。<pwd>\codegen\mex\mandelbrot_count
フォルダーには、CUDA ソース (*.cu) ファイルおよびヘッダー ファイルを含む、他のすべての生成されたファイルが含まれます。GPU Coder アプリに、コード生成が成功したことが示されます。ページの左側には、ソース MATLAB ファイルと生成された出力ファイルが表示されます。[変数] タブには、MATLAB ソースの変数に関する情報が表示されます。[ターゲットのビルド ログ] タブには、コンパイラの警告とエラーを含むビルドのログが表示されます。既定では、アプリはコード ウィンドウに、CUDA ソース ファイルmandelbrot_count.cu
を表示します。別のファイルを表示するには、[ソース コード] または [出力ファイル] ペインでファイル名をクリックします。コード生成レポートを表示するには、[レポートの表示] をクリックします。レポートには、MATLAB コードと生成された CUDA (*.cu) ファイルへのリンクが用意されています。また、MATLAB コード内の変数と式に関するコンパイル時の情報も提供されます。この情報は、エラーおよび警告の原因を探すのに役立ちます。また、コード内のコード生成の問題をデバッグすることにも役立ちます。詳細については、コード生成レポートを参照してください。
[生成コード] タブの [GPU カーネル] セクションでは、GPU コードの生成時に作成されたカーネルの一覧が提供されます。この一覧の項目は関連するソース コードにリンクされています。たとえば、[mandelbrot_count_kernel1] をクリックすると、このカーネルのコード セクションがコード ブラウザー ウィンドウに表示されます。
レポートの確認後、[コード生成レポート] ウィンドウを閉じることができます。後でレポートを表示するには、
<pwd>\codegen\mex\mandelbrot_cout\html
フォルダーにあるreport.mldatx
を開きます。<pwd>\codegen\mex\mandelbrot_count
内には、生成された GPU コードの統計を含むgpu_codegen_info.mat
MAT ファイルがあります。この MAT ファイル内には、スレッドとブロックのサイズ、共有メモリと定数メモリの使用量、および各カーネルの入力引数と出力引数に関する情報を含んだ変数cuda_Kernel
があります。変数cudaMalloc
およびcudaMemcpy
は、すべての GPU 変数のサイズと、ホストおよびデバイス間でのmemcpy
呼び出しの数に関する情報を含みます。GPU Coder アプリで、[次へ] をクリックし、[ワークフローの完了] ページを開きます。
[ワークフローの完了] ページの確認
[ワークフローの完了] ページに、コード生成が成功したことが示されます。プロジェクトの概要と、MATLAB ソース ファイル、コード生成レポート、および生成された出力バイナリへのリンクが提供されます。現在の GPU Coder プロジェクトの構成パラメーターを MATLAB スクリプトとして保存できます。MATLAB スクリプトへの MATLAB Coder プロジェクトの変換を参照してください。
生成コードの正確性の検証
生成された MEX ファイルの正確性を検証するには、生成コードの正確性の検証を参照してください。