Fix Invertd
Fixes #8396 .
Description
This PR fixes a bug where Invertd would fail with a RuntimeError when postprocessing pipelines contain invertible transforms (such as Lambdad) before Invertd is called. Root Cause: Invertd copied the entire applied_operations list (including both preprocessing AND postprocessing transforms) before inversion. When the preprocessing pipeline's inverse was called, it would pop transforms from the end and encounter postprocessing transforms first, causing an ID mismatch error.
Solution: Implements automatic group tracking infrastructure:
Each Compose instance automatically assigns its unique ID as a group identifier to all child transforms (recursively, including deeply nested wrapped transforms)
Transform metadata in applied_operations now includes an optional group field
Invertd automatically filters applied_operations to only include transforms from the target Compose instance
Zero API changes - the solution is fully automatic and transparent to users
Backward compatible - gracefully handles transforms without groups
Types of changes
- [x] Non-breaking change (fix or new feature that would not break existing functionality).
- [ ] Breaking change (fix or new feature that would cause existing functionality to change).
- [x] New tests added to cover the changes.
- [ ] Integration tests passed locally by running
./runtests.sh -f -u --net --coverage. - [ ] Quick tests passed locally by running
./runtests.sh --quick --unittests --disttests. - [x] In-line docstrings updated.
- [ ] Documentation updated, tested
make htmlcommand in thedocs/folder.
Walkthrough
This change implements automatic grouping of nested transforms within Compose instances to enable fine-grained inversion control. When Compose initializes, it assigns a _group identifier (based on instance ID) to nested TraceableTransform objects. This group ID is tracked in the transform info dictionary via a new TraceKeys.GROUP enum member. Invertd now filters applied operations by group ID to invert only transforms from its associated Compose pipeline, preventing cross-interference when multiple pipelines are present. The implementation adds three new private methods (_set_transform_groups in Compose, _filter_transforms_by_group in Invertd) and includes seven new test methods validating multi-pipeline isolation and group tracking behavior.
Estimated code review effort
🎯 3 (Moderate) | ⏱️ ~20 minutes
- monai/transforms/compose.py: Review recursive grouping logic and attribute traversal for nested transforms; verify infinite recursion prevention and Compose re-wrapping avoidance.
- monai/transforms/post/dictionary.py: Examine _filter_transforms_by_group filtering logic and backward-compatibility fallback when no matching group is found.
- tests/transforms/inverse/test_invertd.py: Validate that all seven new test methods correctly exercise the grouping/isolation scenarios and don't introduce false positives; ensure tests cover edge cases like mixed pipelines.
- Cross-file coherence: Confirm TraceKeys.GROUP enum usage is consistent across compose.py, inverse.py, and dictionary.py.
Pre-merge checks and finishing touches
❌ Failed checks (1 warning, 1 inconclusive)
| Check name | Status | Explanation | Resolution |
|---|---|---|---|
| Docstring Coverage | ⚠️ Warning | Docstring coverage is 76.47% which is insufficient. The required threshold is 80.00%. | You can run @coderabbitai generate docstrings to improve docstring coverage. |
| Title check | ❓ Inconclusive | Title is vague and generic, failing to convey the specific changes—adds automatic transform grouping for Invertd to handle multiple pipelines. | Use a more descriptive title like 'Add automatic transform grouping to Invertd for multiple pipeline support' to clarify the main change. |
✅ Passed checks (1 passed)
| Check name | Status | Explanation |
|---|---|---|
| Description check | ✅ Passed | PR description provides clear context: fixes issue #8396, explains the bug, root cause, and solution with automatic group tracking. Includes appropriate checklist items marked. |
✨ Finishing touches
- [ ] 📝 Generate docstrings
🧪 Generate unit tests (beta)
- [ ] Create PR with unit tests
- [ ] Post copyable unit tests in a comment
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.
Comment @coderabbitai help to get the list of available commands and usage tips.