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