Merge commit 'd803bfe2b1fe7f5e219e50ac20d6801a0a58ac75' as 'vendor/ruvector'

This commit is contained in:
ruv
2026-02-28 14:39:40 -05:00
7854 changed files with 3522914 additions and 0 deletions

View File

@@ -0,0 +1,178 @@
//! Benchmarks for hyperbolic HNSW operations
//!
//! Metrics as specified in evaluation protocol:
//! - p50 and p95 latency
//! - Memory overhead
//! - Search recall@k
use criterion::{black_box, criterion_group, criterion_main, Criterion, BenchmarkId};
use ruvector_hyperbolic_hnsw::*;
fn bench_poincare_distance(c: &mut Criterion) {
let dims = [8, 32, 128, 512];
let mut group = c.benchmark_group("poincare_distance");
for dim in dims {
let x: Vec<f32> = (0..dim).map(|i| (i as f32 * 0.01) % 0.9).collect();
let y: Vec<f32> = (0..dim).map(|i| ((i as f32 * 0.02) + 0.1) % 0.9).collect();
group.bench_with_input(BenchmarkId::new("dim", dim), &dim, |b, _| {
b.iter(|| poincare_distance(black_box(&x), black_box(&y), 1.0))
});
}
group.finish();
}
fn bench_mobius_add(c: &mut Criterion) {
let dims = [8, 32, 128];
let mut group = c.benchmark_group("mobius_add");
for dim in dims {
let x: Vec<f32> = (0..dim).map(|i| (i as f32 * 0.01) % 0.5).collect();
let y: Vec<f32> = (0..dim).map(|i| ((i as f32 * 0.02) + 0.1) % 0.5).collect();
group.bench_with_input(BenchmarkId::new("dim", dim), &dim, |b, _| {
b.iter(|| mobius_add(black_box(&x), black_box(&y), 1.0))
});
}
group.finish();
}
fn bench_exp_log_map(c: &mut Criterion) {
let dim = 32;
let p: Vec<f32> = (0..dim).map(|i| (i as f32 * 0.01) % 0.3).collect();
let v: Vec<f32> = (0..dim).map(|i| ((i as f32 * 0.005) - 0.1) % 0.2).collect();
let q: Vec<f32> = (0..dim).map(|i| ((i as f32 * 0.02) + 0.1) % 0.4).collect();
let mut group = c.benchmark_group("exp_log_map");
group.bench_function("exp_map", |b| {
b.iter(|| exp_map(black_box(&v), black_box(&p), 1.0))
});
group.bench_function("log_map", |b| {
b.iter(|| log_map(black_box(&q), black_box(&p), 1.0))
});
group.finish();
}
fn bench_hnsw_insert(c: &mut Criterion) {
let sizes = [100, 500, 1000];
let mut group = c.benchmark_group("hnsw_insert");
group.sample_size(20);
for size in sizes {
let vectors: Vec<Vec<f32>> = (0..size)
.map(|i| vec![
(i as f32 * 0.01) % 0.8,
((i as f32 * 0.02) + 0.1) % 0.8,
])
.collect();
group.bench_with_input(BenchmarkId::new("n", size), &vectors, |b, vecs| {
b.iter(|| {
let mut hnsw = HyperbolicHnsw::default_config();
for v in vecs {
hnsw.insert(v.clone()).unwrap();
}
})
});
}
group.finish();
}
fn bench_hnsw_search(c: &mut Criterion) {
let ks = [1, 5, 10, 50];
// Build index once
let mut hnsw = HyperbolicHnsw::default_config();
for i in 0..1000 {
let v = vec![
(i as f32 * 0.01) % 0.8,
((i as f32 * 0.02) + 0.1) % 0.8,
];
hnsw.insert(v).unwrap();
}
let query = vec![0.4, 0.4];
let mut group = c.benchmark_group("hnsw_search");
for k in ks {
group.bench_with_input(BenchmarkId::new("k", k), &k, |b, &k| {
b.iter(|| hnsw.search(black_box(&query), k))
});
}
group.finish();
}
fn bench_tangent_cache(c: &mut Criterion) {
let sizes = [100, 500, 1000];
let mut group = c.benchmark_group("tangent_cache");
group.sample_size(20);
for size in sizes {
let points: Vec<Vec<f32>> = (0..size)
.map(|i| vec![
(i as f32 * 0.01) % 0.8,
((i as f32 * 0.02) + 0.1) % 0.8,
])
.collect();
let indices: Vec<usize> = (0..size).collect();
group.bench_with_input(BenchmarkId::new("build", size), &(points.clone(), indices.clone()), |b, (p, i)| {
b.iter(|| TangentCache::new(black_box(p), black_box(i), 1.0))
});
}
group.finish();
}
fn bench_search_with_pruning(c: &mut Criterion) {
// Build index with tangent cache
let mut hnsw = HyperbolicHnsw::default_config();
for i in 0..1000 {
let v = vec![
(i as f32 * 0.01) % 0.8,
((i as f32 * 0.02) + 0.1) % 0.8,
];
hnsw.insert(v).unwrap();
}
hnsw.build_tangent_cache().unwrap();
let query = vec![0.4, 0.4];
let mut group = c.benchmark_group("search_comparison");
group.bench_function("standard_search", |b| {
b.iter(|| hnsw.search(black_box(&query), 10))
});
group.bench_function("pruning_search", |b| {
b.iter(|| hnsw.search_with_pruning(black_box(&query), 10))
});
group.finish();
}
criterion_group!(
benches,
bench_poincare_distance,
bench_mobius_add,
bench_exp_log_map,
bench_hnsw_insert,
bench_hnsw_search,
bench_tangent_cache,
bench_search_with_pruning,
);
criterion_main!(benches);