Симулируйте дифракционные шаблоны с использованием библиотек CUDA FFT

В этом примере показано, как использовать GPU Coder™ для использования библиотеки быстрого преобразования CUDA ® (cuFFT) для вычисления двумерного БПФ на графическом процессоре NVIDIA ®. Двумерное преобразование Фурье используется в оптике для вычисления дифракционных шаблонов дальнего поля. Когда монохроматический источник света проходит через небольшую апертуру, например, в двухщелевом эксперименте Юнга, можно наблюдать эти дифракционные шаблоны. В этом примере также показано, как использовать указатели на графический процессор в качестве входов для функции точки входа при генерации CUDA MEX, исходного кода, статических библиотек, динамических библиотек и исполняемых файлов. При использовании этой функциональности эффективность сгенерированного кода улучшается путем минимизации количества вызовов cudaMemcpy в сгенерированном коде.

Необходимые условия для третьих лиц

Необходимый

Этот пример генерирует CUDA MEX и имеет следующие требования к третьим лицам.

  • CUDA включил графический процессор NVIDIA и совместимый драйвер.

Дополнительный

Для сборок, не являющихся MEX, таких как статические, динамические библиотеки или исполняемые файлы, этот пример имеет следующие дополнительные требования.

Проверьте окружение GPU

Чтобы убедиться, что компиляторы и библиотеки, необходимые для выполнения этого примера, настроены правильно, используйте coder.checkGpuInstall функция.

envCfg = coder.gpuEnvConfig('host');
envCfg.BasicCodegen = 1;
envCfg.Quiet = 1;
coder.checkGpuInstall(envCfg);

Определите систему координат

Перед симуляцией света, прошедшего через апертуру, необходимо задать систему координат. Чтобы получить правильное числовое поведение при вызове fft2, вы должны тщательно расположить$x$ и$y$ так, чтобы нулевое значение было в правильном месте. N2 это половина размера в каждой размерности.

N2 = 1024;
[gx, gy] = meshgrid(-1:1/N2:(N2-1)/N2);

Симулируйте дифракционный шаблон для прямоугольной апертуры

Симулируйте эффект прохождения параллельного луча монохроматического света через небольшую прямоугольную апертуру. Двумерное преобразование Фурье описывает световое поле на большом расстоянии от апертуры. Формуляр- aperture как логическая маска, основанная на системе координат. Источник света является версией апертуры с двойной точностью. Найдите световой сигнал дальнего поля при помощи fft2 функция.

aperture       = (abs(gx) < 4/N2) .* (abs(gy) < 2/N2);
lightsource    = double(aperture);
farfieldsignal = fft2(lightsource);

Отображение интенсивности света для прямоугольной апертуры

The visualize.m функция отображает интенсивность света для прямоугольной апертуры. Вычислите интенсивность света дальнего поля из величины в квадрате светового поля. Чтобы помочь визуализации, используйте fftshift функция.

type visualize
function visualize(farfieldsignal, titleStr)

farfieldintensity = real( farfieldsignal .* conj( farfieldsignal ) );
imagesc( fftshift( farfieldintensity ) );
axis( 'equal' ); axis( 'off' );
title(titleStr);

end
str = sprintf('Rectangular Aperture Far-Field Diffraction Pattern in MATLAB');
visualize(farfieldsignal,str);

Сгенерируйте MEX CUDA для функции

Вы не должны создавать функцию точки входа. Можно непосредственно сгенерировать код для MATLAB ® fft2 функция. Чтобы сгенерировать CUDA MEX для fft2 MATLAB function, в объекте строения установите EnablecuFFT свойство и использовать codegen функция. GPU Coder заменяет fft, ifft, fft2, ifft2, fftn, и ifftn вызовы функций в коде MATLAB на соответствующие вызовы библиотеки cuFFT. Для двумерных преобразований и выше, GPU Coder создает несколько 1-D пакетных преобразований. Эти пакетные преобразования имеют более высокую эффективность, чем одиночные преобразования. После генерации MEX-функции можно проверить, что она имеет ту же функциональность, что и исходная функция точки входа MATLAB. Запуск сгенерированного fft2_mex и постройте график результатов.

