- Every metric — cosine, dot product, Euclidean (L2), Manhattan (L1), Hamming
- SIMD + scalar — AVX2 on x86_64, NEON on aarch64, with a readable scalar fallback
- Runtime dispatch — detect CPU features once; route each call to the fastest available kernel
- Two entry points — a type-level
Distancetrait when the metric is known at compile time, andcompute/compute_batchoverDistanceMetricwhen it is chosen at runtime - Allocation-free — every public path borrows; batch evaluation writes into a caller-owned buffer
- Never panics on bad input — empty, mismatched, and non-finite inputs return a typed
IqdbError - Standalone — usable by anyone doing vector similarity in Rust, iQDB or not
Installation
[]
= "0.3"
Quick start
Pick the metric at compile time through the Distance trait:
use ;
let a = ;
let b = ;
// Cosine distance of perpendicular unit vectors is 1.0.
let cos = compute.expect;
assert!;
// Euclidean (L2): a 3-4-5 right triangle.
let l2 = compute.expect;
assert!;
Or pick it at runtime with the DistanceMetric tag from iqdb-types:
use compute;
use DistanceMetric;
let a = ;
let b = ;
// Dot-product similarity: 1*4 + 2*(-5) + 3*6 = 12.
let s = compute.expect;
assert!;
Score one query against many candidates into a caller-owned buffer (no allocation):
use compute_batch;
use DistanceMetric;
let query = ;
let candidates: = ;
let mut out = ;
compute_batch
.expect;
assert_eq!;
Inspect the kernel the host will use:
let features = detect_features;
// On an AVX2 x86_64 host `features.avx2` is true; on aarch64 `features.neon` is.
let _ = ;
Errors
Every fallible call returns iqdb_types::Result. Empty inputs surface as
IqdbError::InvalidVector; length mismatches as
IqdbError::DimensionMismatch { expected, found }; a batch whose output buffer
does not match the candidate count returns IqdbError::InvalidConfig. The
library never panics on hostile input.
Status
This is the v0.3.0 SIMD release: all five metrics ship with a scalar reference path plus runtime-dispatched AVX2 and NEON kernels, each property-tested and differentially verified against the scalar twin. The remaining 0.x work — normalized fast-paths, fuzzing, and the API freeze — lands per the ROADMAP, with the full surface documented in docs/API.md.
Where It Fits
iqdb-distance sits just above the types crate. It powers:
iqdb-types— theDistanceMetricenum and vector types it operates oniqdb-quantize— quantized distance reuses this SIMD infrastructureiqdb-flat/iqdb-hnsw/iqdb-ivf— every index computes distances here
Its only first-party dependency is iqdb-types, so it is unblocked today.
Standards
Built to the iQDB Rust standard. See REPS.md (Rust Efficiency & Performance Standards) and dev/DIRECTIVES.md for the engineering law and the definition of done. Before a PR: cargo fmt --all, cargo clippy --all-targets --all-features -- -D warnings, and cargo test --all-features must be clean.