Skip to content

Commit

Permalink
refactor: move to the same interface as in the Shm code
Browse files Browse the repository at this point in the history
  • Loading branch information
DanielSeemaier committed Apr 30, 2024
1 parent b139e10 commit 78a8f37
Show file tree
Hide file tree
Showing 13 changed files with 680 additions and 216 deletions.
44 changes: 44 additions & 0 deletions kaminpar-dist/coarsening/clusterer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*******************************************************************************
* Interface for clustering algorithms.
*
* @file: clusterer.h
* @author: Daniel Seemaier
* @date: 29.09.21
******************************************************************************/
#pragma once

#include "kaminpar-dist/datastructures/distributed_graph.h"
#include "kaminpar-dist/dkaminpar.h"

#include "kaminpar-common/datastructures/static_array.h"

namespace kaminpar::dist {
class Clusterer {
public:
Clusterer() = default;

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

Clusterer(Clusterer &&) noexcept = default;
Clusterer &operator=(Clusterer &&) noexcept = default;

virtual ~Clusterer() = default;

//
// Optional options
//

virtual void set_communities(const StaticArray<BlockID> & /* communities */) {}
virtual void clear_communities() {}

virtual void set_max_cluster_weight(GlobalNodeWeight /* weight */) {}

//
// Clustering function
//

virtual void cluster(StaticArray<GlobalNodeID> &clustering, const DistributedGraph &graph) = 0;
};
} // namespace kaminpar::dist

39 changes: 0 additions & 39 deletions kaminpar-dist/coarsening/clustering/clusterer.h

This file was deleted.

42 changes: 19 additions & 23 deletions kaminpar-dist/coarsening/clustering/lp/global_lp_clusterer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ struct UnorderedRatingMap {
return std::numeric_limits<std::size_t>::max();
}

void resize(const std::size_t /* capacity */) {}
void resize(std::size_t /* capacity */) {}

