4

问题很简单:我有两个矩阵 A 和 B,它们是 M 乘 N,其中 M >> N。我想先对 A 进行转置,然后将其乘以 B (A^T * B) 到将其放入 C,即 N 乘 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()将矩阵转置为 colum-major ,或者

您可以将存储在行优先的矩阵 A 视为存储在列优先的新矩阵 AT。矩阵 AT 实际上是 A 的转置。对于 B 做同样的事情。然后你可以计算存储在主要列中的矩阵 CC=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;

m在 cuBLAS 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);

请注意,您不必交换mn因为在这种情况下 C 是方阵。

于 2013-01-30T03:51:47.793 回答