Fix fp16/bf16 divmod and floor_divide precision (divide in float before rounding) - #4003
Closed
sashko-zakharchuk wants to merge 1 commit into
Closed
Fix fp16/bf16 divmod and floor_divide precision (divide in float before rounding)#4003sashko-zakharchuk wants to merge 1 commit into
sashko-zakharchuk wants to merge 1 commit into
Conversation
zcbenz
reviewed
Aug 6, 2026
zcbenz
left a comment
Member
There was a problem hiding this comment.
Since this is going to add overhead I think we should follow what PyTorch does, which has the same behavior:
a = torch.tensor([86.5625], dtype=torch.float16)
b = torch.tensor([28.859375], dtype=torch.float16)
print(torch.div(a, b), torch.remainder(a, b))tensor([3.], dtype=torch.float16) tensor([28.8438], dtype=torch.float16)Generally when in doubt we would prefer speed over precision as long as there is a way for users to use high precision computation.
4 tasks
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.
On fp16/bf16,
mx.divmodandmx.floor_dividedividedx / yin the input precisionand narrowed the quotient to fp16/bf16 before
trunc/floor. A true quotient justbelow an integer rounds up when narrowed, so the result is one too high.
The fix computes the division in float32 for the half types before rounding: on CPU in
DivMod'strunc/fmodop, on Metal and CUDA in theFloorDividefunctor thatdivmodreuses, and in thefloor_dividelowering inops.cpp. float32, float64,integer, and sign behavior are untouched (
divmodstill truncates). For non-negativefp16/bf16 operands
divmodandfloor_dividenow agree with each other, and with numpyfor same-dtype operands; for negatives
divmodstill truncates whilefloor_dividefloors.
This is also why
test_divmodis flaky: it compares fp16mx.divmodagainst numpy withunseeded random inputs, and near an integer boundary they disagreed (about 0.04% of
fp16 pairs, more for bf16). With the division in float they match. The test gets a
deterministic boundary case for fp16 and bf16, plus a seeded bf16 batch checked against
a float32 reference (numpy has no bf16).
Part of #3994 (the fp16/bf16 precision part); the floored-vs-truncated sign defects are
a separate change.
Verification
0/200000 random pairs;
1e300 / 1e299float64 stays10(no downcast);-7 / 3stays
(-2, -1)(sign unchanged); fulltest_ops.pypasses.2at the boundary,0/100000 divergence, sign unchanged.
2at the boundary,0/100000 divergence, sign unchanged;
test_divmodpasses.