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 Я не добавил чеки возврата для примера здесь. Всегда проверяйте возвращаемые значения в вашем коде.