代码之家  ›  专栏  ›  技术社区  ›  Ghany

使用“cuFFT设备回调”

  •  4
  • Ghany  · 技术社区  · 10 年前

    这是我的第一个问题,所以我会尽量详细。我正在CUDA 6.5中实现降噪算法。我的代码基于Matlab实现: http://pastebin.com/HLVq48C1 .
    我很想使用新的cuFFT设备回调功能,但我一直坚持 袖扣XtSetCallback 。每次我的袖扣结果是 CUFFT_NOT_已实现 (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 回复  |  直到 10 年前
        1
  •  4
  •   Robert Crovella    10 年前

    参考 documentation :

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

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

    即使你解决了这个问题,你也可能会遇到 CUFFT_LICENSE_ERROR 除非你拿到了一个评估许可证。

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

        2
  •  1
  •   Sebastian    4 年前

    一种新的(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