Skip to main content

SimdKernel

Trait SimdKernel 

Source
pub trait SimdKernel<T>:
    Sized
    + Sealed
    + Send
    + Sync
    + 'static
where T: NumericElement,
{ type Vector: Copy + Send + Sync + 'static; type Mask: Copy + Send + Sync + 'static; type IndexVector: Copy + Send + Sync + 'static; const LANE_COUNT: usize; const LANE_BOUND_CHECK: () = _; const UNROLL_FACTOR: usize = 4; const SUPPORTS_NT_STORE: bool = false;
Show 59 methods // Required methods unsafe fn load_aligned(ptr: *const T) -> Self::Vector; unsafe fn load_unaligned(ptr: *const T) -> Self::Vector; unsafe fn store_aligned(ptr: *mut T, val: Self::Vector); unsafe fn store_unaligned(ptr: *mut T, val: Self::Vector); unsafe fn add(a: Self::Vector, b: Self::Vector) -> Self::Vector; unsafe fn mul(a: Self::Vector, b: Self::Vector) -> Self::Vector; unsafe fn fmadd( a: Self::Vector, b: Self::Vector, c: Self::Vector, ) -> Self::Vector; unsafe fn sum_reduce(v: Self::Vector) -> T; unsafe fn compress(src: Self::Vector, mask: Self::Mask) -> Self::Vector; unsafe fn expand( src: Self::Vector, mask: Self::Mask, fill: Self::Vector, ) -> Self::Vector; unsafe fn gather(base: *const T, indices: Self::IndexVector) -> Self::Vector; unsafe fn gather_masked( base: *const T, indices: Self::IndexVector, mask: Self::Mask, src: Self::Vector, ) -> Self::Vector; unsafe fn mask_from_bools(bits: &[bool]) -> Self::Mask; unsafe fn leading_k_mask(k: usize) -> Self::Mask; unsafe fn mask_to_vector(mask: Self::Mask) -> Self::Vector; unsafe fn vector_to_mask(v: Self::Vector) -> Self::Mask; unsafe fn splat(val: T) -> Self::Vector; unsafe fn mask_to_bitmask(mask: Self::Mask) -> u64; // Provided methods unsafe fn store_streaming(ptr: *mut T, val: Self::Vector) { ... } fn stream_write_barrier() { ... } unsafe fn sub(a: Self::Vector, b: Self::Vector) -> Self::Vector { ... } unsafe fn masked_load_unaligned( ptr: *const T, mask: Self::Mask, src: Self::Vector, ) -> Self::Vector { ... } unsafe fn masked_store_unaligned( ptr: *mut T, mask: Self::Mask, val: Self::Vector, ) { ... } unsafe fn masked_add( a: Self::Vector, b: Self::Vector, mask: Self::Mask, src: Self::Vector, ) -> Self::Vector { ... } unsafe fn masked_mul( a: Self::Vector, b: Self::Vector, mask: Self::Mask, src: Self::Vector, ) -> Self::Vector { ... } unsafe fn masked_fmadd( a: Self::Vector, b: Self::Vector, c: Self::Vector, mask: Self::Mask, ) -> Self::Vector { ... } unsafe fn masked_sum_reduce(v: Self::Vector, mask: Self::Mask) -> T { ... } unsafe fn mask_from_bitmask(bm: u64) -> Self::Mask { ... } unsafe fn scan_vector<Op, SMode>( v: Self::Vector, carry: T, ) -> (Self::Vector, T) where Op: ScanOp<T>, SMode: ScanMode { ... } unsafe fn zero() -> Self::Vector { ... } unsafe fn div(a: Self::Vector, b: Self::Vector) -> Self::Vector { ... } unsafe fn bitand(a: Self::Vector, b: Self::Vector) -> Self::Vector { ... } unsafe fn bitor(a: Self::Vector, b: Self::Vector) -> Self::Vector { ... } unsafe fn bitxor(a: Self::Vector, b: Self::Vector) -> Self::Vector { ... } unsafe fn abs(a: Self::Vector) -> Self::Vector { ... } unsafe fn min(a: Self::Vector, b: Self::Vector) -> Self::Vector { ... } unsafe fn max(a: Self::Vector, b: Self::Vector) -> Self::Vector { ... } unsafe fn sqrt(a: Self::Vector) -> Self::Vector { ... } unsafe fn recip_sqrt(a: Self::Vector) -> Self::Vector { ... } unsafe fn cmp_eq(a: Self::Vector, b: Self::Vector) -> Self::Vector { ... } unsafe fn cmp_ne(a: Self::Vector, b: Self::Vector) -> Self::Vector { ... } unsafe fn cmp_lt(a: Self::Vector, b: Self::Vector) -> Self::Vector { ... } unsafe fn cmp_le(a: Self::Vector, b: Self::Vector) -> Self::Vector { ... } unsafe fn cmp_gt(a: Self::Vector, b: Self::Vector) -> Self::Vector { ... } unsafe fn cmp_ge(a: Self::Vector, b: Self::Vector) -> Self::Vector { ... } unsafe fn blend( mask: Self::Vector, true_val: Self::Vector, false_val: Self::Vector, ) -> Self::Vector { ... } unsafe fn neg(a: Self::Vector) -> Self::Vector { ... } unsafe fn bitnot(a: Self::Vector) -> Self::Vector { ... } unsafe fn min_reduce(v: Self::Vector) -> T { ... } unsafe fn max_reduce(v: Self::Vector) -> T { ... } unsafe fn popcount(a: Self::Vector) -> Self::Vector { ... } unsafe fn horizontal_bitwise_and(v: Self::Vector) -> T { ... } unsafe fn horizontal_bitwise_or(v: Self::Vector) -> T { ... } unsafe fn horizontal_bitwise_xor(v: Self::Vector) -> T { ... } unsafe fn swap_adjacent(v: Self::Vector) -> Self::Vector { ... } unsafe fn dup_even(v: Self::Vector) -> Self::Vector { ... } unsafe fn dup_odd(v: Self::Vector) -> Self::Vector { ... } unsafe fn fmaddsub( a: Self::Vector, b: Self::Vector, c: Self::Vector, ) -> Self::Vector { ... } unsafe fn fmsubadd( a: Self::Vector, b: Self::Vector, c: Self::Vector, ) -> Self::Vector { ... }
}
Expand description

