2011-04-01 7 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
그것은 차원이 1024을 초과하지 않는 경우에는 512

의 다음 배수로 반올림 것, (2) 다음 전원에 FFT 크기를 반올림 것으로 보인다

는 FFT 크기를 반올림 데 그런 다음 FFT를위한 올바른 크기가되도록 데이터를 0으로 채울 필요가 있습니다.

주 우리가 일반적으로 각 FFT 차원이 편리한 숫자가 같은 2

1

무엇을의 전력으로 일반적으로하지 않습니다 image_dimension + kernel_dimension - 1을 할 필요가 있기 때문에 반올림 및 회선에 대한 패드가 필요 @ 이유 폴 R은 정확하다고 말합니다. 그 이유는 고속 푸리에 변환 연산 은 2의 배수가 가장 빠른 속도로 실행되어야하기 때문입니다. Cooley-Tukey algorithm

을 참조하십시오. 2의 거듭 제곱이라는 매트릭스를 선언했는지 확인하고 일반 안전 구현이 필요하지 않아야합니다.

+0

모든 FFT 구현에는 2의 거듭 제곱이 필요하지 않습니다 * CUFFT는 어쨌든 512의 배수를 사용하는 더 큰 FFT 크기의 경우 2의 비 거듭력에 대처할 수 있습니다. 컨볼 루션의 경우 FFT 크기를 2의 제곱으로 할 수 없습니다. 크기는 image_dimension + kernel_dimension - 1이어야하므로 반올림 및 패딩이 필요합니다. –

+0

나는 2의 배수를 의미했습니다. 고마워. – fabrizioM

+1

@farbrizioM : 2의 배수도 2의 배수도 필요하지 않습니다. FFT는 작은 소수 (small primes)로 고려 될 수있는 임의의 크기에 대해 구현 될 수있다. FFTW는 2, 3, 5, 7의 인자로 작동합니다. –