use cubecl::tile::launch::Refusal;
use cubecl_environment::sync::Mutex;
use crate::Hardware;
use crate::routine::{Grid, Routine};
type Prepared<R> = Result<(<R as Routine>::Blueprint, Grid), Refusal>;
pub struct PreparedLaunches<R: Routine> {
held: Mutex<Vec<(R::Problem, Prepared<R>)>>,
}
impl<R: Routine> PreparedLaunches<R>
where
R::Problem: PartialEq,
{
pub const CAPACITY: usize = 16;
pub fn prepare(
&self,
routine: &R,
hw: &Hardware,
problem: &R::Problem,
settings: &R::Settings,
) -> Prepared<R> {
let mut held = self.held.lock();
if let Some((_, prepared)) = held.iter().find(|(held, _)| held == problem) {
return prepared.clone();
}
let prepared = routine.prepare(hw, problem, settings);
if held.len() == Self::CAPACITY {
drop(held.remove(0));
}
held.push((problem.clone(), prepared.clone()));
prepared
}
}
impl<R: Routine> Default for PreparedLaunches<R> {
fn default() -> Self {
Self {
held: Mutex::new(Vec::new()),
}
}
}
impl<R: Routine> core::fmt::Debug for PreparedLaunches<R> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.debug_struct("PreparedLaunches")
.field("held", &self.held.lock().len())
.finish()
}
}