Abstract trait defining low-level vector operations.

Implemented by ZST architecture markers. All methods are unsafe — the caller is responsible for ensuring target-feature prerequisites are satisfied. The #[target_feature] attribute on each impl block ensures the compiler emits the correct machine instruction; calling from a non-gated context requires wrapping in an unsafe { ... } block inside a function that is itself gated by #[target_feature(enable = "...")].

§Examples

Use the always-available Scalar backend for cross-platform code paths:

use hermes_simd_intrinsics::Scalar;
use hermes_simd_core::kernel::SimdKernel;

// SAFETY: `Scalar` requires no special ISA features.
let splat4: <Scalar as SimdKernel<f32>>::Vector =
    unsafe { <Scalar as SimdKernel<f32>>::splat(1.0_f32) };
let sum: f32 = unsafe { <Scalar as SimdKernel<f32>>::sum_reduce(splat4) };
assert_eq!(sum, <Scalar as SimdKernel<f32>>::LANE_COUNT as f32);

Required Associated Constants§

Source

const LANE_COUNT: usize

Number of primitive elements of type T in one Vector.

Provided Associated Constants§

Source

const LANE_BOUND_CHECK: () = _

Compile-time guard that LANE_COUNT fits the fixed MAX_SIMD_LANES scalar-fallback stack buffers. Referencing this const in the buffer-using default methods forces the assertion to be evaluated for each concrete backend at monomorphization, turning a would-be silent stack-buffer overflow into a compile error.

Source

const UNROLL_FACTOR: usize = 4

