Вызов функций BLAS и LAPACK

Можно вызвать LAPACK или функцию BLAS использование файла MEX. Чтобы создать файл MEX, вам нужны опыт программирования C/C++ или Фортрана и программные ресурсы (компиляторы и компоновщики), чтобы создать исполняемый файл. Также полезно понять, как использовать стандартные подпрограммы Фортрана. MATLAB® обеспечивает библиотеки mwlapack и mwblas в matlabroot /extern/lib. Чтобы помочь вам начать, существуют примеры исходного кода в matlabroot /extern/examples/refbook.

Вызывать функции BLAS или LAPACK:

  1. Создайте исходный файл MEX, содержащий стандартную программу шлюза mexFunction.

  2. Убедитесь, что у вас есть поддерживаемый компилятор для вашей платформы. Актуальный перечень поддерживаемых компиляторов см. на сайте «Поддерживаемые и совместимые компиляторы».

  3. Создайте бинарный файл MEX с помощью команды mex.

    • Соедините свой исходный файл с одним или обеими из библиотек, mwlapack и mwblas.

    • Библиотеки mwlapack и mwblas только поддерживают 64-битные целые числа для матричных размерностей. Не используйте опцию -compatibleArrayDims.

    • Чтобы создать файл MEX с функциями, которые используют комплексные числа, смотрите, что Передача Разделяет Комплексные числа к Функциям Фортрана.

Создайте MEX-функцию matrixMultiply Используя функции BLAS

Этот пример показывает, как создать файл MEX в качестве примера matrixMultiply.c, который использует функции от библиотеки BLAS. Чтобы работать с этим файлом, скопируйте его в локальную папку. Например:

copyfile(fullfile(matlabroot,'extern','examples','refbook','matrixMultiply.c'),'.')

Файлы в качестве примера являются файлами только для чтения. Чтобы изменить пример, гарантируйте, что файл перезаписываем путем ввода:

fileattrib('matrixMultiply.c','+w')

Чтобы создать файл MEX, введите:

mex -v matrixMultiply.c -lmwblas

Чтобы запустить файл MEX, введите:

A = [1 3 5; 2 4 7];
B = [-5 8 11; 3 9 21; 4 0 8];
X = matrixMultiply(A,B)
X =
    24    35   114
    30    52   162

Сохраните входные значения от модификации

Много LAPACK и функции BLAS изменяют значения аргументов, переданных им. Это - хорошая практика, чтобы сделать копию аргументов, которые можно изменить прежде, чем передать их этим функциям. Для получения информации о том, как MATLAB обрабатывает аргументы к mexFunction, см. Управление входным параметром и Выходные параметры.

Пример matrixDivide

Этот пример вызывает функцию LAPACK dgesv, который изменяет его входные параметры. Код в этом примере делает копии prhs[0] и prhs[1], и передает копии dgesv, чтобы сохранить содержимое входных параметров.

Чтобы видеть пример, откройте matrixDivide.c в редакторе MATLAB. Чтобы создать файл MEX, скопируйте исходный файл в перезаписываемую папку.

copyfile(fullfile(matlabroot,'extern','examples','refbook','matrixDivide.c'),'.')

Чтобы создать файл, введите:

mex -v matrixDivide.c -lmwlapack

Чтобы протестировать, введите:

A = [1 2; 3 4];
B = [5; 6];
X = matrixDivide(A,B)
X =
   -4.0000
    4.5000

Передайте аргументы функциям Фортрана из программ C/C++

LAPACK и функции BLAS написаны в Фортране. C/C++ и Фортран используют различные соглашения для передающих аргументов к и от функций. Фортран функционирует аргументы передачи ссылкой, в то время как C/C++ функционирует аргументы передачи значением. Когда вы передаете значением, вы передаете копию значения. Когда вы передаете ссылкой, вы передаете указатель на значение. Ссылка является также адресом значения.

Когда вы вызываете стандартную подпрограмму Фортрана, как функция от LAPACK или BLAS, из программы C/C++, убедиться передать аргументы ссылкой. Чтобы передать ссылкой, предшествуйте аргументу с амперсандом (&), если тот аргумент уже не является ссылкой. Например, когда вы создаете матрицу с помощью функции mxGetDoubles, вы создаете ссылку на матрицу и не нуждаетесь в амперсанде перед аргументом.

В следующем фрагменте кода переменные m, n, p, one и zero нужен символ &, чтобы сделать их ссылкой. A переменных, B, C и chn являются указателями, которые являются ссылками.

/* pointers to input & output matrices*/
double *A, *B, *C;
/* matrix dimensions */
mwSignedIndex m,n,p;
/* other inputs to dgemm */
char *chn = "N";
double one = 1.0, zero = 0.0;

/* call BLAS function */
dgemm(chn, chn, &m, &n, &p, &one, A, &m, B, &p, &zero, C, &m);

Пример matrixMultiply

Пример matrixMultiply.c вызывает dgemm, передавая все аргументы ссылкой. Чтобы видеть исходный код, откройте matrixMultiply.c в редакторе MATLAB. Чтобы создать и запустить этот пример, смотрите Сборку matrixMultiply MEX-функция Используя Функции BLAS.

Передайте аргументы функциям Фортрана из программ Фортрана

Можно вызвать LAPACK и функции BLAS от файлов MEX Фортрана. Следующий пример берет две матрицы и умножает их путем вызова стандартного dgemm BLAS. Чтобы запустить пример, скопируйте код в редактор и назовите файл calldgemm.F F.

#include "fintrf.h"

      subroutine mexFunction(nlhs, plhs, nrhs, prhs)
      mwPointer plhs(*), prhs(*)
      integer nlhs, nrhs
      mwPointer mxcreatedoublematrix
      mwPointer mxgetpr
      mwPointer A, B, C
      mwSize mxgetm, mxgetn
      mwSignedIndex m, n, p
      mwSize numel
      double precision one, zero, ar, br
      character ch1, ch2
      
      ch1 = 'N'
      ch2 = 'N'
      one = 1.0
      zero = 0.0
      
      A = mxgetpr(prhs(1))
      B = mxgetpr(prhs(2))
      m = mxgetm(prhs(1))
      p = mxgetn(prhs(1))
      n = mxgetn(prhs(2))
      
      plhs(1) = mxcreatedoublematrix(m, n, 0.0)
      C = mxgetpr(plhs(1))
      numel = 1
      call mxcopyptrtoreal8(A, ar, numel)
      call mxcopyptrtoreal8(B, br, numel)
      
      call dgemm(ch1, ch2, m, n, p, one, %val(A), m,
     +           %val(B), p, zero, %val(C), m)
      
      return
      end

Соединитесь с библиотекой BLAS, которая содержит функцию dgemm.

mex -v -R2017b calldgemm.F -lmwblas

Измените имя функции в системах UNIX

Добавьте символ подчеркивания после имени функции при вызове LAPACK или функций BLAS в системе UNIX®. Например, чтобы вызвать dgemm, используйте:

dgemm_(arg1, arg2, ..., argn);

Или добавьте эти строки к своему исходному коду:

#if !defined(_WIN32)
#define dgemm dgemm_
#endif
Была ли эта тема полезной?