generic_simd/vector/
mod.rs

1//! Vector type interfaces.
2
3pub mod width;
4
5use crate::arch::Token;
6use crate::scalar::Scalar;
7use core::ops::{
8    Add, AddAssign, Deref, DerefMut, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign,
9};
10
11/// Indicates the widest native vector.
12pub trait Native<Token> {
13    type Width: width::Width;
14}
15
16/// Convenience type for the widest native vector size.
17pub type NativeWidth<Scalar, Token> = <Scalar as Native<Token>>::Width;
18
19/// Convenience type for the widest native vector.
20pub type NativeVector<Scalar, Token> = VectorOf<Scalar, NativeWidth<Scalar, Token>, Token>;
21
22/// Convenience type for the vector with a particular width.
23pub type VectorOf<Scalar, Width, Token> = <Scalar as self::Scalar<Token, Width>>::Vector;
24
25/// The fundamental vector type.
26///
27/// # Safety
28/// This trait may only be implemented for types that have the memory layout of an array of
29/// `Scalar` with length `width()`.
30pub unsafe trait Vector: Copy {
31    /// The type of elements in the vector.
32    type Scalar: Copy;
33
34    /// The token that proves support for this vector on the CPU.
35    type Token: Token;
36
37    /// The number of elements in the vector.
38    type Width: width::Width;
39
40    /// The underlying type
41    type Underlying: Copy;
42
43    /// Returns the number of lanes.
44    #[inline]
45    fn width() -> usize {
46        <Self::Width as width::Width>::VALUE
47    }
48
49    /// Creates a new instance of `Token` from a vector.
50    #[inline]
51    fn to_token(self) -> Self::Token {
52        unsafe { Self::Token::new_unchecked() }
53    }
54
55    /// Returns a slice containing the vector.
56    #[inline]
57    fn as_slice(&self) -> &[Self::Scalar] {
58        unsafe { core::slice::from_raw_parts(self as *const _ as *const _, Self::width()) }
59    }
60
61    /// Returns a mutable slice containing the vector.
62    #[inline]
63    fn as_slice_mut(&mut self) -> &mut [Self::Scalar] {
64        unsafe { core::slice::from_raw_parts_mut(self as *mut _ as *mut _, Self::width()) }
65    }
66
67    /// Converts this vector to its underlying type.
68    #[inline]
69    fn to_underlying(self) -> Self::Underlying {
70        assert_eq!(
71            (
72                core::mem::size_of::<Self::Underlying>(),
73                core::mem::align_of::<Self::Underlying>(),
74            ),
75            (core::mem::align_of::<Self>(), core::mem::size_of::<Self>(),)
76        );
77        unsafe { core::mem::transmute_copy(&self) }
78    }
79
80    /// Converts the underlying type to a vector.
81    #[inline]
82    fn from_underlying(
83        #[allow(unused_variables)] token: Self::Token,
84        underlying: Self::Underlying,
85    ) -> Self {
86        assert_eq!(
87            (
88                core::mem::size_of::<Self::Underlying>(),
89                core::mem::align_of::<Self::Underlying>(),
90            ),
91            (core::mem::align_of::<Self>(), core::mem::size_of::<Self>(),)
92        );
93        unsafe { core::mem::transmute_copy(&underlying) }
94    }
95
96    /// Read from a pointer.
97    ///
98    /// # Safety
99    /// * `from` must point to an array of length at least `width()`.
100    #[inline]
101    unsafe fn read_ptr(
102        #[allow(unused_variables)] token: Self::Token,
103        from: *const Self::Scalar,
104    ) -> Self {
105        (from as *const Self).read_unaligned()
106    }
107
108    /// Read from a vector-aligned pointer.
109    ///
110    /// # Safety
111    /// * `from` must point to an array of length at least `width()`.
112    /// * `from` must be aligned for the vector type.
113    #[inline]
114    unsafe fn read_aligned_ptr(
115        #[allow(unused_variables)] token: Self::Token,
116        from: *const Self::Scalar,
117    ) -> Self {
118        (from as *const Self).read()
119    }
120
121    /// Read from a vector-aligned pointer.
122
123    /// Read from a slice without checking the length.
124    ///
125    /// # Safety
126    /// * `from` be length at least `width()`.
127    #[inline]
128    unsafe fn read_unchecked(token: Self::Token, from: &[Self::Scalar]) -> Self {
129        Self::read_ptr(token, from.as_ptr())
130    }
131
132    /// Read from a slice.
133    ///
134    /// # Panic
135    /// Panics if the length of `from` is less than `width()`.
136    #[inline]
137    fn read(token: Self::Token, from: &[Self::Scalar]) -> Self {
138        assert!(
139            from.len() >= Self::width(),
140            "source not larget enough to load vector"
141        );
142        unsafe { Self::read_unchecked(token, from) }
143    }
144
145    /// Write to a pointer.
146    ///
147    /// # Safety
148    /// `from` must point to an array of length at least `width()`
149    #[inline]
150    unsafe fn write_ptr(self, to: *mut Self::Scalar) {
151        (to as *mut Self).write_unaligned(self);
152    }
153
154    /// Write to a pointer.
155    ///
156    /// # Safety
157    /// `from` must point to an array of length at least `width()`
158    /// `from` must be aligned for the vector type.
159    #[inline]
160    unsafe fn write_aligned_ptr(self, to: *mut Self::Scalar) {
161        (to as *mut Self).write(self);
162    }
163
164    /// Write to a slice without checking the length.
165    ///
166    /// # Safety
167    /// `from` must be length at least `width()`.
168    #[inline]
169    unsafe fn write_unchecked(self, to: &mut [Self::Scalar]) {
170        self.write_ptr(to.as_mut_ptr());
171    }
172
173    /// Write to a slice.
174    ///
175    /// # Panics
176    /// Panics if the length of `from` is less than `width()`.
177    #[inline]
178    fn write(self, to: &mut [Self::Scalar]) {
179        assert!(
180            to.len() >= Self::width(),
181            "destination not large enough to store vector"
182        );
183        unsafe { self.write_unchecked(to) };
184    }
185
186    /// Create a new vector with each lane containing zeroes.
187    fn zeroed(token: Self::Token) -> Self;
188
189    /// Create a new vector with each lane containing the provided value.
190    fn splat(token: Self::Token, from: Self::Scalar) -> Self;
191}
192
193/// A supertrait for vectors supporting typical arithmetic operations.
194pub trait Ops:
195    Vector
196    + AsRef<[<Self as Vector>::Scalar]>
197    + AsMut<[<Self as Vector>::Scalar]>
198    + Deref<Target = [<Self as Vector>::Scalar]>
199    + DerefMut
200    + Add<Self, Output = Self>
201    + Add<<Self as Vector>::Scalar, Output = Self>
202    + AddAssign<Self>
203    + AddAssign<<Self as Vector>::Scalar>
204    + Sub<Self, Output = Self>
205    + Sub<<Self as Vector>::Scalar, Output = Self>
206    + SubAssign<Self>
207    + SubAssign<<Self as Vector>::Scalar>
208    + Mul<Self, Output = Self>
209    + Mul<<Self as Vector>::Scalar, Output = Self>
210    + MulAssign<Self>
211    + MulAssign<<Self as Vector>::Scalar>
212    + Div<Self, Output = Self>
213    + Div<<Self as Vector>::Scalar, Output = Self>
214    + DivAssign<Self>
215    + DivAssign<<Self as Vector>::Scalar>
216{
217}
218impl<V> Ops for V where
219    V: Vector
220        + AsRef<[<V as Vector>::Scalar]>
221        + AsMut<[<V as Vector>::Scalar]>
222        + Deref<Target = [<V as Vector>::Scalar]>
223        + DerefMut
224        + Add<V, Output = V>
225        + Add<<V as Vector>::Scalar, Output = V>
226        + AddAssign<V>
227        + AddAssign<<V as Vector>::Scalar>
228        + Sub<V, Output = V>
229        + Sub<<V as Vector>::Scalar, Output = V>
230        + SubAssign<V>
231        + SubAssign<<V as Vector>::Scalar>
232        + Mul<V, Output = V>
233        + Mul<<V as Vector>::Scalar, Output = V>
234        + MulAssign<V>
235        + MulAssign<<V as Vector>::Scalar>
236        + Div<V, Output = V>
237        + Div<<V as Vector>::Scalar, Output = V>
238        + DivAssign<V>
239        + DivAssign<<V as Vector>::Scalar>
240{
241}
242
243/// A supertrait for vectors that allow arithmetic operations over signed types.
244pub trait Signed: Ops + Neg<Output = Self> {}
245impl<V> Signed for V where V: Ops + Neg<Output = V> {}
246
247/// Complex valued vectors.
248pub trait Complex: Signed {
249    /// The real scalar type.
250    type RealScalar: Copy;
251
252    /// Conjugate.
253    fn conj(self) -> Self;
254
255    /// Multiply by i.
256    fn mul_i(self) -> Self;
257
258    /// Multiply by -i.
259    fn mul_neg_i(self) -> Self;
260}