diff --git a/setup.py b/setup.py index c1f4b566..486680ae 100644 --- a/setup.py +++ b/setup.py @@ -7,7 +7,6 @@ # Ensure these are present (in case we are not using PEP-518 compatible build # system). import setuptools_scm -import toml scalib_features = ["pyo3/abi3"] diff --git a/src/scalib/attacks/sascagraph.py b/src/scalib/attacks/sascagraph.py index ad264048..0759aea7 100644 --- a/src/scalib/attacks/sascagraph.py +++ b/src/scalib/attacks/sascagraph.py @@ -223,13 +223,15 @@ def set_table(self, table, values): ) self.tables_[table] = values - def run_bp(self, it): + def run_bp(self, it, progress=False): r"""Runs belief propagation algorithm on the current state of the graph. Parameters ---------- it : int Number of iterations of belief propagation. + progress: bool + Show a progress bar (default: False). """ if self.solved_: raise Exception("Cannot run bp twice on a graph.") @@ -241,6 +243,7 @@ def run_bp(self, it): self.edge_, self.nc_, self.n_, + progress, ) self.solved_ = True diff --git a/src/scalib_ext/scalib-py/src/belief_propagation.rs b/src/scalib_ext/scalib-py/src/belief_propagation.rs index c9890dd0..b20580c8 100644 --- a/src/scalib_ext/scalib-py/src/belief_propagation.rs +++ b/src/scalib_ext/scalib-py/src/belief_propagation.rs @@ -89,6 +89,8 @@ pub fn run_bp( nc: usize, // number of copies in the graph (n_runs) n: usize, + // show a progress bar + progress: bool, ) -> PyResult<()> { // map all python functions to rust ones + generate the mapping in vec_functs_id let functions_rust: Vec = functions @@ -104,8 +106,16 @@ pub fn run_bp( .map(|x| to_var(x.downcast::().unwrap())) .collect(); - scalib::belief_propagation::run_bp(&functions_rust, &mut variables_rust, it, edge, nc, n) - .unwrap(); + scalib::belief_propagation::run_bp( + &functions_rust, + &mut variables_rust, + it, + edge, + nc, + n, + progress, + ) + .unwrap(); variables_rust .iter() diff --git a/src/scalib_ext/scalib-py/src/lib.rs b/src/scalib_ext/scalib-py/src/lib.rs index aa52d4ca..8f8cfa85 100644 --- a/src/scalib_ext/scalib-py/src/lib.rs +++ b/src/scalib_ext/scalib-py/src/lib.rs @@ -43,8 +43,9 @@ fn _scalib_ext(_py: Python, m: &PyModule) -> PyResult<()> { vertex: usize, nc: usize, n: usize, + progress: bool, ) -> PyResult<()> { - belief_propagation::run_bp(py, functions, variables, it, vertex, nc, n) + belief_propagation::run_bp(py, functions, variables, it, vertex, nc, n, progress) } #[pyfn(m, "partial_cp")] diff --git a/src/scalib_ext/scalib/src/belief_propagation.rs b/src/scalib_ext/scalib/src/belief_propagation.rs index 3a4558c2..482451b1 100644 --- a/src/scalib_ext/scalib/src/belief_propagation.rs +++ b/src/scalib_ext/scalib/src/belief_propagation.rs @@ -351,6 +351,8 @@ pub fn run_bp( nc: usize, // number of copies in the graph (n_runs) n: usize, + // show a progress bar + progress: bool, ) -> Result<(), ()> { // Scratch array containing all the edge's messages. let mut edges: Vec> = vec![Array2::::ones((n, nc)); edge]; @@ -386,15 +388,7 @@ pub fn run_bp( } } - // loading bar - let pb = ProgressBar::new(it as u64); - pb.set_style(ProgressStyle::default_spinner().template( - "{msg} {spinner:.green} [{elapsed_precise}] [{bar:40.cyan/blue}] ({pos}/{len}, ETA {eta})", - ) - .on_finish(ProgressFinish::AndClear)); - pb.set_message("Calculating BP..."); - - for _ in (0..it).progress_with(pb) { + let mut bp_iter = || { // This is a technique for runtime borrow-checking: we take reference on all the edges // at once, put them into options, then extract the references out of the options, one // at a time and out-of-order. @@ -422,6 +416,23 @@ pub fn run_bp( }) .collect(); update_variables(&mut edge_for_var, variables); + }; + + if progress { + // loading bar + let pb = ProgressBar::new(it as u64); + pb.set_style(ProgressStyle::default_spinner().template( + "{msg} {spinner:.green} [{elapsed_precise}] [{bar:40.cyan/blue}] ({pos}/{len}, ETA {eta})", + ) + .on_finish(ProgressFinish::AndClear)); + pb.set_message("Calculating BP..."); + for _ in (0..it).progress_with(pb) { + bp_iter(); + } + } else { + for _ in 0..it { + bp_iter(); + } } Ok(())