【问题标题】:CUBLAS works unpredictablyCUBLAS 的工作出人意料
【发布时间】:2011-12-24 09:16:06
【问题描述】:

使用 CUDA+CUBLAS 编写了我的第一个程序。它只使用 'cublasDgemm' 函数并计算 2 个 N*N 矩阵的乘积。

但是,在我启动程序的所有时间里,它一直产生相同的错误答案(例如,当将包含 5 作为单个元素的 1*1 矩阵乘以包含元素 6 的 1*1 矩阵时,它总是说结果是36,而不是 30)。 我检查了几次程序都没有成功。但是,当我在第二天(即重新启动后)回到它时,它工作得很好。我不记得我是否重新编译了它,但事实是它是同一个 VS 项目、相同的代码、具有 GPU 的同一台计算机。

那么,谁能解释一下为什么会发生这种情况?我是否必须进一步期待同样的奇怪行为?

这是我启动的代码:

#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;
}

【问题讨论】:

  • 尝试运行来自CUDA SDK 的不同样本,看看它们是否工作正常。根据我的经验,cuBLAS 本身非常稳定,因此可能会出现零星的硬件故障(它解释了为什么重启可以解决问题)。
  • 看起来你是对的..再也没有遇到过这个问题。

标签: cuda cublas


【解决方案1】:

op(B) 必须是 CUBLAS_OP_T . .

status = cublasDgemm(句柄, CUBLAS_OP_N, CUBLAS_OP_T, N, N, N, &一, devPtrA, N, devPtrB,N, &零, 开发PtrC,N); . . . . 定义为: C = α op ( A ) op ( B ) + β C http://docs.nvidia.com/cuda/cublas/index.html#topic_8_1

【讨论】:

    猜你喜欢
    • 2015-11-16
    • 2014-10-02
    • 2019-03-25
    • 2020-04-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-27
    相关资源
    最近更新 更多