Files
Dmytro Mishkin a2745009f9
Tests on CPU (scheduled) / check-skip (push) Has been cancelled
Tests on CPU (scheduled) / pre-tests (push) Has been cancelled
Tests on CPU (scheduled) / tests-cpu-ubuntu (float32) (push) Has been cancelled
Tests on CPU (scheduled) / tests-cpu-ubuntu (float64) (push) Has been cancelled
Tests on CPU (scheduled) / tests-cpu-windows (windows-2022, 3.11, float32, 2.5.1) (push) Has been cancelled
Tests on CPU (scheduled) / tests-cpu-windows (windows-2022, 3.11, float64, 2.5.1) (push) Has been cancelled
Tests on CPU (scheduled) / tests-cpu-windows (windows-2022, 3.12, float32, 2.5.1) (push) Has been cancelled
Tests on CPU (scheduled) / tests-cpu-windows (windows-2022, 3.12, float64, 2.5.1) (push) Has been cancelled
Tests on CPU (scheduled) / tests-cpu-windows (windows-latest, 3.11, float32, 2.9.1) (push) Has been cancelled
Tests on CPU (scheduled) / tests-cpu-windows (windows-latest, 3.11, float64, 2.9.1) (push) Has been cancelled
Tests on CPU (scheduled) / tests-cpu-windows (windows-latest, 3.12, float32, 2.9.1) (push) Has been cancelled
Tests on CPU (scheduled) / tests-cpu-windows (windows-latest, 3.12, float64, 2.9.1) (push) Has been cancelled
Tests on CPU (scheduled) / tests-cpu-windows (windows-latest, 3.13, float32, 2.9.1) (push) Has been cancelled
Tests on CPU (scheduled) / tests-cpu-windows (windows-latest, 3.13, float64, 2.9.1) (push) Has been cancelled
Tests on CPU (scheduled) / tests-cpu-mac (3.11, float32, 2.5.1) (push) Has been cancelled
Tests on CPU (scheduled) / tests-cpu-mac (3.11, float32, 2.9.1) (push) Has been cancelled
Tests on CPU (scheduled) / tests-cpu-mac (3.12, float32, 2.5.1) (push) Has been cancelled
Tests on CPU (scheduled) / tests-cpu-mac (3.12, float32, 2.9.1) (push) Has been cancelled
Tests on CPU (scheduled) / tests-cpu-mac (3.13, float32, 2.9.1) (push) Has been cancelled
Tests on CPU (scheduled) / coverage (push) Has been cancelled
Tests on CPU (scheduled) / typing (push) Has been cancelled
Tests on CPU (scheduled) / tutorials (push) Has been cancelled
Tests on CPU (scheduled) / docs (push) Has been cancelled
docs(geometry): per-op Convention blocks for crops, flips, pyramid, TPS and elastic (#3926)
* test(geometry): pin crop/flip/pyramid/tps/elastic conventions

Add one test_convention_* per unpinned line from audit2.md §C (16 items):
box/batch broadcast direction, padding_mode='zeros' defaults, CenterCrop2D's
align_corners being ignored under cropping_mode='slice', center_crop3d /
crop_by_boxes3d align_corners defaults, a direct test for
crop_by_transform_mat3d (previously untested), pyrdown's align_corners/
border_type effect and floor-vs-ceil sizing, warp_image_tps's default
align_corners=False breaking identity warps, elastic_transform2d's noise
channel/axis semantics and kernel_size/sigma (y,x) vs alpha (x,y) order, and
crop_by_indices's shape_compensation='pad' path. All tests characterize
current behavior only; no kornia/ changes.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QhGR4iv6NMv5jwpYh4NKyR

* test(geometry): extend §C item 9 pin to pyrup, not just pyrdown

pyrup is an independent implementation (interpolate-then-blur, no
delegation to pyrdown), so the existing pyrdown-only pin gave it no
coverage despite §C item 9 naming both ops. Add a sibling
test_convention_align_corners_and_border_type_change_output in
TestPyrUp mirroring the TestPyrDown assertions: align_corners=False
(default) differs from True, and border_type='reflect' (default)
differs from 'constant' -- both confirmed by execution.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QhGR4iv6NMv5jwpYh4NKyR

* docs(geometry): convention blocks for 2d/3d crop ops

Add Convention: rubric blocks to all 6 crop2d.py symbols (center_crop,
crop_and_resize, crop_by_boxes, crop_by_transform_mat, crop_by_indices,
CenterCrop2D) and all 4 crop3d.py symbols (center_crop3d,
crop_and_resize3d, crop_by_boxes3d, crop_by_transform_mat3d), pinning
box/point order, inclusive-pixel semantics, origin, align_corners and
padding_mode defaults per audit2.md §A.

Also fixes pre-existing wrong docstring facts flagged by the audit:
invalid 'torch.zeros' padding_mode value (crop2d.py, 4 occurrences),
an unmarked 'reflection' literal, crop_and_resize3d's size Args
missing "depth", and crop_by_transform_mat3d's tensor Args wrongly
claiming a 2D (B, C, H, W) shape instead of the actual 3D
(B, C, D, H, W) volume shape.

Docstring-only change; no runtime code touched.

* docs(geometry): fix crop_by_indices shape_compensation gating claim

The Convention block (and a Task 2 test comment) claimed
shape_compensation only matters when box SIZES differ across the
batch, implying same-size/different-position boxes take the fast
uniform-batch path. Verified by execution that's false: the actual
gate (crop2d.py:406) requires src_box to be literally identical
(same position AND size) for every batch item -- same-size,
different-position boxes fall through to the per-item loop where
shape_compensation is genuinely consulted. Reworded both the
Convention block and the test comment to match the code's actual
condition; no assertions changed.

* docs(geometry): convention blocks for flip, pyramid, TPS and elastic ops

* docs: add missing rst entries for transform ops

Adds the 6 symbols the audit found with zero rst coverage anywhere:
crop_by_transform_mat and CenterCrop2D under the existing "Crop
operators"/"Module" sections, and a new "Crop operators (3D)" section
(center_crop3d, crop_and_resize3d, crop_by_boxes3d,
crop_by_transform_mat3d) so 3D crop ops are not listed under the 2D
heading. Verified via a clean sphinx -W build: all six ids render and
no new warnings were introduced.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QhGR4iv6NMv5jwpYh4NKyR

* docs(geometry): final-review polish — 3d inclusive corners, TPS kernel_centers clause, sigma-order pin

- crop3d.py: state that crop_and_resize3d/crop_by_boxes3d boxes are inclusive
  pixel positions, matching crop2d.py's phrasing (verified: box (1,1,1)..(2,2,2)
  gives the exact [1:3,1:3,1:3] slice).
