Repository navigation
Fix moving shape transforms through a shared reduction and fold unsqueeze into multibroadcast - #5365
Merged
Merged
Conversation
Contributor
There was a problem hiding this comment.
🟡 Changes recommended
A shared expanding reduction can shadow a later rewritable input and prevent the intended optimization.
1 open finding
What changed in this PR
Fixes invalid shape-transform rewrites around shared reductions and simplifies redundant unsqueeze/broadcast chains.
Changes:
- Strengthens descriptor rebasing and inverse-transform handling.
- Prevents unsafe shared-reduction rewrites and adds regression coverage.
- Updates affected expected graphs and changelog.
Review performed as a single pass without subagent fan-out. Relevant tests still need CI validation.
| File | Description |
|---|---|
src/simplify_reshapes.cpp |
Guards reduction rewrites and supports axis-expanding broadcasts. |
src/shape_transform_descriptor.cpp |
Implements broadcast detachment, folding, and inverse validation. |
src/include/migraphx/shape_transform_descriptor.hpp |
Exposes axisless-broadcast detection. |
test/simplify_reshapes_test.cpp |
Adds shared and expanding reduction regressions. |
test/shape_transform_descriptor.cpp |
Tests folding, rebasing, and inverse behavior. |
test/rewrite_reduce.cpp |
Updates optimized graph expectations. |
test/fuse_reduce.cpp |
Updates reshape expectation after folding. |
CHANGELOG.md |
Records the resolved issue. |
🧠 Review effort: Balanced
💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Comment on lines
+528
to
+529
| if(not restore_x and not is_private_chain(x_ins, input_ins, ins)) | ||
| return; |
Collaborator
|
This fixes all five failing models from #PR5360 . Thanks |
urpetkov-amd
approved these changes
Oct 8, 2026
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## develop #5365 +/- ##
===========================================
+ Coverage 92.68% 92.72% +0.04%
===========================================
Files 633 635 +2
Lines 36087 36265 +178
===========================================
+ Hits 33446 33625 +179
+ Misses 2641 2640 -1
🚀 New features to boost your workflow:
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Motivation
simplify_reshapesmoves a shape-transform chain between a reduction and a pointwise op into a common space so the two can fuse. When the chain broadcasts a new axis (for examplereduce_mean -> unsqueeze -> multibroadcast -> mul), the pass rebuilt the old reduction for its other consumers withto_src_from_common(), which produced an invalidreshapebecause the broadcasted axis has no source axis to map back to. The result was aMULTIBROADCAST: input shape {1, 1, 1, 1, 6} cannot be broadcastederror at compile time (#5360).While fixing this, the
unsqueeze -> multibroadcastchain itself turned out to be redundant:multibroadcastaligns from the right, so an unsqueezed axis that only follows 1s is added by the broadcast. Folding it exposes the reduction to the pass as a bare broadcast, which previously was always skipped, so the descriptor also needs to tell a broadcast of a new axis apart from a re-broadcast of a reduced axis.Technical Details
shape_transform_descriptor:to_src_from_common()hides the axis of a squeezed-away dimension that came from a broadcast with no source axis ([1:3]becomes[1:$3]).rebase()now refuses to give such a hidden dimension of 1 a different length, so the inverse cannot silently merge the broadcasted axis into a neighbor.generate()drops axis-less dimensions that only follow input dimensions of 1 before emitting amultibroadcast, sounsqueeze{3} + multibroadcast{1,1,1,2,3}on{1,1,1,3}becomes a singlemultibroadcast.optimize_shape_transformsandfind_nested_shape_transformspick this up.rebase(dims, broadcast=true)detaches a hidden broadcast whose source axis is rebased to a size other than 1 or its own length. The axes shift down into a preceding axis-less dimension of 1 and the broadcast becomes its own axis-less dimension, which is the same form the unsqueeze chain produced. Broadcasting a reduced axis back to its size is unaffected.has_axisless_broadcast()reports a broadcasted dimension with no source axis.simplify_reshapes(find_op_shape_transform_op):to_src_from_common()rebases onto the common dims. Otherwise the rewrite proceeds only if the reduction is consumed solely through the chain (is_private_chain), so it becomes dead code, and it bails when the reduction is shared.chain_ops.Tests: new
simplify_reshapescases for the expanding chain, the shared element-preserving chain and the shared expanding chain, plus descriptor cases for the fold, the hidden inverse and the rebase detachment. Existing expectations that contained an unsqueeze absorbed by the broadcast were updated to the shorter equivalent chains (conv_add_layernorm_conv,dequantizelinear_entry_shape_transform_zero_point,pointwise_reshapes_reduce_shadowed_broadcast,dot_skinny_rewrite,dot_softmax_dot_projection_rewrite,optimize_multibroadcast_transpose,generate_shape_transforms_for), andslice_reshape_multibroadcast_rebase_axiscompares output lens since only a size-1 stride changed.Changelog Category
Add a
CHANGELOG.mdentry for any option other thanNot ApplicableFollow the LLVM AI Tool Use Policy for contributions using AI.