1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
use super::sealed::Sealed;
use crate::simd::{
    intrinsics, LaneCount, Mask, Simd, SimdElement, SimdPartialEq, SimdPartialOrd,
    SupportedLaneCount,
};

/// 对浮点数的 SIMD vectors 的操作。
pub trait SimdFloat: Copy + Sealed {
    /// 用于操作此 SIMD vector 类型的掩码类型。
    type Mask;

    /// 此 SIMD vector 类型包含的标量类型。
    type Scalar;

    /// 此 SIMD vector 类型的位表示。
    type Bits;

    /// 原始转换为无符号整数 vector 类型,其大小和数量与 lanes 相同。
    ///
    #[must_use = "method returns a new vector and does not mutate the original value"]
    fn to_bits(self) -> Self::Bits;

    /// 来自具有相同大小和数量的 lanes 的无符号整数 vector 类型的原始变换。
    ///
    #[must_use = "method returns a new vector and does not mutate the original value"]
    fn from_bits(bits: Self::Bits) -> Self;

    /// 生成一个 vector,其中每个 lane 都具有 `self` 中等效索引 lane 的绝对值。
    ///
    #[must_use = "method returns a new vector and does not mutate the original value"]
    fn abs(self) -> Self;

    /// 获取每个 lane 的倒数 (inverse),`1/x`。
    #[must_use = "method returns a new vector and does not mutate the original value"]
    fn recip(self) -> Self;

    /// 将每个 lane 从弧度转换为度数。
    #[must_use = "method returns a new vector and does not mutate the original value"]
    fn to_degrees(self) -> Self;

    /// 将每个 lane 从度数转换为弧度。
    #[must_use = "method returns a new vector and does not mutate the original value"]
    fn to_radians(self) -> Self;

    /// 如果每个 lane 具有正号,则为每个 lane 返回 true,包括 `+0.0`、具有正符号位的 `NaN` 和正无穷大。
    ///
    #[must_use = "method returns a new mask and does not mutate the original value"]
    fn is_sign_positive(self) -> Self::Mask;

    /// 如果每个 lane 具有负号,则为每个 lane 返回 true,包括 `-0.0`、具有负符号位的 `NaN` 和负无穷大。
    ///
    #[must_use = "method returns a new mask and does not mutate the original value"]
    fn is_sign_negative(self) -> Self::Mask;

    /// 如果每个 lane 的值为 `NaN`,则为每个 lane 返回 true。
    #[must_use = "method returns a new mask and does not mutate the original value"]
    fn is_nan(self) -> Self::Mask;

    /// 如果每个 lane 的值是正无穷大或负无穷大,则为每个 lane 返回 true。
    #[must_use = "method returns a new mask and does not mutate the original value"]
    fn is_infinite(self) -> Self::Mask;

    /// 如果每个 lane 的值既不是无穷大也不是 `NaN`,则为每个 lane 返回 true。
    #[must_use = "method returns a new mask and does not mutate the original value"]
    fn is_finite(self) -> Self::Mask;

    /// 如果每个 lane 的值为 subnormal,则为每个 lane 返回 true。
    #[must_use = "method returns a new mask and does not mutate the original value"]
    fn is_subnormal(self) -> Self::Mask;

    /// 如果 lane 的值既不是零、无限、subnormal 也不是 `NaN`,则为每个 lane 返回 true。
    ///
    #[must_use = "method returns a new mask and does not mutate the original value"]
    fn is_normal(self) -> Self::Mask;

    /// 用代表其符号的数字替换每个 lane。
    ///
    /// * `1.0` 如果数字是正数,`+0.0` 或 `INFINITY`
    /// * `-1.0` 如果数字是负数,`-0.0` 或 `NEG_INFINITY`
    /// * `NAN` 如果数字是 `NAN`
    #[must_use = "method returns a new vector and does not mutate the original value"]
    fn signum(self) -> Self;

    /// 以 `self` 的大小和 `sign` 的符号返回每个 lane。
    ///
    /// 对于任何包含 `NAN` 的 lane,将返回带有 `sign` 符号的 `NAN`。
    #[must_use = "method returns a new vector and does not mutate the original value"]
    fn copysign(self, sign: Self) -> Self;

    /// 返回每个 lane 的最小值。
    ///
    /// 如果其中一个值为 `NAN`,则返回另一个值。
    #[must_use = "method returns a new vector and does not mutate the original value"]
    fn simd_min(self, other: Self) -> Self;

    /// 返回每个 lane 的最大值。
    ///
    /// 如果其中一个值为 `NAN`,则返回另一个值。
    #[must_use = "method returns a new vector and does not mutate the original value"]
    fn simd_max(self, other: Self) -> Self;

