cubecl_core/frontend/container/sequence/
base.rs1use serde::{Deserialize, Serialize};
2
3use crate::frontend::{
4 branch::Iterable, indexation::Index, CubeContext, CubeType, ExpandElementTyped, Init,
5 IntoRuntime,
6};
7use crate::prelude::ExpandElement;
8use std::{cell::RefCell, rc::Rc};
9
10#[derive(Debug, Clone, Hash, PartialEq, Eq, Serialize, Deserialize)]
18pub struct Sequence<T: CubeType> {
19 values: Vec<T>,
20}
21
22impl<T: CubeType> Default for Sequence<T> {
23 fn default() -> Self {
24 Self::new()
25 }
26}
27
28impl<T: CubeType> Init for Sequence<T> {
29 fn init(self, _context: &mut CubeContext) -> Self {
30 self
31 }
32}
33
34impl<T: CubeType> Sequence<T> {
35 pub fn new() -> Self {
37 Self { values: Vec::new() }
38 }
39
40 pub fn push(&mut self, value: T) {
42 self.values.push(value);
43 }
44
45 #[allow(clippy::len_without_is_empty)]
47 pub fn len(&self) -> u32 {
48 self.values.len() as u32
49 }
50
51 #[allow(unused_variables, clippy::should_implement_trait)]
53 pub fn index<I: Index>(&self, index: I) -> &T {
54 let index: ExpandElementTyped<u32> = ExpandElement::Plain(index.value()).into();
55 let index = index
56 .constant()
57 .expect("Only constant are supported")
58 .as_usize();
59
60 self.values.get(index).unwrap()
61 }
62
63 #[allow(unused_variables, clippy::should_implement_trait)]
65 pub fn index_mut<I: Index>(&mut self, index: I) -> &mut T {
66 let index: ExpandElementTyped<u32> = ExpandElement::Plain(index.value()).into();
67 let index = index
68 .constant()
69 .expect("Only constant are supported")
70 .as_usize();
71
72 self.values.get_mut(index).unwrap()
73 }
74
75 pub fn __expand_new(_context: &mut CubeContext) -> SequenceExpand<T> {
77 SequenceExpand {
78 values: Rc::new(RefCell::new(Vec::new())),
79 }
80 }
81
82 #[allow(unused_variables, clippy::should_implement_trait)]
84 pub fn insert<I: Index>(&mut self, index: I, value: T) {
85 *self.index_mut(index) = value;
86 }
87
88 pub fn __expand_push(
90 context: &mut CubeContext,
91 expand: &mut SequenceExpand<T>,
92 value: T::ExpandType,
93 ) {
94 expand.__expand_push_method(context, value)
95 }
96
97 pub fn __expand_index(
99 context: &mut CubeContext,
100 expand: SequenceExpand<T>,
101 index: ExpandElementTyped<u32>,
102 ) -> T::ExpandType {
103 expand.__expand_index_method(context, index)
104 }
105
106 pub fn __expand_index_mut(
108 context: &mut CubeContext,
109 expand: SequenceExpand<T>,
110 index: ExpandElementTyped<u32>,
111 ) -> T::ExpandType {
112 expand.__expand_index_mut_method(context, index)
113 }
114}
115
116pub struct SequenceExpand<T: CubeType> {
118 pub(super) values: Rc<RefCell<Vec<T::ExpandType>>>,
121}
122
123impl<T: CubeType> Iterable<T> for SequenceExpand<T> {
124 fn expand(
125 self,
126 context: &mut CubeContext,
127 func: impl FnMut(&mut CubeContext, <T as CubeType>::ExpandType),
128 ) {
129 self.expand_unroll(context, func);
130 }
131
132 fn expand_unroll(
133 self,
134 context: &mut CubeContext,
135 mut func: impl FnMut(&mut CubeContext, <T as CubeType>::ExpandType),
136 ) {
137 for elem in self {
138 func(context, elem);
139 }
140 }
141}
142
143impl<T: CubeType> Init for SequenceExpand<T> {
144 fn init(self, _context: &mut crate::prelude::CubeContext) -> Self {
145 self
146 }
147}
148
149impl<T: CubeType> Clone for SequenceExpand<T> {
150 fn clone(&self) -> Self {
151 Self {
152 values: self.values.clone(),
153 }
154 }
155}
156
157impl<T: CubeType> IntoIterator for Sequence<T> {
158 type Item = T;
159
160 type IntoIter = <Vec<T> as IntoIterator>::IntoIter;
161
162 fn into_iter(self) -> Self::IntoIter {
163 self.values.into_iter()
164 }
165}
166
167impl<T: CubeType> IntoIterator for SequenceExpand<T> {
168 type Item = T::ExpandType;
169
170 type IntoIter = <Vec<T::ExpandType> as IntoIterator>::IntoIter;
171
172 fn into_iter(self) -> Self::IntoIter {
173 self.values.take().into_iter()
174 }
175}
176
177impl<T: CubeType> CubeType for Sequence<T> {
178 type ExpandType = SequenceExpand<T>;
179}
180
181impl<T: CubeType> SequenceExpand<T> {
182 pub fn __expand_push_method(&mut self, _context: &mut CubeContext, value: T::ExpandType) {
184 self.values.borrow_mut().push(value);
185 }
186
187 pub fn __expand_insert_method(
189 &self,
190 _context: &mut CubeContext,
191 index: ExpandElementTyped<u32>,
192 value: T::ExpandType,
193 ) {
194 let index = index
195 .constant()
196 .expect("Only constant are supported")
197 .as_usize();
198
199 let mut values = self.values.borrow_mut();
200
201 if values.len() == index {
202 values.push(value);
203 } else {
204 values[index] = value;
205 }
206 }
207
208 pub fn __expand_index_method(
210 &self,
211 _context: &mut CubeContext,
212 index: ExpandElementTyped<u32>,
213 ) -> T::ExpandType {
214 let index = index
215 .constant()
216 .expect("Only constant are supported")
217 .as_usize();
218
219 self.values.borrow()[index].clone()
220 }
221
222 pub fn __expand_index_mut_method(
224 &self,
225 _context: &mut CubeContext,
226 index: ExpandElementTyped<u32>,
227 ) -> T::ExpandType {
228 let index = index
229 .constant()
230 .expect("Only constant are supported")
231 .as_usize();
232
233 self.values.borrow()[index].clone()
234 }
235
236 pub fn __expand_len_method(&self, _context: &mut CubeContext) -> u32 {
237 let values = self.values.borrow();
238 values.len() as u32
239 }
240}
241
242impl<T: CubeType> IntoRuntime for Sequence<T> {
243 fn __expand_runtime_method(self, _context: &mut CubeContext) -> SequenceExpand<T> {
244 unimplemented!("Sequence doesn't exist at compile time");
245 }
246}