2016-07-19 6 views
0

Ich bekomme einige seltsame Zahlen als Gegenleistung für einen Aufruf der cuBLAS-Bibliothek Funktion cublasSgem vom C-Host-Code. Es wird kompiliert und ausgeführt, aber Zahlen in der resultierenden Matrix sind falsch.Falsches Ergebnis Aufruf cublasSgem von einem C-Host-Code

Das Problem beim Aufrufen dieser Funktionen durch einen C-Host-Code ist, dass C-Sprache Matrizen in Zeilen-Haupt-Reihenfolge liest, während in FORTRAN cuBLAS-Funktionen geschrieben werden, die Matrizen in Spalten-Haupt-Reihenfolge lesen.

Ich habe viele Kombinationen von Parametern für die cublasSgems versucht, aber niemand scheint richtig zu funktionieren.

Ich muss Matrix moltiplication zwischen m1 und m2 durchführen, also habe ich zuerst m2 und dann m1 übergeben, also sollte die cublas Funktion (m2) T und (m1) T lesen, wo T die transponierte Form ist; dabei sollte ich als Ergebnis (r) T = (m2, m1) T erhalten. Mein C-Code schließlich lesen sollte (r) T als r, aber ich kann nicht richtig Zahlen bekommen ... hier ist der Code:

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; 
} 

Antwort

0

Das einzige, was Sie ändern müssen, ist der führende dim von r.

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

Sie könnten diese Antwort für eine detailliertere Erklärung beziehen.

Transpose matrix multiplication in cuBLAS howto

+0

Vielen Dank! Ich habe gerade einige Werte in den zwei Matrizen gespeichert und es funktioniert. Aus irgendeinem Grund kann ich nicht das gleiche Ergebnis mit zufällig generierten Floats-Matrizen erhalten, aber ich kann sagen, dass mein Ziel erreicht ist. Danke nochmal;) – davideAlbertini