Grelee/skimage filters rank#1115
Open
grlee77 wants to merge 46 commits into
Open
Conversation
… eventual cucim.skimage.filter.rank.mean_percentile, etc
Replace the fixed 16-partition default for the uint8 2D rank histogram backend with a scratch-budgeted partition selector. Add environment overrides for forcing the partition count, scratch memory budget, and maximum partition count so benchmark runs can tune the backend without code changes.
…ral, mean_bilateral
…-based implementations
…e selected update module docstring
…kit-image compatibility
- Exclude the shifted anchor pixel from noise_filter footprints so standard disks, balls, and all-ones neighborhoods can detect isolated noise. - Preserve floating-point and wide-integer precision when computing noise distances instead of truncating through int. - Add native uint16 histogram outputs and reject or fall back for unsupported output dtypes, preventing count and sum truncation through uint8 temporaries. - Pass the output dtype scale into histogram kernels so threshold, equalize, autolevel, and subtract-mean match elementwise results for float and uint16 outputs. - Reject all overlapping input/output aliases, including views and transposes, before rank dispatch. - Add regression coverage for shifted anchors, native-distance precision, wide histogram results, output scaling, automatic fallback, and output aliases. Validation: - 281 passed, 3 skipped in filters/rank/tests/test_rank.py - ruff checks passed - git diff --check passed
- Document N-D footprints and output shapes for median filtering.\n- Clarify that cuCIM rank filters support N-D images with reflected boundaries.\n- Correct the scikit-image comparison to its supported 2-D and 3-D inputs.
- Distinguish the per-pixel elementwise implementation from the cooperative sliding-histogram backend. - Document the histogram backend's uint8, 2-D, output-dtype, and fully populated odd rectangular footprint requirements. - Correct dimensionality, dtype conversion, output dtype, overflow, percentile, and boundary-handling descriptions. - Align generated public and internal docstrings with current signatures, dispatch behavior, and supported operations. - Identify the histogram footprint-area cutoffs as RTX A6000 performance-tuning values.
- Apply the repository clang-format style to histogram_rank.cu. - Keep NVRTC-sensitive preprocessor conditions on single lines with narrow formatting guards.
- Clarify that the percentile range module provides internal machinery shared by generic, percentile, and bilateral rank filters. - Summarize elementwise kernel generation and sliding-histogram backend dispatch.
- Rename _percentile_range_filter.py to _rank_filter.py to reflect its shared role across rank-filter APIs. - Update the internal import and scikit-image license-hook path mappings for the new filename.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR adds the
cucim.skimage.filters.rankmodule, providingGPU-accelerated rank filters for CuPy arrays with an API modeled after
skimage.filters.rank. It resolves #235.The existing
cucim.skimage.filters.medianwrapper is also extended withbehavior='rank', which delegates to the new rank median implementation.behavior='ndimage'remains the default.The implementation is intended to be largely compatible with scikit-image for
common rank-filter workflows. The most visible behavioral difference is
boundary handling: cuCIM uses reflected boundary extension, while scikit-image
rank filters crop neighborhoods at image boundaries. cuCIM also supports N-D
inputs and optional native processing of integer and real floating-point
dtypes, with some output-dtype and percentile edge-case behavior differing
from scikit-image.
otsuandwindowed_histogramare not currentlyimplemented.
See the detailed compatibility overview in
cucim.skimage.filters.rank.Implementation Approach
The module uses multiple backend implementations because no single algorithm is
best across all filters, dtypes, dimensionalities, and footprint sizes.
inputs, arbitrary footprint shapes, masks, shifts, and native integer and
real floating-point dtypes. Operations that do not require sorted values use
streaming reductions within this backend. It avoids requiring a fixed
histogram range and is the general fallback.
fully populated, odd-sized rectangular footprints. It maintains a local
sliding histogram and can reuse work between adjacent pixels, which is much
more favorable for larger rectangular windows and filters that can be
expressed from histogram counts, order statistics, prefix counts, or prefix
sums.
By default, non-uint8 inputs are converted to uint8 with
img_as_ubytebeforebackend selection, matching scikit-image rank-filter behavior more closely and
allowing eligible inputs to use the uint8 histogram fast path. Users can opt
out with
cast_to_uint8=Falsewhen they need native-dtype elementwisebehavior.
Testing
The test suite provides several independent checks of correctness and backend
dispatch:
for 2-D inputs, with generic filters also covered in 3-D. Comparisons account
for the documented boundary behavior and explicitly identify the few known
algorithmic differences.
streaming operations and the histogram percentile, prefix-count, prefix-sum,
bilateral, modal, and entropy operations. Forced elementwise and histogram
results are also compared directly.
uint8 conversion, native-dtype processing, output dtypes and scaling,
overflow-sensitive sums, masks, shifts, arbitrary footprints, and trivial or
empty neighborhoods.
compatibility rejection and fallback, histogram counter widths, scratch
partition limits, invalid inputs, and overlapping output aliases.
cucim.skimage.filters.medianwithbehavior='rank'matchesrank.medianfor array and tuple footprints,supports caller-provided output arrays, and retains the existing
behavior='ndimage'default and warning behavior.The complete rank-filter test module currently reports 281 passed tests and 3
documented skips for known algorithmic differences.
Reviewer Notes
The rank module includes support for generic rank filters, percentile-range
filters, bilateral rank filters, entropy, modal/majority, and related
operations. Backend selection is automatic by default, but a
backendkeywordcan force
elementwiseorhistogramfor testing, profiling, and thresholdtuning.
cuCIM Rank Filter Benchmark Summary
Timings are from
cucim_filters_rank_results.csvfiles generated byrun-nv-bench-filters-rank.shorcucim_filters_rank_bench.py.Speedup vs scikit-image CPU: uint8, rectangular footprint with "auto" algorithm tuning
We can see that the histogram-based kernels are consistently much faster than their scikit-image counterparts.
Speedup vs scikit-image CPU: uint8, disk footprint (so only the elementwise backend can be used)
The benchmark was invoked with
backend='auto', but disk footprints are notcompatible with the histogram backend, so every row dispatches to elementwise.
We can see that at large enough footprint size, the "elementwise" backend eventually becomes slower than scikit-image's histogram-based approach.