mirror of
https://gitlab.com/libeigen/eigen.git
synced 2026-04-10 11:34:33 +08:00
Add numext::fma and missing pmadd implementations.
This commit is contained in:
@@ -945,6 +945,38 @@ struct nearest_integer_impl<Scalar, true> {
|
||||
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar run_trunc(const Scalar& x) { return x; }
|
||||
};
|
||||
|
||||
// Default implementation.
|
||||
template <typename Scalar, typename Enable = void>
|
||||
struct fma_impl {
|
||||
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar run(const Scalar& a, const Scalar& b, const Scalar& c) {
|
||||
return a * b + c;
|
||||
}
|
||||
};
|
||||
|
||||
// ADL version if it exists.
|
||||
template <typename T>
|
||||
struct fma_impl<
|
||||
T,
|
||||
std::enable_if_t<std::is_same<T, decltype(fma(std::declval<T>(), std::declval<T>(), std::declval<T>()))>::value>> {
|
||||
static T run(const T& a, const T& b, const T& c) { return fma(a, b, c); }
|
||||
};
|
||||
|
||||
#if defined(EIGEN_GPUCC)
|
||||
template <>
|
||||
struct fma_impl<float, void> {
|
||||
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE float run(const float& a, const float& b, const float& c) {
|
||||
return ::fmaf(a, b, c);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct fma_impl<double, void> {
|
||||
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE double run(const double& a, const double& b, const double& c) {
|
||||
return ::fma(a, b, c);
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
} // end namespace internal
|
||||
|
||||
/****************************************************************************
|
||||
@@ -1852,6 +1884,15 @@ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar arithmetic_shift_right(const Scalar
|
||||
return bit_cast<Scalar, SignedScalar>(bit_cast<SignedScalar, Scalar>(a) >> n);
|
||||
}
|
||||
|
||||
// Use std::fma if available.
|
||||
using std::fma;
|
||||
|
||||
// Otherwise, rely on template implementation.
|
||||
template <typename Scalar>
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar fma(const Scalar& x, const Scalar& y, const Scalar& z) {
|
||||
return internal::fma_impl<Scalar>::run(x, y, z);
|
||||
}
|
||||
|
||||
} // end namespace numext
|
||||
|
||||
namespace internal {
|
||||
|
||||
Reference in New Issue
Block a user