Чтобы повысить скорость выполнения кода, генерируемого для некоторых низкоуровневых векторных и матричных операций (например, умножения матриц) в автономном коде, укажите, что необходимо, чтобы MATLAB ® Coder™ генерировал вызовы BLAS. BLAS - это библиотека программного обеспечения для низкоуровневых векторных и матричных вычислений, которая имеет несколько высокооптимизированных реализаций для конкретных машин. Генератор кода использует интерфейс CBLAS C для BLAS. Если указано, что требуется генерировать вызовы BLAS, а входные массивы для матричных функций соответствуют определенным критериям, генератор кода создает вызовы BLAS. В противном случае генератор кода создает код для матричных функций.
Для вызовов BLAS в автономном коде MATLAB Coder использует указанную библиотеку BLAS. Укажите библиотеку BLAS, оптимизированную для среды выполнения.
Для генерации вызовов BLAS в автономном коде необходимо иметь доступ к классу обратного вызова BLAS. Класс обратного вызова BLAS определяет библиотеку BLAS, файл заголовка CBLAS, определенные типы данных C, используемые конкретным интерфейсом CBLAS, а также параметры компилятора и компоновщика для процесса построения. Выполните одно из следующих действий:
В командной строке задайте свойство объекта конфигурации кода CustomBLASCallback на имя класса обратного вызова.
В приложении MATLAB Coder установите для параметра Custom BLAS library callback имя класса обратного вызова.
Чтобы создать вызовы определенной библиотеки 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 методы. getHeaderFilename возвращает имя файла заголовка CBLAS. При использовании другой библиотеки BLAS замените mkl_cblas.h с именем файла заголовка CBLAS. getBLASIntTypeName возвращает имя целочисленного типа данных, используемого интерфейсом CBLAS. При использовании другой библиотеки BLAS замените MKL_INT с именем целочисленного типа данных, определенного для интерфейса CBLAS. updateBuildInfo предоставляет информацию, необходимую для процесса построения для связи с библиотекой BLAS. Используйте код, аналогичный коду в примере класса обратного вызова, чтобы указать расположение файла заголовка, полное имя пути к библиотеке BLAS и параметры компилятора и компоновщика. Если вы используете библиотеку Intel MKL BLAS, воспользуйтесь консультантом по ссылкам, чтобы узнать, какие библиотеки и параметры компилятора рекомендуются для вашего варианта использования.
Есть три других метода, которые уже реализованы в coder.BLASCallback. Эти методы: getBLASDoubleComplexTypeName, getBLASSingleComplexTypeName, и useEnumNameRatherThanTypedef. По умолчанию класс обратного вызова наследует эти реализации от coder.BLASCallback. В определенных ситуациях при определении класса обратного вызова необходимо переопределить эти методы собственными определениями.
getBLASDoubleComplexTypeName возвращает тип, используемый для комплексных переменных двойной точности в сгенерированном коде. Если библиотека BLAS принимает тип, отличный от double* и void* для аргументов сложного массива с двойной точностью включите этот метод в определение класса обратного вызова.
function doubleComplexTypeName = getBLASDoubleComplexTypeName() doubleComplexTypeName = 'my_double_complex_type'; end
Заменить my_double_complex_type с типом, который используется библиотекой BLAS для аргументов сложного массива с двойной точностью.
getBLASSingleComplexTypeName возвращает тип, используемый для комплексных переменных с одинарной точностью в сгенерированном коде. Если библиотека BLAS принимает тип, отличный от float* и void* для аргументов сложного массива с одинарной точностью включите этот метод в определение класса обратного вызова.
function singleComplexTypeName = getBLASSingleComplexTypeName() doubleComplexTypeName = 'my_single_complex_type'; end
Заменить my_single_complex_type с типом, который используется библиотекой BLAS для аргументов сложного массива с одинарной точностью.
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 useMyBLAS задает библиотеку BLAS, которую требуется использовать в данном примере.
Запишите функцию MATLAB, которая вызывает функцию для операции с базовой матрицей. Например, записать функцию myMultiply умножает две матрицы A и B.
function C = myMultiply(A,B) %#codegen C = A*B; end
Определите объект конфигурации кода для статической библиотеки, динамически связанной библиотеки или исполняемой программы. Например, определите объект конфигурации для динамически связанной библиотеки на платформе Windows.
cfg = coder.config('dll');Укажите класс обратного вызова BLAS useMyBLAS.
cfg.CustomBLASCallback = 'useMyBLAS';Класс обратного вызова должен находиться в пути MATLAB.
Создать код. Укажите, что входные данные A и B это 1000 на 1000 массивов двойников.
codegen myMultiply -args {zeros(1000),zeros(1000)} -config cfg -report
Если A и B достаточно велики, генератор кода производит вызов BLAS для функции умножения матрицы.
Библиотека BLAS должна быть доступна в среде выполнения. Если библиотека BLAS является общей, используйте переменные среды или параметры компоновщика, чтобы указать расположение библиотеки BLAS.
На платформе Windows измените переменную среды PATH.
На платформе Linux ® измените переменную среды LD_LIBRARY_PATH или используйте rpath вариант компоновщика.
На платформе macOS измените переменную среды DYLD_LIBRARY_PATH или используйте rpath вариант компоновщика.
Чтобы указать rpath linker, использовать информацию о построении addLinkFlags метод в updateBuildInfo метод класса обратного вызова BLAS. Например, для компилятора GCC:
buildInfo.addLinkFlags(sprintf('-Wl,-rpath,"%s"',libPath));
При создании кода, включающего вызовы функций библиотеки OpenBLAS, следуйте следующим инструкциям и ограничениям:
Если создается код C++, включающий вызовы функций библиотеки OpenBLAS, компилируйте его с помощью -pedantic выводит предупреждения. Как отключить -pedantic параметр компилятора, включить эти строки в updateBuildInfo способ:
if ctx.getTargetLang() == 'C++' buildInfo.addCompileFlags('-Wno-pedantic'); end
OpenBLAS не поддерживает стандарт C89/C90.