2011-04-01 51 views
2

我正在研究卷积FFT示例的Nvidia SDK(对于大内核),我知道傅里叶变换及其FFT实现背后的理论(至少是基础知识),但我不能弄清楚下面的代码做什么:CUFFT - 填充/初始化问题

const int fftH = snapTransformSize(dataH + kernelH - 1); 
const int fftW = snapTransformSize(dataW + kernelW - 1); 

....//gpu initialization code 

printf("...creating R2C & C2R FFT plans for %i x %i\n", fftH, fftW); 
     cuf ftSafeCall(cufftPlan2d(&fftPlanFwd, fftH, fftW, CUFFT_R2C)); 
     cufftSafeCall(cufftPlan2d(&fftPlanInv, fftH, fftW, CUFFT_C2R)); 

    printf("...uploading to GPU and padding convolution kernel and input data\n"); 
     cutilSafeCall(cudaMemcpy(d_Kernel, h_Kernel, kernelH * kernelW * sizeof(float), cudaMemcpyHostToDevice)); 
     cutilSafeCall(cudaMemcpy(d_Data, h_Data, dataH * dataW * sizeof(float), cudaMemcpyHostToDevice)); 
     cutilSafeCall(cudaMemset(d_PaddedKernel, 0, fftH * fftW * sizeof(float))); 
     cutilSafeCall(cudaMemset(d_PaddedData, 0, fftH * fftW * sizeof(float))); 

     padKernel(
      d_PaddedKernel, 
      d_Kernel, 
      fftH, 
      fftW, 
      kernelH, 
      kernelW, 
      kernelY, 
      kernelX 
     ); 

     padDataClampToBorder(
      d_PaddedData, 
      d_Data, 
      fftH, 
      fftW, 
      dataH, 
      dataW, 
      kernelH, 
      kernelW, 
      kernelY, 
      kernelX 
     ); 

我从来没有使用CUFFT库之前,所以我不知道是什么snapTransformSize确实

(这里的代码)

int snapTransformSize(int dataSize){ 
    int hiBit; 
    unsigned int lowPOT, hiPOT; 

    dataSize = iAlignUp(dataSize, 16); 

    for(hiBit = 31; hiBit >= 0; hiBit--) 
     if(dataSize & (1U << hiBit)) break; 

    lowPOT = 1U << hiBit; 
    if(lowPOT == dataSize) 
     return dataSize; 

    hiPOT = 1U << (hiBit + 1); 
    if(hiPOT <= 1024) 
     return hiPOT; 
    else 
     return iAlignUp(dataSize, 512); 
} 

也不是为什么复杂的飞机是这样初始化的。

您能否提供给我解释链接或答案?

回答

2

这似乎是四舍五入的FFT尺寸为2的下一个动力,除非尺寸将超过1024个,在这种情况下,它调高至512

下一个倍数已经围捕FFT的大小那么你当然需要用零填充你的数据,使它成为FFT的正确大小。

需要注意的是,我们通常需要围捕和垫卷积是因为每个FFT尺寸必须image_dimension + kernel_dimension - 1,这通常不是一个方便的数,如2

1

什么动力@原因保罗R说是正确的。为什么这样做是因为快速傅里叶变换操作 需要以最快的速度执行两个倍数。请参阅Cooley-Tukey algorithm

只要确保您声明的矩阵是2的幂,并且您不应该需要该通用安全实现。

+0

对于所有的FFT实现来说,2的幂不是必须的,看起来CUFFT可以处理更大的FFT大小的2的非幂次,反之它使用512的倍数。对于卷积,通常不能使FFT大小为2的幂,因为尺寸需要是image_dimension + kernel_dimension - 1,因此需要舍入和填充。 – 2011-04-01 08:59:59

+0

我的意思是两个倍数。更正了谢谢。 – fabrizioM 2011-04-01 09:05:47

+1

@farbrizioM:2的倍数和2的倍数都不是必需的。 FFT可以用于任何可以分解成小素数的大小,例如, FFTW的工作因子为2,3,5,7。 – 2011-04-01 09:51:26