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::{builtin::given_names::set_operation_result_name, 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 let op = self.value(scope).defining_op().unwrap();
819 set_operation_result_name(scope.ctx(), op, 0, Some(ident(name)));
820 }
821}
822
823impl<T: CubePrimitive> NativeExpand<T> {
824 pub fn __expand_vector_size_method(&self, scope: &Scope) -> VectorSize {
826 self.value(scope).vector_size(scope.ctx())
827 }
828}
829
830impl<T: ?Sized> From<ExpandValue> for NativeExpand<T> {
831 fn from(expand: ExpandValue) -> Self {
832 Self {
833 expand,
834 _type: PhantomData,
835 }
836 }
837}
838
839impl<T: ?Sized> From<Value> for NativeExpand<T> {
840 fn from(expand: Value) -> Self {
841 Self {
842 expand: expand.into(),
843 _type: PhantomData,
844 }
845 }
846}
847
848impl<T: Scalar + Into<ConstantValue>> NativeExpand<T> {
849 pub fn from_lit(scope: &Scope, lit: T) -> Self {
851 T::elem_type(scope).constant(lit.into()).into()
852 }
853
854 pub fn constant(&self) -> Option<ConstantValue> {
856 match self.expand {
857 ExpandValue::Constant { value, .. } => Some(value),
858 _ => None,
859 }
860 }
861
862 pub fn __expand_into_lit_unchecked_method(self, _scope: &Scope) -> T {
863 let value = self.constant().unwrap();
864 T::from_const_value(value)
865 }
866}
867
868pub(crate) fn init_mut_of_type(scope: &Scope, mut ty: TypeHandle) -> ExpandValue {
869 let ctx = scope.ctx();
870 if let Some(PointerType { inner, .. }) = ty.deref(ctx).downcast_ref() {
871 ty = *inner;
872 }
873 if ty.is_ptr(ctx) {
874 panic!("tried initializing mut for ptr {}", ty.disp(ctx));
875 }
876 scope.create_local_mut(ty, None).into()
877}
878
879impl<T: IntoMut> IntoMut for Option<T> {
880 fn into_mut(self, scope: &Scope) -> Self {
881 self.map(|o| IntoMut::into_mut(o, scope))
882 }
883}
884
885impl<T: CubeType> CubeType for Vec<T> {
886 type ExpandType = Vec<T::ExpandType>;
887}
888
889impl<T: IntoExpand> IntoExpand for Vec<T> {
890 type Expand = Self;
891
892 fn into_expand(self, _: &Scope) -> Self::Expand {
893 self
894 }
895}
896
897impl<T: ExpandTypeClone> ExpandTypeClone for Vec<T> {
898 fn clone_unchecked(&self) -> Self {
899 self.iter().map(|it| it.clone_unchecked()).collect()
900 }
901}
902
903impl<T: IntoMut> IntoMut for Vec<T> {
904 fn into_mut(self, scope: &Scope) -> Self {
905 self.into_iter().map(|e| e.into_mut(scope)).collect()
906 }
907}
908impl<T: CubeDebug> CubeDebug for Vec<T> {}
909
910impl<T: AsRefExpand> AsRefExpand for Vec<T> {
911 fn __expand_ref_method(&self, _: &Scope) -> &Self {
912 self
913 }
914}
915impl<T: AsMutExpand> AsMutExpand for Vec<T> {
916 fn __expand_ref_mut_method(&mut self, _: &Scope) -> &mut Self {
917 self
918 }
919}
920
921pub(crate) fn __expand_new<C: Numeric, Out: Numeric>(scope: &Scope, val: C) -> NativeExpand<Out> {
923 let input: ConstantValue = val.into();
924 Out::elem_type(scope).constant(input).into()
925}
926
927impl CubeType for () {
928 type ExpandType = ();
929}
930
931impl LaunchArg for () {
932 type RuntimeArg = ();
933 type CompilationArg = ();
934
935 fn register(_runtime_arg: Self::RuntimeArg, _launcher: &mut KernelLauncher) {
936 }
938
939 fn expand(
940 _: &Self::CompilationArg,
941 _builder: &mut KernelBuilder,
942 ) -> <Self as CubeType>::ExpandType {
943 }
944}
945
946impl Assign for () {
947 fn __expand_assign_method(&mut self, _: &Scope, _: Self) {}
948}
949
950impl RuntimeAssign for () {
951 fn init_mut(&self, _: &Scope) {}
952}
953
954impl IntoRuntime for () {
955 fn __expand_runtime_method(self, _: &Scope) -> Self::ExpandType {
956 self
957 }
958}
959
960impl IntoExpand for () {
961 type Expand = ();
962
963 fn into_expand(self, _: &Scope) -> Self::Expand {
964 self
965 }
966}
967
968impl CubeDebug for () {}
969
970impl ExpandTypeClone for () {
971 fn clone_unchecked(&self) -> Self {
972 *self
973 }
974}
975
976impl IntoMut for () {
977 fn into_mut(self, _: &Scope) -> Self {
978 self
979 }
980}
981
982impl AsRefExpand for () {
983 fn __expand_ref_method(&self, _: &Scope) -> &Self {
984 self
985 }
986}
987impl AsMutExpand for () {
988 fn __expand_ref_mut_method(&mut self, _: &Scope) -> &mut Self {
989 self
990 }
991}
992
993pub trait DefaultExpand: CubeType {
994 fn __expand_default(scope: &Scope) -> Self::ExpandType;
995}
996
997impl<T: CubeType + Default + IntoRuntime> DefaultExpand for T {
998 fn __expand_default(scope: &Scope) -> T::ExpandType {
999 T::default().__expand_runtime_method(scope)
1000 }
1001}
1002
1003#[derive(Clone, Copy, Debug)]
1004pub struct Const<const N: usize>;
1005
1006pub trait Size: core::fmt::Debug + Clone + Copy + Send + Sync + 'static {
1007 fn __expand_value(scope: &Scope) -> usize;
1008 fn value() -> usize {
1009 unexpanded!()
1010 }
1011 fn try_value_const() -> Option<usize> {
1012 None
1013 }
1014}
1015
1016impl<const VALUE: usize> Size for Const<VALUE> {
1017 fn __expand_value(_scope: &Scope) -> usize {
1018 VALUE
1019 }
1020 fn value() -> usize {
1021 VALUE
1022 }
1023 fn try_value_const() -> Option<usize> {
1024 Some(VALUE)
1025 }
1026}
1027
1028impl<Marker: 'static> Size for DynamicSize<Marker> {
1029 fn __expand_value(scope: &Scope) -> usize {
1030 scope.resolve_size::<Self>().expect("Size to be registered")
1031 }
1032 fn value() -> usize {
1033 unexpanded!()
1034 }
1035}
1036
1037#[macro_export]
1040macro_rules! define_scalar {
1041 ($vis: vis $name: ident) => {
1042 $crate::__private::paste! {
1043 $vis struct [<__ $name>];
1044 $vis type $name = $crate::prelude::DynamicScalar<[<__ $name>]>;
1045 }
1046 };
1047}
1048
1049#[macro_export]
1051macro_rules! define_size {
1052 ($vis: vis $name: ident) => {
1053 $crate::__private::paste! {
1054 $vis struct [<__ $name>];
1055 $vis type $name = $crate::prelude::DynamicSize<[<__ $name>]>;
1056 }
1057 };
1058}