Repository navigation
[torchlib] Implement fmax, fmin and hypot - #3169
Open
Shawn (ShawnNotFound) wants to merge 4 commits into
Open
Shawn (ShawnNotFound) wants to merge 4 commits into
Shawn (ShawnNotFound) wants to merge 4 commits into
Conversation
Max and Min return NaN when either input is NaN, so for floating point inputs the other value is selected where one input is NaN. Both ops are also registered for the prims overloads, which is what torch.export produces for torch.fmax and torch.fmin.
Squaring the inputs overflows or underflows well before the result does, e.g. hypot(300, 400) in float16, so the larger magnitude is factored out first. Zero and infinite inputs are handled separately so that the results match torch.hypot, including hypot(inf, nan) == inf.
Justin Chu (justinchuby)
approved these changes
Nov 6, 2026
Justin Chu (justinchuby)
left a comment
Collaborator
There was a problem hiding this comment.
Thanks!
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #3169 +/- ##
==========================================
+ Coverage 73.34% 73.39% +0.04%
==========================================
Files 269 269
Lines 33564 33597 +33
Branches 3210 3215 +5
==========================================
+ Hits 24618 24657 +39
+ Misses 7876 7870 -6
Partials 1070 1070 ☔ View full report in Codecov by Harness. |
Contributor
There was a problem hiding this comment.
🟡 Changes recommended
The float16 hypot calculation can overflow to infinity when the expected result is finite, requiring float32 intermediates and a boundary-case regression test.
1 open issue
What changed in this PR
Adds TorchLib export support for torch.fmax, torch.fmin, and torch.hypot, registered for both ATen and prims overloads.
Changes:
- Implements NaN-aware
fmaxandfmin, including boolean handling. - Implements scaled
hypotcomputation with zero and infinity handling. - Adds OpInfo coverage and end-to-end tests for special values, integer inputs, and numerical range.
| File | Description |
|---|---|
tests/function_libs/torch_lib/ops_test_data.py |
Registers OpInfo tests for all three operators. |
tests/function_libs/torch_lib/e2e_ops_tests.py |
Adds export tests for edge cases and numerical range. |
onnxscript/function_libs/torch_lib/ops/core.py |
Implements and registers the three operators. |
Review effort: Balanced
Doing the scaling in float32 keeps the intermediate steps in full precision for results near the top of the half precision range. It also makes bfloat16 work on onnxruntime, which has no bfloat16 kernel for Abs.
Justin Chu (justinchuby)
enabled auto-merge (squash)
November 6, 2026 22:36
This branch has not been deployed
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.

torch.fmax,torch.fminandtorch.hypotcurrently fail to export:This implements them and registers them for both the
atenandprimsoverloads, likeaten_remainderdoes.MaxandMinreturn NaN when either input is NaN, but fmax and fmin return the other value and only give NaN when both inputs are NaN. For floating point inputs the NaN positions are filled from the other input. Bool inputs useOr/Andas inaten_maximum/aten_minimum.sqrt(x*x + y*y)directly overflows or underflows well before the result does, e.g.hypot(300, 400)in float16. It's computed asbig * sqrt(1 + (small / big)**2)instead, with zeros and infinities handled separately so that it matchestorch.hypot, includinghypot(inf, nan) == inf. I usedAbs(x) == infrather thanIsInf, sinceIsInfonly accepts float16 from opset 20.Tests: OpInfo entries for the three ops, and e2e tests for NaN inputs, integer inputs and hypot inputs whose squares overflow or underflow. Against PyTorch on random inputs over a wide range, hypot is within 2 ulp for float32 and float64 and 1 ulp for float16.