Skip to main content

cargo_airbender/commands/
run.rs

1use 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}