google::dense_hash_map<GlobalNodeID, EdgeWeight> map{};
};
Expand All @@ -62,17 +62,16 @@ struct GlobalLPClusteringConfig : public LabelPropagationConfig {

class GlobalLPClusteringImpl final
: public ChunkRandomdLabelPropagation<GlobalLPClusteringImpl, GlobalLPClusteringConfig>,
public NonatomicOwnedClusterVector<NodeID, GlobalNodeID> {
public NonatomicClusterVectorRef<NodeID, GlobalNodeID> {
SET_DEBUG(false);

using Base = ChunkRandomdLabelPropagation<GlobalLPClusteringImpl, GlobalLPClusteringConfig>;
using ClusterBase = NonatomicOwnedClusterVector<NodeID, GlobalNodeID>;
using ClusterBase = NonatomicClusterVectorRef<NodeID, GlobalNodeID>;
using WeightDeltaMap = growt::GlobalNodeIDMap<GlobalNodeWeight>;

public:
explicit GlobalLPClusteringImpl(const Context &ctx)
: ClusterBase{ctx.partition.graph->total_n},
_ctx(ctx),
: _ctx(ctx),
_c_ctx(ctx.coarsening),
_changed_label(ctx.partition.graph->n),
_cluster_weights(ctx.partition.graph->total_n - ctx.partition.graph->n),
Expand Down Expand Up @@ -113,15 +112,16 @@ class GlobalLPClusteringImpl final
TIMER_BARRIER(graph.communicator());
}

auto &
compute_clustering(const DistributedGraph &graph, const GlobalNodeWeight max_cluster_weight) {
void set_max_cluster_weight(const GlobalNodeWeight weight) {
_max_cluster_weight = weight;
}

void compute_clustering(StaticArray<GlobalNodeID> &clustering, const DistributedGraph &graph) {
TIMER_BARRIER(graph.communicator());
SCOPED_TIMER("Label propagation");

_max_cluster_weight = max_cluster_weight;

// Ensure that the clustering algorithm was properly initialized
KASSERT(_graph == &graph, "must call initialize() before compute_clustering()", assert::always);
init_clusters_ref(clustering);
initialize(graph);

const int num_chunks = _c_ctx.global_lp.chunks.compute(_ctx.parallel);

Expand All @@ -135,8 +135,6 @@ class GlobalLPClusteringImpl final
break;
}
}

return clusters();
}

void set_max_num_iterations(const int max_num_iterations) {
Expand Down Expand Up @@ -260,7 +258,7 @@ class GlobalLPClusteringImpl final
void move_node(const NodeID lu, const ClusterID gcluster) {
KASSERT(lu < _changed_label.size());
_changed_label[lu] = this->cluster(lu);
NonatomicOwnedClusterVector::move_node(lu, gcluster);
NonatomicClusterVectorRef::move_node(lu, gcluster);

// Detect if a node was moved back to its original cluster
if (_c_ctx.global_lp.prevent_cyclic_moves && gcluster == initial_cluster(lu)) {
Expand Down Expand Up @@ -347,8 +345,6 @@ class GlobalLPClusteringImpl final
}

void allocate(const DistributedGraph &graph) {
ensure_cluster_size(graph.total_n());

const NodeID allocated_num_active_nodes = _changed_label.size();

if (allocated_num_active_nodes < graph.n()) {
Expand Down Expand Up @@ -568,7 +564,7 @@ class GlobalLPClusteringImpl final
weight_delta_handle.find(old_gcluster + 1) == weight_delta_handle.end()) {
change_cluster_weight(old_gcluster, -weight, true);
}
NonatomicOwnedClusterVector::move_node(lnode, new_gcluster);
NonatomicClusterVectorRef::move_node(lnode, new_gcluster);
if (!should_sync_cluster_weights() ||
weight_delta_handle.find(new_gcluster + 1) == weight_delta_handle.end()) {
change_cluster_weight(new_gcluster, weight, false);
Expand Down Expand Up @@ -610,7 +606,7 @@ class GlobalLPClusteringImpl final
if (current != kInvalidNodeID &&
current_weight + u_weight <= max_cluster_weight(u_cluster)) {
change_cluster_weight(current_cluster, u_weight, true);
NonatomicOwnedClusterVector::move_node(u, current_cluster);
NonatomicClusterVectorRef::move_node(u, current_cluster);
current_weight += u_weight;
} else {
current = u;
Expand Down Expand Up @@ -679,13 +675,13 @@ GlobalLPClusterer::GlobalLPClusterer(const Context &ctx)

GlobalLPClusterer::~GlobalLPClusterer() = default;

void GlobalLPClusterer::initialize(const DistributedGraph &graph) {
_impl->initialize(graph);
void GlobalLPClusterer::set_max_cluster_weight(const GlobalNodeWeight weight) {
_impl->set_max_cluster_weight(weight);
}

GlobalLPClusterer::ClusterArray &GlobalLPClusterer::cluster(
const DistributedGraph &graph, const GlobalNodeWeight max_cluster_weight
void GlobalLPClusterer::cluster(
StaticArray<GlobalNodeID> &clustering, const DistributedGraph &graph
) {
return _impl->compute_clustering(graph, max_cluster_weight);
_impl->compute_clustering(clustering, graph);
}
} // namespace kaminpar::dist
8 changes: 4 additions & 4 deletions kaminpar-dist/coarsening/clustering/lp/global_lp_clusterer.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@
******************************************************************************/
#pragma once

#include "kaminpar-dist/coarsening/clustering/clusterer.h"
#include "kaminpar-dist/coarsening/clusterer.h"
#include "kaminpar-dist/context.h"
#include "kaminpar-dist/datastructures/distributed_graph.h"

namespace kaminpar::dist {
class GlobalLPClusterer : public Clusterer<GlobalNodeID> {
class GlobalLPClusterer : public Clusterer {
public:
explicit GlobalLPClusterer(const Context &ctx);

Expand All @@ -24,9 +24,9 @@ class GlobalLPClusterer : public Clusterer<GlobalNodeID> {

~GlobalLPClusterer() override;

void initialize(const DistributedGraph &graph) final;
void set_max_cluster_weight(GlobalNodeWeight weight) final;

ClusterArray &cluster(const DistributedGraph &graph, GlobalNodeWeight max_cluster_weight) final;
void cluster(StaticArray<GlobalNodeID> &clustering, const DistributedGraph &graph) final;

private:
std::unique_ptr<class GlobalLPClusteringImpl> _impl;
Expand Down
59 changes: 31 additions & 28 deletions kaminpar-dist/coarsening/clustering/lp/local_lp_clusterer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -21,20 +21,19 @@ struct LocalLPClusteringConfig : public LabelPropagationConfig {

class LocalLPClusteringImpl final
: public ChunkRandomdLabelPropagation<LocalLPClusteringImpl, LocalLPClusteringConfig>,
public NonatomicOwnedClusterVector<NodeID, NodeID>,
public NonatomicClusterVectorRef<NodeID, NodeID>,
public OwnedRelaxedClusterWeightVector<NodeID, NodeWeight> {
SET_DEBUG(false);

using Base = ChunkRandomdLabelPropagation<LocalLPClusteringImpl, LocalLPClusteringConfig>;
using ClusterBase = NonatomicOwnedClusterVector<NodeID, NodeID>;
using ClusterBase = NonatomicClusterVectorRef<NodeID, NodeID>;
using ClusterWeightBase = OwnedRelaxedClusterWeightVector<NodeID, NodeWeight>;

public:
LocalLPClusteringImpl(const NodeID max_n, const CoarseningContext &c_ctx)
: ClusterBase(max_n),
ClusterWeightBase{max_n},
_ignore_ghost_nodes(c_ctx.local_lp.ignore_ghost_nodes),
: _ignore_ghost_nodes(c_ctx.local_lp.ignore_ghost_nodes),
_keep_ghost_clusters(c_ctx.local_lp.keep_ghost_clusters) {
allocate_cluster_weights(max_n);
allocate(max_n, max_n);
set_max_num_iterations(c_ctx.local_lp.num_iterations);
set_max_degree(c_ctx.local_lp.active_high_degree_threshold);
Expand All @@ -45,9 +44,13 @@ class LocalLPClusteringImpl final
Base::initialize(&graph, graph.n());
}

auto &
compute_clustering(const DistributedGraph &graph, const GlobalNodeWeight max_cluster_weight) {
void set_max_cluster_weight(const GlobalNodeWeight max_cluster_weight) {
_max_cluster_weight = max_cluster_weight;
}

void compute_clustering(StaticArray<NodeID> &clustering, const DistributedGraph &graph) {
init_clusters_ref(clustering);
initialize(graph);

// initialize ghost nodes
if (!_ignore_ghost_nodes) {
Expand Down Expand Up @@ -89,15 +92,6 @@ class LocalLPClusteringImpl final
});
}
}

return clusters();
}

auto &compute_clustering(
const DistributedPartitionedGraph &p_graph, const GlobalNodeWeight max_cluster_weight
) {
_partition = p_graph.partition().data();
return compute_clustering(p_graph.graph(), max_cluster_weight);
}

void set_max_num_iterations(const std::size_t max_num_iterations) {
Expand Down Expand Up @@ -147,7 +141,7 @@ class LocalLPClusteringImpl final
}

using Base::_graph;
NodeWeight _max_cluster_weight;
NodeWeight _max_cluster_weight = std::numeric_limits<NodeWeight>::max();
std::size_t _max_num_iterations;
bool _ignore_ghost_nodes;
bool _keep_ghost_clusters;
Expand All @@ -160,27 +154,36 @@ class LocalLPClusteringImpl final
//

LocalLPClusterer::LocalLPClusterer(const Context &ctx)
: _impl{std::make_unique<LocalLPClusteringImpl>(
: _impl(std::make_unique<LocalLPClusteringImpl>(
ctx.coarsening.local_lp.ignore_ghost_nodes ? ctx.partition.graph->n
: ctx.partition.graph->total_n,
ctx.coarsening
)} {}
)) {}

LocalLPClusterer::~LocalLPClusterer() = default;

void LocalLPClusterer::initialize(const DistributedGraph &graph) {
_impl->initialize(graph);
void LocalLPClusterer::set_communities(const StaticArray<BlockID> &communities) {
_impl->_partition = communities.data();
}

LocalLPClusterer::ClusterArray &LocalLPClusterer::cluster(
const DistributedGraph &graph, const GlobalNodeWeight max_cluster_weight
) {
return _impl->compute_clustering(graph, max_cluster_weight);
void LocalLPClusterer::clear_communities() {
_impl->_partition = nullptr;
}

void LocalLPClusterer::set_max_cluster_weight(GlobalNodeWeight weight) {
_impl->set_max_cluster_weight(weight);
}

LocalLPClusterer::ClusterArray &LocalLPClusterer::cluster(
const DistributedPartitionedGraph &p_graph, const GlobalNodeWeight max_cluster_weight
void LocalLPClusterer::cluster(
StaticArray<GlobalNodeID> &global_clustering, const DistributedGraph &p_graph
) {
return _impl->compute_clustering(p_graph, max_cluster_weight);
static_assert(sizeof(GlobalNodeID) % sizeof(NodeID) == 0, "Size mismatch");
GlobalNodeID *raw_global_clustering = global_clustering.data();
NodeID *raw_local_clustering = reinterpret_cast<NodeID *>(raw_global_clustering);
StaticArray<NodeID> local_clustering(
sizeof(GlobalNodeID) / sizeof(NodeID) * global_clustering.size(), raw_local_clustering
);

return _impl->compute_clustering(local_clustering, p_graph);
}
} // namespace kaminpar::dist
13 changes: 6 additions & 7 deletions kaminpar-dist/coarsening/clustering/lp/local_lp_clusterer.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,12 @@
******************************************************************************/
#pragma once

#include "kaminpar-dist/coarsening/clustering/clusterer.h"
#include "kaminpar-dist/coarsening/clusterer.h"
#include "kaminpar-dist/context.h"
#include "kaminpar-dist/datastructures/distributed_graph.h"
#include "kaminpar-dist/datastructures/distributed_partitioned_graph.h"

namespace kaminpar::dist {
class LocalLPClusterer : public LocalClusterer {
class LocalLPClusterer : public Clusterer {
public:
explicit LocalLPClusterer(const Context &ctx);

Expand All @@ -26,12 +25,12 @@ class LocalLPClusterer : public LocalClusterer {

~LocalLPClusterer() override;

void initialize(const DistributedGraph &graph) final;
void set_communities(const StaticArray<BlockID> &communities) final;
void clear_communities() final;

ClusterArray &cluster(const DistributedGraph &graph, GlobalNodeWeight max_cluster_weight) final;
void set_max_cluster_weight(GlobalNodeWeight weight) final;

ClusterArray &
cluster(const DistributedPartitionedGraph &graph, GlobalNodeWeight max_cluster_weight) final;
void cluster(StaticArray<GlobalNodeID> &clustering, const DistributedGraph &graph) final;

private:
std::unique_ptr<class LocalLPClusteringImpl> _impl;
Expand Down
Loading

0 comments on commit 78a8f37

Please sign in to comment.