Skip to content

Commit 7bb9c40

Browse files
committed
make tests exaustive
1 parent 7a8db3f commit 7bb9c40

File tree

1 file changed

+51
-94
lines changed

1 file changed

+51
-94
lines changed

libc/test/src/math/powf16_test.cpp

Lines changed: 51 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -12,107 +12,64 @@
1212
#include "utils/MPFRWrapper/MPFRUtils.h"
1313

1414
using LlvmLibcPowF16Test = LIBC_NAMESPACE::testing::FPTest<float16>;
15-
using LIBC_NAMESPACE::testing::tlog;
1615

1716
namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
1817

19-
TEST_F(LlvmLibcPowF16Test, TrickyInputs) {
20-
// These values are in half precision.
21-
constexpr mpfr::BinaryInput<float16> INPUTS[] = {
22-
{static_cast<float16>(0x1.08p-2f), static_cast<float16>(0x1.0cp-1f)},
23-
{static_cast<float16>(0x1.66p-1f), static_cast<float16>(0x1.f1p+1f)},
24-
{static_cast<float16>(0x1.c04p-1f), static_cast<float16>(0x1.2p+12f)},
25-
{static_cast<float16>(0x1.aep-1f), static_cast<float16>(0x1.f9p-1f)},
26-
{static_cast<float16>(0x1.ffcp-1f), static_cast<float16>(0x1.fffp-2f)},
27-
{static_cast<float16>(0x1.f55p-1f), static_cast<float16>(0x1.88p+12f)},
28-
{static_cast<float16>(0x1.e84p-1f), static_cast<float16>(0x1.2cp+13f)},
29-
};
30-
31-
for (auto input : INPUTS) {
32-
float16 x = input.x;
33-
float16 y = input.y;
34-
EXPECT_MPFR_MATCH(mpfr::Operation::Pow, input, LIBC_NAMESPACE::powf16(x, y),
35-
1.0); // 1 ULP tolerance is enough for f16
18+
static constexpr float16 SELECTED_VALS[] = {
19+
0.5f16, 0.83984375f16, 1.0f16, 2.0f16, 3.0f16, 3.140625f16, 15.5f16,
20+
};
21+
22+
// Test selected x values against all possible y values.
23+
TEST_F(LlvmLibcPowF16Test, SelectedX_AllY) {
24+
for (size_t i = 0; i < sizeof(SELECTED_VALS) / sizeof(SELECTED_VALS[0]);
25+
++i) {
26+
float16 x = SELECTED_VALS[i];
27+
for (uint16_t y_u = 0; y_u <= 0x7c00U; ++y_u) {
28+
float16 y = FPBits(y_u).get_val();
29+
30+
mpfr::BinaryInput<float16> input{x, y};
31+
float16 result = LIBC_NAMESPACE::powf16(x, y);
32+
EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Pow, input, result, 1.0);
33+
34+
// If the result is infinity and we expect it to continue growing, we can
35+
// terminate the loop early.
36+
if (FPBits(result).is_inf() && FPBits(result).is_pos()) {
37+
// For x > 1, as y increases in the positive range, pow remains inf.
38+
if (x > static_cast<float16>(1.0f) && y > static_cast<float16>(0.0f)) {
39+
// The y_u loop covers the positive range up to 0x7BFF.
40+
break;
41+
}
42+
// For 0 < x < 1, as y becomes more negative, pow becomes inf.
43+
if (x > static_cast<float16>(0.0f) && x < static_cast<float16>(1.0f) &&
44+
y < static_cast<float16>(0.0f)) {
45+
// The y_u loop covers the negative range from 0x8000.
46+
break;
47+
}
48+
}
49+
}
3650
}
3751
}
3852

39-
TEST_F(LlvmLibcPowF16Test, InFloat16Range) {
40-
constexpr uint16_t X_COUNT = 63;
41-
constexpr uint16_t X_START = FPBits(static_cast<float16>(0.25)).uintval();
42-
constexpr uint16_t X_STOP = FPBits(static_cast<float16>(4.0)).uintval();
43-
constexpr uint16_t X_STEP = (X_STOP - X_START) / X_COUNT;
44-
45-
constexpr uint16_t Y_COUNT = 59;
46-
constexpr uint16_t Y_START = FPBits(static_cast<float16>(0.25)).uintval();
47-
constexpr uint16_t Y_STOP = FPBits(static_cast<float16>(4.0)).uintval();
48-
constexpr uint16_t Y_STEP = (Y_STOP - Y_START) / Y_COUNT;
49-
50-
auto test = [&](mpfr::RoundingMode rounding_mode) {
51-
mpfr::ForceRoundingMode __r(rounding_mode);
52-
if (!__r.success)
53-
return;
54-
55-
uint64_t fails = 0;
56-
uint64_t count = 0;
57-
uint64_t cc = 0;
58-
float16 mx = 0.0, my = 0.0, mr = 0.0;
59-
double tol = 1.0; // start with 1 ULP for half precision
60-
61-
for (uint16_t i = 0, v = X_START; i <= X_COUNT; ++i, v += X_STEP) {
62-
float16 x = FPBits(v).get_val();
63-
if (FPBits(x).is_inf_or_nan() || x < static_cast<float16>(0.0))
64-
continue;
65-
66-
for (uint16_t j = 0, w = Y_START; j <= Y_COUNT; ++j, w += Y_STEP) {
67-
float16 y = FPBits(w).get_val();
68-
if (FPBits(y).is_inf_or_nan())
69-
continue;
70-
71-
float16 result = LIBC_NAMESPACE::powf16(x, y);
72-
++cc;
73-
if (FPBits(result).is_inf_or_nan())
74-
continue;
75-
76-
++count;
77-
mpfr::BinaryInput<float16> inputs{x, y};
78-
79-
if (!TEST_MPFR_MATCH_ROUNDING_SILENTLY(mpfr::Operation::Pow, inputs,
80-
result, 1.0, rounding_mode)) {
81-
++fails;
82-
while (!TEST_MPFR_MATCH_ROUNDING_SILENTLY(
83-
mpfr::Operation::Pow, inputs, result, tol, rounding_mode)) {
84-
mx = x;
85-
my = y;
86-
mr = result;
87-
88-
if (tol > 128.0) // half precision is only ~11 bits
89-
break;
90-
91-
tol *= 2.0;
92-
}
53+
// Test selected y values against all possible x values.
54+
TEST_F(LlvmLibcPowF16Test, SelectedY_AllX) {
55+
for (size_t i = 0; i < sizeof(SELECTED_VALS) / sizeof(SELECTED_VALS[0]);
56+
++i) {
57+
float16 y = SELECTED_VALS[i];
58+
for (uint16_t x_u = 0; x_u <= 0x7c00U; ++x_u) {
59+
float16 x = FPBits(x_u).get_val();
60+
mpfr::BinaryInput<float16> input{x, y};
61+
float16 result = LIBC_NAMESPACE::powf16(x, y);
62+
EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Pow, input, result, 1.0);
63+
64+
// If the result is infinity and we expect it to continue growing, we can
65+
// terminate the loop early.
66+
if (FPBits(result).is_inf() && FPBits(result).is_pos()) {
67+
// For y > 0, as x increases in the positive range, pow remains inf.
68+
if (y > 0.0f16 && x > 0.0f16) {
69+
// The x_u loop covers the positive range up to 0x7BFF.
70+
break;
9371
}
9472
}
9573
}
96-
if (fails || (count < cc)) {
97-
tlog << " powf16 failed: " << fails << "/" << count << "/" << cc
98-
<< " tests.\n"
99-
<< " Max ULPs is at most: " << static_cast<uint64_t>(tol) << ".\n";
100-
}
101-
if (fails) {
102-
mpfr::BinaryInput<float16> inputs{mx, my};
103-
EXPECT_MPFR_MATCH(mpfr::Operation::Pow, inputs, mr, 1.0, rounding_mode);
104-
}
105-
};
106-
107-
tlog << " Test Rounding To Nearest...\n";
108-
test(mpfr::RoundingMode::Nearest);
109-
110-
tlog << " Test Rounding Downward...\n";
111-
test(mpfr::RoundingMode::Downward);
112-
113-
tlog << " Test Rounding Upward...\n";
114-
test(mpfr::RoundingMode::Upward);
115-
116-
tlog << " Test Rounding Toward Zero...\n";
117-
test(mpfr::RoundingMode::TowardZero);
74+
}
11875
}

0 commit comments

Comments
 (0)