Skip to content

Commit

Permalink
MG C++ test updates (#3371)
Browse files Browse the repository at this point in the history
* Generate a SG test graph from the MG graph (instead of re-creating assuming that the underlying random number generator output is deterministic for the same seed).
* Add a utility function to collect MG results to compare with SG results.

Additional bug fix
* Recent PR (#3285) mistakenly updated the code to use the same seed for every GPU. Fix this.
f86c2c5

Authors:
  - Seunghwa Kang (https://github.com/seunghwak)

Approvers:
  - Naim (https://github.com/naimnv)
  - Joseph Nke (https://github.com/jnke2016)
  - Chuck Hastings (https://github.com/ChuckHastings)

URL: #3371
  • Loading branch information
seunghwak authored Mar 31, 2023
1 parent 6242ea0 commit afd79ec
Show file tree
Hide file tree
Showing 48 changed files with 1,991 additions and 1,855 deletions.
10 changes: 10 additions & 0 deletions cpp/include/cugraph/graph_view.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -403,6 +403,11 @@ class graph_view_t<vertex_t, edge_t, store_transposed, multi_gpu, std::enable_if
return partition_.vertex_partition_range_lasts();
}

std::tuple<vertex_t, vertex_t> local_vertex_partition_range() const
{
return partition_.local_vertex_partition_range();
}

vertex_t local_vertex_partition_range_size() const
{
return partition_.local_vertex_partition_range_size();
Expand Down Expand Up @@ -805,6 +810,11 @@ class graph_view_t<vertex_t, edge_t, store_transposed, multi_gpu, std::enable_if
return std::vector<vertex_t>{local_vertex_partition_range_last()};
}

std::tuple<vertex_t, vertex_t> local_vertex_partition_range() const
{
return std::make_tuple(vertex_t{0}, this->number_of_vertices());
}

vertex_t local_vertex_partition_range_size() const { return this->number_of_vertices(); }

constexpr vertex_t local_vertex_partition_range_first() const { return vertex_t{0}; }
Expand Down
11 changes: 2 additions & 9 deletions cpp/src/c_api/random.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,15 +66,8 @@ struct select_random_vertices_functor : public cugraph::c_api::abstract_functor

rmm::device_uvector<vertex_t> local_vertices(0, handle_.get_stream());

if (!multi_gpu || (handle_.get_comms().get_rank() == 0)) {
local_vertices = cugraph::select_random_vertices(
handle_, graph_view, rng_state_->rng_state_, num_vertices_, false, false);
}

if constexpr (multi_gpu) {
local_vertices = cugraph::detail::shuffle_int_vertices_to_local_gpu_by_vertex_partitioning(
handle_, std::move(local_vertices), graph_view.vertex_partition_range_lasts());
}
local_vertices = cugraph::select_random_vertices(
handle_, graph_view, rng_state_->rng_state_, num_vertices_, false, false);

cugraph::unrenumber_int_vertices<vertex_t, multi_gpu>(
handle_,
Expand Down
415 changes: 251 additions & 164 deletions cpp/tests/c_api/mg_generate_rmat_test.c

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions cpp/tests/centrality/betweenness_centrality_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -125,8 +125,8 @@ class Tests_BetweennessCentrality

auto d_reference_centralities = cugraph::test::to_device(handle, h_reference_centralities);

cugraph::test::betweenness_centrality_validate<vertex_t, weight_t>(
handle, std::nullopt, d_centralities, std::nullopt, d_reference_centralities);
cugraph::test::betweenness_centrality_validate(
handle, d_centralities, d_reference_centralities);
}
}
};
Expand Down
47 changes: 7 additions & 40 deletions cpp/tests/centrality/betweenness_centrality_validate.cu
Original file line number Diff line number Diff line change
Expand Up @@ -24,40 +24,17 @@
namespace cugraph {
namespace test {

template <typename vertex_t, typename weight_t>
void betweenness_centrality_validate(
raft::handle_t const& handle,
std::optional<rmm::device_uvector<vertex_t>> const& d_cugraph_vertex_ids,
rmm::device_uvector<weight_t>& d_cugraph_results,
std::optional<rmm::device_uvector<vertex_t>> const& d_reference_vertex_ids,
rmm::device_uvector<weight_t>& d_reference_results)
template <typename weight_t>
void betweenness_centrality_validate(raft::handle_t const& handle,
rmm::device_uvector<weight_t>& d_cugraph_results,
rmm::device_uvector<weight_t>& d_reference_results)
{
auto compare_functor = cugraph::test::device_nearly_equal<weight_t>{
weight_t{1e-3},
weight_t{(weight_t{1} / static_cast<weight_t>(d_cugraph_results.size())) * weight_t{1e-3}}};

EXPECT_EQ(d_cugraph_results.size(), d_reference_results.size());

if (d_cugraph_vertex_ids) {
rmm::device_uvector<vertex_t> tmp_keys(d_cugraph_vertex_ids->size(), handle.get_stream());
thrust::copy(handle.get_thrust_policy(),
d_cugraph_vertex_ids->begin(),
d_cugraph_vertex_ids->end(),
tmp_keys.begin());
thrust::sort_by_key(
handle.get_thrust_policy(), tmp_keys.begin(), tmp_keys.end(), d_cugraph_results.begin());
}

if (d_reference_vertex_ids) {
rmm::device_uvector<vertex_t> tmp_keys(d_reference_vertex_ids->size(), handle.get_stream());
thrust::copy(handle.get_thrust_policy(),
d_reference_vertex_ids->begin(),
d_reference_vertex_ids->end(),
tmp_keys.begin());
thrust::sort_by_key(
handle.get_thrust_policy(), tmp_keys.begin(), tmp_keys.end(), d_reference_results.begin());
}

EXPECT_TRUE(thrust::equal(handle.get_thrust_policy(),
d_cugraph_results.begin(),
d_cugraph_results.end(),
Expand Down Expand Up @@ -102,19 +79,9 @@ void edge_betweenness_centrality_validate(raft::handle_t const& handle,
<< "Mismatch in centrality results";
}

template void betweenness_centrality_validate(
raft::handle_t const& handle,
std::optional<rmm::device_uvector<int32_t>> const& d_cugraph_vertex_ids,
rmm::device_uvector<float>& d_cugraph_results,
std::optional<rmm::device_uvector<int32_t>> const& d_reference_vertex_ids,
rmm::device_uvector<float>& d_reference_results);

template void betweenness_centrality_validate(
raft::handle_t const& handle,
std::optional<rmm::device_uvector<int64_t>> const& d_cugraph_vertex_ids,
rmm::device_uvector<float>& d_cugraph_results,
std::optional<rmm::device_uvector<int64_t>> const& d_reference_vertex_ids,
rmm::device_uvector<float>& d_reference_results);
template void betweenness_centrality_validate(raft::handle_t const& handle,
rmm::device_uvector<float>& d_cugraph_results,
rmm::device_uvector<float>& d_reference_results);

template void edge_betweenness_centrality_validate(
raft::handle_t const& handle,
Expand Down
11 changes: 4 additions & 7 deletions cpp/tests/centrality/betweenness_centrality_validate.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,10 @@
namespace cugraph {
namespace test {

template <typename vertex_t, typename weight_t>
void betweenness_centrality_validate(
raft::handle_t const& handle,
std::optional<rmm::device_uvector<vertex_t>> const& d_cugraph_vertex_ids,
rmm::device_uvector<weight_t>& d_cugraph_results,
std::optional<rmm::device_uvector<vertex_t>> const& d_reference_vertex_ids,
rmm::device_uvector<weight_t>& d_reference_results);
template <typename weight_t>
void betweenness_centrality_validate(raft::handle_t const& handle,
rmm::device_uvector<weight_t>& d_cugraph_results,
rmm::device_uvector<weight_t>& d_reference_results);

template <typename vertex_t, typename weight_t>
void edge_betweenness_centrality_validate(raft::handle_t const& handle,
Expand Down
98 changes: 42 additions & 56 deletions cpp/tests/centrality/mg_betweenness_centrality_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,6 @@ class Tests_MGBetweennessCentrality
template <typename vertex_t, typename edge_t, typename weight_t>
void run_current_test(std::tuple<BetweennessCentrality_Usecase, input_usecase_t> const& param)
{
constexpr bool renumber = true;
constexpr bool do_expensive_check = false;

int my_rank = handle_->get_comms().get_rank();

auto [betweenness_usecase, input_usecase] = param;

HighResTimer hr_timer{};
Expand All @@ -74,7 +69,7 @@ class Tests_MGBetweennessCentrality

auto [mg_graph, mg_edge_weights, mg_renumber_map] =
cugraph::test::construct_graph<vertex_t, edge_t, weight_t, false, true>(
*handle_, input_usecase, betweenness_usecase.test_weighted, renumber);
*handle_, input_usecase, betweenness_usecase.test_weighted, true);

if (cugraph::test::g_perf) {
RAFT_CUDA_TRY(cudaDeviceSynchronize()); // for consistent performance measurement
Expand All @@ -88,7 +83,7 @@ class Tests_MGBetweennessCentrality
mg_edge_weights ? std::make_optional((*mg_edge_weights).view()) : std::nullopt;

raft::random::RngState rng_state(handle_->get_comms().get_rank());
auto d_seeds = cugraph::select_random_vertices(
auto d_mg_seeds = cugraph::select_random_vertices(
*handle_, mg_graph_view, rng_state, betweenness_usecase.num_seeds, false, true);

if (cugraph::test::g_perf) {
Expand All @@ -97,15 +92,14 @@ class Tests_MGBetweennessCentrality
hr_timer.start("MG betweenness centrality");
}

auto d_centralities = cugraph::betweenness_centrality(
auto d_mg_centralities = cugraph::betweenness_centrality(
*handle_,
mg_graph_view,
mg_edge_weight_view,
std::make_optional<raft::device_span<vertex_t const>>(
raft::device_span<vertex_t const>{d_seeds.data(), d_seeds.size()}),
raft::device_span<vertex_t const>{d_mg_seeds.data(), d_mg_seeds.size()}),
betweenness_usecase.normalized,
betweenness_usecase.include_endpoints,
do_expensive_check);
betweenness_usecase.include_endpoints);

if (cugraph::test::g_perf) {
RAFT_CUDA_TRY(cudaDeviceSynchronize()); // for consistent performance measurement
Expand All @@ -117,59 +111,53 @@ class Tests_MGBetweennessCentrality
if (betweenness_usecase.check_correctness) {
if (mg_renumber_map) {
cugraph::unrenumber_local_int_vertices(*handle_,
d_seeds.data(),
d_seeds.size(),
d_mg_seeds.data(),
d_mg_seeds.size(),
(*mg_renumber_map).data(),
mg_graph_view.local_vertex_partition_range_first(),
mg_graph_view.local_vertex_partition_range_last());
}

d_seeds = cugraph::test::device_gatherv(
*handle_, raft::device_span<vertex_t const>{d_seeds.data(), d_seeds.size()});

auto [sg_graph, sg_edge_weights, sg_renumber_map] = cugraph::test::mg_graph_to_sg_graph(
*handle_,
mg_graph_view,
mg_edge_weight_view,
mg_renumber_map ? std::make_optional<raft::device_span<vertex_t const>>(
(*mg_renumber_map).data(), (*mg_renumber_map).size())
: std::nullopt,
false);
auto d_mg_aggregate_seeds = cugraph::test::device_gatherv(
*handle_, raft::device_span<vertex_t const>{d_mg_seeds.data(), d_mg_seeds.size()});

auto sg_graph_view = sg_graph.view();

if (sg_renumber_map) {
cugraph::renumber_ext_vertices<vertex_t, false>(
rmm::device_uvector<weight_t> d_mg_aggregate_centralities(0, handle_->get_stream());
std::tie(std::ignore, d_mg_aggregate_centralities) =
cugraph::test::mg_vertex_property_values_to_sg_vertex_property_values(
*handle_,
d_seeds.data(),
d_seeds.size(),
(*sg_renumber_map).data(),
sg_graph_view.local_vertex_partition_range_first(),
sg_graph_view.local_vertex_partition_range_last());
}

if (mg_renumber_map) {
mg_renumber_map = cugraph::test::device_gatherv(
*handle_,
raft::device_span<vertex_t const>((*mg_renumber_map).data(), (*mg_renumber_map).size()));
}

d_centralities = cugraph::test::device_gatherv(
*handle_, raft::device_span<weight_t const>{d_centralities.data(), d_centralities.size()});

if (my_rank == 0) {
auto d_reference_centralities = cugraph::betweenness_centrality(
std::make_optional<raft::device_span<vertex_t const>>((*mg_renumber_map).data(),
(*mg_renumber_map).size()),
mg_graph_view.local_vertex_partition_range(),
std::optional<raft::device_span<vertex_t const>>{std::nullopt},
std::optional<raft::device_span<vertex_t const>>{std::nullopt},
raft::device_span<weight_t const>(d_mg_centralities.data(), d_mg_centralities.size()));

cugraph::graph_t<vertex_t, edge_t, false, false> sg_graph(*handle_);
std::optional<
cugraph::edge_property_t<cugraph::graph_view_t<vertex_t, edge_t, false, false>, weight_t>>
sg_edge_weights{std::nullopt};
std::tie(sg_graph, sg_edge_weights, std::ignore) =
cugraph::test::mg_graph_to_sg_graph(*handle_,
mg_graph_view,
mg_edge_weight_view,
std::make_optional<raft::device_span<vertex_t const>>(
(*mg_renumber_map).data(), (*mg_renumber_map).size()),
false);

if (handle_->get_comms().get_rank() == 0) {
auto sg_graph_view = sg_graph.view();

auto d_sg_centralities = cugraph::betweenness_centrality(
*handle_,
sg_graph_view,
sg_edge_weights ? std::make_optional((*sg_edge_weights).view()) : std::nullopt,
std::make_optional<raft::device_span<vertex_t const>>(
raft::device_span<vertex_t const>{d_seeds.data(), d_seeds.size()}),
std::make_optional<raft::device_span<vertex_t const>>(raft::device_span<vertex_t const>{
d_mg_aggregate_seeds.data(), d_mg_aggregate_seeds.size()}),
betweenness_usecase.normalized,
betweenness_usecase.include_endpoints,
do_expensive_check);
betweenness_usecase.include_endpoints);

cugraph::test::betweenness_centrality_validate<vertex_t, weight_t>(
*handle_, mg_renumber_map, d_centralities, sg_renumber_map, d_reference_centralities);
cugraph::test::betweenness_centrality_validate(
*handle_, d_mg_aggregate_centralities, d_sg_centralities);
}
}
}
Expand Down Expand Up @@ -232,8 +220,7 @@ INSTANTIATE_TEST_SUITE_P(
::testing::Combine(
::testing::Values(BetweennessCentrality_Usecase{50, false, false, false, false},
BetweennessCentrality_Usecase{50, false, false, true, false}),
::testing::Values(
cugraph::test::Rmat_Usecase(10, 16, 0.57, 0.19, 0.19, 0, true, false, 0, true))));
::testing::Values(cugraph::test::Rmat_Usecase(10, 16, 0.57, 0.19, 0.19, 0, true, false))));

INSTANTIATE_TEST_SUITE_P(
rmat_benchmark_test, /* note that scale & edge factor can be overridden in benchmarking (with
Expand All @@ -246,7 +233,6 @@ INSTANTIATE_TEST_SUITE_P(
::testing::Combine(
::testing::Values(BetweennessCentrality_Usecase{500, false, false, false, false},
BetweennessCentrality_Usecase{500, false, false, true, false}),
::testing::Values(
cugraph::test::Rmat_Usecase(20, 32, 0.57, 0.19, 0.19, 0, false, false, 0, true))));
::testing::Values(cugraph::test::Rmat_Usecase(20, 32, 0.57, 0.19, 0.19, 0, false, false))));

CUGRAPH_MG_TEST_PROGRAM_MAIN()
29 changes: 12 additions & 17 deletions cpp/tests/centrality/mg_edge_betweenness_centrality_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,6 @@ class Tests_MGEdgeBetweennessCentrality
template <typename vertex_t, typename edge_t, typename weight_t>
void run_current_test(std::tuple<EdgeBetweennessCentrality_Usecase, input_usecase_t> const& param)
{
constexpr bool renumber = true;
constexpr bool do_expensive_check = false;

auto [betweenness_usecase, input_usecase] = param;

HighResTimer hr_timer{};
Expand All @@ -70,9 +67,9 @@ class Tests_MGEdgeBetweennessCentrality
hr_timer.start("MG Construct graph");
}

auto [mg_graph, mg_edge_weights, d_renumber_map_labels] =
auto [mg_graph, mg_edge_weights, mg_renumber_map] =
cugraph::test::construct_graph<vertex_t, edge_t, weight_t, false, true>(
*handle_, input_usecase, betweenness_usecase.test_weighted, renumber);
*handle_, input_usecase, betweenness_usecase.test_weighted, true);

if (cugraph::test::g_perf) {
RAFT_CUDA_TRY(cudaDeviceSynchronize()); // for consistent performance measurement
Expand Down Expand Up @@ -102,17 +99,15 @@ class Tests_MGEdgeBetweennessCentrality
mg_edge_weight_view,
std::make_optional<raft::device_span<vertex_t const>>(
raft::device_span<vertex_t const>{d_seeds.data(), d_seeds.size()}),
betweenness_usecase.normalized,
do_expensive_check);
betweenness_usecase.normalized);
#else
EXPECT_THROW(cugraph::edge_betweenness_centrality(
*handle_,
mg_graph_view,
mg_edge_weight_view,
std::make_optional<raft::device_span<vertex_t const>>(
raft::device_span<vertex_t const>{d_seeds.data(), d_seeds.size()}),
betweenness_usecase.normalized,
do_expensive_check),
betweenness_usecase.normalized),
cugraph::logic_error);
#endif

Expand Down Expand Up @@ -197,10 +192,10 @@ INSTANTIATE_TEST_SUITE_P(
rmat_small_test,
Tests_MGEdgeBetweennessCentrality_Rmat,
// enable correctness checks
::testing::Combine(::testing::Values(EdgeBetweennessCentrality_Usecase{50, false, false, true},
EdgeBetweennessCentrality_Usecase{50, false, true, true}),
::testing::Values(cugraph::test::Rmat_Usecase(
10, 16, 0.57, 0.19, 0.19, 0, true, false, 0, true))));
::testing::Combine(
::testing::Values(EdgeBetweennessCentrality_Usecase{50, false, false, true},
EdgeBetweennessCentrality_Usecase{50, false, true, true}),
::testing::Values(cugraph::test::Rmat_Usecase(10, 16, 0.57, 0.19, 0.19, 0, true, false))));

INSTANTIATE_TEST_SUITE_P(
rmat_benchmark_test, /* note that scale & edge factor can be overridden in benchmarking (with
Expand All @@ -210,9 +205,9 @@ INSTANTIATE_TEST_SUITE_P(
factor (to avoid running same benchmarks more than once) */
Tests_MGEdgeBetweennessCentrality_Rmat,
// disable correctness checks for large graphs
::testing::Combine(::testing::Values(EdgeBetweennessCentrality_Usecase{500, false, false, false},
EdgeBetweennessCentrality_Usecase{500, false, true, false}),
::testing::Values(cugraph::test::Rmat_Usecase(
20, 32, 0.57, 0.19, 0.19, 0, false, false, 0, true))));
::testing::Combine(
::testing::Values(EdgeBetweennessCentrality_Usecase{500, false, false, false},
EdgeBetweennessCentrality_Usecase{500, false, true, false}),
::testing::Values(cugraph::test::Rmat_Usecase(20, 32, 0.57, 0.19, 0.19, 0, false, false))));

CUGRAPH_MG_TEST_PROGRAM_MAIN()
Loading

0 comments on commit afd79ec

Please sign in to comment.