Loop unrolling register accumulation factor to break loop-carried dependency chains.

Source

const SUPPORTS_NT_STORE: bool = false

Whether this backend provides a non-temporal (cache-bypassing) store via store_streaming. Backends leaving this false keep the regular store default; callers gate the streaming path on this const so it is a compile-time branch, dead-code-eliminated where unsupported.

Required Associated Types§

Source

type Vector: Copy + Send + Sync + 'static

The underlying raw register/vector type for this architecture and element type.

Source

type Mask: Copy + Send + Sync + 'static

Hardware-native mask type.

  • AVX-512 f32: __mmask16
  • AVX-512 f64: __mmask8
  • AVX2 f32: __m256 (float blend mask)
  • AVX2 f64: __m256d
  • NEON f32: uint32x4_t
  • NEON f64: uint64x2_t
  • Scalar f32: [bool; 4]
  • Scalar f64: [bool; 2]
Source

type IndexVector: Copy + Send + Sync + 'static

Integer index vector for gather operations.

  • AVX-512 f32 (16-lane): __m512i (16xi32)
  • AVX-512 f64 (8-lane): __m256i (8xi32)
  • AVX2 f32 (8-lane): __m256i (8xi32)
  • AVX2 f64 (4-lane): __m128i (4xi32)
  • NEON / Scalar: [i32; LANE_COUNT]

Required Methods§

Source

unsafe fn load_aligned(ptr: *const T) -> Self::Vector

Load a vector from an aligned pointer.

§Safety

ptr must be valid for reads and aligned to LANE_COUNT * size_of::<T>() bytes.

§Examples
use hermes_simd_intrinsics::Scalar;
use hermes_simd_core::kernel::SimdKernel;

#[repr(align(64))]
struct AlignedBuf([f32; 4]);

let buf = AlignedBuf([1.0, 2.0, 3.0, 4.0]);
// SAFETY: buf is 64-byte aligned and valid for LANE_COUNT reads.
let v = unsafe { <Scalar as SimdKernel<f32>>::load_aligned(buf.0.as_ptr()) };
let sum: f32 = unsafe { <Scalar as SimdKernel<f32>>::sum_reduce(v) };
assert_eq!(sum, 10.0_f32);
Source

unsafe fn load_unaligned(ptr: *const T) -> Self::Vector

Load a vector from an unaligned pointer.

§Safety

ptr must be valid for reads.

Source

unsafe fn store_aligned(ptr: *mut T, val: Self::Vector)

Store a vector to an aligned pointer.

§Safety

ptr must be valid for writes and aligned to LANE_COUNT * size_of::<T>() bytes.

Source

unsafe fn store_unaligned(ptr: *mut T, val: Self::Vector)

Store a vector to an unaligned pointer.

§Safety

ptr must be valid for writes.

Source

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

Elementwise addition: a + b.

§Safety

Processor must support the required target feature.

Source

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

Elementwise multiplication: a * b.

§Safety

Processor must support the required target feature.

Source

unsafe fn fmadd( a: Self::Vector, b: Self::Vector, c: Self::Vector, ) -> Self::Vector

Fused multiply-add: (a * b) + c.

§Safety

Processor must support the required target feature.

Source

unsafe fn sum_reduce(v: Self::Vector) -> T

Horizontal sum of all lanes.

§Safety

Processor must support the required target feature.

§Examples
use hermes_simd_intrinsics::Scalar;
use hermes_simd_core::kernel::SimdKernel;

let data = [1.0_f32, 2.0, 3.0, 4.0];
// SAFETY: Scalar requires no ISA feature; pointer is valid for LANE_COUNT reads.
let v = unsafe { <Scalar as SimdKernel<f32>>::load_unaligned(data.as_ptr()) };
let total: f32 = unsafe { <Scalar as SimdKernel<f32>>::sum_reduce(v) };
assert!((total - 10.0_f32).abs() < 1e-6);
Source

