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

コマンド ライン インターフェイスを使用したコード生成

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

学習目標

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

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

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

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

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

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

  • codegen コマンドを使用した CUDA コードの生成。

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

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

  • MATLAB

  • MATLAB Coder™

  • GPU Coder

  • C コンパイラ

  • CUDA 対応 NVIDIA® GPU

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

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

例: マンデルブロ集合

説明

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

マンデルブロ集合とは、

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

で定義された軌跡が k→∞ のときに有限の範囲内にとどまる値 z0 で構成された複素平面の領域です。マンデルブロ集合の全体的な幾何形状を図に示しています。この図には、集合の境界の外側周辺における詳しい構造を十分に示すための解像度がありません。拡大率を上げていくと、マンデルブロ集合の詳細な境界が示され、そこでは徐々に細かくなりながら細部が繰り返されていることがわかります。

アルゴリズム

このチュートリアルでは、メインのカージオイドとその左側にある 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 実装です。このチュートリアルでは後ほど、コード生成に適するようにこのファイルを変更します。

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 の現在の作業フォルダーを、前の手順で作成した 2 つのファイルが含まれた場所に変更します。GPU Coder はこのフォルダーに生成コード配置し、このフォルダーに対する完全なアクセス権がない場合は現在の作業フォルダーを変更します。

  2. MATLAB エディターで mandelbrot_test スクリプトを開きます。

  3. 実行ボタン をクリックするか、MATLAB コマンド ウィンドウに mandelbrot_test を入力して、テスト スクリプトを実行します。

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

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

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

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

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

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

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

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

  4. 関数 mandelbrot_count を CUDA カーネルにマッピングするには、元の MATLAB コードを変更し、for-loop 本体の外に coder.gpu.kernelfun プラグマを配置します。

    function count = mandelbrot_count(maxIterations, xGrid, yGrid) %#codegen
    % mandelbrot computation
    
    z0 = xGrid + 1i*yGrid;
    count = ones(size(z0));
    
    % Add Kernelfun pragma to trigger kernel creation
    coder.gpu.kernelfun;
    
    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 アプリを使用する代わりに、codegen コマンドを使用して、MATLAB 関数を CUDA と互換性のある C/C++ スタティックまたはダイナミック ライブラリ、実行可能ファイル、または MEX 関数に変換できます。

入力の型を定義

コンパイル時に、GPU Coder はエントリポイント関数のすべての入力についてデータ型を把握していなければなりません。そのため、エントリポイント関数に入力がある場合は、関数 codegen が含まれたファイルのコンパイル時にその入力のデータ型を指定する必要があります。

入力を生成してから、関数 codegen-args オプションを使用することで、GPU Coder で入力パラメーターのクラス、サイズ、および実数/複素数を特定できるようになります。関数 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 );

または、関数 coder.typeof を使用して、入力データを生成せずに、エントリポイント関数の入力のサイズ、型、および実数/複素数を指定できます。

ARGS = cell(1,1);
ARGS{1} = cell(3,1);
ARGS{1}{1} = coder.typeof(0);
ARGS{1}{2} = coder.typeof(0,[1000 1000]);
ARGS{1}{3} = coder.typeof(0,[1000 1000]);

ビルド構成

出力ファイル名、場所、タイプなどのビルド設定を構成するには、コーダー構成オブジェクトを作成しなければなりません。このオブジェクトを作成するには、関数 coder.gpuConfig を使用します。たとえば、MEX 関数の生成時に codegen で使用する coder.MexCodeConfig コード生成オブジェクトを作成するには、以下を使用します。

cfg = coder.gpuConfig('mex');

その他の利用可能なオプションは次のとおりです。

  • cfg = coder.gpuConfig('lib');、CUDA C/C++ スタティック ライブラリの生成時に codegen で使用するコード生成構成オブジェクトを作成します。

  • cfg = coder.gpuConfig('dll');、CUDA C/C++ ダイナミック ライブラリの生成時に codegen で使用するコード生成構成オブジェクトを作成します。

  • cfg = coder.gpuConfig('exe');、CUDA C/C++ 実行可能ファイルの生成時に codegen で使用するコード生成構成オブジェクトを作成します。

詳細については、coder.gpuConfig を参照してください。

各構成オブジェクトには、既定値に初期化された一連のパラメーターが伴います。ドット表記を使用して、一度に 1 つの構成オブジェクトのパラメーターの値を変更できます。次の構文を使用します。

configuration_object.property = value

次の同等のコマンド ラインを使用して、GPU Coder アプリを使用したコード生成と同じ設定を有効にすることができます。

cfg = coder.gpuConfig('mex');
cfg.GpuConfig.CompilerFlags = '--fmad=false';
cfg.GenerateReport = true;

cfg 構成オブジェクトには、MATLAB Coder と GPU Coder に共通する構成パラメーターと、GPU Coder 固有のパラメーターがあります。MATLAB コマンド ウィンドウに cfg.GpuConfig と入力することで、cfg 構成オブジェクトで利用できるすべての GPU 固有のプロパティを確認できます。

>> cfg.GpuConfig

ans = 

  config with properties:

                    Enabled: 1
                 MallocMode: 'discrete'
           KernelNamePrefix: ''
               EnableCUBLAS: 1
             EnableCUSOLVER: 1
                EnableCUFFT: 1
               Benchmarking: 0
                  SafeBuild: 0
          ComputeCapability: '3.5'
    CustomComputeCapability: ''
              CompilerFlags: ''
        StackLimitPerThread: 1024
            MallocThreshold: 200
           SelectCudaDevice: -1

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

MATLAB Coder と GPU Coder に共通する構成パラメーターの詳細については、coder.CodeConfig クラスを参照してください。

ビルド スクリプト

前述した一連のコマンドを自動化するビルド スクリプト mandelbrot_codegen.m を作成できます。

% GPU code generation for getting started example (mandelbrot_count.m)
%% Create configuration object of class 'coder.MexCodeConfig'.
cfg = coder.gpuConfig('mex');
cfg.GenerateReport = true;
cfg.GpuConfig.CompilerFlags = '--fmad=false';

%% Define argument types for entry-point 'mandelbrot_count'.
ARGS = cell(1,1);
ARGS{1} = cell(3,1);
ARGS{1}{1} = coder.typeof(0);
ARGS{1}{2} = coder.typeof(0,[1000 1000]);
ARGS{1}{3} = coder.typeof(0,[1000 1000]);

%% Invoke GPU Coder.
codegen -config cfg mandelbrot_count -args ARGS{1}

codegen コマンドはファイル mandelbrot_count.m を開き、MATLAB コードを CUDA コードに変換します。

  • -report オプションは、MATLAB コードのデバッグに使用できるコード生成レポートを生成するように codegen に指示します。

  • -args オプションは、入力パラメーター maxIterations、xGrid、および yGrid のクラス、サイズ、および実数/複素数を使用して、ファイル mandelbrot_count.m をコンパイルするように codegen に指示します。

  • -config オプションは、指定した構成オブジェクトをコード生成に使用するように codegen に指示します。

コード生成に成功したら、MATLAB コマンド ウィンドウで [レポートの表示] をクリックすることで、結果のコード生成レポートを表示できます。

>> mandelbrot_codegen
Code generation successful: View report

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

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