From 8066b2d0599b994daf17141a31b82f4c2a866a70 Mon Sep 17 00:00:00 2001 From: Vladyslav Baranovskyi Date: Tue, 5 Nov 2024 21:42:39 +0200 Subject: [PATCH] Tests for float16 --- tests/Math/Float16.cpp | 139 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 139 insertions(+) create mode 100644 tests/Math/Float16.cpp diff --git a/tests/Math/Float16.cpp b/tests/Math/Float16.cpp new file mode 100644 index 0000000..a5f750d --- /dev/null +++ b/tests/Math/Float16.cpp @@ -0,0 +1,139 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ + +#include + +#include +#include + +#include "Math/Float16.hpp" + +// using namespace OpenVulkano::Math; + +namespace +{ + bool almostEqual(float a, float b, float epsilon = 0.001f) { return std::fabs(a - b) < epsilon; } +} + +TEST_CASE("Basic Conversions", "[float16]") +{ + REQUIRE(almostEqual(static_cast(fp16(0.0f)), 0.0f)); + REQUIRE(almostEqual(static_cast(fp16(-0.0f)), -0.0f)); + REQUIRE(almostEqual(static_cast(fp16(1.0f)), 1.0f)); + REQUIRE(almostEqual(static_cast(fp16(-1.0f)), -1.0f)); + REQUIRE(almostEqual(static_cast(fp16(0.5f)), 0.5f)); + REQUIRE(almostEqual(static_cast(fp16(-0.5f)), -0.5f)); + REQUIRE(almostEqual(static_cast(fp16(65504.0f)), 65504.0f)); + REQUIRE(almostEqual(static_cast(fp16(-65504.0f)), -65504.0f)); +} + +TEST_CASE("Infinity and NaN", "[float16]") +{ + fp16 pos_inf = std::numeric_limits::infinity(); + fp16 neg_inf = -std::numeric_limits::infinity(); + fp16 nan_val = std::numeric_limits::quiet_NaN(); + + REQUIRE(std::isinf(static_cast(pos_inf))); + REQUIRE(std::isinf(static_cast(neg_inf))); + REQUIRE(std::isnan(static_cast(nan_val))); + REQUIRE(pos_inf > fp16(65504.0f)); + REQUIRE(neg_inf < fp16(-65504.0f)); +} + +TEST_CASE("Denormalized Values", "[float16]") +{ + fp16 min_denorm = std::numeric_limits::denorm_min(); + REQUIRE(almostEqual(static_cast(min_denorm), 5.96e-8f)); + + fp16 denorm_value(1.0e-5f); + REQUIRE(almostEqual(static_cast(denorm_value), 0.0f)); +} + +TEST_CASE("Special Cases", "[float16]") +{ + fp16 zero(0.0f), neg_zero(-0.0f), epsilon_fp(std::numeric_limits::epsilon()); + fp16 min_normal(std::numeric_limits::min()); + fp16 max_fp(std::numeric_limits::max()); + + REQUIRE(almostEqual(static_cast(zero), 0.0f)); + REQUIRE(almostEqual(static_cast(neg_zero), 0.0f)); + REQUIRE(almostEqual(static_cast(epsilon_fp), 0.00097656f)); + REQUIRE(almostEqual(static_cast(min_normal), 6.10352e-5f)); + REQUIRE(almostEqual(static_cast(max_fp), 65504.0f)); +} + +TEST_CASE("Arithmetic Operations", "[float16]") +{ + fp16 a(1.0f), b(2.0f), c(3.0f), d(4.0f), large(65504.0f), small(0.5f); + + REQUIRE(almostEqual(static_cast(a + b), 3.0f)); + REQUIRE(almostEqual(static_cast(b - a), 1.0f)); + REQUIRE(almostEqual(static_cast(a * b), 2.0f)); + REQUIRE(almostEqual(static_cast(d / c), 1.33333f)); + REQUIRE(almostEqual(static_cast(large * small), 32752.0f)); + + REQUIRE(std::isinf(static_cast(large + large))); + REQUIRE(almostEqual(static_cast(a - a), 0.0f)); +} + +TEST_CASE("Comparisons", "[float16]") +{ + fp16 a(1.0f), b(2.0f), zero(0.0f), neg(-1.0f), inf = std::numeric_limits::infinity(); + + REQUIRE(a < b); + REQUIRE(b > a); + REQUIRE(zero == -zero); + REQUIRE(a != neg); + REQUIRE(inf > b); + REQUIRE(!(inf < b)); +} + +TEST_CASE("Arithmetic with Special Values", "[float16]") +{ + fp16 a(2.0f), inf = std::numeric_limits::infinity(), nan = std::numeric_limits::quiet_NaN(); + + REQUIRE(std::isinf(static_cast(a + inf))); + REQUIRE(std::isinf(static_cast(inf - a))); + REQUIRE(std::isnan(static_cast(inf - inf))); + REQUIRE(std::isnan(static_cast(inf / inf))); + + REQUIRE(std::isnan(static_cast(nan + a))); + REQUIRE(std::isnan(static_cast(nan - a))); + REQUIRE(std::isnan(static_cast(a * nan))); + REQUIRE(std::isnan(static_cast(a / nan))); +} + +TEST_CASE("Boundary Tests", "[float16]") +{ + fp16 near_min(6.10352e-5f), near_max(65504.0f), tiny_pos(1.0e-8f), tiny_neg(-1.0e-8f); + + REQUIRE(almostEqual(static_cast(near_min), 6.10352e-5f)); + REQUIRE(almostEqual(static_cast(near_max), 65504.0f)); + REQUIRE(almostEqual(static_cast(tiny_pos), 0.0f)); + REQUIRE(almostEqual(static_cast(tiny_neg), 0.0f)); +} + +TEST_CASE("Edge Case Conversions", "[float16]") +{ + fp16 max_convertible_fp(65504.0f), too_large(70000.0f), too_small(1.0e-8f); + + REQUIRE(almostEqual(static_cast(max_convertible_fp), 65504.0f)); + REQUIRE(std::isinf(static_cast(too_large))); + REQUIRE(almostEqual(static_cast(too_small), 0.0f)); +} + +TEST_CASE("Special Comparison with Infinity and NaN", "[float16]") +{ + fp16 inf = std::numeric_limits::infinity(); + fp16 neg_inf = -std::numeric_limits::infinity(); + fp16 nan = std::numeric_limits::quiet_NaN(); + fp16 one(1.0f); + + REQUIRE(inf > one); + REQUIRE(neg_inf < -one); + REQUIRE(std::isnan(static_cast(nan))); + REQUIRE(nan != nan); +} \ No newline at end of file