cubecl_core/frontend/element/
cube_elem.rs1use core::fmt::Debug;
2
3use crate::{
4 self as cubecl, Assign, IntoRuntime,
5 frontend::{CanReadValue, IntoExpand, RuntimeAssign, ScalarPartialEq},
6 prelude::{Const, CubeDebug, IntoMut, Size},
7 unexpanded,
8};
9use cubecl_ir::EnumSet;
10use cubecl_ir::{ConstantValue, ElemType, ExpandValue, features::TypeUsage, interfaces::TypedExt};
11use cubecl_macros::{comptime_type, cube, intrinsic};
12use cubecl_runtime::client::Client;
13use pliron::r#type::TypeHandle;
14
15use crate::frontend::CubeType;
16use crate::ir::Scope;
17
18use super::{NativeAssign, NativeExpand};
19
20pub trait CubePrimitive:
23 CubeType<ExpandType = NativeExpand<Self>>
24 + NativeAssign
25 + ConstantTyped
26 + CanReadValue
27 + CubeDebug
28 + Send
29 + Sync
30 + 'static
31 + Clone
32 + Copy
33{
34 type Scalar: Scalar;
35 type Size: Size;
36 type WithScalar<S: Scalar>: CubePrimitive;
37
38 fn from_expand_elem(elem: ExpandValue) -> Self::ExpandType {
39 NativeExpand::new(elem)
40 }
41
42 fn from_const_value(value: ConstantValue) -> Self;
43
44 fn into_lit_unchecked(self) -> Self {
45 self
46 }
47
48 fn packing_factor() -> usize {
49 unexpanded!()
50 }
51
52 fn vector_size() -> usize {
53 unexpanded!()
54 }
55
56 fn __expand_packing_factor(scope: &Scope) -> usize {
57 Self::__expand_as_type(scope).packing_factor(scope.ctx())
58 }
59
60 fn __expand_vector_size(scope: &Scope) -> usize {
61 Self::__expand_as_type(scope).vector_size(scope.ctx())
62 }
63}
64
65pub trait ConstantTyped: CubeType<ExpandType = NativeExpand<Self>> + Sized {
68 fn as_type() -> TypeHandle {
70 unexpanded!()
71 }
72
73 fn size() -> usize {
75 size_of::<Self>()
76 }
77
78 fn size_bits() -> usize {
80 Self::size() * 8
81 }
82
83 fn __expand_as_type(scope: &Scope) -> TypeHandle;
84
85 fn __expand_size(scope: &Scope) -> usize {
86 Self::__expand_as_type(scope).size(scope.ctx())
87 }
88
89 fn __expand_size_bits(scope: &Scope) -> usize {
90 Self::__expand_size(scope) * 8
91 }
92}
93
94pub trait ConstRuntimeAssign<T = <Self as IntoExpand>::Expand>: RuntimeAssign<T> {
96 fn const_init_mut(scope: &Scope) -> Self::Expand;
98}
99
100pub trait CubePrimitiveExpand {
101 type Scalar: Clone + IntoMut + CubeDebug + Assign;
102 type WithScalar<S: Scalar>: Clone + IntoMut + CubeDebug + Assign;
103}
104
105impl<T: CubePrimitive> CubePrimitiveExpand for NativeExpand<T> {
106 type Scalar = NativeExpand<T::Scalar>;
107 type WithScalar<S: Scalar> = NativeExpand<T::WithScalar<S>>;
108}
109
110pub trait Scalar:
114 CubePrimitive<Scalar = Self, Size = Const<1>, WithScalar<Self> = Self>
115 + Default
116 + IntoRuntime
117 + Debug
118 + ScalarPartialEq
119 + Into<ExpandValue>
120{
121 fn elem_type(_scope: &Scope) -> ElemType {
122 Self::elem_type_native()
123 }
124 fn elem_type_native() -> ElemType {
125 unexpanded!()
126 }
127
128 fn supported_uses(client: &Client) -> EnumSet<TypeUsage> {
129 let ty = Self::elem_type_native();
130 client.features().type_usage(ty)
131 }
132}
133
134impl CubeDebug for TypeHandle {}
135impl CubeDebug for ElemType {}
136
137#[cube]
138pub fn elem_type_of<E: CubePrimitive>() -> comptime_type!(ElemType) {
139 intrinsic!(|scope| { E::Scalar::elem_type(scope) })
140}