2013-11-09 3 views
2

Я не могу запустить cublasStrsmBatched (строка 113) без вывода CUBLAS_STATUS_EXECUTION_FAILED (13). Для упрощения все значения матрицы и alpha равны 1.0, все матрицы квадратные, а lda, ldb, m и n равны. Я могу запускать cublasSgemmBatched и cublasStrsm таким же образом, без ошибок. cublasStrsmBatched должен быть таким же, но это не так, не для меня. Скажите, пожалуйста, если у вас есть какие-либо идеи о том, что я делаю неправильно в этом коде:cublasStrsmBatched - выполнение не выполнено

#include <stdio.h> 
#include <stdlib.h> 
#include <cuda_runtime.h> 
#include <cublas_v2.h> 

cublasHandle_t handle; 

void CheckCublasCreate(cublasStatus_t status); 
void CheckAllocateHost(void* h_pointer); 
void CheckCudaMalloc(cudaError_t d_allocStatus); 
void CheckCudaMemcpy(cudaError_t error); 
void CheckCublasSetGetMatrix(cublasStatus_t status); 
void CheckKernelExecution(cublasStatus_t status); 
void CheckCublasDestroy(cublasStatus_t status); 

void TestCublasStrsmBatched(int size, int numOfLinSys); 

int main() 
{ 
    cublasStatus_t status = cublasCreate(&handle); 
    CheckCublasCreate(status); 

    /*arguments are size of square matrix 
    and number of linear systems*/ 
    TestCublasStrsmBatched(2,2); 

    status = cublasDestroy(handle); 
    CheckCublasDestroy(status); 
} 

void TestCublasStrsmBatched(int size, int numOfLinSys) 
{ 
    cublasStatus_t status; 
    cudaError_t error; 
    float **h_A; 
    float **d_A; 
    float **h_B; 
    float **d_B; 
    float **hd_A; 
    float **hd_B; 
    float *alpha; 

    const int n = size; 
    const int m = size; 
    const int lda=m; 
    const int ldb=m; 
    const int matA_numOfElem = m*m; 
    const int matB_numOfElem = m*n; 

    int i,j; 

    h_A = (float **)malloc(numOfLinSys * sizeof(float*)); 
    CheckAllocateHost(h_A); 

    h_B = (float **)malloc(numOfLinSys * sizeof(float*)); 
    CheckAllocateHost(h_B); 

    alpha=(float *)malloc(sizeof(float)); 
    *alpha = 1.0; 

    for (j=0; j<numOfLinSys; j++){ 
     h_A[j] = (float *)malloc(matA_numOfElem * sizeof(float)); 
     CheckAllocateHost(h_A); 
     for (i=0; i < matA_numOfElem; i++) 
      h_A[j][i] = 1.0; 

     h_B[j] = (float *)malloc(matB_numOfElem * sizeof(float)); 
     CheckAllocateHost(h_B); 
     for (i=0; i < matB_numOfElem; i++) 
      h_B[j][i] = 1.0; 
     } 

    hd_A = (float **)malloc(numOfLinSys * sizeof(float*)); 
    CheckAllocateHost(hd_A); 

    hd_B = (float **)malloc(numOfLinSys * sizeof(float*)); 
    CheckAllocateHost(hd_B); 

    for (j=0; j<numOfLinSys; j++){ 
     error = cudaMalloc((void **)&hd_A[j], 
          matA_numOfElem * sizeof(float)); 
     CheckCudaMalloc(error); 

     error = cudaMalloc((void **)&hd_B[j], 
          matB_numOfElem * sizeof(float)); 
     CheckCudaMalloc(error); 

     status = cublasSetMatrix(m, m, sizeof(float), 
           h_A[j], lda, hd_A[j], lda); 
     CheckCublasSetGetMatrix(status); 

     status = cublasSetMatrix(m, n, sizeof(float), 
           h_B[j], ldb, hd_B[j], ldb); 
     CheckCublasSetGetMatrix(status); 
     } 

    error = cudaMalloc((void **)&d_A, numOfLinSys * sizeof(float*)); 
    CheckCudaMalloc(error); 

    error = cudaMalloc((void **)&d_B, numOfLinSys * sizeof(float*)); 
    CheckCudaMalloc(error); 

    error = cudaMemcpy(d_A, hd_A, numOfLinSys * sizeof(float*), 
         cudaMemcpyHostToDevice); 
    CheckCudaMemcpy(error); 

    error = cudaMemcpy(d_B, hd_B, numOfLinSys * sizeof(float*), 
         cudaMemcpyHostToDevice); 
    CheckCudaMemcpy(error); 

    /*After cublasStrsmBatched call 
    status changes to CUBLAS_STATUS_EXECUTION_FAILED (13)*/ 
    status = cublasStrsmBatched(handle, 
           CUBLAS_SIDE_LEFT, CUBLAS_FILL_MODE_LOWER, 
           CUBLAS_OP_N, CUBLAS_DIAG_NON_UNIT, 
           m, n, alpha, d_A, lda, d_B, ldb, numOfLinSys); 
    CheckKernelExecution(status); 
} 


