Skip to main content

PackedField

Trait PackedField 

Source
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§

Source

const LOG_WIDTH: usize = Self::LOG_N

Base-2 logarithm of the number of field elements packed into one packed element.

This is the number of scalars the packed field divides into, i.e. its Divisible log-count.

Source

const WIDTH: usize = _

The number of field elements packed into one packed element.

WIDTH is guaranteed to equal 2^LOG_WIDTH.

Required Methods§

Source

fn from_fn(f: impl FnMut(usize) -> Self::Scalar) -> Self

Construct a packed field element from a function that returns scalar values by index.

Source

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_len must be strictly less than LOG_WIDTH.
Source

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_len must be strictly less than LOG_WIDTH.

Provided Methods§

Source

fn into_iter(self) -> impl ExactSizeIterator<Item = Self::Scalar> + Send + Clone

Yields one scalar per lane, from the lowest lane to the highest.

Source

fn iter( &self, ) -> impl ExactSizeIterator<Item = Self::Scalar> + Send + Clone + '_

Yields one scalar per lane, from the lowest lane to the highest.

Source

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.

Source

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.

Source

fn pow(self, exp: u64) -> Self

Returns the value to the power exp.

Source

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_len must be less than or equal to LOG_WIDTH.
  • block_idx must be less than 2^(Self::LOG_WIDTH - log_block_len).
Source

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", so this trait is not object safe.

Implementors§

Source§

impl PackedField for BinaryField1b

Source§

impl PackedField for Ghash128b

Source§

impl PackedField for GhashSq256b

Source§

impl PackedField for Rijndael8b

Source§

impl<F, PSub, const N: usize> PackedField for SlicedPackedField<F, PSub, N>
where F: ExtensionField<PSub::Scalar>, PSub: PackedField, Self: Square + InvertOrZero + Mul<Output = Self> + WideMul<Output: Debug + Send + Sync + 'static>,

Source§

impl<U, Scalar> PackedField for PackedPrimitiveType<U, Scalar>
where Self: Square + InvertOrZero + Mul<Output = Self> + WideMul<Output: Debug + Send + Sync + 'static>, U: Underlier + Divisible<Scalar::Underlier>, Scalar: BinaryField,