cubek_tile/algebra/
monoid.rs1use cubecl::prelude::*;
4
5pub trait Carrier:
7 CubePartialOrd
8 + CubeAdd
9 + CubeMul
10 + core::ops::Add<Self, Output = Self>
11 + core::ops::Mul<Self, Output = Self>
12 + Sized
13{
14}
15
16impl<T> Carrier for T where
17 T: CubePartialOrd
18 + CubeAdd
19 + CubeMul
20 + core::ops::Add<Self, Output = Self>
21 + core::ops::Mul<Self, Output = Self>
22{
23}
24
25#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
27pub enum Monoid {
28 Sum,
30 Prod,
32 Max,
34 Min,
36}
37
38#[cube]
39impl Monoid {
40 pub fn identity<E: Numeric>(#[comptime] monoid: Monoid) -> E {
42 match comptime!(monoid) {
43 Monoid::Sum => E::from_int(0),
44 Monoid::Prod => E::from_int(1),
45 Monoid::Max => E::min_value(),
46 Monoid::Min => E::max_value(),
47 }
48 }
49
50 fn combine_of<T: Carrier>(lhs: T, rhs: T, #[comptime] monoid: Monoid) -> T {
52 match comptime!(monoid) {
53 Monoid::Sum => lhs + rhs,
54 Monoid::Prod => lhs * rhs,
55 Monoid::Max => max(lhs, rhs),
56 Monoid::Min => min(lhs, rhs),
57 }
58 }
59
60 pub fn reduce<E: Numeric, N: Size>(
62 v: Vector<E, N>,
63 #[comptime] width: usize,
64 #[comptime] monoid: Monoid,
65 ) -> E {
66 let mut acc = Monoid::identity::<E>(monoid);
67 #[unroll]
68 for j in 0..width {
69 acc = monoid.combine::<E>(acc, v.extract(j));
70 }
71 acc
72 }
73
74 pub fn reduce_array<E: Numeric>(
76 arr: &Array<E>,
77 #[comptime] len: usize,
78 seed: E,
79 #[comptime] monoid: Monoid,
80 ) -> E {
81 let mut acc = seed;
82 #[unroll]
83 for i in 0..len {
84 acc = monoid.combine::<E>(acc, arr[i]);
85 }
86 acc
87 }
88}
89
90impl Monoid {
92 pub fn combine<T: Carrier>(self, lhs: T, rhs: T) -> T {
93 Monoid::combine_of::<T>(lhs, rhs, self)
94 }
95
96 pub fn __expand_combine_method<T: Carrier>(
97 self,
98 scope: &Scope,
99 lhs: T::ExpandType,
100 rhs: T::ExpandType,
101 ) -> T::ExpandType {
102 Monoid::__expand_combine_of::<T>(scope, lhs, rhs, self)
103 }
104}
105
106macro_rules! comptime_only {
108 ($ty:ty) => {
109 impl CubeType for $ty {
110 type ExpandType = Self;
111 }
112
113 impl IntoExpand for $ty {
114 type Expand = Self;
115
116 fn into_expand(self, _scope: &Scope) -> Self {
117 self
118 }
119 }
120
121 impl IntoMut for $ty {
122 fn into_mut(self, _scope: &Scope) -> Self {
123 self
124 }
125 }
126
127 impl ExpandTypeClone for $ty {
128 fn clone_unchecked(&self) -> Self {
129 Clone::clone(self)
130 }
131 }
132
133 impl CubeDebug for $ty {}
134
135 impl AsRefExpand for $ty {
136 fn __expand_ref_method(&self, _scope: &Scope) -> &Self {
137 self
138 }
139 }
140
141 impl AsMutExpand for $ty {
142 fn __expand_ref_mut_method(&mut self, _scope: &Scope) -> &mut Self {
143 self
144 }
145 }
146 };
147}
148
149pub(crate) use comptime_only;
150
151comptime_only!(Monoid);