2014-01-16 4 views
2

Благодарим за @hubs, когда вызов cublasSgemv должен заметить, что CUBLAS_OP_T также является транспонированным вектором. /* Я изучаю cuda и cublas в течение месяца, и я хочу проверить работу cublas для дальнейшего использования. Но в моем умножении матрицы-вектора с использованием cublasSgemv ответ неверен. Я инициализирую матрицу A и вектор x в строке. Я послал их к устройству с помощью cudaMemcpy и вызовите функцию cublasSgemv, потому что А-строка из основных, я транспонирование его с помощью параметра 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', и это должно быть ошибочно математически. У вас есть [col x raw] * x [col x 1] = y [строка x 1], и это неправильно. – hubs

+1

, пожалуйста, предоставьте полный код, включая вызов этой функции, а также все переданные ей переменные. –

+0

Как вы можете прочитать в [cublas documentation] (http://docs.nvidia.com/cuda/cublas/#cublas-lt-t-gt-gemv), x - вектор из n (столбцов) элементов, только если используется 'CUBLAS_OP_N'. В противном случае он имеет m (ряд) элементов! – hubs

ответ

3

Чтобы использовать двумерные массивы, хранящиеся в строчном порядке в cublas (который работает с порядком столбцов), вы можете вызвать gemv таким образом.

stat = cublasSgemv(handle, CUBLAS_OP_T, col, row, &alf, d_A, col, d_x, 1, &beta, d_y, 1); 

Вы должны поменять м (строки) и п (столбцы) в вызове, тоже, чтобы выполнить y = A * x, но это позволяет использовать в cublas называют без транспозиции исходного массива.

+0

Спасибо. Я копирую ваш код и вызываю: cudaMemcpy (y, d_y, sizeof (float) * row, cudaMemcpyDeviceToHost), а затем ioutout y [i] для i = 0-> row. половина результата - 1,8628e + 018, другая половина - 18628035948437 ... Где я ошибся? – Zziggurats

+0

Если я изменю только эту строку, как я писал выше, она работает для меня. – hubs

+0

Я новичок в программировании. Как вы думаете, что он не может работать для меня? – Zziggurats