Генерация кода при помощи приложения GPU Coder

Самый легкий способ создать ядра CUDA® состоит в том, чтобы поместить coder.gpu.kernelfun прагма в вашу функцию primary MATLAB®. Первичная функция также известна как функцию entry-point или top-level. Когда GPU Coder™ сталкивается с kernelfun прагма, это пытается параллелизировать весь расчет в этой функции и затем сопоставляет его с графическим процессором. Для получения дополнительной информации о ядрах графического процессора, смотрите Парадигму программирования графического процессора.

Изучение целей

В этом примере вы учитесь как:

  • Подготовьте свой код MATLAB к генерации кода CUDA при помощи kernelfun прагма.

  • Создайте и настройте проект GPU Coder.

  • Задайте свойства входного параметра функции.

  • Проверяйте на готовность генерации кода и проблемы во время выполнения.

  • Задайте свойства генерации кода.

  • Сгенерируйте код CUDA при помощи приложения GPU Coder.

Учебные необходимые условия

Этот пример требует следующих продуктов:

  • MATLAB

  • MATLAB Coder™

  • GPU Coder

  • Компилятор C++

  • NVIDIA® графический процессор включен для CUDA

  • Инструментарий CUDA и драйвер

  • Переменные окружения для компиляторов и библиотек. Для получения дополнительной информации смотрите Переменные окружения.

Пример: множество Мандельброта

Описание

Множество Мандельброта является областью в комплексной плоскости, состоящей из значений z 0, для которого траектории, заданные этим уравнением, остаются ограниченными в k→∞.

zk+1=zk2+z0,k=0,1,

Полная геометрия Множества Мандельброта показана на рисунке. Это представление не имеет разрешения, чтобы показать богато подробную структуру края недалеко от контура набора. При увеличивающихся увеличениях Множество Мандельброта показывает тщательно продуманный контур, который показывает прогрессивно более прекрасную рекурсивную деталь.

Geometry of the Mandelbrot set

Алгоритм

Для этого примера выберите набор пределов, которые задают высоко масштабируемую часть Множества Мандельброта в овраге между основной кардиоидой и лампой p/q с ее левой стороны от него. Сетка 1000 на 1000 действительных частей (x) и мнимые части (y) создается между этими двумя пределами. Алгоритм Мандельброта затем выполнен с помощью итераций в каждом местоположении сетки. Количество итерации 500 рендеринга изображение в полном разрешении.

maxIterations = 500;
gridSize = 1000;
xlim = [-0.748766713922161,-0.748766707771757];
ylim = [0.123640844894862,0.123640851045266];

Этот пример использует реализацию Множества Мандельброта при помощи стандартных команд MATLAB, работающих на центральном процессоре. Это вычисление векторизовано таким образом, что каждое местоположение обновляется одновременно.

Учебные файлы

Создайте функцию MATLAB под названием mandelbrot_count.m со следующими строками кода. Этот код является векторизованной реализацией базовой линии MATLAB Множества Мандельброта. Для каждой точки (xGrid,yGrid) в сетке это вычисляет индекс итерации count в котором траектория, заданная уравнением, достигает расстояния 2 от источника. Это затем возвращает натуральный логарифм count, то, которое используется, генерируют цвет, закодировало график Множества Мандельброта. Позже в этом примере, вы изменяете этот файл, чтобы сделать его подходящим для генерации кода.

function count = mandelbrot_count(maxIterations,xGrid,yGrid)
% mandelbrot computation

z0 = xGrid + 1i*yGrid;
count = ones(size(z0));

z = z0;
for n = 0:maxIterations
    z = z.*z + z0;
    inside = abs(z)<=2;
    count = count + inside;
end
count = log(count);

Создайте скрипт MATLAB по имени mandelbrot_test.m со следующими строками кода. Скрипт генерирует сетку 1000 на 1000 действительных частей (x) и мнимые части (y) между пределами, заданными xlim и ylim. Это также вызывает mandelbrot_count функция и графики получившееся Множество Мандельброта.

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);

%% Mandelbrot computation in MATLAB
count = mandelbrot_count(maxIterations,xGrid,yGrid);

% Show
figure(1)
imagesc(x,y,count);
colormap([jet();flipud(jet());0 0 0]);
axis off
title('Mandelbrot set with MATLAB');

Запустите оригинальный код MATLAB

Запустите пример Мандельброта

Прежде, чем сделать версию MATLAB алгоритма Множества Мандельброта подходящей для генерации кода, можно протестировать функциональность оригинального кода.

  1. Измените текущий MATLAB рабочая папка в местоположение, которое содержит mandelbrot_count.m и mandelbrot_test.m. GPU Coder помещает сгенерированный код в эту папку. Измените свою текущую рабочую папку, если у вас нет полного доступа к этой папке.

  2. Запустите mandelbrot_test скрипт.

