Skip to content

Commit

Permalink
port additional changes/fixes from CuPy
Browse files Browse the repository at this point in the history
after this update all tests under cupyx.scipy.ndimage test suite pass when monkey-patching
them to use the vendored ndimage module from cuCIM
  • Loading branch information
grlee77 committed Jan 18, 2025
1 parent d6b63b3 commit 0683928
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 17 deletions.
59 changes: 42 additions & 17 deletions python/cucim/src/cucim/skimage/_vendored/_ndimage_interpolation.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
_ndimage_interp_kernels as _interp_kernels,
_ndimage_spline_prefilter_core as _spline_prefilter_core,
_ndimage_util as _util,
pad,
)
from cucim.skimage._vendored._internal import _normalize_axis_index

Expand Down Expand Up @@ -239,7 +238,7 @@ def _prepad_for_spline_filter(input, mode, cval):
kwargs = dict(mode="constant", constant_values=cval)
else:
kwargs = dict(mode="edge")
padded = pad(input, npad, **kwargs)
padded = cupy.pad(input, npad, **kwargs)
else:
npad = 0
padded = input
Expand All @@ -252,7 +251,7 @@ def _filter_input(image, prefilter, mode, cval, order):
Spline orders > 1 need a prefiltering stage to preserve resolution.
For boundary modes without analytical spline boundary conditions, some
prepadding of the input with pad is used to maintain accuracy.
prepadding of the input with cupy.pad is used to maintain accuracy.
``npad`` is an integer corresponding to the amount of padding at each edge
of the array.
"""
Expand Down Expand Up @@ -298,8 +297,13 @@ def map_coordinates(
cval (scalar): Value used for points outside the boundaries of
the input if ``mode='constant'`` or ``mode='opencv'``. Default is
0.0
prefilter (bool): It is not used yet. It just exists for compatibility
with :mod:`scipy.ndimage`.
prefilter (bool): Determines if the input array is prefiltered with
``spline_filter`` before interpolation. The default is True, which
will create a temporary ``float64`` array of filtered values if
``order > 1``. If setting this to False, the output will be
slightly blurred if ``order > 1``, unless the input is prefiltered,
i.e. it is the result of calling ``spline_filter`` on the original
input.
Returns:
cupy.ndarray:
Expand All @@ -312,7 +316,7 @@ def map_coordinates(
_check_parameter("map_coordinates", order, mode)

if mode == "opencv" or mode == "_opencv_edge":
input = pad(
input = cupy.pad(
input, [(1, 1)] * input.ndim, "constant", constant_values=cval
)
coordinates = cupy.add(coordinates, 1)
Expand Down Expand Up @@ -394,8 +398,13 @@ def affine_transform(
cval (scalar): Value used for points outside the boundaries of
the input if ``mode='constant'`` or ``mode='opencv'``. Default is
0.0
prefilter (bool): It is not used yet. It just exists for compatibility
with :mod:`scipy.ndimage`.
prefilter (bool): Determines if the input array is prefiltered with
``spline_filter`` before interpolation. The default is True, which
will create a temporary ``float64`` array of filtered values if
``order > 1``. If setting this to False, the output will be
slightly blurred if ``order > 1``, unless the input is prefiltered,
i.e. it is the result of calling ``spline_filter`` on the original
input.
texture_memory (bool): If True, uses GPU texture memory. Supports only:
- 2D and 3D float32 arrays as input
Expand All @@ -415,7 +424,6 @@ def affine_transform(
"""

if texture_memory:
# _texture only available in CuPy 10.x so delay the import
# We do not use this texture-based implementation in cuCIM.
from cucim.skimage._vendored import _texture

