2016-07-19 11 views
0

CホストコードからcuBLASライブラリ関数cublasSgemmを呼び出したときに、奇妙な数値が得られます。コンパイルして実行しますが、結果の行列の数値は正しくありません。CホストコードでcublasSgemmを呼び出す結果が正しくない

これらの関数をCホストコードで呼び出す際の問題は、C言語が行優先順序で行列を読み込み、cuBLAS関数が列優先順序で行列を読み込むFORTRANで記述されることです。

私はcublasSgemmのパラメータの多くの組み合わせを試しましたが、誰も正しく動作していないようです。

m1とm2の間で行列の多重化を実行する必要があるので、まずm2を渡してからcublas関数が(m2)Tと(m1)Tを読み込むようにします。それによって私は結果(r)T =(m2・m1)Tとなるはずです。 私のCコードは、最終的には、Rとして(R)Tを読んでください、私は、正しい番号を取得することはできません...ここ コードです:

cudaError_t vector_matrix_molt(float *m1, float *m2, float *r, int row1, int col1, int row2, int col2) { 

    //Device Memory allocation 
    float *d_m1; 
    float *d_m2; 
    float *d_r; 
    float a = 1.0f; 
    float b = 0.0f; 
    int stride = 1; 
    //CUDA stuff 
    cublasHandle_t handle; 
    cudaError_t cudaStatus; 


    cudaStatus = cudaMalloc((void**)&d_m1, col1*row1*sizeof(float)); 
    if (cudaStatus != cudaSuccess) { 
     fprintf(stderr, "cudaMalloc failed!"); 
     goto Error; 
    } 

    cudaStatus = cudaMalloc((void**)&d_m2, row2*col2*sizeof(float)); 
    if (cudaStatus != cudaSuccess) { 
     fprintf(stderr, "cudaMalloc failed!"); 
     goto Error; 
    } 

    cudaStatus = cudaMalloc((void**)&d_r, row1*col2*sizeof(float)); 
    if (cudaStatus != cudaSuccess) { 
     fprintf(stderr, "cudaMalloc failed!"); 
     goto Error; 
    } 

    cublasCreate(&handle); 

    // Copy Data to Device Memory 
    cudaStatus = cudaMemcpy(d_m1, m1, row1*col1*sizeof(float), cudaMemcpyHostToDevice); 
    if (cudaStatus != cudaSuccess) { 
     fprintf(stderr, "cudaMemcpy 1 failed!"); 
     goto Error; 
    } 

    cudaStatus = cudaMemcpy(d_m2, m2, row2*col2*sizeof(float), cudaMemcpyHostToDevice); 
    if (cudaStatus != cudaSuccess) { 
     fprintf(stderr, "cudaMemcpy 2 failed!"); 
     goto Error; 
    } 

    /*cublasStatus_t cublasSgemm(cublasHandle_t handle, cublasOperation_t transa, cublasOperation_t transb, 
    int m, int n, int k, const float *alpha, const float *A, int lda, const float *B, int ldb, const float *beta, float *C, int ldc 
    */ 
    //Calling cuBLAS library function... 
    cublasSgemm(handle, CUBLAS_OP_N, CUBLAS_OP_N, col2, row1, col1, &a, d_m2, col2, d_m1, col1, &b, d_r, row1); 

    // Check for any errors launching the kernel 
    cudaStatus = cudaGetLastError(); 
    if (cudaStatus != cudaSuccess) { 
     fprintf(stderr, "moltKernel launch failed: %s\n", cudaGetErrorString(cudaStatus)); 
     goto Error; 
    } 

    // cudaDeviceSynchronize waits for the kernel to finish, and returns 
    // any errors encountered during the launch. 
    cudaStatus = cudaDeviceSynchronize(); 
    if (cudaStatus != cudaSuccess) { 
     fprintf(stderr, "cudaDeviceSynchronize returned error code %d after launching cublasSgemv!\n", cudaStatus); 
     //printf("Cuda Error: %s\n", cudaGetErrorString(cudaStatus)); 
     goto Error; 
    } 

    // Copy output vector from GPU buffer to host memory. 
    cudaStatus = cudaMemcpy(r, d_r, row1*col2* sizeof(float), cudaMemcpyDeviceToHost); 
    if (cudaStatus != cudaSuccess) { 
     fprintf(stderr, "cudaMemcpy 3 failed!"); 
     goto Error; 
    } 

Error: 
    cudaFree(d_m1); 
    cudaFree(d_m2); 
    cudaFree(d_r); 

    return cudaStatus; 
} 

答えて

0

を変更する必要がある唯一のものはの主要な薄暗いですr

cublasSgemm(handle, CUBLAS_OP_N, CUBLAS_OP_N, col2, row1, col1, &a, d_m2, col2, d_m1, col1, &b, d_r, col2); 

さらに詳しい説明については、この回答を参照してください。

Transpose matrix multiplication in cuBLAS howto

+0

ありがとうございます!私はちょうど2つの行列にいくつかの値を格納し、それは動作します。 何らかの理由で、ランダムに生成された浮動行列で同じ結果を得ることはできませんが、目標に達したと言えるでしょう。 もう一度おねがいします) – davideAlbertini

関連する問題