exponenta event banner

Пример БПФ

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

n = 2^10;                 % size of mask
M = zeros(n);
I = 1:n; 
x = I-n/2;                % mask x-coordinates 
y = n/2-I;                % mask y-coordinates
[X,Y] = meshgrid(x,y);    % create 2-D mask grid
R = 10;                   % aperture radius
A = (X.^2 + Y.^2 <= R^2); % circular aperture of radius R
M(A) = 1;                 % set mask elements inside aperture to 1
figure
imagesc(M)                % plot mask
axis image

DP = fftshift(fft2(M));
imagesc(abs(DP))
axis image

Подготовиться myFFT для создания ядра

Создание функции точки входа myFFT это вычисляет 2-го Фурье, преобразовывают маски при помощи fft2 функция. Используйте fftshift функция для переупорядочивания выходного сигнала таким образом, чтобы нулевая частотная составляющая находилась в центре. Чтобы сопоставить эту функцию с ядром графического процессора, установите coder.gpu.kernelfun pragma внутри функции.

function [DP] = myFFT(M)

coder.gpu.kernelfun();

DP = fftshift(fft2(M));

Сгенерированный код CUDA

При создании кода CUDA ® графический процессор Coder™ создает вызовы функций (cufftEnsureInitialization) для инициализации библиотеки cuFFT, выполнения операций FFT и освобождения аппаратных ресурсов, используемых библиотекой cuFFT. Фрагмент сгенерированного кода CUDA:

void myFFT(myFFTStackData *SD, const real_T M[1048576], creal_T DP[1048576])
 {
  ...
  cudaMemcpy((void *)gpu_M, (void *)M, 8388608ULL, cudaMemcpyHostToDevice);
  myFFT_kernel1<<<dim3(2048U, 1U, 1U), dim3(512U, 1U, 1U)>>>(gpu_M, gpu_b);
  cufftEnsureInitialization(1024, CUFFT_D2Z, 1024, 1024);
  cufftExecD2Z(*cufftGlobalHandlePtr, (cufftDoubleReal *)&gpu_b[0],
               (cufftDoubleComplex *)&gpu_y1[0]);
  ...
  myFFT_kernel2<<<dim3(2048U, 1U, 1U), dim3(512U, 1U, 1U)>>>(gpu_y1, gpu_y);
  cufftEnsureInitialization(1024, CUFFT_Z2Z, 1024, 1024);
  cufftExecZ2Z(*cufftGlobalHandlePtr, (cufftDoubleComplex *)&gpu_y[0],
               (cufftDoubleComplex *)&gpu_DP[0], CUFFT_FORWARD);
  ...
  cufftEnsureDestruction();
  ...
 }

Первое cudaMemcpy вызов функции передает вход 1024x1024 с двойным значением M в память графического процессора. myFFT_kernel1 перед вызовами библиотеки cuFFT ядро выполняет предварительную обработку входных данных. Двумерный вызов преобразования Фурье fft2 эквивалентно вычислениям fft(fft(M).').'. Поскольку пакетный преобразовывает, обычно имеют более высокую работу по сравнению с единственными преобразованиями, у Кодера GPU есть два требования 1-D cuFFT cufftExecD2Z для вычисления прямого преобразования с двойной точностью вещественно-в-комплексе на входе M за которым следует cufftExecZ2Z для выполнения комплексного преобразования результата с двойной точностью. cufftEnsureDestruction() вызов уничтожает и освобождает все ресурсы графического процессора, связанные с вызовом библиотеки cuFFT.