pub trait Vectorizable<V>: Sized {
    type Padding;
    type Vectorizer: Vectorizer<V>;

    // Required method
    fn create(
        self,
        pad: Option<Self::Padding>
    ) -> (Self::Vectorizer, usize, Option<V>);

    // Provided methods
    fn vectorize(self) -> VectorizedIter<Self::Vectorizer, (), V>  { ... }
    fn vectorize_pad(
        self,
        pad: Self::Padding
    ) -> VectorizedIter<Self::Vectorizer, Option<V>, V>  { ... }
}
Expand description

A trait describing things with direct support for splitting into vectors.

This supports vectorized iteration over shared and mutable slices as well as types composed of them (tuples and short fixed-sized arrays).

Note that, unlike normal iterators, shared slices return owned values (vectors) and mutable slices return proxy objects that allow writing the data back. It is not possible to directly borrow from the slice because of alignment. The tuples and arrays return tuples and arrays of the inner values.

Already pre-vectorized inputs are also supported (this is useful in combination with other not vectorized inputs).

Type hints

Oftentimes, the compiler can infer the type of the base type, but not the length of the vector. It is therefore needed to provide a type hint.

Furthermore, for tuples and arrays, the inner type really needs to be the slice, not something that can coerce into it (eg. vec or array).

Alternatively, you can use the free-standing functions vectorize and vectorize_pad. It allows using the turbofish to provide the hint.

Examples

let data = [1, 2, 3, 4];
let v = data.vectorize().collect::<Vec<u32x2>>();
assert_eq!(vec![u32x2::new([1, 2]), u32x2::new([3, 4])], v);
let data = [1, 2, 3, 4];
for v in data.vectorize() {
    let v: u32x2 = v; // Type hint
    println!("{:?}", v);
}
let input = [1, 2, 3, 4];
let mut output = [0; 4];
let mul = u32x2::splat(2);
// We have to force the coercion to slice by [..]
for (i, mut o) in (&input[..], &mut output[..]).vectorize() {
    *o = mul * i;
}
assert_eq!(output, [2, 4, 6, 8]);
let vectorized = [u32x2::new([1, 2]), u32x2::new([3, 4])];
let not_vectorized = [1, 2, 3, 4];
for (v, n) in (&vectorized[..], &not_vectorized[..]).vectorize() {
    assert_eq!(v, n);
}

Required Associated Types§

source

type Padding

The input type provided by user to fill in the padding/uneven end.

Note that this doesn’t necessarily have to be the same type as the type returned by the resulting iterator. For example, in case of mutable slices, the input is the vector, while the output is MutProxy.

source

type Vectorizer: Vectorizer<V>

An internal type managing the splitting into vectors.

Not of direct interest of the users of this crate.

Required Methods§

source

fn create( self, pad: Option<Self::Padding> ) -> (Self::Vectorizer, usize, Option<V>)

Internal method to create the vectorizer and kick of the iteration.

Provided Methods§

source

fn vectorize(self) -> VectorizedIter<Self::Vectorizer, (), V>

Vectorize a slice or composite of slices

This variant assumes the input is divisible by the size of the vector. Prefer this if possible over vectorize_pad, as it is usually significantly faster.

Panics
  • If the slice length isn’t divisible by the vector size.
  • If the parts of the composite produce different number of vectors. It is not mandated for the slices to be of equal length, only to produce the same number of vectors.
Examples
let longer = [1, 2, 3, 4, 5, 6, 7, 8];
let shorter = [1, 2, 3, 4];
for i in (&shorter[..], &longer[..]).vectorize() {
    let (s, l): (u32x2, u32x4) = i;
    println!("s: {:?}, l: {:?})", s, l);
}
source

fn vectorize_pad( self, pad: Self::Padding ) -> VectorizedIter<Self::Vectorizer, Option<V>, V>

Vectorizes a slice or composite of slices, padding the odd end if needed.

While the vectorize assumes the input can be split into vectors without leftover, this version deals with the uneven rest by producing a padding vector (if needed). The unused lanes are taken from the pad parameter. This is at the cost of some performance (TODO: figure out why it is so much slower).

For mutable slices, padding is used as usual, but the added lanes are not stored anywhere.

The padding is produced at the end.

In case of composites, this still assumes they produce the same number of full vectors and that they all either do or don’t need a padding.

Panics

If the above assumption about number of vectors and same padding behaviour is violated.

let data = [1, 2, 3, 4, 5, 6];
let v = data.vectorize_pad(i32x4::splat(-1)).collect::<Vec<_>>();
assert_eq!(v, vec![i32x4::new([1, 2, 3, 4]), i32x4::new([5, 6, -1, -1])]);

Implementations on Foreign Types§

source§

