use crate::simd_dispatch::{
cosine_dispatched, cosine_normalized_dispatched, dot_product_dispatched, euclidean_dispatched,
hamming_dispatched, prefetch_distance, simd_features_info, SimdFeatures,
PREFETCH_DISTANCE_1536D, PREFETCH_DISTANCE_384D, PREFETCH_DISTANCE_768D,
};
#[test]
fn test_dot_product_dispatched_correctness() {
let a = vec![1.0f32, 2.0, 3.0, 4.0];
let b = vec![5.0f32, 6.0, 7.0, 8.0];
let result = dot_product_dispatched(&a, &b);
assert!((result - 70.0).abs() < 1e-5);
}
#[test]
fn test_euclidean_dispatched_correctness() {
let a = vec![0.0f32, 0.0, 0.0];
let b = vec![3.0f32, 4.0, 0.0];
let result = euclidean_dispatched(&a, &b);
assert!((result - 5.0).abs() < 1e-5);
}
#[test]
fn test_cosine_dispatched_correctness() {
let a = vec![1.0f32, 2.0, 3.0];
let b = vec![1.0f32, 2.0, 3.0];
let result = cosine_dispatched(&a, &b);
assert!((result - 1.0).abs() < 1e-5);
}
#[test]
fn test_cosine_dispatched_orthogonal() {
let a = vec![1.0f32, 0.0, 0.0];
let b = vec![0.0f32, 1.0, 0.0];
let result = cosine_dispatched(&a, &b);
assert!(result.abs() < 1e-5);
}
#[test]
fn test_cosine_normalized_dispatched() {
let a = vec![1.0f32, 0.0];
let b = vec![0.707f32, 0.707];
let result = cosine_normalized_dispatched(&a, &b);
assert!((result - 0.707).abs() < 0.01);
}
#[test]
fn test_hamming_dispatched_correctness() {
let a = vec![1.0f32, 0.0, 1.0, 0.0]; let b = vec![1.0f32, 1.0, 0.0, 0.0];
let result = hamming_dispatched(&a, &b);
assert_eq!(result, 2);
}
#[allow(clippy::cast_precision_loss)]
#[test]
fn test_dot_product_dispatched_768d() {
let a: Vec<f32> = (0..768).map(|i| (i as f32) * 0.001).collect();
let b: Vec<f32> = (0..768).map(|i| ((768 - i) as f32) * 0.001).collect();
let result = dot_product_dispatched(&a, &b);
assert!(result.is_finite());
assert!(result > 0.0);
}
#[test]
fn test_euclidean_dispatched_768d() {
let a: Vec<f32> = vec![0.0; 768];
let b: Vec<f32> = vec![1.0; 768];
let result = euclidean_dispatched(&a, &b);
assert!((result - 768.0_f32.sqrt()).abs() < 0.01);
}
#[allow(clippy::cast_precision_loss)]
#[test]
fn test_cosine_dispatched_768d() {
let a: Vec<f32> = (0..768).map(|i| (i as f32).sin()).collect();
let b = a.clone();
let result = cosine_dispatched(&a, &b);
assert!((result - 1.0).abs() < 1e-4);
}
#[test]
fn test_simd_features_detect() {
let features = SimdFeatures::detect();
let _name = features.best_instruction_set();
println!("SIMD features: {:?}", features);
println!("Best instruction set: {}", features.best_instruction_set());
}
#[test]
fn test_simd_features_info() {
let features = simd_features_info();
assert!(!features.best_instruction_set().is_empty());
}
#[test]
fn test_prefetch_distance_768d() {
assert_eq!(PREFETCH_DISTANCE_768D, 48);
}
#[test]
fn test_prefetch_distance_384d() {
assert_eq!(PREFETCH_DISTANCE_384D, 24);
}
#[test]
fn test_prefetch_distance_1536d() {
assert_eq!(PREFETCH_DISTANCE_1536D, 96);
}
#[test]
fn test_prefetch_distance_function() {
assert_eq!(prefetch_distance(768), 48);
assert_eq!(prefetch_distance(384), 24);
assert_eq!(prefetch_distance(128), 8);
}
#[test]
fn test_dispatch_initialized_once() {
let a = vec![1.0f32; 100];
let b = vec![2.0f32; 100];
let r1 = dot_product_dispatched(&a, &b);
let r2 = dot_product_dispatched(&a, &b);
assert!((r1 - r2).abs() < f32::EPSILON);
}
#[test]
fn test_dispatch_thread_safe() {
use std::sync::Arc;
use std::thread;
let a = Arc::new(vec![1.0f32; 768]);
let b = Arc::new(vec![2.0f32; 768]);
let handles: Vec<_> = (0..4)
.map(|_| {
let a = Arc::clone(&a);
let b = Arc::clone(&b);
thread::spawn(move || {
for _ in 0..100 {
let _ = dot_product_dispatched(&a, &b);
let _ = cosine_dispatched(&a, &b);
let _ = euclidean_dispatched(&a, &b);
}
})
})
.collect();
for h in handles {
h.join().expect("Thread should not panic");
}
}
#[test]
#[should_panic(expected = "Vector dimensions must match")]
fn test_dot_product_dispatched_length_mismatch() {
let a = vec![1.0f32, 2.0];
let b = vec![1.0f32, 2.0, 3.0];
let _ = dot_product_dispatched(&a, &b);
}
#[test]
fn test_empty_vectors() {
let a: Vec<f32> = vec![];
let b: Vec<f32> = vec![];
assert!((dot_product_dispatched(&a, &b) - 0.0).abs() < f32::EPSILON);
}
#[test]
fn test_single_element() {
let a = vec![3.0f32];
let b = vec![4.0f32];
assert!((dot_product_dispatched(&a, &b) - 12.0).abs() < f32::EPSILON);
}