ruprim/reduce/components/instructions/
sum.rs1use ruda_kernel::dsl as kernel_dsl;
2use super::{ReduceFamily, ReduceInstruction, ReduceRequirements};
3use crate::reduce::components::{
4 instructions::{Accumulator, AccumulatorFormat, Item, ReduceStep, Value},
5 precision::ReducePrecision,
6};
7use ruda_kernel::dsl::prelude::*;
8
9#[derive(Debug, RudaType, Clone)]
10pub struct Sum {}
11
12impl ReduceFamily for Sum {
13 type Instruction<P: ReducePrecision> = Self;
14 type Config = ();
15}
16
17#[ruda]
18impl<P: ReducePrecision> ReduceInstruction<P> for Sum {
19 type SharedAccumulator = SharedMemory<Vector<P::EA, P::SI>>;
20 type Config = ();
21
22 fn requirements(_this: &Self) -> ReduceRequirements {
23 ReduceRequirements { coordinates: false }
24 }
25
26 fn accumulator_format(_this: &Self) -> comptime_type!(AccumulatorFormat) {
27 AccumulatorFormat::Single
28 }
29
30 fn from_config(_config: Self::Config) -> Self {
31 Sum {}
32 }
33 fn null_input(_this: &Self) -> Vector<P::EI, P::SI> {
34 Vector::empty().fill(P::EI::from_int(0))
35 }
36
37 fn null_accumulator(_this: &Self) -> Accumulator<P> {
38 Accumulator::<P> {
39 elements: Value::new_single(Vector::empty().fill(P::EA::from_int(0))),
40 args: Value::new_None(),
41 }
42 }
43
44 fn reduce(
45 _this: &Self,
46 accumulator: &mut Accumulator<P>,
47 item: Item<P>,
48 #[comptime] reduce_step: ReduceStep,
49 ) {
50 let accumulator_item = &accumulator.elements.item();
51 let item = item.elements;
52 let elements = match reduce_step {
53 ReduceStep::Plane => *accumulator_item + plane_sum(Vector::cast_from(item)),
54 ReduceStep::Identity => *accumulator_item + Vector::cast_from(item),
55 };
56
57 accumulator.elements.assign(&Value::new_single(elements));
58 }
59
60 fn plane_reduce_inplace(_this: &Self, accumulator: &mut Accumulator<P>) {
61 let sum = plane_sum(Vector::cast_from(accumulator.elements.item()));
62 accumulator.elements.assign(&Value::new_single(sum));
63 }
64
65 fn fuse_accumulators(_this: &Self, accumulator: &mut Accumulator<P>, other: &Accumulator<P>) {
66 let accumulator_item = accumulator.elements.item();
67 let other_item = other.elements.item();
68
69 accumulator
70 .elements
71 .assign(&Value::new_single(accumulator_item + other_item));
72 }
73
74 fn to_output_parallel<Out: Numeric>(
75 _this: &Self,
76 accumulator: Accumulator<P>,
77 _shape_axis_reduce: usize,
78 ) -> Value<Out> {
79 let sum = Vector::vector_sum(accumulator.elements.item());
80
81 Value::new_single(Out::cast_from(sum))
82 }
83
84 fn to_output_perpendicular<Out: Numeric>(
85 _this: &Self,
86 accumulator: Accumulator<P>,
87 _shape_axis_reduce: usize,
88 ) -> Value<Vector<Out, P::SI>> {
89 Value::new_single(Vector::cast_from(accumulator.elements.item()))
90 }
91}