- thin_plate_spline.py: document that kernel_centers must be the second
  positional argument passed to get_tps_transform (verified: passing the other
  point set silently produces the wrong warp).
- test_elastic_transform.py: add an assertion that actually pins the sigma
  (y, x) order claim via an anisotropic-sigma impulse-spread test, since the
  existing symmetric kernel_size/sigma values could not discriminate it.

* docs+tests(geometry): review-wave fixes — laplacian level semantics, scale-pyramid sigmas, rank/shape contracts, MPS 3d border unguard

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QhGR4iv6NMv5jwpYh4NKyR

* test(geometry): precise return annotation for _moved_rows helper

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QhGR4iv6NMv5jwpYh4NKyR

* docs+tests(geometry): round-2 review fixes — laplacian pad condition, scale-pyramid octave-0, dual-shape Args, hflip rank-0, TPS precision wording

* docs(geometry): fix laplacian max_level wording self-contradiction

* docs(geometry): re-derive crop_by_transform_mat homogeneous-form claim after #3650

#3650 (d72d71c2, merged to main) changed crop_by_transform_mat's (B, 3, 3)
dispatch from warp_affine (top-two-rows-only slice) to warp_perspective using
the full matrix, so the previous "only the top two rows are used" bullet is
now false for the homogeneous form. Re-derive it from executed behavior:
(B, 2, 3) affine and its (B, 3, 3) trivial-row embedding still produce
identical output (both align_corners modes), but a non-trivial projective
third row now changes the output. crop3d's sibling
crop_by_transform_mat3d bullet is re-verified unaffected (3D path untouched
by #3650, warp_affine3d still slices to the top three rows).

* docs+tests(geometry): wave-3 fixes — 3d align_corners caveat, warning directives, altitude trims, dedup

* docs(geometry): fix warning antecedent in warp_image_tps

* docs+tests(geometry): wave-4 fixes — degenerate-size caveat, TPS recipe, dedicated issue links, max_level unpin, test robustness

- crop2d.py crop_by_transform_mat: scope the (B,3,3)-uses-full-matrix claim to
  non-degenerate out_size and add a warning for the two degenerate-size
  exceptions (align_corners=True + a size-1 dim -> all-NaN; align_corners=False
  + a size-1 dim -> silent warp_affine fallback that drops the projective row),
  linking #3929.
- pyramid.py ScalePyramid: qualify the "absolute blur = sigmas * pixel_dists"
  rule -- exact for level 0 and octave 1+, but an underestimate for octave-0
  levels >= 1 when init_sigma is below the assumed input blur (verified by
  composing the blur kernels: true ~0.661 vs labeled 0.5, ~32% off, for the
  existing init_sigma=0.25 example).
- thin_plate_spline.py: fix get_tps_transform's incomplete/incorrect bullet
  (neither warp function calls it; the caller composes them) and add one
  explicit recipe code-block; fix warp_image_tps's dangling "this function's
  own points_src" reference (it has no such parameter).
- Retarget both existing `.. warning::` blocks from the closed #3923 to their
  dedicated issues: pyramid.py -> #3927 (both build_pyramid/
  build_laplacian_pyramid), thin_plate_spline.py -> #3928.
