diff options
author | Gael Guennebaud <g.gael@free.fr> | 2018-11-26 14:21:24 +0100 |
---|---|---|
committer | Gael Guennebaud <g.gael@free.fr> | 2018-11-26 14:21:24 +0100 |
commit | 2c44c401146194b9a010a1e3a4bdb5118f9f46e7 (patch) | |
tree | 8f19e02eb4aa5c21c8053cf1de4006a2e18d3d6f /Eigen/src/Core/GenericPacketMath.h | |
parent | 5f6045077cd23e339b66b0b0a7c47c5eede752e3 (diff) |
First step toward a unification of packet log implementation, currently only SSE and AVX are unified.
To this end, I added the following functions: pzero, pcmp_*, pfrexp, pset1frombits functions.
Diffstat (limited to 'Eigen/src/Core/GenericPacketMath.h')
-rw-r--r-- | Eigen/src/Core/GenericPacketMath.h | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/Eigen/src/Core/GenericPacketMath.h b/Eigen/src/Core/GenericPacketMath.h index da1350f1b..316b03f96 100644 --- a/Eigen/src/Core/GenericPacketMath.h +++ b/Eigen/src/Core/GenericPacketMath.h @@ -214,6 +214,38 @@ pxor(const Packet& a, const Packet& b) { return a ^ b; } template<typename Packet> EIGEN_DEVICE_FUNC inline Packet pandnot(const Packet& a, const Packet& b) { return a & (!b); } +/** \internal \returns the significant and exponent of the underlying floating point numbers + * See https://en.cppreference.com/w/cpp/numeric/math/frexp + */ +template<typename Packet> EIGEN_DEVICE_FUNC inline Packet +pfrexp(const Packet &a, Packet &exponent) { return std::frexp(a,&exponent); } + +/** \internal \returns zeros */ +template<typename Packet> EIGEN_DEVICE_FUNC inline Packet +pzero(const Packet& a) { return pxor(a,a); } + +/** \internal \returns bits of \a or \b according to the input bit mask \a mask */ +template<typename Packet> EIGEN_DEVICE_FUNC inline Packet +pselect(const Packet& mask, const Packet& a, const Packet& b) { + return por(pand(a,mask),pandnot(b,mask)); +} + +/** \internal \returns a <= b as a bit mask */ +template<typename Packet> EIGEN_DEVICE_FUNC inline Packet +pcmp_le(const Packet& a, const Packet& b); /* { return a<=b ? pnot(pxor(a,a)) : pxor(a,a); } */ + +/** \internal \returns a < b as a bit mask */ +template<typename Packet> EIGEN_DEVICE_FUNC inline Packet +pcmp_lt(const Packet& a, const Packet& b); /* { return a<b ? pnot(pxor(a,a)) : pxor(a,a); } */ + +/** \internal \returns a == b as a bit mask */ +template<typename Packet> EIGEN_DEVICE_FUNC inline Packet +pcmp_eq(const Packet& a, const Packet& b); /* { return a==b ? pnot(pxor(a,a)) : pxor(a,a); } */ + +/** \internal \returns a < b or a==NaN or b==NaN as a bit mask */ +template<typename Packet> EIGEN_DEVICE_FUNC inline Packet +pcmp_lt_or_nan(const Packet& a, const Packet& b); /* { return pnot(pcmp_le(b,a)); } */ + /** \internal \returns a packet version of \a *from, from must be 16 bytes aligned */ template<typename Packet> EIGEN_DEVICE_FUNC inline Packet pload(const typename unpacket_traits<Packet>::type* from) { return *from; } @@ -226,6 +258,10 @@ ploadu(const typename unpacket_traits<Packet>::type* from) { return *from; } template<typename Packet> EIGEN_DEVICE_FUNC inline Packet pset1(const typename unpacket_traits<Packet>::type& a) { return a; } +/** \internal \returns a packet with constant coefficients set from bits */ +template<typename Packet,typename BitsType> EIGEN_DEVICE_FUNC inline Packet +pset1frombits(BitsType a); + /** \internal \returns a packet with constant coefficients \a a[0], e.g.: (a[0],a[0],a[0],a[0]) */ template<typename Packet> EIGEN_DEVICE_FUNC inline Packet pload1(const typename unpacket_traits<Packet>::type *a) { return pset1<Packet>(*a); } @@ -597,6 +633,29 @@ pinsertlast(const Packet& a, typename unpacket_traits<Packet>::type b) return pblend(mask, pset1<Packet>(b), a); } +/*************************************************************************** + * Some generic implementations to be used by implementors +***************************************************************************/ + +/** \internal shift the bits by n and cast the result to the initial type, i.e.: + * return float(reinterpret_cast<uint>(a) >> n) + */ +template<typename Packet> EIGEN_DEVICE_FUNC inline Packet +pshiftright_and_cast(Packet a, int n); + +/** Default implementation of pfrexp for float. + * It is expected to be called by implementers of template<> pfrexp, + * and the above pshiftright_and_cast function must be implemented. + */ +template<typename Packet> EIGEN_STRONG_INLINE Packet +pfrexp_float(const Packet& a, Packet& exponent) { + const Packet cst_126f = pset1<Packet>(126.0f); + const Packet cst_half = pset1<Packet>(0.5f); + const Packet cst_inv_mant_mask = pset1frombits<Packet>(~0x7f800000u); + exponent = psub(pshiftright_and_cast(a,23), cst_126f); + return por(pand(a, cst_inv_mant_mask), cst_half); +} + } // end namespace internal } // end namespace Eigen |