Skip to content

fix: make transforms structure-agnostic and enforce it in tests - #152

Draft
yeetypete wants to merge 11 commits into
mainfrom
fix/make-transforms-input-agnostic
Draft

yeetypete wants to merge 11 commits into
mainfrom
fix/make-transforms-input-agnostic

Conversation

@yeetypete

@yeetypete yeetypete commented Jul 26, 2026 •

Copy link
Copy Markdown
Owner

vision3d's transforms are supposed to work on any sample structure (a dict, an (inputs, targets) pair, a nested dict, a NamedTuple) deciding what to act on from each leaf's type rather than from a key name or position. In this PR we fix remaining issues in existing transforms and also enforce this contract going forwards.

Structure-agnosticism fixes

PointShuffle, PointSample and PointJitter drew one set of parameters for the whole sample, so a sample holding both a lidar and a radar cloud broke as soon as the two differed in length. Parameters are now keyed by leaf identity and each cloud is shuffled, sampled and jittered independently.

CopyPaste3D treated every plain tensor in a batch as per-box labels, so a batch carrying a timestamp failed with a misleading count error. It now locates labels through labels_getter.

RangeFilter3D still hand-rolls forward to reach the labels_getter, but every leaf dispatches through the standard transform() hook, and calling any transform with no inputs now raises.

Correctness fixes found along the way

  • CopyPaste3D could not be pickled at all: its object database used a lambda as the defaultdict factory, which torch.save and DataLoader's spawn start method both need.
  • Rotating a float64 point cloud or box set failed on the matmul, because the rotation matrix is built in the default dtype.
  • A batch with no boxes was rejected rather than passed through, so lidar-only, camera-only and multimodal batches all failed unless they were annotated.

Test consolidation

Transform structure tests are now their own parametrized test suite driven by a registry. A coverage test fails if a transform is exported without an entry to ensure that all transforms get tested.

fyi: @simonschlaepfer

yeetypete added 11 commits July 26, 2026 18:40
Parameters are keyed by leaf identity, so a sample may now hold several point clouds of differing length (e.g. lidar and radar) and each is shuffled, sampled, and jittered independently.
RangeFilter3D still hand-rolls forward to reach the labels_getter, but every leaf now dispatches through the standard transform() hook and the no-input guard is shared with the base class.
The tests generated random box positions and sizes, so on some draws every jittered pose collided and nothing was pasted, silently skipping the assertions. Fixed unit cubes spaced wider than the offsets under test make the paste impossible to miss.
The object database used a lambda as its defaultdict factory, so the transform could not be pickled at all, which torch.save and DataLoader's spawn start method both require.
The default getter now resolves label-like keys the way torchvision does, so conventions like gt_labels work without a custom getter, and labels_getter=None resolves to a module-level function instead of a lambda so the transform stays pickleable.
Any plain tensor in the batch was treated as per-box labels, so a sample carrying something else such as a timestamp failed with a misleading count error instead of passing it through untouched.
The rotation matrix is built in the default dtype, so rotating a float64 point cloud or box set failed on the matmul rather than returning float64.
A batch with no boxes has nothing to copy or paste, but any point cloud or camera tensor in it was counted against zero box sets and rejected, so lidar-only, camera-only and multimodal batches all failed unless they were annotated.
Every transform exported by vision3d.transforms now has a registry entry, so
the structure, pickling, pass-through and parameter-sharing audits run against
each one automatically instead of being scattered per-transform and skipped
for anything new.
Raise when the entry does not match the target sample during copy /
paste.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant