2015-12-10 2 views
0

Je souhaite remplacer l'appel de "cblas_dgemm()" par cublasDgemm(). Voici l'emballage d'origine de la bibliothèque d'apprentissage automatique Shark:Utilisation de cuBLAS dans OpenAcc

inline void gemm(
    CBLAS_ORDER const Order, CBLAS_TRANSPOSE TransA, CBLAS_TRANSPOSE TransB, 
    int M, int N, int K, 
    double alpha, double const *A, int lda, 
    double const *B, int ldb, 
    double beta, double *C, int ldc 
){ 

    cblas_dgemm(
     Order, TransA, TransB, 
     M, N, K, 
     alpha, 
     A, lda, 
     B, ldb, 
     beta, 
     C, ldc 
    ); 

} 

Et voici le code modifié à l'aide pragma OpenACC:

inline void gemm(
    CBLAS_ORDER const Order, CBLAS_TRANSPOSE TransA, CBLAS_TRANSPOSE TransB, 
    int M, int N, int K, 
    double alpha, double const *A, int lda, 
    double const *B, int ldb, 
    double beta, double *C, int ldc 
){ 
     #ifdef _OPENACC 
     cublasOperation_t OpT_A, OpT_B; 
      switch (TransA) 
     { 
      case CblasNoTrans: 
       OpT_A = CUBLAS_OP_N; 
       break; 
      case CblasTrans: 
       OpT_A = CUBLAS_OP_T; 
       break; 
      case CblasConjTrans: 
       OpT_A = CUBLAS_OP_C; 
       break; 
      default: 
           OpT_A = CUBLAS_OP_N; 
     } 
       switch (TransB) 
       { 
         case CblasNoTrans: 
           OpT_B = CUBLAS_OP_N; 
       break; 
         case CblasTrans: 
           OpT_B = CUBLAS_OP_T; 
       break; 
         case CblasConjTrans: 
           OpT_B = CUBLAS_OP_C; 
       break; 
         default: 
           OpT_B = CUBLAS_OP_N; 
       } 

       cublasHandle_t handle; 
       #pragma acc data copyin(OpT_A, OpT_B, M, N, K, alpha, A[0:M][0:K], lda, B[0:K][0:N], ldb, beta, ldc) copy(C[0:M][0:N]) 
         { 
           #pragma acc host_data use_device(handle,OpT_A, OpT_B, A, B, C, M, N, K, lda, ldb, ldc, alpha, beta) 
           { 
            cublasDgemm(handle,OpT_A,OpT_B,M,N,K,&alpha,A,lda,B,ldb,&beta,C,ldc); 
           } 
         } 

    #else 

    cblas_dgemm(
     Order, TransA, TransB, 
     M, N, K, 
     alpha, 
     A, lda, 
     B, ldb, 
     beta, 
     C, ldc 
    ); 
    #endif 
} 

Le problème est quand je compile le code avec le drapeau OpenACC, les éléments de la matrice des résultats, c'est-à-dire C, sont tous des zéros avant et après l'exécution du noyau. Je ne suis pas sûr de ce qui me manque ici. J'apprécie toute aide.

Répondre

1

Il semble que vous ayez la bonne structure de base. Cependant, vous n'avez besoin d'aucune des variables scalaires sur les directives data ou host_data. Ce sont les variables Op *, M, N, K et ld *. Je pense que c'est probablement votre problème, car cublasDgemm va essayer de résoudre ces variables sur l'hôte afin de lancer le noyau.