diff options
author | Rasmus Munk Larsen <rmlarsen@google.com> | 2020-10-13 21:48:31 +0000 |
---|---|---|
committer | Rasmus Munk Larsen <rmlarsen@google.com> | 2020-10-13 21:48:31 +0000 |
commit | c6953f799b01d36f4236b64f351cc1446e0abe17 (patch) | |
tree | 9abcded97c6effc010d08787c5b43ef7bb043b54 /test/packetmath.cpp | |
parent | 807e51528d220c0efed870f0505dea81a5776085 (diff) |
Add packet generic ops `predux_fmin`, `predux_fmin_nan`, `predux_fmax`, and `predux_fmax_nan` that implement reductions with `PropagateNaN`, and `PropagateNumbers` semantics. Add (slow) generic implementations for most reductions.
Diffstat (limited to 'test/packetmath.cpp')
-rw-r--r-- | test/packetmath.cpp | 62 |
1 files changed, 46 insertions, 16 deletions
diff --git a/test/packetmath.cpp b/test/packetmath.cpp index 53c41c967..c6a1648ba 100644 --- a/test/packetmath.cpp +++ b/test/packetmath.cpp @@ -801,10 +801,6 @@ void packetmath_notcomplex() { Array<Scalar, Dynamic, 1>::Map(data1, PacketSize * 4).setRandom(); - ref[0] = data1[0]; - for (int i = 0; i < PacketSize; ++i) ref[0] = (std::min)(ref[0], data1[i]); - VERIFY(internal::isApprox(ref[0], internal::predux_min(internal::pload<Packet>(data1))) && "internal::predux_min"); - VERIFY((!PacketTraits::Vectorizable) || PacketTraits::HasMin); VERIFY((!PacketTraits::Vectorizable) || PacketTraits::HasMax); @@ -817,13 +813,16 @@ void packetmath_notcomplex() { using ::fmin; using ::fmax; #endif - CHECK_CWISE2_IF(PacketTraits::HasMin, fmin, internal::pfmin); - CHECK_CWISE2_IF(PacketTraits::HasMax, fmax, internal::pfmax); + CHECK_CWISE2_IF(PacketTraits::HasMin, fmin, (internal::pmin<PropagateNumbers>)); + CHECK_CWISE2_IF(PacketTraits::HasMax, fmax, internal::pmax<PropagateNumbers>); CHECK_CWISE1(numext::abs, internal::pabs); CHECK_CWISE2_IF(PacketTraits::HasAbsDiff, REF_ABS_DIFF, internal::pabsdiff); ref[0] = data1[0]; - for (int i = 0; i < PacketSize; ++i) ref[0] = (std::max)(ref[0], data1[i]); + for (int i = 0; i < PacketSize; ++i) ref[0] = internal::pmin(ref[0], data1[i]); + VERIFY(internal::isApprox(ref[0], internal::predux_min(internal::pload<Packet>(data1))) && "internal::predux_min"); + ref[0] = data1[0]; + for (int i = 0; i < PacketSize; ++i) ref[0] = internal::pmax(ref[0], data1[i]); VERIFY(internal::isApprox(ref[0], internal::predux_max(internal::pload<Packet>(data1))) && "internal::predux_max"); for (int i = 0; i < PacketSize; ++i) ref[i] = data1[0] + Scalar(i); @@ -852,16 +851,47 @@ void packetmath_notcomplex() { } } - for (int i = 0; i < PacketSize; ++i) { - data1[i] = internal::random<bool>() ? std::numeric_limits<Scalar>::quiet_NaN() : Scalar(0); - data1[i + PacketSize] = internal::random<bool>() ? std::numeric_limits<Scalar>::quiet_NaN() : Scalar(0); + + // Test NaN propagation. + if (!NumTraits<Scalar>::IsInteger) { + // Test reductions with no NaNs. + ref[0] = data1[0]; + for (int i = 0; i < PacketSize; ++i) ref[0] = internal::pmin<PropagateNumbers>(ref[0], data1[i]); + VERIFY(internal::isApprox(ref[0], internal::predux_min<PropagateNumbers>(internal::pload<Packet>(data1))) && "internal::predux_min<PropagateNumbers>"); + ref[0] = data1[0]; + for (int i = 0; i < PacketSize; ++i) ref[0] = internal::pmin<PropagateNaN>(ref[0], data1[i]); + VERIFY(internal::isApprox(ref[0], internal::predux_min<PropagateNaN>(internal::pload<Packet>(data1))) && "internal::predux_min<PropagateNaN>"); + ref[0] = data1[0]; + for (int i = 0; i < PacketSize; ++i) ref[0] = internal::pmax<PropagateNumbers>(ref[0], data1[i]); + VERIFY(internal::isApprox(ref[0], internal::predux_max<PropagateNumbers>(internal::pload<Packet>(data1))) && "internal::predux_max<PropagateNumbers>"); + ref[0] = data1[0]; + for (int i = 0; i < PacketSize; ++i) ref[0] = internal::pmax<PropagateNaN>(ref[0], data1[i]); + VERIFY(internal::isApprox(ref[0], internal::predux_max<PropagateNaN>(internal::pload<Packet>(data1))) && "internal::predux_max<PropagateNumbers>"); + // A single NaN. + const size_t index = std::numeric_limits<size_t>::quiet_NaN() % PacketSize; + data1[index] = std::numeric_limits<Scalar>::quiet_NaN(); + VERIFY(PacketSize==1 || !(numext::isnan)(internal::predux_min<PropagateNumbers>(internal::pload<Packet>(data1)))); + VERIFY((numext::isnan)(internal::predux_min<PropagateNaN>(internal::pload<Packet>(data1)))); + VERIFY(PacketSize==1 || !(numext::isnan)(internal::predux_max<PropagateNumbers>(internal::pload<Packet>(data1)))); + VERIFY((numext::isnan)(internal::predux_max<PropagateNaN>(internal::pload<Packet>(data1)))); + // All NaNs. + for (int i = 0; i < 4 * PacketSize; ++i) data1[i] = std::numeric_limits<Scalar>::quiet_NaN(); + VERIFY((numext::isnan)(internal::predux_min<PropagateNumbers>(internal::pload<Packet>(data1)))); + VERIFY((numext::isnan)(internal::predux_min<PropagateNaN>(internal::pload<Packet>(data1)))); + VERIFY((numext::isnan)(internal::predux_max<PropagateNumbers>(internal::pload<Packet>(data1)))); + VERIFY((numext::isnan)(internal::predux_max<PropagateNaN>(internal::pload<Packet>(data1)))); + + // Test NaN propagation for coefficient-wise min and max. + for (int i = 0; i < PacketSize; ++i) { + data1[i] = internal::random<bool>() ? std::numeric_limits<Scalar>::quiet_NaN() : Scalar(0); + data1[i + PacketSize] = internal::random<bool>() ? std::numeric_limits<Scalar>::quiet_NaN() : Scalar(0); + } + // Note: NaN propagation is implementation defined for pmin/pmax, so we do not test it here. + CHECK_CWISE2_IF(PacketTraits::HasMin, fmin, (internal::pmin<PropagateNumbers>)); + CHECK_CWISE2_IF(PacketTraits::HasMax, fmax, internal::pmax<PropagateNumbers>); + CHECK_CWISE2_IF(PacketTraits::HasMin, propagate_nan_min, (internal::pmin<PropagateNaN>)); + CHECK_CWISE2_IF(PacketTraits::HasMax, propagate_nan_max, internal::pmax<PropagateNaN>); } - // Test NaN propagation for pfmin and pfmax. It should be equivalent to std::fmin. - // Note: NaN propagation is implementation defined for pmin/pmax, so we do not test it here. - CHECK_CWISE2_IF(PacketTraits::HasMin, fmin, internal::pfmin); - CHECK_CWISE2_IF(PacketTraits::HasMax, fmax, internal::pfmax); - CHECK_CWISE2_IF(PacketTraits::HasMin, propagate_nan_min, internal::pfmin_nan); - CHECK_CWISE2_IF(PacketTraits::HasMax, propagate_nan_max, internal::pfmax_nan); } template <> |