Skip to content

Commit

Permalink
Update --verbose option in D2 coloring perftest
Browse files Browse the repository at this point in the history
- for symmetric D2 coloring, verify precondition that local graph is structurally symmetric.
  (local means the 0..nrows by 0..nrows submatrix, since entries in higher columns are allowed
  and are ignored by the algorithms)
- verify correctness of coloring like unit test does
  • Loading branch information
brian-kelley committed Aug 8, 2022
1 parent 251bffa commit 1170e96
Showing 1 changed file with 105 additions and 225 deletions.
330 changes: 105 additions & 225 deletions perf_test/graph/KokkosGraph_color_d2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ struct D2Parameters {

D2Parameters() {
algorithm = COLORING_D2_DEFAULT;
repeat = 6;
repeat = 1;
verbose = 0;
use_threads = 0;
use_openmp = 0;
Expand All @@ -105,7 +105,76 @@ typedef default_scalar kk_scalar_t;
typedef default_size_type kk_size_type;
typedef default_lno_t kk_lno_t;

using namespace KokkosGraph;
using KokkosKernels::Impl::xorshiftHash;

template <typename lno_t, typename size_type, typename rowmap_t,
typename entries_t>
bool verifySymmetric(lno_t numVerts, const rowmap_t& d_rowmap,
const entries_t& d_entries) {
auto rowmap =
Kokkos::create_mirror_view_and_copy(Kokkos::HostSpace(), d_rowmap);
auto entries =
Kokkos::create_mirror_view_and_copy(Kokkos::HostSpace(), d_entries);
size_t hash = 0;
for (lno_t v = 0; v < numVerts; v++) {
size_type rowBegin = rowmap(v);
size_type rowEnd = rowmap(v + 1);
for (size_type i = rowBegin; i < rowEnd; i++) {
lno_t nei = entries(i);
if (nei < numVerts && nei != v) {
hash ^= xorshiftHash<size_t>(xorshiftHash<size_t>(v) ^
xorshiftHash<size_t>(nei));
}
}
}
return hash == 0U;
}

template <typename lno_t, typename size_type, typename rowmap_t,
typename entries_t, typename colors_t>
bool verifyD2Coloring(lno_t numVerts, const rowmap_t& d_rowmap,
const entries_t& d_entries, const colors_t& d_colors) {
auto rowmap =
Kokkos::create_mirror_view_and_copy(Kokkos::HostSpace(), d_rowmap);
auto entries =
Kokkos::create_mirror_view_and_copy(Kokkos::HostSpace(), d_entries);
auto colors =
Kokkos::create_mirror_view_and_copy(Kokkos::HostSpace(), d_colors);
// Just do the simplest possible neighbors-of-neighbors loop to find conflicts
for (lno_t v = 0; v < numVerts; v++) {
if (colors(v) == 0) {
std::cout << "Vertex " << v << " is uncolored.\n";
return false;
}
size_type rowBegin = rowmap(v);
size_type rowEnd = rowmap(v + 1);
for (size_type i = rowBegin; i < rowEnd; i++) {
lno_t nei1 = entries(i);
if (nei1 < numVerts && nei1 != v) {
// check for dist-1 conflict
if (colors(v) == colors(nei1)) {
std::cout << "Dist-1 conflict between " << v << " and " << nei1
<< '\n';
return false;
}
// iterate over dist-2 neighbors
size_type colBegin = rowmap(nei1);
size_type colEnd = rowmap(nei1 + 1);
for (size_type j = colBegin; j < colEnd; j++) {
lno_t nei2 = entries(j);
if (nei2 < numVerts && nei2 != v) {
if (colors(v) == colors(nei2)) {
std::cout << "Dist-2 conflict between " << v << " and " << nei2
<< '\n';
return false;
}
}
}
}
}
}
return true;
}

void print_options(std::ostream& os, const char* app_name,
unsigned int indent = 0) {
Expand Down Expand Up @@ -180,8 +249,12 @@ void print_options(std::ostream& os, const char* app_name,
<< " --repeat <N> Set number of test repetitions (Default: 1) "
<< std::endl
<< spaces
<< " --verbose Enable verbose mode (record and print "
"timing + extra information)"
<< " --verbose Enable verbose mode. Print more detailed "
"timing information, and for --symmetric_d2,"
<< std::endl
<< spaces
<< " verify input graph is symmetric "
"(undirected) and verify coloring."
<< std::endl
<< spaces << " --help Print out command line help."
<< std::endl
Expand Down Expand Up @@ -313,6 +386,21 @@ void run_experiment(crsGraph_t crsGraph, int num_cols,
kh.set_verbose(true);
}

if (verbose && params.d2_color_type == MODE_D2_SYMMETRIC) {
if (verifySymmetric<lno_t, size_type, decltype(crsGraph.row_map),
decltype(crsGraph.entries)>(
crsGraph.numRows(), crsGraph.row_map, crsGraph.entries)) {
std::cout << std::endl
<< "Distance-2 Graph is symmetric (valid input)" << std::endl;
} else {
std::cout << std::endl
<< "Distance-2 Graph is nonsymmetric (INVALID INPUT)"
<< std::endl;
// Don't attempt coloring when input is invalid
return;
}
}

// accumulators for average stats
size_t total_colors = 0;
size_t total_phases = 0;
Expand All @@ -324,7 +412,6 @@ void run_experiment(crsGraph_t crsGraph, int num_cols,
<< "Run Graph Color D2 (" << label_algorithm << ")" << std::endl;

// If any of the runs have an invalid result, this will be set to false.
bool all_results_valid = true;

// Loop over # of experiments to run
for (int i = 0; i < repeat; ++i) {
Expand Down Expand Up @@ -357,234 +444,27 @@ void run_experiment(crsGraph_t crsGraph, int num_cols,
<< std::endl;

std::cout << "\t";
KokkosKernels::Impl::print_1Dview(
kh.get_distance2_graph_coloring_handle()->get_vertex_colors());
auto colors = kh.get_distance2_graph_coloring_handle()->get_vertex_colors();
KokkosKernels::Impl::print_1Dview(colors);
std::cout << std::endl;

// If verbose mode is on and there the graph has fewer than 1500 verts, dump
// a GraphVIZ DOT file.
if (verbose && repeat == i + 1 && crsGraph.numRows() < 1500) {
auto colors =
kh.get_distance2_graph_coloring_handle()->get_vertex_colors();
std::ofstream os("G.dot", std::ofstream::out);
kh.get_distance2_graph_coloring_handle()->dump_graphviz(
os, crsGraph.numRows(), crsGraph.row_map, crsGraph.entries, colors);
}

// ------------------------------------------
// Verify correctness
// Verify correctness (for undirected/symmetric D2 coloring only, not
// bipartite)
// ------------------------------------------
// TODO bmk: write a faster color verification
/*
bool d2_coloring_is_valid = false;
bool d2_coloring_validation_flags[4] = { false };
d2_coloring_is_valid = KokkosGraph::Impl::graph_verify_distance2_color(&kh,
crsGraph.numRows(), num_cols, crsGraph.row_map, crsGraph.entries,
crsGraph.row_map, crsGraph.entries, d2_coloring_validation_flags);
// Print out messages based on coloring validation check.
if(d2_coloring_is_valid)
{
std::cout << std::endl << "Distance-2 Graph Coloring is VALID" <<
std::endl << std::endl;
}
else
{
all_results_valid = false;
if (verbose && params.d2_color_type == MODE_D2_SYMMETRIC) {
if (verifyD2Coloring<lno_t, size_type, decltype(crsGraph.row_map),
decltype(crsGraph.entries), decltype(colors)>(
crsGraph.numRows(), crsGraph.row_map, crsGraph.entries, colors)) {
std::cout << std::endl
<< "Distance-2 Graph Coloring is NOT VALID" << std::endl
<< " - Vert(s) left uncolored : " <<
d2_coloring_validation_flags[1] << std::endl
<< " - Invalid D2 Coloring : " <<
d2_coloring_validation_flags[2] << std::endl
<< std::endl;
}
if(d2_coloring_validation_flags[3])
{
std::cout << "Distance-2 Graph Coloring may have poor quality." <<
std::endl
<< " - Vert(s) have high color value : " <<
d2_coloring_validation_flags[3] << std::endl
<< "Distance-2 Graph Coloring is VALID" << std::endl
<< std::endl;
} else {
std::cout << std::endl
<< "Distance-2 Graph Coloring is NOT VALID" << std::endl;
}
}
*/

// ------------------------------------------
// Print out the colors histogram
// ------------------------------------------
KokkosGraph::Impl::graph_print_distance2_color_histogram(&kh, false);

} // for i...

// ------------------------------------------
// Compute Distance 2 Degree Stats
// ------------------------------------------
std::cout << "Compute Distance-2 Degree " << std::endl;

Kokkos::Timer timer;

double total_time =
kh.get_distance2_graph_coloring_handle()->get_overall_coloring_time();
double total_time_color_greedy = kh.get_distance2_graph_coloring_handle()
->get_overall_coloring_time_phase1();
double total_time_find_conflicts = kh.get_distance2_graph_coloring_handle()
->get_overall_coloring_time_phase2();
double total_time_resolve_conflicts =
kh.get_distance2_graph_coloring_handle()
->get_overall_coloring_time_phase3();
double total_time_matrix_squared = kh.get_distance2_graph_coloring_handle()
->get_overall_coloring_time_phase4();
double total_time_matrix_squared_d1 =
kh.get_distance2_graph_coloring_handle()
->get_overall_coloring_time_phase5();

double avg_time = total_time / (double)repeat;
double avg_time_color_greedy = total_time_color_greedy / (double)repeat;
double avg_time_find_conflicts = total_time_find_conflicts / (double)repeat;
double avg_time_resolve_conflicts =
total_time_resolve_conflicts / (double)repeat;
double avg_colors = total_colors / (double)repeat;
double avg_phases = total_phases / (double)repeat;
double avg_time_matrix_squared = total_time_matrix_squared / (double)repeat;
double avg_time_matrix_squared_d1 =
total_time_matrix_squared_d1 / (double)repeat;

std::string short_mtx_file(params.mtx_file);
short_mtx_file =
short_mtx_file.substr(short_mtx_file.find_last_of("/\\") + 1);

int result;
char hostname[100];
char username[100];

result = gethostname(hostname, 100);
if (result) {
perror("gethostname");
}

result = getlogin_r(username, 100);
if (result) {
perror("getlogin_r");
}

std::string all_results_valid_str = "PASSED";
if (!all_results_valid) all_results_valid_str = "FAILED";

std::string currentDateTimeStr = getCurrentDateTimeStr();

std::cout << "Summary" << std::endl
<< "-------" << std::endl
<< " Date/Time : " << currentDateTimeStr << std::endl
<< " KExecSName : " << Kokkos::DefaultExecutionSpace::name()
<< std::endl
<< " Filename : " << short_mtx_file << std::endl
<< " Num Verts : " << crsGraph.numRows() << std::endl
<< " Num Edges : " << crsGraph.entries.extent(0)
<< std::endl
<< " Concurrency : "
<< Kokkos::DefaultExecutionSpace::concurrency() << std::endl
<< " Algorithm : " << label_algorithm << std::endl
<< "Overall Time/Stats" << std::endl
<< " Total Time : " << total_time << std::endl
<< " Avg Time : " << avg_time << std::endl
<< "VB Distance[1|2] Stats " << std::endl
<< " Avg Time CG : " << avg_time_color_greedy << std::endl
<< " Avg Time FC : " << avg_time_find_conflicts << std::endl
<< " Avg Time RC : " << avg_time_resolve_conflicts
<< std::endl
<< "Matrix-Squared + D1 Stats" << std::endl
<< " Avg Time to M^2: " << avg_time_matrix_squared << std::endl
<< " Avg Time to D1 : " << avg_time_matrix_squared_d1
<< std::endl
<< "Coloring Stats" << std::endl
<< " Avg colors : " << avg_colors << std::endl
<< " Avg Phases : " << avg_phases << std::endl
<< " Validation : " << all_results_valid_str << std::endl
<< std::endl;

std::cout << "CSVTIMEHDR"
<< ","
<< "Filename"
<< ","
<< "Host"
<< ","
<< "DateTime"
<< ","
<< "Num Rows"
<< ","
<< "Num Edges"
<< ","
<< "Execution Space"
<< ","
<< "Algorithm"
<< ","
<< "Concurrency"
<< ","
<< "Repetitions"
<< ","
<< "Total Time"
<< ","
<< "Total Time to M^2"
<< ","
<< "Total Time D1(M^2)"
<< ","
<< "Total Time CG"
<< ","
<< "Total Time FC"
<< ","
<< "Total Time RC"
<< ","
<< "Avg Colors"
<< ","
<< "Avg Num Phases"
<< ","
<< "Validation" << std::endl;

std::cout << "CSVTIMEDATA"
<< "," << short_mtx_file << "," << hostname << ","
<< currentDateTimeStr << "," << crsGraph.numRows() << ","
<< crsGraph.entries.extent(0) << ","
<< Kokkos::DefaultExecutionSpace::name() << "," << label_algorithm
<< "," << Kokkos::DefaultExecutionSpace::concurrency() << ","
<< repeat << "," << total_time << "," << total_time_matrix_squared
<< "," << total_time_matrix_squared_d1 << ","
<< total_time_color_greedy << "," << total_time_find_conflicts
<< "," << total_time_resolve_conflicts

<< "," << avg_colors << "," << avg_phases << ","
<< all_results_valid_str << std::endl;

std::cout << "CSVHISTHDR"
<< ","
<< "Filename"
<< ","
<< "Host"
<< ","
<< "DateTime"
<< ","
<< "Num Rows"
<< ","
<< "Num Edges"
<< ","
<< "Execution Space"
<< ","
<< "Algorithm"
<< ","
<< "Concurrency"
<< ","
<< "Histogram: 1 .. N" << std::endl;

std::cout << "CSVHISTDATA"
<< "," << short_mtx_file << "," << hostname << ","
<< currentDateTimeStr << "," << crsGraph.numRows() << ","
<< crsGraph.entries.extent(0) << ","
<< Kokkos::DefaultExecutionSpace::name() << "," << label_algorithm
<< "," << Kokkos::DefaultExecutionSpace::concurrency() << ",";
KokkosGraph::Impl::graph_print_distance2_color_histogram(&kh, true);
std::cout << std::endl;

// Kokkos::print_configuration(std::cout);
}

template <typename size_type, typename lno_t, typename exec_space,
Expand Down

0 comments on commit 1170e96

Please sign in to comment.