Main Content

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

gpucoder.stridedMatrixMultiply

ストライド バッチ行列乗算演算の最適化された GPU 実装

説明

D = gpucoder.stridedMatrixMultiply(A,B) は、行列のバッチについて、ストライド行列-行列乗算を実行します。バッチの各インスタンスの入力行列 A および B は、前のインスタンスのアドレスと同じアドレス オフセットに位置します。関数 gpucoder.stridedMatrixMultiply は次の形式の行列-行列乗算を実行します。

D=αAB

ここで、α はスカラー乗算係数、AB、および D はそれぞれ mk 列、kn 列、および mn 列の次元をもつ行列です。A および B は、転置またはエルミート共役にすることもできます。既定の設定では、α は 1 に設定され、行列は転置されません。さまざまなスカラー乗算係数を指定し、入力行列の転置演算を実行するには、Name,Value ペアの引数を使用します。

関数 gpucoder.stridedMatrixMultiply に渡されるすべてのバッチは一様でなければなりません。つまり、すべてのインスタンスは同じ次元 m,n,k でなければなりません。

___ = gpucoder.stridedMatrixMultiply(___,Name,Value) は、1 つ以上の Name,Value ペアの引数で指定されたオプションを使用することにより、ストライド バッチ行列乗算演算を実行します。

すべて折りたたむ

シンプルなバッチ行列-行列乗算を実行し、関数 gpucoder.stridedMatrixMultiply を使用して、適切な cublas<t>gemmStridedBatched API を呼び出す CUDA® コードを生成します。

1 つのファイル内に、行列入力 A および B を受け入れるエントリポイント関数 myStridedMatMul を記述します。入力行列は転置しないため、'nn' オプションを使用します。

function [D] = myStridedMatMul(A,B,alpha)

[D] = gpucoder.stridedMatrixMultiply(A,B,'alpha',alpha, ...
    'transpose','nn');

end

コード生成で使用する double の行列の型を作成するには、関数 coder.newtype を使用します。

A = coder.newtype('double',[5 4 100],[0 0]);
B = coder.newtype('double',[4 5 100],[0 0]);
alpha = 0.3;
inputs = {A,B,alpha};

CUDA ライブラリを生成するには、関数 codegen を使用します。

cfg = coder.gpuConfig('lib');
cfg.GpuConfig.EnableCUBLAS = true;
cfg.GpuConfig.EnableCUSOLVER = true;
cfg.GenerateReport = true;
codegen -config cfg-args inputs myStridedMatMul

生成された CUDA コードには、入力および出力行列を初期化するためのカーネル myStridedMatMul_kernelNN が含まれます。さらに、コードには cuBLAS ライブラリに対する cublasDgemmStridedBatched API 呼び出しも含まれます。以下のコードは、生成されたコードのスニペットです。

//
// File: myStridedMatMul.cu
//
...
void myStridedMatMul(const double A_data[], const int A_size[3], const double
                     B_data[], const int B_size[3], double alpha, double D_data[],
                     int D_size[3])
{
  double alpha1;
...
  beta1 = 0.0;
  cudaMemcpy(gpu_alpha1, &alpha1, 8ULL, cudaMemcpyHostToDevice);
  cudaMemcpy(gpu_A_data, (void *)A_data, A_size[0] * A_size[1] * A_size[2] *
             sizeof(double), cudaMemcpyHostToDevice);
  cudaMemcpy(gpu_B_data, (void *)B_data, B_size[0] * B_size[1] * B_size[2] *
             sizeof(double), cudaMemcpyHostToDevice);
  cudaMemcpy(gpu_beta1, &beta1, 8ULL, cudaMemcpyHostToDevice);
  if (D_data_dirtyOnCpu) {
    cudaMemcpy(gpu_D_data, &D_data[0], 25 * D_size[2] * sizeof(double),
               cudaMemcpyHostToDevice);
  }

  if (batchDimsA[2] >= batchDimsB[2]) {
    if (batchDimsA[2] >= 1) {
      ntilecols = batchDimsA[2];
    } else {
      ntilecols = 1;
    }
  } else {
    ntilecols = batchDimsB[2];
  }

  cublasDgemmStridedBatched(getCublasGlobalHandle(), CUBLAS_OP_N, CUBLAS_OP_N, 5,
    5, 4, (double *)gpu_alpha1, (double *)&gpu_A_data[0], 5, strideA, (double *)
    &gpu_B_data[0], 4, strideB, (double *)gpu_beta1, (double *)&gpu_D_data[0], 5,
    25, ntilecols);
  cudaMemcpy(&D_data[0], gpu_D_data, 25 * D_size[2] * sizeof(double),
             cudaMemcpyDeviceToHost);
...
}

入力引数

すべて折りたたむ

オペランド。ベクトルまたは行列として指定します。gpucoder.stridedMatrixMultiply は最初の 2 つの次元に沿って乗算します。

データ型: double | single | int8 | int16 | int32 | int64 | uint8 | uint16 | uint32 | uint64
複素数のサポート: あり

名前と値のペアの引数

オプションの引数 Name,Value のコンマ区切りペアを指定します。Name は引数名で、Value は対応する値です。Name は引用符で囲まなければなりません。Name1,Value1,...,NameN,ValueN のように、複数の名前と値のペアの引数を、任意の順番で指定できます。

例: D = gpucoder.stridedMatrixMultiply(A,B,'alpha',0.3,'transpose','CC');

A との乗算に使用されるスカラーの値。既定値は 1 です。

2 つの文字からなる文字ベクトルまたは string で、行列乗算の前に行列 A および B で実行される演算を示します。可能な値は、標準 ('N')、転置 ('T')、または複素共役転置 ('C') です。

出力引数

すべて折りたたむ

積。スカラー、ベクトル、または行列として返されます。配列 D には、入力 A と同じ数の行と、入力 B と同じ数の列があります。

R2020a で導入