대용량 커널 용 회귀 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);
}
도 아니고 복합 평면이 초기화되는 이유도 아닙니다.
설명 링크 나 답변을 제공해 주시겠습니까?
모든 FFT 구현에는 2의 거듭 제곱이 필요하지 않습니다 * CUFFT는 어쨌든 512의 배수를 사용하는 더 큰 FFT 크기의 경우 2의 비 거듭력에 대처할 수 있습니다. 컨볼 루션의 경우 FFT 크기를 2의 제곱으로 할 수 없습니다. 크기는 image_dimension + kernel_dimension - 1이어야하므로 반올림 및 패딩이 필요합니다. –
나는 2의 배수를 의미했습니다. 고마워. – fabrizioM
@farbrizioM : 2의 배수도 2의 배수도 필요하지 않습니다. FFT는 작은 소수 (small primes)로 고려 될 수있는 임의의 크기에 대해 구현 될 수있다. FFTW는 2, 3, 5, 7의 인자로 작동합니다. –