unsafe fn compress(src: Self::Vector, mask: Self::Mask) -> Self::Vector

Compress: pack selected lanes (where mask[i]=1) into the low lanes of the result.

Unselected high lanes of the result are unspecified.

§Safety

Processor must support the required target feature.

Source

unsafe fn expand( src: Self::Vector, mask: Self::Mask, fill: Self::Vector, ) -> Self::Vector

Expand: scatter the low lanes of src into result positions where mask[i]=1.

Result positions where mask[i]=0 are filled with fill.

§Safety

Processor must support the required target feature.

Source

unsafe fn gather(base: *const T, indices: Self::IndexVector) -> Self::Vector

Gather: load LANE_COUNT elements at base + indices[i] for each lane i.

§Safety

All base + indices[i] must be valid for reads.

Source

unsafe fn gather_masked( base: *const T, indices: Self::IndexVector, mask: Self::Mask, src: Self::Vector, ) -> Self::Vector

Masked gather: gather active lanes; inactive lanes take value from src.

§Safety

Active base + indices[i] must be valid for reads.

Source

unsafe fn mask_from_bools(bits: &[bool]) -> Self::Mask

Construct a mask from a slice of booleans (length must equal LANE_COUNT).

§Panics

Panics in debug builds if bits.len() != LANE_COUNT.

§Safety

Processor must support the required target feature.

Source

unsafe fn leading_k_mask(k: usize) -> Self::Mask

Construct a mask with the first k lanes active and the rest inactive.

If k >= LANE_COUNT, all lanes are active. Used for tail handling.

§Safety

Processor must support the required target feature.

Source

unsafe fn mask_to_vector(mask: Self::Mask) -> Self::Vector

Convert the native mask back to a vector register where active lanes are set to T::ALL_ONES and inactive lanes to T::ZERO.

§Safety

Processor must support the required target feature.

Source

unsafe fn vector_to_mask(v: Self::Vector) -> Self::Mask

Convert a comparison-result vector into the native mask, the inverse of SimdKernel::mask_to_vector.

A lane is active iff its sign bit is set, matching hardware movemask semantics (_mm256_movemask_ps and friends). The cmp_* family returns Self::Vector with active lanes set to T::ALL_ONES — whose sign bit is set — so composing this with SimdKernel::mask_to_bitmask yields one bit per comparison outcome, and trailing_zeros then locates the first matching lane without leaving vector registers.

§Safety

Processor must support the required target feature.

Source

unsafe fn splat(val: T) -> Self::Vector

Broadcast a scalar value to all lanes.

§Safety

Processor must support the required target feature.

§Examples
use hermes_simd_intrinsics::Scalar;
use hermes_simd_core::kernel::SimdKernel;

// SAFETY: Scalar backend requires no ISA feature.
let v = unsafe { <Scalar as SimdKernel<f32>>::splat(42.0_f32) };
let sum: f32 = unsafe { <Scalar as SimdKernel<f32>>::sum_reduce(v) };
assert_eq!(sum, 42.0_f32 * <Scalar as SimdKernel<f32>>::LANE_COUNT as f32);
Source

unsafe fn mask_to_bitmask(mask: Self::Mask) -> u64

Convert the native mask back to a raw u64 bitmask.

§Safety

Processor must support the required target feature.

Provided Methods§

Source

unsafe fn store_streaming(ptr: *mut T, val: Self::Vector)

Store a vector with a non-temporal (streaming) hint that bypasses the cache, avoiding the read-for-ownership traffic a normal write-allocate pays for write-only data larger than the last-level cache (measured 1.71× on out-of-LLC AVX2 f32 elementwise writes; see streaming_bench).

The default is a normal aligned store — correct but not cache-bypassing — so a backend without a non-temporal instruction inherits safe behavior. After a run of streaming stores the caller must issue stream_write_barrier before the results are read, since non-temporal stores are weakly ordered.

§Safety

ptr must be valid for writes and aligned to LANE_COUNT * size_of::<T>() bytes (non-temporal stores fault on misalignment).