impl<'a, A: Align, B: Repr, const S: usize> Vectorizable<Vector<A, B, S>> for &'a [B]

§

type Vectorizer = ReadVectorizer<'a, A, B, S>

§

type Padding = Vector<A, B, S>

source§

fn create( self, pad: Option<Vector<A, B, S>> ) -> (Self::Vectorizer, usize, Option<Vector<A, B, S>>)

source§

impl<'a, A: Align, B: Repr, const S: usize> Vectorizable<MutProxy<'a, B, Vector<A, B, S>>> for &'a mut [B]

§

type Vectorizer = WriteVectorizer<'a, A, B, S>

§

type Padding = Vector<A, B, S>

source§

fn create( self, pad: Option<Vector<A, B, S>> ) -> (Self::Vectorizer, usize, Option<MutProxy<'a, B, Vector<A, B, S>>>)

source§

impl<A, AR, B, BR> Vectorizable<(AR, BR)> for (A, B)where A: Vectorizable<AR>, B: Vectorizable<BR>,

§

type Vectorizer = (<A as Vectorizable<AR>>::Vectorizer, <B as Vectorizable<BR>>::Vectorizer)

§

type Padding = (<A as Vectorizable<AR>>::Padding, <B as Vectorizable<BR>>::Padding)

source§

fn create( self, pad: Option<Self::Padding> ) -> (Self::Vectorizer, usize, Option<(AR, BR)>)

source§

impl<A, AR, B, BR, C, CR> Vectorizable<(AR, BR, CR)> for (A, B, C)where A: Vectorizable<AR>, B: Vectorizable<BR>, C: Vectorizable<CR>,

§

type Vectorizer = (<A as Vectorizable<AR>>::Vectorizer, <B as Vectorizable<BR>>::Vectorizer, <C as Vectorizable<CR>>::Vectorizer)

§

type Padding = (<A as Vectorizable<AR>>::Padding, <B as Vectorizable<BR>>::Padding, <C as Vectorizable<CR>>::Padding)

source§

fn create( self, pad: Option<Self::Padding> ) -> (Self::Vectorizer, usize, Option<(AR, BR, CR)>)

source§

impl<A, AR, B, BR, C, CR, D, DR> Vectorizable<(AR, BR, CR, DR)> for (A, B, C, D)where A: Vectorizable<AR>, B: Vectorizable<BR>, C: Vectorizable<CR>, D: Vectorizable<DR>,

§

type Vectorizer = (<A as Vectorizable<AR>>::Vectorizer, <B as Vectorizable<BR>>::Vectorizer, <C as Vectorizable<CR>>::Vectorizer, <D as Vectorizable<DR>>::Vectorizer)

§

type Padding = (<A as Vectorizable<AR>>::Padding, <B as Vectorizable<BR>>::Padding, <C as Vectorizable<CR>>::Padding, <D as Vectorizable<DR>>::Padding)

source§

fn create( self, pad: Option<Self::Padding> ) -> (Self::Vectorizer, usize, Option<(AR, BR, CR, DR)>)

source§

impl<A, AR, B, BR, C, CR, D, DR, E, ER> Vectorizable<(AR, BR, CR, DR, ER)> for (A, B, C, D, E)where A: Vectorizable<AR>, B: Vectorizable<BR>, C: Vectorizable<CR>, D: Vectorizable<DR>, E: Vectorizable<ER>,

§

type Vectorizer = (<A as Vectorizable<AR>>::Vectorizer, <B as Vectorizable<BR>>::Vectorizer, <C as Vectorizable<CR>>::Vectorizer, <D as Vectorizable<DR>>::Vectorizer, <E as Vectorizable<ER>>::Vectorizer)

§

type Padding = (<A as Vectorizable<AR>>::Padding, <B as Vectorizable<BR>>::Padding, <C as Vectorizable<CR>>::Padding, <D as Vectorizable<DR>>::Padding, <E as Vectorizable<ER>>::Padding)

source§

fn create( self, pad: Option<Self::Padding> ) -> (Self::Vectorizer, usize, Option<(AR, BR, CR, DR, ER)>)

source§

impl<A, AR, B, BR, C, CR, D, DR, E, ER, F, FR> Vectorizable<(AR, BR, CR, DR, ER, FR)> for (A, B, C, D, E, F)where A: Vectorizable<AR>, B: Vectorizable<BR>, C: Vectorizable<CR>, D: Vectorizable<DR>, E: Vectorizable<ER>, F: Vectorizable<FR>,

§

type Vectorizer = (<A as Vectorizable<AR>>::Vectorizer, <B as Vectorizable<BR>>::Vectorizer, <C as Vectorizable<CR>>::Vectorizer, <D as Vectorizable<DR>>::Vectorizer, <E as Vectorizable<ER>>::Vectorizer, <F as Vectorizable<FR>>::Vectorizer)

§

type Padding = (<A as Vectorizable<AR>>::Padding, <B as Vectorizable<BR>>::Padding, <C as Vectorizable<CR>>::Padding, <D as Vectorizable<DR>>::Padding, <E as Vectorizable<ER>>::Padding, <F as Vectorizable<FR>>::Padding)

source§

fn create( self, pad: Option<Self::Padding> ) -> (Self::Vectorizer, usize, Option<(AR, BR, CR, DR, ER, FR)>)

source§

impl<A, AR, B, BR, C, CR, D, DR, E, ER, F, FR, G, GR> Vectorizable<(AR, BR, CR, DR, ER, FR, GR)> for (A, B, C, D, E, F, G)where A: Vectorizable<AR>, B: Vectorizable<BR>, C: Vectorizable<CR>, D: Vectorizable<DR>, E: Vectorizable<ER>, F: Vectorizable<FR>, G: Vectorizable<GR>,

§

type Vectorizer = (<A as Vectorizable<AR>>::Vectorizer, <B as Vectorizable<BR>>::Vectorizer, <C as Vectorizable<CR>>::Vectorizer, <D as Vectorizable<DR>>::Vectorizer, <E as Vectorizable<ER>>::Vectorizer, <F as Vectorizable<FR>>::Vectorizer, <G as Vectorizable<GR>>::Vectorizer)

§

type Padding = (<A as Vectorizable<AR>>::Padding, <B as Vectorizable<BR>>::Padding, <C as Vectorizable<CR>>::Padding, <D as Vectorizable<DR>>::Padding, <E as Vectorizable<ER>>::Padding, <F as Vectorizable<FR>>::Padding, <G as Vectorizable<GR>>::Padding)

source§

fn create( self, pad: Option<Self::Padding> ) -> (Self::Vectorizer, usize, Option<(AR, BR, CR, DR, ER, FR, GR)>)

source§

impl<A, AR, B, BR, C, CR, D, DR, E, ER, F, FR, G, GR, H, HR> Vectorizable<(AR, BR, CR, DR, ER, FR, GR, HR)> for (A, B, C, D, E, F, G, H)where A: Vectorizable<AR>, B: Vectorizable<BR>, C: Vectorizable<CR>, D: Vectorizable<DR>, E: Vectorizable<ER>, F: Vectorizable<FR>, G: Vectorizable<GR>, H: Vectorizable<HR>,

§

type Vectorizer = (<A as Vectorizable<AR>>::Vectorizer, <B as Vectorizable<BR>>::Vectorizer, <C as Vectorizable<CR>>::Vectorizer, <D as Vectorizable<DR>>::Vectorizer, <E as Vectorizable<ER>>::Vectorizer, <F as Vectorizable<FR>>::Vectorizer, <G as Vectorizable<GR>>::Vectorizer, <H as Vectorizable<HR>>::Vectorizer)

§

type Padding = (<A as Vectorizable<AR>>::Padding, <B as Vectorizable<BR>>::Padding, <C as Vectorizable<CR>>::Padding, <D as Vectorizable<DR>>::Padding, <E as Vectorizable<ER>>::Padding, <F as Vectorizable<FR>>::Padding, <G as Vectorizable<GR>>::Padding, <H as Vectorizable<HR>>::Padding)

source§

fn create( self, pad: Option<Self::Padding> ) -> (Self::Vectorizer, usize, Option<(AR, BR, CR, DR, ER, FR, GR, HR)>)

source§

impl<T, TR, const S: usize> Vectorizable<[TR; S]> for [T; S]where T: Vectorizable<TR> + Copy, T::Padding: Copy,

§

type Vectorizer = [<T as Vectorizable<TR>>::Vectorizer; S]

§

type Padding = [<T as Vectorizable<TR>>::Padding; S]

source§

fn create( self, pad: Option<Self::Padding> ) -> (Self::Vectorizer, usize, Option<[TR; S]>)

source§

impl<'a, A: Align, B: Repr, const S: usize> Vectorizable<Vector<A, B, S>> for &'a [Vector<A, B, S>]

§

type Padding = ()

§

type Vectorizer = &'a [Vector<A, B, S>]

source§

fn create( self, _pad: Option<()> ) -> (Self::Vectorizer, usize, Option<Vector<A, B, S>>)

source§

impl<'a, A: Align, B: Repr, const S: usize> Vectorizable<&'a mut Vector<A, B, S>> for &'a mut [Vector<A, B, S>]

§

type Padding = ()

§

type Vectorizer = &'a mut [Vector<A, B, S>]

source§

fn create( self, _pad: Option<()> ) -> (Self::Vectorizer, usize, Option<&'a mut Vector<A, B, S>>)

Implementors§