sochdb_vector/simd/mod.rs
1//! Pure Rust SIMD kernels for SochDB vector operations.
2//!
3//! This module provides high-performance SIMD implementations for:
4//! - **BPS Scan**: L1 distance computation for Block Projection Sketches
5//! - **Int8 Dot Product**: Quantized dot products for reranking
6//! - **Visibility Check**: MVCC visibility bitmap generation
7//!
8//! # Architecture
9//!
10//! The module uses a trait-based abstraction (`SimdBackend`) that allows
11//! swapping between architecture-specific intrinsics (`core::arch`) and
12//! portable SIMD (`core::simd`) when it stabilizes.
13//!
14//! # CPU Detection
15//!
16//! Runtime CPU feature detection is used to select the optimal code path:
17//! - x86_64: AVX-512 > AVX2 > SSE4.1 > Scalar
18//! - aarch64: NEON (mandatory) + optional SVE
19//! - Other: Scalar fallback
20//!
21//! # Safety
22//!
23//! SIMD intrinsic functions are `unsafe` because they require specific CPU
24//! features. The dispatch layer handles feature detection and ensures
25//! that intrinsics are only called when the CPU supports them.
26
27pub mod bps_scan;
28pub mod dispatch;
29pub mod dot_i8;
30pub mod visibility;
31
32#[cfg(feature = "portable-simd")]
33pub mod portable;
34
35// Re-export main types and functions
36pub use bps_scan::{bps_scan, bps_scan_u32};
37pub use dispatch::{CpuFeatures, SimdLevel, cpu_features, simd_level};
38pub use dot_i8::{dot_i8, dot_i8_batch};
39pub use visibility::{visibility_check, visibility_check_with_txn};
40
41/// Trait for SIMD backend abstraction.
42///
43/// This allows the algorithm code to be generic over the backend,
44/// enabling A/B testing and gradual migration to `core::simd`.
45pub trait SimdBackend {
46 /// 32 x u8 vector type
47 type U8x32;
48 /// 32 x i8 vector type
49 type I8x32;
50 /// 8 x f32 vector type
51 type F32x8;
52 /// 4 x u64 vector type
53 type U64x4;
54
55 /// Compute L1 distance between two u8 vectors
56 fn l1_distance_u8(a: Self::U8x32, b: Self::U8x32) -> Self::U8x32;
57
58 /// Compute dot product of two i8 vectors
59 fn dot_i8(a: Self::I8x32, b: Self::I8x32) -> i32;
60
61 /// Compute dot product of two f32 vectors
62 fn dot_f32(a: Self::F32x8, b: Self::F32x8) -> f32;
63}