mac 在 Matlab 中使用 mex 的 Openmp
Openmp with mex in Matlab on mac
我有 OS X El Capitan 和 Matlab R2016a,我想使用 OpenMP,它以前工作过。我已经设法通过自制软件安装 gcc-5 并让 openmp 在那里工作。我可以从这个帖子 中看出,至少在 R2014a 中,可以手动插入 mexopts.sh 并对其进行编辑。但是,我没有这样的文件可用于重定向编译器标志 (CC) 以指向使用 -fopenmp 标志的 gcc-5 编译器。
有什么建议吗?我是不是完全走错了路?
Mac 更新OS 10.12,MATLAB 2016b:
以下的一般原则仍然适用。向下滚动以查看我必须做出的更改。
clang
已更新为包括 OpenMP 支持,但是,与 Xcode 7.3.1 一起安装的版本尚不支持 OpenMP。相反,它可以安装 homebrew
. The previous solution using clang-omp
不再起作用,因为 clang-omp
已从 brew
中删除。
以下过程已通过 Mac OS X 10.11.6, clang 3.8.1, MATLAB 2016a 测试。
安装llvm
从 brew
(从 Terminal
)安装当前版本的 llvm
:
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
的定义以指向与 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
所以它类似于
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 行 ff)。将 /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.
Mac 更新OS 10.12,MATLAB 2016b
- MATLAB 2016b 将构建配置和其他文件存储在
/Users/username/Library/Application Support/MathWorks/MATLAB/R2016b
而不是用户主文件夹的 .matlab/R*/
中(检查 prefdir
)。
- 如果使用上述设置,更新到 macOS10.12 后,MATLAB 会在启动时崩溃。要使其立即运行,只需注释掉
~/.matlab7rc.sh
中的 LDPATH_PREFIX
行。事实上,OS、clang
和 MATLAB 的这种组合不需要 LDPATH_PREFIX
- 我发现我必须重新安装
llvm
:brew reinstall llvm
MATLAB 有它自己的 libiomp5
版本,这应该被链接起来。更改您的构建配置 XML (clang++_openmp_maci64.xml
),以便 -fopenmp
的每个出现都被 -fopenmp=libiomp5
替换。在每次出现 -L/usr/local/opt/llvm/lib
之前添加 -L$MATLABROOT/sys/os/maci64
。最后,链接器选项应该是 -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 崩溃。
我有 OS X El Capitan 和 Matlab R2016a,我想使用 OpenMP,它以前工作过。我已经设法通过自制软件安装 gcc-5 并让 openmp 在那里工作。我可以从这个帖子
有什么建议吗?我是不是完全走错了路?
Mac 更新OS 10.12,MATLAB 2016b: 以下的一般原则仍然适用。向下滚动以查看我必须做出的更改。
clang
已更新为包括 OpenMP 支持,但是,与 Xcode 7.3.1 一起安装的版本尚不支持 OpenMP。相反,它可以安装 homebrew
. The previous solution using clang-omp
不再起作用,因为 clang-omp
已从 brew
中删除。
以下过程已通过 Mac OS X 10.11.6, clang 3.8.1, MATLAB 2016a 测试。
安装llvm
从 brew
(从 Terminal
)安装当前版本的 llvm
:
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
的定义以指向与 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
所以它类似于
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 行 ff)。将 /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.
Mac 更新OS 10.12,MATLAB 2016b
- MATLAB 2016b 将构建配置和其他文件存储在
/Users/username/Library/Application Support/MathWorks/MATLAB/R2016b
而不是用户主文件夹的.matlab/R*/
中(检查prefdir
)。 - 如果使用上述设置,更新到 macOS10.12 后,MATLAB 会在启动时崩溃。要使其立即运行,只需注释掉
~/.matlab7rc.sh
中的LDPATH_PREFIX
行。事实上,OS、clang
和 MATLAB 的这种组合不需要 - 我发现我必须重新安装
llvm
:brew reinstall llvm
MATLAB 有它自己的
libiomp5
版本,这应该被链接起来。更改您的构建配置 XML (clang++_openmp_maci64.xml
),以便-fopenmp
的每个出现都被-fopenmp=libiomp5
替换。在每次出现-L/usr/local/opt/llvm/lib
之前添加-L$MATLABROOT/sys/os/maci64
。最后,链接器选项应该是-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"
LDPATH_PREFIX
这应该使上面的示例再次编译并且不会使 MATLAB 崩溃。