2015-12-10 15 views
0

Я хочу заменить вызов на «cblas_dgemm()» с помощью cublasDgemm(). Вот оригинал обертка из библиотеки машинного обучения Shark:Использование cuBLAS в 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 
    ); 

} 

А вот модифицированный код с помощью 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 
} 

Проблема заключается в том, когда я скомпилировать код с OpenAcc флагом, элементами матрица результатов, т.е. C, - все нули до и после выполнения ядра. Я не уверен, чего здесь не хватает. Я ценю любую помощь.

ответ

1

Похоже, что у вас есть базовая структура. Однако вам не нужны никакие скалярные переменные в директивах data или host_data. Это переменные Op *, M, N, K и ld *. Я думаю, что это, скорее всего, ваша проблема, поскольку cublasDgemm попытается разрешить эти переменные на хосте, чтобы запустить ядро.