В этом примере показано, как интегрировать код CUDA®, сгенерированный для нейронной сети для глубокого обучения в Simulink®. Графический процессор coder™ не поддерживает генерацию кода для блоков Simulink, но можно все еще использовать вычислительную мощность графических процессоров в Simulink путем генерации динамически подключаемой библиотеки (dll) с GPU Coder и затем интеграции его в Simulink как Блок s-function при помощи Legacy Code Tool. Для получения дополнительной информации см. legacy_code. Чтобы проиллюстрировать эту концепцию, пример использует Обнаружение Маршрута, Оптимизированное с GPU Coder (GPU Coder). Исходный пример использовал файл C++ с функциями OpenCV, чтобы считать системы координат, чертить маршруты и наложить информацию о частоте кадров о видеовыходе. Этот пример использует блоки Simulink от Системы Компьютерного зрения Toolbox™, чтобы выполнить те же операции.
CUDA включил NVIDIA®, графический процессор с вычисляет возможность 3.2 или выше.
NVIDIA инструментарий CUDA и драйвер.
Библиотека NVIDIA cuDNN.
Переменные окружения для компиляторов и библиотек. Для получения информации о поддерживаемых версиях компиляторов и библиотек, смотрите Сторонние продукты (GPU Coder). Для подготовки переменных окружения смотрите Подготовку Необходимых как условие продуктов (GPU Coder).
Интерфейс GPU Coder™ для Библиотек Глубокого обучения поддерживает пакет. Чтобы установить этот пакет поддержки, используйте Add-On Explorer.
Используйте coder.checkGpuInstall
функция, чтобы проверить, что компиляторы и библиотеки, необходимые для выполнения этого примера, настраиваются правильно.
envCfg = coder.gpuEnvConfig('host'); envCfg.DeepLibTarget = 'cudnn'; envCfg.DeepCodegen = 1; envCfg.Quiet = 1; coder.checkGpuInstall(envCfg);
Эта схема иллюстрирует общую процедуру для использования Legacy Code Tool
интегрировать код CUDA, сгенерированный для нейронной сети для глубокого обучения в Simulink.
[laneNet,coeffMeans,coeffStds] = getLaneDetectionNetwork();
Архитектура предварительно обученного SeriesNetwork
похоже на AlexNet
за исключением того, что последние несколько слоев заменяются меньшим, полносвязным слоем и регрессией выходной слой. Эта сеть берет вход изображений и выходные параметры два контура маршрута, которые соответствуют левым и правым маршрутам автомобиля, оборудованного датчиком. Каждый контур маршрута представлен параболическим уравнением. Здесь, боковое смещение и продольное расстояние от транспортного средства. Сетевые выходные параметры эти три параметра, и которые описывают параболическое уравнение для левых и правых контуров маршрута. Переменные coeffStds
и coeffMeans
содержите среднее значение и значения станд. от обучившего сеть. Эти значения требуются в процессе моделирования.
Этот пример использует detect_lane.m функцию точки входа. detect_lane
функция вычисляет и координаты, соответствующие положениям маршрута от, и параметры. detect_lane
функция также выполняет расчеты, которые сопоставляют и координаты, чтобы отобразить координаты.
Запускать detect_lane
функция на графическом процессоре от Simulink, сгенерируйте разделяемую библиотеку при помощи GPU Coder. Входные параметры к detect_lane
функция является видеокадром, средним значением и значениями станд. Значения передаются при помощи -args
опция отражает размер этих входных параметров. Скопируйте сгенерированную библиотеку в папку верхнего уровня.
Isize = single(zeros(227,227)); cfg = coder.gpuConfig('dll'); cfg.TargetLang = 'C++'; cfg.GenerateReport = true; cfg.DeepLearningConfig = coder.DeepLearningConfig('cudnn'); codegen -args {ones(227,227,3,'single'),ones(1,6,'double'),ones(1,6,'double')} -config cfg detect_lane if ispc copyfile(fullfile(pwd, 'codegen','dll', 'detect_lane','detect_lane.dll'), pwd); else copyfile(fullfile(pwd, 'codegen','dll', 'detect_lane','detect_lane.so'), pwd); end
Code generation successful: To view the report, open('codegen/dll/detect_lane/html/report.mldatx').
Пример обнаружения маршрута зависит от времени выполнения CUDA NVIDIA, cuBLAS, и cuDNN библиотеки. Legacy Code Tool
структура данных задает:
Имя для S-функции
Технические требования для существующей функции C++
Вся библиотека и заголовочные файлы требуются для компиляции и путей к файлам
Опции для сгенерированной S-функции
После определения структуры используйте функцию legacy_code для:
Инициализируйте Legacy Code Tool
структура данных для функции C++
Сгенерируйте S-функцию для использования в процессе моделирования
Скомпилируйте и соедините сгенерированную S-функцию в динамически загружаемый исполняемый файл (MEX)
Сгенерируйте Блок s-function маскированный для вызова сгенерированной S-функции
srcPath = fullfile(pwd, 'codegen', 'dll', 'detect_lane'); if ispc cuPath = getenv('CUDA_PATH'); cudaLibPath = fullfile(cuPath,'lib','x64'); cudaIncPath = fullfile(cuPath,'include'); cudnnPath = getenv('NVIDIA_CUDNN'); cudnnIncPath = fullfile(cudnnPath,'include'); cudnnLibPath = fullfile(cudnnPath,'lib','x64'); libs = {'detect_lane.lib','cudart.lib','cublas.lib','cudnn.lib'}; else [~,nvccPath] = system('which nvcc'); nvccPath = regexp(nvccPath, '[\f\n\r]', 'split'); cuPath = erase(nvccPath{1},'/bin/nvcc'); cudaLibPath = fullfile(cuPath,'lib64'); cudaIncPath = fullfile(cuPath,'include'); cudnnPath = getenv('NVIDIA_CUDNN'); cudnnIncPath = fullfile(cudnnPath,'include'); cudnnLibPath = fullfile(cudnnPath,'lib64'); [~,cmdout] = system('ldconfig -p | grep "libcublas.so "'); pathStrIdx = strfind(cmdout,'/usr/'); cublasLibPath = fileparts(cmdout(33:end)); cublasIncPath = '/usr/include'; libs = {'detect_lane.so','libcudart.so','libcublas.so','libcudnn.so'}; end headerPath = {srcPath;cudnnIncPath;cudaIncPath;cublasIncPath}; libPath = {srcPath;cudnnLibPath;cudaLibPath;cublasLibPath}; % Define the Legacy Code Tool data structure def = legacy_code('initialize'); def.SFunctionName = 'lane_detect_sfun'; def.OutputFcnSpec = 'void detect_lane(single u1[154587],double u2[6],double u3[6],uint8 y1[1],single y2[56],single y3[56])'; def.IncPaths = headerPath; def.HeaderFiles = {'detect_lane.h'}; def.LibPaths = libPath; def.HostLibFiles = libs; def.Options.useTlcWithAccel = false; def.Options.language = 'C++'; legacy_code('sfcn_cmex_generate', def); status = evalc("legacy_code('compile', def)");
OutputFcnSpec
аргумент задает функцию что S-вызовы-функции на каждом временном шаге. detect_lane.h
заголовочный файл в codegen папке предоставляет функциональную информацию о спецификации. Сопоставьте detect_lane
аргументы функции к Блоку s-function Simulink при помощи исключительно пронумерованного u
лексема для входных портов и y
лексема для выходных портов. Типы данных генерации кода, заданные в tmwtypes.h, должны также быть сопоставлены с типами данных, которые поддерживает Simulink. Для получения дополнительной информации смотрите Объявление Технических требований Функции Legacy Code Tool. Поскольку этот пример уже содержит полную модель Simulink, генерация Блока s-function не выполняется. Чтобы сгенерировать Блок s-function, используйте:
legacy_code('slblock_generate', def);
Переместитесь весь пред - и операции последующей обработки в main_lanenet.cpp
файл исходного примера в Simulink. Входная подсистема Обработки видеоданных удаляет нормализацию, выполняемую мультимедийным блоком читателя, и изменяет размер входного видеокадра к входному размеру слоя сети обнаружения маршрута, 227 227 3. Подсистема затем преобразует 3D видеокадр в одномерный вектор, требуемый detect_lane
библиотека. Точки Маршрута позволили процессам подсистемы левых и правых точек маршрута сделать их подходящими для блока Draw Lanes. Модель Simulink использует видеодисплей, чтобы показать обнаружение маршрута на демонстрационном видео.
open_system('main_lanenet'); set_param('main_lanenet', 'SimulationCommand', 'update');
Чтобы видеть обнаружение маршрута на демонстрационном видео, запустите симуляцию.
sim('main_lanenet', 'timeout', 30);
Закройте модель Simulink.
close_system('main_lanenet');