honeycomb_benches/
grid_gen.rs1use std::time::{Duration, Instant};
7
8use honeycomb::{
9 core::stm::atomically_with_err,
10 prelude::{CMap2, CMapBuilder, CoordsFloat, DartIdType, GridDescriptor, OrbitPolicy},
11};
12use rand::{
13 SeedableRng,
14 distr::{Bernoulli, Distribution},
15 rngs::SmallRng,
16};
17use rayon::prelude::*;
18
19use crate::cli::{Generate2dGridArgs, Split};
20
21pub fn bench_generate_2d_grid<T: CoordsFloat>(args: Generate2dGridArgs) -> CMap2<T> {
22 let descriptor = GridDescriptor::<2, T>::default()
23 .n_cells([args.nx.get(), args.ny.get()])
24 .len_per_cell([T::from(args.lx).unwrap(), T::from(args.ly).unwrap()])
25 .split_cells(args.split.is_some_and(|s| s == Split::Uniform));
26
27 let mut map = CMapBuilder::from_grid_descriptor(descriptor)
28 .build()
29 .unwrap();
30
31 if args.split.is_some_and(|s| s == Split::Random) {
32 let _ = split_faces_randomly(&mut map, 0.6, 9_817_498_146_784);
35 }
36
37 map
38}
39
40fn split_faces_randomly<T: CoordsFloat>(
41 map: &mut CMap2<T>,
42 p_bernoulli: f64,
43 seed: u64,
44) -> (Duration, Duration) {
45 let mut instant = Instant::now();
47 let faces = map.iter_faces().collect::<Vec<_>>();
48 let n_diag = faces.len();
49 let rng = SmallRng::seed_from_u64(seed);
50 let dist = Bernoulli::new(p_bernoulli).unwrap();
51 let splits: Vec<bool> = dist.sample_iter(rng).take(n_diag).collect();
52 let sample_time = instant.elapsed();
53
54 instant = Instant::now();
56 let nd = map.allocate_used_darts(n_diag * 2);
57 let nd_range = (nd..nd + (n_diag * 2) as DartIdType).collect::<Vec<_>>();
58 faces
59 .into_iter()
60 .zip(nd_range.chunks(2))
61 .zip(splits)
62 .par_bridge()
63 .for_each(|((df, sl), split)| {
64 let square = df as DartIdType;
65 assert_eq!(map.orbit(OrbitPolicy::FaceLinear, df).count(), 4);
66 let (ddown, dright, dup, dleft) = (square, square + 1, square + 2, square + 3);
67
68 let &[dsplit1, dsplit2] = sl else {
69 unreachable!()
70 };
71 let (dbefore1, dbefore2, dafter1, dafter2) = if split {
72 (ddown, dup, dleft, dright)
73 } else {
74 (dright, dleft, ddown, dup)
75 };
76 let _ = map.force_link::<2>(dsplit1, dsplit2);
77
78 while atomically_with_err(|t| {
79 map.unsew::<1>(t, dbefore1)?;
80 map.unsew::<1>(t, dbefore2)?;
81 map.sew::<1>(t, dsplit1, dafter1)?;
82 map.sew::<1>(t, dsplit2, dafter2)?;
83
84 map.sew::<1>(t, dbefore1, dsplit1)?;
85 map.sew::<1>(t, dbefore2, dsplit2)?;
86 Ok(())
87 })
88 .is_err()
89 {}
90 });
91 (sample_time, instant.elapsed())
92}