New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Importing pyfftw and diplib in the same process can lead to segfaults #130
Comments
This is interesting. You're using the version of DIPlib on PyPI? It doesn't use FFTW at all! I don't understand what could be causing this. I would expect things like this if they both dynamically link to a different version of FFTW, which you could fix by ensuring that both use the same dynamic library. I will have to build pyFFTW myself to test this, since there's no version for Mac aarch64 on PyPI. |
Yes, this is with pypi's diplib. For example, I can repro this by creating a clean conda environment |
Following these steps
I do not get an error message on Ubuntu 22.04.2 LTS. |
I just came across this thread at random, but wanted to share: even if not both are using FFTW, there can be incompatibilities with libraries that emulate FFTW. This is done, for example, by MKL (using the FFTW-Wrappers) and CUDA (to some extent). Does this help? |
@emmenlau Thanks! If DIPlib doesn't link to FFTW, it uses PocketFFT, which is linked statically and is written in C++, so cannot have name clashes with C functions in FFTW. BTW: NumPy and SciPy both also use PocketFFT, and I've never had an issue with either of them because they both statically link it. |
I have finally been able to build pyFFTW (for some reason, the include directory was confusing @anntzer Just to be sure, if you don't import pyfftw, it all works as expected? |
Yes, even importing pyfftw after diplib makes the issue go away.
Ah, good point: doing this with homebrew's python 3.11 make the problem go away. Curious... |
The plot thickens! I will have to find some time to install Conda and seeing if I can reproduce this issue on my end. Are you using the Conda version of DIPlib? Could that fix the incompatibility? Someone here claims that it's not recommended to use |
AFAICT it is not available for M1 macs(?) |
I installed miniconda, and tried installing pyFFTW in a conda environment. Nothing I tried has worked. Homebrew's FFTW is the wrong OS version (?), and it wouldn't find Conda's FFTW. Anyway, if you have an FFTW that uses OpenMP, it might be a problem with two different OpenMP libraries loaded. DIPlib is distributed with its own copy of libomp.dylib. Your example code loads FFTW first, meaning it loads whatever version of OpenMP it uses. DIPlib is loaded later and crashes when trying to use a function that uses OpenMP. If you load the packages on the other order, it's DIPlib's version of OpenMP that is loaded, and the DIPlib function works fine. But does a pyFFTW function work in this case? |
The following works for me:
(Normally If it doesn't (and you have homebrew fftw installed), can you post the error message? Good point re: openmp, I haven't actually extensively tried running pyfftw after that (incl. trying to trigger some openmp-related code); I'll report once I get a chance to try. |
Thank you! That worked. Indeed, pyFFTW now links to 6 different FFTW libraries: for single, double and long floats, and for each of those, a serial and an OpenMP version. The OpenMP versions link to GGC's OpenMP library ( I'm fairly certain that this is what you are running into. Unfortunately, it seems I'm having no trouble using both of these at the same time. I still cannot reproduce the crash! Is it possible that these two OpenMP libraries don't interfere with each other at all, and you're seeing a different problem? I'm on macOS 12, maybe that makes a difference? |
(I am on macos 13.4.1.) |
You can build DIPlib without OpenMP by setting But we can’t really offer no-OpenMP wheels on PyPI. That would double the number of builds to make and complicate deployment. And I’m guessing few people would want to install a slower version of purpose. For people willing to build it themselves, it is possible to ensure all packages use the same OpenMP version. It does however make sense to add some warnings regarding vendored OpenMP and potential incompatibilities between packages because of that. Just because you’re the first to bring this to our attention doesn’t mean you’re the first to run into this issue — thank you for reporting! |
Thanks for your patience and helpfulness in investigating what is a rather obscure situation! Actually I remembered that threadpoolctl (https://pypi.org/project/threadpoolctl/) is very useful in these situations; upon further investigation I realized that I had things even more messed up in my conda environment: I had (some time ago) also installed fftw via conda; my build of pyfftw did not actually link it but (as shown by So I guess if you want to be extra-safe one option would be to add a dependency on threadpoolctl (which is pure python and has no extra dependencies) and check before importing the main library that there isn't already "another" libomp loaded (and I guess pyfftw could do something similar), but I'd totally also understand if you just close this as "too obscure". |
From the page linked above, copied here for future reference:
|
I made a note on the DIPlib home page, and (see the commit referenced above) on the README file that will be shown on PyPI with the next release. I think that is all we can do for now. |
I think the note is good enough; at least it gives something to google at, and I think most people running into these weird incompatibilities are somewhat likely to be building at least some of the packages themselves and more likely to be able to figure out the problem based on your writeup.
Assuming we could really pre-detect the incompatibility (which I agree seems to complex to be worth it), I guess you could just refuse to import diplib at all (and throw an ImportError with a suitable descriptive error message). |
If this becomes a more common issue, I will put in the effort for a better error message. It's a good idea. Thanks! |
Component
PyDIP 3.4.0.
Describe the bug
Importing pyfftw and diplib in the same process, and having diplib try to access its own internal fftw library, can lead to segfaults.
To Reproduce
(the array size above is just some awkward numbers to trigger the use of fftw)
System information:
ver
at the MATLAB command prompt, and copy-paste the result here). N/ANote: pyFFTW was installed from their git HEAD (
pip install git+https://github.com/pyFFTW/pyFFTW
) as their latest release does not support py3.11 AFAICT.I suspect we end up with two copies of fftw with incompatible ABIs which step onto another...
The text was updated successfully, but these errors were encountered: