2

畳み込みFFTの例(大規模カーネルの場合)のNvidia SDKを見ていますが、フーリエ変換とそのFFT実装(少なくとも基本)の背後にある理論は知っていますが、次のコードが何をするのか理解できません。

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);
}

また、複素平面がそのように初期化される理由もありません。

説明リンクや回答を教えていただけますか?

4

3 に答える 3

2

次元が1024を超えない限り、FFT次元は2の次の累乗に切り上げられているように見えます。1024を超える場合は、512の次の倍数に切り上げられます。

FFTサイズを切り上げたら、もちろん、データをゼロで埋めて、FFTの正しいサイズにする必要があります。

通常、畳み込みのために切り上げてパディングする必要がある理由は、各FFT次元がである必要があるためですimage_dimension + kernel_dimension - 1。これは、通常、2の累乗などの便利な数値ではありません。

于 2011-04-01T08:47:12.587 に答える
1

@PaulRの言うことは正しいです。これは、高速フーリエ変換操作を最速で実行するには2の倍数が必要なためです。Cooley-Tukeyアルゴリズムを参照してください

2の累乗である行列を宣言していることを確認してください。その一般的な、安全な実装は必要ありません。

于 2011-04-01T08:55:01.733 に答える
-1

FFTの次元を2の累乗に切り上げ、次元が1024を超えるまで、512の倍数に切り上げます。データをゼロで埋めて、FFTの正しいサイズにする必要があります。`

于 2021-09-23T09:11:18.733 に答える