1use cubecl_core::prelude::*;
2use std::{marker::PhantomData, ops::Deref};
3
4use crate::tensor::{
5 View, ViewExpand, VirtualViewMutExpand,
6 layout::{Coordinates, Coords1d, Layout, VirtualLayoutExpand},
7};
8
9mod layout {
10 use core::{cell::RefCell, fmt::Debug, hash::Hash};
11
12 use alloc::rc::Rc;
13 use cubecl_core::{
14 self as cubecl,
15 format::DebugRaw,
16 hash::{StableHash, StableHasher},
17 prelude::*,
18 zspace::{Shape, Strides, metadata::Metadata},
19 };
20
21 use crate::tensor::layout::LayoutExpand;
22
23 use super::*;
24
25 #[allow(clippy::len_without_is_empty)]
26 pub trait MemoryArg: 'static {
27 fn len(&self) -> usize;
28 fn shape(&self) -> &[usize];
29 fn strides(&self) -> &[usize];
30 }
31
32 impl<R: Runtime> MemoryArg for TensorArg<R> {
33 fn len(&self) -> usize {
34 self.size()
35 }
36
37 fn shape(&self) -> &[usize] {
38 self.shape()
39 }
40
41 fn strides(&self) -> &[usize] {
42 self.strides()
43 }
44 }
45 impl<R: Runtime> MemoryArg for BufferArg<R> {
46 fn len(&self) -> usize {
47 self.size()
48 }
49
50 fn shape(&self) -> &[usize] {
51 self.shape()
52 }
53
54 fn strides(&self) -> &[usize] {
55 &[1]
56 }
57 }
58 impl<R: Runtime, K: TensorMapKind> MemoryArg for TensorMapArg<R, K> {
59 fn len(&self) -> usize {
60 self.tensor.size()
61 }
62
63 fn shape(&self) -> &[usize] {
64 self.tensor.shape()
65 }
66
67 fn strides(&self) -> &[usize] {
68 self.tensor.strides()
69 }
70 }
71
72 impl MemoryArg for Metadata {
73 fn len(&self) -> usize {
74 self.shape.num_elements()
75 }
76
77 fn shape(&self) -> &[usize] {
78 &self.shape
79 }
80
81 fn strides(&self) -> &[usize] {
82 &self.strides
83 }
84 }
85
86 pub trait ViewLayoutLaunchArg: CubeType + Send + Sync + 'static {
90 type RuntimeArg<R: Runtime>: Send + Sync;
92 type CompilationArg: CompilationArg;
94
95 fn register<R: Runtime, B: MemoryArg>(
96 arg: Self::RuntimeArg<R>,
97 buffer: &B,
98 ty: Type,
99 launcher: &mut KernelLauncher<R>,
100 ) -> Self::CompilationArg;
101
102 fn expand(
104 arg: &Self::CompilationArg,
105 ty: Type,
106 builder: &mut KernelBuilder,
107 ) -> <Self as CubeType>::ExpandType;
108
109 fn expand_output(
111 arg: &Self::CompilationArg,
112 ty: Type,
113 builder: &mut KernelBuilder,
114 ) -> <Self as CubeType>::ExpandType {
115 Self::expand(arg, ty, builder)
116 }
117 }
118
119 impl<T: LaunchArg + Send + Sync> ViewLayoutLaunchArg for T {
120 type RuntimeArg<R: Runtime> = <T as LaunchArg>::RuntimeArg<R>;
121 type CompilationArg = <T as LaunchArg>::CompilationArg;
122
123 fn register<R: Runtime, B: MemoryArg>(
124 arg: Self::RuntimeArg<R>,
125 _buffer: &B,
126 _ty: Type,
127 launcher: &mut KernelLauncher<R>,
128 ) -> Self::CompilationArg {
129 <T as LaunchArg>::register(arg, launcher)
130 }
131
132 fn expand(
133 arg: &Self::CompilationArg,
134 _ty: Type,
135 builder: &mut KernelBuilder,
136 ) -> <Self as CubeType>::ExpandType {
137 <T as LaunchArg>::expand(arg, builder)
138 }
139 }
140
141 pub struct VirtualViewLayoutLaunch<C: Coordinates, S: Coordinates, B: MemoryArg, R: Runtime> {
142 _ty: core::marker::PhantomData<R>,
143 #[allow(clippy::type_complexity)]
144 register: Box<
145 dyn FnOnce(&B, Type, &mut KernelLauncher<R>) -> VirtualViewLayoutCompilationArg<C, S>
146 + Send
147 + Sync,
148 >,
149 }
150
151 impl<C: Coordinates, S: Coordinates, B: MemoryArg, R: Runtime> VirtualViewLayoutLaunch<C, S, B, R> {
152 pub fn new<L: Layout<Coordinates = C, SourceCoordinates = S> + ViewLayoutLaunchArg>(
153 layout: L::RuntimeArg<R>,
154 ) -> Self {
155 Self {
156 _ty: PhantomData,
157 register: Box::new(move |buffer, ty, launcher| {
158 let comp_arg = L::register::<R, B>(layout, buffer, ty, launcher);
159 let comp_arg_2 = comp_arg.clone();
160 let expand = Rc::new(RefCell::new(
161 move |ty: Type, builder: &mut KernelBuilder, is_out: bool| {
162 let expand = match is_out {
163 true => L::expand_output(&comp_arg_2, ty, builder),
164 false => L::expand(&comp_arg_2, ty, builder),
165 };
166 VirtualLayoutExpand::new(expand)
167 },
168 ));
169 VirtualViewLayoutCompilationArg::new(comp_arg, expand)
170 }),
171 }
172 }
173
174 pub fn register(
175 self,
176 buffer: &B,
177 ty: Type,
178 launcher: &mut KernelLauncher<R>,
179 ) -> VirtualViewLayoutCompilationArg<C, S> {
180 (self.register)(buffer, ty, launcher)
181 }
182 }
183
184 type ExpandFn<C, S> =
185 Rc<RefCell<dyn FnMut(Type, &mut KernelBuilder, bool) -> VirtualLayoutExpand<C, S> + Send>>;
186
187 #[derive(Clone)]
188 pub struct VirtualViewLayoutCompilationArg<C: Coordinates, S: Coordinates> {
189 type_name: String,
190 debug: Rc<dyn core::fmt::Debug>,
191 hash: StableHash,
192 expand: ExpandFn<C, S>,
193 }
194
195 unsafe impl<C: Coordinates, S: Coordinates> Send for VirtualViewLayoutCompilationArg<C, S> {}
197 unsafe impl<C: Coordinates, S: Coordinates> Sync for VirtualViewLayoutCompilationArg<C, S> {}
198
199 impl<C: Coordinates, S: Coordinates> VirtualViewLayoutCompilationArg<C, S> {
200 pub fn new<L: CompilationArg + 'static>(arg: L, expand: ExpandFn<C, S>) -> Self {
201 let hash = StableHasher::hash_one(&arg);
204 Self {
205 type_name: core::any::type_name::<L>().to_string(),
206 debug: Rc::new(arg),
207 hash,
208 expand,
209 }
210 }
211
212 pub fn expand(&self, ty: Type, builder: &mut KernelBuilder) -> VirtualLayoutExpand<C, S> {
213 let mut expand = self.expand.borrow_mut();
214 (expand)(ty, builder, false)
215 }
216
217 pub fn expand_output(
218 &self,
219 ty: Type,
220 builder: &mut KernelBuilder,
221 ) -> VirtualLayoutExpand<C, S> {
222 let mut expand = self.expand.borrow_mut();
223 (expand)(ty, builder, true)
224 }
225 }
226
227 impl<C: Coordinates, S: Coordinates> PartialEq for VirtualViewLayoutCompilationArg<C, S> {
228 fn eq(&self, other: &Self) -> bool {
229 self.type_name == other.type_name && self.hash == other.hash
230 }
231 }
232 impl<C: Coordinates, S: Coordinates> Eq for VirtualViewLayoutCompilationArg<C, S> {}
233
234 impl<C: Coordinates, S: Coordinates> core::hash::Hash for VirtualViewLayoutCompilationArg<C, S> {
235 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
236 self.type_name.hash(state);
237 self.hash.hash(state);
238 }
239 }
240
241 impl<C: Coordinates, S: Coordinates> core::fmt::Debug for VirtualViewLayoutCompilationArg<C, S> {
242 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
243 f.debug_struct(stringify!(VirtualLayout))
244 .field("type", &DebugRaw(&self.type_name))
245 .field("value", &self.debug)
246 .finish()
247 }
248 }
249
250 #[derive(CubeType)]
251 pub struct ConcreteLayout<L: Layout + ViewLayoutLaunchArg> {
252 value: L,
253 }
254
255 #[cube]
256 impl<L: Layout + ViewLayoutLaunchArg> Layout for ConcreteLayout<L> {
257 type Coordinates = L::Coordinates;
258 type SourceCoordinates = L::SourceCoordinates;
259
260 fn to_source_pos(&self, pos: Self::Coordinates) -> Self::SourceCoordinates {
261 self.value.to_source_pos(pos)
262 }
263
264 fn to_source_pos_checked(&self, pos: Self::Coordinates) -> (Self::SourceCoordinates, bool) {
265 self.value.to_source_pos_checked(pos)
266 }
267
268 fn shape(&self) -> Self::Coordinates {
269 self.value.shape()
270 }
271
272 fn is_in_bounds(&self, pos: Self::Coordinates) -> bool {
273 self.value.is_in_bounds(pos)
274 }
275 }
276
277 impl<L: Layout + ViewLayoutLaunchArg> Deref for ConcreteLayout<L> {
278 type Target = L;
279
280 fn deref(&self) -> &Self::Target {
281 &self.value
282 }
283 }
284
285 impl<L: Layout + ViewLayoutLaunchArg> Deref for ConcreteLayoutExpand<L> {
286 type Target = <L as CubeType>::ExpandType;
287
288 fn deref(&self) -> &Self::Target {
289 &self.value
290 }
291 }
292
293 pub struct ConcreteLayoutLaunch<L: Layout + ViewLayoutLaunchArg, R: Runtime> {
294 meta: Metadata,
295 ty: Type,
296 value: L::RuntimeArg<R>,
297 }
298
299 impl<L: Layout + ViewLayoutLaunchArg, R: Runtime> ConcreteLayoutLaunch<L, R> {
300 pub fn new(meta: Metadata, ty: Type, value: L::RuntimeArg<R>) -> Self {
301 Self { meta, ty, value }
302 }
303
304 pub fn from_handle(handle: &TensorBinding<R>, ty: Type, value: L::RuntimeArg<R>) -> Self {
305 Self {
306 meta: Metadata {
307 shape: handle.shape.clone(),
308 strides: handle.strides.clone(),
309 },
310 ty,
311 value,
312 }
313 }
314
315 pub fn from_shape_strides(
316 shape: Shape,
317 strides: Strides,
318 ty: Type,
319 value: L::RuntimeArg<R>,
320 ) -> Self {
321 Self {
322 meta: Metadata { shape, strides },
323 ty,
324 value,
325 }
326 }
327 }
328
329 pub struct ConcreteLayoutCompilationArg<L: Layout + ViewLayoutLaunchArg> {
330 ty: Type,
331 value: L::CompilationArg,
332 }
333
334 impl<L: Layout + ViewLayoutLaunchArg> Debug for ConcreteLayoutCompilationArg<L> {
335 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
336 f.debug_struct("ConcreteLayoutCompilationArg")
337 .field("ty", &self.ty)
338 .field("value", &self.value)
339 .finish()
340 }
341 }
342
343 impl<L: Layout + ViewLayoutLaunchArg> Hash for ConcreteLayoutCompilationArg<L> {
344 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
345 self.ty.hash(state);
346 self.value.hash(state);
347 }
348 }
349
350 impl<L: Layout + ViewLayoutLaunchArg> Eq for ConcreteLayoutCompilationArg<L> {}
351 impl<L: Layout + ViewLayoutLaunchArg> PartialEq for ConcreteLayoutCompilationArg<L> {
352 fn eq(&self, other: &Self) -> bool {
353 self.ty == other.ty && self.value == other.value
354 }
355 }
356
357 impl<L: Layout + ViewLayoutLaunchArg> Clone for ConcreteLayoutCompilationArg<L> {
358 fn clone(&self) -> Self {
359 Self {
360 ty: self.ty,
361 value: self.value.clone(),
362 }
363 }
364 }
365
366 impl<L: Layout + ViewLayoutLaunchArg> LaunchArg for ConcreteLayout<L> {
367 type RuntimeArg<R: Runtime> = ConcreteLayoutLaunch<L, R>;
368 type CompilationArg = ConcreteLayoutCompilationArg<L>;
369
370 fn register<R: Runtime>(
371 arg: Self::RuntimeArg<R>,
372 launcher: &mut KernelLauncher<R>,
373 ) -> Self::CompilationArg {
374 ConcreteLayoutCompilationArg {
375 value: L::register(arg.value, &arg.meta, arg.ty, launcher),
376 ty: arg.ty,
377 }
378 }
379
380 fn expand(
381 arg: &Self::CompilationArg,
382 builder: &mut KernelBuilder,
383 ) -> <Self as CubeType>::ExpandType {
384 ConcreteLayoutExpand {
385 value: L::expand(&arg.value, arg.ty, builder),
386 }
387 }
388 }
389}
390
391pub use layout::*;
392
393mod dynamic {
394 use cubecl_common::quant::scheme::QuantScheme;
395
396 use crate::{
397 quant::{
398 self,
399 view::{RegisterDynamic, run_with_quant_type},
400 },
401 tensor::{
402 ViewMut, ViewMutExpand, VirtualViewExpand,
403 launch::layout::{ViewLayoutLaunchArg, VirtualViewLayoutLaunch},
404 layout::as_dyn::{IntoDyn, IntoDyn2Layout, IntoDynLayout},
405 },
406 };
407
408 use super::*;
409
410 #[allow(clippy::type_complexity)]
411 pub enum ViewArg<C: Coordinates, R: Runtime> {
412 Array(
413 BufferArg<R>,
414 VirtualViewLayoutLaunch<C, Coords1d, BufferArg<R>, R>,
415 ),
416 Tensor(
417 TensorArg<R>,
418 VirtualViewLayoutLaunch<C, Coords1d, TensorArg<R>, R>,
419 ),
420 TensorMapTiled(
421 TensorMapArg<R, Tiled>,
422 VirtualViewLayoutLaunch<C, Sequence<i32>, TensorMapArg<R, Tiled>, R>,
423 ),
424 TensorMapIm2col(
425 TensorMapArg<R, Im2col>,
426 VirtualViewLayoutLaunch<C, (Sequence<i32>, Sequence<i32>), TensorMapArg<R, Im2col>, R>,
427 ),
428 Quantized {
429 values: Box<ViewArg<C, R>>,
430 scales: Box<ViewArg<C, R>>,
431 scheme: QuantScheme,
432 },
433 }
434
435 impl<C: Coordinates, R: Runtime> ViewArg<C, R> {
436 pub fn new_array<
437 L: Layout<Coordinates = C, SourceCoordinates = Coords1d> + ViewLayoutLaunchArg,
438 >(
439 buffer: BufferArg<R>,
440 layout: L::RuntimeArg<R>,
441 ) -> Self {
442 let layout = VirtualViewLayoutLaunch::new::<L>(layout);
443 ViewArg::Array(buffer, layout)
444 }
445
446 pub fn new_tensor<
447 L: Layout<Coordinates = C, SourceCoordinates = Coords1d> + ViewLayoutLaunchArg,
448 >(
449 buffer: TensorArg<R>,
450 layout: L::RuntimeArg<R>,
451 ) -> Self {
452 let layout = VirtualViewLayoutLaunch::new::<L>(layout);
453 ViewArg::Tensor(buffer, layout)
454 }
455
456 pub fn new_tensor_map_tiled<
457 L: Layout<Coordinates = C, SourceCoordinates: IntoDyn> + ViewLayoutLaunchArg,
458 >(
459 buffer: TensorMapArg<R, Tiled>,
460 layout: L::RuntimeArg<R>,
461 ) -> ViewArg<C, R> {
462 let layout = VirtualViewLayoutLaunch::new::<IntoDynLayout<L>>(layout);
463 ViewArg::TensorMapTiled(buffer, layout)
464 }
465
466 pub fn new_tensor_map_im2col<
467 L: Layout<Coordinates = C, SourceCoordinates = (P, O)> + ViewLayoutLaunchArg,
468 P: IntoDyn,
469 O: IntoDyn,
470 >(
471 buffer: TensorMapArg<R, Im2col>,
472 layout: L::RuntimeArg<R>,
473 ) -> ViewArg<C, R> {
474 let layout = VirtualViewLayoutLaunch::new::<IntoDyn2Layout<L, P, O>>(layout);
475 ViewArg::TensorMapIm2col(buffer, layout)
476 }
477
478 pub fn new_quantized(values: Self, scales: Self, scheme: QuantScheme) -> Self {
481 Self::Quantized {
482 values: Box::new(values),
483 scales: Box::new(scales),
484 scheme,
485 }
486 }
487 }
488 #[derive(Clone)]
489 pub enum ViewCompilationArg<C: Coordinates> {
490 Array {
491 buffer: BufferCompilationArg,
492 layout: VirtualViewLayoutCompilationArg<C, Coords1d>,
493 },
494 TensorMapTiled {
495 buffer: (),
496 layout: VirtualViewLayoutCompilationArg<C, Sequence<i32>>,
497 },
498 TensorMapIm2col {
499 buffer: (),
500 layout: VirtualViewLayoutCompilationArg<C, (Sequence<i32>, Sequence<i32>)>,
501 },
502 Quantized {
503 values: Box<ViewCompilationArg<C>>,
504 scales: Box<ViewCompilationArg<C>>,
505 scheme: QuantScheme,
506 },
507 }
508
509 impl<C: Coordinates> Eq for ViewCompilationArg<C> {}
510 impl<C: Coordinates> PartialEq for ViewCompilationArg<C> {
511 fn eq(&self, other: &Self) -> bool {
512 match (self, other) {
513 (
514 ViewCompilationArg::Array { buffer, layout },
515 ViewCompilationArg::Array {
516 buffer: buffer_other,
517 layout: layout_other,
518 },
519 ) => buffer == buffer_other && layout == layout_other,
520 (
521 ViewCompilationArg::TensorMapTiled { buffer, layout },
522 ViewCompilationArg::TensorMapTiled {
523 buffer: buffer_other,
524 layout: layout_other,
525 },
526 ) => buffer == buffer_other && layout == layout_other,
527 (
528 ViewCompilationArg::TensorMapIm2col { buffer, layout },
529 ViewCompilationArg::TensorMapIm2col {
530 buffer: buffer_other,
531 layout: layout_other,
532 },
533 ) => buffer == buffer_other && layout == layout_other,
534 (
535 ViewCompilationArg::Quantized {
536 values,
537 scales,
538 scheme,
539 },
540 ViewCompilationArg::Quantized {
541 values: values_other,
542 scales: scales_other,
543 scheme: scheme_other,
544 },
545 ) => values == values_other && scales == scales_other && scheme == scheme_other,
546 _ => false,
547 }
548 }
549 }
550 impl<C: Coordinates> core::hash::Hash for ViewCompilationArg<C> {
551 fn hash<H: core::hash::Hasher>(&self, ra_expand_state: &mut H) {
552 match self {
553 ViewCompilationArg::Array { buffer, layout } => {
554 buffer.hash(ra_expand_state);
555 layout.hash(ra_expand_state);
556 }
557 ViewCompilationArg::TensorMapTiled { buffer, layout } => {
558 buffer.hash(ra_expand_state);
559 layout.hash(ra_expand_state);
560 }
561 ViewCompilationArg::TensorMapIm2col { buffer, layout } => {
562 buffer.hash(ra_expand_state);
563 layout.hash(ra_expand_state);
564 }
565 ViewCompilationArg::Quantized {
566 values,
567 scales,
568 scheme,
569 } => {
570 values.hash(ra_expand_state);
571 scales.hash(ra_expand_state);
572 scheme.hash(ra_expand_state);
573 }
574 }
575 }
576 }
577 impl<C: Coordinates> core::fmt::Debug for ViewCompilationArg<C> {
578 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
579 match self {
580 ViewCompilationArg::Array { buffer, layout } => f
581 .debug_struct("ArrayView")
582 .field("buffer", &buffer)
583 .field("layout", &layout)
584 .finish(),
585 ViewCompilationArg::TensorMapTiled { buffer, layout } => f
586 .debug_struct("TensorMapTiledView")
587 .field("buffer", &buffer)
588 .field("layout", &layout)
589 .finish(),
590 ViewCompilationArg::TensorMapIm2col { buffer, layout } => f
591 .debug_struct("TensorMapIm2colView")
592 .field("buffer", &buffer)
593 .field("layout", &layout)
594 .finish(),
595 ViewCompilationArg::Quantized {
596 values,
597 scales,
598 scheme,
599 } => f
600 .debug_struct("QuantizedView")
601 .field("values", &values)
602 .field("scales", &scales)
603 .field("scheme", &scheme)
604 .finish(),
605 }
606 }
607 }
608
609 impl<E: CubePrimitive, C: Coordinates + 'static> LaunchArg for View<'static, E, C> {
610 type RuntimeArg<R: Runtime> = ViewArg<C, R>;
611 type CompilationArg = ViewCompilationArg<C>;
612
613 fn register<R: Runtime>(
614 arg: Self::RuntimeArg<R>,
615 launcher: &mut KernelLauncher<R>,
616 ) -> Self::CompilationArg {
617 let ty = launcher.with_scope(|scope| E::__expand_as_type(scope));
618 match arg {
619 ViewArg::Array(buffer, layout) => ViewCompilationArg::Array {
620 layout: layout.register(&buffer, ty, launcher),
621 buffer: <[E] as LaunchArg>::register(buffer, launcher),
622 },
623 ViewArg::Tensor(buffer, layout) => ViewCompilationArg::Array {
624 layout: layout.register(&buffer, ty, launcher),
625 buffer: <[E] as LaunchArg>::register(buffer.into_buffer_arg(), launcher),
626 },
627 ViewArg::TensorMapTiled(buffer, layout) => ViewCompilationArg::TensorMapTiled {
628 layout: layout.register(&buffer, ty, launcher),
629 buffer: <TensorMap<E, Tiled> as LaunchArg>::register(buffer, launcher),
630 },
631 ViewArg::TensorMapIm2col(buffer, layout) => ViewCompilationArg::TensorMapIm2col {
632 layout: layout.register(&buffer, ty, launcher),
633 buffer: <TensorMap<E, Im2col> as LaunchArg>::register(buffer, launcher),
634 },
635 ViewArg::Quantized {
636 values,
637 scales,
638 scheme,
639 } => {
640 let register = RegisterDynamic {
641 values: *values,
642 scales: *scales,
643 scheme,
644 launcher,
645 _ty: PhantomData::<E>,
646 };
647 run_with_quant_type(register, scheme)
648 }
649 }
650 }
651 fn expand(
652 arg: &Self::CompilationArg,
653 builder: &mut KernelBuilder,
654 ) -> <Self as CubeType>::ExpandType {
655 let ty = E::__expand_as_type(&builder.scope);
656 match arg {
657 ViewCompilationArg::Array { buffer, layout } => {
658 let layout = layout.expand(ty, builder);
659 let buffer = <Box<[E]> as LaunchArg>::expand(buffer, builder);
660 let view =
661 VirtualViewMutExpand::<E, C, Coords1d, Box<[E]>>::new(buffer, layout);
662 ViewExpand::new(&builder.scope, view)
663 }
664 ViewCompilationArg::TensorMapTiled { buffer, layout } => {
665 let layout = layout.expand(ty, builder);
666 let buffer = <TensorMap<E, Tiled> as LaunchArg>::expand(buffer, builder);
667 let view =
668 VirtualViewMutExpand::<E, C, Sequence<i32>, TensorMap<E, Tiled>>::new(
669 buffer, layout,
670 );
671 ViewExpand::new(&builder.scope, view)
672 }
673 ViewCompilationArg::TensorMapIm2col { buffer, layout } => {
674 let layout = layout.expand(ty, builder);
675 let buffer = <TensorMap<E, Im2col> as LaunchArg>::expand(buffer, builder);
676 let view = VirtualViewExpand::<
677 E,
678 C,
679 (Sequence<i32>, Sequence<i32>),
680 TensorMap<E, Im2col>,
681 >::new(buffer, layout);
682 ViewExpand::new(&builder.scope, view)
683 }
684 ViewCompilationArg::Quantized {
685 values,
686 scales,
687 scheme,
688 } => quant::view::expand_dynamic(values, scales, *scheme, builder),
689 }
690 }
691 }
692
693 impl<E: CubePrimitive, C: Coordinates + 'static> LaunchArg for ViewMut<'static, E, C> {
694 type RuntimeArg<R: Runtime> = ViewArg<C, R>;
695 type CompilationArg = ViewCompilationArg<C>;
696
697 fn register<R: Runtime>(
698 arg: Self::RuntimeArg<R>,
699 launcher: &mut KernelLauncher<R>,
700 ) -> Self::CompilationArg {
701 <View<'static, E, C> as LaunchArg>::register(arg, launcher)
702 }
703
704 fn expand(
705 arg: &Self::CompilationArg,
706 builder: &mut KernelBuilder,
707 ) -> <Self as CubeType>::ExpandType {
708 let ty = E::__expand_as_type(&builder.scope);
709 match arg {
710 ViewCompilationArg::Array { buffer, layout } => {
711 let layout = layout.expand(ty, builder);
712 let buffer = <Box<[E]> as LaunchArg>::expand(buffer, builder);
713 let view =
714 VirtualViewMutExpand::<E, C, Coords1d, Box<[E]>>::new(buffer, layout);
715 ViewMutExpand::new(&builder.scope, view)
716 }
717 ViewCompilationArg::TensorMapTiled { buffer, layout } => {
718 let layout = layout.expand(ty, builder);
719 let buffer = <TensorMap<E, Tiled> as LaunchArg>::expand(buffer, builder);
720 let view =
721 VirtualViewMutExpand::<E, C, Sequence<i32>, TensorMap<E, Tiled>>::new(
722 buffer, layout,
723 );
724 ViewMutExpand::new(&builder.scope, view)
725 }
726 ViewCompilationArg::TensorMapIm2col { .. } => {
727 unimplemented!("im2col not supported for writing")
728 }
729 ViewCompilationArg::Quantized { .. } => {
730 unimplemented!("quantized views not supported for writing")
731 }
732 }
733 }
734 }
735}
736
737pub use dynamic::*;