openvm_circuit/metrics/cycle_tracker/
mod.rs

1#[derive(Clone, Debug, Default)]
2pub struct CycleTracker {
3    /// Stack of span names, with most recent at the end
4    stack: Vec<String>,
5}
6
7impl CycleTracker {
8    pub fn new() -> Self {
9        Self::default()
10    }
11
12    /// Starts a new cycle tracker span for the given name.
13    /// If a span already exists for the given name, it ends the existing span and pushes a new one to the vec.
14    pub fn start(&mut self, mut name: String) {
15        // hack to remove "CT-" prefix
16        if name.starts_with("CT-") {
17            name = name.split_off(3);
18        }
19        self.stack.push(name);
20    }
21
22    /// Ends the cycle tracker span for the given name.
23    /// If no span exists for the given name, it panics.
24    pub fn end(&mut self, mut name: String) {
25        // hack to remove "CT-" prefix
26        if name.starts_with("CT-") {
27            name = name.split_off(3);
28        }
29        let stack_top = self.stack.pop();
30        assert_eq!(stack_top.unwrap(), name, "Stack top does not match name");
31    }
32
33    /// Ends the current cycle tracker span.
34    pub fn force_end(&mut self) {
35        self.stack.pop();
36    }
37
38    /// Get full name of span with all parent names separated by ";" in flamegraph format
39    pub fn get_full_name(&self) -> String {
40        self.stack.join(";")
41    }
42}
43
44#[cfg(feature = "bench-metrics")]
45mod emit {
46    use metrics::counter;
47
48    use super::CycleTracker;
49
50    impl CycleTracker {
51        pub fn increment_opcode(&self, (dsl_ir, opcode): &(Option<String>, String)) {
52            let labels = [
53                ("opcode", opcode.clone()),
54                ("dsl_ir", dsl_ir.clone().unwrap_or_default()),
55                ("cycle_tracker_span", self.get_full_name()),
56            ];
57            counter!("frequency", &labels).increment(1u64);
58        }
59
60        pub fn increment_cells_used(
61            &self,
62            (dsl_ir, opcode, air_name): &(Option<String>, String, String),
63            trace_cells_used: usize,
64        ) {
65            if trace_cells_used == 0 {
66                return;
67            }
68            let labels = [
69                ("air_name", air_name.clone()),
70                ("opcode", opcode.clone()),
71                ("dsl_ir", dsl_ir.clone().unwrap_or_default()),
72                ("cycle_tracker_span", self.get_full_name()),
73            ];
74            counter!("cells_used", &labels).increment(trace_cells_used as u64);
75        }
76    }
77}