Skip to content

morphology: dask backends raise on 1xN or Nx1 kernels (empty-slice bug) #1399

@brendancol

Description

@brendancol

Describe the bug

_morph_chunk_numpy and _morph_chunk_cupy write the per-chunk result back with result[hy:-hy, hx:-hx] = interior (xrspatial/morphology.py:337 and :391). When hy == 0 (1xN kernel) or hx == 0 (Nx1 kernel), the slice becomes 0:-0, which is empty, and the assignment raises ValueError: could not broadcast input array.

The numpy and cupy non-dask backends accept these kernels fine, so this is a backend-parity break: dask raises on input the other backends compute.

Reproducer

import numpy as np
import xarray as xr
import dask.array as da
from xrspatial.morphology import morph_erode

kernel = np.array([[1, 1, 1]], dtype=np.uint8)  # 1x3
data = da.from_array(np.full((10, 10), 5.0), chunks=(5, 5))
agg = xr.DataArray(data)
morph_erode(agg, kernel=kernel, boundary='nearest').compute()
# ValueError: could not broadcast input array from shape (5,5) into shape (0,5)

Same failure with a 3x1 kernel (hx == 0).

Expected behavior

Dask should produce the same result as the numpy backend for these kernels.

Fix sketch

Replace the slice expression with one that handles hy == 0 / hx == 0:

result[hy:hy + rows, hx:hx + cols] = interior

Apply to both _morph_chunk_numpy (line 337) and _morph_chunk_cupy (line 391).

Additional context

Found during the morphology accuracy sweep (2026-04-30). Related to #1397 (centre-cell leak), but a separate fix surface.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingfocal toolsFocal statistics and hotspot analysishigh-priority

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions