Ускорение матричных операций в сгенерированном автономном коде при помощи вызовов BLAS

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

Для вызовов BLAS в автономном коде MATLAB Coder использует указанную вами библиотеку BLAS. Укажите библиотеку BLAS, которая оптимизирована для вашего окружения выполнения.

Настройка библиотеки BLAS

Для генерации вызовов BLAS в автономном коде необходимо иметь доступ к классу коллбэка BLAS. Класс коллбэка BLAS задает библиотеку BLAS, файл заголовка CBLAS, некоторые типы данных C, используемые конкретным интерфейсом CBLAS, и опции компилятора и линкера для процесса сборки. Выполните одно из следующих действий:

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

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

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

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

Класс коллбэка должен быть выведен из абстрактного класса coder.BLASCallback. Этот пример является реализацией класса коллбэка mklcallback для интегрирования с библиотекой Intel MKL BLAS в Windows® платформы.

classdef mklcallback < coder.BLASCallback
    methods (Static)
        function updateBuildInfo(buildInfo, ~)
            libPath = fullfile(pwd,'mkl','WIN','lib','intel64');
            libPriority = '';
            libPreCompiled = true;
            libLinkOnly = true;
            libs = {'mkl_intel_ilp64.lib' 'mkl_intel_thread.lib' 'mkl_core.lib'};
            buildInfo.addLinkObjects(libs, libPath, libPriority, libPreCompiled, ...
                                  libLinkOnly);
            buildInfo.addLinkObjects('libiomp5md.lib',fullfile(matlabroot,'bin', ...
                             'win64'), libPriority, libPreCompiled, libLinkOnly);
            buildInfo.addIncludePaths(fullfile(pwd,'mkl','WIN','include'));
            buildInfo.addDefines('-DMKL_ILP64');
        end
        function headerName = getHeaderFilename()
            headerName = 'mkl_cblas.h';
        end
        function intTypeName = getBLASIntTypeName()
            intTypeName = 'MKL_INT';
        end
    end
end

Вы должны предоставить getHeaderFilename, getBLASIntTypeName, и updateBuildInfo методы. The getHeaderFilename метод возвращает имя файла заголовка CBLAS. Если вы используете другую библиотеку BLAS, замените mkl_cblas.h с именем файла заголовка CBLAS. The getBLASIntTypeName метод возвращает имя целочисленного типа данных, используемого интерфейсом CBLAS. Если вы используете другую библиотеку BLAS, замените MKL_INT с именем целочисленного типа данных, характерного для интерфейса CBLAS. The updateBuildInfo метод предоставляет информацию, необходимую для соединения процесса сборки с библиотекой BLAS. Используйте код, подобный коду в классе обратного коллбэка примера, чтобы указать местоположение файла заголовка, полное имя пути библиотеки BLAS и опции компилятора и линкера. Если вы используете библиотеку Intel MKL BLAS, используйте ссылку линии advisor, чтобы увидеть, какие библиотеки и опции компилятора рекомендованы для использования.

Существует три других метода, которые уже реализованы в coder.BLASCallback. Эти методы getBLASDoubleComplexTypeName, getBLASSingleComplexTypeName, и useEnumNameRatherThanTypedef. По умолчанию ваш класс коллбэка наследует эти реализации от coder.BLASCallback. В определенных ситуациях необходимо переопределить эти методы собственными определениями, когда вы задаете свой класс коллбэка.

The getBLASDoubleComplexTypeName метод возвращает тип, используемый для комплексных переменных двойной точности в сгенерированном коде. Если библиотека BLAS принимает тип, отличный от double* и void* для аргументов комплексного массива двойной точности включите этот метод в определение класса коллбэка.

function doubleComplexTypeName = getBLASDoubleComplexTypeName()
doubleComplexTypeName = 'my_double_complex_type';
end

Замените my_double_complex_type с типом, который библиотека BLAS принимает для аргументов комплексного массива двойной точности.

The getBLASSingleComplexTypeName метод возвращает тип, используемый для комплексных переменных с одной точностью в сгенерированном коде. Если библиотека BLAS принимает тип, отличный от float* и void* для аргументов комплексного массива с одной точностью включите этот метод в определение класса коллбэка.

function singleComplexTypeName = getBLASSingleComplexTypeName()
doubleComplexTypeName = 'my_single_complex_type';
end

Замените my_single_complex_type с типом, который библиотека BLAS принимает для аргументов комплексного массива с одной точностью.

The useEnumNameRatherThanTypedef метод возвращает false по умолчанию. Если типы для перечислений в библиотеке BLAS, включают enum ключевое слово, переопределите этот метод, чтобы вернуться true в определении класса коллбэка.

function p = useEnumNameRatherThanTypedef()
p = true;
end

Отрывок из сгенерированного исходного кода C, который включает enum ключевое слово:

enum CBLAS_SIDE t;
enum CBLAS_UPLO b_t;
double temp;
enum CBLAS_TRANSPOSE c_t;
enum CBLAS_DIAG d_t;

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

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

  1. Написание функции MATLAB, которая вызывает функцию для основной операции матрицы. Например, напишите функцию myMultiply который умножает две матрицы A и B.

    function C = myMultiply(A,B) %#codegen
    C = A*B;
    end

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

    cfg = coder.config('dll');
  3. Задайте класс коллбэка BLAS useMyBLAS.

    cfg.CustomBLASCallback = 'useMyBLAS';

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

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

    codegen myMultiply -args {zeros(1000),zeros(1000)} -config cfg -report

    Если A и B достаточно большие, генератор кода производит вызов BLAS для функции матричного умножения.

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

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

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

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

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

Чтобы задать rpath опция linker, используйте информацию о сборке addLinkFlags метод в updateBuildInfo метод класса коллбэка BLAS. Для примера, для компилятора GCC:

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

Указания и ограничения по применению библиотеки OpenBLAS

Если вы генерируете код, который включает вызовы функций библиотеки OpenBLAS, следуйте следующим рекомендациям и ограничениям:

  • Если вы генерируете код С++, который включает вызовы функций библиотеки OpenBLAS, компилируйте его с -pedantic опция выдает предупреждения. Чтобы отключить -pedantic опция компилятора, включите эти линии в updateBuildInfo метод:

    if ctx.getTargetLang() == 'C++'
        buildInfo.addCompileFlags('-Wno-pedantic');
    end
  • OpenBLAS не поддерживает стандарт C89/C90.

См. также

Похожие темы

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