Генерация кода GPU: набор Мандельброта

В этом примере показано, как сгенерировать код CUDA ® из простой функции MATLAB ® с помощью GPU Coder™. Реализация набора Мандельброт при помощи стандартных команд MATLAB действует как функция точки входа. Этот пример использует codegen команда для генерации MEX-функции, которая запускается на графическом процессоре. Для проверки ошибок времени выполнения можно запустить MEX-функцию.

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

Необходимый

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

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

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

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

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

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

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

Набор Мандельброта

Набор Мандельброта является областью в комплексной плоскости, состоящей из значений$z_0$, для которых заданы траектории

$$z_{k+1} = {z_k}^2 + z_0, k = 0,1,...$$

остаются ограниченными в. $k\rightarrow\infty$Общая геометрия набора Мандельброта показана на рисунке. Это представление не имеет разрешения, чтобы показать богато детализированную структуру бахромы непосредственно за границей набора.

Задайте входные области

Выберите набор пределов, которые определяют сильно увеличенную часть набора Мандельброта в овраге между основным кардиоидом и$p/q$ луковицей налево. A 1000x1000 сетка$Re\{x\}$ и$Im\{y\}$ создается между этими двумя пределами. Алгоритм Мандельброта затем итератируется в каждом местоположении сетки. Чтобы отобразить изображение в полном разрешении, достаточно числа итерации 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

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

Чтобы сгенерировать 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-функции

После генерации 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

См. также

Приложения

Функции

Объекты

Похожие темы