pub mod time;
use crate::{context::HeatCliContext, generation::crate_gen::backend::BackendType, print_info};
#[derive(Debug, Clone)]
pub struct RunCommand {
pub run_id: String,
pub run_params: RunParams,
}
#[derive(Debug, Clone)]
pub enum RunParams {
Training {
function: String,
config_path: String,
project: String,
key: String,
},
}
#[derive(Debug)]
pub struct BuildCommand {
pub run_id: String,
pub backend: BackendType,
}
pub(crate) fn execute_experiment_command(
build_command: BuildCommand,
run_command: RunCommand,
context: &mut HeatCliContext,
) -> anyhow::Result<()> {
execute_build_command(build_command, context)?;
execute_run_command(run_command, context)?;
Ok(())
}
pub(crate) fn execute_build_command(
build_command: BuildCommand,
context: &mut HeatCliContext,
) -> anyhow::Result<()> {
print_info!(
"Building experiment project with command: {:?}",
build_command
);
context.generate_crate(&build_command)?;
let build_status = context.make_build_command(&build_command)?.status();
match build_status {
Err(e) => {
return Err(anyhow::anyhow!(format!(
"Failed to build experiment project: {:?}",
e
)));
}
Ok(status) if !status.success() => {
return Err(anyhow::anyhow!(format!(
"Failed to build experiment project: {:?}",
build_command
)));
}
_ => {
print_info!("Project built successfully.");
}
}
context.copy_executable_to_bin(&build_command.run_id)
}
pub(crate) fn execute_run_command(
run_command: RunCommand,
context: &HeatCliContext,
) -> anyhow::Result<()> {
print_info!("Running experiment with command: {:?}", run_command);
let mut command = context.make_run_command(&run_command);
let run_status = command.status();
match run_status {
Err(e) => {
return Err(anyhow::anyhow!(format!(
"Error running experiment command: {:?}",
e
)));
}
Ok(status) if !status.success() => {
return Err(anyhow::anyhow!(format!(
"Failed to run experiment: {:?}",
run_command
)));
}
_ => {
print_info!("Experiment ran successfully.");
}
}
Ok(())
}
pub(crate) fn execute_sequentially(
commands: Vec<(BuildCommand, RunCommand)>,
mut context: HeatCliContext,
) -> anyhow::Result<()> {
for cmd in commands {
execute_experiment_command(cmd.0, cmd.1, &mut context)?
}
Ok(())
}
pub(crate) fn execute_parallel_build_all_then_run(
commands: Vec<(BuildCommand, RunCommand)>,
mut context: HeatCliContext,
) -> anyhow::Result<()> {
let (build_commands, run_commands): (Vec<BuildCommand>, Vec<RunCommand>) =
commands.into_iter().unzip();
for build_command in build_commands {
execute_build_command(build_command, &mut context)
.expect("Should be able to build experiment.");
}
std::thread::scope(|scope| {
for run_command in &run_commands {
scope.spawn(|| {
execute_run_command(run_command.clone(), &context)
.expect("Should be able to build and run experiment.");
});
}
});
Ok(())
}