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