void CheckCublasCreate(cublasStatus_t status) 
{ 
    if (status != CUBLAS_STATUS_SUCCESS){ 
     fprintf(stderr, 
       "!!!! CUBLAS initialization error \n"); 
     exit(EXIT_FAILURE); 
     } 
} 

void CheckAllocateHost(void* h_pointer) 
{ 
    if (h_pointer == 0){ 
     fprintf(stderr, 
       "!!!! host memory allocation error \n"); 
     exit(EXIT_FAILURE); 
     } 
} 

void CheckCudaMalloc(cudaError_t error) 
{ 
    if (error != cudaSuccess){ 
     fprintf(stderr, 
       "!!!! device memory allocation error (error code %s)\n", 
       cudaGetErrorString(error)); 
     exit(EXIT_FAILURE); 
     } 
} 

void CheckCudaMemcpy(cudaError_t error) 
{ 
    if (error != cudaSuccess){ 
     fprintf(stderr, "!!!! data copy error (error code %s)\n", 
       cudaGetErrorString(error)); 
     exit(EXIT_FAILURE); 
     } 
} 

void CheckCublasSetGetMatrix(cublasStatus_t status) 
{ 
    if (status != CUBLAS_STATUS_SUCCESS){ 
     fprintf(stderr, "!!!! device access error \n"); 
     exit(EXIT_FAILURE); 
     } 
} 

void CheckKernelExecution(cublasStatus_t status) 
{ 
    if (status != CUBLAS_STATUS_SUCCESS){ 
     fprintf(stderr, "!!!! kernel execution error.\n"); 
     exit(EXIT_FAILURE); 
     } 
} 

void CheckCublasDestroy(cublasStatus_t status) 
{ 
    if (status != CUBLAS_STATUS_SUCCESS){ 
     fprintf(stderr, "!!!! shutdown error \n"); 
     exit(EXIT_FAILURE); 
     } 
} 

Использование Linux, CUDA 5.5, T10 и Windows, CUDA 5.5, GTX285

Спасибо!

ответ

2

Перевернутый треугольный backsolver - это то, что я не пробовал раньше в CUBLAS, поэтому мне было интересно взглянуть и посмотреть, что может произойти. Ваш код является довольно сложным, так что я не пытайтесь понять это, но когда я запустил его, оказалось, терпят неудачу с внутренним неудачным запуском CUBLAS:

$ cuda-memcheck ./a.out 
========= CUDA-MEMCHHECK 
!!!! kernel execution error. 
========= Program hit error 8 on CUDA API call to cudaLaunch 
=========  Saved host backtrace up to driver entry point at error 
=========  Host Frame:/Library/Frameworks/CUDA.framework/Versions/A/Libraries/libcuda_256.00.35.dylib (cudbgGetAPIVersion + 0x27bd7) [0x4538e7] 
=========  Host Frame:/usr/local/cuda/lib/libcudart.dylib (cudaLaunch + 0x26c) [0x45c8c] 
=========  Host Frame:/usr/local/cuda/lib/libcublas.dylib (cublasZgetrfBatched + 0x1e34) [0x196ae4] 
=========  Host Frame:/usr/local/cuda/lib/libcublas.dylib (cublasCtrsmBatched + 0x64d) [0x1974cd] 
=========  Host Frame:/usr/local/cuda/lib/libcublas.dylib (cublasCtrsmBatched + 0xacb) [0x19794b] 
=========  Host Frame:/Users/talonmies/./a.out (_Z22TestCublasStrsmBatchedii + 0x3c1) [0x1b28] 
=========  Host Frame:/Users/talonmies/./a.out (main + 0x3d) [0x1b7d] 
=========  Host Frame:/Users/talonmies/./a.out (start + 0x35) [0x14e9] 
=========  Host Frame:[0x1] 

(Это OS X машина с вычислить 1,2 GPU и CUDA 5.0). Ошибка 8 - cudaErrorInvalidDeviceFunction, которая обычно появляется только в том случае, если библиотека или fatbinary не имеют архитектуры, которая соответствует или не может быть переделана JIT во что-то, что может выполнить ваш GPU.

Заинтригованный, я написал свой собственный гораздо более простой случай REPRO с нуля:

#include <iostream> 
#include <cublas_v2.h> 

int main(void) 
{ 
    const int Neq = 5, Nrhs = 2, Nsys = 4; 

    float Atri[Neq][Neq] = 
     { { 1, 6, 11, 16, 21}, 
     { 0, 7, 12, 17, 22}, 
     { 0, 0, 13, 18, 23}, 
     { 0, 0, 0, 19, 24}, 
     { 0, 0, 0, 0, 25} }; 

    float B[Nrhs][Neq] = 
     { { 1, 27, 112, 290, 595}, 
     { 2, 40, 148, 360, 710} }; 


    float *syslhs[Nsys], *sysrhs[Nsys]; 
    float *A_, *B_, **syslhs_, **sysrhs_; 

    size_t Asz = sizeof(float) * (size_t)(Neq * Neq); 
    size_t Bsz = sizeof(float) * (size_t)(Neq * Nrhs); 

    cudaMalloc((void **)(&A_), Asz); 
    cudaMalloc((void **)(&B_), Bsz * size_t(Nsys)); 

    cudaMemcpy(A_, Atri, Asz, cudaMemcpyHostToDevice); 
    for(int i=0; i<Nsys; i++) { 
     syslhs[i] = A_; 
     sysrhs[i] = (float*)((char *)B_ + i*Bsz); 
     cudaMemcpy(sysrhs[i], B, Bsz, cudaMemcpyHostToDevice); 
    } 

    size_t syssz = sizeof(float *) * (size_t)Nsys; 
    cudaMalloc((void **)&syslhs_, syssz); 
    cudaMalloc((void **)&sysrhs_, syssz); 
    cudaMemcpy(syslhs_, syslhs, syssz, cudaMemcpyHostToDevice); 
    cudaMemcpy(sysrhs_, sysrhs, syssz, cudaMemcpyHostToDevice); 

    const cublasSideMode_t side = CUBLAS_SIDE_LEFT; 
    const cublasDiagType_t diag = CUBLAS_DIAG_NON_UNIT; 
    const cublasFillMode_t ulo = CUBLAS_FILL_MODE_LOWER; 
    const cublasOperation_t trans = CUBLAS_OP_N; 
    float alpha = 1.f; 

    cublasHandle_t handle; 
    cublasCreate(&handle); 

    cublasStrsmBatched(
       handle, 
       side, ulo, trans, diag, 
       Neq, Nrhs, 
       &alpha, 
       syslhs_, Neq, 
       sysrhs_, Neq, 
       Nsys 
       ); 


    for(int k=0; k<Nsys; k++) { 
     cudaMemcpy(B, sysrhs[k], Bsz, cudaMemcpyDeviceToHost); 
     for(int i=0; i<Nrhs; i++) { 
      for(int j=0; j<Neq; j++) { 
       std::cout << B[i][j] << ","; 
      } 
      std::cout << std::endl; 
     } 
     std::cout << std::endl; 
    } 

    return 0; 
} 

Это также не так же, как ваш код. При первой проверке это действительно кажется внутренней проблемой CUBLAS, хотя очень сложно сказать, что. Единственное, о чем я могу думать, это то, что эти решатели поддерживаются только с возможностью вычисления. 3.5 устройства не поддерживается на вычислительных устройствах 1.x, но в документации это не упоминается. Между нами мы проверили вычисление 1.2, вычислили 1.3 и вычислить 3.0 [ошибка с моей стороны, я читал K10 не T10 в вашем вопросе] устройства, поэтому осталось немного больше .....

Все, что я могу предложить, это попытаться запустить ваш код с помощью cuda-memcheck и посмотреть, сообщает ли он об одной и той же ошибке. если это произойдет, я увижу отчет об ошибке в NVIDIA в будущем.


EDIT: Я грубо игнорировал EULA и использовал cuobjdump для изучения cubin полезных нагрузок в библиотеке 5 cublas CUDA. Для одинарной точности порционный trsm процедуры я нашел cubins для

  • 32 бит sm_20
  • 32 бит sm_30
  • 32 бит sm_35
  • 64 бит sm_20
  • 64 бит sm_30
  • 64 бит sm_35

В библиотеке явно нет кубов sm_1x, поэтому мое устройство compute_12 s hould создать ошибку библиотеки времени выполнения, которую я вижу. Он также объясняет вашу ошибку с помощью GTX 285 и Telsa T10, которые являются одновременно compute_13.


EDIT2:

Как и предполагалось, мой репро код отлично работает на системе Linux с compute_30 устройства под как CUDA 5.0 и CUDA 5.5 библиотек выпуска.

+0

Да, cuda-memcheck сообщает о той же ошибке. Я должен успокоиться перед отправкой отчета об ошибке. Отправлен запрос на тест-драйв GPU. – user2971354

+0

Между тем, я хотел бы попросить, может ли кто-нибудь получить доступ к картам с возможностями 3.5, чтобы попробовать коды выше, пожалуйста. – user2971354

+0

@ user2971354: См. Мой обновленный ответ. У меня будет доступ, чтобы подтвердить это, но, похоже, нет кода для одного из ваших двух графических процессоров в библиотеке. Указанную документацию/версию следует изменить, чтобы отразить это. Завтра у меня будет доступ к карте Кеплера, поэтому я могу проверить эту гипотезу. Было бы хорошо, если бы вы могли принять этот ответ, чтобы получить его от оставшегося без ответа списка вопросов. – talonmies

Смежные вопросы