Ускорение линейной алгебры в сгенерированном автономном коде при помощи вызовов LAPACK

Чтобы улучшить скорость выполнения кода, сгенерированного для определенных функций линейной алгебры в автономном (библиотеке или исполняемой программе) коде, задайте, что вы хотите MATLAB® Coder™ для генерации вызовов LAPACK. LAPACK является программной библиотекой для числовой линейной алгебры. MATLAB Coder использует интерфейс LAPACKE C для LAPACK. Если вы задаете, что хотите сгенерировать вызовы LAPACK, и входные массивы для функций линейной алгебры соответствуют определенным критериям, генератор кода производит вызовы LAPACK. В противном случае генератор кода производит код для линейных алгебраических функций.

Для вызовов LAPACK в автономном коде MATLAB Coder использует указанную вами библиотеку LAPACK. Укажите библиотеку LAPACK, которая оптимизирована для вашего окружения выполнения. См. www.netlib.org/lapack/faq.html#_what_and_where_are_the_lapack_vendors_implementations.

Указание библиотеки LAPACK

Для генерации вызовов LAPACK в автономном коде необходимо иметь доступ к классу коллбэка LAPACK. Класс коллбэка LAPACK задает библиотеку LAPACK и файл заголовка LAPACKE для вызовов LAPACK. Чтобы указать, что необходимо сгенерировать вызовы LAPACK и использовать определенную библиотеку LAPACK, укажите имя класса коллбэка LAPACK.

  • В командной строке установите свойство объекта строения кода CustomLAPACKCallback на имя класса коллбэка.

  • В приложении MATLAB Coder установите Custom LAPACK library callback имя класса коллбэка.

Запись класса коллбэка LAPACK

Чтобы указать местоположение конкретной библиотеки LAPACK и файла заголовка LAPACKE, запишите класс коллбэка LAPACK. Совместное использование класса коллбэка с другими пользователями, которые хотят использовать эту библиотеку LAPACK для вызовов LAPACK в автономном коде.

Класс коллбэка должен быть выведен из абстрактного класса coder.LAPACKCallback. Используйте следующий пример класса коллбэка в качестве шаблона.

classdef useMyLAPACK < coder.LAPACKCallback
    methods (Static)
        function hn = getHeaderFilename()
            hn = 'mylapacke_custom.h';
        end
        function updateBuildInfo(buildInfo, buildctx)
            buildInfo.addIncludePaths(fullfile(pwd,'include'));
            libName = 'mylapack';
            libPath = fullfile(pwd,'lib');
            [~,linkLibExt] = buildctx.getStdLibInfo();
            buildInfo.addLinkObjects([libName linkLibExt], libPath, ...
                '', true, true);
            buildInfo.addDefines('HAVE_LAPACK_CONFIG_H');
            buildInfo.addDefines('LAPACK_COMPLEX_STRUCTURE');
            buildInfo.addDefines('LAPACK_ILP64'); 
        end
    end
end

Вы должны предоставить getHeaderFilename и updateBuildInfo методы. getHeaderFilename метод возвращает имя файла заголовка LAPACKE. В примере класса коллбэка замените mylapacke_custom.h с именем файла заголовка LAPACKE. updateBuildInfo метод предоставляет информацию, необходимую для соединения процесса сборки с библиотекой LAPACK. Используйте код, подобный коду в шаблоне, чтобы указать местоположение заголовочных файлов и полное имя пути библиотеки LAPACK. В примере класса коллбэка замените mylapack с именем библиотеки LAPACK.

Если ваш компилятор поддерживает только комплексные данные типа, которые представлены в виде структур, включите эти линии в updateBuildInfo способ.

buildInfo.addDefines('HAVE_LAPACK_CONFIG_H');
buildInfo.addDefines('LAPACK_COMPLEX_STRUCTURE');

Необходимо указать целые типы, которые использует библиотека LAPACK. Отсутствие указания этого целого типа может привести к неправильному поведению или сбоям. Выполните одно из следующих действий:

  • Включите эти линии в updateBuildInfo способ.

    buildInfo.addDefines('HAVE_LAPACK_CONFIG_H');
    buildInfo.addDefines('LAPACK_ILP64');

  • Кроме того, можно непосредственно задать целый тип, который использует библиотека LAPACK. Для примера, если целый тип long long, включите эту линию в updateBuildInfo способ.

    buildInfo.addDefines('lapack_int=long long');

Сгенерируйте вызовы LAPACK путем определения класса коллбэка LAPACK

В этом примере показано, как сгенерировать код, который вызывает функции LAPACK в определенной библиотеке LAPACK. В данном примере предположим, что класс коллбэка LAPACK useMyLAPACK задает библиотеку LAPACK, которую необходимо использовать.

  1. Написание функции MATLAB, которая вызывает линейную алгебру. Для примера напишите функцию mysvd который вызывает функцию MATLAB svd.

    function s = mysvd(A)
        %#codegen
        s = svd(A);
    end

  2. Задайте объект строения кода для статической библиотеки, динамически связанной библиотеки или исполняемой программы. Например, задайте объект строения для динамически связанной библиотеки в Windows® платформы.

    cfg = coder.config('dll');

  3. Задайте класс коллбэка LAPACK useMyLAPACK.

    cfg.CustomLAPACKCallback = 'useMyLAPACK';

    Класс коллбэка должен находиться в пути MATLAB.

  4. Сгенерируйте код. Задайте, что входной A - это массив типа double 500 на 500.

    codegen mysvd -args {zeros(500)} -config cfg -report

Если A достаточно велик, генератор кода производит вызов LAPACK для svd. Вот пример вызова функции LAPACK Library для svd.

info_t = LAPACKE_dgesvd(LAPACK_COL_MAJOR, 'N', 'N', (lapack_int)500,
    (lapack_int)500, &A[0], (lapack_int)500, &S[0], NULL, (lapack_int)1, NULL,
    (lapack_int)1, &superb[0]);

Поиск библиотеки LAPACK в среде выполнения

Библиотека LAPACK должна быть доступна в среде выполнения. Если библиотека LAPACK является общей, используйте переменные окружения или опции линкера, чтобы задать расположение библиотеки LAPACK.

  • На платформе Windows измените переменный ПУТЬ окружения.

  • На Linux® платформы, измените переменную окружения LD_LIBRARY_PATH или используйте rpath опция linker.

  • На платформе macOS измените переменную окружения DYLD_LIBRARY_PATH или используйте rpath опция linker.

Чтобы задать rpath опция linker, вы можете использовать информацию о сборке addLinkFlags метод в updateBuildInfo метод вашего coder.LAPACKCallback класс. Для примера, для компилятора GCC:

buildInfo.addLinkFlags(sprintf('-Wl,-rpath,"%s"',libPath));

См. также

Похожие темы

Внешние веб-сайты