joule-profiler-cli 3.0.1

CLI tool to measure program energy consumption
Documentation
use anyhow::Result;
use joule_profiler_cli::config::load_global_config;
use joule_profiler_cli::config::source::register_source;
use joule_profiler_cli::config::table::ConfigTable;
use joule_profiler_cli::{CliArgs, config_table_to_displayer, init_logging};
use joule_profiler_core::JouleProfiler;
use joule_profiler_core::config::Command;

#[cfg(feature = "_rapl")]
use joule_profiler_cli::RaplBackend;
#[cfg(feature = "amdsmi")]
use joule_profiler_source_amdsmi::AmdSmi;
#[cfg(feature = "cgroup")]
use joule_profiler_source_cgroup::Cgroup;
#[cfg(feature = "nvml")]
use joule_profiler_source_nvml::Nvml;
#[cfg(feature = "perf_event")]
use joule_profiler_source_perf_event::PerfEvent;
#[cfg(feature = "procfs")]
use joule_profiler_source_procfs::Procfs;
#[cfg(feature = "rapl-perf")]
use joule_profiler_source_rapl::perf;
#[cfg(feature = "rapl-powercap")]
use joule_profiler_source_rapl::powercap;

#[tokio::main]
async fn main() -> Result<()> {
    let mut cli = CliArgs::from_args();
    cli.validate()?;

    init_logging(cli.verbose);

    let mut profiler = JouleProfiler::new();

    let global_config = load_global_config(cli.config_file.as_deref(), &cli.overrides)?;
    let mut config_table = ConfigTable::new(global_config, &cli.sources);

    config_table.apply_cli(&mut cli);

    #[cfg(feature = "_rapl")]
    match config_table.profiler_config.rapl_backend {
        #[cfg(feature = "rapl-perf")]
        RaplBackend::Perf => register_source::<perf::Rapl>(&mut profiler, &mut config_table),
        #[cfg(feature = "rapl-powercap")]
        RaplBackend::Powercap => {
            register_source::<powercap::Rapl>(&mut profiler, &mut config_table)
        }
    }?;

    #[cfg(feature = "perf_event")]
    register_source::<PerfEvent>(&mut profiler, &mut config_table)?;

    #[cfg(feature = "cgroup")]
    register_source::<Cgroup>(&mut profiler, &mut config_table)?;

    #[cfg(feature = "procfs")]
    register_source::<Procfs>(&mut profiler, &mut config_table)?;

    #[cfg(feature = "nvml")]
    register_source::<Nvml>(&mut profiler, &mut config_table)?;

    #[cfg(feature = "amdsmi")]
    register_source::<AmdSmi>(&mut profiler, &mut config_table)?;

    config_table.ensure_sources_are_known()?;

    let mut displayer = config_table_to_displayer(&config_table)?;
    let config = config_table.to_config(cli)?;

    match config.command {
        Command::Profile(profile_config) => {
            let results = profiler.profile(&profile_config).await?;
            displayer.display_results(
                &profile_config.cmd,
                &profile_config.token_pattern,
                &results,
            )?;
        }
        Command::ListSensors => {
            let sensors = profiler.list_sensors()?;
            displayer.list_sensors(&sensors)?;
        }
    }

    Ok(())
}