pub trait PackedField:
Default
+ Debug
+ Clone
+ Copy
+ Eq
+ Sized
+ FieldOps
+ Add<Self::Scalar, Output = Self>
+ Sub<Self::Scalar, Output = Self>
+ Mul<Self::Scalar, Output = Self>
+ AddAssign<Self::Scalar>
+ SubAssign<Self::Scalar>
+ MulAssign<Self::Scalar>
+ Send
+ Sync
+ Zeroable
+ Random
+ WideMul<Output: Debug + Send + Sync + 'static>
+ 'static
+ Divisible<Self::Scalar>
+ Maskable<Self::Scalar> {
const LOG_WIDTH: usize = Self::LOG_N;
const WIDTH: usize = _;
// Required methods
fn from_fn(f: impl FnMut(usize) -> Self::Scalar) -> Self;
fn interleave(self, other: Self, log_block_len: usize) -> (Self, Self);
fn unzip(self, other: Self, log_block_len: usize) -> (Self, Self);
// Provided methods
fn into_iter(
self,
) -> impl ExactSizeIterator<Item = Self::Scalar> + Send + Clone { ... }
fn iter(
&self,
) -> impl ExactSizeIterator<Item = Self::Scalar> + Send + Clone + '_ { ... }
fn iter_slice(
slice: &[Self],
) -> impl ExactSizeIterator<Item = Self::Scalar> + Send + Clone + '_ { ... }
fn from_scalars(values: impl IntoIterator<Item = Self::Scalar>) -> Self { ... }
fn pow(self, exp: u64) -> Self { ... }
fn spread(self, log_block_len: usize, block_idx: usize) -> Self { ... }
unsafe fn spread_unchecked(
self,
log_block_len: usize,
block_idx: usize,
) -> Self { ... }
}Expand description
A packed field represents a vector of underlying field elements.
Arithmetic operations on packed field elements can be accelerated with SIMD CPU instructions.
The vector width is a constant, WIDTH. This trait requires that the width must be a power of
two.
Provided Associated Constants§
Required Methods§
Sourcefn from_fn(f: impl FnMut(usize) -> Self::Scalar) -> Self
fn from_fn(f: impl FnMut(usize) -> Self::Scalar) -> Self
Construct a packed field element from a function that returns scalar values by index.
Sourcefn interleave(self, other: Self, log_block_len: usize) -> (Self, Self)
fn interleave(self, other: Self, log_block_len: usize) -> (Self, Self)
Interleaves blocks of this packed vector with another packed vector.
The operation can be seen as stacking the two vectors, dividing them into 2x2 matrices of
blocks, where each block is 2^log_block_width elements, and transposing the matrices.
Consider this example, where LOG_WIDTH is 3 and log_block_len is 1:
A = [a0, a1, a2, a3, a4, a5, a6, a7]
B = [b0, b1, b2, b3, b4, b5, b6, b7]
The interleaved result is A’ = [a0, a1, b0, b1, a4, a5, b4, b5] B’ = [a2, a3, b2, b3, a6, a7, b6, b7]
§Preconditions
log_block_lenmust be strictly less thanLOG_WIDTH.
Sourcefn unzip(self, other: Self, log_block_len: usize) -> (Self, Self)
fn unzip(self, other: Self, log_block_len: usize) -> (Self, Self)
Unzips interleaved blocks of this packed vector with another packed vector.
Consider this example, where LOG_WIDTH is 3 and log_block_len is 1:
A = [a0, a1, b0, b1, a2, a3, b2, b3]
B = [a4, a5, b4, b5, a6, a7, b6, b7]
The transposed result is A’ = [a0, a1, a2, a3, a4, a5, a6, a7] B’ = [b0, b1, b2, b3, b4, b5, b6, b7]
§Preconditions
log_block_lenmust be strictly less thanLOG_WIDTH.
Provided Methods§
Sourcefn into_iter(self) -> impl ExactSizeIterator<Item = Self::Scalar> + Send + Clone
fn into_iter(self) -> impl ExactSizeIterator<Item = Self::Scalar> + Send + Clone
Yields one scalar per lane, from the lowest lane to the highest.
Sourcefn iter(
&self,
) -> impl ExactSizeIterator<Item = Self::Scalar> + Send + Clone + '_
fn iter( &self, ) -> impl ExactSizeIterator<Item = Self::Scalar> + Send + Clone + '_
Yields one scalar per lane, from the lowest lane to the highest.
Sourcefn iter_slice(
slice: &[Self],
) -> impl ExactSizeIterator<Item = Self::Scalar> + Send + Clone + '_
fn iter_slice( slice: &[Self], ) -> impl ExactSizeIterator<Item = Self::Scalar> + Send + Clone + '_
Yields every scalar of the whole slice: element by element, each element’s lanes in order.
Sourcefn from_scalars(values: impl IntoIterator<Item = Self::Scalar>) -> Self
fn from_scalars(values: impl IntoIterator<Item = Self::Scalar>) -> Self
Construct a packed field element from a sequence of scalars.
If the number of values in the sequence is less than the packing width, the remaining elements are set to zero. If greater than the packing width, the excess elements are ignored.
Sourcefn spread(self, log_block_len: usize, block_idx: usize) -> Self
fn spread(self, log_block_len: usize, block_idx: usize) -> Self
Spread takes a block of elements within a packed field and repeats them to the full packing width.
Spread can be seen as an extension of the functionality of Divisible::broadcast.
§Examples
use binius_field::{BinaryField1b, PackedField, PackedBinaryField8x1b};
let input =
PackedBinaryField8x1b::from_scalars([0, 1, 0, 1, 0, 1, 0, 1].map(BinaryField1b::from));
assert_eq!(
input.spread(0, 1),
PackedBinaryField8x1b::from_scalars([1, 1, 1, 1, 1, 1, 1, 1].map(BinaryField1b::from))
);
assert_eq!(
input.spread(1, 0),
PackedBinaryField8x1b::from_scalars([0, 0, 0, 0, 1, 1, 1, 1].map(BinaryField1b::from))
);
assert_eq!(
input.spread(2, 0),
PackedBinaryField8x1b::from_scalars([0, 0, 1, 1, 0, 0, 1, 1].map(BinaryField1b::from))
);
assert_eq!(input.spread(3, 0), input);§Preconditions
log_block_lenmust be less than or equal toLOG_WIDTH.block_idxmust be less than2^(Self::LOG_WIDTH - log_block_len).
Sourceunsafe fn spread_unchecked(self, log_block_len: usize, block_idx: usize) -> Self
unsafe fn spread_unchecked(self, log_block_len: usize, block_idx: usize) -> Self
Unsafe version of Self::spread.
§Safety
The caller must ensure that log_block_len is less than or equal to LOG_WIDTH and
block_idx is less than 2^(Self::LOG_WIDTH - log_block_len).
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".