Source

fn stream_write_barrier()

Fence ordering this backend’s non-temporal stores before subsequent reads. No-op by default (only meaningful where store_streaming is a weakly ordered non-temporal store).

Source

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

Elementwise subtraction: a - b.

Default: scalar fallback via crate::kernel_helpers::generic_binary_op. Float and SIMD backends override this with the appropriate vectorized instruction (e.g., _mm256_sub_ps for AVX2 f32, vsubq_f32 for NEON).

§Safety

Processor must support the required target feature.

Source

unsafe fn masked_load_unaligned( ptr: *const T, mask: Self::Mask, src: Self::Vector, ) -> Self::Vector

Masked load: active lanes loaded from ptr, inactive lanes taken from src.

§Safety

ptr must be valid for reading LANE_COUNT elements. Active lanes determined by mask.

Default: scalar-emulated merge via kernel_helpers::generic_masked_load. Backends with a native masked load (AVX-512, SVE) override this.

Source

unsafe fn masked_store_unaligned( ptr: *mut T, mask: Self::Mask, val: Self::Vector, )

Masked store: active lanes written to ptr, inactive lanes left unchanged.

§Safety

ptr must be valid for writing LANE_COUNT elements.

Default: scalar-emulated merge via kernel_helpers::generic_masked_store. Backends with a native masked store override this.

Source

unsafe fn masked_add( a: Self::Vector, b: Self::Vector, mask: Self::Mask, src: Self::Vector, ) -> Self::Vector

Masked elementwise add: active lanes compute a + b, inactive lanes yield src.

§Safety

Processor must support the required target feature.

Default: blend(mask_to_vector(mask), add(a, b), src). Backends with a native masked add override this.

Source

unsafe fn masked_mul( a: Self::Vector, b: Self::Vector, mask: Self::Mask, src: Self::Vector, ) -> Self::Vector

Masked elementwise multiply: active lanes compute a * b, inactive lanes yield src.

§Safety

Processor must support the required target feature.

Default: blend(mask_to_vector(mask), mul(a, b), src). Backends with a native masked multiply override this.

Source

unsafe fn masked_fmadd( a: Self::Vector, b: Self::Vector, c: Self::Vector, mask: Self::Mask, ) -> Self::Vector

Masked fused multiply-add: active lanes compute (a * b) + c, inactive lanes retain c.

The merge source for inactive lanes is the addend c, matching AVX-512 semantics for _mm512_mask_fmadd_ps(a, mask, b, c).

§Safety

Processor must support the required target feature.

Default: blend(mask_to_vector(mask), fmadd(a, b, c), c) — inactive lanes retain the addend c. Backends with a native masked FMA override this.

Source

unsafe fn masked_sum_reduce(v: Self::Vector, mask: Self::Mask) -> T

Masked horizontal sum: only lanes where mask[i]=1 contribute.

§Safety

Processor must support the required target feature.

Default: sum_reduce(blend(mask_to_vector(mask), v, zero)) — inactive lanes contribute zero. Backends with a native masked reduction override this.

Source

unsafe fn mask_from_bitmask(bm: u64) -> Self::Mask

Convert a raw u64 bitmask to the architecture-native mask type.

Default: expands to a boolean array then calls mask_from_bools.

§Safety

Processor must support the required target feature.

Source

unsafe fn scan_vector<Op, SMode>(v: Self::Vector, carry: T) -> (Self::Vector, T)
where Op: ScanOp<T>, SMode: ScanMode,

Perform an intra-vector prefix scan (inclusive or exclusive) of the vector, using the specified ScanOp strategy and starting carry value. Returns the scanned vector and the final carry value.

§Safety

Processor must support the required target feature.

Source

unsafe fn zero() -> Self::Vector

Set all lanes to zero.

Default: delegates to splat(T::ZERO). Backends may override with an architecture-specific XOR-zero idiom (e.g., _mm256_xor_ps) if profiling shows a register-pressure benefit.

