openvm_benchmarks_execute/
main.rs
1use cargo_openvm::{default::DEFAULT_APP_CONFIG_PATH, util::read_config_toml_or_default};
2use clap::{Parser, ValueEnum};
3use eyre::Result;
4use openvm_benchmarks_utils::{get_elf_path, get_programs_dir, read_elf_file};
5use openvm_circuit::arch::{instructions::exe::VmExe, VmExecutor};
6use openvm_sdk::StdIn;
7use openvm_stark_sdk::bench::run_with_metric_collection;
8use openvm_transpiler::FromElf;
9
10#[derive(Debug, Clone, ValueEnum)]
11enum BuildProfile {
12 Debug,
13 Release,
14}
15
16static AVAILABLE_PROGRAMS: &[&str] = &[
17 "fibonacci_recursive",
18 "fibonacci_iterative",
19 "quicksort",
20 "bubblesort",
21 "pairing",
22 "keccak256",
23 "keccak256_iter",
24 "sha256",
25 "sha256_iter",
26 "revm_transfer",
27 "revm_snailtracer",
28];
29
30#[derive(Parser)]
31#[command(author, version, about = "OpenVM Benchmark CLI", long_about = None)]
32struct Cli {
33 #[arg(short, long)]
35 programs: Vec<String>,
36
37 #[arg(short, long)]
39 skip: Vec<String>,
40
41 #[arg(short, long, default_value = "OUTPUT_PATH")]
43 output: String,
44
45 #[arg(short, long)]
47 list: bool,
48
49 #[arg(short, long)]
51 verbose: bool,
52}
53
54fn main() -> Result<()> {
55 let cli = Cli::parse();
56
57 if cli.list {
58 println!("Available benchmark programs:");
59 for program in AVAILABLE_PROGRAMS {
60 println!(" {}", program);
61 }
62 return Ok(());
63 }
64
65 if cli.verbose {
67 tracing_subscriber::fmt::init();
68 }
69
70 let mut programs_to_run = if cli.programs.is_empty() {
71 AVAILABLE_PROGRAMS.to_vec()
72 } else {
73 for program in &cli.programs {
75 if !AVAILABLE_PROGRAMS.contains(&program.as_str()) {
76 eprintln!("Unknown program: {}", program);
77 eprintln!("Use --list to see available programs");
78 std::process::exit(1);
79 }
80 }
81 cli.programs.iter().map(|s| s.as_str()).collect()
82 };
83
84 if !cli.skip.is_empty() {
86 for program in &cli.skip {
88 if !AVAILABLE_PROGRAMS.contains(&program.as_str()) {
89 eprintln!("Unknown program to skip: {}", program);
90 eprintln!("Use --list to see available programs");
91 std::process::exit(1);
92 }
93 }
94
95 let skip_set: Vec<&str> = cli.skip.iter().map(|s| s.as_str()).collect();
96 programs_to_run.retain(|&program| !skip_set.contains(&program));
97 }
98
99 tracing::info!("Starting benchmarks with metric collection");
100
101 run_with_metric_collection(&cli.output, || -> Result<()> {
102 for program in &programs_to_run {
103 tracing::info!("Running program: {}", program);
104
105 let program_dir = get_programs_dir().join(program);
106 let elf_path = get_elf_path(&program_dir);
107 let elf = read_elf_file(&elf_path)?;
108
109 let config_path = program_dir.join(DEFAULT_APP_CONFIG_PATH);
110 let vm_config = read_config_toml_or_default(&config_path)?.app_vm_config;
111
112 let exe = VmExe::from_elf(elf, vm_config.transpiler())?;
113
114 let executor = VmExecutor::new(vm_config);
115 executor.execute(exe, StdIn::default())?;
116 tracing::info!("Completed program: {}", program);
117 }
118 tracing::info!("All programs executed successfully");
119 Ok(())
120 })
121}