Самый легкий способ создать ядра 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
- тело цикла.
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, смотрите, Проверяют Правильность Сгенерированного кода.