最新のリリースでは、このページがまだ翻訳されていません。 このページの最新版は英語でご覧になれます。

GPU Coder アプリを使用したコード生成

CUDA® カーネルを作成する最も簡単な方法は、coder.gpu.kernelfun プラグマを "基本" MATLAB® 関数に配置することです。基本関数は、"最上位" 関数または "エントリポイント" 関数とも呼ばれます。GPU Coder™ は kernelfun プラグマを検出すると、この関数内のすべての計算を並列化し、その計算を GPU にマッピングしようとします。GPU カーネルの詳細については、GPU プログラミングのパラダイムを参照してください。

学習目標

このチュートリアルでは、次の方法を学びます。

  • kernelfun プラグマを使用した CUDA コード生成のための MATLAB コードの準備。

  • GPU Coder プロジェクトの作成と設定。

  • 関数入力のプロパティの定義。

  • コード生成の準備状態と実行時の問題のチェック。

  • コード生成のプロパティの指定。

  • GPU Coder アプリを使用した CUDA C コードの生成。

チュートリアルの前提条件

このチュートリアルには、次の製品が必要です。

  • MATLAB

  • MATLAB Coder™

  • GPU Coder

  • C コンパイラ

  • CUDA 対応 NVIDIA® GPU

  • CUDA ツールキットおよびドライバー

  • コンパイラおよびライブラリの環境変数。詳細については、環境変数を参照してください。

例:マンデルブロ集合

説明

チュートリアルを完了するためにこの例のアルゴリズムを熟知している必要はありません。

マンデルブロ集合とは、下記の方程式で定義された軌跡が k→∞ のときに有限の範囲内にとどまる値 z0 で構成された複素平面の領域です。

zk+1=zk2+z0,k=0,1,

マンデルブロ集合の全体的な幾何形状を図に示しています。この図には、集合の境界の外側周辺における詳しい構造を十分に示すための解像度がありません。拡大率を上げていくと、マンデルブロ集合の詳細な境界が示され、そこでは徐々に細かくなりながら細部が繰り返されていることがわかります。

アルゴリズム

このチュートリアルでは、メインのカージオイドとその左側にある p/q 球状部との谷間にある、マンデルブロ集合の大きく拡大された部分を指定する一連の範囲を選択します。これらの 2 つの範囲間に、実数部 (x) と虚数部 (y) の 1000x1000 のグリッドを作成します。次に、マンデルブロ アルゴリズムを各グリッド位置で反復します。完全な解像度のイメージをレンダリングするには 500 回の反復回数で十分です。

maxIterations = 500;
gridSize = 1000;
xlim = [-0.748766713922161,-0.748766707771757];
ylim = [0.123640844894862,0.123640851045266];

このチュートリアルでは、CPU で実行される標準の MATLAB コマンドを使ったマンデルブロ集合の実装を使用します。この実装は、電子書籍『Experiments with MATLAB』(Cleve Moler 著) で提供されているコードに基づきます。この計算はすべての場所が同時に更新されるようにベクトル化されています。

チュートリアル ファイル