Тестовый скрипт запускает и показывает геометрию Мандельброта в граничном множестве переменными xlim и ylim.

Plot of Mandelbrot set in MATLAB

Подготовьте код MATLAB к генерации кода

Прежде чем вы сгенерируете код с GPU Coder, проверяйте на кодирование проблем в оригинальном коде MATLAB.

Проверяйте на проблемы во время проектирования

Существует два инструмента, которые помогают вам обнаружить проблемы генерации кода во время проектирования:

  • Инструмент Code Analyzer

  • Инструмент готовности генерации кода

Анализатор кода является инструментом, включенным в редактор MATLAB, который постоянно проверяет ваш код, когда вы вводите его. Отчеты Анализатора кода выпускают и рекомендуют модификациям максимизировать эффективность и поддерживаемость вашего кода. Чтобы идентифицировать предупреждения и ошибки, характерные для генерации кода из вашего кода MATLAB, добавьте %#codegen директива к вашему файлу MATLAB. Для получения дополнительной информации смотрите настройки Анализатора кода.

Примечание

Анализатор кода не обнаруживает все проблемы генерации кода. После устранения ошибок или предупреждений, что Анализатор кода обнаруживает, скомпилируйте свой код с GPU Coder, чтобы определить, имеет ли код другие проблемы соответствия.

Инструмент готовности генерации кода экранирует код MATLAB на функции и функции, которые не поддерживаются для генерации кода. Этот инструмент предоставляет отчет что проблемы списков и рекомендации для того, чтобы сделать код MATLAB подходящим для генерации кода. Можно получить доступ к инструменту готовности генерации кода этими способами:

  • В браузере текущей папки — щелкают правой кнопкой по файлу MATLAB, который содержит функцию точки входа.

  • В командной строке — при помощи coder.screener функция с -gpu флаг.

  • В приложении GPU Coder — после определения файлов точки входа, выполнение приложения Анализатор кода и инструмент готовности генерации кода.

Проверяйте на проблемы во время генерации кода

Можно использовать GPU Coder, чтобы проверять на проблемы во время генерации кода. Когда GPU Coder обнаруживает ошибки или предупреждения, он генерирует сообщение об ошибке, которое описывает проблемы и обеспечивает ссылки на проблематичный код MATLAB. Для получения дополнительной информации см. Отчеты Генерации кода.

Сделайте код MATLAB подходящим для генерации кода

Чтобы начать процесс создания вашего кода MATLAB, подходящего для генерации кода, используйте файл mandelbrot_count.m.

  1. Установите свою текущую папку MATLAB на папку работы, которая содержит ваши файлы для этого примера.

  2. В редакторе MATLAB откройте mandelbrot_count.m. Индикатор сообщения Анализатора кода в главном правом угле редактора MATLAB является зеленым. Анализатор не обнаружил ошибки, предупреждения или возможности для улучшения кода.

  3. После объявления функции добавьте %#codegen директива, чтобы включить проверку ошибок, которая характерна для генерации кода.

    function count = mandelbrot_count(maxIterations,xGrid,yGrid) %#codegen
    

    Индикатор сообщения Анализатора кода остается зеленым, указывая, что он не обнаружил проблем генерации кода.

  4. Сопоставлять mandelbrot_count функционируйте к ядру CUDA, измените оригинальный код MATLAB путем размещения coder.gpu.kernelfun прагма в теле функции.

    function count = mandelbrot_count(maxIterations,xGrid,yGrid) %#codegen
    % Add kernelfun pragma to trigger kernel creation
    coder.gpu.kernelfun;
    
    % mandelbrot computation
    z0 = xGrid + 1i*yGrid;
    count = ones(size(z0));
    
    z = z0;
    for n = 0:maxIterations
        z = z.*z + z0;
        inside = abs(z)<=2;
        count = count + inside;
    end
    count = log(count);
    

    Если вы используете coder.gpu.kernelfun прагма, GPU Coder пытается сопоставить расчеты в функциональном mandelbrot_count к графическому процессору.

  5. Сохраните файл. Вы теперь готовы скомпилировать свой код при помощи приложения GPU Coder.

Сгенерируйте код при помощи приложения GPU Coder

Откройте приложение GPU Coder

На вкладке Apps панели инструментов MATLAB, под Code Generation, кликают по значку приложения GPU Coder. Можно также открыть приложение путем ввода gpucoder в командном окне MATLAB. Приложение открывает страницу исходных файлов Select.

