Sup*_*ker 3 macos matlab gcc openmp mex
我有OS X El Capitan和Matlab R2016a,我想使用之前有效的OpenMP.我已经设法通过自制软件安装gcc-5并在那里运行openmp.我可以从这个线程中看到GCC C/C++ MEX Matlab R2015 Mac OS X(带有OpenMP)至少在R2014a中不起作用,可以手动插入mexopts.sh并进行编辑.但是,我没有使用这样的文件来重定向编译器标志(CC)以指向与-fopenmp标志一起使用的gcc-5编译器.
有什么建议?我完全走错了路吗?
更新macOS 10.12,MATLAB 2016b:以下 的一般原则仍然适用.向下滚动以查看我必须进行的更改.
clang已更新为包含OpenMP支持,但是,随Xcode 7.3.1安装的版本尚不支持OpenMP.相反,它可以安装homebrew.在以前的解决方案使用clang-omp不工作了,因为clang-omp已移出brew.
以下过程已使用Mac OS X 10.11.6,clang 3.8.1,MATLAB 2016a进行了测试.
llvm安装当前版本的llvmfrom brew(from Terminal):
brew install llvm
Run Code Online (Sandbox Code Playgroud)
然后,将默认mex编译器配置文件复制到MATLAB配置目录.要查找默认配置,请mex -setup C++在MATLAB提示符下输入.一个选项应该是这样的
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"
Run Code Online (Sandbox Code Playgroud)
将定义更改CXX为指向clang安装的位置brew.在默认位置,这应该是
CXX="/usr/local/opt/llvm/bin/clang++"
Run Code Online (Sandbox Code Playgroud)
添加-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"
Run Code Online (Sandbox Code Playgroud)
添加-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"
Run Code Online (Sandbox Code Playgroud)
要激活此构建配置,请在MATLAB提示符下输入:
mex -setup:~/.matlab/R2016a/clang++_openmp_maci64.xml C++
Run Code Online (Sandbox Code Playgroud)
现在,MATLAB必须在运行时了解库的位置.检查您是否有文件~/.matlab7rc.sh.如果没有,请将模板复制matlabroot/bin到主目录中.在文本编辑器中打开此文件.向下滚动到该mac|maci|maci64)部分(第188行).添加/usr/local/opt/llvm/lib到LDPATH_PREFIX,所以它可能会读取
LDPATH_PREFIX='/usr/local/opt/llvm/lib'
Run Code Online (Sandbox Code Playgroud)
重启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
}
Run Code Online (Sandbox Code Playgroud)
这应该在MATLAB提示符下编译:
mex mex_par_test.cpp
Run Code Online (Sandbox Code Playgroud)
Building with 'LLVM Clang++ OpenMP'. MEX completed successfully.
调用编译的函数mex_par_test应该产生类似的东西
如果启用了并行处理,您应该看到"来自线程x的Hello world"行,其中"x"表示线程号.将有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.
/Users/username/Library/Application Support/MathWorks/MATLAB/R2016b而不是存储在.matlab/R*/用户的主文件夹中(检查prefdir).LDPATH_PREFIX行~/.matlab7rc.sh.事实上,LDPATH_PREFIXOS clang和MATLAB的这种组合不应该需要llvm:brew reinstall llvmMATLAB有自己的版本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.所以,我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/llvm/lib -Wl,-rpath,$MATLABROOT/sys/os/maci64:/usr/local/opt/llvm/lib -fopenmp=libiomp5"
Run Code Online (Sandbox Code Playgroud)这应该使上面的例子再次编译,也不会崩溃MATLAB.