Skip to content

Commit

Permalink
Implement feedback on MIS2 update
Browse files Browse the repository at this point in the history
- Move MIS-2 related stuff from KokkosGraph::Experimental to
KokkosGraph. Keep deprecated versions in Experimental for backward
compatibility.
- Rename the 3 phases of MIS2 based aggregation to be more descriptive
  • Loading branch information
brian-kelley committed Dec 1, 2021
1 parent 7964bb9 commit 7ed2e66
Show file tree
Hide file tree
Showing 7 changed files with 88 additions and 53 deletions.
3 changes: 1 addition & 2 deletions example/wiki/graph/KokkosGraph_wiki_coarsening.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,7 @@ int main() {
std::cout << "Coarsened vertex labels:\n";
Ordinal numClusters = 0;
auto labels =
KokkosGraph::Experimental::graph_mis2_aggregate<ExecSpace, RowmapType,
ColindsType>(
KokkosGraph::graph_mis2_aggregate<ExecSpace, RowmapType, ColindsType>(
rowmapDevice, colindsDevice, numClusters);
// coarsening labels can be printed in the same way as colors
GraphDemo::printColoring(labels, numClusters);
Expand Down
26 changes: 14 additions & 12 deletions example/wiki/graph/KokkosGraph_wiki_mis2.cpp
Original file line number Diff line number Diff line change
@@ -1,34 +1,36 @@
#include "KokkosGraph_wiki_9pt_stencil.hpp"
#include "KokkosGraph_MIS2.hpp"

int main()
{
int main() {
Kokkos::initialize();
{
using GraphDemo::numVertices;
RowmapType rowmapDevice;
ColindsType colindsDevice;
//Step 1: Generate the graph on host, allocate space on device, and copy.
//See function "generate9pt" below.
// Step 1: Generate the graph on host, allocate space on device, and copy.
// See function "generate9pt" below.
GraphDemo::generate9pt(rowmapDevice, colindsDevice);
//Step 2: Run distance-2 MIS and print the results, with three different algorithms
// Step 2: Run distance-2 MIS and print the results, with three different
// algorithms
{
//Run coloring
auto misDevice = KokkosGraph::Experimental::graph_d2_mis<ExecSpace, RowmapType, ColindsType>(
rowmapDevice, colindsDevice, KokkosGraph::MIS2_FAST);
// Run coloring
auto misDevice =
KokkosGraph::graph_d2_mis<ExecSpace, RowmapType, ColindsType>(
rowmapDevice, colindsDevice, KokkosGraph::MIS2_FAST);
std::cout << "Distance-2 MIS, FAST algorithm: contains "
<< misDevice.extent(0) << " out of " << GraphDemo::numVertices << " vertices.\n";
<< misDevice.extent(0) << " out of " << GraphDemo::numVertices
<< " vertices.\n";
GraphDemo::printMIS(misDevice);
putchar('\n');
misDevice = KokkosGraph::Experimental::graph_d2_mis<ExecSpace, RowmapType, ColindsType>(
misDevice = KokkosGraph::graph_d2_mis<ExecSpace, RowmapType, ColindsType>(
rowmapDevice, colindsDevice, KokkosGraph::MIS2_QUALITY);
std::cout << "Distance-2 MIS, QUALITY algorithm: contains "
<< misDevice.extent(0) << " out of " << GraphDemo::numVertices << " vertices.\n";
<< misDevice.extent(0) << " out of " << GraphDemo::numVertices
<< " vertices.\n";
GraphDemo::printMIS(misDevice);
putchar('\n');
}
}
Kokkos::finalize();
return 0;
}

6 changes: 3 additions & 3 deletions perf_test/graph/KokkosGraph_mis_d2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -276,9 +276,9 @@ void run_mis2(const MIS2Parameters& params) {

t.reset();
for (int rep = 0; rep < params.repeat; rep++) {
mis = KokkosGraph::Experimental::graph_d2_mis<device_t, decltype(rowmap),
decltype(entries)>(
rowmap, entries, params.algo);
mis = KokkosGraph::graph_d2_mis<device_t, decltype(rowmap),
decltype(entries)>(rowmap, entries,
params.algo);
exec_space().fence();
}
double totalTime = t.seconds();
Expand Down
43 changes: 40 additions & 3 deletions src/graph/KokkosGraph_MIS2.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,6 @@ namespace KokkosGraph {

enum MIS2_Algorithm { MIS2_QUALITY, MIS2_FAST };

namespace Experimental {

// Compute a distance-2 maximal independent set, given a symmetric CRS graph.
// Returns a list of the vertices in the set.
//
Expand Down Expand Up @@ -123,7 +121,46 @@ inline const char* mis2_algorithm_name(MIS2_Algorithm algo) {
return "*** Invalid MIS2 algo enum value.\n";
}

} // end namespace Experimental
} // end namespace KokkosGraph

// For backward compatibility
namespace KokkosGraph {
namespace Experimental {

template <typename device_t, typename rowmap_t, typename colinds_t,
typename lno_view_t = typename colinds_t::non_const_type>
[[deprecated]] lno_view_t graph_d2_mis(const rowmap_t& rowmap,
const colinds_t& colinds,
MIS2_Algorithm algo = MIS2_FAST) {
return KokkosGraph::graph_d2_mis<device_t, rowmap_t, colinds_t, lno_view_t>(
rowmap, colinds, algo);
}

template <typename device_t, typename rowmap_t, typename colinds_t,
typename labels_t = typename colinds_t::non_const_type>
[[deprecated]] labels_t graph_mis2_coarsen(
const rowmap_t& rowmap, const colinds_t& colinds,
typename colinds_t::non_const_value_type& numClusters) {
return KokkosGraph::graph_mis2_coarsen<device_t, rowmap_t, colinds_t,
labels_t>(rowmap, colinds,
numClusters);
}

template <typename device_t, typename rowmap_t, typename colinds_t,
typename labels_t = typename colinds_t::non_const_type>
[[deprecated]] labels_t graph_mis2_aggregate(
const rowmap_t& rowmap, const colinds_t& colinds,
typename colinds_t::non_const_value_type& numAggregates) {
return KokkosGraph::graph_mis2_aggregate<device_t, rowmap_t, colinds_t,
labels_t>(rowmap, colinds,
numAggregates);
}

[[deprecated]] inline const char* mis2_algorithm_name(MIS2_Algorithm algo) {
return KokkosGraph::mis2_algorithm_name(algo);
}

} // namespace Experimental
} // namespace KokkosGraph

#endif
43 changes: 21 additions & 22 deletions src/graph/impl/KokkosGraph_Distance2MIS_impl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@
#include <cstdint>

namespace KokkosGraph {
namespace Experimental {
namespace Impl {

template <typename device_t, typename rowmap_t, typename entries_t,
Expand Down Expand Up @@ -971,7 +970,7 @@ struct D2_MIS_Aggregation {
char_view_t roots_;
};

void phase1() {
void createPrimaryAggregates() {
// Compute an MIS-2
D2_MIS_RandomPriority<device_t, rowmap_t, entries_t, mis2_view> d2mis(
rowmap, entries);
Expand Down Expand Up @@ -1064,7 +1063,7 @@ struct D2_MIS_Aggregation {
char_view_t roots_;
};

void phase2() {
void createSecondaryAggregates() {
labels_t candAggSizes(
Kokkos::ViewAllocateWithoutInitializing("Phase2 Candidate Agg Sizes"),
numVerts);
Expand Down Expand Up @@ -1217,7 +1216,7 @@ struct D2_MIS_Aggregation {
char_view_t roots_;
};

void phase3() {
void aggregateLeftovers() {
// Phase3 is cleanup. All aggregates have already been created, but some
// vertices might be unaggregated. Compute the current size of each
// aggregate, and then join each unaggregated node to the smallest
Expand All @@ -1240,23 +1239,24 @@ struct D2_MIS_Aggregation {

// phase 2 creates new aggregates in between the initial MIS-2 neighborhoods.
// Effectively slows coarsening rate by adding new aggregates.
void compute(bool enablePhase2) {
// Pseudocode:
//
// -Phase 1: compute MIS-2, construct an aggregate from each in-set point
// and its neighbors -Phase 2: Until no new aggregates can be formed this
// way:
// -Compute an MIS-2 that excludes all aggregated nodes
// -For each in-set point:
// -Count unaggregated neighbors.
// -If total agg size would be >= 3, make the aggregate.
// -Phase 3: join still unaggregated nodes to a neighboring aggregate
// -Ideally, the smallest neighboring aggregate.
// -To remain deterministic, could simply use the agg sizes from end of
// phase 2 and not update them during phase 3.
phase1();
if (enablePhase2) phase2();
phase3();
void compute(bool enableSecondaryAggregates) {
// * Phase 1: compute MIS-2, construct a 'primary' aggregate from each
// in-set point and its neighbors
createPrimaryAggregates();
// * Phase 2:
// - Compute an MIS-2 on subgraph of unaggregated nodes
// - For each in-set point:
// - Count unaggregated neighbors.
// - If total agg size would be >= 3, create the new aggregate.
// - This is optional: enabling this phase slows coarsening rate (i.e.
// coarse graph is larger)
if (enableSecondaryAggregates) createSecondaryAggregates();
// * Phase 3: join still unaggregated (leftover) vertices to a neighboring
// aggregate
// - Ideally, the smallest neighboring aggregate.
// - To remain deterministic, we use the agg sizes from end of
// phase 2 and hold those constant during phase 3.
aggregateLeftovers();
}

rowmap_t rowmap;
Expand All @@ -1268,7 +1268,6 @@ struct D2_MIS_Aggregation {
};

} // namespace Impl
} // namespace Experimental
} // namespace KokkosGraph

#endif
7 changes: 4 additions & 3 deletions src/sparse/impl/KokkosSparse_cluster_gauss_seidel_impl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -588,9 +588,10 @@ class ClusterGaussSeidel {
if (clusterAlgo == CLUSTER_DEFAULT) clusterAlgo = CLUSTER_MIS2;
switch (clusterAlgo) {
case CLUSTER_MIS2: {
vertClusters = KokkosGraph::Experimental::graph_mis2_aggregate<
MyExecSpace, raw_rowmap_t, raw_colinds_t, nnz_view_t>(
raw_sym_xadj, raw_sym_adj, numClusters);
vertClusters =
KokkosGraph::graph_mis2_aggregate<MyExecSpace, raw_rowmap_t,
raw_colinds_t, nnz_view_t>(
raw_sym_xadj, raw_sym_adj, numClusters);
break;
}
case CLUSTER_BALLOON: {
Expand Down
13 changes: 5 additions & 8 deletions unit_test/graph/Test_Graph_mis2.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,6 @@
using namespace KokkosKernels;
using namespace KokkosKernels::Experimental;

using namespace KokkosGraph;
using namespace KokkosGraph::Experimental;

enum CoarseningType { PHASE2, NO_PHASE2 };

namespace Test {
Expand Down Expand Up @@ -141,8 +138,8 @@ void test_mis2(lno_t numVerts, size_type nnz, lno_t bandwidth,
// For each algorithm, compute and verify the MIS
std::vector<MIS2_Algorithm> algos = {MIS2_FAST, MIS2_QUALITY};
for (auto algo : algos) {
auto mis =
graph_d2_mis<device, rowmap_t, entries_t>(symRowmap, symEntries, algo);
auto mis = KokkosGraph::graph_d2_mis<device, rowmap_t, entries_t>(
symRowmap, symEntries, algo);
auto misHost =
Kokkos::create_mirror_view_and_copy(Kokkos::HostSpace(), mis);
bool success = Test::verifyD2MIS<lno_t, size_type, decltype(rowmapHost),
Expand Down Expand Up @@ -187,11 +184,11 @@ void test_mis2_coarsening(lno_t numVerts, size_type nnz, lno_t bandwidth,
labels_t labels;
switch (algo) {
case NO_PHASE2:
labels = graph_mis2_coarsen<device, rowmap_t, entries_t>(
labels = KokkosGraph::graph_mis2_coarsen<device, rowmap_t, entries_t>(
symRowmap, symEntries, numClusters);
break;
case PHASE2:
labels = graph_mis2_aggregate<device, rowmap_t, entries_t>(
labels = KokkosGraph::graph_mis2_aggregate<device, rowmap_t, entries_t>(
symRowmap, symEntries, numClusters);
}
auto labelsHost =
Expand Down Expand Up @@ -260,7 +257,7 @@ void test_mis2_coarsening_zero_rows() {
// note: MIS2 coarsening first calls MIS2 on the fine graph, so this covers
// the zero-row case for MIS2 alone.
lno_t numClusters;
auto labels = graph_mis2_coarsen<device, rowmap_t, entries_t>(
auto labels = KokkosGraph::graph_mis2_coarsen<device, rowmap_t, entries_t>(
fineRowmap, fineEntries, numClusters);
EXPECT_EQ(numClusters, 0);
EXPECT_EQ(labels.extent(0), 0);
Expand Down

0 comments on commit 7ed2e66

Please sign in to comment.