honeycomb_benches/
shift.rs1use rayon::prelude::*;
19
20use honeycomb::core::stm::{Transaction, TransactionControl};
21use honeycomb::prelude::{
22 CMap2, CMapBuilder, CoordsFloat, DartIdType, Orbit2, OrbitPolicy, Vertex2, VertexIdType,
23 NULL_DART_ID,
24};
25
26use crate::cli::ShiftArgs;
27use crate::utils::hash_file;
28
29pub fn bench_shift<T: CoordsFloat>(args: ShiftArgs) -> CMap2<T> {
30 let mut instant = std::time::Instant::now();
31 let input_map = args.input.to_str().unwrap();
32 let input_hash = hash_file(input_map).unwrap();
33 let map: CMap2<T> = CMapBuilder::from(input_map).build().unwrap();
34 let build_time = instant.elapsed();
35
36 if args.no_conflict {
37 todo!("TODO: require a partitioning algorithm")
38 } else {
39 instant = std::time::Instant::now();
40 let tmp: Vec<(VertexIdType, Vec<VertexIdType>)> = map
42 .iter_vertices()
43 .filter_map(|v| {
44 if Orbit2::new(&map, OrbitPolicy::Vertex, v as DartIdType)
45 .any(|d| map.beta::<2>(d) == NULL_DART_ID)
46 {
47 None
48 } else {
49 Some((
50 v,
51 Orbit2::new(&map, OrbitPolicy::Vertex, v as DartIdType)
52 .map(|d| map.vertex_id(map.beta::<2>(d)))
53 .collect(),
54 ))
55 }
56 })
57 .collect();
58 let n_v = tmp.len();
59 let graph_time = instant.elapsed();
60 let n_threads = std::thread::available_parallelism()
61 .map(|v| v.get())
62 .unwrap_or(1);
63
64 println!("| shift benchmark");
65 println!("|-> input : {input_map} (hash: {input_hash:#0x})");
66 println!("|-> backend : rayon-iter with {n_threads} thread(s)",);
67 println!("|-> # of rounds: {}", args.n_rounds.get());
68 println!("|-+ init time :");
69 println!("| |-> map built in {}ms", build_time.as_millis());
70 println!("| |-> graph built in {}ms", graph_time.as_millis());
71
72 println!(" Round | process_time | throughput(vertex/s) | n_transac_retry");
73 let mut round = 0;
75 let mut process_time;
76 loop {
77 instant = std::time::Instant::now();
78 let n_retry: u32 = tmp
79 .par_iter()
80 .map(|(vid, neigh)| {
81 let mut n = 0;
82 Transaction::with_control(
83 |_| {
84 n += 1;
85 TransactionControl::Retry
86 },
87 |trans| {
88 let mut new_val = Vertex2::default();
89 for v in neigh {
90 let vertex = map.read_vertex(trans, *v)?.unwrap();
91 new_val.0 += vertex.0;
92 new_val.1 += vertex.1;
93 }
94 new_val.0 /= T::from(neigh.len()).unwrap();
95 new_val.1 /= T::from(neigh.len()).unwrap();
96 map.write_vertex(trans, *vid, new_val)
97 },
98 ); n
100 })
101 .sum();
102 process_time = instant.elapsed().as_secs_f64();
103 println!(
104 " {:>5} | {:>12.6e} | {:>20.6e} | {:>15}",
105 round,
106 process_time,
107 n_v as f64 / process_time,
108 n_retry,
109 );
110
111 round += 1;
112 if round >= args.n_rounds.get() {
113 break;
114 }
115 }
116 }
117
118 map
119}