Fix aten_pow_scalar type promotion when the exponent is not floating point - #3036
Open
om singhal (Om-singhaI) wants to merge 1 commit into
Open
Fix aten_pow_scalar type promotion when the exponent is not floating point#3036om singhal (Om-singhaI) wants to merge 1 commit into
om singhal (Om-singhaI) wants to merge 1 commit into
Conversation
…point aten_pow_scalar cast the scalar base down to the exponent's dtype, so a float base over an integer or boolean exponent built an integer Pow. torch promotes the other way: a float scalar outranks an integral tensor, so 2.0 ** torch.tensor([1, 2, 3]) is float32. The exporter stamps the float result type on the output value while the node itself produces int64, so the model fails to load in onnxruntime. Boolean exponents fail earlier still, since Pow has no boolean inputs. Promote to float32 when a float scalar meets an integral exponent, and to int64 when an int scalar meets a boolean one. Every case that already agreed with torch keeps the exponent's dtype and the same nodes as before.
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #3036 +/- ##
==========================================
- Coverage 72.70% 72.69% -0.01%
==========================================
Files 265 265
Lines 32298 32302 +4
Branches 3059 3061 +2
==========================================
Hits 23481 23481
- Misses 7779 7783 +4
Partials 1038 1038 ☔ View full report in Codecov by Harness. |
Contributor
Author
|
Is the
|
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.
aten_pow_scalarcasts the scalar base down to the exponent's dtype:When the base is a Python float and the exponent tensor is an integer, that casts the float down to int64 and builds an integer
Pow. torch promotes the other way. A float scalar outranks an integral tensor, so2.0 ** torch.tensor([1, 2, 3])is float32.Repro on main:
The graph contradicts itself. The output value carries
FLOATbecause that's the dtype torch reports for the result, while theCastwe emit isto=7and thePowreally returns int64. So it isn't just a wrong dtype, the model doesn't load at all.A boolean exponent fails even earlier, for a float base and an int base both, because
Powaccepts no boolean inputs:aten_pow_tensor_scalarright above already handles the mirror case correctly. It refuses to narrow and casts up toFLOATinstead. This applies the same rule in the other direction.I promote to float32 when a float scalar meets an integral exponent, and to int64 when an int scalar meets a boolean one. Everything that already agreed with torch falls through to the original line untouched, so an int scalar over an int tensor still keeps the exponent's dtype and emits the same nodes as before.
Five tests in
e2e_ops_tests.pynext to the existingtest_pow_tensor_scalar_*ones. Three of them fail on main (float base over int64, float base over bool, int base over bool). The other two pin the cases that must not move (float base over float16, int base over int64), and they pass either way.