4

問題は単純です: 私は 2 つの行列 A と B を持っています。これらは M × N であり、ここで M >> N です。最初に A の転置を取り、それを B (A^T * B) で乗算して、これを C に入れます。これは N x N です。A と B のすべてをセットアップしましたが、間違った答えを返さずに適切に cublasSgemm を呼び出すにはどうすればよいでしょうか?

cuBlas には、事前に転置するための cublasOperation_t 列挙型があることは理解していますが、どういうわけか、それを正しく使用していません。私の行列 A と B は行優先順、つまり [row1][row2][row3]..... デバイス メモリ内にあります。つまり、A が A 転置として解釈されるためには、BLAS は A が列優先順であることを認識する必要があります。私の現在のコードは以下のようになります:

float *A, *B, *C;
// initialize A, B, C as device arrays, fill them with values
// initialize m = num_row_A, n = num_row_B, and k = num_col_A;
// set lda = m, ldb = k, ldc = m;
// alpha = 1, beta = 0;
// set up cuBlas handle ...

cublasSgemm(handle, CUBLAS_OP_T, CUBLAS_OP_N, m, n, k, &alpha, A, lda, B, ldb, &beta, C, ldc);

私の質問:

m、k、n を正しく設定していますか?

lda、ldb、ldcはどうですか?

ありがとう!

4

1 に答える 1

13

cuBLASは常に、行列が列メジャーに格納されていると想定しているためです。cublas_geam()を使用して、最初に行列を列メジャーに転置するか、または

行メジャーに格納された行列Aを、列メジャーに格納された新しい行列ATとして扱うことができます。行列ATは、実際にはAの転置です。Bの場合も同じことを行います。次に、列メジャーに格納されている行列Cを計算できます。C=AT * BT^T

float* AT = A;
float* BT = B;

先頭の次元はストレージに関連するパラメーターであり、転置フラグを使用するかどうかに関係なく変更されませCUBLAS_OP_Tん。

lda = num_col_A = num_row_AT = N;
ldb = num_col_B = num_row_BT = N;
ldc = num_row_C = N;

mcuBLAS GEMMルーチンにnは、結果行列Cの#rowsと#colsがあります。

m = num_row_C = num_row_AT = num_col_A = N;
n = num_col_C = num_row_BT = num_col_B = N;

kはA^TとBの共通の次元であり、

k = num_col_AT = num_row_B = M;

次に、次の方法でGEMMルーチンを呼び出すことができます。

cublasSgemm(handle, CUBLAS_OP_N, CUBLAS_OP_T, m, n, k, &alpha, AT, lda, BT, ldb, &beta, C, ldc);

CT = BT * AT^T行列Cを行メジャーに格納する場合は、次の式を使用して列メジャーに格納されるCTを計算できます。

cublasSgemm(handle, CUBLAS_OP_N, CUBLAS_OP_T, n, m, k, &alpha, BT, ldb, AT, lda, &beta, CT, ldc);

この場合、Cは正方行列であるため、m交換する必要はないことに注意してください。n

于 2013-01-30T03:51:47.793 に答える