Этот пример показывает, как интегрировать GPU Coder™ в Simulink®. В то время как GPU Coder не поддержан для блоков Simulink, можно все еще усилить графические процессоры в Simulink путем генерации динамически подключаемой библиотеки (dll) использование GPU Coder и затем интеграция его в блок Simulink с помощью кодера. API ExternalDependency. Обнаружение ребра Sobel используется в качестве примера, чтобы продемонстрировать эту концепцию.
CUDA-поддерживающий NVIDIA® графический процессор с вычисляет возможность 3.0 или выше.
NVIDIA инструментарий CUDA.
Переменные окружения для компиляторов и библиотек. Для получения дополнительной информации смотрите Переменные окружения.
Simulink, чтобы создать модель в Simulink.
Computer Vision Toolbox™, чтобы использовать видео средство чтения и средство просмотра, используемое в примере.
Следующая строка кода создает папку в вашей текущей рабочей папке (pwd) и копирует все соответствующие файлы в эту папку. Если вы не хотите выполнять эту операцию или если вы не можете сгенерировать файлы в этой папке, изменить вашу текущую рабочую папку.
gpucoderdemo_setup('gpucoderdemo_in_simulink');
Используйте coder.checkGpuInstall, функционируют и проверяют, что компиляторы и библиотеки, необходимые для выполнения этого примера, настраиваются правильно.
envCfg = coder.gpuEnvConfig('host');
envCfg.BasicCodegen = 1;
envCfg.Quiet = 1;
coder.checkGpuInstall(envCfg);
Функция sobelEdge.m берет изображение (представленный как одна матрица) и возвращает изображение с обнаруженными ребрами.
type sobelEdge
function [ magnitude ] = sobelEdge( Image ) %#codegen % Copyright 2017 The MathWorks, Inc. maskX = single([-1 0 1 ; -2 0 2; -1 0 1]); maskY = single([-1 -2 -1 ; 0 0 0 ; 1 2 1]); coder.gpu.kernelfun(); resX = conv2(Image, maskX, 'same'); resY = conv2(Image, maskY, 'same'); magnitude = sqrt(resX.^2 + resY.^2); thresh = magnitude < 0.4; magnitude(thresh) = 0; end
Чтобы запустить эту функцию на графическом процессоре от Simulink, сгенерируйте разделяемую библиотеку при помощи GPU Coder и вызовите сгенерированный код (библиотека) от Simulink при помощи кодера. API ExternalDependency. Скопируйте сгенерированную библиотеку в директорию верхнего уровня.
Isize = single(zeros(240, 320)); cfg = coder.gpuConfig('dll'); codegen -args {Isize} -config cfg sobelEdge if ispc copyfile(fullfile(pwd, 'codegen','dll', 'sobelEdge','sobelEdge.dll'), pwd); else copyfile(fullfile(pwd, 'codegen','dll', 'sobelEdge','sobelEdge.so'), pwd); end
Прежде, чем сгенерировать код C/CUDA, необходимо сначала протестировать MEX-функцию в MATLAB®, чтобы гарантировать, что это функционально эквивалентно оригинальному коду MATLAB и что никакие ошибки времени выполнения не происходят.
SobelAPI.m является классом, который задает API, чтобы вызвать сгенерированный DLL. Большая часть этой функции является стандартным шаблоном. Метод интереса является SobelAPI.sobelEdge, который называется, чтобы выполнить DLL. Эта функция просто вызывает sobelEdge DLL через вызов coder.ceval.
type SobelAPI
% Copyright 2017 The MathWorks, Inc. classdef SobelAPI < coder.ExternalDependency %#codegen methods (Static) function bName = getDescriptiveName(~) bName = 'SobelAPI'; end function tf = isSupportedContext(ctx) if ctx.isMatlabHostTarget() tf = true; else error('sobel library not available for this target'); end end function updateBuildInfo(buildInfo, ctx) [~, linkLibExt, execLibExt, ~] = ctx.getStdLibInfo(); % Header files hdrFilePath = fullfile(pwd, 'codegen', 'dll', 'sobelEdge'); buildInfo.addIncludePaths(hdrFilePath); % Link files linkFiles = strcat('sobelEdge', linkLibExt); linkPath = hdrFilePath; linkPriority = ''; linkPrecompiled = true; linkLinkOnly = true; group = ''; buildInfo.addLinkObjects(linkFiles, linkPath, ... linkPriority, linkPrecompiled, linkLinkOnly, group); % Non-build files nbFiles = 'sobelEdge'; nbFiles = strcat(nbFiles, execLibExt); buildInfo.addNonBuildFiles(nbFiles,'',''); end %API for library function 'sobelEdge' function c = sobelEdge(I) % running in generated code, call library function coder.cinclude('sobelEdge.h'); c = coder.nullcopy(I); coder.ceval('sobelEdge', coder.rref(I), coder.wref(c)); end end end % LocalWords: sobel
В Simulink создайте блок MATLAB function, который вызывает SobelAPI.sobelEdge. Это эквивалентно подписанию сгенерированного кода DLL Кодера GPU. Таким образом, когда блок MATLAB function выполняется, этот DLL будет работать на графическом процессоре вашей хост-машины. И так же для генерации кода от Simulink, код CUDA будет вызван. Модель Simulink использует видео средство чтения и видеодисплей, чтобы показать эффект алгоритма.
open_system('gpucoder_sobelEdge'); set_param('gpucoder_sobelEdge', 'SimulationCommand', 'update');
Запустите симуляцию, чтобы видеть эффект алгоритма Sobel.
sim('gpucoder_sobelEdge', 'timeout', 30);
Удалите файлы и возвратитесь к исходной папке
close_system('gpucoder_sobelEdge');
cleanup