openvm_circuit/metrics/cycle_tracker/
mod.rs1#[derive(Clone, Debug, Default)]
2pub struct CycleTracker {
3 stack: Vec<String>,
5}
6
7impl CycleTracker {
8 pub fn new() -> Self {
9 Self::default()
10 }
11
12 pub fn top(&self) -> Option<&String> {
13 self.stack.last()
14 }
15
16 pub fn start(&mut self, mut name: String) {
20 if name.starts_with("CT-") {
22 name = name.split_off(3);
23 }
24 self.stack.push(name);
25 }
26
27 pub fn end(&mut self, mut name: String) {
30 if name.starts_with("CT-") {
32 name = name.split_off(3);
33 }
34 let stack_top = self.stack.pop();
35 assert_eq!(stack_top.unwrap(), name, "Stack top does not match name");
36 }
37
38 pub fn force_end(&mut self) {
40 self.stack.pop();
41 }
42
43 pub fn get_full_name(&self) -> String {
45 self.stack.join(";")
46 }
47}
48
49#[cfg(feature = "metrics")]
50mod emit {
51 use metrics::counter;
52
53 use super::CycleTracker;
54
55 impl CycleTracker {
56 pub fn increment_opcode(&self, (dsl_ir, opcode): &(Option<String>, String)) {
57 let labels = [
58 ("opcode", opcode.clone()),
59 ("dsl_ir", dsl_ir.clone().unwrap_or_default()),
60 ("cycle_tracker_span", self.get_full_name()),
61 ];
62 counter!("frequency", &labels).increment(1u64);
63 }
64
65 pub fn increment_cells_used(
66 &self,
67 (dsl_ir, opcode, air_name): &(Option<String>, String, String),
68 trace_cells_used: usize,
69 ) {
70 if trace_cells_used == 0 {
71 return;
72 }
73 let labels = [
74 ("air_name", air_name.clone()),
75 ("opcode", opcode.clone()),
76 ("dsl_ir", dsl_ir.clone().unwrap_or_default()),
77 ("cycle_tracker_span", self.get_full_name()),
78 ];
79 counter!("cells_used", &labels).increment(trace_cells_used as u64);
80 }
81 }
82}