Этот пример демонстрирует, как использовать GPU Coder™, чтобы усилить библиотеку CUDA® Fast Fourier Transform (cuFFT) и вычислить двумерный БПФ на графическом процессоре NVIDIA®. Двумерное преобразование Фурье используется в оптике, чтобы вычислить шаблоны дифракции далекого поля. Эти дифракционные шаблоны наблюдаются, когда монохроматический источник света проходит через маленькую апертуру, такой как в эксперименте двойного разреза Янга.
CUDA включил NVIDIA, графический процессор с вычисляет возможность 3.2 или выше.
NVIDIA инструментарий CUDA.
Переменные окружения для компиляторов и библиотек. Для получения дополнительной информации смотрите Переменные окружения.
Следующая строка кода создает папку в вашей текущей рабочей папке (pwd) и копирует все соответствующие файлы в эту папку. Если вы не хотите выполнять эту операцию или если вы не можете сгенерировать файлы в этой папке, изменить вашу текущую рабочую папку.
gpucoderdemo_setup('gpucoderdemo_fft');
Используйте 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 );
Функция 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);
В данном примере мы не должны создавать функцию точки входа и можем непосредственно сгенерировать код для MATLAB® fft2
функция. Сгенерировать MEX CUDA для fft2
MATLAB функция, набор
EnablecuFFT
и используйте codegen
функция. Установка EnablecuFFT
свойство в объекте настройки позволяет GPU Coder заменить fft
ifft
fft2
ifft2
fftn
, и ifftn
вызовы функции в вашем коде MATLAB к соответствующим cuFFT вызовам библиотеки. Для двумерных преобразований и выше, GPU Coder создает несколько 1D пакетных преобразований. Эти пакетные преобразования имеют более высокую производительность, чем одно преобразования. После генерации 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);
Один из самых известных экспериментов в оптике является экспериментом двойного разреза Янга, который показывает легкую интерференцию, когда апертура включает два параллельных разреза. Серия ярких точек отображается, где конструктивная интерференция происходит. В этом случае мы формируем апертуру, представляющую два разреза. Мы ограничиваем апертуру в y
направление, чтобы гарантировать, что получившийся шаблон не полностью сконцентрирован вдоль горизонтальной оси.
slits = (abs( gx ) <= 10/N2) .* (abs( gx ) >= 8/N2); aperture = slits .* (abs(gy) < 20/N2); lightsource = double( aperture );
Начиная с размера, типа и сложности входных параметров остается то же самое, мы можем снова использовать fft2_mex
функции сгенерированы в предыдущем разделе. Мы вычисляем и отображаем интенсивность как прежде.
farfieldsignalGPU = fft2_mex( lightsource );
str = sprintf('Double Slit Far-field Diffraction Pattern on GPU');
visualize(farfieldsignalGPU,str);
Удалите сгенерированные файлы и возвратитесь к исходной папке.
cleanup