Release Notes
Current Release - v0.6.0
GRIDR v0.6.0 — Release Notes
Release date: 2026-06-10 Type: Performance Improvment Release
This release focuses on performance work that had been pending in the queue: a fast path for identity-resolution resampling, faster B-Spline kernels, a rewrite of the bounds-check logic in the separable convolution core, SIMD compilation flags enabled by default.
You will notice a 2 × – 4 × reduction in total computation time for typical resampling workloads—varying with the interpolator and the grid size. At the same time, GridR now outperforms SciPy on irregular‑grid interpolation tasks, giving you faster results with the same API.

We also fixed the Docker /dev/shm issue several users reported, and exposed trust_padding as an explicit parameter instead of relying on an implicit default.
There are two breaking changes (trust_padding and GridMetricsError propagation) and one deprecation (shmutils). Migration is straightforward; see the migration section at the end.
⚡Performance
AVX2 + FMA wheels on PyPI
PyPI wheels are now pre-compiled with AVX2 and FMA enabled. The gain is most visible on B-Spline prefiltering, cubic and B-Spline kernel evaluation, and large-grid workloads where the inner convolution loop dominates.
Fast path for (1, 1) resampling
When array_grid_resampling is called with grid_resolution=(1, 1) GridR now switches to a dedicated point-mesh code path that skips the full mesh interpolation machinery.
result = array_grid_resampling(
array_in=image,
grid_row=grid_row,
grid_col=grid_col,
grid_resolution=(1, 1), # fast path
interp=interp,
standalone=True,
)
Safe-window masking
When a large region of your input is known to be fully valid (e.g. a small invalid border around a clean image), you can declare it as a “safe window” and skip per-sample mask checks inside that region.
import numpy as np
from gridr.core.grid.grid_resampling import array_grid_resampling
# Image is 50×60, invalid patch at rows 4-30 cols 13-23.
# Rows 30-49 cols 23-59 are entirely valid.
result = array_grid_resampling(
array_in=image,
array_in_mask=mask,
array_in_mask_safe_win=np.asarray([(30, 49), (23, 59)]),
grid_row=grid_row,
grid_col=grid_col,
grid_resolution=(1, 1),
interp=interp,
standalone=True,
)
GridR trusts the declaration. If you mark a region as safe but it actually contains invalid samples, the output in that area will be wrong — there’s no runtime verification. Use this only when you have an upstream guarantee.
The safe window is automatically eroded during B-Spline prefiltering by the kernel’s influence radius. You don’t need to adjust it when switching interpolation methods.
Faster B-Spline kernels
All kernel weights are now computed in a single call with shared computations, instead of being computed individually. Applies to orders 3, 5, 7, 9, and 11.
Two-stage short-circuit on mask validation
Mask validation inside the interpolation core has been reordered to test the most probable case first (kernel fully inside a valid region). The expensive per-sample weight test is now only invoked when the cheap one is inconclusive.
Unchecked indexing on the fast inner-loop path
By default Rust checks that every array index is inside the array’s limits. In the convolution routine and the mask‑validation step we already know—through formal proof—that the indices we use can never be out of range. For these specific sections we have switched to “unchecked” mode, turning off the automatic bounds checks. This removes a small runtime overhead and speeds up the processing, while still remaining safe because the code guarantees the indices are valid.
Benchmarking framework
pytest-benchmark is now wired into the test tree. Machine config is captured automatically so results are reproducible across runs.
# Core method vs scipy
pytest tests/python/benchmarks/time/test_time_core_array_grid_resampling.py
# Chain method vs CNES ORION (needs ORION_BIN_PATH)
export ORION_BIN_PATH=/path/to/orion
pytest tests/python/benchmarks/time/test_time_chain_array_grid_resampling.py
Suite |
Benchmarks |
Reference |
|---|---|---|
|
|
|
|
|
CNES ORION (proprietary) |
🛡️ Stability fixes
Degenerate grids no longer crash array_grid_resampling
When a grid is malformed (e.g. single-point grid, metrics can’t be computed), array_grid_resampling now:
emits a
UserWarning: “Grid metrics cannot be computed. Check your input grid data”fills the output with
nodata_outmarks the output mask as fully invalid
This matches the existing behaviour of basic_grid_resampling_chain.
Input mask dimension check in basic_grid_resampling_chain
The input mask is now verified to share width and height with the input array. Previously, a mismatch surfaced as an opaque indexing error from the Rust call stack.
📚 Breaking changes
trust_padding is now required when boundary_condition is set
In v0.5.0, providing boundary_condition silently meant “padded border is valid data”. For most interpolators this was fine; for B-Spline it was already handled correctly under the hood, since prefiltering devalidates the padded border via influence-radius erosion.
v0.6.0 exposes that decision as trust_padding. It must be explicit whenever boundary_condition is set — there is no implicit default.
# Before
array_grid_resampling(..., boundary_condition='reflect', standalone=True)
# After (drop-in equivalent of v0.5.x)
array_grid_resampling(
...,
boundary_condition='reflect',
trust_padding=True,
standalone=True,
)
trust_padding=True→ padded border treated as valid; matches v0.5.x.trust_padding=False→ padded border treated as invalid; useful when boundary samples shouldn’t contribute to the result.
For B-Spline, prefiltering still erodes the trusted region by the kernel’s influence radius regardless of this flag. So under identity transforms you’ll see NODATA at corners — that’s the prefilter, not a regression.
Applies to array_grid_resampling, basic_grid_resampling_array, and basic_grid_resampling_chain.
GridMetricsError no longer propagates from array_grid_resampling
Code that caught GridMetricsError around array_grid_resampling will no longer see the exception. Migrate to the warning-based pattern (see Stability fixes above). basic_grid_resampling_chain is unaffected; it already had this contract.
Deprecations
gridr.scaling.shmutils
The shmutils module is deprecated and will be removed in a future release. Use gridr.scaling.shared_array instead. The legacy module still works but emits a DeprecationWarning on import.
Two renames:
SharedMemoryArray→SharedArray(the old name remains as an alias)create_and_register_sma→create_and_register, which now appendsSharedArrayinstances to the tracking list instead of name strings
# Before
from gridr.scaling.shmutils import SharedMemoryArray, create_and_register_sma
register = []
sma = create_and_register_sma(shape, dtype, register, prefix="buf")
# register contains: ["1-buf-..."]
# After
from gridr.scaling.shared_array import SharedArray, create_and_register
register = []
sa = create_and_register(shape, dtype, register, prefix="buf")
# register contains the SharedArray instance
SharedArray.clear_buffers accepts both forms during the transition, but new code should use instances.
These modules are internal plumbing for the chain subsystem. Most users won’t import from shmutils directly.
📖 Documentation
The user-guide documentation has been reorganized and broken into a series of shorter, self-contained notebook pages that work independently.
A new notebook walks through the standalone preprocessing pipeline: source extent computation, padding strategies per boundary condition, mask preparation (including safe-window logic), and B-Spline prefiltering with its effect on the safe window. Ships with a grid_resampling_plot_utils.py helper for adaptive matplotlib rendering.
Location: notebooks/grid_resampling_core_standalone.ipynb.
Two new reference pages were also added for the shared-memory subsystem: the SharedArray documentation, and a central catalog of environment variables with Docker / Kubernetes / systemd / GitLab CI recipes.
🔧 Migration
Add
trust_padding=Truewherever you use a boundary condition. This preserves the v0.5.x behaviour.array_grid_resampling( ..., boundary_condition='reflect', trust_padding=True, standalone=True, )
(Optional) If you know your input is mostly valid, declare a safe window via
array_in_mask_safe_win.(Optional) Replace any
try/except GridMetricsErroraroundarray_grid_resamplingwith the warning-based pattern.(Only if you import from
shmutils) Switch togridr.scaling.shared_arrayto silence the deprecation warning.(Docker) If you were raising
--shm-size, keep doing it or switch toGRIDR_SHARED_MEMORY_BACKEND=mmap.
Internals
Substantial Rust refactor. None of this changes the Python API:
Const-generic separable convolution:
KROWSandKCOLSare now compile-time parameters, enabling zero-cost specialization across the four convolution variants (masked/unmasked × bounds-checked/unchecked).GxArrayViewInterpolatorCoretrait: B-Spline, bicubic, and linear interpolators now only implementcompute_weights; kernel application is inherited.Unified mask strategy: the standalone and chain Python paths share a single
resolve_mask_strategyfunction, guaranteeing identical mask decisions for identical inputs.
📦 Installation
pip install --upgrade gridr
Wheels are built with AVX2 + FMA. Requirements:
Python ≥ 3.10
PyO3 ≥ 0.27.2
x86_64 with AVX2 and FMA (Intel Haswell / AMD Excavator and later, i.e. essentially anything from 2013 onwards)
For older CPUs or non-x86_64 platforms, build from source.
Links
Documentation: https://gridr.readthedocs.io/
Issues: https://github.com/CNES/gridr/issues
Discussions: https://github.com/CNES/gridr/discussions