Skip to content

Commit

Permalink
feat: add example coarsener, configure with --c-algorithm=example
Browse files Browse the repository at this point in the history
  • Loading branch information
DanielSeemaier committed Apr 30, 2024
1 parent f0f8204 commit b5c977d
Show file tree
Hide file tree
Showing 5 changed files with 119 additions and 2 deletions.
63 changes: 63 additions & 0 deletions kaminpar-shm/coarsening/example_coarsener.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
#include "kaminpar-shm/coarsening/example_coarsener.h"

#include "kaminpar-shm/coarsening/contraction/cluster_contraction.h"
#include "kaminpar-shm/coarsening/max_cluster_weights.h"
#include "kaminpar-shm/factories.h"
#include "kaminpar-shm/kaminpar.h"

#include "kaminpar-common/assert.h"

namespace kaminpar::shm {
ExampleCoarsener::ExampleCoarsener(const Context &ctx, const PartitionContext &p_ctx)
: _clustering_algorithm(factory::create_clusterer(ctx)),
_c_ctx(ctx.coarsening),
_p_ctx(p_ctx) {}

void ExampleCoarsener::initialize(const Graph *graph) {
_hierarchy.clear();
_input_graph = graph;
}

bool ExampleCoarsener::coarsen() {
const NodeWeight total_node_weight = current().total_node_weight();
const NodeID prev_n = current().n();

// Compute the graph clustering via label propagation
StaticArray<NodeID> clustering(prev_n, static_array::noinit);
_clustering_algorithm->set_max_cluster_weight(
compute_max_cluster_weight<NodeWeight>(_c_ctx, _p_ctx, prev_n, total_node_weight)
);
_clustering_algorithm->compute_clustering(clustering, current(), false);

// Construct the coarse graph by contracting the current graph
std::unique_ptr<CoarseGraph> coarsened =
contract_clustering(current(), std::move(clustering), _c_ctx.contraction);
_hierarchy.push_back(std::move(coarsened));
// Coarse graph: coarsened->get()

// Determine whether the coarsening process should continue
const NodeID next_n = current().n();
const bool converged = (1.0 - 1.0 * next_n / prev_n) <= _c_ctx.convergence_threshold;
return !converged;
}

PartitionedGraph ExampleCoarsener::uncoarsen(PartitionedGraph &&p_graph) {
// Graph partition of the coarse graph that must be projected onto the finer graph:
const BlockID p_graph_k = p_graph.k();
const StaticArray<BlockID> p_graph_partition = p_graph.take_raw_partition();

// Current coarse graph
std::unique_ptr<CoarseGraph> coarsened = std::move(_hierarchy.back());
KASSERT(&coarsened->get() == &p_graph.graph());

// Pop coarse graph from the hierarchy: this destroys the graph wrapped in p_graph, i.e., p_graph
// may no longer be used
_hierarchy.pop_back();
const NodeID next_n = current().n();

StaticArray<BlockID> partition(next_n);
coarsened->project(p_graph_partition, partition);
return {current(), p_graph_k, std::move(partition)};
}
} // namespace kaminpar::shm

46 changes: 46 additions & 0 deletions kaminpar-shm/coarsening/example_coarsener.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#pragma once

#include "kaminpar-shm/coarsening/clusterer.h"
#include "kaminpar-shm/coarsening/coarsener.h"
#include "kaminpar-shm/coarsening/contraction/cluster_contraction.h"
#include "kaminpar-shm/datastructures/graph.h"
#include "kaminpar-shm/datastructures/partitioned_graph.h"
#include "kaminpar-shm/kaminpar.h"

namespace kaminpar::shm {
class ExampleCoarsener : public Coarsener {
public:
ExampleCoarsener(const Context &ctx, const PartitionContext &p_ctx);

ExampleCoarsener(const ExampleCoarsener &) = delete;
ExampleCoarsener &operator=(const ExampleCoarsener) = delete;

ExampleCoarsener(ExampleCoarsener &&) = delete;
ExampleCoarsener &operator=(ExampleCoarsener &&) = delete;

void initialize(const Graph *graph) final;

bool coarsen() final;
PartitionedGraph uncoarsen(PartitionedGraph &&p_graph) final;

[[nodiscard]] const Graph &current() const final {
return _hierarchy.empty() ? *_input_graph : _hierarchy.back()->get();
}

[[nodiscard]] std::size_t level() const final {
return _hierarchy.size();
}

private:
std::unique_ptr<CoarseGraph> pop_hierarchy(PartitionedGraph &&p_graph);

const CoarseningContext &_c_ctx;
const PartitionContext &_p_ctx;

const Graph *_input_graph;
std::vector<std::unique_ptr<CoarseGraph>> _hierarchy;

std::unique_ptr<Clusterer> _clustering_algorithm;
};
} // namespace kaminpar::shm

7 changes: 5 additions & 2 deletions kaminpar-shm/context_io.cc
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ std::unordered_map<std::string, CoarseningAlgorithm> get_coarsening_algorithms()
return {
{"noop", CoarseningAlgorithm::NOOP},
{"clustering", CoarseningAlgorithm::CLUSTERING},
{"example", CoarseningAlgorithm::EXAMPLE},
};
}

Expand All @@ -74,6 +75,8 @@ std::ostream &operator<<(std::ostream &out, const CoarseningAlgorithm algorithm)
return out << "noop";
case CoarseningAlgorithm::CLUSTERING:
return out << "clustering";
case CoarseningAlgorithm::EXAMPLE:
return out << "example";
}

return out << "<invalid>";
Expand Down Expand Up @@ -567,8 +570,8 @@ void print(const Context &ctx, std::ostream &out) {
out << "Execution mode: " << ctx.parallel.num_threads << "\n";
out << "Seed: " << Random::get_seed() << "\n";
out << "Graph: " << ctx.debug.graph_name
<< " [node ordering: " << ctx.node_ordering << "]"
<< " [edge ordering: " << ctx.edge_ordering << "]\n";
<< " [node ordering: " << ctx.node_ordering << "]" << " [edge ordering: " << ctx.edge_ordering
<< "]\n";
print(ctx.partition, out);
cio::print_delimiter("Graph Compression", '-');
print(ctx.compression, out);
Expand Down
4 changes: 4 additions & 0 deletions kaminpar-shm/factories.cc
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

// Coarsening
#include "kaminpar-shm/coarsening/cluster_coarsener.h"
#include "kaminpar-shm/coarsening/example_coarsener.h"
#include "kaminpar-shm/coarsening/noop_coarsener.h"

// Refinement
Expand Down Expand Up @@ -77,6 +78,9 @@ std::unique_ptr<Coarsener> create_coarsener(const Context &ctx, const PartitionC

case CoarseningAlgorithm::CLUSTERING:
return std::make_unique<ClusteringCoarsener>(ctx, p_ctx);

case CoarseningAlgorithm::EXAMPLE:
return std::make_unique<ExampleCoarsener>(ctx, p_ctx);
}

__builtin_unreachable();
Expand Down
1 change: 1 addition & 0 deletions kaminpar-shm/kaminpar.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ enum class EdgeOrdering {
enum class CoarseningAlgorithm {
NOOP,
CLUSTERING,
EXAMPLE,
};

enum class ClusteringAlgorithm {
Expand Down

0 comments on commit b5c977d

Please sign in to comment.