Skip to content

Commit

Permalink
feat: compile circuits for nargo info in parallel
Browse files Browse the repository at this point in the history
  • Loading branch information
TomAFrench committed Sep 12, 2023
1 parent 476f8a9 commit 73a85b3
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 77 deletions.
64 changes: 33 additions & 31 deletions tooling/nargo_cli/src/cli/compile_cmd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,20 +63,45 @@ pub(crate) fn run(
let workspace = resolve_workspace_from_toml(&toml_path, selection)?;
let circuit_dir = workspace.target_directory_path();

let (np_language, is_opcode_supported) = backend.get_backend_info()?;

let (binary_packages, contract_packages): (Vec<_>, Vec<_>) = workspace
.members
.iter()
.into_iter()
.filter(|package| !package.is_library())
.partition(|package| package.is_binary());

let (compiled_programs, compiled_contracts) =
compile_workspace(backend, &binary_packages, &contract_packages, &args.compile_options)?;

// Save build artifacts to disk.
for (package, (program, debug_artifact)) in binary_packages.into_iter().zip(compiled_programs) {
save_program(debug_artifact, program, &package, &circuit_dir, args.output_debug);
}
for (package, contracts_with_debug_artifacts) in
contract_packages.into_iter().zip(compiled_contracts)
{
save_contracts(contracts_with_debug_artifacts, &package, &circuit_dir, args.output_debug);
}

Ok(())
}

pub(super) fn compile_workspace(
backend: &Backend,
binary_packages: &[Package],
contract_packages: &[Package],
compile_options: &CompileOptions,
) -> Result<
(Vec<(CompiledProgram, DebugArtifact)>, Vec<Vec<(CompiledContract, DebugArtifact)>>),
CliError,
> {
let (np_language, is_opcode_supported) = backend.get_backend_info()?;

// Compile all of the packages in parallel.
let program_results: Vec<(FileManager, CompilationResult<(CompiledProgram, DebugArtifact)>)> =
binary_packages
.par_iter()
.map(|package| {
compile_program(package, &args.compile_options, np_language, &is_opcode_supported)
compile_program(package, &compile_options, np_language, &is_opcode_supported)
})
.collect();
#[allow(clippy::type_complexity)]
Expand All @@ -86,35 +111,25 @@ pub(crate) fn run(
)> = contract_packages
.par_iter()
.map(|package| {
compile_contracts(package, &args.compile_options, np_language, &is_opcode_supported)
compile_contracts(package, &compile_options, np_language, &is_opcode_supported)
})
.collect();

// Report any warnings/errors which were encountered during compilation.
let compiled_programs: Vec<(CompiledProgram, DebugArtifact)> = program_results
.into_iter()
.map(|(file_manager, compilation_result)| {
report_errors(compilation_result, &file_manager, args.compile_options.deny_warnings)
report_errors(compilation_result, &file_manager, compile_options.deny_warnings)
})
.collect::<Result<_, _>>()?;
let compiled_contracts: Vec<Vec<(CompiledContract, DebugArtifact)>> = contract_results
.into_iter()
.map(|(file_manager, compilation_result)| {
report_errors(compilation_result, &file_manager, args.compile_options.deny_warnings)
report_errors(compilation_result, &file_manager, compile_options.deny_warnings)
})
.collect::<Result<_, _>>()?;

// Save build artifacts to disk.
for (package, (program, debug_artifact)) in binary_packages.into_iter().zip(compiled_programs) {
save_program(debug_artifact, program, package, &circuit_dir, args.output_debug);
}
for (package, contracts_with_debug_artifacts) in
contract_packages.into_iter().zip(compiled_contracts)
{
save_contracts(contracts_with_debug_artifacts, package, &circuit_dir, args.output_debug);
}

Ok(())
Ok((compiled_programs, compiled_contracts))
}

