2014-01-16 47 views
2

感谢@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; 

}

+0

什么excact意味着,答案是错误的?我认为你以错误的方式使用'cublasSgemv'。你使用'CUBLAS_OP_T',这意味着你将使用'd_A'的转置,这应该是数学错误的。你有A [col x raw] * x [col x 1] = y [row x 1],这是错误的。 – hubs

+1

请提供完整的代码,包括对此函数的调用以及传递给它的所有变量。 –

+0

正如你可以在[cublas文档](http://docs.nvidia.com/cuda/cublas/#cublas-lt-t-gt-gemv)中看到的那样,x是仅包含n(列)元素的向量如果使用'CUBLAS_OP_N'。否则它有m(行)elemens! – hubs

回答

3

若要使用在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调用而不调换原始数组。

+0

谢谢。我复制你的代码,然后调用:cudaMemcpy(y,d_y,sizeof(float)* row,cudaMemcpyDeviceToHost);然后我为我= 0->行输出y [i]。一半的结果是1.8628e + 018,另一半是18628035948437 ......我哪里出错了? – Zziggurats

+0

如果我只改变这一行,就像我上面写的那样,它适用于我。 – hubs

+0

我是编程新手。你认为它不适合我吗? – Zziggurats