cargo_airbender/commands/
run.rs1use crate::cli::{FlamegraphArgs, RunArgs};
2use crate::error::{CliError, Result};
3use crate::input;
4use crate::ui;
5use airbender_host::Runner;
6
7pub fn flamegraph(args: FlamegraphArgs) -> Result<()> {
8 let input_words = input::parse_input_words(&args.input)?;
9 let flamegraph_output = args.output.clone();
10 let flamegraph = airbender_host::FlamegraphConfig {
11 output: args.output,
12 sampling_rate: args.sampling_rate,
13 inverse: args.inverse,
14 elf_path: args.elf_path,
15 };
16 let runner = airbender_host::TranspilerRunnerBuilder::new(&args.app_bin)
17 .with_flamegraph(flamegraph)
18 .maybe_cycles(args.cycles)
19 .build()
20 .map_err(|err| {
21 CliError::with_source(
22 format!(
23 "failed to initialize transpiler runner for `{}`",
24 args.app_bin.display()
25 ),
26 err,
27 )
28 })?;
29
30 let outcome = runner.run(&input_words).map_err(|err| {
31 CliError::with_source(
32 format!(
33 "failed to generate flamegraph for `{}`",
34 args.app_bin.display()
35 ),
36 err,
37 )
38 })?;
39
40 report_execution_outcome("transpiler", &outcome);
41 ui::field("flamegraph", flamegraph_output.display());
42
43 Ok(())
44}
45
46pub fn run(args: RunArgs) -> Result<()> {
47 let input_words = input::parse_input_words(&args.input)?;
48 let mut builder = airbender_host::TranspilerRunnerBuilder::new(&args.app_bin)
49 .maybe_cycles(args.cycles)
50 .maybe_text_path(args.text_path.as_ref());
51 if args.jit {
52 builder = builder.with_jit();
53 }
54 let runner = builder.build().map_err(|err| {
55 CliError::with_source(
56 format!(
57 "failed to initialize transpiler runner for `{}`",
58 args.app_bin.display()
59 ),
60 err,
61 )
62 })?;
63
64 let outcome = runner.run(&input_words).map_err(|err| {
65 CliError::with_source(
66 format!(
67 "transpiler execution failed for `{}`",
68 args.app_bin.display()
69 ),
70 err,
71 )
72 })?;
73
74 report_execution_outcome("transpiler", &outcome);
75
76 Ok(())
77}
78
79fn report_execution_outcome(mode: &str, outcome: &airbender_host::ExecutionResult) {
80 ui::success(format!("{mode} execution finished"));
81 ui::field("cycles", outcome.cycles_executed);
82 ui::field("reached_end", outcome.reached_end);
83 ui::field("outputs", format_output_registers(&outcome.receipt.output));
84}
85
86fn format_output_registers(output: &[u32]) -> String {
87 if output.is_empty() {
88 return "<none>".to_string();
89 }
90
91 let mut registers = String::new();
92 for (offset, value) in output.iter().enumerate() {
93 use std::fmt::Write;
94 let _ = write!(registers, "x{}={} ", offset + 10, value);
95 }
96
97 registers.trim_end().to_string()
98}