使用“cuFFT设备回调”

4
这是我的第一个问题,所以我会尽可能详细。我正在实现CUDA 6.5中的降噪算法。我的代码基于Matlab实现:http://pastebin.com/HLVq48C1
我很想使用新的cuFFT设备回调功能,但我卡在了cufftXtSetCallback上。每次我的cufftResult都是 (14)。即使nVidia提供的示例也失败了...... 我的设备回调测试代码:
__device__ void noiseStampCallback(void *dataOut,
                                size_t offset,
                                cufftComplex element,
                                void *callerInfo,
                                void *sharedPointer) {
    element.x = offset;
    element.y = 2;
    ((cufftComplex*)dataOut)[offset] = element;
}
__device__ cufftCallbackStoreC noiseStampCallbackPtr = noiseStampCallback;

我的代码中涉及到CUDA部分:

cufftHandle forwardFFTPlan;//RtC
//find how many windows there are
int batch = targetFile->getNbrOfNoiseWindows();
size_t worksize;

cufftCreate(&forwardFFTPlan);
cufftMakePlan1d(forwardFFTPlan, WINDOW, CUFFT_R2C, batch, &worksize); //WINDOW = 2048 

//host memory, allocate
float *h_wave;
cufftComplex *h_complex_waveSpec;
unsigned int m_num_real_elems = batch*WINDOW*2;
h_wave = (float*)malloc(m_num_real_elems * sizeof(float));
h_complex_waveSpec = (cufftComplex*)malloc((m_num_real_elems/2+1)*sizeof(cufftComplex));

//init
memset(h_wave, 0, sizeof(float) * m_num_real_elems); //last window won't probably be full of file data, so fill memory with 0
memset(h_complex_waveSpec, 0, sizeof(cufftComplex) * (m_num_real_elems/2+1));
targetFile->getNoiseFile(h_wave); //fill h_wave with samples from sound file

//device memory, allocate, copy from host
float *d_wave;
cufftComplex *d_complex_waveSpec;

cudaMalloc((void**)&d_wave, m_num_real_elems * sizeof(float));
cudaMalloc((void**)&d_complex_waveSpec, (m_num_real_elems/2+1) * sizeof(cufftComplex));

cudaMemcpy(d_wave, h_wave, m_num_real_elems * sizeof(float), cudaMemcpyHostToDevice);

//prepare callback
cufftCallbackStoreC hostNoiseStampCallbackPtr;

cudaMemcpyFromSymbol(&hostNoiseStampCallbackPtr,
                          noiseStampCallbackPtr,
                          sizeof(hostNoiseStampCallbackPtr));

cufftResult status = cufftXtSetCallback(forwardFFTPlan,
                                        (void **)&hostNoiseStampCallbackPtr,
                                        CUFFT_CB_ST_COMPLEX,
                                        NULL);
//always return status 14 - CUFFT_NOT_IMPLEMENTED

//run forward plan
cufftResult result = cufftExecR2C(forwardFFTPlan, d_wave, d_complex_waveSpec);
//result seems to be okay without cufftXtSetCallback

我知道我在CUDA方面只是一个初学者。我的问题是:
如何正确调用cufftXtSetCallback,或者这个错误的原因是什么?

2个回答

4

参考文档:

回调 API 仅在静态链接的 cuFFT 库中提供,且仅适用于 64 位 LINUX 操作系统。使用此 API 需要当前许可证。免费评估许可证可供注册开发人员使用,有效期至 2015 年 6 月 30 日。有关更多信息,请访问 cuFFT 开发人员页面

我认为您遇到了未实现的错误,因为您可能不在 64 位 Linux 平台上,或者没有明确链接到 CUFFT 静态库。 cufft 回调示例 中的 Makefile 将提供正确的链接方法。

即使您解决了这个问题,如果没有获取评估许可证,您也很可能遇到 CUFFT_LICENSE_ERROR

请注意,链接到 cufft 静态库还存在各种设备限制。应该可以构建一个静态链接的 CUFFT 应用程序,该应用程序将在 cc 2.0 及更高版本的设备上运行。


你说得对。我漏掉了这个笔记中的64位LINUX部分。好的,谢谢你的帮助! - Ghany
我们知道这些限制非常让人烦恼,我们正在努力在未来的版本中去除其中一些。它们存在于技术原因之中,所以需要进行一些工程处理来解决它们。请继续关注… - Jonathan Cohen
我发现这个网页对于设置静态链接代码以及获取许可证非常有帮助。该网页还表示许可证将来会被取消。http://devblogs.nvidia.com/parallelforall/cuda-pro-tip-use-cufft-callbacks-custom-data-processing/ - MrMas
我刚刚遇到了这个问题。在Cuda 7.0中,回调函数是免费的(我是不是世界上最后一个知道这个消息的人)?https://devtalk.nvidia.com/default/topic/833368/long-term-cufft-callback-licenses/ - MrMas
3
@JonathanCohen: 你知道64位Linux静态链接限制是否计划在不久的将来进行更改吗?虽然64位和静态链接并不是太大的问题,但在OS X / Windows上获得支持会很不错。 - Jason R

1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接