-
Notifications
You must be signed in to change notification settings - Fork 66
Support common subexpression elimination pass (CSE) #2304
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
Conversation
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 PR adds a common subexpression elimination (CSE) pass for ONNX graphs, updates the model serialization API to use metadata_props
, and includes tests for the new pass.
- Rename
meta_data_props
parameter tometadata_props
in model constructors and deserialization. - Implement
CommonSubexpressionEliminationPass
incommon_subexpression_elimination.py
. - Add unit tests for the CSE pass in
common_subexpression_elimination_test.py
.
Reviewed Changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.
File | Description |
---|---|
onnxscript/ir/serde.py | Renamed meta_data_props to metadata_props |
onnxscript/ir/_core.py | Updated constructor parameter name to metadata_props |
onnxscript/ir/passes/common/common_subexpression_elimination.py | Added CSE functional pass implementation |
onnxscript/ir/passes/common/common_subexpression_elimination_test.py | Added tests covering CSE behavior |
Comments suppressed due to low confidence (1)
onnxscript/ir/passes/common/common_subexpression_elimination.py:45
- [nitpick] Variable name
input
shadows the built-ininput()
function. Consider renaming tograph_input
or similar for clarity.
for input in old_graph.inputs:
onnxscript/ir/passes/common/common_subexpression_elimination.py
Outdated
Show resolved
Hide resolved
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #2304 +/- ##
==========================================
+ Coverage 70.11% 70.16% +0.04%
==========================================
Files 196 198 +2
Lines 24662 24846 +184
Branches 2656 2670 +14
==========================================
+ Hits 17292 17433 +141
- Misses 6453 6495 +42
- Partials 917 918 +1 ☔ View full report in Codecov by Sentry. |
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
onnxscript/ir/passes/common/common_subexpression_elimination.py
Outdated
Show resolved
Hide resolved
onnxscript/ir/passes/common/common_subexpression_elimination.py
Outdated
Show resolved
Hide resolved
onnxscript/ir/passes/common/common_subexpression_elimination.py
Outdated
Show resolved
Hide resolved
onnxscript/ir/passes/common/common_subexpression_elimination.py
Outdated
Show resolved
Hide resolved
I don't know what the best is, but: what about changing inplace the node input (if two results are the same, then the second one can be replaced inplace with the first one). And then add a pass to remove the unused nodes. |
onnxscript/ir/passes/common/common_subexpression_elimination.py
Outdated
Show resolved
Hide resolved
onnxscript/ir/passes/common/common_subexpression_elimination.py
Outdated
Show resolved
Hide resolved
Changed to inplace pass. Subgraph is not yet tackled. |
onnxscript/ir/passes/common/common_subexpression_elimination.py
Outdated
Show resolved
Hide resolved
I think it is ok to leave subgraphs untouched. |
onnxscript/ir/passes/common/common_subexpression_elimination.py
Outdated
Show resolved
Hide resolved
onnxscript/ir/passes/common/common_subexpression_elimination.py
Outdated
Show resolved
Hide resolved
It would be better to move the PR to https://github.com/onnx/ir-py at this point, after all tests passing |
Optimizer seems still using the current repo passes. |
onnxscript/ir/passes/common/common_subexpression_elimination.py
Outdated
Show resolved
Hide resolved
onnxscript/ir/passes/common/common_subexpression_elimination_test.py
Outdated
Show resolved
Hide resolved
Hopefully fixed by #2324, but let me know if not |
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.
CodeQL found more than 20 potential problems in the proposed changes. Check the Files changed tab for more details.
Now I have to land the PR in onnx-ir first. |
for idx, graph_output in enumerate(graph.outputs): | ||
if graph_output in replacement_mapping: | ||
new_value = replacement_mapping[graph_output] | ||
if new_value.is_graph_output(): |
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.
We can't rename it if is a graph input also. We could change this condition to new_value.is_graph_output() or new_value.is_graph_input()
... I think it won't show up in CSE, but will be necessary if we move this as an IR utility used in other scenarios.
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.
Is there a kind of case that we would cse graph inputs? In this PR, it's deleting nodes and affecting their outputs.
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.
I see what you mean
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.
I will add that in onnx/ir-py#36
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.
@gramalingam I don't see how new_value here could be graph_input. It has to be from a node output. Does that sound right?
CSE pass from microsoft/onnxscript#2304 --------- Signed-off-by: Ti-Tai Wang <titaiwang@microsoft.com> Signed-off-by: Justin Chu <justinchuby@users.noreply.github.com> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: Justin Chu <justinchuby@users.noreply.github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Fix microsoft#2105 For the logic, this PR follows https://github.com/pytorch/pytorch/blob/main/torch/fx/passes/dialect/common/cse_pass.py. Essentially, this PR traverses the original graph and examines whether the values or the nodes are duplicated. If it's not, the value or the node is saved in mappings, and added to the new graph. If it is duplicated, the value or the node is replaced with the mapped/saved value or node. (FunctionalPass) CSE subgraph is not supported: microsoft#2345. --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Fix microsoft#2105 For the logic, this PR follows https://github.com/pytorch/pytorch/blob/main/torch/fx/passes/dialect/common/cse_pass.py. Essentially, this PR traverses the original graph and examines whether the values or the nodes are duplicated. If it's not, the value or the node is saved in mappings, and added to the new graph. If it is duplicated, the value or the node is replaced with the mapped/saved value or node. (FunctionalPass) CSE subgraph is not supported: microsoft#2345. --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Fix #2105
For the logic, this PR follows https://github.com/pytorch/pytorch/blob/main/torch/fx/passes/dialect/common/cse_pass.py.
Essentially, this PR traverses the original graph and examines whether the values or the nodes are duplicated. If it's not, the value or the node is saved in mappings, and added to the new graph. If it is duplicated, the value or the node is replaced with the mapped/saved value or node. (FunctionalPass)
CSE subgraph is not supported: #2345.