DIPlib / diplib

Quantitative Image Analysis in C++, MATLAB and Python
https://diplib.org
Apache License 2.0
228 stars 50 forks source link

macOS build DIPimage crashes with OpenMP #101

Closed ronligt closed 1 year ago

ronligt commented 2 years ago

Component DIPimage Git commit ID: b819793c

Describe the bug Build DIPimage on macOS with Xcode clang++ and Homebrew libomp (all external libs Homebrew). When using build DIPimage in Matlab 2021b ft (FFTW is not used) crashes Matlab:

>> a = readim('erika.ics','')
Displayed in figure 10
>> b = ft(a,{},[])
OMP: Error #178: Function pthread_mutex_init failed:
OMP: System error #22: Invalid argument
OMP: Error #178: Function pthread_mutex_init failed:
OMP: System error #22: Invalid argument
OMP: Error #178: Function pthread_mutex_init failed:
OMP: System error #22: Invalid argument

To Reproduce As instructed in https://github.com/DIPlib/diplib/blob/master/INSTALL_MacOS.md#openmp libomp is installed with Homebrew. All other external dependencies are also installed with Homebrew. In make the Apple clang++ is configured. Building with make -j gives no errors and dipimage can be started in Matlab without warnings or errors. The following relevant libraries are linked:

$ otool -L libDIP.dylib
libDIP.dylib:
    @rpath/libDIP.dylib (compatibility version 0.0.0, current version 0.0.0)
    /usr/local/opt/libomp/lib/libomp.dylib (compatibility version 5.0.0, current version 5.0.0)
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1311.0.0)
    /usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 1200.3.0)

Note: when build with gcc-11 (Homebrew) Matlab does not crash and the ft is calculated! For this libDIP.dylib the linked libraries are:

$ otool -L /usr/local/lib/libDIP.dylib
/usr/local/lib/libDIP.dylib:
    @rpath/libDIP.dylib (compatibility version 0.0.0, current version 0.0.0)
    /usr/local/opt/gcc/lib/gcc/11/libgomp.1.dylib (compatibility version 2.0.0, current version 2.0.0)
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1311.0.0)
    /usr/local/opt/gcc/lib/gcc/11/libstdc++.6.dylib (compatibility version 7.0.0, current version 7.29.0)
    /usr/local/lib/gcc/11/libgcc_s.1.dylib (compatibility version 1.0.0, current version 1.0.0)

System information:

crisluengo commented 2 years ago

Could this be a compatibility issue with an OMP library used by MATLAB?

Are there other functions that also fail, or is it just ft?

ronligt commented 2 years ago

checking...

ronligt commented 2 years ago

That might be the problem!

check: https://nl.mathworks.com/matlabcentral/answers/237411-can-i-make-use-of-openmp-in-my-matlab-mex-files

And checking the OMP lib from Matlab:

$ cd /Applications/MATLAB_R2021b.app/sys/os/maci64
$ ❯ ls
README.libgfortran  libgfortran.3.dylib libifcore.dylib     libintlc.dylib      libirc.dylib
libgfortran.2.dylib libgfortran.dylib   libimf.dylib        libiomp5.dylib      libsvml.dylib

I will try to install the Intel oneAPI Base and HPC toolkit and see if I can use the libiomp5.dylib and header files in cmake.

Hold on...

crisluengo commented 2 years ago

MATLAB R2017a and R2018b both use that same libiomp5.dylib, and I don't have this problem in either of those.

But I'm also on Big Sur, so both my OS and my MATLAB are older.

crisluengo commented 2 years ago

Try this: add the following lines somewhere inside the /Applications/MATLAB_R2021b.app/bin/matlab script (see this Stack Overflow answer):

export DYLD_PRINT_LIBRARIES=1
export DYLD_PRINT_LIBRARIES_POST_LAUNCH=1
export DYLD_PRINT_RPATHS=1

When you now start MATLAB from the terminal (by just running that script), you should see information about what libraries are loaded. You should probably ignore all of that for now. If you now run a DIPlib function, you should see in the terminal formation about the libraries loaded specifically for DIPlib. Does it load the /usr/local/opt/libomp/lib/libomp.dylib library?

ronligt commented 2 years ago

I've added the environment variables to the matlab-script and after calling a DIPlib function it did load the libomp.dylib library. At the startup of Matlab also the libiomp5.dylib was loaded...

I also tried building DIPlib with the Intel compiler using libiomp5. It failed however with the following error:

make[2]: *** [src/CMakeFiles/DIP.dir/library/framework_full.cpp.o] Error 2
make[2]: *** Waiting for unfinished jobs....
/Users/rligteringen/diplib/source/diplib/src/library/framework_scan.cpp(470): error: directive bound to nonblock
     #pragma omp parallel num_threads( static_cast< int >( nThreads ))

I did some digging with the error message directive bound to nonblock but could not find a solution. A simple openmp helloworld worked fine with icc -qopenmp.

Desperately also tried using the iomp5 library with clang to no avail...

Perhaps at this moment we're better off using gcc with libgomp for the macOS release?

crisluengo commented 2 years ago

"directive bound to nonblack" I guess means that the Intel compiler doesn't like

#pragma omp parallel num_threads( static_cast< int >( nThreads ))
try { ... }

but wants it to be

#pragma omp parallel num_threads( static_cast< int >( nThreads ))
{
   try { ... }
}

Silly!

Anyway, I don't see the point in using the Intel compiler here, distributing its runtime libraries is going to be as much of a hassle as distributing the GCC libraries, and we know the GCC compiler works just fine out of the box.

On the other hand, if it's only ft that has a problem, you could choose to only create a distribution with FFTW. I honestly think that the non-FFTW version of DIPlib is not useful in a MATLAB environment, MATLAB itself is already using FFTW anyway. If people want to distribute proprietary code that uses DIPlib, they can build DIPlib themselves.

crisluengo commented 2 years ago

I am having MATLAB crash on my M1 Mac when running a script… even if DIPimage is not even added to the path. Running a function is OK, running a script is not. Updated MATLAB to the latest release, R2022a, and it’s still happening.

I’ve also read that people are having trouble with the Image Processing Toolbox on M1. We’ll have to wait for a native M1 version of MATLAB. There’s a beta test version available already.

HenkMutsaerts commented 1 year ago

I'm running the Matlab R2022b beta version that is fully ARM64 on my Macbook M2 Pro now, and I also couldn't make this work. I can compile DIPlib, this all works fine, but when Matlab starts up it complains:


Warning: Executing startup failed in matlabrc.
This indicates a potentially serious problem in your MATLAB setup, which should be resolved as soon as possible.  Error detected was:
DIPimage does not currently support your version of MATLAB on your platform. Please see http://www.diplib.org/ 

Now I am able to use dip_image, it loads a 4D image correctly, but it doesn't handle the intensity correctly, I can measure values higher than 255 but the display thresholds the values at 255, and several function dependencies crash:

Error using dipshow
Undefined function 'dip_minimumpixel' for input arguments of type 'dip_image'.

Error while evaluating Menu Callback.

Error using dipshow
Undefined function 'dip_minimumpixel' for input arguments of type 'dip_image'.

Error while evaluating Menu Callback.

Error using dipshow
Undefined function 'dip_minimumpixel' for input arguments of type 'dip_image'.

Error while evaluating Menu Callback.

Error using dipshow
Undefined function 'dip_minimumpixel' for input arguments of type 'dip_image'.

Error while evaluating Menu Callback.

Unrecognized function or variable 'dip_minimumpixel'.

Error in dip_image/min (line 65)
            [position,value] = dip_minimumpixel(in1,in2,1);

Error in dipmapping

Error in dipmapping

Error while evaluating UIControl Callback.

Error using dipshow
Error using  *
Undefined function 'dip_arith' for input arguments of type 'dip_image'.

Error in dipmapping

Error in dipmapping

Error in dipmapping

Error while evaluating UIControl Callback.

And

Displayed in figure 1
Error using dip_image/max
Undefined function 'dip_maximum' for input arguments of type 'dip_image'.

Error in dipprojection

Error while evaluating Menu Callback.
crisluengo commented 1 year ago

@HenkMutsaerts It looks like you are running DIPimage 2.x. We never made a release for the new M1 ARM64 architecture, the last time we built a release for the 2.x branch was many years ago, before the M1 existed. The 2.x branch is no longer supported. FB I once built the current 3.x branch (this repo) for an M1 native MATLAB test demo that I had access to for a few weeks. It is possible and works well, though I needed to make some fixes to two of the scripts provided with MATLAB, I presume these things are fixed by now.

Please try to build the toolbox following the step-by-step instructions in the documentation. It is not hard, and requires only freely available tools. You don’t need to worry about the DIPviewer or DIPjavaio (Bio-formats interface) modules, nor anything related to Python — this removes the need for quite a few dependencies.

crisluengo commented 1 year ago

Closing because of inactivity.