Skip to content

Commit 2871b75

Browse files
committed
Add greedy strategy
1 parent ae18739 commit 2871b75

2 files changed

Lines changed: 111 additions & 0 deletions

File tree

mt-kahypar/dynamic/dynamic_partitioner.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include "mt-kahypar/dynamic/strategies/hashing.h"
88
#include "mt-kahypar/dynamic/competitors/hermes.h"
99
#include "mt-kahypar/dynamic/competitors/leopard.h"
10+
#include "mt-kahypar/dynamic/strategies/greedy.h"
1011
#include "mt-kahypar/partition/registries/registry.h"
1112

1213
namespace mt_kahypar::dyn {
@@ -63,6 +64,8 @@ namespace mt_kahypar::dyn {
6364
strategy = new Hermes(hypergraph_m, context);
6465
} else if (context.dynamic.strategy == "leopard") {
6566
strategy = new Leopard(hypergraph_m, context);
67+
} else if (context.dynamic.strategy == "greedy") {
68+
strategy = new Greedy(hypergraph_m, context);
6669
} else {
6770
throw std::runtime_error("Unknown dynamic strategy: " + context.dynamic.strategy);
6871
}
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
#pragma once
2+
3+
#include <mt-kahypar/dynamic/dynamic_strategy.h>
4+
5+
#include "mt-kahypar/io/command_line_options.h"
6+
7+
namespace mt_kahypar::dyn {
8+
9+
class Greedy : public DynamicStrategy {
10+
11+
private:
12+
std::vector<PartitionID> partition_assignment;
13+
std::vector<size_t> partition_connectivities;
14+
std::vector<HypernodeWeight> partition_weights;
15+
HypernodeWeight global_partition_weight;
16+
bool first_change = true;
17+
public:
18+
19+
Greedy(ds::MutableHypergraph& hypergraph_m, Context& context)
20+
: DynamicStrategy(hypergraph_m, context) {}
21+
22+
MutablePartitionedHypergraph& init() override {
23+
partitioned_hypergraph_m = partition_hypergraph_km1(hypergraph_m, context);
24+
ASSERT(partitioned_hypergraph_m.checkAllConnectivitySets());
25+
partition_connectivities = std::vector<size_t>(context.partition.k, 0);
26+
partition_weights = std::vector<HypernodeWeight>(context.partition.k, 0);
27+
global_partition_weight = 0;
28+
for (HypernodeID hn = 0; hn < 100; ++hn)
29+
{
30+
partition_assignment.push_back(partitioned_hypergraph_m.partID(hn));
31+
partition_weights[partitioned_hypergraph_m.partID(hn)]++;
32+
global_partition_weight++;
33+
}
34+
return partitioned_hypergraph_m;
35+
}
36+
37+
void partition(Change& change, size_t changes_size) override {
38+
(void) changes_size;
39+
if (first_change) {
40+
first_change = false;
41+
partition_assignment.reserve(changes_size);
42+
}
43+
// ASSERT(metrics::isBalanced(partitioned_hypergraph_m, context));
44+
// ASSERT(partitioned_hypergraph_m.checkAllConnectivitySets());
45+
46+
partition_connectivities = std::vector<size_t>(context.partition.k, 0);
47+
// Removals are not supported in streaming mode
48+
49+
ASSERT(change.removed_nodes.empty());
50+
ASSERT(change.removed_edges.empty());
51+
ASSERT(change.removed_pins.empty());
52+
53+
HypernodeID added_node = change.added_nodes.front();
54+
55+
56+
for (const auto& [node, edge] : change.added_pins)
57+
{
58+
if (node != added_node) {
59+
partition_connectivities[partition_assignment[node]]++;
60+
}
61+
}
62+
63+
PartitionID added_partition = 0;
64+
for (PartitionID p = 0; p < context.partition.k; ++p)
65+
{
66+
if ((partition_connectivities[p] > partition_connectivities[added_partition] && 1 + partition_weights[p] <= ((double)global_partition_weight / context.partition.k) * (1.0 + context.partition.epsilon)) || 1 + partition_weights[added_partition] > ((double)global_partition_weight / context.partition.k) * (1.0 + context.partition.epsilon)) {
67+
added_partition = p;
68+
}
69+
}
70+
partition_assignment.push_back(added_partition);
71+
partition_weights[added_partition]++;
72+
global_partition_weight++;
73+
74+
// compute and print the current imbalance if the nodeid is a multiple of 1000
75+
// if (added_node % 1000 == 0)
76+
// {
77+
// HypernodeWeight max_partition_weight = 0;
78+
// for (PartitionID p = 0; p < context.partition.k; ++p) {
79+
// max_partition_weight = std::max(max_partition_weight, partition_weights[p]);
80+
// }
81+
// double imbalance = (double)max_partition_weight / (double)global_partition_weight;
82+
// std::cout << "Current imbalance after adding node " << added_node << ": " << imbalance << std::endl;
83+
// std::cout << "Global partition weight: " << global_partition_weight << std::endl;
84+
// std::cout << "Partition weights: ";
85+
// for (PartitionID p = 0; p < context.partition.k; ++p)
86+
// {
87+
// std::cout << partition_weights[p] << " ";
88+
// }
89+
//
90+
// }
91+
}
92+
void printAdditionalFinalStats() override {
93+
// write partitioning to context.partition.graph_partition_filename
94+
95+
auto filename = context.partition.graph_partition_filename;
96+
if (filename.empty()) {
97+
throw InvalidInputException("No filename for output partition file specified");
98+
}
99+
std::ofstream out_stream(filename.c_str());
100+
for (const PartitionID p : partition_assignment)
101+
{
102+
out_stream << p << std::endl;
103+
}
104+
out_stream.close();
105+
}
106+
107+
};
108+
}

0 commit comments

Comments
 (0)