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

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

Цели обучения

В этом руководстве вы узнаете, как:

  • Подготовьте код 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];

В этом руководстве используется реализация набора Mandelbrot с помощью стандартных команд 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.

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

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

  • Инструмент анализатора кода

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

Анализатор кода является инструментом, включенным в РЕДАКТОРА 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 pragma, GPU Coder пытается сопоставить расчеты в функции mandelbrot_count на графический процессор.

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

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

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

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

Выбор исходных файлов

  1. На странице Select исходных файлов введите или выберите имя функции primary, mandelbrot_count. Первичная функция также известна как top-level или entry-point функция. Приложение создает проект с именем по умолчанию 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 перейдите к Check for Run-Time Issues шагу.

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

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

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

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

  • Проверка соответствия размера стека.

Примечание

В коде могут быть определенные конструкции 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, инструктирует компилятор отключить оптимизацию Multiply-add (FMAD) с плавающей точкой. Эта опция предназначена для предотвращения численного несоответствия в сгенерированном коде из-за архитектурных различий между центральным процессором и графическим процессором. Для получения дополнительной информации см. раздел «Численные различия между центральным процессором и графическим процессором».

    GPU Coder specific settings window of the app

  3. Нажмите Generate.

    GPU Coder генерирует исполняемый файл MEX mandelbrot_count_mex в рабочей папке. The <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 представлен список ядер, созданных во время генерации кода GPU. Элементы этого списка ссылаются на соответствующий исходный код. Например, когда вы нажимаете mandelbrot_count_kernel1, секция кода для этого ядра отображается в окне браузера кода.

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

  5. The <pwd>\codegen\mex\mandelbrot_count содержит gpu_codegen_info.mat MAT-файл, содержащий статистику сгенерированного графического процессора. Этот MAT-файл содержит cuda_Kernel переменная, которая имеет информацию о потоке и размерах блоков, совместном и постоянном использовании памяти, а также входных и выходных аргументов каждого ядра. The 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 смотрите «Проверка правильности сгенерированного кода».

См. также

Приложения

Функции

Объекты

Похожие темы