9

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

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

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

4

3 回答 3

10

在 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 用户编写了这样的函数?”

于 2012-10-24T01:36:39.337 回答
2

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

根据cuBLAS 指南的第 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";
}
于 2012-10-24T01:31:15.893 回答
-1

在流行的 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)
于 2021-01-05T11:01:05.907 回答