Этот пример показывает, как двумерное преобразование Фурье может использоваться на оптической маске, чтобы вычислить ее дифракционный шаблон. Создайте логический массив, который задает оптическую маску с небольшой круговой апертурой.
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-D преобразование Фурье маски при помощи fft2 функция. Используйте fftshift функция, чтобы переставить выход так, чтобы компонент нулевой частоты находился в центре. Чтобы сопоставить эту функцию с ядром графический процессор, поместите coder.gpu.kernelfun прагма внутри функции.
function [DP] = myFFT(M)
coder.gpu.kernelfun();
DP = fftshift(fft2(M));Когда вы генерируете CUDA® код, GPU 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 в память графический процессор. The myFFT_kernel1 ядро выполняет предварительную обработку входных данных перед вызовами библиотеки cuFFT. Двумерный вызов преобразования Фурье fft2 эквивалентно вычислительным fft(fft(M).').'. Поскольку пакетные преобразования обычно имеют более высокую эффективность по сравнению с одинарными преобразованиями, GPU Coder имеет два 1-D вызова cuFFT cufftExecD2Z для вычисления преобразования входа с двойной точностью от реального до комплексного M далее следуют cufftExecZ2Z чтобы выполнить двойное прецизионное комплексное преобразование результата. The cufftEnsureDestruction() вызов уничтожает и освобождает все ресурсы GPU, связанные с вызовом библиотеки cuFFT.