相当于 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?的主要内容,如果未能解决你的问题,请参考以下文章