使用" cuFFT设备回调"

时间:2014-09-13 10:10:53

标签: c++ cuda callback nvidia cufft

这是我的第一个问题,所以我会尝试尽可能详细。我正致力于在CUDA 6.5中实现降噪算法。我的代码基于这个Matlab实现:http://pastebin.com/HLVq48C1
我喜欢使用新的cuFFT设备回拨功能,但我坚持使用 cufftXtSetCallback 。每次我的cufftResult CUFFT_NOT_IMPLEMENTED (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 个答案:

答案 0 :(得分:3)

参考documentation

  

回调API仅在静态链接的cuFFT库中可用,并且仅在64位LINUX操作系统上可用。使用此API需要当前许可证。 2015年6月30日之前,注册开发人员可以获得免费评估许可。要了解详情,请访问cuFFT developer page

我认为您收到了未实现的错误,因为您不是在Linux 64位平台上,或者您没有显式链接到CUFFT静态库。 cufft callback sample中的Makefile将提供正确的链接方法。

即使你解决了这个问题,除非你获得了一个评估许可证,否则你可能会遇到CUFFT_LICENSE_ERROR

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

答案 1 :(得分:1)

新的(2019年)可能性是cuFFT设备扩展(cuFFTDX)。作为数学库抢先体验的一部分,它们是设备FFT函数,可以内联到用户内核中。

cuFFTDX的公告:

https://developer.download.nvidia.com/video/gputechconf/gtc/2019/presentation/s9240-cuda-new-features-and-beyond.pdf

数学图书馆抢先体验:

https://developer.nvidia.com/cuda-math-library-early-access-program-page

示例代码:

https://github.com/mnicely/cufft_examples