【问题标题】:The cublas function call cublasSgemvcublas 函数调用 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

标签: c cuda cublas


【解决方案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
  • 我不会去猜测你在做什么。如果您发布一个完整的、可编译的代码来打印出数字(以不同的表示法),我可以看看。
猜你喜欢
  • 2018-05-24
  • 2014-04-11
  • 1970-01-01
  • 2015-05-22
  • 2012-09-16
  • 2012-08-26
  • 2014-05-03
  • 1970-01-01
  • 2019-12-13
相关资源
最近更新 更多