Skip to main content

hermes_simd_core/
compute.rs

1//! Unified computation view abstraction.
2//!
3//! `ComputeView` is the top-level sealed abstraction over dense SIMD views,
4//! masked views, sparse matrix views, and bitboard views. It provides a
5//! universal `len()` query and a blanket `reduce()` extension for dense views.
6
7use crate::align::Alignment;
8use crate::arch::SimdArch;
9use crate::bitboard::BitBoardView;
10use crate::execution::ExecutionMode;
11use crate::sparse::{SparseFormat, SparseView};
12use crate::view::SimdView;
13
14/// Top-level trait abstracting over dense, masked, sparse, tiled, and bitboard backends.
15///
16/// Sealed via the `SimdArch` bound (which requires `crate::private::Sealed`). All
17/// implementations in this workspace are registered here; external crates cannot
18/// implement `ComputeView` without also implementing `SimdArch` (which is sealed).
19///
20/// # Examples
21///
22/// Query the length of a dense `SimdView` through the `ComputeView` facade:
23///
24/// ```rust
25/// use hermes_simd_core::compute::ComputeView;
26/// use hermes_simd_core::view::SimdView;
27/// use hermes_simd_intrinsics::Scalar;
28/// use hermes_simd_core::align::Unaligned;
29/// use hermes_simd_core::execution::Unmasked;
30///
31/// let data = [1.0_f32; 16];
32/// let view: SimdView<'_, f32, Scalar, Unaligned, Unmasked, &[f32]> =
33///     SimdView::new(&data).unwrap();
34/// assert_eq!(view.len(), 16);
35/// assert!(!view.is_empty());
36/// ```
37pub trait ComputeView {
38    /// Scalar element type of the view (e.g. `f32`, `f64`, `u64`).
39    type Element;
40
41    /// SIMD architecture ZST marker.
42    type Arch: SimdArch;
43
44    /// Backend/format/execution mode selection marker.
45    /// - Dense `SimdView`: `Mode` (e.g. `Unmasked`, `Masked`)
46    /// - `SparseView`: `Format` (e.g. `Csr`, `SellP<4>`)
47    /// - `BitBoardView`: `Backend` (e.g. `KoggeStone`)
48    type Backend;
49
50    /// Returns the logical size of the view.
51    ///
52    /// - `SimdView`: element count
53    /// - `SparseView`: row count (`nrows()`)
54    /// - `BitBoardView`: board element count
55    fn len(&self) -> usize;
56
57    /// Returns `true` if the view contains no elements.
58    #[inline(always)]
59    fn is_empty(&self) -> bool {
60        self.len() == 0
61    }
62}
63
64impl<'a, T, Arch, Align, Mode, Ref> ComputeView for SimdView<'a, T, Arch, Align, Mode, Ref>
65where
66    Arch: SimdArch,
67    Align: Alignment,
68    Mode: ExecutionMode,
69    Ref: 'a,
70{
71    type Element = T;
72    type Arch = Arch;
73    type Backend = Mode;
74
75    #[inline(always)]
76    fn len(&self) -> usize {
77        self.as_slice().len()
78    }
79}
80
81impl<'a, T, Format, Arch> ComputeView for SparseView<'a, T, Format, Arch>
82where
83    Format: SparseFormat,
84    Arch: SimdArch,
85{
86    type Element = T;
87    type Arch = Arch;
88    type Backend = Format;
89
90    #[inline(always)]
91    fn len(&self) -> usize {
92        self.nrows()
93    }
94}
95
96impl<'a, Backend, Arch, Ref> ComputeView for BitBoardView<'a, Backend, Arch, Ref>
97where
98    Arch: SimdArch,
99    Ref: 'a,
100{
101    type Element = u64;
102    type Arch = Arch;
103    type Backend = Backend;
104
105    #[inline(always)]
106    fn len(&self) -> usize {
107        self.as_slice().len()
108    }
109}
110
111// ---------------------------------------------------------------------------
112// ComputeReduce — blanket extension trait for SIMD reduction over ComputeView
113// ---------------------------------------------------------------------------
114
115use crate::ops::ReductionOp;
116use crate::scalar::Scalar;
117
118/// Extension trait that provides `reduce()` over any [`SimdView`]-backed [`ComputeView`].
119///
120/// # Design
121///
122/// `ComputeReduce` is a blanket extension: it is automatically satisfied by any type
123/// that implements `ComputeView` with a `SimdView` backend. It does not add a vtable
124/// entry — the sole method `reduce` is `#[inline(always)]` and monomorphizes to the
125/// same code as calling `view.reduce(op)` directly.
126///
127/// # Examples
128///
129/// ```rust
130/// use hermes_simd_core::compute::{ComputeView, ComputeReduce};
131/// use hermes_simd_core::view::SimdView;
132/// use hermes_simd_core::ops::Sum;
133/// use hermes_simd_intrinsics::Scalar;
134/// use hermes_simd_core::align::Unaligned;
135/// use hermes_simd_core::execution::Unmasked;
136///
137/// let data = [1.0_f32; 8];
138/// let view: SimdView<'_, f32, Scalar, Unaligned, Unmasked, &[f32]> =
139///     SimdView::new(&data).unwrap();
140/// let total: f32 = view.compute_reduce(Sum);
141/// assert!((total - 8.0_f32).abs() < 1e-6);
142/// ```
143pub trait ComputeReduce: ComputeView
144where
145    Self::Arch: crate::kernel::SimdKernel<Self::Element>,
146    Self::Element: Scalar,
147{
148    /// Reduce all elements to a scalar using the given strategy.
149    ///
150    /// Delegates to the `SimdView::reduce` implementation, which uses
151    /// multi-accumulator unrolled SIMD + scalar tail handling.
152    fn compute_reduce<Op: ReductionOp<Self::Element>>(&self, op: Op) -> Self::Element;
153}
154
155impl<'a, T, Arch, Align, Mode, Ref> ComputeReduce for SimdView<'a, T, Arch, Align, Mode, Ref>
156where
157    T: Scalar,
158    Arch: SimdArch + crate::kernel::SimdKernel<T>,
159    Align: Alignment,
160    Mode: ExecutionMode,
161    Ref: 'a,
162{
163    #[inline(always)]
164    fn compute_reduce<Op: ReductionOp<T>>(&self, op: Op) -> T {
165        self.reduce(op)
166    }
167}