Skip to main content

fluxbench_logic/
synthetic.rs

1//! Synthetic Metrics
2//!
3//! Computed metrics derived from benchmark results.
4
5use crate::context::{ContextError, MetricContext};
6use serde::{Deserialize, Serialize};
7
8/// Definition of a synthetic metric registered via `#[flux::synthetic]`
9#[derive(Debug, Clone)]
10pub struct SyntheticDef {
11    /// Unique identifier
12    pub id: &'static str,
13    /// Formula to compute the metric
14    pub formula: &'static str,
15    /// Unit for display (e.g., "ns", "MB/s")
16    pub unit: Option<&'static str>,
17}
18
19/// Result of computing a synthetic metric
20#[derive(Debug, Clone, Serialize, Deserialize)]
21pub struct SyntheticResult {
22    /// Metric identifier
23    pub id: String,
24    /// Computed value
25    pub value: f64,
26    /// Formula used
27    pub formula: String,
28    /// Display unit
29    pub unit: Option<String>,
30}
31
32/// Compute all synthetic metrics
33pub fn compute_synthetics(
34    synthetics: &[SyntheticDef],
35    context: &MetricContext,
36) -> Vec<Result<SyntheticResult, ContextError>> {
37    synthetics
38        .iter()
39        .map(|s| {
40            context.evaluate(s.formula).map(|value| SyntheticResult {
41                id: s.id.to_string(),
42                value,
43                formula: s.formula.to_string(),
44                unit: s.unit.map(|u| u.to_string()),
45            })
46        })
47        .collect()
48}
49
50#[cfg(test)]
51mod tests {
52    use super::*;
53
54    #[test]
55    fn test_synthetic_computation() {
56        let mut ctx = MetricContext::new();
57        ctx.set("raw", 100.0);
58        ctx.set("overhead", 20.0);
59
60        let synthetics = vec![SyntheticDef {
61            id: "net_time",
62            formula: "raw - overhead",
63            unit: Some("ns"),
64        }];
65
66        let results = compute_synthetics(&synthetics, &ctx);
67        assert_eq!(results.len(), 1);
68
69        let result = results[0].as_ref().unwrap();
70        assert_eq!(result.id, "net_time");
71        assert!((result.value - 80.0).abs() < f64::EPSILON);
72    }
73}