finufft icon indicating copy to clipboard operation
finufft copied to clipboard

`finufft==2.2.0` Windows DLL issues

Open garrettwrong opened this issue 1 year ago • 8 comments

Hi, ran into some trouble trying to mix the latest (2.2.0) release with other packages. I was able to trace it back to what looks like an incompatibility between (py)fftw and finufft's packaged (py)fftw libraries. At the very least it is now a small case that doesn't include ASPIRE for your consideration.

On a win10 VM with conda/git installed, using 2.2.0 checkout, in finufft\python\finufft\test:

conda create -n fin_fftw_test python=3.8
conda activate fin_fftw_test
pip install pyfftw "finufft==2.2.0" pytest

For reference

pip freeze
colorama==0.4.6
exceptiongroup==1.2.0
finufft==2.2.0
iniconfig==2.0.0
numpy==1.24.4
packaging==23.2
pluggy==1.3.0
pyFFTW==0.13.1
pytest==7.4.4
tomli==2.0.1

python test_finufft_plan.py will run.

However, making this change loading pyfftw

diff --git a/python/finufft/test/test_finufft_plan.py b/python/finufft/test/test_finufft_plan.py
index b185d34e..85f3d571 100644
--- a/python/finufft/test/test_finufft_plan.py
+++ b/python/finufft/test/test_finufft_plan.py
@@ -2,6 +2,8 @@ import pytest

 import numpy as np

+import pyfftw
+

 from finufft import Plan

 import utils

Results in a fatal exceptions. This happens in our application because we import both pyfftw and finufft for different components. The best part is that the actual meaningful message appears to pop up (and require clicking okay) in dialog box; which I only became aware of after setting up a VM for this 😂 .

Screenshot 2024-01-22 at 8 51 30 AM

garrettwrong avatar Jan 22 '24 16:01 garrettwrong

@garrettwrong I see pyfftw wheel https://files.pythonhosted.org/packages/9f/37/11a6955c427a1a5ab9cbad47f6f4b1349593742f526e97bf196c7e02e9be/pyFFTW-0.13.1-cp38-cp38-win_amd64.whl on pipy packages in:

libfftw3-3.dll
libfftw3f-3.dll
libfftw3l-3.dll

finufft packages in:

libfftw3-3.dll
libfftw3f-3.dll
libfftw3f_omp-3.dll
libfftw3_omp-3.dll

So does it mean pyfftw is not using threaded fftw? Why the error messasge is about libfftw3_omp-3.dll.

lu1and10 avatar Jan 22 '24 17:01 lu1and10

@garrettwrong I did some search, pyfftw's pipy wheels are build with fftw 3.3.5 https://github.com/pyFFTW/pyFFTW/blob/82ae9eafac5fdd411f38852a1d379bb013526460/.github/workflows/wheel_tests_and_release.yml#L170-L180. We use pacman's mingw-w64-x86_64-fftw threaded 3.3.10. I guess it's not compatible as you said. To use pyfftw and finufft together, you may need to install pyfftw from conda-forge:

conda config --add channels conda-forge
conda install pyfftw

And then install finufft from pip, hopefully this works for you. I know this sounds weird, but we have not added finufft to conda. I guess this is just Windows problem? Linux and MacOS are fine, right?

lu1and10 avatar Jan 22 '24 22:01 lu1and10

HI, thanks for getting back to me.

The CI on Github Actions that originally failed was using conda-forge as the highest channel and conda installing for fftw and pyfftw... so I can report that wont fix generally. I will also try it on this VM also and report back later today. Should note, which version of packages you will get with those commands can depend on your/my cache etc etc.

I made this report just to be simpler and avoid the confusion of additional channels. The log dump I got in practice was unworkable (and it did not even contain strings relating to the the error after I had found ...).

Yes, it is happening on the Windows platform, that I know of.

Truth be told, it took a frustrating long time to get to this point of a small actionable report, and I'm not familiar with library searching/loading techniques on Windows. ASPIRE worked around by rolling back to the 2.1.0 release for Windows. Would prefer all platforms be on the same release. If finufft makes clear which (py)fftws are required, its possible for this package or ASPIRE to require those (and perhaps only then for Windows if the linux libraries are not going to cause conflicts).

Hope that makes sense. Maybe you can figure something better out. Thanks.

garrettwrong avatar Jan 23 '24 12:01 garrettwrong

@garrettwrong I’m able to run anaconda installed pyfftw and pip installed finufft on my native installed windows. I also tried github action miniconda, it seems working with the failing example you showed in this issue, see https://github.com/lu1and10/test-conda/actions/runs/7626907069/job/20774377250. finufft pipy wheel generator action does not changes too much, finufft 2.2.0 packages in fftw 3.3.10 dll from windows pacman package manager. finufft 2.1.0 use the pacman fftw too, the difference would be pacman updates fftw to 3.3.10. If updating to latest fftw version helps, It will be reasonable to ask pyffw’s pypi wheel to package in fftw 3.3.10 instead of the old fftw 3.3.5 it currently packages in. Downgrading seems not a sustenance solution.

