native 0.0.1
Vectors, masks and wide register packs for C++26
Loading...
Searching...
No Matches
sincos_body.h
Go to the documentation of this file.
1
2// Altered source: paired polynomial and reducer with explicit binary32
3// operation order. Original notices are retained below.
4// Precondition: finite input with |x| < 8192. No global math replacement.
5namespace NATIVE_BACKEND_NAMESPACE::native {
6 namespace detail {
7 template <class V> struct trig_conversion;
8 template <> struct trig_conversion<fp32x1> {
9 static native_inline uint32x1 integer(fp32x1 x) noexcept {
10 return uint32x1(static_cast<std::uint32_t>(x.value));
11 }
12 static native_inline fp32x1 floating(uint32x1 x) noexcept {
13 return fp32x1(static_cast<float>(x.value));
14 }
15 };
16#if NATIVE_HAS_AVX2
17 template <> struct trig_conversion<fp32x4> {
18 static native_inline uint32x4 integer(fp32x4 x) noexcept {
19 return uint32x4::from_native(_mm_cvttps_epi32(x.value));
20 }
21 static native_inline fp32x4 floating(uint32x4 x) noexcept {
22 return fp32x4(_mm_cvtepi32_ps(x.value));
23 }
24 };
25 template <> struct trig_conversion<fp32x8> {
26 static native_inline uint32x8 integer(fp32x8 x) noexcept {
27 return uint32x8::from_native(_mm256_cvttps_epi32(x.value));
28 }
29 static native_inline fp32x8 floating(uint32x8 x) noexcept {
30 return fp32x8(_mm256_cvtepi32_ps(x.value));
31 }
32 };
33#endif
34#if NATIVE_HAS_AVX512F && NATIVE_HAS_AVX512DQ
35 template <> struct trig_conversion<fp32x16> {
36 static native_inline uint32x16 integer(fp32x16 x) noexcept {
37 return uint32x16::from_native(_mm512_cvttps_epi32(x.value));
38 }
39 static native_inline fp32x16 floating(uint32x16 x) noexcept {
40 return fp32x16(_mm512_cvtepi32_ps(x.value));
41 }
42 };
43#endif
44#if NATIVE_HAS_ARM_NEON
45 template <> struct trig_conversion<fp32x4> {
46 static native_inline uint32x4 integer(fp32x4 x) noexcept {
47 return uint32x4::from_native(vreinterpretq_u8_s32(vcvtq_s32_f32(x.value)));
48 }
49 static native_inline fp32x4 floating(uint32x4 x) noexcept {
50 return fp32x4(vcvtq_f32_s32(vreinterpretq_s32_u8(x.value)));
51 }
52 };
53#endif
54 enum class trig_kind { sine, cosine, paired };
55 template <trig_kind K, float_register V, std::size_t N>
56 native_flatten native_inline auto trig(std::array<V, N> const & input) noexcept {
57 using B = fp32_bit_bridge<V>;
58 using I = typename B::bits_type;
59 using C = trig_conversion<V>;
60 if constexpr (N == 0) {
61 if constexpr (K == trig_kind::paired) return std::pair<std::array<V, N>, std::array<V, N>>{};
62 else return std::array<V, N>{};
63 } else {
64 auto const & [...original] = input;
65 auto [...sign_sine] = std::array{(B::encode(original) & I(0x80000000u))...};
66 auto [...x] = std::array{B::decode(B::encode(original) & I(0x7fffffffu))...};
67 auto [...y] = std::array{(x * V(1.27323954473516f))...};
68 auto const [...j] = std::array{((C::integer(y) + I(1)) & I(0xfffffffeu))...};
69 ((y = C::floating(j)), ...);
70 ((sign_sine = sign_sine ^ ((j & I(4)).template left<29>())), ...);
71 auto const [...sign_cosine] = std::array{((((j - I(2)) ^ I(0xffffffffu)) & I(4)).template left<29>())...};
72 auto [...mask] = std::array<I, N>{};
73 if constexpr (K == trig_kind::cosine) {
74 ((mask = mask_bits<::native::uint32_t>(((j - I(2)) & I(2)) == I(0))), ...);
75 } else {
76 ((mask = mask_bits<::native::uint32_t>((j & I(2)) == I(0))), ...);
77 }
78 ((x = fma(y, V(-0.78515625f), x)), ...);
79 ((x = fma(y, V(-2.4187564849853515625e-4f), x)), ...);
80 ((x = fma(y, V(-3.77489497744594108e-8f), x)), ...);
81 auto const [...z] = std::array{(x * x)...};
82 auto [...cosine] = std::array{fma(V(2.443315711809948e-5f), z, V(-1.388731625493765e-3f))...};
83 ((cosine = fma(cosine, z, V(4.166664568298827e-2f))), ...);
84 ((cosine = cosine * z), ...);
85 ((cosine = cosine * z), ...);
86 ((cosine = cosine - z * V(0.5f)), ...);
87 ((cosine = cosine + V(1.0f)), ...);
88 auto [...sine] = std::array{fma(V(-1.9515295891e-4f), z, V(8.3321608736e-3f))...};
89 ((sine = fma(sine, z, V(-1.6666654611e-1f))), ...);
90 ((sine = sine * z), ...);
91 ((sine = fma(sine, x, x)), ...);
92 auto [...selected_sine] = std::array{B::decode(mask & B::encode(sine))...};
93 auto [...selected_cosine] = std::array{B::decode((mask ^ I(0xffffffffu)) & B::encode(cosine))...};
94 if constexpr (K == trig_kind::paired) {
95 // Preserve subtraction selection, including its signed-zero effects.
96 ((sine = sine - selected_sine), ...);
97 ((cosine = cosine - selected_cosine), ...);
98 ((selected_sine = B::decode(B::encode(selected_cosine + selected_sine) ^ sign_sine)), ...);
99 ((selected_cosine = B::decode(B::encode(cosine + sine) ^ sign_cosine)), ...);
100 return std::pair{std::array{selected_sine...}, std::array{selected_cosine...}};
101 } else if constexpr (K == trig_kind::sine) {
102 return std::array{B::decode(B::encode(selected_cosine + selected_sine) ^ sign_sine)...};
103 } else {
104 return std::array{B::decode(B::encode(selected_cosine + selected_sine) ^ sign_cosine)...};
105 }
106 }
107 }
108 } // namespace detail
109 template <float_register V, std::size_t N>
110 native_inline std::array<V, N> sin(std::array<V, N> const & x) noexcept {
111 return detail::trig<detail::trig_kind::sine>(x);
112 }
113 template <float_register V, std::size_t N>
114 native_inline std::array<V, N> cos(std::array<V, N> const & x) noexcept {
115 return detail::trig<detail::trig_kind::cosine>(x);
116 }
117 template <float_register V, std::size_t N>
118 native_inline std::pair<std::array<V, N>, std::array<V, N>> sincos(std::array<V, N> const & x) noexcept {
119 return detail::trig<detail::trig_kind::paired>(x);
120 }
121} // namespace NATIVE_BACKEND_NAMESPACE::native
122
123/*
124 AVX implementation of sin, cos, sincos, exp and log
125
126 Based on "sse_mathfun.h", by Julien Pommier
127 http://gruntthepeon.free.fr/ssemath/
128
129 Copyright (C) 2012 Giovanni Garberoglio
130 Interdisciplinary Laboratory for Computational Science (LISC)
131 Fondazione Bruno Kessler and University of Trento
132 via Sommarive, 18
133 I-38123 Trento (Italy)
134
135 This software is provided 'as-is', without any express or implied
136 warranty. In no event will the authors be held liable for any damages
137 arising from the use of this software.
138
139 Permission is granted to anyone to use this software for any purpose,
140 including commercial applications, and to alter it and redistribute it
141 freely, subject to the following restrictions:
142
143 1. The origin of this software must not be misrepresented; you must not
144 claim that you wrote the original software. If you use this software
145 in a product, an acknowledgment in the product documentation would be
146 appreciated but is not required.
147 2. Altered source versions must be plainly marked as such, and must not be
148 misrepresented as being the original software.
149 3. This notice may not be removed or altered from any source distribution.
150*/
151
152/* RTS repository license (retained verbatim):
153Software License Agreement (BSD 2-Clause License)
154========================================
155
156Copyright 2017 Edward Kmett
157
158Redistribution and use in source and binary forms, with or without
159modification, are permitted provided that the following conditions are met:
160
161 * Redistributions of source code must retain the above copyright
162 notice, this list of conditions and the following disclaimer.
163
164 * Redistributions in binary form must reproduce the above copyright
165 notice, this list of conditions and the following disclaimer in the
166 documentation and/or other materials provided with the distribution.
167
168THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
169ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
170WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
171DISCLAIMED. IN NO EVENT SHALL YAHOO! INC. BE LIABLE FOR ANY
172DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
173(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
174LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
175ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
176(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
177SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
178*/
179
#define native_inline
inline [[always_inline]]
Definition attributes.h:212
#define native_flatten
portable [[flatten]]
Definition attributes.h:228
typename mask_traits< std::remove_cvref_t< T > >::type mask
Definition mask_traits.h:22
constexpr simd< fp16, 32, Arch > fma(simd< fp16, 32, Arch > a, simd< fp16, 32, Arch > b, simd< fp16, 32, Arch > c) noexcept