2011-04-05 18 views
6

CUDA के साथ मैट्रिक्स गुणा को लागू करने के बाद। मैंने इसे CUBLAS के साथ कार्यान्वित करने की कोशिश की (मंच में कुछ लोगों की सलाह के लिए धन्यवाद)।CUBLAS मैट्रिक्स गुणा

मैं वर्ग मैट्रिक्स गुणा कर सकता हूं लेकिन (हाँ एक बार फिर ...) मुझे गैर स्क्वायर मैट्रिस के साथ काम करने में कठिनाइयों का सामना करना पड़ रहा है। एकमात्र प्रकार का गैर स्क्वायर मैट्रिक्स गुणा जो काम करता है वह तब होता है जब आप मैट्रिक्स ए की चौड़ाई (ए * बी = सी) बदलते हैं।

मुझे कोई त्रुटि नहीं मिलती है लेकिन परिणामी मैट्रिक्स गलत मान देता है। यहां मेरा कोड है (यह मूल रूप से सरल क्यूबला एसडीके उदाहरण का अनुकूलन है):

#include <stdlib.h> 
#include <stdio.h> 
#include "cublas.h" 
#define HA 2 
#define WA 9 
#define WB 2 
#define HB WA 
#define WC WB 
#define HC HA 
#define index(i,j,ld) (((j)*(ld))+(i)) 

void printMat(float*P,int uWP,int uHP){ 
//printf("\n %f",P[1]); 
int i,j; 
for(i=0;i<uHP;i++){ 

    printf("\n"); 

    for(j=0;j<uWP;j++) 
     printf("%f ",P[index(i,j,uHP)]); 
     //printf("%f ",P[i*uWP+j]); 
} 
} 




