openvm_static_verifier/
profiling.rs

1//! Cell-count profiling for the static verifier circuit.
2//!
3//! When the `cell-profiling` feature is enabled, [`CellProfiler`] tracks advice cell allocations
4//! across pipeline stages and can generate flamegraph SVGs via `inferno`.
5//!
6//! When the feature is disabled, all methods are `#[inline(always)]` no-ops with zero overhead.
7
8#[cfg(feature = "cell-profiling")]
9mod enabled {
10    use std::{fs::File, io::BufWriter};
11
12    use crate::context_tree::ContextTree;
13
14    pub struct CellProfiler {
15        tree: ContextTree,
16    }
17
18    impl CellProfiler {
19        pub fn new(label: &str, cell_count: usize) -> Self {
20            Self {
21                tree: ContextTree::with_name(label, cell_count),
22            }
23        }
24
25        pub fn push(&mut self, name: &str, cell_count: usize) {
26            self.tree.push(name, tracing::Level::DEBUG, cell_count);
27        }
28
29        pub fn pop(&mut self, cell_count: usize) {
30            self.tree.pop(cell_count);
31        }
32
33        pub fn print(&self, cell_count: usize) {
34            self.tree.print(cell_count);
35        }
36
37        pub fn write_flamegraph(&self, path: &str, title: &str, cell_count: usize) {
38            let file = File::create(path).expect("Failed to create flamegraph file");
39            let mut writer = BufWriter::new(file);
40            self.tree
41                .write_flamegraph(&mut writer, title, cell_count, false);
42        }
43
44        pub fn write_flamegraph_reversed(&self, path: &str, title: &str, cell_count: usize) {
45            let file = File::create(path).expect("Failed to create flamegraph file");
46            let mut writer = BufWriter::new(file);
47            self.tree
48                .write_flamegraph(&mut writer, title, cell_count, true);
49        }
50    }
51}
52
53#[cfg(not(feature = "cell-profiling"))]
54mod disabled {
55    pub struct CellProfiler;
56
57    impl CellProfiler {
58        #[inline(always)]
59        pub fn new(_label: &str, _cell_count: usize) -> Self {
60            Self
61        }
62
63        #[inline(always)]
64        pub fn push(&mut self, _name: &str, _cell_count: usize) {}
65
66        #[inline(always)]
67        pub fn pop(&mut self, _cell_count: usize) {}
68
69        #[inline(always)]
70        pub fn print(&self, _cell_count: usize) {}
71
72        #[inline(always)]
73        pub fn write_flamegraph(&self, _path: &str, _title: &str, _cell_count: usize) {}
74
75        #[inline(always)]
76        pub fn write_flamegraph_reversed(&self, _path: &str, _title: &str, _cell_count: usize) {}
77    }
78}
79
80#[cfg(not(feature = "cell-profiling"))]
81pub use disabled::CellProfiler;
82#[cfg(feature = "cell-profiling")]
83pub use enabled::CellProfiler;