Skip to main content

SimdBase

Trait SimdBase 

Source
pub trait SimdBase<S: Simd>:
    Copy
    + Sync
    + Send
    + Debug
    + 'static
    + Seal
    + Bytes<Bytes = Self::ByteVector>
    + SimdFrom<Self::Element, S>
    + SimdFrom<Self::Array, S>
    + Index<usize, Output = Self::Element>
    + IndexMut<usize, Output = Self::Element>
    + Deref<Target = Self::Array>
    + DerefMut<Target = Self::Array>
    + Add<Output = Self>
    + AddAssign
    + Add<Self::Element, Output = Self>
    + AddAssign<Self::Element>
    + Sub<Output = Self>
    + SubAssign
    + Sub<Self::Element, Output = Self>
    + SubAssign<Self::Element>
    + Mul<Output = Self>
    + MulAssign
    + Mul<Self::Element, Output = Self>
    + MulAssign<Self::Element> {
    type Element: SimdElement;
    type ByteVector: SimdBase<S, Element = u8, ByteVector = Self::ByteVector>;
    type Mask: SimdMask<S, Element = <Self::Element as SimdElement>::Mask> + Select<Self>;
    type Block: SimdBase<S, Element = Self::Element, Block = Self::Block>;
    type Array: Copy + Debug + IntoIterator<Item = Self::Element> + AsRef<[Self::Element]> + AsMut<[Self::Element]> + From<Self>;

    const N: usize;
Show 38 methods // Required methods fn witness(&self) -> S; fn as_slice(&self) -> &[Self::Element]; fn as_mut_slice(&mut self) -> &mut [Self::Element]; fn from_slice(simd: S, slice: &[Self::Element]) -> Self; fn store_slice(&self, slice: &mut [Self::Element]); fn block_splat(block: Self::Block) -> Self; fn from_fn(simd: S, f: impl FnMut(usize) -> Self::Element) -> Self; fn splat(simd: S, val: Self::Element) -> Self; fn slide<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self; fn slide_within_blocks<const SHIFT: usize>( self, rhs: impl SimdInto<Self, S>, ) -> Self; fn swizzle_dyn_within_blocks( self, indices: impl SimdInto<Self::Bytes, S>, ) -> Self; fn swizzle_dyn(self, indices: impl SimdInto<Self::Bytes, S>) -> Self; fn swizzle_dyn_precise(self, indices: impl SimdInto<Self::Bytes, S>) -> Self; fn max(self, rhs: impl SimdInto<Self, S>) -> Self; fn min(self, rhs: impl SimdInto<Self, S>) -> Self; fn max_precise(self, rhs: impl SimdInto<Self, S>) -> Self; fn min_precise(self, rhs: impl SimdInto<Self, S>) -> Self; fn simd_eq(self, rhs: impl SimdInto<Self, S>) -> Self::Mask; fn simd_lt(self, rhs: impl SimdInto<Self, S>) -> Self::Mask; fn simd_le(self, rhs: impl SimdInto<Self, S>) -> Self::Mask; fn simd_ge(self, rhs: impl SimdInto<Self, S>) -> Self::Mask; fn simd_gt(self, rhs: impl SimdInto<Self, S>) -> Self::Mask; fn zip_low(self, rhs: impl SimdInto<Self, S>) -> Self; fn zip_high(self, rhs: impl SimdInto<Self, S>) -> Self; fn unzip_low(self, rhs: impl SimdInto<Self, S>) -> Self; fn unzip_high(self, rhs: impl SimdInto<Self, S>) -> Self; fn interleave(self, rhs: impl SimdInto<Self, S>) -> (Self, Self); fn deinterleave(self, rhs: impl SimdInto<Self, S>) -> (Self, Self); // Provided methods fn load_array(simd: S, val: Self::Array) -> Self { ... } fn load_array_ref(simd: S, val: &Self::Array) -> Self { ... } fn as_array(self) -> Self::Array { ... } fn as_array_ref(&self) -> &Self::Array { ... } fn as_array_mut(&mut self) -> &mut Self::Array { ... } fn store_array(self, dest: &mut Self::Array) { ... } fn rotate_elements_left<const OFFSET: usize>(self) -> Self { ... } fn rotate_elements_right<const OFFSET: usize>(self) -> Self { ... } fn shift_elements_left<const OFFSET: usize>( self, padding: Self::Element, ) -> Self { ... } fn shift_elements_right<const OFFSET: usize>( self, padding: Self::Element, ) -> Self { ... }
}
Expand description

Base functionality implemented by all SIMD vectors.

Required Associated Constants§

Source

const N: usize

This vector type’s lane count. This is useful when you’re working with a native-width vector (e.g. Simd::f32s) and want to process data in native-width chunks.

Required Associated Types§

Source

type Element: SimdElement

The type of this vector’s elements.

Source

type ByteVector: SimdBase<S, Element = u8, ByteVector = Self::ByteVector>

The same-width SIMD vector of u8 lanes used as the byte representation.

This is the same type as Bytes::Bytes.

This associated type exists because expressing the SimdBase bound directly on Bytes::Bytes creates a trait-solver cycle. The Bytes<Bytes = Self::ByteVector> supertrait bound ensures that the two types are identical. Generic callers should normally use Bytes::Bytes, not this associated type.

Source

type Mask: SimdMask<S, Element = <Self::Element as SimdElement>::Mask> + Select<Self>

A SIMD vector mask with the same number of logical lanes.

Masks intentionally do not implement SimdBase. SSE, NEON, WASM, and the fallback backend currently store masks as all-zero/all-one integer vectors, but AVX-512/RVV/SVE-style targets use compact predicate registers instead.

Source

type Block: SimdBase<S, Element = Self::Element, Block = Self::Block>

A 128-bit SIMD vector of the same scalar type.

Source

type Array: Copy + Debug + IntoIterator<Item = Self::Element> + AsRef<[Self::Element]> + AsMut<[Self::Element]> + From<Self>

The array type that this vector type corresponds to, which will always be [Self::Element; Self::N]. It has the same layout as this vector type, but likely has a lower alignment.

Required Methods§

Source

fn witness(&self) -> S

Get the Simd implementation associated with this type.

Source

fn as_slice(&self) -> &[Self::Element]

Source

fn as_mut_slice(&mut self) -> &mut [Self::Element]

Source

fn from_slice(simd: S, slice: &[Self::Element]) -> Self

Create a SIMD vector from a slice.

The slice must be exactly the size of the SIMD vector.

Source

fn store_slice(&self, slice: &mut [Self::Element])

Store a SIMD vector into a slice.

The slice must be exactly the size of the SIMD vector.

Source

fn block_splat(block: Self::Block) -> Self

Create a SIMD vector from a 128-bit vector of the same scalar type, repeated.

Source

fn from_fn(simd: S, f: impl FnMut(usize) -> Self::Element) -> Self

Create a SIMD vector where each element is produced by calling f with that element’s lane index (from 0 to SimdBase::N - 1).

Source

fn splat(simd: S, val: Self::Element) -> Self

Create a SIMD vector with all elements set to the given value.

Source

fn slide<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self

Concatenate [self, rhs] and extract Self::N elements starting at index SHIFT.

SHIFT must be within [0, Self::N].

This can be used to implement a “shift items” operation by providing all zeroes as one operand. For a left shift, the right-hand side should be all zeroes. For a right shift by M items, the left-hand side should be all zeroes, and the shift amount will be Self::N - M.

This can also be used to rotate items within a vector by providing the same vector as both operands.


slide::<1>([a b c d], [e f g h]) == [b c d e]
Source

fn slide_within_blocks<const SHIFT: usize>( self, rhs: impl SimdInto<Self, S>, ) -> Self

Like slide, but operates independently on each 128-bit block.

Source

fn swizzle_dyn_within_blocks( self, indices: impl SimdInto<Self::Bytes, S>, ) -> Self

Dynamically swizzle this vector’s bytes independently within each 128-bit block.

The indices operand is a same-width byte vector. For each output byte, index values 0..=15 select the corresponding byte from the same 128-bit input block.

Out-of-range index behavior varies by platform.

Source

fn swizzle_dyn(self, indices: impl SimdInto<Self::Bytes, S>) -> Self

Dynamically swizzle this vector’s bytes across the whole vector.

The indices operand is a same-width byte vector. For each output byte, index values within the vector’s byte length select the corresponding byte from the input vector. Out-of-range indices safely produce implementation-defined byte values.

Use SimdBase::swizzle_dyn_precise if out-of-range indices must produce zero.

Source

fn swizzle_dyn_precise(self, indices: impl SimdInto<Self::Bytes, S>) -> Self

Dynamically swizzle this vector’s bytes across the whole vector.

The indices operand is a same-width byte vector. For each output byte, index values within the vector’s byte length select the corresponding byte from the input vector. Out-of-range indices produce zero.

Source

fn max(self, rhs: impl SimdInto<Self, S>) -> Self

Return the element-wise maximum of two vectors.

For floating-point vectors, if either operand is NaN, the result for that lane is implementation-defined– it could be either the first or second operand. See max_precise for a version that returns the non-NaN operand if only one is NaN.

If one floating-point operand is positive zero and the other is negative zero, the result is also implementation-defined, and it could be either one.

Source

fn min(self, rhs: impl SimdInto<Self, S>) -> Self

Return the element-wise minimum of two vectors.

For floating-point vectors, if either operand is NaN, the result for that lane is implementation-defined– it could be either the first or second operand. See min_precise for a version that returns the non-NaN operand if only one is NaN.

If one floating-point operand is positive zero and the other is negative zero, the result is also implementation-defined, and it could be either one.

Source

fn max_precise(self, rhs: impl SimdInto<Self, S>) -> Self

Return the element-wise maximum of two vectors.

For integer vectors, this operation is the same as max.

For floating-point vectors, if one operand is a quiet NaN and the other is not, this operation will choose the non-NaN operand.

If one floating-point operand is positive zero and the other is negative zero, the result is implementation-defined, and it could be either one.

If a floating-point operand is a signaling NaN, the result is not just implementation-defined, but fully non-deterministic: it may be either NaN or the non-NaN operand. Signaling NaN values are not produced by floating-point math operations, only from manual initialization with specific bit patterns. You probably don’t need to worry about them.

Source

fn min_precise(self, rhs: impl SimdInto<Self, S>) -> Self

Return the element-wise minimum of two vectors.

For integer vectors, this operation is the same as min.

For floating-point vectors, if one operand is a quiet NaN and the other is not, this operation will choose the non-NaN operand.

If one floating-point operand is positive zero and the other is negative zero, the result is implementation-defined, and it could be either one.

If a floating-point operand is a signaling NaN, the result is not just implementation-defined, but fully non-deterministic: it may be either NaN or the non-NaN operand. Signaling NaN values are not produced by floating-point math operations, only from manual initialization with specific bit patterns. You probably don’t need to worry about them.

Source

fn simd_eq(self, rhs: impl SimdInto<Self, S>) -> Self::Mask

Compare two vectors element-wise for equality.

Returns a mask where each logical lane is true if the corresponding elements are equal, and false if not.

Source

fn simd_lt(self, rhs: impl SimdInto<Self, S>) -> Self::Mask

Compare two vectors element-wise for less than.

Returns a mask where each logical lane is true if self is less than rhs, and false if not.

Source

fn simd_le(self, rhs: impl SimdInto<Self, S>) -> Self::Mask

Compare two vectors element-wise for less than or equal.

Returns a mask where each logical lane is true if self is less than or equal to rhs, and false if not.

Source

fn simd_ge(self, rhs: impl SimdInto<Self, S>) -> Self::Mask

Compare two vectors element-wise for greater than or equal.

Returns a mask where each logical lane is true if self is greater than or equal to rhs, and false if not.

Source

fn simd_gt(self, rhs: impl SimdInto<Self, S>) -> Self::Mask

Compare two vectors element-wise for greater than.

Returns a mask where each logical lane is true if self is greater than rhs, and false if not.

Source

fn zip_low(self, rhs: impl SimdInto<Self, S>) -> Self

Interleave the lower half elements of two vectors.

For vectors [a0, a1, a2, a3] and [b0, b1, b2, b3], returns [a0, b0, a1, b1].

Note: This operation is only useful if you need to discard elements a2, a3, b2, b3. For fully interleaving two vectors prefer interleave, which is faster than zip_low followed by zip_high on some platforms.

Source

fn zip_high(self, rhs: impl SimdInto<Self, S>) -> Self

Interleave the upper half elements of two vectors.

For vectors [a0, a1, a2, a3] and [b0, b1, b2, b3], returns [a2, b2, a3, b3].

Note: This operation is only useful if you need to discard elements a0, a1, b0, b1.For fully interleaving two vectors prefer interleave, which is faster than zip_low followed by zip_high on some platforms.

Source

fn unzip_low(self, rhs: impl SimdInto<Self, S>) -> Self

Extract even-indexed elements from two vectors.

For vectors [a0, a1, a2, a3] and [b0, b1, b2, b3], returns [a0, a2, b0, b2].

Note: This operation is only useful if you need to discard elements a1, a3, b1, b3.For fully deinterleaving two vectors prefer deinterleave, which is faster than unzip_low followed by unzip_high on some platforms.

Source

fn unzip_high(self, rhs: impl SimdInto<Self, S>) -> Self

Extract odd-indexed elements from two vectors.

For vectors [a0, a1, a2, a3] and [b0, b1, b2, b3], returns [a1, a3, b1, b3].

Note: This operation is only useful if you need to discard elements a0, a2, b0, b2.For fully deinterleaving two vectors prefer deinterleave, which is faster than unzip_low followed by unzip_high on some platforms.

Source

fn interleave(self, rhs: impl SimdInto<Self, S>) -> (Self, Self)

Interleave two vectors.

