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