2011-12-24 5 views
0

A écrit mon premier programme en utilisant CUDA + CUBLAS. Il utilise simplement une fonction 'cublasDgemm' et calcule un produit de 2 matrices N * N. Cependant, tout le temps que je lançais mon programme, il continuait à produire la même mauvaise réponse (par exemple en multipliant 1 * 1 matrice contenant 5 en un seul élément par 1 * 1 matrice contenant l'élément 6, on disait toujours le résultat est 36, pas 30). J'ai vérifié le programme plusieurs fois sans succès. Mais, quand je suis revenu à lui le jour néxy (c'est-à-dire après le redémarrage), cela a très bien fonctionné. Je ne me souviens pas si je l'ai recompilé ou non, mais la vérité est que c'est le même projet VS, même code, même ordinateur avec son GPU. Alors, quelqu'un peut-il m'expliquer pourquoi cela est-il arrivé? Et dois-je m'attendre à un même comportement étrange?CUBLAS travaille de façon imprévisible

Voici le code que je lançais:

#include <iostream> 
#include <string> 
#include <iomanip> 
#include <cuda_runtime.h> 
#include <cublas_v2.h> 

const int N = 5; 
#define IDX2F(i,j) ((i) * N + j) 

void fail(const cudaError_t& cudaStatus, const std::string& errorMessage) { 
    if (cudaStatus != cudaSuccess) { 
     std::cerr << errorMessage << std::endl; 
     exit(EXIT_FAILURE); 
    } 
} 

void fail(const cublasStatus_t& status, const std::string& errorMessage) { 
    if (status != CUBLAS_STATUS_SUCCESS) { 
     std::cerr << errorMessage << std::endl; 
     exit(EXIT_FAILURE); 
    } 
} 

void printMatrix(const double *C) { 
    for (int i=0; i<N; i++) { 
     for (int j=0; j<N; j++) { 
      std::cout << std::fixed << std::setprecision(2) << C[IDX2F(i,j)] << ' '; 
     } 
     std::cout << std::endl; 
    } 
    std::cout << std::endl; 
} 

int main(int argc, char **argv) { 
    cudaError_t cudaStatus; 
    cublasStatus_t status; 
    cublasHandle_t handle; 

    double *A = new double[N*N]; 
    double *devPtrA; 

    double *B = new double[N*N]; 
    double *devPtrB; 

    double *C = new double[N*N]; 
    double *devPtrC; 

    for (int i=0; i<N; i++) 
     for (int j=0; j<N; j++) 
      A[IDX2F(i,j)] = i + j; 

    for (int i=0; i<N; i++) 
     for (int j=0; j<N; j++) 
      B[IDX2F(i,j)] = i + j * 0.5; 

    // do not have to set anything into matrix C, because beta = 0 

    // allocate mamory on GPU 
    cudaStatus = cudaMalloc((void**)&devPtrC, N*N*sizeof(*C)); 
    fail(cudaStatus, "device memory allocation failed"); 

    cudaStatus = cudaMalloc((void**)&devPtrA, N*N*sizeof(*A)); 
    fail(cudaStatus, "device memory allocation failed"); 

    cudaStatus = cudaMalloc((void**)&devPtrB, N*N*sizeof(*B)); 
    fail(cudaStatus, "device memory allocation failed"); 

    // create GPU handle 
    status = cublasCreate(&handle); 
    fail(status, "CUBLAS initialization failed"); 

    // copying matrices from host to GPU 
    status = cublasSetMatrix(N, N, sizeof (*B), B, N, devPtrB, N); 
    fail(status, "failed to load data from host to GPU"); 

    status = cublasSetMatrix(N, N, sizeof (*A), A, N, devPtrA, N); 
    fail(status, "failed to load data from host to GPU"); 

    const double ONE = 1; 
    const double ZERO = 0; 

    printMatrix(A); 
    printMatrix(B); 

    status = cublasDgemm( handle, 
          CUBLAS_OP_N, CUBLAS_OP_N, 
          N, N, N, 
          &ONE, 
          devPtrA, N, 
          devPtrB, N, 
          &ZERO, 
          devPtrC, N); 

    fail(status, "error cublasDgemm"); 

    status = cublasGetMatrix(N, N, sizeof (*C), devPtrC, N, C, N); 
    fail(status, "could not load result back from GPU to host"); 

    printMatrix(C); 

    status = cublasDestroy(handle); 
    fail(status, "could not destroy CUBLAS handle"); 

    cudaStatus = cudaFree(devPtrC); 
    fail(cudaStatus, "device memory freeing failed"); 

    cudaStatus = cudaFree(devPtrB); 
    fail(cudaStatus, "device memory freeing failed"); 

    cudaStatus = cudaFree(devPtrA); 
    fail(cudaStatus, "device memory freeing failed"); 

    delete[] C; 
    delete[] B; 
    delete[] A; 

    return EXIT_SUCCESS; 
} 
+1

Essayez d'exécuter différents échantillons de [CUDA SDK] (http://developer.nvidia.com/gpu-computing-sdk) à voir s'ils fonctionnent bien ou non. D'après mon expérience, cuBLAS lui-même est assez stable, donc il y a peut-être eu des problèmes matériels sporadiques (cela explique pourquoi le redémarrage l'a guéri). – aland

+0

On dirait que vous aviez raison .. Jamais rencontré à nouveau ce problème. – Ixanezis

Répondre

Questions connexes