The resulting vectors contain elements taken alternately from self and rhs, first filling the first result, and then the second.

The reverse of this operation is deinterleave.

For vectors [a0, a1, a2, a3] and [b0, b1, b2, b3], returns ([a0, b0, a1, b1], [a2, b2, a3, b3]).

Source

fn deinterleave(self, rhs: impl SimdInto<Self, S>) -> (Self, Self)

Deinterleave two vectors.

The first result contains all even-indexed elements from self followed by all even-indexed elements from rhs. The second result contains all odd-indexed elements from self followed by all odd-indexed elements from rhs.

The reverse of this operation is interleave.

For vectors [a0, b0, a1, b1] and [a2, b2, a3, b3], returns ([a0, a1, a2, a3], [b0, b1, b2, b3]).

Provided Methods§

Source

fn load_array(simd: S, val: Self::Array) -> Self

Create a SIMD vector from its corresponding lane array.

Source

fn load_array_ref(simd: S, val: &Self::Array) -> Self

Create a SIMD vector from a reference to its corresponding lane array.

Source

fn as_array(self) -> Self::Array

Convert this SIMD vector to its corresponding lane array.

Source

fn as_array_ref(&self) -> &Self::Array

Project this SIMD vector reference to its corresponding lane array reference.

Source

fn as_array_mut(&mut self) -> &mut Self::Array

Project this mutable SIMD vector reference to its corresponding mutable lane array reference.

Source

fn store_array(self, dest: &mut Self::Array)

Store this SIMD vector into its corresponding lane array.

Source

fn rotate_elements_left<const OFFSET: usize>(self) -> Self

Rotate the vector elements to the left by OFFSET.

If OFFSET is greater than or equal to Self::N, it wraps modulo Self::N.

Source

fn rotate_elements_right<const OFFSET: usize>(self) -> Self

Rotate the vector elements to the right by OFFSET.

If OFFSET is greater than or equal to Self::N, it wraps modulo Self::N.

Source

fn shift_elements_left<const OFFSET: usize>( self, padding: Self::Element, ) -> Self

Shift the vector elements to the left by OFFSET, filling in with padding from the right.

If OFFSET is greater than or equal to Self::N, all lanes are filled with padding.

Source

fn shift_elements_right<const OFFSET: usize>( self, padding: Self::Element, ) -> Self

Shift the vector elements to the right by OFFSET, filling in with padding from the left.

If OFFSET is greater than or equal to Self::N, all lanes are filled with padding.

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementors§

Source§

impl<S: Simd> SimdBase<S> for f32x4<S>

Source§

impl<S: Simd> SimdBase<S> for f32x8<S>

Source§

impl<S: Simd> SimdBase<S> for f32x16<S>

Source§

impl<S: Simd> SimdBase<S> for f64x2<S>

Source§

impl<S: Simd> SimdBase<S> for f64x4<S>

Source§

impl<S: Simd> SimdBase<S> for f64x8<S>

Source§

impl<S: Simd> SimdBase<S> for i8x16<S>

Source§

impl<S: Simd> SimdBase<S> for i8x32<S>

Source§

impl<S: Simd> SimdBase<S> for i8x64<S>

Source§

impl<S: Simd> SimdBase<S> for i16x8<S>

Source§

impl<S: Simd> SimdBase<S> for i16x16<S>

Source§

impl<S: Simd> SimdBase<S> for i16x32<S>

Source§

impl<S: Simd> SimdBase<S> for i32x4<S>

Source§

impl<S: Simd> SimdBase<S> for i32x8<S>

Source§

impl<S: Simd> SimdBase<S> for i32x16<S>

Source§

impl<S: Simd> SimdBase<S> for i64x2<S>

Source§

impl<S: Simd> SimdBase<S> for i64x4<S>

Source§

impl<S: Simd> SimdBase<S> for i64x8<S>

Source§

impl<S: Simd> SimdBase<S> for u8x16<S>

Source§

impl<S: Simd> SimdBase<S> for u8x32<S>

Source§

impl<S: Simd> SimdBase<S> for u8x64<S>

Source§

impl<S: Simd> SimdBase<S> for u16x8<S>

Source§

impl<S: Simd> SimdBase<S> for u16x16<S>

Source§

impl<S: Simd> SimdBase<S> for u16x32<S>

Source§

impl<S: Simd> SimdBase<S> for u32x4<S>

Source§

impl<S: Simd> SimdBase<S> for u32x8<S>

Source§

impl<S: Simd> SimdBase<S> for u32x16<S>

Source§

impl<S: Simd> SimdBase<S> for u64x2<S>

Source§

impl<S: Simd> SimdBase<S> for u64x4<S>

Source§

impl<S: Simd> SimdBase<S> for u64x8<S>