В этом примере показано, как создать автономный исполняемый файл CUDA ®, который использует библиотеку Решатель (cuSOLVER). Пример использует приложение аппроксимирования кривыми, которое имитирует автоматическое отслеживание маршрута на дороге, чтобы проиллюстрировать:
Аппроксимация полинома произвольного порядка к зашумленным данным с помощью матричной QR-факторизации.
Использование coder.LAPACKCallback
Класс для предоставления информации библиотеки LAPACK для генератора кода при генерации независимых исполняемых файлов.
Графический процессор NVIDIA ® с поддержкой CUDA.
Инструментарий и драйвер 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 = 2; % Distance that we look ahead N = 25; % Total number of sensors providing estimates of road boundary Ts = Duration / N; % Sample interval FracPeriod = 0.5; % Fraction of period of sinusoid to match y = sin(2*pi* (0:N-1)' * (FracPeriod/N)) + sqrt(0.3) * randn(N,1); % y will contain the simulated sensor outputs
Используйте этот код для формирования матрицы Вандермонда:
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');
The 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: To view the report, open('codegen/exe/linsolveQR/html/report.mldatx').
При выполнении сгенерированного независимого исполняемого файла выходы вычисляются и записываются в файлы, разделенные запятыми. Считайте эти выходы назад в 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.checkGpuInstall
| coder.gpu.constantMemory
| coder.gpu.kernel
| coder.gpu.kernelfun
| gpucoder.matrixMatrixKernel
| gpucoder.stencilKernel