Repository navigation
fix(shader): round the f16 fused multiply-adds once - #2000
Conversation
MarcZX10
left a comment
There was a problem hiding this comment.
The finite-value path has a sound basis: the f16 product is exact in f32, and the SPIR-V f32 add/sub/mul emitters apply NoContraction, which the TwoSum error recovery needs. The new execution test also exercises the conversion boundary and all six instruction families.
One scope note: the PR says NaNs were not measured or included in the hardware matrix, while the new non-mix path replaces one FMA with multiply/add operations. The existing TechnicalDebt entry still says arithmetic NaN bits are driver-dependent; please confirm that remains the intended documented limit for this path, especially invalid inf * 0 inputs to the non-packed instructions. I am not approving without upstream validation: Build and Conventions are still action_required on this head.
|
Yes, that stays the documented limit: the scalar f16 FMA NaN payload is the driver's, as TechnicalDebt says for
Checked with a throwaway probe (12 lanes of NaN, sNaN,
|
v_fma_f16, v_fmac_f16, v_fmamk_f16, v_fmaak_f16, v_pk_fma_f16 and v_pk_fmac_f16 rounded an f32 fused multiply-add to f16, rounding twice. The product of two f16 values is exact in f32, so the sum is now rounded to odd in f32 with an exact error term and then rounded to nearest even in f16, which rounds the exact result once.
888724c to
6de064f
Compare
|
Other open pull requests touch the same code. Merging one will break the other, or both implement the same thing. If this one builds on them, list them in Depends on.
|
|
Native Windows run, since no Windows results were posted. Setup: Windows 10 (19045), RTX 3060 Laptop (NVIDIA 616.92), MinGW-w64 GCC 15.2.0 (WinLibs r7), Release. Head
No title was run. 🤖 Addressed by Claude Code |
|
Checked on the HW oracle (RDNA2 gfx1035) with the test's seven instruction forms: with f16 denormals kept, at IEEE=0 and IEEE=1, the hardware matches the |
…ingle-rounding fix(shader): round the f16 fused multiply-adds once
What
v_fma_f16,v_fmac_f16,v_fmamk_f16,v_fmaak_f16,v_pk_fma_f16andv_pk_fmac_f16were translated as an f32 FMA rounded to f16, which rounds twice:0x62e9 * 0xd159 + 0x23ecgave0xf89e, the hardware0xf89f(TechnicalDebt).The product of two f16 values is exact in f32. The translation now adds it to the addend in f32, recovers the exact rounding error with TwoSum, rounds the sum to odd and converts it with the existing round-to-nearest-even f16 conversion. Rounding to odd with at least p + 2 bits and then to nearest with p bits is one rounding (Boldo and Melquiond, "Emulation of FMA and Correctly Rounded Sums: Proved Algorithms Using Rounding to Odd", IEEE Transactions on Computers 57(4), 2008); f32 has 24 bits, f16 11. The f32 add and sub are already emitted with
NoContraction, so drivers keep them exact. No f64 is needed.v_fma_mix*(f32 sources) is unchanged.Source of the semantics: measured on RDNA2, gfx1036 (Ryzen iGPU, RADV, Mesa 22.3.6), through a Vulkan compute shader whose f16
fma()ACO compiled tov_fmac_f16_e32,v_pk_fmac_f16,v_fma_f16andv_pk_fma_f16(checked in theRADV_DEBUG=shadersdisassembly). For each of the four, 2,200,256 inputs (the test rows, 1M uniform random, 1M near-cancellation, 200k with subnormal results) all match exact single rounding to nearest even, with f16 denormals kept and overflow to infinity. Not run with the hardware oracle: the float mode was the driver's default, and no NaN inputs were used. The PS5's gfx1013 is not measured.Removes the TechnicalDebt entry.
Tested
Linux (Debian 12, GCC 12.2), Release.
agc_driver_float16_fma_rounding: 64 lanes, 7 instruction forms. 116 of its 128v_fma_f16/v_pk_fma_f16triples and 37 of itsv_fmaak_f16/v_fmamk_f16rows round differently when rounded twice; they include results at the f16 overflow boundary (252 * 260 - 2^-24:0x7bff, twice rounded0x7c00), subnormal results, signed zeros and infinities. Fails on main (lane 0v_fma_f16is0xf89e, expected0xf89f); passes on RADV gfx1036, Intel Arc A310 (ANV) and lavapipe, under 0.1 s.agc_driver_float16_ternary_clamp,agc_driver_packed_alu,agc_driver_fma_rounding,agc_driver_float16_modifierspass on all three devices.agc|shader|recompiler|spirv|fused|vopon lavapipe (Mesa 22.3.6): 6 failures that fail identically on main (missing device features), andagc_driver_flat_storetimed out under-j12. On RADV gfx1036: 8 failures that also fail on main, andagc_driver_scalar_wide_loadsfailed once under-j8and passes 5 of 5 alone.Checklist
main; no other open PR implements the same functionsNotImplemented_nid_no_patch); silent stubs are listed in TechnicalDebt.mdfiles or images added to the repository (attach them to this PR)