相当于 cuBLAS 的 cudaGetErrorString?

Posted

技术标签:

【中文标题】相当于 cuBLAS 的 cudaGetErrorString?【英文标题】:Equivalent of cudaGetErrorString for cuBLAS? 【发布时间】:2012-10-14 00:45:43 【问题描述】:

CUDA 运行时有一个方便的函数cudaGetErrorString(cudaError_t error),它将错误枚举转换为可读字符串。 cudaGetErrorString 用于CUDA_SAFE_CALL(someCudaFunction()) 宏中,许多人使用它来处理 CUDA 错误。

我现在正在熟悉 cuBLAS,我想为 cuBLAS 创建一个类似于 CUDA_SAFE_CALL 的宏。为了使我的宏打印输出有用,我想在 cuBLAS 中有类似于 cudaGetErrorString 的东西。

cuBLAS 中是否有 cudaGetErrorString() 的等价物?或者,有没有 cuBLAS 用户写过这样的函数?

【问题讨论】:

【参考方案1】:

在 CUDA 5.0 中,假设您安装了示例,有一个文件 ..../samples/common/inc/helper_cuda.h 包含以下内容:

#ifdef CUBLAS_API_H_
// cuBLAS API errors
static const char *_cudaGetErrorEnum(cublasStatus_t error)

    switch (error)
    
        case CUBLAS_STATUS_SUCCESS:
            return "CUBLAS_STATUS_SUCCESS";

        case CUBLAS_STATUS_NOT_INITIALIZED:
            return "CUBLAS_STATUS_NOT_INITIALIZED";

        case CUBLAS_STATUS_ALLOC_FAILED:
            return "CUBLAS_STATUS_ALLOC_FAILED";

        case CUBLAS_STATUS_INVALID_VALUE:
            return "CUBLAS_STATUS_INVALID_VALUE";

        case CUBLAS_STATUS_ARCH_MISMATCH:
            return "CUBLAS_STATUS_ARCH_MISMATCH";

        case CUBLAS_STATUS_MAPPING_ERROR:
            return "CUBLAS_STATUS_MAPPING_ERROR";

        case CUBLAS_STATUS_EXECUTION_FAILED:
            return "CUBLAS_STATUS_EXECUTION_FAILED";

        case CUBLAS_STATUS_INTERNAL_ERROR:
            return "CUBLAS_STATUS_INTERNAL_ERROR";
    

    return "<unknown>";

#endif

在以前版本的 CUDA SDK(示例)中可能有类似的东西。如果您问这个问题,这不是回答“内置的东西”的问题,而是回答您的问题“是否有任何 cuBLAS 用户编写了这样的函数?”

【讨论】:

太棒了!我最终在我的回答中自己编写了大致相同的代码。 :) 据我所知,没有这样的功能。我建议通过 NVIDIA 错误报告系统提交功能请求(称为 RFE = 增强请求)。【参考方案2】:

我仍然很好奇 cuBLAS 中是否有内置的方法来获取错误字符串,但我现在自己写了

根据cuBLAS Guide 的第 8.1 节,cuBLAS 中只有 8 种类型的 cublasError_t 值。 我把它们打印出来了……

printf("CUBLAS_STATUS_SUCCESS = %d \n", CUBLAS_STATUS_SUCCESS);
printf("CUBLAS_STATUS_NOT_INITIALIZED = %d \n", CUBLAS_STATUS_NOT_INITIALIZED);
printf("CUBLAS_STATUS_ALLOC_FAILED = %d \n", CUBLAS_STATUS_ALLOC_FAILED);
printf("CUBLAS_STATUS_INVALID_VALUE = %d \n", CUBLAS_STATUS_INVALID_VALUE);
printf("CUBLAS_STATUS_ARCH_MISMATCH = %d \n", CUBLAS_STATUS_ARCH_MISMATCH);
printf("CUBLAS_STATUS_MAPPING_ERROR = %d \n", CUBLAS_STATUS_MAPPING_ERROR);
printf("CUBLAS_STATUS_EXECUTION_FAILED = %d \n", CUBLAS_STATUS_EXECUTION_FAILED);
printf("CUBLAS_STATUS_INTERNAL_ERROR = %d \n", CUBLAS_STATUS_INTERNAL_ERROR);

打印输出:

CUBLAS_STATUS_SUCCESS = 0 
CUBLAS_STATUS_NOT_INITIALIZED = 1 
CUBLAS_STATUS_ALLOC_FAILED = 3 
CUBLAS_STATUS_INVALID_VALUE = 7 
CUBLAS_STATUS_ARCH_MISMATCH = 8 
CUBLAS_STATUS_MAPPING_ERROR = 11 
CUBLAS_STATUS_EXECUTION_FAILED = 13 
CUBLAS_STATUS_INTERNAL_ERROR = 14

获取 cuBLAS 错误字符串的函数:

