Skip to content

Commit

Permalink
remove recursion in sinus range reduction -- should be faster on GPU
Browse files Browse the repository at this point in the history
  • Loading branch information
JeWaVe committed Nov 5, 2024
1 parent 83b7f81 commit b57d080
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 41 deletions.
77 changes: 39 additions & 38 deletions src/aerobus.h
Original file line number Diff line number Diff line change
Expand Up @@ -4567,7 +4567,7 @@ namespace aerobus {
bool return_x = false;
bool return_fast_sin = false;
bool return_fast_cos = false;
upper_type transform = u_constants::zero;
upper_type transform = u_constants::zero();
};

static constexpr upper_type d_pi = constants::pi();
Expand All @@ -4576,45 +4576,46 @@ namespace aerobus {
static constexpr upper_type pi_2 = u_constants::pi_2();
static constexpr upper_type pi_4 = u_constants::pi_4();

// TODO(JeWaVe) : remove recursion
static DEVICE behavior eval(upper_type u_x, T x) {
::printf("entering eval with %.12F\n", u_x);
const upper_type u_eps = std::numeric_limits<upper_type>::epsilon();
const T eps = std::numeric_limits<T>::epsilon();
if (x <= eps && x >= -eps) {
return {
.return_x = true,
.transform = u_x
};
} else if (x < -eps) {
auto red = eval(-u_x, -x);
red.negate = !red.negate;
return red;
} else if (u_x < pi_4) {
return {
.return_fast_sin = true,
.transform = u_x
};
} else if (u_x < pi_2) {
return {
.return_fast_cos = true,
.transform = pi_2 - u_x
};
} else if (x < d_pi - eps) {
return eval(pi - u_x, static_cast<T>(pi - u_x));
} else if (x < d_pi + eps) {
return {
.negate = true,
.return_x = true,
.transform = u_x - pi
};
} else if (u_x < two_pi) {
auto result = eval(two_pi - u_x, static_cast<T>(two_pi - u_x));
result.negate = !result.negate;
return result;
} else {
upper_type red = aerobus::meta_libm<upper_type>::fmod(u_x, u_constants::two_pi());
return eval(red, static_cast<T>(red));
behavior result {};
while (true) {
if (x <= eps && x >= -eps) {
result.return_x = true;
result.transform = u_x;
return result;
} else if (x < -eps) {
u_x = -u_x;
x = -x;
result.negate = !result.negate;
continue;
} else if (u_x < pi_4) {
result.return_fast_sin = true;
result.transform = u_x;
return result;
} else if (u_x < pi_2) {
result.return_fast_cos = true;
result.transform = pi_2 - u_x;
return result;
} else if (x < d_pi - eps) {
u_x = pi - u_x;
x = static_cast<T>(u_x);
continue;
} else if (x < d_pi + eps) {
result.negate = true;
result.return_x = true;
result.transform = u_x - pi;
return result;
} else if (u_x < two_pi) {
u_x = two_pi - u_x;
x = static_cast<T>(u_x);
result.negate = !result.negate;
continue;
} else {
u_x = aerobus::meta_libm<upper_type>::fmod(u_x, u_constants::two_pi());
x = static_cast<T>(u_x);
continue;
}
}
}
};
Expand Down
6 changes: 3 additions & 3 deletions src/lib_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1243,9 +1243,9 @@ TEST(libm, sin) {
float aero = aerobus::libm::sin(x);
float expected = std::sin(x);
// uncomment to see small differences (usually 1E-24)
EXPECT_EQ(aero, expected) <<
std::hexfloat << "input : " << x << " expected : " << expected << " computed " << aero <<
std::endl << " difference is : " << aero - expected << std::endl;
// EXPECT_EQ(aero, expected) <<
// std::hexfloat << "input : " << x << " expected : " << expected << " computed " << aero <<
// std::endl << " difference is : " << aero - expected << std::endl;
EXPECT_TRUE((std::fabs(expected - aero) < std::numeric_limits<float>::epsilon())) << "aerobus::sin(" << x << ")"
<< " computed : " << std::hexfloat << aero << " but should " << expected << std::endl
<< "difference is : " << std::fabs(aero - expected) << std::endl;
Expand Down

0 comments on commit b57d080

Please sign in to comment.