В этом примере показано, как создать автономный исполняемый файл CUDA®, который усиливает библиотеку CUDA Solver (cuSOLVER). Пример использует приложение аппроксимирования кривыми, которое подражает автоматическому отслеживанию маршрута на дороге, чтобы проиллюстрировать:
Подбор кривой полиному произвольного порядка к зашумленным данным при помощи матричной QR-факторизации.
Используя coder.LAPACKCallback
класс, чтобы предоставить информацию о библиотеке LAPACK для генератора кода при генерации независимых исполняемых файлов.
CUDA включил NVIDIA® графический процессор.
NVIDIA инструментарий CUDA и драйвер.
Библиотека LAPACK, которая оптимизирована для вашей среды выполнения. Для получения дополнительной информации см. реализации поставщиков LAPACK. Этот пример использует mwlapack
библиотеки, которые MATLAB® обеспечивает в matlabroot/extern/lib.
Переменные окружения для компиляторов и библиотек. Для получения информации о поддерживаемых версиях компиляторов и библиотек, смотрите Стороннее Оборудование. Для подготовки переменных окружения смотрите Подготовку Необходимых как условие продуктов.
Чтобы проверить, что компиляторы и библиотеки, необходимые для выполнения этого примера, настраиваются правильно, используйте coder.checkGpuInstall
функция.
envCfg = coder.gpuEnvConfig('host');
envCfg.BasicCodegen = 1;
envCfg.Quiet = 1;
coder.checkGpuInstall(envCfg);
В приложениях аппроксимирования кривыми цель состоит в том, чтобы оценить коэффициенты полинома младшего разряда. Полином затем используется в качестве модели для наблюдаемых зашумленных данных, которые в этом примере представляют контур маршрута дороги перед транспортным средством. Например, при использовании квадратичного полинома, существует три коэффициента (, , и ) оценить:
Полином, который подходит лучше всего, задан как тот, который минимизирует сумму квадратичных невязок между собой и зашумленными данными. Чтобы решить эту задачу наименьших квадратов, вы получаете и решаете сверхрешительную линейную систему. Явная обратная матрица не требуется, чтобы решать систему.
В этом примере неизвестные являются коэффициентами каждого термина в полиноме. Поскольку полином, который вы используете в качестве модели всегда, начинает с текущего положения на дороге, постоянный термин в полиноме принят, чтобы быть нулем. Оцените коэффициенты для линейных и терминов высшего порядка. Настройте матричное уравнение Ax=y, таким образом что:
содержит датчик выходные параметры.
содержит полиномиальные коэффициенты, которые мы должны получить.
постоянная матрица, связанная с порядком полинома и местоположениями датчиков.
Решите уравнение с помощью QR-факторизации :
и
где pinv () представляет псевдоинверсию. Учитывая матрицу , можно использовать следующий код, чтобы реализовать решение этого матричного уравнения. Факторинг допускает более легкое решение системы.
[Q,R,P] = qr(A); z = Q' * y; x = R \ z; yhat = A * x;
Используйте функцию linsolveQR, чтобы решить уравнение с помощью QR-факторизации .
type linsolveQR.m
function [yhat,x] = linsolveQR(A,y) %#codegen % Copyright 2019 The MathWorks, Inc. [Q,R,P] = qr(A); z = Q' * y; x = R \ z; yhat = A * x; end
Чтобы протестировать алгоритм, постоянно изгибающаяся дорожная модель используется, то есть, синусоида, которая загрязнена аддитивным шумом. Путем варьирования частоты синусоиды в модели можно подчеркнуть алгоритм различными суммами. Этот код симулирует шумный датчик выходные параметры с помощью нашей дорожной модели:
% Duration - Distance that we look ahead % N - Total number of sensors providing estimates of road boundary % Ts - Sample interval % FracPeriod - Fraction of period of sinusoid to match % y - Contains the simulated sensor outputs Duration = 2; N = 25; Ts = Duration / N; FracPeriod = 0.5; y = sin(2*pi* (0:N-1)' * (FracPeriod/N)) + sqrt(0.3) * randn(N,1);
Используйте этот код, чтобы сформировать матрицу Вандермонда :
Npoly = 3; % Order of polynomial to use in fitting v = (0:Ts:((N-1)*Ts))'; A = zeros(length(v), Npoly); for i = Npoly : -1 : 1 A(:,i) = v.^i; end
Матрица Вандермонда и датчик выходная матрица передаются как входные параметры linsolveQR
функция точки входа. Эти входные параметры записаны в разделенные от запятой файлы и читаются из рукописного основного qrmain.cu.
writematrix(reshape(A, 1, 75), 'inputA.csv'); writematrix(reshape(y, 1, 25), 'inputY.csv');
qr
функция только частично поддерживается в cuSOLVER
библиотека. В таких случаях GPU Coder™ использует LAPACK
библиотека для определенных вызовов функции линейной алгебры. LAPACK
внешняя библиотека программного обеспечения в числовой линейной алгебре. Для целей MEX генератор кода использует LAPACK
библиотека включена в MATLAB.
Для автономных целей необходимо задать пользовательский coder.LAPACKCallback
класс, который задает библиотеки LAPACK наряду с заголовочными файлами, чтобы использовать для вызовов линейной алгебры в сгенерированном коде. В этом примере lapackCallback класс коллбэка задает пути к этим библиотекам в updateBuildInfo
метод. Необходимо изменить этот файл с именами библиотеки и путями для пользовательской установки LAPACK на компьютере.
type lapackCallback.m
classdef lapackCallback < coder.LAPACKCallback % % Copyright 2019 The MathWorks, Inc. methods (Static) function hn = getHeaderFilename() hn = 'lapacke.h'; end function updateBuildInfo(buildInfo, buildctx) [~, libExt] = buildctx.getStdLibInfo(); % Specify path to LAPACK library if ispc lapackLocation = [matlabroot,'\extern']; libName = ['libmwlapack' libExt]; buildInfo.addIncludePaths([lapackLocation,'\include']); libPath = [lapackLocation,'\lib\win64\microsoft\']; else lapackLocation = [matlabroot]; libName = ['libmwlapack' libExt]; buildInfo.addIncludePaths([lapackLocation,'/extern/include']); libPath = [lapackLocation,'/bin/glnxa64']; end % Add include path and LAPACK library for linking buildInfo.addLinkObjects(libName, libPath, 1000, true, true); buildInfo.addDefines('HAVE_LAPACK_CONFIG_H'); buildInfo.addDefines('LAPACK_COMPLEX_STRUCTURE'); end end end
Сгенерируйте независимый исполняемый файл определением CustomLAPACKCallback
свойство в объекте настройки кода и использовании рукописного основного qrmain.cu
.
cfg = coder.gpuConfig('exe'); cfg.GpuConfig.EnableCUSOLVER = 1; cfg.CustomLAPACKCallback = 'lapackCallback'; cfg.CustomSource = 'qrmain.cu'; cfg.CustomInclude = '.'; codegen -config cfg -args {A,y} linsolveQR -report
Code generation successful: View report
Когда вы выполняете сгенерированный независимый исполняемый файл, выходные параметры и вычислены и записаны в разделенные от запятой файлы. Считайте эти выходные параметры назад в MATLAB и используйте plot
функция, чтобы визуализировать данные о датчике и кривую по экспериментальным точкам.
if ispc system('linsolveQR.exe'); else system('./linsolveQR'); end yhat = reshape(readmatrix('outputYhat.csv'), 25, 1); x = reshape(readmatrix('outputX.csv'), 3, 1); figure plot(v, y, 'k.', v, yhat, 'r') axis([0 N*Ts -3 3]); grid; xlabel('Distance Ahead of the Vehicle'); legend('Sensor data','Curve fit'); title('Estimate the Lane Boundary Ahead of the Vehicle');
codegen
| coder.gpu.kernel
| coder.gpu.kernelfun
| gpucoder.matrixMatrixKernel
| coder.gpu.constantMemory
| gpucoder.stencilKernel
| coder.checkGpuInstall