【发布时间】: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