Skip to main content

hurray_core/layout/
csr.rs

1//! CSR (Compressed Sparse Row) layout descriptor.
2//!
3//! Tag `0x07`. Rank MUST be 2. Buffer count = 3 (values + col_indices + row_ptr).
4//! See `docs/spec/layouts/csr.md`.
5
6/// Descriptor for the CSR (Compressed Sparse Row) sparse layout.
7///
8/// CSR is defined **only for rank-2 tensors**. A conforming implementation MUST
9/// reject a CSR descriptor whose tensor rank is not 2 (checked by
10/// [`LayoutDescriptor::validate_against_shape`]).
11///
12/// Three buffers are required:
13///
14/// | Buffer | Contents |
15/// |--------|----------|
16/// | 0 — `values` | Non-zero values in row-major order; `nnz` elements. |
17/// | 1 — `col_indices` | Column index of each non-zero; `nnz` `uint64` elements. |
18/// | 2 — `row_ptr` | Row pointer array; `nrows + 1` `uint64` elements where `nrows = shape[0]`. |
19///
20/// The `byte_offset` field MUST be `0` for CSR tensors.
21///
22/// # Examples
23///
24/// ```
25/// use hurray_core::layout::{CsrLayout, LayoutDescriptor};
26///
27/// let layout = LayoutDescriptor::Csr(CsrLayout::new(5));
28/// assert_eq!(layout.tag(), 0x07);
29/// assert_eq!(layout.buffer_count().map(|n| n.get()), Some(3));
30/// ```
31#[derive(Debug, Clone, PartialEq, Eq, Hash)]
32#[non_exhaustive]
33pub struct CsrLayout {
34    /// Number of stored (non-zero) elements. MAY be 0 for an empty sparse matrix.
35    pub nnz: u64,
36}
37
38impl CsrLayout {
39    /// Creates a new [`CsrLayout`].
40    ///
41    /// # Examples
42    ///
43    /// ```
44    /// use hurray_core::layout::CsrLayout;
45    ///
46    /// let c = CsrLayout::new(5);
47    /// assert_eq!(c.nnz, 5);
48    /// ```
49    pub fn new(nnz: u64) -> Self {
50        Self { nnz }
51    }
52}
53
54#[cfg(test)]
55mod tests {
56    use super::*;
57    use crate::layout::LayoutDescriptor;
58
59    #[test]
60    fn csr_tag_is_0x07() {
61        let layout = LayoutDescriptor::Csr(CsrLayout::new(0));
62        assert_eq!(layout.tag(), 0x07);
63    }
64
65    #[test]
66    fn csr_buffer_count_is_3() {
67        use std::num::NonZeroU8;
68        let layout = LayoutDescriptor::Csr(CsrLayout::new(5));
69        assert_eq!(layout.buffer_count(), Some(NonZeroU8::new(3).unwrap()));
70    }
71}