cublas 函数调用 cublasSgemv
Posted
技术标签:
【中文标题】cublas 函数调用 cublasSgemv【英文标题】:The cublas function call cublasSgemv 【发布时间】:2014-02-05 12:18:30 【问题描述】:感谢@hubs,当调用 cublasSgemv 时应该注意到 CUBLAS_OP_T 也是转置向量。 /*我学习cuda和cublas一个月了,我想测试一下cublas的性能以备进一步使用。但是在我使用 cublasSgemv 的矩阵向量乘法中,答案是错误的。 我以行优先方式初始化矩阵 A 和向量 x。我使用 cudaMemcpy 将它们发送到设备,并调用函数 cublasSgemv ,因为 A 是行优先的,我使用参数 CUBLAS_OP_T 对其进行转置。*/
//the row is 50,and col is 10, A[i]=i;x[i]=1; And A matrix is row major.
//the answer I get is 45,545,.....4545,0,0,0,0,0,0,0,0,........0
int main()
int row=50;
int col=10;
int N=row*col;
float*A=new float[N];
float* y_gpu=new float[50];
for (int i=0;i<N;i++)
A[i]=(float)i;
float* x=new float[10];
for (int i=0;i<10;i++)
x[i]=1;
GpuVec(A,x,y_gpu,row,col); //call the function
for(int i=0;i<50;i++)
cout<<" "<<y_gpu[i]<<endl; //
return 0;
int GpuVec(const float* A,const float* x, float* y,const int row,const int col)
cudaError_t cudastat;
cublasStatus_t stat;
int size=row*col;
cublasHandle_t handle;
float* d_A; //device matrix
float* d_x; //device vector
float* d_y; //device result
cudastat=cudaMalloc((void**)&d_A,size*sizeof(float));
cudastat=cudaMalloc((void**)&d_x,col*sizeof(float));
cudastat=cudaMalloc((void**)&d_y,row*sizeof(float));// when I copy y to d_y ,can I cout d_y?
cudaMemcpy(d_A,A,sizeof(float)*size,cudaMemcpyHostToDevice); //copy A to device d_A
cudaMemcpy(d_x,x,sizeof(float)*col,cudaMemcpyHostToDevice); //copy x to device d_x
float alf=1.0;
float beta=0;
stat=cublasCreate(&handle);
stat=cublasSgemv(handle,CUBLAS_OP_T,col,row,&alf,d_A,col,d_x,1,&beta,d_y,1);//swap col and row
cudaMemcpy(y,d_y,sizeof(float)*row,cudaMemcpyDeviceToHost); // copy device result to host
cudaFree(d_A);
cudaFree(d_x);
cudaFree(d_y);
cublasDestroy(handle);
return 0;
【问题讨论】:
excact 是什么意思,答案是错误的?我认为您以错误的方式使用cublasSgemv
。您使用CUBLAS_OP_T
,这意味着您将使用d_A
的转置,这应该是数学错误。你有 A[col x raw] * x[col x 1] = y[row x 1] 这是错误的。
请提供完整的代码,包括对该函数的调用以及传递给它的所有变量。
正如您在cublas documentation 中所读到的,只有在使用CUBLAS_OP_N
时,x 才是由n(列)元素组成的向量。否则它有 m(行)个元素!
我编辑代码,谢谢@RobertCrovella
A[rowcol] in c。但在 cublas 中它将是 A[colrow]。所以我转置A。对吗?@hubs
【参考方案1】:
要在 cublas 中使用以行优先顺序存储的二维数组(适用于列优先顺序),您可以通过这种方式调用 gemv
。
stat = cublasSgemv(handle, CUBLAS_OP_T, col, row, &alf, d_A, col, d_x, 1, &beta, d_y, 1);
您也必须在调用中交换 m(行)和 n(列)才能执行 y = A * x
,但它允许您使用 cublas 调用而无需转置原始数组。
【讨论】:
谢谢。我复制你的代码,然后调用:cudaMemcpy(y,d_y,sizeof(float)*row,cudaMemcpyDeviceToHost);然后我 cout y[i] for i=0->row。结果的一半是 1.8628e+018,另一半是 18628035948437……我哪里出错了? 如果我只改变这一行,就像我上面写的那样,它对我有用。 我是编程新手。你认为它对我不起作用是什么? 1.8628e+018 与 18628035948437.... 相同,只是用指数表示。例如18628 = 1.8628e+004 我不会去猜测你在做什么。如果您发布一个完整的、可编译的代码来打印出数字(以不同的表示法),我可以看看。以上是关于cublas 函数调用 cublasSgemv的主要内容,如果未能解决你的问题,请参考以下文章