Expand Down Expand Up @@ -565,8 +573,13 @@ def rotate(
cval (scalar): Value used for points outside the boundaries of
the input if ``mode='constant'`` or ``mode='opencv'``. Default is
0.0
prefilter (bool): It is not used yet. It just exists for compatibility
with :mod:`scipy.ndimage`.
prefilter (bool): Determines if the input array is prefiltered with
``spline_filter`` before interpolation. The default is True, which
will create a temporary ``float64`` array of filtered values if
``order > 1``. If setting this to False, the output will be
slightly blurred if ``order > 1``, unless the input is prefiltered,
i.e. it is the result of calling ``spline_filter`` on the original
input.
Returns:
cupy.ndarray or None:
Expand Down Expand Up @@ -606,7 +619,9 @@ def rotate(
iy, ix = in_plane_shape
out_bounds = rot_matrix @ [[0, 0, iy, iy], [0, ix, 0, ix]]
# Compute the shape of the transformed input plane
out_plane_shape = (out_bounds.ptp(axis=1) + 0.5).astype(cupy.int64)
out_plane_shape = (numpy.ptp(out_bounds, axis=1) + 0.5).astype(
cupy.int64
)
else:
out_plane_shape = img_shape[axes]

Expand Down Expand Up @@ -673,8 +688,13 @@ def shift(
cval (scalar): Value used for points outside the boundaries of
the input if ``mode='constant'`` or ``mode='opencv'``. Default is
0.0
prefilter (bool): It is not used yet. It just exists for compatibility
with :mod:`scipy.ndimage`.
prefilter (bool): Determines if the input array is prefiltered with
``spline_filter`` before interpolation. The default is True, which
will create a temporary ``float64`` array of filtered values if
``order > 1``. If setting this to False, the output will be
slightly blurred if ``order > 1``, unless the input is prefiltered,
i.e. it is the result of calling ``spline_filter`` on the original
input.
Returns:
cupy.ndarray or None:
Expand Down Expand Up @@ -759,8 +779,13 @@ def zoom(
cval (scalar): Value used for points outside the boundaries of
the input if ``mode='constant'`` or ``mode='opencv'``. Default is
0.0
prefilter (bool): It is not used yet. It just exists for compatibility
with :mod:`scipy.ndimage`.
prefilter (bool): Determines if the input array is prefiltered with
``spline_filter`` before interpolation. The default is True, which
will create a temporary ``float64`` array of filtered values if
``order > 1``. If setting this to False, the output will be
slightly blurred if ``order > 1``, unless the input is prefiltered,
i.e. it is the result of calling ``spline_filter`` on the original
input.
grid_mode (bool, optional): If False, the distance from the pixel
centers is zoomed. Otherwise, the distance including the full pixel
extent is used. For example, a 1d signal of length 5 is considered
Expand Down Expand Up @@ -797,7 +822,7 @@ def zoom(
zoom = []
offset = []
for in_size, out_size in zip(input.shape, output_shape):
if out_size > 1:
if out_size > 0:
zoom.append(float(in_size) / out_size)
offset.append((zoom[-1] - 1) / 2.0)
else:
Expand Down
8 changes: 8 additions & 0 deletions python/cucim/src/cucim/skimage/_vendored/ndimage.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@
# measurements
# fourier filters
# additional filters
from cupyx.scipy.ndimage import distance_transform_edt # NOQA
from cupyx.scipy.ndimage import fourier_ellipsoid # NOQA
from cupyx.scipy.ndimage import fourier_gaussian # NOQA
from cupyx.scipy.ndimage import fourier_shift # NOQA
from cupyx.scipy.ndimage import fourier_uniform # NOQA
from cupyx.scipy.ndimage import generic_filter # NOQA
from cupyx.scipy.ndimage import generic_filter1d # NOQA
from cupyx.scipy.ndimage import label # NOQA
from cupyx.scipy.ndimage import value_indices # NOQA

from cucim.skimage._vendored._ndimage_filters import convolve # NOQA
from cucim.skimage._vendored._ndimage_filters import convolve1d # NOQA
Expand Down Expand Up @@ -71,9 +73,15 @@


try:
# `sum_labels` is only available as `sum` in older releases of CuPy
from cupyx.scipy.ndimage import sum_labels # NOQA
except ImportError:
from cupyx.scipy.ndimage import sum as sum_labels # NOQA
try:
from cupyx.scipy.ndimage import sum # NOQA
except ImportError:
# `sum` is deprecated and may be removed in a future version of CuPy
pass

from cupyx.scipy.ndimage import center_of_mass # NOQA
from cupyx.scipy.ndimage import extrema # NOQA
Expand Down

0 comments on commit 0683928

Please sign in to comment.