Skip to content

Commit

Permalink
Fix cufinufft fallback (#536)
Browse files Browse the repository at this point in the history
* py: fix bug in cufinufft library fallback

* py: add tests for fallback library loading

* py: skip fallback tests in CI

These tests checks that the fallback mechanism is working properly. In
other words, if there is no bundled library, it should look in the
system path (e.g. `LD_LIBRARY_PATH` on Unix systems) and try to load it
from there.

For some reason, these tests work locally, but in CI, the library is
imported as usual, even with the patched function. Perhaps this has
something to do with the fact that the module is already loaded, so
`import finufft` is a no-op (this is evidenced by the fact that any
`print` statement in `finufft._finufft` is not detected in the output).
  • Loading branch information
janden authored Aug 27, 2024
1 parent 897b226 commit 95ee4cf
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 2 deletions.
2 changes: 1 addition & 1 deletion Jenkinsfile
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ pipeline {
source $HOME/bin/activate
python3 -m pip install --no-cache-dir --upgrade pycuda cupy-cuda112 numba
python3 -m pip install --no-cache-dir torch==1.12.1+cu113 -f https://download.pytorch.org/whl/torch_stable.html
python3 -m pip install --no-cache-dir pytest
python3 -m pip install --no-cache-dir pytest pytest-mock
python -c "from numba import cuda; cuda.cudadrv.libs.test()"
python3 -m pytest --framework=pycuda python/cufinufft
python3 -m pytest --framework=numba python/cufinufft
Expand Down
1 change: 1 addition & 0 deletions python/cufinufft/cufinufft/_cufinufft.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import importlib.util
import pathlib
import numpy as np
from ctypes.util import find_library

from ctypes import c_double
from ctypes import c_int
Expand Down
25 changes: 25 additions & 0 deletions python/cufinufft/tests/test_fallback.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import pytest

import numpy as np
from ctypes.util import find_library


# Check to make sure the fallback mechanism works if there is no bundled
# dynamic library.
@pytest.mark.skip(reason="Patching seems to fail in CI")
def test_fallback(mocker):
def fake_load_library(lib_name, path):
if lib_name in ["libcufinufft", "cufinufft"]:
raise OSError()
else:
return np.ctypeslib.load_library(lib_name, path)

# Block out the bundled library.
mocker.patch("numpy.ctypeslib.load_library", fake_load_library)

# Make sure an error is raised if no system library is found.
if find_library("cufinufft") is None:
with pytest.raises(ImportError, match="suitable cufinufft"):
import cufinufft
else:
import cufinufft
2 changes: 1 addition & 1 deletion python/finufft/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ input = "finufft/__init__.py"
build-verbosity = 1
# Not building for PyPy and musllinux for now.
skip = "pp* *musllinux*"
test-requires = "pytest"
test-requires = ["pytest", "pytest-mock"]
test-command = "pytest {project}/python/finufft/test"

[tool.cibuildwheel.linux]
Expand Down
20 changes: 20 additions & 0 deletions python/finufft/test/test_fallback.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import pytest

import numpy as np
from ctypes.util import find_library

@pytest.mark.skip(reason="Patching seems to fail in CI")
def test_fallback(mocker):
def fake_load_library(lib_name, path):
if lib_name in ["libfinufft", "finufft"]:
raise OSError()
else:
return np.ctypeslib.load_library(lib_name, path)

mocker.patch("numpy.ctypeslib.load_library", fake_load_library)

if find_library("finufft") is None:
with pytest.raises(ImportError, match="suitable finufft"):
import finufft
else:
import finufft

0 comments on commit 95ee4cf

Please sign in to comment.