diff --git a/plonky2/Cargo.toml b/plonky2/Cargo.toml index ae94f780..b3fa5113 100644 --- a/plonky2/Cargo.toml +++ b/plonky2/Cargo.toml @@ -11,16 +11,16 @@ edition = "2021" default-run = "generate_constants" [features] -default = ["parallel", "rand", "rand_chacha", "gate_testing"] +default = ["parallel", "rand", "rand_chacha", "timing", "gate_testing"] parallel = ["maybe_rayon/parallel"] rand = ["dep:rand", "plonky2_field/rand"] gate_testing = ["rand"] rand_chacha = ["dep:rand_chacha"] +timing = [] [dependencies] plonky2_field = { path = "../field" } plonky2_util = { path = "../util" } -env_logger = "0.9.0" log = "0.4.14" itertools = "0.10.0" num = { version = "0.4", features = [ "rand" ] } @@ -38,6 +38,7 @@ static_assertions = "1.1.0" rand = "0.8.4" rand_chacha = "0.3.1" criterion = "0.3.5" +env_logger = "0.9.0" tynm = "0.1.6" structopt = "0.3.26" num_cpus = "1.13.1" diff --git a/plonky2/src/util/timing.rs b/plonky2/src/util/timing.rs index 4250d688..42033038 100644 --- a/plonky2/src/util/timing.rs +++ b/plonky2/src/util/timing.rs @@ -1,8 +1,10 @@ +#[cfg(feature = "timing")] use std::time::{Duration, Instant}; use log::{log, Level}; /// The hierarchy of scopes, and the time consumed by each one. Useful for profiling. +#[cfg(feature = "timing")] pub struct TimingTree { /// The name of this scope. name: String, @@ -16,13 +18,25 @@ pub struct TimingTree { children: Vec, } +#[cfg(not(feature = "timing"))] +pub struct TimingTree(Level); + +#[cfg(feature = "timing")] impl Default for TimingTree { fn default() -> Self { TimingTree::new("root", Level::Debug) } } +#[cfg(not(feature = "timing"))] +impl Default for TimingTree { + fn default() -> Self { + TimingTree::new("", Level::Debug) + } +} + impl TimingTree { + #[cfg(feature = "timing")] pub fn new(root_name: &str, level: Level) -> Self { Self { name: root_name.to_string(), @@ -33,18 +47,26 @@ impl TimingTree { } } + #[cfg(not(feature = "timing"))] + pub fn new(_root_name: &str, level: Level) -> Self { + Self(level) + } + /// Whether this scope is still in scope. + #[cfg(feature = "timing")] fn is_open(&self) -> bool { self.exit_time.is_none() } /// A description of the stack of currently-open scopes. + #[cfg(feature = "timing")] pub fn open_stack(&self) -> String { let mut stack = Vec::new(); self.open_stack_helper(&mut stack); stack.join(" > ") } + #[cfg(feature = "timing")] fn open_stack_helper(&self, stack: &mut Vec) { if self.is_open() { stack.push(self.name.clone()); @@ -54,6 +76,7 @@ impl TimingTree { } } + #[cfg(feature = "timing")] pub fn push(&mut self, ctx: &str, mut level: log::Level) { assert!(self.is_open()); @@ -76,7 +99,11 @@ impl TimingTree { }) } + #[cfg(not(feature = "timing"))] + pub fn push(&mut self, _ctx: &str, _level: log::Level) {} + /// Close the deepest open scope from this tree. + #[cfg(feature = "timing")] pub fn pop(&mut self) { assert!(self.is_open()); @@ -90,6 +117,10 @@ impl TimingTree { self.exit_time = Some(Instant::now()); } + #[cfg(not(feature = "timing"))] + pub fn pop(&mut self) {} + + #[cfg(feature = "timing")] fn duration(&self) -> Duration { self.exit_time .unwrap_or_else(Instant::now) @@ -97,6 +128,7 @@ impl TimingTree { } /// Filter out children with a low duration. + #[cfg(feature = "timing")] pub fn filter(&self, min_delta: Duration) -> Self { Self { name: self.name.clone(), @@ -112,10 +144,20 @@ impl TimingTree { } } + #[cfg(feature = "timing")] pub fn print(&self) { self.print_helper(0); } + #[cfg(not(feature = "timing"))] + pub fn print(&self) { + log!( + self.0, + "TimingTree is not supported without the 'timing' feature enabled" + ); + } + + #[cfg(feature = "timing")] fn print_helper(&self, depth: usize) { let prefix = "| ".repeat(depth); log!(