-
Notifications
You must be signed in to change notification settings - Fork 24
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
construction algorithm for fixed vertex free subhypergraph
- Loading branch information
1 parent
34b3544
commit c1b17cb
Showing
9 changed files
with
306 additions
and
3 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
set(FixedVertexSources | ||
fixed_vertex_removal.cpp) | ||
|
||
foreach(modtarget IN LISTS PARTITIONING_SUITE_TARGETS) | ||
target_sources(${modtarget} PRIVATE ${FixedVertexSources}) | ||
endforeach() |
119 changes: 119 additions & 0 deletions
119
mt-kahypar/partition/fixed_vertices/fixed_vertex_removal.cpp
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,119 @@ | ||
/******************************************************************************* | ||
* MIT License | ||
* | ||
* This file is part of Mt-KaHyPar. | ||
* | ||
* Copyright (C) 2023 Tobias Heuer <tobias.heuer@kit.edu> | ||
* | ||
* Permission is hereby granted, free of charge, to any person obtaining a copy | ||
* of this software and associated documentation files (the "Software"), to deal | ||
* in the Software without restriction, including without limitation the rights | ||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
* copies of the Software, and to permit persons to whom the Software is | ||
* furnished to do so, subject to the following conditions: | ||
* | ||
* The above copyright notice and this permission notice shall be included in all | ||
* copies or substantial portions of the Software. | ||
* | ||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
* SOFTWARE. | ||
******************************************************************************/ | ||
|
||
#include "mt-kahypar/partition/fixed_vertices/fixed_vertex_removal.h" | ||
|
||
#include "tbb/parallel_invoke.h" | ||
|
||
#include "mt-kahypar/definitions.h" | ||
#include "mt-kahypar/parallel/parallel_prefix_sum.h" | ||
|
||
namespace mt_kahypar { | ||
|
||
template<typename Hypergraph> | ||
ExtractedHypergraph<Hypergraph> FixedVertexRemoval<Hypergraph>::remove(const Hypergraph& hypergraph) { | ||
ExtractedHypergraph<Hypergraph> extracted_hg; | ||
vec<HypernodeID>& hn_mapping = extracted_hg.hn_mapping; | ||
vec<HyperedgeID> he_mapping; | ||
|
||
parallel::TBBPrefixSum<HypernodeID> hn_mapping_prefix_sum(hn_mapping); | ||
parallel::TBBPrefixSum<HyperedgeID> he_mapping_prefix_sum(he_mapping); | ||
tbb::parallel_invoke([&] { | ||
hn_mapping.assign(hypergraph.initialNumNodes() + 1, 0); | ||
hypergraph.doParallelForAllNodes([&](const HypernodeID hn) { | ||
if ( !hypergraph.isFixed(hn) ) { | ||
// Mark free vertices as valid | ||
hn_mapping[hn + 1] = 1; | ||
} | ||
}); | ||
// Prefix sums computes mapping of the nodes of the input hypergraph to the nodes | ||
// of the fixed vertex free subhypergraph | ||
tbb::parallel_scan(tbb::blocked_range<size_t>(UL(0), UL(hypergraph.initialNumNodes() + 1)), hn_mapping_prefix_sum); | ||
}, [&] { | ||
he_mapping.assign(hypergraph.initialNumEdges() + 1, 0); | ||
hypergraph.doParallelForAllEdges([&](const HypernodeID he) { | ||
size_t edge_size = 0; | ||
for ( const HypernodeID& pin : hypergraph.pins(he) ) { | ||
if ( !hypergraph.isFixed(pin) ) { | ||
++edge_size; | ||
} | ||
} | ||
if ( edge_size > 1 ) { | ||
// Mark edges with more than one pin as valid | ||
he_mapping[he + 1] = 1; | ||
} | ||
}); | ||
// Prefix sums computes mapping of the edges of the input hypergraph to the edges | ||
// of the fixed vertex free subhypergraph | ||
tbb::parallel_scan(tbb::blocked_range<size_t>(UL(0), UL(hypergraph.initialNumEdges() + 1)), he_mapping_prefix_sum); | ||
}); | ||
// Remove sentinel | ||
hn_mapping.pop_back(); | ||
|
||
const HypernodeID num_nodes = hn_mapping_prefix_sum.total_sum(); | ||
const HyperedgeID num_edges = he_mapping_prefix_sum.total_sum(); | ||
HyperedgeVector edge_vector; | ||
vec<HyperedgeWeight> hyperedge_weights; | ||
vec<HypernodeWeight> hypernode_weights; | ||
tbb::parallel_invoke([&] { | ||
tbb::parallel_invoke([&] { | ||
edge_vector.resize(num_edges); | ||
}, [&] { | ||
hyperedge_weights.resize(num_edges); | ||
}); | ||
|
||
// Construct edge vector of the fixed vertex free subhypergraph | ||
hypergraph.doParallelForAllEdges([&](const HyperedgeID& he) { | ||
if ( he_mapping_prefix_sum.value(he + 1) ) { | ||
// Hyperedge contains more than one pin in fixed vertex free subhypergraph | ||
const HyperedgeID e = he_mapping[he]; | ||
hyperedge_weights[e] = hypergraph.edgeWeight(he); | ||
for ( const HypernodeID& pin : hypergraph.pins(he) ) { | ||
if ( !hypergraph.isFixed(pin) ) { | ||
edge_vector[e].push_back(hn_mapping[pin]); | ||
} | ||
} | ||
} | ||
}); | ||
}, [&] { | ||
hypernode_weights.resize(num_nodes); | ||
hypergraph.doParallelForAllNodes([&](const HypernodeID& hn) { | ||
if ( !hypergraph.isFixed(hn) ) { | ||
hypernode_weights[hn_mapping[hn]] = hypergraph.nodeWeight(hn); | ||
} else { | ||
hn_mapping[hn] = kInvalidHypernode; | ||
} | ||
}); | ||
}); | ||
|
||
// Construct fixed vertex free subhypergraph | ||
extracted_hg.hg = Factory::construct(num_nodes, num_edges, | ||
edge_vector, hyperedge_weights.data(), hypernode_weights.data(), true); | ||
return extracted_hg; | ||
} | ||
|
||
INSTANTIATE_CLASS_WITH_HYPERGRAPHS(FixedVertexRemoval) | ||
} |
47 changes: 47 additions & 0 deletions
47
mt-kahypar/partition/fixed_vertices/fixed_vertex_removal.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,47 @@ | ||
/******************************************************************************* | ||
* MIT License | ||
* | ||
* This file is part of Mt-KaHyPar. | ||
* | ||
* Copyright (C) 2023 Tobias Heuer <tobias.heuer@kit.edu> | ||
* | ||
* Permission is hereby granted, free of charge, to any person obtaining a copy | ||
* of this software and associated documentation files (the "Software"), to deal | ||
* in the Software without restriction, including without limitation the rights | ||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
* copies of the Software, and to permit persons to whom the Software is | ||
* furnished to do so, subject to the following conditions: | ||
* | ||
* The above copyright notice and this permission notice shall be included in all | ||
* copies or substantial portions of the Software. | ||
* | ||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
* SOFTWARE. | ||
******************************************************************************/ | ||
|
||
#pragma once | ||
|
||
#include <atomic> | ||
|
||
#include "mt-kahypar/datastructures/hypergraph_common.h" | ||
#include "mt-kahypar/parallel/stl/scalable_vector.h" | ||
|
||
namespace mt_kahypar { | ||
|
||
template<typename Hypergraph> | ||
class FixedVertexRemoval { | ||
|
||
using Factory = typename Hypergraph::Factory; | ||
using HyperedgeVector = vec<vec<HypernodeID>>; | ||
|
||
public: | ||
static ExtractedHypergraph<Hypergraph> remove(const Hypergraph& hypergraph); | ||
|
||
}; | ||
|
||
} // namespace mt_kahypar |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,7 @@ | ||
add_subdirectory(preprocessing) | ||
add_subdirectory(mapping) | ||
add_subdirectory(coarsening) | ||
add_subdirectory(fixed_vertices) | ||
add_subdirectory(initial_partitioning) | ||
add_subdirectory(refinement) | ||
add_subdirectory(determinism) |
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,3 @@ | ||
target_sources(mt_kahypar_tests PRIVATE | ||
fixed_vertex_support_test.cc | ||
fixed_vertex_removal_test.cc) |
127 changes: 127 additions & 0 deletions
127
tests/partition/fixed_vertices/fixed_vertex_removal_test.cc
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,127 @@ | ||
/******************************************************************************* | ||
* MIT License | ||
* | ||
* This file is part of Mt-KaHyPar. | ||
* | ||
* Copyright (C) 2023 Tobias Heuer <tobias.heuer@kit.edu> | ||
* | ||
* Permission is hereby granted, free of charge, to any person obtaining a copy | ||
* of this software and associated documentation files (the "Software"), to deal | ||
* in the Software without restriction, including without limitation the rights | ||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
* copies of the Software, and to permit persons to whom the Software is | ||
* furnished to do so, subject to the following conditions: | ||
* | ||
* The above copyright notice and this permission notice shall be included in all | ||
* copies or substantial portions of the Software. | ||
* | ||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
* SOFTWARE. | ||
******************************************************************************/ | ||
|
||
|
||
|
||
#include "gmock/gmock.h" | ||
#include "tbb/task_group.h" | ||
|
||
#include "mt-kahypar/datastructures/static_hypergraph.h" | ||
#include "mt-kahypar/datastructures/static_hypergraph_factory.h" | ||
#include "mt-kahypar/datastructures/fixed_vertex_support.h" | ||
#include "mt-kahypar/partition/fixed_vertices/fixed_vertex_removal.h" | ||
|
||
using ::testing::Test; | ||
|
||
namespace mt_kahypar { | ||
namespace ds { | ||
|
||
|
||
class AFixedVertexRemoval : public Test { | ||
|
||
public: | ||
using Hypergraph = StaticHypergraph; | ||
using Factory = typename Hypergraph::Factory; | ||
|
||
AFixedVertexRemoval() : | ||
hypergraph(Factory::construct( | ||
7 , 4, { {0, 2}, {0, 1, 3, 4}, {3, 4, 6}, {2, 5, 6} })) { } | ||
|
||
void addFixedVertices(const PartitionID k, | ||
const vec<PartitionID>& fixed_vertex_blocks) { | ||
FixedVertexSupport<Hypergraph> fixed_vertices(hypergraph.initialNumNodes(), k); | ||
fixed_vertices.setHypergraph(&hypergraph); | ||
for ( const HypernodeID& hn : hypergraph.nodes() ) { | ||
if ( fixed_vertex_blocks[hn] != kInvalidPartition ) { | ||
fixed_vertices.fixToBlock(hn, fixed_vertex_blocks[hn]); | ||
} | ||
} | ||
hypergraph.addFixedVertexSupport(std::move(fixed_vertices)); | ||
} | ||
|
||
void verifyFixedVertexFreeSubhypergraph(const Hypergraph& hypergraph, | ||
const vec<HypernodeID>& hn_mapping, | ||
const HypernodeID expected_num_nodes, | ||
const vec<vec<HypernodeID>>& expected_pins) { | ||
const HyperedgeID expected_num_edges = expected_pins.size(); | ||
ASSERT_EQ(expected_num_nodes, hypergraph.initialNumNodes()); | ||
ASSERT_EQ(expected_num_edges, hypergraph.initialNumEdges()); | ||
|
||
vec<HypernodeID> to_original(expected_num_nodes, 0); | ||
for ( size_t i = 0; i < hn_mapping.size(); ++i ) { | ||
if ( hn_mapping[i] != kInvalidHypernode ) { | ||
to_original[hn_mapping[i]] = i; | ||
} | ||
} | ||
|
||
for ( const HyperedgeID& he : hypergraph.edges() ) { | ||
ASSERT_EQ(UL(hypergraph.edgeSize(he)), expected_pins[he].size()); | ||
size_t i = 0; | ||
for ( const HypernodeID& pin : hypergraph.pins(he) ) { | ||
ASSERT_EQ(expected_pins[he][i++], to_original[pin]); | ||
} | ||
} | ||
} | ||
|
||
Hypergraph hypergraph; | ||
}; | ||
|
||
|
||
TEST_F(AFixedVertexRemoval, ConstructFixedVertexFreeSubhypergraph1) { | ||
addFixedVertices(3, { kInvalidPartition, kInvalidPartition, 0, kInvalidPartition, 1, kInvalidPartition, 2 }); | ||
ExtractedHypergraph<StaticHypergraph> extracted_hg = FixedVertexRemoval<StaticHypergraph>::remove(hypergraph); | ||
verifyFixedVertexFreeSubhypergraph(extracted_hg.hg, extracted_hg.hn_mapping, 4, { { 0, 1, 3 } }); | ||
} | ||
|
||
TEST_F(AFixedVertexRemoval, ConstructFixedVertexFreeSubhypergraph2) { | ||
addFixedVertices(3, { 0, kInvalidPartition, kInvalidPartition, kInvalidPartition, kInvalidPartition, kInvalidPartition, 2 }); | ||
ExtractedHypergraph<StaticHypergraph> extracted_hg = FixedVertexRemoval<StaticHypergraph>::remove(hypergraph); | ||
verifyFixedVertexFreeSubhypergraph(extracted_hg.hg, extracted_hg.hn_mapping, | ||
5, { { 1, 3, 4 }, { 3, 4 }, { 2, 5 } }); | ||
} | ||
|
||
TEST_F(AFixedVertexRemoval, ConstructFixedVertexFreeSubhypergraph3) { | ||
addFixedVertices(3, { 0, 1, 2, kInvalidPartition, kInvalidPartition, 2, 2 }); | ||
ExtractedHypergraph<StaticHypergraph> extracted_hg = FixedVertexRemoval<StaticHypergraph>::remove(hypergraph); | ||
verifyFixedVertexFreeSubhypergraph(extracted_hg.hg, extracted_hg.hn_mapping, | ||
2, { { 3, 4 }, { 3, 4 } }); | ||
} | ||
|
||
TEST_F(AFixedVertexRemoval, ConstructFixedVertexFreeSubhypergraph4) { | ||
addFixedVertices(3, { kInvalidPartition, 1, kInvalidPartition, 2, 1, kInvalidPartition, 2 }); | ||
ExtractedHypergraph<StaticHypergraph> extracted_hg = FixedVertexRemoval<StaticHypergraph>::remove(hypergraph); | ||
verifyFixedVertexFreeSubhypergraph(extracted_hg.hg, extracted_hg.hn_mapping, | ||
3, { { 0, 2 }, { 2, 5 } }); | ||
} | ||
|
||
TEST_F(AFixedVertexRemoval, ConstructFixedVertexFreeSubhypergraph5) { | ||
addFixedVertices(3, { kInvalidPartition, 1, 0, 2, 1, kInvalidPartition, 2 }); | ||
ExtractedHypergraph<StaticHypergraph> extracted_hg = FixedVertexRemoval<StaticHypergraph>::remove(hypergraph); | ||
verifyFixedVertexFreeSubhypergraph(extracted_hg.hg, extracted_hg.hn_mapping, 2, { }); | ||
} | ||
|
||
} // namespace ds | ||
} // namespace mt_kahypar |
File renamed without changes.