Skip to content

Commit afba4e7

Browse files
committed
cbrt cos/d/h/pi
1 parent 0e060cf commit afba4e7

File tree

13 files changed

+137
-113
lines changed

13 files changed

+137
-113
lines changed

include/eve/module/math/regular/cbrt.hpp

Lines changed: 37 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -74,40 +74,45 @@ namespace eve
7474
namespace detail
7575
{
7676
template<eve::floating_value T, callable_options O>
77-
EVE_FORCEINLINE constexpr auto cbrt_(EVE_REQUIRES(cpu_), O const& , T x) noexcept
77+
EVE_FORCEINLINE constexpr auto cbrt_(EVE_REQUIRES(cpu_), O const& o, T x) noexcept
7878
{
79-
using vt_t = element_type_t<T>;
80-
auto test0 = is_eqz(x) || is_not_finite(x);
81-
if constexpr( eve::scalar_value<T> )
82-
if( test0 ) return x;
83-
constexpr vt_t factor[5] = {0.6299605249474365823836,
84-
0.793700525984099737376,
85-
1.0,
86-
1.2599210498948731647672,
87-
1.587401051968199474751};
88-
auto ax = eve::abs(x);
89-
auto test = is_less(eve::abs(x), T(100) * smallestposval(eve::as<T>()));
90-
ax = ldexp[test](ax, 54);
91-
/* Reduce x. xm now is an range [0.5, 1.0]. */
92-
auto [xm, xe] = ifrexp[raw](ax);
93-
T u;
94-
if constexpr( std::is_same_v<vt_t, double> )
95-
u = eve::reverse_horner(xm, T(0x1.6b69cba168ff2p-2), T(0x1.8218dde9028b4p+0), T(-0x1.0eb8277cd8d5dp+1)
96-
, T(0x1.39350adad51ecp+1), T(-0x1.d5ae6cfa20f0cp+0)
97-
, T(0x1.91e2a6fe7e984p-1), T(-0x1.29801e893366dp-3));
98-
else if constexpr( std::is_same_v<vt_t, float> )
99-
u = eve::reverse_horner(xm, T(0x1.f87bc4p-2f), T(0x1.6527f4p-1f), T(-0x1.88324ap-3f));
100-
auto t2 = sqr(u) * u;
101-
u *= fma(xm, T(2), t2) / fma(T(2), t2, xm);
79+
if constexpr(std::same_as<eve::element_type_t<T>, eve::float16_t>)
80+
return eve::detail::apply_fp16_as_fp32(eve::cbrt[o], x);
81+
else
82+
{
83+
using vt_t = element_type_t<T>;
84+
auto test0 = is_eqz(x) || is_not_finite(x);
85+
if constexpr( eve::scalar_value<T> )
86+
if( test0 ) return x;
87+
constexpr vt_t factor[5] = {0.6299605249474365823836,
88+
0.793700525984099737376,
89+
1.0,
90+
1.2599210498948731647672,
91+
1.587401051968199474751};
92+
auto ax = eve::abs(x);
93+
auto test = is_less(eve::abs(x), T(100) * smallestposval(eve::as<T>()));
94+
ax = ldexp[test](ax, 54);
95+
/* Reduce x. xm now is an range [0.5, 1.0]. */
96+
auto [xm, xe] = ifrexp[raw](ax);
97+
T u;
98+
if constexpr( std::is_same_v<vt_t, double> )
99+
u = eve::reverse_horner(xm, T(0x1.6b69cba168ff2p-2), T(0x1.8218dde9028b4p+0), T(-0x1.0eb8277cd8d5dp+1)
100+
, T(0x1.39350adad51ecp+1), T(-0x1.d5ae6cfa20f0cp+0)
101+
, T(0x1.91e2a6fe7e984p-1), T(-0x1.29801e893366dp-3));
102+
else if constexpr( std::is_same_v<vt_t, float> )
103+
u = eve::reverse_horner(xm, T(0x1.f87bc4p-2f), T(0x1.6527f4p-1f), T(-0x1.88324ap-3f));
104+
auto t2 = sqr(u) * u;
105+
u *= fma(xm, T(2), t2) / fma(T(2), t2, xm);
102106

103-
if constexpr( eve::scalar_value<T> ) u *= factor[2 + xe % 3];
104-
else u *= gather(&factor[0], 2 + xe - (xe / 3) * 3);
105-
u = minus[is_ltz(x)](u);
106-
if constexpr( eve::scalar_value<T> ) xe = add[test](int(xe) / 3, -18);
107-
else xe = add[test](xe / 3, -18);
108-
auto z = ldexp(u, xe);
109-
if constexpr( eve::scalar_value<T> ) return z;
110-
else return if_else(test0, x, z);
107+
if constexpr( eve::scalar_value<T> ) u *= factor[2 + xe % 3];
108+
else u *= gather(&factor[0], 2 + xe - (xe / 3) * 3);
109+
u = minus[is_ltz(x)](u);
110+
if constexpr( eve::scalar_value<T> ) xe = add[test](int(xe) / 3, -18);
111+
else xe = add[test](xe / 3, -18);
112+
auto z = ldexp(u, xe);
113+
if constexpr( eve::scalar_value<T> ) return z;
114+
else return if_else(test0, x, z);
115+
}
111116
}
112117
}
113118
}

