Skip to content

bilateral() ignores the boundary parameter on the cupy backend #3625

Description

@brendancol

Describe the bug

bilateral() accepts boundary='nan' | 'nearest' | 'reflect' | 'wrap'. The numpy backend pads via _pad_array, and both dask backends forward the mode to map_overlap. The cupy backend drops it: in the _bilateral dispatcher, cupy_func=_bilateral_cupy is the only entry not wrapped in partial(..., boundary=boundary), and _bilateral_cupy has no boundary handling at all. Every mode behaves like boundary='nan' on cupy, with no warning or error.

import numpy as np
import xarray as xr
import cupy
from xrspatial import bilateral

rng = np.random.default_rng(7)
data = rng.standard_normal((12, 16)) * 10 + 100

for boundary in ('nan', 'nearest', 'reflect', 'wrap'):
    r_np = bilateral(xr.DataArray(data), sigma_spatial=1.0, sigma_range=25.0,
                     boundary=boundary).data
    r_cp = bilateral(xr.DataArray(cupy.asarray(data)), sigma_spatial=1.0,
                     sigma_range=25.0, boundary=boundary).data.get()
    print(boundary, np.nanmax(np.abs(r_np - r_cp)))

Output:

nan      4.26e-14
nearest  2.90
reflect  1.45
wrap     3.08

The data has std ~10, so the edge-ring error for the non-default modes is around 30% of a standard deviation. Comparing cupy boundary='nearest' against numpy boundary='nan' gives max diff 4.26e-14: the parameter is ignored, not applied differently.

Expected behavior

cupy matches numpy for every boundary mode, the same way dask+cupy already does (it forwards the mode through _boundary_to_dask in map_overlap).

The existing boundary test (assert_boundary_mode_correctness) only compares numpy against dask+numpy, which is why this never showed up. A cupy boundary parity test should land with the fix.

Additional context

Found during an accuracy sweep of xrspatial/bilateral.py. _pad_array in xrspatial/utils.py already handles cupy arrays via cupy.pad, so the fix can mirror _bilateral_numpy_boundary.

Metadata

Metadata

Assignees

No one assigned

    Labels

    backend-coverageAdding missing dask/cupy/dask+cupy backend supportbugSomething isn't workinggpuCuPy / CUDA GPU support

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions