Skip to main content

Backend

Trait Backend 

Source
pub trait Backend<T: Scalar>: Copy {
    type Vector: Copy;
    type Mask: Copy;
    type IVector: Copy;

    const UNROLL: usize = 4;
Show 55 methods // Required methods fn lanes(self) -> usize; fn splat(self, v: T) -> Self::Vector; fn load(self, s: &[T]) -> Self::Vector; fn store(self, v: Self::Vector, s: &mut [T]); fn add(self, a: Self::Vector, b: Self::Vector) -> Self::Vector; fn sub(self, a: Self::Vector, b: Self::Vector) -> Self::Vector; fn mul(self, a: Self::Vector, b: Self::Vector) -> Self::Vector; fn neg(self, a: Self::Vector) -> Self::Vector; fn min(self, a: Self::Vector, b: Self::Vector) -> Self::Vector; fn max(self, a: Self::Vector, b: Self::Vector) -> Self::Vector; fn le(self, a: Self::Vector, b: Self::Vector) -> Self::Mask; fn lt(self, a: Self::Vector, b: Self::Vector) -> Self::Mask; fn ge(self, a: Self::Vector, b: Self::Vector) -> Self::Mask; fn gt(self, a: Self::Vector, b: Self::Vector) -> Self::Mask; fn mask_and(self, a: Self::Mask, b: Self::Mask) -> Self::Mask; fn mask_or(self, a: Self::Mask, b: Self::Mask) -> Self::Mask; fn mask_not(self, a: Self::Mask) -> Self::Mask; fn select( self, m: Self::Mask, a: Self::Vector, b: Self::Vector, ) -> Self::Vector; fn any(self, m: Self::Mask) -> bool; fn all(self, m: Self::Mask) -> bool; fn reduce_sum(self, v: Self::Vector) -> T; fn reduce_min(self, v: Self::Vector) -> T; fn reduce_max(self, v: Self::Vector) -> T; fn iload(self, s: &[u32]) -> Self::IVector; fn istore(self, v: Self::IVector, out: &mut [u32]); // Provided methods fn div(self, _a: Self::Vector, _b: Self::Vector) -> Self::Vector where T: FloatScalar { ... } fn fma( self, _a: Self::Vector, _b: Self::Vector, _c: Self::Vector, ) -> Self::Vector where T: FloatScalar { ... } fn sqrt(self, _a: Self::Vector) -> Self::Vector where T: FloatScalar { ... } fn madd( self, a: Self::Vector, b: Self::Vector, acc: Self::Vector, ) -> Self::Vector { ... } fn shl(self, _a: Self::Vector, _k: u32) -> Self::Vector where T: IntScalar { ... } fn shr(self, _a: Self::Vector, _k: u32) -> Self::Vector where T: IntScalar { ... } fn bit_and(self, _a: Self::Vector, _b: Self::Vector) -> Self::Vector where T: IntScalar { ... } fn bit_or(self, _a: Self::Vector, _b: Self::Vector) -> Self::Vector where T: IntScalar { ... } fn bit_xor(self, _a: Self::Vector, _b: Self::Vector) -> Self::Vector where T: IntScalar { ... } fn bit_not(self, _a: Self::Vector) -> Self::Vector where T: IntScalar { ... } fn abs(self, a: Self::Vector) -> Self::Vector { ... } fn mask_bitmask(self, m: Self::Mask) -> u32 { ... } fn isplat(self, v: u32) -> Self::IVector { ... } fn iramp(self) -> Self::IVector { ... } fn iadd(self, a: Self::IVector, b: Self::IVector) -> Self::IVector { ... } fn isub(self, a: Self::IVector, b: Self::IVector) -> Self::IVector { ... } fn imul(self, a: Self::IVector, b: Self::IVector) -> Self::IVector { ... } fn iand(self, a: Self::IVector, b: Self::IVector) -> Self::IVector { ... } fn ior(self, a: Self::IVector, b: Self::IVector) -> Self::IVector { ... } fn ixor(self, a: Self::IVector, b: Self::IVector) -> Self::IVector { ... } fn inot(self, a: Self::IVector) -> Self::IVector { ... } fn ishl(self, a: Self::IVector, k: u32) -> Self::IVector { ... } fn ishr(self, a: Self::IVector, k: u32) -> Self::IVector { ... } fn ishr_arith(self, a: Self::IVector, k: u32) -> Self::IVector { ... } fn ieq(self, a: Self::IVector, b: Self::IVector) -> Self::Mask { ... } fn ilt_u(self, a: Self::IVector, b: Self::IVector) -> Self::Mask { ... } fn ilt_s(self, a: Self::IVector, b: Self::IVector) -> Self::Mask { ... } fn iselect( self, m: Self::Mask, a: Self::IVector, b: Self::IVector, ) -> Self::IVector { ... } fn to_bits(self, v: Self::Vector) -> Self::IVector { ... } fn from_bits(self, v: Self::IVector) -> Self::Vector { ... }
}
Expand description

An instruction-set execution context for scalar T. Implemented by ScalarBackend (every T) and, per (ISA, scalar), by the hand-rolled core::arch backends.

Provided Associated Constants§

Source

const UNROLL: usize = 4

Independent accumulator chains the multi-accumulator reductions (Gang::reduce, Gang::zip_reduce, Gang::count_n) run: the ILP unroll factor, a compile-time constant baked in at dispatch. Must not exceed MAX_UNROLL. The default suits x86’s 2–3 vector pipes; wide cores (Apple NEON, SVE) raise it, the scalar floor drops it to 1.

Required Associated Types§

Source

type Vector: Copy

The varying register holding Backend::lanes elements of T.

Source

type Mask: Copy

The boolean mask companion to Backend::Vector.

Source

type IVector: Copy

The 32-bit integer companion register: lanes() lanes of u32 (reinterpretable as i32) riding alongside the float lanes, for lane indices, counters, and bit manipulation. Every default below is a correct-but-slow store/compute/reload round-trip; backends with native integer lanes override the ones that matter.

Required Methods§

Source

fn lanes(self) -> usize

Number of T lanes in one register under this backend.

Source

fn splat(self, v: T) -> Self::Vector

Source

fn load(self, s: &[T]) -> Self::Vector

Load exactly one register. s.len() must equal Backend::lanes.

Source

fn store(self, v: Self::Vector, s: &mut [T])

Store exactly one register. s.len() must equal Backend::lanes.

Source

fn add(self, a: Self::Vector, b: Self::Vector) -> Self::Vector

Source

fn sub(self, a: Self::Vector, b: Self::Vector) -> Self::Vector

Source

fn mul(self, a: Self::Vector, b: Self::Vector) -> Self::Vector

Source

fn neg(self, a: Self::Vector) -> Self::Vector

Negation: IEEE sign flip for the float elements, wrapping for the integer elements.

Source

fn min(self, a: Self::Vector, b: Self::Vector) -> Self::Vector

Lane-wise IEEE 754-2019 minimumNumber: if exactly one operand of a lane is NaN, that lane takes the other operand; NaN comes out only when both are NaN. Which zero wins a -0.0/+0.0 tie is backend-specific. Every backend implements this contract, natively where the ISA has it (aarch64 FMINNM, RVV vfmin), with a NaN-patching fixup where it doesn’t (x86 min + unord-blend, wasm pmin + bitselect).

Source

fn max(self, a: Self::Vector, b: Self::Vector) -> Self::Vector

Lane-wise IEEE 754-2019 maximumNumber; see min for the NaN contract.

Source

fn le(self, a: Self::Vector, b: Self::Vector) -> Self::Mask

Source

fn lt(self, a: Self::Vector, b: Self::Vector) -> Self::Mask

Source

fn ge(self, a: Self::Vector, b: Self::Vector) -> Self::Mask

Source

fn gt(self, a: Self::Vector, b: Self::Vector) -> Self::Mask

Source

fn mask_and(self, a: Self::Mask, b: Self::Mask) -> Self::Mask

Source

fn mask_or(self, a: Self::Mask, b: Self::Mask) -> Self::Mask

Source

fn mask_not(self, a: Self::Mask) -> Self::Mask

Source

fn select(self, m: Self::Mask, a: Self::Vector, b: Self::Vector) -> Self::Vector

Source

fn any(self, m: Self::Mask) -> bool

Cross-lane: true if any active lane of the mask is set.

Source

fn all(self, m: Self::Mask) -> bool

Cross-lane: true if every lane of the mask is set.

Source

fn reduce_sum(self, v: Self::Vector) -> T

Source

fn reduce_min(self, v: Self::Vector) -> T

Horizontal minimum with min’s minimumNumber semantics folded pairwise: NaN lanes are ignored, and the result is NaN only if every lane is NaN.

Source

fn reduce_max(self, v: Self::Vector) -> T

Horizontal maximum; see reduce_min.

Source

fn iload(self, s: &[u32]) -> Self::IVector

Load exactly lanes() integers.

Source

fn istore(self, v: Self::IVector, out: &mut [u32])

Store exactly lanes() integers.

Provided Methods§

Source

fn div(self, _a: Self::Vector, _b: Self::Vector) -> Self::Vector
where T: FloatScalar,

Float-family only. where T: FloatScalar makes integer-element calls a compile error, so the defaults below are statically unreachable; float backends override them.

Source

fn fma( self, _a: Self::Vector, _b: Self::Vector, _c: Self::Vector, ) -> Self::Vector
where T: FloatScalar,

Source

fn sqrt(self, _a: Self::Vector) -> Self::Vector
where T: FloatScalar,

Source

fn madd( self, a: Self::Vector, b: Self::Vector, acc: Self::Vector, ) -> Self::Vector

a*b + acc with the element family’s natural fusion: float backends override this with their fused fma; integer elements and the portable default use the two-op multiply-add (wrapping for ints). Family-neutral so shared machinery (the runtime unroll sweep, generic reduction steps) can use it without a FloatScalar bound.

Source

fn shl(self, _a: Self::Vector, _k: u32) -> Self::Vector
where T: IntScalar,

Integer-family only: lane-wise shift by a uniform count (k < 32). shr is logical (zero-filling) for u32, arithmetic (sign-filling) for i32. Statically unreachable defaults, same scheme as div.

Source

fn shr(self, _a: Self::Vector, _k: u32) -> Self::Vector
where T: IntScalar,

Source

fn bit_and(self, _a: Self::Vector, _b: Self::Vector) -> Self::Vector
where T: IntScalar,

Integer-family lane-wise bitwise ops.

Source

fn bit_or(self, _a: Self::Vector, _b: Self::Vector) -> Self::Vector
where T: IntScalar,

Source

fn bit_xor(self, _a: Self::Vector, _b: Self::Vector) -> Self::Vector
where T: IntScalar,

Source

fn bit_not(self, _a: Self::Vector) -> Self::Vector
where T: IntScalar,

Source

fn abs(self, a: Self::Vector) -> Self::Vector

Absolute value. The default is max(a, -a); backends override with a dedicated instruction or a sign-bit clear.

Source

fn mask_bitmask(self, m: Self::Mask) -> u32

Pack the mask into the low lanes bits of a u32: bit i set iff lane i is set; bits at and above lanes() are zero. Lets a caller popcount the set lanes or walk them by trailing_zeros. The default materializes the mask through select+store and packs scalar; fixed-width backends override it with a native movemask. lanes() never exceeds MAX_LANES (32), so a u32 always has room.

Source

fn isplat(self, v: u32) -> Self::IVector

Source

fn iramp(self) -> Self::IVector

Lane indices 0, 1, …, lanes()-1.

Source

fn iadd(self, a: Self::IVector, b: Self::IVector) -> Self::IVector

Wrapping lane-wise arithmetic, matching SIMD integer instruction semantics.

Source

fn isub(self, a: Self::IVector, b: Self::IVector) -> Self::IVector

Source

fn imul(self, a: Self::IVector, b: Self::IVector) -> Self::IVector

Low 32 bits of the lane-wise product (vmul/pmulld semantics, identical for u32 and i32).

Source

fn iand(self, a: Self::IVector, b: Self::IVector) -> Self::IVector

Source

fn ior(self, a: Self::IVector, b: Self::IVector) -> Self::IVector

Source

fn ixor(self, a: Self::IVector, b: Self::IVector) -> Self::IVector

Source

fn inot(self, a: Self::IVector) -> Self::IVector

Source

fn ishl(self, a: Self::IVector, k: u32) -> Self::IVector

Lane-wise shifts by a uniform count; k must be < 32.

Source

fn ishr(self, a: Self::IVector, k: u32) -> Self::IVector

Logical (zero-filling) right shift; k must be < 32.

Source

fn ishr_arith(self, a: Self::IVector, k: u32) -> Self::IVector

Arithmetic (sign-filling) right shift, for the i32 view; k must be < 32.

Source

fn ieq(self, a: Self::IVector, b: Self::IVector) -> Self::Mask

Source

fn ilt_u(self, a: Self::IVector, b: Self::IVector) -> Self::Mask

Unsigned lane-wise <.

Source

fn ilt_s(self, a: Self::IVector, b: Self::IVector) -> Self::Mask

Signed lane-wise < (the i32 view).

Source

fn iselect( self, m: Self::Mask, a: Self::IVector, b: Self::IVector, ) -> Self::IVector

m ? a : b on integer lanes, with the same Mask the float compares produce.

Source

fn to_bits(self, v: Self::Vector) -> Self::IVector

Reinterpret each float lane’s bit pattern as a u32 lane: exact for 32-bit T; 16-bit T zero-extends; f64 truncates to the low half (see Scalar::to_bits32).

Source

fn from_bits(self, v: Self::IVector) -> Self::Vector

Inverse of to_bits.

Dyn Compatibility§

This trait is not dyn compatible.

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

Implementors§