Генерация кода при помощи приложения 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,

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

Алгоритм

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

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

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

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

Создайте функцию 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 x 1 000 сеток действительных частей (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.

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

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

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

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

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

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

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

Примечание

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

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

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

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

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

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

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

Сделайте код 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 в текущей папке.

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

Входные Define типы

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

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

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

Для получения дополнительной информации о входных спецификациях, смотрите Входную Спецификацию (MATLAB 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).

  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 функция.

    Примечание

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

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

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

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

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

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

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

    MEX

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

    Static Library

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

    Dynamic Library

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

    Executable

    Автономная программа (требует отдельного основного файла, записанного в C).

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

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

    Эта таблица описывает настройки, характерные для GPU Coder.

    Свойства настройки GPU Coder

    Установка пользовательского интерфейсаТип значенияОписание
    Kernel Name Prefix

    String

    Задайте пользовательский префикс имени для имен ядра в сгенерированном коде. Например, ввод 'CUDA_' создает ядра с именами CUDA_kernel1, CUDA_kernel2, и так далее. Если никакое имя не обеспечивается, GPU Coder предварительно ожидает имя ядра с именем функции точки входа.

    Имена ядра могут содержать прописные буквы, строчные буквы, цифры 0-9 и символ подчеркивания _. GPU Coder удаляет неподдерживаемые символы из имен ядра и добавляет alpha к префиксам, которые не начинаются с алфавитной буквы.

    Malloc Mode

    Enumerated

    'Discrete'|'Unified'

    Выбирает тип выделения памяти графического процессора: Discrete или Unified.

    Malloc ThresholdInteger

    Размер, выше которого частные переменные выделяются на куче вместо стека.

    Stack LimitInteger

    Доступный предел стека на поток графического процессора.

    Enable cuSOLVER

    Boolean

    'True'|'False'

    Позволяет GPU Coder использовать cuSOLVER вызовы библиотеки, где это необходимо.

    Benchmarking

    Boolean

    'True'|'False'

    Генерирует код CUDA со сравнительным тестированием опций, таких как cudaEvent API к точно времени kernel, memcpy, и другие события.

    Safe Build

    Boolean

    'True'|'False'

    Генерирует код с проверкой ошибок на вызовы API CUDA и вызовы ядра.

    Minimum Compute Capability

    Enumerated

    '3.2'|'3.5'|'3.7'|'5.0'|'5.2'|'5.3'|'6.0'|'6.1'

    Выбор минимум вычисляет возможность генерации кода. Вычислить возможность идентифицирует функции, поддерживавшие оборудованием графического процессора, и используется приложениями во время выполнения, чтобы определить, который показывает оборудование, инструкции доступны на существующем графическом процессоре. Если вы задаете пользовательский, вычисляют возможность, GPU Coder игнорирует эту установку.

    Custom Compute Capability

    String

    Задайте имя NVIDIA виртуальная архитектура графического процессора, для которой должны быть скомпилированы файлы входа CUDA.

    Например, чтобы задать виртуальный тип архитектуры -arch=compute_50. Можно задать действительную архитектуру с помощью -arch=sm_50. Для получения дополнительной информации см. Опции для Регулирования темы Генерации кода графического процессора в документации инструментария CUDA.

    Compiler Flags

    String

    Передайте дополнительные флаги компилятору графического процессора. Например, --fmad=false сообщает nvcc компилятор, чтобы отключить сокращение с плавающей точкой умножается и добавляет к синглу, С плавающей точкой, Умножаются - Добавляет инструкция (FMAD).

    Для подобных параметров компилятора NVIDIA смотрите тему на Опциях Команды NVCC в документации инструментария CUDA.

    SelectCudaDevice

    Integer

    Во много среде графического процессора, такой как платформы NVIDIADrive, задайте устройство CUDA, чтобы предназначаться.

  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, кликают по имени файла.

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

    Раздел 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 вызовы между хостом и устройством.

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

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

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

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

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

Похожие темы