Skip to content

focal: pin result .name across backends in focal_stats and hotspots#2735

Open
brendancol wants to merge 1 commit into
mainfrom
deep-sweep-metadata-focal-2026-05-29
Open

focal: pin result .name across backends in focal_stats and hotspots#2735
brendancol wants to merge 1 commit into
mainfrom
deep-sweep-metadata-focal-2026-05-29

Conversation

@brendancol
Copy link
Copy Markdown
Contributor

What

focal_stats and hotspots returned a DataArray whose .name differed across the four backends. On the dask paths the name was a non-deterministic dask graph token (_trim-<hash>).

backend focal_stats (before) hotspots (before)
numpy focal_apply None
dask+numpy focal_apply _trim-<hash>
cupy None None
dask+cupy _trim-<hash> _trim-<hash>

Why

The dask code paths build the output xr.DataArray without an explicit name=. When the backing array is a dask array, xarray adopts the dask array's internal graph-layer name as the public .name. .name is user-visible metadata: it shows in the repr, becomes the variable key in to_dataset(), and sets default plot labels. A chained pipeline got a different name depending on which backend ran. Same class as the zonal.apply fix (#2611).

Fix

  • focal_stats: set result.name = 'focal_apply' after construction (the name the numpy/dask+numpy paths already emit). Assigning at the dask DataArray constructor does not override the graph name, so this is done post-construction.
  • hotspots: pass name='hotspots'.

The rest of the metadata (attrs res/crs/nodatavals, coords, dims) was already preserved consistently across all four backends.

Tests

Two parametrized regression tests assert name consistency for focal_stats and hotspots across numpy / dask+numpy / cupy / dask+cupy. Full focal suite: 122 passed (CUDA host, all backends live).

Fixes #2733

The dask paths of focal_stats and hotspots built the output DataArray
without an explicit name=, so xarray adopted the dask array's internal
graph token (_trim-<hash>) as the public .name. That made .name differ
across the four backends and leaked a non-deterministic implementation
detail.

focal_stats now sets result.name='focal_apply' (the name the numpy path
already emits); hotspots passes name='hotspots'. Adds parametrized
name-consistency tests for both functions across all four backends.

Fixes #2733
@github-actions github-actions Bot added the performance PR touches performance-sensitive code label May 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

performance PR touches performance-sensitive code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

focal_stats and hotspots: result .name differs across backends

1 participant