Выход CUFFT не выровнен так же, как выход FFTW - PullRequest
3 голосов
/ 26 сентября 2011

Я делаю 1D БПФ. У меня есть те же входные данные, что и в FFTW, однако возврат из CUFFT, похоже, не "выровнен" так же, как FFTW. То есть в моем FFTW-коде я мог бы вычислить центр заполнения нулями, а затем сделать некоторое смещение, чтобы «выровнять по левому краю» все мои данные, и получить конечные нули.

В CUFFT результат от FFT - это данные, которые выглядят одинаково, однако нули не «центрированы» в выходных данных, поэтому остальная часть моего алгоритма ломается. (При смещении влево для выравнивания данных после «плохого сдвига» все еще есть «пробел»).

Может кто-нибудь подсказать мне? Я думал, что это как-то связано с этими флагами совместимости, но даже с cufftSetCompatibilityMode (plan, CUFFT_COMPATIBILITY_FFTW_ALL); Я все еще получаю плохой результат.

Ниже приведен график величины данных из первого ряда. Данные слева являются выходом обратного CUFFT, а выход справа - выходом обратного FFTW.

Спасибо! enter image description here

Вот код настройки для планов FFTW и CUFFT

ifft = fftwf_plan_dft_1d(freqCols, reinterpret_cast<fftwf_complex*>(indata), 

                  reinterpret_cast<fftwf_complex*>(outdata), 

                  FFTW_BACKWARD, FFTW_ESTIMATE);

CUFFT:

cufftSetCompatibilityMode(plan, CUFFT_COMPATIBILITY_FFTW_ALL);
cufftPlan1d(&plan, width, CUFFT_C2C, height);

и выполнение кода:

fftwf_execute(ifft);

CUFFT:

cufftExecC2C(plan, d_image, d_image, CUFFT_INVERSE); //in place inverse

Выполнен тестовый код:

complex<float> *input = (complex<float>*)fftwf_malloc(sizeof(fftwf_complex) * 100);
    complex<float> *output = (complex<float>*)fftwf_malloc(sizeof(fftwf_complex) * 100);

    fftwf_plan ifft;
    ifft = fftwf_plan_dft_1d(100, reinterpret_cast<fftwf_complex*>(input), 

                          reinterpret_cast<fftwf_complex*>(output), 

                          FFTW_BACKWARD, FFTW_ESTIMATE);


    cufftComplex *inplace = (cufftComplex *)malloc(100*sizeof(cufftComplex));
    cufftComplex *d_inplace;
    cudaMalloc((void **)&d_inplace,100*sizeof(cufftComplex));
    for(int i = 0; i < 100; i++)
    {
        inplace[i] = make_cuComplex(cos(.5*M_PI*i),sin(.5*M_PI*i));
        input[i] = complex<float>(cos(.5*M_PI*i),sin(.5*M_PI*i));
    }

    cutilSafeCall(cudaMemcpy(d_inplace, inplace, 100*sizeof(cufftComplex), cudaMemcpyHostToDevice));
    cufftHandle plan;
    cufftPlan1d(&plan, 100, CUFFT_C2C, 1);
    cufftExecC2C(plan, d_inplace, d_inplace, CUFFT_INVERSE);
    cutilSafeCall(cudaMemcpy(inplace, d_inplace, 100*sizeof(cufftComplex), cudaMemcpyDeviceToHost));


    fftwf_execute(ifft);

Когда я выгрузил выходные данные обоих вызовов FFT, они выглядели одинаково. Хотя я не совсем уверен, на что я смотрел. Данные имели значение 100 в 75-й строке. Это правильно?

1 Ответ

2 голосов
/ 27 сентября 2011

Похоже, вы могли поменять местами действительные и мнимые компоненты ваших сложных данных при вводе в одно из IFFT. Этот обмен изменит четную функцию на нечетную функцию во временной области.

...