pub(crate) fn compile_bin_package(
Expand All @@ -136,19 +151,6 @@ pub(crate) fn compile_bin_package(
Ok((program, debug_artifact))
}

pub(crate) fn compile_contract_package(
package: &Package,
compile_options: &CompileOptions,
np_language: Language,
is_opcode_supported: &impl Fn(&Opcode) -> bool,
) -> Result<Vec<(CompiledContract, DebugArtifact)>, CliError> {
let (file_manager, compilation_result) =
compile_contracts(package, compile_options, np_language, &is_opcode_supported);
let contracts_with_debug_artifacts =
report_errors(compilation_result, &file_manager, compile_options.deny_warnings)?;
Ok(contracts_with_debug_artifacts)
}

fn compile_program(
package: &Package,
compile_options: &CompileOptions,
Expand Down
83 changes: 37 additions & 46 deletions tooling/nargo_cli/src/cli/info_cmd.rs
Original file line number Diff line number Diff line change
@@ -1,22 +1,18 @@
use acvm::acir::circuit::Opcode;
use acvm::Language;
use acvm_backend_barretenberg::BackendError;
use clap::Args;
use iter_extended::{try_vecmap, vecmap};
use nargo::package::Package;
use nargo_toml::{get_package_manifest, resolve_workspace_from_toml, PackageSelection};
use noirc_driver::CompileOptions;
use noirc_driver::{CompileOptions, CompiledContract, CompiledProgram};
use noirc_frontend::graph::CrateName;
use prettytable::{row, table, Row};
use serde::Serialize;

use crate::backends::Backend;
use crate::errors::CliError;

use super::{
compile_cmd::{compile_bin_package, compile_contract_package},
NargoConfig,
};
use super::{compile_cmd::compile_workspace, NargoConfig};

/// Provides detailed information on a circuit
///
Expand Down Expand Up @@ -52,30 +48,36 @@ pub(crate) fn run(
let selection = args.package.map_or(default_selection, PackageSelection::Selected);
let workspace = resolve_workspace_from_toml(&toml_path, selection)?;

let mut info_report = InfoReport::default();

let (np_language, is_opcode_supported) = backend.get_backend_info()?;
for package in &workspace {
if package.is_contract() {
let contract_info = count_opcodes_and_gates_in_contracts(
backend,
package,
&args.compile_options,
np_language,
&is_opcode_supported,
)?;
info_report.contracts.extend(contract_info);
} else {
let program_info = count_opcodes_and_gates_in_program(
backend,
package,
&args.compile_options,
np_language,
&is_opcode_supported,
)?;
info_report.programs.push(program_info);
}
}
let (binary_packages, contract_packages): (Vec<_>, Vec<_>) = workspace
.members
.into_iter()
.filter(|package| !package.is_library())
.partition(|package| package.is_binary());

let (compiled_programs, compiled_contracts) =
compile_workspace(backend, &binary_packages, &contract_packages, &args.compile_options)
.map(|(programs, contracts_vec)| {
// TODO: We must be able to handle this a better way.
(
vecmap(programs, |(program, _)| program),
vecmap(contracts_vec, |contracts| vecmap(contracts, |(contract, _)| contract)),
)
})?;

let (np_language, _) = backend.get_backend_info()?;
let program_info =
try_vecmap(binary_packages.iter().zip(compiled_programs), |(package, program)| {
count_opcodes_and_gates_in_program(backend, program, package, np_language)
})?;

let contract_info = try_vecmap(compiled_contracts, |contracts| {
count_opcodes_and_gates_in_contracts(backend, contracts, np_language)
})?;

let info_report = InfoReport {
programs: program_info,
contracts: contract_info.into_iter().flatten().collect(),
};

if args.json {
// Expose machine-readable JSON data.
Expand Down Expand Up @@ -169,15 +171,10 @@ impl From<ContractInfo> for Vec<Row> {

fn count_opcodes_and_gates_in_program(
backend: &Backend,
compiled_program: CompiledProgram,
package: &Package,
compile_options: &CompileOptions,
np_language: Language,
is_opcode_supported: &impl Fn(&Opcode) -> bool,
language: Language,
) -> Result<ProgramInfo, CliError> {
let (compiled_program, _) =
compile_bin_package(package, compile_options, np_language, &is_opcode_supported)?;
let (language, _) = backend.get_backend_info()?;

Ok(ProgramInfo {
name: package.name.to_string(),
language,
Expand All @@ -188,16 +185,10 @@ fn count_opcodes_and_gates_in_program(

fn count_opcodes_and_gates_in_contracts(
backend: &Backend,
package: &Package,
compile_options: &CompileOptions,
np_language: Language,
is_opcode_supported: &impl Fn(&Opcode) -> bool,
compiled_contracts: Vec<CompiledContract>,
language: Language,
) -> Result<Vec<ContractInfo>, CliError> {
let contracts =
compile_contract_package(package, compile_options, np_language, &is_opcode_supported)?;
let (language, _) = backend.get_backend_info()?;

try_vecmap(contracts, |(contract, _)| {
try_vecmap(compiled_contracts, |contract| {
let functions = try_vecmap(contract.functions, |function| -> Result<_, BackendError> {
Ok(FunctionInfo {
name: function.name,
Expand Down

0 comments on commit 73a85b3

Please sign in to comment.