Выберите Source Files

  1. На странице исходных файлов Select введите или выберите имя функции primary, mandelbrot_count. Первичная функция также известна как функцию entry-point или top-level. Приложение создает проект с именем по умолчанию mandelbrot_count.prj в текущей папке.

    Select source files window of GPU Coder app

  2. Нажмите Next и перейдите к шагу Define Input Types. Приложение анализирует функцию для кодирования готовность генерации кода и проблемы. Если приложение идентифицирует проблемы, оно открывает страницу Review Code Generation Readiness, где можно рассмотреть и устранить проблемы. В этом примере, потому что приложение не обнаруживает проблемы, оно открывает страницу Define Input Types.

Определите входные типы

Генератор кода должен определить типы данных всех переменных в файлах MATLAB во время компиляции. Поэтому необходимо задать типы данных всех входных переменных. Можно задать типы входных данных одним из этих двух способов:

  • Обеспечьте тестовый файл, который вызывает функции точки входа проекта. Приложение GPU Coder может вывести типы входного параметра путем выполнения тестового файла.

  • Введите входные типы непосредственно.

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

В этом примере, чтобы задать свойства входных параметров maxIterations, xGrid, и yGrid, задайте тестовый файл mandelbrot_test.m:

  1. Введите или выберите тестовый файл mandelbrot_test.m.

  2. Нажмите Autodefine Input Types.

    Тестовый файл mandelbrot_test.m вызывает функцию точки входа, mandelbrot_count.m с ожидаемыми входными типами. Приложение выводит что вход maxIterations double(1x1) и входные параметры xGrid и yGrid double(1000x1000).

    Define input types window of the GPU Coder app

  3. Нажмите Next переходят к шагу the Check for Run-Time Issues.

Проверяйте на проблемы во время выполнения

Шаг Check for Run-Time Issues генерирует файл MEX от ваших функций точки входа, запускает MEX-функцию и сообщает о проблемах. Этот шаг является дополнительным. Однако это - лучшая практика выполнить этот шаг. Используя этот шаг, можно обнаружить и зафиксировать дефекты, которые более трудно диагностировать в сгенерированном коде графического процессора.

GPU Coder предоставляет возможность выполнять специфичные для графического процессора проверки в этой точке. Когда вы выбираете эту опцию, GPU Coder генерирует код CUDA и файл MEX от ваших функций точки входа, запускает MEX-функцию и сообщает о проблемах. Некоторые специфичные для графического процессора проверки на этапе выполнения включают:

  • Проверки на разливы регистра.

  • Сложите проверки соответствия размера.

Примечание

Могут быть определенные построения MATLAB в вашем коде, которые заставляют Check for Run-Time Issues приводить специфичные для центрального процессора проверки к сбою, но передавать специфичные для графического процессора проверки.

  1. Чтобы открыть диалоговое окно Check for Run-Time Issues, кликните по стреле Check for Issues.

  2. В диалоговом окне Check for Run-Time Issues задайте тестовый файл или введите код, который вызывает функцию точки входа с входными параметрами в качестве примера. В данном примере используйте тестовый файл mandelbrot_test.m то, что вы раньше задавали входные типы.

  3. Чтобы включить специфичные для графического процессора проверки, установите переключатель GPU. Нажмите Check for Issues.

    Приложение генерирует MEX-функцию. Это запускает тестовый скрипт mandelbrot_test заменяя вызовы mandelbrot_count с вызовами сгенерированного MEX. Если приложение обнаруживает проблемы во время генерации MEX-функции или выполнения, это предоставляет предупреждающие сообщения и сообщения об ошибке. Можно кликнуть по этим сообщениям, чтобы перейти к проблематичному коду и устранить проблему. В этом примере приложение не обнаруживает проблемы. MEX-функция имеет ту же функциональность как оригинал mandelbrot_count функция.

    Check for run-time issues window of the GPU Coder app

    Примечание

    Могут быть определенные построения MATLAB в вашем коде, которые заставляют Check for Run-Time Issues приводить специфичные для центрального процессора проверки к сбою, но передавать специфичные для графического процессора проверки.

  4. Нажмите Next переходят к шагу Generate Code.

