Самый легкий способ создать ядра CUDA® состоит в том, чтобы поместить прагму coder.gpu.kernelfun
в вашу функцию primary MATLAB®. Первичная функция также известна как функцию entry-point или top-level. Когда GPU Coder™ сталкивается с прагмой kernelfun
, он пытается параллелизировать все вычисление в этой функции и затем сопоставляет его с графическим процессором.
В этом примере вы учитесь как:
Подготовьте свой код MATLAB к генерации кода CUDA при помощи прагмы kernelfun
.
Создайте и настройте проект GPU Coder.
Задайте свойства входного параметра функции.
Проверяйте на готовность генерации кода и проблемы во время выполнения.
Задайте свойства генерации кода.
Сгенерируйте код CUDA при помощи команды codegen
.
Этот пример требует следующих продуктов:
MATLAB
MATLAB Coder™
GPU Coder
Компилятор C
NVIDIA® графический процессор включен для CUDA
Инструментарий CUDA и драйвер
Переменные окружения для компиляторов и библиотек. Для получения дополнительной информации смотрите Переменные окружения
Вы не должны быть знакомы с алгоритмом в примере, чтобы завершить пример.
Множество Мандельброта является областью в комплексной плоскости, состоящей из значений z 0 для который траектории, заданные
останьтесь ограниченными в k→∞. Полную геометрию Множества Мандельброта показывают в фигуре. Это представление не имеет разрешения, чтобы показать богато подробную структуру края недалеко от контура набора. При увеличивающихся увеличениях Множество Мандельброта показывает тщательно продуманный контур, который показывает прогрессивно более прекрасную рекурсивную деталь.
Для этого примера выберите набор пределов, которые задают высоко масштабируемую часть Множества Мандельброта в долине между основной кардиоидой и лампой 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 Множества Мандельброта. Позже в этом примере, вы изменяете этот файл, чтобы сделать его подходящим для генерации кода.
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 к местоположению, которое содержит эти два файла, которые вы создали на предыдущем шаге. GPU Coder помещает сгенерированный код в эту папку, измените свою текущую рабочую папку, если у вас нет полного доступа к этой папке.
Откройте скрипт mandelbrot_test
в редакторе MATLAB.
Запустите тестовый скрипт путем щелкания по кнопке Run или путем ввода mandelbrot_test
в Окно Команды MATLAB.
Тестовый скрипт запускает и показывает геометрию Мандельброта в граничном множестве переменными xlim
и ylim
.
Чтобы начать процесс создания вашего кода MATLAB, подходящего для генерации кода, используйте файл mandelbrot_count.m
.
Установите свою текущую папку MATLAB на папку работы, которая содержит ваши файлы для этого примера.
В редакторе MATLAB откройте mandelbrot_count.m
. Файл открывается в редакторе MATLAB. Индикатор сообщения Анализатора кода в правом верхнем углу редактора MATLAB является зеленым. Анализатор не обнаружил ошибки, предупреждения или возможности для улучшения кода.
Включите MATLAB для проверки ошибок генерации кода. После объявления функции добавьте директиву %#codegen
.
function count = mandelbrot_count(maxIterations, xGrid, yGrid) %#codegen
Индикатор сообщения Анализатора кода остается зеленым, указывая, что он не обнаружил проблемы генерации кода.
Чтобы сопоставить функцию mandelbrot_count
с ядром CUDA, измените оригинальный код MATLAB путем размещения прагмы coder.gpu.kernelfun
вне тела for-loop
.
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
, графический процессор Coderattempts, чтобы сопоставить вычисления в функциональном mandelbrot_count
к графическому процессору.
Сохраните файл. Вы теперь готовы скомпилировать свой код при помощи интерфейса командной строки.
Можно использовать команду codegen
, чтобы перевести функции MATLAB в совместимый C/C++ CUDA статическая или динамическая библиотека, исполняемый файл или MEX-функция, вместо того, чтобы использовать приложение GPU Coder.
Во время компиляции GPU Coder должен знать типы данных всех входных параметров к функции точки входа. Поэтому, если ваша функция точки входа имеет входные параметры, необходимо задать ее тип данных в то время, когда вы компилируете файл с функцией codegen
.
Можно сгенерировать входные параметры и затем использовать опцию -args
в функции codegen
, чтобы позволить GPU Coder определить класс, размер и сложность входных параметров. Чтобы сгенерировать входные параметры для функции 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 );
Также можно задать размер, тип и сложность входных параметров к функциям точки входа, не генерируя входные данные при помощи функции 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
при генерации C/C++ CUDA статическая библиотека.
cfg = coder.gpuConfig('dll');
, чтобы создать настройку генерации кода возражают для использования с codegen
при генерации C/C++ CUDA динамическая библиотека.
cfg = coder.gpuConfig('exe');
, чтобы создать настройку генерации кода возражают для использования с codegen
при генерации исполняемого файла C/C++ CUDA.
Для получения дополнительной информации смотрите coder.gpuConfig
.
Каждый объект настройки идет с набором параметров, инициализированных к значениям по умолчанию. Можно использовать запись через точку, чтобы изменить значение одного параметра объекта настройки за один раз. Используйте этот синтаксис:
configuration_object.property = value
Можно включить те же настройки как в Генерации кода при помощи Приложения GPU Coder при помощи следующих эквивалентов командной строки:
cfg = coder.gpuConfig('mex'); cfg.GpuConfig.CompilerFlags = '--fmad=false'; cfg.GenerateReport = true;
Объект настройки 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
Флаг --fmad=false
, когда передано nvcc
, сообщает, что компилятор, чтобы отключить С плавающей точкой Умножается - Добавляет оптимизация (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}
Команда codegen
открывает файл mandelbrot_count.m
и переводит код MATLAB в код CUDA.
Опция -report
сообщает, что codegen
, чтобы сгенерировать генерацию кода сообщает, что можно использовать, чтобы отладить код MATLAB.
Опция -args
дает команду codegen
компилировать файл mandelbrot_count.m
при помощи класса, размера и сложности входных параметров maxIterations, xGrid и yGrid.
Опция -config
дает команду codegen
использовать заданный объект настройки для генерации кода.
Когда генерация кода успешна, можно просмотреть получившийся отчет генерации кода путем нажатия на View Report в Окне Команды MATLAB.
>> mandelbrot_codegen Code generation successful: View report
Чтобы проверить правильность сгенерированного файла MEX, смотрите, Проверяют Правильность Сгенерированного кода.