penumbra_sdk_proof_setup/
parallel_utils.rs1pub fn transform<A, B, const N: usize>(data: [A; N], f: impl Fn(A) -> B) -> [B; N] {
2 match data.into_iter().map(f).collect::<Vec<B>>().try_into() {
3 Ok(x) => x,
4 _ => panic!("The size of the iterator should not have changed"),
5 }
6}
7
8#[cfg(not(feature = "parallel"))]
9pub fn transform_parallel<A, B, const N: usize>(data: [A; N], f: impl Fn(A) -> B) -> [B; N] {
10 transform(data, f)
11}
12
13#[cfg(feature = "parallel")]
14pub fn transform_parallel<A: Send, B: Sync + Send, const N: usize>(
15 data: [A; N],
16 f: impl Fn(A) -> B + Sync + Send,
17) -> [B; N] {
18 use rayon::prelude::*;
19 let out: Vec<B> = data.into_par_iter().map(f).collect();
20 match out.try_into() {
22 Ok(x) => x,
23 _ => panic!("The size of the iterator should not have changed"),
24 }
25}
26
27pub fn flatten_results<A, E, const N: usize>(data: [Result<A, E>; N]) -> Result<[A; N], E> {
28 let mut buf = Vec::with_capacity(N);
29 for x in data {
30 buf.push(x?);
31 }
32 match buf.try_into() {
33 Ok(x) => Ok(x),
34 _ => panic!("The size of the iterator should not have changed"),
35 }
36}
37
38#[cfg(not(feature = "parallel"))]
39pub fn zip_map_parallel<A: Send, B: Send, C: Sync + Send>(
40 a: &mut [A],
41 b: &mut [B],
42 f: impl Fn(&A, &B) -> C + Send + Sync,
43) -> Vec<C> {
44 a.iter().zip(b.iter()).map(|(a, b)| f(a, b)).collect()
45}
46
47#[cfg(feature = "parallel")]
48pub fn zip_map_parallel<A: Send, B: Send, C: Sync + Send>(
49 a: &mut [A],
50 b: &mut [B],
51 f: impl Fn(&A, &B) -> C + Send + Sync,
52) -> Vec<C> {
53 use rayon::prelude::*;
54
55 a.into_par_iter()
56 .zip(b.into_par_iter())
57 .map(|(a, b)| f(a, b))
58 .collect()
59}