const char* cublasGetErrorString(cublasStatus_t status)

    switch(status)
    
        case CUBLAS_STATUS_SUCCESS: return "CUBLAS_STATUS_SUCCESS";
        case CUBLAS_STATUS_NOT_INITIALIZED: return "CUBLAS_STATUS_NOT_INITIALIZED";
        case CUBLAS_STATUS_ALLOC_FAILED: return "CUBLAS_STATUS_ALLOC_FAILED";
        case CUBLAS_STATUS_INVALID_VALUE: return "CUBLAS_STATUS_INVALID_VALUE"; 
        case CUBLAS_STATUS_ARCH_MISMATCH: return "CUBLAS_STATUS_ARCH_MISMATCH"; 
        case CUBLAS_STATUS_MAPPING_ERROR: return "CUBLAS_STATUS_MAPPING_ERROR";
        case CUBLAS_STATUS_EXECUTION_FAILED: return "CUBLAS_STATUS_EXECUTION_FAILED"; 
        case CUBLAS_STATUS_INTERNAL_ERROR: return "CUBLAS_STATUS_INTERNAL_ERROR"; 
    
    return "unknown error";

【讨论】:

您的cublasGetErrorString非常糟糕的编程习惯。您永远不应该按值引用枚举,而只能按名称引用。使用枚举的全部意义在于将值抽象出来。 NVIDIA 明天可能会决定更改枚举的值,您的代码将会中断,而 this code 不会。【参考方案3】:

按照流行的 gpuErrchk 解决方案what-is-the-canonical-way-to-check-for-errors-using-the-cuda-runtime-api,我使用 cuBLAS 替代方案重载了该函数,以处理 cuBLAS 错误。然后,您可以像往常一样使用 gpuErrchk 轻松包装您的 cuBLAS 函数调用。

从其他人提到的 helper_cuda.h 文件来看,继续为其他 cuda 库(cuFFT 等)添加重载函数会很容易。希望这可以帮助某人。请告诉我是否有更好的方法!

inline void error::gpuAssert(cudaError_t code, const char *file, int line, bool abort=true) const

    if (code != cudaSuccess)
    
        fprintf(stderr,"GPUassert: %s %s %d\n", cudaGetErrorString(code), file, line);
        if (abort) exit(code);
    


inline void error::gpuAssert(cublasStatus_t code, const char *file, int line, bool abort=true) const

    if (code != CUBLAS_STATUS_SUCCESS)
    
        switch (code) 
            case CUBLAS_STATUS_NOT_INITIALIZED:
            fprintf(stderr, "cuBLAS Error: CUBLAS_STATUS_NOT_INITIALIZED file: %s line: %d ", file, line);
            break; 
            
            case CUBLAS_STATUS_ALLOC_FAILED:
            fprintf(stderr, "cuBLAS Error: CUBLAS_STATUS_ALLOC_FAILED file: %s line: %d ", file, line); 
            break; 

            case CUBLAS_STATUS_INVALID_VALUE:
            fprintf(stderr, "cuBLAS Error: CUBLAS_STATUS_INVALID_VALUE file: %s line: %d ", file, line); 
            break; 

            case CUBLAS_STATUS_ARCH_MISMATCH:
            fprintf(stderr, "cuBLAS Error: CUBLAS_STATUS_ARCH_MISMATCH file: %s line: %d ", file, line); 
            break; 

            case CUBLAS_STATUS_MAPPING_ERROR:
            fprintf(stderr, "cuBLAS Error: CUBLAS_STATUS_MAPPING_ERROR file: %s line: %d ", file, line); 
            break; 

            case CUBLAS_STATUS_EXECUTION_FAILED:
            fprintf(stderr, "cuBLAS Error: CUBLAS_STATUS_EXECUTION_FAILED file: %s line: %d ", file, line); 
            break; 

            case CUBLAS_STATUS_INTERNAL_ERROR:
            fprintf(stderr, "cuBLAS Error: CUBLAS_STATUS_INTERNAL_ERROR file: %s line: %d ", file, line); 
            break; 

            case CUBLAS_STATUS_NOT_SUPPORTED:
            fprintf(stderr, "cuBLAS Error: CUBLAS_STATUS_NOT_SUPPORTED file: %s line: %d ", file, line); 
            break; 

            case CUBLAS_STATUS_LICENSE_ERROR:
            fprintf(stderr, "cuBLAS Error: CUBLAS_STATUS_LICENSE_ERROR file: %s line: %d ", file, line); 
            break; 
        
        if (abort) exit(code);
    


#define gpuErrchk(ans)  gpuAssert((ans), __FILE__, __LINE__); 

示例输出:

 ** On entry to SGEMM  parameter number 13 had an illegal value
cuBLAS Error: CUBLAS_STATUS_INVALID_VALUE file: ../src/XX.cu line: 323 Segmentation fault (core dumped)

【讨论】:

以上是关于相当于 cuBLAS 的 cudaGetErrorString?的主要内容,如果未能解决你的问题,请参考以下文章

cublas如何实现异步标量变量传输

cublas相关的知识

如何使用 CUBLAS 对复数执行 Hadamard 乘积?

异步 cuBLAS 调用

cublas 函数的重叠输入和输出

Cublas - 列/行明智的操作