cfg = coder.gpuConfig('mex');
cfg.GpuConfig.EnableCUFFT = 1;
codegen -config cfg -args {lightsource} fft2

farfieldsignalGPU = fft2_mex(lightsource);
str = sprintf('Rectangular Aperture Far-Field Diffraction Pattern on GPU');
visualize(farfieldsignalGPU,str);
Code generation successful.

Симулируйте эксперимент Young's Double-Slit

Двойной щелевой эксперимент Юнга показывает световые помехи, когда отверстие содержит две параллельные щели. Серия ярких точек видна там, где имеют место конструктивные интерференции. В этом случае образуйте отверстие, представляющее две щели. Ограничьте отверстие в$y$ направлении, чтобы убедиться, что полученный шаблон не полностью сконцентрирован вдоль горизонтальной оси.

slits          = (abs(gx) <= 10/N2) .* (abs(gx) >= 8/N2);
aperture       = slits .* (abs(gy) < 20/N2);
lightsource    = double(aperture);

Отобразите интенсивность света для двойной щели Юнга

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

farfieldsignalGPU = fft2_mex(lightsource);
str = sprintf('Double Slit Far-Field Diffraction Pattern on GPU');
visualize(farfieldsignalGPU,str);

Сгенерируйте MEX CUDA, используя в качестве входных параметров указатель на графический процессор

В CUDA MEX, сгенерированном выше, вход, предоставленный MEX, копируется из центрального процессора в память GPU, расчет выполняется на графическом процессоре и результат копируется обратно на центральный процессор. Кроме того, код CUDA может быть сгенерирован таким образом, чтобы он принимал указатели графический процессор непосредственно. Для целей MEX указатели на графический процессор могут передаваться от MATLAB ® к CUDA MEX с помощью gpuArray. Для других целей необходимо выделить память графический процессор и скопировать входы из центральный процессор в графический процессор внутри рукописной основной функции, прежде чем они будут переданы в функцию точки входа.

lightsource_gpu = gpuArray(lightsource);
cfg = coder.gpuConfig('mex');
cfg.GpuConfig.EnableCUFFT = 1;
codegen -config cfg -args {lightsource_gpu} fft2 -o fft2_gpu_mex
Code generation successful.

Только числовые и логические типы входных матриц могут передаваться в качестве указателей графический процессор на функцию точки входа. Другие типы данных, которые не поддерживаются, могут быть переданы в качестве входов центральный процессор. Во время генерации кода, если хотя бы один из входов, предоставленных функции точки входа, является указателем на графический процессор, выходы, возвращенные от функции, также являются указателями на графический процессор. Однако, если тип данных выхода не поддерживается как указатель на графический процессор, такой как struct или массив ячеек, выход будет возвращен как указатель на центральный процессор. Для получения дополнительной информации о передаче указателей на графический процессор в функцию точки входа, смотрите Поддержку массивов графических процессоров.

Заметьте различие в сгенерированном коде CUDA при использовании lightsource_gpu Вход графический процессор. Он избегает копирования входов из центрального процессора в память графический процессор и избегает копирования результатов из графический процессор в память CPU. Это приводит к меньшему количеству cudaMemcpys и повышает эффективность сгенерированного CUDA MEX.

Проверьте результаты использования CUDA MEX указателя на графический процессор в качестве входов

Чтобы проверить, что сгенерированный MEX CUDA использует gpuArray имеет ту же функциональность, запускает сгенерированный fft2_gpu_mex, собрать результаты на хосте и построить график результатов.

farfieldsignal_gpu = fft2_gpu_mex(lightsource_gpu);
farfieldsignal_cpu = gather(farfieldsignal_gpu);
str = sprintf('Double Slit Far-Field Diffraction Pattern on GPU using gpuArray');
visualize(farfieldsignal_cpu,str);

См. также

Функции

Объекты

Похожие темы

Для просмотра документации необходимо авторизоваться на сайте