Recognise the repeat_interleave idiom in RemovePermutesAroundElementwiseOps (#21790) - #21790
Recognise the repeat_interleave idiom in RemovePermutesAroundElementwiseOps (#21790)#21790mcremon-meta wants to merge 1 commit into
Conversation
🔗 Helpful Links🧪 See artifacts and rendered test results at hud.pytorch.org/pr/pytorch/executorch/21790
Note: Links to docs will display an error until the docs builds have been completed. ✅ No FailuresAs of commit 2ec948f with merge base c6213ae ( This comment was automatically generated by Dr. CI and updates every 15 minutes. |
|
@mcremon-meta has exported this pull request. If you are a Meta employee, you can view the originating Diff in D114508262. |
This PR needs a
|
…iseOps (#21790) Summary: `repeat_interleave(scale, dim)` lowers to a three-node idiom:: unsqueeze(dim + 1) -> expand_copy(scale at dim + 1) -> view_copy(merge dim, dim + 1) which the region walker could not cross, so any permuted region containing one was rejected. torchaudio's `Stretch2d` is built from this, so it blocks every upsampling network -- on wavernn it strands the permutes `ConvToChannelsLast` put around each conv in the upsample path. Adding `expand_copy` to `_permutable_ops` on its own does not help: traversal then dies one node later at the merging `view_copy`. That merge is *not* unconditionally layout-invariant the way `cat`/`slice` are -- flattening two dims only commutes with a permutation that leaves them adjacent and in order, otherwise the flatten reorders elements. Worse, handling the three nodes separately would force a choice of un-permuted position for the intermediate unit dim (inserting a size-1 dim is ambiguous: any position gives a consistent permutation). That arbitrary choice then decides whether the later merge is still legal, coupling two rewrites that look independent. So the triple is matched as a unit (`_interleave_triple`). It is rank-preserving overall, so the permutation flows through unchanged and the only rewrite needed is remapping the interleaved dim, `new_dim = P[old_dim]`, plus rebuilding the three shape args in un-permuted space (`update_interleave`). No intermediate layout is ever materialised, so the ambiguity does not arise. Guards: head and expand must each have exactly one user (otherwise the in-place rewrite would corrupt another consumer), every non-inserted dim of the expand must pass through untouched, and the view's output shape must be exactly the merge. Symbolic shapes are declined. The head may be either an explicit `unsqueeze_copy` or a `view_copy` that inserts one unit dim, matching how the pass already treats the two spellings interchangeably. Differential Revision: D114508262
f7d45fa to
657d2fd
Compare
…iseOps (#21790) Summary: `repeat_interleave(scale, dim)` lowers to a three-node idiom:: unsqueeze(dim + 1) -> expand_copy(scale at dim + 1) -> view_copy(merge dim, dim + 1) which the region walker could not cross, so any permuted region containing one was rejected. torchaudio's `Stretch2d` is built from this, so it blocks every upsampling network -- on wavernn it strands the permutes `ConvToChannelsLast` put around each conv in the upsample path. Adding `expand_copy` to `_permutable_ops` on its own does not help: traversal then dies one node later at the merging `view_copy`. That merge is *not* unconditionally layout-invariant the way `cat`/`slice` are -- flattening two dims only commutes with a permutation that leaves them adjacent and in order, otherwise the flatten reorders elements. Worse, handling the three nodes separately would force a choice of un-permuted position for the intermediate unit dim (inserting a size-1 dim is ambiguous: any position gives a consistent permutation). That arbitrary choice then decides whether the later merge is still legal, coupling two rewrites that look independent. So the triple is matched as a unit (`_interleave_triple`). It is rank-preserving overall, so the permutation flows through unchanged and the only rewrite needed is remapping the interleaved dim, `new_dim = P[old_dim]`, plus rebuilding the three shape args in un-permuted space (`update_interleave`). No intermediate layout is ever materialised, so the ambiguity does not arise. Guards: head and expand must each have exactly one user (otherwise the in-place rewrite would corrupt another consumer), every non-inserted dim of the expand must pass through untouched, and the view's output shape must be exactly the merge. Symbolic shapes are declined. The head may be either an explicit `unsqueeze_copy` or a `view_copy` that inserts one unit dim, matching how the pass already treats the two spellings interchangeably. Differential Revision: D114508262
657d2fd to
2ec948f
Compare
Summary:
repeat_interleave(scale, dim)lowers to a three-node idiom::which the region walker could not cross, so any permuted region containing one
was rejected. torchaudio's
Stretch2dis built from this, so it blocks everyupsampling network -- on wavernn it strands the permutes
ConvToChannelsLastput around each conv in the upsample path.
Adding
expand_copyto_permutable_opson its own does not help: traversalthen dies one node later at the merging
view_copy. That merge is notunconditionally layout-invariant the way
cat/sliceare -- flattening twodims only commutes with a permutation that leaves them adjacent and in order,
otherwise the flatten reorders elements.
Worse, handling the three nodes separately would force a choice of un-permuted
position for the intermediate unit dim (inserting a size-1 dim is ambiguous:
any position gives a consistent permutation). That arbitrary choice then
decides whether the later merge is still legal, coupling two rewrites that
look independent.
So the triple is matched as a unit (
_interleave_triple). It is rank-preservingoverall, so the permutation flows through unchanged and the only rewrite needed
is remapping the interleaved dim,
new_dim = P[old_dim], plus rebuilding thethree shape args in un-permuted space (
update_interleave). No intermediatelayout is ever materialised, so the ambiguity does not arise.
Guards: head and expand must each have exactly one user (otherwise the in-place
rewrite would corrupt another consumer), every non-inserted dim of the expand
must pass through untouched, and the view's output shape must be exactly the
merge. Symbolic shapes are declined. The head may be either an explicit
unsqueeze_copyor aview_copythat inserts one unit dim, matching how thepass already treats the two spellings interchangeably.
Differential Revision: D114508262