lu1and10 avatar Jan 23 '24 14:01 lu1and10

Hi Libin, I'm more of the opinion that the package/packaging is broken under Windows (except in the case that was used above for testing). This is because FINUFFT's Python package is not declaring it has a strong dependency (evidenced by the crashing library conflicts). Note, conda/conda-forge are also not FINUFFT requirements (and shouldn't need to be).

Other softwares may freely try to pip install a different version, downgrade, or upgrade pyfftw (and so possibly fftw3). Because FFT is so ubiquitous, this is pretty likely to occur when left uncontrolled... and this is what is happening... Downstream packages are not the best place to codify FINUFFT depends...

I suspect the reason this is not seen on Linux may have to do with differences in how libraries are pathed/loaded between the platforms, but I do not know as much about win to be sure. If that is the case, it is possible this is only an issue on Windows and only requires defining the stricter requirements there. One can define per-platform package requirements; this is exactly what I did to downgrade FINUFFT in ASPIRE for Windows. There are probably several other ways to improve this, but I'm leaving that up to you guys. Thanks!

garrettwrong avatar Jan 25 '24 12:01 garrettwrong

@garrettwrong If you change your ci for windows as in https://github.com/lu1and10/ASPIRE-Python/commit/c2968111247b71340c8b9fff1d60e41a521b4ce5 to install finufft 2.2.0 on windows, your ci should work now. I updated a particular windows wheel to have name mangling on the dependent libs.

The difference between finufft 2.2.0 and 2.1.0 on windows wheels that makes you ci break is because we package the latest version pacman's fftw binary libs into the wheel. The new fftw lib included in the wheel is not compatible with the other fftw lib loaded in your failing environment, in your case most probably it's not compatible with pyfftw's version fftw. Both finufft and pyfftw does not do name mangling for the dependent libs on windows wheels. Now I have uploaded a windows finufft 2.2.0 wheel with name mangling of its dependent libs, if you unzip https://files.pythonhosted.org/packages/a8/37/04143aee63e3773debe77979e44f85e1e22d87c1948f5acab4cca3d1ecee/finufft-2.2.0-py3-none-win_amd64.whl you can see the dependent libs are now named as the following:

finufft.libs\
    libfftw3-3-8da03c819386f322fa060b460872a182.dll
    libfftw3f-3-68e4ebbe3923cb7a9405827c92378dec.dll
    libfftw3f_omp-3-e0a93fa6acb0bb214734ac7b69b9f95b.dll
    libfftw3_omp-3-31e685fea8d246729c98d5b29f4f03f1.dll
    libgcc_s_seh-1-5fbd00711a76ec16f9e07ca7d599d0ed.dll
    libgomp-1-90b27781b511f73cf8c19bd3a46534ab.dll
    libstdc++-6-5bc5601741f23998c6df95cac6b3eac2.dll
    libwinpthread-1-4f3a129cda57f49b816441d95f9bad85.dll

It should not conflict with any other incompatible libs with the hashed name.

While I have checked pyfftw windows wheels, its dll is still named libfftw3-3.dll, so if there is other package you are using trying to load some incompatible libs with the same name it may still result in the error you had in your fin ci run. It will be safer that pyfftw's windows wheel also does the name mangling for its dependent libs. As FFT is so ubiquitous, you may still encounter such incompatible situation in the future if loading other packages depending on fftw.

lu1and10 avatar Jan 26 '24 03:01 lu1and10

Hi Libin, thanks for taking a deeper look at this. I think I follow what you are saying regarding the libraries.

I am checking if pip will pickup the latest win package from pypi, in CI and on my VM. The result of pip install finufft combined with other software is really the primary concern of this issue...

On my VM, it looks like even after purging cache, pip install finufft is still going to try picking up the first set of wheels with the library conflicts (eg finufft-2.2.0-cp38-cp38-win_amd64.whl).

I can report back about the CI later, but I have a strong suspicion it will be the same.

I think fixing this may require releasing updated packages for the entire platform. Given I had a workaround in place when I reported, we can wait for the next release if it will be fixed then. Thanks

garrettwrong avatar Jan 26 '24 12:01 garrettwrong

Garrett, Thanks for letting us know this issue. It's good to know that this incompatible dependent lib loading issue. We should upload the wheel with name mangling libs in later releases for windows. Linux wheels already have name mangling that's why linux is good. While MacOS seems to not have name mangling either, but both finufft and pyfftw use brew install fftw which is compatible by luck... Worth keep an eye such issue in the future. pipy can only upload wheel of the same name once, I can only upload finufft-2.2.0-py3-none-win_amd64.whl for this release, naive pip install will search index for the one finufft-2.2.0-cp38-cp38-win_amd64.whl in your ci, so I have to use the -f and --no-index flags. I think for general ASPIRE users using default pip install on windows, 2.1.0 wheel is a safer choice before next release.

lu1and10 avatar Jan 26 '24 13:01 lu1and10

Closing as this should be fixed by #429, It can be reopened if there is still a problem

DiamonDinoia avatar Jul 17 '24 16:07 DiamonDinoia