- max_level: drop the two test pins that blessed non-positive max_level as
  contractual behavior (the bounds check should reject it); replace the Args
  "currently behaves like max_level=1" sentences with warnings noting the
  bounds check gap, consistently on both builders.
- crop3d.py crop_by_boxes3d: replace the duplicated 3D box-corner convention
  with a cross-reference to crop_and_resize3d (its sibling), keeping only the
  differing dst_box-determines-resolution line.
- test_elastic_transform.py: replace the exact threshold-crossing pixel-list
  pin for sigma's (y, x) order with a robust ordering-property assertion
  (weighted row-spread std, ~18x ratio); mutation-killed by swapping the
  sigma_y/sigma_x assignment.
- test_crop3d.py: consolidate the ~85-line align_corners-default test onto a
  single small fixture, dropping the duplicated 7x7x7 box literals already
  covered by test_crop_by_boxes_resizing.
- Add missing generation-snippet comments (test_pyramid.py octave0 sigmas
  example, test_flip.py hflip rank-1 literal).
- CLAUDE.md: note that tests run under the repo .venv (torch 2.9.1, via
  `pixi run test`/`uv run pytest`), not the separate .pixi environment.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QhGR4iv6NMv5jwpYh4NKyR

* docs(geometry): restore integer qualifier in max_level warnings

Wave-4's new max_level warnings on build_pyramid/build_laplacian_pyramid
over-broadened wave 3's deliberate "non-positive INTEGER" qualifier to
plain "non-positive values" -- false for non-integer max_level (e.g. -0.5),
which raises TypeError from range() rather than returning a single-element
list. Restored the integer qualifier, word-identical in both warnings, with
the verified non-integer TypeError behavior noted inline.

Re-verified by execution: max_level=0/-1 -> single-element list (both
builders); max_level=-0.5/-1.5 -> TypeError: 'float' object cannot be
interpreted as an integer (both builders).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QhGR4iv6NMv5jwpYh4NKyR

* docs+tests(geometry): wave-5 — TPS arg-order prose, nominal sigma framing, xfail #3928, durability trims

Convergence pass on PR #3926: fix a wrong argument-position claim in
warp_image_tps's kernel_centers prose (second positional arg of the
reversed get_tps_transform call, not first); rewrite ScalePyramid's
sigmas/pixel_dists documentation as nominal bookkeeping metadata with a
single propagation caveat instead of a per-level exactness claim that
kept being wrong across waves; drop the TypeError-specific max_level
wording (subtractive, since the exact exception class kept churning);
convert the TPS default-align_corners-breaks-identity pin to a
strict-xfail asserting the *intended* behavior so a future fix forces
the mark's removal instead of silently staying green; centralize the
duplicated MPS 2D grid_sample 'border' guard into a shared conftest
helper; drop the hflip rank-0 pin (blessed accident of torch.flip's
0-d dim wrapping, not a documented contract); shrink the ScalePyramid
sigma-pin fixture 64x64 -> 32x32 (re-verified unchanged values); add a
comment on the intentionally-unguarded 3D MPS border call; add the
missing Returns section to crop_by_indices; make the CLAUDE.md
dual-environment note version-free.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QhGR4iv6NMv5jwpYh4NKyR

* test(geometry): make 2d border-padding guard a runtime capability probe

