Skip to content

Commit

Permalink
refactor sparsification targets
Browse files Browse the repository at this point in the history
  • Loading branch information
Dominik Rosch committed Feb 11, 2025
1 parent 14e9686 commit fc8af15
Show file tree
Hide file tree
Showing 15 changed files with 91 additions and 123 deletions.
3 changes: 2 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,8 @@ endif ()

if (TRUE)
add_subdirectory(external/growt EXCLUDE_FROM_ALL)
add_library(growt INTERFACE)
add_library(growt INTERFACE
tests/shm/coarsening/sparsification/sparisfng_cluster_coarsener_test.cpp)
target_include_directories(growt SYSTEM INTERFACE "external/growt")
endif ()

Expand Down
28 changes: 14 additions & 14 deletions kaminpar-cli/kaminpar_arguments.cc
Original file line number Diff line number Diff line change
Expand Up @@ -149,21 +149,21 @@ CLI::Option_group *create_coarsening_options(CLI::App *app, Context &ctx) {
- forest-fire, ff)")
->capture_default_str();

coarsening->add_option("--s-target", ctx.sparsification.target)
->transform(CLI::CheckedTransformer(get_sparsification_target_selection(), CLI::ignore_case)
.description(""))
->description(
R"(The target of the sparsification in every coarsening Step. The factor c is supplied with --s-factor.
One of the following options:
- density: the density should increase by at most a factor of c
- edge-reduction c: the amount of edges should be reduced by at least a factor of c)"
)
->capture_default_str();
coarsening->add_option("--s-density-factor", ctx.sparsification.density_target_factor)
->default_val(std::numeric_limits<double>::infinity())
->description(R"(By which factor the density should at least be reduced from one level to the next:
new density <= factor * old density
The default is infinity.)"
);

coarsening->add_option("--s-reduction-factor", ctx.sparsification.reduction_target_factor)
->default_val(std::numeric_limits<double>::infinity())
->description(R"(By which factor the number of edges should at least be reduced from one level to the next:
new number of edges <= factor * old number of edges
The default is infinity.)"
);


coarsening->add_option("--s-factor", ctx.sparsification.target_factor)
->check(CLI::PositiveNumber)
->description(R"(The factor c for the sparsification target, supplied with --s-target.)")
->default_val(1);
coarsening->add_flag("--s-no-approx", ctx.sparsification.no_approx)
->description("Disables some approximations of sparsification algorithms.")
->default_val(false);
Expand Down
5 changes: 2 additions & 3 deletions kaminpar-shm/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ add_library(kaminpar_shm ${KAMINPAR_SHM_SOURCE_FILES}
coarsening/sparsifing_cluster_coarsener.h
coarsening/sparsification/networkit_utils.cpp
coarsening/sparsification/networkit_utils.h
coarsening/sparsification/SparsificationTarget.h
coarsening/sparsification/DensitySparsificationTarget.h
coarsening/sparsification/EdgeReductionSparsificationTarget.h
coarsening/sparsification/kNeighbourSampler.cpp
coarsening/sparsification/kNeighbourSampler.h
Expand All @@ -33,7 +31,8 @@ add_library(kaminpar_shm ${KAMINPAR_SHM_SOURCE_FILES}
coarsening/sparsification/UnbiasedThesholdSampler.h
coarsening/sparsification/WeightedForestFireScore.cpp
coarsening/sparsification/WeightedForestFireScore.h
coarsening/sparsification/IndependentRandomSampler.cpp)
coarsening/sparsification/IndependentRandomSampler.cpp
)
target_include_directories(kaminpar_shm PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/../")
target_link_libraries(kaminpar_shm PUBLIC kaminpar_common networkit)
target_compile_options(kaminpar_shm PRIVATE ${KAMINPAR_WARNING_FLAGS})
Expand Down

This file was deleted.

23 changes: 0 additions & 23 deletions kaminpar-shm/coarsening/sparsification/SparsificationTarget.h

This file was deleted.

4 changes: 2 additions & 2 deletions kaminpar-shm/coarsening/sparsification/ThresholdSampler.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,9 @@ template <typename Score> class ThresholdSampler : public ScoreBacedSampler<Scor
utils::quickselect_k_smallest<Score>(target_edge_amount, scores.begin(), scores.end());
}

