fluxbench_core/lib.rs
1#![warn(missing_docs)]
2//! FluxBench Core - Worker Runtime
3//!
4//! This crate provides the execution environment for benchmarks:
5//! - `Bencher` struct for iteration-based benchmarking
6//! - High-precision timing (RDTSC with Instant fallback)
7//! - Global allocator interceptor for memory tracking
8//! - CPU affinity pinning for stable TSC readings
9
10mod allocator;
11mod bencher;
12mod measure;
13mod worker;
14
15pub use allocator::{TrackingAllocator, current_allocation, reset_allocation_counter};
16pub use bencher::{Bencher, BenchmarkResult, IterationMode, run_benchmark_loop};
17/// Whether this platform provides hardware cycle counters (x86_64 RDTSCP or AArch64 CNTVCT_EL0).
18/// When `false`, cycle counts are reported as 0 and only wall-clock nanoseconds are available.
19pub use measure::HAS_CYCLE_COUNTER;
20pub use measure::Instant;
21pub use measure::Timer;
22pub use worker::WorkerMain;
23
24/// Benchmark definition registered via `#[flux::bench]`
25#[derive(Debug, Clone)]
26pub struct BenchmarkDef {
27 /// Unique identifier
28 pub id: &'static str,
29 /// Human-readable name
30 pub name: &'static str,
31 /// Group this benchmark belongs to
32 pub group: &'static str,
33 /// Severity level for CI reporting
34 pub severity: Severity,
35 /// Regression threshold percentage
36 pub threshold: f64,
37 /// Absolute time budget in nanoseconds
38 pub budget_ns: Option<u64>,
39 /// Tags for filtering
40 pub tags: &'static [&'static str],
41 /// Function pointer to the wrapper
42 pub runner_fn: fn(&mut Bencher),
43 /// Source file path
44 pub file: &'static str,
45 /// Source line number
46 pub line: u32,
47 /// Module path
48 pub module_path: &'static str,
49 /// Per-benchmark warmup override (nanoseconds)
50 pub warmup_ns: Option<u64>,
51 /// Per-benchmark measurement override (nanoseconds)
52 pub measurement_ns: Option<u64>,
53 /// Per-benchmark fixed sample count
54 pub samples: Option<u64>,
55 /// Per-benchmark minimum iterations
56 pub min_iterations: Option<u64>,
57 /// Per-benchmark maximum iterations
58 pub max_iterations: Option<u64>,
59 /// Benchmark IDs that must run before this one
60 pub depends_on: &'static [&'static str],
61}
62
63/// Severity levels for CI integration
64#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
65pub enum Severity {
66 /// Critical benchmark - regression fails the build
67 Critical,
68 /// Warning level - logged but doesn't fail
69 Warning,
70 /// Informational only
71 Info,
72}
73
74/// Group definition for organizing benchmarks
75#[derive(Debug, Clone)]
76pub struct GroupDef {
77 /// Group identifier
78 pub id: &'static str,
79 /// Human-readable description
80 pub description: &'static str,
81 /// Tags for filtering
82 pub tags: &'static [&'static str],
83 /// Parent group (for nested groups)
84 pub parent: Option<&'static str>,
85}
86
87/// Chart type for dashboard layout
88#[derive(Debug, Clone, Copy, PartialEq, Eq)]
89pub enum ChartType {
90 /// Violin plot
91 Violin,
92 /// Bar chart
93 Bar,
94 /// Scatter plot
95 Scatter,
96 /// Line chart
97 Line,
98 /// Histogram
99 Histogram,
100}
101
102/// Chart definition for dashboard
103#[derive(Debug, Clone)]
104pub struct ChartDef {
105 /// Chart title
106 pub title: &'static str,
107 /// Chart type
108 pub chart_type: ChartType,
109 /// Grid position (row, col)
110 pub position: (u32, u32),
111 /// Items to display (benchmark IDs)
112 pub items: &'static [&'static str],
113 /// Optional target line
114 pub target_line: Option<f64>,
115}
116
117/// Report/dashboard definition
118#[derive(Debug, Clone)]
119pub struct ReportDef {
120 /// Dashboard title
121 pub title: &'static str,
122 /// Grid layout (rows, cols)
123 pub layout: (u32, u32),
124 /// Charts in the dashboard
125 pub charts: &'static [ChartDef],
126}
127
128/// Comparison group - groups multiple benchmarks for side-by-side comparison
129#[derive(Debug, Clone)]
130pub struct CompareDef {
131 /// Comparison identifier
132 pub id: &'static str,
133 /// Human-readable title
134 pub title: &'static str,
135 /// Benchmark IDs to compare
136 pub benchmarks: &'static [&'static str],
137 /// Optional baseline benchmark (first one if not specified)
138 pub baseline: Option<&'static str>,
139 /// Metric to compare (default: mean)
140 pub metric: &'static str,
141 /// Group for chart generation (comparisons with same group form a chart)
142 pub group: Option<&'static str>,
143 /// X-axis value for this comparison point (e.g., "1", "10", "100")
144 pub x: Option<&'static str>,
145 /// Series labels (display names) - must match benchmarks array length
146 /// If not specified, benchmark IDs are used as labels
147 pub series: Option<&'static [&'static str]>,
148}
149
150// Collect all registered benchmarks
151inventory::collect!(BenchmarkDef);
152inventory::collect!(GroupDef);
153inventory::collect!(ReportDef);
154inventory::collect!(CompareDef);
155
156/// Anchor to prevent LTO from stripping inventory entries
157#[used]
158#[doc(hidden)]
159pub static REGISTRY_ANCHOR: fn() = || {
160 for _ in inventory::iter::<BenchmarkDef> {}
161 for _ in inventory::iter::<GroupDef> {}
162 for _ in inventory::iter::<ReportDef> {}
163 for _ in inventory::iter::<CompareDef> {}
164};