问题很简单:我有两个矩阵A和B,它们是M乘N,其中M>> N.我想首先采用A的转置,然后将其乘以B(A ^ T * B)将其放入C中,即N乘N.我已为A和B设置了所有内容,但是如何做我没有给出错误的答案而正确调用了cublasSgemm?
据我所知,cuBlas有一个cublasOperation_t enum用于预先转置事物,但不知怎的,我还没有正确使用它。我的矩阵A和B按行主顺序排列,即[row1] [row2] [row3] .....在设备存储器中。这意味着A被解释为A-transposed,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怎么样?
谢谢!
答案 0 :(得分:12)
因为cuBLAS总是假设矩阵存储在列主要中。您可以使用cublas_geam()或
将矩阵首先转换为colum-major您可以将存储在行主中的矩阵A视为存储在column-major中的新矩阵AT。矩阵AT实际上是A的转置。对于B做同样的事情。然后,您可以通过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;
cuBLAS GEMM例程中的 m
和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);
如果您希望矩阵C存储在行主中,您可以使用公式CT = BT * AT^T
计算存储在列专业中的CT
cublasSgemm(handle, CUBLAS_OP_N, CUBLAS_OP_T, n, m, k, &alpha, BT, ldb, AT, lda, &beta, CT, ldc);
请注意,您不必交换m
和n
,因为在这种情况下C是方阵。