Skip to main content

noirc_artifacts_info/
lib.rs

1use acvm::acir::circuit::ExpressionWidth;
2use iter_extended::vecmap;
3use noirc_artifacts::program::ProgramArtifact;
4use prettytable::{Row, row, table};
5use rayon::iter::{IndexedParallelIterator, IntoParallelIterator, ParallelIterator};
6use serde::Serialize;
7
8#[derive(Debug, Default, Serialize)]
9pub struct InfoReport {
10    pub programs: Vec<ProgramInfo>,
11}
12
13#[derive(Debug, Serialize)]
14pub struct ProgramInfo {
15    pub package_name: String,
16    #[serde(skip)]
17    pub expression_width: Option<ExpressionWidth>,
18    pub functions: Vec<FunctionInfo>,
19    #[serde(skip)]
20    pub unconstrained_functions_opcodes: usize,
21    pub unconstrained_functions: Vec<FunctionInfo>,
22}
23
24impl From<ProgramInfo> for Vec<Row> {
25    fn from(program_info: ProgramInfo) -> Self {
26        let expression_width = if let Some(expression_width) = program_info.expression_width {
27            format!("{expression_width:?}")
28        } else {
29            "N/A".to_string()
30        };
31        let mut main = vecmap(program_info.functions, |function| {
32            row![
33                Fm->format!("{}", program_info.package_name),
34                Fc->format!("{}", function.name),
35                format!("{}", expression_width),
36                Fc->format!("{}", function.opcodes),
37                Fc->format!("{}", program_info.unconstrained_functions_opcodes),
38            ]
39        });
40        main.extend(vecmap(program_info.unconstrained_functions, |function| {
41            row![
42                Fm->format!("{}", program_info.package_name),
43                Fc->format!("{}", function.name),
44                format!("N/A", ),
45                Fc->format!("N/A"),
46                Fc->format!("{}", function.opcodes),
47            ]
48        }));
49        main
50    }
51}
52
53#[derive(Debug, Serialize)]
54pub struct FunctionInfo {
55    pub name: String,
56    pub opcodes: usize,
57}
58
59pub fn count_opcodes_and_gates_in_program(
60    compiled_program: ProgramArtifact,
61    package_name: String,
62    expression_width: Option<ExpressionWidth>,
63) -> ProgramInfo {
64    let functions = compiled_program
65        .bytecode
66        .functions
67        .into_par_iter()
68        .enumerate()
69        .map(|(i, function)| FunctionInfo {
70            name: compiled_program.names[i].clone(),
71            opcodes: function.opcodes.len(),
72        })
73        .collect();
74
75    let opcodes_len: Vec<usize> = compiled_program
76        .bytecode
77        .unconstrained_functions
78        .iter()
79        .map(|func| func.bytecode.len())
80        .collect();
81    let unconstrained_functions_opcodes = compiled_program
82        .bytecode
83        .unconstrained_functions
84        .into_par_iter()
85        .map(|function| function.bytecode.len())
86        .sum();
87    let unconstrained_info: Vec<FunctionInfo> = compiled_program
88        .brillig_names
89        .clone()
90        .iter()
91        .zip(opcodes_len)
92        .map(|(name, len)| FunctionInfo { name: name.clone(), opcodes: len })
93        .collect();
94
95    ProgramInfo {
96        package_name,
97        expression_width,
98        functions,
99        unconstrained_functions_opcodes,
100        unconstrained_functions: unconstrained_info,
101    }
102}
103
104pub fn show_info_report(info_report: InfoReport, json: bool) {
105    if json {
106        // Expose machine-readable JSON data.
107        println!("{}", serde_json::to_string(&info_report).unwrap());
108    } else {
109        // Otherwise print human-readable table.
110        if !info_report.programs.is_empty() {
111            let mut program_table = table!([Fm->"Package", Fm->"Function", Fm->"Expression Width", Fm->"ACIR Opcodes", Fm->"Brillig Opcodes"]);
112
113            for program_info in info_report.programs {
114                let program_rows: Vec<Row> = program_info.into();
115                for row in program_rows {
116                    program_table.add_row(row);
117                }
118            }
119            program_table.printstd();
120        }
121    }
122}