aboutsummaryrefslogtreecommitdiffhomepage
path: root/test/packetmath.cpp
diff options
context:
space:
mode:
authorGravatar Antonio Sanchez <cantonios@google.com>2020-05-28 10:41:28 -0700
committerGravatar Antonio Sánchez <cantonios@google.com>2020-06-11 17:26:56 +0000
commita7d2552af8b34f6befba9988c36fe5d9723892e6 (patch)
tree3ca16204e91819de1b8bdf0b9307081b3789de20 /test/packetmath.cpp
parent463ec866483806640c0a589afa427193a4599e8e (diff)
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.
Diffstat (limited to 'test/packetmath.cpp')
-rw-r--r--test/packetmath.cpp143
1 files changed, 93 insertions, 50 deletions
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]);