cubek_std/tile/
scheduler.rs1use cubecl::prelude::*;
2
3use crate::PartitionSize;
4
5#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
7pub enum PartitionSchedulerScheme {
8 Offset,
10 Naive,
12}
13
14#[derive(CubeType)]
17pub struct PartitionScheduler {
18 pub m: AxisScheduler,
19 pub n: AxisScheduler,
20 pub k: AxisScheduler,
21}
22
23#[cube]
24impl PartitionScheduler {
25 pub fn new(
30 partition_index_m: u32,
31 partition_index_n: u32,
32 #[comptime] partition_size: PartitionSize,
33 #[comptime] partition_schedule_scheme: PartitionSchedulerScheme,
34 ) -> PartitionScheduler {
35 match partition_schedule_scheme {
36 PartitionSchedulerScheme::Offset => {
37 let m_offset = (partition_index_n / partition_size.k()) % partition_size.m();
39
40 let n_offset = (partition_index_m / partition_size.k()) % partition_size.n();
42
43 let k_offset = (partition_index_m + partition_index_n) % partition_size.k();
45
46 PartitionScheduler {
47 m: AxisScheduler::new_Offset(OffsetAxisScheduler::new(
48 m_offset,
49 partition_index_m,
50 partition_size.m(),
51 )),
52 n: AxisScheduler::new_Offset(OffsetAxisScheduler::new(
53 n_offset,
54 partition_index_n,
55 partition_size.n(),
56 )),
57 k: AxisScheduler::new_Offset(OffsetAxisScheduler::new(
58 k_offset,
59 0u32,
60 partition_size.k(),
61 )),
62 }
63 }
64 PartitionSchedulerScheme::Naive => PartitionScheduler {
65 m: AxisScheduler::new_Naive(NaiveAxisScheduler::new(
66 partition_index_m,
67 partition_size.m(),
68 )),
69 n: AxisScheduler::new_Naive(NaiveAxisScheduler::new(
70 partition_index_n,
71 partition_size.n(),
72 )),
73 k: AxisScheduler::new_Naive(NaiveAxisScheduler::new(0u32, partition_size.k())),
74 },
75 }
76 }
77
78 pub fn map_m(&self, i: u32) -> u32 {
80 self.m.map(i)
81 }
82
83 pub fn map_n(&self, i: u32) -> u32 {
85 self.n.map(i)
86 }
87
88 pub fn map_k(&self, i: u32) -> u32 {
90 self.k.map(i)
91 }
92}
93
94#[derive(CubeType)]
96#[allow(unused)]
97pub enum AxisScheduler {
98 Offset(OffsetAxisScheduler),
99 Naive(NaiveAxisScheduler),
100}
101
102#[derive(CubeType)]
108pub struct OffsetAxisScheduler {
109 inner_offset: u32,
110 outer_offset: u32,
111 #[cube(comptime)]
112 len: u32,
113}
114
115#[derive(CubeType)]
118pub struct NaiveAxisScheduler {
119 outer_offset: u32,
120}
121
122#[cube]
123impl AxisScheduler {
124 pub fn map(&self, i: u32) -> u32 {
125 match self {
126 AxisScheduler::Offset(offset_axis_scheduler) => offset_axis_scheduler.map(i),
127 AxisScheduler::Naive(naive_axis_scheduler) => naive_axis_scheduler.map(i),
128 }
129 }
130}
131
132#[cube]
133impl OffsetAxisScheduler {
134 pub fn new(
135 inner_offset: u32,
136 partition_index: u32,
137 #[comptime] len: u32,
138 ) -> OffsetAxisScheduler {
139 let outer_offset = partition_index * len;
140 OffsetAxisScheduler {
141 inner_offset,
142 outer_offset,
143 len,
144 }
145 }
146
147 pub fn map(&self, i: u32) -> u32 {
148 let relative = (i + self.inner_offset) % self.len;
149 relative + self.outer_offset
150 }
151}
152
153#[cube]
154impl NaiveAxisScheduler {
155 pub fn new(partition_index: u32, #[comptime] len: u32) -> NaiveAxisScheduler {
156 let outer_offset = partition_index * len;
157 NaiveAxisScheduler { outer_offset }
158 }
159
160 pub fn map(&self, i: u32) -> u32 {
161 i + self.outer_offset
162 }
163}
164
165#[derive(Default, Clone, Copy, PartialEq, Eq, Hash, Debug)]
169pub enum PartitionBuffering {
170 Single,
171 #[default]
172 Double,
173}