macos - 在 Mac 上的 Matlab 中使用 mex 进行 Openmp

标签 macos matlab gcc openmp mex

我有 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 更新
  • MATLAB 2016b 将构建配置和其他文件存储在用户主文件夹中的 /Users/username/Library/Application Support/MathWorks/MATLAB/R2016b 而不是 .matlab/R*/ 中(检查 prefdir )。
  • 如果使用上述设置,
  • MATLAB 在更新到 macOS 10.12 后会在启动时崩溃。要使其立即工作,只需注释掉 LDPATH_PREFIX 中的 ~/.matlab7rc.sh 行。实际上,对于 OS、LDPATH_PREFIX 和 MATLAB
  • 的这种组合,应该不需要 clang
  • 我发现我必须重新安装 llvm : brew reinstall llvm
  • MATLAB 带有自己的 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 。所以我的 CXXFLAGSLDFLAGS 现在读取
    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/

    相关文章:

    c - 为什么我可以用 GCC 制作的最小编译 exe 是 67KB?

    c++ - macOS 上使用 cpptools 1.71.1+ : When trying to compile code in C++, 的 VS Code "-std=gnu++14"出现在所有标志之前。怎么删除呢?

    macos - 在 Mac 上启动 postgres 服务器

    linux - 终端命令进行延时拍摄,如何在 X 时间后停止?

    java - 如何在 OS X 上的 Java 中设置 DSCP 字节

    linux - 用于在 Octave 中的结构中导航字段的 GUI?

    linux - 如何卸载从源代码安装的 gcc?

    matlab - 有没有办法在 matlab 中使用哈希表/ HashMap ?

    c++ - 使用 MATLAB 'dos' 命令调用并行化可执行文件的行为不同于独立可执行文件

    c++ - 在编译时使用注释自动包装 C/C++ 函数