Repository navigation
Conversation
rmlarsen
force-pushed
the
fpmp-sqrt-compare
branch
from
November 13, 2026 19:20
9a4939f to
c9543f2
Compare
rmlarsen
force-pushed
the
fpmp-hyp-compare
branch
from
November 13, 2026 19:20
6960b2b to
a51a65a
Compare
…onto a pair kernel, and handle their special values sqrt and rsqrt take one Newton step and its second-order term from a single-limb seed (__fpmp_sqrt_seed: on the host the correctly rounded sqrtf and 0.5 / y, on the device the approximate reciprocal square root after one single-limb step). The public functions go through __fpmp2_sqrt_checked and __fpmp2_rsqrt_checked, which answer the IEEE special values on entry and scale operands below 2^-78 (fp32mp2) and 2^-916 (fp64mp2) by a power of four, where the kernel's residual would underflow; internal callers keep the bare kernels. hypot, rhypot, norm3d, norm4d, rnorm3d and rnorm4d share one pair kernel, __internal_fpmp2_norm: the squares and their rounding errors are summed as a pair, scaled by a power of two where they could overflow or underflow, and the root or reciprocal root is taken with the kernels above. fdim is a pair subtraction (__fpmp2_high_sub). Both replace fallbacks that computed in double: for fp64mp2 those carried 53 bits, and for fp32mp2 they put FP64 instructions on the device. Special values follow C99 Annex F for sqrt, rsqrt, fdim, fmax, fmin, copysign, signbit, hypot and the norms: fmax(+0, -0) is +0 and fmin(-0, +0) is -0, an infinite operand of hypot or a norm wins over NaN, and an infinite or NaN result has canonical limbs. copysign and signbit test the sign with the float signbit, without a conversion on the device. A probe of 30,249 special operands per type finds no failure on the host or the device; the parent commit had 9,235 and 5,465 (fp32mp2, host and device) and 16,347 and 8,023 (fp64mp2), most of them a NaN result with a zero low limb. asinh and acosh add the square root to x with __fpmp_two_sum instead of the fast variant: the high limb of the new root can round across that of x, and acosh(0x1.fffffep24 + 1) was off by 2^-29. Largest error against MPFR in u^2, host / device (sm_75), before -> after: sqrt 5.5 / 8.4 -> 0.5 / 0.5, and operands below 2^-78 no longer give garbage; rsqrt 7.3 / 10.6 -> 2.7 / 3.9. The fp64mp2 fdim, hypot and norms go from 53 bits to at most 4.5u^2. The fp32mp2 ones were correctly rounded through double (0.55u^2) and are now at 2.4u^2 (fdim), 3.2u^2 (hypot) and 3.5u^2 to 5.4u^2 (the others). Time against the parent commit, fp32mp2 on the host (x86-64 / Cortex-A76 / Apple M4): sqrt 1.12x / 1.09x / 0.90x, rsqrt 0.89x / 0.88x / 0.89x, fdim 4.7x / 2.8x / 1.9x, hypot 1.91x / 1.22x / 1.12x, norm4d 1.92x / 1.13x / 0.85x. The fp64mp2 norms take 2 to 8 times as long: they were a single double operation. fp32 SASS instructions: sqrt 18 -> 55, rsqrt 17 -> 45 (the kernel is inlined a second time for the scaled operands), hypot 23 fp32 and 22 fp64 -> 61 fp32. Host results are the same bits with GCC on x86-64 and Cortex-A76 and with Apple clang on the M4. New test fpmp/math_sqrt.pass.cpp; the special-value tables of these functions in fpmp_spec.rst are regenerated, and the error bounds and the list of dedicated functions in the documentation are updated. Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
rmlarsen
force-pushed
the
fpmp-hyp-compare
branch
from
November 13, 2026 23:41
a51a65a to
f425f30
Compare
rmlarsen
force-pushed
the
fpmp-sqrt-compare
branch
from
November 13, 2026 23:41
c9543f2 to
00e56da
Compare
…s can step in The two __fpmp_sqrt_seed overloads were _CCCL_TRIVIAL_HOST_DEVICE_API, which also marks a function artificial and nodebug. They are _CCCL_HOST_DEVICE_API _CCCL_FORCEINLINE now, like the other kernels added since NVIDIA#12543. Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
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.
Results, compared with
fpmp-hyp-comparefp32mp2andfp64mp2sqrtandrsqrttake one Newton step plus its second-order term;hypot,rhypot,norm3d,norm4d,rnorm3d,rnorm4dandfdimare computed in pair arithmetic instead of indouble; and these functions, withfmax,fmin,copysignandsignbit, get the C99 Annex F special values. Every comparison below is against the parent commit,fpmp-hyp-compare(6960b2b), not againstmain: the earlier branches of the stack also changefpmp_impl_divsqrt.h, and no run againstmainwas made.Special values. A probe of 30,249 special operands per type over 13 functions (
sqrt,rsqrt,fabs,copysign,fdim,fmax,fmin,hypot,rhypotand the four norms), against MPFR, on the host and on the device (sm_75):fp32mp2, hostfp32mp2, devicefp64mp2, hostfp64mp2, devicefp32mp2row (5,449 forfp64mp2) were a result of the right class with the wrong limbs, mostly a NaN result with a zero low limb, infdim,hypot,rhypotand the norms.fp32mp2host: 3,781, of which 3,774 in the norms; device: 13) or a finite value beyond the tolerance (fp32mp2: 4 and 2, all insqrt;fp64mp2: 1,141 on the host and 2,466 on the device, insqrt,fdim,hypot,rhypotand the norms).fmax(+0, -0)is +0 andfmin(-0, +0)is -0; an infinite operand ofhypotor a norm wins over a NaN; an infinite or NaN result has canonical limbs.Accuracy. Largest relative error against MPFR in u² (u = 2⁻²⁴ for
fp32mp2, 2⁻⁵³ forfp64mp2), host / device (sm_75), over 6 ranges of operands forsqrtandrsqrtand 8 for the others (on this branch 1,048,576 operands per range forfp32mp2and 262,144 forfp64mp2):fp32mp2parentfp32mp2this branchfp64mp2parentfp64mp2this branchsqrt, operands ≥ 2⁻⁷⁸ (2⁻⁹¹⁶)rsqrtfdimhypotrhypotnorm3drnorm3dnorm4drnorm4dsqrtis within 0.5u² of the exact root over the whole range on the host, subnormal operands included (mean 0.12u²; the parent's mean is 0.60u²). On the parent,fp32mp2operands in the lowest two ranges (subnormal, and normal ones below about 2⁻⁷⁸) gave results off by up to 3.5e7u² on the host, and on the device none of the 262,144 subnormal operands gave a finite result, forsqrtor forrsqrt(the parent's device figures in the table leave that range out); thefp64mp2sqrtwas off by up to 1.8e16u² there.fp64mp2fdim,hypotand norms carried 53 bits (errors of 1e16u² and more), and on the host the norms returned a non-finite result for 140,175 to 148,318 of the sampled operands; they are now within 4.5u².fp32mp2fdim,hypotand norms were computed indoubleand came out correctly rounded to within 0.56u². In pair arithmetic they err by up to 2.4u² (fdim), 3.2u² (hypot) and 3.5u² to 5.4u² (the others), with a mean of 0.14u² to 0.37u² in the worst range (0.10u² to 0.25u² before). In exchange the device code has no FP64 instruction.asinhandacoshadd the square root to x with an error-free sum that does not assume which operand is larger: the high limb of the new root can round across that of x, andacosh(0x1.fffffep24 + 1)was off by 2⁻²⁹ without it. Their largest errors on this branch are 6.3u² and 7.4u² (1,048,576 pairs in each of 10 and 8 ranges).Performance. ns per call on the host, parent → this branch (ratio above 1 is faster):
fp32mp2sqrtrsqrtfdimhypotrhypotnorm3drnorm3dnorm4drnorm4dfp64mp2sqrtrsqrtfdimhypotrhypotnorm3drnorm3dnorm4drnorm4d-O3 -march=x86-64-v3. Pi 5: Cortex-A76, GCC 14-O3 -mcpu=cortex-a76. M4: Apple M4, Apple clang 21.sqrtandrsqrtrows come from the run of the kernel layout that was committed, and its other rows from a run made before the last change to thesqrtandrsqrtwrappers; on x86-64 that change moved the same rows by at most 4% (hypotfrom 9.54 to 9.18 ns).fp32mp2rsqrttakes 12% to 14% longer on all three hosts (0.88× to 0.89×; thefp64mp2one 0.89× to 0.98×),sqrt10% longer on the M4, and thefp32mp2norms 9% to 18% longer on the M4 (norm3dandnorm4d0.85×).fp64mp2fdim,hypotand norms take 2 to 8 times as long (up to 0.12× on x86-64): on the parent they were a singledoubleoperation, which is also why they carried only 53 bits.SASS instructions per kernel on sm_89,
fp32+fp64(total):fp32mp2sqrtrsqrtfdimhypotrhypotnorm3drnorm3dnorm4drnorm4dcopysignsqrtandrsqrtgrow threefold: the second-order term is new, and the kernel is inlined a second time in the branch for scaled (tiny) operands. The norms,fdimandcopysignlose every FP64 instruction and are shorter in total. Thefp64mp2kernels grow throughout (sqrt33 → 70fp64instructions,hypot17 → 72,norm4d30 → 106). GPU timings on the B200/B300 are not in this branch.Platform independence. A hash of the host results over every range of the nine functions is identical for GCC on x86-64, GCC 14 on Cortex-A76 and Apple clang 21 on the M4, for both types.
Implementation
sqrt,rsqrt(fpmp_impl_divsqrt.h). From a single-limb seed y ≈ 1/√a (__fpmp_sqrt_seedinfpmp_impl.h: on the host the correctly roundedsqrtfand 0.5/y, on the device the approximate reciprocal square root after one single-limb step) the kernels take one Newton step and add its second-order term, with the residual formed exactly by fma.sqrtandrsqrtgo through__fpmp2_sqrt_checkedand__fpmp2_rsqrt_checked, which answer the IEEE special values on entry and scale operands below 2⁻⁷⁸ (fp32mp2) and 2⁻⁹¹⁶ (fp64mp2) by a power of four, where the kernel's residual would underflow. Internal callers keep the bare kernels.hypot,rhypot,norm3d,norm4d,rnorm3dandrnorm4dshare one pair kernel,__internal_fpmp2_norm: the squares and their rounding errors are summed as a pair, scaled by a power of two where they could overflow or underflow, and the root or reciprocal root is taken with the kernels above.fdimis a pair subtraction (__fpmp2_high_sub).fmax,fmin,copysign,signbit. The zeros are ordered by sign, and the sign is tested with the floatsignbit, without a conversion todoubleon the device.asinh,acoshadd the root to x with__fpmp_two_sum.Testing
fpmp/math_sqrt.pass.cpp, host and device, both types: the nine functions against MPFR references over the whole range of each (subnormal operands and results, and operands whose squares overflow or underflow, included), the results that must be exact, and the IEEE 754 special values, with those offabs,copysign,fmaxandfmin.cuda/fp/units/fpmp: 30 passed, 1 unsupported on sm_89 and on sm_75.math_sqrt,math_hyperbolicandmathpass built with Apple clang 21 on the M4.fpmp_spec.rstare regenerated, and the error bounds and the list of dedicated functions in the documentation are updated.Not run: MSVC, and the B200/B300 benchmarks.
Merge order
On top of
fpmp-hyp-compare(f425f30), which is on top offpmp-explog-compare(624b214) and NVIDIA#12568 (PR numbers are those of the upstream repository). This branch's changes are 00e56da and e71c6b0; the second declares the two__fpmp_sqrt_seedoverloads_CCCL_HOST_DEVICE_API _CCCL_FORCEINLINE, so that a debugger can step into them.Checklist
🤖 Generated with Claude Code