data_beans/
sparse_util.rs1use clap::ValueEnum;
2
3pub struct ValuesIndicesPointers<'a> {
4 pub values: &'a [f32],
5 pub indices: &'a [u64],
6 pub indptr: &'a [u64],
7}
8
9pub struct CooTripletsShape {
10 pub triplets: Vec<(u64, u64, f32)>,
11 pub shape: TripletsShape,
12}
13
14pub struct TripletsShape {
15 pub nrows: usize,
16 pub ncols: usize,
17 pub nnz: usize,
18}
19
20#[derive(ValueEnum, Clone, Copy, Debug, PartialEq)]
21#[clap(rename_all = "lowercase")]
22pub enum IndexPointerType {
23 Column,
24 Row,
25}
26
27pub trait SparseTripletsTraits {
28 fn to_coo(&self, pointer_type: IndexPointerType) -> anyhow::Result<CooTripletsShape>;
30}
31
32impl<'a> SparseTripletsTraits for ValuesIndicesPointers<'a> {
37 fn to_coo(&self, pointer_type: IndexPointerType) -> anyhow::Result<CooTripletsShape> {
38 use rayon::prelude::*;
39
40 let indices = self.indices;
41 let indptr = self.indptr;
42 let values = self.values;
43
44 let nelem = values.len();
45 if nelem != indices.len() {
46 return Err(anyhow::anyhow!(
47 "`values` and `indices` have different sizes"
48 ));
49 }
50 if indptr.is_empty() {
51 return Err(anyhow::anyhow!("`indptr` is empty"));
52 }
53 let nvectors = indptr.len() - 1;
54
55 let triplets: Vec<(u64, u64, f32)> = (0..nvectors)
60 .into_par_iter()
61 .flat_map_iter(|idx| {
62 let j = idx as u64;
63 let start = indptr[idx] as usize;
64 let end = indptr[idx + 1] as usize;
65 let end = end.min(nelem);
66 let start = start.min(end);
67 indices[start..end]
68 .iter()
69 .zip(values[start..end].iter())
70 .map(move |(&i, &x_ij)| match pointer_type {
71 IndexPointerType::Column => (i, j, x_ij),
72 IndexPointerType::Row => (j, i, x_ij),
73 })
74 })
75 .collect();
76
77 let nnz = triplets.len();
78
79 let max_idx_index = indices.par_iter().copied().max().unwrap_or(0) as usize + 1;
82 let (nrows, ncols) = match pointer_type {
83 IndexPointerType::Column => (max_idx_index, nvectors),
84 IndexPointerType::Row => (nvectors, max_idx_index),
85 };
86
87 Ok(CooTripletsShape {
88 triplets,
89 shape: TripletsShape { nrows, ncols, nnz },
90 })
91 }
92}