use diskann_benchmark_core as benchmark_core;
use serde::Serialize;
#[derive(Debug, Clone, Serialize)]
#[non_exhaustive]
pub(crate) struct RecallMetrics {
pub(crate) recall_k: usize,
pub(crate) recall_n: usize,
pub(crate) num_queries: usize,
pub(crate) average: f64,
pub(crate) minimum: usize,
pub(crate) maximum: usize,
}
impl From<&benchmark_core::recall::RecallMetrics> for RecallMetrics {
fn from(m: &benchmark_core::recall::RecallMetrics) -> Self {
Self {
recall_k: m.recall_k,
recall_n: m.recall_n,
num_queries: m.num_queries,
average: m.average,
minimum: m.minimum,
maximum: m.maximum,
}
}
}
#[cfg(any(
feature = "spherical-quantization",
feature = "minmax-quantization",
feature = "product-quantization"
))]
pub(crate) fn compute_multiple_recalls<T>(
results: &dyn benchmark_core::recall::Rows<T>,
groundtruth: &dyn benchmark_core::recall::Rows<T>,
recall_k: &[usize],
recall_n: &[usize],
) -> Result<Vec<RecallMetrics>, benchmark_core::recall::ComputeRecallError>
where
T: benchmark_core::recall::RecallCompatible,
{
let mut result = Vec::new();
for k in recall_k {
for n in recall_n {
if k > n {
continue;
}
let recall = benchmark_core::recall::knn(groundtruth, None, results, *k, *n, false)?;
result.push((&recall).into());
}
}
Ok(result)
}
#[derive(Debug, Clone, Serialize)]
#[non_exhaustive]
pub(crate) struct AveragePrecisionMetrics {
pub(crate) num_queries: usize,
pub(crate) average_precision: f64,
}
impl From<&benchmark_core::recall::AveragePrecisionMetrics> for AveragePrecisionMetrics {
fn from(m: &benchmark_core::recall::AveragePrecisionMetrics) -> Self {
Self {
num_queries: m.num_queries,
average_precision: m.average_precision,
}
}
}