@@ -58,11 +58,24 @@ pair<unsigned, unsigned> compute_lmin_lmax(const WeightedSBGraph& graph, unsigne
5858 return make_pair (LMin, LMax);
5959}
6060
61- CostMatrixImbalance generate_gain_matrix (const WeightedSBGraph& graph, CommunicationCost& cost_matrix, unsigned partition_a_id,
61+ pair<GainObjectImbalance, CostMatrixImbalance> generate_gain_matrix (const WeightedSBGraph& graph, CommunicationCost& cost_matrix, unsigned partition_a_id,
6262 Partition& partition_a, unsigned partition_b_id, Partition& partition_b, unsigned LMin,
6363 unsigned LMax)
6464{
6565 SBG::Util::Internal::TimeProfiler profiler (" generate_gain_matrix" );
66+ const auto & fact = graph.fact ();
67+ // create the max_gain object with a dummy initialization, any gain will be greater than -infinity
68+ GainObjectImbalance max_gain = GainObjectImbalance{
69+ numeric_limits<size_t >::infinity (),
70+ numeric_limits<size_t >::infinity (),
71+ -numeric_limits<size_t >::infinity (),
72+ fact.createSet (),
73+ fact.createSet (),
74+ 0 ,
75+ fact.createSet (),
76+ fact.createSet (),
77+ 0
78+ };
6679 CostMatrixImbalance local_cost_matrix;
6780
6881 for (size_t i = 0 ; i < partition_a.size (); i++) {
@@ -91,12 +104,15 @@ CostMatrixImbalance generate_gain_matrix(const WeightedSBGraph& graph, Communica
91104 auto ic_edges = ic_i_a.cup (ic_j_b);
92105
93106 int gain = ec_edges.cardinal () - ic_edges.cardinal ();
94- auto gain_object = GainObjectImbalance{i, j, gain, ec_i_a, ic_i_a, set_i_a.cardinal (), ec_j_b, ic_j_b, set_j_b.cardinal ()};
95- local_cost_matrix.insert (gain_object);
107+ local_cost_matrix.emplace_back (i, j, gain, ec_i_a, ic_i_a, set_i_a.cardinal (), ec_j_b, ic_j_b, set_j_b.cardinal ());
108+
109+ if (local_cost_matrix.back ().gain > max_gain.gain ) {
110+ max_gain = local_cost_matrix.back ();
111+ }
96112 }
97113 }
98114
99- return local_cost_matrix;
115+ return { max_gain, local_cost_matrix } ;
100116}
101117
102118// Partition a and b (A_c and B_c in the definition) are the remining nodes to be visited, not the actual partitions
@@ -150,7 +166,7 @@ pair<pair<Set, Set>, pair<Set, Set>> update_sets(Partition& partition_a, Partiti
150166 return make_pair (make_pair (node_a, rest_a), make_pair (node_b, rest_b));
151167}
152168
153- void update_diff (CostMatrixImbalance& cost_matrix, Partition& remaining_partition_a, Set& moved_from_partition_a,
169+ GainObjectImbalance update_diff (CostMatrixImbalance& cost_matrix, Partition& remaining_partition_a, Set& moved_from_partition_a,
154170 pair<Set, Set> affected_node_a, Partition& remaining_partition_b, Set& moved_from_partition_b,
155171 pair<Set, Set> affected_node_b, const WeightedSBGraph& graph, const NodeWeight& node_weight,
156172 const GainObjectImbalance& gain_object, unsigned LMin, unsigned LMax)
@@ -159,6 +175,11 @@ void update_diff(CostMatrixImbalance& cost_matrix, Partition& remaining_partitio
159175 logging::sbg_log << affected_node_a.first << " , " << affected_node_a.second << endl;
160176 logging::sbg_log << affected_node_b.first << " , " << affected_node_b.second << endl;
161177
178+ if (cost_matrix.empty ()) {
179+ logging::sbg_log << " Cost matrix is empty, nothing to update." << endl;
180+ return gain_object;
181+ }
182+
162183 const SetAF& set_factory = graph.fact ();
163184
164185 // Firstly, check if indexes need fixing. Three possible causes.
@@ -195,7 +216,7 @@ void update_diff(CostMatrixImbalance& cost_matrix, Partition& remaining_partitio
195216 g.b_idx --;
196217 }
197218
198- new_cost_matrix.insert (g );
219+ new_cost_matrix.push_back ( move (g) );
199220 }
200221 cost_matrix = new_cost_matrix;
201222 }
@@ -204,6 +225,14 @@ void update_diff(CostMatrixImbalance& cost_matrix, Partition& remaining_partitio
204225 auto affected_nodes = affected_node_a.first .cup (affected_node_b.first );
205226 auto discarded_edges = graph.map1 ().preImage (affected_nodes).cup (graph.map2 ().preImage (affected_nodes));
206227 CostMatrixImbalance new_cost_matrix;
228+
229+ if (cost_matrix.empty ()) {
230+ logging::sbg_log << " After updating cost matrix is empty, nothing to update." << endl;
231+ return gain_object;
232+ }
233+
234+ // using a reference to copy the element only once when returning
235+ GainObjectImbalance& max_gain_object = cost_matrix.front ();
207236 for (auto g : cost_matrix) {
208237 bool change = false ;
209238
@@ -242,13 +271,19 @@ void update_diff(CostMatrixImbalance& cost_matrix, Partition& remaining_partitio
242271 g.gain = gain;
243272 }
244273
245- new_cost_matrix.insert (g);
274+ new_cost_matrix.push_back (move (g));
275+
276+ if (new_cost_matrix.back ().gain > max_gain_object.gain ) {
277+ max_gain_object = new_cost_matrix.back ();
278+ }
246279 }
247280 cost_matrix = new_cost_matrix;
248281
249282#if PARTITION_IMBALANCE_DEBUG
250283 logging::sbg_log << remaining_partition_a << " , " << remaining_partition_b << " , " << gain_object << " , " << cost_matrix << endl;
251284#endif
285+
286+ return max_gain_object;
252287}
253288
254289// auto return type we’ll let the compiler deduce what the return type should be from the return statement
@@ -293,7 +328,7 @@ int kl_sbg_imbalance(const WeightedSBGraph& graph, CommunicationCost& cost_matri
293328 Set b_v = set_fact.createSet ();
294329 const auto node_weights = graph.get_node_weights ();
295330
296- CostMatrixImbalance gm = generate_gain_matrix (graph, cost_matrix, partition_a_id, partition_a, partition_b_id, partition_b, LMin, LMax);
331+ auto [g, gm] = generate_gain_matrix (graph, cost_matrix, partition_a_id, partition_a, partition_b_id, partition_b, LMin, LMax);
297332
298333#if PARTITION_IMBALANCE_DEBUG
299334 logging::sbg_log << LMin << " , " << LMax << gm << endl;
@@ -303,13 +338,16 @@ int kl_sbg_imbalance(const WeightedSBGraph& graph, CommunicationCost& cost_matri
303338 logging::sbg_log << " inside the while " << a_c << " , " << b_c << " " ;
304339 logging::sbg_log << get_partition_size (a_c, node_weights, set_fact) << " , " << get_partition_size (b_c, node_weights, set_fact) << endl;
305340 logging::sbg_log << gm << endl;
341+
306342 assert (not gm.empty ());
307- GainObjectImbalance g = max_diff (gm);
343+
308344 logging::sbg_log << g << endl;
345+
309346 pair<Set, Set> a_ = {set_fact.createSet (), set_fact.createSet ()}, b_ = {set_fact.createSet (), set_fact.createSet ()};
310347 tie (a_, b_) = update_sets (a_c, b_c, a_v, b_v, g, graph);
311- update_diff (gm, a_c, a_v, a_, b_c, b_v, b_, graph, node_weights, g, LMin, LMax);
348+ auto new_max_gain = update_diff (gm, a_c, a_v, a_, b_c, b_v, b_, graph, node_weights, g, LMin, LMax);
312349 update_sum (par_sum, g.gain , max_par_sum, max_par_sum_set, a_v, b_v);
350+ g = move (new_max_gain);
313351 }
314352
315353 if (max_par_sum > 0 ) {
0 commit comments