ruda_kernel/dsl/frontend/container/array/
base.rs1use alloc::vec::Vec;
2use core::{
3 marker::PhantomData,
4 ops::{Deref, DerefMut},
5};
6
7use ruda_core::ir::{ManagedVariable, Scope, VectorSize};
8
9use crate::dsl::frontend::{RudaPrimitive, NativeExpand};
10use crate::dsl::prelude::*;
11use crate::dsl::{
12 frontend::RudaType,
13 ir::{Metadata, Type},
14 unexpanded,
15};
16use ruda_kernel_macros::{ruda, intrinsic};
17
18pub struct Array<E> {
20 _val: PhantomData<E>,
21}
22
23type ArrayExpand<E> = NativeExpand<Array<E>>;
24
25mod new {
27
28 use ruda_kernel_macros::intrinsic;
29
30 use super::*;
31 use crate::dsl::ir::Variable;
32
33 #[ruda]
34 impl<T: RudaPrimitive + Clone> Array<T> {
35 #[allow(unused_variables)]
37 pub fn new(#[comptime] length: usize) -> Self {
38 intrinsic!(|scope| {
39 let elem = T::as_type(scope);
40 scope.create_local_array(elem, length).into()
41 })
42 }
43 }
44
45 impl<T: RudaPrimitive + Clone> Array<T> {
46 #[allow(unused_variables)]
48 pub fn from_data<C: RudaPrimitive>(data: impl IntoIterator<Item = C>) -> Self {
49 intrinsic!(|scope| {
50 scope
51 .create_const_array(Type::new(T::as_type(scope)), data.values)
52 .into()
53 })
54 }
55
56 pub fn __expand_from_data<C: RudaPrimitive>(
58 scope: &mut Scope,
59 data: ArrayData<C>,
60 ) -> <Self as RudaType>::ExpandType {
61 let var = scope.create_const_array(T::as_type(scope), data.values);
62 NativeExpand::new(var)
63 }
64 }
65
66 pub struct ArrayData<C> {
68 values: Vec<Variable>,
69 _ty: PhantomData<C>,
70 }
71
72 impl<C: RudaPrimitive + Into<NativeExpand<C>>, T: IntoIterator<Item = C>> From<T> for ArrayData<C> {
73 fn from(value: T) -> Self {
74 let values: Vec<Variable> = value
75 .into_iter()
76 .map(|value| {
77 let value: NativeExpand<C> = value.into();
78 *value.expand
79 })
80 .collect();
81 ArrayData {
82 values,
83 _ty: PhantomData,
84 }
85 }
86 }
87}
88
89mod vector {
91 use super::*;
92
93 impl<P: RudaPrimitive> Array<P> {
94 pub fn vector_size(&self) -> VectorSize {
102 P::vector_size()
103 }
104
105 pub fn __expand_vector_size(
107 expand: <Self as RudaType>::ExpandType,
108 scope: &mut Scope,
109 ) -> VectorSize {
110 expand.__expand_vector_size_method(scope)
111 }
112 }
113}
114
115mod vectorization {
117 use super::*;
118
119 #[ruda]
120 impl<T: RudaPrimitive + Clone> Array<T> {
121 #[allow(unused_variables)]
122 pub fn to_vectorized<N: Size>(self) -> T {
123 let factor = N::value();
124 intrinsic!(|scope| {
125 let var = self.expand.clone();
126 let item = Type::new(var.storage_type()).with_vector_size(factor);
127
128 let new_var = if factor == 1 {
129 let new_var = scope.create_local(item);
130 let element =
131 index::expand(scope, self.clone(), NativeExpand::from_lit(scope, 0));
132 assign::expand_no_check::<T>(scope, element, new_var.clone().into());
133 new_var
134 } else {
135 let new_var = scope.create_local_mut(item);
136 for i in 0..factor {
137 let expand: Self = self.expand.clone().into();
138 let element =
139 index::expand(scope, expand, NativeExpand::from_lit(scope, i));
140 index_assign::expand::<NativeExpand<Array<T>>, T>(
141 scope,
142 new_var.clone().into(),
143 NativeExpand::from_lit(scope, i),
144 element,
145 );
146 }
147 new_var
148 };
149 new_var.into()
150 })
151 }
152 }
153}
154
155mod metadata {
157 use crate::dsl::{ir::Instruction, prelude::expand_length_native};
158
159 use super::*;
160
161 #[ruda]
162 impl<E: RudaType> Array<E> {
163 #[allow(clippy::len_without_is_empty)]
165 pub fn len(&self) -> usize {
166 intrinsic!(|scope| {
167 ManagedVariable::Plain(expand_length_native(scope, *self.expand)).into()
168 })
169 }
170
171 pub fn buffer_len(&self) -> usize {
173 intrinsic!(|scope| {
174 let out = scope.create_local(usize::as_type(scope));
175 scope.register(Instruction::new(
176 Metadata::BufferLength {
177 var: self.expand.into(),
178 },
179 out.clone().into(),
180 ));
181 out.into()
182 })
183 }
184 }
185}
186
187mod indexation {
189 use ruda_core::ir::{IndexAssignOperator, IndexOperator, Operator};
190
191 use crate::dsl::ir::Instruction;
192
193 use super::*;
194
195 #[ruda]
196 impl<E: RudaPrimitive> Array<E> {
197 #[allow(unused_variables)]
203 pub unsafe fn index_unchecked(&self, i: usize) -> &E {
204 intrinsic!(|scope| {
205 let out = scope.create_local(self.expand.ty);
206 scope.register(Instruction::new(
207 Operator::UncheckedIndex(IndexOperator {
208 list: *self.expand,
209 index: i.expand.consume(),
210 vector_size: 0,
211 unroll_factor: 1,
212 }),
213 *out,
214 ));
215 out.into()
216 })
217 }
218
219 #[allow(unused_variables)]
225 pub unsafe fn index_assign_unchecked(&mut self, i: usize, value: E) {
226 intrinsic!(|scope| {
227 scope.register(Instruction::new(
228 Operator::UncheckedIndexAssign(IndexAssignOperator {
229 index: i.expand.consume(),
230 value: value.expand.consume(),
231 vector_size: 0,
232 unroll_factor: 1,
233 }),
234 *self.expand,
235 ));
236 })
237 }
238 }
239}
240
241impl<C: RudaType> RudaType for Array<C> {
242 type ExpandType = NativeExpand<Array<C>>;
243}
244
245impl<C: RudaType> RudaType for &Array<C> {
246 type ExpandType = NativeExpand<Array<C>>;
247}
248
249impl<C: RudaType> IntoMut for NativeExpand<Array<C>> {
250 fn into_mut(self, _scope: &mut crate::dsl::ir::Scope) -> Self {
251 self
253 }
254}
255
256impl<T: RudaPrimitive> SizedContainer for Array<T> {
257 type Item = T;
258}
259
260impl<T: RudaType> Iterator for &Array<T> {
261 type Item = T;
262
263 fn next(&mut self) -> Option<Self::Item> {
264 unexpanded!()
265 }
266}
267
268impl<T: RudaPrimitive> List<T> for Array<T> {
269 fn __expand_read(
270 scope: &mut Scope,
271 this: NativeExpand<Array<T>>,
272 idx: NativeExpand<usize>,
273 ) -> NativeExpand<T> {
274 index::expand(scope, this, idx)
275 }
276}
277
278impl<T: RudaPrimitive> Deref for Array<T> {
279 type Target = [T];
280
281 fn deref(&self) -> &Self::Target {
282 unexpanded!()
283 }
284}
285
286impl<T: RudaPrimitive> DerefMut for Array<T> {
287 fn deref_mut(&mut self) -> &mut Self::Target {
288 unexpanded!()
289 }
290}
291
292impl<T: RudaPrimitive> ListExpand<T> for NativeExpand<Array<T>> {
293 fn __expand_read_method(&self, scope: &mut Scope, idx: NativeExpand<usize>) -> NativeExpand<T> {
294 index::expand(scope, self.clone(), idx)
295 }
296 fn __expand_read_unchecked_method(
297 &self,
298 scope: &mut Scope,
299 idx: NativeExpand<usize>,
300 ) -> NativeExpand<T> {
301 index_unchecked::expand(scope, self.clone(), idx)
302 }
303
304 fn __expand_len_method(&self, scope: &mut Scope) -> NativeExpand<usize> {
305 Self::__expand_len(scope, self.clone())
306 }
307}
308
309impl<T: RudaPrimitive> Vectorized for Array<T> {}
310impl<T: RudaPrimitive> VectorizedExpand for NativeExpand<Array<T>> {
311 fn vector_size(&self) -> VectorSize {
312 self.expand.ty.vector_size()
313 }
314}
315
316impl<T: RudaPrimitive> ListMut<T> for Array<T> {
317 fn __expand_write(
318 scope: &mut Scope,
319 this: NativeExpand<Array<T>>,
320 idx: NativeExpand<usize>,
321 value: NativeExpand<T>,
322 ) {
323 index_assign::expand(scope, this, idx, value);
324 }
325}
326
327impl<T: RudaPrimitive> ListMutExpand<T> for NativeExpand<Array<T>> {
328 fn __expand_write_method(
329 &self,
330 scope: &mut Scope,
331 idx: NativeExpand<usize>,
332 value: NativeExpand<T>,
333 ) {
334 index_assign::expand(scope, self.clone(), idx, value);
335 }
336}