CUFFT: Как рассчитать FFT наклонного указателя?

Я пытаюсь вычислить FFT изображения с помощью CUFFT. Кажется, что CUFFT предлагает только FFT простых указателей устройства, выделенных с cudaMalloc,

Мои входные изображения распределяются с использованием cudaMallocPitch но нет опции для обработки высоты тона указателя изображения.

В настоящее время я должен удалить выравнивание строк, затем выполнить fft и скопировать результаты обратно в наклонный указатель. Мой текущий код выглядит следующим образом:

void fft_device(float* src, cufftComplex* dst, int width, int height, int srcPitch, int dstPitch)
{
    //src and dst are device pointers allocated with cudaMallocPitch

    //Convert them to plain pointers. No padding of rows.
    float *plainSrc;
    cufftComplex *plainDst;

    cudaMalloc<float>(&plainSrc,width * height * sizeof(float));
    cudaMalloc<cufftComplex>(&plainDst,width * height * sizeof(cufftComplex));

    cudaMemcpy2D(plainSrc,width * sizeof(float),src,srcPitch,width * sizeof(float),height,cudaMemcpyDeviceToDevice);

    cufftHandle handle;
    cufftPlan2d(&handle,width,height,CUFFT_R2C);

    cufftSetCompatibilityMode(handle,CUFFT_COMPATIBILITY_NATIVE);

    cufftExecR2C(handle,plainSrc,plainDst);

    cufftDestroy(handle);

    cudaMemcpy2D(dst,dstPitch,plainDst,width * sizeof(cufftComplex),width * sizeof(cufftComplex),height,cudaMemcpyDeviceToDevice);

    cudaFree(plainSrc);
    cudaFree(plainDst);
} 

Это дает правильный результат, но я не хочу делать 2 дополнительных выделения памяти и копии внутри функции. Я хочу сделать что-то вроде этого:

void fft_device(float* src, cufftComplex* dst, int width, int height, int srcPitch, int dstPitch)
{
    //src and dst are device pointers allocated with cudaMallocPitch
    //Don't know how to handle pitch here???
    cufftHandle handle;
    cufftPlan2d(&handle,width,height,CUFFT_R2C);

    cufftSetCompatibilityMode(handle,CUFFT_COMPATIBILITY_NATIVE);

    cufftExecR2C(handle,src,dst);

    cufftDestroy(handle);
}

Вопрос:

Как рассчитать FFT наклонного указателя непосредственно с помощью CUFFT?

1 ответ

Решение

Я думаю, что вы можете быть заинтересованы в cufftPlanMany что позволит вам делать 1D, 2D и 3D FFT с шагом. Ключевыми здесь являются параметры inembed и onembed.

Вы можете найти CUDA_CUFFT_Users_Guide.pdf (страницы 23-24) для получения дополнительной информации. Но для вашего примера вы будете делать что-то вроде следующего.

void fft_device(float* src, cufftComplex* dst,
                int width, int height,
                int srcPitch, int dstPitch)
{
    cufftHandle handle;
    int rank = 2; // 2D fft
    int n[] = {width, height};    // Size of the Fourier transform
    int istride = 1, ostride = 1; // Stride lengths
    int idist = 1, odist = 1;     // Distance between batches
    int inembed[] = {srcPitch, height}; // Input size with pitch
    int onembed[] = {dstPitch, height}; // Output size with pitch
    int batch = 1;
    cufftPlanMany(&handle, rank, n, 
                  inembed, istride, idist,
                  onembed, ostride, odist, CUFFT_R2C, batch);

    cufftSetCompatibilityMode(handle,CUFFT_COMPATIBILITY_NATIVE);
    cufftExecR2C(handle,src,dst);
    cufftDestroy(handle);
}

PS Я не добавил чеки возврата для примера здесь. Всегда проверяйте возвращаемые значения в вашем коде.

Другие вопросы по тегам