Генерация кода с использованием интерфейса командной строки

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

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

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

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

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

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

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

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

  • Сгенерируйте код CUDA при помощи codegen команда.

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

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

  • 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 набора Мандельброта. Позже, в этом руководстве, вы изменяете этот файл, чтобы сделать его подходящим для генерации кода.

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

  2. Откройте mandelbrot_test скрипт в редакторе MATLAB.

  3. Запустите тестовый скрипт, нажав кнопку run или введя mandelbrot_test в Командном Окне MATLAB.

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

    Plot of Mandelbrot set in MATLAB

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

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

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

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

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

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

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

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

    function count = mandelbrot_count(maxIterations, xGrid, yGrid) %#codegen
    % mandelbrot computation
    
    z0 = xGrid + 1i*yGrid;
    count = ones(size(z0));
    
    % Add Kernelfun pragma to trigger kernel creation
    coder.gpu.kernelfun;
    
    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. Сохраните файл. Теперь вы готовы скомпилировать код с помощью интерфейса командной строки.

Генерация кода из командной строки

Вы можете использовать codegen команда для преобразования функций MATLAB в статическую или динамическую библиотеку, исполняемую функцию или MEX-функцию CUDA вместо использования приложения GPU Coder.

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

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

Можно сгенерировать входы и затем использовать -args опция в codegen функция, позволяющая GPU Coder определять класс, размер и сложность входных параметров. Чтобы сгенерировать входы для mandelbrot_count function, использовать следующие команды:

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

Кроме того, можно задать размер, тип и сложность входов функций точки входа, не генерируя входные данные при помощи coder.typeof функция.

ARGS = cell(1,1);
ARGS{1} = cell(3,1);
ARGS{1}{1} = coder.typeof(0);
ARGS{1}{2} = coder.typeof(0,[1000 1000]);
ARGS{1}{3} = coder.typeof(0,[1000 1000]);

Создание Строения

Чтобы сконфигурировать настройки сборки, такие как имя выходного файла, расположение, тип, необходимо создать объекты строения кодера. Чтобы создать объекты, используйте coder.gpuConfig функция. Например, чтобы создать coder.MexCodeConfig объект генерации кода для использования со codegen при генерации MEX-функции используйте:

cfg = coder.gpuConfig('mex');

Другие доступные опции:

  • cfg = coder.gpuConfig('lib');, чтобы создать объект строения генерации кода для использования с codegen при создании статической библиотеки CUDA.

  • cfg = coder.gpuConfig('dll');, чтобы создать объект строения генерации кода для использования с codegen при генерации динамической библиотеки CUDA.

  • cfg = coder.gpuConfig('exe');, чтобы создать объект строения генерации кода для использования с codegen при генерации исполняемого файла CUDA.

Для получения дополнительной информации см. coder.gpuConfig.

Каждый объект строения поставляется с набором параметров, инициализированных до значений по умолчанию. Вы можете использовать запись через точку для изменения значения одного параметра объекта строения за раз. Используйте следующий синтаксис:

configuration_object.property = value

Можно включить те же настройки, что и в Генерации кода, Используя Приложение GPU Coder с помощью следующих эквивалентов командной строки:

cfg = coder.gpuConfig('mex');
cfg.GpuConfig.CompilerFlags = '--fmad=false';
cfg.GenerateReport = true;

The cfg объект строения имеет параметры конфигурации, которые являются общими для MATLAB Coder и GPU Coder, и параметры, которые являются специфичными для GPU Coder. Вы можете увидеть все свойства конкретного графического процессора, доступные в cfg объект строения путем ввода cfg.GpuConfig в Командном Окне MATLAB.

>> cfg.GpuConfig

ans = 

  config with properties:

                    Enabled: 1
                 MallocMode: 'discrete'
           KernelNamePrefix: ''
               EnableCUBLAS: 1
             EnableCUSOLVER: 1
                EnableCUFFT: 1
               Benchmarking: 0
                  SafeBuild: 0
          ComputeCapability: '3.5'
    CustomComputeCapability: ''
              CompilerFlags: ''
        StackLimitPerThread: 1024
            MallocThreshold: 200
           SelectCudaDevice: -1

The --fmad=false флаг при передаче в nvcc, инструктирует компилятор отключить оптимизацию с плавающей точкой Multiply-Add (FMAD). Эта опция предназначена для предотвращения численного несоответствия в сгенерированном коде из-за архитектурных различий в центральном процессоре и графическом процессоре. Для получения дополнительной информации см. раздел «Численные различия между центральным процессором и графическим процессором».

Для получения дополнительной информации о параметрах конфигурации, общих для MATLAB Coder и GPU Coder, см. coder.CodeConfig класс.

Скрипт сборки

Можно создать скрипт сборки mandelbrot_codegen.m который автоматизирует последовательность команд, упомянутых ранее.

% GPU code generation for getting started example (mandelbrot_count.m)
%% Create configuration object of class 'coder.MexCodeConfig'.
cfg = coder.gpuConfig('mex');
cfg.GenerateReport = true;
cfg.GpuConfig.CompilerFlags = '--fmad=false';

%% Define argument types for entry-point 'mandelbrot_count'.
ARGS = cell(1,1);
ARGS{1} = cell(3,1);
ARGS{1}{1} = coder.typeof(0);
ARGS{1}{2} = coder.typeof(0,[1000 1000]);
ARGS{1}{3} = coder.typeof(0,[1000 1000]);

%% Invoke GPU Coder.
codegen -config cfg mandelbrot_count -args ARGS{1}

The codegen команда открывает файл mandelbrot_count.m и переводит код MATLAB в код CUDA.

  • The -report опции codegen чтобы сгенерировать отчет генерации кода, который можно использовать для отладки кода MATLAB.

  • The -args опции codegen для компиляции файла mandelbrot_count.m при помощи класса, размера и сложности входных параметров maxIterations, xGrid и yGrid.

  • The -config опции codegen использовать указанный объект строения для генерации кода.

Когда генерация кода успешна, можно просмотреть результат отчета генерации кода, нажав View Report в Командном Окне MATLAB.

>> mandelbrot_codegen
Code generation successful: View report

Code generation report window

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

Для проверки правильности сгенерированного файла MEX смотрите раздел «Проверка правильности сгенерированного кода».

См. также

Приложения

Функции

Объекты

Похожие темы