§Safety

Processor must support the required target feature.

Source

unsafe fn div(a: Self::Vector, b: Self::Vector) -> Self::Vector

Elementwise division: a / b.

§Safety

Processor must support the required target feature.

Source

unsafe fn bitand(a: Self::Vector, b: Self::Vector) -> Self::Vector

Elementwise bitwise AND: a & b.

§Safety

Processor must support the required target feature.

Source

unsafe fn bitor(a: Self::Vector, b: Self::Vector) -> Self::Vector

Elementwise bitwise OR: a | b.

§Safety

Processor must support the required target feature.

Source

unsafe fn bitxor(a: Self::Vector, b: Self::Vector) -> Self::Vector

Elementwise bitwise XOR: a ^ b.

§Safety

Processor must support the required target feature.

Source

unsafe fn abs(a: Self::Vector) -> Self::Vector

Elementwise absolute value.

§Safety

Processor must support the required target feature.

Source

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

Elementwise minimum of a and b.

§Safety

Processor must support the required target feature.

Source

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

Elementwise maximum of a and b.

§Safety

Processor must support the required target feature.

Source

unsafe fn sqrt(a: Self::Vector) -> Self::Vector

Elementwise square root.

§Safety

Processor must support the required target feature.

Source

unsafe fn recip_sqrt(a: Self::Vector) -> Self::Vector

Elementwise reciprocal square root, 1/√x, to full T precision (~1 ulp).

Native backends override this where a faster full-precision path exists: f32 uses a hardware rsqrt seed plus one Newton–Raphson step (which already reaches f32’s 23-bit mantissa); f64 has no rsqrt approximation accurate enough for its 52-bit mantissa, so it uses the correctly-rounded hardware sqrt + divide. The result is therefore precision-consistent across every backend — not a reduced-accuracy fast approximation.

§Safety

Processor must support the required target feature.

Source

unsafe fn cmp_eq(a: Self::Vector, b: Self::Vector) -> Self::Vector

Elementwise equal: a == b.

§Safety

Processor must support the required target feature.

Source

unsafe fn cmp_ne(a: Self::Vector, b: Self::Vector) -> Self::Vector

Elementwise not equal: a != b.

§Safety

Processor must support the required target feature.

Source

unsafe fn cmp_lt(a: Self::Vector, b: Self::Vector) -> Self::Vector

Elementwise less than: a < b.

§Safety

Processor must support the required target feature.

Source

unsafe fn cmp_le(a: Self::Vector, b: Self::Vector) -> Self::Vector

Elementwise less than or equal: a <= b.

§Safety

Processor must support the required target feature.

Source

unsafe fn cmp_gt(a: Self::Vector, b: Self::Vector) -> Self::Vector

Elementwise greater than: a > b.

§Safety

Processor must support the required target feature.

Source

unsafe fn cmp_ge(a: Self::Vector, b: Self::Vector) -> Self::Vector

Elementwise greater than or equal: a >= b.

§Safety

Processor must support the required target feature.

Source

unsafe fn blend( mask: Self::Vector, true_val: Self::Vector, false_val: Self::Vector, ) -> Self::Vector

Elementwise blend: select lanes from true_val where the sign bit of mask is set, and from false_val otherwise.

§Safety

Processor must support the required target feature.

Source

unsafe fn neg(a: Self::Vector) -> Self::Vector

Elementwise negate: -a.

Default implementation: XOR each lane with T::SIGN_MASK (the IEEE 754 sign bit). This avoids the sub(zero, a) path, which panics on backends that do not implement subtraction (e.g. bf16 on AVX2). Every backend implements bitxor and splat.

§Safety

Processor must support the required target feature.

Source

unsafe fn bitnot(a: Self::Vector) -> Self::Vector

Elementwise bitwise NOT: !a.

§Safety

Processor must support the required target feature.

Source

unsafe fn min_reduce(v: Self::Vector) -> T

