Description
Summary
I would like to add the fused-multiply-add instruction either directly to system or to std/math.
This instruction is crucial for high-performance computing. It computes a product and an addition in one cycle: fma(a, x, y) = a*x + y. Not only is this instruction faster but it also comes with less rounding errors. It is guaranteed to compute the product as if it had infinite precision.
The problem with this instruction, is that some operations should not use a fused-multiple add. Indeed, when one wants to compute the product of two complex numbers a = x + iy and b = x' + iy', the imaginary part is given by: yx' + xy'. This sum of two products can be computed by using fma in two ways, but none of them would be accurate enough, to distinguish whether the complex number product is real or complex. (See e.g. Nicolas J. Higham, Accuracy and Stability of Numerical Algorithms, 2002).
Consequently, it is up to the programmer and not the compiler to decide, given the context, whether or not a fused multiply-add should be used.
This difference of rounding with the two separate instructions enable the use of error-free transformations like the two-product error free transformation of Ogita et al (2005)
Description
Currently, I import in my projects:
proc fma(x,y,z: float32): float32 {.importc: "fmaf", header: "<math.h>".}
proc fma(x,y,z: float64): float64 {.importc: "fma", header: "<math.h>".}
A solution would be to add these imports in std/math. We would know be able to use error-free transformations without these imports:
import std/math
# Two-productFMA Ogita et al. 2005
# Expresses x*y accurately as h + l
h = x*y # Floating-point approximation of x*y
l = fma(x, y, -h) # Floating-point rounding in l
Alternatives
No response
Examples
No response
Backwards Compatibility
There might be some issues with the JS backend, as always when it comes with floating-point arithmetic support.
I propose to align with the C++ specification.
Links
https://en.wikipedia.org/wiki/Multiply%E2%80%93accumulate_operation
https://en.cppreference.com/w/cpp/numeric/math/fma
https://epubs.siam.org/doi/epdf/10.1137/030601818