cubecl_core/frontend/container/sequence/
base.rs1use alloc::vec::Vec;
2use cubecl_ir::Scope;
3use serde::{Deserialize, Serialize};
4
5use crate::prelude::*;
6use core::ops::{Deref, Index, IndexMut};
7
8#[derive(Debug, Clone, Hash, PartialEq, Eq, Serialize, Deserialize, PartialOrd, Ord)]
16pub struct Sequence<T: CubeType> {
17 values: Vec<T>,
18}
19
20impl<T: CubeType> Default for Sequence<T> {
21 fn default() -> Self {
22 Self::new()
23 }
24}
25
26impl<T: CubeType> IntoExpand for SequenceExpand<T> {
27 type Expand = Self;
28
29 fn into_expand(self, _scope: &Scope) -> Self::Expand {
30 self
31 }
32}
33
34impl<T: CubeType> IntoMut for Sequence<T> {
35 fn into_mut(self, _scope: &Scope) -> Self {
36 self
37 }
38}
39impl<T: CubeType> CubeDebug for Sequence<T> {}
40
41impl<T: CubeType<ExpandType: Clone>> DerefExpand for SequenceExpand<T> {
42 type Target = Self;
43
44 fn __expand_deref_method(&self, _: &Scope) -> Self::Target {
45 self.clone()
46 }
47}
48
49impl<T: CubeType> Sequence<T> {
50 pub fn reverse(&mut self) {
51 self.values.reverse();
52 }
53
54 pub fn reversed(&self) -> Sequence<T>
55 where
56 T: Clone,
57 {
58 Self {
59 values: self.values.iter().cloned().rev().collect(),
60 }
61 }
62}
63
64impl<T: CubeType> Sequence<T> {
65 pub fn new() -> Self {
67 Self { values: Vec::new() }
68 }
69
70 pub fn push(&mut self, value: T) {
72 self.values.push(value);
73 }
74
75 #[allow(clippy::len_without_is_empty)]
77 pub fn len(&self) -> usize {
78 self.values.len()
79 }
80
81 #[allow(clippy::should_implement_trait)]
83 pub fn index(&self, index: usize) -> &T {
84 self.values.get(index).unwrap()
85 }
86
87 #[allow(clippy::should_implement_trait)]
89 pub fn index_mut(&mut self, index: usize) -> &mut T {
90 self.values.get_mut(index).unwrap()
91 }
92
93 pub fn __expand_new(_scope: &Scope) -> SequenceExpand<T> {
95 SequenceExpand { values: Vec::new() }
96 }
97
98 #[allow(clippy::should_implement_trait)]
100 pub fn insert(&mut self, index: usize, value: T) {
101 *self.index_mut(index) = value;
102 }
103
104 pub fn __expand_push(scope: &Scope, expand: &mut SequenceExpand<T>, value: T::ExpandType) {
106 expand.__expand_push_method(scope, value)
107 }
108
109 pub fn __expand_index<'a>(
111 scope: &Scope,
112 expand: &'a SequenceExpand<T>,
113 index: NativeExpand<usize>,
114 ) -> &'a T::ExpandType {
115 expand.__expand_index_method(scope, index)
116 }
117
118 pub fn __expand_index_mut<'a>(
120 scope: &Scope,
121 expand: &'a mut SequenceExpand<T>,
122 index: NativeExpand<usize>,
123 ) -> &'a mut T::ExpandType {
124 expand.__expand_index_mut_method(scope, index)
125 }
126}
127
128impl<T: CubeType> AsRefExpand for SequenceExpand<T> {
129 fn __expand_ref_method(&self, _: &Scope) -> &Self {
130 self
131 }
132}
133impl<T: CubeType> AsMutExpand for SequenceExpand<T> {
134 fn __expand_ref_mut_method(&mut self, _: &Scope) -> &mut Self {
135 self
136 }
137}
138
139impl<T: CubeType> Index<usize> for Sequence<T> {
140 type Output = T;
141
142 fn index(&self, index: usize) -> &Self::Output {
143 self.values.index(index)
144 }
145}
146
147impl<T: CubeType> IndexMut<usize> for Sequence<T> {
148 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
149 self.values.index_mut(index)
150 }
151}
152
153impl<T: CubeType> Deref for Sequence<T> {
154 type Target = [T];
155
156 fn deref(&self) -> &Self::Target {
157 &self.values
158 }
159}
160
161impl<T: CubeType> IndexExpand<NativeExpand<usize>> for SequenceExpand<T> {
162 type Output = T::ExpandType;
163
164 fn __expand_index_method(&self, scope: &Scope, index: NativeExpand<usize>) -> &Self::Output {
165 self.__expand_index_method(scope, index)
166 }
167}
168
169impl<T: CubeType> IndexMutExpand<NativeExpand<usize>> for SequenceExpand<T> {
170 fn __expand_index_mut_method(
171 &mut self,
172 scope: &Scope,
173 index: NativeExpand<usize>,
174 ) -> &mut T::ExpandType {
175 self.__expand_index_mut_method(scope, index)
176 }
177}
178
179#[derive(Debug)]
181pub struct SequenceExpand<T: CubeType> {
182 pub(super) values: Vec<T::ExpandType>,
185}
186
187impl<T: CubeType> Iterable for SequenceExpand<T> {
188 type Item = T::ExpandType;
189
190 fn expand(self, scope: &Scope, func: &mut dyn FnMut(&Scope, <T as CubeType>::ExpandType)) {
191 self.expand_unroll(scope, func);
192 }
193
194 fn expand_unroll(
195 self,
196 scope: &Scope,
197 func: &mut dyn FnMut(&Scope, <T as CubeType>::ExpandType),
198 ) {
199 let body = scope.unrolled_loop_child();
200 for elem in self {
201 scope.update_flags_before_unrolled_iteration(&body);
202 func(&body, elem);
203 }
204 scope.finalize_unrolled_loop(&body);
205 }
206
207 fn const_len(&self) -> Option<usize> {
208 Some(self.values.len())
209 }
210}
211
212impl<T: CubeType> IntoMut for SequenceExpand<T> {
213 fn into_mut(self, scope: &Scope) -> Self {
214 Self {
215 values: self
216 .values
217 .into_iter()
218 .map(|v| IntoMut::into_mut(v, scope))
219 .collect(),
220 }
221 }
222}
223impl<T: CubeType> CubeDebug for SequenceExpand<T> {}
224
225impl<T: CubeType<ExpandType: Clone>> Clone for SequenceExpand<T> {
226 fn clone(&self) -> Self {
227 Self {
228 values: self.values.clone(),
229 }
230 }
231}
232impl<T: CubeType> ExpandTypeClone for SequenceExpand<T> {
233 fn clone_unchecked(&self) -> Self {
234 Self {
235 values: self.values.iter().map(|it| it.clone_unchecked()).collect(),
236 }
237 }
238}
239
240impl<T: CubeType> IntoIterator for Sequence<T> {
241 type Item = T;
242
243 type IntoIter = <Vec<T> as IntoIterator>::IntoIter;
244
245 fn into_iter(self) -> Self::IntoIter {
246 self.values.into_iter()
247 }
248}
249
250impl<T: CubeType> IntoIterator for SequenceExpand<T> {
251 type Item = T::ExpandType;
252
253 type IntoIter = <Vec<T::ExpandType> as IntoIterator>::IntoIter;
254
255 fn into_iter(self) -> Self::IntoIter {
256 self.values.into_iter()
257 }
258}
259
260impl<T: CubeType<ExpandType: Clone>> SequenceExpand<T> {
261 pub fn iter_cloned(&self) -> impl Iterator<Item = T::ExpandType> {
263 self.values.clone().into_iter()
264 }
265}
266
267impl<T: CubeType> CubeType for Sequence<T> {
268 type ExpandType = SequenceExpand<T>;
269}
270
271impl<T: CubeType> SequenceExpand<T> {
272 #[allow(clippy::len_without_is_empty)]
273 pub fn len(&self) -> usize {
274 self.values.len()
275 }
276 pub fn __expand_push_method(&mut self, _scope: &Scope, value: T::ExpandType) {
278 self.values.push(value);
279 }
280
281 pub fn __expand_insert_method(&mut self, _scope: &Scope, index: usize, value: T::ExpandType) {
283 if self.values.len() == index {
284 self.values.push(value);
285 } else {
286 self.values[index] = value;
287 }
288 }
289
290 pub fn __expand_index_method(
292 &self,
293 _scope: &Scope,
294 index: NativeExpand<usize>,
295 ) -> &T::ExpandType {
296 let index = index.constant().expect("Index must be constant").as_usize();
297 &self.values[index]
298 }
299
300 pub fn __expand_index_mut_method(
302 &mut self,
303 _scope: &Scope,
304 index: NativeExpand<usize>,
305 ) -> &mut T::ExpandType {
306 let index = index.constant().expect("Index must be constant").as_usize();
307 &mut self.values[index]
308 }
309
310 pub fn __expand_len_method(&self, _scope: &Scope) -> usize {
311 self.values.len()
312 }
313
314 pub fn __expand_reverse_method(&mut self, _scope: &Scope) {
315 self.values.reverse();
316 }
317
318 pub fn __expand_reversed_method(&self, _scope: &Scope) -> Self
319 where
320 T::ExpandType: Clone,
321 {
322 Self {
323 values: self.values.iter().cloned().rev().collect(),
324 }
325 }
326
327 pub fn __expand_clone_method(&self, _scope: &Scope) -> Self
328 where
329 T::ExpandType: Clone,
330 {
331 self.clone()
332 }
333}
334
335#[macro_export]
336macro_rules! seq {
337 ($($value: expr),*) => {
338 $crate::seq![$($value,)*]
339 };
340 ($($value: expr,)*) => {{
341 let mut seq = Sequence::new();
342 $(seq.push($value);)*
343 seq
344 }}
345}
346
347#[macro_export]
348macro_rules! __expand_seq {
349 ($scope: expr, $($value: expr),*) => {
350 $crate::__expand_seq![$scope, $($value,)*]
351 };
352 ($scope: expr, $($value: expr,)*) => {{
353 let mut seq = Sequence::__expand_new($scope);
354 $(seq.__expand_push_method($scope, $value.into());)*
355 seq
356 }}
357}