【发布时间】:2018-07-30 05:25:00
【问题描述】:
对于大小为 4x3 和 2x3 的两个矩阵 X 和 Q 记忆中的样子
x = [0 1 2 3 4 5 6 7 8 9 10 11]
q = [3 4 5 6 7 8]
我尝试使用 cublas 乘法 cublasSgemm,但无法获得预期的结果。
因为它们以行优先顺序存储,所以它们应该被解释为 3x4 和 3x2,所以对我来说似乎
cublasSgemm(cublas_handle,
CUBLAS_OP_T, CUBLAS_OP_N,
q_rows_num, x_rows_num, dim,
&alpha, // 1
q_device, q_rows_num,
x, x_rows_num,
&beta, // 0
x_q_multiplication, q_rows_num);
在哪里
dim = 3
x_rows_num = 4
q_rows_num = 2
会起作用,但在那种情况下我会出错
** On entry to SGEMM parameter number 8 had an illegal value
我也尝试过改组参数,但找不到任何可行的设置。
那么是否可以在不改变列优先顺序的情况下将它们相乘?
编辑:
所以我在这个工作示例中所做的更改得到了预期的结果:
#include <cublas_v2.h>
#include <iostream>
#include <cuda.h>
#include <cuda_runtime.h>
int main()
{
int x_rows_num = 4;
int q_rows_num = 2;
int dim = 3;
int N = x_rows_num*dim;
int M = q_rows_num*dim;
float *x, *q, *x_q_multiplication;
cudaMallocManaged(&x, N*sizeof(float));
cudaMallocManaged(&q, M*sizeof(float));
cudaMallocManaged(&x_q_multiplication, q_rows_num*x_rows_num*dim);
for (int i = 0; i< N; i++) x[i] = i*1.0f;
for (int i = 0; i< M; i++) q[i] = (i + 3)*1.0f;
float *q_device;
cudaMallocManaged(&q_device, M*sizeof(float));
cudaMemcpy(q_device, q, M*sizeof(float), cudaMemcpyHostToDevice);
cublasHandle_t handle;
cublasCreate(&handle);
float alpha = 1.f;
float beta = 0.f;
cublasSgemm(handle,
CUBLAS_OP_T, CUBLAS_OP_N,
x_rows_num, q_rows_num, dim,
&alpha,
x, dim,
q, dim,
&beta,
x_q_multiplication, x_rows_num);
cudaDeviceSynchronize();
for (int i = 0; i < q_rows_num*x_rows_num; i++) std::cout << x_q_multiplication[i] << " ";
cudaFree(x);
cudaFree(q);
cudaFree(x_q_multiplication);
return 0;
}
但我仍然不确定为什么 dim 成为主要维度
【问题讨论】:
-
cublasSgemm(cublas_handle, CUBLAS_OP_T, CUBLAS_OP_N, q_rows_num, x_rows_num, dim, &alpha, q_device, dim, x, dim, &beta, x_q_multiplication, q_rows_num);工作,但我不知道为什么,我认为前导 dim 将始终是原始行数。 -
@RobertCrovella 关于您的第一条评论我在原始帖子中附上了示例,并更改了前导维度。关于您的第二条评论,我感到有些冒犯,因为正如您在原始示例(cublasSgemm 执行)中看到的那样,我想乘以 q^t * x 并且对 cublas 的解释是 2x3 * 3x4 矩阵乘法,但您似乎停止阅读在它之前。我还认为,很明显,预期结果只是以任何顺序乘法的结果。