cubecl_tile/stage/pipeline/
slot.rs1use cubecl::ir::Scope;
4use cubecl::prelude::*;
5use cubecl::unexpanded;
6
7use super::payload::base::{Payload, PayloadExpand};
8use super::payload::pair::OperandPair;
9use crate::*;
10
11pub(crate) const FIRST_SLOT: usize = 0;
12
13#[derive(CubeType)]
15pub struct Slot<T: CubeType> {
16 pub(crate) data: T,
17 pub(crate) pipeline: Meeting,
18 #[cube(comptime)]
20 pub(crate) refills: Vec<Refill>,
21}
22
23#[cube]
24impl<T: CubeType> Slot<T> {
25 pub(crate) fn wrap(data: T, pipeline: Meeting, #[comptime] refills: Vec<Refill>) -> Slot<T> {
27 Slot::<T> {
28 data,
29 pipeline,
30 refills,
31 }
32 }
33
34 #[allow(dead_code)] pub(crate) fn has_fixed(&self) -> comptime_type!(bool) {
37 comptime!(self.refills.contains(&Refill::Once))
38 }
39
40 #[allow(dead_code)] pub(crate) fn acquire_write(&self) {
43 match &self.pipeline {
44 Meeting::Barrier { empty, writes, .. } => empty.wait_parity(*writes ^ 1),
45 Meeting::Cube => sync_cube(),
46 Meeting::Plane => sync_plane(),
47 }
48 }
49
50 #[allow(dead_code)] pub(crate) fn release_write(&mut self) {
54 match &mut self.pipeline {
55 Meeting::Barrier {
56 full,
57 all_publish,
58 commits,
59 elected,
60 writes,
61 ..
62 } => {
63 if *all_publish || UNIT_POS == *elected {
64 if *commits {
67 full.commit_copy_async();
68 }
69 full.arrive();
70 }
71 *writes ^= 1;
72 }
73 Meeting::Cube | Meeting::Plane => {}
74 }
75 }
76
77 #[allow(dead_code)] pub(crate) fn acquire_read(&self) {
80 match &self.pipeline {
81 Meeting::Barrier { full, reads, .. } => full.wait_parity(*reads),
82 Meeting::Cube | Meeting::Plane => {}
83 }
84 }
85
86 #[allow(dead_code)] pub(crate) fn release_read(&mut self) {
89 match &mut self.pipeline {
90 Meeting::Barrier { empty, reads, .. } => {
91 empty.arrive();
92 *reads ^= 1;
93 }
94 Meeting::Cube | Meeting::Plane => {}
95 }
96 }
97
98 pub fn publish(&self) {
101 match &self.pipeline {
102 Meeting::Cube => sync_cube(),
103 Meeting::Plane => sync_plane(),
104 Meeting::Barrier { .. } => {}
105 }
106 }
107}
108
109#[cube]
110impl<P: Payload<P> + CubeType<ExpandType: Clone>> Slot<P> {
111 pub(crate) fn refill(&mut self, src: &P, region: &Region, #[comptime] only: Refill) {
113 let refills = comptime!(self.refills.clone());
114 let writes = comptime!(refills.contains(&only));
115 if comptime!(writes || only == Refill::EveryRegion) {
116 self.acquire_write();
117 self.data
118 .bring(src, &self.pipeline, region, comptime!(refills), only);
119 self.release_write();
120 }
121 }
122}
123
124impl Slot<OperandPair> {
126 pub fn consume(&mut self, _compute: impl FnOnce(&Tile, &Tile)) {
128 unexpanded!()
129 }
130}
131
132impl SlotExpand<OperandPair> {
133 pub fn __expand_consume_method<F>(&mut self, scope: &Scope, compute: F)
134 where
135 F: FnOnce(&Scope, &TileExpand, &TileExpand),
136 {
137 self.__expand_acquire_read_method(scope);
138 compute(scope, &self.data.lhs, &self.data.rhs);
139 self.__expand_release_read_method(scope);
140 }
141}
142
143impl Slot<Tile> {
144 pub fn consume(&mut self, _compute: impl FnOnce(&Tile)) {
146 unexpanded!()
147 }
148}
149
150impl SlotExpand<Tile> {
151 pub fn __expand_consume_method<F>(&mut self, scope: &Scope, compute: F)
152 where
153 F: FnOnce(&Scope, &TileExpand),
154 {
155 self.__expand_acquire_read_method(scope);
156 compute(scope, &self.data);
157 self.__expand_release_read_method(scope);
158 }
159}