Skip to content

Commit

Permalink
collect the reused part and undef after usage
Browse files Browse the repository at this point in the history
Co-authored-by: Marcel Koch <[email protected]>
  • Loading branch information
yhmtsai and MarcelKoch committed Oct 25, 2024
1 parent 7770129 commit 62a2f76
Show file tree
Hide file tree
Showing 5 changed files with 134 additions and 192 deletions.
4 changes: 4 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v5.0.0
hooks:
- id: end-of-file-fixer
- repo: https://github.com/pre-commit/mirrors-clang-format
rev: 'v14.0.0' # The default in Ubuntu 22.04, which is used in our CI
hooks:
Expand Down
108 changes: 16 additions & 92 deletions core/test/base/extended_float.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,86 +9,22 @@

#include <gtest/gtest.h>

#include <ginkgo/core/base/half.hpp>


namespace {


template <std::size_t N>
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 <std::size_t N>
using floating = typename floating_impl<N>::type;


class ExtendedFloatTestBase : public ::testing::Test {
protected:
using half = gko::half;
template <typename T, std::size_t NumComponents, std::size_t ComponentId>
using truncated = gko::truncated<T, NumComponents, ComponentId>;

static constexpr auto byte_size = gko::byte_size;

template <std::size_t N>
static floating<N - 1> create_from_bits(const char (&s)[N])
{
auto bits = std::bitset<N - 1>(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<floating<N - 1>>::bits_type;
auto bits_val = static_cast<bits_type>(bits);
floating<N - 1> result;
static_assert(sizeof(floating<N - 1>) == 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 <typename T>
static std::bitset<sizeof(T) * byte_size> get_bits(T val)
{
using bits_type = typename gko::detail::float_traits<T>::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<sizeof(T) * byte_size>(bits);
}

template <std::size_t N>
static std::bitset<N - 1> get_bits(const char (&s)[N])
{
return std::bitset<N - 1>(s);
}
};


class TruncatedDouble : public ExtendedFloatTestBase {};
#include "core/test/base/floating_bit_helper.hpp"


using namespace floating_bit_helper;

using half = gko::half;

template <typename T, std::size_t NumComponents, std::size_t ComponentId>
using truncated = gko::truncated<T, NumComponents, ComponentId>;


// 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");
Expand All @@ -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");
Expand All @@ -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");
Expand All @@ -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");
Expand Down Expand Up @@ -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");

Expand All @@ -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<truncated<float, 2, 0>>(x);
Expand All @@ -205,6 +132,3 @@ TEST_F(TruncatedFloat, AssemblesFloatFromHalves)


// clang-format on


} // namespace
82 changes: 82 additions & 0 deletions core/test/base/floating_bit_helper.hpp
Original file line number Diff line number Diff line change
@@ -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 <bitset>
#include <cstring>

#include <ginkgo/core/base/half.hpp>

namespace floating_bit_helper {


constexpr auto byte_size = gko::detail::byte_size;


template <std::size_t N>
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 <std::size_t N>
using floating = typename floating_impl<N>::type;


template <std::size_t N>
floating<N - 1> create_from_bits(const char (&s)[N])
{
auto bits = std::bitset<N - 1>(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<floating<N - 1>>::bits_type;
auto bits_val = static_cast<bits_type>(bits);
floating<N - 1> result;
static_assert(sizeof(floating<N - 1>) == 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 <typename T>
std::bitset<sizeof(T) * byte_size> get_bits(T val)
{
using bits_type = typename gko::detail::float_traits<T>::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<sizeof(T) * byte_size>(bits);
}

template <std::size_t N>
std::bitset<N - 1> get_bits(const char (&s)[N])
{
return std::bitset<N - 1>(s);
}


} // namespace floating_bit_helper

#endif // GKO_CORE_TEST_BASE_FLOATING_BIT_HELPER_HPP_
Loading

0 comments on commit 62a2f76

Please sign in to comment.