native 0.0.1
Vectors, masks and wide register packs for C++26
Loading...
Searching...
No Matches
exp_body.h
Go to the documentation of this file.
1
2namespace NATIVE_BACKEND_NAMESPACE::native {
3 // Compatibility entry points share the promoted pack graph.
4 template<bool Flush = false, unsigned Degree = 6, float_register V, std::size_t N>
5 requires (Degree >= 1 && Degree <= 7)
6 native_nodiscard native_flatten native_inline constexpr native_pure std::array<V, N> exp(std::array<V, N> const & input) noexcept {
7 if constexpr (N == 0) return input;
8 else {
9 auto const [masks, replacements, values, exponents] =
10 ::math::detail::exp_reduced<Flush, Degree>(::wide::promote(input));
11 auto const & [...in_range] = masks;
12 auto const & [...replacement] = replacements;
13 auto const & [...y] = values;
14 auto const & [...n] = exponents;
15 // Finish in this entry's target scope: the generic scaling bridge can
16 // exceed Clang's inline-cost budget for AVX-512 without VL.
17 return {{::wide::detail::native_ops<V>::exp_scale(in_range, replacement, y, n)...}};
18 }
19 }
20 template<bool Flush = false, unsigned Degree = 6, float_register V>
21 requires (Degree >= 1 && Degree <= 7)
22 native_nodiscard native_inline constexpr native_pure V exp(V x) noexcept {
23 return ::NATIVE_BACKEND_NAMESPACE::native::exp<Flush, Degree>(std::array{x})[0];
24 }
25#if NATIVE_HAS_ARM_NEON
26 native_nodiscard native_inline constexpr native_pure float32x4_t exp(float32x4_t x) noexcept {
27 return ::NATIVE_BACKEND_NAMESPACE::native::exp(fp32x4(x)).value;
28 }
29 template<std::size_t N>
30 native_nodiscard native_inline constexpr native_pure std::array<float32x4_t, N> exp(std::array<float32x4_t, N> const & input) noexcept {
31 if constexpr (N == 0) return {};
32 else {
33 auto const & [...value] = input;
34 auto const [...result] = ::NATIVE_BACKEND_NAMESPACE::native::exp(std::array{fp32x4(value)...});
35 return {{result.value...}};
36 }
37 }
38#endif
39}
40
41namespace native {
42 // SIMD and array overloads let native::wide reuse the staged array kernel.
43#define NATIVE_PROMOTED_MATH_ENTRY(name) \
44 template<std::size_t L, ::native::isa<> Arch> \
45 requires NATIVE_ARCH_REQUIRES(Arch) && ::NATIVE_BACKEND_NAMESPACE::float_shape<L> \
46 native_nodiscard native_inline constexpr simd<float,L,Arch> name(simd<float,L,Arch> input) noexcept { \
47 return ::math::name(input); \
48 } \
49 template<std::size_t L, std::size_t N, ::native::isa<> Arch> \
50 requires NATIVE_ARCH_REQUIRES(Arch) && ::NATIVE_BACKEND_NAMESPACE::float_shape<L> \
51 native_nodiscard native_inline constexpr std::array<simd<float,L,Arch>,N> \
52 name(std::array<simd<float,L,Arch>,N> const & input) noexcept { return ::math::name(input); }
53 NATIVE_PROMOTED_MATH_ENTRY(expm1)
54 NATIVE_PROMOTED_MATH_ENTRY(damping_gain)
55 NATIVE_PROMOTED_MATH_ENTRY(log)
56 NATIVE_PROMOTED_MATH_ENTRY(log2)
57 NATIVE_PROMOTED_MATH_ENTRY(log1p)
58 NATIVE_PROMOTED_MATH_ENTRY(tanh)
59#undef NATIVE_PROMOTED_MATH_ENTRY
62 template<bool Flush = false, std::size_t L, ::native::isa<> Arch>
63 requires NATIVE_ARCH_REQUIRES(Arch) && ::NATIVE_BACKEND_NAMESPACE::float_shape<L>
65 exp2(simd<float,L,Arch> input) noexcept { return ::math::exp2<Flush>(input); }
68 template<bool Flush = false, std::size_t L, std::size_t N, ::native::isa<> Arch>
69 requires NATIVE_ARCH_REQUIRES(Arch) && ::NATIVE_BACKEND_NAMESPACE::float_shape<L>
70 native_nodiscard native_inline constexpr std::array<simd<float,L,Arch>,N>
71 exp2(std::array<simd<float,L,Arch>,N> const & input) noexcept { return ::math::exp2<Flush>(input); }
74 template<bool Flush, std::size_t L, ::native::isa<> Arch>
75 requires NATIVE_ARCH_REQUIRES(Arch) && ::NATIVE_BACKEND_NAMESPACE::float_shape<L>
76 native_nodiscard native_inline constexpr simd<float,L,Arch>
77 exp2(simd<float,L,Arch> input, std::bool_constant<Flush>) noexcept { return ::math::exp2<Flush>(input); }
80 template<bool Flush, std::size_t L, std::size_t N, ::native::isa<> Arch>
81 requires NATIVE_ARCH_REQUIRES(Arch) && ::NATIVE_BACKEND_NAMESPACE::float_shape<L>
82 native_nodiscard native_inline constexpr std::array<simd<float,L,Arch>,N>
83 exp2(std::array<simd<float,L,Arch>,N> const & input, std::bool_constant<Flush>) noexcept {
84 return ::math::exp2<Flush>(input);
85 }
86
88 template<std::size_t L, ::native::isa<> Arch>
89 requires NATIVE_ARCH_REQUIRES(Arch) && ::NATIVE_BACKEND_NAMESPACE::float_shape<L>
90 native_nodiscard native_inline constexpr simd<float,L,Arch>
91 atan2(simd<float,L,Arch> y, simd<float,L,Arch> x) noexcept { return ::math::atan2(y,x); }
94 template<std::size_t L, std::size_t N, ::native::isa<> Arch>
95 requires NATIVE_ARCH_REQUIRES(Arch) && ::NATIVE_BACKEND_NAMESPACE::float_shape<L>
96 native_nodiscard native_inline constexpr std::array<simd<float,L,Arch>,N>
97 atan2(std::array<simd<float,L,Arch>,N> const & y,
98 std::array<simd<float,L,Arch>,N> const & x) noexcept { return ::math::atan2(y,x); }
99
108 template<bool Flush = false, unsigned Degree = 6, std::size_t L, ::native::isa<> Arch> requires (Degree >= 1 && Degree <= 7) && NATIVE_ARCH_REQUIRES(Arch) && ::NATIVE_BACKEND_NAMESPACE::float_shape<L>
110 return ::NATIVE_BACKEND_NAMESPACE::native::exp<Flush, Degree>(input);
111 }
112
114 template<bool Flush = false, unsigned Degree = 6, std::size_t L, std::size_t N, ::native::isa<> Arch> requires (Degree >= 1 && Degree <= 7) && NATIVE_ARCH_REQUIRES(Arch) && ::NATIVE_BACKEND_NAMESPACE::float_shape<L>
115 native_nodiscard native_inline constexpr std::array<simd<float,L,Arch>,N> exp(std::array<simd<float,L,Arch>,N> const & input) noexcept {
116 return ::NATIVE_BACKEND_NAMESPACE::native::exp<Flush, Degree>(input);
117 }
118 // A tag argument avoids confusing this policy with register-width template
119 // arguments on other exp overloads during dependent lookup.
122 template<bool Flush, unsigned Degree = 6, std::size_t L, std::size_t N, ::native::isa<> Arch> requires (Degree >= 1 && Degree <= 7) && NATIVE_ARCH_REQUIRES(Arch) && ::NATIVE_BACKEND_NAMESPACE::float_shape<L>
123 native_nodiscard native_inline constexpr std::array<simd<float,L,Arch>,N> exp(
124 std::array<simd<float,L,Arch>,N> const & input, std::bool_constant<Flush>, std::integral_constant<unsigned, Degree> = {}) noexcept {
125 return ::NATIVE_BACKEND_NAMESPACE::native::exp<Flush, Degree>(input);
126 }
127
129 template<bool Flush, unsigned Degree = 6, std::size_t L, ::native::isa<> Arch> requires (Degree >= 1 && Degree <= 7) && NATIVE_ARCH_REQUIRES(Arch) && ::NATIVE_BACKEND_NAMESPACE::float_shape<L>
130 native_nodiscard native_inline constexpr simd<float,L,Arch> exp(simd<float,L,Arch> input, std::bool_constant<Flush>, std::integral_constant<unsigned, Degree> = {}) noexcept {
131 return ::NATIVE_BACKEND_NAMESPACE::native::exp<Flush, Degree>(input);
132 }
133}
134
#define native_inline
inline [[always_inline]]
Definition attributes.h:212
#define native_flatten
portable [[flatten]]
Definition attributes.h:228
#define native_nodiscard
C++17 [[nodiscard]].
Definition attributes.h:189
#define native_pure
[[pure]]
Definition attributes.h:126
constexpr simd< float, L, Arch > atan2(simd< float, L, Arch > y, simd< float, L, Arch > x) noexcept
Definition exp_body.h:91
constexpr simd< float, L, Arch > exp2(simd< float, L, Arch > input) noexcept
Definition exp_body.h:65
constexpr simd< float, L, Arch > exp(simd< float, L, Arch > input) noexcept
Evaluate the binary32 range-reduced exponential approximation. Degree selects a polynomial from one t...
Definition exp_body.h:109
constexpr wide< R, N > tanh(wide< R, N > const &input) noexcept([] { if constexpr(requires(std::array< R, N > const &a) { detail::wide_generic_detail::adl_tanh(a);}) return noexcept(wide< R, N >{detail::wide_generic_detail::adl_tanh(std::declval< std::array< R, N > const & >())});else return noexcept(wide< R, N >()) &&std::is_nothrow_move_constructible_v< wide< R, N > > &&(N==0||noexcept(std::declval< R & >()=detail::wide_generic_detail::adl_tanh(std::declval< R const & >())));}())
Definition wide.h:1193
constexpr wide< R, N > log(wide< R, N > const &input) noexcept([] { if constexpr(requires(std::array< R, N > const &a) { detail::wide_generic_detail::adl_log(a);}) return noexcept(wide< R, N >{detail::wide_generic_detail::adl_log(std::declval< std::array< R, N > const & >())});else return noexcept(wide< R, N >()) &&std::is_nothrow_move_constructible_v< wide< R, N > > &&(N==0||noexcept(std::declval< R & >()=detail::wide_generic_detail::adl_log(std::declval< R const & >())));}())
Definition wide.h:1130
constexpr wide< R, N > log2(wide< R, N > const &input) noexcept([] { if constexpr(requires(std::array< R, N > const &a) { detail::wide_generic_detail::adl_log2(a);}) return noexcept(wide< R, N >{detail::wide_generic_detail::adl_log2(std::declval< std::array< R, N > const & >())});else return noexcept(wide< R, N >()) &&std::is_nothrow_move_constructible_v< wide< R, N > > &&(N==0||noexcept(std::declval< R & >()=detail::wide_generic_detail::adl_log2(std::declval< R const & >())));}())
Definition wide.h:1151
constexpr wide< R, N > damping_gain(wide< R, N > const &input) noexcept([] { if constexpr(requires(std::array< R, N > const &a) { detail::wide_generic_detail::adl_damping_gain(a);}) return noexcept(wide< R, N >{detail::wide_generic_detail::adl_damping_gain(std::declval< std::array< R, N > const & >())});else return noexcept(wide< R, N >()) &&std::is_nothrow_move_constructible_v< wide< R, N > > &&(N==0||noexcept(std::declval< R & >()=detail::wide_generic_detail::adl_damping_gain(std::declval< R const & >())));}())
Definition wide.h:1109
constexpr wide< R, N > expm1(wide< R, N > const &input) noexcept([] { if constexpr(requires(std::array< R, N > const &a) { detail::wide_generic_detail::adl_expm1(a);}) return noexcept(wide< R, N >{detail::wide_generic_detail::adl_expm1(std::declval< std::array< R, N > const & >())});else return noexcept(wide< R, N >()) &&std::is_nothrow_move_constructible_v< wide< R, N > > &&(N==0||noexcept(std::declval< R & >()=detail::wide_generic_detail::adl_expm1(std::declval< R const & >())));}())
Definition wide.h:1088
constexpr wide< R, N > log1p(wide< R, N > const &input) noexcept([] { if constexpr(requires(std::array< R, N > const &a) { detail::wide_generic_detail::adl_log1p(a);}) return noexcept(wide< R, N >{detail::wide_generic_detail::adl_log1p(std::declval< std::array< R, N > const & >())});else return noexcept(wide< R, N >()) &&std::is_nothrow_move_constructible_v< wide< R, N > > &&(N==0||noexcept(std::declval< R & >()=detail::wide_generic_detail::adl_log1p(std::declval< R const & >())));}())
Definition wide.h:1172
Architecture-tagged vectors, register packs and supporting value types. Native arithmetic follows its...
Omitted architecture arguments use the native.simd provider's baseline.