cubecl_core/frontend/container/
shared_memory.rs1use core::ops::{Deref, DerefMut};
2
3use crate::{
4 self as cubecl,
5 frontend::container::slice,
6 prelude::{Vectorized, VectorizedExpand},
7 unexpanded,
8};
9use cubecl_ir::{VectorSize, dialect::general::FreeOp, interfaces::TypedExt, types::ArrayType};
10use cubecl_macros::{cube, intrinsic};
11
12use crate::{
13 frontend::{CubePrimitive, CubeType, IntoMut, NativeExpand},
14 ir::Scope,
15 prelude::*,
16};
17
18pub type SharedExpand<T> = NativeExpand<Shared<T>>;
19
20pub struct Shared<E: NativeCubeType + ?Sized> {
21 _val: *mut E,
22}
23
24impl<E: NativeCubeType + ?Sized> Clone for Shared<E> {
26 fn clone(&self) -> Self {
27 Self { _val: self._val }
28 }
29}
30
31impl<T: NativeCubeType + ?Sized> IntoMut for NativeExpand<Shared<T>> {
32 fn into_mut(self, _scope: &Scope) -> Self {
33 self
34 }
35}
36
37impl<T: NativeCubeType + ?Sized> CubeType for Shared<T> {
38 type ExpandType = NativeExpand<Shared<T>>;
39}
40
41impl<T: NativeCubeType + ?Sized> AsMutExpand for SharedExpand<T> {
42 fn __expand_ref_mut_method(&mut self, _: &Scope) -> &mut Self {
43 self
44 }
45}
46
47#[cube]
48impl<T: CubePrimitive> Shared<[T]> {
49 pub fn new_slice(#[comptime] len: usize) -> Self {
55 intrinsic!(|scope| {
56 let inner = T::__expand_as_type(scope);
57 let ty = ArrayType::get(scope.ctx(), inner, len);
58 let buffer = scope.create_shared(ty, None);
59 let slice = slice::from_raw_parts::<T>(
60 scope,
61 buffer,
62 0usize.into_expand(scope),
63 len.into_expand(scope),
64 );
65 slice.expand.into()
66 })
67 }
68
69 #[allow(unused_variables)]
75 pub fn new_aligned_slice(#[comptime] len: usize, #[comptime] alignment: usize) -> Self {
76 intrinsic!(|scope| {
77 let inner = T::__expand_as_type(scope);
78 let ty = ArrayType::get(scope.ctx(), inner, len);
79 let buffer = scope.create_shared(ty, Some(alignment));
80 let slice = slice::from_raw_parts::<T>(
81 scope,
82 buffer,
83 0usize.into_expand(scope),
84 len.into_expand(scope),
85 );
86 slice.expand.into()
87 })
88 }
89
90 #[allow(clippy::len_without_is_empty)]
91 pub fn len(&self) -> usize {
92 intrinsic!(|scope| len_static(scope, &self))
93 }
94}
95
96impl<T: NativeCubeType + ?Sized> Shared<T> {
97 pub fn map<U: NativeCubeType + ?Sized>(self, _map: impl FnOnce(&T) -> &U) -> Shared<U> {
98 unexpanded!()
99 }
100}
101
102impl<T: NativeCubeType + ?Sized> SharedExpand<T> {
103 pub fn __expand_map_method<U: NativeCubeType + ?Sized>(
104 self,
105 scope: &Scope,
106 map: impl for<'a> FnOnce(&Scope, &'a NativeExpand<T>) -> &'a NativeExpand<U>,
107 ) -> SharedExpand<U> {
108 let out = map(scope, self.__expand_ref_method(scope));
109 out.expand.into()
110 }
111}
112
113#[cube]
114impl<T: CubePrimitive> Shared<T> {
115 pub fn new() -> Self {
121 intrinsic!(|scope| {
122 let val = scope.create_shared(T::__expand_as_type(scope), None);
123 NativeExpand::new(val.into())
124 })
125 }
126}
127
128#[cube]
129impl<T: NativeCubeType + ?Sized> Shared<T> {
130 pub fn inner_ref(&self) -> &T {
131 intrinsic!(|scope| { unsafe { self.as_type_ref_unchecked() } })
132 }
133
134 pub fn inner_mut(&mut self) -> &mut T {
135 intrinsic!(|scope| { unsafe { self.as_type_mut_unchecked() } })
136 }
137}
138
139impl<T: CubePrimitive> Default for Shared<T> {
140 fn default() -> Self {
141 Self::new()
142 }
143}
144impl<T: CubePrimitive> Shared<T> {
145 pub fn __expand_default(scope: &Scope) -> <Self as CubeType>::ExpandType {
146 Self::__expand_new(scope)
147 }
148}
149
150#[cube]
151impl<T: NativeCubeType + ?Sized> Shared<T> {
152 pub unsafe fn free(&self) {
158 intrinsic!(|scope| {
159 let val = scope.extract_field(self.value(scope), 0);
160 scope.register(&FreeOp::new(scope.ctx_mut(), val))
161 })
162 }
163}
164
165fn len_static<T: CubePrimitive>(
166 scope: &Scope,
167 shared: &NativeExpand<Shared<[T]>>,
168) -> NativeExpand<usize> {
169 let array_ty = inner_array_ty(scope, shared.value(scope));
170 array_ty.deref(scope.ctx()).length.into()
171}
172
173impl<T: CubePrimitive> List<T> for Shared<[T]> {}
174impl<T: CubePrimitive> ListExpand<T> for NativeExpand<Shared<[T]>> {
175 fn __expand_len_method(&self, scope: &Scope) -> NativeExpand<usize> {
176 Self::__expand_len_method(self, scope)
177 }
178}
179
180impl<T: CubePrimitive> Vectorized for Shared<[T]> {}
181impl<T: CubePrimitive> VectorizedExpand for NativeExpand<Shared<[T]>> {
182 fn __expand_vector_size_method(&self, scope: &Scope) -> VectorSize {
183 self.__extract_list(scope).vector_size(scope.ctx())
184 }
185}
186
187impl<T: NativeCubeType + ?Sized> Deref for Shared<T> {
188 type Target = T;
189
190 fn deref(&self) -> &Self::Target {
191 unexpanded!()
192 }
193}
194impl<T: NativeCubeType + ?Sized> DerefMut for Shared<T> {
195 fn deref_mut(&mut self) -> &mut Self::Target {
196 unexpanded!()
197 }
198}
199
200impl<T: NativeCubeType + ?Sized> Deref for SharedExpand<T> {
201 type Target = NativeExpand<T>;
202
203 fn deref(&self) -> &Self::Target {
204 unsafe { self.as_type_ref_unchecked() }
205 }
206}
207impl<T: NativeCubeType + ?Sized> DerefMut for SharedExpand<T> {
208 fn deref_mut(&mut self) -> &mut Self::Target {
209 unsafe { self.as_type_mut_unchecked() }
210 }
211}
212
213impl<'a, T: NativeCubeType + ?Sized> From<&'a SharedExpand<T>> for &'a NativeExpand<T> {
214 fn from(value: &'a SharedExpand<T>) -> Self {
215 value
216 }
217}
218
219impl<'a, T: NativeCubeType + ?Sized> From<&'a mut SharedExpand<T>> for &'a mut NativeExpand<T> {
220 fn from(value: &'a mut SharedExpand<T>) -> Self {
221 value
222 }
223}
224
225impl<T: NativeCubeType + ?Sized> AsDerefExpand for SharedExpand<T> {
226 type Target = NativeExpand<T>;
227
228 fn __expand_as_deref_method(&self, _: &Scope) -> &Self::Target {
229 unsafe { self.as_type_ref_unchecked::<T>() }
230 }
231}
232impl<T: NativeCubeType + ?Sized> AsDerefMutExpand for SharedExpand<T> {
233 fn __expand_as_deref_mut_method(&mut self, _: &Scope) -> &mut Self::Target {
234 unsafe { self.as_type_mut_unchecked::<T>() }
235 }
236}
237
238impl<T: CubePrimitive> Assign<NativeExpand<T>> for SharedExpand<T> {
239 fn __expand_assign_method(&mut self, scope: &Scope, value: NativeExpand<T>) {
240 let value = value.read_value(scope);
241 assign::expand_element(scope, value.into(), self.expand);
242 }
243}
244
245impl<T: CubePrimitive> RuntimeAssign<NativeExpand<T>> for SharedExpand<T> {
246 fn init_mut(&self, scope: &Scope) -> Self::Expand {
247 Shared::<T>::__expand_new(scope)
248 }
249}