次のコード行を使用して 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 スクリプトを作成します。このスクリプトは、xlimylim で指定した範囲間に実数部 (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 バージョンのマンデルブロ集合アルゴリズムをコード生成に適したものにする前に、元のコードの機能をテストできます。

  1. 現在の MATLAB 作業フォルダーを mandelbrot_count.mmandelbrot_test.m が含まれた場所に変更します。GPU Coder はこのフォルダーに生成コードを配置します。このフォルダーに対する完全なアクセス権がない場合は現在の作業フォルダーを変更してください。

  2. mandelbrot_test スクリプトを実行します。

テスト スクリプトが実行され、変数 xlim および ylim により設定された境界内のマンデルブロの幾何形状が表示されます。

コード生成用の MATLAB コードの準備

GPU Coder でコードを生成する前に、元の MATLAB コードにおけるコーディングの問題をチェックします。

設計時の問題の確認

設計時にコード生成の問題を検出するのに役立つ次の 2 つのツールがあります。

  • コード アナライザー ツール

  • コード生成の準備状態ツール

コード アナライザーは、MATLAB エディターに組み込まれたツールであり、入力されたコードを継続的にチェックします。コード アナライザーは問題を報告し、コードのパフォーマンスと保守性を最大化するための変更を提案します。MATLAB コードからのコード生成に固有の警告とエラーを識別するには、%#codegen 命令を MATLAB ファイルに追加します。詳細については、コード アナライザー基本設定を参照してください。

メモ

コード アナライザーは、コード生成の問題をすべて検出するわけではありません。コード アナライザーで検出されたエラーや警告を取り除いた後、コードに他のコンプライアンスの問題があるかどうかを確認するには、GPU Coder を使用してコードをコンパイルします。

コード生成の準備状態ツールは、コード生成でサポートされていない機能と関数について、MATLAB コードをスクリーニングします。このツールで提供されるレポートには、MATLAB コードをコード生成に適したものにするための問題と推奨事項が一覧表示されます。コード生成の準備状態ツールには次の方法でアクセスできます。

  • [現在のフォルダー] ブラウザーで、エントリポイント関数を含む MATLAB ファイルを右クリックします。

  • コマンド ラインで、関数 coder.screener() を使用します。

  • GPU Coder アプリで、エントリポイント ファイルを指定した後、コード アナライザーおよびコード生成の準備状態ツールを実行します。

コード生成時の問題の確認

GPU Coder を使用して、コード生成時の問題をチェックできます。GPU Coder によりエラーまたは警告が検出されると、問題の説明と、問題のある MATLAB コードへのリンクが用意されたエラー レポートが生成されます。詳細については、コード生成レポートを参照してください。

コード生成に適した MATLAB コードの作成

MATLAB コードをコード生成に適したものにするプロセスを始める前に、ファイル mandelbrot_count.m を使用します。

  1. MATLAB の現在のフォルダーを、このチュートリアル用のファイルが含まれた作業フォルダーに設定します。

  2. MATLAB エディターで、mandelbrot_count.m を開きます。MATLAB エディターの右上隅にあるコード アナライザー メッセージ インジケーターは緑色になっています。アナライザーは、コード内にエラー、警告、および改善機会を検出しませんでした。

  3. 関数宣言の後ろに %#codegen 命令を追加して、コード生成に固有のエラー チェックをオンにします。

    function count = mandelbrot_count(maxIterations,xGrid,yGrid) %#codegen

    コード アナライザー メッセージ インジケーターは緑色のままです。これはコード生成の問題が検出されていないことを示します。

  4. 関数 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 にマッピングしようとします。

  5. ファイルを保存します。GPU Coder アプリを使用してコードをコンパイルする準備が整いました。

GPU Coder アプリを使用したコード生成

GPU Coder アプリを開く

MATLAB ツールストリップの [アプリ] タブにある [コード生成] で、GPU Coder アプリ アイコンをクリックします。また、MATLAB コマンド ウィンドウで gpucoder と入力してもアプリを開くことができます。[ソース ファイルの選択] ページが開きます。

ソース ファイルの選択

  1. [ソース ファイルの選択] ページで、"基本" 関数 mandelbrot_count の名前を入力または選択します。基本関数は、"最上位" 関数または "エントリポイント" 関数とも呼ばれます。アプリによって、mandelbrot_count.prj という既定の名前が付いたプロジェクトが現在のフォルダーに作成されます。

  2. [次へ] をクリックして [入力の型を定義] 手順に進みます。アプリにより、コーディング問題とコード生成の準備状態について関数が解析されます。アプリで問題が特定された場合は、[コード生成の準備状態の確認] ページが開き、そこで問題を確認および修正できます。この例では、アプリは問題を検出しないため、[入力の型を定義] ページが開きます。

入力の型を定義

コード ジェネレーターはコンパイル時に MATLAB ファイル内のすべての変数のデータ型を決定しなければなりません。そのため、すべての入力変数のデータ型を指定する必要があります。入力データ型は次の 2 つの方法で指定できます。

  • プロジェクトのエントリポイント関数を呼び出すテスト ファイルを指定。GPU Coder アプリはテスト ファイルを実行することで入力引数の型を推測できます。

  • 入力の型を直接入力。

入力仕様の詳細については、入力仕様を参照してください。

この例では、入力 maxIterationsxGrid、および yGrid のプロパティを定義するために、テスト ファイル mandelbrot_test.m を指定します。

  1. テスト ファイル mandelbrot_test.m を入力または選択します。

  2. [入力の型の自動定義] をクリックします。

    テスト ファイル mandelbrot_test.m は、想定される入力の型を使用してエントリポイント関数 mandelbrot_count.m を呼び出します。アプリは入力 maxIterationsdouble(1x1) であり、入力 xGrid および yGriddouble(1000x1000) であると推測します。

  3. [次へ] をクリックして [実行時の問題の確認] 手順に進みます。

実行時の問題の確認

[実行時の問題の確認] 手順では、エントリポイント関数から MEX ファイルが生成され、MEX 関数を実行して、問題が報告されます。この手順はオプションです。ただし、この手順を実行することをお勧めします。この手順を使用して、生成された GPU コードでの診断が難しい欠陥を検出および修正できます。

この時点で、GPU Coder によって GPU 固有のチェックを実行するオプションが提供されます。このオプションを選択すると、GPU Coder は、エントリポイント関数から CUDA C コードと MEX ファイルを生成し、MEX 関数を実行して、問題を報告します。以下は GPU 固有の実行時チェックの一部です。

  • レジスタ スピルのチェック。

  • スタック サイズの適合性チェック。

メモ

コード内に存在する特定の MATLAB コンストラクトが原因で、[実行時の問題の確認] で CPU 固有のチェックに失敗しても、GPU 固有のチェックはパスする場合があります。

  1. [実行時の問題の確認] ダイアログ ボックスを開くには、[問題の確認] 矢印をクリックします。

  2. [実行時の問題の確認] ダイアログ ボックスで、テスト ファイルを指定するか、入力例を使用してエントリポイント関数を呼び出すコードを入力します。この例では、入力の型を定義するために使用したテスト ファイル mandelbrot_test.m を使用します。

  3. GPU 固有のチェックを有効にするには、[GPU] オプション ボタンを選択します。[問題の確認] をクリックします。

    アプリによって MEX 関数が生成されます。mandelbrot_count の呼び出しと生成された MEX の呼び出しを置き換えて、テスト スクリプト mandelbrot_test が実行されます。MEX 関数の生成時または実行時にアプリにより問題が検出された場合は、警告およびエラー メッセージが表示されます。これらのメッセージをクリックすると、問題のあるコードに移動して、その問題を修正できます。この例では、アプリは問題を検出しません。MEX 関数には元の関数 mandelbrot_count と同じ機能があります。

    メモ

    コード内に存在する特定の MATLAB コンストラクトが原因で、[実行時の問題の確認] で CPU 固有のチェックに失敗しても、GPU 固有のチェックはパスする場合があります。

  4. [次へ] をクリックして [コード生成] 手順に進みます。

CUDA コードの生成

  1. [生成] ダイアログ ボックスを開くには、[生成] 矢印をクリックします。

  2. [生成] ダイアログ ボックスで、GPU Coder で実行するビルドのタイプを選択できます。利用可能なオプションを次の表に示します。

    ビルド タイプ説明
    ソース コード

    外部プロジェクトと統合する CUDA C ソース コード。

    MEX

    MATLAB 内で実行するコンパイル済みコード。

    スタティック ライブラリ

    外部プロジェクトとの静的なリンクに使用されるバイナリ ライブラリ。

    ダイナミック ライブラリ

    外部プロジェクトとの動的なリンクに使用されるバイナリ ライブラリ。

    実行可能ファイル

    スタンドアロン プログラム (C で記述された個別のメイン ファイルが必要)。

    このチュートリアルでは、[ビルド タイプ][MEX(.mex)] に設定します。MEX 出力を生成することにより、生成された CUDA コードの正確性を MATLAB 内からチェックできます。MEX ビルド タイプに、[ツールチェーン][ハードウェア ボード] のような追加設定は不要です。また、ソース コードのみを生成するオプションは提供されません。環境変数が適切に設定されている限り、GPU Coder は利用可能な CUDA ツールチェーンを自動的に選択できます。

    詳細オプションを表示するには、[詳細設定] を選択します。[コンパイラ フラグ] オプションに、--fmad=false を追加します。このフラグは、nvcc に渡すと、浮動小数点積和演算 (FMAD) 最適化を無効にするようにこのコンパイラに指示します。このオプションは、CPU と GPU のアーキテクチャの違いが原因で生成コードで数値の不一致が生じることを防ぐために設定します。詳細については、CPU と GPU の数値の差を参照してください。

    次の表に、GPU Coder に固有の設定を示します。

    GPU Coder 構成プロパティ

    UI 設定値の型説明
    Kernel Name Prefix

    String

    生成コードにおけるカーネル名のカスタム名の接頭辞を指定します。たとえば、'CUDA_' と入力すると、CUDA_kernel1CUDA_kernel2 などの名前のカーネルが作成されます。名前を指定しない場合、GPU Coder によって、カーネル名の先頭にエントリポイント関数の名前が追加されます。

    カーネル名には大文字、小文字、0 ~ 9 の数字、アンダースコア文字 _ を使用できます。GPU Coder は、サポートされていない文字をカーネル名から削除し、先頭がアルファベット文字でない接頭辞には alpha を追加します。

    Malloc Mode

    Enumerated

    'Discrete'|'Unified'

    GPU メモリ割り当てのタイプを次から選択します。[Discrete] または [Unified]

    Malloc ThresholdInteger

    それを超えるとプライベート変数がスタックではなくヒープに割り当てられるようになるサイズ。

    Stack LimitInteger

    GPU スレッドあたりの利用可能なスタック。

    Enable cuSOLVER

    Boolean

    'True'|'False'

    必要に応じて、GPU Coder で cuSOLVER ライブラリの呼び出しを利用できるようにします。

    Benchmarking

    Boolean

    'True'|'False'

    cudaEvent API などのベンチマーク オプションを使用して CUDA コードを生成し、kernelmemcpy などのイベントの時間を正確に計測します。

    Safe Build

    Boolean

    'True'|'False'

    CUDA API やカーネルの呼び出しに対するエラー チェックを使用してコードを生成します。

    Minimum Compute Capability

    Enumerated

    '3.2'|'3.5'|'3.7'|'5.0'|'5.2'|'5.3'|'6.0'|'6.1'

    コード生成に最低限の Compute Capability を選択します。Compute Capability は、GPU ハードウェアでサポートされている機能を識別するものであり、現在の GPU で利用できるハードウェア機能や命令を判断するために実行時のアプリケーションで使用されます。カスタム Compute Capability を指定すると、GPU Coder はこの設定を無視します。

    Custom Compute Capability

    String

    それを対象に CUDA 入力ファイルをコンパイルしなければならない NVIDIA 仮想 GPU アーキテクチャの名前を指定します。

    たとえば、仮想アーキテクチャ タイプ -arch=compute_50 を指定します。-arch=sm_50 を使用すると、実際のアーキテクチャを指定できます。詳細については、CUDA ツールキット ドキュメンテーションの「Options for Steering GPU Code Generation」トピックを参照してください。

    Compiler Flags

    String

    GPU コンパイラに追加フラグを渡します。たとえば、--fmad=false は、nvcc コンパイラに対し、浮動小数点の乗算と加算を単一の浮動小数点積和演算 (FMAD) 命令へと縮約することを無効化するように指示します。

    類似の NVIDIA コンパイラ オプションについては、CUDA ツールキット ドキュメンテーションの「NVCC Command Options」のトピックを参照してください。

    SelectCudaDevice

    Integer

    NVIDIA Drive プラットフォームなどのマルチ GPU 環境で、ターゲットにする CUDA デバイスを指定します。

  3. [生成] をクリックします。

    GPU Coder は MEX 実行可能ファイル mandelbrot_count_mex を作業フォルダーに生成します。<pwd>\codegen\mex\mandelbrot_count フォルダーには、CUDA ソース (*.cu) ファイルおよびヘッダー ファイルを含む、他のすべての生成されたファイルが含まれます。GPU Coder アプリに、コード生成が成功したことが示されます。ページの左側には、ソース MATLAB ファイルと生成された出力ファイルが表示されます。[変数] タブには、MATLAB ソースの変数に関する情報が表示されます。[ターゲットのビルド ログ] タブには、コンパイラの警告とエラーを含むビルドのログが表示されます。既定では、アプリはコード ウィンドウに、CUDA ソース ファイル mandelbrot_count.cu を表示します。別のファイルを表示するには、[ソース コード] または [出力ファイル] ペインでファイル名をクリックします。

  4. コード生成レポートを表示するには、[レポートの表示] をクリックします。レポートには、MATLAB コードと生成された CUDA (*.cu) ファイルへのリンクが用意されています。また、MATLAB コード内の変数と式に関するコンパイル時の情報も提供されます。この情報は、エラーおよび警告の原因を探すのに役立ちます。また、コード内のコード生成の問題をデバッグすることにも役立ちます。詳細については、コード生成レポートを参照してください。

    [生成コード] タブの [GPU カーネル] セクションでは、GPU コードの生成時に作成されたカーネルの一覧が提供されます。この一覧の項目は関連するソース コードにリンクされています。たとえば、[mandelbrot_count_kernel1] をクリックすると、このカーネルのコード セクションがコード ブラウザー ウィンドウに表示されます。

    レポートの確認後、[コード生成レポート] ウィンドウを閉じることができます。後でレポートを表示するには、<pwd>\codegen\mex\mandelbrot_cout\html フォルダーにある report.mldatx を開きます。

  5. <pwd>\codegen\mex\mandelbrot_count 内には、生成された GPU コードの統計を含む gpu_codegen_info.mat MAT ファイルがあります。この MAT ファイル内には、スレッドとブロックのサイズ、共有メモリと定数メモリの使用量、および各カーネルの入力引数と出力引数に関する情報を含んだ変数 cuda_Kernel があります。変数 cudaMalloc および cudaMemcpy は、すべての GPU 変数のサイズと、ホストおよびデバイス間での memcpy 呼び出しの数に関する情報を含みます。

  6. GPU Coder アプリで、[次へ] をクリックし、[ワークフローの完了] ページを開きます。

[ワークフローの完了] ページの確認

[ワークフローの完了] ページに、コード生成が成功したことが示されます。プロジェクトの概要と、MATLAB ソース ファイル、コード生成レポート、および生成された出力バイナリへのリンクが提供されます。現在の GPU Coder プロジェクトの構成パラメーターを MATLAB スクリプトとして保存できます。MATLAB スクリプトへの MATLAB Coder プロジェクトの変換を参照してください。

生成コードの正確性の検証

生成された MEX ファイルの正確性を検証するには、生成コードの正確性の検証を参照してください。

関連するトピック