Horizontal minimum across all lanes.

Default: scalar lane-by-lane scan using crate::scalar::NumericElement::min_scalar. AVX-512 impls override with _mm512_reduce_min_ps / _mm256_reduce_min_ps or equivalent.

§Safety

Processor must support the required target feature.

Source

unsafe fn max_reduce(v: Self::Vector) -> T

Horizontal maximum across all lanes.

Default: scalar lane-by-lane scan using crate::scalar::NumericElement::max_scalar. AVX-512 impls override with _mm512_reduce_max_ps / _mm256_reduce_max_ps or equivalent.

§Safety

Processor must support the required target feature.

Source

unsafe fn popcount(a: Self::Vector) -> Self::Vector

Elementwise population count (number of set bits).

Default: scalar lane-by-lane scan using crate::scalar::NumericElement::count_ones. Target-specific intrinsics override this.

§Safety

Processor must support the required target feature.

Source

unsafe fn horizontal_bitwise_and(v: Self::Vector) -> T

Horizontal bitwise AND across all lanes.

Default: scalar lane-by-lane scan using crate::scalar::NumericElement::bitand. Target-specific intrinsics override this.

§Safety

Processor must support the required target feature.

Source

unsafe fn horizontal_bitwise_or(v: Self::Vector) -> T

Horizontal bitwise OR across all lanes.

Default: scalar lane-by-lane scan using crate::scalar::NumericElement::bitor. Target-specific intrinsics override this.

§Safety

Processor must support the required target feature.

Source

unsafe fn horizontal_bitwise_xor(v: Self::Vector) -> T

Horizontal bitwise XOR across all lanes.

Default: scalar lane-by-lane scan using crate::scalar::NumericElement::bitxor. Target-specific intrinsics override this.

§Safety

Processor must support the required target feature.

Source

unsafe fn swap_adjacent(v: Self::Vector) -> Self::Vector

Swap each adjacent lane pair: [a0, a1, a2, a3, ...] -> [a1, a0, a3, a2, ...].

Default: scalar emulation via store/swap/load. x86 backends override with _mm256_permute_ps(v, 0b1011_0001) / _mm256_permute_pd(v, 0b0101) and the AVX-512 equivalents.

§Safety

Processor must support the required target feature.

Source

unsafe fn dup_even(v: Self::Vector) -> Self::Vector

Duplicate even lanes into odd lanes: [a0, a1, a2, a3, ...] -> [a0, a0, a2, a2, ...].

Default: scalar emulation. x86 backends override with moveldup_ps / movedup_pd.

§Safety

Processor must support the required target feature.

Source

unsafe fn dup_odd(v: Self::Vector) -> Self::Vector

Duplicate odd lanes into even lanes: [a0, a1, a2, a3, ...] -> [a1, a1, a3, a3, ...].

Default: scalar emulation. x86 backends override with movehdup_ps / an odd-lane permute_pd. An unpaired trailing lane (odd LANE_COUNT) passes through unchanged.

§Safety

Processor must support the required target feature.

Source

unsafe fn fmaddsub( a: Self::Vector, b: Self::Vector, c: Self::Vector, ) -> Self::Vector

Alternating fused multiply: even lanes a*b - c, odd lanes a*b + c.

Default: scalar emulation. x86 backends override with _mm256_fmaddsub_ps/pd / _mm512_fmaddsub_ps/pd.

§Safety

Processor must support the required target feature.

Source

unsafe fn fmsubadd( a: Self::Vector, b: Self::Vector, c: Self::Vector, ) -> Self::Vector

Alternating fused multiply: even lanes a*b + c, odd lanes a*b - c.

Default: scalar emulation. x86 backends override with _mm256_fmsubadd_ps/pd / _mm512_fmsubadd_ps/pd.

§Safety

Processor must support the required target feature.

Dyn Compatibility§

This trait is not dyn compatible.

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

Implementors§

Source§

impl SimdKernel<Bf4> for Avx2

