Skip to content

Fused multiple-add instruction #23342

Open
@dlesnoff

Description

@dlesnoff

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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions