Skip to content

Commit

Permalink
[cpp] Improve tests for Double<T>
Browse files Browse the repository at this point in the history
  • Loading branch information
tobiashienzsch committed Oct 2, 2024
1 parent ed05fb6 commit 457f950
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 6 deletions.
4 changes: 3 additions & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,9 @@ jobs:

- name: GCOV
if: runner.os == 'Linux'
run: gcovr --xml-pretty --exclude-unreachable-branches --exclude-throw-branches -r src -s build -o build/coverage.xml
run: |
./build/src/cpp/pffdtd-engine test
gcovr --xml-pretty --exclude-unreachable-branches --exclude-throw-branches -r src -s build -o build/coverage.xml
- name: Upload coverage report
uses: codecov/codecov-action@v4
Expand Down
19 changes: 19 additions & 0 deletions src/cpp/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -185,15 +185,34 @@ auto main(int argc, char** argv) -> int {
if (*test) {
// NOLINTBEGIN
using pffdtd::Double;
PFFDTD_ASSERT(static_cast<float>(Double{42.0F} + 2.0F) == 44.0F);
PFFDTD_ASSERT(static_cast<float>(Double{42.0F} + Double{2.0F}) == 44.0F);
PFFDTD_ASSERT(static_cast<float>(Double{42.0F} - Double{2.0F}) == 40.0F);
PFFDTD_ASSERT(static_cast<float>(Double{42.0F} * Double{2.0F}) == 84.0F);
PFFDTD_ASSERT(static_cast<float>(Double{42.0F} / Double{2.0F}) == 21.0F);

PFFDTD_ASSERT(static_cast<double>(Double{42.0} + 2.0) == 44.0);
PFFDTD_ASSERT(static_cast<double>(Double{42.0} + Double{2.0}) == 44.0);
PFFDTD_ASSERT(static_cast<double>(Double{42.0} - Double{2.0}) == 40.0);
PFFDTD_ASSERT(static_cast<double>(Double{42.0} * Double{2.0}) == 84.0);
PFFDTD_ASSERT(static_cast<double>(Double{42.0} / Double{2.0}) == 21.0);

auto a = Double{42.0};
PFFDTD_ASSERT(a == a);
PFFDTD_ASSERT(a != Double<double>{});
PFFDTD_ASSERT(Double<double>{} != a);
PFFDTD_ASSERT(static_cast<double>(+a) == +42.0);
PFFDTD_ASSERT(static_cast<double>(-a) == -42.0);

a += Double{2.0};
PFFDTD_ASSERT(static_cast<double>(a) == 44.0);
a -= Double{2.0};
PFFDTD_ASSERT(static_cast<double>(a) == 42.0);
a *= Double{2.0};
PFFDTD_ASSERT(static_cast<double>(a) == 84.0);
a /= Double{2.0};
PFFDTD_ASSERT(static_cast<double>(a) == 42.0);

// NOLINTEND
}

Expand Down
18 changes: 13 additions & 5 deletions src/cpp/pffdtd/double.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ namespace pffdtd {

/// https://hal.science/hal-01351529v3/document
/// https://inria.hal.science/inria-00070314/document
/// https://people.eecs.berkeley.edu/~jrs/papers/robustr.pdf
/// https://github.com/sukop/doubledouble
/// https://github.com/JuliaMath/DoubleFloats.jl
/// https://github.com/FlorisSteenkamp/double-double
Expand Down Expand Up @@ -53,29 +54,34 @@ struct Double {

friend constexpr auto operator-(Double x) noexcept -> Double { return {-x.high(), -x.low()}; }

friend constexpr auto operator+(Double lhs, Real rhs) noexcept -> Double {
auto [sl, sh] = twoSum(lhs.high(), rhs);
return twoSumFast(sh, lhs.low() + sl);
}

friend constexpr auto operator+(Double lhs, Double rhs) noexcept -> Double {
auto [r, e] = twoSum(lhs.high(), rhs.high());
e += lhs.low() + rhs.low();
return twoSumQuick(r, e);
return twoSumFast(r, e);
}

friend constexpr auto operator-(Double lhs, Double rhs) noexcept -> Double {
auto [r, e] = twoDifference(lhs.high(), rhs.high());
e += lhs.low() - rhs.low();
return twoSumQuick(r, e);
return twoSumFast(r, e);
}

friend constexpr auto operator*(Double lhs, Double rhs) noexcept -> Double {
auto [r, e] = twoProduct(lhs.high(), rhs.high());
e += lhs.high() * rhs.low() + lhs.low() * rhs.high();
return twoSumQuick(r, e);
return twoSumFast(r, e);
}

friend constexpr auto operator/(Double lhs, Double rhs) noexcept -> Double {
auto r = lhs.high() / rhs.high();
auto [s, f] = twoProduct(r, rhs.high());
auto e = (lhs.high() - s - f + lhs.low() - r * rhs.low()) / rhs.high();
return twoSumQuick(r, e);
return twoSumFast(r, e);
}

friend constexpr auto operator+=(Double& lhs, Double rhs) noexcept -> Double& {
Expand All @@ -98,6 +104,8 @@ struct Double {
return lhs;
}

friend constexpr auto operator==(Double lhs, Double rhs) noexcept -> bool = default;

private:
[[nodiscard]] static constexpr auto split(Real a) noexcept -> Double {
constexpr auto const digits = FloatTraits<Real>::digits;
Expand All @@ -121,7 +129,7 @@ struct Double {
return Double{r, e};
}

[[nodiscard]] static constexpr auto twoSumQuick(Real x, Real y) noexcept -> Double {
[[nodiscard]] static constexpr auto twoSumFast(Real x, Real y) noexcept -> Double {
auto r = x + y;
auto e = y - (r - x);
return Double{r, e};
Expand Down
8 changes: 8 additions & 0 deletions src/cpp/pffdtd/sycl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

#pragma once

#include "pffdtd/float.hpp"
#include "pffdtd/time.hpp"

#if not defined(PFFDTD_HAS_SYCL)
Expand All @@ -27,4 +28,11 @@ template<typename Accessor>
auto toString(sycl::info::device_type type) -> std::string;
auto summary(sycl::device const& dev) -> void;

template<>
struct FloatTraits<sycl::half> {
static constexpr auto digits = 11;
static constexpr auto minExponent = -13;
static constexpr auto maxExponent = 16;
};

} // namespace pffdtd

0 comments on commit 457f950

Please sign in to comment.