use cubecl::prelude::*;
use crate::*;
pub(crate) const FIRST_SLOT: usize = 0;
#[derive(CubeType)]
pub struct Slot<T: CubeType> {
pub(crate) data: T,
pub(crate) pipeline: Meeting,
#[cube(comptime)]
pub(crate) refills: Vec<Refill>,
}
#[cube]
impl<T: CubeType> Slot<T> {
pub(crate) fn wrap(data: T, pipeline: Meeting, #[comptime] refills: Vec<Refill>) -> Slot<T> {
Slot::<T> {
data,
pipeline,
refills,
}
}
#[allow(dead_code)] pub(crate) fn has_fixed(&self) -> comptime_type!(bool) {
comptime!(self.refills.contains(&Refill::Once))
}
#[allow(dead_code)] pub(crate) fn acquire_write(&self) {
match &self.pipeline {
Meeting::Barrier { empty, writes, .. } => empty.wait_parity(*writes ^ 1),
Meeting::Cube => sync_cube(),
Meeting::Plane => sync_plane(),
}
}
#[allow(dead_code)] pub(crate) fn release_write(&mut self) {
match &mut self.pipeline {
Meeting::Barrier {
full,
all_publish,
commits,
elected,
writes,
..
} => {
if *all_publish || UNIT_POS == *elected {
if *commits {
full.commit_copy_async();
}
full.arrive();
}
*writes ^= 1;
}
Meeting::Cube | Meeting::Plane => {}
}
}
#[allow(dead_code)] pub(crate) fn acquire_read(&self) {
match &self.pipeline {
Meeting::Barrier { full, reads, .. } => full.wait_parity(*reads),
Meeting::Cube | Meeting::Plane => {}
}
}
#[allow(dead_code)] pub(crate) fn release_read(&mut self) {
match &mut self.pipeline {
Meeting::Barrier { empty, reads, .. } => {
empty.arrive();
*reads ^= 1;
}
Meeting::Cube | Meeting::Plane => {}
}
}
pub fn publish(&self) {
match &self.pipeline {
Meeting::Cube => sync_cube(),
Meeting::Plane => sync_plane(),
Meeting::Barrier { .. } => {}
}
}
}