В этом примере показано, как создать автономный исполняемый файл CUDA ®, использующий библиотеку CUDA Solver (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;
Используйте функцию linsolureQR для решения уравнения с помощью 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');
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