CUFFT - вопрос заполнения/инициализации

Я просматриваю Nvidia SDK для примера свертки FFT (для больших ядер), я знаю теорию преобразований Фурье и их реализации 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);
}

ни почему сложная плоскость такая инициализированная.

Можете ли вы предоставить мне пояснительные ссылки или ответы, пожалуйста?


person Marco A.    schedule 01.04.2011    source источник


Ответы (2)


Кажется, что он округляет размеры БПФ до следующей степени 2, если только размер не превышает 1024, и в этом случае он округляется до следующего кратного 512.

Округлив размер БПФ, вам, конечно, нужно дополнить свои данные нулями, чтобы сделать их правильным размером для БПФ.

Обратите внимание, что причина, по которой нам обычно нужно округлять и дополнять для свертки, заключается в том, что каждое измерение БПФ должно быть image_dimension + kernel_dimension - 1, что обычно не является удобным числом, например степенью 2.

person Paul R    schedule 01.04.2011

То, что говорит @Paul R, верно. Почему это происходит, так это потому, что операция быстрого преобразования Фурье требует выполнения с максимальной скоростью, кратной двум. См. алгоритм Кули-Тьюки.

просто убедитесь, что вы объявляете матрицу, которая является степенью двойки, и вам не нужна эта общая безопасная реализация.

person fabrizioM    schedule 01.04.2011
comment
Степень двойки не необходима для всех реализаций БПФ, и кажется, что CUFFT в любом случае может справиться с не степенью двойки для больших размеров БПФ, где вместо этого используется число, кратное 512. Для свертки вы обычно не можете сделать размер FFT степенью 2, потому что размеры должны быть image_dimension + kernel_dimension - 1, следовательно, необходимо округлять и заполнять. - person Paul R; 01.04.2011
comment
@farbrizioM: ни кратное 2, ни степень 2 не нужны. БПФ может быть реализован для любого размера, который можно разложить на небольшие простые числа, например. FFTW работает с коэффициентами 2, 3, 5, 7. - person Paul R; 01.04.2011
comment
Да, БПФ можно реализовать для нестепеней двойки, но вы упускаете суть: степени двойки можно вычислить намного быстрее, поэтому код пытается повысить производительность, преобразуя, например, 500-точечное БПФ в 512-точечное БПФ. - person Die in Sente; 02.04.2011
comment
Спасибо всем за ваши ответы, я изучу, как это лучше реализовано, но теперь у меня есть отправная точка для начала изучения. Читая ваши ответы, я полагаю, что код CUFFT может работать для всех размеров ядра/матрицы. Если бы это предположение было верным, я был бы ОПРЕДЕЛЕННО счастлив! - person Marco A.; 02.04.2011