我将以下宏用于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".


看来cufftResultcudaError_t不立即兼容。

通过此NVIDIA CUDA Library链接进行更多调查,看来cudaGetErrorString需要输入cudaError_t输入类型。

我的问题如下:


有没有办法使cufftResultcudaError_t兼容,以便我可以在CUFFT例程上使用CUDA_CALL并从错误代码接收消息字符串?
有任何技术原因为什么要为CUFFT库实现不同的错误? :-)


谢谢。

编辑罗伯特·克罗韦拉的回答

我已经将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); \
}


}

还返回错误类型字符串。

最佳答案

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

08-25 06:42