◆ fma()

Value boost::simd::fma ( Value const &  x,
Value const &  y,
Value const &  z 
)

This function object computes the (fused) multiply add of these three parameters.

Header <boost/simd/function/fma.hpp>
Notes
The call fma(x, y, z) is similar to x*y+z

But really conformant fused multiply/add also implies

  • only one rounding
  • no "intermediate" overflow

fma provides this for all integral types and also each time it is reasonable in terms of performance for floating ones (i.e. if the system has the hard wired capability).

If you need pedantic fma capabilities in all circumstances in your own code you can use the pedantic_ or std_ decorator (although both can be very expensive).

Decorators
  • std_ for floating entries to call directly std::fma. This generally implies pedantic fma behaviour, but in no way improved performances.
  • pedantic_ ensures the fma properties and allows SIMD acceleration if available.
See also
fms, fnma, fnms
Example:
#include <boost/simd/arithmetic.hpp>
#include <boost/simd/pack.hpp>
#include <boost/simd/function/enumerate.hpp>
#include <iostream>
namespace bs = boost::simd;
using pack_ft = bs::pack <float, 4>;
int main()
{
pack_ft pf = bs::enumerate<pack_ft>(-1, 2);
pack_ft qf = bs::enumerate<pack_ft>( 0, 3);
pack_ft rf = bs::enumerate<pack_ft>( 2, 5);
std::cout
<< "---- simd" << '\n'
<< " <- pf = " << pf << '\n'
<< " <- qf = " << qf << '\n'
<< " <- rf = " << rf << '\n'
<< " -> bs::fma(pf, qf, rf) = " << bs::fma(pf, qf, rf) << '\n';
float xf = 3.0f, yf = -3.0f, zf = 2.0f;
std::cout
<< "---- scalar" << '\n'
<< " <- xf = " << xf << '\n'
<< " <- yf = " << yf << '\n'
<< " <- yf = " << zf << '\n'
<< " -> bs::fma(xf, yf, rf) = " << bs::fma(xf, yf, zf) << '\n';
return 0;
}
Possible output:
---- simd
<- pf = (-1, 1, 3, 5)
<- qf = (0, 3, 6, 9)
<- rf = (2, 7, 12, 17)
-> bs::fma(pf, qf, rf) = (2, 10, 30, 62)
---- scalar
<- xf = 3
<- yf = -3
<- yf = 2
-> bs::fma(xf, yf, rf) = -7