本页对应的英文页面已更新,但尚未翻译。 若要查看最新内容,请点击此处访问英文页面。

调用 LAPACK 和 BLAS 函数

您可以使用 MEX 文件调用 LAPACK 或 BLAS 函数。要创建 MEX 文件,您需要具备 C/C++ 或 Fortran 编程经验以及软件资源(编译器和链接器)来编译一个可执行文件。了解如何使用 Fortran 子例程也很有帮助。MATLAB®matlabroot/extern/lib 中提供了 mwlapackmwblas。为帮助您快速入门,matlabroot/extern/examples/refbook 中提供了源代码示例。

要调用 LAPACK 或 BLAS 函数,请执行下列操作:

  1. 创建包含 mexFunction 入口例程的源 MEX 文件。

  2. 确保您所用的编译器受平台支持。 有关支持的编译器的最新列表,请参阅支持和兼容的编译器网站。

  3. 使用 mex 命令编译一个二进制 MEX 文件。

    • 将源文件链接到库 mwlapackmwblas,或者同时链接到两者。

    • mwlapackmwblas 库仅支持 64 位整数作为矩阵维度。请勿使用 -compatibleArrayDims 选项。

    • 要通过使用复数的函数编译 MEX 文件,请参阅Pass Separate Complex Numbers to Fortran Functions

使用 BLAS 函数编译 matrixMultiply MEX 函数

此示例说明如何使用 BLAS 库中的函数编译示例 MEX 文件 matrixMultiply.c。要使用此文件,请将其复制到一个本地文件夹。例如:

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 的参数的信息,请参阅Managing Input and Output Parameters

matrixDivide 示例

此示例调用 LAPACK 函数 dgesv,该函数会修改其输入参数。此示例中的代码会制作 prhs[0]prhs[1] 的副本,并将副本传递给 dgesv 以保留输入参数的内容。

要查看该示例,请在 MATLAB 编辑器中打开 matrixDivide.c。要创建 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++ 程序传递给 Fortran 函数

LAPACK 和 BLAS 函数是用 Fortran 编写的。C/C++ 和 Fortran 使用不同约定在函数之间传递参数。Fortran 函数通过引用传递参数,而 C/C++ 函数通过值传递参数。当通过值传递参数时,传递的是值的副本。当通过引用传递参数时,传递的是值的指针。引用也就是值的地址。

当您从 C/C++ 程序调用 Fortran 子例程(如来自 LAPACK 或 BLAS 的函数)时,请务必通过引用传递参数。要通过引用传递参数,请在参数前面使用“与”符号 (&),除非该参数本身已是引用。例如,使用 mxGetDoubles 函数创建矩阵时,您可以创建对矩阵的引用,不需要在参数前使用 & 符号。

在以下代码段中,变量 mnponezero 需要 & 字符使其变为引用。变量 ABCchn 是指针,它们是引用。

/* 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,即通过引用传递所有参数。要查看源代码,请在 MATLAB 编辑器中打开 matrixMultiply.c。要编译并运行此示例,请参阅使用 BLAS 函数编译 matrixMultiply MEX 函数

将参数从 Fortran 程序传递给 Fortran 函数

您可以从 Fortran MEX 文件中调用 LAPACK 和 BLAS 函数。以下示例使用两个矩阵,并通过调用 BLAS 例程 dgemm 将这两个矩阵相乘。要运行该示例,请将代码复制到编辑器中并将文件命名为 calldgemm.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 系统上修改函数名称

在 UNIX® 系统上调用 LAPACK 或 BLAS 函数时,在函数名称后面添加下划线字符。例如,要调用 dgemm,请使用:

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

或者将以下行添加到您的源代码中:

#if !defined(_WIN32)
#define dgemm dgemm_
#endif