Main Content

このページの翻訳は最新ではありません。ここをクリックして、英語の最新版を参照してください。

coder.gpu.kernelfun

関数を GPU カーネルにマッピングするプラグマ

説明

coder.gpu.kernelfun() は、それが配置されている関数内のすべての計算を GPU にマッピングしようとするグローバル レベルのプラグマです。この関数内のループが GPU カーネルに並列化されるのは、並列ループ解析チェックをパスした場合のみです。この解析は、すべてのループ反復が互いに依存していないことを証明しようとします。

このプラグマは入力パラメーターを必要としません。生成されるカーネルの次元は、ループ パラメーターに基づいて自動的に計算されます。

この関数はコード生成関数です。MATLAB® では効果がありません。

すべて折りたたむ

この例では、kernelfun プラグマを関数で使用し、CUDA® コードを生成する方法について説明します。

1 つのファイル内に、サイズ 1x4096 の 2 つのベクトル入力 x,y と、1 つのスカラー入力 scale を受け入れるエントリポイント関数 scalars を記述します。この関数には反復の長さが異なる 2 つの for ループがあります。1 つはベクトル加算用で、1 つは累積和を求めるためのループです。coder.gpu.kernelfun() プラグマを関数 scalars 内に配置します。

function [vout, sout1] = scalars(x,y,scale)
    coder.gpu.kernelfun;
    sout1 = 0;
    vout = coder.nullcopy(zeros(1,1024));
    
    for i=1:1024
        vout(i) = x(i) + y(i);
    end

    for i=1:4096
        sout1 = (x(i)*scale) + sout1;    
    end
end

関数 codegen を使用して CUDA MEX 関数を生成します。

codegen -config coder.gpuConfig('mex')...
 -args {ones(1,4096,'double'),ones(1,4096,'double'),coder.typeof(0)}...
 -report scalars

GPU Coder により 3 つのカーネルが作成されます。sout1=0 の初期化用の scalars_kernel1、ベクトル加算用の scalars_kernel2 に加えて、scalars_kernel3 は累積和用のリダクション カーネルです。

  scalars_kernel1<<<dim3(1U, 1U, 1U), dim3(32U, 1U, 1U)>>>(gpu_sout1);
  cudaMemcpy(gpu_y, y, 32768U, cudaMemcpyHostToDevice);
  cudaMemcpy(gpu_x, x, 32768U, cudaMemcpyHostToDevice);
  scalars_kernel2<<<dim3(2U, 1U, 1U), dim3(512U, 1U, 1U)>>>(gpu_y, gpu_x, gpu_vout);
  scalars_kernel3<<<dim3(8U, 1U, 1U), dim3(512U, 1U, 1U)>>>(scale, gpu_x, gpu_sout1);
  cudaMemcpy(vout, gpu_vout, 32768U, cudaMemcpyDeviceToHost);
  cudaMemcpy(sout1, gpu_sout1, 8U, cudaMemcpyDeviceToHost);

scalars_kernel2 には 1 ブロックあたり 512 スレッドを含む 2 つのブロック (合計 1024 スレッド) が用意され、それぞれが各要素を加算します。同様に、scalars_kernel3 には 1 ブロックあたり 512 スレッドを含む 8 つのブロックが用意され、合計では 4096 スレッドになります。GPU Coder は、関数 cudamMemcpy の呼び出しの数を最小化する最適化も実行します。この例では、入力 x のコピーが GPU 内にあるため、scalars_kernel2 および scalars_kernel3 の間に追加の cudamMemcpy は必要ありません。メモリ最適化に加えて、カーネル間の逐次コードは CUDA スレッドにマッピングされ、データが GPU 上に維持されます。

R2017b で導入