icentral_timing_update/
timing_update_bc_graph.rs

1crate::ix!();
2
3pub struct TimingUpdateConfig {
4
5    /// None means do all sources, not approx
6    ///
7    pub limit_sources: Option<usize>,
8
9    /*algo flag*/
10
11    pub do_brandes:    bool,
12
13    /* brandes time */
14
15    pub num_threads:   usize,
16
17    /// in case the edges are already in the graph
18    ///
19    pub del_edge:      bool,
20
21    pub op:            Operation,
22}
23
24impl Default for TimingUpdateConfig {
25
26    fn default() -> Self {
27        Self {
28            limit_sources: None,
29            do_brandes:    true,
30            num_threads:   1,
31            del_edge:      false,
32            op:            Operation::Insertion,
33        }
34    }
35}
36
37/**
38  | Actual timing details are done here
39  | 
40  */
41pub fn timing_update_bc_graph<GH>(
42    graph:         &mut Graph<GH>,
43    edge_vec:      &mut Vec<Edge>,
44    algo_flag:     &CompType,
45    brandes_time: Option<Duration>,
46    config:       TimingUpdateConfig) 
47-> Result<(),BetweennessCentralityError> 
48{
49    #[cfg(target_feature = "mpi")]
50    {
51        let mut brandes_time:   Duration = brandes_time.unwrap_or(Duration::default());
52
53        let del_edge:          bool = config.del_edge;
54        let do_brandes:        bool = config.do_brandes;
55        let num_threads:      usize = config.num_threads;
56        let op:           Operation = config.op;
57
58        let universe = mpi::initialize().unwrap();
59        let world    = universe.world();
60
61        let rank = world.rank();
62        let size = world.size();
63
64        //let mut status: MPI_Status = zeroed!();;
65
66        let mut tm: Timer = Timer::default();
67
68        let graph_len = graph.len();
69
70        let mut scores = graph.create_scores_vector();
71
72        let mut tm_vec:      Vec<Duration> = vec![];
73        let mut speedup_vec: Vec::<f64> = vec![];
74
75        if do_brandes {
76
77            tm.start();
78
79            // fast_brandes_BC(graph, scores);
80            scores = brandes_bc(graph,None)?;
81
82            tm.stop();
83
84            brandes_time = tm.interval();
85        }
86
87        if rank == 0 {
88
89            graph.print_header();
90
91            debug!("Brandes_tm[{:.2?}]", brandes_time);
92        }
93
94        for i in 0..edge_vec.len() {
95
96            let e: Edge = edge_vec[i];
97
98            if del_edge {
99                graph.remove_edge(&e);
100            }
101
102            tm.start();
103
104            update_bc(
105                &mut scores, 
106                graph, 
107                algo_flag.clone(), 
108                e, 
109                Some(num_threads), 
110                Some(op.clone())
111            );
112
113            tm.stop();
114
115            let e_time = tm.interval();
116
117            tm_vec.push(e_time);
118
119            let e_speedup: f64 = brandes_time.div_duration_f64(e_time);
120
121            speedup_vec.push(e_speedup);
122
123            if rank == 0 {
124
125                debug!(
126                    "e({:.6},{:.6})  tm[{:.2?}]  sup[{:.2}]", 
127                    e.src, 
128                    e.dst, 
129                    e_time, 
130                    e_speedup
131                );
132            }
133
134            if del_edge {
135                graph.insert_edge(&e);
136            }
137
138            // synchronization barrier so no one
139            // starts next edge before others
140            //
141            world.barrier();
142        }
143
144        let tm_stats      = SimpleStats::from(&mut tm_vec);
145        let speedup_stats = SpeedupStats::from(&mut speedup_vec);
146
147        if rank == 0 {
148
149            debug!(
150                "Avg.tm[{:.2?}]  Avg.sup[{:.2?}]", 
151                tm_stats.mean, 
152                speedup_stats.mean
153            );
154        }
155
156        Ok(())
157    }
158
159    Err(BetweennessCentralityError::NoMPI)
160}