调用 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