stwo_gpu/core/pcs/
utils.rs1use core::ops::{Deref, DerefMut};
2
3use itertools::zip_eq;
4use serde::{Deserialize, Serialize};
5use std_shims::{vec, BTreeSet, Vec};
6
7use super::TreeSubspan;
8use crate::core::ColumnVec;
9
10#[derive(Debug, Clone, Serialize, Deserialize)]
12pub struct TreeVec<T>(pub Vec<T>);
13
14impl<T> TreeVec<T> {
15 pub const fn new(vec: Vec<T>) -> TreeVec<T> {
16 TreeVec(vec)
17 }
18 pub fn map<U, F: Fn(T) -> U>(self, f: F) -> TreeVec<U> {
19 TreeVec(self.0.into_iter().map(f).collect())
20 }
21 pub fn zip<U>(self, other: impl Into<TreeVec<U>>) -> TreeVec<(T, U)> {
22 let other = other.into();
23 TreeVec(self.0.into_iter().zip(other.0).collect())
24 }
25 pub fn zip_eq<U>(self, other: impl Into<TreeVec<U>>) -> TreeVec<(T, U)> {
26 let other = other.into();
27 TreeVec(zip_eq(self.0, other.0).collect())
28 }
29 pub fn as_ref(&self) -> TreeVec<&T> {
30 TreeVec(self.iter().collect())
31 }
32 pub fn as_mut(&mut self) -> TreeVec<&mut T> {
33 TreeVec(self.iter_mut().collect())
34 }
35}
36
37impl<'a, T> From<&'a TreeVec<T>> for TreeVec<&'a T> {
39 fn from(val: &'a TreeVec<T>) -> Self {
40 val.as_ref()
41 }
42}
43
44impl<'a, T> From<&'a TreeVec<&'a Vec<T>>> for TreeVec<Vec<&'a T>> {
46 fn from(val: &'a TreeVec<&'a Vec<T>>) -> Self {
47 TreeVec(val.iter().map(|vec| vec.iter().collect()).collect())
48 }
49}
50
51impl<T> Deref for TreeVec<T> {
52 type Target = Vec<T>;
53 fn deref(&self) -> &Self::Target {
54 &self.0
55 }
56}
57
58impl<T> DerefMut for TreeVec<T> {
59 fn deref_mut(&mut self) -> &mut Self::Target {
60 &mut self.0
61 }
62}
63
64impl<T> Default for TreeVec<T> {
65 fn default() -> Self {
66 TreeVec(Vec::new())
67 }
68}
69
70impl<T> TreeVec<ColumnVec<T>> {
71 pub fn map_cols<U, F: FnMut(T) -> U>(self, mut f: F) -> TreeVec<ColumnVec<U>> {
72 TreeVec(
73 self.0
74 .into_iter()
75 .map(|column| column.into_iter().map(&mut f).collect())
76 .collect(),
77 )
78 }
79
80 #[cfg(feature = "parallel")]
81 pub fn par_map_cols<U, F>(self, f: F) -> TreeVec<ColumnVec<U>>
82 where
83 T: Send,
84 U: Send,
85 F: Fn(T) -> U + Sync + Send,
86 {
87 use rayon::iter::{IntoParallelIterator, ParallelIterator};
88 TreeVec(
89 self.0
90 .into_par_iter()
91 .map(|column| column.into_par_iter().map(&f).collect::<Vec<_>>())
92 .collect(),
93 )
94 }
95
96 pub fn zip_cols<U>(
100 self,
101 other: impl Into<TreeVec<ColumnVec<U>>>,
102 ) -> TreeVec<ColumnVec<(T, U)>> {
103 let other = other.into();
104 TreeVec(
105 zip_eq(self.0, other.0)
106 .map(|(column1, column2)| zip_eq(column1, column2).collect())
107 .collect(),
108 )
109 }
110
111 pub fn as_cols_ref(&self) -> TreeVec<ColumnVec<&T>> {
112 TreeVec(self.iter().map(|column| column.iter().collect()).collect())
113 }
114
115 pub fn flatten(self) -> ColumnVec<T> {
118 self.0.into_iter().flatten().collect()
119 }
120
121 pub fn append_cols(&mut self, mut other: TreeVec<ColumnVec<T>>) {
123 let n_trees = self.0.len().max(other.0.len());
124 self.0.resize_with(n_trees, Default::default);
125 for (self_col, other_col) in self.0.iter_mut().zip(other.0.iter_mut()) {
126 self_col.append(other_col);
127 }
128 }
129
130 pub fn concat_cols(
133 trees: impl Iterator<Item = TreeVec<ColumnVec<T>>>,
134 ) -> TreeVec<ColumnVec<T>> {
135 let mut result = TreeVec::default();
136 for tree in trees {
137 result.append_cols(tree);
138 }
139 result
140 }
141
142 pub fn sub_tree(&self, locations: &[TreeSubspan]) -> TreeVec<ColumnVec<&T>> {
148 let tree_indices: BTreeSet<usize> = locations.iter().map(|l| l.tree_index).collect();
149 assert_eq!(tree_indices.len(), locations.len());
150 let max_tree_index = tree_indices.iter().max().unwrap_or(&0);
151 let mut res = TreeVec(vec![Vec::new(); max_tree_index + 1]);
152
153 for &location in locations {
154 let chunk = self.get_chunk(location).unwrap();
156 res[location.tree_index] = chunk;
157 }
158
159 res
160 }
161
162 fn get_chunk(&self, location: TreeSubspan) -> Option<ColumnVec<&T>> {
163 let tree = self.0.get(location.tree_index)?;
164 let chunk = tree.get(location.col_start..location.col_end)?;
165 Some(chunk.iter().collect())
166 }
167}
168
169impl<T> TreeVec<&ColumnVec<T>> {
170 pub fn map_cols<U, F: FnMut(&T) -> U>(self, mut f: F) -> TreeVec<ColumnVec<U>> {
171 TreeVec(
172 self.0
173 .into_iter()
174 .map(|column| column.iter().map(&mut f).collect())
175 .collect(),
176 )
177 }
178}
179
180impl<'a, T> From<&'a TreeVec<ColumnVec<T>>> for TreeVec<ColumnVec<&'a T>> {
181 fn from(val: &'a TreeVec<ColumnVec<T>>) -> Self {
182 val.as_cols_ref()
183 }
184}
185
186impl<T> TreeVec<ColumnVec<Vec<T>>> {
187 pub fn flatten_cols(self) -> Vec<T> {
190 self.0.into_iter().flatten().flatten().collect()
191 }
192}
193
194pub fn prepare_preprocessed_query_positions(
195 query_positions: &[usize],
196 max_log_size: u32,
197 pp_max_log_size: u32,
198) -> Vec<usize> {
199 if pp_max_log_size == 0 {
200 return vec![];
201 };
202 if max_log_size < pp_max_log_size {
203 return query_positions
204 .iter()
205 .map(|pos| (pos >> 1 << (pp_max_log_size - max_log_size + 1)) + (pos & 1))
206 .collect();
207 }
208 query_positions
209 .iter()
210 .map(|pos| (pos >> (max_log_size - pp_max_log_size + 1) << 1) + (pos & 1))
211 .collect()
212}