diff options
-rw-r--r-- | Eigen/src/Core/GenericPacketMath.h | 5 | ||||
-rw-r--r-- | Eigen/src/Core/arch/NEON/PacketMath.h | 10 | ||||
-rw-r--r-- | test/packetmath.cpp | 143 | ||||
-rw-r--r-- | unsupported/test/cxx11_tensor_morphing.cpp | 1 |
4 files changed, 95 insertions, 64 deletions
diff --git a/Eigen/src/Core/GenericPacketMath.h b/Eigen/src/Core/GenericPacketMath.h index 7f35b3114..cb8848731 100644 --- a/Eigen/src/Core/GenericPacketMath.h +++ b/Eigen/src/Core/GenericPacketMath.h @@ -96,7 +96,6 @@ struct default_packet_traits HasRint = 0, HasFloor = 0, HasCeil = 0, - HasCast = 0, HasSign = 0 }; }; @@ -325,7 +324,7 @@ pcmp_eq(const Packet& a, const Packet& b) { return a==b ? ptrue(a) : pzero(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 a>=b ? pzero(a) : ptrue(a); } +pcmp_lt_or_nan(const Packet& a, const Packet& b) { return a>=b ? pzero(a) : ptrue(a); } /** \internal \returns \a or \b for each field in packet according to \mask */ template<typename Packet> EIGEN_DEVICE_FUNC inline Packet @@ -392,7 +391,7 @@ ploaddup(const typename unpacket_traits<Packet>::type* from) { return *from; } * For instance, for a packet of 8 elements, 2 scalars will be read from \a *from and * replicated to form: {from[0],from[0],from[0],from[0],from[1],from[1],from[1],from[1]} * Currently, this function is only used in matrix products. - * For packet-size smaller or equal to 4, this function is equivalent to pload1 + * For packet-size smaller or equal to 4, this function is equivalent to pload1 */ template<typename Packet> EIGEN_DEVICE_FUNC inline Packet ploadquad(const typename unpacket_traits<Packet>::type* from) diff --git a/Eigen/src/Core/arch/NEON/PacketMath.h b/Eigen/src/Core/arch/NEON/PacketMath.h index 065c8100f..ddd43c377 100644 --- a/Eigen/src/Core/arch/NEON/PacketMath.h +++ b/Eigen/src/Core/arch/NEON/PacketMath.h @@ -121,7 +121,6 @@ struct packet_traits<float> : default_packet_traits size = 4, HasHalfPacket = 1, - HasCast = 1, HasAdd = 1, HasSub = 1, HasShift = 1, @@ -162,7 +161,6 @@ struct packet_traits<int8_t> : default_packet_traits size = 16, HasHalfPacket = 1, - HasCast = 1, HasAdd = 1, HasSub = 1, HasShift = 1, @@ -192,7 +190,6 @@ struct packet_traits<uint8_t> : default_packet_traits size = 16, HasHalfPacket = 1, - HasCast = 1, HasAdd = 1, HasSub = 1, HasShift = 1, @@ -224,7 +221,6 @@ struct packet_traits<int16_t> : default_packet_traits size = 8, HasHalfPacket = 1, - HasCast = 1, HasAdd = 1, HasSub = 1, HasShift = 1, @@ -254,7 +250,6 @@ struct packet_traits<uint16_t> : default_packet_traits size = 8, HasHalfPacket = 1, - HasCast = 1, HasAdd = 1, HasSub = 1, HasShift = 1, @@ -285,7 +280,6 @@ struct packet_traits<int32_t> : default_packet_traits size = 4, HasHalfPacket = 1, - HasCast = 1, HasAdd = 1, HasSub = 1, HasShift = 1, @@ -315,7 +309,6 @@ struct packet_traits<uint32_t> : default_packet_traits size = 4, HasHalfPacket = 1, - HasCast = 1, HasAdd = 1, HasSub = 1, HasShift = 1, @@ -347,7 +340,6 @@ struct packet_traits<int64_t> : default_packet_traits size = 2, HasHalfPacket = 1, - HasCast = 1, HasCmp = 1, HasAdd = 1, HasSub = 1, @@ -378,7 +370,6 @@ struct packet_traits<uint64_t> : default_packet_traits size = 2, HasHalfPacket = 1, - HasCast = 1, HasCmp = 1, HasAdd = 1, HasSub = 1, @@ -3185,7 +3176,6 @@ template<> struct packet_traits<double> : default_packet_traits size = 2, HasHalfPacket = 0, - HasCast = 1, HasCmp = 1, HasAdd = 1, HasSub = 1, diff --git a/test/packetmath.cpp b/test/packetmath.cpp index 540cf6a86..64ba28741 100644 --- a/test/packetmath.cpp +++ b/test/packetmath.cpp @@ -29,58 +29,113 @@ inline bool REF_SUB(const bool& a, const bool& b) { return a ^ b;} template <> inline bool REF_MUL(const bool& a, const bool& b) { return a && b;} -template<typename FromScalar, typename FromPacket, typename ToScalar, typename ToPacket, bool CanCast = false> +// Uses pcast to cast from one array to another. +template<typename SrcPacket, typename TgtPacket, int SrcCoeffRatio, int TgtCoeffRatio> +struct pcast_array { + static void cast(const typename internal::unpacket_traits<SrcPacket>::type* src, size_t size, typename internal::unpacket_traits<TgtPacket>::type* dst) { + static const int TgtPacketSize = internal::unpacket_traits<TgtPacket>::size; + for (size_t i=0; i<size; i+=TgtPacketSize) { + internal::pstoreu(dst+i, internal::pcast<SrcPacket,TgtPacket>(internal::ploadu<SrcPacket>(src+i))); + } + } +}; + +template<typename SrcPacket,typename TgtPacket> +struct pcast_array<SrcPacket, TgtPacket, 2, 1>{ + static void cast(const typename internal::unpacket_traits<SrcPacket>::type* src, size_t size, typename internal::unpacket_traits<TgtPacket>::type* dst) { + static const int SrcPacketSize = internal::unpacket_traits<SrcPacket>::size; + static const int TgtPacketSize = internal::unpacket_traits<TgtPacket>::size; + for (size_t i=0; i<size; i+=TgtPacketSize) { + SrcPacket a = internal::ploadu<SrcPacket>(src+i); + SrcPacket b = internal::ploadu<SrcPacket>(src+i+SrcPacketSize); + internal::pstoreu(dst+i, internal::pcast<SrcPacket,TgtPacket>(a, b)); + } + } +}; + +template<typename SrcPacket, typename TgtPacket> +struct pcast_array<SrcPacket, TgtPacket, 4, 1>{ + static void cast(const typename internal::unpacket_traits<SrcPacket>::type* src, size_t size, typename internal::unpacket_traits<TgtPacket>::type* dst) { + static const int SrcPacketSize = internal::unpacket_traits<SrcPacket>::size; + static const int TgtPacketSize = internal::unpacket_traits<TgtPacket>::size; + for (size_t i=0; i<size; i+=TgtPacketSize) { + SrcPacket a = internal::ploadu<SrcPacket>(src+i); + SrcPacket b = internal::ploadu<SrcPacket>(src+i+SrcPacketSize); + SrcPacket c = internal::ploadu<SrcPacket>(src+i+2*SrcPacketSize); + SrcPacket d = internal::ploadu<SrcPacket>(src+i+3*SrcPacketSize); + internal::pstoreu(dst+i, internal::pcast<SrcPacket,TgtPacket>(a, b)); + } + } +}; + +template<typename SrcPacket, typename TgtPacket, int SrcCoeffRatio, int TgtCoeffRatio, bool CanCast = false> struct test_cast_helper; -template<typename FromScalar, typename FromPacket, typename ToScalar, typename ToPacket> -struct test_cast_helper<FromScalar, FromPacket, ToScalar, ToPacket, false> { +template<typename SrcPacket, typename TgtPacket, int SrcCoeffRatio, int TgtCoeffRatio> +struct test_cast_helper<SrcPacket, TgtPacket, SrcCoeffRatio, TgtCoeffRatio, false> { static void run() {} }; -template<typename FromScalar, typename FromPacket, typename ToScalar, typename ToPacket> -struct test_cast_helper<FromScalar, FromPacket, ToScalar, ToPacket, true> { +template<typename SrcPacket, typename TgtPacket, int SrcCoeffRatio, int TgtCoeffRatio> +struct test_cast_helper<SrcPacket, TgtPacket, SrcCoeffRatio, TgtCoeffRatio, true> { static void run() { - static const int PacketSize = internal::unpacket_traits<FromPacket>::size; - EIGEN_ALIGN_MAX FromScalar data1[PacketSize]; - EIGEN_ALIGN_MAX ToScalar data2[PacketSize]; - EIGEN_ALIGN_MAX ToScalar ref[PacketSize]; + typedef typename internal::unpacket_traits<SrcPacket>::type SrcScalar; + typedef typename internal::unpacket_traits<TgtPacket>::type TgtScalar; + static const int SrcPacketSize = internal::unpacket_traits<SrcPacket>::size; + static const int TgtPacketSize = internal::unpacket_traits<TgtPacket>::size; + static const int DataSize = SrcPacketSize*SrcCoeffRatio; + VERIFY(DataSize == TgtPacketSize*TgtCoeffRatio && "Packet sizes and cast ratios are mismatched."); + + EIGEN_ALIGN_MAX SrcScalar data1[DataSize]; + EIGEN_ALIGN_MAX TgtScalar data2[DataSize]; + EIGEN_ALIGN_MAX TgtScalar ref[DataSize]; // Construct a packet of scalars that will not overflow when casting - for (int i=0; i<PacketSize; ++i) { - const FromScalar from_scalar = Array<FromScalar,1,1>::Random().value(); - const ToScalar to_scalar = Array<ToScalar,1,1>::Random().value(); - const FromScalar c = sizeof(ToScalar) > sizeof(FromScalar) ? static_cast<FromScalar>(to_scalar) : from_scalar; - data1[i] = (NumTraits<FromScalar>::IsSigned && !NumTraits<ToScalar>::IsSigned) ? numext::abs(c) : c; + for (int i=0; i<DataSize; ++i) { + const SrcScalar a = Array<SrcScalar,1,1>::Random().value(); + const TgtScalar b = Array<TgtScalar,1,1>::Random().value(); + const SrcScalar c = sizeof(TgtScalar) > sizeof(SrcScalar) ? static_cast<SrcScalar>(b) : a; + data1[i] = (NumTraits<SrcScalar>::IsSigned && !NumTraits<TgtScalar>::IsSigned) ? numext::abs(c) : c; } - for (int i=0; i<PacketSize; ++i) - ref[i] = static_cast<const ToScalar>(data1[i]); - internal::pstore(data2, internal::pcast<FromPacket, ToPacket>(internal::pload<FromPacket>(data1))); + for (int i=0; i<DataSize; ++i) + ref[i] = static_cast<const TgtScalar>(data1[i]); - VERIFY(test::areApprox(ref, data2, PacketSize) && "internal::pcast<>"); + pcast_array<SrcPacket, TgtPacket, SrcCoeffRatio, TgtCoeffRatio>::cast(data1, DataSize, data2); + + VERIFY(test::areApprox(ref, data2, DataSize) && "internal::pcast<>"); } }; -template<typename FromPacket, typename ToScalar> +template<typename SrcScalar, typename TgtScalar> void test_cast() { - typedef typename internal::unpacket_traits<FromPacket>::type FromScalar; - typedef typename internal::packet_traits<FromScalar> FromPacketTraits; - typedef typename internal::packet_traits<ToScalar>::type Full; - typedef typename internal::unpacket_traits<Full>::half Half; - typedef typename internal::unpacket_traits<typename internal::unpacket_traits<Full>::half>::half Quarter; - - static const int PacketSize = internal::unpacket_traits<FromPacket>::size; - static const bool CanCast = - FromPacketTraits::HasCast && - (PacketSize == internal::unpacket_traits<Full>::size || - PacketSize == internal::unpacket_traits<Half>::size || - PacketSize == internal::unpacket_traits<Quarter>::size); - - typedef typename internal::conditional<internal::unpacket_traits<Quarter>::size == PacketSize, Quarter, - typename internal::conditional<internal::unpacket_traits<Half>::size == PacketSize, Half, Full>::type>::type - ToPacket; - - test_cast_helper<FromScalar, FromPacket, ToScalar, ToPacket, CanCast>::run(); + typedef typename internal::packet_traits<SrcScalar> SrcPacketTraits; + typedef typename internal::packet_traits<TgtScalar> TgtPacketTraits; + typedef typename internal::type_casting_traits<SrcScalar, TgtScalar> TypeCastingTraits; + static const int SrcCoeffRatio = TypeCastingTraits::SrcCoeffRatio; + static const int TgtCoeffRatio = TypeCastingTraits::TgtCoeffRatio; + + static const bool HasFullCast = TypeCastingTraits::VectorizedCast; + static const bool HasHalfCast = HasFullCast && internal::packet_traits<SrcScalar>::HasHalfPacket && internal::packet_traits<TgtScalar>::HasHalfPacket; + + test_cast_helper<typename SrcPacketTraits::type, typename TgtPacketTraits::type, SrcCoeffRatio, TgtCoeffRatio, HasFullCast>::run(); + test_cast_helper<typename SrcPacketTraits::half, typename TgtPacketTraits::half, SrcCoeffRatio, TgtCoeffRatio, HasHalfCast>::run(); +} + +template<typename Scalar, typename Packet> void packetmath_pcast_ops() { + const static bool IsFullPacket = internal::is_same<typename internal::packet_traits<Scalar>::type,Packet>::value; + if (IsFullPacket) { + test_cast<Scalar, float>(); + test_cast<Scalar, double>(); + test_cast<Scalar, int8_t>(); + test_cast<Scalar, uint8_t>(); + test_cast<Scalar, int16_t>(); + test_cast<Scalar, uint16_t>(); + test_cast<Scalar, int32_t>(); + test_cast<Scalar, uint32_t>(); + test_cast<Scalar, int64_t>(); + test_cast<Scalar, uint64_t>(); + } } template<typename Scalar,typename Packet> @@ -341,6 +396,7 @@ template<typename Scalar,typename Packet> void packetmath() CHECK_CWISE2_IF(true, internal::pand, internal::pand); packetmath_boolean_mask_ops<Scalar, Packet>(); + packetmath_pcast_ops<Scalar, Packet>(); } @@ -584,19 +640,6 @@ template<typename Scalar,typename Packet> void packetmath_notcomplex() Array<Scalar,Dynamic,1>::Map(data1, PacketSize*4).setRandom(); - if (PacketTraits::HasCast) { - test_cast<Packet, float>(); - test_cast<Packet, double>(); - test_cast<Packet, int8_t>(); - test_cast<Packet, uint8_t>(); - test_cast<Packet, int16_t>(); - test_cast<Packet, uint16_t>(); - test_cast<Packet, int32_t>(); - test_cast<Packet, uint32_t>(); - test_cast<Packet, int64_t>(); - test_cast<Packet, uint64_t>(); - } - ref[0] = data1[0]; for (int i=0; i<PacketSize; ++i) ref[0] = (std::min)(ref[0],data1[i]); diff --git a/unsupported/test/cxx11_tensor_morphing.cpp b/unsupported/test/cxx11_tensor_morphing.cpp index 59f4c34b3..e8c42a4cd 100644 --- a/unsupported/test/cxx11_tensor_morphing.cpp +++ b/unsupported/test/cxx11_tensor_morphing.cpp @@ -53,7 +53,6 @@ static void test_static_reshape() { Eigen::IndexList<type2index<2>, type2index<3>, type2index<7>> dim; Tensor<float, 3> reshaped = tensor.reshape(static_cast<Eigen::DSizes<ptrdiff_t,3>>(dim)); - for (int i = 0; i < 2; ++i) { for (int j = 0; j < 3; ++j) { for (int k = 0; k < 7; ++k) { |