Skip to content

feat: add fold4d / Fold4d module (inverse of unfold4d)#5173

Open
Bellman281 wants to merge 1 commit into
tracel-ai:mainfrom
Bellman281:feat/fold4d
Open

feat: add fold4d / Fold4d module (inverse of unfold4d)#5173
Bellman281 wants to merge 1 commit into
tracel-ai:mainfrom
Bellman281:feat/fold4d

Conversation

@Bellman281

Copy link
Copy Markdown
Contributor

Pull Request Template

Checklist

  • Confirmed that cargo run-checks command has been executed.
  • Made sure the book is up to date with changes in this PR.

Related Issues/PRs

Provide links to relevant issues and dependent PRs.

Changes

Summarize the problem being addressed and your solution.

Testing

Describe how these changes have been tested.

@Bellman281

Copy link
Copy Markdown
Contributor Author

Checklist

  • Confirmed that cargo run-checks command has been executed.
  • Made sure the book is up to date with changes in this PR.

Related Issues/PRs

Closes #786.

Changes

Adds a fold operation (col2im), the inverse of the existing Unfold4d / unfold4d.

  • burn_tensor::module::fold4d(x, output_size, kernel_size, options) — combines an
    array of sliding local blocks [N, C * kH * kW, L] back into a tensor
    [N, C, H, W], summing the values of blocks that overlap. Matches
    torch.nn.functional.fold.
  • Fold4d / Fold4dConfig in burn-nn, mirroring Unfold4d, exposing
    output_size, kernel_size, stride, padding, and dilation.

Implementation. fold4d is the adjoint of unfold4d. Since unfold4d is a
conv2d with a one-hot "im2col" kernel, fold4d reuses that exact kernel through
conv_transpose2d, with padding_out = (size + 2·pad − dil·(k−1) − 1) mod stride to
recover the requested output_size. It is composed entirely from existing ops, so the
backward pass comes for free through autodiff and no backend / IR / router changes are
needed.

No book change: Unfold4d has no entry in the module reference, so there is nothing to
mirror for Fold4d.

Testing

  • Known-answer test: folds a [1, 4, 4] column tensor into a 3×3 output with a
    2×2 kernel; expected values were computed independently with a numpy col2im
    reference.
  • Round-trip test: verifies fold4d(unfold4d(x)) equals a numpy-computed reference
    (overlaps summed), confirming fold is the true adjoint of unfold.
  • The conv_transpose2d + padding_out approach was cross-checked against a direct
    col2im implementation across 7 configurations (varying stride, padding, dilation,
    and channels), all matching exactly.
  • cargo run-checks passes (fmt, clippy, typos, tests).

@codecov

codecov Bot commented Jul 17, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 66.03%. Comparing base (bd6e8fa) to head (8705717).
⚠️ Report is 6 commits behind head on main.

❌ Your project check has failed because the head coverage (66.03%) is below the target coverage (80.00%). You can increase the head coverage or adjust the target coverage.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #5173      +/-   ##
==========================================
+ Coverage   65.97%   66.03%   +0.06%     
==========================================
  Files        1198     1203       +5     
  Lines      182691   183118     +427     
==========================================
+ Hits       120526   120921     +395     
- Misses      62165    62197      +32     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@Bellman281

Copy link
Copy Markdown
Contributor Author

Thanks! All CI checks are green (macOS just finishing up), and codecov/patch is 100%.
@Charles23R @nathanielsimard whenever you have a moment, this is ready for review — it adds fold4d / Fold4d as the inverse of Unfold4d (closes #786), built as its adjoint via conv_transpose2d so autodiff is free and no backend changes were needed. 🙏

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