2016-06-08 20 views
0

In meinem aktuellen Projekt verwende ich CUDA mit cublasSgetrfBatched und cublasSgetriBatched, um die Inverse einer Matrix zu berechnen und das Ergebnis zurückzugeben. Während ich beim Aufrufen der ersten Funktion keine Fehlermeldung erhalte, führt der folgende Aufruf von cudaDeviceSynchronize zu Fehlercode 30: unbekannter Fehler.CUDA unbekannter Fehler nach cuBLAS Aufruf

Seltsamerweise scheint dies nur bei größeren Matrizen (n ~ 1600+) zu passieren und funktioniert gut für kleinere (n ~ 1400-). Die Speicherauslastung ist immer noch relativ klein, daher scheint dies kein Problem zu sein.

Alle Tipps oder Hilfe würde sehr geschätzt werden.

Reproduzierbare Probe

#include <string> 
#include <cuda_runtime.h> 
#include <cublas_v2.h> 
#include <conio.h> 

#define CUDA_CALL(res, str) { if (res != cudaSuccess) { printf("CUDA Error : %s : %s %d : ERR %s\n", str, __FILE__, __LINE__, cudaGetErrorName(res)); } } 
#define CUBLAS_CALL(res, str) { if (res != CUBLAS_STATUS_SUCCESS) { printf("CUBLAS Error : %s : %s %d : ERR %d\n", str, __FILE__, __LINE__, int(res)); } } 

float* d_GetInv(float* L, int n) 
{ 
    cublasHandle_t cu_cublasHandle; 
    CUBLAS_CALL(cublasCreate(&cu_cublasHandle), "Failed to initialize cuBLAS!"); 

    float** adL; 
    float** adC; 
    float* dL; 
    float* dC; 
    int* dLUPivots; 
    int* dLUInfo; 

    size_t szA = n * n * sizeof(float); 

    CUDA_CALL(cudaMalloc(&adL, sizeof(float*)), "Failed to allocate adL!"); 
    CUDA_CALL(cudaMalloc(&adC, sizeof(float*)), "Failed to allocate adC!"); 
    CUDA_CALL(cudaMalloc(&dL, szA), "Failed to allocate dL!"); 
    CUDA_CALL(cudaMalloc(&dC, szA), "Failed to allocate dC!"); 
    CUDA_CALL(cudaMalloc(&dLUPivots, n * sizeof(int)), "Failed to allocate dLUPivots!"); 
    CUDA_CALL(cudaMalloc(&dLUInfo, sizeof(int)), "Failed to allocate dLUInfo!"); 

    CUDA_CALL(cudaMemcpy(dL, L, szA, cudaMemcpyHostToDevice), "Failed to copy to dL!"); 
    CUDA_CALL(cudaMemcpy(adL, &dL, sizeof(float*), cudaMemcpyHostToDevice), "Failed to copy to adL!"); 
    CUDA_CALL(cudaMemcpy(adC, &dC, sizeof(float*), cudaMemcpyHostToDevice), "Failed to copy to adC!"); 

    CUBLAS_CALL(cublasSgetrfBatched(cu_cublasHandle, n, adL, n, dLUPivots, dLUInfo, 1), "Failed to perform LU decomp operation!"); 
    CUDA_CALL(cudaDeviceSynchronize(), "Failed to synchronize after kernel call!"); 

    CUBLAS_CALL(cublasSgetriBatched(cu_cublasHandle, n, (const float **)adL, n, dLUPivots, adC, n, dLUInfo, 1), "Failed to perform Inverse operation!"); 
    CUDA_CALL(cudaDeviceSynchronize(), "Failed to synchronize after kernel call!"); 

    float* res = (float*)malloc(szA); 

    CUDA_CALL(cudaMemcpy(res, dC, szA, cudaMemcpyDeviceToHost), "Failed to copy to res!"); 

    CUDA_CALL(cudaFree(adL), "Failed to free adL!"); 
    CUDA_CALL(cudaFree(adC), "Failed to free adC!"); 
    CUDA_CALL(cudaFree(dL), "Failed to free dL!"); 
    CUDA_CALL(cudaFree(dC), "Failed to free dC!"); 
    CUDA_CALL(cudaFree(dLUPivots), "Failed to free dLUPivots!"); 
    CUDA_CALL(cudaFree(dLUInfo), "Failed to free dLUInfo!"); 

    CUBLAS_CALL(cublasDestroy(cu_cublasHandle), "Failed to destroy cuBLAS!"); 

    return res; 
} 

int main() 
{ 
    int n = 1600; 
    float* L = (float*)malloc(n * n * sizeof(float)); 
    for(int i = 0; i < n * n; i++) 
     L[i] = ((float)rand()/(float)(RAND_MAX)) * 9.0f; 

    float* inv = d_GetInv(L, n); 

    printf("done."); 
    _getch(); 

    return 0; 
} 

Der Code wurde mit laufen:

GPU: GTX 780 3GB

CPU: i7-4790S @ 3.20 GHz

+0

unter Windows? Möglicherweise tritt ein WDDM-Timeout auf. –

+0

@Robert Crovella, danke für die schnelle Antwort! Dies scheint in der Tat das Problem gewesen zu sein und leicht durch die Anhebung der Grenze zu beheben. – at1012

Antwort