-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'sparsification-random' into sparsification
- Loading branch information
Showing
22 changed files
with
477 additions
and
50 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
52 changes: 52 additions & 0 deletions
52
kaminpar-shm/coarsening/sparsification/IndependentRandomSampler.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
#pragma once | ||
#include "ScoreBacedSampler.h" | ||
#include "sparsification_utils.h" | ||
|
||
#include "kaminpar-common/random.h" | ||
|
||
namespace kaminpar::shm::sparsification { | ||
template <typename Score> class IndependentRandomSampler : public ScoreBacedSampler<Score> { | ||
public: | ||
IndependentRandomSampler( | ||
std::unique_ptr<ScoreFunction<Score>> scoreFunction, | ||
std::unique_ptr<ReweighingFunction<Score>> reweighingFunction | ||
) | ||
: ScoreBacedSampler<Score>(std::move(scoreFunction), std::move(reweighingFunction)) {} | ||
|
||
StaticArray<EdgeWeight> sample(const CSRGraph &g, EdgeID target_edge_amount) override { | ||
auto scores = this->_score_function->scores(g); | ||
double factor = normalizationFactor(g, scores, target_edge_amount); | ||
|
||
StaticArray<EdgeWeight> sample(g.m(), 0); | ||
utils::for_upward_edges(g, [&](EdgeID e) { | ||
sample[e] = Random::instance().random_bool(factor * scores[e]) | ||
? this->_reweighing_function->new_weight(g.edge_weight(e), scores[e]) | ||
: 0; | ||
}); | ||
return sample; | ||
} | ||
|
||
private: | ||
double normalizationFactor(const CSRGraph &g, const StaticArray<Score> &scores, EdgeID target) { | ||
StaticArray<Score> sorted_scores(g.m() / 2); | ||
StaticArray<Score> prefix_sum(g.m() / 2); | ||
EdgeID i = 0; | ||
utils::for_upward_edges(g, [&](EdgeID e) { sorted_scores[i++] = scores[e]; }); | ||
std::sort(sorted_scores.begin(), sorted_scores.end()); | ||
parallel::prefix_sum(sorted_scores.begin(), sorted_scores.end(), prefix_sum.begin()); | ||
|
||
EdgeID upper = 0; | ||
EdgeID lower = sorted_scores.size(); | ||
while (lower + 1 < upper) { | ||
EdgeID mid = lower + (upper - lower) / 2; | ||
if (target < (sorted_scores.size() - mid + prefix_sum[mid] / sorted_scores[mid + 1])) | ||
upper = mid; | ||
else | ||
lower = mid; | ||
} | ||
EdgeID index = lower; | ||
|
||
return static_cast<double>((target - (sorted_scores.size() - index))) / prefix_sum[index]; | ||
} | ||
}; | ||
}; // namespace kaminpar::shm::sparsification |
59 changes: 59 additions & 0 deletions
59
kaminpar-shm/coarsening/sparsification/IndexDistributionWithReplacement.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
// A random distribution over {0, ..., n-1} with probailies propotional to given values | ||
// Implemented using the alias Method | ||
|
||
|
||
#include "kaminpar-common/random.h" | ||
namespace kaminpar::shm::sparsification { | ||
template <typename T> class IndexDistributionWithReplacement { | ||
public: | ||
IndexDistributionWithReplacement(std::initializer_list<T> values) { | ||
UniformRandomDistribution(values.begin(), values.end()); | ||
} | ||
|
||
template <class Iterator> IndexDistributionWithReplacement(Iterator begin, Iterator end) { | ||
size_t size = end - begin; | ||
_probabilities.resize(size); | ||
_aliases.resize(size); | ||
double sum = 0; | ||
for (Iterator current = begin; current != end; current++) { | ||
sum += *current; | ||
_probabilities[current - begin] = *current; | ||
} | ||
|
||
std::vector<size_t> too_small, too_large; | ||
for (size_t i = 0; i != _probabilities.size(); i++) { | ||
_probabilities[i] *= size / sum; | ||
if (_probabilities[i] < 1) | ||
too_small.push_back(i); | ||
else if (_probabilities[i] > 1) | ||
too_large.push_back(i); | ||
_aliases[i] = i; // default alias to not get issues from rounding errors | ||
} | ||
|
||
while (!too_large.empty() && !too_small.empty()) { | ||
auto large = too_large.back(); | ||
too_large.pop_back(); | ||
auto small = too_small.back(); | ||
too_small.pop_back(); | ||
|
||
_aliases[small] = large; | ||
_probabilities[large] -= 1 - _probabilities[small]; | ||
|
||
if (_probabilities[large] < 1) | ||
too_small.push_back(large); | ||
if (_probabilities[large] > 1) | ||
too_large.push_back(large); | ||
|
||
} | ||
} | ||
|
||
size_t operator()() { | ||
size_t i = Random::instance().random_index(0, _probabilities.size()); | ||
return Random::instance().random_bool(_probabilities[i]) ? i : _aliases[i]; | ||
} | ||
|
||
private: | ||
std::vector<double> _probabilities; | ||
std::vector<size_t> _aliases; | ||
}; | ||
} // namespace kaminpar::shm::sparsification |
96 changes: 96 additions & 0 deletions
96
kaminpar-shm/coarsening/sparsification/IndexDistributionWithoutReplacement.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
#pragma once | ||
|
||
#include "kaminpar-common/random.h" | ||
|
||
namespace kaminpar::shm::sparsification { | ||
class IndexDistributionWithoutReplacement { | ||
public: | ||
IndexDistributionWithoutReplacement(std::vector<double> values) { | ||
IndexDistributionWithoutReplacement(values.begin(), values.end()); | ||
} | ||
IndexDistributionWithoutReplacement(StaticArray<double> values) { | ||
IndexDistributionWithoutReplacement(values.begin(), values.end()); | ||
} | ||
template <typename Iterator> | ||
IndexDistributionWithoutReplacement(Iterator values_begin, Iterator values_end) | ||
: remaining_objects(values_end - values_begin) { | ||
if (remaining_objects == 0) | ||
return; | ||
|
||
// size of a complete binary tree, where all values can be in the leaves | ||
size_t size = 1; | ||
while (size <= 2 * remaining_objects) { | ||
size *= 2; | ||
} | ||
size -= 1; | ||
segment_tree.resize(size, 0); | ||
|
||
// initalize leafs | ||
const size_t first_leaf = firstLeaf(); | ||
for (size_t leaf = first_leaf; leaf < first_leaf + remaining_objects; leaf++) { | ||
segment_tree[leaf] = *(values_begin + (leaf - first_leaf)); | ||
} | ||
|
||
// calculate sum of subtrees | ||
for (size_t node = segment_tree.size() - 1; node != 0; node--) { | ||
segment_tree[parent(node)] += segment_tree[node]; | ||
} | ||
} | ||
|
||
size_t operator()() { | ||
double r = Random::instance().random_double() * segment_tree[0]; | ||
|
||
size_t current_subtree = 0; | ||
while (not isLeaf(current_subtree)) { | ||
if (r <= segment_tree[leftChild(current_subtree)]) { | ||
current_subtree = leftChild(current_subtree); | ||
} else { | ||
r -= segment_tree[leftChild(current_subtree)]; | ||
current_subtree = rightChild(current_subtree); | ||
} | ||
} | ||
|
||
size_t index = to_index(current_subtree); | ||
double value = segment_tree[current_subtree]; | ||
|
||
// delete | ||
while (current_subtree != 0) { | ||
segment_tree[current_subtree] -= value; | ||
current_subtree = parent(current_subtree); | ||
} | ||
segment_tree[0] -= value; | ||
|
||
remaining_objects--; | ||
return index; | ||
} | ||
|
||
size_t size() { | ||
return remaining_objects; | ||
} | ||
bool empty() { | ||
return remaining_objects == 0; | ||
} | ||
|
||
private: | ||
bool isLeaf(size_t i) { | ||
return i >= firstLeaf(); | ||
} | ||
size_t parent(size_t i) { | ||
return (i - 1) / 2; | ||
} | ||
size_t leftChild(size_t i) { | ||
return 2 * i + 1; | ||
} | ||
size_t rightChild(size_t i) { | ||
return 2 * i + 2; | ||
} | ||
size_t firstLeaf() { | ||
return segment_tree.size() / 2; | ||
} | ||
size_t to_index(size_t leaf) { | ||
return leaf - firstLeaf(); | ||
} | ||
std::vector<double> segment_tree; | ||
size_t remaining_objects; | ||
}; | ||
} // namespace kaminpar::shm::sparsification |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.