include/eve/module/math/regular/cos.hpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,9 @@ namespace eve
9999
template<typename T, callable_options O>
100100
constexpr EVE_FORCEINLINE T cos_(EVE_REQUIRES(cpu_), O const& o , T const& a0)
101101
{
102-
if constexpr(O::contains(quarter_circle))
102+
if constexpr(std::same_as<eve::element_type_t<T>, eve::float16_t>)
103+
return eve::detail::apply_fp16_as_fp32(eve::cos[o], a0);
104+
else if constexpr(O::contains(quarter_circle))
103105
{
104106
auto x2 = sqr(a0);
105107
auto x2nlepi2_16 = is_not_less_equal(x2, pi2o_16[upper](as(a0)));

include/eve/module/math/regular/cosd.hpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,9 +85,11 @@ namespace eve
8585
namespace detail
8686
{
8787
template<typename T, callable_options O>
88-
constexpr EVE_FORCEINLINE T cosd_(EVE_REQUIRES(cpu_), O const&, T const& a0)
88+
constexpr EVE_FORCEINLINE T cosd_(EVE_REQUIRES(cpu_), O const& o, T const& a0)
8989
{
90-
if constexpr(O::contains(quarter_circle))
90+
if constexpr(std::same_as<eve::element_type_t<T>, eve::float16_t>)
91+
return eve::detail::apply_fp16_as_fp32(eve::cosd[o], a0);
92+
else if constexpr(O::contains(quarter_circle))
9193
{
9294
return eve::cospi[quarter_circle](div_180(a0));
9395
}

include/eve/module/math/regular/cosh.hpp

Lines changed: 33 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -83,47 +83,51 @@ namespace eve
8383
namespace detail
8484
{
8585
template<typename T, callable_options O>
86-
constexpr EVE_FORCEINLINE T cosh_(EVE_REQUIRES(cpu_), O const&, T const& a0)
86+
constexpr EVE_FORCEINLINE T cosh_(EVE_REQUIRES(cpu_), O const& o, T const& a0)
8787
{
88-
//////////////////////////////////////////////////////////////////////////////
88+
if constexpr( scalar_value<T> )
89+
{
90+
if( is_eqz(a0) ) return one(eve::as(a0));
91+
} //////////////////////////////////////////////////////////////////////////////
8992
// if x = abs(a0) according x < Threshold e = exp(x) or exp(x/2) is
9093
// respectively computed
9194
// * in the first case cosh (e+rec[pedantic](e))/2
9295
// * in the second cosh is (e/2)*e (avoiding undue overflow)
9396
// Threshold is maxlog - Log_2
9497
//////////////////////////////////////////////////////////////////////////////
95-
if constexpr( scalar_value<T> )
96-
{
97-
if( is_eqz(a0) ) return one(eve::as(a0));
98-
}
99-
T ovflimitmln2 = maxlog(as(a0))-log_2(as(a0));
100-
auto x = eve::abs(a0);
101-
if constexpr( scalar_value<T> )
98+
if constexpr(std::same_as<eve::element_type_t<T>, eve::float16_t>)
99+
return eve::detail::apply_fp16_as_fp32(eve::cosh[o], a0);
100+
else
102101
{
103-
if(is_not_finite(x)) return x;
104-
else if( x >= ovflimitmln2 )
102+
T ovflimitmln2 = maxlog(as(a0))-log_2(as(a0));
103+
auto x = eve::abs(a0);
104+
if constexpr( scalar_value<T> )
105+
{
106+
if(is_not_finite(x)) return x;
107+
else if( x >= ovflimitmln2 )
108+
{
109+
auto w = exp(x * half(eve::as<T>()));
110+
auto t = half(eve::as<T>()) * w;
111+
t *= w;
112+
return t;
113+
}
114+
auto t = exp(x);
115+
return (x > 22) ? t * half(eve::as<T>()) : average(t, rec[pedantic](t));
116+
}
117+
else
105118
{
119+
auto t = exp(x);
120+
auto invt = if_else(x > 22, eve::zero, rec[pedantic](t));
121+
auto c = average(t, invt);
122+
auto test = x < ovflimitmln2;
123+
if( eve::all(test) ) return c;
106124
auto w = exp(x * half(eve::as<T>()));
107-
auto t = half(eve::as<T>()) * w;
125+
t = half(eve::as<T>()) * w;
108126
t *= w;
109-
return t;
110-
}
111-
auto t = exp(x);
112-
return (x > 22) ? t * half(eve::as<T>()) : average(t, rec[pedantic](t));
113-
}
114-
else
115-
{
116-
auto t = exp(x);
117-
auto invt = if_else(x > 22, eve::zero, rec[pedantic](t));
118-
auto c = average(t, invt);
119-
auto test = x < ovflimitmln2;
120-
if( eve::all(test) ) return c;
121-
auto w = exp(x * half(eve::as<T>()));
122-
t = half(eve::as<T>()) * w;
123-
t *= w;
124127

125-
c = if_else(test, c, t);
126-
return c;
128+
c = if_else(test, c, t);
129+
return c;
130+
}
127131
}
128132
}
129133
}

include/eve/module/math/regular/cospi.hpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,9 +86,11 @@ namespace eve
8686
namespace detail
8787
{
8888
template<typename T, callable_options O>
89-
constexpr EVE_FORCEINLINE T cospi_(EVE_REQUIRES(cpu_), O const&, T const& a0)
89+
constexpr EVE_FORCEINLINE T cospi_(EVE_REQUIRES(cpu_), O const& o, T const& a0)
9090
{
91-
if constexpr(O::contains(quarter_circle))
91+
if constexpr(std::same_as<eve::element_type_t<T>, eve::float16_t>)
92+
return eve::detail::apply_fp16_as_fp32(eve::cospi[o], a0);
93+
else if constexpr(O::contains(quarter_circle))
9294
{
9395
return eve::cos[quarter_circle](a0*pi(eve::as<T>()));
9496
}

test/std_proxy.hpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,11 @@ MAKE_STD_PROXY(abs);
3232
MAKE_STD_PROXY(acos);
3333
MAKE_STD_PROXY(acosh);
3434
MAKE_STD_PROXY(atan);
35+
MAKE_STD_PROXY(atanh);
36+
MAKE_STD_PROXY(cbrt);
3537
MAKE_STD_PROXY(ceil);
38+
MAKE_STD_PROXY(cos);
39+
MAKE_STD_PROXY(cosh);
3640
MAKE_STD_PROXY(exp);
3741
MAKE_STD_PROXY(exp2);
3842
MAKE_STD_PROXY(expm1);
@@ -42,7 +46,9 @@ MAKE_STD_PROXY(log1p);
4246
MAKE_STD_PROXY(log2);
4347
MAKE_STD_PROXY(log10);
4448
MAKE_STD_PROXY(nearbyint);
49+
MAKE_STD_PROXY(sin);
4550
MAKE_STD_PROXY(sqrt);
51+
MAKE_STD_PROXY(tan);
4652
MAKE_STD_PROXY(trunc);
4753

4854
#undef MAKE_STD_PROXY

test/unit/module/math/agd.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
**/
77
//==================================================================================================
88
#include "test.hpp"
9-
9+
#include "std_proxy.hpp"
1010
#include <eve/module/core.hpp>
1111
#include <eve/module/math.hpp>
1212

@@ -15,7 +15,7 @@
1515
//==================================================================================================
1616
// Types tests
1717
//==================================================================================================
18-
TTS_CASE_TPL("Check return types of agd", eve::test::simd::ieee_reals)
18+
TTS_CASE_TPL("Check return types of agd", eve::test::simd::ieee_reals_wf16)
1919
<typename T>(tts::type<T>)
2020
{
2121
using v_t = eve::element_type_t<T>;
@@ -31,22 +31,22 @@ auto maxi = ::tts::constant([]<typename T>(eve::as<T> const& tgt) { return eve::
3131
auto mini = ::tts::constant([]<typename T>(eve::as<T> const& tgt) { return -eve::pio_2(tgt); });
3232

3333
TTS_CASE_WITH("Check behavior of agd on wide",
34-
eve::test::simd::ieee_reals,
34+
eve::test::simd::ieee_reals_wf16,
3535
tts::generate(tts::randoms(mini, maxi), tts::randoms(-1.0, 1.0)))
3636
<typename T>(T const& a0, T const& a1)
3737
{
3838
using v_t = eve::element_type_t<T>;
3939
using eve::agd;
40-
TTS_ULP_EQUAL(agd(a0), tts::map([](auto e) -> v_t { return 2*std::atanh(std::tan(e*eve::half(eve::as(e)))); }, a0), 27.5);
41-
TTS_ULP_EQUAL(agd(a1), tts::map([](auto e) -> v_t { return 2*std::atanh(std::tan(e*eve::half(eve::as(e)))); }, a1), 8.0);
40+
TTS_ULP_EQUAL(agd(a0), tts::map([](auto e) -> v_t { return static_cast<v_t>(2*std_atanh(std_tan(e*eve::half(eve::as(e))))); }, a0), 27.5);
41+
TTS_ULP_EQUAL(agd(a1), tts::map([](auto e) -> v_t { return static_cast<v_t>(2*std_atanh(std_tan(e*eve::half(eve::as(e))))); }, a1), 8.0);
4242
};
4343

4444

4545
//==================================================================================================
4646
// Tests for masked agd
4747
//==================================================================================================
4848
TTS_CASE_WITH("Check behavior of eve::agd[cx](eve::wide)",
49-
eve::test::simd::ieee_reals,
49+
eve::test::simd::ieee_reals_wf16,
5050
tts::generate(tts::randoms(eve::valmin, eve::valmax),
5151
tts::logicals(0, 3)))
5252
<typename T, typename M>(T const& a0,

test/unit/module/math/arg.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
**/
77
//==================================================================================================
88
#include "test.hpp"
9-
9+
#include "std_proxy.hpp"
1010
#include <eve/module/core.hpp>
1111
#include <eve/module/math.hpp>
1212

@@ -15,7 +15,7 @@
1515
//==================================================================================================
1616
// Types tests
1717
//==================================================================================================
18-
TTS_CASE_TPL("Check return types of eve::arg(simd)", eve::test::simd::ieee_reals)
18+
TTS_CASE_TPL("Check return types of eve::arg(simd)", eve::test::simd::ieee_reals_wf16)
1919
<typename T>(tts::type<T>)
2020
{
2121
using v_t = eve::element_type_t<T>;
@@ -30,7 +30,7 @@ TTS_CASE_TPL("Check return types of eve::arg(simd)", eve::test::simd::ieee_reals
3030
// Tests for eve::arg
3131
//==================================================================================================
3232
TTS_CASE_WITH("Check behavior of eve::arg(simd)",
33-
eve::test::simd::ieee_reals,
33+
eve::test::simd::ieee_reals_wf16,
3434
tts::generate(tts::between(-1.0, 1.0)))
3535
<typename T>(T const& a0)
3636
{
@@ -44,7 +44,7 @@ TTS_CASE_WITH("Check behavior of eve::arg(simd)",
4444
// Tests for eve::arg[eve::pedantic]
4545
//==================================================================================================
4646
TTS_CASE_WITH("Check behavior of eve::arg[eve::pedantic](simd)",
47-
eve::test::simd::ieee_reals,
47+
eve::test::simd::ieee_reals_wf16,
4848
tts::generate(tts::between(-1.0, 1.0)))
4949
<typename T>(T a0)
5050
{

test/unit/module/math/cbrt.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
**/
77
//==================================================================================================
88
#include "test.hpp"
9-
9+
#include "std_proxy.hpp"
1010
#include <eve/module/core.hpp>
1111
#include <eve/module/math.hpp>
1212

@@ -15,7 +15,7 @@
1515
//==================================================================================================
1616
// Types tests
1717
//==================================================================================================
18-
TTS_CASE_TPL("Check return types of cbrt", eve::test::simd::ieee_reals)
18+
TTS_CASE_TPL("Check return types of cbrt", eve::test::simd::ieee_reals_wf16)
1919
<typename T>(tts::type<T>)
2020
{
2121
using v_t = eve::element_type_t<T>;
@@ -28,21 +28,21 @@ TTS_CASE_TPL("Check return types of cbrt", eve::test::simd::ieee_reals)
2828
// cbrt tests
2929
//==================================================================================================
3030
TTS_CASE_WITH("Check behavior of cbrt on wide",
31-
eve::test::simd::ieee_reals,
31+
eve::test::simd::ieee_reals_wf16,
3232
tts::generate(tts::randoms(eve::valmin, eve::valmax)))
3333
<typename T>(T const& a0)
3434
{
3535
using v_t = eve::element_type_t<T>;
3636

37-
TTS_ULP_EQUAL(eve::cbrt(a0), tts::map([](auto e) -> v_t { return std::cbrt(e); }, a0), 2);
37+
TTS_ULP_EQUAL(eve::cbrt(a0), tts::map([](auto e) -> v_t { return static_cast<v_t>(std_cbrt(e)); }, a0), 2);
3838
};
3939

4040

4141
//==================================================================================================
4242
// Tests for masked cbrt
4343
//==================================================================================================
4444
TTS_CASE_WITH("Check behavior of eve::masked(eve::cbrt)(eve::wide)",
45-
eve::test::simd::ieee_reals,
45+
eve::test::simd::ieee_reals_wf16,
4646
tts::generate(tts::randoms(eve::valmin, eve::valmax),
4747
tts::logicals(0, 3)))
4848
<typename T, typename M>(T const& a0,

0 commit comments

Comments
 (0)