int main (int argc, char** argv) { 
    cublasStatus status; 
     int i,j; 
     cublasInit(); 

     float *A = (float*)malloc(HA*WA*sizeof(float)); 
     float *B = (float*)malloc(HB*WB*sizeof(float)); 
     float *C = (float*)malloc(HC*WC*sizeof(float)); 
    if (A == 0) { 
     fprintf (stderr, "!!!! host memory allocation error (A)\n"); 
     return EXIT_FAILURE; 
    } 
    if (B == 0) { 
     fprintf (stderr, "!!!! host memory allocation error (A)\n"); 
     return EXIT_FAILURE; 
    } 
    if (C == 0) { 
     fprintf (stderr, "!!!! host memory allocation error (A)\n"); 
     return EXIT_FAILURE; 
     } 


     for (i=0;i<HA;i++) 
    for (j=0;j<WA;j++) 
     A[index(i,j,HA)] = (float) index(i,j,HA); 
     for (i=0;i<HB;i++) 
    for (j=0;j<WB;j++) 
     B[index(i,j,HB)] = (float) index(i,j,HB); 
    /* 
    for (i=0;i<HA*WA;i++) 
    A[i]=(float) i; 
    for (i=0;i<HB*WB;i++) 
    B[i]=(float) i;   */ 


     float* AA; float* BB; float* CC; 

    /*ALLOCATE ON THE DEVICE*/ 
    status=cublasAlloc(HA*WA,sizeof(float),(void**)&AA); 
     if (status != CUBLAS_STATUS_SUCCESS) { 
     fprintf (stderr, "!!!! device memory allocation error (A)\n"); 
     return EXIT_FAILURE; 
     } 

     status=cublasAlloc(HB*WB,sizeof(float),(void**)&BB); 
     if (status != CUBLAS_STATUS_SUCCESS) { 
     fprintf (stderr, "!!!! device memory allocation error (A)\n"); 
     return EXIT_FAILURE; 
     } 

     status=cublasAlloc(HC*WC,sizeof(float),(void**)&CC); 
     if (status != CUBLAS_STATUS_SUCCESS) { 
     fprintf (stderr, "!!!! device memory allocation error (A)\n"); 
     return EXIT_FAILURE; 
     } 

    /*SET MATRIX*/ 
     status=cublasSetMatrix(HA,WA,sizeof(float),A,HA,AA,HA); 
     if (status != CUBLAS_STATUS_SUCCESS) { 
     fprintf (stderr, "!!!! device memory allocation error (A)\n"); 
     return EXIT_FAILURE; 
     } 

     status=cublasSetMatrix(HB,WB,sizeof(float),B,HB,BB,HB); 
     if (status != CUBLAS_STATUS_SUCCESS) { 
     fprintf (stderr, "!!!! device memory allocation error (A)\n"); 
     return EXIT_FAILURE; 
     } 

    /*KERNEL*/ 
     cublasSgemm('n','n',HA,WB,WA,1,AA,HA,BB,HB,0,CC,HC); 

     status = cublasGetError(); 
     if (status != CUBLAS_STATUS_SUCCESS) { 
     fprintf (stderr, "!!!! kernel execution error.\n"); 
     return EXIT_FAILURE; 
     } 
     cublasGetMatrix(HC,WC,sizeof(float),CC,HC,C,HC); 
     if (status != CUBLAS_STATUS_SUCCESS) { 
     fprintf (stderr, "!!!! device read error (A)\n"); 
     return EXIT_FAILURE; 
     } 


    /* PERFORMANCE OUTPUT*/ 

    printf("\nMatriz A:\n"); 
    printMat(A,WA,HA); 
    printf("\nMatriz B:\n"); 
    printMat(B,WB,HB); 
    printf("\nMatriz C:\n"); 
    printMat(C,WC,HC); 

     free(A); free(B); free (C); 
     status = cublasFree(AA); 
     if (status != CUBLAS_STATUS_SUCCESS) { 
     fprintf (stderr, "!!!! memory free error (A)\n"); 
     return EXIT_FAILURE; 
     } 
     status = cublasFree(BB); 
     if (status != CUBLAS_STATUS_SUCCESS) { 
     fprintf (stderr, "!!!! memory free error (B)\n"); 
     return EXIT_FAILURE; 
     } 
     status = cublasFree(CC); 
     if (status != CUBLAS_STATUS_SUCCESS) { 
     fprintf (stderr, "!!!! memory free error (C)\n"); 
    return EXIT_FAILURE; 
    } 

     /* Shutdown */ 
     status = cublasShutdown(); 
     if (status != CUBLAS_STATUS_SUCCESS) { 
     fprintf (stderr, "!!!! shutdown error (A)\n"); 
     return EXIT_FAILURE; 
     } 

    if (argc > 1) { 
     if (!strcmp(argv[1], "-noprompt") ||!strcmp(argv[1], "-qatest")) 
     { 
    return EXIT_SUCCESS; 
     } 
     } 
     else 
     { 
      printf("\nPress ENTER to exit...\n"); 
      getchar(); 
     } 

return EXIT_SUCCESS; 


    } 

कोई विचार? साथ ही, क्या किसी के पास काम करने वाले कूब्स में मैट्रिक्स गुणा कार्यान्वयन है, इसलिए मैं तुलना कर सकता हूं? अग्रिम में धन्यवाद।

+0

cuBLAS 'dgemm' उदाहरण के लिए +1 :-) – fommil

उत्तर

7

मुझे समझ में नहीं आता कि आपको लगता है कि आपके द्वारा पोस्ट किया गया कोड काम क्यों नहीं करता है। जब मैं संकलित करता हूं और इसे चलाता हूं, परिणामी निष्पादन योग्य उसी आउटपुट का उत्पादन करता है जो मुझे मिलता है यदि मैं मैटलैब में एक ही मैट्रिस दर्ज करता हूं और उनके उत्पाद की गणना करता हूं।

कब्ला एक फोरट्रान ब्लैस है, यह कॉलम प्रमुख क्रम में इनपुट की अपेक्षा करता है (और आपका कोड कॉलम प्रमुख आदेश दिया गया है)। यदि परिणाम आप जो चाहते हैं उससे मेल नहीं खाते हैं, तो आपको कहीं भी कॉलम और पंक्ति प्रमुख आदेश को भ्रमित करना होगा।

+0

आप बिल्कुल सही थे;)। मुझे पहले MATLAB (कॉलम प्रमुख) के साथ काम करना पड़ा, लेकिन मुझे कभी भी पंक्ति प्रमुख और कॉलम प्रमुख ऑर्डरिंग के बीच भेद नहीं करना पड़ा – Bernardo

संबंधित मुद्दे