调用 LAPACK 和 BLAS 函数
您可以使用 MEX 文件调用 LAPACK 或 BLAS 函数。要创建 MEX 文件,您需要具备 C/C++ 或 Fortran 编程经验以及软件资源(编译器和链接器)来编译一个可执行文件。了解如何使用 Fortran 子例程也很有帮助。MATLAB® 在 matlabroot
/extern/lib
中提供了 mwlapack
和 mwblas
。为帮助您快速入门,matlabroot
/extern/examples/refbook
中提供了源代码示例。
要调用 LAPACK 或 BLAS 函数,请执行下列操作:
创建包含
mexFunction
入口例程的源 MEX 文件。确保您所用的编译器受平台支持。有关支持的编译器的最新列表,请参阅支持和兼容的编译器。
使用
mex
命令加上分离式复矩阵编译标志-R2017b
编译二进制 MEX 文件。将源文件链接到库
mwlapack
或mwblas
,或者同时链接到两者。mwlapack
和mwblas
库仅支持 64 位整数作为矩阵维度。请勿使用-compatibleArrayDims
选项。要通过使用复数的函数编译 MEX 文件,请参阅Pass Separate Complex Numbers to Fortran Functions。
有关 BLAS 或 LAPACK 函数的信息,请参阅 https://netlib.org/blas/ 或 https://netlib.org/lapack/。
使用 BLAS 函数编译 matrixMultiply
MEX 函数
此示例说明如何使用 BLAS 库中的函数编译示例 MEX 文件 matrixMultiply.c
。要使用此文件,请将其复制到一个本地文件夹。例如:
copyfile(fullfile(matlabroot,'extern','examples','refbook','matrixMultiply.c'),'.')
示例文件是只读文件。要修改示例,请通过键入以下命令确保该文件是可写的:
fileattrib('matrixMultiply.c','+w')
要编译 MEX 文件,请键入:
mex -v -R2017b 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 -R2017b 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
函数创建矩阵时,您可以创建对矩阵的引用,不需要在参量前使用 & 符号。
在以下代码段中,变量 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
,即按引用传递所有参量。要查看源代码,请在 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