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
* 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>