Skip to content

Guard single-point input in kriging() variogram#2924

Merged
brendancol merged 2 commits into
mainfrom
deep-sweep-security-interpolate-kriging-2026-06-04-01
Jun 5, 2026
Merged

Guard single-point input in kriging() variogram#2924
brendancol merged 2 commits into
mainfrom
deep-sweep-security-interpolate-kriging-2026-06-04-01

Conversation

@brendancol

Copy link
Copy Markdown
Contributor

Closes #2917

kriging() crashed with an opaque numpy ValueError ("zero-size array to reduction operation maximum which has no identity") whenever the input reduced to a single point: either one point passed directly, or all but one point dropped by NaN filtering.

  • _experimental_variogram now returns empty arrays when there are no distance pairs, before calling dists.max(). This routes the single-point case to the existing default-variogram fallback that already handles coincident points, so the call produces a constant-valued raster instead of raising.

Backend coverage: numpy (the variogram and matrix build run on host arrays for all four backends, so the fix applies regardless of the template's backend).

Test plan:

  • test_single_point — one input point yields a finite constant prediction
  • test_single_valid_point_after_nan_drop — NaN filtering down to one point reaches the same fallback
  • existing kriging suite still passes (18 passed)

@github-actions github-actions Bot added the performance PR touches performance-sensitive code label Jun 4, 2026

@brendancol brendancol left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR Review: Guard single-point input in kriging() variogram

Blockers

None.

Suggestions

None.

Nits

None.

What looks good

  • The guard is placed correctly: dists.size == 0 is checked before dists.max(), which is exactly where the empty-reduction crash originated (_kriging.py).
  • It reuses the existing default-variogram fallback rather than adding a parallel code path. The dists.size == 0 (n<2) and max_dist <= 0 (coincident points) cases stay distinct, and both are needed.
  • Because the variogram and matrix build run on host numpy arrays ahead of backend dispatch, the fix covers all four backends without touching the dispatch layer.
  • Two tests cover both routes into the single-point state: one point passed directly, and one point left after NaN filtering. Both assert a finite constant prediction and the expected warning.

Verification

  • Reproduced the original ValueError on main, confirmed it is gone after the change.
  • Single point returns a constant raster equal to the point value (42.0 and 7.0 in the two tests); ordinary-kriging weight collapses to 1.0 with no spatial structure, which is the sensible degenerate result.
  • Full kriging suite: 18 passed.

Checklist

  • Algorithm correct for the degenerate case
  • All backends covered (fix is upstream of dispatch)
  • NaN handling correct (NaN-drop-to-one routes to fallback)
  • Edge cases covered by tests
  • No premature materialization
  • Benchmark not needed (bug fix)
  • README not applicable (no API change)
  • Docstrings unchanged; behavior already documented via MemoryError/warning paths

A single input point (or all-but-one points NaN) left np.triu_indices
with no pairs, so dists was zero-size and dists.max() raised an opaque
ValueError. Return empty arrays before the reduction so kriging() reaches
the existing default-variogram fallback, matching the identical-points
behavior.
@brendancol brendancol force-pushed the deep-sweep-security-interpolate-kriging-2026-06-04-01 branch from aec6657 to b2f7106 Compare June 5, 2026 01:21
@brendancol brendancol merged commit 274fe9b into main Jun 5, 2026
7 checks passed
brendancol added a commit that referenced this pull request Jun 5, 2026
)

Closes gaps found by the test-coverage sweep on interpolate/_kriging.py:
- dask+numpy return_variance branch (_chunk_var) was unexercised
- nlags only tested at default; added non-default + invalid-input paths
- two-point <3-lag-bins UserWarning path
- all-NaN kriging input ValueError (only idw was covered)
- output metadata preservation (coords/dims/attrs/name)

The single-point crash (source bug #2920) is now fixed on main by #2924,
which also adds passing single-point tests, so the xfail placeholder this
PR originally carried is dropped to avoid a strict-xfail XPASS.

Test-only; no source changes. GPU paths validated on a CUDA host.
brendancol added a commit that referenced this pull request Jun 5, 2026
) (#2928)

Closes gaps found by the test-coverage sweep on interpolate/_kriging.py:
- dask+numpy return_variance branch (_chunk_var) was unexercised
- nlags only tested at default; added non-default + invalid-input paths
- two-point <3-lag-bins UserWarning path
- all-NaN kriging input ValueError (only idw was covered)
- output metadata preservation (coords/dims/attrs/name)

The single-point crash (source bug #2920) is now fixed on main by #2924,
which also adds passing single-point tests, so the xfail placeholder this
PR originally carried is dropped to avoid a strict-xfail XPASS.

Test-only; no source changes. GPU paths validated on a CUDA host.
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.

kriging() raises an opaque numpy error for a single input point

1 participant