From 6ce0b6156f658b1b621b07ae3cfcd9b385aae5b0 Mon Sep 17 00:00:00 2001 From: Naim Date: Wed, 6 Dec 2023 16:44:22 +0100 Subject: [PATCH] Add rng state to Louvain --- cpp/include/cugraph/algorithms.hpp | 4 ++- cpp/src/c_api/louvain.cpp | 25 ++++++------- cpp/src/community/ecg_impl.cuh | 25 +++++++------ cpp/src/community/ecg_mg.cu | 18 ++++++---- cpp/src/community/ecg_sg.cu | 18 ++++++---- cpp/src/community/louvain_impl.cuh | 28 ++++++--------- cpp/src/community/louvain_mg.cu | 12 +++++++ cpp/src/community/louvain_sg.cu | 12 +++++++ cpp/tests/community/louvain_test.cpp | 48 +++++++++++++++---------- cpp/tests/community/mg_louvain_test.cpp | 17 +++++---- 10 files changed, 128 insertions(+), 79 deletions(-) diff --git a/cpp/include/cugraph/algorithms.hpp b/cpp/include/cugraph/algorithms.hpp index e9f6f79710b..99a4d68dacc 100644 --- a/cpp/include/cugraph/algorithms.hpp +++ b/cpp/include/cugraph/algorithms.hpp @@ -565,6 +565,7 @@ weight_t hungarian(raft::handle_t const& handle, template std::pair louvain( raft::handle_t const& handle, + std::optional> rng_state, graph_view_t const& graph_view, std::optional> edge_weight_view, vertex_t* clustering, @@ -612,6 +613,7 @@ std::pair louvain( template std::pair>, weight_t> louvain( raft::handle_t const& handle, + std::optional> rng_state, graph_view_t const& graph_view, std::optional> edge_weight_view, size_t max_level = 100, @@ -814,9 +816,9 @@ void ecg(raft::handle_t const& handle, template std::tuple, size_t, weight_t> ecg( raft::handle_t const& handle, + raft::random::RngState& rng_state, graph_view_t const& graph_view, std::optional> edge_weight_view, - raft::random::RngState& rng_state, weight_t min_weight, size_t ensemble_size, size_t max_level = 100, diff --git a/cpp/src/c_api/louvain.cpp b/cpp/src/c_api/louvain.cpp index 0e48b29388a..bcb3b8d2ebc 100644 --- a/cpp/src/c_api/louvain.cpp +++ b/cpp/src/c_api/louvain.cpp @@ -95,18 +95,19 @@ struct louvain_functor : public cugraph::c_api::abstract_functor { // could add support in Louvain for std::nullopt as the edge weights behaving // as desired and only instantiating a real edge_property_view_t for the // coarsened graphs. - auto [level, modularity] = - cugraph::louvain(handle_, - graph_view, - (edge_weights != nullptr) - ? std::make_optional(edge_weights->view()) - : std::make_optional(cugraph::c_api::create_constant_edge_property( - handle_, graph_view, weight_t{1}) - .view()), - clusters.data(), - max_level_, - static_cast(threshold_), - static_cast(resolution_)); + auto [level, modularity] = cugraph::louvain( + handle_, + std::optional>{std::nullopt}, + graph_view, + (edge_weights != nullptr) + ? std::make_optional(edge_weights->view()) + : std::make_optional( + cugraph::c_api::create_constant_edge_property(handle_, graph_view, weight_t{1}) + .view()), + clusters.data(), + max_level_, + static_cast(threshold_), + static_cast(resolution_)); rmm::device_uvector vertices(graph_view.local_vertex_partition_range_size(), handle_.get_stream()); diff --git a/cpp/src/community/ecg_impl.cuh b/cpp/src/community/ecg_impl.cuh index 74de35a0d12..c325dbac4b1 100644 --- a/cpp/src/community/ecg_impl.cuh +++ b/cpp/src/community/ecg_impl.cuh @@ -17,9 +17,9 @@ namespace detail { template std::tuple, size_t, weight_t> ecg( raft::handle_t const& handle, + raft::random::RngState& rng_state, graph_view_t const& graph_view, std::optional> edge_weight_view, - raft::random::RngState& rng_state, weight_t min_weight, size_t ensemble_size, size_t max_level, @@ -40,13 +40,15 @@ std::tuple, size_t, weight_t> ecg( handle.get_stream()); for (size_t i = 0; i < ensemble_size; i++) { - std::tie(std::ignore, modularity) = cugraph::louvain(handle, - graph_view, - edge_weight_view, - cluster_assignments.data(), - size_t{1}, - threshold, - resolution); + std::tie(std::ignore, modularity) = cugraph::louvain( + handle, + std::make_optional(std::reference_wrapper(rng_state)), + graph_view, + edge_weight_view, + cluster_assignments.data(), + size_t{1}, + threshold, + resolution); // std::tie(std::ignore, modularity) = cugraph::leiden(handle, // rng_state, @@ -132,13 +134,14 @@ std::tuple, size_t, weight_t> ecg( static_cast(e_weight), static_cast(e_frequency)); - return min_weight + e_weight * e_frequency / ensemble_size; + return min_weight + (e_weight - min_weight) * e_frequency / ensemble_size; }, modified_edge_weights.mutable_view()); std::tie(max_level, modularity) = cugraph::louvain(handle, + std::make_optional(std::reference_wrapper(rng_state)), graph_view, std::make_optional(modified_edge_weights.view()), cluster_assignments.data(), @@ -171,9 +174,9 @@ std::tuple, size_t, weight_t> ecg( template std::tuple, size_t, weight_t> ecg( raft::handle_t const& handle, + raft::random::RngState& rng_state, graph_view_t const& graph_view, std::optional> edge_weight_view, - raft::random::RngState& rng_state, weight_t min_weight, size_t ensemble_size, size_t max_level, @@ -181,9 +184,9 @@ std::tuple, size_t, weight_t> ecg( weight_t resolution) { return detail::ecg(handle, + rng_state, graph_view, edge_weight_view, - rng_state, min_weight, ensemble_size, max_level, diff --git a/cpp/src/community/ecg_mg.cu b/cpp/src/community/ecg_mg.cu index 61cd71386f9..f25640c3ab4 100644 --- a/cpp/src/community/ecg_mg.cu +++ b/cpp/src/community/ecg_mg.cu @@ -4,9 +4,10 @@ namespace cugraph { template std::tuple, size_t, float> ecg( raft::handle_t const& handle, + raft::random::RngState& rng_state, graph_view_t const& graph_view, std::optional> edge_weight_view, - raft::random::RngState& rng_state, + float min_weight, size_t ensemble_size, size_t max_level, @@ -15,9 +16,10 @@ template std::tuple, size_t, float> ecg( template std::tuple, size_t, float> ecg( raft::handle_t const& handle, + raft::random::RngState& rng_state, graph_view_t const& graph_view, std::optional> edge_weight_view, - raft::random::RngState& rng_state, + float min_weight, size_t ensemble_size, size_t max_level, @@ -26,9 +28,10 @@ template std::tuple, size_t, float> ecg( template std::tuple, size_t, float> ecg( raft::handle_t const& handle, + raft::random::RngState& rng_state, graph_view_t const& graph_view, std::optional> edge_weight_view, - raft::random::RngState& rng_state, + float min_weight, size_t ensemble_size, size_t max_level, @@ -37,9 +40,10 @@ template std::tuple, size_t, float> ecg( template std::tuple, size_t, double> ecg( raft::handle_t const& handle, + raft::random::RngState& rng_state, graph_view_t const& graph_view, std::optional> edge_weight_view, - raft::random::RngState& rng_state, + double min_weight, size_t ensemble_size, size_t max_level, @@ -48,9 +52,10 @@ template std::tuple, size_t, double> ecg( template std::tuple, size_t, double> ecg( raft::handle_t const& handle, + raft::random::RngState& rng_state, graph_view_t const& graph_view, std::optional> edge_weight_view, - raft::random::RngState& rng_state, + double min_weight, size_t ensemble_size, size_t max_level, @@ -59,9 +64,10 @@ template std::tuple, size_t, double> ecg( template std::tuple, size_t, double> ecg( raft::handle_t const& handle, + raft::random::RngState& rng_state, graph_view_t const& graph_view, std::optional> edge_weight_view, - raft::random::RngState& rng_state, + double min_weight, size_t ensemble_size, size_t max_level, diff --git a/cpp/src/community/ecg_sg.cu b/cpp/src/community/ecg_sg.cu index 9b32fe7b32e..f73b4046740 100644 --- a/cpp/src/community/ecg_sg.cu +++ b/cpp/src/community/ecg_sg.cu @@ -3,9 +3,10 @@ namespace cugraph { template std::tuple, size_t, float> ecg( raft::handle_t const& handle, + raft::random::RngState& rng_state, graph_view_t const& graph_view, std::optional> edge_weight_view, - raft::random::RngState& rng_state, + float min_weight, size_t ensemble_size, size_t max_level, @@ -14,9 +15,10 @@ template std::tuple, size_t, float> ecg( template std::tuple, size_t, float> ecg( raft::handle_t const& handle, + raft::random::RngState& rng_state, graph_view_t const& graph_view, std::optional> edge_weight_view, - raft::random::RngState& rng_state, + float min_weight, size_t ensemble_size, size_t max_level, @@ -25,9 +27,10 @@ template std::tuple, size_t, float> ecg( template std::tuple, size_t, float> ecg( raft::handle_t const& handle, + raft::random::RngState& rng_state, graph_view_t const& graph_view, std::optional> edge_weight_view, - raft::random::RngState& rng_state, + float min_weight, size_t ensemble_size, size_t max_level, @@ -36,9 +39,10 @@ template std::tuple, size_t, float> ecg( template std::tuple, size_t, double> ecg( raft::handle_t const& handle, + raft::random::RngState& rng_state, graph_view_t const& graph_view, std::optional> edge_weight_view, - raft::random::RngState& rng_state, + double min_weight, size_t ensemble_size, size_t max_level, @@ -47,9 +51,10 @@ template std::tuple, size_t, double> ecg( template std::tuple, size_t, double> ecg( raft::handle_t const& handle, + raft::random::RngState& rng_state, graph_view_t const& graph_view, std::optional> edge_weight_view, - raft::random::RngState& rng_state, + double min_weight, size_t ensemble_size, size_t max_level, @@ -58,9 +63,10 @@ template std::tuple, size_t, double> ecg( template std::tuple, size_t, double> ecg( raft::handle_t const& handle, + raft::random::RngState& rng_state, graph_view_t const& graph_view, std::optional> edge_weight_view, - raft::random::RngState& rng_state, + double min_weight, size_t ensemble_size, size_t max_level, diff --git a/cpp/src/community/louvain_impl.cuh b/cpp/src/community/louvain_impl.cuh index ff3e3d68f35..effbbf81b67 100644 --- a/cpp/src/community/louvain_impl.cuh +++ b/cpp/src/community/louvain_impl.cuh @@ -45,12 +45,12 @@ void check_clustering(graph_view_t const& gr template std::pair>, weight_t> louvain( raft::handle_t const& handle, + std::optional> rng_state, graph_view_t const& graph_view, std::optional> edge_weight_view, size_t max_level, weight_t threshold, - weight_t resolution, - bool is_random_initial_cluster = false) + weight_t resolution) { using graph_t = cugraph::graph_t; using graph_view_t = cugraph::graph_view_t; @@ -84,18 +84,7 @@ std::pair>, weight_t> louvain( current_graph_view.local_vertex_partition_range_size(), handle.get_stream()); - if (is_random_initial_cluster) { - raft::random::RngState rng_state(0); - // rmm::device_uvector random_cluster_assignments = cugraph::select_random_vertices( - // handle, - // graph_view, - // std::optional>{std::nullopt}, - // rng_state, - // graph_view.number_of_vertices(), - // false, - // false, - // true); - + if (rng_state) { rmm::device_uvector random_cluster_assignments( graph_view.local_vertex_partition_range_size(), handle.get_stream()); @@ -113,7 +102,7 @@ std::pair>, weight_t> louvain( random_numbers.size(), float{0.0}, float{1.0}, - rng_state); + *rng_state); thrust::sort_by_key(handle.get_thrust_policy(), random_numbers.begin(), random_numbers.end(), @@ -382,6 +371,7 @@ void flatten_dendrogram(raft::handle_t const& handle, template std::pair>, weight_t> louvain( raft::handle_t const& handle, + std::optional> rng_state, graph_view_t const& graph_view, std::optional> edge_weight_view, size_t max_level, @@ -391,7 +381,8 @@ std::pair>, weight_t> louvain( CUGRAPH_EXPECTS(!graph_view.has_edge_mask(), "unimplemented."); CUGRAPH_EXPECTS(edge_weight_view.has_value(), "Graph must be weighted"); - return detail::louvain(handle, graph_view, edge_weight_view, max_level, threshold, resolution); + return detail::louvain( + handle, rng_state, graph_view, edge_weight_view, max_level, threshold, resolution); } template @@ -408,6 +399,7 @@ void flatten_dendrogram(raft::handle_t const& handle, template std::pair louvain( raft::handle_t const& handle, + std::optional> rng_state, graph_view_t const& graph_view, std::optional> edge_weight_view, vertex_t* clustering, @@ -423,8 +415,8 @@ std::pair louvain( std::unique_ptr> dendrogram; weight_t modularity; - std::tie(dendrogram, modularity) = - detail::louvain(handle, graph_view, edge_weight_view, max_level, threshold, resolution); + std::tie(dendrogram, modularity) = detail::louvain( + handle, rng_state, graph_view, edge_weight_view, max_level, threshold, resolution); detail::flatten_dendrogram(handle, graph_view, *dendrogram, clustering); diff --git a/cpp/src/community/louvain_mg.cu b/cpp/src/community/louvain_mg.cu index 0be32ed049f..c84a94fb947 100644 --- a/cpp/src/community/louvain_mg.cu +++ b/cpp/src/community/louvain_mg.cu @@ -22,6 +22,7 @@ namespace cugraph { template std::pair>, float> louvain( raft::handle_t const&, + std::optional>, graph_view_t const&, std::optional>, size_t, @@ -29,6 +30,7 @@ template std::pair>, float> louvain( float); template std::pair>, float> louvain( raft::handle_t const&, + std::optional>, graph_view_t const&, std::optional>, size_t, @@ -36,6 +38,7 @@ template std::pair>, float> louvain( float); template std::pair>, float> louvain( raft::handle_t const&, + std::optional>, graph_view_t const&, std::optional>, size_t, @@ -43,6 +46,7 @@ template std::pair>, float> louvain( float); template std::pair>, double> louvain( raft::handle_t const&, + std::optional>, graph_view_t const&, std::optional>, size_t, @@ -50,6 +54,7 @@ template std::pair>, double> louvain( double); template std::pair>, double> louvain( raft::handle_t const&, + std::optional>, graph_view_t const&, std::optional>, size_t, @@ -57,6 +62,7 @@ template std::pair>, double> louvain( double); template std::pair>, double> louvain( raft::handle_t const&, + std::optional>, graph_view_t const&, std::optional>, size_t, @@ -65,6 +71,7 @@ template std::pair>, double> louvain( template std::pair louvain( raft::handle_t const&, + std::optional>, graph_view_t const&, std::optional>, int32_t*, @@ -73,6 +80,7 @@ template std::pair louvain( float); template std::pair louvain( raft::handle_t const&, + std::optional>, graph_view_t const&, std::optional>, int32_t*, @@ -81,6 +89,7 @@ template std::pair louvain( double); template std::pair louvain( raft::handle_t const&, + std::optional>, graph_view_t const&, std::optional>, int32_t*, @@ -89,6 +98,7 @@ template std::pair louvain( float); template std::pair louvain( raft::handle_t const&, + std::optional>, graph_view_t const&, std::optional>, int32_t*, @@ -97,6 +107,7 @@ template std::pair louvain( double); template std::pair louvain( raft::handle_t const&, + std::optional>, graph_view_t const&, std::optional>, int64_t*, @@ -105,6 +116,7 @@ template std::pair louvain( float); template std::pair louvain( raft::handle_t const&, + std::optional>, graph_view_t const&, std::optional>, int64_t*, diff --git a/cpp/src/community/louvain_sg.cu b/cpp/src/community/louvain_sg.cu index 3fc0ffab928..ccba05b9a7a 100644 --- a/cpp/src/community/louvain_sg.cu +++ b/cpp/src/community/louvain_sg.cu @@ -22,6 +22,7 @@ namespace cugraph { template std::pair>, float> louvain( raft::handle_t const&, + std::optional>, graph_view_t const&, std::optional>, size_t, @@ -29,6 +30,7 @@ template std::pair>, float> louvain( float); template std::pair>, float> louvain( raft::handle_t const&, + std::optional>, graph_view_t const&, std::optional>, size_t, @@ -36,6 +38,7 @@ template std::pair>, float> louvain( float); template std::pair>, float> louvain( raft::handle_t const&, + std::optional>, graph_view_t const&, std::optional>, size_t, @@ -43,6 +46,7 @@ template std::pair>, float> louvain( float); template std::pair>, double> louvain( raft::handle_t const&, + std::optional>, graph_view_t const&, std::optional>, size_t, @@ -50,6 +54,7 @@ template std::pair>, double> louvain( double); template std::pair>, double> louvain( raft::handle_t const&, + std::optional>, graph_view_t const&, std::optional>, size_t, @@ -57,6 +62,7 @@ template std::pair>, double> louvain( double); template std::pair>, double> louvain( raft::handle_t const&, + std::optional>, graph_view_t const&, std::optional>, size_t, @@ -65,6 +71,7 @@ template std::pair>, double> louvain( template std::pair louvain( raft::handle_t const&, + std::optional>, graph_view_t const&, std::optional>, int32_t*, @@ -73,6 +80,7 @@ template std::pair louvain( float); template std::pair louvain( raft::handle_t const&, + std::optional>, graph_view_t const&, std::optional>, int32_t*, @@ -81,6 +89,7 @@ template std::pair louvain( double); template std::pair louvain( raft::handle_t const&, + std::optional>, graph_view_t const&, std::optional>, int32_t*, @@ -89,6 +98,7 @@ template std::pair louvain( float); template std::pair louvain( raft::handle_t const&, + std::optional>, graph_view_t const&, std::optional>, int32_t*, @@ -97,6 +107,7 @@ template std::pair louvain( double); template std::pair louvain( raft::handle_t const&, + std::optional>, graph_view_t const&, std::optional>, int64_t*, @@ -105,6 +116,7 @@ template std::pair louvain( float); template std::pair louvain( raft::handle_t const&, + std::optional>, graph_view_t const&, std::optional>, int64_t*, diff --git a/cpp/tests/community/louvain_test.cpp b/cpp/tests/community/louvain_test.cpp index 284dcc94b8c..c153ff2951b 100644 --- a/cpp/tests/community/louvain_test.cpp +++ b/cpp/tests/community/louvain_test.cpp @@ -212,27 +212,39 @@ class Tests_Louvain weight_t modularity; if (resolution) { - std::tie(level, modularity) = - cugraph::louvain(handle, - graph_view, - edge_weight_view, - clustering_v.data(), - max_level ? *max_level : size_t{100}, - threshold ? static_cast(*threshold) : weight_t{1e-7}, - static_cast(*resolution)); + std::tie(level, modularity) = cugraph::louvain( + handle, + std::optional>{std::nullopt}, + graph_view, + edge_weight_view, + clustering_v.data(), + max_level ? *max_level : size_t{100}, + threshold ? static_cast(*threshold) : weight_t{1e-7}, + static_cast(*resolution)); } else if (threshold) { - std::tie(level, modularity) = cugraph::louvain(handle, - graph_view, - edge_weight_view, - clustering_v.data(), - max_level ? *max_level : size_t{100}, - static_cast(*threshold)); + std::tie(level, modularity) = cugraph::louvain( + handle, + std::optional>{std::nullopt}, + graph_view, + edge_weight_view, + clustering_v.data(), + max_level ? *max_level : size_t{100}, + static_cast(*threshold)); } else if (max_level) { - std::tie(level, modularity) = - cugraph::louvain(handle, graph_view, edge_weight_view, clustering_v.data(), *max_level); + std::tie(level, modularity) = cugraph::louvain( + handle, + std::optional>{std::nullopt}, + graph_view, + edge_weight_view, + clustering_v.data(), + *max_level); } else { - std::tie(level, modularity) = - cugraph::louvain(handle, graph_view, edge_weight_view, clustering_v.data()); + std::tie(level, modularity) = cugraph::louvain( + handle, + std::optional>{std::nullopt}, + graph_view, + edge_weight_view, + clustering_v.data()); } RAFT_CUDA_TRY(cudaDeviceSynchronize()); // for consistent performance measurement diff --git a/cpp/tests/community/mg_louvain_test.cpp b/cpp/tests/community/mg_louvain_test.cpp index 41339e32d77..507d6fc8bb2 100644 --- a/cpp/tests/community/mg_louvain_test.cpp +++ b/cpp/tests/community/mg_louvain_test.cpp @@ -126,13 +126,15 @@ class Tests_MGLouvain rmm::device_uvector d_sg_cluster_v(sg_graph_view.number_of_vertices(), handle_->get_stream()); - std::tie(std::ignore, sg_modularity) = cugraph::louvain(handle, - sg_graph_view, - sg_edge_weight_view, - d_sg_cluster_v.data(), - size_t{1}, - threshold, - resolution); + std::tie(std::ignore, sg_modularity) = cugraph::louvain( + handle, + std::optional>{std::nullopt}, + sg_graph_view, + sg_edge_weight_view, + d_sg_cluster_v.data(), + size_t{1}, + threshold, + resolution); EXPECT_TRUE(cugraph::test::check_invertible( handle, @@ -191,6 +193,7 @@ class Tests_MGLouvain auto [dendrogram, mg_modularity] = cugraph::louvain( *handle_, + std::optional>{std::nullopt}, mg_graph_view, mg_edge_weight_view, louvain_usecase.max_level_,