double inclusion_probaility_if_equal = (target_edge_amount / 2 - threshold.number_of_elements_smaller) / threshold.number_of_elemtns_equal;
double inclusion_probability_if_equal = (target_edge_amount - threshold.number_of_elements_smaller) / static_cast<double>(threshold.number_of_elemtns_equal);
utils::parallel_for_upward_edges(g, [&](EdgeID e) {
if (scores[e] < threshold.value || (scores[e] == threshold.value && Random::instance().random_bool(inclusion_probaility_if_equal))) {
if (scores[e] < threshold.value || (scores[e] == threshold.value && Random::instance().random_bool(inclusion_probability_if_equal))) {
sample[e] = g.edge_weight(e);
}
});
Expand Down
34 changes: 24 additions & 10 deletions kaminpar-shm/coarsening/sparsifing_cluster_coarsener.cc
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
#include "kaminpar-shm/coarsening/sparsifing_cluster_coarsener.h"

#include "contraction/cluster_contraction_preprocessing.h"
#include "sparsification/DensitySparsificationTarget.h"
#include "sparsification/UniformRandomSampler.h"
#include "sparsification/sparsification_utils.h"

Expand All @@ -30,9 +29,9 @@ SparsifyingClusteringCoarsener::SparsifyingClusteringCoarsener(
)
: _clustering_algorithm(factory::create_clusterer(ctx)),
_sampling_algorithm(factory::create_sampler(ctx)),
_sparsification_target(factory::create_sparsification_target(ctx)),
_c_ctx(ctx.coarsening),
_p_ctx(p_ctx) {}
_p_ctx(p_ctx),
_s_ctx(ctx.sparsification) {}

void SparsifyingClusteringCoarsener::initialize(const Graph *graph) {
_hierarchy.clear();
Expand All @@ -52,8 +51,8 @@ SparsifyingClusteringCoarsener::sparsify(const CSRGraph &g, StaticArray<EdgeWeig
auto nodes = StaticArray<EdgeID>(g.n() + 1);
sparsification::utils::parallel_for_edges_with_endpoints(g, [&](EdgeID e, NodeID u, NodeID v) {
if (u < v && sample[e]) {
__atomic_add_fetch(&nodes[u+1],1,__ATOMIC_RELAXED);
__atomic_add_fetch(&nodes[v+1],1,__ATOMIC_RELAXED);
__atomic_add_fetch(&nodes[u + 1], 1, __ATOMIC_RELAXED);
__atomic_add_fetch(&nodes[v + 1], 1, __ATOMIC_RELAXED);
}
});
parallel::prefix_sum(nodes.begin(), nodes.end(), nodes.begin());
Expand All @@ -64,8 +63,8 @@ SparsifyingClusteringCoarsener::sparsify(const CSRGraph &g, StaticArray<EdgeWeig

sparsification::utils::parallel_for_edges_with_endpoints(g, [&](EdgeID e, NodeID u, NodeID v) {
if (u < v && sample[e]) {
auto v_edges_added = __atomic_fetch_add(&edges_added[v],1,__ATOMIC_RELAXED);
auto u_edges_added = __atomic_fetch_add(&edges_added[u],1,__ATOMIC_RELAXED);
auto v_edges_added = __atomic_fetch_add(&edges_added[v], 1, __ATOMIC_RELAXED);
auto u_edges_added = __atomic_fetch_add(&edges_added[u], 1, __ATOMIC_RELAXED);
edges[nodes[v] + v_edges_added] = u;
edges[nodes[u] + u_edges_added] = v;
edge_weights[nodes[v] + v_edges_added] = sample[e];
Expand All @@ -82,6 +81,14 @@ SparsifyingClusteringCoarsener::sparsify(const CSRGraph &g, StaticArray<EdgeWeig
);
}

EdgeID
SparsifyingClusteringCoarsener::sparsificationTarget(EdgeID old_m, NodeID old_n, EdgeID new_n) {
double target = std::min(
_s_ctx.reduction_target_factor * old_m, _s_ctx.density_target_factor * old_m / old_n * new_n
);
return target < old_m ? static_cast<EdgeID>(target) : old_m;
}

bool SparsifyingClusteringCoarsener::coarsen() {
SCOPED_HEAP_PROFILER("Level", std::to_string(_hierarchy.size()));
SCOPED_TIMER("Level", std::to_string(_hierarchy.size()));
Expand Down Expand Up @@ -111,9 +118,16 @@ bool SparsifyingClusteringCoarsener::coarsen() {
);
};

auto target_edge_amount = _sparsification_target->computeTarget(
_hierarchy.empty() ? *_input_graph : _hierarchy.back()->get(), coarsened->get().n()
);
EdgeID target_edge_amount;
if (_hierarchy.empty()) {
target_edge_amount =
sparsificationTarget(_input_graph->m(), _input_graph->n(), coarsened->get().n());
} else {
target_edge_amount = sparsificationTarget(
_hierarchy.back()->get().m(), _hierarchy.back()->get().n(), coarsened->get().n()
);
}

if (coarsened->get().m() > target_edge_amount) { // sparsify
KASSERT(coarsened->get().m() % 2 == 0, "graph should be undirected", assert::always);

Expand Down
4 changes: 2 additions & 2 deletions kaminpar-shm/coarsening/sparsifing_cluster_coarsener.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
#pragma once

#include "sparsification/Sampler.h"
#include "sparsification/SparsificationTarget.h"

#include "kaminpar-shm/coarsening/clusterer.h"
#include "kaminpar-shm/coarsening/coarsener.h"
Expand All @@ -31,6 +30,7 @@ class SparsifyingClusteringCoarsener : public Coarsener {
void initialize(const Graph *graph) final;

CSRGraph sparsify(const CSRGraph &csr, StaticArray<EdgeWeight> sample);
EdgeID sparsificationTarget(EdgeID old_m, NodeID old_n, EdgeID new_m);

bool coarsen() final;
PartitionedGraph uncoarsen(PartitionedGraph &&p_graph) final;
Expand All @@ -52,13 +52,13 @@ class SparsifyingClusteringCoarsener : public Coarsener {

const CoarseningContext &_c_ctx;
const PartitionContext &_p_ctx;
const SparsificationContext &_s_ctx;

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

std::unique_ptr<Clusterer> _clustering_algorithm;
std::unique_ptr<sparsification::Sampler> _sampling_algorithm;
std::unique_ptr<sparsification::SparsificationTarget> _sparsification_target;

contraction::MemoryContext _contraction_m_ctx{};
};
Expand Down
27 changes: 10 additions & 17 deletions kaminpar-shm/context_io.cc
Original file line number Diff line number Diff line change
Expand Up @@ -94,10 +94,10 @@ std::unordered_map<std::string, SparsificationAlgorithm> get_sparsification_algo
{"rw/or", SparsificationAlgorithm::RANDOM_WITHOUT_REPLACEMENT},
{"independent-random", SparsificationAlgorithm::INDEPENDENT_RANDOM},
{"ir", SparsificationAlgorithm::INDEPENDENT_RANDOM},
{"threshold", SparsificationAlgorithm::THRESHOLD},
{"t", SparsificationAlgorithm::THRESHOLD},
{"unbiased-threshold", SparsificationAlgorithm::UNBIASED_THRESHOLD},
{"ut", SparsificationAlgorithm::UNBIASED_THRESHOLD},
{"threshold", SparsificationAlgorithm::THRESHOLD},
{"t", SparsificationAlgorithm::THRESHOLD},
{"unbiased-threshold", SparsificationAlgorithm::UNBIASED_THRESHOLD},
{"ut", SparsificationAlgorithm::UNBIASED_THRESHOLD},
};
}
std::unordered_map<std::string, ScoreFunctionSection> get_score_function() {
Expand All @@ -113,14 +113,6 @@ std::unordered_map<std::string, ScoreFunctionSection> get_score_function() {
};
}

std::unordered_map<std::string, SparsificationTargetSelection>
get_sparsification_target_selection() {
return {
{"density", SparsificationTargetSelection::DENSITY},
{"edge-reduction", SparsificationTargetSelection::EDGE_REDUCTION}
};
}

std::ostream &operator<<(std::ostream &out, const CoarseningAlgorithm algorithm) {
switch (algorithm) {
case CoarseningAlgorithm::NOOP:
Expand Down Expand Up @@ -470,7 +462,8 @@ void print(const GraphCompressionContext &c_ctx, std::ostream &out) {
}

out << "Compresion Ratio: " << c_ctx.compression_ratio
<< " [size reduction: " << (c_ctx.size_reduction / (float)(1024 * 1024)) << " mb]" << "\n";
<< " [size reduction: " << (c_ctx.size_reduction / (float)(1024 * 1024)) << " mb]"
<< "\n";
out << " High Degree Node Count: " << c_ctx.num_high_degree_nodes << "\n";
out << " High Degree Part Count: " << c_ctx.num_high_degree_parts << "\n";
out << " Interval Node Count: " << c_ctx.num_interval_nodes << "\n";
Expand Down Expand Up @@ -607,8 +600,8 @@ void print(const RefinementContext &r_ctx, std::ostream &out) {
<< r_ctx.jet.num_fruitless_iterations << " fruitless (improvement < "
<< 100.0 * (1 - r_ctx.jet.fruitless_threshold) << "%)\n";
out << " Gain temperature: coarse [" << r_ctx.jet.initial_gain_temp_on_coarse_level
<< ", " << r_ctx.jet.final_gain_temp_on_coarse_level << "], " << "fine ["
<< r_ctx.jet.initial_gain_temp_on_fine_level << ", "
<< ", " << r_ctx.jet.final_gain_temp_on_coarse_level << "], "
<< "fine [" << r_ctx.jet.initial_gain_temp_on_fine_level << ", "
<< r_ctx.jet.final_gain_temp_on_fine_level << "]\n";
out << " Balancing algorithm: " << r_ctx.jet.balancing_algorithm << "\n";
}
Expand Down Expand Up @@ -652,8 +645,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
2 changes: 0 additions & 2 deletions kaminpar-shm/context_io.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,6 @@ std::unordered_map<std::string, CoarseningAlgorithm> get_coarsening_algorithms()

std::unordered_map<std::string, SparsificationAlgorithm> get_sparsification_algorithms();
std::unordered_map<std::string, ScoreFunctionSection> get_score_function();
std::unordered_map<std::string, SparsificationTargetSelection>
get_sparsification_target_selection();

std::ostream &operator<<(std::ostream &out, ClusteringAlgorithm algorithm);

Expand Down
20 changes: 1 addition & 19 deletions kaminpar-shm/factories.cc
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,6 @@
#include <networkit/auxiliary/Multiprecision.hpp>
#include <networkit/sparsification/ForestFireScore.hpp>

#include "coarsening/sparsification/DensitySparsificationTarget.h"
#include "coarsening/sparsification/EdgeReductionSparsificationTarget.h"
#include "coarsening/sparsification/IndependentRandomSampler.h"
#include "coarsening/sparsification/NetworKitScoreAdapter.h"
#include "coarsening/sparsification/NetworKitWeightedForestFireScore.hpp"
Expand Down Expand Up @@ -160,6 +158,7 @@ std::unique_ptr<sparsification::Sampler> create_sampler(const Context &ctx) {
std::make_unique<WeightFunction>()

);
__builtin_unreachable();
}
case SparsificationAlgorithm::RANDOM_WITHOUT_REPLACEMENT:
switch (ctx.sparsification.score_function) {
Expand Down Expand Up @@ -223,7 +222,6 @@ std::unique_ptr<sparsification::Sampler> create_sampler(const Context &ctx) {
case ScoreFunctionSection::WEIGHT:
return std::make_unique<sparsification::IndependentRandomSampler<EdgeWeight>>(
std::make_unique<WeightFunction>(), ctx.sparsification.no_approx

);
}
case SparsificationAlgorithm::THRESHOLD:
Expand Down Expand Up @@ -262,22 +260,6 @@ std::unique_ptr<sparsification::Sampler> create_sampler(const Context &ctx) {
__builtin_unreachable();
}

std::unique_ptr<sparsification::SparsificationTarget>
create_sparsification_target(const Context &ctx) {
switch (ctx.sparsification.target) {
case SparsificationTargetSelection::DENSITY:
return std::make_unique<sparsification::DensitySparsificationTarget>(
ctx.sparsification.target_factor
);
case SparsificationTargetSelection::EDGE_REDUCTION:
return std::make_unique<sparsification::EdgeReductionSparsificationTarget>(
ctx.sparsification.target_factor
);
}

__builtin_unreachable();
}

namespace {
std::unique_ptr<Refiner> create_refiner(const Context &ctx, const RefinementAlgorithm algorithm) {
switch (algorithm) {
Expand Down
3 changes: 0 additions & 3 deletions kaminpar-shm/factories.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@

#include "coarsening/sparsification/Sampler.h"
#include "coarsening/sparsification/ScoreBacedSampler.h"
#include "coarsening/sparsification/SparsificationTarget.h"

#include "kaminpar-shm/coarsening/clusterer.h"
#include "kaminpar-shm/coarsening/coarsener.h"
Expand All @@ -29,8 +28,6 @@ std::unique_ptr<Coarsener> create_coarsener(const Context &ctx, const PartitionC
std::unique_ptr<Coarsener> create_coarsener(const Context &ctx);

std::unique_ptr<sparsification::Sampler> create_sampler(const Context &ctx);
std::unique_ptr<sparsification::SparsificationTarget>
create_sparsification_target(const Context &ctx);

std::unique_ptr<Refiner> create_refiner(const Context &ctx);

Expand Down
9 changes: 2 additions & 7 deletions kaminpar-shm/kaminpar.h
Original file line number Diff line number Diff line change
Expand Up @@ -109,11 +109,6 @@ enum class ScoreFunctionSection {
WEIGHTED_FOREST_FIRE,
};

enum class SparsificationTargetSelection {
DENSITY,
EDGE_REDUCTION
};

enum class ClusteringAlgorithm {
NOOP,
LABEL_PROPAGATION,
Expand Down Expand Up @@ -237,8 +232,8 @@ struct SparsificationContext {
SparsificationAlgorithm algorithm;
ScoreFunctionSection score_function;

SparsificationTargetSelection target;
float target_factor;
float density_target_factor;
float reduction_target_factor;

bool no_approx;

Expand Down
1 change: 1 addition & 0 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ kaminpar_add_shm_test(test_shm_cluster_contraction shm/coarsening/cluster_contra

# KaMinPar -> Coarsening
kaminpar_add_shm_test(test_shm_sparsification_utils shm/coarsening/sparsification/sparsfication_utils_test.cc)
kaminpar_add_shm_test(test_shm_sparsifing_cluster_coarsener shm/coarsening/sparsification/sparisfng_cluster_coarsener_test.cpp)

# KaMinPar -> Data structures
kaminpar_add_shm_test(test_shm_graph shm/datastructures/graph_test.cc)
Expand Down
Loading

0 comments on commit fc8af15

Please sign in to comment.