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