Skip to content

Make PermutedDims a valid broadcast leaf#198

Merged
mtfishman merged 2 commits into
mainfrom
mf/permuteddims-broadcast
Jul 1, 2026
Merged

Make PermutedDims a valid broadcast leaf#198
mtfishman merged 2 commits into
mainfrom
mf/permuteddims-broadcast

Conversation

@mtfishman

@mtfishman mtfishman commented Jul 1, 2026

Copy link
Copy Markdown
Member

Summary

Makes PermutedDims a valid Base.Broadcasted leaf, so a linear-combination broadcast that carries a lazily permuted operand (adding a permuted array, say) flattens through tryflattenlinear and materializes via bipermutedimsopadd! on the parent. The wrapper is still never indexed.

Generalizes islinearbroadcast so any leaf type participates, not just AbstractArray/Broadcasted. The default leaf slot is now ::Any, with ::Number marking the scalars, and that distinction is what keeps the predicate correct: scaling by a scalar is linear while a scalar shift (a .+ 1) is affine, and an elementwise array product is nonlinear while scaling is not. A PermutedDims wrapper (or a backend tensor) is then admitted by the ::Any slot with no dedicated method, and PermutedDims becomes public.

Builds on #195.

## Summary

Makes `PermutedDims` a valid `Base.Broadcasted` leaf, so a linear-combination broadcast that carries a lazily permuted operand (adding a permuted array, say) flattens through `tryflattenlinear` and materializes via `bipermutedimsopadd!` on the parent, instead of hitting the `broadcastable` fallback that would `collect` it. It implements the broadcast-leaf interface (`axes`, `eltype`, `broadcastable`, `BroadcastStyle`) and is still never indexed, since the fold absorbs it into a single leaf call.

Generalizes `islinearbroadcast` so any leaf type participates, not just `AbstractArray`/`Broadcasted`. The default leaf slot is now `::Any`, with `::Number` marking the scalars, and that distinction is what keeps the predicate correct: scaling by a scalar is linear while a scalar shift (`a .+ 1`) is affine, and an elementwise array product is nonlinear while scaling is not. A `PermutedDims` wrapper (or a backend tensor) is then admitted by the `::Any` slot with no dedicated method, and `PermutedDims` becomes public.

Builds on #195.
@codecov

codecov Bot commented Jul 1, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 38.70968% with 19 lines in your changes missing coverage. Please review.
✅ Project coverage is 82.95%. Comparing base (7420b03) to head (e04423d).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
src/linearbroadcasted.jl 26.08% 17 Missing ⚠️
src/permutedimsadd.jl 75.00% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #198      +/-   ##
==========================================
- Coverage   83.38%   82.95%   -0.43%     
==========================================
  Files          22       22              
  Lines         656      669      +13     
==========================================
+ Hits          547      555       +8     
- Misses        109      114       +5     
Flag Coverage Δ
docs 26.86% <0.00%> (-0.56%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ 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.

@mtfishman mtfishman enabled auto-merge (squash) July 1, 2026 23:11
@mtfishman mtfishman merged commit 9281f33 into main Jul 1, 2026
19 of 21 checks passed
@mtfishman mtfishman deleted the mf/permuteddims-broadcast branch July 1, 2026 23:28
mtfishman added a commit to ITensor/ITensorBase.jl that referenced this pull request Jul 1, 2026
## Summary

Aligns a misaligned operand in named-tensor broadcasting with
`TensorAlgebra.PermutedDims` instead of `Base.PermutedDimsArray`.
`PermutedDimsArray` encodes the permutation in a type parameter, so a
runtime permutation forces a type-unstable, allocating construction on
every permuted add. `PermutedDims` stores the permutation in a field,
builds cheaply and type-stably, and is a broadcast leaf the
linear-combination fold absorbs via `bipermutedimsopadd!`, so a permuted
add no longer pays that type-construction floor and closes most of the
gap to an aligned add. The wrapper stays confined to the broadcast
alignment path (`broadcasted_unnamed`) and is never returned by the
public `unnamed(a, names)`.

Builds on the broadcast-friendly `PermutedDims` from
ITensor/TensorAlgebra.jl#198.
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