Сгенерируйте код CUDA

  1. Чтобы открыть диалоговое окно Generate, кликните по стреле Generate.

    Generate code window of the GPU Coder app

  2. В диалоговом окне Generate можно выбрать тип сборки, которую вы хотите, чтобы GPU Coder выполнил. Доступные параметры перечислены в этой таблице.

    Создайте типОписание
    Source code

    Исходный код CUDA, чтобы объединяться с внешним проектом.

    MEX

    Скомпилированный код, чтобы запуститься в MATLAB.

    Static Library

    Бинарная библиотека для статического подключения с внешним проектом.

    Dynamic Library

    Бинарная библиотека для динамического подключения с внешним проектом.

    Executable

    Автономная программа (требует пользовательского основного файла CUDA).

    Для этого примера, набор Build type к MEX(.mex). Путем генерации MEX выход можно проверять правильность сгенерированного кода CUDA из MATLAB. Тип сборки MEX не требует дополнительных настроек как Toolchain и Hardware Board. Это также не предоставляет возможность генерировать только исходный код. GPU Coder может автоматически выбрать доступный набор инструментальных средств CUDA, пока Переменные окружения установлены правильно.

    Чтобы просмотреть расширенные настройки, выберите More Settings - > GPU Code. К опции Compiler Flags добавьте --fmad=false. Этот флаг, когда передано nvcc, сообщает, что компилятор, чтобы отключить С плавающей точкой Умножается - добавляет оптимизация (FMAD). Эта опция собирается предотвратить числовое несоответствие в сгенерированном коде из-за архитектурных различий между центральным процессором и графическим процессором. Для получения дополнительной информации смотрите Числовые Различия Между центральным процессором и графическим процессором.

    GPU Coder specific settings window of the app

  3. Нажмите Generate.

    GPU Coder генерирует исполняемый файл MEX mandelbrot_count_mex в вашей рабочей папке. <pwd>\codegen\mex\mandelbrot_count папка содержит все другой сгенерированные файлы включая источник CUDA (*.cu) и заголовочные файлы. Приложение GPU Coder указывает что генерация кода, за которой следуют. Это отображает исходные файлы MATLAB и сгенерированные выходные файлы на левой стороне страницы. На вкладке Variables это отображает информацию об исходных переменных MATLAB. На вкладке Target Build Log это отображает журнал сборки, включая предупреждения компилятора и ошибки. По умолчанию, в окне кода, отображения приложения исходный файл CUDA mandelbrot_count.cu. Чтобы просмотреть различный файл, в Source Code или панели Output Files, кликают по имени файла.

    App window showing successful MEX code generation

  4. Чтобы просмотреть отчет генерации кода, нажмите View Report. Отчет обеспечивает ссылки на ваш код MATLAB и сгенерированный CUDA (*.cu) файлы. Это также предоставляет информацию о времени компиляции для переменных и выражений в вашем коде MATLAB. Эта информация помогает вам найти источники ошибки и предупреждений. Это также помогает вам отладить проблемы генерации кода в своем коде. Для получения дополнительной информации см. Отчеты Генерации кода.

    Code generation report window

    Раздел GPU Kernels по вкладке Generated Code предоставляет список ядер, созданных во время генерации кода графического процессора. Элементы в этом списке соединяются с соответствующим исходным кодом. Например, когда вы нажимаете mandelbrot_count_kernel1, секцию кода для этого ядра показывают в окне браузера кода.

    После того, как вы рассмотрите отчет, можно закрыть окно Code Generation Report. Чтобы просмотреть отчет позже, откройте report.mldatx в <pwd>\codegen\mex\mandelbrot_cout\html папка.

  5. <pwd>\codegen\mex\mandelbrot_count содержит gpu_codegen_info.mat MAT-файл, который содержит статистику для сгенерированного кода графического процессора. Этот MAT-файл содержит cuda_Kernel переменная, которая имеет информацию о потоке и размерах блока, совместно использованном и постоянном использовании памяти и аргументах ввода и вывода каждого ядра. cudaMalloc и cudaMemcpy переменные содержат информацию о размере всех переменных GPU и количестве memcpy вызовы между хостом и устройством.

    Screenshot of the contents of MAT-file containing code generation info

  6. В приложении GPU Coder нажмите Next, чтобы открыть страницу Finish Workflow.

Рассмотрите страницу рабочего процесса конца

Страница Finish Workflow указывает что генерация кода, за которой следуют. Это предоставляет сводные данные проекта и ссылки на исходные файлы MATLAB, отчет генерации кода и сгенерированные выходные двоичные файлы. Можно сохранить параметры конфигурации текущего проекта GPU Coder как скрипт MATLAB. Смотрите Преобразуют Проект MATLAB Coder в СКРИПТ MATLAB.

Finish workflow window of the app

Проверьте правильность сгенерированного кода

Чтобы проверить правильность сгенерированного файла MEX, смотрите, Проверяют Правильность Сгенерированного кода.

Смотрите также

Приложения

Функции

Объекты

Похожие темы