Skip to main content

hermes_simd_core/sparse/
view.rs

1//! Format-parameterized sparse matrix views.
2
3use super::{
4    BlockedCoo, BlockedCooData, Csr, CsrData, DenseWithMask, DenseWithMaskData, SellP, SellPData,
5    SparseFormat, SparseShape, Validated, ValidatedData,
6};
7use crate::arch::{assert_arch_executable, SimdArch};
8use core::marker::PhantomData;
9
10/// Format-parameterized sparse matrix view.
11pub struct SparseView<'a, T: 'a, Format, Arch>
12where
13    Format: SparseFormat,
14    Arch: SimdArch,
15{
16    pub(crate) data: Format::Storage<'a, T>,
17    _arch: PhantomData<Arch>,
18    _lifetime: PhantomData<&'a ()>,
19}
20
21impl<'a, T: 'a, Format, Arch> SparseView<'a, T, Format, Arch>
22where
23    Format: SparseFormat,
24    Arch: SimdArch,
25{
26    /// Create a `SparseView` from the format's storage representation.
27    ///
28    /// # Panics
29    /// If `Arch` cannot execute on this host.
30    #[inline(always)]
31    pub fn new(data: Format::Storage<'a, T>) -> Self {
32        assert_arch_executable::<Arch>();
33        Self {
34            data,
35            _arch: PhantomData,
36            _lifetime: PhantomData,
37        }
38    }
39
40    /// Get a reference to the underlying storage representation.
41    #[inline(always)]
42    pub fn storage(&self) -> &Format::Storage<'a, T> {
43        &self.data
44    }
45
46    /// Number of rows in the sparse matrix.
47    #[inline(always)]
48    pub fn nrows(&self) -> usize {
49        self.data.nrows()
50    }
51
52    /// Number of columns in the sparse matrix.
53    #[inline(always)]
54    pub fn ncols(&self) -> usize {
55        self.data.ncols()
56    }
57}
58
59impl<'a, T: 'a, Arch> SparseView<'a, T, Csr, Arch>
60where
61    Arch: SimdArch,
62{
63    /// Create a `SparseView` over CSR data.
64    ///
65    /// # Panics
66    /// If `Arch` cannot execute on this host.
67    #[inline]
68    pub fn from_csr(data: CsrData<'a, T>) -> Self {
69        assert_arch_executable::<Arch>();
70        Self {
71            data,
72            _arch: PhantomData,
73            _lifetime: PhantomData,
74        }
75    }
76
77    /// Access the underlying CSR data.
78    #[inline(always)]
79    pub fn csr_data(&self) -> &CsrData<'a, T> {
80        &self.data
81    }
82}
83
84impl<'a, T: 'a, Arch> SparseView<'a, T, Validated<Csr>, Arch>
85where
86    Arch: SimdArch,
87{
88    /// Validate CSR storage and create a SpMV-ready view.
89    #[inline]
90    pub fn try_from_csr(data: CsrData<'a, T>) -> Result<Self, crate::SimdError> {
91        Ok(Self {
92            data: ValidatedData::new(data)?,
93            _arch: PhantomData,
94            _lifetime: PhantomData,
95        })
96    }
97
98    /// Create a SpMV-ready view from already-validated CSR storage.
99    ///
100    /// # Panics
101    /// If `Arch` cannot execute on this host.
102    #[inline]
103    pub fn from_validated_csr(data: ValidatedData<CsrData<'a, T>>) -> Self {
104        assert_arch_executable::<Arch>();
105        Self {
106            data,
107            _arch: PhantomData,
108            _lifetime: PhantomData,
109        }
110    }
111}
112
113impl<'a, T: 'a, const C: usize, Arch> SparseView<'a, T, SellP<C>, Arch>
114where
115    Arch: SimdArch,
116{
117    /// Create a `SparseView` over SELL-p data (generic C).
118    ///
119    /// # Panics
120    /// If `Arch` cannot execute on this host.
121    #[inline]
122    pub fn from_sellp(data: SellPData<'a, T, C>) -> Self {
123        assert_arch_executable::<Arch>();
124        Self {
125            data,
126            _arch: PhantomData,
127            _lifetime: PhantomData,
128        }
129    }
130}
131
132impl<'a, T: 'a, const C: usize, Arch> SparseView<'a, T, Validated<SellP<C>>, Arch>
133where
134    Arch: SimdArch,
135{
136    /// Validate SELL-p storage and create a SpMV-ready view.
137    #[inline]
138    pub fn try_from_sellp(data: SellPData<'a, T, C>) -> Result<Self, crate::SimdError> {
139        Ok(Self {
140            data: ValidatedData::new(data)?,
141            _arch: PhantomData,
142            _lifetime: PhantomData,
143        })
144    }
145
146    /// Create a SpMV-ready view from already-validated SELL-p storage.
147    ///
148    /// # Panics
149    /// If `Arch` cannot execute on this host.
150    #[inline]
151    pub fn from_validated_sellp(data: ValidatedData<SellPData<'a, T, C>>) -> Self {
152        assert_arch_executable::<Arch>();
153        Self {
154            data,
155            _arch: PhantomData,
156            _lifetime: PhantomData,
157        }
158    }
159}
160
161impl<'a, T: 'a, const BM: usize, const BN: usize, Arch> SparseView<'a, T, BlockedCoo<BM, BN>, Arch>
162where
163    Arch: SimdArch,
164{
165    /// Create a `SparseView` over Blocked-COO data (generic BM, BN).
166    ///
167    /// # Panics
168    /// If `Arch` cannot execute on this host.
169    #[inline]
170    pub fn from_blocked_coo(data: BlockedCooData<'a, T, BM, BN>) -> Self {
171        assert_arch_executable::<Arch>();
172        Self {
173            data,
174            _arch: PhantomData,
175            _lifetime: PhantomData,
176        }
177    }
178}
179
180impl<'a, T: 'a, const BM: usize, const BN: usize, Arch>
181    SparseView<'a, T, Validated<BlockedCoo<BM, BN>>, Arch>
182where
183    Arch: SimdArch,
184{
185    /// Validate Blocked-COO storage and create a SpMV-ready view.
186    #[inline]
187    pub fn try_from_blocked_coo(
188        data: BlockedCooData<'a, T, BM, BN>,
189    ) -> Result<Self, crate::SimdError> {
190        Ok(Self {
191            data: ValidatedData::new(data)?,
192            _arch: PhantomData,
193            _lifetime: PhantomData,
194        })
195    }
196
197    /// Create a SpMV-ready view from already-validated Blocked-COO storage.
198    ///
199    /// # Panics
200    /// If `Arch` cannot execute on this host.
201    #[inline]
202    pub fn from_validated_blocked_coo(data: ValidatedData<BlockedCooData<'a, T, BM, BN>>) -> Self {
203        assert_arch_executable::<Arch>();
204        Self {
205            data,
206            _arch: PhantomData,
207            _lifetime: PhantomData,
208        }
209    }
210}
211
212impl<'a, T: 'a, Arch> SparseView<'a, T, DenseWithMask, Arch>
213where
214    Arch: SimdArch,
215{
216    /// Create a `SparseView` over dense-with-mask data.
217    ///
218    /// # Panics
219    /// If `Arch` cannot execute on this host.
220    #[inline]
221    pub fn from_dense_with_mask(data: DenseWithMaskData<'a, T>) -> Self {
222        assert_arch_executable::<Arch>();
223        Self {
224            data,
225            _arch: PhantomData,
226            _lifetime: PhantomData,
227        }
228    }
229}
230
231/// Extension trait providing generic dimension access for any `SparseView`.
232pub trait SparseViewShape {
233    /// Number of rows.
234    fn nrows(&self) -> usize;
235    /// Number of columns.
236    fn ncols(&self) -> usize;
237}
238
239impl<'a, T: 'a, Format, Arch> SparseViewShape for SparseView<'a, T, Format, Arch>
240where
241    Format: SparseFormat,
242    Arch: SimdArch,
243    Format::Storage<'a, T>: SparseShape,
244{
245    #[inline(always)]
246    fn nrows(&self) -> usize {
247        self.data.nrows()
248    }
249    #[inline(always)]
250    fn ncols(&self) -> usize {
251        self.data.ncols()
252    }
253}
254
255impl<'a, T: 'a, Format, Arch> super::types::SparseValidate for SparseView<'a, T, Format, Arch>
256where
257    Format: SparseFormat,
258    Arch: SimdArch,
259    Format::Storage<'a, T>: super::types::SparseValidate,
260{
261    #[inline]
262    fn validate(&self) -> Result<(), crate::SimdError> {
263        self.data.validate()
264    }
265}