use core::fmt::{Debug, Display};
use cubecl::tile::launch::{Refusal, Vectorization};
use cubecl::tune::Work;
use crate::Hardware;
use crate::microkernel::{KernelEstimate, Microkernel};
use crate::routine::Grid;
pub const ADMITTED_PLAN_RUNS: &str =
"the selector admitted this plan, so the tile engine launches it and binds its operands";
pub const ROUTINE_LISTS_NO_SETTING: Refusal = Refusal::Declined {
why: "the routine lists no setting on this device",
};
pub trait Routine {
type Problem: Debug + Clone + EstimatedProblem;
type Microkernel: Microkernel;
type Settings: Debug + Clone + Display;
type Blueprint: Debug + Clone + PartialEq;
type Partitioning: Debug + Clone;
fn settings(&self, hw: &Hardware) -> Vec<Self::Settings>;
fn vectorize(
&self,
microkernel: &Self::Microkernel,
partitioning: &Self::Partitioning,
vectorization: &mut Vectorization<<Self::Microkernel as Microkernel>::Operand>,
);
fn prepare(
&self,
hw: &Hardware,
problem: &Self::Problem,
settings: &Self::Settings,
) -> Result<(Self::Blueprint, Grid), Refusal>;
fn prepare_first_served(
&self,
hw: &Hardware,
problem: &Self::Problem,
) -> Result<(Self::Blueprint, Grid), Refusal> {
let mut declined = ROUTINE_LISTS_NO_SETTING;
for settings in self.settings(hw) {
match self.prepare(hw, problem, &settings) {
Ok(prepared) => return Ok(prepared),
Err(why) => declined = why,
}
}
Err(declined)
}
fn estimate(
&self,
problem: &Self::Problem,
blueprint: &Self::Blueprint,
grid: &Grid,
estimate: &mut KernelEstimate,
);
}
pub trait EstimatedProblem {
fn demand(&self) -> Work;
}