From cbba0e3322650ba67a65e351bed76f58afc50e9a Mon Sep 17 00:00:00 2001 From: Michael Wang Date: Tue, 25 Oct 2022 17:19:08 -0700 Subject: [PATCH 1/3] add utility --- cpp/tests/utility/vector_equality.hpp | 64 +++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/cpp/tests/utility/vector_equality.hpp b/cpp/tests/utility/vector_equality.hpp index b964a02ea..f96fd2bd5 100644 --- a/cpp/tests/utility/vector_equality.hpp +++ b/cpp/tests/utility/vector_equality.hpp @@ -16,6 +16,7 @@ #pragma once +#include #include #include @@ -42,6 +43,16 @@ auto floating_eq(T val) } } +template +auto floating_near(T val, T abs_error) +{ + if constexpr (std::is_same_v) { + return ::testing::FloatNear(val, abs_error); + } else { + return ::testing::FloatNear(val, abs_error); + } +} + MATCHER(vec_2d_matcher, std::string(negation ? "are not" : "are") + " approximately equal vec_2d structs") { @@ -57,6 +68,22 @@ MATCHER(vec_2d_matcher, return false; } +MATCHER_P(vec_2d_near_matcher, + abs_error, + std::string(negation ? "are not" : "are") + " approximately equal vec_2d structs") +{ + auto lhs = std::get<0>(arg); + auto rhs = std::get<1>(arg); + + if (::testing::Matches(floating_near(rhs.x, abs_error))(lhs.x) && + ::testing::Matches(floating_near(rhs.y, abs_error))(lhs.y)) + return true; + + *result_listener << lhs << " != " << rhs; + + return false; +} + MATCHER(float_matcher, std::string(negation ? "are not" : "are") + " approximately equal floats") { auto lhs = std::get<0>(arg); @@ -69,6 +96,20 @@ MATCHER(float_matcher, std::string(negation ? "are not" : "are") + " approximate return false; } +MATCHER_P(float_near_matcher, + abs_error, + std::string(negation ? "are not" : "are") + " approximately equal floats") +{ + auto lhs = std::get<0>(arg); + auto rhs = std::get<1>(arg); + + if (::testing::Matches(floating_near(rhs, abs_error))(lhs)) return true; + + *result_listener << std::setprecision(18) << lhs << " != " << rhs; + + return false; +} + template thrust::host_vector to_host(Vector const& dvec) { @@ -103,5 +144,28 @@ inline void expect_vector_equivalent(Vector1 const& lhs, Vector2 const& rhs) } } +template +inline void expect_vector_equivalent(Vector1 const& lhs, Vector2 const& rhs, T abs_error) +{ + static_assert(std::is_same_v, "Value type mismatch."); + static_assert(!std::is_integral_v, "Integral types cannot be compared with an error."); + + if constexpr (cuspatial::is_vec_2d()) { + EXPECT_THAT(to_host(lhs), + ::testing::Pointwise(vec_2d_near_matcher(abs_error), to_host(rhs))); + } else if constexpr (std::is_floating_point_v) { + EXPECT_THAT(to_host(lhs), + ::testing::Pointwise(float_near_matcher(abs_error), to_host(rhs))); + } else { + EXPECT_EQ(lhs, rhs); + } +} + +#define CUSPATIAL_EXPECT_VECTORS_EQUIVALENT(lhs, rhs, ...) \ + do { \ + SCOPED_TRACE(" <-- line of failure\n"); \ + expect_vector_equivalent(lhs, rhs, ##__VA_ARGS__); \ + } while (0) + } // namespace test } // namespace cuspatial From 69f91c3510e8430d22258c958246b7eb90cb7453 Mon Sep 17 00:00:00 2001 From: Michael Wang Date: Tue, 25 Oct 2022 17:27:26 -0700 Subject: [PATCH 2/3] remove stale includes --- cpp/tests/utility/vector_equality.hpp | 1 - 1 file changed, 1 deletion(-) diff --git a/cpp/tests/utility/vector_equality.hpp b/cpp/tests/utility/vector_equality.hpp index f96fd2bd5..1e737aee0 100644 --- a/cpp/tests/utility/vector_equality.hpp +++ b/cpp/tests/utility/vector_equality.hpp @@ -16,7 +16,6 @@ #pragma once -#include #include #include From be5e06f579cd2b55bd762b38036ee6b9ffc49d27 Mon Sep 17 00:00:00 2001 From: Michael Wang Date: Fri, 28 Oct 2022 12:58:03 -0700 Subject: [PATCH 3/3] update names --- cpp/tests/utility/vector_equality.hpp | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/cpp/tests/utility/vector_equality.hpp b/cpp/tests/utility/vector_equality.hpp index 1e737aee0..4082300ff 100644 --- a/cpp/tests/utility/vector_equality.hpp +++ b/cpp/tests/utility/vector_equality.hpp @@ -32,8 +32,14 @@ namespace cuspatial { namespace test { +/** + * @brief Compare two floats are close within N ULPs + * + * N is predefined by GoogleTest + * https://google.github.io/googletest/reference/assertions.html#EXPECT_FLOAT_EQ + */ template -auto floating_eq(T val) +auto floating_eq_by_ulp(T val) { if constexpr (std::is_same_v) { return ::testing::FloatEq(val); @@ -42,8 +48,11 @@ auto floating_eq(T val) } } +/** + * @brief Compare two floats are close within `abs_error` + */ template -auto floating_near(T val, T abs_error) +auto floating_eq_by_abs_error(T val, T abs_error) { if constexpr (std::is_same_v) { return ::testing::FloatNear(val, abs_error); @@ -58,8 +67,8 @@ MATCHER(vec_2d_matcher, auto lhs = std::get<0>(arg); auto rhs = std::get<1>(arg); - if (::testing::Matches(floating_eq(rhs.x))(lhs.x) && - ::testing::Matches(floating_eq(rhs.y))(lhs.y)) + if (::testing::Matches(floating_eq_by_ulp(rhs.x))(lhs.x) && + ::testing::Matches(floating_eq_by_ulp(rhs.y))(lhs.y)) return true; *result_listener << lhs << " != " << rhs; @@ -74,8 +83,8 @@ MATCHER_P(vec_2d_near_matcher, auto lhs = std::get<0>(arg); auto rhs = std::get<1>(arg); - if (::testing::Matches(floating_near(rhs.x, abs_error))(lhs.x) && - ::testing::Matches(floating_near(rhs.y, abs_error))(lhs.y)) + if (::testing::Matches(floating_eq_by_abs_error(rhs.x, abs_error))(lhs.x) && + ::testing::Matches(floating_eq_by_abs_error(rhs.y, abs_error))(lhs.y)) return true; *result_listener << lhs << " != " << rhs; @@ -88,7 +97,7 @@ MATCHER(float_matcher, std::string(negation ? "are not" : "are") + " approximate auto lhs = std::get<0>(arg); auto rhs = std::get<1>(arg); - if (::testing::Matches(floating_eq(rhs))(lhs)) return true; + if (::testing::Matches(floating_eq_by_ulp(rhs))(lhs)) return true; *result_listener << std::setprecision(18) << lhs << " != " << rhs; @@ -102,7 +111,7 @@ MATCHER_P(float_near_matcher, auto lhs = std::get<0>(arg); auto rhs = std::get<1>(arg); - if (::testing::Matches(floating_near(rhs, abs_error))(lhs)) return true; + if (::testing::Matches(floating_eq_by_abs_error(rhs, abs_error))(lhs)) return true; *result_listener << std::setprecision(18) << lhs << " != " << rhs;