CUFFT - вопрос заполнения / инициализации - PullRequest
2 голосов
/ 01 апреля 2011

Я смотрю на 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);
}

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

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

Ответы [ 2 ]

2 голосов
/ 01 апреля 2011

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

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

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

1 голос
/ 01 апреля 2011

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

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

...