1use alloc::sync::Arc;
2use core::{cell::UnsafeCell, marker::PhantomData};
3use cubecl::prelude::*;
4use cubecl_core::{self as cubecl, unexpanded};
5use std::ops::{Deref, DerefMut};
6
7use crate::tensor::{
8 ViewExpand, ViewMut, ViewMutExpand,
9 layout::{
10 Coordinates, Coords1d, Layout, VirtualLayout, VirtualLayoutExpand, simple::SimpleLayout,
11 },
12 view::View,
13};
14
15#[derive(Clone)]
17pub struct VirtualTensor<E: Numeric, N: Size, IO = ReadOnly> {
18 _e: PhantomData<E>,
20 _n: PhantomData<N>,
21 _p: PhantomData<IO>,
22}
23
24#[derive(Clone)]
26pub struct VirtualTensorExpand<E: Numeric, N: Size, IO> {
27 state: Arc<UnsafeCell<dyn VirtualTensorOperationsExpand<E, N>>>,
28 _p: PhantomData<IO>,
29}
30
31impl<E: Numeric, N: Size, IO> VirtualTensorExpand<E, N, IO> {
32 fn state_read(&self) -> &dyn VirtualTensorOperationsExpand<E, N> {
33 unsafe { &mut *self.state.get() }
35 }
36
37 #[allow(clippy::mut_from_ref)]
38 pub(crate) fn state_write(&self) -> &mut dyn VirtualTensorOperationsExpand<E, N> {
39 unsafe { &mut *self.state.get() }
42 }
43}
44
45#[cube]
46impl<E: Numeric, N: Size, IO: Clone> VirtualTensor<E, N, IO> {
47 #[allow(unused)]
48 pub fn read(&self, index: usize) -> Vector<E, N> {
49 intrinsic!(|scope| { self.state_read().__expand_read_method(scope, index) })
50 }
51
52 #[allow(unused, clippy::len_without_is_empty)]
53 pub fn len(&self) -> usize {
54 intrinsic!(|scope| { self.state_read().__expand_len_method(scope) })
55 }
56}
57
58impl<T: Numeric, N: Size, IO: Clone> Deref for VirtualTensor<T, N, IO> {
59 type Target = [Vector<T, N>];
60
61 fn deref(&self) -> &Self::Target {
62 unexpanded!()
63 }
64}
65
66impl<T: Numeric, N: Size> DerefMut for VirtualTensor<T, N, ReadWrite> {
67 fn deref_mut(&mut self) -> &mut Self::Target {
68 unexpanded!()
69 }
70}
71
72impl<E: Numeric, N: Size, IO: Clone> Vectorized for VirtualTensor<E, N, IO> {}
73impl<E: Numeric, N: Size, IO: Clone> VectorizedExpand for VirtualTensorExpand<E, N, IO> {
74 fn vector_size(&self) -> VectorSize {
75 self.state_read().vector_size()
76 }
77}
78
79impl<E: Numeric, N: Size, IO: Clone> SliceOperator<Vector<E, N>> for VirtualTensor<E, N, IO> {}
80impl<E: Numeric, N: Size, IO: Clone> SliceOperatorExpand<Vector<E, N>>
81 for VirtualTensorExpand<E, N, IO>
82{
83 fn __expand_slice_method(
84 &self,
85 scope: &Scope,
86 start: NativeExpand<usize>,
87 end: NativeExpand<usize>,
88 ) -> &SliceExpand<Vector<E, N>> {
89 self.state_read()
90 .__expand_read_window_method(scope, start, end)
91 }
92
93 fn __expand_slice_mut_method(
94 &mut self,
95 _: &Scope,
96 _: NativeExpand<usize>,
97 _: NativeExpand<usize>,
98 ) -> &mut SliceExpand<Vector<E, N>> {
99 todo!("VirtualTensor don't support slice mut yet");
100 }
101}
102
103#[cube]
104impl<E: Numeric, N: Size, IO: Clone> VirtualTensor<E, N, IO> {
105 pub fn as_slice(&self) -> &[Vector<E, N>] {
106 self.slice(0, self.len())
107 }
108
109 pub fn as_mut_slice(&mut self) -> &mut [Vector<E, N>] {
110 self.slice_mut(0, self.len())
111 }
112
113 pub fn as_tensor_map(&self) -> ComptimeOption<TensorMap<E, Tiled>> {
114 intrinsic!(|scope| self.state_read().__expand_as_tensor_map_method(scope))
115 }
116 #[allow(unused)]
117 pub fn slice(&self, start: usize, end: usize) -> &[Vector<E, N>] {
118 intrinsic!(|scope| self
119 .state_read()
120 .__expand_read_window_method(scope, start, end))
121 }
122 #[allow(unused)]
124 pub fn shape(&self, axis: usize) -> usize {
125 intrinsic!(|scope| { self.state_read().__expand_shape_method(scope, axis) })
126 }
127 #[allow(unused)]
129 pub fn stride(&self, axis: usize) -> usize {
130 intrinsic!(|scope| self.state_read().__expand_stride_method(scope, axis))
131 }
132 pub fn rank(&self) -> usize {
134 intrinsic!(|scope| self.state_read().__expand_rank_method(scope))
135 }
136
137 pub fn buffer_len(&self) -> usize {
138 intrinsic!(|scope| self.state_read().__expand_buffer_len_method(scope))
139 }
140}
141
142impl<E: Numeric, N: Size, IO: Clone + 'static> VirtualTensor<E, N, IO> {
143 pub fn view<C: Coordinates + 'static>(
146 &self,
147 layout: impl Into<VirtualLayout<C, Coords1d>>,
148 ) -> View<'_, Vector<E, N>, C> {
149 View::new::<&VirtualTensor<E, N, IO>, Coords1d>(self, layout)
150 }
151
152 pub fn into_view<C: Coordinates + 'static>(
155 self,
156 layout: impl Into<VirtualLayout<C, Coords1d>>,
157 ) -> View<'static, Vector<E, N>, C> {
158 View::new::<VirtualTensor<E, N, IO>, Coords1d>(self, layout)
159 }
160}
161
162#[cube]
163impl<E: Numeric, N: Size, IO: Clone + 'static> VirtualTensor<E, N, IO> {
164 pub fn as_view(&self) -> View<'_, Vector<E, N>, usize> {
166 let vector_size = self.vector_size();
167 View::new::<&VirtualTensor<E, N, IO>, usize>(
168 self,
169 SimpleLayout::new(self.len() * vector_size, vector_size),
170 )
171 }
172}
173
174impl<E: Numeric, N: Size, IO: Clone + 'static> VirtualTensorExpand<E, N, IO> {
175 pub fn __expand_view_method<C: Coordinates + 'static>(
178 &self,
179 scope: &Scope,
180 layout: VirtualLayoutExpand<C, Coords1d>,
181 ) -> ViewExpand<'_, Vector<E, N>, C> {
182 View::__expand_new::<&VirtualTensor<E, N, IO>, Coords1d>(scope, self, layout)
183 }
184
185 pub fn __expand_into_view_method<C: Coordinates + 'static>(
186 self,
187 scope: &Scope,
188 layout: VirtualLayoutExpand<C, Coords1d>,
189 ) -> ViewExpand<'static, Vector<E, N>, C> {
190 View::__expand_new::<VirtualTensor<E, N, IO>, Coords1d>(scope, self, layout)
191 }
192}
193
194impl<E: Numeric, N: Size> VirtualTensor<E, N, ReadWrite> {
195 pub fn view_mut<C: Coordinates + 'static>(
198 &mut self,
199 layout: impl Layout<Coordinates = C, SourceCoordinates = Coords1d> + 'static,
200 ) -> ViewMut<'_, Vector<E, N>, C> {
201 ViewMut::new::<&mut VirtualTensor<E, N, ReadWrite>, Coords1d>(self, layout)
202 }
203 pub fn __expand_view_mut<'a, C: Coordinates + 'static>(
204 scope: &Scope,
205 this: &'a mut VirtualTensorExpand<E, N, ReadWrite>,
206 layout: VirtualLayoutExpand<C, Coords1d>,
207 ) -> ViewMutExpand<'a, Vector<E, N>, C> {
208 this.__expand_view_mut_method::<C>(scope, layout)
209 }
210
211 pub fn into_view_mut<C: Coordinates + 'static>(
212 self,
213 layout: impl Layout<Coordinates = C, SourceCoordinates = Coords1d> + 'static,
214 ) -> ViewMut<'static, Vector<E, N>, C> {
215 ViewMut::new::<VirtualTensor<E, N, ReadWrite>, Coords1d>(self, layout)
216 }
217}
218
219impl<E: Numeric, N: Size> VirtualTensorExpand<E, N, ReadWrite> {
220 pub fn __expand_view_mut_method<C: Coordinates + 'static>(
221 &mut self,
222 scope: &Scope,
223 layout: VirtualLayoutExpand<C, Coords1d>,
224 ) -> ViewMutExpand<'_, Vector<E, N>, C> {
225 ViewMut::__expand_new::<&mut VirtualTensor<E, N, ReadWrite>, Coords1d>(scope, self, layout)
226 }
227
228 pub fn __expand_into_view_mut_method<C: Coordinates + 'static>(
229 self,
230 scope: &Scope,
231 layout: VirtualLayoutExpand<C, Coords1d>,
232 ) -> ViewMutExpand<'static, Vector<E, N>, C> {
233 ViewMut::__expand_new::<VirtualTensor<E, N, ReadWrite>, Coords1d>(scope, self, layout)
234 }
235}
236
237#[cube]
238impl<E: Numeric, N: Size> VirtualTensor<E, N, ReadWrite> {
239 pub fn as_view_mut(&mut self) -> ViewMut<'_, Vector<E, N>, usize> {
241 let vector_size = self.vector_size();
242 let layout = SimpleLayout::new(self.len() * vector_size, vector_size);
243 ViewMut::new::<&mut VirtualTensor<E, N, ReadWrite>, usize>(self, layout)
244 }
245}
246
247#[cube]
248impl<E: Numeric, N: Size, IO: Clone + 'static> VirtualTensor<E, N, IO> {
249 pub fn coordinate(&self, index: usize, dim: usize) -> usize {
250 let num_strides = index / self.stride(dim);
251 num_strides % self.shape(dim)
252 }
253}
254
255#[cube]
256impl<E: Numeric, N: Size> VirtualTensor<E, N, ReadWrite> {
257 #[allow(unused)]
258 pub fn write(&mut self, index: usize, value: Vector<E, N>) {
259 intrinsic!(|scope| self
260 .state_write()
261 .__expand_write_method(scope, index, value))
262 }
263}
264
265impl<E: Numeric, N: Size> VirtualTensor<E, N, ReadOnly> {
266 pub fn new<V: VirtualTensorOperations<E, N> + 'static>(_v: V) -> Self {
268 unexpanded!()
269 }
270
271 pub fn __expand_new<V: VirtualTensorOperations<E, N> + 'static>(
273 _scope: &Scope,
274 v: V::ExpandType,
275 ) -> VirtualTensorExpand<E, N, ReadOnly> {
276 VirtualTensorExpand {
277 state: Arc::new(UnsafeCell::new(v)),
278 _p: PhantomData,
279 }
280 }
281}
282
283impl<E: Numeric, N: Size> VirtualTensor<E, N, ReadWrite> {
284 pub fn new<V: VirtualTensorOperations<E, N> + 'static>(_v: V) -> Self {
286 unexpanded!()
287 }
288
289 pub fn __expand_new<V: VirtualTensorOperations<E, N> + 'static>(
291 _scope: &Scope,
292 v: V::ExpandType,
293 ) -> VirtualTensorExpand<E, N, ReadWrite> {
294 VirtualTensorExpand {
295 state: Arc::new(UnsafeCell::new(v)),
296 _p: PhantomData,
297 }
298 }
299}
300
301#[cube(expand_base_traits = "VectorizedExpand")]
311pub trait VirtualTensorOperations<E: Numeric, N: Size>: Vectorized {
312 fn as_tensor_map(&self) -> ComptimeOption<TensorMap<E, Tiled>> {
313 unexpanded!()
314 }
315 fn read(&self, _index: usize) -> Vector<E, N> {
317 unexpanded!()
318 }
319 fn read_window(&self, _start: usize, _end: usize) -> &[Vector<E, N>] {
320 unexpanded!()
321 }
322 #[allow(unused)]
324 fn write(&mut self, _index: usize, value: Vector<E, N>) {
325 unexpanded!()
326 }
327 fn shape(&self, _axis: usize) -> usize {
329 unexpanded!()
330 }
331 fn stride(&self, _axis: usize) -> usize {
333 unexpanded!()
334 }
335 fn rank(&self) -> usize {
337 unexpanded!()
338 }
339 fn len(&self) -> usize {
340 unexpanded!()
341 }
342 fn buffer_len(&self) -> usize {
343 unexpanded!()
344 }
345}
346
347mod __cube_type {
349 use super::*;
350
351 impl<E: Numeric, N: Size, IO: Clone> CubeType for VirtualTensor<E, N, IO> {
352 type ExpandType = VirtualTensorExpand<E, N, IO>;
353 }
354
355 impl<E: Numeric, N: Size, IO: Clone> IntoExpand for VirtualTensorExpand<E, N, IO> {
356 type Expand = VirtualTensorExpand<E, N, IO>;
357
358 fn into_expand(self, _: &Scope) -> Self::Expand {
359 self
360 }
361 }
362
363 impl<E: Numeric, N: Size, IO: Clone> ExpandTypeClone for VirtualTensorExpand<E, N, IO> {
364 fn clone_unchecked(&self) -> Self {
365 self.clone()
366 }
367 }
368
369 impl<E: Numeric, N: Size, IO> IntoMut for VirtualTensorExpand<E, N, IO> {
370 fn into_mut(self, _scope: &Scope) -> Self {
371 self
372 }
373 }
374
375 impl<E: Numeric, N: Size, IO> CubeDebug for VirtualTensorExpand<E, N, IO> {}
376
377 impl<E: Numeric, N: Size, IO: Clone> AsRefExpand for VirtualTensorExpand<E, N, IO> {
378 fn __expand_ref_method(&self, _: &Scope) -> &Self {
379 self
380 }
381 }
382
383 impl<E: Numeric, N: Size, IO: Clone> AsMutExpand for VirtualTensorExpand<E, N, IO> {
384 fn __expand_ref_mut_method(&mut self, _: &Scope) -> &mut Self {
385 self
386 }
387 }
388}
389
390mod __tensor {
392 use super::*;
393
394 impl<E: Numeric, N: Size> VirtualTensorOperations<E, N> for Tensor<Vector<E, N>> {}
395 impl<E: Numeric, N: Size> VirtualTensorOperationsExpand<E, N> for TensorExpand<Vector<E, N>> {
396 fn __expand_read_method(
397 &self,
398 scope: &Scope,
399 index: NativeExpand<usize>,
400 ) -> NativeExpand<Vector<E, N>> {
401 unsafe {
402 self.__expand_get_unchecked_method(scope, index)
403 .__expand_deref_method(scope)
404 }
405 }
406 fn __expand_read_window_method(
407 &self,
408 context: &Scope,
409 start: NativeExpand<usize>,
410 end: NativeExpand<usize>,
411 ) -> &'static SliceExpand<Vector<E, N>> {
412 unsafe { core::mem::transmute(self.__expand_slice_method(context, start, end)) }
413 }
414
415 fn __expand_write_method(
416 &mut self,
417 scope: &Scope,
418 index: NativeExpand<usize>,
419 value: NativeExpand<Vector<E, N>>,
420 ) {
421 unsafe {
422 self.__expand_get_unchecked_mut_method(scope, index)
423 .__expand_assign_method(scope, value)
424 };
425 }
426
427 fn __expand_shape_method(
428 &self,
429 scope: &Scope,
430 axis: NativeExpand<usize>,
431 ) -> NativeExpand<usize> {
432 self.__expand_shape_method(scope, axis)
433 }
434
435 fn __expand_stride_method(
436 &self,
437 scope: &Scope,
438 axis: NativeExpand<usize>,
439 ) -> NativeExpand<usize> {
440 self.__expand_stride_method(scope, axis)
441 }
442
443 fn __expand_rank_method(&self, scope: &Scope) -> NativeExpand<usize> {
444 self.__expand_rank_method(scope)
445 }
446 fn __expand_len_method(&self, scope: &Scope) -> NativeExpand<usize> {
447 self.__expand_len_method(scope)
448 }
449 fn __expand_buffer_len_method(&self, scope: &Scope) -> NativeExpand<usize> {
450 self.__expand_buffer_len_method(scope)
451 }
452
453 fn __expand_as_tensor_map_method(
454 &self,
455 scope: &Scope,
456 ) -> ComptimeOptionExpand<TensorMap<E, Tiled>> {
457 ComptimeOption::__expand_new_None(scope)
458 }
459 }
460}
461
462mod __tensor_map {
464 use super::*;
465
466 impl<E: Numeric, N: Size> VirtualTensorOperations<E, N> for TensorMap<E, Tiled> {}
467 impl<E: Numeric, N: Size> VirtualTensorOperationsExpand<E, N>
468 for NativeExpand<TensorMap<E, Tiled>>
469 {
470 fn __expand_read_method(
471 &self,
472 _scope: &Scope,
473 _index: NativeExpand<usize>,
474 ) -> NativeExpand<Vector<E, N>> {
475 todo!()
476 }
477 fn __expand_read_window_method(
478 &self,
479 _context: &Scope,
480 _start: NativeExpand<usize>,
481 _end: NativeExpand<usize>,
482 ) -> &'static SliceExpand<Vector<E, N>> {
483 todo!()
484 }
485
486 fn __expand_write_method(
487 &mut self,
488 _scope: &Scope,
489 _index: NativeExpand<usize>,
490 _value: NativeExpand<Vector<E, N>>,
491 ) {
492 todo!()
493 }
494
495 fn __expand_shape_method(
496 &self,
497 _scope: &Scope,
498 _axis: NativeExpand<usize>,
499 ) -> NativeExpand<usize> {
500 todo!()
501 }
502
503 fn __expand_stride_method(
504 &self,
505 _scope: &Scope,
506 _axis: NativeExpand<usize>,
507 ) -> NativeExpand<usize> {
508 todo!()
509 }
510
511 fn __expand_rank_method(&self, _scope: &Scope) -> NativeExpand<usize> {
512 todo!()
513 }
514 fn __expand_len_method(&self, _scope: &Scope) -> NativeExpand<usize> {
515 todo!()
516 }
517 fn __expand_buffer_len_method(&self, _scope: &Scope) -> NativeExpand<usize> {
518 todo!()
519 }
520
521 fn __expand_as_tensor_map_method(
522 &self,
523 scope: &Scope,
524 ) -> ComptimeOptionExpand<TensorMap<E, Tiled>> {
525 ComptimeOption::__expand_new_Some(scope, *self)
526 }
527 }
528}