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