Release Notes — 2.1.2

Summary

This is a performance and correctness patch release. It delivers 8×–54× speedups for MaskDropout bbox filtering and 3.5×–5.6× speedups for ConstrainedCoarseDropout, fixes a crash in GridDropout with equal-bounds unit_size_range, fixes bbox coordinate handling in mask_dropout_bboxes, and hardens the release pipeline with SBOM generation, PyPI trusted publishing (OIDC), and supply-chain security tooling. Dependency albucore is bumped to 0.1.5.


Performance

MaskDropout — bbox filtering (mask_dropout_bboxes)

Replaced the O(N·H·W) ogrid broadcast with a hybrid strategy:

  • Per-box slice sums for typical detection workloads (≤8× image coverage by bboxes).
  • Integral-image (prefix-sum) query when boxes collectively cover the image many times over.

Benchmarks on 1024×1024 images across 9 size/channel combinations:

Speedup
mask_dropout_bboxes function8×–54×
MaskDropout full pipeline1.2×–1.4×

ConstrainedCoarseDropout — mask sampling (sample_points_from_components)

Replaced the per-component np.argwhere(labels == label) loop with a single nonzero pass: all foreground pixels are collected once, sorted/grouped by label, then sampled within each group.

Speedup
sample_points_from_components5×–6×
ConstrainedCoarseDropout full pipeline3.5×–5.6×

Bug fixes

GridDropout crash with equal-bounds unit_size_range

calculate_grid_dimensions treated the upper bound of unit_size_range as exclusive (matching NumPy's integers(low, high) convention), causing GridDropout(unit_size_range=(n, n)) to raise a ValueError. The upper bound is now treated as inclusive. A regression test is added.

mask_dropout_bboxes — bbox coordinate handling

Two correctness issues fixed:

  1. Rounding: plain .astype(np.int32) truncated float bbox coordinates inconsistently. Now uses floor for inclusive min corners and ceil for exclusive max corners, so fractional denormalized coordinates don't silently drop pixel rows/columns.
  2. Clamping: bbox coordinates were used as raw array indices without clamping. Bboxes extending outside the image (e.g. when clip_after_transform=False) could produce IndexError in the integral-image path or silent wrap-around in the slice path. Coordinates are now clipped to [0, width] / [0, height].

Infrastructure

Release integrity

  • PyPI publishing now uses OIDC trusted publishing (no long-lived API tokens).
  • Release workflow generates SBOM (CycloneDX) and SHA-256 checksums for all release assets.
  • SECURITY.md added with disclosure process, supported versions, and SLAs.
  • uv.lock is now committed and checked in CI for reproducible builds.
  • Pre-commit hook added to enforce uv.lock consistency.

Dependency bump

  • albucore updated from 0.1.3 → 0.1.5.

Commits

CommitDescription
932e050perf(dropout): speed up MaskDropout bbox filtering and ConstrainedCoarseDropout mask sampling (#211)
c9ed204refactor(core): add same-shape batch helper _apply_to_batch_same_shape (#210)
60b0666feat(security): release integrity — policy, trusted publishing, SBOM (#209)
0b54c0dchore: bump version to 2.1.2, albucore to 0.1.5, overhaul release workflow (#212)