在Mac上的Matlab中使用mex进行Open操作

时间:2016-05-21 11:38:09

标签: macos matlab gcc openmp mex

我有OS X El Capitan和Matlab R2016a,我想使用以前有效的OpenMP。我已经设法通过自制软件安装gcc-5并在那里运行openmp。我可以从这个帖子GCC C/C++ MEX Matlab R2015 Mac OS X (with OpenMP) doesn't work看到,至少在R2014a中,可以手动插入mexopts.sh并进行编辑。但是,我没有使用这样的文件来重定向编译器标志(CC)以指向与-fopenmp标志一起使用的gcc-5编译器。

有什么建议吗?我完全走错了路吗?

1 个答案:

答案 0 :(得分:5)

更新macOS 10.12,MATLAB 2016b: 以下的一般原则仍然适用。向下滚动以查看我必须进行的更改。

clang已更新为包含OpenMP支持,但是,随Xcode 7.3.1安装的版本尚不支持OpenMP。相反,它可以与homebrew一起安装。使用previous solutionclang-omp不再有效,因为clang-omp已从brew中移除。

以下过程已经过Mac OS X 10.11.6,clang 3.8.1,MATLAB 2016a测试。

安装llvm

llvm(来自brew)安装当前版本的Terminal

brew install llvm

修改MATLAB构建配置

然后,将默认的mex编译器配置文件复制到MATLAB配置目录中。要查找默认配置,请在MATLAB提示符下输入mex -setup C++。一个选项应该是类似

的内容
  

Xcode Clang++ mex -setup:/Applications/Matlab/MATLAB_R2016a/MATLAB_R2016a.app/bin/maci64/mexopts/clang++_maci64.xml C++

(此处和之后我们将假设MATLAB 2016a是使用的版本)。 将/Applications/Matlab/MATLAB_R2016a/MATLAB_R2016a.app/bin/maci64/mexopts/clang++_maci64.xml复制到~/.matlab/R2016a,并将其命名为clang++_openmp_maci64.xml,以便能够将其区分开来。在文本编辑器中打开clang++_openmp_maci64.xml并按如下所示进行修改: 在开始时,为名称等输入不同的值,再次能够区分它们:

Name="LLVM Clang++ OpenMP"
ShortName="Clang++ OpenMP"
Manufacturer="LLVM"

CXX的定义更改为指向与clang一起安装的brew的位置。在默认位置,这应该是

CXX="/usr/local/opt/llvm/bin/clang++"

-fopenmp -Wall -I/usr/local/opt/llvm/include添加到CXXFLAGS,因此会读取

CXXFLAGS="-fno-common -arch x86_64 -mmacosx-version-min=$SDKVER -fexceptions -isysroot $ISYSROOT -fobjc-arc -std=c++11 -stdlib=libc++ -fopenmp -Wall -I/usr/local/opt/llvm/include"

-L/usr/local/opt/llvm/lib -Wl,-rpath,/usr/local/opt/llvm/lib -fopenmp添加到LDFLAGS,以便与

类似
LDFLAGS="-Wl,-twolevel_namespace -undefined error -arch x86_64 -mmacosx-version-min=$SDKVER -Wl,-syslibroot,$ISYSROOT -framework Cocoa $LDBUNDLE $LINKEXPORT -stdlib=libc++ -L/usr/local/opt/llvm/lib -Wl,-rpath,/usr/local/opt/llvm/lib -fopenmp"

要激活此构建配置,请在MATLAB提示符下输入:

mex -setup:~/.matlab/R2016a/clang++_openmp_maci64.xml C++

修改MATLAB运行时变量

现在,MATLAB必须在运行时了解库的位置。检查您是否有文件~/.matlab7rc.sh。如果没有,请将模板从matlabroot/bin复制到您的主目录中。 在文本编辑器中打开此文件。向下滚动到mac|maci|maci64)部分(第188行)。将/usr/local/opt/llvm/lib添加到LDPATH_PREFIX,以便可以阅读

LDPATH_PREFIX='/usr/local/opt/llvm/lib'

重启MATLAB。

测试配置

创建包含

的文件mex_par_test.cpp
#include "mex.h"
#if defined(_OPENMP)
#include <omp.h>
#endif
void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
#if defined(_OPENMP)
    if (nrhs > 0) {
        omp_set_num_threads(mxGetScalar(prhs[0]));
    }
    {
        mexPrintf("If parallel processing is enabled, you should see the line\n\"Hello world from thread x\", where 'x' represents a thread number.\nThere will be %i threads in parallel.\n\n", omp_get_max_threads());
#pragma omp parallel
        {
#pragma omp critical
            mexPrintf("Hello world from thread %i.\n", omp_get_thread_num());
        }
    }
#else
    mexPrintf("SSIMS Toolbox was not compiled with support for parallelization.\n\n");
#endif
}

这应该在MATLAB提示符下编译:

mex mex_par_test.cpp
  

Building with 'LLVM Clang++ OpenMP'. MEX completed successfully.

使用mex_par_test调用已编译的函数应该会产生类似

的内容
  

如果启用了并行处理,您应该看到&#34; Hello行   来自线程x&#34;的世界,其中&#39; x&#39;代表一个线程号。这里将   并行12个线程。

     

Hello world from thread 0. Hello world from thread 3. Hello world from thread 8. Hello world from thread 1. Hello world from thread 2. Hello world from thread 11. Hello world from thread 4. Hello world from thread 7. Hello world from thread 10. Hello world from thread 9. Hello world from thread 5. Hello world from thread 6.

macOS 10.12,MATLAB 2016b

的更新
  • MATLAB 2016b将构建配置和其他文件存储在/Users/username/Library/Application Support/MathWorks/MATLAB/R2016b而不是.matlab/R*/的用户主文件夹中(检查prefdir)。
  • 如果使用了上述设置,则在更新到macOS 10.12后,MATLAB在启动时崩溃。要立即开始工作,只需在LDPATH_PREFIX中注释掉~/.matlab7rc.sh行。实际上,对于OS,LDPATH_PREFIX和MATLAB
  • 的组合,不应该需要clang
  • 我发现我必须重新安装llvmbrew reinstall llvm
  • MATLAB附带了自己的libiomp5版本,应该与之相关联。更改构建配置XML(clang++_openmp_maci64.xml),以便-fopenmp的每个事件都替换为-fopenmp=libiomp5。在每次-L$MATLABROOT/sys/os/maci64出现之前添加-L/usr/local/opt/llvm/lib。最后,链接器选项应为-Wl,-rpath,$MATLABROOT/sys/os/maci64:/usr/local/opt/llvm/lib而不是-Wl,-rpath,/usr/local/opt/llvm/lib。因此,我的CXXFLAGSLDFLAGS现已阅读

    CXXFLAGS="-fno-common -arch x86_64 -fexceptions -fobjc-arc -std=c++11 -stdlib=libc++ -fopenmp=libiomp5 -Wall -I/usr/local/opt/llvm/include"
    LDFLAGS="-Wl,-twolevel_namespace -undefined error -arch x86_64 -Wl $LDBUNDLE $LINKEXPORT -stdlib=libc++ -L$MATLABROOT/sys/os/maci64 -L/usr/local/opt/llvm/lib -Wl,-rpath,$MATLABROOT/sys/os/maci64:/usr/local/opt/llvm/lib -fopenmp=libiomp5"
    

这应该使上面的例子再次编译,也不会使MATLAB崩溃。