2011-12-24 1 views
0

Написал мою первую программу, используя CUDA + CUBLAS. Он просто использует функцию 'cublasDgemm' и вычисляет произведение 2 N * N матриц.CUBLAS работает непредсказуемо

Однако, все время, когда я запускал свою программу, он продолжал производить один и тот же неправильный ответ (например, при умножении матрицы 1 * 1, содержащей 5 в виде одного элемента, на матрицу 1 * 1, содержащую элемент 6, всегда указывал результат составляет 36, а не 30). Я проверил программу несколько раз без успеха. Но, когда я вернулся к нему в другой день (т. Е. После перезагрузки), он работал отлично. Я не помню, перекомпилировал ли я это или нет, но правда в том, что это тот же проект VS, тот же код, тот же компьютер с его графическим процессором.

Итак, может ли кто-нибудь объяснить мне, почему это могло произойти? И еще я должен ожидать такое же странное поведение?

Вот код, который я запускал:

#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

Попробуйте запустить различные образцы из [CUDA SDK] (http://developer.nvidia.com/gpu-computing-sdk) до посмотрите, хорошо ли они работают или нет. По моему опыту, сама cuBLAS довольно стабильна, поэтому может возникнуть спорадический аппаратный сбой (это объясняет, почему перезагрузка вылечила его). – aland

+0

Похоже, ты был прав. Никогда еще не сталкивался с этой проблемой. – Ixanezis

ответ

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