use core::ops::{Add, Mul};
use num_traits::{One, Zero};
use crate::{Aligned4, Aligned8, Aligned16, Aligned32, Aligned64, Simd};
#[duplicate::duplicate_item(
_mod_ _vec_;
[simd_impls] [Simd];
[impls_a4] [Aligned4];
[impls_a8] [Aligned8];
[impls_a16] [Aligned16];
[impls_a32] [Aligned32];
[impls_a64] [Aligned64];
)]
mod _mod_ {
use super::*;
impl<T, const N: usize> _vec_<T, N>
where
T: Zero + Add<Output = T> + Copy,
{
#[inline(always)]
pub fn reduce_sum(self) -> T {
let mut acc = T::zero();
for x in self.0 {
acc = acc + x;
}
acc
}
#[inline(always)]
pub fn reduce_sum_n(self, n: usize) -> T {
assert!(n <= N, "reduce_sum_n: n = {n} exceeds lane count {N}");
let mut acc = T::zero();
for x in self.0.iter().take(n) {
acc = acc + *x;
}
acc
}
}
impl<T, const N: usize> _vec_<T, N>
where
T: One + Mul<Output = T> + Copy,
{
#[inline(always)]
pub fn reduce_product(self) -> T {
let mut acc = T::one();
for x in self.0 {
acc = acc * x;
}
acc
}
#[inline(always)]
pub fn reduce_product_n(self, n: usize) -> T {
assert!(n <= N, "reduce_product_n: n = {n} exceeds lane count {N}");
let mut acc = T::one();
for x in self.0.iter().take(n) {
acc = acc * *x;
}
acc
}
}
}