В этом примере показано, как сгенерировать код CUDA ® из простой функции MATLAB ® с помощью GPU Coder™. Реализация набора Мандельброт при помощи стандартных команд MATLAB действует как функция точки входа. Этот пример использует codegen
команда для генерации MEX-функции, которая запускается на графическом процессоре. Для проверки ошибок времени выполнения можно запустить MEX-функцию.
Необходимый
Этот пример генерирует CUDA MEX и имеет следующие требования к третьим лицам.
CUDA включает графический процессор NVIDIA ® и совместимый драйвер.
Дополнительный
Для сборок, не являющихся MEX, таких как статические, динамические библиотеки или исполняемые файлы, этот пример имеет следующие дополнительные требования.
Набор инструментальных средств NVIDIA.
Переменные окружения для компиляторов и библиотек. Для получения дополнительной информации см. раздел «Оборудование сторонних производителей» и «Настройка продуктов для подготовки».
Чтобы убедиться, что компиляторы и библиотеки, необходимые для выполнения этого примера, настроены правильно, используйте coder.checkGpuInstall
функция.
envCfg = coder.gpuEnvConfig('host');
envCfg.BasicCodegen = 1;
envCfg.Quiet = 1;
coder.checkGpuInstall(envCfg);
Набор Мандельброта является областью в комплексной плоскости, состоящей из значений, для которых заданы траектории
остаются ограниченными в. Общая геометрия набора Мандельброта показана на рисунке. Это представление не имеет разрешения, чтобы показать богато детализированную структуру бахромы непосредственно за границей набора.
Выберите набор пределов, которые определяют сильно увеличенную часть набора Мандельброта в овраге между основным кардиоидом и луковицей налево. A 1000x1000
сетка и создается между этими двумя пределами. Алгоритм Мандельброта затем итератируется в каждом местоположении сетки. Чтобы отобразить изображение в полном разрешении, достаточно числа итерации 500.
maxIterations = 500; gridSize = 1000; xlim = [-0.748766713922161, -0.748766707771757]; ylim = [ 0.123640844894862, 0.123640851045266]; x = linspace( xlim(1), xlim(2), gridSize ); y = linspace( ylim(1), ylim(2), gridSize ); [xGrid,yGrid] = meshgrid( x, y );
The mandelbrot_count.m
функция точки входа содержит векторизованную реализацию набора Мандельброта, основанную на коде, представленном в электронной книге «Эксперименты с MATLAB» Клева Молера. Директива% # codegen включает MATLAB для проверки ошибки генерации кода. Когда GPU Coder встречается с coder.gpu.kernelfun
pragma, она пытается параллелизировать все расчеты в рамках этой функции, а затем преобразует его в графический процессор.
type mandelbrot_count
function count = mandelbrot_count(maxIterations, xGrid, yGrid) %#codegen % Copyright 2016-2019 The MathWorks, Inc. z0 = xGrid + 1i*yGrid; count = ones(size(z0)); % Map computation to GPU. coder.gpu.kernelfun; z = z0; for n = 0:maxIterations z = z.*z + z0; inside = abs(z)<=2; count = count + inside; end count = log(count);
mandelbrot_count
Запуск mandelbrot_count
функция с ранее сгенерированными значениями xGrid, yGrid, а затем график результатов.
count = mandelbrot_count(maxIterations, xGrid, yGrid); figure(2), imagesc( x, y, count ); colormap( [jet();flipud( jet() );0 0 0] ); title('Mandelbrot Set on MATLAB'); axis off
Чтобы сгенерировать CUDA MEX для mandelbrot_count
function, создайте объект строения кода GPU и запустите codegen
команда. Из-за архитектурных различий между центральным процессором и графическим процессором числовая верификация не всегда совпадает. Этот сценарий верен при использовании одного типа данных в коде MATLAB и выполнении операций накопления этих значений типов данных. Как и в этом примере Мандельброта, даже двойные типы данных вызывают числовые ошибки. Одной из причин этого несоответствия является то, что графические процессоры модулей с плавающей точкой используют слитые инструкции Multiply-Add (FMAD) с плавающей точкой, и центральный процессор не использует эти инструкции. The fmad=false
опция, которая передается в nvcc
компилятор отключает эту оптимизацию FMAD.
cfg = coder.gpuConfig('mex'); cfg.GpuConfig.CompilerFlags = '--fmad=false'; codegen -config cfg -args {maxIterations,xGrid,yGrid} mandelbrot_count
Code generation successful: To view the report, open('codegen/mex/mandelbrot_count/html/report.mldatx').
После генерации MEX-функции проверьте, что она имеет ту же функциональность, что и исходная функция точки входа MATLAB. Запуск сгенерированного mandelbrot_count_mex
и постройте график результатов.
countGPU = mandelbrot_count_mex(maxIterations, xGrid, yGrid); figure(2), imagesc( x, y, countGPU ); colormap( [jet();flipud( jet() );0 0 0] ); title('Mandelbrot Set on GPU'); axis off