From a7d2552af8b34f6befba9988c36fe5d9723892e6 Mon Sep 17 00:00:00 2001 From: Antonio Sanchez Date: Thu, 28 May 2020 10:41:28 -0700 Subject: Remove HasCast and fix packetmath cast tests. The use of the `packet_traits<>::HasCast` field is currently inconsistent with `type_casting_traits<>`, and is unused apart from within `test/packetmath.cpp`. In addition, those packetmath cast tests do not currently reflect how casts are performed in practice: they ignore the `SrcCoeffRatio` and `TgtCoeffRatio` fields, assuming a 1:1 ratio. Here we remove the unsed `HasCast`, and modify the packet cast tests to better reflect their usage. --- test/packetmath.cpp | 143 ++++++++++++++++++++++++++++++++++------------------ 1 file changed, 93 insertions(+), 50 deletions(-) (limited to 'test/packetmath.cpp') 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 +// Uses pcast to cast from one array to another. +template +struct pcast_array { + static void cast(const typename internal::unpacket_traits::type* src, size_t size, typename internal::unpacket_traits::type* dst) { + static const int TgtPacketSize = internal::unpacket_traits::size; + for (size_t i=0; i(internal::ploadu(src+i))); + } + } +}; + +template +struct pcast_array{ + static void cast(const typename internal::unpacket_traits::type* src, size_t size, typename internal::unpacket_traits::type* dst) { + static const int SrcPacketSize = internal::unpacket_traits::size; + static const int TgtPacketSize = internal::unpacket_traits::size; + for (size_t i=0; i(src+i); + SrcPacket b = internal::ploadu(src+i+SrcPacketSize); + internal::pstoreu(dst+i, internal::pcast(a, b)); + } + } +}; + +template +struct pcast_array{ + static void cast(const typename internal::unpacket_traits::type* src, size_t size, typename internal::unpacket_traits::type* dst) { + static const int SrcPacketSize = internal::unpacket_traits::size; + static const int TgtPacketSize = internal::unpacket_traits::size; + for (size_t i=0; i(src+i); + SrcPacket b = internal::ploadu(src+i+SrcPacketSize); + SrcPacket c = internal::ploadu(src+i+2*SrcPacketSize); + SrcPacket d = internal::ploadu(src+i+3*SrcPacketSize); + internal::pstoreu(dst+i, internal::pcast(a, b)); + } + } +}; + +template struct test_cast_helper; -template -struct test_cast_helper { +template +struct test_cast_helper { static void run() {} }; -template -struct test_cast_helper { +template +struct test_cast_helper { static void run() { - static const int PacketSize = internal::unpacket_traits::size; - EIGEN_ALIGN_MAX FromScalar data1[PacketSize]; - EIGEN_ALIGN_MAX ToScalar data2[PacketSize]; - EIGEN_ALIGN_MAX ToScalar ref[PacketSize]; + typedef typename internal::unpacket_traits::type SrcScalar; + typedef typename internal::unpacket_traits::type TgtScalar; + static const int SrcPacketSize = internal::unpacket_traits::size; + static const int TgtPacketSize = internal::unpacket_traits::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::Random().value(); - const ToScalar to_scalar = Array::Random().value(); - const FromScalar c = sizeof(ToScalar) > sizeof(FromScalar) ? static_cast(to_scalar) : from_scalar; - data1[i] = (NumTraits::IsSigned && !NumTraits::IsSigned) ? numext::abs(c) : c; + for (int i=0; i::Random().value(); + const TgtScalar b = Array::Random().value(); + const SrcScalar c = sizeof(TgtScalar) > sizeof(SrcScalar) ? static_cast(b) : a; + data1[i] = (NumTraits::IsSigned && !NumTraits::IsSigned) ? numext::abs(c) : c; } - for (int i=0; i(data1[i]); - internal::pstore(data2, internal::pcast(internal::pload(data1))); + for (int i=0; i(data1[i]); - VERIFY(test::areApprox(ref, data2, PacketSize) && "internal::pcast<>"); + pcast_array::cast(data1, DataSize, data2); + + VERIFY(test::areApprox(ref, data2, DataSize) && "internal::pcast<>"); } }; -template +template void test_cast() { - typedef typename internal::unpacket_traits::type FromScalar; - typedef typename internal::packet_traits FromPacketTraits; - typedef typename internal::packet_traits::type Full; - typedef typename internal::unpacket_traits::half Half; - typedef typename internal::unpacket_traits::half>::half Quarter; - - static const int PacketSize = internal::unpacket_traits::size; - static const bool CanCast = - FromPacketTraits::HasCast && - (PacketSize == internal::unpacket_traits::size || - PacketSize == internal::unpacket_traits::size || - PacketSize == internal::unpacket_traits::size); - - typedef typename internal::conditional::size == PacketSize, Quarter, - typename internal::conditional::size == PacketSize, Half, Full>::type>::type - ToPacket; - - test_cast_helper::run(); + typedef typename internal::packet_traits SrcPacketTraits; + typedef typename internal::packet_traits TgtPacketTraits; + typedef typename internal::type_casting_traits 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::HasHalfPacket && internal::packet_traits::HasHalfPacket; + + test_cast_helper::run(); + test_cast_helper::run(); +} + +template void packetmath_pcast_ops() { + const static bool IsFullPacket = internal::is_same::type,Packet>::value; + if (IsFullPacket) { + test_cast(); + test_cast(); + test_cast(); + test_cast(); + test_cast(); + test_cast(); + test_cast(); + test_cast(); + test_cast(); + test_cast(); + } } template @@ -341,6 +396,7 @@ template void packetmath() CHECK_CWISE2_IF(true, internal::pand, internal::pand); packetmath_boolean_mask_ops(); + packetmath_pcast_ops(); } @@ -584,19 +640,6 @@ template void packetmath_notcomplex() Array::Map(data1, PacketSize*4).setRandom(); - if (PacketTraits::HasCast) { - test_cast(); - test_cast(); - test_cast(); - test_cast(); - test_cast(); - test_cast(); - test_cast(); - test_cast(); - test_cast(); - test_cast(); - } - ref[0] = data1[0]; for (int i=0; i