在mac上使用mex在Matlab中打开 [英] Openmp with mex in Matlab on mac
问题描述
我有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
$ p $然后复制一个默认的
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
toLDFLAGS = - 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
〜/ .matlab7rc.sh
中的 LDPATH_PREFIX
行。实际上,这个OS组合, clang
和MATLAB LDPATH_PREFIX
$ b llvm
: brew reinstall llvm
MATLAB自带版本的 libiomp5
,这应该与之相关联。改变你的构建配置XML( clang ++ _ openmp_maci64.xml
),这样每一个 -fopenmp
code> -fopenmp = libiomp5 。在每次出现 -L / usr / local / opt / llvm / lib $ c之前添加
-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 (checkprefdir
). - 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 myCXXFLAGS
andLDFLAGS
now readCXXFLAGS="-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屋!