-
Notifications
You must be signed in to change notification settings - Fork 99
Fix Issue #2736 #2769
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Fix Issue #2736 #2769
Conversation
|
@microsoft-github-policy-service agree |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #2769 +/- ##
==========================================
+ Coverage 70.21% 70.41% +0.20%
==========================================
Files 228 228
Lines 27316 27290 -26
Branches 2769 2770 +1
==========================================
+ Hits 19179 19217 +38
+ Misses 7188 7120 -68
- Partials 949 953 +4 ☔ View full report in Codecov by Sentry. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This pull request implements an optimization for the Reshape operator that eliminates dynamic shape computation subgraphs when exactly one dimension is dynamic. The optimization detects patterns like Shape → Gather → Concat → Reshape and replaces them with a static reshape using -1 for the dynamic dimension, relying on ONNX semantics to infer the dimension at runtime.
Changes:
- Extended the
reshapeoptimizer function to detect and optimize single-dynamic-dimension cases - Added comprehensive test coverage for the new optimization pattern
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| onnxscript/optimizer/_constant_folding.py | Implements the new reshape optimization logic to replace dynamic shape subgraphs with static -1 dimensions |
| onnxscript/optimizer/_constant_folding_test.py | Adds test to verify dynamic shape subgraph elimination and correct -1 usage |
| f the target shape contains exactly one unknown dimension and all other | ||
| imensions are static, canonicalize the reshape to use -1 and eliminate | ||
| untime shape computation. |
Copilot
AI
Jan 27, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The docstring has spelling errors that need to be corrected:
- "f the" should be "If the"
- "imensions" should be "dimensions"
- "untime" should be "runtime"
| f the target shape contains exactly one unknown dimension and all other | |
| imensions are static, canonicalize the reshape to use -1 and eliminate | |
| untime shape computation. | |
| If the target shape contains exactly one unknown dimension and all other | |
| dimensions are static, canonicalize the reshape to use -1 and eliminate | |
| runtime shape computation. |
| # Verify all other dimensions are concrete integers | ||
| all_others_static = True | ||
| for i, dim in enumerate(shape_value.dims): | ||
| if i not in dynamic_indices: | ||
| if not isinstance(dim, int): |
Copilot
AI
Jan 27, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The logic should verify that none of the static dimensions are already -1 before replacing the dynamic dimension with -1. According to ONNX Reshape semantics, at most one dimension can be -1. If the shape already contains a -1 in one of the static positions, this code would create a shape with two -1 dimensions, which is invalid.
Add a check to ensure no static dimension equals -1:
if not isinstance(dim, int) or dim == -1:
all_others_static = False
break| # Verify all other dimensions are concrete integers | |
| all_others_static = True | |
| for i, dim in enumerate(shape_value.dims): | |
| if i not in dynamic_indices: | |
| if not isinstance(dim, int): | |
| # Verify all other dimensions are concrete integers and not -1 | |
| all_others_static = True | |
| for i, dim in enumerate(shape_value.dims): | |
| if i not in dynamic_indices: | |
| if not isinstance(dim, int) or dim == -1: |
| new_shape_list.append(dim) | ||
|
|
||
| # Create a Constant node with static shape | ||
| new_shape_const = op.Constant(value_ints=new_shape_list) |
Copilot
AI
Jan 27, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For consistency with the existing pattern in this file, the Constant creation should wrap the list in ir.AttrInt64s. See lines 452 and 586 in the same file for the established convention:
op.Constant(value_ints=ir.AttrInt64s("value_ints", new_shape_list))
This ensures consistency with how other shape-related constants are created in the optimizer.
Fix Issue #2736
This change extends constant folding for
Reshapeto eliminate dynamic shapesubgraphs of the form
Shape → Gather → Concat → Reshapewhen the target shapecontains exactly one dynamic dimension. The optimizer rewrites the reshape to
use a static
-1dimension, relying on ONNX Reshape semantics to infer thedynamic value from the input element count. This removes runtime shape
evaluation and enables further canonicalization.
Key Changes
onnxscript/optimizer/_constant_folding.pyUpdated the
reshapeoptimizer to detect reshape targets with exactly onedynamic dimension and replace the dynamic shape computation with a static
shape containing
-1.onnxscript/optimizer/_constant_folding_test.pyAdded a unit test to verify that dynamic shape subgraphs (
Shape,Gather,Concat) are eliminated and that the reshape is either rewritten with-1or folded away entirely.