    /// 将每个 lane 限制在一定的区间内,除非它是 NaN。
    ///
    /// 对于 `self` 中的每个 lane,如果 lane 大于 `max`,则返回 `max` 中对应的 lane,如果 lane 小于 `min`,则返回 `min` 中对应的 lane。
    /// 否则返回 `self` 中的 lane。
    ///
    #[must_use = "method returns a new vector and does not mutate the original value"]
    fn simd_clamp(self, min: Self, max: Self) -> Self;

    /// 返回 vector 的 lane 的总和。
    ///
    /// # Examples
    ///
    /// ```
    /// # #![feature(portable_simd)]
    /// # #[cfg(feature = "as_crate")] use core_simd::simd;
    /// # #[cfg(not(feature = "as_crate"))] use core::simd;
    /// # use simd::{f32x2, SimdFloat};
    /// let v = f32x2::from_array([1., 2.]);
    /// assert_eq!(v.reduce_sum(), 3.);
    /// ```
    fn reduce_sum(self) -> Self::Scalar;

    /// 减少乘。返回 vector 的 lanes 的乘积。
    ///
    /// # Examples
    ///
    /// ```
    /// # #![feature(portable_simd)]
    /// # #[cfg(feature = "as_crate")] use core_simd::simd;
    /// # #[cfg(not(feature = "as_crate"))] use core::simd;
    /// # use simd::{f32x2, SimdFloat};
    /// let v = f32x2::from_array([3., 4.]);
    /// assert_eq!(v.reduce_product(), 12.);
    /// ```
    fn reduce_product(self) -> Self::Scalar;

    /// 返回 vector 中的最大 lane。
    ///
    /// 返回基于相等的值,因此包含 `0.` 和 `-0.` 的 vector 可以返回任意一个值。
    ///
    ///
    /// 这个函数不会返回 `NaN`,除非所有的 lane 都是 `NaN`。
    ///
    /// # Examples
    ///
    /// ```
    /// # #![feature(portable_simd)]
    /// # #[cfg(feature = "as_crate")] use core_simd::simd;
    /// # #[cfg(not(feature = "as_crate"))] use core::simd;
    /// # use simd::{f32x2, SimdFloat};
    /// let v = f32x2::from_array([1., 2.]);
    /// assert_eq!(v.reduce_max(), 2.);
    ///
    /// // 跳过 NaN 值...
    /// let v = f32x2::from_array([1., f32::NAN]);
    /// assert_eq!(v.reduce_max(), 1.);
    ///
    /// // ...除非所有值都是 NaN
    /// let v = f32x2::from_array([f32::NAN, f32::NAN]);
    /// assert!(v.reduce_max().is_nan());
    /// ```
    fn reduce_max(self) -> Self::Scalar;

    /// 返回 vector 中的最小 lane。
    ///
    /// 返回基于相等的值,因此包含 `0.` 和 `-0.` 的 vector 可以返回任意一个值。
    ///
    ///
    /// 这个函数不会返回 `NaN`,除非所有的 lane 都是 `NaN`。
    ///
    /// # Examples
    ///
    /// ```
    /// # #![feature(portable_simd)]
    /// # #[cfg(feature = "as_crate")] use core_simd::simd;
    /// # #[cfg(not(feature = "as_crate"))] use core::simd;
    /// # use simd::{f32x2, SimdFloat};
    /// let v = f32x2::from_array([3., 7.]);
    /// assert_eq!(v.reduce_min(), 3.);
    ///
    /// // 跳过 NaN 值...
    /// let v = f32x2::from_array([1., f32::NAN]);
    /// assert_eq!(v.reduce_min(), 1.);
    ///
    /// // ...除非所有值都是 NaN
    /// let v = f32x2::from_array([f32::NAN, f32::NAN]);
    /// assert!(v.reduce_min().is_nan());
    /// ```
    fn reduce_min(self) -> Self::Scalar;
}

