在mac上使用mex在Matlab中打开 [英] Openmp with mex in Matlab on mac

查看:256
本文介绍了在mac上使用mex在Matlab中打开的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

有什么建议吗?我完全错误的方式吗?

解决方案

更新macOS 10.12,MATLAB 2016b:
下面的一般原则依然如此。向下滚动查看我必须做出的更改。






clang has已更新为包含OpenMP支持,但是,随Xcode 7.3.1一起安装的版本不支持OpenMP。相反,它可以使用 homebrew 进行安装。使用以前的解决方案 .github.iorel =nofollow noreferrer> clang-omp 不再起作用,因为 clang-omp 已从 brew 中移除。



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



安装 llvm



brew (从 Terminal )安装当前版本的 llvm
$ b

  brew install llvm 
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
制造商=LLVM

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

  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 to

  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。
$ b

测试配置



创建一个文件 mex_par_test.cpp 包含

  #includemex.h
#if defined(_OPENMP)
#include
#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(如果启用了并行处理,您应该看到line \\\\来自线程x \的Hello world,其中'x'表示一个线程number.'nThere会有%i个线程并行。\ n \ n,omp_get_max_threads());
#pragma omp parallel
{
#pragma omp critical
mexPrintf(Hello world from thread%i.\\\
,omp_get_thread_num());


#else
mexPrintf(SSIMS工具箱没有编译支持并行化。\\\ n);
#endif
}

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

  mex mex_par_test.cpp 




使用'LLVM Clang ++ OpenMP'构建。
MEX已成功完成


使用 mex_par_test调用编译后的函数应该产生类似于


如果启用了并行处理,您应该看到Hello
世界从线程x,其中'x'代表线程号。


$ p $ 线程0中的Hello world。
线程中的Hello world 3. $
来自线程1的Hello world。
来自线程2的Hello world。
来自线程11的Hello world。
来自线程的Hello world 4. $
来自线程10的Hello World。
来自线程9的Hello world。
来自线程5的Hello world。
来自线程6的Hello World。




更新macOS 10.12,MATLAB 2016b




  • MATLAB 2016b在 / Users / username / Library / Application Support / MathWorks / MATLAB / R2016b 中存储配置和其他文件,而不是在$ (code> prefdir )。

  • .matlab / R * / >如果已经使用了上述设置,则在更新到macOS 10.12之后,MATLAB会在启动时崩溃。要立即使用它,只需注释〜/ .matlab7rc.sh 中的 LDPATH_PREFIX 行。实际上,这个OS组合, clang 和MATLAB
  • $ b不应该需要 LDPATH_PREFIX $ b
  • 我发现我必须重新安装 llvm brew reinstall llvm

  • MATLAB自带版本的 libiomp5 ,这应该与之相关联。改变你的构建配置XML( clang ++ _ openmp_maci64.xml ),这样每一个 -fopenmp code> -fopenmp = libiomp5 。在每次出现 -L / usr / local / opt / llvm / lib -L $ MATLABROOT / sys / os / maci64 $ C>。最后,链接器选项应该是 -Wl,-rpath,$ MATLABROOT / sys / os / maci64:/ usr / local / opt / llvm / lib 而不是 -Wl,-rpath,在/ usr /本地的/ opt / LLVM / lib中。所以我的 CXXFLAGS LDFLAGS 现在被读取

      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 /
    / lib / wl,-rpath,$ MATLABROOT / sys / os / maci64:/ usr / local / opt / llvm / >



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


I have OS X El Capitan and Matlab R2016a and I would like to use OpenMP, which has previously worked. I have managed to install gcc-5 via homebrew and have openmp working there. I can see from this thread GCC C/C++ MEX Matlab R2015 Mac OS X (with OpenMP) doesn't work that at least in R2014a, it was possible to insert mexopts.sh manually and edit it. However, I do not have such a file to use in order to redirect the compiler flag (CC) to point at the gcc-5 compiler that works with the -fopenmp flag.

Any suggestions? Am I going entirely the wrong way?

解决方案

Update for macOS 10.12, MATLAB 2016b: The general principle of the following still holds true. Scroll down for changes I had to make.


clang has been updated to include OpenMP support, however, the version installed with Xcode 7.3.1 does not support OpenMP yet. Instead, it can be installed with homebrew. The previous solution using clang-omp does not work anymore, because clang-omp has been removed from brew.

The following process has been tested with Mac OS X 10.11.6, clang 3.8.1, MATLAB 2016a.

Install llvm

Install the current version of llvm from brew (from Terminal):

brew install llvm

Modify MATLAB build configuration

Then, copy a default mex compiler configuration file to your MATLAB configuration directory. To find the default configuration, enter mex -setup C++ on your MATLAB prompt. One option should read something like

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

(Here and later we will assume MATLAB 2016a is the version used). Copy /Applications/Matlab/MATLAB_R2016a/MATLAB_R2016a.app/bin/maci64/mexopts/clang++_maci64.xml to ~/.matlab/R2016a, and name it clang++_openmp_maci64.xml to be able to tell it apart. Open clang++_openmp_maci64.xml in a text editor and modify it as follows: At the beginning, enter different values for name etc, again to be able to tell it apart:

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

Change the definition of CXX to point to the location of clang as installed with brew. At the default location, this should be

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

Add -fopenmp -Wall -I/usr/local/opt/llvm/include to CXXFLAGS, so it will read

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"

Add -L/usr/local/opt/llvm/lib -Wl,-rpath,/usr/local/opt/llvm/lib -fopenmp to LDFLAGS so it is similar to

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"

To activate this build configuration, enter at the MATLAB prompt:

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

Modify MATLAB runtime variables

Now, MATLAB has to know about the locations of the libraries at runtime. Check if you have a file ~/.matlab7rc.sh. If not, copy the template from matlabroot/bin into your home directory. Open this file in a text editor. Scroll down to the mac|maci|maci64) section (line 188 ff). Add /usr/local/opt/llvm/lib to LDPATH_PREFIX, so it might read

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

Restart MATLAB.

Test configuration

Create a file mex_par_test.cpp containing

#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
}

This should compile at the MATLAB prompt:

mex mex_par_test.cpp

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

Calling the compiled function with mex_par_test should yield something like

If parallel processing is enabled, you should see the line "Hello world from thread x", where 'x' represents a thread number. There will be 12 threads in parallel.

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.

Update for macOS 10.12, MATLAB 2016b

  • MATLAB 2016b stores build configurations and other files in /Users/username/Library/Application Support/MathWorks/MATLAB/R2016b rather than in .matlab/R*/ in the user's home folder (check prefdir).
  • MATLAB crashes on startup after update to macOS 10.12 if the setup described above has been used. To get it working immediately, just comment out the LDPATH_PREFIX line in ~/.matlab7rc.sh. In fact, LDPATH_PREFIX should not be needed for this combination of OS, clang, and MATLAB
  • I found I had to reinstall llvm: brew reinstall llvm
  • MATLAB comes with its own version of libiomp5, and this should be linked against. Change your build configuration XML (clang++_openmp_maci64.xml) so that every incidence of -fopenmp is replaced by -fopenmp=libiomp5. Add -L$MATLABROOT/sys/os/maci64 before each occurrence of -L/usr/local/opt/llvm/lib. Finally, linker options should be -Wl,-rpath,$MATLABROOT/sys/os/maci64:/usr/local/opt/llvm/lib instead of -Wl,-rpath,/usr/local/opt/llvm/lib. So my CXXFLAGS and LDFLAGS now read

    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"
    

This should make the example above compile again and also not crash MATLAB.

这篇关于在mac上使用mex在Matlab中打开的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