From 263ca460d894a3fc51d206dfc0e8da459f2dc8a0 Mon Sep 17 00:00:00 2001 From: Derek Chow Date: Wed, 28 Jul 2021 12:18:39 -0700 Subject: [PATCH 1/2] Add select benchmark. --- bench/benchSelect.cpp | 54 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 bench/benchSelect.cpp diff --git a/bench/benchSelect.cpp b/bench/benchSelect.cpp new file mode 100644 index 000000000..055b0eb6f --- /dev/null +++ b/bench/benchSelect.cpp @@ -0,0 +1,54 @@ +// Build with: g++ -O3 -DNDEBUG benchSelect.cpp -I ../ -o benchSelect + +#include + +#include + +#include "BenchUtil.h" + +template +double BenchmarkSelect(int rows, int cols, int iterations) { + typedef Eigen::Array Array; + Array x = Array::Random(rows, cols); + Array x_transpose = x.transpose(); + + Array zero = Array::Zero(rows, cols); + Array ones = Array::Ones(rows, cols); + + BenchTimer timer; + timer.reset(); + timer.start(); + for (int i = 0; i < iterations; i++) { + Array result = (x == x_transpose).select(ones, zero); + } + timer.stop(); + + return timer.value(); +} + +int main(int argc, char *argv[]) +{ + constexpr int rows = 512; + constexpr int cols = 512; + constexpr int iterations = 10000; + + #define RUN_BENCHMARK(TYPE) \ + { \ + double runtime = BenchmarkSelect(rows, cols, iterations); \ + std::cout << #TYPE << ": Ran " << iterations << " in " << runtime \ + << " seconds.\n"; \ + } + + RUN_BENCHMARK(int8_t); + RUN_BENCHMARK(int16_t); + RUN_BENCHMARK(int32_t); + RUN_BENCHMARK(int64_t); + RUN_BENCHMARK(uint8_t); + RUN_BENCHMARK(uint16_t); + RUN_BENCHMARK(uint32_t); + RUN_BENCHMARK(uint64_t); + RUN_BENCHMARK(float); + RUN_BENCHMARK(double); + + return 0; +} -- GitLab From 317580201191f645c6277b4b513bfa3e94679421 Mon Sep 17 00:00:00 2001 From: Derek Chow Date: Tue, 3 Aug 2021 10:35:43 -0700 Subject: [PATCH 2/2] Add typed scalar comparison functions. --- Eigen/src/Core/functors/BinaryFunctors.h | 84 ++++++++++++++++++++++++ bench/benchSelect.cpp | 16 ++++- 2 files changed, 99 insertions(+), 1 deletion(-) diff --git a/Eigen/src/Core/functors/BinaryFunctors.h b/Eigen/src/Core/functors/BinaryFunctors.h index 3c7601963..dd8f4d04e 100644 --- a/Eigen/src/Core/functors/BinaryFunctors.h +++ b/Eigen/src/Core/functors/BinaryFunctors.h @@ -278,6 +278,90 @@ struct scalar_cmp_op : binary_op_base struct scalar_typed_cmp_op; + +template +struct functor_traits > { + enum { + Cost = (NumTraits::AddCost+NumTraits::AddCost)/2, + PacketAccess = is_same::value && + packet_traits::HasCmp + }; +}; + +template +struct scalar_typed_cmp_op : binary_op_base +{ + typedef typename ScalarBinaryOpTraits >::ReturnType result_type; + EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type operator()(const LhsScalar& a, const RhsScalar& b) const {return a==b;} + template + EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet packetOp(const Packet& a, const Packet& b) const + { return internal::pcmp_eq(a,b); } +}; + +template +struct scalar_typed_cmp_op : binary_op_base +{ + typedef typename ScalarBinaryOpTraits >::ReturnType result_type; + EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type operator()(const LhsScalar& a, const RhsScalar& b) const {return a + EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet packetOp(const Packet& a, const Packet& b) const + { return internal::pcmp_lt(a,b); } +}; + +template +struct scalar_typed_cmp_op : binary_op_base +{ + typedef typename ScalarBinaryOpTraits >::ReturnType result_type; + EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type operator()(const LhsScalar& a, const RhsScalar& b) const {return a<=b;} + template + EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet packetOp(const Packet& a, const Packet& b) const + { return internal::pcmp_le(a,b); } +}; + +template +struct scalar_typed_cmp_op : binary_op_base +{ + typedef typename ScalarBinaryOpTraits >::ReturnType result_type; + EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type operator()(const LhsScalar& a, const RhsScalar& b) const {return a>b;} + template + EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet packetOp(const Packet& a, const Packet& b) const + { return internal::pcmp_lt(b,a); } +}; + +template +struct scalar_typed_cmp_op : binary_op_base +{ + typedef typename ScalarBinaryOpTraits >::ReturnType result_type; + EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type operator()(const LhsScalar& a, const RhsScalar& b) const {return a>=b;} + template + EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet packetOp(const Packet& a, const Packet& b) const + { return internal::pcmp_le(b,a); } +}; + +template +struct scalar_typed_cmp_op : binary_op_base +{ + typedef typename ScalarBinaryOpTraits >::ReturnType result_type; + EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type operator()(const LhsScalar& a, const RhsScalar& b) const {return !(a<=b || b<=a);} + template + EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet packetOp(const Packet& a, const Packet& b) const + { return internal::pcmp_eq(internal::por(internal::pcmp_le(a, b), internal::pcmp_le(b, a)), internal::pzero(a)); } +}; + +template +struct scalar_typed_cmp_op : binary_op_base +{ + typedef typename ScalarBinaryOpTraits >::ReturnType result_type; + EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type operator()(const LhsScalar& a, const RhsScalar& b) const {return a!=b;} + template + EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet packetOp(const Packet& a, const Packet& b) const + { return internal::pcmp_eq(internal::pcmp_eq(a, b), internal::pzero(a)); } +}; + /** \internal * \brief Template functor to compute the hypot of two \b positive \b and \b real scalars * diff --git a/bench/benchSelect.cpp b/bench/benchSelect.cpp index 055b0eb6f..b638f9f54 100644 --- a/bench/benchSelect.cpp +++ b/bench/benchSelect.cpp @@ -6,6 +6,20 @@ #include "BenchUtil.h" +namespace impl { +template +const Eigen::CwiseBinaryOp< + Eigen::internal::scalar_typed_cmp_op, + const LhsExpr, + const RhsExpr> +equal(const LhsExpr& A, const RhsExpr& B) { + return Eigen::CwiseBinaryOp< + Eigen::internal::scalar_typed_cmp_op, + const LhsExpr, + const RhsExpr>(A, B); +} +} // namespace impl + template double BenchmarkSelect(int rows, int cols, int iterations) { typedef Eigen::Array Array; @@ -19,7 +33,7 @@ double BenchmarkSelect(int rows, int cols, int iterations) { timer.reset(); timer.start(); for (int i = 0; i < iterations; i++) { - Array result = (x == x_transpose).select(ones, zero); + Array result = impl::equal(x, x_transpose).select(ones, zero); } timer.stop(); -- GitLab