我有 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 编译器。
有什么建议么?我完全走错路了吗?
最佳答案
macOS 10.12、MATLAB 2016b 的 更新:
以下的一般原则仍然成立。向下滚动以查看我必须做出的更改。clang
已更新为包含 OpenMP 支持,但是,随 Xcode 7.3.1 安装的版本尚不支持 OpenMP。相反,它可以与 homebrew
一起安装。使用 previous solution 的 clang-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 等输入不同的值,再次能够区分它:
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
调用编译函数应该会产生类似的结果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.
macOS 10.12、MATLAB 2016b 更新
/Users/username/Library/Application Support/MathWorks/MATLAB/R2016b
而不是 .matlab/R*/
中(检查 prefdir
)。 LDPATH_PREFIX
中的 ~/.matlab7rc.sh
行。实际上,对于 OS、LDPATH_PREFIX
和 MATLAB clang
llvm
: brew reinstall llvm
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"
这应该使上面的示例再次编译并且不会使 MATLAB 崩溃。
关于macos - 在 Mac 上的 Matlab 中使用 mex 进行 Openmp,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37362414/