无法编译 MEX LAPACK 示例

Cannot compile MEX LAPACK example

总结

我正在尝试编写一些使用 LAPACK 的 MEX 文件,我想我应该先查看 MathWorks 提供的示例。

但是,我在编译它们时遇到了一些问题。将 [MATLAB root]/extern/examples/refbook 中的 matrixDivide.c 示例复制到工作目录后,我尝试构建一个 mex 文件,但失败并出现错误 undefined reference to `dgesv_'(其中 dgesv 是正在调用 LAPACK 例程)。

我能够构建一个不使用 LAPACK 的不同的 mex 示例 (timestwo.c)。

所以这是怎么回事?结尾的下划线有什么用?这个 memcpy 警告怎么样?

更多信息

我认为这与该用户遇到的问题非常相似: How can I use CLAPACK,BLAS or LAPACK in a mex file?

我已经用 MATLAB R2013b 和 R2014b 试过了。我在 64 位 Linux (RHEL 6) 上 运行,我的编译器是 gcc 4.4.7(这不是 MathWorks 推荐的版本,而是我能得到的最新版本)。

以下是我要编译的代码的相关部分:

  1 /*=========================================================
  2  * matrixDivide.c - Example for illustrating how to use 
  3  * LAPACK within a C MEX-file.
  4  *
  5  * X = matrixDivide(A,B) computes the solution to a 
  6  * system of linear equations A * X = B
  7  * using LAPACK routine DGESV, where 
  8  * A is an N-by-N matrix  
  9  * X and B are N-by-1 matrices.
 10  *
 11  * This is a MEX-file for MATLAB.
 12  * Copyright 2009-2010 The MathWorks, Inc.
 13  *=======================================================*/
 14 /* $Revision: 1.1.6.3 $ $Date: 2011/01/28 18:11:56 $ */
 15 
 16 #if !defined(_WIN32)
 17 #define dgesv dgesv_
 18 #endif
 19 
 20 #include "mex.h"
 21 #include "lapack.h"
 22 
 23 void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
 24 {

      [ snip ]

 73     /* Call LAPACK */
 74     dgesv(&m,&n,A2,&m,iPivot,B2,&p,&info);
 75     /* plhs[0] now holds X */
 76 
 77     mxDestroyArray(Awork);
 78     mxDestroyArray(mxPivot);
 79 }

这是失败的 mex 构建的输出:

>> mex -v -largeArrayDims matrixDivide.c
-> mexopts.sh sourced from directory (DIR = $MATLAB/bin)
   FILE = /sw/matlab/R2013b/bin/mexopts.sh
----------------------------------------------------------------
->    MATLAB                = /sw/matlab/R2013b
->    CC                    = gcc
->    CC flags:
         CFLAGS             = -ansi -D_GNU_SOURCE  -fexceptions -fPIC -fno-omit-frame-pointer -pthread
         CDEBUGFLAGS        = -g
         COPTIMFLAGS        = -O -DNDEBUG
         CLIBS              = -Wl,-rpath-link,/sw/matlab/R2013b/bin/glnxa64 -L/sw/matlab/R2013b/bin/glnxa64 -lmx -lmex -lmat -lm -lstdc++
         arguments          = 
->    CXX                   = g++
->    CXX flags:
         CXXFLAGS           = -ansi -D_GNU_SOURCE -fPIC -fno-omit-frame-pointer -pthread
         CXXDEBUGFLAGS      = -g
         CXXOPTIMFLAGS      = -O -DNDEBUG
         CXXLIBS            = -Wl,-rpath-link,/sw/matlab/R2013b/bin/glnxa64 -L/sw/matlab/R2013b/bin/glnxa64 -lmx -lmex -lmat -lm
         arguments          = 
->    FC                    = gfortran
->    FC flags:
         FFLAGS             = -fexceptions -fbackslash -fPIC -fno-omit-frame-pointer
         FDEBUGFLAGS        = -g
         FOPTIMFLAGS        = -O
         FLIBS              = -Wl,-rpath-link,/sw/matlab/R2013b/bin/glnxa64 -L/sw/matlab/R2013b/bin/glnxa64 -lmx -lmex -lmat -lm
         arguments          = 
->    LD                    = gcc
->    Link flags:
         LDFLAGS            = -pthread -shared -Wl,--version-script,/sw/matlab/R2013b/extern/lib/glnxa64/mexFunction.map -Wl,--no-undefined
         LDDEBUGFLAGS       = -g
         LDOPTIMFLAGS       = -O
         LDEXTENSION        = .mexa64
         arguments          = 
->    LDCXX                 = 
->    Link flags:
         LDCXXFLAGS         = 
         LDCXXDEBUGFLAGS    = 
         LDCXXOPTIMFLAGS    = 
         LDCXXEXTENSION     = 
         arguments          = 
----------------------------------------------------------------

-> gcc -c  -I/sw/matlab/R2013b/extern/include -I/sw/matlab/R2013b/simulink/include -DMATLAB_MEX_FILE -ansi -D_GNU_SOURCE  -fexceptions -fPIC -fno-omit-frame-pointer -pthread  -O -DNDEBUG  "matrixDivide.c"

In file included from matrixDivide.c:21:
/sw/matlab/R2013b/extern/include/lapack.h:6907:1: warning: "dgesv" redefined
matrixDivide.c:17:1: warning: this is the location of the previous definition
matrixDivide.c: In function `mexFunction':
matrixDivide.c:64: warning: incompatible implicit declaration of built-in function ?memcpy?
-> gcc -O -pthread -shared -Wl,--version-script,/sw/matlab/R2013b/extern/lib/glnxa64/mexFunction.map -Wl,--no-undefined -o  "matrixDivide.mexa64"  matrixDivide.o  -Wl,-rpath-link,/sw/matlab/R2013b/bin/glnxa64 -L/sw/matlab/R2013b/bin/glnxa64 -lmx -lmex -lmat -lm -lstdc++

matrixDivide.o: In function `mexFunction':
matrixDivide.c:(.text+0x1c6): undefined reference to `dgesv_'
collect2: ld returned 1 exit status

    mex: link of ' "matrixDivide.mexa64"' failed.

经过一番折腾,我发现了我的(相当初级的)错误。

您需要为链接器指定 -lmwlapack 选项(and/or -lmwblas,视情况而定):

mex -largeArrayDims -lmwlapack matrixDivide.c

甚至MathWorks page I was trying to follow along on上也这么说。 RTFM!