Skip to content

Fix sign and float64 precision of portable remainder - #23683

Open
usmanmateen wants to merge 1 commit into
pytorch:mainfrom
usmanmateen:fix/remainder-sign-and-double
Open

usmanmateen wants to merge 1 commit into
pytorch:mainfrom
usmanmateen:fix/remainder-sign-and-double

Conversation

@usmanmateen

@usmanmateen usmanmateen commented Oct 11, 2026 •

Copy link
Copy Markdown

Summary

Fixes #23682.

ATen's remainder gives a result with the sign of the divisor. utils::remainder_override in kernels/portable/cpu/util/math_util.h follows that for floating-point types: it adds b when exactly one operand is negative and the fmod result is nonzero, as the comment above the overloads describes. The integer overload returned a % b, so -7 % 3 gave -1 instead of 2. This adds the same correction for signed integer types.

The floating-point overload also kept the fmod result in a float, so float64 results were rounded to float precision (123456789.123456789 % 1000 gave 789.1234741210938 instead of 789.1234567910433). It now uses CTYPE.

Both remainder.Tensor_out and remainder.Scalar_out in the portable kernels use this helper, and so does the Cadence HiFi remainder operator.

Test plan

Added two tests to kernels/test/op_remainder_test.cpp:

  • IntegerResultHasSignOfDivisor covers all four sign combinations plus exact multiples, for both the Tensor and Scalar variants.
  • DoubleKeepsDoublePrecision checks a float64 case with atol=1e-6. Rounding to float would be off by about 1.7e-5.

I built portable_kernels_test with CMake (EXECUTORCH_BUILD_TESTS=ON) on Linux x86_64 (WSL2). Before this change, both new tests fail; after it, all three OpRemainderOutTest tests pass, and the full portable_kernels_test run passes (1650 tests). clang-format 18.1.3 reports no changes on the two files.

This PR was authored with AI assistance (Claude Code).

cc @nil-is-all

ATen's remainder takes the sign of the divisor, but the integer overload
of remainder_override returned a % b, which takes the sign of the
dividend. The floating-point overload already corrected this, but stored
the fmod result in a float, so double results lost precision.

Fixes pytorch#23682
@pytorch-bot

pytorch-bot Bot commented Oct 11, 2026 •

Copy link
Copy Markdown

🔗 Helpful Links

🧪 See artifacts and rendered test results at hud.pytorch.org/pr/pytorch/executorch/23683

Note: Links to docs will display an error until the docs builds have been completed.

⚠️ 15 Awaiting Approval

As of commit 2b45ec5 with merge base f2575be (image):

AWAITING APPROVAL - The following workflows need approval before CI can run:

This comment was automatically generated by Dr. CI and updates every 15 minutes.

@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Oct 11, 2026
@usmanmateen

Copy link
Copy Markdown
Author

@pytorchbot label "release notes: ops & kernels"

@pytorch-bot pytorch-bot Bot added the release notes: ops & kernels Changes to the opset and any new / changed kernel implementations label Oct 11, 2026
@executorch-triage executorch-triage Bot added the community: contribution PRs coming from community (excluding hardware partners) label Oct 11, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. community: contribution PRs coming from community (excluding hardware partners) release notes: ops & kernels Changes to the opset and any new / changed kernel implementations

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Portable remainder kernel: wrong sign for integers and float64 rounded to float

1 participant