cubecl_core/frontend/container/tensor/
base.rs1use crate::{
2 frontend::container::iter::{SizedContainer, SizedContainerExpand},
3 ir::Scope,
4 prelude::*,
5 unexpanded,
6};
7use alloc::boxed::Box;
8use core::ops::{Deref, DerefMut};
9use cubecl_ir::VectorSize;
10
11use crate as cubecl;
12
13#[derive(CubeType)]
16pub struct Tensor<T: CubePrimitive> {
17 pub(super) meta: TensorMeta,
18 pub(super) buffer: [T],
19}
20
21#[derive(CubeType, Clone)]
22#[expand(derive(Clone))]
23pub struct OwnedTensor<T: CubePrimitive> {
24 #[allow(unused)]
25 pub(super) meta: TensorMeta,
26 pub(super) buffer: Box<[T]>,
27}
28
29impl<T: CubePrimitive> TensorExpand<T> {
30 pub fn __expand_from_parts(meta: TensorMetaExpand, buffer: NativeExpand<[T]>) -> Self {
32 Self { meta, buffer }
33 }
34}
35
36#[cube]
37impl<T: CubePrimitive> OwnedTensor<T> {
38 pub fn from_parts(meta: TensorMeta, buffer: Box<[T]>) -> Self {
39 OwnedTensor::<T> { meta, buffer }
40 }
41}
42
43#[cube]
44impl<T: CubePrimitive> OwnedTensor<T> {
45 pub fn as_slice(&self) -> &[T] {
46 &self.buffer
47 }
48
49 pub fn as_mut_slice(&mut self) -> &mut [T] {
50 &mut self.buffer
51 }
52}
53
54#[cube]
55impl<T: CubePrimitive> Tensor<T> {
56 pub fn as_slice(&self) -> &[T] {
57 &self.buffer
58 }
59
60 pub fn as_mut_slice(&mut self) -> &mut [T] {
61 &mut self.buffer
62 }
63}
64
65mod metadata {
67 use cubecl_ir::dialect::general::{ShapeOp, StrideOp};
68
69 use super::*;
70
71 #[cube]
72 impl<T: CubePrimitive> Tensor<T> {
73 pub fn stride(&self, dim: usize) -> usize {
75 intrinsic!(|scope| {
76 let dim = dim.read_value(scope);
77 let buffer_idx = ext_meta_idx(scope, self.__extract_list(scope));
78 let op = StrideOp::new(scope.ctx_mut(), dim, buffer_idx);
79 scope.register_with_result(&op).into()
80 })
81 }
82
83 pub fn shape(&self, dim: usize) -> usize {
85 intrinsic!(|scope| {
86 let dim = dim.read_value(scope);
87 let buffer_idx = ext_meta_idx(scope, self.__extract_list(scope));
88 let op = ShapeOp::new(scope.ctx_mut(), dim, buffer_idx);
89 scope.register_with_result(&op).into()
90 })
91 }
92
93 pub fn coordinate(&self, index: usize, dim: usize) -> usize {
98 let stride = self.stride(dim);
99 let shape = self.shape(dim);
100 (index / stride) % shape
101 }
102
103 #[allow(clippy::len_without_is_empty)]
110 pub fn len(&self) -> usize {
111 self.meta.len
112 }
113
114 #[allow(clippy::len_without_is_empty)]
121 pub fn buffer_len(&self) -> usize {
122 intrinsic!(|scope| { self.__extract_length(scope) })
123 }
124
125 pub fn rank(&self) -> usize {
127 self.meta.rank
128 }
129 }
130}
131
132mod vector {
134 use super::*;
135
136 impl<P: Scalar, N: Size> Tensor<Vector<P, N>> {
137 pub fn vector_size(&self) -> VectorSize {
145 N::value()
146 }
147
148 pub fn __expand_vector_size(
150 expand: <Self as CubeType>::ExpandType,
151 scope: &Scope,
152 ) -> VectorSize {
153 expand.__expand_vector_size_method(scope)
154 }
155 }
156}
157
158impl<'a, E: CubePrimitive> From<&'a OwnedTensorExpand<E>> for &'a TensorExpand<E> {
159 fn from(value: &'a OwnedTensorExpand<E>) -> Self {
160 value.deref()
161 }
162}
163
164impl<'a, E: CubePrimitive> From<&'a mut OwnedTensorExpand<E>> for &'a mut TensorExpand<E> {
165 fn from(value: &'a mut OwnedTensorExpand<E>) -> Self {
166 value.deref_mut()
167 }
168}
169
170impl<'a, E: CubePrimitive> From<&'a TensorExpand<E>> for &'a SliceExpand<E> {
171 fn from(value: &'a TensorExpand<E>) -> Self {
172 value.deref()
173 }
174}
175
176impl<'a, E: CubePrimitive> From<&'a mut TensorExpand<E>> for &'a mut SliceExpand<E> {
177 fn from(value: &'a mut TensorExpand<E>) -> Self {
178 value.deref_mut()
179 }
180}
181
182impl<T: CubePrimitive> SizedContainer<usize> for Tensor<T> {
183 fn len(&self) -> usize {
184 unexpanded!()
185 }
186}
187
188impl<T: CubePrimitive> SizedContainerExpand<usize> for TensorExpand<T> {
189 fn __expand_len_method(&self, scope: &Scope) -> NativeExpand<usize> {
190 self.__expand_len_method(scope)
191 }
192}
193
194impl<T: CubePrimitive> Iterator for &Tensor<T> {
195 type Item = T;
196
197 fn next(&mut self) -> Option<Self::Item> {
198 unexpanded!()
199 }
200}
201
202impl<T: CubePrimitive> List<T> for Tensor<T> {}
203
204impl<T: CubePrimitive> Deref for Tensor<T> {
205 type Target = [T];
206
207 fn deref(&self) -> &Self::Target {
208 unexpanded!()
209 }
210}
211
212impl<T: CubePrimitive> DerefMut for Tensor<T> {
213 fn deref_mut(&mut self) -> &mut Self::Target {
214 unexpanded!()
215 }
216}
217
218impl<T: CubePrimitive> Deref for TensorExpand<T> {
219 type Target = SliceExpand<T>;
220
221 fn deref(&self) -> &Self::Target {
222 &self.buffer
223 }
224}
225
226impl<T: CubePrimitive> DerefMut for TensorExpand<T> {
227 fn deref_mut(&mut self) -> &mut Self::Target {
228 &mut self.buffer
229 }
230}
231
232impl<T: CubePrimitive> Deref for OwnedTensor<T> {
233 type Target = Tensor<T>;
234
235 fn deref(&self) -> &Self::Target {
236 unexpanded!()
237 }
238}
239
240impl<T: CubePrimitive> DerefMut for OwnedTensor<T> {
241 fn deref_mut(&mut self) -> &mut Self::Target {
242 unexpanded!()
243 }
244}
245
246impl<T: CubePrimitive> Deref for OwnedTensorExpand<T> {
247 type Target = TensorExpand<T>;
248
249 fn deref(&self) -> &Self::Target {
250 unsafe { core::mem::transmute(self) }
252 }
253}
254
255impl<T: CubePrimitive> DerefMut for OwnedTensorExpand<T> {
256 fn deref_mut(&mut self) -> &mut Self::Target {
257 unsafe { core::mem::transmute(self) }
259 }
260}
261
262impl<T: CubePrimitive> ListExpand<T> for TensorExpand<T> {
263 fn __expand_len_method(&self, scope: &Scope) -> NativeExpand<usize> {
264 Self::__expand_len_method(self, scope)
265 }
266}
267
268impl<T: CubePrimitive> Vectorized for Tensor<T> {}
269impl<T: CubePrimitive> VectorizedExpand for TensorExpand<T> {
270 fn __expand_vector_size_method(&self, scope: &Scope) -> VectorSize {
271 self.buffer.__expand_vector_size_method(scope)
272 }
273}