use cubecl::{prelude::Client, server::Handle};
use crate::{ExecutionOutcome, TestOutcome, ValidationResult};
#[track_caller]
pub fn launch_and_capture_outcome<F>(
client: &Client,
outputs: &[&Handle],
launch: F,
) -> ExecutionOutcome
where
F: FnOnce(&Client) -> ExecutionOutcome,
{
debug_assert!(
!outputs.is_empty(),
"a launch with no outputs to check cannot report an asynchronous failure"
);
match launch(client) {
ExecutionOutcome::Executed => match Unrun::of(client, outputs) {
Some(unrun) => unrun.outcome(),
None => ExecutionOutcome::Executed,
},
other => other,
}
}
enum Unrun {
Refused(String),
Broken(String),
}
impl Unrun {
fn of(client: &Client, outputs: &[&Handle]) -> Option<Self> {
let error = client.check(outputs.iter().copied()).err()?;
let reason = format!("{error:?}");
Some(match error.is_refusal() {
true => Self::Refused(reason),
false => Self::Broken(reason),
})
}
#[track_caller]
fn outcome(self) -> ExecutionOutcome {
match self {
Self::Refused(reason) => ExecutionOutcome::CompileError(reason),
Self::Broken(reason) => {
TestOutcome::Validated(ValidationResult::Error(reason.clone())).enforce();
ExecutionOutcome::CompileError(reason)
}
}
}
}