Skip to content

Commit

Permalink
refactor(shm-fm): rename DenseGainCache to SparseGainCache
Browse files Browse the repository at this point in the history
  • Loading branch information
DanielSeemaier committed Feb 6, 2024
1 parent 77969d1 commit 49ed629
Show file tree
Hide file tree
Showing 6 changed files with 55 additions and 46 deletions.
4 changes: 2 additions & 2 deletions kaminpar-shm/factories.cc
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
#include "kaminpar-shm/refinement/multi_refiner.h"

// Gain cache strategies for the FM algorithm
#include "kaminpar-shm/refinement/gains/dense_gain_cache.h"
#include "kaminpar-shm/refinement/gains/sparse_gain_cache.h"
#include "kaminpar-shm/refinement/gains/hybrid_gain_cache.h"
#include "kaminpar-shm/refinement/gains/on_the_fly_gain_cache.h"

Expand Down Expand Up @@ -89,7 +89,7 @@ std::unique_ptr<Refiner> create_refiner(const Context &ctx, const RefinementAlgo

case RefinementAlgorithm::KWAY_FM: {
if (ctx.refinement.kway_fm.gain_cache_strategy == GainCacheStrategy::DENSE) {
return std::make_unique<FMRefiner<fm::DefaultDeltaPartitionedGraph, fm::DenseGainCache>>(ctx);
return std::make_unique<FMRefiner<fm::DefaultDeltaPartitionedGraph, fm::SparseGainCache>>(ctx);
} else if (ctx.refinement.kway_fm.gain_cache_strategy == GainCacheStrategy::ON_THE_FLY) {
return std::make_unique<FMRefiner<fm::DefaultDeltaPartitionedGraph, fm::OnTheFlyGainCache>>(
ctx
Expand Down
6 changes: 3 additions & 3 deletions kaminpar-shm/refinement/balancer/greedy_balancer.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
#include "kaminpar-shm/datastructures/graph.h"
#include "kaminpar-shm/datastructures/partitioned_graph.h"
#include "kaminpar-shm/metrics.h"
#include "kaminpar-shm/refinement/gains/dense_gain_cache.h"
#include "kaminpar-shm/refinement/gains/sparse_gain_cache.h"
#include "kaminpar-shm/refinement/refiner.h"

#include "kaminpar-common/datastructures/binary_heap.h"
Expand Down Expand Up @@ -103,7 +103,7 @@ class GreedyBalancer : public Refiner {
void initialize(const PartitionedGraph &p_graph) final;
bool refine(PartitionedGraph &p_graph, const PartitionContext &p_ctx) final;

void track_moves(DenseGainCache<> *gain_cache) {
void track_moves(SparseGainCache<> *gain_cache) {
_gain_cache = gain_cache;
}

Expand Down Expand Up @@ -157,6 +157,6 @@ class GreedyBalancer : public Refiner {

Statistics _stats;

DenseGainCache<> *_gain_cache = nullptr;
SparseGainCache<> *_gain_cache = nullptr;
};
} // namespace kaminpar::shm
9 changes: 3 additions & 6 deletions kaminpar-shm/refinement/fm/fm_refiner.cc
Original file line number Diff line number Diff line change
Expand Up @@ -776,19 +776,16 @@ std::pair<BlockID, EdgeWeight> LocalizedFMRefiner<DeltaPartitionedGraph, GainCac
// Instantiate variants that are actually configurable

namespace fm {
template class SharedData<DenseGainCache>;
template class SharedData<SparseGainCache>;
template class SharedData<HighDegreeGainCache>;
template class SharedData<OnTheFlyGainCache>;
} // namespace fm

// template class FMRefiner<fm::DefaultDeltaPartitionedGraph, fm::DenseGainCache>;
// template class LocalizedFMRefiner<fm::DefaultDeltaPartitionedGraph, fm::DenseGainCache>;

template class FMRefiner<fm::DefaultDeltaPartitionedGraph, fm::OnTheFlyGainCache>;
template class LocalizedFMRefiner<fm::DefaultDeltaPartitionedGraph, fm::OnTheFlyGainCache>;

template class FMRefiner<fm::DefaultDeltaPartitionedGraph, fm::DenseGainCache>;
template class LocalizedFMRefiner<fm::DefaultDeltaPartitionedGraph, fm::DenseGainCache>;
template class FMRefiner<fm::DefaultDeltaPartitionedGraph, fm::SparseGainCache>;
template class LocalizedFMRefiner<fm::DefaultDeltaPartitionedGraph, fm::SparseGainCache>;

template class FMRefiner<fm::DefaultDeltaPartitionedGraph, fm::HighDegreeGainCache>;
template class LocalizedFMRefiner<fm::DefaultDeltaPartitionedGraph, fm::HighDegreeGainCache>;
Expand Down
49 changes: 30 additions & 19 deletions kaminpar-shm/refinement/fm/fm_refiner.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@
#include "kaminpar-shm/datastructures/graph.h"
#include "kaminpar-shm/datastructures/partitioned_graph.h"
#include "kaminpar-shm/refinement/fm/stopping_policies.h"
#include "kaminpar-shm/refinement/gains/dense_gain_cache.h"
#include "kaminpar-shm/refinement/gains/hybrid_gain_cache.h"
#include "kaminpar-shm/refinement/gains/on_the_fly_gain_cache.h"
#include "kaminpar-shm/refinement/gains/sparse_gain_cache.h"
#include "kaminpar-shm/refinement/refiner.h"

#include "kaminpar-common/datastructures/binary_heap.h"
Expand All @@ -27,7 +27,7 @@
namespace kaminpar::shm {
namespace fm {
using DefaultDeltaPartitionedGraph = GenericDeltaPartitionedGraph<>;
using DenseGainCache = DenseGainCache<>;
using SparseGainCache = SparseGainCache<>;
using OnTheFlyGainCache = OnTheFlyGainCache<>;
using HighDegreeGainCache = HybridGainCache<>;

Expand Down Expand Up @@ -88,7 +88,7 @@ class NodeTracker {
);
}

int owner(const NodeID u) const {
[[nodiscard]] int owner(const NodeID u) const {
return __atomic_load_n(&_state[u], __ATOMIC_RELAXED);
}

Expand Down Expand Up @@ -158,7 +158,7 @@ template <typename GainCache> class BorderNodes {
return polled;
}

NodeID get() const {
[[nodiscard]] NodeID get() const {
return has_more() ? _border_nodes[_next_border_node] : kInvalidNodeID;
}

Expand All @@ -182,7 +182,7 @@ template <typename GainCache> class BorderNodes {
tbb::concurrent_vector<NodeID> _border_nodes;
};

template <typename GainCache = fm::DenseGainCache> struct SharedData {
template <typename GainCache = fm::SparseGainCache> struct SharedData {
SharedData(const Context &ctx, const NodeID max_n, const BlockID max_k)
: node_tracker(max_n),
gain_cache(ctx, max_n, max_k),
Expand Down Expand Up @@ -228,11 +228,11 @@ struct AppliedMove {

template <
typename DeltaPartitionedGraph = fm::DefaultDeltaPartitionedGraph,
typename GainCache = fm::DenseGainCache>
typename GainCache = fm::SparseGainCache>
class FMRefiner : public Refiner {
public:
FMRefiner(const Context &ctx);
~FMRefiner(); // Required for the std::unique_ptr<> member.
~FMRefiner() override; // Required for the std::unique_ptr<> member.

FMRefiner(const FMRefiner &) = delete;
FMRefiner &operator=(const FMRefiner &) = delete;
Expand All @@ -249,20 +249,20 @@ class FMRefiner : public Refiner {
using MovesVec = std::vector<fm::AppliedMove>;
using Batches = tbb::concurrent_vector<std::pair<SeedNodesVec, MovesVec>>;

std::vector<fm::BatchStats>
[[nodiscard]] std::vector<fm::BatchStats>
dbg_compute_batch_stats(const PartitionedGraph &graph, Batches next_batches) const;

std::pair<PartitionedGraph, Batches>
[[nodiscard]] std::pair<PartitionedGraph, Batches>
dbg_build_prev_p_graph(const PartitionedGraph &p_graph, Batches next_batches) const;

fm::BatchStats dbg_compute_single_batch_stats_in_sequence(
[[nodiscard]] fm::BatchStats dbg_compute_single_batch_stats_in_sequence(
PartitionedGraph &p_graph,
const std::vector<NodeID> &seeds,
const std::vector<fm::AppliedMove> &moves,
const std::vector<NodeID> &distances
) const;

std::vector<NodeID> dbg_compute_batch_distances(
[[nodiscard]] std::vector<NodeID> dbg_compute_batch_distances(
const Graph &graph,
const std::vector<NodeID> &seeds,
const std::vector<fm::AppliedMove> &moves
Expand All @@ -276,7 +276,7 @@ class FMRefiner : public Refiner {

template <
typename DeltaPartitionedGraph = fm::DefaultDeltaPartitionedGraph,
typename GainCache = fm::DenseGainCache>
typename GainCache = fm::SparseGainCache>
class LocalizedFMRefiner {
public:
LocalizedFMRefiner(
Expand Down Expand Up @@ -313,23 +313,34 @@ class LocalizedFMRefiner {
const PartitionContext &_p_ctx;
const KwayFMRefinementContext &_fm_ctx;

// Graph to work on
// Shared: Graph to work on
PartitionedGraph &_p_graph;

// Data shared among all workers
// Shared: Data shared among all workers
fm::SharedData<GainCache> &_shared;

// Data local to this worker
DeltaPartitionedGraph _d_graph; // O(|Delta|) space
typename GainCache::template DeltaCache<DeltaPartitionedGraph> _d_gain_cache; // O(|Delta|) space
BinaryMaxHeap<EdgeWeight> _block_pq; // O(k) space
std::vector<SharedBinaryMaxHeap<EdgeWeight>> _node_pqs; // O(k + |Touched|) space
// Thread-local: O(|Delta|) space
DeltaPartitionedGraph _d_graph;

// Thread local: O(|Delta|) sparse
using DeltaGainCache = typename GainCache::template DeltaCache<DeltaPartitionedGraph>;
DeltaGainCache _d_gain_cache;

// Thread local: O(k) space
BinaryMaxHeap<EdgeWeight> _block_pq;

// Thread local: O(k + |Touched|) space
std::vector<SharedBinaryMaxHeap<EdgeWeight>> _node_pqs;

AdaptiveStoppingPolicy _stopping_policy;

// Thread local: O(|Touched|) space
std::vector<NodeID> _touched_nodes;

// Thread local: O(1) space
std::vector<NodeID> _seed_nodes;

// Thread local: O(|Touched|) space if move recording is enabled
std::vector<fm::AppliedMove> _applied_moves;
bool _record_applied_moves = false;
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* Gain cache that caches one gain for each node and block, using a total of
* O(|V| * k) memory.
*
* @file: dense_gain_cache.h
* @file: sparse_gain_cache.h
* @author: Daniel Seemaier
* @date: 15.03.2023
******************************************************************************/
Expand All @@ -24,15 +24,15 @@
#include "kaminpar-common/timer.h"

namespace kaminpar::shm {
template <typename DeltaPartitionedGraph, typename GainCache> class DenseDeltaGainCache;
template <typename DeltaPartitionedGraph, typename GainCache> class SparseDeltaGainCache;

template <bool iterate_exact_gains = false> class DenseGainCache {
using Self = DenseGainCache<iterate_exact_gains>;
template <typename, typename> friend class DenseDeltaGainCache;
template <bool iterate_exact_gains = false> class SparseGainCache {
using Self = SparseGainCache<iterate_exact_gains>;
template <typename, typename> friend class SparseDeltaGainCache;

public:
template <typename DeltaPartitionedGraph>
using DeltaCache = DenseDeltaGainCache<DeltaPartitionedGraph, Self>;
using DeltaCache = SparseDeltaGainCache<DeltaPartitionedGraph, Self>;

// gains() will iterate over all blocks, including those not adjacent to the node.
constexpr static bool kIteratesNonadjacentBlocks = true;
Expand All @@ -42,7 +42,7 @@ template <bool iterate_exact_gains = false> class DenseGainCache {
// (more expensive, but safes a call to gain() if the exact gain for the best block is needed).
constexpr static bool kIteratesExactGains = iterate_exact_gains;

DenseGainCache(const Context & /* ctx */, const NodeID max_n, const BlockID max_k)
SparseGainCache(const Context & /* ctx */, const NodeID max_n, const BlockID max_k)
: _max_n(max_n),
_max_k(max_k),
_gain_cache(
Expand Down Expand Up @@ -160,7 +160,8 @@ template <bool iterate_exact_gains = false> class DenseGainCache {
}
}

bool check_cached_gain_for_node(const PartitionedGraph &p_graph, const NodeID u) const {
[[nodiscard]] bool
check_cached_gain_for_node(const PartitionedGraph &p_graph, const NodeID u) const {
const BlockID block_u = p_graph.block(u);
std::vector<EdgeWeight> actual_external_degrees(_k, 0);
EdgeWeight actual_weighted_degree = 0;
Expand Down Expand Up @@ -200,19 +201,19 @@ template <bool iterate_exact_gains = false> class DenseGainCache {
StaticArray<EdgeWeight> _weighted_degrees;
};

template <typename DeltaPartitionedGraph, typename GainCache> class DenseDeltaGainCache {
template <typename DeltaPartitionedGraph, typename GainCache> class SparseDeltaGainCache {
public:
constexpr static bool kIteratesNonadjacentBlocks = GainCache::kIteratesNonadjacentBlocks;
constexpr static bool kIteratesExactGains = GainCache::kIteratesExactGains;

DenseDeltaGainCache(const GainCache &gain_cache, const DeltaPartitionedGraph & /* d_graph */)
SparseDeltaGainCache(const GainCache &gain_cache, const DeltaPartitionedGraph & /* d_graph */)
: _gain_cache(gain_cache) {}

EdgeWeight conn(const NodeID node, const BlockID block) const {
[[nodiscard]] EdgeWeight conn(const NodeID node, const BlockID block) const {
return _gain_cache.conn(node, block) + conn_delta(node, block);
}

EdgeWeight gain(const NodeID node, const BlockID from, const BlockID to) const {
[[nodiscard]] EdgeWeight gain(const NodeID node, const BlockID from, const BlockID to) const {
return _gain_cache.gain(node, from, to) + conn_delta(node, to) - conn_delta(node, from);
}

Expand Down Expand Up @@ -248,7 +249,7 @@ template <typename DeltaPartitionedGraph, typename GainCache> class DenseDeltaGa
}

private:
EdgeWeight conn_delta(const NodeID node, const BlockID block) const {
[[nodiscard]] EdgeWeight conn_delta(const NodeID node, const BlockID block) const {
const auto it = _gain_cache_delta.get_if_contained(_gain_cache.index(node, block));
return it != _gain_cache_delta.end() ? *it : 0;
}
Expand Down
6 changes: 3 additions & 3 deletions kaminpar-shm/refinement/jet/jet_refiner.cc
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
#include "kaminpar-shm/datastructures/partitioned_graph.h"
#include "kaminpar-shm/metrics.h"
#include "kaminpar-shm/refinement/balancer/greedy_balancer.h"
#include "kaminpar-shm/refinement/gains/dense_gain_cache.h"
#include "kaminpar-shm/refinement/gains/sparse_gain_cache.h"

#include "kaminpar-common/datastructures/noinit_vector.h"
#include "kaminpar-common/degree_buckets.h"
Expand All @@ -39,7 +39,7 @@ bool JetRefiner::refine(PartitionedGraph &p_graph, const PartitionContext &p_ctx
SCOPED_TIMER("Jet Refiner");

START_TIMER("Allocation");
DenseGainCache gain_cache(_ctx, p_graph.n(), p_graph.k());
SparseGainCache gain_cache(_ctx, p_graph.n(), p_graph.k());
gain_cache.initialize(p_graph);

NoinitVector<BlockID> next_partition(p_graph.n());
Expand Down Expand Up @@ -165,7 +165,7 @@ bool JetRefiner::refine(PartitionedGraph &p_graph, const PartitionContext &p_ctx
TIMED_SCOPE("Update best partition") {
if (final_cut <= best_cut) {
p_graph.pfor_nodes([&](const NodeID u) { best_partition[u] = p_graph.block(u); });
last_iteration_is_best = true;
last_iteration_is_best = true;
} else {
last_iteration_is_best = false;
}
Expand Down

0 comments on commit 49ed629

Please sign in to comment.