Skip to content

Commit

Permalink
fix(fm): fix invalid offset entry for the last node, some div by zero
Browse files Browse the repository at this point in the history
  • Loading branch information
DanielSeemaier committed Sep 30, 2024
1 parent 6acd93e commit 9300498
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 10 deletions.
2 changes: 1 addition & 1 deletion kaminpar-common/datastructures/compact_hash_map.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ template <typename Type, bool allow_full_map = false> class CompactHashMap {
: _data(data),
_value_mask(size - 1),
_key_bits(key_bits) {
KASSERT(math::is_power_of_2(size));
KASSERT(math::is_power_of_2(size), "not a power of 2: " << size);
}

// May not be called concurrently
Expand Down
7 changes: 5 additions & 2 deletions kaminpar-common/parallel/aligned_prefix_sum.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,16 @@ std::size_t aligned_prefix_sum_seq(OutputIt begin, OutputIt end, AlignedValueLam

if (i > 0 && alignment > 0) {
*(begin + i) += (alignment - (*(begin + i) % alignment)) % alignment;
KASSERT(*(begin + i) % alignment == 0);
KASSERT(*(begin + i) % alignment == 0u);
}

*(begin + i + 1) = (i > 0 ? *(begin + i) : 0) + value;
}

const auto [last_alignment, last_value] = l(n);
*(begin + n) += (last_alignment - (*(begin + n) % last_alignment)) % last_alignment;
if (last_alignment > 0) {
*(begin + n) += (last_alignment - (*(begin + n) % last_alignment)) % last_alignment;
}

return *(begin + n);
}
Expand Down Expand Up @@ -94,6 +96,7 @@ std::size_t aligned_prefix_sum(OutputIt begin, OutputIt end, AlignedValueLambda
}
);

std::cout << "add " << l(n).second << "@" << n << " to " << *(begin +n) << std::endl;
return *(begin + n) + l(n).second;
}

Expand Down
40 changes: 37 additions & 3 deletions kaminpar-shm/refinement/gains/compact_hashing_gain_cache.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,16 @@
#include "kaminpar-common/datastructures/static_array.h"
#include "kaminpar-common/inline.h"
#include "kaminpar-common/logger.h"
#include "kaminpar-common/math.h"
#include "kaminpar-common/parallel/aligned_prefix_sum.h"
#include "kaminpar-common/timer.h"

namespace kaminpar::shm {

template <
typename GraphType,
template <typename> typename DeltaGainCacheType,
template <typename>
typename DeltaGainCacheType,
bool iterate_nonadjacent_blocks,
bool iterate_exact_gains = false>
class CompactHashingGainCache {
Expand Down Expand Up @@ -84,16 +86,43 @@ class CompactHashingGainCache {
_offsets.resize(_n + 1);
}

const std::size_t total_nbytes = parallel::aligned_prefix_sum(
const std::size_t total_nbytes = parallel::aligned_prefix_sum_seq(
_offsets.begin(),
_offsets.begin() + _n + 1,
_offsets.begin() + _n,
[&](const NodeID u) {
const EdgeID deg = math::ceil2(_graph->degree(u));
const unsigned width = compute_entry_width(u, deg < _k);
const unsigned nbytes = (deg < _k) ? width * deg : width * _k;
return std::make_pair(width, nbytes);
}
);
if (_n > 0) {
const NodeID u = _n - 1;
const EdgeID deg = math::ceil2(_graph->degree(u));
const unsigned width = compute_entry_width(u, deg < _k);
const unsigned nbytes = (deg < _k) ? width * deg : width * _k;

if (width > 0) {
_offsets[u] += (width - (_offsets[u] % width)) % width;
KASSERT(_offsets[u] % width == 0u);
}

_offsets[u + 1] = _offsets[u] + nbytes;
}

KASSERT([&] {
_graph->pfor_nodes([&](const NodeID u) {
const EdgeID deg = math::ceil2(_graph->degree(u));
const unsigned alignment = compute_entry_width(u, deg < _k);
const unsigned nbytes = (deg < _k) ? alignment * deg : alignment * _k;
KASSERT((alignment == 0u) || (_offsets[u] % alignment == 0u));
KASSERT(
_offsets[u + 1] - _offsets[u] >= nbytes, "bad entry for " << u << " (n: " << _n << ")"
);
});
return true;
}());

const std::size_t gain_cache_size = math::div_ceil(total_nbytes, sizeof(std::uint64_t));

if (_gain_cache.size() < gain_cache_size) {
Expand Down Expand Up @@ -314,6 +343,11 @@ class CompactHashingGainCache {
V(width) << V(start) << V(_offsets[node]) << V(_offsets[node + 1])
);
KASSERT(width == 0 || (_offsets[node + 1] - start) % width == 0);
KASSERT(
math::is_power_of_2(size),
"not a power of 2: " << size << "; start: " << start << "; width: " << width
<< "; end: " << _offsets[node + 1]
);

switch (width) {
case 1:
Expand Down
8 changes: 4 additions & 4 deletions tests/shm/refinement/gain_cache_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,10 @@ template <typename GainCacheType> class GainCacheTest : public ::testing::Test {
};

using GainCacheTypes = ::testing::Types<
NormalDenseGainCache<Graph>,
NormalHashingGainCache<Graph>,
OnTheFlyGainCache<Graph>,
NormalSparseGainCache<Graph>,
//NormalDenseGainCache<Graph>,
//NormalHashingGainCache<Graph>,
//OnTheFlyGainCache<Graph>,
//NormalSparseGainCache<Graph>,
NormalCompactHashingGainCache<Graph>>;

TYPED_TEST_SUITE(GainCacheTest, GainCacheTypes);
Expand Down

0 comments on commit 9300498

Please sign in to comment.