1use super::{CubePrimitive, Numeric};
2use crate::{
3 ir::{ConstantValue, ExpandValue, Scope},
4 prelude::{DynamicSize, KernelBuilder, KernelLauncher, Scalar, assign},
5 unexpanded,
6};
7use alloc::{boxed::Box, vec::Vec};
8use core::{fmt::Debug, marker::PhantomData};
9use cubecl_common::{e2m1, e2m1x2, e2m3, e3m2, e4m3, e5m2, flex32, tf32, ue8m0};
10use cubecl_ir::{
11 VectorSize, ident,
12 interfaces::TypedExt,
13 pliron::{
14 debug_info::set_operation_result_name, printable::Printable, r#type::Typed, value::Value,
15 },
16 types::PointerType,
17};
18use cubecl_runtime::runtime::Runtime;
19use half::{bf16, f16};
20use pliron::r#type::TypeHandle;
21use variadics_please::{all_tuples, all_tuples_enumerated};
22
23#[diagnostic::on_unimplemented(note = "Consider using `#[derive(CubeType)]` on `{Self}`")]
36pub trait CubeType {
37 type ExpandType: IntoExpand<Expand = Self::ExpandType>
38 + ExpandTypeClone
39 + IntoMut
40 + CubeDebug
41 + AsRefExpand
42 + AsMutExpand;
43}
44
45pub trait NativeCubeType: CubeType<ExpandType = NativeExpand<Self>> {}
46
47impl<'a, T: CubeType + ?Sized> CubeType for &'a T {
48 type ExpandType = &'a T::ExpandType;
49}
50
51impl<'a, T: CubeType + ?Sized> CubeType for &'a mut T {
52 type ExpandType = &'a mut T::ExpandType;
53}
54
55impl<T: CubeType + ?Sized> CubeType for *const T {
56 type ExpandType = *const T::ExpandType;
57}
58
59impl<T: CubeType + ?Sized> CubeType for *mut T {
60 type ExpandType = *mut T::ExpandType;
61}
62
63impl<T: CubeType<ExpandType = NativeExpand<T>> + ?Sized> NativeCubeType for T {}
64
65pub trait IntoExpand {
66 type Expand;
67 fn into_expand(self, scope: &Scope) -> Self::Expand;
68}
69
70impl<'a, T: IntoExpand<Expand = T> + ?Sized> IntoExpand for &'a T {
71 type Expand = &'a T;
72
73 fn into_expand(self, _: &Scope) -> Self::Expand {
74 self
75 }
76}
77
78impl<'a, T: IntoExpand<Expand = T> + ?Sized> IntoExpand for &'a mut T {
79 type Expand = &'a mut T;
80
81 fn into_expand(self, _: &Scope) -> Self::Expand {
82 self
83 }
84}
85
86impl<T: IntoExpand<Expand = T> + ?Sized> IntoExpand for *const T {
87 type Expand = *const T;
88
89 fn into_expand(self, _: &Scope) -> Self::Expand {
90 self
91 }
92}
93
94impl<T: IntoExpand<Expand = T> + ?Sized> IntoExpand for *mut T {
95 type Expand = *mut T;
96
97 fn into_expand(self, _: &Scope) -> Self::Expand {
98 self
99 }
100}
101
102pub trait ExpandTypeClone {
103 fn clone_unchecked(&self) -> Self;
109}
110
111impl<T: ExpandTypeClone + ?Sized> ExpandTypeClone for &T {
112 fn clone_unchecked(&self) -> Self {
113 self
114 }
115}
116
117impl<T: ExpandTypeClone + ?Sized> ExpandTypeClone for &mut T {
118 #[allow(mutable_transmutes)]
119 fn clone_unchecked(&self) -> Self {
120 unsafe { core::mem::transmute(&**self) }
121 }
122}
123
124impl<T: ExpandTypeClone + ?Sized> ExpandTypeClone for *const T {
125 fn clone_unchecked(&self) -> Self {
126 *self
127 }
128}
129
130impl<T: ExpandTypeClone + ?Sized> ExpandTypeClone for *mut T {
131 fn clone_unchecked(&self) -> Self {
132 *self
133 }
134}
135
136pub trait AsRefExpand<T: ?Sized = Self> {
140 fn __expand_as_ref_method(&self, scope: &Scope) -> &T {
141 self.__expand_ref_method(scope)
142 }
143 fn __expand_ref_method(&self, scope: &Scope) -> &T;
144}
145
146impl<T: AsRefExpand + ?Sized> AsRefExpand for &T {
147 fn __expand_ref_method(&self, _: &Scope) -> &Self {
148 self
149 }
150}
151
152impl<T: AsRefExpand + ?Sized> AsRefExpand for &mut T {
153 fn __expand_ref_method(&self, _: &Scope) -> &Self {
154 self
155 }
156}
157
158impl<T: AsRefExpand + ?Sized> AsRefExpand for *const T {
159 fn __expand_ref_method(&self, _: &Scope) -> &Self {
160 self
161 }
162}
163
164impl<T: AsRefExpand + ?Sized> AsRefExpand for *mut T {
165 fn __expand_ref_method(&self, _: &Scope) -> &Self {
166 self
167 }
168}
169
170pub trait AsMutExpand<T: ?Sized = Self> {
173 fn __expand_as_mut_method(&mut self, scope: &Scope) -> &mut T {
174 self.__expand_ref_mut_method(scope)
175 }
176 fn __expand_ref_mut_method(&mut self, scope: &Scope) -> &mut T;
177}
178
179impl<T: AsMutExpand + ?Sized> AsMutExpand for &T {
180 fn __expand_ref_mut_method(&mut self, _: &Scope) -> &mut Self {
181 self
182 }
183}
184
185impl<T: AsMutExpand + ?Sized> AsMutExpand for &mut T {
186 fn __expand_ref_mut_method(&mut self, _: &Scope) -> &mut Self {
187 self
188 }
189}
190
191impl<T: AsMutExpand + ?Sized> AsMutExpand for *const T {
192 fn __expand_ref_mut_method(&mut self, _: &Scope) -> &mut Self {
193 self
194 }
195}
196
197impl<T: AsMutExpand + ?Sized> AsMutExpand for *mut T {
198 fn __expand_ref_mut_method(&mut self, _: &Scope) -> &mut Self {
199 self
200 }
201}
202
203pub trait DerefExpand {
206 type Target;
207
208 fn __expand_deref_method(&self, scope: &Scope) -> Self::Target;
209}
210
211pub fn __expand_deref<T: DerefExpand<Target = T>>(scope: &Scope, value: &T) -> T {
212 value.__expand_deref_method(scope)
213}
214
215pub trait AsDerefExpand {
216 type Target;
217 fn __expand_as_deref_method(&self, scope: &Scope) -> &Self::Target;
218}
219
220pub trait AsDerefMutExpand: AsDerefExpand {
221 fn __expand_as_deref_mut_method(&mut self, scope: &Scope) -> &mut Self::Target;
222}
223
224impl<T> AsDerefExpand for &mut T {
225 type Target = T;
226 fn __expand_as_deref_method(&self, _: &Scope) -> &T {
227 self
228 }
229}
230
231pub trait CubeEnum: Sized {
232 type RuntimeValue: ExpandTypeClone + CubeDebug;
233
234 fn discriminant(&self) -> NativeExpand<i32>;
235
236 fn runtime_value(self) -> Self::RuntimeValue;
239
240 fn discriminant_of_value(&self, variant_name: &'static str) -> i32 {
241 Self::discriminant_of(variant_name)
242 }
243
244 fn discriminant_of(variant_name: &'static str) -> i32;
245}
246
247pub trait Assign<T = Self> {
248 fn __expand_assign_method(&mut self, scope: &Scope, value: T);
250}
251
252pub trait RuntimeAssign<T = <Self as IntoExpand>::Expand>: IntoExpand<Expand: Assign<T>> {
253 fn init_mut(&self, scope: &Scope) -> Self::Expand;
255}
256
257pub fn __expand_assign<T: Assign<T>>(scope: &Scope, target: &mut T, value: T) {
258 target.__expand_assign_method(scope, value);
259}
260
261impl<T: CubePrimitive> Assign for T {
262 fn __expand_assign_method(&mut self, _scope: &Scope, value: Self) {
263 *self = value;
264 }
265}
266
267impl<T: CubePrimitive + IntoExpand<Expand = NativeExpand<T>>> RuntimeAssign for T {
268 fn init_mut(&self, scope: &Scope) -> NativeExpand<T> {
269 init_mut_of_type(scope, T::__expand_as_type(scope)).into()
270 }
271}
272
273impl<T: NativeAssign + NativeCubeType + CanReadValue> Assign for NativeExpand<T> {
274 fn __expand_assign_method(&mut self, scope: &Scope, value: Self) {
275 let value = value.read_value(scope);
276 assign::expand(scope, value.into(), self);
277 }
278}
279
280impl<T: NativeAssign + NativeCubeType + CanReadValue> RuntimeAssign for NativeExpand<T> {
281 fn init_mut(&self, scope: &Scope) -> Self::Expand {
282 T::elem_init_mut(scope, self.expand).into()
283 }
284}
285
286impl<T: Assign> Assign for Option<T> {
287 fn __expand_assign_method(&mut self, scope: &Scope, value: Self) {
288 match (self, value) {
289 (Some(this), Some(other)) => this.__expand_assign_method(scope, other),
290 (None, None) => {}
291 _ => panic!("Can't assign mismatched enum variants"),
292 }
293 }
294}
295
296impl<T: Assign> Assign for Vec<T> {
297 fn __expand_assign_method(&mut self, scope: &Scope, value: Self) {
298 assert!(
299 self.len() == value.len(),
300 "Can't assign mismatched vector lengths"
301 );
302 for (this, other) in self.iter_mut().zip(value) {
303 this.__expand_assign_method(scope, other);
304 }
305 }
306}
307
308pub trait CloneExpand {
309 fn __expand_clone_method(&self, scope: &Scope) -> Self;
310}
311impl<T: Clone> CloneExpand for T {
312 fn __expand_clone_method(&self, _: &Scope) -> Self {
313 self.clone()
314 }
315}
316
317pub trait IntoRuntime:
319 IntoExpand<Expand = <Self as CubeType>::ExpandType> + CubeType + Sized
320{
321 fn runtime(self) -> Self {
322 self
323 }
324
325 fn __expand_runtime_method(self, scope: &Scope) -> Self::ExpandType;
326}
327
328pub trait IntoComptime: Sized {
330 #[allow(clippy::wrong_self_convention)]
331 fn comptime(self) -> Self {
332 self
333 }
334}
335
336impl<T: Sized> IntoComptime for T {}
337
338pub trait IntoMut: Sized {
340 fn into_mut(self, scope: &Scope) -> Self;
342}
343
344impl<T: IntoMut> IntoMut for &T {
345 fn into_mut(self, _: &Scope) -> Self {
346 self
347 }
348}
349
350impl<T: IntoMut> IntoMut for &mut T {
351 fn into_mut(self, _: &Scope) -> Self {
352 self
353 }
354}
355
356impl<T: IntoMut> IntoMut for *const T {
357 fn into_mut(self, _: &Scope) -> Self {
358 self
359 }
360}
361
362impl<T: IntoMut> IntoMut for *mut T {
363 fn into_mut(self, _: &Scope) -> Self {
364 self
365 }
366}
367
368pub fn into_mut_assign<T: RuntimeAssign>(value: T, scope: &Scope) -> T::Expand {
369 let mut out = value.init_mut(scope);
370 out.__expand_assign_method(scope, value.into_expand(scope));
371 out
372}
373
374pub trait CubeDebug {
375 #[allow(unused)]
378 fn set_debug_name(&self, scope: &Scope, name: &'static str) {}
379}
380
381impl<T: CubeDebug + ?Sized> CubeDebug for &T {
382 fn set_debug_name(&self, scope: &Scope, name: &'static str) {
383 T::set_debug_name(self, scope, name);
384 }
385}
386
387impl<T: CubeDebug + ?Sized> CubeDebug for &mut T {
388 fn set_debug_name(&self, scope: &Scope, name: &'static str) {
389 T::set_debug_name(self, scope, name);
390 }
391}
392
393impl<T: CubeDebug + ?Sized> CubeDebug for *const T {
394 fn set_debug_name(&self, scope: &Scope, name: &'static str) {
395 T::set_debug_name(unsafe { &**self }, scope, name);
396 }
397}
398
399impl<T: CubeDebug + ?Sized> CubeDebug for *mut T {
400 fn set_debug_name(&self, scope: &Scope, name: &'static str) {
401 T::set_debug_name(unsafe { &**self }, scope, name);
402 }
403}
404
405impl CubeDebug for i128 {}
406
407pub trait CubeComptime: core::fmt::Debug + core::hash::Hash + Eq + Clone + Copy {}
422impl<T> CubeComptime for T where T: core::fmt::Debug + core::hash::Hash + Eq + Clone + Copy {}
423
424pub trait CompilationArg:
426 Clone + PartialEq + Eq + core::hash::Hash + core::fmt::Debug + Send + Sync + 'static
427{
428 fn dynamic_cast<Arg: CompilationArg>(&self) -> Arg {
435 assert!(size_of::<Arg>() == size_of::<Self>());
438 let this = Box::new(self.clone());
439 unsafe { *Box::from_raw(Box::into_raw(this) as *mut Arg) }
440 }
441}
442
443impl<T: Clone + PartialEq + Eq + core::hash::Hash + core::fmt::Debug + Send + Sync + 'static>
444 CompilationArg for T
445{
446}
447
448#[diagnostic::on_unimplemented(note = "Consider using `#[derive(CubeLaunch)]` on `{Self}`")]
457pub trait LaunchArg: CubeType + 'static {
458 type RuntimeArg<R: Runtime>: Send + Sync;
460 type CompilationArg: CompilationArg;
462
463 fn register<R: Runtime>(
464 arg: Self::RuntimeArg<R>,
465 launcher: &mut KernelLauncher<R>,
466 ) -> Self::CompilationArg;
467
468 fn expand(
470 arg: &Self::CompilationArg,
471 builder: &mut KernelBuilder,
472 ) -> <Self as CubeType>::ExpandType;
473}
474
475macro_rules! impl_launch_arg_ref {
476 ($ty: ty) => {
477 impl<T: LaunchArg + ?Sized + 'static> LaunchArg for $ty {
478 type RuntimeArg<R: Runtime> = T::RuntimeArg<R>;
479 type CompilationArg = T::CompilationArg;
480
481 fn register<R: Runtime>(
482 arg: Self::RuntimeArg<R>,
483 launcher: &mut KernelLauncher<R>,
484 ) -> Self::CompilationArg {
485 T::register(arg, launcher)
486 }
487
488 fn expand(
489 arg: &Self::CompilationArg,
490 builder: &mut KernelBuilder,
491 ) -> <Self as CubeType>::ExpandType {
492 let value = T::expand(arg, builder);
493 builder.scope.create_kernel_ref(value)
494 }
495 }
496 };
497}
498
499impl_launch_arg_ref!(&'static T);
500impl_launch_arg_ref!(&'static mut T);
501impl_launch_arg_ref!(*const T);
502impl_launch_arg_ref!(*mut T);
503
504macro_rules! launch_tuple {
505 ($(($T:ident, $t:ident)),*) => {
506 impl<$($T: LaunchArg),*> LaunchArg for ($($T,)*) {
507 type RuntimeArg<R: Runtime> = ($($T::RuntimeArg<R>,)*);
508 type CompilationArg = ($($T::CompilationArg,)*);
509
510 fn register<R: Runtime>(runtime_arg: Self::RuntimeArg<R>, launcher: &mut KernelLauncher<R>) -> Self::CompilationArg {
511 let ($($t,)*) = runtime_arg;
512 ($($T::register($t, launcher),)*)
513 }
514
515 fn expand(arg: &Self::CompilationArg, builder: &mut KernelBuilder) -> ($(<$T as CubeType>::ExpandType,)*) {
516 let ($($t,)*) = arg;
517 ($($T::expand($t, builder),)*)
518 }
519 }
520 };
521}
522
523all_tuples!(launch_tuple, 1, 12, T, t);
524
525macro_rules! as_ref_tuple {
526 ($(($T:ident, $t:ident)),*) => {
527 impl<$($T: AsRefExpand),*> AsRefExpand for ($($T,)*) {
528 fn __expand_ref_method(&self, _: &Scope) -> &($($T,)*) {
529 self
530 }
531 }
532 };
533}
534
535all_tuples!(as_ref_tuple, 1, 12, T, t);
536
537macro_rules! as_mut_tuple {
538 ($(($T:ident, $t:ident)),*) => {
539 impl<$($T: AsMutExpand),*> AsMutExpand for ($($T,)*) {
540 fn __expand_ref_mut_method(&mut self, _: &Scope) -> &mut ($($T,)*) {
541 self
542 }
543 }
544 };
545}
546
547all_tuples!(as_mut_tuple, 1, 12, T, t);
548
549macro_rules! deref_tuple {
550 ($(($T:ident, $t:ident)),*) => {
551 impl<$($T: DerefExpand),*> DerefExpand for ($($T,)*) {
552 type Target = ($($T::Target,)*);
553
554 fn __expand_deref_method(&self, scope: &Scope) -> Self::Target {
555 let ($($t,)*) = self;
556 ($($t.__expand_deref_method(scope),)*)
557 }
558 }
559 };
560}
561
562all_tuples!(deref_tuple, 1, 12, T, t);
563
564#[derive(new, Clone, Copy, Debug)]
566pub struct NativeExpand<T: ?Sized> {
567 pub expand: ExpandValue,
568 pub(crate) _type: PhantomData<T>,
569}
570
571impl<T: ?Sized> IntoExpand for NativeExpand<T> {
572 type Expand = Self;
573
574 fn into_expand(self, _: &Scope) -> Self::Expand {
575 self
576 }
577}
578
579impl<T: ?Sized> ExpandTypeClone for NativeExpand<T> {
580 fn clone_unchecked(&self) -> Self {
581 NativeExpand {
582 expand: self.expand,
583 _type: PhantomData,
584 }
585 }
586}
587
588impl<T: ?Sized> NativeExpand<T> {
589 pub unsafe fn as_type_ref_unchecked<E: ?Sized>(&self) -> &NativeExpand<E> {
593 unsafe { core::mem::transmute::<&NativeExpand<T>, &NativeExpand<E>>(self) }
594 }
595
596 pub unsafe fn as_type_mut_unchecked<E: ?Sized>(&mut self) -> &mut NativeExpand<E> {
600 unsafe { core::mem::transmute::<&mut NativeExpand<T>, &mut NativeExpand<E>>(self) }
601 }
602}
603
604pub trait ReadValue {
608 fn read_value(&self, scope: &Scope) -> Value;
609}
610
611impl<T: CubePrimitive> ReadValue for NativeExpand<T> {
612 fn read_value(&self, scope: &Scope) -> Value {
613 self.expand.read_value(scope)
614 }
615}
616
617pub trait CanReadValue: CubeType<ExpandType: ReadValue> {}
618impl<T: CubeType<ExpandType: ReadValue>> CanReadValue for T {}
619
620pub trait HasValue {
621 fn value(&self, scope: &Scope) -> Value;
622}
623
624impl<T: ?Sized> HasValue for NativeExpand<T> {
625 fn value(&self, scope: &Scope) -> Value {
626 self.expand.value(scope)
627 }
628}
629
630impl<T: ?Sized> HasValue for &NativeExpand<T> {
631 fn value(&self, scope: &Scope) -> Value {
632 self.expand.value(scope)
633 }
634}
635
636impl<T: ?Sized> HasValue for &mut NativeExpand<T> {
637 fn value(&self, scope: &Scope) -> Value {
638 self.expand.value(scope)
639 }
640}
641
642impl<T: ?Sized> HasValue for *const NativeExpand<T> {
643 fn value(&self, scope: &Scope) -> Value {
644 unsafe { &**self }.value(scope)
645 }
646}
647
648impl<T: ?Sized> HasValue for *mut NativeExpand<T> {
649 fn value(&self, scope: &Scope) -> Value {
650 unsafe { &**self }.value(scope)
651 }
652}
653
654impl<T: ?Sized> AsRefExpand for NativeExpand<T> {
655 fn __expand_ref_method(&self, _: &Scope) -> &Self {
656 self
657 }
658}
659
660#[diagnostic::do_not_recommend]
661impl<T: CubePrimitive> AsMutExpand for NativeExpand<T> {
662 fn __expand_ref_mut_method(&mut self, _scope: &Scope) -> &mut Self {
663 self
664 }
665}
666
667impl<T: CubePrimitive> DerefExpand for NativeExpand<T> {
668 type Target = Self;
669
670 fn __expand_deref_method(&self, scope: &Scope) -> NativeExpand<T> {
671 self.read_value(scope).into()
672 }
673}
674
675impl<T: ?Sized> From<NativeExpand<T>> for ExpandValue {
676 fn from(value: NativeExpand<T>) -> Self {
677 value.expand
678 }
679}
680
681macro_rules! from_const {
682 ($lit:ty) => {
683 impl From<$lit> for NativeExpand<$lit> {
684 fn from(value: $lit) -> Self {
685 let variable: ExpandValue = value.into();
686 variable.into()
687 }
688 }
689 };
690}
691
692from_const!(u8);
693from_const!(u16);
694from_const!(u32);
695from_const!(u64);
696from_const!(usize);
697from_const!(isize);
698from_const!(i64);
699from_const!(i8);
700from_const!(i16);
701from_const!(i32);
702from_const!(f64);
703from_const!(f16);
704from_const!(bf16);
705from_const!(flex32);
706from_const!(tf32);
707from_const!(f32);
708from_const!(e2m1);
709from_const!(e2m1x2);
710from_const!(e2m3);
711from_const!(e3m2);
712from_const!(e4m3);
713from_const!(e5m2);
714from_const!(ue8m0);
715from_const!(bool);
716
717macro_rules! tuple_cube_type {
718 ($($P:ident),*) => {
719 impl<$($P: CubeType),*> CubeType for ($($P,)*) {
720 type ExpandType = ($($P::ExpandType,)*);
721 }
722
723 impl<$($P: IntoExpand),*> IntoExpand for ($($P,)*) {
724 type Expand = ($($P::Expand,)*);
725
726 #[allow(non_snake_case, unused, clippy::unused_unit)]
727 fn into_expand(self, scope: &Scope) -> Self::Expand {
728 let ($($P,)*) = self;
729 ($(
730 $P.into_expand(scope),
731 )*)
732 }
733 }
734
735 impl<$($P: ExpandTypeClone),*> ExpandTypeClone for ($($P,)*) {
736 #[allow(non_snake_case, unused, clippy::unused_unit)]
737 fn clone_unchecked(&self) -> Self {
738 let ($($P,)*) = self;
739 ($(
740 $P.clone_unchecked(),
741 )*)
742 }
743 }
744 }
745}
746macro_rules! tuple_init {
747 ($($P:ident),*) => {
748 impl<$($P: IntoMut),*> IntoMut for ($($P,)*) {
749 #[allow(non_snake_case, unused, clippy::unused_unit)]
750 fn into_mut(self, scope: &Scope) -> Self {
751 let ($($P,)*) = self;
752 ($(
753 $P.into_mut(scope),
754 )*)
755 }
756 }
757 }
758}
759macro_rules! tuple_debug {
760 ($($P:ident),*) => {
761 impl<$($P: CubeDebug),*> CubeDebug for ($($P,)*) {}
762 }
763}
764macro_rules! tuple_runtime {
765 ($($P:ident),*) => {
766 impl<$($P: IntoRuntime),*> IntoRuntime for ($($P,)*) {
767 #[allow(non_snake_case, unused, clippy::unused_unit)]
768 fn __expand_runtime_method(self, scope: &Scope) -> Self::ExpandType {
769 let ($($P,)*) = self;
770 ($(
771 $P.__expand_runtime_method(scope),
772 )*)
773 }
774 }
775 }
776}
777macro_rules! tuple_assign {
778 ($(($n: tt, $P:ident)),*) => {
779 impl<$($P: Assign),*> Assign for ($($P,)*) {
780 #[allow(non_snake_case, unused, clippy::unused_unit)]
781 fn __expand_assign_method(&mut self, scope: &Scope, value: Self) {
782 let ($($P,)*) = self;
783 $(
784 $P.__expand_assign_method(scope, value.$n);
785 )*
786 }
787 }
788
789 impl<$($P: RuntimeAssign),*> RuntimeAssign for ($($P,)*) {
790 #[allow(non_snake_case, unused, clippy::unused_unit)]
791 fn init_mut(&self, scope: &Scope) -> Self::Expand {
792 let ($($P,)*) = self;
793 ($(
794 $P.init_mut(scope),
795 )*)
796 }
797 }
798 }
799}
800
801all_tuples!(tuple_cube_type, 1, 12, P);
802all_tuples!(tuple_debug, 1, 12, P);
803all_tuples!(tuple_init, 1, 12, P);
804all_tuples!(tuple_runtime, 1, 12, P);
805all_tuples_enumerated!(tuple_assign, 1, 12, P);
806
807pub trait NativeAssign: CubeType {
809 fn elem_init_mut(scope: &Scope, elem: ExpandValue) -> ExpandValue {
810 init_mut_of_type(scope, elem.value(scope).get_type(scope.ctx()))
811 }
812}
813
814impl<T: NativeAssign + NativeCubeType + CanReadValue> IntoMut for NativeExpand<T> {
815 fn into_mut(self, scope: &Scope) -> Self {
816 into_mut_assign(self, scope)
817 }
818}
819
820impl<T: ?Sized> CubeDebug for NativeExpand<T> {
821 fn set_debug_name(&self, scope: &Scope, name: &'static str) {
822 let op = self.value(scope).defining_op().unwrap();
823 set_operation_result_name(scope.ctx(), op, 0, Some(ident(name)));
824 }
825}
826
827impl<T: CubePrimitive> NativeExpand<T> {
828 pub fn __expand_vector_size_method(&self, scope: &Scope) -> VectorSize {
830 self.value(scope).vector_size(scope.ctx())
831 }
832}
833
834impl<T: ?Sized> From<ExpandValue> for NativeExpand<T> {
835 fn from(expand: ExpandValue) -> Self {
836 Self {
837 expand,
838 _type: PhantomData,
839 }
840 }
841}
842
843impl<T: ?Sized> From<Value> for NativeExpand<T> {
844 fn from(expand: Value) -> Self {
845 Self {
846 expand: expand.into(),
847 _type: PhantomData,
848 }
849 }
850}
851
852impl<T: Scalar + Into<ConstantValue>> NativeExpand<T> {
853 pub fn from_lit(scope: &Scope, lit: T) -> Self {
855 T::elem_type(scope).constant(lit.into()).into()
856 }
857
858 pub fn constant(&self) -> Option<ConstantValue> {
860 match self.expand {
861 ExpandValue::Constant { value, .. } => Some(value),
862 _ => None,
863 }
864 }
865
866 pub fn __expand_into_lit_unchecked_method(self, _scope: &Scope) -> T {
867 let value = self.constant().unwrap();
868 T::from_const_value(value)
869 }
870}
871
872pub(crate) fn init_mut_of_type(scope: &Scope, mut ty: TypeHandle) -> ExpandValue {
873 let ctx = scope.ctx();
874 if let Some(PointerType { inner, .. }) = ty.deref(ctx).downcast_ref() {
875 ty = *inner;
876 }
877 if ty.is_ptr(ctx) {
878 panic!("tried initializing mut for ptr {}", ty.disp(ctx));
879 }
880 scope.create_local_mut(ty, None).into()
881}
882
883impl<T: IntoMut> IntoMut for Option<T> {
884 fn into_mut(self, scope: &Scope) -> Self {
885 self.map(|o| IntoMut::into_mut(o, scope))
886 }
887}
888
889impl<T: CubeType> CubeType for Vec<T> {
890 type ExpandType = Vec<T::ExpandType>;
891}
892
893impl<T: IntoExpand> IntoExpand for Vec<T> {
894 type Expand = Self;
895
896 fn into_expand(self, _: &Scope) -> Self::Expand {
897 self
898 }
899}
900
901impl<T: ExpandTypeClone> ExpandTypeClone for Vec<T> {
902 fn clone_unchecked(&self) -> Self {
903 self.iter().map(|it| it.clone_unchecked()).collect()
904 }
905}
906
907impl<T: IntoMut> IntoMut for Vec<T> {
908 fn into_mut(self, scope: &Scope) -> Self {
909 self.into_iter().map(|e| e.into_mut(scope)).collect()
910 }
911}
912impl<T: CubeDebug> CubeDebug for Vec<T> {}
913
914impl<T: AsRefExpand> AsRefExpand for Vec<T> {
915 fn __expand_ref_method(&self, _: &Scope) -> &Self {
916 self
917 }
918}
919impl<T: AsMutExpand> AsMutExpand for Vec<T> {
920 fn __expand_ref_mut_method(&mut self, _: &Scope) -> &mut Self {
921 self
922 }
923}
924
925pub(crate) fn __expand_new<C: Numeric, Out: Numeric>(scope: &Scope, val: C) -> NativeExpand<Out> {
927 let input: ConstantValue = val.into();
928 Out::elem_type(scope).constant(input).into()
929}
930
931impl CubeType for () {
932 type ExpandType = ();
933}
934
935impl LaunchArg for () {
936 type RuntimeArg<R: Runtime> = ();
937 type CompilationArg = ();
938
939 fn register<R: Runtime>(_runtime_arg: Self::RuntimeArg<R>, _launcher: &mut KernelLauncher<R>) {
940 }
942
943 fn expand(
944 _: &Self::CompilationArg,
945 _builder: &mut KernelBuilder,
946 ) -> <Self as CubeType>::ExpandType {
947 }
948}
949
950impl Assign for () {
951 fn __expand_assign_method(&mut self, _: &Scope, _: Self) {}
952}
953
954impl RuntimeAssign for () {
955 fn init_mut(&self, _: &Scope) {}
956}
957
958impl IntoRuntime for () {
959 fn __expand_runtime_method(self, _: &Scope) -> Self::ExpandType {
960 self
961 }
962}
963
964impl IntoExpand for () {
965 type Expand = ();
966
967 fn into_expand(self, _: &Scope) -> Self::Expand {
968 self
969 }
970}
971
972impl CubeDebug for () {}
973
974impl ExpandTypeClone for () {
975 fn clone_unchecked(&self) -> Self {
976 *self
977 }
978}
979
980impl IntoMut for () {
981 fn into_mut(self, _: &Scope) -> Self {
982 self
983 }
984}
985
986impl AsRefExpand for () {
987 fn __expand_ref_method(&self, _: &Scope) -> &Self {
988 self
989 }
990}
991impl AsMutExpand for () {
992 fn __expand_ref_mut_method(&mut self, _: &Scope) -> &mut Self {
993 self
994 }
995}
996
997pub trait DefaultExpand: CubeType {
998 fn __expand_default(scope: &Scope) -> Self::ExpandType;
999}
1000
1001impl<T: CubeType + Default + IntoRuntime> DefaultExpand for T {
1002 fn __expand_default(scope: &Scope) -> T::ExpandType {
1003 T::default().__expand_runtime_method(scope)
1004 }
1005}
1006
1007#[derive(Clone, Copy, Debug)]
1008pub struct Const<const N: usize>;
1009
1010pub trait Size: core::fmt::Debug + Clone + Copy + Send + Sync + 'static {
1011 fn __expand_value(scope: &Scope) -> usize;
1012 fn value() -> usize {
1013 unexpanded!()
1014 }
1015 fn try_value_const() -> Option<usize> {
1016 None
1017 }
1018}
1019
1020impl<const VALUE: usize> Size for Const<VALUE> {
1021 fn __expand_value(_scope: &Scope) -> usize {
1022 VALUE
1023 }
1024 fn value() -> usize {
1025 VALUE
1026 }
1027 fn try_value_const() -> Option<usize> {
1028 Some(VALUE)
1029 }
1030}
1031
1032impl<Marker: 'static> Size for DynamicSize<Marker> {
1033 fn __expand_value(scope: &Scope) -> usize {
1034 scope.resolve_size::<Self>().expect("Size to be registered")
1035 }
1036 fn value() -> usize {
1037 unexpanded!()
1038 }
1039}
1040
1041#[macro_export]
1044macro_rules! define_scalar {
1045 ($vis: vis $name: ident) => {
1046 $crate::__private::paste! {
1047 $vis struct [<__ $name>];
1048 $vis type $name = $crate::prelude::DynamicScalar<[<__ $name>]>;
1049 }
1050 };
1051}
1052
1053#[macro_export]
1055macro_rules! define_size {
1056 ($vis: vis $name: ident) => {
1057 $crate::__private::paste! {
1058 $vis struct [<__ $name>];
1059 $vis type $name = $crate::prelude::DynamicSize<[<__ $name>]>;
1060 }
1061 };
1062}