Repository navigation
Keep the FACTO pow exponent representable in float32 (#24179) - #24179
Conversation
🔗 Helpful Links🧪 See artifacts and rendered test results at hud.pytorch.org/pr/pytorch/executorch/24179
Note: Links to docs will display an error until the docs builds have been completed. ✅ No FailuresAs of commit dfe9115 with merge base bf9bef3 ( This comment was automatically generated by Dr. CI and updates every 15 minutes. |
|
@aliafzal has exported this pull request. If you are a Meta employee, you can view the originating Diff in D127746756. |
This PR needs a
|
3c82dc8 to
c0dd09e
Compare
Summary: `pow.Tensor_Scalar`'s `exponent` fell into `facto_testcase_gen`'s generic scalar branch, `Gt(0)` and `Le(2)`. The open lower bound makes `nextup(0) = 5e-324` an edge value. That value flushes to 0 when a float32 kernel reads it, so `0 ** 5e-324` (0 in eager, computed with a double exponent) becomes `0 ** 0 = 1` on device. The exponent now gets its own lower bound of `torch.finfo(torch.float32).tiny`. Integer exponents are unchanged (≥ 1), and the upper bound stays 2. Found by the Jarvis nightly operator tests: `test_pow_Tensor_Scalar_out_20` (int32 input, exponent `5e-324`) fails on nxp, DLA, Artemis v3/v4 and CPU with `max_abs_diff = 1.0`. Reviewed By: DrJessop Differential Revision: D127746756
c0dd09e to
ab68f86
Compare
Summary: `pow.Tensor_Scalar`'s `exponent` fell into `facto_testcase_gen`'s generic scalar branch, `Gt(0)` and `Le(2)`. The open lower bound makes `nextup(0) = 5e-324` an edge value. That value flushes to 0 when a float32 kernel reads it, so `0 ** 5e-324` (0 in eager, computed with a double exponent) becomes `0 ** 0 = 1` on device. The exponent now gets its own lower bound of `torch.finfo(torch.float32).tiny`. Integer exponents are unchanged (≥ 1), and the upper bound stays 2. Found by the Jarvis nightly operator tests: `test_pow_Tensor_Scalar_out_20` (int32 input, exponent `5e-324`) fails on nxp, DLA, Artemis v3/v4 and CPU with `max_abs_diff = 1.0`. Reviewed By: DrJessop Differential Revision: D127746756
ab68f86 to
a8b84fc
Compare
…torch#24176) Summary: `add.Scalar(Tensor self, Scalar other, Scalar alpha=1)` takes `alpha` positionally, but `add.Tensor(Tensor self, Tensor other, *, Scalar alpha=1)` takes it as keyword-only, and the same holds for `sub`. When `alpha` was the third positional argument, `get_replacement` passed it through `*args[2:]`, and building the `.Tensor` node raised `RuntimeError: aten::add() takes 2 positional argument(s) but 3 was/were given`. The 3-argument path now binds the call by name with `torch.fx.operator_schemas.normalize_function` (the part of `get_arg` that doesn't need a `Node`; `call_operator` gets no node), passes `self` (`input` after normalization) and `other` positionally, and `alpha` as a kwarg. `get_replacement` always gets 2 args and no longer forwards extra ones. The Arm `ReplaceScalarWithTensorByProfilePass` subclass routes through the same base `call_operator`, so it gets the fix too for edge `add/sub.Scalar`. `torch.ops.aten.add/sub.Scalar` with a positional `alpha` still pass through unreplaced, as before. The changed path previously always raised, so no graph that worked before is affected. Authored with Claude Code. Reviewed By: DrJessop Differential Revision: D127746753
…#24177) Summary: `pow.Tensor_Scalar(int32, 2.0)` returns float32, but the `mul.Tensor(x, x)` chain that `ReplacePowWithMulPass` emits stays int32. The pass copied the float32 `meta` onto the int32 `mul` nodes, so the lowered program's output dtype no longer matched the eager reference. The pass now gives up when the input dtype differs from the `pow` output dtype. Authored with Claude Code. Reviewed By: DrJessop Differential Revision: D127746754
…ch#24178) Summary: `div.Tensor_mode(a, b, rounding_mode=None)` is true division. The HiFi `div_out_mode` sent `None` to the non-optimized path, where `mode_is_trunc` was false and the code fell through to `floor_divide` (its comment assumed the mode "must be floor"). So `7 / 2` returned 3 and `-7 / 2` returned -4. The kernel now delegates to `div_out` when `mode` has no value, which is what the portable and Fusion G3 `div_out_mode` already do. Authored with Claude Code. Reviewed By: DrJessop Differential Revision: D127746755
Summary: `pow.Tensor_Scalar`'s `exponent` fell into `facto_testcase_gen`'s generic scalar branch, `Gt(0)` and `Le(2)`. The open lower bound makes `nextup(0) = 5e-324` an edge value. That value flushes to 0 when a float32 kernel reads it, so `0 ** 5e-324` (0 in eager, computed with a double exponent) becomes `0 ** 0 = 1` on device. The exponent now gets its own lower bound of `torch.finfo(torch.float32).tiny`. Integer exponents are unchanged (≥ 1), and the upper bound stays 2. Authored with Claude Code. Reviewed By: DrJessop Differential Revision: D127746756
a8b84fc to
dfe9115
Compare
Summary:
pow.Tensor_Scalar'sexponentfell intofacto_testcase_gen's generic scalar branch,Gt(0)andLe(2). The open lower bound makesnextup(0) = 5e-324an edge value. That value flushes to 0 when a float32 kernel reads it, so0 ** 5e-324(0 in eager, computed with a double exponent) becomes0 ** 0 = 1on device. The exponent now gets its own lower bound oftorch.finfo(torch.float32).tiny. Integer exponents are unchanged (≥ 1), and the upper bound stays 2.Authored with Claude Code.
Reviewed By: DrJessop
Differential Revision: D127746756