感谢@hubs,当调用cublasSgemv时应该注意到CUBLAS_OP_T也是转置向量。 /*我正在学习cuda和cublas一个月,我想测试cublas的性能以备后用。但在使用cublasSgemv的矩阵向量乘法中,答案是错误的。 我初始化矩阵A和矢量x在行中。我送他们到设备使用cudaMemcpy,并调用该函数cublasSgemv,因为A是行重大,我使用参数CUBLAS_OP_T它调换。*/cublas函数调用cublasSgemv
//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],这是错误的。 – hubs
请提供完整的代码,包括对此函数的调用以及传递给它的所有变量。 –
正如你可以在[cublas文档](http://docs.nvidia.com/cuda/cublas/#cublas-lt-t-gt-gemv)中看到的那样,x是仅包含n(列)元素的向量如果使用'CUBLAS_OP_N'。否则它有m(行)elemens! – hubs