问题
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?
回答1:
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
#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 (check prefdir).
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 my CXXFLAGS and LDFLAGS now read
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"
This should make the example above compile again and also not crash MATLAB.
来源:https://stackoverflow.com/questions/37362414/openmp-with-mex-in-matlab-on-mac