Самый легкий способ создать 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→∞.
Общая геометрия набора Мандельброта показана на рисунке. Это представление не имеет разрешения, чтобы показать богато детализированную структуру бахромы непосредственно за границей набора. При увеличении увеличения набор Мандельброта показывает сложный контур, которая обнаруживает постепенно более мелкие рекурсивные детали.
Для этого руководства выберите набор пределов, которые задают сильно увеличенную часть набора Мандельброта в овраге между основным кардиоидом и 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 на место, содержащее два файла, созданные вами на предыдущем шаге. 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
pragma, GPU Coder пытается сопоставить расчеты в функции mandelbrot_count
на графический процессор.
Сохраните файл. Теперь вы готовы скомпилировать код с помощью интерфейса командной строки.
Вы можете использовать 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
Для проверки правильности сгенерированного файла MEX смотрите раздел «Проверка правильности сгенерированного кода».