Skip to content

Add edge_detection tests for Inf, boundary NaN, degenerate shapes, and multi-chunk dask#3685

Open
brendancol wants to merge 3 commits into
mainfrom
deep-sweep-test-coverage-edge_detection-2026-07-18
Open

Add edge_detection tests for Inf, boundary NaN, degenerate shapes, and multi-chunk dask#3685
brendancol wants to merge 3 commits into
mainfrom
deep-sweep-test-coverage-edge_detection-2026-07-18

Conversation

@brendancol

Copy link
Copy Markdown
Contributor

Closes #3682

Test-only change from the test-coverage audit of edge_detection. The source is untouched; every new test pins behavior that was verified correct on a CUDA host but had no coverage.

  • Inf and -Inf input: exact expected 3x3 neighborhood per operator (inf where the kernel weight has one sign, NaN where inf meets -inf or a zero weight), unaffected cells stay 0.
  • NaN at the raster corner under all four boundary modes, with numpy vs dask+numpy (multi-chunk), cupy, and dask+cupy parity. Earlier NaN tests only used an interior cell on numpy; NaN-input backend divergence has shipped before (kde, kde/line_density NaN inputs: backends disagree and the auto extent collapses to zeros #3628).
  • Degenerate shapes: 1x1 (all-NaN with boundary='nan', 0 with 'reflect'), 1x6 and 6x1 strips, (0, 5) empty raster.
  • Multi-chunk dask equivalence (chunks smaller than the array) for dask+numpy and dask+cupy; the existing dask tests all used one chunk, so chunk stitching was never exercised from this file.
  • boundary='invalid' raises ValueError (same test the other convolution-backed modules have).
  • lat/lon dim names pass through.

Backends: numpy, cupy, dask+numpy, dask+cupy all exercised; the GPU tests ran locally, not just in CI.

Test plan:

Also carries the sweep state CSV row for this audit.

@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: Add edge_detection tests for Inf, boundary NaN, degenerate shapes, and multi-chunk dask

Test-only PR, source untouched. Ran the new suite locally on a CUDA host: 222 passed, GPU tests executed rather than skipped.

Blockers (must fix before merge)

None.

Suggestions (should fix, not blocking)

  • Integer dtype input is still untested. #3682 calls out input-space gaps, and convolve_2d promotes int32 to float32; a small test pinning the promoted dtype and a known value would close that corner (new sections of xrspatial/tests/test_edge_detection.py).
  • TestInfHandling.test_negative_inf (test_edge_detection.py, ~line 396) only asserts an inf-or-nan mask. The -inf case is the +inf expected block negated with NaN kept, so it could pin exact values the way test_inf_neighborhood does.

Nits (optional improvements)

  • The module-level inf = np.inf / nan = np.nan aliases (test_edge_detection.py, ~line 358) leak into the module namespace for the sake of one parametrize table. Inlining np.inf/np.nan in the table would keep the namespace clean, at the cost of longer lines.

What looks good

  • test_inf_neighborhood pins exact per-operator 3x3 expectations instead of a loose isfinite check, including the 0-weight -> NaN cells.
  • NaN-at-corner parity runs all 4 boundary modes on all 4 backends; this is the combination that has caught real divergence elsewhere (kde #3628).
  • Multi-chunk dask tests (chunks=(4,5) on 9x11, chunks=(3,4) on 8x10) finally exercise chunk stitching from this file; previous dask tests were all single-chunk.
  • test_invalid_boundary_raises matches the pattern aspect/morphology/diffusion/bilateral already use.
  • The pre-existing E302 at line 22 was left alone (tracked by #3675), no drive-by edits.

Checklist

  • Algorithm matches reference/paper (n/a, test-only; expectations match probed behavior)
  • All implemented backends produce consistent results
  • NaN handling is correct
  • Edge cases are covered by tests
  • Dask chunk boundaries handled correctly
  • No premature materialization or unnecessary copies
  • Benchmark exists or is not needed (missing, tracked separately in #3672)
  • README feature matrix updated (n/a)
  • Docstrings present and accurate (n/a; docstring gaps tracked in #3674/#3676)

@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: follow-up after 65687d4

Re-checked the branch after the review fixes.

Blockers

None.

Suggestions

None. Both earlier suggestions are addressed:

  • TestIntegerDtype.test_int32_promotes_to_float32 pins the float32 promotion and compares against the float64-input result for all five operators.
  • test_negative_inf now asserts the exact negated neighborhood via the shared INF_NEIGHBORHOODS table instead of an inf-or-nan mask.

The nit is also done: the module-level inf/nan aliases are gone, with the expected blocks built from np.inf/np.nan directly.

Verification

  • 227 tests pass locally on a CUDA host (was 222 at first review, 87 before the PR).
  • flake8 on the file reports only the pre-existing E302 at line 22 (#3675).

Nothing further from me.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

edge_detection tests never see Inf, boundary NaN, degenerate shapes, or multi-chunk dask

1 participant