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