Skip to main content

Maskable

Trait Maskable 

Source
pub trait Maskable<T>:
    Divisible<T>
    + Copy
    + Zeroable {
    type Mask: Send + Sync;

    // Required methods
    fn make_mask(selectors: impl Iterator<Item = bool>) -> Self::Mask;
    fn select(&self, mask: &Self::Mask) -> Self;
}
Expand description

Branchless conditional lane selection for fields and packed fields.

Maskable<T> keeps a chosen subset of a value’s T-lanes and zeroes the rest, against a precomputed Self::Mask. It is the high-level, underlier-free primitive behind the branchless masked accumulation in the shift protocol: a mask is built once with make_mask and reused across many select calls, so the per-call cost is a single bitwise AND on a binary field.

It is a parent trait of Field (Maskable<Self>, a single lane) and PackedField (Maskable<Self::Scalar>, one entry per packed lane), mirroring how Divisible is a parent trait of both.

Required Associated Types§

Source

type Mask: Send + Sync

A precomputed mask selecting which T-lanes select keeps.

Send + Sync so a precomputed mask table can be shared across threads (e.g. a parallel fold over a precomputed Vec<Self::Mask>).

Required Methods§

Source

fn make_mask(selectors: impl Iterator<Item = bool>) -> Self::Mask

Builds a mask from per-lane boolean selectors, in LSB-to-MSB lane order (the same ordering as Divisible). Consumes at most Divisible::N selectors; any lane past the end of the iterator, or whose selector is false, is not selected.

Source

fn select(&self, mask: &Self::Mask) -> Self

Returns a value keeping the lanes selected when mask was built and zeroing the rest.

For a mask built by Self::make_mask(selectors), this equals

Self::from_iter(zip(self.ref_iter(), selectors)
    .map(|(val, selected)| if selected { val } else { <zero> }))

but branchless: on a binary field each selected lane of the mask is all-ones and each unselected lane all-zeros, so this is a single bitwise AND.

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 Maskable<AESTowerField8b> for AESTowerField8b

Source§

impl Maskable<BinaryField1b> for BinaryField1b

Source§

type Mask = SmallU<1>

Source§

impl Maskable<BinaryField128bGhash> for BinaryField128bGhash

Source§

impl Maskable<GhashSq256b> for GhashSq256b

Source§

type Mask = ScaledUnderlier<M128, 2>

Source§

impl<F, PSub, const N: usize> Maskable<F> for SlicedPackedField<F, PSub, N>
where F: ExtensionField<PSub::Scalar>, PSub: PackedField,

Source§

type Mask = <PSub as Maskable<<PSub as FieldOps>::Scalar>>::Mask

Source§

impl<U, Scalar> Maskable<Scalar> for PackedPrimitiveType<U, Scalar>
where U: UnderlierType + Divisible<Scalar::Underlier>, Scalar: BinaryField,

Source§

type Mask = U