supports_2d_border_padding hardcoded device.type != "mps", so it would
stay silently skipped forever once PyTorch adds 2D border-padding
support on MPS. Replace it with a cached runtime probe that attempts a
tiny grid_sample(padding_mode='border') and only treats the known
"Unsupported Border padding mode" RuntimeError as unsupported,
re-raising anything else. Cached per device type via functools.cache.

* docs+tests(geometry): wave-7 — TPS normalized-coords requirement, probe into testing pkg, visible MPS skips, dedup

- thin_plate_spline.py: warp_image_tps's Convention block now states that all
  control points feeding kernel_weights/affine_weights (and kernel_centers
  itself) must already be in normalized [-1, 1] grid coordinates, since the
  function always evaluates the TPS on a grid built via
  create_meshgrid(..., normalized_coordinates=True) regardless of the
  align_corners argument; pixel-space control points silently produce a
  wrong warp of the correct shape. Pinned by a new
  test_convention_control_points_normalized_coords. The get_tps_transform
  <-> warp_points_tps/warp_image_tps kernel_centers binding rule is now
  stated in full once (get_tps_transform) with the other two functions
  cross-referencing it in one line each instead of restating it.
- testing/base.py: moved supports_2d_border_padding (and its runtime probe)
  out of tests/geometry/transform/conftest.py, which only resolved via
  pytest's default prepend import mode and raced other conftest.py modules
  for sys.modules['conftest']. Deleted that conftest.py; both call sites now
  import it from testing.base alongside BaseTester.
- test_elastic_transform.py/test_thin_plate_spline.py: split each
  border-padding half out of its guarded `if` block into its own test that
  pytest.skips visibly on MPS, instead of the guard silently no-op'ing the
  assertion. The zeros-default assertions stay unguarded in the original
  tests. Also split test_convention_kernel_size_sigma_yx_alpha_xy_order into
  independent test_convention_alpha_xy_order /
  test_convention_sigma_yx_order tests with no shared state.
- flips.py: hflip's "requires rank >= 1" claim was unenforced
  (hflip(torch.tensor(5.0)) succeeds); its Convention block now states only
  that it flips the last dimension, no rank-floor claim. vflip/rot180 keep
  their enforced "requires rank >= 2". Dropped the directed
  "unlike center_crop/pyrdown"/"unlike hflip/vflip/rot180" cross-op
  couplings from rot180/hflip/vflip and center_crop's Convention blocks.
- CLAUDE.md: deduplicated the dual-environment note (was stated twice in
  consecutive sentences).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QhGR4iv6NMv5jwpYh4NKyR

* test(geometry): fix stale conftest path in comment

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QhGR4iv6NMv5jwpYh4NKyR

* docs(geometry): TPS two-frame normalization, truncation attribution, warning trims

thin_plate_spline.py: the Convention blocks for get_tps_transform/warp_image_tps
claimed all control points use the corner-aligned normalization regardless of
align_corners -- wrong at the default. warp_image_tps's internal output/destination
lattice (create_meshgrid(..., normalized_coordinates=True)) is always corner-aligned,
but kernel_centers and the source-side control points must instead match the
function's own align_corners: at the default False that is the half-pixel mapping
(2x+1)/W - 1, not the corner-aligned 2x/(W-1) - 1. Rewrote both Convention blocks and
the accompanying warning to distinguish the two frames, and reworded the "[-1, 1]"
mention to describe it as the in-bounds extent rather than a validity bound. Fixed a
test comment that claimed an unperformed pixel-space contrast.

crop3d.py: crop_by_transform_mat3d's Convention block misattributed the (B,4,4) ->
(B,3,4) truncation to warp_affine3d; the slice happens in crop_by_transform_mat3d
itself, and warp_affine3d actually rejects (B,4,4) input.

test_flip.py: fixed a stale comment claiming hflip has a "documented rank floor of 1";
the docstring documents no floor at all, and rank-0 also works.

pyramid.py: dropped the "(non-integer max_level values still raise an error)"
parenthetical from both max_level warnings -- the split is more nuanced (positive
floats raise the check's BaseError, negative floats pass the check and die
incidentally in range() with TypeError) and is out of scope for a warning about the
non-positive-integer gap.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QhGR4iv6NMv5jwpYh4NKyR

* docs(geometry): explicit hflip rank bullet; correct rank-0 comment

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QhGR4iv6NMv5jwpYh4NKyR

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-08-09 22:45:51 +02:00
..
2025-12-31 18:20:32 +01:00
2025-12-31 18:20:32 +01:00