CUFFT 错误处理
Posted
技术标签:
【中文标题】CUFFT 错误处理【英文标题】:CUFFT error handling 【发布时间】:2013-04-22 10:34:28 【问题描述】:我正在使用以下宏来处理 CUFFT 错误:
#define cufftSafeCall(err) __cufftSafeCall(err, __FILE__, __LINE__)
inline void __cufftSafeCall(cufftResult err, const char *file, const int line)
if( CUFFT_SUCCESS != err)
fprintf(stderr, "cufftSafeCall() CUFFT error in file <%s>, line %i.\n",
file, line);
getch(); exit(-1);
此宏不会从错误代码中返回消息字符串。 《CUDA 编程:使用 GPU 进行并行计算的开发人员指南》一书建议使用以下宏
#define CUDA_CALL(call) const cudaError_t err = (call); \
if(err != cudaSuccess) \
\
fprintf(stderr, "CUDA error in file '%s', line %d\n %s\nerror %d: %s\nterminating!\n",__FILE__, __LINE__,err, \
cudaGetErrorString(err)); \
cudaDeviceReset(); assert(0); \
(注意:它在没有改变功能的情况下进行了一些定制)。这本书说:“这种技术适用于所有 CUDA 调用,除了内核调用。”但是,当在 CUFFT 例程调用中使用 CUDA_CALL
时,编译器会返回
a value of type "cufftResult" cannot be used to initialize an entity of type "const cudaError_t".
看来cufftResult
和cudaError_t
并不能立即兼容。
再调查一下,从这个NVIDIA CUDA Library 链接,似乎cudaGetErrorString
需要cudaError_t
输入类型。
我的问题如下:
-
有没有办法让
cufftResult
和cudaError_t
兼容,这样我就可以在CUFFT 例程上使用CUDA_CALL
并从错误代码中接收消息字符串?
为 CUFFT 库实现不同的错误是否有任何技术原因? :-)
谢谢。
按照 ROBERT CROVELLA 的回答进行编辑
我已将 CufftSafeCall 例程修改为
inline void __cufftSafeCall(cufftResult err, const char *file, const int line)
if( CUFFT_SUCCESS != err)
fprintf(stderr, "CUFFT error in file '%s', line %d\n %s\nerror %d: %s\nterminating!\n",__FILE__, __LINE__,err, \
_cudaGetErrorEnum(err)); \
cudaDeviceReset(); assert(0); \
也返回错误类型字符串。
【问题讨论】:
【参考方案1】:cufft 不是 cuda 运行时 api 的一部分。 cufft 是一个独立的函数库。因为它是独立的,所以不要让 cufft 错误枚举依赖于 cuda 运行时 api 库是有意义的;这种联系阻碍了模块、代码和库的独立开发。
所以当书中提到 CUDA 调用时,他们指的是 cuda 运行时 api,而不是 cufft 库 api。
由于枚举值returned from cufft 库调用独立于(并且大部分正交于)枚举值returned from the cuda runtime api,我认为不可能以任何直接的方式在单个宏中协调这两个集合。而且由于 cuda 调用和 cufft 调用可能混合在任何一段代码中,我想不出一种环境方法来做到这一点。然而,其他人可能会想出一个聪明的方法。
如果你想要一个 cufft 错误枚举到字符串解析器,/usr/local/cuda/samples/common/inc/helper_cuda.h
中的一个(假设安装了标准的 linux CUDA 5)可能会感兴趣。为方便起见,将其粘贴在这里:
#ifdef _CUFFT_H_
// cuFFT API errors
static const char *_cudaGetErrorEnum(cufftResult error)
switch (error)
case CUFFT_SUCCESS:
return "CUFFT_SUCCESS";
case CUFFT_INVALID_PLAN:
return "CUFFT_INVALID_PLAN";
case CUFFT_ALLOC_FAILED:
return "CUFFT_ALLOC_FAILED";
case CUFFT_INVALID_TYPE:
return "CUFFT_INVALID_TYPE";
case CUFFT_INVALID_VALUE:
return "CUFFT_INVALID_VALUE";
case CUFFT_INTERNAL_ERROR:
return "CUFFT_INTERNAL_ERROR";
case CUFFT_EXEC_FAILED:
return "CUFFT_EXEC_FAILED";
case CUFFT_SETUP_FAILED:
return "CUFFT_SETUP_FAILED";
case CUFFT_INVALID_SIZE:
return "CUFFT_INVALID_SIZE";
case CUFFT_UNALIGNED_DATA:
return "CUFFT_UNALIGNED_DATA";
return "<unknown>";
#endif
【讨论】:
非常感谢您的回答。我已经相应地更新了我的帖子。你有什么想法?谢谢。【参考方案2】:我在我的项目中使用了以下宏:
// NOTE: include cufft to import '_cudaGetErrorEnum(cufftResult error)'
#include <cufft.h>
#include <helper_cuda.h>
#define CHECK_CUFFT_ERRORS(call) \
cufftResult_t err; \
if ((err = (call)) != CUFFT_SUCCESS) \
fprintf(stderr, "cuFFT error %d:%s at %s:%d\n", err, _cudaGetErrorEnum(err), \
__FILE__, __LINE__); \
exit(1); \
\
【讨论】:
以上是关于CUFFT 错误处理的主要内容,如果未能解决你的问题,请参考以下文章