From 7c2461fde44dadc21cbb3547549e7e79dad12896 Mon Sep 17 00:00:00 2001 From: "Yu-Hsiang M. Tsai" Date: Thu, 24 Oct 2024 14:02:22 +0200 Subject: [PATCH] collect the reused part and undef after usage Co-authored-by: Marcel Koch --- core/test/base/extended_float.cpp | 108 ++++------------------ core/test/base/floating_bit_helper.hpp | 82 +++++++++++++++++ core/test/base/half.cpp | 123 +++++-------------------- include/ginkgo/core/base/half.hpp | 9 +- 4 files changed, 130 insertions(+), 192 deletions(-) create mode 100644 core/test/base/floating_bit_helper.hpp diff --git a/core/test/base/extended_float.cpp b/core/test/base/extended_float.cpp index bdb7a58ed84..764f5fc0c8d 100644 --- a/core/test/base/extended_float.cpp +++ b/core/test/base/extended_float.cpp @@ -9,86 +9,22 @@ #include -#include - - -namespace { - - -template -struct floating_impl; - -template <> -struct floating_impl<16> { - using type = gko::half; -}; - -template <> -struct floating_impl<32> { - using type = float; -}; - -template <> -struct floating_impl<64> { - using type = double; -}; - -template -using floating = typename floating_impl::type; - - -class ExtendedFloatTestBase : public ::testing::Test { -protected: - using half = gko::half; - template - using truncated = gko::truncated; - - static constexpr auto byte_size = gko::byte_size; - - template - static floating create_from_bits(const char (&s)[N]) - { - auto bits = std::bitset(s).to_ullong(); - // We cast to the same size of integer type first. - // Otherwise, the first memory chunk is different when we use - // reinterpret_cast or memcpy to get the smaller type out of unsigned - // long long. - using bits_type = - typename gko::detail::float_traits>::bits_type; - auto bits_val = static_cast(bits); - floating result; - static_assert(sizeof(floating) == sizeof(bits_type), - "the type should have the same size as its bits_type"); - std::memcpy(&result, &bits_val, sizeof(bits_type)); - return result; - } - - template - static std::bitset get_bits(T val) - { - using bits_type = typename gko::detail::float_traits::bits_type; - bits_type bits; - static_assert(sizeof(T) == sizeof(bits_type), - "the type should have the same size as its bits_type"); - std::memcpy(&bits, &val, sizeof(T)); - return std::bitset(bits); - } - - template - static std::bitset get_bits(const char (&s)[N]) - { - return std::bitset(s); - } -}; - - -class TruncatedDouble : public ExtendedFloatTestBase {}; +#include "core/test/base/floating_bit_helper.hpp" + + +using namespace floating_bit_helper; + +using half = gko::half; + +template +using truncated = gko::truncated; + // clang-format does terrible formatting of string literal concatenation // clang-format off -TEST_F(TruncatedDouble, SplitsDoubleToHalves) +TEST(TruncatedDouble, SplitsDoubleToHalves) { double x = create_from_bits("1" "11110100100" "1111" "1000110110110101" "1100101011010101" "1001011101110111"); @@ -102,7 +38,7 @@ TEST_F(TruncatedDouble, SplitsDoubleToHalves) } -TEST_F(TruncatedDouble, AssemblesDoubleFromHalves) +TEST(TruncatedDouble, AssemblesDoubleFromHalves) { double x = create_from_bits("1" "11110100100" "1111" "1000110110110101" "1100101011010101" "1001011101110111"); @@ -121,7 +57,7 @@ TEST_F(TruncatedDouble, AssemblesDoubleFromHalves) } -TEST_F(TruncatedDouble, SplitsDoubleToQuarters) +TEST(TruncatedDouble, SplitsDoubleToQuarters) { double x = create_from_bits("1" "11110100100" "1111" "1000110110110101" "1100101011010101" "1001011101110111"); @@ -138,7 +74,7 @@ TEST_F(TruncatedDouble, SplitsDoubleToQuarters) } -TEST_F(TruncatedDouble, AssemblesDoubleFromQuarters) +TEST(TruncatedDouble, AssemblesDoubleFromQuarters) { double x = create_from_bits("1" "11110100100" "1111" "1000110110110101" "1100101011010101" "1001011101110111"); @@ -167,16 +103,7 @@ TEST_F(TruncatedDouble, AssemblesDoubleFromQuarters) } -// clang-format on - - -class TruncatedFloat : public ExtendedFloatTestBase {}; - - -// clang-format off - - -TEST_F(TruncatedFloat, SplitsFloatToHalves) +TEST(TruncatedFloat, SplitsFloatToHalves) { float x = create_from_bits("1" "11110100" "1001111" "1000110110110101"); @@ -188,7 +115,7 @@ TEST_F(TruncatedFloat, SplitsFloatToHalves) } -TEST_F(TruncatedFloat, AssemblesFloatFromHalves) +TEST(TruncatedFloat, AssemblesFloatFromHalves) { float x = create_from_bits("1" "11110100" "1001111" "1000110110110101"); auto p1 = static_cast>(x); @@ -205,6 +132,3 @@ TEST_F(TruncatedFloat, AssemblesFloatFromHalves) // clang-format on - - -} // namespace diff --git a/core/test/base/floating_bit_helper.hpp b/core/test/base/floating_bit_helper.hpp new file mode 100644 index 00000000000..6b3f261d894 --- /dev/null +++ b/core/test/base/floating_bit_helper.hpp @@ -0,0 +1,82 @@ +// SPDX-FileCopyrightText: 2024 The Ginkgo authors +// +// SPDX-License-Identifier: BSD-3-Clause + +#ifndef GKO_CORE_TEST_BASE_FLOATING_BIT_HELPER_HPP_ +#define GKO_CORE_TEST_BASE_FLOATING_BIT_HELPER_HPP_ + + +#include +#include + +#include + +namespace floating_bit_helper { + + +constexpr auto byte_size = gko::detail::byte_size; + + +template +struct floating_impl; + +template <> +struct floating_impl<16> { + using type = gko::half; +}; + +template <> +struct floating_impl<32> { + using type = float; +}; + +template <> +struct floating_impl<64> { + using type = double; +}; + + +template +using floating = typename floating_impl::type; + + +template +static floating create_from_bits(const char (&s)[N]) +{ + auto bits = std::bitset(s).to_ullong(); + // We cast to the same size of integer type first. + // Otherwise, the first memory chunk is different when we use + // reinterpret_cast or memcpy to get the smaller type out of unsigned + // long long. + using bits_type = + typename gko::detail::float_traits>::bits_type; + auto bits_val = static_cast(bits); + floating result; + static_assert(sizeof(floating) == sizeof(bits_type), + "the type should have the same size as its bits_type"); + std::memcpy(&result, &bits_val, sizeof(bits_type)); + return result; +} + + +template +static std::bitset get_bits(T val) +{ + using bits_type = typename gko::detail::float_traits::bits_type; + bits_type bits; + static_assert(sizeof(T) == sizeof(bits_type), + "the type should have the same size as its bits_type"); + std::memcpy(&bits, &val, sizeof(T)); + return std::bitset(bits); +} + +template +static std::bitset get_bits(const char (&s)[N]) +{ + return std::bitset(s); +} + + +} // namespace floating_bit_helper + +#endif // GKO_CORE_TEST_BASE_FLOATING_BIT_HELPER_HPP_ \ No newline at end of file diff --git a/core/test/base/half.cpp b/core/test/base/half.cpp index 51d3e60ce40..39c47c49e15 100644 --- a/core/test/base/half.cpp +++ b/core/test/base/half.cpp @@ -2,88 +2,22 @@ // // SPDX-License-Identifier: BSD-3-Clause -#include -#include -#include - #include #include +#include "core/test/base/floating_bit_helper.hpp" + -template -struct floating_impl; - -template <> -struct floating_impl<16> { - using type = gko::half; -}; - -template <> -struct floating_impl<32> { - using type = float; -}; - -template <> -struct floating_impl<64> { - using type = double; -}; - -template -using floating = typename floating_impl::type; - - -class ExtendedFloatTestBase : public ::testing::Test { -protected: - using half = gko::half; - - static constexpr auto byte_size = gko::detail::byte_size; - - template - static floating create_from_bits(const char (&s)[N]) - { - auto bits = std::bitset(s).to_ullong(); - // We cast to the same size of integer type first. - // Otherwise, the first memory chunk is different when we use - // reinterpret_cast or memcpy to get the smaller type out of unsigned - // long long. - using bits_type = - typename gko::detail::float_traits>::bits_type; - auto bits_val = static_cast(bits); - floating result; - static_assert(sizeof(floating) == sizeof(bits_type), - "the type should have the same size as its bits_type"); - std::memcpy(&result, &bits_val, sizeof(bits_type)); - return result; - } - - template - static std::bitset get_bits(T val) - { - using bits_type = typename gko::detail::float_traits::bits_type; - bits_type bits; - static_assert(sizeof(T) == sizeof(bits_type), - "the type should have the same size as its bits_type"); - std::memcpy(&bits, &val, sizeof(T)); - return std::bitset(bits); - } - - template - static std::bitset get_bits(const char (&s)[N]) - { - return std::bitset(s); - } -}; - - -class FloatToHalf : public ExtendedFloatTestBase {}; +using half = gko::half; +using namespace floating_bit_helper; // clang-format does terrible formatting of string literal concatenation // clang-format off -TEST_F(FloatToHalf, ConvertsOne) +TEST(FloatToHalf, ConvertsOne) { half x = create_from_bits("0" "01111111" "00000000000000000000000"); @@ -91,7 +25,7 @@ TEST_F(FloatToHalf, ConvertsOne) } -TEST_F(FloatToHalf, ConvertsZero) +TEST(FloatToHalf, ConvertsZero) { half x = create_from_bits("0" "00000000" "00000000000000000000000"); @@ -99,7 +33,7 @@ TEST_F(FloatToHalf, ConvertsZero) } -TEST_F(FloatToHalf, ConvertsInf) +TEST(FloatToHalf, ConvertsInf) { half x = create_from_bits("0" "11111111" "00000000000000000000000"); @@ -107,7 +41,7 @@ TEST_F(FloatToHalf, ConvertsInf) } -TEST_F(FloatToHalf, ConvertsNegInf) +TEST(FloatToHalf, ConvertsNegInf) { half x = create_from_bits("1" "11111111" "00000000000000000000000"); @@ -115,7 +49,7 @@ TEST_F(FloatToHalf, ConvertsNegInf) } -TEST_F(FloatToHalf, ConvertsNan) +TEST(FloatToHalf, ConvertsNan) { half x = create_from_bits("0" "11111111" "00000000000000000000001"); @@ -128,7 +62,7 @@ TEST_F(FloatToHalf, ConvertsNan) } -TEST_F(FloatToHalf, ConvertsNegNan) +TEST(FloatToHalf, ConvertsNegNan) { half x = create_from_bits("1" "11111111" "00010000000000000000000"); @@ -141,7 +75,7 @@ TEST_F(FloatToHalf, ConvertsNegNan) } -TEST_F(FloatToHalf, FlushesToZero) +TEST(FloatToHalf, FlushesToZero) { half x = create_from_bits("0" "00000111" "00010001000100000001000"); @@ -149,7 +83,7 @@ TEST_F(FloatToHalf, FlushesToZero) } -TEST_F(FloatToHalf, FlushesToNegZero) +TEST(FloatToHalf, FlushesToNegZero) { half x = create_from_bits("1" "00000010" "00010001000100000001000"); @@ -157,7 +91,7 @@ TEST_F(FloatToHalf, FlushesToNegZero) } -TEST_F(FloatToHalf, FlushesToInf) +TEST(FloatToHalf, FlushesToInf) { half x = create_from_bits("0" "10100000" "10010000000000010000100"); @@ -165,7 +99,7 @@ TEST_F(FloatToHalf, FlushesToInf) } -TEST_F(FloatToHalf, FlushesToNegInf) +TEST(FloatToHalf, FlushesToNegInf) { half x = create_from_bits("1" "11000000" "10010000000000010000100"); @@ -173,7 +107,7 @@ TEST_F(FloatToHalf, FlushesToNegInf) } -TEST_F(FloatToHalf, TruncatesSmallNumber) +TEST(FloatToHalf, TruncatesSmallNumber) { half x = create_from_bits("0" "01110001" "10010000000000010000100"); @@ -181,7 +115,7 @@ TEST_F(FloatToHalf, TruncatesSmallNumber) } -TEST_F(FloatToHalf, TruncatesLargeNumberRoundToEven) +TEST(FloatToHalf, TruncatesLargeNumberRoundToEven) { half neg_x = create_from_bits("1" "10001110" "10010011111000010000100"); half neg_x2 = create_from_bits("1" "10001110" "10010011101000010000100"); @@ -199,16 +133,7 @@ TEST_F(FloatToHalf, TruncatesLargeNumberRoundToEven) } -// clang-format on - - -class HalfToFloat : public ExtendedFloatTestBase {}; - - -// clang-format off - - -TEST_F(HalfToFloat, ConvertsOne) +TEST(HalfToFloat, ConvertsOne) { float x = create_from_bits("0" "01111" "0000000000"); @@ -216,7 +141,7 @@ TEST_F(HalfToFloat, ConvertsOne) } -TEST_F(HalfToFloat, ConvertsZero) +TEST(HalfToFloat, ConvertsZero) { float x = create_from_bits("0" "00000" "0000000000"); @@ -224,7 +149,7 @@ TEST_F(HalfToFloat, ConvertsZero) } -TEST_F(HalfToFloat, ConvertsInf) +TEST(HalfToFloat, ConvertsInf) { float x = create_from_bits("0" "11111" "0000000000"); @@ -232,7 +157,7 @@ TEST_F(HalfToFloat, ConvertsInf) } -TEST_F(HalfToFloat, ConvertsNegInf) +TEST(HalfToFloat, ConvertsNegInf) { float x = create_from_bits("1" "11111" "0000000000"); @@ -240,7 +165,7 @@ TEST_F(HalfToFloat, ConvertsNegInf) } -TEST_F(HalfToFloat, ConvertsNan) +TEST(HalfToFloat, ConvertsNan) { float x = create_from_bits("0" "11111" "0001001000"); @@ -253,7 +178,7 @@ TEST_F(HalfToFloat, ConvertsNan) } -TEST_F(HalfToFloat, ConvertsNegNan) +TEST(HalfToFloat, ConvertsNegNan) { float x = create_from_bits("1" "11111" "0000000001"); @@ -266,7 +191,7 @@ TEST_F(HalfToFloat, ConvertsNegNan) } -TEST_F(HalfToFloat, ExtendsSmallNumber) +TEST(HalfToFloat, ExtendsSmallNumber) { float x = create_from_bits("0" "00001" "1000010001"); @@ -274,7 +199,7 @@ TEST_F(HalfToFloat, ExtendsSmallNumber) } -TEST_F(HalfToFloat, ExtendsLargeNumber) +TEST(HalfToFloat, ExtendsLargeNumber) { float x = create_from_bits("1" "11110" "1001001111"); diff --git a/include/ginkgo/core/base/half.hpp b/include/ginkgo/core/base/half.hpp index 4ff6e6c6987..7b2817b0f22 100644 --- a/include/ginkgo/core/base/half.hpp +++ b/include/ginkgo/core/base/half.hpp @@ -304,7 +304,7 @@ class half { this->float2half(static_cast(val)); } - constexpr half(const half& val) : data_(0) { data_ = val.data_; }; + constexpr half(const half& val) : data_(val.data_){}; template half& operator=(const V val) @@ -336,11 +336,14 @@ class half { data_ = result.data_; \ return *this; \ } + HALF_OPERATOR(+, +=) HALF_OPERATOR(-, -=) HALF_OPERATOR(*, *=) HALF_OPERATOR(/, /=) +#undef HALF_OPERATOR + // Do operation with different type // If it is floating point, using floating point as type. // If it is integer, using half as type @@ -375,6 +378,8 @@ class half { HALF_FRIEND_OPERATOR(*, *=) HALF_FRIEND_OPERATOR(/, /=) +#undef HALF_FRIEND_OPERATOR + // the negative half operator-() const { @@ -590,6 +595,8 @@ class complex { COMPLEX_HALF_OPERATOR(*, *=) COMPLEX_HALF_OPERATOR(/, /=) +#undef COMPLEX_HALF_OPERATOR + private: value_type real_; value_type imag_;