Available on x86 or x86-64 only.
Source§

impl SimdKernel<Bf4> for Avx512

Available on x86 or x86-64 only.
Source§

impl SimdKernel<Bf4> for Scalar

Source§

impl SimdKernel<Bf8> for Avx2

Available on x86 or x86-64 only.
Source§

impl SimdKernel<Bf8> for Avx512

Available on x86 or x86-64 only.
Source§

impl SimdKernel<Bf8> for Scalar

Source§

impl SimdKernel<Bf16> for Avx2

Available on x86 or x86-64 only.
Source§

impl SimdKernel<Bf16> for Avx512

Available on x86 or x86-64 only.
Source§

impl SimdKernel<Bf16> for Scalar

Source§

impl SimdKernel<F4> for Avx2

Available on x86 or x86-64 only.
Source§

impl SimdKernel<F4> for Avx512

Available on x86 or x86-64 only.
Source§

impl SimdKernel<F4> for Scalar

Source§

impl SimdKernel<F8> for Avx2

Available on x86 or x86-64 only.
Source§

impl SimdKernel<F8> for Avx512

Available on x86 or x86-64 only.
Source§

impl SimdKernel<F8> for Scalar

Source§

impl SimdKernel<F16> for Avx2

Available on x86 or x86-64 only.
Source§

impl SimdKernel<F16> for Avx512

Available on x86 or x86-64 only.
Source§

impl SimdKernel<F16> for Scalar

Source§

impl SimdKernel<F32> for Avx2

Available on x86 or x86-64 only.
Source§

impl SimdKernel<F32> for Avx512

Available on x86 or x86-64 only.
Source§

impl SimdKernel<F32> for Scalar

Source§

impl SimdKernel<F64> for Avx2

Available on x86 or x86-64 only.
Source§

impl SimdKernel<F64> for Avx512

Available on x86 or x86-64 only.
Source§

impl SimdKernel<F64> for Scalar

Source§

impl SimdKernel<I8> for Avx2

Available on x86 or x86-64 only.
Source§

impl SimdKernel<I8> for Avx512

Available on x86 or x86-64 only.
Source§

impl SimdKernel<I8> for Scalar

Source§

impl SimdKernel<I16> for Avx2

Available on x86 or x86-64 only.
Source§

impl SimdKernel<I16> for Avx512

Available on x86 or x86-64 only.
Source§

impl SimdKernel<I16> for Scalar

Source§

impl SimdKernel<I32> for Avx2

Available on x86 or x86-64 only.
Source§

impl SimdKernel<I32> for Avx512

Available on x86 or x86-64 only.
Source§

impl SimdKernel<I32> for Scalar

Source§

impl SimdKernel<f32> for Avx2

Available on x86 or x86-64 only.
Source§

impl SimdKernel<f32> for Avx512

Available on x86 or x86-64 only.
Source§

impl SimdKernel<f32> for Scalar

Source§

impl SimdKernel<f32> for SveArch

Source§

impl SimdKernel<f64> for Avx2

Available on x86 or x86-64 only.
Source§

impl SimdKernel<f64> for Avx512

Available on x86 or x86-64 only.
Source§

impl SimdKernel<f64> for Scalar

Source§

impl SimdKernel<f64> for SveArch

Source§

impl SimdKernel<i8> for Avx2

Available on x86 or x86-64 only.
Source§

impl SimdKernel<i8> for Avx512

Available on x86 or x86-64 only.
Source§

impl SimdKernel<i8> for Scalar

Source§

impl SimdKernel<i16> for Avx2

Available on x86 or x86-64 only.
Source§

impl SimdKernel<i16> for Avx512

Available on x86 or x86-64 only.
Source§

impl SimdKernel<i16> for Scalar

Source§

impl SimdKernel<i32> for Avx2

Available on x86 or x86-64 only.
Source§

impl SimdKernel<i32> for Avx512

Available on x86 or x86-64 only.
Source§

impl SimdKernel<i32> for Scalar