cubecl_tile/algebra/
semiring.rs1use cubecl::prelude::*;
4
5use super::monoid::{Carrier, Monoid};
6use crate::comptime_only;
7
8#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
10pub struct Semiring {
11 add: Monoid,
12 mul: Monoid,
13}
14
15impl Semiring {
16 pub const SUM_PROD: Self = Self {
18 add: Monoid::Sum,
19 mul: Monoid::Prod,
20 };
21 pub const MIN_SUM: Self = Self {
23 add: Monoid::Min,
24 mul: Monoid::Sum,
25 };
26 pub const MAX_SUM: Self = Self {
28 add: Monoid::Max,
29 mul: Monoid::Sum,
30 };
31
32 pub const fn add(self) -> Monoid {
34 self.add
35 }
36
37 pub const fn mul(self) -> Monoid {
39 self.mul
40 }
41}
42
43#[cube]
44impl Semiring {
45 fn step_of<T: Carrier + CubePrimitive>(
49 lhs: T,
50 rhs: T,
51 acc: T,
52 #[comptime] semiring: Semiring,
53 ) -> T {
54 let element = elem_type_of::<T>();
55 if comptime!(semiring == Semiring::SUM_PROD && element.is_float()) {
56 fma(lhs, rhs, acc)
57 } else {
58 let product = semiring.mul().combine::<T>(lhs, rhs);
59 semiring.add().combine::<T>(product, acc)
60 }
61 }
62}
63
64impl Semiring {
66 pub fn step<T: Carrier + CubePrimitive>(self, lhs: T, rhs: T, acc: T) -> T {
67 Semiring::step_of::<T>(lhs, rhs, acc, self)
68 }
69
70 pub fn __expand_step_method<T: Carrier + CubePrimitive>(
71 self,
72 scope: &Scope,
73 lhs: T::ExpandType,
74 rhs: T::ExpandType,
75 acc: T::ExpandType,
76 ) -> T::ExpandType {
77 Semiring::__expand_step_of::<T>(scope, lhs, rhs, acc, self)
78 }
79}
80
81comptime_only!(Semiring);