Accuracy: Round to nearest, ties to even for generic_float - #5193
Accuracy: Round to nearest, ties to even for generic_float#5193CharlieL7 wants to merge 6 commits into
generic_float#5193Conversation
There was a problem hiding this comment.
Pull request overview
Updates MIGraphX’s generic_float (notably migraphx::half and migraphx::bf16) float32 host conversion to use round-to-nearest, ties-to-even (RNE), aligning with typical hardware conversion behavior and improving numeric agreement with allclose()-style comparisons.
Changes:
- Implemented RNE rounding in
generic_floatfloat32→target conversion, including correct carry/overflow behavior (to infinity when appropriate). - Updated unit tests and ONNX verify gold data to reflect RNE results and overflow-to-inf behavior.
- Adjusted
rewrite_resize_testcomparisons to use an elementwise tolerance for narrow types to avoid 1-ULP mismatches.
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
src/include/migraphx/generic_float.hpp |
Implements RNE rounding logic for float32 conversions used by half/bf16. |
test/half.cpp |
Adds/updates tests to pin RNE rounding behavior and overflow/subnormal corner cases for half. |
test/bf16.cpp |
Adds/updates tests to pin RNE rounding behavior and overflow/subnormal corner cases for bf16. |
test/rewrite_resize_test.cpp |
Uses elementwise allclose tolerance for narrow output types where interpolation precision differs. |
test/onnx/verify/gelu_default_test.cpp |
Updates expected outputs to match ORT CPU EP rounding behavior. |
test/onnx/verify/gelu_default_bf16_test.cpp |
Refreshes bf16 expectations and comments for the verify test. |
test/onnx/verify/group_query_attention_test.cpp |
Updates expected values/comments to reflect more precise ORT-sourced gold data. |
CHANGELOG.md |
Documents the behavior change for float32→half/bf16 host conversion. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| * Allow for 1 arg slicing over a dynamic dimension. (#5015) | ||
| * Route convolutions and dot operations through rocMLIR when MIOpen or GEMM libraries are disabled at build time (#5059). | ||
| * Rejected symbolic input shapes in the multi-input `slice` calls, and pointed both symbolic `slice` errors at `dyn_slice` (#5088). | ||
| * Changed host conversion of float32 to `migraphx::half` and `migraphx::bf16` to round to nearest with ties to even instead of truncating, matching the hardware conversions these types emulate. Values above the target type's overflow threshold, including `std::numeric_limits<float>::max()`, now convert to infinity rather than to the largest finite value, so fp16 and bf16 model output can shift by up to one ULP (#5193). |
| constexpr const int diff = float32_parts::exponent_bias() - exponent_bias(); | ||
| constexpr const int drop = int(float32_parts::mantissa_width() - MantissaSize); | ||
|
|
||
| if(f.exponent != 0 and f.exponent != float32_parts::max_exponent() and |
There was a problem hiding this comment.
So fp32 and bf16 uses round_normal. Is this an optimization? So are we doing the same RNE algorithm and just taking advantage that it has the same exponent as float to do this automatically?
Regressions detected 🔴 * No develop baseline was found for this PR's branch point; compared against the latest available develop run instead. |
|
Motivation
generic_floatwhen trying to compare withallclose().Technical Details
generic_floatso that the reference values are correctly rounded when compared to the target results.Changelog Category
Add a
CHANGELOG.mdentry for any option other thanNot ApplicableFollow the LLVM AI Tool Use Policy for contributions using AI.