macro_rules! impl_trait {
    { $($ty:ty { bits: $bits_ty:ty, mask: $mask_ty:ty }),* } => {
        $(
        impl<const LANES: usize> Sealed for Simd<$ty, LANES>
        where
            LaneCount<LANES>: SupportedLaneCount,
        {
        }

        impl<const LANES: usize> SimdFloat for Simd<$ty, LANES>
        where
            LaneCount<LANES>: SupportedLaneCount,
        {
            type Mask = Mask<<$mask_ty as SimdElement>::Mask, LANES>;
            type Scalar = $ty;
            type Bits = Simd<$bits_ty, LANES>;

            #[inline]
            fn to_bits(self) -> Simd<$bits_ty, LANES> {
                assert_eq!(core::mem::size_of::<Self>(), core::mem::size_of::<Self::Bits>());
                // 安全性: 在 vector 类型之间转换是安全的
                unsafe { core::mem::transmute_copy(&self) }
            }

            #[inline]
            fn from_bits(bits: Simd<$bits_ty, LANES>) -> Self {
                assert_eq!(core::mem::size_of::<Self>(), core::mem::size_of::<Self::Bits>());
                // 安全性: 在 vector 类型之间转换是安全的
                unsafe { core::mem::transmute_copy(&bits) }
            }

            #[inline]
            fn abs(self) -> Self {
                // 安全性: `self` 是一个浮点数 vector
                unsafe { intrinsics::simd_fabs(self) }
            }

            #[inline]
            fn recip(self) -> Self {
                Self::splat(1.0) / self
            }

            #[inline]
            fn to_degrees(self) -> Self {
                // to_degrees 使用一个特殊的常量来获得更好的精度,所以提取这个常量
                self * Self::splat(Self::Scalar::to_degrees(1.))
            }

            #[inline]
            fn to_radians(self) -> Self {
                self * Self::splat(Self::Scalar::to_radians(1.))
            }

            #[inline]
            fn is_sign_positive(self) -> Self::Mask {
                !self.is_sign_negative()
            }

            #[inline]
            fn is_sign_negative(self) -> Self::Mask {
                let sign_bits = self.to_bits() & Simd::splat((!0 >> 1) + 1);
                sign_bits.simd_gt(Simd::splat(0))
            }

            #[inline]
            fn is_nan(self) -> Self::Mask {
                self.simd_ne(self)
            }

            #[inline]
            fn is_infinite(self) -> Self::Mask {
                self.abs().simd_eq(Self::splat(Self::Scalar::INFINITY))
            }

            #[inline]
            fn is_finite(self) -> Self::Mask {
                self.abs().simd_lt(Self::splat(Self::Scalar::INFINITY))
            }

            #[inline]
            fn is_subnormal(self) -> Self::Mask {
                self.abs().simd_ne(Self::splat(0.0)) & (self.to_bits() & Self::splat(Self::Scalar::INFINITY).to_bits()).simd_eq(Simd::splat(0))
            }

            #[inline]
            #[must_use = "method returns a new mask and does not mutate the original value"]
            fn is_normal(self) -> Self::Mask {
                !(self.abs().simd_eq(Self::splat(0.0)) | self.is_nan() | self.is_subnormal() | self.is_infinite())
            }

            #[inline]
            fn signum(self) -> Self {
                self.is_nan().select(Self::splat(Self::Scalar::NAN), Self::splat(1.0).copysign(self))
            }

            #[inline]
            fn copysign(self, sign: Self) -> Self {
                let sign_bit = sign.to_bits() & Self::splat(-0.).to_bits();
                let magnitude = self.to_bits() & !Self::splat(-0.).to_bits();
                Self::from_bits(sign_bit | magnitude)
            }

            #[inline]
            fn simd_min(self, other: Self) -> Self {
                // 安全性: `self` 和 `other` 是浮动 vectors
                unsafe { intrinsics::simd_fmin(self, other) }
            }

            #[inline]
            fn simd_max(self, other: Self) -> Self {
                // 安全性: `self` 和 `other` 是浮点 vectors
                unsafe { intrinsics::simd_fmax(self, other) }
            }

            #[inline]
            fn simd_clamp(self, min: Self, max: Self) -> Self {
                assert!(
                    min.simd_le(max).all(),
                    "each lane in `min` must be less than or equal to the corresponding lane in `max`",
                );
                let mut x = self;
                x = x.simd_lt(min).select(min, x);
                x = x.simd_gt(max).select(max, x);
                x
            }

            #[inline]
            fn reduce_sum(self) -> Self::Scalar {
                // i586 上的 LLVM 总和不准确
                if cfg!(all(target_arch = "x86", not(target_feature = "sse2"))) {
                    self.as_array().iter().sum()
                } else {
                    // 安全性: `self` 是一个浮点数 vector
                    unsafe { intrinsics::simd_reduce_add_ordered(self, 0.) }
                }
            }

            #[inline]
            fn reduce_product(self) -> Self::Scalar {
                // LLVM 产品在 i586 上不准确
                if cfg!(all(target_arch = "x86", not(target_feature = "sse2"))) {
                    self.as_array().iter().product()
                } else {
                    // 安全性: `self` 是一个浮点数 vector
                    unsafe { intrinsics::simd_reduce_mul_ordered(self, 1.) }
                }
            }

            #[inline]
            fn reduce_max(self) -> Self::Scalar {
                // 安全性: `self` 是一个浮点数 vector
                unsafe { intrinsics::simd_reduce_max(self) }
            }

            #[inline]
            fn reduce_min(self) -> Self::Scalar {
                // 安全性: `self` 是一个浮点数 vector
                unsafe { intrinsics::simd_reduce_min(self) }
            }
        }
        )*
    }
}

impl_trait! { f32 { bits: u32, mask: i32 }, f64 { bits: u64, mask: i64 } }