Skip to content

Commit dc09d6d

Browse files
committed
refactor: migrate combination logic to combine.h and combine.cpp
1 parent e44a5dd commit dc09d6d

4 files changed

Lines changed: 90 additions & 134 deletions

File tree

mt-kahypar/partition/evo_partitioner.cpp

Lines changed: 2 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include <tbb/task_arena.h>
66
#include <csignal>
77

8+
#include "evolutionary/combine.h"
89
#include "evolutionary/mutate.h"
910
#include "evolutionary/strategy_picker.h"
1011
#include "mt-kahypar/partition/evolutionary/evo_logs.h"
@@ -600,35 +601,6 @@ namespace mt_kahypar {
600601
return individual;
601602
}
602603

603-
604-
template<typename TypeTraits>
605-
vec<PartitionID> EvoPartitioner<TypeTraits>::combinePartitions(const Context& context, Population& population, const std::vector<size_t>& ids) {
606-
// aquire lock --- possibly unnecessary
607-
std::vector<std::vector<PartitionID>> parent_partitions;
608-
for (auto id : ids) {
609-
parent_partitions.push_back(population.partitionCopySafe(id)); // FIXED
610-
}
611-
612-
vec<PartitionID> combined(parent_partitions[0].size());
613-
std::unordered_map<std::string, int> tuple_to_block;
614-
int current_community = 0;
615-
616-
for (int vertex = 0; vertex < combined.size(); vertex++) {
617-
std::string partition_tuple;
618-
for (size_t i = 0; i < parent_partitions.size(); ++i) {
619-
partition_tuple += std::to_string(parent_partitions[i][vertex]) + ",";
620-
}
621-
622-
if (tuple_to_block.find(partition_tuple) == tuple_to_block.end()) {
623-
tuple_to_block[partition_tuple] = current_community++;
624-
}
625-
626-
combined[vertex] = tuple_to_block[partition_tuple];
627-
}
628-
629-
return combined;
630-
}
631-
632604
template<typename TypeTraits>
633605
bool EvoPartitioner<TypeTraits>::insert_individual_into_population(Individual&& individual, const Context& context, Population& population, int iteration) {
634606
bool improved = false;
@@ -654,59 +626,7 @@ namespace mt_kahypar {
654626
std::mt19937* rng
655627
) {
656628

657-
std::vector<size_t> parents;
658-
size_t best;
659-
if (context.partition.deterministic) {
660-
// use dedicated deterministic method
661-
best = population.randomIndividualSafe(context, rng);
662-
parents.push_back(best);
663-
for (int x = 1; x < context.evolutionary.kway_combine; x++) {
664-
size_t new_parent = population.randomIndividualSafe(context, rng);
665-
parents.push_back(new_parent);
666-
if (population.fitnessAtSafe(new_parent) <= population.fitnessAtSafe(best)) {
667-
best = new_parent;
668-
}
669-
}
670-
}
671-
else {
672-
best = population.randomIndividualSafe(context, rng);
673-
parents.push_back(best);
674-
for (int x = 1; x < context.evolutionary.kway_combine; x++) {
675-
size_t new_parent = population.randomIndividualSafe(context, rng);
676-
parents.push_back(new_parent);
677-
if (population.fitnessAtSafe(new_parent) <= population.fitnessAtSafe(best)) {
678-
best = new_parent;
679-
}
680-
}
681-
}
682-
683-
std::vector<PartitionID> best_partition = population.partitionCopySafe(best);
684-
std::unordered_map<PartitionID, int> comm_to_block;
685-
vec<PartitionID> comms = combinePartitions(context, population, parents);
686-
687-
Hypergraph hypergraph = input_hg.copy(parallel_tag_t{});
688-
PartitionedHypergraph partitioned_hypergraph(context.partition.k, hypergraph);
689-
690-
for (const HypernodeID& hn : hypergraph.nodes()) {
691-
partitioned_hypergraph.setOnlyNodePart(hn, best_partition[hn]);
692-
if (comm_to_block.find(comms[hn]) == comm_to_block.end()) {
693-
comm_to_block[comms[hn]] = best_partition[hn];
694-
}
695-
}
696-
697-
partitioned_hypergraph.initializePartition();
698-
hypergraph.setCommunityIDs(std::move(comms));
699-
700-
if (context.partition.mode == Mode::direct) {
701-
Context vc_context(context);
702-
vc_context.setupPartWeights(hypergraph.totalWeight());
703-
Multilevel<TypeTraits>::evolutionPartitionVCycle(
704-
hypergraph, partitioned_hypergraph, vc_context, comm_to_block, target_graph);
705-
} else {
706-
throw InvalidParameterException("Invalid partitioning mode!");
707-
}
708-
709-
return Individual(partitioned_hypergraph, context);
629+
return combine::usingKWaySelection<TypeTraits>(input_hg, target_graph, population, context, rng);
710630
}
711631

712632
template<typename TypeTraits>

mt-kahypar/partition/evolutionary/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
set(EvolutionarySources
22
action.h
33
combine.h
4+
combine.cpp
45
diversifier.h
56
edge_frequency.h
67
evo_logs.h
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
#include "mt-kahypar/partition/evolutionary/combine.h"
2+
3+
4+
namespace mt_kahypar::combine {
5+
vec<PartitionID> combinePartitions(mt_kahypar::Population& population, const std::vector<size_t>& ids) {
6+
// aquire lock --- possibly unnecessary
7+
std::vector<std::vector<PartitionID>> parent_partitions;
8+
for (auto id : ids) {
9+
parent_partitions.push_back(population.partitionCopySafe(id)); // FIXED
10+
}
11+
12+
vec<PartitionID> combined(parent_partitions[0].size());
13+
std::unordered_map<std::string, int> tuple_to_block;
14+
int current_community = 0;
15+
16+
for (int vertex = 0; vertex < combined.size(); vertex++) {
17+
std::string partition_tuple;
18+
for (size_t i = 0; i < parent_partitions.size(); ++i) {
19+
partition_tuple += std::to_string(parent_partitions[i][vertex]) + ",";
20+
}
21+
22+
if (tuple_to_block.find(partition_tuple) == tuple_to_block.end()) {
23+
tuple_to_block[partition_tuple] = current_community++;
24+
}
25+
26+
combined[vertex] = tuple_to_block[partition_tuple];
27+
}
28+
29+
return combined;
30+
}
31+
32+
}
33+

mt-kahypar/partition/evolutionary/combine.h

Lines changed: 54 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -26,63 +26,65 @@
2626
#include <vector>
2727

2828
#include "mt-kahypar/io/sql_plottools_serializer.h"
29+
#include "mt-kahypar/partition/multilevel.h"
2930
#include "mt-kahypar/partition/evolutionary/edge_frequency.h"
3031
#include "mt-kahypar/partition/evolutionary/population.h"
3132

3233

33-
namespace mt_kahypar {
34-
namespace combine {
35-
static constexpr bool debug = false;
3634

37-
template<typename Hypergraph>
38-
Individual partitions(Hypergraph& hg,
39-
const Parents& parents,
40-
Context& context) {
41-
const HighResClockTimepoint start = std::chrono::high_resolution_clock::now();
42-
DBG << V(context.evolutionary.action.decision());
43-
DBG << "Parent 1: initial" << V(parents.first.fitness());
44-
DBG << "Parent 2: initial" << V(parents.second.fitness());
45-
context.evolutionary.parent1 = &parents.first.partition();
46-
context.evolutionary.parent2 = &parents.second.partition();
47-
#ifndef NDEBUG
48-
ASSERT(parents.first.fitness() == ([](Hypergraph& hg, const Parents& parents) -> int {
49-
hg.setPartition(parents.first.partition());
50-
HyperedgeWeight metric = metrics::km1(hg);
51-
hg.reset();
52-
return metric;
53-
})(hg, parents));
54-
DBG << "initial" << V(metrics::km1(hg)) << V(metrics::imbalance(hg, context));
55-
56-
ASSERT(parents.second.fitness() == ([](Hypergraph& hg, const Parents& parents) -> int {
57-
hg.setPartition(parents.second.partition());
58-
HyperedgeWeight metric = metrics::km1(hg);
59-
hg.reset();
60-
return metric;
61-
})(hg, parents));
62-
63-
#endif
35+
namespace mt_kahypar::combine {
36+
static constexpr bool debug = false;
6437

65-
hg.reset();
66-
const HypernodeID original_contraction_limit_multiplier =
67-
context.coarsening.contraction_limit_multiplier;
68-
if (context.evolutionary.unlimited_coarsening_contraction) {
69-
context.coarsening.contraction_limit_multiplier = 1;
38+
vec<PartitionID> combinePartitions(Population& population, const std::vector<size_t>& ids);
39+
40+
template <typename TypeTraits>
41+
Individual usingKWaySelection(const typename TypeTraits::Hypergraph& input_hg, TargetGraph* target_graph, Population& population, Context context, std::mt19937* rng) {
42+
std::vector<size_t> parents;
43+
//Maybe change to actually use Tournament Selection
44+
size_t best(population.randomIndividualSafe(context, rng));
45+
parents.push_back(best);
46+
for (int x = 1; x < context.evolutionary.kway_combine; x++) {
47+
size_t new_parent = population.randomIndividualSafe(context, rng);
48+
parents.push_back(new_parent);
49+
if (population.fitnessAtSafe(new_parent) <= population.fitnessAtSafe(best)) {
50+
best = new_parent;
51+
}
52+
}
53+
54+
std::vector<PartitionID> best_partition = population.partitionCopySafe(best);
55+
std::unordered_map<PartitionID, int> comm_to_block;
56+
vec<PartitionID> comms = combinePartitions(population, parents);
57+
58+
typename TypeTraits::Hypergraph hypergraph = input_hg.copy(parallel_tag_t{});
59+
typename TypeTraits::PartitionedHypergraph partitioned_hypergraph(context.partition.k, hypergraph);
60+
61+
for (const HypernodeID& hn : hypergraph.nodes()) {
62+
partitioned_hypergraph.setOnlyNodePart(hn, best_partition[hn]);
63+
if (comm_to_block.find(comms[hn]) == comm_to_block.end()) {
64+
comm_to_block[comms[hn]] = best_partition[hn];
65+
}
66+
}
67+
68+
partitioned_hypergraph.initializePartition();
69+
hypergraph.setCommunityIDs(std::move(comms));
70+
71+
if (context.partition.mode == Mode::direct) {
72+
Context vc_context(context);
73+
vc_context.setupPartWeights(hypergraph.totalWeight());
74+
Multilevel<TypeTraits>::evolutionPartitionVCycle(
75+
hypergraph, partitioned_hypergraph, vc_context, comm_to_block, target_graph);
76+
} else {
77+
throw InvalidParameterException("Invalid partitioning mode!");
78+
}
79+
80+
return Individual(partitioned_hypergraph, context);
81+
82+
83+
84+
return Individual(2);
7085
}
7186

72-
Partitioner().partition(hg, context);
73-
74-
const HighResClockTimepoint end = std::chrono::high_resolution_clock::now();
75-
Timer::instance().add(context, Timepoint::evolutionary,
76-
std::chrono::duration<double>(end - start).count());
77-
78-
context.coarsening.contraction_limit_multiplier = original_contraction_limit_multiplier;
79-
DBG << "Offspring" << V(metrics::km1(hg)) << V(metrics::imbalance(hg, context));
80-
ASSERT(metrics::km1(hg) <= std::min(parents.first.fitness(), parents.second.fitness()));
81-
io::serializer::serializeEvolutionary(context, hg);
82-
return Individual(hg, context);
83-
}
84-
85-
template<typename Hypergraph>
87+
/*template<typename Hypergraph>
8688
Individual usingTournamentSelection(Hypergraph& hg, const Context& context, const Population& population) {
8789
Context temporary_context(context);
8890
@@ -128,6 +130,6 @@ Individual edgeFrequency(Hypergraph& hg, const Context& context, const Populatio
128130
DBG << "final result" << V(metrics::km1(hg)) << V(metrics::imbalance(hg, context));
129131
io::serializer::serializeEvolutionary(temporary_context, hg);
130132
return Individual(hg, context);
131-
}
132-
} // namespace combine
133-
} // namespace mt_kahypar
133+
}*/
134+
} // namespace mt_kahypar::combine
135+

0 commit comments

Comments
 (0)