diff --git a/cpp/include/cugraph/algorithms.hpp b/cpp/include/cugraph/algorithms.hpp index 7715ce30882..3bef908a56d 100644 --- a/cpp/include/cugraph/algorithms.hpp +++ b/cpp/include/cugraph/algorithms.hpp @@ -18,6 +18,7 @@ #include #include +#include #include #include @@ -332,6 +333,8 @@ void edge_betweenness_centrality(const raft::handle_t& handle, * @param handle RAFT handle object to encapsulate resources (e.g. CUDA stream, communicator, and * handles to various CUDA libraries) to run graph algorithms. * @param graph_view Graph view object. + * @param edge_weight_view Optional view object holding edge weights for @p graph_view. Currently, + * edge_weight_view.has_value() should be false as we don't support weighted graphs, yet. * @param vertices Optional, if specified this provides either a vertex_t count of how many * random seeds to select, or a device_span identifying a list of pre-selected vertices * to use as seeds for the traversals for approximating betweenness. @@ -344,7 +347,8 @@ void edge_betweenness_centrality(const raft::handle_t& handle, template rmm::device_uvector betweenness_centrality( const raft::handle_t& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, std::optional>> vertices, bool const normalized = true, bool const include_endpoints = false, @@ -375,6 +379,8 @@ rmm::device_uvector betweenness_centrality( * @param handle RAFT handle object to encapsulate resources (e.g. CUDA stream, communicator, and * handles to various CUDA libraries) to run graph algorithms. * @param graph_view Graph view object. + * @param edge_weight_view Optional view object holding edge weights for @p graph_view. Currently, + * edge_weight_view.has_value() should be false as we don't support weighted graphs, yet. * @param vertices Optional, if specified this provides either a vertex_t count of how many * random seeds to select, or a device_span identifying a list of pre-selected vertices * to use as seeds for the traversals for approximating betweenness. @@ -386,7 +392,8 @@ rmm::device_uvector betweenness_centrality( template rmm::device_uvector edge_betweenness_centrality( const raft::handle_t& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, std::optional>> vertices, bool normalized = true, bool do_expensive_check = false); @@ -651,7 +658,7 @@ weight_t hungarian(raft::handle_t const& handle, * @tparam graph_view_t Type of graph * * @param[in] handle Library handle (RAFT). If a communicator is set in the handle, - * @param[in] graph input graph object (CSR) + * @param[in] graph input graph object * @param[out] clustering Pointer to device array where the clustering should be stored * @param[in] max_level (optional) maximum number of levels to run (default 100) * @param[in] resolution (optional) The value of the resolution parameter to use. @@ -665,13 +672,22 @@ weight_t hungarian(raft::handle_t const& handle, * 2) modularity of the returned clustering * */ -template -std::pair louvain( +template +std::pair louvain( raft::handle_t const& handle, - graph_view_t const& graph_view, - typename graph_view_t::vertex_type* clustering, - size_t max_level = 100, - typename graph_view_t::weight_type resolution = typename graph_view_t::weight_type{1}); + graph_view_t const& graph_view, + std::optional> edge_weight_view, + vertex_t* clustering, + size_t max_level = 100, + weight_t resolution = weight_t{1}); + +template +std::pair louvain( + raft::handle_t const& handle, + legacy::GraphCSRView const& graph_view, + vertex_t* clustering, + size_t max_level = 100, + weight_t resolution = weight_t{1}); /** * @brief Louvain implementation, returning dendrogram @@ -689,7 +705,7 @@ std::pair louvain( * @tparam graph_view_t Type of graph * * @param[in] handle Library handle (RAFT) - * @param[in] graph_view Input graph view object (CSR) + * @param[in] graph_view Input graph view object * @param[in] max_level (optional) maximum number of levels to run (default 100) * @param[in] resolution (optional) The value of the resolution parameter to use. * Called gamma in the modularity formula, this changes the size @@ -702,13 +718,13 @@ std::pair louvain( * 2) modularity of the returned clustering * */ -template -std::pair>, - typename graph_view_t::weight_type> -louvain(raft::handle_t const& handle, - graph_view_t const& graph_view, - size_t max_level = 100, - typename graph_view_t::weight_type resolution = typename graph_view_t::weight_type{1}); +template +std::pair>, weight_t> louvain( + raft::handle_t const& handle, + graph_view_t const& graph_view, + std::optional> edge_weight_view, + size_t max_level = 100, + weight_t resolution = weight_t{1}); /** * @brief Flatten a Dendrogram at a particular level @@ -1067,7 +1083,6 @@ weight_t hungarian(raft::handle_t const& handle, * * @tparam vertex_t Type of vertex identifiers. Needs to be an integral type. * @tparam edge_t Type of edge identifiers. Needs to be an integral type. - * @tparam weight_t Type of edge weights. Needs to be a floating point type. * @tparam multi_gpu Flag indicating whether template instantiation should target single-GPU (false) * or multi-GPU (true). * @param handle RAFT handle object to encapsulate resources (e.g. CUDA stream, communicator, and @@ -1087,9 +1102,9 @@ weight_t hungarian(raft::handle_t const& handle, * farther than @p depth_limit hops from @p source_vertex will be marked as unreachable. * @param do_expensive_check A flag to run expensive checks for input arguments (if set to `true`). */ -template +template void bfs(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, vertex_t* distances, vertex_t* predecessors, vertex_t const* sources, @@ -1110,7 +1125,6 @@ void bfs(raft::handle_t const& handle, * * @tparam vertex_t Type of vertex identifiers. Needs to be an integral type. * @tparam edge_t Type of edge identifiers. Needs to be an integral type. - * @tparam weight_t Type of edge weights. Needs to be a floating point type. * @tparam multi_gpu Flag indicating whether template instantiation should target single-GPU (false) * or multi-GPU (true). * @param handle RAFT handle object to encapsulate resources (e.g. CUDA stream, communicator, and @@ -1127,10 +1141,10 @@ void bfs(raft::handle_t const& handle, * Unused elements in the paths * will be set to invalid_vertex_id (-1 for a signed * vertex_t, std::numeric_limits::max() for an unsigned vertex_t type). */ -template +template std::tuple, vertex_t> extract_bfs_paths( raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, vertex_t const* distances, vertex_t const* predecessors, vertex_t const* destinations, @@ -1154,6 +1168,7 @@ std::tuple, vertex_t> extract_bfs_paths( * @param handle RAFT handle object to encapsulate resources (e.g. CUDA stream, communicator, and * handles to various CUDA libraries) to run graph algorithms. * @param graph_view Graph view object. + * @param edge_weight_view View object holding edge weights for @p graph_view. * @param distances Pointer to the output distance array. * @param predecessors Pointer to the output predecessor array or `nullptr`. * @param source_vertex Source vertex to start single-source shortest-path. @@ -1164,7 +1179,8 @@ std::tuple, vertex_t> extract_bfs_paths( */ template void sssp(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view, weight_t* distances, vertex_t* predecessors, vertex_t source_vertex, @@ -1189,6 +1205,8 @@ void sssp(raft::handle_t const& handle, * @param handle RAFT handle object to encapsulate resources (e.g. CUDA stream, communicator, and * handles to various CUDA libraries) to run graph algorithms. * @param graph_view Graph view object. + * @param edge_weight_view Optional view object holding edge weights for @p graph_view. If @p + * edge_weight_view.has_value() == false, edge weights are assumed to be 1.0. * @param precomputed_vertex_out_weight_sums Pointer to an array storing sums of out-going edge * weights for the vertices (for re-use) or `std::nullopt`. If `std::nullopt`, these values are * freshly computed. Computing these values outside this function reduces the number of memory @@ -1214,7 +1232,8 @@ void sssp(raft::handle_t const& handle, */ template void pagerank(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, std::optional precomputed_vertex_out_weight_sums, std::optional personalization_vertices, std::optional personalization_values, @@ -1242,6 +1261,8 @@ void pagerank(raft::handle_t const& handle, * @param handle RAFT handle object to encapsulate resources (e.g. CUDA stream, communicator, and * handles to various CUDA libraries) to run graph algorithms. * @param graph_view Graph view object. + * @param edge_weight_view Optional view object holding edge weights for @p graph_view. If @p + * edge_weight_view.has_value() == false, edge weights are assumed to be 1.0. * @param initial_centralities Optional device span containing initial values for the eigenvector * centralities * @param epsilon Error tolerance to check convergence. Convergence is assumed if the sum of the @@ -1254,7 +1275,8 @@ void pagerank(raft::handle_t const& handle, template rmm::device_uvector eigenvector_centrality( raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, std::optional> initial_centralities, weight_t epsilon, size_t max_iterations = 500, @@ -1269,7 +1291,6 @@ rmm::device_uvector eigenvector_centrality( * * @tparam vertex_t Type of vertex identifiers. Needs to be an integral type. * @tparam edge_t Type of edge identifiers. Needs to be an integral type. - * @tparam weight_t Type of edge weights. Needs to be a floating point type. * @tparam multi_gpu Flag indicating whether template instantiation should target single-GPU (false) * or multi-GPU (true). * @param handle RAFT handle object to encapsulate resources (e.g. CUDA stream, communicator, and @@ -1286,20 +1307,19 @@ rmm::device_uvector eigenvector_centrality( * @param normalize If set to `true`, final hub and authority scores are normalized (the L1-norm of * the returned hub and authority score arrays is 1.0) before returning. * @param do_expensive_check A flag to run expensive checks for input arguments (if set to `true`). - * @return std::tuple A tuple of sum of the differences of hub scores of the last + * @return std::tuple A tuple of sum of the differences of hub scores of the last * two iterations and the total number of iterations taken to reach the final result */ -template -std::tuple hits( - raft::handle_t const& handle, - graph_view_t const& graph_view, - weight_t* hubs, - weight_t* authorities, - weight_t epsilon, - size_t max_iterations, - bool has_initial_hubs_guess, - bool normalize, - bool do_expensive_check); +template +std::tuple hits(raft::handle_t const& handle, + graph_view_t const& graph_view, + result_t* hubs, + result_t* authorities, + result_t epsilon, + size_t max_iterations, + bool has_initial_hubs_guess, + bool normalize, + bool do_expensive_check); /** * @brief Compute Katz Centrality scores. @@ -1318,6 +1338,8 @@ std::tuple hits( * @param handle RAFT handle object to encapsulate resources (e.g. CUDA stream, communicator, and * handles to various CUDA libraries) to run graph algorithms. * @param graph_view Graph view object. + * @param edge_weight_view Optional view object holding edge weights for @p graph_view. If @p + * edge_weight_view.has_value() == false, edge weights are assumed to be 1.0. * @param betas Pointer to an array holding the values to be added to each vertex's new Katz * Centrality score in every iteration or `nullptr`. If set to `nullptr`, constant @p beta is used * instead. @@ -1339,7 +1361,8 @@ std::tuple hits( */ template void katz_centrality(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, result_t const* betas, result_t* katz_centralities, result_t alpha, @@ -1365,13 +1388,13 @@ void katz_centrality(raft::handle_t const& handle, * @param handle RAFT handle object to encapsulate resources (e.g. CUDA stream, communicator, and * handles to various CUDA libraries) to run graph algorithms. Must have at least one worker stream. * @param graph_view Graph view object of, we extract induced egonet subgraphs from @p graph_view. + * @param edge_weight_view Optional view object holding edge weights for @p graph_view. * @param source_vertex Pointer to egonet center vertices (size == @p n_subgraphs). * @param n_subgraphs Number of induced EgoNet subgraphs to extract (ie. number of elements in @p * source_vertex). * @param radius Include all neighbors of distance <= radius from @p source_vertex. - * @return std::tuple, rmm::device_uvector, - * rmm::device_uvector, rmm::device_uvector> Quadraplet of edge source vertices, - * edge destination vertices, edge weights, and edge offsets for each induced EgoNet subgraph. + * @return Quadraplet of edge source vertices, edge destination vertices, edge weights (if @p + * edge_weight_view.has_value() == true), and edge offsets for each induced EgoNet subgraph. */ template std::tuple, @@ -1379,7 +1402,8 @@ std::tuple, std::optional>, rmm::device_uvector> extract_ego(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, vertex_t* source_vertex, vertex_t n_subgraphs, vertex_t radius); @@ -1396,6 +1420,7 @@ extract_ego(raft::handle_t const& handle, * @param handle RAFT handle object to encapsulate resources (e.g. CUDA stream, communicator, and * handles to various CUDA libraries) to run graph algorithms. Must have at least one worker stream. * @param graph_view Graph view object of, we extract induced egonet subgraphs from @p graph_view. + * @param edge_weight_view Optional view object holding edge weights for @p graph_view. * @param source_vertex Pointer to egonet center vertices (size == @p n_subgraphs). * @param n_subgraphs Number of induced EgoNet subgraphs to extract (ie. number of elements in @p * source_vertex). @@ -1410,7 +1435,8 @@ std::tuple, std::optional>, rmm::device_uvector> extract_ego(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, raft::device_span source_vertices, vertex_t radius, bool do_expensive_check = false); @@ -1447,17 +1473,17 @@ extract_ego(raft::handle_t const& handle, * sizes. Note: if the graph is un-weighted the edge (weight) paths consists of `weight_t{1}` * entries; */ -template -std::tuple, - rmm::device_uvector, - rmm::device_uvector> -random_walks(raft::handle_t const& handle, - graph_t const& graph, - typename graph_t::vertex_type const* ptr_d_start, - index_t num_paths, - index_t max_depth, - bool use_padding = false, - std::unique_ptr sampling_strategy = nullptr); +template +std:: + tuple, rmm::device_uvector, rmm::device_uvector> + random_walks(raft::handle_t const& handle, + graph_view_t const& graph_view, + std::optional> edge_weight_view, + vertex_t const* ptr_d_start, + index_t num_paths, + index_t max_depth, + bool use_padding = false, + std::unique_ptr sampling_strategy = nullptr); /** * @brief returns uniform random walks from starting sources, where each path is of given @@ -1466,8 +1492,8 @@ random_walks(raft::handle_t const& handle, * @p start_vertices can contain duplicates, in which case different random walks will * be generated for each instance. * - * If the graph is weighted, the return contains edge weights. If the graph is unweighted then - * the returned value will be std::nullopt. + * If @p edge_weight_view.has_value() is true, the return contains edge weights. If the graph is @p + * edge_weight_view.has_value() is false, the returned value will be std::nullopt. * * @tparam vertex_t Type of vertex identifiers. Needs to be an integral type. * @tparam edge_t Type of edge identifiers. Needs to be an integral type. @@ -1476,11 +1502,12 @@ random_walks(raft::handle_t const& handle, * @param handle RAFT handle object to encapsulate resources (e.g. CUDA stream, communicator, and * handles to various CUDA libraries) to run graph algorithms. * @param graph_view graph view to operate on + * @param edge_weight_view Optional view object holding edge weights for @p graph_view. * @param start_vertices Device span defining the starting vertices * @param max_length maximum length of random walk * @param seed (optional, defaults to system time), seed for random number generation * @return tuple containing device vectors of vertices and the edge weights (if - * the graph is weighted)
+ * @p edge_weight_view.has_value() is true)
* For each input selector there will be (max_length+1) elements in the * vertex vector with the starting vertex followed by the subsequent * vertices in the random walk. If a path terminates before max_length, @@ -1497,7 +1524,8 @@ random_walks(raft::handle_t const& handle, template std::tuple, std::optional>> uniform_random_walks(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, raft::device_span start_vertices, size_t max_length, uint64_t seed = std::numeric_limits::max()); @@ -1521,6 +1549,7 @@ uniform_random_walks(raft::handle_t const& handle, * @param handle RAFT handle object to encapsulate resources (e.g. CUDA stream, communicator, and * handles to various CUDA libraries) to run graph algorithms. * @param graph_view graph view to operate on + * @param edge_weight_view View object holding edge weights for @p graph_view. * @param start_vertices Device span defining the starting vertices * @param max_length maximum length of random walk * @param seed (optional, defaults to system time), seed for random number generation @@ -1539,7 +1568,8 @@ uniform_random_walks(raft::handle_t const& handle, template std::tuple, std::optional>> biased_random_walks(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view, raft::device_span start_vertices, size_t max_length, uint64_t seed = std::numeric_limits::max()); @@ -1551,9 +1581,10 @@ biased_random_walks(raft::handle_t const& handle, * @p start_vertices can contain duplicates, in which case different random walks will * be generated for each instance. * - * If the graph is weighted, the return contains edge weights and the node2vec computation - * will utilize the edge weights. If the graph is unweighted then the return will not contain - * edge weights and the node2vec computation will assume an edge weight of 1 for all edges. + * If the @p edge_weight_view.has_value() = true, the return contains edge weights and the node2vec + * computation will utilize the edge weights. If @p edge_weight_view.has_value() == false, then the + * return will not contain edge weights and the node2vec computation will assume an edge weight of 1 + * for all edges. * * @tparam vertex_t Type of vertex identifiers. Needs to be an integral type. * @tparam edge_t Type of edge identifiers. Needs to be an integral type. @@ -1562,6 +1593,8 @@ biased_random_walks(raft::handle_t const& handle, * @param handle RAFT handle object to encapsulate resources (e.g. CUDA stream, communicator, and * handles to various CUDA libraries) to run graph algorithms. * @param graph_view graph view to operate on + * @param edge_weight_view Optional view object holding edge weights for @p graph_view. If @p + * edge_weight_view.has_value() == false, edge weights are assumed to be 1.0. * @param start_vertices Device span defining the starting vertices * @param max_length maximum length of random walk * @param p node2vec return parameter @@ -1582,7 +1615,8 @@ biased_random_walks(raft::handle_t const& handle, template std::tuple, std::optional>> node2vec_random_walks(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, raft::device_span start_vertices, size_t max_length, weight_t p, @@ -1610,13 +1644,12 @@ node2vec_random_walks(raft::handle_t const& handle, * Tuple consisting of two arrays representing the offsets and indices of * the sub-sampled graph. */ -template -std::tuple, - rmm::device_uvector> +template +std::tuple, rmm::device_uvector> sample_neighbors_adjacency_list(raft::handle_t const& handle, raft::random::RngState& rng_state, - graph_t const& graph, - typename graph_t::vertex_type const* ptr_d_start, + graph_view_t const& graph_view, + vertex_t const* ptr_d_start, size_t num_start_vertices, size_t sampling_size, ops::gnn::graph::SamplingAlgoT sampling_algo); @@ -1641,16 +1674,15 @@ sample_neighbors_adjacency_list(raft::handle_t const& handle, * Tuple consisting of two arrays representing the source and destination nodes of * the sub-sampled graph. */ -template -std::tuple, - rmm::device_uvector> -sample_neighbors_edgelist(raft::handle_t const& handle, - raft::random::RngState& rng_state, - graph_t const& graph, - typename graph_t::vertex_type const* ptr_d_start, - size_t num_start_vertices, - size_t sampling_size, - ops::gnn::graph::SamplingAlgoT sampling_algo); +template +std::tuple, rmm::device_uvector> sample_neighbors_edgelist( + raft::handle_t const& handle, + raft::random::RngState& rng_state, + graph_view_t const& graph_view, + vertex_t const* ptr_d_start, + size_t num_start_vertices, + size_t sampling_size, + ops::gnn::graph::SamplingAlgoT sampling_algo); #endif /** @@ -1661,7 +1693,6 @@ sample_neighbors_edgelist(raft::handle_t const& handle, * * @tparam vertex_t Type of vertex identifiers. Needs to be an integral type. * @tparam edge_t Type of edge identifiers. Needs to be an integral type. - * @tparam weight_t Type of edge weights. Needs to be a floating point type. * @tparam multi_gpu Flag indicating whether template instantiation should target single-GPU (false) * or multi-GPU (true). * @param handle RAFT handle object to encapsulate resources (e.g. CUDA stream, communicator, and @@ -1670,12 +1701,11 @@ sample_neighbors_edgelist(raft::handle_t const& handle, * @param components Pointer to the output component ID array. * @param do_expensive_check A flag to run expensive checks for input arguments (if set to `true`). */ -template -void weakly_connected_components( - raft::handle_t const& handle, - graph_view_t const& graph_view, - vertex_t* components, - bool do_expensive_check = false); +template +void weakly_connected_components(raft::handle_t const& handle, + graph_view_t const& graph_view, + vertex_t* components, + bool do_expensive_check = false); /** * @brief Identify whether the core number computation should be based off incoming edges, @@ -1691,7 +1721,6 @@ enum class k_core_degree_type_t { IN = 0, OUT = 1, INOUT = 2 }; * * @tparam vertex_t Type of vertex identifiers. Needs to be an integral type. * @tparam edge_t Type of edge identifiers. Needs to be an integral type. - * @tparam weight_t Type of edge weights. Needs to be a floating point type. * @tparam multi_gpu Flag indicating whether template instantiation should target single-GPU (false) * or multi-GPU (true). * @param handle RAFT handle object to encapsulate resources (e.g. CUDA stream, communicator, and @@ -1706,9 +1735,9 @@ enum class k_core_degree_type_t { IN = 0, OUT = 1, INOUT = 2 }; * their core numbers set to their degrees on k_last-core. * @param do_expensive_check A flag to run expensive checks for input arguments (if set to `true`). */ -template +template void core_number(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, edge_t* core_numbers, k_core_degree_type_t degree_type, size_t k_first = 0, @@ -1725,6 +1754,7 @@ void core_number(raft::handle_t const& handle, * @tparam weight_t Type of edge weights. Needs to be a floating point type. * @tparam multi_gpu Flag indicating whether template instantiation should target single-GPU (false) * @param graph_view Graph view object. + * @param edge_weight_view Optional view object holding edge weights for @p graph_view. * @param k Order of the core. This value must not be negative. * @param degree_type Optional parameter to dictate whether to compute the K-core decomposition * based on in-degrees, out-degrees, or in-degrees + out_degrees. One of @p @@ -1740,7 +1770,8 @@ std::tuple, rmm::device_uvector, std::optional>> k_core(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, size_t k, std::optional degree_type, std::optional> core_numbers, @@ -1764,6 +1795,7 @@ k_core(raft::handle_t const& handle, * @param handle RAFT handle object to encapsulate resources (e.g. CUDA stream, communicator, and * handles to various CUDA libraries) to run graph algorithms. * @param graph_view Graph View object to generate NBR Sampling on. + * @param edge_weight_view Optional view object holding edge weights for @p graph_view. * @param starting_vertices Device span of starting vertex IDs for the NBR Sampling. * @param fan_out Host span defining branching out (fan-out) degree per source vertex for each * level @@ -1782,13 +1814,13 @@ std::tuple, rmm::device_uvector, rmm::device_uvector, rmm::device_uvector> -uniform_nbr_sample( - raft::handle_t const& handle, - graph_view_t const& graph_view, - raft::device_span starting_vertices, - raft::host_span fan_out, - bool with_replacement = true, - uint64_t seed = 0); +uniform_nbr_sample(raft::handle_t const& handle, + graph_view_t const& graph_view, + std::optional> edge_weight_view, + raft::device_span starting_vertices, + raft::host_span fan_out, + bool with_replacement = true, + uint64_t seed = 0); /* * @brief Compute triangle counts. @@ -1798,7 +1830,6 @@ uniform_nbr_sample( * * @tparam vertex_t Type of vertex identifiers. Needs to be an integral type. * @tparam edge_t Type of edge identifiers. Needs to be an integral type. - * @tparam weight_t Type of edge weights. Needs to be a floating point type. * @tparam multi_gpu Flag indicating whether template instantiation should target single-GPU (false) * @param handle RAFT handle object to encapsulate resources (e.g. CUDA stream, communicator, and * handles to various CUDA libraries) to run graph algorithms. @@ -1810,9 +1841,9 @@ uniform_nbr_sample( * vertices.has_value() is true). * @param do_expensive_check A flag to run expensive checks for input arguments (if set to `true`). */ -template +template void triangle_count(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, std::optional> vertices, raft::device_span counts, bool do_expensive_check = false); @@ -1832,18 +1863,19 @@ void triangle_count(raft::handle_t const& handle, * @param handle RAFT handle object to encapsulate resources (e.g. CUDA stream, communicator, and * handles to various CUDA libraries) to run graph algorithms. * @param graph_view Graph view object. + * @param edge_weight_view Optional view object holding edge weights for @p graph_view. If @p + * edge_weight_view.has_value() == true, use the weights associated with the graph. If false, assume + * a weight of 1 for all edges. * @param vertex_pairs tuple of device spans defining the vertex pairs to compute similarity for * In a multi-gpu context each vertex pair should be local to this GPU. - * @param use_weights If true use the weights associated with the graph. If false assume a weight - * of 1 for all edges. * @return similarity coefficient for the corresponding @p vertex_pairs */ template rmm::device_uvector jaccard_coefficients( raft::handle_t const& handle, - graph_view_t const& graph_view, - std::tuple, raft::device_span> vertex_pairs, - bool use_weights); + graph_view_t const& graph_view, + std::optional> edge_weight_view, + std::tuple, raft::device_span> vertex_pairs); /** * @brief Compute Sorensen similarity coefficient @@ -1860,18 +1892,20 @@ rmm::device_uvector jaccard_coefficients( * @param handle RAFT handle object to encapsulate resources (e.g. CUDA stream, communicator, and * handles to various CUDA libraries) to run graph algorithms. * @param graph_view Graph view object. + * @param edge_weight_view Optional view object holding edge weights for @p graph_view. If @p + * edge_weight_view.has_value() == true, use the weights associated with the graph. If false, assume + * a weight of 1 for all edges. + * @param vertex_pairs tuple of device spans defining the vertex pairs to compute similarity for * @param vertex_pairs tuple of device spans defining the vertex pairs to compute similarity for * In a multi-gpu context each vertex pair should be local to this GPU. - * @param use_weights If true use the weights associated with the graph. If false assume a weight - * of 1 for all edges. * @return similarity coefficient for the corresponding @p vertex_pairs */ template rmm::device_uvector sorensen_coefficients( raft::handle_t const& handle, - graph_view_t const& graph_view, - std::tuple, raft::device_span> vertex_pairs, - bool use_weights); + graph_view_t const& graph_view, + std::optional> edge_weight_view, + std::tuple, raft::device_span> vertex_pairs); /** * @brief Compute overlap similarity coefficient @@ -1888,18 +1922,20 @@ rmm::device_uvector sorensen_coefficients( * @param handle RAFT handle object to encapsulate resources (e.g. CUDA stream, communicator, and * handles to various CUDA libraries) to run graph algorithms. * @param graph_view Graph view object. + * @param edge_weight_view Optional view object holding edge weights for @p graph_view. If @p + * edge_weight_view.has_value() == true, use the weights associated with the graph. If false, assume + * a weight of 1 for all edges. + * @param vertex_pairs tuple of device spans defining the vertex pairs to compute similarity for * @param vertex_pairs tuple of device spans defining the vertex pairs to compute similarity for * In a multi-gpu context each vertex pair should be local to this GPU. - * @param use_weights If true use the weights associated with the graph. If false assume a weight - * of 1 for all edges. * @return similarity coefficient for the corresponding @p vertex_pairs */ template rmm::device_uvector overlap_coefficients( raft::handle_t const& handle, - graph_view_t const& graph_view, - std::tuple, raft::device_span> vertex_pairs, - bool use_weights); + graph_view_t const& graph_view, + std::optional> edge_weight_view, + std::tuple, raft::device_span> vertex_pairs); /* * @brief Enumerate K-hop neighbors @@ -1910,7 +1946,6 @@ rmm::device_uvector overlap_coefficients( * * @tparam vertex_t Type of vertex identifiers. Needs to be an integral type. * @tparam edge_t Type of edge identifiers. Needs to be an integral type. - * @tparam weight_t Type of edge weights. Needs to be a floating point type. * @tparam multi_gpu Flag indicating whether template instantiation should target single-GPU (false) * @param handle RAFT handle object to encapsulate resources (e.g. CUDA stream, communicator, and * handles to various CUDA libraries) to run graph algorithms. @@ -1923,10 +1958,10 @@ rmm::device_uvector overlap_coefficients( * beginning (inclusive) and end (exclusive) of the K-hop neighbors of the i'th element of @p * start_vertices, respectively. */ -template +template std::tuple, rmm::device_uvector> k_hop_nbrs( raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, raft::device_span start_vertices, size_t k, bool do_expensive_check = false); diff --git a/cpp/include/cugraph/detail/decompress_edge_partition.cuh b/cpp/include/cugraph/detail/decompress_edge_partition.cuh index 8cd9b0d2531..5005dfbe12e 100644 --- a/cpp/include/cugraph/detail/decompress_edge_partition.cuh +++ b/cpp/include/cugraph/detail/decompress_edge_partition.cuh @@ -16,6 +16,7 @@ #pragma once #include +#include #include #include @@ -40,9 +41,9 @@ namespace detail { // FIXME: block size requires tuning int32_t constexpr decompress_edge_partition_block_size = 1024; -template +template __global__ void decompress_to_edgelist_mid_degree( - edge_partition_device_view_t edge_partition, + edge_partition_device_view_t edge_partition, vertex_t major_range_first, vertex_t major_range_last, vertex_t* majors) @@ -59,10 +60,10 @@ __global__ void decompress_to_edgelist_mid_degree( auto major = edge_partition.major_from_major_offset_nocheck(static_cast(major_offset)); vertex_t const* indices{nullptr}; - thrust::optional weights{thrust::nullopt}; + [[maybe_unused]] edge_t edge_offset{}; edge_t local_degree{}; - thrust::tie(indices, weights, local_degree) = edge_partition.local_edges(major_offset); - auto local_offset = edge_partition.local_offset(major_offset); + thrust::tie(indices, edge_offset, local_degree) = edge_partition.local_edges(major_offset); + auto local_offset = edge_partition.local_offset(major_offset); for (edge_t i = lane_id; i < local_degree; i += raft::warp_size()) { majors[local_offset + i] = major; } @@ -70,9 +71,9 @@ __global__ void decompress_to_edgelist_mid_degree( } } -template +template __global__ void decompress_to_edgelist_high_degree( - edge_partition_device_view_t edge_partition, + edge_partition_device_view_t edge_partition, vertex_t major_range_first, vertex_t major_range_last, vertex_t* majors) @@ -86,9 +87,9 @@ __global__ void decompress_to_edgelist_high_degree( auto major = edge_partition.major_from_major_offset_nocheck(static_cast(major_offset)); vertex_t const* indices{nullptr}; - thrust::optional weights{thrust::nullopt}; + [[maybe_unused]] edge_t edge_offset{}; edge_t local_degree{}; - thrust::tie(indices, weights, local_degree) = + thrust::tie(indices, edge_offset, local_degree) = edge_partition.local_edges(static_cast(major_offset)); auto local_offset = edge_partition.local_offset(major_offset); for (edge_t i = threadIdx.x; i < local_degree; i += blockDim.x) { @@ -98,10 +99,10 @@ __global__ void decompress_to_edgelist_high_degree( } } -template +template void decompress_edge_partition_to_fill_edgelist_majors( raft::handle_t const& handle, - edge_partition_device_view_t edge_partition, + edge_partition_device_view_t edge_partition, vertex_t* majors, std::optional> const& segment_offsets) { @@ -183,334 +184,12 @@ void decompress_edge_partition_to_fill_edgelist_majors( } } -template -__global__ void partially_decompress_to_edgelist_high_degree( - edge_partition_device_view_t edge_partition, - vertex_t const* input_majors, - edge_t const* input_major_start_offsets, - vertex_t input_major_count, - vertex_t* output_majors, - vertex_t* output_minors, - thrust::optional output_weights, - thrust::optional> property, - thrust::optional> global_edge_index) -{ - size_t idx = static_cast(blockIdx.x); - while (idx < static_cast(input_major_count)) { - auto major = input_majors[idx]; - auto major_partition_offset = static_cast(major - edge_partition.major_range_first()); - vertex_t const* indices{nullptr}; - thrust::optional weights{thrust::nullopt}; - edge_t local_degree{}; - thrust::tie(indices, weights, local_degree) = - edge_partition.local_edges(static_cast(major_partition_offset)); - auto major_offset = input_major_start_offsets[idx]; - for (edge_t i = threadIdx.x; i < local_degree; i += blockDim.x) { - output_majors[major_offset + i] = major; - output_minors[major_offset + i] = indices[i]; - - if (output_weights) (*output_weights)[major_offset + i] = (*weights)[i]; - } - if (property) { - auto input_property = thrust::get<0>(*property)[idx]; - prop_t* output_property = thrust::get<1>(*property); - for (edge_t i = threadIdx.x; i < local_degree; i += blockDim.x) { - output_property[major_offset + i] = input_property; - } - } - if (global_edge_index) { - auto adjacency_list_offset = thrust::get<0>(*global_edge_index)[major_partition_offset]; - auto minor_map = thrust::get<1>(*global_edge_index); - for (edge_t i = threadIdx.x; i < local_degree; i += blockDim.x) { - minor_map[major_offset + i] = adjacency_list_offset + i; - } - } - idx += gridDim.x; - } -} - -template -__global__ void partially_decompress_to_edgelist_mid_degree( - edge_partition_device_view_t edge_partition, - vertex_t const* input_majors, - edge_t const* input_major_start_offsets, - vertex_t input_major_count, - vertex_t* output_majors, - vertex_t* output_minors, - thrust::optional output_weights, - thrust::optional> property, - thrust::optional> global_edge_index) -{ - auto const tid = threadIdx.x + blockIdx.x * blockDim.x; - static_assert(decompress_edge_partition_block_size % raft::warp_size() == 0); - auto const lane_id = tid % raft::warp_size(); - size_t idx = static_cast(tid / raft::warp_size()); - while (idx < static_cast(input_major_count)) { - auto major = input_majors[idx]; - auto major_partition_offset = static_cast(major - edge_partition.major_range_first()); - vertex_t const* indices{nullptr}; - thrust::optional weights{thrust::nullopt}; - edge_t local_degree{}; - - thrust::tie(indices, weights, local_degree) = - edge_partition.local_edges(major_partition_offset); - - auto major_offset = input_major_start_offsets[idx]; - for (edge_t i = lane_id; i < local_degree; i += raft::warp_size()) { - output_majors[major_offset + i] = major; - output_minors[major_offset + i] = indices[i]; - - if (output_weights) (*output_weights)[major_offset + i] = (*weights)[i]; - } - if (property) { - auto input_property = thrust::get<0>(*property)[idx]; - prop_t* output_property = thrust::get<1>(*property); - for (edge_t i = lane_id; i < local_degree; i += raft::warp_size()) { - output_property[major_offset + i] = input_property; - } - } - if (global_edge_index) { - auto adjacency_list_offset = thrust::get<0>(*global_edge_index)[major_partition_offset]; - auto minor_map = thrust::get<1>(*global_edge_index); - for (edge_t i = threadIdx.x; i < local_degree; i += blockDim.x) { - minor_map[major_offset + i] = adjacency_list_offset + i; - } - } - idx += gridDim.x * (blockDim.x / raft::warp_size()); - } -} - -template -void partially_decompress_edge_partition_to_fill_edgelist( - raft::handle_t const& handle, - edge_partition_device_view_t edge_partition, - vertex_t const* input_majors, - edge_t const* input_major_start_offsets, - vertex_t input_majors_size, - std::vector const& segment_offsets, - vertex_t* majors, - vertex_t* minors, - thrust::optional weights, - thrust::optional> property, - thrust::optional> global_edge_index, - // FIXME: Once PR 2356 is merged, this parameter could go away because - // major_hypersparse_first will be part of edge_partition - std::optional> local_edge_partition_segment_offsets) -{ - if constexpr (multi_gpu) { - auto execution_policy = handle.get_thrust_policy(); - static_assert(detail::num_sparse_segments_per_vertex_partition == 3); - if (segment_offsets[1] - segment_offsets[0] > 0) { - raft::grid_1d_block_t update_grid(segment_offsets[1] - segment_offsets[0], - detail::decompress_edge_partition_block_size, - handle.get_device_properties().maxGridSize[0]); - - detail::partially_decompress_to_edgelist_high_degree<<>>( - edge_partition, - input_majors + segment_offsets[0], - input_major_start_offsets, - segment_offsets[1], - majors, - minors, - weights, - property ? thrust::make_optional(thrust::make_tuple( - thrust::get<0>(*property) + segment_offsets[0], thrust::get<1>(*property))) - : thrust::nullopt, - global_edge_index); - } - if (segment_offsets[2] - segment_offsets[1] > 0) { - raft::grid_1d_warp_t update_grid(segment_offsets[2] - segment_offsets[1], - detail::decompress_edge_partition_block_size, - handle.get_device_properties().maxGridSize[0]); - - detail::partially_decompress_to_edgelist_mid_degree<<>>( - edge_partition, - input_majors + segment_offsets[1], - input_major_start_offsets + segment_offsets[1] - segment_offsets[0], - segment_offsets[2] - segment_offsets[1], - majors, - minors, - weights, - property ? thrust::make_optional(thrust::make_tuple( - thrust::get<0>(*property) + segment_offsets[1], thrust::get<1>(*property))) - : thrust::nullopt, - global_edge_index); - } - if (segment_offsets[3] - segment_offsets[2] > 0) { - thrust::for_each( - execution_policy, - thrust::make_counting_iterator(vertex_t{0}), - thrust::make_counting_iterator(segment_offsets[3] - segment_offsets[2]), - [edge_partition, - input_majors = input_majors + segment_offsets[2], - input_major_start_offsets = - input_major_start_offsets + segment_offsets[2] - segment_offsets[0], - majors, - minors, - output_weights = weights, - property = - property ? thrust::make_optional(thrust::make_tuple( - thrust::get<0>(*property) + segment_offsets[2], thrust::get<1>(*property))) - : thrust::nullopt, - global_edge_index] __device__(auto idx) { - auto major = input_majors[idx]; - auto major_offset = input_major_start_offsets[idx]; - auto major_partition_offset = - static_cast(major - edge_partition.major_range_first()); - vertex_t const* indices{nullptr}; - thrust::optional weights{thrust::nullopt}; - edge_t local_degree{}; - thrust::tie(indices, weights, local_degree) = - edge_partition.local_edges(major_partition_offset); - - // FIXME: This can lead to thread divergence if local_degree varies significantly - // within threads in this warp - thrust::fill( - thrust::seq, majors + major_offset, majors + major_offset + local_degree, major); - thrust::copy(thrust::seq, indices, indices + local_degree, minors + major_offset); - if (output_weights) - thrust::copy( - thrust::seq, *weights, *weights + local_degree, *output_weights + major_offset); - - if (property) { - auto major_input_property = thrust::get<0>(*property)[idx]; - auto minor_output_property = thrust::get<1>(*property); - thrust::fill(thrust::seq, - minor_output_property + major_offset, - minor_output_property + major_offset + local_degree, - major_input_property); - } - if (global_edge_index) { - auto adjacency_list_offset = thrust::get<0>(*global_edge_index)[major_partition_offset]; - auto minor_map = thrust::get<1>(*global_edge_index); - thrust::sequence(thrust::seq, - minor_map + major_offset, - minor_map + major_offset + local_degree, - adjacency_list_offset); - } - }); - } - if (edge_partition.dcs_nzd_vertex_count() && (*(edge_partition.dcs_nzd_vertex_count()) > 0)) { - thrust::for_each( - execution_policy, - thrust::make_counting_iterator(vertex_t{0}), - thrust::make_counting_iterator(segment_offsets[4] - segment_offsets[3]), - [edge_partition, - input_majors = input_majors + segment_offsets[3], - input_major_start_offsets = - input_major_start_offsets + segment_offsets[3] - segment_offsets[0], - majors, - minors, - output_weights = weights, - property = - property ? thrust::make_optional(thrust::make_tuple( - thrust::get<0>(*property) + segment_offsets[3], thrust::get<1>(*property))) - : thrust::nullopt, - // FIXME: Once PR 2356 is merged, this parameter could go away because - // major_hypersparse_first will be part of edge_partition - segment_offsets_last = (*local_edge_partition_segment_offsets) - [detail::num_sparse_segments_per_vertex_partition], - global_edge_index] __device__(auto idx) { - auto major = input_majors[idx]; - auto major_offset = input_major_start_offsets[idx]; - auto major_idx = edge_partition.major_hypersparse_idx_from_major_nocheck(major); - if (major_idx) { - vertex_t const* indices{nullptr}; - thrust::optional weights{thrust::nullopt}; - edge_t local_degree{}; - // FIXME: Once PR 2356 is merged, this computation should be changed to use - // major_hypersparse_first which will be part of edge_partition - thrust::tie(indices, weights, local_degree) = - edge_partition.local_edges(segment_offsets_last + *major_idx); - thrust::fill( - thrust::seq, majors + major_offset, majors + major_offset + local_degree, major); - thrust::copy(thrust::seq, indices, indices + local_degree, minors + major_offset); - if (output_weights) - thrust::copy( - thrust::seq, *weights, *weights + local_degree, *output_weights + major_offset); - if (property) { - auto major_input_property = thrust::get<0>(*property)[idx]; - auto minor_output_property = thrust::get<1>(*property); - thrust::fill(thrust::seq, - minor_output_property + major_offset, - minor_output_property + major_offset + local_degree, - major_input_property); - } - if (global_edge_index) { - auto major_partition_offset = - static_cast(*major_idx - edge_partition.major_range_first()); - auto adjacency_list_offset = - thrust::get<0>(*global_edge_index)[major_partition_offset]; - auto minor_map = thrust::get<1>(*global_edge_index); - thrust::sequence(thrust::seq, - minor_map + major_offset, - minor_map + major_offset + local_degree, - adjacency_list_offset); - } - } - }); - } - } else { - thrust::for_each( - handle.get_thrust_policy(), - thrust::make_counting_iterator(vertex_t{0}), - thrust::make_counting_iterator(input_majors_size), - [edge_partition, - input_majors, - input_major_start_offsets, - majors, - minors, - output_weights = weights, - property = property ? thrust::make_optional(thrust::make_tuple(thrust::get<0>(*property), - thrust::get<1>(*property))) - : thrust::nullopt, - global_edge_index] __device__(auto idx) { - auto major = input_majors[idx]; - auto major_offset = input_major_start_offsets[idx]; - vertex_t const* indices{nullptr}; - thrust::optional weights{thrust::nullopt}; - edge_t local_degree{}; - thrust::tie(indices, weights, local_degree) = edge_partition.local_edges(major); - - // FIXME: This can lead to thread divergence if local_degree varies significantly - // within threads in this warp - thrust::fill( - thrust::seq, majors + major_offset, majors + major_offset + local_degree, major); - thrust::copy(thrust::seq, indices, indices + local_degree, minors + major_offset); - if (output_weights) - thrust::copy( - thrust::seq, *weights, *weights + local_degree, *output_weights + major_offset); - - if (property) { - auto major_input_property = thrust::get<0>(*property)[idx]; - auto minor_output_property = thrust::get<1>(*property); - thrust::fill(thrust::seq, - minor_output_property + major_offset, - minor_output_property + major_offset + local_degree, - major_input_property); - } - if (global_edge_index) { - auto adjacency_list_offset = thrust::get<0>(*global_edge_index)[major]; - auto minor_map = thrust::get<1>(*global_edge_index); - thrust::sequence(thrust::seq, - minor_map + major_offset, - minor_map + major_offset + local_degree, - adjacency_list_offset); - } - }); - } -} - template void decompress_edge_partition_to_edgelist( raft::handle_t const& handle, - edge_partition_device_view_t const edge_partition, + edge_partition_device_view_t edge_partition, + std::optional> + edge_partition_weight_view, vertex_t* edgelist_majors /* [OUT] */, vertex_t* edgelist_minors /* [OUT] */, std::optional edgelist_weights /* [OUT] */, @@ -524,10 +203,11 @@ void decompress_edge_partition_to_edgelist( edge_partition.indices(), edge_partition.indices() + number_of_edges, edgelist_minors); - if (edgelist_weights) { + if (edge_partition_weight_view) { + assert(edgelist_weights.has_value()); thrust::copy(handle.get_thrust_policy(), - *(edge_partition.weights()), - *(edge_partition.weights()) + number_of_edges, + (*edge_partition_weight_view).value_first(), + (*edge_partition_weight_view).value_first() + number_of_edges, (*edgelist_weights)); } } diff --git a/cpp/include/cugraph/edge_partition_device_view.cuh b/cpp/include/cugraph/edge_partition_device_view.cuh index da90cdd6521..2e18a71898f 100644 --- a/cpp/include/cugraph/edge_partition_device_view.cuh +++ b/cpp/include/cugraph/edge_partition_device_view.cuh @@ -92,16 +92,12 @@ struct local_degree_op_t { } }; -template +template class edge_partition_device_view_base_t { public: edge_partition_device_view_base_t(raft::device_span offsets, - raft::device_span indices, - std::optional> weights) - : offsets_(offsets), - indices_(indices), - weights_(weights ? thrust::optional>(*weights) - : thrust::nullopt) + raft::device_span indices) + : offsets_(offsets), indices_(indices) { } @@ -112,21 +108,15 @@ class edge_partition_device_view_base_t { __host__ __device__ edge_t const* offsets() const { return offsets_.data(); } __host__ __device__ vertex_t const* indices() const { return indices_.data(); } - __host__ __device__ thrust::optional weights() const - { - return weights_ ? thrust::optional{(*weights_).data()} : thrust::nullopt; - } // major_idx == major offset if CSR/CSC, major_offset != major_idx if DCSR/DCSC - __device__ thrust::tuple, edge_t> local_edges( + __device__ thrust::tuple local_edges( vertex_t major_idx) const noexcept { auto edge_offset = offsets_[major_idx]; auto local_degree = offsets_[major_idx + 1] - edge_offset; auto indices = indices_.data() + edge_offset; - auto weights = weights_ ? thrust::optional{(*weights_).data() + edge_offset} - : thrust::nullopt; - return thrust::make_tuple(indices, weights, local_degree); + return thrust::make_tuple(indices, edge_offset, local_degree); } // major_idx == major offset if CSR/CSC, major_offset != major_idx if DCSR/DCSC @@ -142,30 +132,20 @@ class edge_partition_device_view_base_t { // should be trivially copyable to device raft::device_span offsets_{nullptr}; raft::device_span indices_{nullptr}; - thrust::optional> weights_{thrust::nullopt}; }; } // namespace detail -template +template class edge_partition_device_view_t; // multi-GPU version -template -class edge_partition_device_view_t> - : public detail::edge_partition_device_view_base_t { +template +class edge_partition_device_view_t> + : public detail::edge_partition_device_view_base_t { public: - edge_partition_device_view_t(edge_partition_view_t view) - : detail::edge_partition_device_view_base_t( - view.offsets(), view.indices(), view.weights()), + edge_partition_device_view_t(edge_partition_view_t view) + : detail::edge_partition_device_view_base_t(view.offsets(), view.indices()), dcs_nzd_vertices_(detail::to_thrust_optional(view.dcs_nzd_vertices())), major_hypersparse_first_(detail::to_thrust_optional(view.major_hypersparse_first())), major_range_first_(view.major_range_first()), @@ -359,17 +339,12 @@ class edge_partition_device_view_t -class edge_partition_device_view_t> - : public detail::edge_partition_device_view_base_t { +template +class edge_partition_device_view_t> + : public detail::edge_partition_device_view_base_t { public: - edge_partition_device_view_t(edge_partition_view_t view) - : detail::edge_partition_device_view_base_t( - view.offsets(), view.indices(), view.weights()), + edge_partition_device_view_t(edge_partition_view_t view) + : detail::edge_partition_device_view_base_t(view.offsets(), view.indices()), number_of_vertices_(view.major_range_last()) { } diff --git a/cpp/include/cugraph/edge_partition_edge_property_device_view.cuh b/cpp/include/cugraph/edge_partition_edge_property_device_view.cuh index ed8466c725e..688d9ecf82f 100644 --- a/cpp/include/cugraph/edge_partition_edge_property_device_view.cuh +++ b/cpp/include/cugraph/edge_partition_edge_property_device_view.cuh @@ -39,6 +39,8 @@ class edge_partition_edge_property_device_view_t { value_first_ = view.value_firsts()[partition_idx]; } + __host__ __device__ ValueIterator value_first() { return value_first_; } + __device__ ValueIterator get_iter(edge_t offset) const { return value_first_ + offset; } __device__ value_type get(edge_t offset) const { return *get_iter(offset); } diff --git a/cpp/include/cugraph/edge_partition_view.hpp b/cpp/include/cugraph/edge_partition_view.hpp index 3ba36be6a86..42465273718 100644 --- a/cpp/include/cugraph/edge_partition_view.hpp +++ b/cpp/include/cugraph/edge_partition_view.hpp @@ -24,13 +24,12 @@ namespace cugraph { namespace detail { -template +template class edge_partition_view_base_t { public: edge_partition_view_base_t(raft::device_span offsets, - raft::device_span indices, - std::optional> weights) - : offsets_(offsets), indices_(indices), weights_(weights) + raft::device_span indices) + : offsets_(offsets), indices_(indices) { } @@ -38,31 +37,24 @@ class edge_partition_view_base_t { raft::device_span offsets() const { return offsets_; } raft::device_span indices() const { return indices_; } - std::optional> weights() const { return weights_; } private: raft::device_span offsets_{}; raft::device_span indices_{}; - std::optional> weights_{std::nullopt}; }; } // namespace detail -template +template class edge_partition_view_t; // multi-GPU version -template -class edge_partition_view_t> - : public detail::edge_partition_view_base_t { +template +class edge_partition_view_t> + : public detail::edge_partition_view_base_t { public: edge_partition_view_t(raft::device_span offsets, raft::device_span indices, - std::optional> weights, std::optional> dcs_nzd_vertices, std::optional major_hypersparse_first, vertex_t major_range_first, @@ -70,7 +62,7 @@ class edge_partition_view_t(offsets, indices, weights), + : detail::edge_partition_view_base_t(offsets, indices), dcs_nzd_vertices_(dcs_nzd_vertices), major_hypersparse_first_(major_hypersparse_first), major_range_first_(major_range_first), @@ -109,15 +101,14 @@ class edge_partition_view_t -class edge_partition_view_t> - : public detail::edge_partition_view_base_t { +template +class edge_partition_view_t> + : public detail::edge_partition_view_base_t { public: edge_partition_view_t(raft::device_span offsets, raft::device_span indices, - std::optional> weights, vertex_t number_of_vertices) - : detail::edge_partition_view_base_t(offsets, indices, weights), + : detail::edge_partition_view_base_t(offsets, indices), number_of_vertices_(number_of_vertices) { } diff --git a/cpp/include/cugraph/edge_property.hpp b/cpp/include/cugraph/edge_property.hpp index 5db579c7f20..f9159f713cc 100644 --- a/cpp/include/cugraph/edge_property.hpp +++ b/cpp/include/cugraph/edge_property.hpp @@ -27,8 +27,6 @@ namespace cugraph { -namespace detail { - template class edge_property_view_t { public: @@ -59,8 +57,6 @@ class edge_dummy_property_view_t { using value_iterator = void*; }; -} // namespace detail - template class edge_property_t { public: @@ -98,8 +94,8 @@ class edge_property_t { edge_partition_edge_counts[i] = size_dataframe_buffer(buffers_[i]); } - return detail::edge_property_view_t( - edge_partition_value_firsts, edge_partition_edge_counts); + return edge_property_view_t(edge_partition_value_firsts, + edge_partition_edge_counts); } auto mutable_view() @@ -113,8 +109,8 @@ class edge_property_t { edge_partition_edge_counts[i] = size_dataframe_buffer(buffers_[i]); } - return detail::edge_property_view_t(edge_partition_value_firsts, - edge_partition_edge_counts); + return edge_property_view_t(edge_partition_value_firsts, + edge_partition_edge_counts); } private: @@ -125,7 +121,7 @@ class edge_dummy_property_t { public: using value_type = thrust::nullopt_t; - auto view() const { return detail::edge_dummy_property_view_t{}; } + auto view() const { return edge_dummy_property_view_t{}; } }; } // namespace cugraph diff --git a/cpp/include/cugraph/eidecl_graph.hpp b/cpp/include/cugraph/eidecl_graph.hpp index 2a7a6e49b94..a07f50ef980 100644 --- a/cpp/include/cugraph/eidecl_graph.hpp +++ b/cpp/include/cugraph/eidecl_graph.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021, NVIDIA CORPORATION. + * Copyright (c) 2020-2022, NVIDIA CORPORATION. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,68 +16,36 @@ #pragma once namespace cugraph { -extern template class graph_t; -extern template class graph_t; -extern template class graph_t; -extern template class graph_t; -extern template class graph_t; -extern template class graph_t; -extern template class graph_t; -extern template class graph_t; -extern template class graph_t; -extern template class graph_t; -extern template class graph_t; -extern template class graph_t; -extern template class graph_t; -extern template class graph_t; -extern template class graph_t; -extern template class graph_t; -extern template class graph_t; -extern template class graph_t; -extern template class graph_t; -extern template class graph_t; -extern template class graph_t; -extern template class graph_t; -extern template class graph_t; -extern template class graph_t; -extern template class graph_t; -extern template class graph_t; -extern template class graph_t; -extern template class graph_t; -extern template class graph_t; -extern template class graph_t; -extern template class graph_t; -extern template class graph_t; -extern template class graph_view_t; -extern template class graph_view_t; -extern template class graph_view_t; -extern template class graph_view_t; -extern template class graph_view_t; -extern template class graph_view_t; -extern template class graph_view_t; -extern template class graph_view_t; -extern template class graph_view_t; -extern template class graph_view_t; -extern template class graph_view_t; -extern template class graph_view_t; -extern template class graph_view_t; -extern template class graph_view_t; -extern template class graph_view_t; -extern template class graph_view_t; -extern template class graph_view_t; -extern template class graph_view_t; -extern template class graph_view_t; -extern template class graph_view_t; -extern template class graph_view_t; -extern template class graph_view_t; -extern template class graph_view_t; -extern template class graph_view_t; -extern template class graph_view_t; -extern template class graph_view_t; -extern template class graph_view_t; -extern template class graph_view_t; -extern template class graph_view_t; -extern template class graph_view_t; -extern template class graph_view_t; -extern template class graph_view_t; +extern template class graph_t; +extern template class graph_t; +extern template class graph_t; +extern template class graph_t; +extern template class graph_t; +extern template class graph_t; +extern template class graph_t; +extern template class graph_t; +extern template class graph_t; +extern template class graph_t; +extern template class graph_t; +extern template class graph_t; +extern template class graph_t; +extern template class graph_t; +extern template class graph_t; +extern template class graph_t; +extern template class graph_view_t; +extern template class graph_view_t; +extern template class graph_view_t; +extern template class graph_view_t; +extern template class graph_view_t; +extern template class graph_view_t; +extern template class graph_view_t; +extern template class graph_view_t; +extern template class graph_view_t; +extern template class graph_view_t; +extern template class graph_view_t; +extern template class graph_view_t; +extern template class graph_view_t; +extern template class graph_view_t; +extern template class graph_view_t; +extern template class graph_view_t; } // namespace cugraph diff --git a/cpp/include/cugraph/graph.hpp b/cpp/include/cugraph/graph.hpp index b3ee7133c87..5a7b4b543d6 100644 --- a/cpp/include/cugraph/graph.hpp +++ b/cpp/include/cugraph/graph.hpp @@ -34,13 +34,6 @@ namespace cugraph { -template -struct edgelist_t { - raft::device_span srcs{}; - raft::device_span dsts{}; - std::optional> weights{}; -}; - template struct graph_meta_t; @@ -72,53 +65,35 @@ struct graph_meta_t> { // graph_t is an owning graph class (note that graph_view_t is a non-owning graph class) template class graph_t; // multi-GPU version -template -class graph_t> - : public detail::graph_base_t { +template +class graph_t> + : public detail::graph_base_t { public: using vertex_type = vertex_t; using edge_type = edge_t; - using weight_type = weight_t; static constexpr bool is_storage_transposed = store_transposed; static constexpr bool is_multi_gpu = multi_gpu; - graph_t(raft::handle_t const& handle) : detail::graph_base_t() {} - - // FIXME: to be deleted once we retire cython.cu - graph_t(raft::handle_t const& handle, - std::vector> const& edgelists, - graph_meta_t meta, - bool do_expensive_check = false); + graph_t(raft::handle_t const& handle) : detail::graph_base_t() {} graph_t( raft::handle_t const& handle, std::vector>&& edge_partition_offsets, std::vector>&& edge_partition_indices, - std::optional>>&& edge_partition_weights, std::optional>>&& edge_partition_dcs_nzd_vertices, graph_meta_t meta, bool do_expensive_check = false); - bool is_weighted() const { return edge_partition_weights_.has_value(); } - - graph_view_t view() const + graph_view_t view() const { std::vector offsets(edge_partition_offsets_.size(), nullptr); std::vector indices(edge_partition_indices_.size(), nullptr); - auto weights = edge_partition_weights_ ? std::make_optional>( - (*edge_partition_weights_).size(), nullptr) - : std::nullopt; auto dcs_nzd_vertices = edge_partition_dcs_nzd_vertices_ ? std::make_optional>( (*edge_partition_dcs_nzd_vertices_).size(), nullptr) @@ -130,7 +105,6 @@ class graph_t( + return graph_view_t( *(this->handle_ptr()), offsets, indices, - weights, dcs_nzd_vertices, dcs_nzd_vertex_counts, graph_view_meta_t{ @@ -247,7 +220,6 @@ class graph_t> edge_partition_offsets_{}; std::vector> edge_partition_indices_{}; - std::optional>> edge_partition_weights_{std::nullopt}; // nzd: nonzero (local) degree std::optional>> edge_partition_dcs_nzd_vertices_{ @@ -291,47 +263,32 @@ class graph_t -class graph_t> - : public detail::graph_base_t { +template +class graph_t> + : public detail::graph_base_t { public: using vertex_type = vertex_t; using edge_type = edge_t; - using weight_type = weight_t; static constexpr bool is_storage_transposed = store_transposed; static constexpr bool is_multi_gpu = multi_gpu; graph_t(raft::handle_t const& handle) - : detail::graph_base_t(), + : detail::graph_base_t(), offsets_(0, handle.get_stream()), indices_(0, handle.get_stream()){}; - // FIXME: to be deleted once we retire cython.cu - graph_t(raft::handle_t const& handle, - edgelist_t const& edgelist, - graph_meta_t meta, - bool do_expensive_check = false); - graph_t(raft::handle_t const& handle, rmm::device_uvector&& offsets, rmm::device_uvector&& indices, - std::optional>&& weights, graph_meta_t meta, bool do_expensive_check = false); - bool is_weighted() const { return weights_.has_value(); } - - graph_view_t view() const + graph_view_t view() const { - return graph_view_t( + return graph_view_t( *(this->handle_ptr()), offsets_.data(), indices_.data(), - weights_ ? std::optional{(*weights_).data()} : std::nullopt, graph_view_meta_t{this->number_of_vertices(), this->number_of_edges(), this->graph_properties(), @@ -341,7 +298,6 @@ class graph_t offsets_; rmm::device_uvector indices_; - std::optional> weights_{std::nullopt}; // segment offsets based on vertex degree, relevant only if sorted_by_global_degree is true std::optional> segment_offsets_{}; diff --git a/cpp/include/cugraph/graph_functions.hpp b/cpp/include/cugraph/graph_functions.hpp index c6479fb0c96..87c0963869c 100644 --- a/cpp/include/cugraph/graph_functions.hpp +++ b/cpp/include/cugraph/graph_functions.hpp @@ -348,11 +348,12 @@ void renumber_local_ext_vertices(raft::handle_t const& handle, * @param handle RAFT handle object to encapsulate resources (e.g. CUDA stream, communicator, and * handles to various CUDA libraries) to run graph algorithms. * @param graph_view Graph view object of the graph to be decompressed. + * @param edge_weight_view Optional view object holding edge weights for @p graph_view. * @param renumber_map If valid, return the renumbered edge list based on the provided @p * renumber_map * @param do_expensive_check A flag to run expensive checks for input arguments (if set to `true`). - * @return Tuple of edge sources, destinations, and (optional) edge weights (if the input graph is - * weighted). + * @return Tuple of edge sources, destinations, and (optional) edge weights (if @p + * edge_weight_view.has_value() is true). */ template , std::optional>> decompress_to_edgelist( raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, std::optional> renumber_map, bool do_expensive_check = false); @@ -413,26 +415,34 @@ symmetrize_edgelist(raft::handle_t const& handle, * @param handle RAFT handle object to encapsulate resources (e.g. CUDA stream, communicator, and * handles to various CUDA libraries) to run graph algorithms. * @param graph Graph object to be symmetrized. + * @param edge_weights Optional owning object holding edge weights for @p graph. * @param renumber_map Renumber map to recover the original vertex IDs from the renumbered vertex * IDs. This should be valid if multi-GPU. * @param reciprocal If true, an edge is kept only when the reversed edge also exists. If false, * keep (and symmetrize) all the edges that appear only in one direction. * @param do_expensive_check A flag to run expensive checks for input arguments (if set to `true`). - * @return rmm::device_uvector Return a symmetrized graph and anew renumber map (to - * recover the original vertex IDs). + * @return Return a symmetrized graph, an owning object holding edge weights (if @p + * edge_weights.has_value() is true) and a new renumber map (to recover the original vertex IDs, if + * @p renumber_map.has_value() is true). */ template -std::tuple, - std::optional>> -symmetrize_graph(raft::handle_t const& handle, - graph_t&& graph, - std::optional>&& renumber_map, - bool reciprocal = false, - bool do_expensive_check = false); +std::tuple< + graph_t, + std::optional< + edge_property_t, weight_t>>, + std::optional>> +symmetrize_graph( + raft::handle_t const& handle, + graph_t&& graph, + std::optional, + weight_t>>&& edge_weights, + std::optional>&& renumber_map, + bool reciprocal = false, + bool do_expensive_check = false); /** * @brief Transpose the input graph. @@ -447,23 +457,31 @@ symmetrize_graph(raft::handle_t const& handle, * @param handle RAFT handle object to encapsulate resources (e.g. CUDA stream, communicator, and * handles to various CUDA libraries) to run graph algorithms. * @param graph Graph object to be transposed. + * @param edge_weights Optional owning object holding edge weights for @p graph. * @param renumber_map Renumber map to recover the original vertex IDs from the renumbered vertex * IDs. This should be valid if multi-GPU. * @param do_expensive_check A flag to run expensive checks for input arguments (if set to `true`). - * @return rmm::device_uvector Return a transposed graph and a new renumber map (to - * recover the original vertex IDs). + * @return Return a transposed graph, an owning object holding edge weights (if @p + * edge_weights.has_value() is true) and a new renumber map (to recover the original vertex IDs, if + * @p renumber_map.has_value() is true). */ template -std::tuple, - std::optional>> -transpose_graph(raft::handle_t const& handle, - graph_t&& graph, - std::optional>&& renumber_map, - bool do_expensive_check = false); +std::tuple< + graph_t, + std::optional< + edge_property_t, weight_t>>, + std::optional>> +transpose_graph( + raft::handle_t const& handle, + graph_t&& graph, + std::optional, + weight_t>>&& edge_weights, + std::optional>&& renumber_map, + bool do_expensive_check = false); /** * @brief Transpose the storage format (no change in an actual graph topology). @@ -481,24 +499,32 @@ transpose_graph(raft::handle_t const& handle, * @param handle RAFT handle object to encapsulate resources (e.g. CUDA stream, communicator, and * handles to various CUDA libraries) to run graph algorithms. * @param graph Graph object to transpose its storage format. + * @param edge_weights Optional owning object holding edge weights for @p graph. * @param renumber_map Renumber map to recover the original vertex IDs from the renumbered vertex * IDs. This should be valid if multi-GPU. * @param do_expensive_check A flag to run expensive checks for input arguments (if set to `true`). * @return std::tuple, - * rmm::device_uvector> Return a storage transposed graph and a new renumber map (to - * recover the original vertex IDs for the returned graph). + * @return Return a storage transposed graph, an owning object holding edge weights (if @p + * edge_weights.has_value() is true) and a new renumber map (to recover the original vertex IDs, if + * @p renumber_map.has_value() is true). */ template -std::tuple, - std::optional>> -transpose_graph_storage(raft::handle_t const& handle, - graph_t&& graph, - std::optional>&& renumber_map, - bool do_expensive_check = false); +std::tuple< + graph_t, + std::optional< + edge_property_t, weight_t>>, + std::optional>> +transpose_graph_storage( + raft::handle_t const& handle, + graph_t&& graph, + std::optional, + weight_t>>&& edge_weights, + std::optional>&& renumber_map, + bool do_expensive_check = false); /** * @brief Compute the coarsened graph. @@ -517,6 +543,7 @@ transpose_graph_storage(raft::handle_t const& handle, * @param handle RAFT handle object to encapsulate resources (e.g. CUDA stream, communicator, and * handles to various CUDA libraries) to run graph algorithms. * @param graph_view Graph view object of the input graph to be coarsened. + * @param edge_weight_view Optional view object holding edge weights for @p graph_view. * @param labels Vertex labels (assigned to this process in multi-GPU) to be used in coarsening. * @param renumber Flag indicating whether to renumber vertices or not (must be true if @p multi_gpu * is true). Setting @p renumber to false is highly discouraged except for testing as this @@ -526,23 +553,25 @@ transpose_graph_storage(raft::handle_t const& handle, * many isolated vertices if the number of unique elements (over the entire set of GPUs in * multi-GPU) in @p labels is much smaller than the assumed number of vertices. * @param do_expensive_check A flag to run expensive checks for input arguments (if set to `true`). - * @return std::tuple, - * rmm::device_uvector> Tuple of the coarsened graph and the renumber map (if @p renumber - * is true). + * @return Tuple of the coarsened graph, coarsened graph edge weights (if @p + * edge_weight_view.has_value() is true) and the renumber map (if @p renumber is true). */ template -std::tuple, - std::optional>> -coarsen_graph( - raft::handle_t const& handle, - graph_view_t const& graph_view, - vertex_t const* labels, - bool renumber, - bool do_expensive_check = false); +std::tuple< + graph_t, + std::optional< + edge_property_t, weight_t>>, + std::optional>> +coarsen_graph(raft::handle_t const& handle, + graph_view_t const& graph_view, + std::optional> edge_weight_view, + vertex_t const* labels, + bool renumber, + bool do_expensive_check = false); /** * @brief Relabel old labels to new labels. @@ -575,6 +604,8 @@ void relabel(raft::handle_t const& handle, bool skip_missing_labels, bool do_expensive_check = false); +// FIXME: the first two elements of the returned tuple should be source & destination instead of +// major & minor. Major & minor shouldn't be used in the non-detail public API. /** * @brief extract induced subgraph(s). * @@ -588,6 +619,7 @@ void relabel(raft::handle_t const& handle, * @param handle RAFT handle object to encapsulate resources (e.g. CUDA stream, communicator, and * handles to various CUDA libraries) to run graph algorithms. * @param graph_view Graph view object, we extract induced subgraphs from @p graph_view. + * @param edge_weight_view Optional view object holding edge weights for @p graph_view. * @param subgraph_offsets Span pointing to subgraph vertex offsets * @param subgraph_vertices Span pointing to subgraph vertices. * @p subgraph_offsets and @p subgraph_vertices provide vertex sets (or local vertex sets in @@ -597,13 +629,11 @@ void relabel(raft::handle_t const& handle, * multi-GPU, the vertex set for each subgraph is distributed in multiple-GPUs and each GPU holds * only the vertices that are local to the GPU. * @param do_expensive_check A flag to run expensive checks for input arguments (if set to `true`). - * @return std::tuple, rmm::device_uvector, - * rmm::device_uvector, rmm::device_uvector> Quadraplet of edge major (destination - * if @p store_transposed is true, source otherwise) vertices, edge minor (source if @p - * store_transposed is true, destination otherwise) vertices, edge weights, and edge offsets for - * each induced subgraphs (size == num_subgraphs + 1). The sizes of the edge major & minor vertices - * are edge_offsets[num_subgraphs]. The size of the edge weights is either - * edge_offsets[num_subgraphs] (if @p graph_view is weighted) or 0 (if @p graph_view is unweighted). + * @return Quadraplet of edge major (destination if @p store_transposed is true, source otherwise) + * vertices, edge minor (source if @p store_transposed is true, destination otherwise) vertices, + * edge weights (if @p edge_weight_view.has_value() is true), and edge offsets for each induced + * subgraphs (size == num_subgraphs + 1). The sizes of the edge major & minor vertices are + * edge_offsets[num_subgraphs]. */ template , rmm::device_uvector> extract_induced_subgraphs( raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, raft::device_span subgraph_offsets, raft::device_span subgraph_vertices, bool do_expensive_check = false); @@ -630,7 +661,6 @@ extract_induced_subgraphs( * * @tparam vertex_t Type of vertex identifiers. Needs to be an integral type. * @tparam edge_t Type of edge identifiers. Needs to be an integral type. - * @tparam weight_t Type of edge weights. Needs to be a floating point type. * @tparam edge_type_t Type of edge type identifiers. Needs to be an integral type. * @tparam store_transposed Flag indicating whether to use sources (if false) or destinations (if * true) as major indices in storing edges using a 2D sparse matrix. transposed. @@ -654,12 +684,10 @@ extract_induced_subgraphs( * @param renumber Flag indicating whether to renumber vertices or not (must be true if @p multi_gpu * is true). * @param do_expensive_check A flag to run expensive checks for input arguments (if set to `true`). - * @return std::tuple, - * std::optional, thrust::tuple>>, std::optional>> - * Tuple of the generated graph and optional edge_property_t object storing edge IDs and types - * (valid if @p edgelist_id_type_pairss.has_value() is true, and a renumber map (if @p renumber is - * true) or) std::nullopt (if @p renumber is false). + * @return Tuple of the generated graph and optional edge_property_t objects storing edge weights + * and edge IDs & types (valid if @p edgelist_weights.has_value() and @p + * edgelist_id_type_pairss.has_value() are true, respectively) and a renumber map (if @p renumber is + * true). */ template -std::tuple, - std::optional< - edge_property_t, - thrust::tuple>>, - std::optional>> +std::tuple< + graph_t, + std::optional< + edge_property_t, weight_t>>, + std::optional, + thrust::tuple>>, + std::optional>> create_graph_from_edgelist( raft::handle_t const& handle, std::optional>&& vertices, @@ -694,7 +724,6 @@ create_graph_from_edgelist( * * @tparam vertex_t Type of vertex identifiers. Needs to be an integral type. * @tparam edge_t Type of edge identifiers. Needs to be an integral type. - * @tparam weight_t Type of edge weights. Needs to be a floating point type. * @tparam store_transposed Flag indicating whether to use sources (if false) or destinations (if * true) as major indices in storing edges using a 2D sparse matrix. transposed. * @tparam multi_gpu Flag indicating whether template instantiation should target single-GPU (false) @@ -705,14 +734,10 @@ create_graph_from_edgelist( * @param start_vertices Optional list of starting vertices to discover two-hop neighbors of * @return tuple containing pairs of vertices that are 2-hops apart. */ -template +template std::tuple, rmm::device_uvector> get_two_hop_neighbors( raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, std::optional> start_vertices); /** @@ -729,6 +754,7 @@ std::tuple, rmm::device_uvector> get_two * handles to various CUDA libraries) to run graph algorithms. * @param graph_view Graph view object of the input graph to compute per-vertex incoming edge weight * sums. + * @param edge_weight_view View object holding edge weights for @p graph_view. * @return Incoming edge weight sums for each vertex. */ template rmm::device_uvector compute_in_weight_sums( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); /** * @brief Compute per-vertex outgoing edge weight sums. @@ -754,6 +781,7 @@ rmm::device_uvector compute_in_weight_sums( * handles to various CUDA libraries) to run graph algorithms. * @param graph_view Graph view object of the input graph to compute per-vertex outgoing edge weight * sums. + * @param edge_weight_view View object holding edge weights for @p graph_view. * @return Outgoing edge weight sums for each vertex. */ template rmm::device_uvector compute_out_weight_sums( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); /** * @brief Compute maximum per-vertex incoming edge weight sums. @@ -779,6 +808,7 @@ rmm::device_uvector compute_out_weight_sums( * handles to various CUDA libraries) to run graph algorithms. * @param graph_view Graph view object of the input graph to compute the maximum per-vertex incoming * edge weight sums. + * @param edge_weight_view View object holding edge weights for @p graph_view. * @return Maximum per-vertex incoming edge weight sums. */ template weight_t compute_max_in_weight_sum( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); /** * @brief Compute maximum per-vertex outgoing edge weight sums. @@ -804,6 +835,7 @@ weight_t compute_max_in_weight_sum( * handles to various CUDA libraries) to run graph algorithms. * @param graph_view Graph view object of the input graph to compute the maximum per-vertex outgoing * edge weight sums. + * @param edge_weight_view View object holding edge weights for @p graph_view. * @return Maximum per-vertex outgoing edge weight sums. */ template weight_t compute_max_out_weight_sum( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); /** * @brief Sum the weights of the entire set of edges. @@ -828,6 +861,7 @@ weight_t compute_max_out_weight_sum( * @param handle RAFT handle object to encapsulate resources (e.g. CUDA stream, communicator, and * handles to various CUDA libraries) to run graph algorithms. * @param graph_view Graph view object of the input graph to sum the edge weights. + * @param edge_weight_view View object holding edge weights for @p graph_view. * @return Sum of the weights of the entire set of edges. */ template weight_t compute_total_edge_weight( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); } // namespace cugraph diff --git a/cpp/include/cugraph/graph_view.hpp b/cpp/include/cugraph/graph_view.hpp index e6ec148ed44..fed3afb72e0 100644 --- a/cpp/include/cugraph/graph_view.hpp +++ b/cpp/include/cugraph/graph_view.hpp @@ -260,7 +260,7 @@ size_t constexpr mid_degree_threshold{1024}; size_t constexpr num_sparse_segments_per_vertex_partition{3}; // Common for both graph_view_t & graph_t and both single-GPU & multi-GPU versions -template +template class graph_base_t : public graph_envelope_t::base_graph_t /*<- visitor logic*/ { public: graph_base_t() = default; // Note: required by visitor logic @@ -382,42 +382,28 @@ struct graph_view_meta_t class graph_view_t; // multi-GPU version -template -class graph_view_t> - : public detail::graph_base_t { +template +class graph_view_t> + : public detail::graph_base_t { public: using vertex_type = vertex_t; using edge_type = edge_t; - using weight_type = weight_t; static constexpr bool is_storage_transposed = store_transposed; static constexpr bool is_multi_gpu = multi_gpu; graph_view_t(raft::handle_t const& handle, std::vector const& edge_partition_offsets, std::vector const& edge_partition_indices, - std::optional> const& edge_partition_weights, std::optional> const& edge_partition_dcs_nzd_vertices, std::optional> const& edge_partition_dcs_nzd_vertex_counts, graph_view_meta_t meta); - bool is_weighted() const { return edge_partition_weights_.has_value(); } - std::vector vertex_partition_range_offsets() const { return partition_.vertex_partition_range_offsets(); @@ -606,7 +592,7 @@ class graph_view_tlocal_vertex_partition_range_last()); } - edge_partition_view_t local_edge_partition_view( + edge_partition_view_t local_edge_partition_view( size_t partition_idx) const { vertex_t major_range_first{}; @@ -638,17 +624,12 @@ class graph_view_t( + return edge_partition_view_t( raft::device_span(edge_partition_offsets_[partition_idx], edge_partition_offsets_[partition_idx] + offset_size), raft::device_span( edge_partition_indices_[partition_idx], edge_partition_indices_[partition_idx] + edge_partition_number_of_edges_[partition_idx]), - edge_partition_weights_ ? std::make_optional>( - (*edge_partition_weights_)[partition_idx], - (*edge_partition_weights_)[partition_idx] + - edge_partition_number_of_edges_[partition_idx]) - : std::nullopt, edge_partition_dcs_nzd_vertices_ ? std::make_optional>( (*edge_partition_dcs_nzd_vertices_)[partition_idx], @@ -765,7 +746,6 @@ class graph_view_t edge_partition_offsets_{}; std::vector edge_partition_indices_{}; - std::optional> edge_partition_weights_{}; // relevant only if we use the CSR + DCSR (or CSC + DCSC) hybrid format std::optional> edge_partition_dcs_nzd_vertices_{}; @@ -811,33 +791,20 @@ class graph_view_t -class graph_view_t> - : public detail::graph_base_t { +template +class graph_view_t> + : public detail::graph_base_t { public: using vertex_type = vertex_t; using edge_type = edge_t; - using weight_type = weight_t; static constexpr bool is_storage_transposed = store_transposed; static constexpr bool is_multi_gpu = multi_gpu; graph_view_t(raft::handle_t const& handle, edge_t const* offsets, vertex_t const* indices, - std::optional weights, graph_view_meta_t meta); - bool is_weighted() const { return weights_.has_value(); } - std::vector vertex_partition_range_offsets() const { return std::vector{local_vertex_partition_range_first(), @@ -945,16 +912,13 @@ class graph_view_t(this->number_of_vertices()); } - edge_partition_view_t local_edge_partition_view( + edge_partition_view_t local_edge_partition_view( size_t partition_idx = 0) const { assert(partition_idx == 0); // there is only one edge partition in single-GPU - return edge_partition_view_t( + return edge_partition_view_t( raft::device_span(offsets_, offsets_ + (this->number_of_vertices() + 1)), raft::device_span(indices_, indices_ + this->number_of_edges()), - weights_ ? std::make_optional>( - *weights_, *weights_ + this->number_of_edges()) - : std::nullopt, this->number_of_vertices()); } @@ -1048,7 +1012,6 @@ class graph_view_t weights_{std::nullopt}; // segment offsets based on vertex degree, relevant only if vertex IDs are renumbered std::optional> segment_offsets_{std::nullopt}; diff --git a/cpp/include/cugraph/utilities/dataframe_buffer.hpp b/cpp/include/cugraph/utilities/dataframe_buffer.hpp index e3339c5f535..ed08a1d89a0 100644 --- a/cpp/include/cugraph/utilities/dataframe_buffer.hpp +++ b/cpp/include/cugraph/utilities/dataframe_buffer.hpp @@ -108,39 +108,44 @@ auto allocate_dataframe_buffer(size_t buffer_size, rmm::cuda_stream_view stream_ std::make_index_sequence(), buffer_size, stream_view); } -template -void resize_dataframe_buffer(Type& buffer, +template +void resize_dataframe_buffer(BufferType& buffer, size_t new_buffer_size, rmm::cuda_stream_view stream_view) { - if constexpr (is_std_tuple_of_arithmetic_vectors::value) { + static_assert(is_std_tuple_of_arithmetic_vectors>::value || + is_arithmetic_vector, rmm::device_uvector>::value); + if constexpr (is_std_tuple_of_arithmetic_vectors>::value) { std::apply([new_buffer_size, stream_view](auto&&... args) { (args.resize(new_buffer_size, stream_view), ...); }, buffer); - } else if constexpr (is_arithmetic_vector::value) { + } else { buffer.resize(new_buffer_size, stream_view); } } -template -void shrink_to_fit_dataframe_buffer(Type& buffer, rmm::cuda_stream_view stream_view) +template +void shrink_to_fit_dataframe_buffer(BufferType& buffer, rmm::cuda_stream_view stream_view) { - if constexpr (is_std_tuple_of_arithmetic_vectors::value) { + static_assert(is_std_tuple_of_arithmetic_vectors>::value || + is_arithmetic_vector, rmm::device_uvector>::value); + if constexpr (is_std_tuple_of_arithmetic_vectors>::value) { std::apply([stream_view](auto&&... args) { (args.shrink_to_fit(stream_view), ...); }, buffer); - } else if constexpr (is_arithmetic_vector::value) { + } else { buffer.shrink_to_fit(stream_view); } } -template -size_t size_dataframe_buffer(Type& buffer) +template +size_t size_dataframe_buffer(BufferType& buffer) { - if constexpr (is_std_tuple_of_arithmetic_vectors::value) { + static_assert(is_std_tuple_of_arithmetic_vectors>::value || + is_arithmetic_vector, rmm::device_uvector>::value); + if constexpr (is_std_tuple_of_arithmetic_vectors>::value) { return std::get<0>(buffer).size(); - } else if constexpr (is_arithmetic_vector::value) { + } else { return buffer.size(); } - return size_t{}; } template void transform(const BufferType& input, BufferType& output, Op&& op) { - if constexpr (is_std_tuple_of_arithmetic_vectors::value) { + static_assert(is_std_tuple_of_arithmetic_vectors>::value || + is_arithmetic_vector, rmm::device_uvector>::value); + if constexpr (is_std_tuple_of_arithmetic_vectors>::value) { size_t constexpr tuple_size = std::tuple_size::value; detail::transform_tuple_impl(std::make_index_sequence(), input, output, op); - } else if constexpr (is_arithmetic_vector::value) { + } else { std::invoke(op, input, output); } } diff --git a/cpp/include/cugraph/utilities/thrust_tuple_utils.hpp b/cpp/include/cugraph/utilities/thrust_tuple_utils.hpp index 230de14326a..83c4e84287e 100644 --- a/cpp/include/cugraph/utilities/thrust_tuple_utils.hpp +++ b/cpp/include/cugraph/utilities/thrust_tuple_utils.hpp @@ -57,6 +57,12 @@ struct compute_thrust_tuple_element_sizes_impl { void compute(std::array::value>& arr) const {} }; +template +size_t sum_thrust_tuple_element_sizes(std::index_sequence) +{ + return (... + sizeof(typename thrust::tuple_element::type)); +} + template auto thrust_tuple_to_std_tuple(TupleType tup, std::index_sequence) { @@ -168,6 +174,13 @@ struct compute_thrust_tuple_element_sizes { } }; +template +constexpr size_t sum_thrust_tuple_element_sizes() +{ + return detail::sum_thrust_tuple_element_sizes( + std::make_index_sequence::value>()); +} + template auto thrust_tuple_to_std_tuple(TupleType tup) { diff --git a/cpp/src/c_api/betweenness_centrality.cpp b/cpp/src/c_api/betweenness_centrality.cpp index 96824ecee98..dcb4d836eba 100644 --- a/cpp/src/c_api/betweenness_centrality.cpp +++ b/cpp/src/c_api/betweenness_centrality.cpp @@ -80,16 +80,20 @@ struct betweenness_centrality_functor : public cugraph::c_api::abstract_functor } auto graph = - reinterpret_cast*>( - graph_->graph_); + reinterpret_cast*>(graph_->graph_); auto graph_view = graph->view(); + auto edge_weights = reinterpret_cast< + cugraph::edge_property_t, + weight_t>*>(graph_->edge_weights_); + auto number_map = reinterpret_cast*>(graph_->number_map_); auto centralities = cugraph::betweenness_centrality( handle_, graph_view, + (edge_weights != nullptr) ? std::make_optional(edge_weights->view()) : std::nullopt, num_vertices_ > 0 ? std::make_optional(std::variant>( static_cast(num_vertices_))) @@ -160,17 +164,21 @@ struct edge_betweenness_centrality_functor : public cugraph::c_api::abstract_fun } auto graph = - reinterpret_cast*>( - graph_->graph_); + reinterpret_cast*>(graph_->graph_); auto graph_view = graph->view(); + auto edge_weights = reinterpret_cast< + cugraph::edge_property_t, + weight_t>*>(graph_->edge_weights_); + auto number_map = reinterpret_cast*>(graph_->number_map_); auto centralities = cugraph::edge_betweenness_centrality( handle_, graph_view, + (edge_weights != nullptr) ? std::make_optional(edge_weights->view()) : std::nullopt, num_vertices_ > 0 ? std::make_optional(std::variant>{ static_cast(num_vertices_)}) diff --git a/cpp/src/c_api/bfs.cpp b/cpp/src/c_api/bfs.cpp index a850e06495f..803e5971237 100644 --- a/cpp/src/c_api/bfs.cpp +++ b/cpp/src/c_api/bfs.cpp @@ -79,8 +79,7 @@ struct bfs_functor : public abstract_functor { } auto graph = - reinterpret_cast*>( - graph_->graph_); + reinterpret_cast*>(graph_->graph_); auto graph_view = graph->view(); @@ -113,7 +112,7 @@ struct bfs_functor : public abstract_functor { graph_view.local_vertex_partition_range_last(), do_expensive_check_); - cugraph::bfs( + cugraph::bfs( handle_, graph_view, distances.data(), diff --git a/cpp/src/c_api/core_number.cpp b/cpp/src/c_api/core_number.cpp index d4bc76ceaeb..964a7b8966d 100644 --- a/cpp/src/c_api/core_number.cpp +++ b/cpp/src/c_api/core_number.cpp @@ -64,12 +64,10 @@ struct core_number_functor : public cugraph::c_api::abstract_functor { error_code_ = cugraph::c_api:: transpose_storage( handle_, graph_, error_.get()); - if (error_code_ != CUGRAPH_SUCCESS) - ; + if (error_code_ != CUGRAPH_SUCCESS) return; } auto graph = - reinterpret_cast*>( - graph_->graph_); + reinterpret_cast*>(graph_->graph_); auto graph_view = graph->view(); @@ -80,14 +78,13 @@ struct core_number_functor : public cugraph::c_api::abstract_functor { auto degree_type = reinterpret_cast(degree_type); - cugraph::core_number( - handle_, - graph_view, - core_numbers.data(), - degree_type, - size_t{0}, - std::numeric_limits::max(), - do_expensive_check_); + cugraph::core_number(handle_, + graph_view, + core_numbers.data(), + degree_type, + size_t{0}, + std::numeric_limits::max(), + do_expensive_check_); rmm::device_uvector vertex_ids(graph_view.local_vertex_partition_range_size(), handle_.get_stream()); diff --git a/cpp/src/c_api/eigenvector_centrality.cpp b/cpp/src/c_api/eigenvector_centrality.cpp index 69dcb94181e..3d10a7d2b0e 100644 --- a/cpp/src/c_api/eigenvector_centrality.cpp +++ b/cpp/src/c_api/eigenvector_centrality.cpp @@ -72,16 +72,21 @@ struct eigenvector_centrality_functor : public cugraph::c_api::abstract_functor if (error_code_ != CUGRAPH_SUCCESS) return; } - auto graph = reinterpret_cast*>( - graph_->graph_); + auto graph = + reinterpret_cast*>(graph_->graph_); auto graph_view = graph->view(); + auto edge_weights = reinterpret_cast< + cugraph::edge_property_t, + weight_t>*>(graph_->edge_weights_); + auto number_map = reinterpret_cast*>(graph_->number_map_); auto centralities = cugraph::eigenvector_centrality( handle_, graph_view, + (edge_weights != nullptr) ? std::make_optional(edge_weights->view()) : std::nullopt, std::optional>{}, static_cast(epsilon_), max_iterations_, diff --git a/cpp/src/c_api/extract_ego.cpp b/cpp/src/c_api/extract_ego.cpp index 8cbb19de55d..465e53f8259 100644 --- a/cpp/src/c_api/extract_ego.cpp +++ b/cpp/src/c_api/extract_ego.cpp @@ -75,11 +75,14 @@ struct extract_ego_functor : public cugraph::c_api::abstract_functor { } auto graph = - reinterpret_cast*>( - graph_->graph_); + reinterpret_cast*>(graph_->graph_); auto graph_view = graph->view(); + auto edge_weights = reinterpret_cast< + cugraph::edge_property_t, + weight_t>*>(graph_->edge_weights_); + auto number_map = reinterpret_cast*>(graph_->number_map_); rmm::device_uvector source_vertices(source_vertices_->size_, handle_.get_stream()); @@ -106,6 +109,7 @@ struct extract_ego_functor : public cugraph::c_api::abstract_functor { cugraph::extract_ego( handle_, graph_view, + (edge_weights != nullptr) ? std::make_optional(edge_weights->view()) : std::nullopt, raft::device_span{source_vertices.data(), source_vertices.size()}, radius_, do_expensive_check_); diff --git a/cpp/src/c_api/extract_paths.cpp b/cpp/src/c_api/extract_paths.cpp index fa3c4fe843d..be019999ce9 100644 --- a/cpp/src/c_api/extract_paths.cpp +++ b/cpp/src/c_api/extract_paths.cpp @@ -80,8 +80,7 @@ struct extract_paths_functor : public abstract_functor { } auto graph = - reinterpret_cast*>( - graph_->graph_); + reinterpret_cast*>(graph_->graph_); auto graph_view = graph->view(); @@ -119,14 +118,13 @@ struct extract_paths_functor : public abstract_functor { graph_view.local_vertex_partition_range_last(), false); - auto [result, max_path_length] = - cugraph::extract_bfs_paths( - handle_, - graph_view, - paths_result_->distances_->view()->as_type(), - predecessors.data(), - destinations.data(), - destinations.size()); + auto [result, max_path_length] = cugraph::extract_bfs_paths( + handle_, + graph_view, + paths_result_->distances_->view()->as_type(), + predecessors.data(), + destinations.data(), + destinations.size()); std::vector vertex_partition_range_lasts = graph_view.vertex_partition_range_lasts(); diff --git a/cpp/src/c_api/graph.hpp b/cpp/src/c_api/graph.hpp index cf1bc82f9ae..b629e917726 100644 --- a/cpp/src/c_api/graph.hpp +++ b/cpp/src/c_api/graph.hpp @@ -37,9 +37,12 @@ struct cugraph_graph_t { void* graph_; // graph_t<...>* void* number_map_; // rmm::device_uvector* + void* edge_weights_; // edge_property_t< + // graph_view_t, + // weight_t>* void* edge_properties_; // edge_property_t< - // graph_view_t, thrust::tuple>> + // graph_view_t, + // thrust::tuple>> }; template store_transposed_) { auto p_graph = - reinterpret_cast*>( + reinterpret_cast*>( graph->graph_); auto number_map = reinterpret_cast*>(graph->number_map_); + auto edge_weights = reinterpret_cast< + edge_property_t, weight_t>*>( + graph->edge_weights_); + + if (graph->edge_properties_ != nullptr) { + error->error_message_ = + "transpose failed, transposing a graph with edge ID, type pairs unimplemented."; + return CUGRAPH_NOT_IMPLEMENTED; + } + auto graph_transposed = - new cugraph::graph_t(handle); + new cugraph::graph_t(handle); - std::optional> new_number_map{}; + std::optional> new_number_map{std::nullopt}; - std::tie(*graph_transposed, new_number_map) = cugraph::transpose_graph_storage( - handle, - std::move(*p_graph), - std::make_optional>(std::move(*number_map))); + auto new_edge_weights = new std::optional< + edge_property_t, weight_t>>( + std::nullopt); + + std::tie(*graph_transposed, *new_edge_weights, new_number_map) = + cugraph::transpose_graph_storage( + handle, + std::move(*p_graph), + (edge_weights != nullptr) ? std::make_optional(std::move(*edge_weights)) : std::nullopt, + std::make_optional>(std::move(*number_map))); *number_map = std::move(new_number_map.value()); + if (edge_weights != nullptr) { delete edge_weights; } + delete p_graph; graph->graph_ = graph_transposed; + graph->edge_weights_ = new_edge_weights; graph->store_transposed_ = !store_transposed; return CUGRAPH_SUCCESS; diff --git a/cpp/src/c_api/graph_functions.cpp b/cpp/src/c_api/graph_functions.cpp index 3b385b84371..6c813191233 100644 --- a/cpp/src/c_api/graph_functions.cpp +++ b/cpp/src/c_api/graph_functions.cpp @@ -122,8 +122,7 @@ struct two_hop_neighbors_functor : public cugraph::c_api::abstract_functor { } auto graph = - reinterpret_cast*>( - graph_->graph_); + reinterpret_cast*>(graph_->graph_); auto graph_view = graph->view(); auto number_map = reinterpret_cast*>(graph_->number_map_); diff --git a/cpp/src/c_api/graph_mg.cpp b/cpp/src/c_api/graph_mg.cpp index ec892d4055b..fe5a0f24338 100644 --- a/cpp/src/c_api/graph_mg.cpp +++ b/cpp/src/c_api/graph_mg.cpp @@ -81,9 +81,14 @@ struct create_graph_functor : public cugraph::c_api::abstract_functor { std::optional> new_number_map; std::optional, + cugraph::graph_view_t, + weight_t>> + new_edge_weights{std::nullopt}; + + std::optional, thrust::tuple>> - new_edge_properties; + new_edge_properties{std::nullopt}; rmm::device_uvector edgelist_srcs(src_->size_, handle_.get_stream()); rmm::device_uvector edgelist_dsts(dst_->size_, handle_.get_stream()); @@ -106,7 +111,7 @@ struct create_graph_functor : public cugraph::c_api::abstract_functor { } std::optional, rmm::device_uvector>> - edgelist_edge_tuple{}; + edgelist_edge_tuple{std::nullopt}; if (edge_type_ids_ && edge_ids_) { auto edgelist_edge_type_ids = @@ -139,17 +144,20 @@ struct create_graph_functor : public cugraph::c_api::abstract_functor { std::move(store_transposed ? edgelist_srcs : edgelist_dsts), std::move(edgelist_weights)); - auto graph = - new cugraph::graph_t(handle_); + auto graph = new cugraph::graph_t(handle_); rmm::device_uvector* number_map = new rmm::device_uvector(0, handle_.get_stream()); + auto edge_weights = new cugraph::edge_property_t< + cugraph::graph_view_t, + weight_t>(handle_); + auto edge_properties = new cugraph::edge_property_t< - cugraph::graph_view_t, + cugraph::graph_view_t, thrust::tuple>(handle_); - std::tie(*graph, new_edge_properties, new_number_map) = + std::tie(*graph, new_edge_weights, new_edge_properties, new_number_map) = cugraph::create_graph_from_edgelistview().local_vertex_partition_range_first()); } + if (new_edge_weights) { *edge_weights = std::move(new_edge_weights.value()); } + if (new_edge_properties) { *edge_properties = std::move(new_edge_properties.value()); } // Set up return @@ -188,7 +198,8 @@ struct create_graph_functor : public cugraph::c_api::abstract_functor { multi_gpu, graph, number_map, - edge_properties}; + new_edge_weights ? edge_weights : nullptr, + new_edge_properties ? edge_properties : nullptr}; result_ = reinterpret_cast(result); } @@ -198,10 +209,15 @@ struct create_graph_functor : public cugraph::c_api::abstract_functor { struct destroy_graph_functor : public cugraph::c_api::abstract_functor { void* graph_; void* number_map_; + void* edge_weights_; void* edge_properties_; - destroy_graph_functor(void* graph, void* number_map, void* edge_properties) - : abstract_functor(), graph_(graph), number_map_(number_map), edge_properties_(edge_properties) + destroy_graph_functor(void* graph, void* number_map, void* edge_weights, void* edge_properties) + : abstract_functor(), + graph_(graph), + number_map_(number_map), + edge_weights_(edge_weights), + edge_properties_(edge_properties) { } @@ -214,8 +230,7 @@ struct destroy_graph_functor : public cugraph::c_api::abstract_functor { void operator()() { auto internal_graph_pointer = - reinterpret_cast*>( - graph_); + reinterpret_cast*>(graph_); delete internal_graph_pointer; @@ -224,11 +239,15 @@ struct destroy_graph_functor : public cugraph::c_api::abstract_functor { delete internal_number_map_pointer; - auto internal_edge_property_pointer = reinterpret_cast, - thrust::tuple>*>(edge_properties_); + auto internal_edge_weight_pointer = reinterpret_cast< + cugraph::edge_property_t, + weight_t>*>(edge_weights_); + if (internal_edge_weight_pointer) { delete internal_edge_weight_pointer; } - delete internal_edge_property_pointer; + auto internal_edge_property_pointer = reinterpret_cast< + cugraph::edge_property_t, + thrust::tuple>*>(edge_properties_); + if (internal_edge_property_pointer) { delete internal_edge_property_pointer; } } }; @@ -360,8 +379,10 @@ extern "C" void cugraph_mg_graph_free(cugraph_graph_t* ptr_graph) if (ptr_graph != NULL) { auto internal_pointer = reinterpret_cast(ptr_graph); - destroy_graph_functor functor( - internal_pointer->graph_, internal_pointer->number_map_, internal_pointer->edge_properties_); + destroy_graph_functor functor(internal_pointer->graph_, + internal_pointer->number_map_, + internal_pointer->edge_weights_, + internal_pointer->edge_properties_); cugraph::dispatch::vertex_dispatcher( cugraph::c_api::dtypes_mapping[internal_pointer->vertex_type_], diff --git a/cpp/src/c_api/graph_sg.cpp b/cpp/src/c_api/graph_sg.cpp index abc67296c67..bc16a313ab3 100644 --- a/cpp/src/c_api/graph_sg.cpp +++ b/cpp/src/c_api/graph_sg.cpp @@ -85,9 +85,14 @@ struct create_graph_functor : public cugraph::c_api::abstract_functor { std::optional> new_number_map; std::optional, + cugraph::graph_view_t, + weight_t>> + new_edge_weights{std::nullopt}; + + std::optional, thrust::tuple>> - new_edge_properties; + new_edge_properties{std::nullopt}; rmm::device_uvector edgelist_srcs(src_->size_, handle_.get_stream()); rmm::device_uvector edgelist_dsts(dst_->size_, handle_.get_stream()); @@ -110,7 +115,7 @@ struct create_graph_functor : public cugraph::c_api::abstract_functor { } std::optional, rmm::device_uvector>> - edgelist_edge_tuple{}; + edgelist_edge_tuple{std::nullopt}; if (edge_type_ids_ && edge_ids_) { auto edgelist_edge_type_ids = @@ -133,17 +138,20 @@ struct create_graph_functor : public cugraph::c_api::abstract_functor { std::make_tuple(std::move(edgelist_edge_ids), std::move(edgelist_edge_type_ids)); } - auto graph = - new cugraph::graph_t(handle_); + auto graph = new cugraph::graph_t(handle_); rmm::device_uvector* number_map = new rmm::device_uvector(0, handle_.get_stream()); + auto edge_weights = new cugraph::edge_property_t< + cugraph::graph_view_t, + weight_t>(handle_); + auto edge_properties = new cugraph::edge_property_t< - cugraph::graph_view_t, + cugraph::graph_view_t, thrust::tuple>(handle_); - std::tie(*graph, std::ignore, new_number_map) = + std::tie(*graph, new_edge_weights, new_edge_properties, new_number_map) = cugraph::create_graph_from_edgelistview().local_vertex_partition_range_first()); } + if (new_edge_weights) { *edge_weights = std::move(new_edge_weights.value()); } + if (new_edge_properties) { *edge_properties = std::move(new_edge_properties.value()); } // Set up return @@ -182,7 +192,8 @@ struct create_graph_functor : public cugraph::c_api::abstract_functor { multi_gpu, graph, number_map, - edge_properties}; + new_edge_weights ? edge_weights : nullptr, + new_edge_properties ? edge_properties : nullptr}; result_ = reinterpret_cast(result); } @@ -242,9 +253,14 @@ struct create_graph_csr_functor : public cugraph::c_api::abstract_functor { std::optional> new_number_map; std::optional, + cugraph::graph_view_t, + weight_t>> + new_edge_weights{std::nullopt}; + + std::optional, thrust::tuple>> - new_edge_properties; + new_edge_properties{std::nullopt}; rmm::device_uvector edgelist_srcs(0, handle_.get_stream()); rmm::device_uvector edgelist_dsts(indices_->size_, handle_.get_stream()); @@ -292,17 +308,20 @@ struct create_graph_csr_functor : public cugraph::c_api::abstract_functor { std::make_tuple(std::move(edgelist_edge_ids), std::move(edgelist_edge_type_ids)); } - auto graph = - new cugraph::graph_t(handle_); + auto graph = new cugraph::graph_t(handle_); rmm::device_uvector* number_map = new rmm::device_uvector(0, handle_.get_stream()); + auto edge_weights = new cugraph::edge_property_t< + cugraph::graph_view_t, + weight_t>(handle_); + auto edge_properties = new cugraph::edge_property_t< - cugraph::graph_view_t, + cugraph::graph_view_t, thrust::tuple>(handle_); - std::tie(*graph, std::ignore, new_number_map) = + std::tie(*graph, new_edge_weights, new_edge_properties, new_number_map) = cugraph::create_graph_from_edgelistview().local_vertex_partition_range_first()); } + if (new_edge_weights) { *edge_weights = std::move(new_edge_weights.value()); } + if (new_edge_properties) { *edge_properties = std::move(new_edge_properties.value()); } // Set up return @@ -341,7 +362,8 @@ struct create_graph_csr_functor : public cugraph::c_api::abstract_functor { multi_gpu, graph, number_map, - edge_properties}; + new_edge_weights ? edge_weights : nullptr, + new_edge_properties ? edge_properties : nullptr}; result_ = reinterpret_cast(result); } @@ -351,10 +373,15 @@ struct create_graph_csr_functor : public cugraph::c_api::abstract_functor { struct destroy_graph_functor : public cugraph::c_api::abstract_functor { void* graph_; void* number_map_; + void* edge_weights_; void* edge_properties_; - destroy_graph_functor(void* graph, void* number_map, void* edge_properties) - : abstract_functor(), graph_(graph), number_map_(number_map), edge_properties_(edge_properties) + destroy_graph_functor(void* graph, void* number_map, void* edge_weights, void* edge_properties) + : abstract_functor(), + graph_(graph), + number_map_(number_map), + edge_weights_(edge_weights), + edge_properties_(edge_properties) { } @@ -367,8 +394,7 @@ struct destroy_graph_functor : public cugraph::c_api::abstract_functor { void operator()() { auto internal_graph_pointer = - reinterpret_cast*>( - graph_); + reinterpret_cast*>(graph_); delete internal_graph_pointer; @@ -377,10 +403,15 @@ struct destroy_graph_functor : public cugraph::c_api::abstract_functor { delete internal_number_map_pointer; - auto internal_edge_property_pointer = reinterpret_cast, - thrust::tuple>*>(edge_properties_); - delete internal_edge_property_pointer; + auto internal_edge_weight_pointer = reinterpret_cast< + cugraph::edge_property_t, + weight_t>*>(edge_weights_); + if (internal_edge_weight_pointer) { delete internal_edge_weight_pointer; } + + auto internal_edge_property_pointer = reinterpret_cast< + cugraph::edge_property_t, + thrust::tuple>*>(edge_properties_); + if (internal_edge_property_pointer) { delete internal_edge_property_pointer; } } }; @@ -604,8 +635,10 @@ extern "C" void cugraph_sg_graph_free(cugraph_graph_t* ptr_graph) { auto internal_pointer = reinterpret_cast(ptr_graph); - destroy_graph_functor functor( - internal_pointer->graph_, internal_pointer->number_map_, internal_pointer->edge_properties_); + destroy_graph_functor functor(internal_pointer->graph_, + internal_pointer->number_map_, + internal_pointer->edge_weights_, + internal_pointer->edge_properties_); cugraph::dispatch::vertex_dispatcher( cugraph::c_api::dtypes_mapping[internal_pointer->vertex_type_], diff --git a/cpp/src/c_api/hits.cpp b/cpp/src/c_api/hits.cpp index 586eed3d1f0..1dcf1604100 100644 --- a/cpp/src/c_api/hits.cpp +++ b/cpp/src/c_api/hits.cpp @@ -99,8 +99,8 @@ struct hits_functor : public cugraph::c_api::abstract_functor { if (error_code_ != CUGRAPH_SUCCESS) return; } - auto graph = reinterpret_cast*>( - graph_->graph_); + auto graph = + reinterpret_cast*>(graph_->graph_); auto graph_view = graph->view(); diff --git a/cpp/src/c_api/induced_subgraph.cpp b/cpp/src/c_api/induced_subgraph.cpp index 5c442e90ac3..3af73060dea 100644 --- a/cpp/src/c_api/induced_subgraph.cpp +++ b/cpp/src/c_api/induced_subgraph.cpp @@ -77,11 +77,14 @@ struct induced_subgraph_functor : public cugraph::c_api::abstract_functor { } auto graph = - reinterpret_cast*>( - graph_->graph_); + reinterpret_cast*>(graph_->graph_); auto graph_view = graph->view(); + auto edge_weights = reinterpret_cast< + cugraph::edge_property_t, + weight_t>*>(graph_->edge_weights_); + auto number_map = reinterpret_cast*>(graph_->number_map_); rmm::device_uvector subgraph_offsets(0, handle_.get_stream()); @@ -123,6 +126,7 @@ struct induced_subgraph_functor : public cugraph::c_api::abstract_functor { auto [src, dst, wgt, graph_offsets] = cugraph::extract_induced_subgraphs( handle_, graph_view, + (edge_weights != nullptr) ? std::make_optional(edge_weights->view()) : std::nullopt, raft::device_span{subgraph_offsets.data(), subgraph_offsets.size()}, raft::device_span{subgraph_vertices.data(), subgraph_vertices.size()}, do_expensive_check_); diff --git a/cpp/src/c_api/k_core.cpp b/cpp/src/c_api/k_core.cpp index 8f038c265d4..57729ae15a4 100644 --- a/cpp/src/c_api/k_core.cpp +++ b/cpp/src/c_api/k_core.cpp @@ -76,11 +76,14 @@ struct k_core_functor : public cugraph::c_api::abstract_functor { // FIXME: Transpose_storage may have a bug, since if store_transposed is True it can reverse // the bool value of is_symmetric auto graph = - reinterpret_cast*>( - graph_->graph_); + reinterpret_cast*>(graph_->graph_); auto graph_view = graph->view(); + auto edge_weights = reinterpret_cast< + cugraph::edge_property_t, + weight_t>*>(graph_->edge_weights_); + auto number_map = reinterpret_cast*>(graph_->number_map_); rmm::device_uvector k_cores(graph_view.local_vertex_partition_range_size(), @@ -93,6 +96,7 @@ struct k_core_functor : public cugraph::c_api::abstract_functor { cugraph::k_core( handle_, graph_view, + (edge_weights != nullptr) ? std::make_optional(edge_weights->view()) : std::nullopt, k_, std::make_optional(degree_type), (core_result_ == nullptr) diff --git a/cpp/src/c_api/katz.cpp b/cpp/src/c_api/katz.cpp index 3d73d88c331..952265062b6 100644 --- a/cpp/src/c_api/katz.cpp +++ b/cpp/src/c_api/katz.cpp @@ -82,11 +82,15 @@ struct katz_functor : public cugraph::c_api::abstract_functor { if (error_code_ != CUGRAPH_SUCCESS) return; } - auto graph = reinterpret_cast*>( - graph_->graph_); + auto graph = + reinterpret_cast*>(graph_->graph_); auto graph_view = graph->view(); + auto edge_weights = reinterpret_cast< + cugraph::edge_property_t, + weight_t>*>(graph_->edge_weights_); + auto number_map = reinterpret_cast*>(graph_->number_map_); rmm::device_uvector centralities(graph_view.local_vertex_partition_range_size(), @@ -120,6 +124,7 @@ struct katz_functor : public cugraph::c_api::abstract_functor { cugraph::katz_centrality( handle_, graph_view, + (edge_weights != nullptr) ? std::make_optional(edge_weights->view()) : std::nullopt, betas_ == nullptr ? nullptr : betas.data(), centralities.data(), static_cast(alpha_), diff --git a/cpp/src/c_api/louvain.cpp b/cpp/src/c_api/louvain.cpp index 01317903833..9442966106a 100644 --- a/cpp/src/c_api/louvain.cpp +++ b/cpp/src/c_api/louvain.cpp @@ -84,18 +84,26 @@ struct louvain_functor : public cugraph::c_api::abstract_functor { } auto graph = - reinterpret_cast*>( - graph_->graph_); + reinterpret_cast*>(graph_->graph_); auto graph_view = graph->view(); + auto edge_weights = reinterpret_cast< + cugraph::edge_property_t, + weight_t>*>(graph_->edge_weights_); + auto number_map = reinterpret_cast*>(graph_->number_map_); rmm::device_uvector clusters(graph_view.local_vertex_partition_range_size(), handle_.get_stream()); auto [level, modularity] = cugraph::louvain( - handle_, graph_view, clusters.data(), max_level_, static_cast(resolution_)); + handle_, + graph_view, + (edge_weights != nullptr) ? std::make_optional(edge_weights->view()) : std::nullopt, + clusters.data(), + max_level_, + static_cast(resolution_)); rmm::device_uvector vertices(graph_view.local_vertex_partition_range_size(), handle_.get_stream()); diff --git a/cpp/src/c_api/pagerank.cpp b/cpp/src/c_api/pagerank.cpp index 7f03b137281..af51c222daf 100644 --- a/cpp/src/c_api/pagerank.cpp +++ b/cpp/src/c_api/pagerank.cpp @@ -109,11 +109,15 @@ struct pagerank_functor : public cugraph::c_api::abstract_functor { if (error_code_ != CUGRAPH_SUCCESS) return; } - auto graph = reinterpret_cast*>( - graph_->graph_); + auto graph = + reinterpret_cast*>(graph_->graph_); auto graph_view = graph->view(); + auto edge_weights = reinterpret_cast< + cugraph::edge_property_t, + weight_t>*>(graph_->edge_weights_); + auto number_map = reinterpret_cast*>(graph_->number_map_); rmm::device_uvector pageranks(graph_view.local_vertex_partition_range_size(), @@ -212,6 +216,7 @@ struct pagerank_functor : public cugraph::c_api::abstract_functor { cugraph::pagerank( handle_, graph_view, + (edge_weights != nullptr) ? std::make_optional(edge_weights->view()) : std::nullopt, precomputed_vertex_out_weight_sums_ ? std::make_optional(precomputed_vertex_out_weight_sums.data()) : std::nullopt, diff --git a/cpp/src/c_api/random_walks.cpp b/cpp/src/c_api/random_walks.cpp index 534a2fa29fe..4f3198fb967 100644 --- a/cpp/src/c_api/random_walks.cpp +++ b/cpp/src/c_api/random_walks.cpp @@ -90,11 +90,14 @@ struct node2vec_functor : public abstract_functor { } auto graph = - reinterpret_cast*>( - graph_->graph_); + reinterpret_cast*>(graph_->graph_); auto graph_view = graph->view(); + auto edge_weights = reinterpret_cast< + cugraph::edge_property_t, + weight_t>*>(graph_->edge_weights_); + auto number_map = reinterpret_cast*>(graph_->number_map_); rmm::device_uvector start_vertices(start_vertices_->size_, handle_.get_stream()); @@ -120,6 +123,7 @@ struct node2vec_functor : public abstract_functor { auto [paths, weights, sizes] = cugraph::random_walks( handle_, graph_view, + (edge_weights != nullptr) ? std::make_optional(edge_weights->view()) : std::nullopt, start_vertices.data(), static_cast(start_vertices.size()), static_cast(max_length_), @@ -191,11 +195,14 @@ struct uniform_random_walks_functor : public cugraph::c_api::abstract_functor { } auto graph = - reinterpret_cast*>( - graph_->graph_); + reinterpret_cast*>(graph_->graph_); auto graph_view = graph->view(); + auto edge_weights = reinterpret_cast< + cugraph::edge_property_t, + weight_t>*>(graph_->edge_weights_); + auto number_map = reinterpret_cast*>(graph_->number_map_); rmm::device_uvector start_vertices(start_vertices_->size_, handle_.get_stream()); @@ -219,6 +226,7 @@ struct uniform_random_walks_functor : public cugraph::c_api::abstract_functor { auto [paths, weights] = cugraph::uniform_random_walks( handle_, graph_view, + (edge_weights != nullptr) ? std::make_optional(edge_weights->view()) : std::nullopt, raft::device_span{start_vertices.data(), start_vertices.size()}, max_length_, seed_); @@ -291,11 +299,14 @@ struct biased_random_walks_functor : public cugraph::c_api::abstract_functor { } auto graph = - reinterpret_cast*>( - graph_->graph_); + reinterpret_cast*>(graph_->graph_); auto graph_view = graph->view(); + auto edge_weights = reinterpret_cast< + cugraph::edge_property_t, + weight_t>*>(graph_->edge_weights_); + auto number_map = reinterpret_cast*>(graph_->number_map_); rmm::device_uvector start_vertices(start_vertices_->size_, handle_.get_stream()); @@ -319,6 +330,7 @@ struct biased_random_walks_functor : public cugraph::c_api::abstract_functor { auto [paths, weights] = cugraph::biased_random_walks( handle_, graph_view, + edge_weights->view(), raft::device_span{start_vertices.data(), start_vertices.size()}, max_length_, seed_); @@ -392,11 +404,14 @@ struct node2vec_random_walks_functor : public cugraph::c_api::abstract_functor { } auto graph = - reinterpret_cast*>( - graph_->graph_); + reinterpret_cast*>(graph_->graph_); auto graph_view = graph->view(); + auto edge_weights = reinterpret_cast< + cugraph::edge_property_t, + weight_t>*>(graph_->edge_weights_); + auto number_map = reinterpret_cast*>(graph_->number_map_); rmm::device_uvector start_vertices(start_vertices_->size_, handle_.get_stream()); @@ -420,6 +435,7 @@ struct node2vec_random_walks_functor : public cugraph::c_api::abstract_functor { auto [paths, weights] = cugraph::node2vec_random_walks( handle_, graph_view, + (edge_weights != nullptr) ? std::make_optional(edge_weights->view()) : std::nullopt, raft::device_span{start_vertices.data(), start_vertices.size()}, max_length_, static_cast(p_), diff --git a/cpp/src/c_api/similarity.cpp b/cpp/src/c_api/similarity.cpp index 9e077f8e93f..3241018bfbd 100644 --- a/cpp/src/c_api/similarity.cpp +++ b/cpp/src/c_api/similarity.cpp @@ -88,11 +88,14 @@ struct similarity_functor : public cugraph::c_api::abstract_functor { } auto graph = - reinterpret_cast*>( - graph_->graph_); + reinterpret_cast*>(graph_->graph_); auto graph_view = graph->view(); + auto edge_weights = reinterpret_cast< + cugraph::edge_property_t, + weight_t>*>(graph_->edge_weights_); + auto number_map = reinterpret_cast*>(graph_->number_map_); rmm::device_uvector v1(vertex_pairs_->first_->size_, handle_.get_stream()); @@ -126,6 +129,7 @@ struct similarity_functor : public cugraph::c_api::abstract_functor { auto similarity_coefficients = call_similarity_(handle_, graph_view, + use_weight_ ? std::make_optional(edge_weights->view()) : std::nullopt, std::make_tuple(raft::device_span{v1.data(), v1.size()}, raft::device_span{v2.data(), v2.size()}), use_weight_); @@ -141,11 +145,12 @@ struct jaccard_functor { template rmm::device_uvector operator()( raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view, std::tuple, raft::device_span> vertex_pairs, bool use_weights) { - return cugraph::jaccard_coefficients(handle, graph_view, vertex_pairs, use_weights); + return cugraph::jaccard_coefficients(handle, graph_view, edge_weight_view, vertex_pairs); } }; @@ -153,11 +158,12 @@ struct sorensen_functor { template rmm::device_uvector operator()( raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view, std::tuple, raft::device_span> vertex_pairs, bool use_weights) { - return cugraph::sorensen_coefficients(handle, graph_view, vertex_pairs, use_weights); + return cugraph::sorensen_coefficients(handle, graph_view, edge_weight_view, vertex_pairs); } }; @@ -165,11 +171,12 @@ struct overlap_functor { template rmm::device_uvector operator()( raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view, std::tuple, raft::device_span> vertex_pairs, bool use_weights) { - return cugraph::overlap_coefficients(handle, graph_view, vertex_pairs, use_weights); + return cugraph::overlap_coefficients(handle, graph_view, edge_weight_view, vertex_pairs); } }; @@ -199,6 +206,13 @@ extern "C" cugraph_error_code_t cugraph_jaccard_coefficients( cugraph_similarity_result_t** result, cugraph_error_t** error) { + if (use_weight) { + CAPI_EXPECTS( + reinterpret_cast(graph)->edge_weights_ != nullptr, + CUGRAPH_INVALID_INPUT, + "use_weight is true but edge weights are not provided.", + *error); + } similarity_functor functor( handle, graph, vertex_pairs, jaccard_functor{}, use_weight, do_expensive_check); @@ -214,6 +228,13 @@ extern "C" cugraph_error_code_t cugraph_sorensen_coefficients( cugraph_similarity_result_t** result, cugraph_error_t** error) { + if (use_weight) { + CAPI_EXPECTS( + reinterpret_cast(graph)->edge_weights_ != nullptr, + CUGRAPH_INVALID_INPUT, + "use_weight is true but edge weights are not provided.", + *error); + } similarity_functor functor( handle, graph, vertex_pairs, sorensen_functor{}, use_weight, do_expensive_check); @@ -229,6 +250,13 @@ extern "C" cugraph_error_code_t cugraph_overlap_coefficients( cugraph_similarity_result_t** result, cugraph_error_t** error) { + if (use_weight) { + CAPI_EXPECTS( + reinterpret_cast(graph)->edge_weights_ != nullptr, + CUGRAPH_INVALID_INPUT, + "use_weight is true but edge weights are not provided.", + *error); + } similarity_functor functor( handle, graph, vertex_pairs, overlap_functor{}, use_weight, do_expensive_check); diff --git a/cpp/src/c_api/sssp.cpp b/cpp/src/c_api/sssp.cpp index e4b2b3c7073..031be637dd5 100644 --- a/cpp/src/c_api/sssp.cpp +++ b/cpp/src/c_api/sssp.cpp @@ -75,11 +75,14 @@ struct sssp_functor : public abstract_functor { } auto graph = - reinterpret_cast*>( - graph_->graph_); + reinterpret_cast*>(graph_->graph_); auto graph_view = graph->view(); + auto edge_weights = reinterpret_cast< + cugraph::edge_property_t, + weight_t>*>(graph_->edge_weights_); + auto number_map = reinterpret_cast*>(graph_->number_map_); rmm::device_uvector source_ids(1, handle_.get_stream()); @@ -110,6 +113,7 @@ struct sssp_functor : public abstract_functor { cugraph::sssp( handle_, graph_view, + edge_weights->view(), distances.data(), compute_predecessors_ ? predecessors.data() : nullptr, src, diff --git a/cpp/src/c_api/triangle_count.cpp b/cpp/src/c_api/triangle_count.cpp index 12387de480e..a90df366c80 100644 --- a/cpp/src/c_api/triangle_count.cpp +++ b/cpp/src/c_api/triangle_count.cpp @@ -81,8 +81,7 @@ struct triangle_count_functor : public cugraph::c_api::abstract_functor { } auto graph = - reinterpret_cast*>( - graph_->graph_); + reinterpret_cast*>(graph_->graph_); auto graph_view = graph->view(); @@ -115,7 +114,7 @@ struct triangle_count_functor : public cugraph::c_api::abstract_functor { counts.resize(graph_view.local_vertex_partition_range_size(), handle_.get_stream()); } - cugraph::triangle_count( + cugraph::triangle_count( handle_, graph_view, vertices_ == nullptr diff --git a/cpp/src/c_api/uniform_neighbor_sampling.cpp b/cpp/src/c_api/uniform_neighbor_sampling.cpp index 6ebf81a8381..39626cdd898 100644 --- a/cpp/src/c_api/uniform_neighbor_sampling.cpp +++ b/cpp/src/c_api/uniform_neighbor_sampling.cpp @@ -98,11 +98,14 @@ struct uniform_neighbor_sampling_functor : public cugraph::c_api::abstract_funct } auto graph = - reinterpret_cast*>( - graph_->graph_); + reinterpret_cast*>(graph_->graph_); auto graph_view = graph->view(); + auto edge_weights = reinterpret_cast< + cugraph::edge_property_t, + weight_t>*>(graph_->edge_weights_); + auto number_map = reinterpret_cast*>(graph_->number_map_); rmm::device_uvector start(start_->size_, handle_.get_stream()); @@ -123,6 +126,7 @@ struct uniform_neighbor_sampling_functor : public cugraph::c_api::abstract_funct auto&& [srcs, dsts, weights, counts] = cugraph::uniform_nbr_sample( handle_, graph_view, + (edge_weights != nullptr) ? std::make_optional(edge_weights->view()) : std::nullopt, raft::device_span(start.data(), start.size()), raft::host_span(fan_out_->as_type(), fan_out_->size_), with_replacement_); diff --git a/cpp/src/c_api/weakly_connected_components.cpp b/cpp/src/c_api/weakly_connected_components.cpp index b5f41e53626..49cbed268ad 100644 --- a/cpp/src/c_api/weakly_connected_components.cpp +++ b/cpp/src/c_api/weakly_connected_components.cpp @@ -67,8 +67,7 @@ struct wcc_functor : public cugraph::c_api::abstract_functor { } auto graph = - reinterpret_cast*>( - graph_->graph_); + reinterpret_cast*>(graph_->graph_); auto graph_view = graph->view(); @@ -77,7 +76,7 @@ struct wcc_functor : public cugraph::c_api::abstract_functor { rmm::device_uvector components(graph_view.local_vertex_partition_range_size(), handle_.get_stream()); - cugraph::weakly_connected_components( + cugraph::weakly_connected_components( handle_, graph_view, components.data(), do_expensive_check_); rmm::device_uvector vertex_ids(graph_view.local_vertex_partition_range_size(), diff --git a/cpp/src/centrality/betweenness_centrality_impl.cuh b/cpp/src/centrality/betweenness_centrality_impl.cuh index 8d1b0280365..64cdbf9b6f4 100644 --- a/cpp/src/centrality/betweenness_centrality_impl.cuh +++ b/cpp/src/centrality/betweenness_centrality_impl.cuh @@ -26,7 +26,8 @@ namespace detail { template rmm::device_uvector betweenness_centrality( const raft::handle_t& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, std::optional>> vertices, bool const normalized, bool const include_endpoints, @@ -43,7 +44,8 @@ rmm::device_uvector betweenness_centrality( template rmm::device_uvector edge_betweenness_centrality( const raft::handle_t& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, std::optional>> vertices, bool const normalized, bool const do_expensive_check) @@ -60,7 +62,8 @@ rmm::device_uvector edge_betweenness_centrality( template rmm::device_uvector betweenness_centrality( const raft::handle_t& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, std::optional>> vertices, bool const normalized, bool const include_endpoints, @@ -72,7 +75,8 @@ rmm::device_uvector betweenness_centrality( template rmm::device_uvector edge_betweenness_centrality( const raft::handle_t& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, std::optional>> vertices, bool const normalized, bool const do_expensive_check) diff --git a/cpp/src/centrality/betweenness_centrality_mg.cu b/cpp/src/centrality/betweenness_centrality_mg.cu index 2238fd5b3cd..4180d8300c9 100644 --- a/cpp/src/centrality/betweenness_centrality_mg.cu +++ b/cpp/src/centrality/betweenness_centrality_mg.cu @@ -17,10 +17,12 @@ namespace cugraph { -// SG instantiation +// MG instantiation + template rmm::device_uvector betweenness_centrality( raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, std::optional>> vertices, bool const normalized, bool const include_endpoints, @@ -28,7 +30,8 @@ template rmm::device_uvector betweenness_centrality( template rmm::device_uvector betweenness_centrality( raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, std::optional>> vertices, bool const normalized, bool const include_endpoints, @@ -36,7 +39,8 @@ template rmm::device_uvector betweenness_centrality( template rmm::device_uvector betweenness_centrality( raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, std::optional>> vertices, bool const normalized, bool const include_endpoints, @@ -44,7 +48,8 @@ template rmm::device_uvector betweenness_centrality( template rmm::device_uvector betweenness_centrality( raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, std::optional>> vertices, bool const normalized, bool const include_endpoints, @@ -52,7 +57,8 @@ template rmm::device_uvector betweenness_centrality( template rmm::device_uvector betweenness_centrality( raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, std::optional>> vertices, bool const normalized, bool const include_endpoints, @@ -60,7 +66,8 @@ template rmm::device_uvector betweenness_centrality( template rmm::device_uvector betweenness_centrality( raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, std::optional>> vertices, bool const normalized, bool const include_endpoints, @@ -68,42 +75,48 @@ template rmm::device_uvector betweenness_centrality( template rmm::device_uvector edge_betweenness_centrality( const raft::handle_t& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, std::optional>> vertices, bool const normalized, bool const do_expensive_check); template rmm::device_uvector edge_betweenness_centrality( const raft::handle_t& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, std::optional>> vertices, bool const normalized, bool const do_expensive_check); template rmm::device_uvector edge_betweenness_centrality( const raft::handle_t& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, std::optional>> vertices, bool const normalized, bool const do_expensive_check); template rmm::device_uvector edge_betweenness_centrality( const raft::handle_t& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, std::optional>> vertices, bool const normalized, bool const do_expensive_check); template rmm::device_uvector edge_betweenness_centrality( const raft::handle_t& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, std::optional>> vertices, bool const normalized, bool const do_expensive_check); template rmm::device_uvector edge_betweenness_centrality( const raft::handle_t& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, std::optional>> vertices, bool const normalized, bool const do_expensive_check); diff --git a/cpp/src/centrality/betweenness_centrality_sg.cu b/cpp/src/centrality/betweenness_centrality_sg.cu index 78b768d4f50..d7892a1e435 100644 --- a/cpp/src/centrality/betweenness_centrality_sg.cu +++ b/cpp/src/centrality/betweenness_centrality_sg.cu @@ -18,9 +18,11 @@ namespace cugraph { // SG instantiation + template rmm::device_uvector betweenness_centrality( raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, std::optional>> vertices, bool const normalized, bool const include_endpoints, @@ -28,7 +30,8 @@ template rmm::device_uvector betweenness_centrality( template rmm::device_uvector betweenness_centrality( raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, std::optional>> vertices, bool const normalized, bool const include_endpoints, @@ -36,7 +39,8 @@ template rmm::device_uvector betweenness_centrality( template rmm::device_uvector betweenness_centrality( raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, std::optional>> vertices, bool const normalized, bool const include_endpoints, @@ -44,7 +48,8 @@ template rmm::device_uvector betweenness_centrality( template rmm::device_uvector betweenness_centrality( raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, std::optional>> vertices, bool const normalized, bool const include_endpoints, @@ -52,7 +57,8 @@ template rmm::device_uvector betweenness_centrality( template rmm::device_uvector betweenness_centrality( raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, std::optional>> vertices, bool const normalized, bool const include_endpoints, @@ -60,7 +66,8 @@ template rmm::device_uvector betweenness_centrality( template rmm::device_uvector betweenness_centrality( raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, std::optional>> vertices, bool const normalized, bool const include_endpoints, @@ -68,42 +75,48 @@ template rmm::device_uvector betweenness_centrality( template rmm::device_uvector edge_betweenness_centrality( const raft::handle_t& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, std::optional>> vertices, bool const normalized, bool const do_expensive_check); template rmm::device_uvector edge_betweenness_centrality( const raft::handle_t& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, std::optional>> vertices, bool const normalized, bool const do_expensive_check); template rmm::device_uvector edge_betweenness_centrality( const raft::handle_t& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, std::optional>> vertices, bool const normalized, bool const do_expensive_check); template rmm::device_uvector edge_betweenness_centrality( const raft::handle_t& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, std::optional>> vertices, bool const normalized, bool const do_expensive_check); template rmm::device_uvector edge_betweenness_centrality( const raft::handle_t& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, std::optional>> vertices, bool const normalized, bool const do_expensive_check); template rmm::device_uvector edge_betweenness_centrality( const raft::handle_t& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, std::optional>> vertices, bool const normalized, bool const do_expensive_check); diff --git a/cpp/src/centrality/eigenvector_centrality_impl.cuh b/cpp/src/centrality/eigenvector_centrality_impl.cuh index 69676777707..ff5b19f6f0b 100644 --- a/cpp/src/centrality/eigenvector_centrality_impl.cuh +++ b/cpp/src/centrality/eigenvector_centrality_impl.cuh @@ -44,26 +44,28 @@ namespace detail { template rmm::device_uvector eigenvector_centrality( raft::handle_t const& handle, - graph_view_t const& pull_graph_view, + graph_view_t const& pull_graph_view, + std::optional> edge_weight_view, std::optional> initial_centralities, weight_t epsilon, size_t max_iterations, bool do_expensive_check) { - using GraphViewType = graph_view_t; + using GraphViewType = graph_view_t; auto const num_vertices = pull_graph_view.number_of_vertices(); if (num_vertices == 0) { return rmm::device_uvector(0, handle.get_stream()); } if (do_expensive_check) { - if (pull_graph_view.is_weighted()) { + if (edge_weight_view) { auto num_nonpositive_edge_weights = count_if_e(handle, pull_graph_view, edge_src_dummy_property_t{}.view(), edge_dst_dummy_property_t{}.view(), - [] __device__(vertex_t, vertex_t, weight_t w, auto, auto) { return w <= 0.0; }); + *edge_weight_view, + [] __device__(vertex_t, vertex_t, auto, auto, weight_t w) { return w <= 0.0; }); CUGRAPH_EXPECTS(num_nonpositive_edge_weights == 0, - "Invalid input argument: input graph should have postive edge weights."); + "Invalid input argument: input edge weights should have postive values."); } } @@ -95,14 +97,27 @@ rmm::device_uvector eigenvector_centrality( update_edge_src_property(handle, pull_graph_view, centralities.begin(), edge_src_centralities); - per_v_transform_reduce_incoming_e( - handle, - pull_graph_view, - edge_src_centralities.view(), - edge_dst_dummy_property_t{}.view(), - [] __device__(vertex_t, vertex_t, weight_t w, auto src_val, auto) { return src_val * w; }, - weight_t{0}, - centralities.begin()); + if (edge_weight_view) { + per_v_transform_reduce_incoming_e( + handle, + pull_graph_view, + edge_src_centralities.view(), + edge_dst_dummy_property_t{}.view(), + *edge_weight_view, + [] __device__(vertex_t, vertex_t, auto src_val, auto, weight_t w) { return src_val * w; }, + weight_t{0}, + centralities.begin()); + } else { + per_v_transform_reduce_incoming_e( + handle, + pull_graph_view, + edge_src_centralities.view(), + edge_dst_dummy_property_t{}.view(), + edge_dummy_property_t{}.view(), + [] __device__(vertex_t, vertex_t, auto src_val, auto, auto) { return src_val * 1.0; }, + weight_t{0}, + centralities.begin()); + } // Normalize the centralities auto hypotenuse = sqrt(transform_reduce_v( @@ -142,7 +157,8 @@ rmm::device_uvector eigenvector_centrality( template rmm::device_uvector eigenvector_centrality( raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, std::optional> initial_centralities, weight_t epsilon, size_t max_iterations, @@ -159,8 +175,13 @@ rmm::device_uvector eigenvector_centrality( static_cast(graph_view.local_vertex_partition_range_size()), "Centralities should be same size as vertex range"); - return detail::eigenvector_centrality( - handle, graph_view, initial_centralities, epsilon, max_iterations, do_expensive_check); + return detail::eigenvector_centrality(handle, + graph_view, + edge_weight_view, + initial_centralities, + epsilon, + max_iterations, + do_expensive_check); } } // namespace cugraph diff --git a/cpp/src/centrality/eigenvector_centrality_mg.cu b/cpp/src/centrality/eigenvector_centrality_mg.cu index 09b3d1b3058..394a456b351 100644 --- a/cpp/src/centrality/eigenvector_centrality_mg.cu +++ b/cpp/src/centrality/eigenvector_centrality_mg.cu @@ -18,9 +18,11 @@ namespace cugraph { // MG instantiation + template rmm::device_uvector eigenvector_centrality( raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, std::optional> initial_centralities, float epsilon, size_t max_iterations, @@ -28,7 +30,8 @@ template rmm::device_uvector eigenvector_centrality( template rmm::device_uvector eigenvector_centrality( raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, std::optional> initial_centralities, float epsilon, size_t max_iterations, @@ -36,7 +39,8 @@ template rmm::device_uvector eigenvector_centrality( template rmm::device_uvector eigenvector_centrality( raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, std::optional> initial_centralities, float epsilon, size_t max_iterations, @@ -44,7 +48,8 @@ template rmm::device_uvector eigenvector_centrality( template rmm::device_uvector eigenvector_centrality( raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, std::optional> initial_centralities, double epsilon, size_t max_iterations, @@ -52,7 +57,8 @@ template rmm::device_uvector eigenvector_centrality( template rmm::device_uvector eigenvector_centrality( raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, std::optional> initial_centralities, double epsilon, size_t max_iterations, @@ -60,7 +66,8 @@ template rmm::device_uvector eigenvector_centrality( template rmm::device_uvector eigenvector_centrality( raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, std::optional> initial_centralities, double epsilon, size_t max_iterations, diff --git a/cpp/src/centrality/eigenvector_centrality_sg.cu b/cpp/src/centrality/eigenvector_centrality_sg.cu index 3d025638d6d..754c6b108e4 100644 --- a/cpp/src/centrality/eigenvector_centrality_sg.cu +++ b/cpp/src/centrality/eigenvector_centrality_sg.cu @@ -18,9 +18,11 @@ namespace cugraph { // SG instantiation + template rmm::device_uvector eigenvector_centrality( raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, std::optional> initial_centralities, float epsilon, size_t max_iterations, @@ -28,7 +30,8 @@ template rmm::device_uvector eigenvector_centrality( template rmm::device_uvector eigenvector_centrality( raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, std::optional> initial_centralities, float epsilon, size_t max_iterations, @@ -36,7 +39,8 @@ template rmm::device_uvector eigenvector_centrality( template rmm::device_uvector eigenvector_centrality( raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, std::optional> initial_centralities, float epsilon, size_t max_iterations, @@ -44,7 +48,8 @@ template rmm::device_uvector eigenvector_centrality( template rmm::device_uvector eigenvector_centrality( raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, std::optional> initial_centralities, double epsilon, size_t max_iterations, @@ -52,7 +57,8 @@ template rmm::device_uvector eigenvector_centrality( template rmm::device_uvector eigenvector_centrality( raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, std::optional> initial_centralities, double epsilon, size_t max_iterations, @@ -60,7 +66,8 @@ template rmm::device_uvector eigenvector_centrality( template rmm::device_uvector eigenvector_centrality( raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, std::optional> initial_centralities, double epsilon, size_t max_iterations, diff --git a/cpp/src/centrality/katz_centrality_impl.cuh b/cpp/src/centrality/katz_centrality_impl.cuh index a850d0d7de3..fffa992c0f7 100644 --- a/cpp/src/centrality/katz_centrality_impl.cuh +++ b/cpp/src/centrality/katz_centrality_impl.cuh @@ -38,21 +38,23 @@ namespace cugraph { namespace detail { -template -void katz_centrality(raft::handle_t const& handle, - GraphViewType const& pull_graph_view, - result_t const* betas, - result_t* katz_centralities, - result_t alpha, - result_t beta, // relevant only if betas == nullptr - result_t epsilon, - size_t max_iterations, - bool has_initial_guess, - bool normalize, - bool do_expensive_check) +template +void katz_centrality( + raft::handle_t const& handle, + GraphViewType const& pull_graph_view, + std::optional> + edge_weight_view, + result_t const* betas, + result_t* katz_centralities, + result_t alpha, + result_t beta, // relevant only if betas == nullptr + result_t epsilon, + size_t max_iterations, + bool has_initial_guess, + bool normalize, + bool do_expensive_check) { using vertex_t = typename GraphViewType::vertex_type; - using weight_t = typename GraphViewType::weight_type; static_assert(std::is_integral::value, "GraphViewType::vertex_type should be integral."); @@ -107,16 +109,31 @@ void katz_centrality(raft::handle_t const& handle, update_edge_src_property( handle, pull_graph_view, old_katz_centralities, edge_src_katz_centralities); - per_v_transform_reduce_incoming_e( - handle, - pull_graph_view, - edge_src_katz_centralities.view(), - edge_dst_dummy_property_t{}.view(), - [alpha] __device__(vertex_t, vertex_t, weight_t w, auto src_val, auto) { - return static_cast(alpha * src_val * w); - }, - betas != nullptr ? result_t{0.0} : beta, - new_katz_centralities); + if (edge_weight_view) { + per_v_transform_reduce_incoming_e( + handle, + pull_graph_view, + edge_src_katz_centralities.view(), + edge_dst_dummy_property_t{}.view(), + *edge_weight_view, + [alpha] __device__(vertex_t, vertex_t, auto src_val, auto, weight_t w) { + return static_cast(alpha * src_val * w); + }, + betas != nullptr ? result_t{0.0} : beta, + new_katz_centralities); + } else { + per_v_transform_reduce_incoming_e( + handle, + pull_graph_view, + edge_src_katz_centralities.view(), + edge_dst_dummy_property_t{}.view(), + edge_dummy_property_t{}.view(), + [alpha] __device__(vertex_t, vertex_t, auto src_val, auto, auto) { + return static_cast(alpha * src_val * 1.0); + }, + betas != nullptr ? result_t{0.0} : beta, + new_katz_centralities); + } if (betas != nullptr) { auto val_first = thrust::make_zip_iterator(thrust::make_tuple(new_katz_centralities, betas)); @@ -176,7 +193,8 @@ void katz_centrality(raft::handle_t const& handle, template void katz_centrality(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, result_t const* betas, result_t* katz_centralities, result_t alpha, @@ -189,6 +207,7 @@ void katz_centrality(raft::handle_t const& handle, { detail::katz_centrality(handle, graph_view, + edge_weight_view, betas, katz_centralities, alpha, diff --git a/cpp/src/centrality/katz_centrality_mg.cu b/cpp/src/centrality/katz_centrality_mg.cu index badd9995fa1..b7b3b0a2f6e 100644 --- a/cpp/src/centrality/katz_centrality_mg.cu +++ b/cpp/src/centrality/katz_centrality_mg.cu @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, NVIDIA CORPORATION. + * Copyright (c) 2021-2022, NVIDIA CORPORATION. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,76 +19,88 @@ namespace cugraph { // MG instantiation -template void katz_centrality(raft::handle_t const& handle, - graph_view_t const& graph_view, - float const* betas, - float* katz_centralities, - float alpha, - float beta, - float epsilon, - size_t max_iterations, - bool has_initial_guess, - bool normalize, - bool do_expensive_check); +template void katz_centrality( + raft::handle_t const& handle, + graph_view_t const& graph_view, + std::optional> edge_weight_view, + float const* betas, + float* katz_centralities, + float alpha, + float beta, + float epsilon, + size_t max_iterations, + bool has_initial_guess, + bool normalize, + bool do_expensive_check); -template void katz_centrality(raft::handle_t const& handle, - graph_view_t const& graph_view, - double const* betas, - double* katz_centralities, - double alpha, - double beta, - double epsilon, - size_t max_iterations, - bool has_initial_guess, - bool normalize, - bool do_expensive_check); +template void katz_centrality( + raft::handle_t const& handle, + graph_view_t const& graph_view, + std::optional> edge_weight_view, + double const* betas, + double* katz_centralities, + double alpha, + double beta, + double epsilon, + size_t max_iterations, + bool has_initial_guess, + bool normalize, + bool do_expensive_check); -template void katz_centrality(raft::handle_t const& handle, - graph_view_t const& graph_view, - float const* betas, - float* katz_centralities, - float alpha, - float beta, - float epsilon, - size_t max_iterations, - bool has_initial_guess, - bool normalize, - bool do_expensive_check); +template void katz_centrality( + raft::handle_t const& handle, + graph_view_t const& graph_view, + std::optional> edge_weight_view, + float const* betas, + float* katz_centralities, + float alpha, + float beta, + float epsilon, + size_t max_iterations, + bool has_initial_guess, + bool normalize, + bool do_expensive_check); -template void katz_centrality(raft::handle_t const& handle, - graph_view_t const& graph_view, - double const* betas, - double* katz_centralities, - double alpha, - double beta, - double epsilon, - size_t max_iterations, - bool has_initial_guess, - bool normalize, - bool do_expensive_check); +template void katz_centrality( + raft::handle_t const& handle, + graph_view_t const& graph_view, + std::optional> edge_weight_view, + double const* betas, + double* katz_centralities, + double alpha, + double beta, + double epsilon, + size_t max_iterations, + bool has_initial_guess, + bool normalize, + bool do_expensive_check); -template void katz_centrality(raft::handle_t const& handle, - graph_view_t const& graph_view, - float const* betas, - float* katz_centralities, - float alpha, - float beta, - float epsilon, - size_t max_iterations, - bool has_initial_guess, - bool normalize, - bool do_expensive_check); +template void katz_centrality( + raft::handle_t const& handle, + graph_view_t const& graph_view, + std::optional> edge_weight_view, + float const* betas, + float* katz_centralities, + float alpha, + float beta, + float epsilon, + size_t max_iterations, + bool has_initial_guess, + bool normalize, + bool do_expensive_check); -template void katz_centrality(raft::handle_t const& handle, - graph_view_t const& graph_view, - double const* betas, - double* katz_centralities, - double alpha, - double beta, - double epsilon, - size_t max_iterations, - bool has_initial_guess, - bool normalize, - bool do_expensive_check); +template void katz_centrality( + raft::handle_t const& handle, + graph_view_t const& graph_view, + std::optional> edge_weight_view, + double const* betas, + double* katz_centralities, + double alpha, + double beta, + double epsilon, + size_t max_iterations, + bool has_initial_guess, + bool normalize, + bool do_expensive_check); } // namespace cugraph diff --git a/cpp/src/centrality/katz_centrality_sg.cu b/cpp/src/centrality/katz_centrality_sg.cu index 5f3d2104046..22b7a79b1d8 100644 --- a/cpp/src/centrality/katz_centrality_sg.cu +++ b/cpp/src/centrality/katz_centrality_sg.cu @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, NVIDIA CORPORATION. + * Copyright (c) 2021-2022, NVIDIA CORPORATION. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,76 +19,88 @@ namespace cugraph { // SG instantiation -template void katz_centrality(raft::handle_t const& handle, - graph_view_t const& graph_view, - float const* betas, - float* katz_centralities, - float alpha, - float beta, - float epsilon, - size_t max_iterations, - bool has_initial_guess, - bool normalize, - bool do_expensive_check); +template void katz_centrality( + raft::handle_t const& handle, + graph_view_t const& graph_view, + std::optional> edge_weight_view, + float const* betas, + float* katz_centralities, + float alpha, + float beta, + float epsilon, + size_t max_iterations, + bool has_initial_guess, + bool normalize, + bool do_expensive_check); -template void katz_centrality(raft::handle_t const& handle, - graph_view_t const& graph_view, - double const* betas, - double* katz_centralities, - double alpha, - double beta, - double epsilon, - size_t max_iterations, - bool has_initial_guess, - bool normalize, - bool do_expensive_check); +template void katz_centrality( + raft::handle_t const& handle, + graph_view_t const& graph_view, + std::optional> edge_weight_view, + double const* betas, + double* katz_centralities, + double alpha, + double beta, + double epsilon, + size_t max_iterations, + bool has_initial_guess, + bool normalize, + bool do_expensive_check); -template void katz_centrality(raft::handle_t const& handle, - graph_view_t const& graph_view, - float const* betas, - float* katz_centralities, - float alpha, - float beta, - float epsilon, - size_t max_iterations, - bool has_initial_guess, - bool normalize, - bool do_expensive_check); +template void katz_centrality( + raft::handle_t const& handle, + graph_view_t const& graph_view, + std::optional> edge_weight_view, + float const* betas, + float* katz_centralities, + float alpha, + float beta, + float epsilon, + size_t max_iterations, + bool has_initial_guess, + bool normalize, + bool do_expensive_check); -template void katz_centrality(raft::handle_t const& handle, - graph_view_t const& graph_view, - double const* betas, - double* katz_centralities, - double alpha, - double beta, - double epsilon, - size_t max_iterations, - bool has_initial_guess, - bool normalize, - bool do_expensive_check); +template void katz_centrality( + raft::handle_t const& handle, + graph_view_t const& graph_view, + std::optional> edge_weight_view, + double const* betas, + double* katz_centralities, + double alpha, + double beta, + double epsilon, + size_t max_iterations, + bool has_initial_guess, + bool normalize, + bool do_expensive_check); -template void katz_centrality(raft::handle_t const& handle, - graph_view_t const& graph_view, - float const* betas, - float* katz_centralities, - float alpha, - float beta, - float epsilon, - size_t max_iterations, - bool has_initial_guess, - bool normalize, - bool do_expensive_check); +template void katz_centrality( + raft::handle_t const& handle, + graph_view_t const& graph_view, + std::optional> edge_weight_view, + float const* betas, + float* katz_centralities, + float alpha, + float beta, + float epsilon, + size_t max_iterations, + bool has_initial_guess, + bool normalize, + bool do_expensive_check); -template void katz_centrality(raft::handle_t const& handle, - graph_view_t const& graph_view, - double const* betas, - double* katz_centralities, - double alpha, - double beta, - double epsilon, - size_t max_iterations, - bool has_initial_guess, - bool normalize, - bool do_expensive_check); +template void katz_centrality( + raft::handle_t const& handle, + graph_view_t const& graph_view, + std::optional> edge_weight_view, + double const* betas, + double* katz_centralities, + double alpha, + double beta, + double epsilon, + size_t max_iterations, + bool has_initial_guess, + bool normalize, + bool do_expensive_check); } // namespace cugraph diff --git a/cpp/src/community/detail/common_methods.cuh b/cpp/src/community/detail/common_methods.cuh index 21baadac643..7b123027e99 100644 --- a/cpp/src/community/detail/common_methods.cuh +++ b/cpp/src/community/detail/common_methods.cuh @@ -54,9 +54,9 @@ struct key_aggregated_edge_op_t { __device__ auto operator()( vertex_t src, vertex_t neighbor_cluster, - weight_t new_cluster_sum, thrust::tuple src_info, - weight_t a_new) const + weight_t a_new, + weight_t new_cluster_sum) const { auto k_k = thrust::get<0>(src_info); auto src_cluster = thrust::get<1>(src_info); @@ -113,25 +113,37 @@ struct cluster_update_op_t { template struct return_edge_weight_t { __device__ auto operator()( - vertex_t, vertex_t, weight_t w, thrust::nullopt_t, thrust::nullopt_t) const + vertex_t, vertex_t, thrust::nullopt_t, thrust::nullopt_t, weight_t w) const { return w; } }; -template -typename graph_view_t::weight_type compute_modularity( +// a workaround for cudaErrorInvalidDeviceFunction error when device lambda is used +template +struct return_one_t { + __device__ auto operator()( + vertex_t, vertex_t, thrust::nullopt_t, thrust::nullopt_t, thrust::nullopt_t) const + { + return 1.0; + } +}; + +template +weight_t compute_modularity( raft::handle_t const& handle, - graph_view_t const& graph_view, - edge_src_property_t const& src_clusters_cache, - edge_dst_property_t const& dst_clusters_cache, - rmm::device_uvector const& next_clusters, - rmm::device_uvector const& cluster_weights, - typename graph_view_t::weight_type total_edge_weight, - typename graph_view_t::weight_type resolution) + graph_view_t const& graph_view, + std::optional> edge_weight_view, + edge_src_property_t, vertex_t> const& + src_clusters_cache, + edge_dst_property_t, vertex_t> const& + dst_clusters_cache, + rmm::device_uvector const& next_clusters, + rmm::device_uvector const& cluster_weights, + weight_t total_edge_weight, + weight_t resolution) { - using vertex_t = typename graph_view_t::vertex_type; - using weight_t = typename graph_view_t::weight_type; + CUGRAPH_EXPECTS(edge_weight_view.has_value(), "Graph must be weighted."); weight_t sum_degree_squared = thrust::transform_reduce( handle.get_thrust_policy(), @@ -141,7 +153,7 @@ typename graph_view_t::weight_type compute_modularity( weight_t{0}, thrust::plus()); - if constexpr (graph_view_t::is_multi_gpu) { + if constexpr (multi_gpu) { sum_degree_squared = host_scalar_allreduce( handle.get_comms(), sum_degree_squared, raft::comms::op_t::SUM, handle.get_stream()); } @@ -149,13 +161,14 @@ typename graph_view_t::weight_type compute_modularity( weight_t sum_internal = transform_reduce_e( handle, graph_view, - graph_view_t::is_multi_gpu + multi_gpu ? src_clusters_cache.view() : detail::edge_major_property_view_t(next_clusters.begin()), - graph_view_t::is_multi_gpu ? dst_clusters_cache.view() - : detail::edge_minor_property_view_t( - next_clusters.begin(), vertex_t{0}), - [] __device__(auto, auto, weight_t wt, auto src_cluster, auto nbr_cluster) { + multi_gpu ? dst_clusters_cache.view() + : detail::edge_minor_property_view_t(next_clusters.begin(), + vertex_t{0}), + *edge_weight_view, + [] __device__(auto, auto, auto src_cluster, auto nbr_cluster, weight_t wt) { if (src_cluster == nbr_cluster) { return wt; } else { @@ -171,12 +184,16 @@ typename graph_view_t::weight_type compute_modularity( } template -cugraph::graph_t graph_contraction( - raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, - raft::device_span labels) +std::tuple< + cugraph::graph_t, + std::optional, weight_t>>> +graph_contraction(raft::handle_t const& handle, + cugraph::graph_view_t const& graph_view, + std::optional> edge_weights, + raft::device_span labels) { - auto [new_graph, numbering_map] = coarsen_graph(handle, graph_view, labels.data(), true); + auto [new_graph, new_edge_weights, numbering_map] = + coarsen_graph(handle, graph_view, edge_weights, labels.data(), true); auto new_graph_view = new_graph.view(); @@ -195,32 +212,35 @@ cugraph::graph_t graph_contraction labels.size(), false); - return std::move(new_graph); + return std::make_tuple(std::move(new_graph), std::move(new_edge_weights)); } -template -rmm::device_uvector update_clustering_by_delta_modularity( +template +rmm::device_uvector update_clustering_by_delta_modularity( raft::handle_t const& handle, - graph_view_t const& graph_view, - typename graph_view_t::weight_type total_edge_weight, - typename graph_view_t::weight_type resolution, - rmm::device_uvector const& vertex_weights_v, - rmm::device_uvector&& cluster_keys_v, - rmm::device_uvector&& cluster_weights_v, - rmm::device_uvector&& next_clusters_v, - edge_src_property_t const& + graph_view_t const& graph_view, + std::optional> edge_weight_view, + weight_t total_edge_weight, + weight_t resolution, + rmm::device_uvector const& vertex_weights_v, + rmm::device_uvector&& cluster_keys_v, + rmm::device_uvector&& cluster_weights_v, + rmm::device_uvector&& next_clusters_v, + edge_src_property_t, weight_t> const& src_vertex_weights_cache, - edge_src_property_t const& src_clusters_cache, - edge_dst_property_t const& dst_clusters_cache, + edge_src_property_t, vertex_t> const& + src_clusters_cache, + edge_dst_property_t, vertex_t> const& + dst_clusters_cache, bool up_down) { - using vertex_t = typename graph_view_t::vertex_type; - using weight_t = typename graph_view_t::weight_type; + CUGRAPH_EXPECTS(edge_weight_view.has_value(), "Graph must be weighted."); rmm::device_uvector vertex_cluster_weights_v(0, handle.get_stream()); - edge_src_property_t src_cluster_weights(handle); + edge_src_property_t, weight_t> + src_cluster_weights(handle); - if constexpr (graph_view_t::is_multi_gpu) { + if constexpr (multi_gpu) { cugraph::detail::compute_gpu_id_from_ext_vertex_t vertex_to_gpu_id_op{ handle.get_comms().get_size()}; @@ -238,7 +258,9 @@ rmm::device_uvector update_clustering_by_del vertex_to_gpu_id_op, handle.get_stream()); - src_cluster_weights = edge_src_property_t(handle, graph_view); + src_cluster_weights = + edge_src_property_t, weight_t>(handle, + graph_view); update_edge_src_property( handle, graph_view, vertex_cluster_weights_v.begin(), src_cluster_weights); vertex_cluster_weights_v.resize(0, handle.get_stream()); @@ -273,13 +295,14 @@ rmm::device_uvector update_clustering_by_del per_v_transform_reduce_outgoing_e( handle, graph_view, - graph_view_t::is_multi_gpu + multi_gpu ? src_clusters_cache.view() : detail::edge_major_property_view_t(next_clusters_v.data()), - graph_view_t::is_multi_gpu ? dst_clusters_cache.view() - : detail::edge_minor_property_view_t( - next_clusters_v.data(), vertex_t{0}), - [] __device__(auto src, auto dst, auto wt, auto src_cluster, auto nbr_cluster) { + multi_gpu ? dst_clusters_cache.view() + : detail::edge_minor_property_view_t( + next_clusters_v.data(), vertex_t{0}), + *edge_weight_view, + [] __device__(auto src, auto dst, auto src_cluster, auto nbr_cluster, weight_t wt) { weight_t sum{0}; weight_t subtract{0}; @@ -294,12 +317,14 @@ rmm::device_uvector update_clustering_by_del thrust::make_zip_iterator( thrust::make_tuple(old_cluster_sum_v.begin(), cluster_subtract_v.begin()))); - edge_src_property_t> + edge_src_property_t, + thrust::tuple> src_old_cluster_sum_subtract_pairs(handle); - if constexpr (graph_view_t::is_multi_gpu) { + if constexpr (multi_gpu) { src_old_cluster_sum_subtract_pairs = - edge_src_property_t>(handle, graph_view); + edge_src_property_t, + thrust::tuple>(handle, graph_view); update_edge_src_property(handle, graph_view, thrust::make_zip_iterator(thrust::make_tuple( @@ -317,7 +342,7 @@ rmm::device_uvector update_clustering_by_del auto cluster_old_sum_subtract_pair_first = thrust::make_zip_iterator( thrust::make_tuple(old_cluster_sum_v.cbegin(), cluster_subtract_v.cbegin())); auto zipped_src_device_view = - graph_view_t::is_multi_gpu + multi_gpu ? view_concat(src_vertex_weights_cache.view(), src_clusters_cache.view(), src_cluster_weights.view(), @@ -342,9 +367,10 @@ rmm::device_uvector update_clustering_by_del handle, graph_view, zipped_src_device_view, - graph_view_t::is_multi_gpu ? dst_clusters_cache.view() - : detail::edge_minor_property_view_t( - next_clusters_v.data(), vertex_t{0}), + *edge_weight_view, + multi_gpu ? dst_clusters_cache.view() + : detail::edge_minor_property_view_t( + next_clusters_v.data(), vertex_t{0}), cluster_key_weight_map.view(), detail::key_aggregated_edge_op_t{total_edge_weight, resolution}, thrust::make_tuple(vertex_t{-1}, weight_t{0}), @@ -361,24 +387,25 @@ rmm::device_uvector update_clustering_by_del return std::move(next_clusters_v); } -template -std::tuple, - rmm::device_uvector> +template +std::tuple, rmm::device_uvector> compute_cluster_keys_and_values( raft::handle_t const& handle, - graph_view_t const& graph_view, - rmm::device_uvector const& next_clusters_v, - edge_src_property_t const& src_clusters_cache) + graph_view_t const& graph_view, + std::optional> edge_weight_view, + rmm::device_uvector const& next_clusters_v, + edge_src_property_t, vertex_t> const& + src_clusters_cache) { - using vertex_t = typename graph_view_t::vertex_type; - using weight_t = typename graph_view_t::weight_type; + CUGRAPH_EXPECTS(edge_weight_view.has_value(), "Graph must be weighted."); auto [cluster_keys, cluster_values] = cugraph::transform_reduce_e_by_src_key( handle, graph_view, edge_src_dummy_property_t{}.view(), edge_dst_dummy_property_t{}.view(), - graph_view_t::is_multi_gpu + *edge_weight_view, + multi_gpu ? src_clusters_cache.view() : detail::edge_major_property_view_t(next_clusters_v.data()), detail::return_edge_weight_t{}, diff --git a/cpp/src/community/detail/common_methods.hpp b/cpp/src/community/detail/common_methods.hpp index bd73410b631..14b3e042ab9 100644 --- a/cpp/src/community/detail/common_methods.hpp +++ b/cpp/src/community/detail/common_methods.hpp @@ -18,8 +18,10 @@ #include #include +#include #include #include +#include #include #include @@ -70,47 +72,57 @@ void timer_display(raft::handle_t const& handle, HighResTimer const& hr_timer, s #endif } -template -typename graph_view_t::weight_type compute_modularity( +template +weight_t compute_modularity( raft::handle_t const& handle, - graph_view_t const& graph_view, - edge_src_property_t const& src_clusters_cache, - edge_dst_property_t const& dst_clusters_cache, - rmm::device_uvector const& next_clusters, - rmm::device_uvector const& cluster_weights, - typename graph_view_t::weight_type total_edge_weight, - typename graph_view_t::weight_type resolution); + graph_view_t const& graph_view, + std::optional> edge_weight_view, + edge_src_property_t, vertex_t> const& + src_clusters_cache, + edge_dst_property_t, vertex_t> const& + dst_clusters_cache, + rmm::device_uvector const& next_clusters, + rmm::device_uvector const& cluster_weights, + weight_t total_edge_weight, + weight_t resolution); template -cugraph::graph_t graph_contraction( - raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, - raft::device_span labels); +std::tuple< + graph_t, + std::optional, weight_t>>> +graph_contraction(raft::handle_t const& handle, + graph_view_t const& graph_view, + std::optional> edge_weights, + raft::device_span labels); -template -rmm::device_uvector update_clustering_by_delta_modularity( +template +rmm::device_uvector update_clustering_by_delta_modularity( raft::handle_t const& handle, - graph_view_t const& graph_view, - typename graph_view_t::weight_type total_edge_weight, - typename graph_view_t::weight_type resolution, - rmm::device_uvector const& vertex_weights_v, - rmm::device_uvector&& cluster_keys_v, - rmm::device_uvector&& cluster_weights_v, - rmm::device_uvector&& next_clusters_v, - edge_src_property_t const& + graph_view_t const& graph_view, + std::optional> edge_weight_view, + weight_t total_edge_weight, + weight_t resolution, + rmm::device_uvector const& vertex_weights_v, + rmm::device_uvector&& cluster_keys_v, + rmm::device_uvector&& cluster_weights_v, + rmm::device_uvector&& next_clusters_v, + edge_src_property_t, weight_t> const& src_vertex_weights_cache, - edge_src_property_t const& src_clusters_cache, - edge_dst_property_t const& dst_clusters_cache, + edge_src_property_t, vertex_t> const& + src_clusters_cache, + edge_dst_property_t, vertex_t> const& + dst_clusters_cache, bool up_down); -template -std::tuple, - rmm::device_uvector> +template +std::tuple, rmm::device_uvector> compute_cluster_keys_and_values( raft::handle_t const& handle, - graph_view_t const& graph_view, - rmm::device_uvector const& next_clusters_v, - edge_src_property_t const& src_clusters_cache); + graph_view_t const& graph_view, + std::optional> edge_weight_view, + rmm::device_uvector const& next_clusters_v, + edge_src_property_t, vertex_t> const& + src_clusters_cache); } // namespace detail } // namespace cugraph diff --git a/cpp/src/community/detail/common_methods_mg.cu b/cpp/src/community/detail/common_methods_mg.cu index fce83834b2d..3d52658338e 100644 --- a/cpp/src/community/detail/common_methods_mg.cu +++ b/cpp/src/community/detail/common_methods_mg.cu @@ -20,10 +20,11 @@ namespace detail { template float compute_modularity( raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, - edge_src_property_t, int32_t> const& + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view, + edge_src_property_t, int32_t> const& src_clusters_cache, - edge_dst_property_t, int32_t> const& + edge_dst_property_t, int32_t> const& dst_clusters_cache, rmm::device_uvector const& next_clusters, rmm::device_uvector const& cluster_weights, @@ -32,10 +33,11 @@ template float compute_modularity( template float compute_modularity( raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, - edge_src_property_t, int32_t> const& + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view, + edge_src_property_t, int32_t> const& src_clusters_cache, - edge_dst_property_t, int32_t> const& + edge_dst_property_t, int32_t> const& dst_clusters_cache, rmm::device_uvector const& next_clusters, rmm::device_uvector const& cluster_weights, @@ -44,10 +46,11 @@ template float compute_modularity( template float compute_modularity( raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, - edge_src_property_t, int64_t> const& + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view, + edge_src_property_t, int64_t> const& src_clusters_cache, - edge_dst_property_t, int64_t> const& + edge_dst_property_t, int64_t> const& dst_clusters_cache, rmm::device_uvector const& next_clusters, rmm::device_uvector const& cluster_weights, @@ -56,10 +59,11 @@ template float compute_modularity( template double compute_modularity( raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, - edge_src_property_t, int32_t> const& + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view, + edge_src_property_t, int32_t> const& src_clusters_cache, - edge_dst_property_t, int32_t> const& + edge_dst_property_t, int32_t> const& dst_clusters_cache, rmm::device_uvector const& next_clusters, rmm::device_uvector const& cluster_weights, @@ -68,10 +72,11 @@ template double compute_modularity( template double compute_modularity( raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, - edge_src_property_t, int32_t> const& + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view, + edge_src_property_t, int32_t> const& src_clusters_cache, - edge_dst_property_t, int32_t> const& + edge_dst_property_t, int32_t> const& dst_clusters_cache, rmm::device_uvector const& next_clusters, rmm::device_uvector const& cluster_weights, @@ -80,194 +85,225 @@ template double compute_modularity( template double compute_modularity( raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, - edge_src_property_t, int64_t> const& + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view, + edge_src_property_t, int64_t> const& src_clusters_cache, - edge_dst_property_t, int64_t> const& + edge_dst_property_t, int64_t> const& dst_clusters_cache, rmm::device_uvector const& next_clusters, rmm::device_uvector const& cluster_weights, double total_edge_weight, double resolution); -template cugraph::graph_t graph_contraction( - raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, - raft::device_span labels); +template std::tuple< + cugraph::graph_t, + std::optional, float>>> +graph_contraction(raft::handle_t const& handle, + cugraph::graph_view_t const& graph_view, + std::optional> edge_weights, + raft::device_span labels); -template cugraph::graph_t graph_contraction( - raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, - raft::device_span labels); +template std::tuple< + cugraph::graph_t, + std::optional, float>>> +graph_contraction(raft::handle_t const& handle, + cugraph::graph_view_t const& graph_view, + std::optional> edge_weights, + raft::device_span labels); -template cugraph::graph_t graph_contraction( - raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, - raft::device_span labels); +template std::tuple< + cugraph::graph_t, + std::optional, float>>> +graph_contraction(raft::handle_t const& handle, + cugraph::graph_view_t const& graph_view, + std::optional> edge_weights, + raft::device_span labels); -template cugraph::graph_t graph_contraction( - raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, - raft::device_span labels); +template std::tuple< + cugraph::graph_t, + std::optional, double>>> +graph_contraction(raft::handle_t const& handle, + cugraph::graph_view_t const& graph_view, + std::optional> edge_weights, + raft::device_span labels); -template cugraph::graph_t graph_contraction( - raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, - raft::device_span labels); +template std::tuple< + cugraph::graph_t, + std::optional, double>>> +graph_contraction(raft::handle_t const& handle, + cugraph::graph_view_t const& graph_view, + std::optional> edge_weights, + raft::device_span labels); -template cugraph::graph_t graph_contraction( - raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, - raft::device_span labels); +template std::tuple< + cugraph::graph_t, + std::optional, double>>> +graph_contraction(raft::handle_t const& handle, + cugraph::graph_view_t const& graph_view, + std::optional> edge_weights, + raft::device_span labels); template rmm::device_uvector update_clustering_by_delta_modularity( raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view, float total_edge_weight, float resolution, rmm::device_uvector const& vertex_weights_v, rmm::device_uvector&& cluster_keys_v, rmm::device_uvector&& cluster_weights_v, rmm::device_uvector&& next_clusters_v, - edge_src_property_t, float> const& + edge_src_property_t, float> const& src_vertex_weights_cache, - edge_src_property_t, int32_t> const& + edge_src_property_t, int32_t> const& src_clusters_cache, - edge_dst_property_t, int32_t> const& + edge_dst_property_t, int32_t> const& dst_clusters_cache, bool up_down); template rmm::device_uvector update_clustering_by_delta_modularity( raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view, float total_edge_weight, float resolution, rmm::device_uvector const& vertex_weights_v, rmm::device_uvector&& cluster_keys_v, rmm::device_uvector&& cluster_weights_v, rmm::device_uvector&& next_clusters_v, - edge_src_property_t, float> const& + edge_src_property_t, float> const& src_vertex_weights_cache, - edge_src_property_t, int32_t> const& + edge_src_property_t, int32_t> const& src_clusters_cache, - edge_dst_property_t, int32_t> const& + edge_dst_property_t, int32_t> const& dst_clusters_cache, bool up_down); template rmm::device_uvector update_clustering_by_delta_modularity( raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view, float total_edge_weight, float resolution, rmm::device_uvector const& vertex_weights_v, rmm::device_uvector&& cluster_keys_v, rmm::device_uvector&& cluster_weights_v, rmm::device_uvector&& next_clusters_v, - edge_src_property_t, float> const& + edge_src_property_t, float> const& src_vertex_weights_cache, - edge_src_property_t, int64_t> const& + edge_src_property_t, int64_t> const& src_clusters_cache, - edge_dst_property_t, int64_t> const& + edge_dst_property_t, int64_t> const& dst_clusters_cache, bool up_down); template rmm::device_uvector update_clustering_by_delta_modularity( raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view, double total_edge_weight, double resolution, rmm::device_uvector const& vertex_weights_v, rmm::device_uvector&& cluster_keys_v, rmm::device_uvector&& cluster_weights_v, rmm::device_uvector&& next_clusters_v, - edge_src_property_t, double> const& + edge_src_property_t, double> const& src_vertex_weights_cache, - edge_src_property_t, int32_t> const& + edge_src_property_t, int32_t> const& src_clusters_cache, - edge_dst_property_t, int32_t> const& + edge_dst_property_t, int32_t> const& dst_clusters_cache, bool up_down); template rmm::device_uvector update_clustering_by_delta_modularity( raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view, double total_edge_weight, double resolution, rmm::device_uvector const& vertex_weights_v, rmm::device_uvector&& cluster_keys_v, rmm::device_uvector&& cluster_weights_v, rmm::device_uvector&& next_clusters_v, - edge_src_property_t, double> const& + edge_src_property_t, double> const& src_vertex_weights_cache, - edge_src_property_t, int32_t> const& + edge_src_property_t, int32_t> const& src_clusters_cache, - edge_dst_property_t, int32_t> const& + edge_dst_property_t, int32_t> const& dst_clusters_cache, bool up_down); template rmm::device_uvector update_clustering_by_delta_modularity( raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view, double total_edge_weight, double resolution, rmm::device_uvector const& vertex_weights_v, rmm::device_uvector&& cluster_keys_v, rmm::device_uvector&& cluster_weights_v, rmm::device_uvector&& next_clusters_v, - edge_src_property_t, double> const& + edge_src_property_t, double> const& src_vertex_weights_cache, - edge_src_property_t, int64_t> const& + edge_src_property_t, int64_t> const& src_clusters_cache, - edge_dst_property_t, int64_t> const& + edge_dst_property_t, int64_t> const& dst_clusters_cache, bool up_down); template std::tuple, rmm::device_uvector> compute_cluster_keys_and_values( raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view, rmm::device_uvector const& next_clusters_v, - edge_src_property_t, int32_t> const& + edge_src_property_t, int32_t> const& src_clusters_cache); template std::tuple, rmm::device_uvector> compute_cluster_keys_and_values( raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view, rmm::device_uvector const& next_clusters_v, - edge_src_property_t, int32_t> const& + edge_src_property_t, int32_t> const& src_clusters_cache); template std::tuple, rmm::device_uvector> compute_cluster_keys_and_values( raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view, rmm::device_uvector const& next_clusters_v, - edge_src_property_t, int64_t> const& + edge_src_property_t, int64_t> const& src_clusters_cache); template std::tuple, rmm::device_uvector> compute_cluster_keys_and_values( raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view, rmm::device_uvector const& next_clusters_v, - edge_src_property_t, int32_t> const& + edge_src_property_t, int32_t> const& src_clusters_cache); template std::tuple, rmm::device_uvector> compute_cluster_keys_and_values( raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view, rmm::device_uvector const& next_clusters_v, - edge_src_property_t, int32_t> const& + edge_src_property_t, int32_t> const& src_clusters_cache); template std::tuple, rmm::device_uvector> compute_cluster_keys_and_values( raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view, rmm::device_uvector const& next_clusters_v, - edge_src_property_t, int64_t> const& + edge_src_property_t, int64_t> const& src_clusters_cache); } // namespace detail diff --git a/cpp/src/community/detail/common_methods_sg.cu b/cpp/src/community/detail/common_methods_sg.cu index 576f740092c..fdbd0468b75 100644 --- a/cpp/src/community/detail/common_methods_sg.cu +++ b/cpp/src/community/detail/common_methods_sg.cu @@ -20,10 +20,11 @@ namespace detail { template float compute_modularity( raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, - edge_src_property_t, int32_t> const& + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view, + edge_src_property_t, int32_t> const& src_clusters_cache, - edge_dst_property_t, int32_t> const& + edge_dst_property_t, int32_t> const& dst_clusters_cache, rmm::device_uvector const& next_clusters, rmm::device_uvector const& cluster_weights, @@ -32,10 +33,11 @@ template float compute_modularity( template float compute_modularity( raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, - edge_src_property_t, int32_t> const& + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view, + edge_src_property_t, int32_t> const& src_clusters_cache, - edge_dst_property_t, int32_t> const& + edge_dst_property_t, int32_t> const& dst_clusters_cache, rmm::device_uvector const& next_clusters, rmm::device_uvector const& cluster_weights, @@ -44,10 +46,11 @@ template float compute_modularity( template float compute_modularity( raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, - edge_src_property_t, int64_t> const& + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view, + edge_src_property_t, int64_t> const& src_clusters_cache, - edge_dst_property_t, int64_t> const& + edge_dst_property_t, int64_t> const& dst_clusters_cache, rmm::device_uvector const& next_clusters, rmm::device_uvector const& cluster_weights, @@ -56,10 +59,11 @@ template float compute_modularity( template double compute_modularity( raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, - edge_src_property_t, int32_t> const& + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view, + edge_src_property_t, int32_t> const& src_clusters_cache, - edge_dst_property_t, int32_t> const& + edge_dst_property_t, int32_t> const& dst_clusters_cache, rmm::device_uvector const& next_clusters, rmm::device_uvector const& cluster_weights, @@ -68,10 +72,11 @@ template double compute_modularity( template double compute_modularity( raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, - edge_src_property_t, int32_t> const& + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view, + edge_src_property_t, int32_t> const& src_clusters_cache, - edge_dst_property_t, int32_t> const& + edge_dst_property_t, int32_t> const& dst_clusters_cache, rmm::device_uvector const& next_clusters, rmm::device_uvector const& cluster_weights, @@ -80,194 +85,225 @@ template double compute_modularity( template double compute_modularity( raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, - edge_src_property_t, int64_t> const& + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view, + edge_src_property_t, int64_t> const& src_clusters_cache, - edge_dst_property_t, int64_t> const& + edge_dst_property_t, int64_t> const& dst_clusters_cache, rmm::device_uvector const& next_clusters, rmm::device_uvector const& cluster_weights, double total_edge_weight, double resolution); -template cugraph::graph_t graph_contraction( - raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, - raft::device_span labels); +template std::tuple< + cugraph::graph_t, + std::optional, float>>> +graph_contraction(raft::handle_t const& handle, + cugraph::graph_view_t const& graph_view, + std::optional> edge_weights, + raft::device_span labels); -template cugraph::graph_t graph_contraction( - raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, - raft::device_span labels); +template std::tuple< + cugraph::graph_t, + std::optional, float>>> +graph_contraction(raft::handle_t const& handle, + cugraph::graph_view_t const& graph_view, + std::optional> edge_weights, + raft::device_span labels); -template cugraph::graph_t graph_contraction( - raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, - raft::device_span labels); +template std::tuple< + cugraph::graph_t, + std::optional, float>>> +graph_contraction(raft::handle_t const& handle, + cugraph::graph_view_t const& graph_view, + std::optional> edge_weights, + raft::device_span labels); -template cugraph::graph_t graph_contraction( - raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, - raft::device_span labels); +template std::tuple< + cugraph::graph_t, + std::optional, double>>> +graph_contraction(raft::handle_t const& handle, + cugraph::graph_view_t const& graph_view, + std::optional> edge_weights, + raft::device_span labels); -template cugraph::graph_t graph_contraction( - raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, - raft::device_span labels); +template std::tuple< + cugraph::graph_t, + std::optional, double>>> +graph_contraction(raft::handle_t const& handle, + cugraph::graph_view_t const& graph_view, + std::optional> edge_weights, + raft::device_span labels); -template cugraph::graph_t graph_contraction( - raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, - raft::device_span labels); +template std::tuple< + cugraph::graph_t, + std::optional, double>>> +graph_contraction(raft::handle_t const& handle, + cugraph::graph_view_t const& graph_view, + std::optional> edge_weights, + raft::device_span labels); template rmm::device_uvector update_clustering_by_delta_modularity( raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view, float total_edge_weight, float resolution, rmm::device_uvector const& vertex_weights_v, rmm::device_uvector&& cluster_keys_v, rmm::device_uvector&& cluster_weights_v, rmm::device_uvector&& next_clusters_v, - edge_src_property_t, float> const& + edge_src_property_t, float> const& src_vertex_weights_cache, - edge_src_property_t, int32_t> const& + edge_src_property_t, int32_t> const& src_clusters_cache, - edge_dst_property_t, int32_t> const& + edge_dst_property_t, int32_t> const& dst_clusters_cache, bool up_down); template rmm::device_uvector update_clustering_by_delta_modularity( raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view, float total_edge_weight, float resolution, rmm::device_uvector const& vertex_weights_v, rmm::device_uvector&& cluster_keys_v, rmm::device_uvector&& cluster_weights_v, rmm::device_uvector&& next_clusters_v, - edge_src_property_t, float> const& + edge_src_property_t, float> const& src_vertex_weights_cache, - edge_src_property_t, int32_t> const& + edge_src_property_t, int32_t> const& src_clusters_cache, - edge_dst_property_t, int32_t> const& + edge_dst_property_t, int32_t> const& dst_clusters_cache, bool up_down); template rmm::device_uvector update_clustering_by_delta_modularity( raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view, float total_edge_weight, float resolution, rmm::device_uvector const& vertex_weights_v, rmm::device_uvector&& cluster_keys_v, rmm::device_uvector&& cluster_weights_v, rmm::device_uvector&& next_clusters_v, - edge_src_property_t, float> const& + edge_src_property_t, float> const& src_vertex_weights_cache, - edge_src_property_t, int64_t> const& + edge_src_property_t, int64_t> const& src_clusters_cache, - edge_dst_property_t, int64_t> const& + edge_dst_property_t, int64_t> const& dst_clusters_cache, bool up_down); template rmm::device_uvector update_clustering_by_delta_modularity( raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view, double total_edge_weight, double resolution, rmm::device_uvector const& vertex_weights_v, rmm::device_uvector&& cluster_keys_v, rmm::device_uvector&& cluster_weights_v, rmm::device_uvector&& next_clusters_v, - edge_src_property_t, double> const& + edge_src_property_t, double> const& src_vertex_weights_cache, - edge_src_property_t, int32_t> const& + edge_src_property_t, int32_t> const& src_clusters_cache, - edge_dst_property_t, int32_t> const& + edge_dst_property_t, int32_t> const& dst_clusters_cache, bool up_down); template rmm::device_uvector update_clustering_by_delta_modularity( raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view, double total_edge_weight, double resolution, rmm::device_uvector const& vertex_weights_v, rmm::device_uvector&& cluster_keys_v, rmm::device_uvector&& cluster_weights_v, rmm::device_uvector&& next_clusters_v, - edge_src_property_t, double> const& + edge_src_property_t, double> const& src_vertex_weights_cache, - edge_src_property_t, int32_t> const& + edge_src_property_t, int32_t> const& src_clusters_cache, - edge_dst_property_t, int32_t> const& + edge_dst_property_t, int32_t> const& dst_clusters_cache, bool up_down); template rmm::device_uvector update_clustering_by_delta_modularity( raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view, double total_edge_weight, double resolution, rmm::device_uvector const& vertex_weights_v, rmm::device_uvector&& cluster_keys_v, rmm::device_uvector&& cluster_weights_v, rmm::device_uvector&& next_clusters_v, - edge_src_property_t, double> const& + edge_src_property_t, double> const& src_vertex_weights_cache, - edge_src_property_t, int64_t> const& + edge_src_property_t, int64_t> const& src_clusters_cache, - edge_dst_property_t, int64_t> const& + edge_dst_property_t, int64_t> const& dst_clusters_cache, bool up_down); template std::tuple, rmm::device_uvector> compute_cluster_keys_and_values( raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view, rmm::device_uvector const& next_clusters_v, - edge_src_property_t, int32_t> const& + edge_src_property_t, int32_t> const& src_clusters_cache); template std::tuple, rmm::device_uvector> compute_cluster_keys_and_values( raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view, rmm::device_uvector const& next_clusters_v, - edge_src_property_t, int32_t> const& + edge_src_property_t, int32_t> const& src_clusters_cache); template std::tuple, rmm::device_uvector> compute_cluster_keys_and_values( raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view, rmm::device_uvector const& next_clusters_v, - edge_src_property_t, int64_t> const& + edge_src_property_t, int64_t> const& src_clusters_cache); template std::tuple, rmm::device_uvector> compute_cluster_keys_and_values( raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view, rmm::device_uvector const& next_clusters_v, - edge_src_property_t, int32_t> const& + edge_src_property_t, int32_t> const& src_clusters_cache); template std::tuple, rmm::device_uvector> compute_cluster_keys_and_values( raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view, rmm::device_uvector const& next_clusters_v, - edge_src_property_t, int32_t> const& + edge_src_property_t, int32_t> const& src_clusters_cache); template std::tuple, rmm::device_uvector> compute_cluster_keys_and_values( raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view, rmm::device_uvector const& next_clusters_v, - edge_src_property_t, int64_t> const& + edge_src_property_t, int64_t> const& src_clusters_cache); } // namespace detail diff --git a/cpp/src/community/egonet_impl.cuh b/cpp/src/community/egonet_impl.cuh index 3c18ea3055f..dd6eeab8b86 100644 --- a/cpp/src/community/egonet_impl.cuh +++ b/cpp/src/community/egonet_impl.cuh @@ -17,6 +17,7 @@ #include +#include #include #include #include @@ -38,7 +39,6 @@ #include #include -#include #include #include #include @@ -65,7 +65,8 @@ std::tuple, std::optional>, rmm::device_uvector> extract(raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view, raft::device_span source_vertex, vertex_t radius, bool do_expensive_check) @@ -132,15 +133,15 @@ extract(raft::handle_t const& handle, source = raft::device_span{source_vertex.data(), size_t{0}}; } - cugraph::bfs(multi_gpu ? handle : light_handle, - graph_view, - reached[i].data(), - nullptr, - source.data(), - source.size(), - direction_optimizing, - radius, - do_expensive_check); + cugraph::bfs(multi_gpu ? handle : light_handle, + graph_view, + reached[i].data(), + nullptr, + source.data(), + source.size(), + direction_optimizing, + radius, + do_expensive_check); // identify reached vertex ids from distance array thrust::transform( @@ -202,6 +203,7 @@ extract(raft::handle_t const& handle, return cugraph::extract_induced_subgraphs( handle, graph_view, + edge_weight_view, raft::device_span(neighbors_offsets.data(), neighbors_offsets.size()), raft::device_span(neighbors.data(), neighbors.size()), do_expensive_check); @@ -217,7 +219,8 @@ std::tuple, std::optional>, rmm::device_uvector> extract_ego(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, vertex_t* source_vertex, vertex_t n_subgraphs, vertex_t radius) @@ -231,6 +234,7 @@ extract_ego(raft::handle_t const& handle, return extract(handle, graph_view, + edge_weight_view, raft::device_span{source_vertex, static_cast(n_subgraphs)}, radius, false); @@ -242,7 +246,8 @@ std::tuple, std::optional>, rmm::device_uvector> extract_ego(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, raft::device_span source_vertex, vertex_t radius, bool do_expensive_check) @@ -250,7 +255,7 @@ extract_ego(raft::handle_t const& handle, CUGRAPH_EXPECTS(radius > 0, "Radius should be at least 1"); CUGRAPH_EXPECTS(radius < graph_view.number_of_vertices(), "radius is too large"); - return extract(handle, graph_view, source_vertex, radius, do_expensive_check); + return extract(handle, graph_view, edge_weight_view, source_vertex, radius, do_expensive_check); } } // namespace cugraph diff --git a/cpp/src/community/egonet_mg.cu b/cpp/src/community/egonet_mg.cu index 4e043e54320..00db537d84a 100644 --- a/cpp/src/community/egonet_mg.cu +++ b/cpp/src/community/egonet_mg.cu @@ -18,12 +18,14 @@ namespace cugraph { // MG FP32 + template std::tuple, rmm::device_uvector, std::optional>, rmm::device_uvector> extract_ego(raft::handle_t const&, - graph_view_t const&, + graph_view_t const&, + std::optional>, int32_t*, int32_t, int32_t); @@ -34,7 +36,8 @@ template std::tuple, rmm::device_uvector> extract_ego(raft::handle_t const&, - graph_view_t const&, + graph_view_t const&, + std::optional>, int32_t*, int32_t, int32_t); @@ -44,18 +47,54 @@ template std::tuple, rmm::device_uvector> extract_ego(raft::handle_t const&, - graph_view_t const&, + graph_view_t const&, + std::optional>, int64_t*, int64_t, int64_t); +template std::tuple, + rmm::device_uvector, + std::optional>, + rmm::device_uvector> +extract_ego(raft::handle_t const& handle, + graph_view_t const& graph_view, + std::optional>, + raft::device_span source_vertex, + int32_t radius, + bool do_expensive_check); + +template std::tuple, + rmm::device_uvector, + std::optional>, + rmm::device_uvector> +extract_ego(raft::handle_t const& handle, + graph_view_t const& graph_view, + std::optional>, + raft::device_span source_vertex, + int32_t radius, + bool do_expensive_check); + +template std::tuple, + rmm::device_uvector, + std::optional>, + rmm::device_uvector> +extract_ego(raft::handle_t const& handle, + graph_view_t const& graph_view, + std::optional>, + raft::device_span source_vertex, + int64_t radius, + bool do_expensive_check); + // MG FP64 + template std::tuple, rmm::device_uvector, std::optional>, rmm::device_uvector> extract_ego(raft::handle_t const&, - graph_view_t const&, + graph_view_t const&, + std::optional>, int32_t*, int32_t, int32_t); @@ -65,7 +104,8 @@ template std::tuple, std::optional>, rmm::device_uvector> extract_ego(raft::handle_t const&, - graph_view_t const&, + graph_view_t const&, + std::optional>, int32_t*, int32_t, int32_t); @@ -75,47 +115,19 @@ template std::tuple, std::optional>, rmm::device_uvector> extract_ego(raft::handle_t const&, - graph_view_t const&, + graph_view_t const&, + std::optional>, int64_t*, int64_t, int64_t); -template std::tuple, - rmm::device_uvector, - std::optional>, - rmm::device_uvector> -extract_ego(raft::handle_t const& handle, - graph_view_t const& graph_view, - raft::device_span source_vertex, - int32_t radius, - bool do_expensive_check); - -template std::tuple, - rmm::device_uvector, - std::optional>, - rmm::device_uvector> -extract_ego(raft::handle_t const& handle, - graph_view_t const& graph_view, - raft::device_span source_vertex, - int32_t radius, - bool do_expensive_check); - -template std::tuple, - rmm::device_uvector, - std::optional>, - rmm::device_uvector> -extract_ego(raft::handle_t const& handle, - graph_view_t const& graph_view, - raft::device_span source_vertex, - int64_t radius, - bool do_expensive_check); - template std::tuple, rmm::device_uvector, std::optional>, rmm::device_uvector> extract_ego(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional>, raft::device_span source_vertex, int32_t radius, bool do_expensive_check); @@ -125,7 +137,8 @@ template std::tuple, std::optional>, rmm::device_uvector> extract_ego(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional>, raft::device_span source_vertex, int32_t radius, bool do_expensive_check); @@ -135,7 +148,8 @@ template std::tuple, std::optional>, rmm::device_uvector> extract_ego(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional>, raft::device_span source_vertex, int64_t radius, bool do_expensive_check); diff --git a/cpp/src/community/egonet_sg.cu b/cpp/src/community/egonet_sg.cu index 02150f8e791..32860d844cd 100644 --- a/cpp/src/community/egonet_sg.cu +++ b/cpp/src/community/egonet_sg.cu @@ -18,12 +18,14 @@ namespace cugraph { // SG FP32 + template std::tuple, rmm::device_uvector, std::optional>, rmm::device_uvector> extract_ego(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional>, int32_t* source_vertex, int32_t n_subgraphs, int32_t radius); @@ -33,7 +35,8 @@ template std::tuple, std::optional>, rmm::device_uvector> extract_ego(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional>, int32_t* source_vertex, int32_t n_subgraphs, int32_t radius); @@ -43,78 +46,87 @@ template std::tuple, std::optional>, rmm::device_uvector> extract_ego(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional>, int64_t* source_vertex, int64_t n_subgraphs, int64_t radius); -// SG FP64 template std::tuple, rmm::device_uvector, - std::optional>, + std::optional>, rmm::device_uvector> -extract_ego(raft::handle_t const&, - graph_view_t const& graph_view, - int32_t* source_vertex, - int32_t n_subgraphs, - int32_t radius); +extract_ego(raft::handle_t const& handle, + graph_view_t const& graph_view, + std::optional>, + raft::device_span source_vertex, + int32_t radius, + bool do_expensive_check); template std::tuple, rmm::device_uvector, - std::optional>, + std::optional>, rmm::device_uvector> extract_ego(raft::handle_t const& handle, - graph_view_t const& graph_view, - int32_t* source_vertex, - int32_t n_subgraphs, - int32_t radius); + graph_view_t const& graph_view, + std::optional>, + raft::device_span source_vertex, + int32_t radius, + bool do_expensive_check); template std::tuple, rmm::device_uvector, - std::optional>, + std::optional>, rmm::device_uvector> extract_ego(raft::handle_t const& handle, - graph_view_t const& graph_view, - int64_t* source_vertex, - int64_t n_subgraphs, - int64_t radius); + graph_view_t const& graph_view, + std::optional>, + raft::device_span source_vertex, + int64_t radius, + bool do_expensive_check); + +// SG FP64 template std::tuple, rmm::device_uvector, - std::optional>, + std::optional>, rmm::device_uvector> -extract_ego(raft::handle_t const& handle, - graph_view_t const& graph_view, - raft::device_span source_vertex, - int32_t radius, - bool do_expensive_check); +extract_ego(raft::handle_t const&, + graph_view_t const& graph_view, + std::optional>, + int32_t* source_vertex, + int32_t n_subgraphs, + int32_t radius); template std::tuple, rmm::device_uvector, - std::optional>, + std::optional>, rmm::device_uvector> extract_ego(raft::handle_t const& handle, - graph_view_t const& graph_view, - raft::device_span source_vertex, - int32_t radius, - bool do_expensive_check); + graph_view_t const& graph_view, + std::optional>, + int32_t* source_vertex, + int32_t n_subgraphs, + int32_t radius); template std::tuple, rmm::device_uvector, - std::optional>, + std::optional>, rmm::device_uvector> extract_ego(raft::handle_t const& handle, - graph_view_t const& graph_view, - raft::device_span source_vertex, - int64_t radius, - bool do_expensive_check); + graph_view_t const& graph_view, + std::optional>, + int64_t* source_vertex, + int64_t n_subgraphs, + int64_t radius); template std::tuple, rmm::device_uvector, std::optional>, rmm::device_uvector> extract_ego(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional>, raft::device_span source_vertex, int32_t radius, bool do_expensive_check); @@ -124,7 +136,8 @@ template std::tuple, std::optional>, rmm::device_uvector> extract_ego(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional>, raft::device_span source_vertex, int32_t radius, bool do_expensive_check); @@ -134,7 +147,8 @@ template std::tuple, std::optional>, rmm::device_uvector> extract_ego(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional>, raft::device_span source_vertex, int64_t radius, bool do_expensive_check); diff --git a/cpp/src/community/legacy/louvain.cu b/cpp/src/community/legacy/louvain.cu index 3bba62021a6..679aa93a5b4 100644 --- a/cpp/src/community/legacy/louvain.cu +++ b/cpp/src/community/legacy/louvain.cu @@ -66,46 +66,23 @@ void flatten_dendrogram(raft::handle_t const& handle, } // namespace detail -template -std::pair>, - typename graph_view_t::weight_type> -louvain(raft::handle_t const& handle, - graph_view_t const& graph_view, - size_t max_level, - typename graph_view_t::weight_type resolution) -{ - return detail::louvain(handle, graph_view, max_level, resolution); -} - -template -void flatten_dendrogram(raft::handle_t const& handle, - graph_view_t const& graph_view, - Dendrogram const& dendrogram, - typename graph_view_t::vertex_type* clustering) -{ - detail::flatten_dendrogram(handle, graph_view, dendrogram, clustering); -} - -template -std::pair louvain( +template +std::pair louvain( raft::handle_t const& handle, - graph_view_t const& graph_view, - typename graph_view_t::vertex_type* clustering, + legacy::GraphCSRView const& graph_view, + vertex_t* clustering, size_t max_level, - typename graph_view_t::weight_type resolution) + weight_t resolution) { - using vertex_t = typename graph_view_t::vertex_type; - using weight_t = typename graph_view_t::weight_type; - CUGRAPH_EXPECTS(graph_view.has_data(), "Graph must be weighted"); detail::check_clustering(graph_view, clustering); std::unique_ptr> dendrogram; weight_t modularity; - std::tie(dendrogram, modularity) = louvain(handle, graph_view, max_level, resolution); + std::tie(dendrogram, modularity) = detail::louvain(handle, graph_view, max_level, resolution); - flatten_dendrogram(handle, graph_view, *dendrogram, clustering); + detail::flatten_dendrogram(handle, graph_view, *dendrogram, clustering); return std::make_pair(dendrogram->num_levels(), modularity); } diff --git a/cpp/src/community/leiden_impl.cuh b/cpp/src/community/leiden_impl.cuh index bffb1b6d2e0..34549efe661 100644 --- a/cpp/src/community/leiden_impl.cuh +++ b/cpp/src/community/leiden_impl.cuh @@ -34,27 +34,19 @@ namespace detail { // FIXME: Can we have a common check_clustering to be used by both // Louvain and Leiden, and possibly other clustering methods? -template -void check_clustering( - graph_view_t const& graph_view, - vertex_t* clustering) +template +void check_clustering(graph_view_t const& graph_view, + vertex_t* clustering) { if (graph_view.local_vertex_partition_range_size() > 0) CUGRAPH_EXPECTS(clustering != nullptr, "Invalid input argument: clustering is null"); } -template +template std::pair>, weight_t> leiden( raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, size_t max_level, weight_t resolution) { @@ -65,16 +57,11 @@ std::pair>, weight_t> leiden( // FIXME: Can we have a common flatten_dendrogram to be used by both // Louvain and Leiden, and possibly other clustering methods? -template -void flatten_dendrogram( - raft::handle_t const& handle, - graph_view_t const& graph_view, - Dendrogram const& dendrogram, - vertex_t* clustering) +template +void flatten_dendrogram(raft::handle_t const& handle, + graph_view_t const& graph_view, + Dendrogram const& dendrogram, + vertex_t* clustering) { rmm::device_uvector vertex_ids_v(graph_view.number_of_vertices(), handle.get_stream()); @@ -89,22 +76,22 @@ void flatten_dendrogram( } // namespace detail -template -std::pair>, - typename GraphViewType::weight_type> -leiden(raft::handle_t const& handle, - GraphViewType const& graph_view, - size_t max_level, - typename GraphViewType::weight_type resolution) +template +std::pair>, weight_t> leiden( + raft::handle_t const& handle, + graph_view_t const& graph_view, + std::optional> edge_weight_view, + size_t max_level, + weight_t resolution) { - return detail::leiden(handle, graph_view, max_level, resolution); + return detail::leiden(handle, graph_view, edge_weight_view, max_level, resolution); } -template +template void flatten_dendrogram(raft::handle_t const& handle, - GraphViewType const& graph_view, - Dendrogram const& dendrogram, - typename GraphViewType::vertex_type* clustering) + graph_view_t const& graph_view, + Dendrogram const& dendrogram, + vertex_t* clustering) { detail::flatten_dendrogram(handle, graph_view, dendrogram, clustering); } diff --git a/cpp/src/community/leiden_sg.cu b/cpp/src/community/leiden_sg.cu index 76346562491..61e01b787bf 100644 --- a/cpp/src/community/leiden_sg.cu +++ b/cpp/src/community/leiden_sg.cu @@ -22,37 +22,43 @@ namespace cugraph { template std::pair>, float> leiden( raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, size_t max_level, float resolution); template std::pair>, float> leiden( raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, size_t max_level, float resolution); template std::pair>, float> leiden( raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, size_t max_level, float resolution); template std::pair>, double> leiden( raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, size_t max_level, double resolution); template std::pair>, double> leiden( raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, size_t max_level, double resolution); template std::pair>, double> leiden( raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, size_t max_level, double resolution); diff --git a/cpp/src/community/louvain_impl.cuh b/cpp/src/community/louvain_impl.cuh index fd36be01987..a698b2e1efe 100644 --- a/cpp/src/community/louvain_impl.cuh +++ b/cpp/src/community/louvain_impl.cuh @@ -35,8 +35,8 @@ namespace cugraph { namespace detail { -template -void check_clustering(graph_view_t const& graph_view, +template +void check_clustering(graph_view_t const& graph_view, vertex_t* clustering) { if (graph_view.local_vertex_partition_range_size() > 0) @@ -46,20 +46,27 @@ void check_clustering(graph_view_t template std::pair>, weight_t> louvain( raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, size_t max_level, weight_t resolution) { - using graph_t = cugraph::graph_t; - using graph_view_t = cugraph::graph_view_t; + using graph_t = cugraph::graph_t; + using graph_view_t = cugraph::graph_view_t; + + CUGRAPH_EXPECTS(edge_weight_view.has_value(), "Graph must be weighted"); std::unique_ptr> dendrogram = std::make_unique>(); graph_t current_graph(handle); graph_view_t current_graph_view(graph_view); + std::optional> current_edge_weights(handle); + std::optional> current_edge_weight_view( + edge_weight_view); HighResTimer hr_timer; - weight_t best_modularity = weight_t{-1}; - weight_t total_edge_weight = compute_total_edge_weight(handle, current_graph_view); + weight_t best_modularity = weight_t{-1}; + weight_t total_edge_weight = + compute_total_edge_weight(handle, current_graph_view, *current_edge_weight_view); rmm::device_uvector cluster_keys_v(0, handle.get_stream()); rmm::device_uvector cluster_weights_v(0, handle.get_stream()); @@ -89,7 +96,8 @@ std::pair>, weight_t> louvain( detail::timer_start( handle, hr_timer, "compute_vertex_and_cluster_weights"); - vertex_weights_v = compute_out_weight_sums(handle, current_graph_view); + vertex_weights_v = + compute_out_weight_sums(handle, current_graph_view, *current_edge_weight_view); cluster_keys_v.resize(vertex_weights_v.size(), handle.get_stream()); cluster_weights_v.resize(vertex_weights_v.size(), handle.get_stream()); @@ -104,8 +112,9 @@ std::pair>, weight_t> louvain( handle.get_stream()); if constexpr (graph_view_t::is_multi_gpu) { - std::tie(cluster_keys_v, cluster_weights_v) = shuffle_ext_vertices_and_values_by_gpu_id( - handle, std::move(cluster_keys_v), std::move(cluster_weights_v)); + std::tie(cluster_keys_v, cluster_weights_v) = + detail::shuffle_ext_vertices_and_values_by_gpu_id( + handle, std::move(cluster_keys_v), std::move(cluster_weights_v)); src_vertex_weights_cache = edge_src_property_t(handle, current_graph_view); @@ -141,6 +150,7 @@ std::pair>, weight_t> louvain( weight_t new_Q = detail::compute_modularity(handle, current_graph_view, + current_edge_weight_view, src_clusters_cache, dst_clusters_cache, next_clusters_v, @@ -159,6 +169,7 @@ std::pair>, weight_t> louvain( next_clusters_v = detail::update_clustering_by_delta_modularity(handle, current_graph_view, + current_edge_weight_view, total_edge_weight, resolution, vertex_weights_v, @@ -178,12 +189,13 @@ std::pair>, weight_t> louvain( } std::tie(cluster_keys_v, cluster_weights_v) = detail::compute_cluster_keys_and_values( - handle, current_graph_view, next_clusters_v, src_clusters_cache); + handle, current_graph_view, current_edge_weight_view, next_clusters_v, src_clusters_cache); up_down = !up_down; new_Q = detail::compute_modularity(handle, current_graph_view, + current_edge_weight_view, src_clusters_cache, dst_clusters_cache, next_clusters_v, @@ -222,12 +234,15 @@ std::pair>, weight_t> louvain( src_clusters_cache.clear(handle); dst_clusters_cache.clear(handle); - current_graph = cugraph::detail::graph_contraction( + std::tie(current_graph, current_edge_weights) = cugraph::detail::graph_contraction( handle, current_graph_view, + current_edge_weight_view, raft::device_span{dendrogram->current_level_begin(), dendrogram->current_level_size()}); - current_graph_view = current_graph.view(); + current_graph_view = current_graph.view(); + current_edge_weight_view = std::make_optional>( + (*current_edge_weights).view()); detail::timer_stop(handle, hr_timer); } @@ -237,12 +252,11 @@ std::pair>, weight_t> louvain( return std::make_pair(std::move(dendrogram), best_modularity); } -template -void flatten_dendrogram( - raft::handle_t const& handle, - graph_view_t const& graph_view, - Dendrogram const& dendrogram, - vertex_t* clustering) +template +void flatten_dendrogram(raft::handle_t const& handle, + graph_view_t const& graph_view, + Dendrogram const& dendrogram, + vertex_t* clustering) { rmm::device_uvector vertex_ids_v(graph_view.number_of_vertices(), handle.get_stream()); @@ -257,46 +271,46 @@ void flatten_dendrogram( } // namespace detail -template -std::pair>, - typename graph_view_t::weight_type> -louvain(raft::handle_t const& handle, - graph_view_t const& graph_view, - size_t max_level, - typename graph_view_t::weight_type resolution) +template +std::pair>, weight_t> louvain( + raft::handle_t const& handle, + graph_view_t const& graph_view, + std::optional> edge_weight_view, + size_t max_level, + weight_t resolution) { - return detail::louvain(handle, graph_view, max_level, resolution); + CUGRAPH_EXPECTS(edge_weight_view.has_value(), "Graph must be weighted"); + return detail::louvain(handle, graph_view, edge_weight_view, max_level, resolution); } -template +template void flatten_dendrogram(raft::handle_t const& handle, - graph_view_t const& graph_view, - Dendrogram const& dendrogram, - typename graph_view_t::vertex_type* clustering) + graph_view_t const& graph_view, + Dendrogram const& dendrogram, + vertex_t* clustering) { detail::flatten_dendrogram(handle, graph_view, dendrogram, clustering); } -template -std::pair louvain( +template +std::pair louvain( raft::handle_t const& handle, - graph_view_t const& graph_view, - typename graph_view_t::vertex_type* clustering, + graph_view_t const& graph_view, + std::optional> edge_weight_view, + vertex_t* clustering, size_t max_level, - typename graph_view_t::weight_type resolution) + weight_t resolution) { - using vertex_t = typename graph_view_t::vertex_type; - using weight_t = typename graph_view_t::weight_type; - - CUGRAPH_EXPECTS(graph_view.is_weighted(), "Graph must be weighted"); + CUGRAPH_EXPECTS(edge_weight_view.has_value(), "Graph must be weighted"); detail::check_clustering(graph_view, clustering); std::unique_ptr> dendrogram; weight_t modularity; - std::tie(dendrogram, modularity) = louvain(handle, graph_view, max_level, resolution); + std::tie(dendrogram, modularity) = + detail::louvain(handle, graph_view, edge_weight_view, max_level, resolution); - flatten_dendrogram(handle, graph_view, *dendrogram, clustering); + detail::flatten_dendrogram(handle, graph_view, *dendrogram, clustering); return std::make_pair(dendrogram->num_levels(), modularity); } diff --git a/cpp/src/community/louvain_mg.cu b/cpp/src/community/louvain_mg.cu index 8ee28f6b954..d6d266df273 100644 --- a/cpp/src/community/louvain_mg.cu +++ b/cpp/src/community/louvain_mg.cu @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021, NVIDIA CORPORATION. + * Copyright (c) 2020-2022, NVIDIA CORPORATION. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,58 +19,83 @@ namespace cugraph { // Explicit template instantations + template std::pair>, float> louvain( - raft::handle_t const&, graph_view_t const&, size_t, float); + raft::handle_t const&, + graph_view_t const&, + std::optional>, + size_t, + float); template std::pair>, float> louvain( - raft::handle_t const&, graph_view_t const&, size_t, float); + raft::handle_t const&, + graph_view_t const&, + std::optional>, + size_t, + float); template std::pair>, float> louvain( - raft::handle_t const&, graph_view_t const&, size_t, float); + raft::handle_t const&, + graph_view_t const&, + std::optional>, + size_t, + float); template std::pair>, double> louvain( raft::handle_t const&, - graph_view_t const&, + graph_view_t const&, + std::optional>, size_t, double); template std::pair>, double> louvain( raft::handle_t const&, - graph_view_t const&, + graph_view_t const&, + std::optional>, size_t, double); template std::pair>, double> louvain( raft::handle_t const&, - graph_view_t const&, + graph_view_t const&, + std::optional>, size_t, double); -template std::pair louvain(raft::handle_t const&, - graph_view_t const&, - int32_t*, - size_t, - float); +template std::pair louvain( + raft::handle_t const&, + graph_view_t const&, + std::optional>, + int32_t*, + size_t, + float); template std::pair louvain( raft::handle_t const&, - graph_view_t const&, + graph_view_t const&, + std::optional>, int32_t*, size_t, double); -template std::pair louvain(raft::handle_t const&, - graph_view_t const&, - int32_t*, - size_t, - float); +template std::pair louvain( + raft::handle_t const&, + graph_view_t const&, + std::optional>, + int32_t*, + size_t, + float); template std::pair louvain( raft::handle_t const&, - graph_view_t const&, + graph_view_t const&, + std::optional>, int32_t*, size_t, double); -template std::pair louvain(raft::handle_t const&, - graph_view_t const&, - int64_t*, - size_t, - float); +template std::pair louvain( + raft::handle_t const&, + graph_view_t const&, + std::optional>, + int64_t*, + size_t, + float); template std::pair louvain( raft::handle_t const&, - graph_view_t const&, + graph_view_t const&, + std::optional>, int64_t*, size_t, double); diff --git a/cpp/src/community/louvain_sg.cu b/cpp/src/community/louvain_sg.cu index e60fd189216..4e26aa1cf18 100644 --- a/cpp/src/community/louvain_sg.cu +++ b/cpp/src/community/louvain_sg.cu @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021, NVIDIA CORPORATION. + * Copyright (c) 2020-2022, NVIDIA CORPORATION. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,61 +19,83 @@ namespace cugraph { // Explicit template instantations + template std::pair>, float> louvain( - raft::handle_t const&, graph_view_t const&, size_t, float); + raft::handle_t const&, + graph_view_t const&, + std::optional>, + size_t, + float); template std::pair>, float> louvain( - raft::handle_t const&, graph_view_t const&, size_t, float); + raft::handle_t const&, + graph_view_t const&, + std::optional>, + size_t, + float); template std::pair>, float> louvain( - raft::handle_t const&, graph_view_t const&, size_t, float); + raft::handle_t const&, + graph_view_t const&, + std::optional>, + size_t, + float); template std::pair>, double> louvain( raft::handle_t const&, - graph_view_t const&, + graph_view_t const&, + std::optional>, size_t, double); template std::pair>, double> louvain( raft::handle_t const&, - graph_view_t const&, + graph_view_t const&, + std::optional>, size_t, double); template std::pair>, double> louvain( raft::handle_t const&, - graph_view_t const&, + graph_view_t const&, + std::optional>, size_t, double); template std::pair louvain( raft::handle_t const&, - graph_view_t const&, + graph_view_t const&, + std::optional>, int32_t*, size_t, float); template std::pair louvain( raft::handle_t const&, - graph_view_t const&, + graph_view_t const&, + std::optional>, int32_t*, size_t, double); template std::pair louvain( raft::handle_t const&, - graph_view_t const&, + graph_view_t const&, + std::optional>, int32_t*, size_t, float); template std::pair louvain( raft::handle_t const&, - graph_view_t const&, + graph_view_t const&, + std::optional>, int32_t*, size_t, double); template std::pair louvain( raft::handle_t const&, - graph_view_t const&, + graph_view_t const&, + std::optional>, int64_t*, size_t, float); template std::pair louvain( raft::handle_t const&, - graph_view_t const&, + graph_view_t const&, + std::optional>, int64_t*, size_t, double); diff --git a/cpp/src/community/triangle_count_impl.cuh b/cpp/src/community/triangle_count_impl.cuh index b5bbd8172cb..e2f2c785f52 100644 --- a/cpp/src/community/triangle_count_impl.cuh +++ b/cpp/src/community/triangle_count_impl.cuh @@ -57,7 +57,8 @@ struct invalid_or_outside_local_vertex_partition_range_t { template struct is_not_self_loop_t { - __device__ bool operator()(vertex_t src, vertex_t dst, thrust::nullopt_t, thrust::nullopt_t) const + __device__ bool operator()( + vertex_t src, vertex_t dst, thrust::nullopt_t, thrust::nullopt_t, thrust::nullopt_t) const { return src != dst; } @@ -73,10 +74,8 @@ struct is_two_or_greater_t { template struct in_two_core_t { - __device__ bool operator()(vertex_t, - vertex_t, - uint8_t src_in_two_core, - uint8_t dst_in_two_core) const + __device__ bool operator()( + vertex_t, vertex_t, uint8_t src_in_two_core, uint8_t dst_in_two_core, thrust::nullopt_t) const { return (src_in_two_core == uint8_t{1}) && (dst_in_two_core == uint8_t{1}); } @@ -87,7 +86,8 @@ struct low_to_high_degree_t { __device__ bool operator()(vertex_t src, vertex_t dst, edge_t src_out_degree, - edge_t dst_out_degree) const + edge_t dst_out_degree, + thrust::nullopt_t) const { return (src_out_degree < dst_out_degree) ? true : (((src_out_degree == dst_out_degree) && @@ -142,13 +142,15 @@ struct vertex_offset_from_vertex_t { } // namespace -template +template void triangle_count(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, std::optional> vertices, raft::device_span counts, bool do_expensive_check) { + using weight_t = float; // dummy + // 1. Check input arguments. CUGRAPH_EXPECTS( @@ -192,26 +194,23 @@ void triangle_count(raft::handle_t const& handle, // 2. Exclude self-loops (FIXME: better mask-out once we add masking support). - std::optional> modified_graph{std::nullopt}; - std::optional> modified_graph_view{ - std::nullopt}; + std::optional> modified_graph{std::nullopt}; + std::optional> modified_graph_view{std::nullopt}; std::optional> renumber_map{std::nullopt}; if (graph_view.count_self_loops(handle) > edge_t{0}) { - rmm::device_uvector srcs(size_t{0}, handle.get_stream()); - rmm::device_uvector dsts(size_t{0}, handle.get_stream()); - std::tie(srcs, dsts, std::ignore) = extract_if_e(handle, - graph_view, - edge_src_dummy_property_t{}.view(), - edge_dst_dummy_property_t{}.view(), - is_not_self_loop_t{}); + auto [srcs, dsts] = extract_if_e(handle, + graph_view, + edge_src_dummy_property_t{}.view(), + edge_dst_dummy_property_t{}.view(), + is_not_self_loop_t{}); if constexpr (multi_gpu) { std::tie(srcs, dsts, std::ignore) = detail::shuffle_edgelist_by_gpu_id( handle, std::move(srcs), std::move(dsts), std::nullopt); } - std::tie(*modified_graph, std::ignore, renumber_map) = + std::tie(*modified_graph, std::ignore, std::ignore, renumber_map) = create_graph_from_edgelist( handle, std::nullopt, @@ -255,13 +254,11 @@ void triangle_count(raft::handle_t const& handle, handle, cur_graph_view, in_two_core_flags.begin(), edge_src_in_two_cores); update_edge_dst_property( handle, cur_graph_view, in_two_core_flags.begin(), edge_dst_in_two_cores); - rmm::device_uvector srcs(size_t{0}, handle.get_stream()); - rmm::device_uvector dsts(size_t{0}, handle.get_stream()); - std::tie(srcs, dsts, std::ignore) = extract_if_e(handle, - cur_graph_view, - edge_src_in_two_cores.view(), - edge_dst_in_two_cores.view(), - in_two_core_t{}); + auto [srcs, dsts] = extract_if_e(handle, + cur_graph_view, + edge_src_in_two_cores.view(), + edge_dst_in_two_cores.view(), + in_two_core_t{}); if constexpr (multi_gpu) { std::tie(srcs, dsts, std::ignore) = detail::shuffle_edgelist_by_gpu_id( @@ -269,7 +266,7 @@ void triangle_count(raft::handle_t const& handle, } std::optional> tmp_renumber_map{std::nullopt}; - std::tie(*modified_graph, std::ignore, tmp_renumber_map) = + std::tie(*modified_graph, std::ignore, std::ignore, tmp_renumber_map) = create_graph_from_edgelist( handle, std::nullopt, @@ -309,13 +306,11 @@ void triangle_count(raft::handle_t const& handle, cur_graph_view); update_edge_src_property(handle, cur_graph_view, out_degrees.begin(), edge_src_out_degrees); update_edge_dst_property(handle, cur_graph_view, out_degrees.begin(), edge_dst_out_degrees); - rmm::device_uvector srcs(size_t{0}, handle.get_stream()); - rmm::device_uvector dsts(size_t{0}, handle.get_stream()); - std::tie(srcs, dsts, std::ignore) = extract_if_e(handle, - cur_graph_view, - edge_src_out_degrees.view(), - edge_dst_out_degrees.view(), - low_to_high_degree_t{}); + auto [srcs, dsts] = extract_if_e(handle, + cur_graph_view, + edge_src_out_degrees.view(), + edge_dst_out_degrees.view(), + low_to_high_degree_t{}); if constexpr (multi_gpu) { std::tie(srcs, dsts, std::ignore) = detail::shuffle_edgelist_by_gpu_id( @@ -323,7 +318,7 @@ void triangle_count(raft::handle_t const& handle, } std::optional> tmp_renumber_map{std::nullopt}; - std::tie(*modified_graph, std::ignore, tmp_renumber_map) = + std::tie(*modified_graph, std::ignore, std::ignore, tmp_renumber_map) = create_graph_from_edgelist( handle, std::nullopt, diff --git a/cpp/src/community/triangle_count_mg.cu b/cpp/src/community/triangle_count_mg.cu index 9013c86e7fd..c863fe3c20f 100644 --- a/cpp/src/community/triangle_count_mg.cu +++ b/cpp/src/community/triangle_count_mg.cu @@ -19,37 +19,19 @@ namespace cugraph { template void triangle_count(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, std::optional> vertices, raft::device_span counts, bool do_expensive_check); template void triangle_count(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, std::optional> vertices, - raft::device_span counts, - bool do_expensive_check); - -template void triangle_count(raft::handle_t const& handle, - graph_view_t const& graph_view, - std::optional> vertices, - raft::device_span counts, - bool do_expensive_check); - -template void triangle_count(raft::handle_t const& handle, - graph_view_t const& graph_view, - std::optional> vertices, - raft::device_span counts, - bool do_expensive_check); - -template void triangle_count(raft::handle_t const& handle, - graph_view_t const& graph_view, - std::optional> vertices, raft::device_span counts, bool do_expensive_check); template void triangle_count(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, std::optional> vertices, raft::device_span counts, bool do_expensive_check); diff --git a/cpp/src/community/triangle_count_sg.cu b/cpp/src/community/triangle_count_sg.cu index 14c6b128c89..ab46dee0b15 100644 --- a/cpp/src/community/triangle_count_sg.cu +++ b/cpp/src/community/triangle_count_sg.cu @@ -19,37 +19,19 @@ namespace cugraph { template void triangle_count(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, std::optional> vertices, raft::device_span counts, bool do_expensive_check); template void triangle_count(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, std::optional> vertices, - raft::device_span counts, - bool do_expensive_check); - -template void triangle_count(raft::handle_t const& handle, - graph_view_t const& graph_view, - std::optional> vertices, - raft::device_span counts, - bool do_expensive_check); - -template void triangle_count(raft::handle_t const& handle, - graph_view_t const& graph_view, - std::optional> vertices, - raft::device_span counts, - bool do_expensive_check); - -template void triangle_count(raft::handle_t const& handle, - graph_view_t const& graph_view, - std::optional> vertices, raft::device_span counts, bool do_expensive_check); template void triangle_count(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, std::optional> vertices, raft::device_span counts, bool do_expensive_check); diff --git a/cpp/src/components/weakly_connected_components_impl.cuh b/cpp/src/components/weakly_connected_components_impl.cuh index 185252deb5c..0527835a154 100644 --- a/cpp/src/components/weakly_connected_components_impl.cuh +++ b/cpp/src/components/weakly_connected_components_impl.cuh @@ -190,6 +190,7 @@ struct e_op_t { __device__ thrust::optional operator()(thrust::tuple tagged_src, vertex_t dst, thrust::nullopt_t, + thrust::nullopt_t, thrust::nullopt_t) const { auto tag = thrust::get<1>(tagged_src); @@ -270,7 +271,6 @@ void weakly_connected_components_impl(raft::handle_t const& handle, { using vertex_t = typename GraphViewType::vertex_type; using edge_t = typename GraphViewType::edge_type; - using weight_t = typename GraphViewType::weight_type; static_assert(std::is_integral::value, "GraphViewType::vertex_type should be integral."); @@ -304,11 +304,7 @@ void weakly_connected_components_impl(raft::handle_t const& handle, static_cast(handle.get_device_properties().multiProcessorCount) * edge_t{1024}; size_t num_levels{0}; - graph_t + graph_t level_graph(handle); rmm::device_uvector level_renumber_map(0, handle.get_stream()); std::vector> level_component_vectors{}; @@ -579,6 +575,7 @@ void weakly_connected_components_impl(raft::handle_t const& handle, vertex_frontier.bucket(bucket_idx_cur), edge_src_dummy_property_t{}.view(), edge_dst_dummy_property_t{}.view(), + edge_dummy_property_t{}.view(), e_op_t{ GraphViewType::is_multi_gpu ? detail::edge_partition_endpoint_property_device_view_t( @@ -727,11 +724,11 @@ void weakly_connected_components_impl(raft::handle_t const& handle, } std::optional> tmp_renumber_map{std::nullopt}; - std::tie(level_graph, std::ignore, tmp_renumber_map) = + std::tie(level_graph, std::ignore, std::ignore, tmp_renumber_map) = create_graph_from_edgelist(handle, std::nullopt, @@ -780,12 +777,11 @@ void weakly_connected_components_impl(raft::handle_t const& handle, } // namespace -template -void weakly_connected_components( - raft::handle_t const& handle, - graph_view_t const& graph_view, - vertex_t* components, - bool do_expensive_check) +template +void weakly_connected_components(raft::handle_t const& handle, + graph_view_t const& graph_view, + vertex_t* components, + bool do_expensive_check) { weakly_connected_components_impl(handle, graph_view, components, do_expensive_check); } diff --git a/cpp/src/components/weakly_connected_components_mg.cu b/cpp/src/components/weakly_connected_components_mg.cu index 3fd2f9ef5ac..0702da8d54b 100644 --- a/cpp/src/components/weakly_connected_components_mg.cu +++ b/cpp/src/components/weakly_connected_components_mg.cu @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, NVIDIA CORPORATION. + * Copyright (c) 2021-2022, NVIDIA CORPORATION. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,39 +19,22 @@ namespace cugraph { // MG instantiations -template void weakly_connected_components( - raft::handle_t const& handle, - graph_view_t const& graph_view, - int32_t* components, - bool do_expensive_check); - -template void weakly_connected_components( - raft::handle_t const& handle, - graph_view_t const& graph_view, - int32_t* components, - bool do_expensive_check); template void weakly_connected_components( raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, int32_t* components, bool do_expensive_check); template void weakly_connected_components( raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, int32_t* components, bool do_expensive_check); template void weakly_connected_components( raft::handle_t const& handle, - graph_view_t const& graph_view, - int64_t* components, - bool do_expensive_check); - -template void weakly_connected_components( - raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, int64_t* components, bool do_expensive_check); diff --git a/cpp/src/components/weakly_connected_components_sg.cu b/cpp/src/components/weakly_connected_components_sg.cu index ac118b098ed..836281102a4 100644 --- a/cpp/src/components/weakly_connected_components_sg.cu +++ b/cpp/src/components/weakly_connected_components_sg.cu @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, NVIDIA CORPORATION. + * Copyright (c) 2021-2022, NVIDIA CORPORATION. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,39 +19,22 @@ namespace cugraph { // SG instantiations -template void weakly_connected_components( - raft::handle_t const& handle, - graph_view_t const& graph_view, - int32_t* components, - bool do_expensive_check); - -template void weakly_connected_components( - raft::handle_t const& handle, - graph_view_t const& graph_view, - int32_t* components, - bool do_expensive_check); template void weakly_connected_components( raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, int32_t* components, bool do_expensive_check); template void weakly_connected_components( raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, int32_t* components, bool do_expensive_check); template void weakly_connected_components( raft::handle_t const& handle, - graph_view_t const& graph_view, - int64_t* components, - bool do_expensive_check); - -template void weakly_connected_components( - raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, int64_t* components, bool do_expensive_check); diff --git a/cpp/src/cores/core_number_impl.cuh b/cpp/src/cores/core_number_impl.cuh index 26b6cc461a8..86fd15905b0 100644 --- a/cpp/src/cores/core_number_impl.cuh +++ b/cpp/src/cores/core_number_impl.cuh @@ -53,10 +53,8 @@ struct e_op_t { size_t k{}; edge_t delta{}; - __device__ thrust::optional operator()(vertex_t, - vertex_t, - thrust::nullopt_t, - edge_t dst_val) const + __device__ thrust::optional operator()( + vertex_t, vertex_t, thrust::nullopt_t, edge_t dst_val, thrust::nullopt_t) const { return dst_val >= k ? thrust::optional{delta} : thrust::nullopt; } @@ -79,9 +77,9 @@ struct mult_degree_by_two_t { } // namespace -template +template void core_number(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, edge_t* core_numbers, k_core_degree_type_t degree_type, size_t k_first, @@ -177,8 +175,8 @@ void core_number(raft::handle_t const& handle, vertex_frontier_t vertex_frontier(handle, num_buckets); - edge_dst_property_t, edge_t> - dst_core_numbers(handle, graph_view); + edge_dst_property_t, edge_t> dst_core_numbers( + handle, graph_view); update_edge_dst_property(handle, graph_view, core_numbers, dst_core_numbers); auto k = std::max(k_first, size_t{2}); // degree 0|1 vertices belong to 0|1-core @@ -229,6 +227,7 @@ void core_number(raft::handle_t const& handle, vertex_frontier.bucket(bucket_idx_cur), edge_src_dummy_property_t{}.view(), dst_core_numbers.view(), + edge_dummy_property_t{}.view(), e_op_t{k, delta}, reduce_op::plus()); diff --git a/cpp/src/cores/core_number_mg.cu b/cpp/src/cores/core_number_mg.cu index 3471417075a..f483198ece0 100644 --- a/cpp/src/cores/core_number_mg.cu +++ b/cpp/src/cores/core_number_mg.cu @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, NVIDIA CORPORATION. + * Copyright (c) 2021-2022, NVIDIA CORPORATION. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,7 +21,7 @@ namespace cugraph { // MG instantiation template void core_number(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, int32_t* core_numbers, k_core_degree_type_t degree_type, size_t k_first, @@ -29,31 +29,7 @@ template void core_number(raft::handle_t const& handle, bool do_expensive_check); template void core_number(raft::handle_t const& handle, - graph_view_t const& graph_view, - int32_t* core_numbers, - k_core_degree_type_t degree_type, - size_t k_first, - size_t k_last, - bool do_expensive_check); - -template void core_number(raft::handle_t const& handle, - graph_view_t const& graph_view, - int64_t* core_numbers, - k_core_degree_type_t degree_type, - size_t k_first, - size_t k_last, - bool do_expensive_check); - -template void core_number(raft::handle_t const& handle, - graph_view_t const& graph_view, - int64_t* core_numbers, - k_core_degree_type_t degree_type, - size_t k_first, - size_t k_last, - bool do_expensive_check); - -template void core_number(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, int64_t* core_numbers, k_core_degree_type_t degree_type, size_t k_first, @@ -61,7 +37,7 @@ template void core_number(raft::handle_t const& handle, bool do_expensive_check); template void core_number(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, int64_t* core_numbers, k_core_degree_type_t degree_type, size_t k_first, diff --git a/cpp/src/cores/core_number_sg.cu b/cpp/src/cores/core_number_sg.cu index 19667fa4535..5ebac9d0624 100644 --- a/cpp/src/cores/core_number_sg.cu +++ b/cpp/src/cores/core_number_sg.cu @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, NVIDIA CORPORATION. + * Copyright (c) 2021-2022, NVIDIA CORPORATION. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,7 +21,7 @@ namespace cugraph { // MG instantiation template void core_number(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, int32_t* core_numbers, k_core_degree_type_t degree_type, size_t k_first, @@ -29,31 +29,7 @@ template void core_number(raft::handle_t const& handle, bool do_expensive_check); template void core_number(raft::handle_t const& handle, - graph_view_t const& graph_view, - int32_t* core_numbers, - k_core_degree_type_t degree_type, - size_t k_first, - size_t k_last, - bool do_expensive_check); - -template void core_number(raft::handle_t const& handle, - graph_view_t const& graph_view, - int64_t* core_numbers, - k_core_degree_type_t degree_type, - size_t k_first, - size_t k_last, - bool do_expensive_check); - -template void core_number(raft::handle_t const& handle, - graph_view_t const& graph_view, - int64_t* core_numbers, - k_core_degree_type_t degree_type, - size_t k_first, - size_t k_last, - bool do_expensive_check); - -template void core_number(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, int64_t* core_numbers, k_core_degree_type_t degree_type, size_t k_first, @@ -61,7 +37,7 @@ template void core_number(raft::handle_t const& handle, bool do_expensive_check); template void core_number(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, int64_t* core_numbers, k_core_degree_type_t degree_type, size_t k_first, diff --git a/cpp/src/cores/k_core_impl.cuh b/cpp/src/cores/k_core_impl.cuh index e6e176d7287..a908e00a927 100644 --- a/cpp/src/cores/k_core_impl.cuh +++ b/cpp/src/cores/k_core_impl.cuh @@ -26,7 +26,8 @@ std::tuple, rmm::device_uvector, std::optional>> k_core(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, size_t k, std::optional degree_type, std::optional> core_numbers, diff --git a/cpp/src/cores/k_core_mg.cu b/cpp/src/cores/k_core_mg.cu index 644e83af078..e07c5e83cd3 100644 --- a/cpp/src/cores/k_core_mg.cu +++ b/cpp/src/cores/k_core_mg.cu @@ -24,7 +24,8 @@ template std::tuple, rmm::device_uvector, std::optional>> k_core(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, size_t k, std::optional degree_type, std::optional> core_numbers, @@ -34,7 +35,8 @@ template std::tuple, rmm::device_uvector, std::optional>> k_core(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, size_t k, std::optional degree_type, std::optional> core_numbers, @@ -44,7 +46,8 @@ template std::tuple, rmm::device_uvector, std::optional>> k_core(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, size_t k, std::optional degree_type, std::optional> core_numbers, @@ -54,7 +57,8 @@ template std::tuple, rmm::device_uvector, std::optional>> k_core(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, size_t k, std::optional degree_type, std::optional> core_numbers, @@ -64,7 +68,8 @@ template std::tuple, rmm::device_uvector, std::optional>> k_core(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, size_t k, std::optional degree_type, std::optional> core_numbers, @@ -74,7 +79,8 @@ template std::tuple, rmm::device_uvector, std::optional>> k_core(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, size_t k, std::optional degree_type, std::optional> core_numbers, diff --git a/cpp/src/cores/k_core_sg.cu b/cpp/src/cores/k_core_sg.cu index 7ced6181a6e..b45bfd32d30 100644 --- a/cpp/src/cores/k_core_sg.cu +++ b/cpp/src/cores/k_core_sg.cu @@ -24,7 +24,8 @@ template std::tuple, rmm::device_uvector, std::optional>> k_core(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, size_t k, std::optional degree_type, std::optional> core_numbers, @@ -34,7 +35,8 @@ template std::tuple, rmm::device_uvector, std::optional>> k_core(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, size_t k, std::optional degree_type, std::optional> core_numbers, @@ -44,7 +46,8 @@ template std::tuple, rmm::device_uvector, std::optional>> k_core(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, size_t k, std::optional degree_type, std::optional> core_numbers, @@ -54,7 +57,8 @@ template std::tuple, rmm::device_uvector, std::optional>> k_core(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, size_t k, std::optional degree_type, std::optional> core_numbers, @@ -64,7 +68,8 @@ template std::tuple, rmm::device_uvector, std::optional>> k_core(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, size_t k, std::optional degree_type, std::optional> core_numbers, @@ -74,7 +79,8 @@ template std::tuple, rmm::device_uvector, std::optional>> k_core(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, size_t k, std::optional degree_type, std::optional> core_numbers, diff --git a/cpp/src/link_analysis/hits_impl.cuh b/cpp/src/link_analysis/hits_impl.cuh index 0d8a40fee3e..3e2eee51067 100644 --- a/cpp/src/link_analysis/hits_impl.cuh +++ b/cpp/src/link_analysis/hits_impl.cuh @@ -118,7 +118,8 @@ std::tuple hits(raft::handle_t const& handle, graph_view, prev_src_hubs.view(), edge_dst_dummy_property_t{}.view(), - [] __device__(auto, auto, auto, auto prev_src_hub_value, auto) { return prev_src_hub_value; }, + edge_dummy_property_t{}.view(), + [] __device__(auto, auto, auto prev_src_hub_value, auto, auto) { return prev_src_hub_value; }, result_t{0}, authorities); @@ -130,7 +131,8 @@ std::tuple hits(raft::handle_t const& handle, graph_view, edge_src_dummy_property_t{}.view(), curr_dst_auth.view(), - [] __device__(auto src, auto dst, auto, auto, auto curr_dst_auth_value) { + edge_dummy_property_t{}.view(), + [] __device__(auto src, auto dst, auto, auto curr_dst_auth_value, auto) { return curr_dst_auth_value; }, result_t{0}, @@ -188,17 +190,16 @@ std::tuple hits(raft::handle_t const& handle, } // namespace detail -template -std::tuple hits( - raft::handle_t const& handle, - graph_view_t const& graph_view, - weight_t* const hubs, - weight_t* const authorities, - weight_t epsilon, - size_t max_iterations, - bool has_initial_hubs_guess, - bool normalize, - bool do_expensive_check) +template +std::tuple hits(raft::handle_t const& handle, + graph_view_t const& graph_view, + result_t* const hubs, + result_t* const authorities, + result_t epsilon, + size_t max_iterations, + bool has_initial_hubs_guess, + bool normalize, + bool do_expensive_check) { return detail::hits(handle, graph_view, diff --git a/cpp/src/link_analysis/hits_mg.cu b/cpp/src/link_analysis/hits_mg.cu index 4c18107f9bd..fad475d3fc1 100644 --- a/cpp/src/link_analysis/hits_mg.cu +++ b/cpp/src/link_analysis/hits_mg.cu @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, NVIDIA CORPORATION. + * Copyright (c) 2021-2022, NVIDIA CORPORATION. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,7 +21,7 @@ namespace cugraph { // MG instantiation template std::tuple hits( raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, float* const hubs, float* const authorities, float epsilon, @@ -32,7 +32,7 @@ template std::tuple hits( template std::tuple hits( raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, double* const hubs, double* const authorities, double epsilon, @@ -43,7 +43,7 @@ template std::tuple hits( template std::tuple hits( raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, float* const hubs, float* const authorities, float epsilon, @@ -54,7 +54,7 @@ template std::tuple hits( template std::tuple hits( raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, double* const hubs, double* const authorities, double epsilon, @@ -65,7 +65,7 @@ template std::tuple hits( template std::tuple hits( raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, float* const hubs, float* const authorities, float epsilon, @@ -76,7 +76,7 @@ template std::tuple hits( template std::tuple hits( raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, double* const hubs, double* const authorities, double epsilon, diff --git a/cpp/src/link_analysis/hits_sg.cu b/cpp/src/link_analysis/hits_sg.cu index 24315e241e1..1f1b04b65b0 100644 --- a/cpp/src/link_analysis/hits_sg.cu +++ b/cpp/src/link_analysis/hits_sg.cu @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, NVIDIA CORPORATION. + * Copyright (c) 2021-2022, NVIDIA CORPORATION. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,7 +21,7 @@ namespace cugraph { // SG instantiation template std::tuple hits( raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, float* const hubs, float* const authorities, float epsilon, @@ -32,7 +32,7 @@ template std::tuple hits( template std::tuple hits( raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, double* const hubs, double* const authorities, double epsilon, @@ -43,7 +43,7 @@ template std::tuple hits( template std::tuple hits( raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, float* const hubs, float* const authorities, float epsilon, @@ -54,7 +54,7 @@ template std::tuple hits( template std::tuple hits( raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, double* const hubs, double* const authorities, double epsilon, @@ -65,7 +65,7 @@ template std::tuple hits( template std::tuple hits( raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, float* const hubs, float* const authorities, float epsilon, @@ -76,7 +76,7 @@ template std::tuple hits( template std::tuple hits( raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, double* const hubs, double* const authorities, double epsilon, diff --git a/cpp/src/link_analysis/pagerank_impl.cuh b/cpp/src/link_analysis/pagerank_impl.cuh index 21145a58b08..a9dbd1c6429 100644 --- a/cpp/src/link_analysis/pagerank_impl.cuh +++ b/cpp/src/link_analysis/pagerank_impl.cuh @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -45,11 +46,13 @@ namespace cugraph { namespace detail { // FIXME: personalization_vector_size is confusing in OPG (local or aggregate?) -template +template void pagerank( raft::handle_t const& handle, GraphViewType const& pull_graph_view, - std::optional precomputed_vertex_out_weight_sums, + std::optional> + edge_weight_view, + std::optional precomputed_vertex_out_weight_sums, std::optional personalization_vertices, std::optional personalization_values, std::optional personalization_vector_size, @@ -61,7 +64,7 @@ void pagerank( bool do_expensive_check) { using vertex_t = typename GraphViewType::vertex_type; - using weight_t = typename GraphViewType::weight_type; + using edge_t = typename GraphViewType::edge_type; static_assert(std::is_integral::value, "GraphViewType::vertex_type should be integral."); @@ -105,15 +108,17 @@ void pagerank( "Invalid input argument: outgoing edge weight sum values should be non-negative."); } - if (pull_graph_view.is_weighted()) { + if (edge_weight_view) { auto num_negative_edge_weights = count_if_e(handle, pull_graph_view, edge_src_dummy_property_t{}.view(), edge_dst_dummy_property_t{}.view(), - [] __device__(vertex_t, vertex_t, weight_t w, auto, auto) { return w < 0.0; }); - CUGRAPH_EXPECTS(num_negative_edge_weights == 0, - "Invalid input argument: input graph should have non-negative edge weights."); + *edge_weight_view, + [] __device__(vertex_t, vertex_t, auto, auto, weight_t w) { return w < 0.0; }); + CUGRAPH_EXPECTS( + num_negative_edge_weights == 0, + "Invalid input argument: input edge weights should have non-negative values."); } if (has_initial_guess) { @@ -156,13 +161,25 @@ void pagerank( // 2. compute the sums of the out-going edge weights (if not provided) - auto tmp_vertex_out_weight_sums = precomputed_vertex_out_weight_sums - ? std::nullopt - : std::optional>{ - compute_out_weight_sums(handle, pull_graph_view)}; - auto vertex_out_weight_sums = precomputed_vertex_out_weight_sums - ? *precomputed_vertex_out_weight_sums - : (*tmp_vertex_out_weight_sums).data(); + std::optional> tmp_vertex_out_weight_sums{std::nullopt}; + if (!precomputed_vertex_out_weight_sums) { + if (edge_weight_view) { + tmp_vertex_out_weight_sums = + compute_out_weight_sums(handle, pull_graph_view, *edge_weight_view); + } else { + auto tmp_vertex_out_degrees = pull_graph_view.compute_out_degrees(handle); + tmp_vertex_out_weight_sums = + rmm::device_uvector(tmp_vertex_out_degrees.size(), handle.get_stream()); + thrust::transform(handle.get_thrust_policy(), + tmp_vertex_out_degrees.begin(), + tmp_vertex_out_degrees.end(), + (*tmp_vertex_out_weight_sums).begin(), + detail::typecast_t{}); + } + } + auto vertex_out_weight_sums = precomputed_vertex_out_weight_sums + ? *precomputed_vertex_out_weight_sums + : (*tmp_vertex_out_weight_sums).data(); // 3. initialize pagerank values @@ -246,16 +263,31 @@ void pagerank( static_cast(num_vertices) : result_t{0.0}; - per_v_transform_reduce_incoming_e( - handle, - pull_graph_view, - edge_src_pageranks.view(), - edge_dst_dummy_property_t{}.view(), - [alpha] __device__(vertex_t, vertex_t, weight_t w, auto src_val, auto) { - return src_val * w * alpha; - }, - unvarying_part, - pageranks); + if (edge_weight_view) { + per_v_transform_reduce_incoming_e( + handle, + pull_graph_view, + edge_src_pageranks.view(), + edge_dst_dummy_property_t{}.view(), + *edge_weight_view, + [alpha] __device__(vertex_t, vertex_t, auto src_val, auto, weight_t w) { + return src_val * w * alpha; + }, + unvarying_part, + pageranks); + } else { + per_v_transform_reduce_incoming_e( + handle, + pull_graph_view, + edge_src_pageranks.view(), + edge_dst_dummy_property_t{}.view(), + edge_dummy_property_t{}.view(), + [alpha] __device__(vertex_t, vertex_t, auto src_val, auto, auto) { + return src_val * 1.0 * alpha; + }, + unvarying_part, + pageranks); + } if (aggregate_personalization_vector_size > 0) { auto vertex_partition = vertex_partition_device_view_t( @@ -297,7 +329,8 @@ void pagerank( template void pagerank(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, std::optional precomputed_vertex_out_weight_sums, std::optional personalization_vertices, std::optional personalization_values, @@ -311,6 +344,7 @@ void pagerank(raft::handle_t const& handle, { detail::pagerank(handle, graph_view, + edge_weight_view, precomputed_vertex_out_weight_sums, personalization_vertices, personalization_values, diff --git a/cpp/src/link_analysis/pagerank_mg.cu b/cpp/src/link_analysis/pagerank_mg.cu index 40388bec353..d6dd5f60544 100644 --- a/cpp/src/link_analysis/pagerank_mg.cu +++ b/cpp/src/link_analysis/pagerank_mg.cu @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, NVIDIA CORPORATION. + * Copyright (c) 2021-2022, NVIDIA CORPORATION. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,7 +19,8 @@ namespace cugraph { // MG instantiation template void pagerank(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, std::optional precomputed_vertex_out_weight_sums, std::optional personalization_vertices, std::optional personalization_values, @@ -32,7 +33,8 @@ template void pagerank(raft::handle_t const& handle, bool do_expensive_check); template void pagerank(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, std::optional precomputed_vertex_out_weight_sums, std::optional personalization_vertices, std::optional personalization_values, @@ -45,7 +47,8 @@ template void pagerank(raft::handle_t const& handle, bool do_expensive_check); template void pagerank(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, std::optional precomputed_vertex_out_weight_sums, std::optional personalization_vertices, std::optional personalization_values, @@ -58,7 +61,8 @@ template void pagerank(raft::handle_t const& handle, bool do_expensive_check); template void pagerank(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, std::optional precomputed_vertex_out_weight_sums, std::optional personalization_vertices, std::optional personalization_values, @@ -71,7 +75,8 @@ template void pagerank(raft::handle_t const& handle, bool do_expensive_check); template void pagerank(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, std::optional precomputed_vertex_out_weight_sums, std::optional personalization_vertices, std::optional personalization_values, @@ -84,7 +89,8 @@ template void pagerank(raft::handle_t const& handle, bool do_expensive_check); template void pagerank(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, std::optional precomputed_vertex_out_weight_sums, std::optional personalization_vertices, std::optional personalization_values, diff --git a/cpp/src/link_analysis/pagerank_sg.cu b/cpp/src/link_analysis/pagerank_sg.cu index 97579f4d6b0..3dc0adc45df 100644 --- a/cpp/src/link_analysis/pagerank_sg.cu +++ b/cpp/src/link_analysis/pagerank_sg.cu @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, NVIDIA CORPORATION. + * Copyright (c) 2021-2022, NVIDIA CORPORATION. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,7 +19,8 @@ namespace cugraph { // SG instantiation template void pagerank(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, std::optional precomputed_vertex_out_weight_sums, std::optional personalization_vertices, std::optional personalization_values, @@ -32,7 +33,8 @@ template void pagerank(raft::handle_t const& handle, bool do_expensive_check); template void pagerank(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, std::optional precomputed_vertex_out_weight_sums, std::optional personalization_vertices, std::optional personalization_values, @@ -45,7 +47,8 @@ template void pagerank(raft::handle_t const& handle, bool do_expensive_check); template void pagerank(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, std::optional precomputed_vertex_out_weight_sums, std::optional personalization_vertices, std::optional personalization_values, @@ -58,7 +61,8 @@ template void pagerank(raft::handle_t const& handle, bool do_expensive_check); template void pagerank(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, std::optional precomputed_vertex_out_weight_sums, std::optional personalization_vertices, std::optional personalization_values, @@ -71,7 +75,8 @@ template void pagerank(raft::handle_t const& handle, bool do_expensive_check); template void pagerank(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, std::optional precomputed_vertex_out_weight_sums, std::optional personalization_vertices, std::optional personalization_values, @@ -84,7 +89,8 @@ template void pagerank(raft::handle_t const& handle, bool do_expensive_check); template void pagerank(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, std::optional precomputed_vertex_out_weight_sums, std::optional personalization_vertices, std::optional personalization_values, diff --git a/cpp/src/link_prediction/jaccard_impl.cuh b/cpp/src/link_prediction/jaccard_impl.cuh index 875d9fac3d9..95007ed3a13 100644 --- a/cpp/src/link_prediction/jaccard_impl.cuh +++ b/cpp/src/link_prediction/jaccard_impl.cuh @@ -48,16 +48,16 @@ struct weighted_jaccard_functor_t { template rmm::device_uvector jaccard_coefficients( raft::handle_t const& handle, - graph_view_t const& graph_view, - std::tuple, raft::device_span> vertex_pairs, - bool use_weights) + graph_view_t const& graph_view, + std::optional> edge_weight_view, + std::tuple, raft::device_span> vertex_pairs) { - if (use_weights) + if (!edge_weight_view) return detail::similarity( - handle, graph_view, vertex_pairs, use_weights, detail::weighted_jaccard_functor_t{}); + handle, graph_view, edge_weight_view, vertex_pairs, detail::jaccard_functor_t{}); else return detail::similarity( - handle, graph_view, vertex_pairs, use_weights, detail::jaccard_functor_t{}); + handle, graph_view, edge_weight_view, vertex_pairs, detail::weighted_jaccard_functor_t{}); } } // namespace cugraph diff --git a/cpp/src/link_prediction/jaccard_mg.cu b/cpp/src/link_prediction/jaccard_mg.cu index 2c7cd970f20..3cf93ccbcc8 100644 --- a/cpp/src/link_prediction/jaccard_mg.cu +++ b/cpp/src/link_prediction/jaccard_mg.cu @@ -19,38 +19,38 @@ namespace cugraph { template rmm::device_uvector jaccard_coefficients( raft::handle_t const& handle, - graph_view_t const& graph_view, - std::tuple, raft::device_span> vertex_pairs, - bool use_weights); + graph_view_t const& graph_view, + std::optional> edge_weight_view, + std::tuple, raft::device_span> vertex_pairs); template rmm::device_uvector jaccard_coefficients( raft::handle_t const& handle, - graph_view_t const& graph_view, - std::tuple, raft::device_span> vertex_pairs, - bool use_weights); + graph_view_t const& graph_view, + std::optional> edge_weight_view, + std::tuple, raft::device_span> vertex_pairs); template rmm::device_uvector jaccard_coefficients( raft::handle_t const& handle, - graph_view_t const& graph_view, - std::tuple, raft::device_span> vertex_pairs, - bool use_weights); + graph_view_t const& graph_view, + std::optional> edge_weight_view, + std::tuple, raft::device_span> vertex_pairs); template rmm::device_uvector jaccard_coefficients( raft::handle_t const& handle, - graph_view_t const& graph_view, - std::tuple, raft::device_span> vertex_pairs, - bool use_weights); + graph_view_t const& graph_view, + std::optional> edge_weight_view, + std::tuple, raft::device_span> vertex_pairs); template rmm::device_uvector jaccard_coefficients( raft::handle_t const& handle, - graph_view_t const& graph_view, - std::tuple, raft::device_span> vertex_pairs, - bool use_weights); + graph_view_t const& graph_view, + std::optional> edge_weight_view, + std::tuple, raft::device_span> vertex_pairs); template rmm::device_uvector jaccard_coefficients( raft::handle_t const& handle, - graph_view_t const& graph_view, - std::tuple, raft::device_span> vertex_pairs, - bool use_weights); + graph_view_t const& graph_view, + std::optional> edge_weight_view, + std::tuple, raft::device_span> vertex_pairs); } // namespace cugraph diff --git a/cpp/src/link_prediction/jaccard_sg.cu b/cpp/src/link_prediction/jaccard_sg.cu index 7032a0d0808..64e698b54be 100644 --- a/cpp/src/link_prediction/jaccard_sg.cu +++ b/cpp/src/link_prediction/jaccard_sg.cu @@ -19,38 +19,38 @@ namespace cugraph { template rmm::device_uvector jaccard_coefficients( raft::handle_t const& handle, - graph_view_t const& graph_view, - std::tuple, raft::device_span> vertex_pairs, - bool use_weights); + graph_view_t const& graph_view, + std::optional> edge_weight_view, + std::tuple, raft::device_span> vertex_pairs); template rmm::device_uvector jaccard_coefficients( raft::handle_t const& handle, - graph_view_t const& graph_view, - std::tuple, raft::device_span> vertex_pairs, - bool use_weights); + graph_view_t const& graph_view, + std::optional> edge_weight_view, + std::tuple, raft::device_span> vertex_pairs); template rmm::device_uvector jaccard_coefficients( raft::handle_t const& handle, - graph_view_t const& graph_view, - std::tuple, raft::device_span> vertex_pairs, - bool use_weights); + graph_view_t const& graph_view, + std::optional> edge_weight_view, + std::tuple, raft::device_span> vertex_pairs); template rmm::device_uvector jaccard_coefficients( raft::handle_t const& handle, - graph_view_t const& graph_view, - std::tuple, raft::device_span> vertex_pairs, - bool use_weights); + graph_view_t const& graph_view, + std::optional> edge_weight_view, + std::tuple, raft::device_span> vertex_pairs); template rmm::device_uvector jaccard_coefficients( raft::handle_t const& handle, - graph_view_t const& graph_view, - std::tuple, raft::device_span> vertex_pairs, - bool use_weights); + graph_view_t const& graph_view, + std::optional> edge_weight_view, + std::tuple, raft::device_span> vertex_pairs); template rmm::device_uvector jaccard_coefficients( raft::handle_t const& handle, - graph_view_t const& graph_view, - std::tuple, raft::device_span> vertex_pairs, - bool use_weights); + graph_view_t const& graph_view, + std::optional> edge_weight_view, + std::tuple, raft::device_span> vertex_pairs); } // namespace cugraph diff --git a/cpp/src/link_prediction/overlap_impl.cuh b/cpp/src/link_prediction/overlap_impl.cuh index 5e80b08c5a6..8d4d5fab15c 100644 --- a/cpp/src/link_prediction/overlap_impl.cuh +++ b/cpp/src/link_prediction/overlap_impl.cuh @@ -48,16 +48,16 @@ struct weighted_overlap_functor_t { template rmm::device_uvector overlap_coefficients( raft::handle_t const& handle, - graph_view_t const& graph_view, - std::tuple, raft::device_span> vertex_pairs, - bool use_weights) + graph_view_t const& graph_view, + std::optional> edge_weight_view, + std::tuple, raft::device_span> vertex_pairs) { - if (use_weights) + if (!edge_weight_view) return detail::similarity( - handle, graph_view, vertex_pairs, use_weights, detail::weighted_overlap_functor_t{}); + handle, graph_view, edge_weight_view, vertex_pairs, detail::overlap_functor_t{}); else return detail::similarity( - handle, graph_view, vertex_pairs, use_weights, detail::overlap_functor_t{}); + handle, graph_view, edge_weight_view, vertex_pairs, detail::weighted_overlap_functor_t{}); } } // namespace cugraph diff --git a/cpp/src/link_prediction/overlap_mg.cu b/cpp/src/link_prediction/overlap_mg.cu index 2d566cb1b35..6366c47e9e3 100644 --- a/cpp/src/link_prediction/overlap_mg.cu +++ b/cpp/src/link_prediction/overlap_mg.cu @@ -19,38 +19,38 @@ namespace cugraph { template rmm::device_uvector overlap_coefficients( raft::handle_t const& handle, - graph_view_t const& graph_view, - std::tuple, raft::device_span> vertex_pairs, - bool use_weights); + graph_view_t const& graph_view, + std::optional> edge_weight_view, + std::tuple, raft::device_span> vertex_pairs); template rmm::device_uvector overlap_coefficients( raft::handle_t const& handle, - graph_view_t const& graph_view, - std::tuple, raft::device_span> vertex_pairs, - bool use_weights); + graph_view_t const& graph_view, + std::optional> edge_weight_view, + std::tuple, raft::device_span> vertex_pairs); template rmm::device_uvector overlap_coefficients( raft::handle_t const& handle, - graph_view_t const& graph_view, - std::tuple, raft::device_span> vertex_pairs, - bool use_weights); + graph_view_t const& graph_view, + std::optional> edge_weight_view, + std::tuple, raft::device_span> vertex_pairs); template rmm::device_uvector overlap_coefficients( raft::handle_t const& handle, - graph_view_t const& graph_view, - std::tuple, raft::device_span> vertex_pairs, - bool use_weights); + graph_view_t const& graph_view, + std::optional> edge_weight_view, + std::tuple, raft::device_span> vertex_pairs); template rmm::device_uvector overlap_coefficients( raft::handle_t const& handle, - graph_view_t const& graph_view, - std::tuple, raft::device_span> vertex_pairs, - bool use_weights); + graph_view_t const& graph_view, + std::optional> edge_weight_view, + std::tuple, raft::device_span> vertex_pairs); template rmm::device_uvector overlap_coefficients( raft::handle_t const& handle, - graph_view_t const& graph_view, - std::tuple, raft::device_span> vertex_pairs, - bool use_weights); + graph_view_t const& graph_view, + std::optional> edge_weight_view, + std::tuple, raft::device_span> vertex_pairs); } // namespace cugraph diff --git a/cpp/src/link_prediction/overlap_sg.cu b/cpp/src/link_prediction/overlap_sg.cu index 43f29fc8b2c..f8a29196581 100644 --- a/cpp/src/link_prediction/overlap_sg.cu +++ b/cpp/src/link_prediction/overlap_sg.cu @@ -19,38 +19,38 @@ namespace cugraph { template rmm::device_uvector overlap_coefficients( raft::handle_t const& handle, - graph_view_t const& graph_view, - std::tuple, raft::device_span> vertex_pairs, - bool use_weights); + graph_view_t const& graph_view, + std::optional> edge_weight_view, + std::tuple, raft::device_span> vertex_pairs); template rmm::device_uvector overlap_coefficients( raft::handle_t const& handle, - graph_view_t const& graph_view, - std::tuple, raft::device_span> vertex_pairs, - bool use_weights); + graph_view_t const& graph_view, + std::optional> edge_weight_view, + std::tuple, raft::device_span> vertex_pairs); template rmm::device_uvector overlap_coefficients( raft::handle_t const& handle, - graph_view_t const& graph_view, - std::tuple, raft::device_span> vertex_pairs, - bool use_weights); + graph_view_t const& graph_view, + std::optional> edge_weight_view, + std::tuple, raft::device_span> vertex_pairs); template rmm::device_uvector overlap_coefficients( raft::handle_t const& handle, - graph_view_t const& graph_view, - std::tuple, raft::device_span> vertex_pairs, - bool use_weights); + graph_view_t const& graph_view, + std::optional> edge_weight_view, + std::tuple, raft::device_span> vertex_pairs); template rmm::device_uvector overlap_coefficients( raft::handle_t const& handle, - graph_view_t const& graph_view, - std::tuple, raft::device_span> vertex_pairs, - bool use_weights); + graph_view_t const& graph_view, + std::optional> edge_weight_view, + std::tuple, raft::device_span> vertex_pairs); template rmm::device_uvector overlap_coefficients( raft::handle_t const& handle, - graph_view_t const& graph_view, - std::tuple, raft::device_span> vertex_pairs, - bool use_weights); + graph_view_t const& graph_view, + std::optional> edge_weight_view, + std::tuple, raft::device_span> vertex_pairs); } // namespace cugraph diff --git a/cpp/src/link_prediction/similarity_impl.cuh b/cpp/src/link_prediction/similarity_impl.cuh index 3f39092df36..03dba0cdc0c 100644 --- a/cpp/src/link_prediction/similarity_impl.cuh +++ b/cpp/src/link_prediction/similarity_impl.cuh @@ -34,12 +34,12 @@ namespace detail { template rmm::device_uvector similarity( raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, std::tuple, raft::device_span> vertex_pairs, - bool use_weights, functor_t functor) { - using GraphViewType = graph_view_t; + using GraphViewType = graph_view_t; constexpr bool do_expensive_check = false; CUGRAPH_EXPECTS(std::get<0>(vertex_pairs).size() == std::get<1>(vertex_pairs).size(), @@ -47,14 +47,11 @@ rmm::device_uvector similarity( CUGRAPH_EXPECTS(graph_view.is_symmetric(), "similarity algorithms require an undirected(symmetric) graph"); - if (use_weights) - CUGRAPH_EXPECTS(graph_view.is_weighted(), "attempting to use weights on an unweighted graph"); - size_t num_vertex_pairs = std::get<0>(vertex_pairs).size(); auto vertex_pairs_begin = thrust::make_zip_iterator(std::get<0>(vertex_pairs).data(), std::get<1>(vertex_pairs).data()); - if (use_weights) { + if (edge_weight_view) { // FIXME: need implementation, similar to unweighted // Use compute_out_weight_sums instead of compute_out_degrees // Sum up for each common edge compute (u,a,v): min weight ((u,a), (a,v)) and diff --git a/cpp/src/link_prediction/sorensen_impl.cuh b/cpp/src/link_prediction/sorensen_impl.cuh index 07f8c183c29..f23416ec6ab 100644 --- a/cpp/src/link_prediction/sorensen_impl.cuh +++ b/cpp/src/link_prediction/sorensen_impl.cuh @@ -48,16 +48,16 @@ struct weighted_sorensen_functor_t { template rmm::device_uvector sorensen_coefficients( raft::handle_t const& handle, - graph_view_t const& graph_view, - std::tuple, raft::device_span> vertex_pairs, - bool use_weights) + graph_view_t const& graph_view, + std::optional> edge_weight_view, + std::tuple, raft::device_span> vertex_pairs) { - if (use_weights) + if (!edge_weight_view) return detail::similarity( - handle, graph_view, vertex_pairs, use_weights, detail::weighted_sorensen_functor_t{}); + handle, graph_view, edge_weight_view, vertex_pairs, detail::sorensen_functor_t{}); else return detail::similarity( - handle, graph_view, vertex_pairs, use_weights, detail::sorensen_functor_t{}); + handle, graph_view, edge_weight_view, vertex_pairs, detail::weighted_sorensen_functor_t{}); } } // namespace cugraph diff --git a/cpp/src/link_prediction/sorensen_mg.cu b/cpp/src/link_prediction/sorensen_mg.cu index f62b8cbf522..d5ba33f823e 100644 --- a/cpp/src/link_prediction/sorensen_mg.cu +++ b/cpp/src/link_prediction/sorensen_mg.cu @@ -19,38 +19,38 @@ namespace cugraph { template rmm::device_uvector sorensen_coefficients( raft::handle_t const& handle, - graph_view_t const& graph_view, - std::tuple, raft::device_span> vertex_pairs, - bool use_weights); + graph_view_t const& graph_view, + std::optional> edge_weight_view, + std::tuple, raft::device_span> vertex_pairs); template rmm::device_uvector sorensen_coefficients( raft::handle_t const& handle, - graph_view_t const& graph_view, - std::tuple, raft::device_span> vertex_pairs, - bool use_weights); + graph_view_t const& graph_view, + std::optional> edge_weight_view, + std::tuple, raft::device_span> vertex_pairs); template rmm::device_uvector sorensen_coefficients( raft::handle_t const& handle, - graph_view_t const& graph_view, - std::tuple, raft::device_span> vertex_pairs, - bool use_weights); + graph_view_t const& graph_view, + std::optional> edge_weight_view, + std::tuple, raft::device_span> vertex_pairs); template rmm::device_uvector sorensen_coefficients( raft::handle_t const& handle, - graph_view_t const& graph_view, - std::tuple, raft::device_span> vertex_pairs, - bool use_weights); + graph_view_t const& graph_view, + std::optional> edge_weight_view, + std::tuple, raft::device_span> vertex_pairs); template rmm::device_uvector sorensen_coefficients( raft::handle_t const& handle, - graph_view_t const& graph_view, - std::tuple, raft::device_span> vertex_pairs, - bool use_weights); + graph_view_t const& graph_view, + std::optional> edge_weight_view, + std::tuple, raft::device_span> vertex_pairs); template rmm::device_uvector sorensen_coefficients( raft::handle_t const& handle, - graph_view_t const& graph_view, - std::tuple, raft::device_span> vertex_pairs, - bool use_weights); + graph_view_t const& graph_view, + std::optional> edge_weight_view, + std::tuple, raft::device_span> vertex_pairs); } // namespace cugraph diff --git a/cpp/src/link_prediction/sorensen_sg.cu b/cpp/src/link_prediction/sorensen_sg.cu index 555cb4d0a78..376077cb3f2 100644 --- a/cpp/src/link_prediction/sorensen_sg.cu +++ b/cpp/src/link_prediction/sorensen_sg.cu @@ -19,38 +19,38 @@ namespace cugraph { template rmm::device_uvector sorensen_coefficients( raft::handle_t const& handle, - graph_view_t const& graph_view, - std::tuple, raft::device_span> vertex_pairs, - bool use_weights); + graph_view_t const& graph_view, + std::optional> edge_weight_view, + std::tuple, raft::device_span> vertex_pairs); template rmm::device_uvector sorensen_coefficients( raft::handle_t const& handle, - graph_view_t const& graph_view, - std::tuple, raft::device_span> vertex_pairs, - bool use_weights); + graph_view_t const& graph_view, + std::optional> edge_weight_view, + std::tuple, raft::device_span> vertex_pairs); template rmm::device_uvector sorensen_coefficients( raft::handle_t const& handle, - graph_view_t const& graph_view, - std::tuple, raft::device_span> vertex_pairs, - bool use_weights); + graph_view_t const& graph_view, + std::optional> edge_weight_view, + std::tuple, raft::device_span> vertex_pairs); template rmm::device_uvector sorensen_coefficients( raft::handle_t const& handle, - graph_view_t const& graph_view, - std::tuple, raft::device_span> vertex_pairs, - bool use_weights); + graph_view_t const& graph_view, + std::optional> edge_weight_view, + std::tuple, raft::device_span> vertex_pairs); template rmm::device_uvector sorensen_coefficients( raft::handle_t const& handle, - graph_view_t const& graph_view, - std::tuple, raft::device_span> vertex_pairs, - bool use_weights); + graph_view_t const& graph_view, + std::optional> edge_weight_view, + std::tuple, raft::device_span> vertex_pairs); template rmm::device_uvector sorensen_coefficients( raft::handle_t const& handle, - graph_view_t const& graph_view, - std::tuple, raft::device_span> vertex_pairs, - bool use_weights); + graph_view_t const& graph_view, + std::optional> edge_weight_view, + std::tuple, raft::device_span> vertex_pairs); } // namespace cugraph diff --git a/cpp/src/prims/count_if_e.cuh b/cpp/src/prims/count_if_e.cuh index eeedcb8a363..340ccba0c7a 100644 --- a/cpp/src/prims/count_if_e.cuh +++ b/cpp/src/prims/count_if_e.cuh @@ -32,41 +32,44 @@ namespace cugraph { * This function is inspired by thrust::count_if(). * * @tparam GraphViewType Type of the passed non-owning graph object. - * @tparam EdgePartitionSrcValueInputWrapper Type of the wrapper for edge partition source property - * values. - * @tparam EdgePartitionDstValueInputWrapper Type of the wrapper for edge partition destination - * property values. + * @tparam EdgeSrcValueInputWrapper Type of the wrapper for edge source property values. + * @tparam EdgeDstValueInputWrapper Type of the wrapper for edge destination property values. + * @tparam EdgeValueInputWrapper Type of the wrapper for edge property values. * @tparam EdgeOp Type of the quaternary (or quinary) edge operator. * @param handle RAFT handle object to encapsulate resources (e.g. CUDA stream, communicator, and * handles to various CUDA libraries) to run graph algorithms. * @param graph_view Non-owning graph object. - * @param edge_partition_src_value_input Device-copyable wrapper used to access source input - * property values (for the edge sources assigned to this process in multi-GPU). Use either - * cugraph::edge_partition_src_property_t::device_view() (if @p e_op needs to access source property - * values) or cugraph::dummy_property_t::device_view() (if @p e_op does not access source property - * values). Use update_edge_src_property to fill the wrapper. - * @param edge_partition_dst_value_input Device-copyable wrapper used to access destination input - * property values (for the edge destinations assigned to this process in multi-GPU). Use either - * cugraph::edge_partition_dst_property_t::device_view() (if @p e_op needs to access destination - * property values) or cugraph::dummy_property_t::device_view() (if @p e_op does not access - * destination property values). Use update_edge_dst_property to fill the wrapper. - * @param e_op Quaternary (or quinary) operator takes edge source, edge destination, (optional edge - * weight), property values for the source, and property values for the destination and returns if - * this edge should be included in the returned count. + * @param edge_src_value_input Wrapper used to access source input property values (for the edge + * sources assigned to this process in multi-GPU). Use either cugraph::edge_src_property_t::view() + * (if @p e_op needs to access source property values) or cugraph::edge_src_dummy_property_t::view() + * (if @p e_op does not access source property values). Use update_edge_src_property to + * fill the wrapper. + * @param edge_dst_value_input Wrapper used to access destination input property values (for the + * edge destinations assigned to this process in multi-GPU). Use either + * cugraph::edge_dst_property_t::view() (if @p e_op needs to access destination property values) or + * cugraph::edge_dst_dummy_property_t::view() (if @p e_op does not access destination property + * values). Use update_edge_dst_property to fill the wrapper. + * @param edge_value_input Wrapper used to access edge input property values (for the edges assigned + * to this process in multi-GPU). Use either cugraph::edge_property_t::view() (if @p e_op needs to + * access edge property values) or cugraph::edge_dummy_property_t::view() (if @p e_op does not + * access edge property values). + * @param e_op Quinary operator takes edge source, edge destination, property values for the source, + * destination, and edge and returns true if this edge should be included in the returned count. * @param do_expensive_check A flag to run expensive checks for input arguments (if set to `true`). * @return GraphViewType::edge_type Number of times @p e_op returned true. */ template -typename GraphViewType::edge_type count_if_e( - raft::handle_t const& handle, - GraphViewType const& graph_view, - EdgePartitionSrcValueInputWrapper edge_partition_src_value_input, - EdgePartitionDstValueInputWrapper edge_partition_dst_value_input, - EdgeOp e_op, - bool do_expensive_check = false) +typename GraphViewType::edge_type count_if_e(raft::handle_t const& handle, + GraphViewType const& graph_view, + EdgeSrcValueInputWrapper edge_src_value_input, + EdgeDstValueInputWrapper edge_dst_value_input, + EdgeValueInputWrapper edge_value_input, + EdgeOp e_op, + bool do_expensive_check = false) { using vertex_t = typename GraphViewType::vertex_type; using edge_t = typename GraphViewType::edge_type; @@ -77,12 +80,14 @@ typename GraphViewType::edge_type count_if_e( return transform_reduce_e(handle, graph_view, - edge_partition_src_value_input, - edge_partition_dst_value_input, + edge_src_value_input, + edge_dst_value_input, + edge_value_input, cast_edge_op_bool_to_integer{e_op}, edge_t{0}); diff --git a/cpp/src/prims/detail/extract_transform_v_frontier_e.cuh b/cpp/src/prims/detail/extract_transform_v_frontier_e.cuh index 2300280b6da..44aa9e6fd3a 100644 --- a/cpp/src/prims/detail/extract_transform_v_frontier_e.cuh +++ b/cpp/src/prims/detail/extract_transform_v_frontier_e.cuh @@ -18,6 +18,7 @@ #include #include +#include #include #include #include @@ -166,18 +167,19 @@ template __global__ void extract_transform_v_frontier_e_hypersparse( edge_partition_device_view_t edge_partition, KeyIterator key_first, KeyIterator key_last, EdgePartitionSrcValueInputWrapper edge_partition_src_value_input, EdgePartitionDstValueInputWrapper edge_partition_dst_value_input, + EdgePartitionEdgeValueInputWrapper edge_partition_e_value_input, BufferKeyOutputIterator buffer_key_output_first, BufferValueOutputIterator buffer_value_output_first, size_t* buffer_idx_ptr, @@ -185,12 +187,12 @@ __global__ void extract_transform_v_frontier_e_hypersparse( { using vertex_t = typename GraphViewType::vertex_type; using edge_t = typename GraphViewType::edge_type; - using weight_t = typename GraphViewType::weight_type; using key_t = typename thrust::iterator_traits::value_type; using e_op_result_t = typename evaluate_edge_op::result_type; auto const tid = threadIdx.x + blockIdx.x * blockDim.x; @@ -211,7 +213,6 @@ __global__ void extract_transform_v_frontier_e_hypersparse( buffer_warp_start_indices[extract_transform_v_frontier_e_kernel_block_size / raft::warp_size()]; auto indices = edge_partition.indices(); - auto weights = edge_partition.weights(); vertex_t num_keys = static_cast(thrust::distance(key_first, key_last)); auto rounded_up_num_keys = @@ -301,12 +302,13 @@ __global__ void extract_transform_v_frontier_e_hypersparse( key_t, EdgePartitionSrcValueInputWrapper, EdgePartitionDstValueInputWrapper, + EdgePartitionEdgeValueInputWrapper, EdgeOp>() .compute(key_or_src, key_or_dst, - weights ? (*weights)[local_edge_offset] : weight_t{1.0}, edge_partition_src_value_input.get(src_offset), edge_partition_dst_value_input.get(dst_offset), + edge_partition_e_value_input.get(local_edge_offset), e_op); } auto ballot_e_op = @@ -338,18 +340,19 @@ template __global__ void extract_transform_v_frontier_e_low_degree( edge_partition_device_view_t edge_partition, KeyIterator key_first, KeyIterator key_last, EdgePartitionSrcValueInputWrapper edge_partition_src_value_input, EdgePartitionDstValueInputWrapper edge_partition_dst_value_input, + EdgePartitionEdgeValueInputWrapper edge_partition_e_value_input, BufferKeyOutputIterator buffer_key_output_first, BufferValueOutputIterator buffer_value_output_first, size_t* buffer_idx_ptr, @@ -357,12 +360,12 @@ __global__ void extract_transform_v_frontier_e_low_degree( { using vertex_t = typename GraphViewType::vertex_type; using edge_t = typename GraphViewType::edge_type; - using weight_t = typename GraphViewType::weight_type; using key_t = typename thrust::iterator_traits::value_type; using e_op_result_t = typename evaluate_edge_op::result_type; auto const tid = threadIdx.x + blockIdx.x * blockDim.x; @@ -381,7 +384,6 @@ __global__ void extract_transform_v_frontier_e_low_degree( buffer_warp_start_indices[extract_transform_v_frontier_e_kernel_block_size / raft::warp_size()]; auto indices = edge_partition.indices(); - auto weights = edge_partition.weights(); vertex_t num_keys = static_cast(thrust::distance(key_first, key_last)); auto rounded_up_num_keys = @@ -464,12 +466,13 @@ __global__ void extract_transform_v_frontier_e_low_degree( key_t, EdgePartitionSrcValueInputWrapper, EdgePartitionDstValueInputWrapper, + EdgePartitionEdgeValueInputWrapper, EdgeOp>() .compute(key_or_src, key_or_dst, - weights ? (*weights)[local_edge_offset] : weight_t{1.0}, edge_partition_src_value_input.get(src_offset), edge_partition_dst_value_input.get(dst_offset), + edge_partition_e_value_input.get(local_edge_offset), e_op); } auto ballot = __ballot_sync(uint32_t{0xffffffff}, e_op_result ? uint32_t{1} : uint32_t{0}); @@ -501,18 +504,19 @@ template __global__ void extract_transform_v_frontier_e_mid_degree( edge_partition_device_view_t edge_partition, KeyIterator key_first, KeyIterator key_last, EdgePartitionSrcValueInputWrapper edge_partition_src_value_input, EdgePartitionDstValueInputWrapper edge_partition_dst_value_input, + EdgePartitionEdgeValueInputWrapper edge_partition_e_value_input, BufferKeyOutputIterator buffer_key_output_first, BufferValueOutputIterator buffer_value_output_first, size_t* buffer_idx_ptr, @@ -520,12 +524,12 @@ __global__ void extract_transform_v_frontier_e_mid_degree( { using vertex_t = typename GraphViewType::vertex_type; using edge_t = typename GraphViewType::edge_type; - using weight_t = typename GraphViewType::weight_type; using key_t = typename thrust::iterator_traits::value_type; using e_op_result_t = typename evaluate_edge_op::result_type; auto const tid = threadIdx.x + blockIdx.x * blockDim.x; @@ -546,9 +550,10 @@ __global__ void extract_transform_v_frontier_e_mid_degree( } auto major_offset = edge_partition.major_offset_from_major_nocheck(major); vertex_t const* indices{nullptr}; - thrust::optional weights{thrust::nullopt}; + edge_t local_edge_offset{}; edge_t local_out_degree{}; - thrust::tie(indices, weights, local_out_degree) = edge_partition.local_edges(major_offset); + thrust::tie(indices, local_edge_offset, local_out_degree) = + edge_partition.local_edges(major_offset); auto rounded_up_local_out_degree = ((static_cast(local_out_degree) + (raft::warp_size() - 1)) / raft::warp_size()) * raft::warp_size(); @@ -574,12 +579,13 @@ __global__ void extract_transform_v_frontier_e_mid_degree( key_t, EdgePartitionSrcValueInputWrapper, EdgePartitionDstValueInputWrapper, + EdgePartitionEdgeValueInputWrapper, EdgeOp>() .compute(key_or_src, key_or_dst, - weights ? (*weights)[i] : weight_t{1.0}, edge_partition_src_value_input.get(src_offset), edge_partition_dst_value_input.get(dst_offset), + edge_partition_e_value_input.get(local_edge_offset + i), e_op); } auto ballot = __ballot_sync(uint32_t{0xffffffff}, e_op_result ? uint32_t{1} : uint32_t{0}); @@ -611,18 +617,19 @@ template __global__ void extract_transform_v_frontier_e_high_degree( edge_partition_device_view_t edge_partition, KeyIterator key_first, KeyIterator key_last, EdgePartitionSrcValueInputWrapper edge_partition_src_value_input, EdgePartitionDstValueInputWrapper edge_partition_dst_value_input, + EdgePartitionEdgeValueInputWrapper edge_partition_e_value_input, BufferKeyOutputIterator buffer_key_output_first, BufferValueOutputIterator buffer_value_output_first, size_t* buffer_idx_ptr, @@ -630,12 +637,12 @@ __global__ void extract_transform_v_frontier_e_high_degree( { using vertex_t = typename GraphViewType::vertex_type; using edge_t = typename GraphViewType::edge_type; - using weight_t = typename GraphViewType::weight_type; using key_t = typename thrust::iterator_traits::value_type; using e_op_result_t = typename evaluate_edge_op::result_type; auto idx = static_cast(blockIdx.x); @@ -654,10 +661,11 @@ __global__ void extract_transform_v_frontier_e_high_degree( } auto major_offset = edge_partition.major_offset_from_major_nocheck(major); vertex_t const* indices{nullptr}; - thrust::optional weights{thrust::nullopt}; + edge_t local_edge_offset{}; edge_t local_out_degree{}; - thrust::tie(indices, weights, local_out_degree) = edge_partition.local_edges(major_offset); - auto rounded_up_local_out_degree = ((static_cast(local_out_degree) + + thrust::tie(indices, local_edge_offset, local_out_degree) = + edge_partition.local_edges(major_offset); + auto rounded_up_local_out_degree = ((static_cast(local_out_degree) + (extract_transform_v_frontier_e_kernel_block_size - 1)) / extract_transform_v_frontier_e_kernel_block_size) * extract_transform_v_frontier_e_kernel_block_size; @@ -685,12 +693,13 @@ __global__ void extract_transform_v_frontier_e_high_degree( key_t, EdgePartitionSrcValueInputWrapper, EdgePartitionDstValueInputWrapper, + EdgePartitionEdgeValueInputWrapper, EdgeOp>() .compute(key_or_src, key_or_dst, - weights ? (*weights)[i] : weight_t{1.0}, edge_partition_src_value_input.get(src_offset), edge_partition_dst_value_input.get(dst_offset), + edge_partition_e_value_input.get(local_edge_offset + i), e_op); } BlockScan(temp_storage) @@ -725,6 +734,7 @@ template std::tuple< decltype(allocate_optional_dataframe_buffer(size_t{0}, rmm::cuda_stream_view{})), @@ -734,12 +744,12 @@ extract_transform_v_frontier_e(raft::handle_t const& handle, VertexFrontierBucketType const& frontier, EdgeSrcValueInputWrapper edge_src_value_input, EdgeDstValueInputWrapper edge_dst_value_input, + EdgeValueInputWrapper edge_value_input, EdgeOp e_op, bool do_expensive_check = false) { using vertex_t = typename GraphViewType::vertex_type; using edge_t = typename GraphViewType::edge_type; - using weight_t = typename GraphViewType::weight_type; using key_t = typename VertexFrontierBucketType::key_type; using output_key_t = OutputKeyT; using output_value_t = OutputValueT; @@ -748,6 +758,7 @@ extract_transform_v_frontier_e(raft::handle_t const& handle, key_t, EdgeSrcValueInputWrapper, EdgeDstValueInputWrapper, + EdgeValueInputWrapper, EdgeOp>::result_type; using edge_partition_src_input_device_view_t = std::conditional_t< @@ -770,6 +781,12 @@ extract_transform_v_frontier_e(raft::handle_t const& handle, edge_partition_endpoint_property_device_view_t< vertex_t, typename EdgeDstValueInputWrapper::value_iterator>>>; + using edge_partition_e_input_device_view_t = std::conditional_t< + std::is_same_v, + detail::edge_partition_edge_dummy_property_device_view_t, + detail::edge_partition_edge_property_device_view_t< + edge_t, + typename EdgeValueInputWrapper::value_iterator>>; static_assert(GraphViewType::is_storage_transposed == incoming); static_assert(!std::is_same_v || @@ -847,7 +864,7 @@ extract_transform_v_frontier_e(raft::handle_t const& handle, for (size_t i = 0; i < graph_view.number_of_local_edge_partitions(); ++i) { auto edge_partition = - edge_partition_device_view_t( + edge_partition_device_view_t( graph_view.local_edge_partition_view(i)); auto edge_partition_frontier_key_buffer = @@ -910,6 +927,7 @@ extract_transform_v_frontier_e(raft::handle_t const& handle, edge_partition_src_input_device_view_t(edge_src_value_input, i); edge_partition_dst_value_input = edge_partition_dst_input_device_view_t(edge_dst_value_input); } + auto edge_partition_e_value_input = edge_partition_e_input_device_view_t(edge_value_input, i); if (segment_offsets) { static_assert(num_sparse_segments_per_vertex_partition == 3); @@ -948,6 +966,7 @@ extract_transform_v_frontier_e(raft::handle_t const& handle, edge_partition_frontier_key_first + h_offsets[0], edge_partition_src_value_input, edge_partition_dst_value_input, + edge_partition_e_value_input, get_optional_dataframe_buffer_begin(key_buffer), get_optional_dataframe_buffer_begin(value_buffer), buffer_idx.data(), @@ -964,6 +983,7 @@ extract_transform_v_frontier_e(raft::handle_t const& handle, edge_partition_frontier_key_first + h_offsets[1], edge_partition_src_value_input, edge_partition_dst_value_input, + edge_partition_e_value_input, get_optional_dataframe_buffer_begin(key_buffer), get_optional_dataframe_buffer_begin(value_buffer), buffer_idx.data(), @@ -980,6 +1000,7 @@ extract_transform_v_frontier_e(raft::handle_t const& handle, edge_partition_frontier_key_first + h_offsets[2], edge_partition_src_value_input, edge_partition_dst_value_input, + edge_partition_e_value_input, get_optional_dataframe_buffer_begin(key_buffer), get_optional_dataframe_buffer_begin(value_buffer), buffer_idx.data(), @@ -996,6 +1017,7 @@ extract_transform_v_frontier_e(raft::handle_t const& handle, edge_partition_frontier_key_first + h_offsets[3], edge_partition_src_value_input, edge_partition_dst_value_input, + edge_partition_e_value_input, get_optional_dataframe_buffer_begin(key_buffer), get_optional_dataframe_buffer_begin(value_buffer), buffer_idx.data(), @@ -1014,6 +1036,7 @@ extract_transform_v_frontier_e(raft::handle_t const& handle, edge_partition_frontier_key_last, edge_partition_src_value_input, edge_partition_dst_value_input, + edge_partition_e_value_input, get_optional_dataframe_buffer_begin(key_buffer), get_optional_dataframe_buffer_begin(value_buffer), buffer_idx.data(), diff --git a/cpp/src/prims/detail/nbr_intersection.cuh b/cpp/src/prims/detail/nbr_intersection.cuh index 0b8c45c2e50..460d269d0d3 100644 --- a/cpp/src/prims/detail/nbr_intersection.cuh +++ b/cpp/src/prims/detail/nbr_intersection.cuh @@ -121,12 +121,12 @@ struct reorder_group_count_t { } }; -template +template struct update_rx_major_local_degree_t { int row_comm_size{}; int col_comm_size{}; - edge_partition_device_view_t edge_partition{}; + edge_partition_device_view_t edge_partition{}; size_t reordered_idx_first{}; size_t local_partition_idx{}; @@ -166,12 +166,12 @@ struct update_rx_major_local_degree_t { } }; -template +template struct update_rx_major_local_nbrs_t { int row_comm_size{}; int col_comm_size{}; - edge_partition_device_view_t edge_partition{}; + edge_partition_device_view_t edge_partition{}; size_t reordered_idx_first{}; size_t local_partition_idx{}; @@ -194,18 +194,18 @@ struct update_rx_major_local_nbrs_t { auto major = rx_majors[rx_group_firsts[row_comm_rank * col_comm_size + local_partition_idx] + offset_in_local_edge_partition]; vertex_t const* indices{nullptr}; - [[maybe_unused]] thrust::optional weights{thrust::nullopt}; + [[maybe_unused]] edge_t edge_offset{0}; edge_t local_degree{0}; if (multi_gpu && (edge_partition.major_hypersparse_first() && (major >= *(edge_partition.major_hypersparse_first())))) { auto major_hypersparse_idx = edge_partition.major_hypersparse_idx_from_major_nocheck(major); if (major_hypersparse_idx) { - thrust::tie(indices, weights, local_degree) = edge_partition.local_edges( + thrust::tie(indices, edge_offset, local_degree) = edge_partition.local_edges( (*(edge_partition.major_hypersparse_first()) - edge_partition.major_range_first()) + *major_hypersparse_idx); } } else { - thrust::tie(indices, weights, local_degree) = + thrust::tie(indices, edge_offset, local_degree) = edge_partition.local_edges(edge_partition.major_offset_from_major_nocheck(major)); } // FIXME: this can lead to thread-divergence with a mix of high-degree and low-degree @@ -236,7 +236,6 @@ template struct pick_min_degree_t { FirstElementToIdxMap first_element_to_idx_map{}; @@ -245,7 +244,7 @@ struct pick_min_degree_t { SecondElementToIdxMap second_element_to_idx_map{}; size_t const* second_element_offsets{nullptr}; - edge_partition_device_view_t edge_partition{}; + edge_partition_device_view_t edge_partition{}; __device__ edge_t operator()(thrust::tuple pair) const { @@ -314,7 +313,6 @@ template struct copy_intersecting_nbrs_and_update_intersection_size_t { FirstElementToIdxMap first_element_to_idx_map{}; @@ -325,7 +323,7 @@ struct copy_intersecting_nbrs_and_update_intersection_size_t { size_t const* second_element_offsets{nullptr}; vertex_t const* second_element_indices{nullptr}; - edge_partition_device_view_t edge_partition{}; + edge_partition_device_view_t edge_partition{}; VertexPairIterator vertex_pair_first; size_t const* nbr_intersection_offsets{nullptr}; @@ -338,7 +336,7 @@ struct copy_intersecting_nbrs_and_update_intersection_size_t { auto pair = *(vertex_pair_first + i); vertex_t const* indices0{nullptr}; - [[maybe_unused]] thrust::optional weights0{thrust::nullopt}; + [[maybe_unused]] edge_t local_edge_offset0{0}; edge_t local_degree0{0}; if constexpr (std::is_same_v) { vertex_t major = thrust::get<0>(pair); @@ -348,16 +346,16 @@ struct copy_intersecting_nbrs_and_update_intersection_size_t { auto major_hypersparse_idx = edge_partition.major_hypersparse_idx_from_major_nocheck(major); if (major_hypersparse_idx) { - thrust::tie(indices0, weights0, local_degree0) = edge_partition.local_edges( + thrust::tie(indices0, local_edge_offset0, local_degree0) = edge_partition.local_edges( (*(edge_partition.major_hypersparse_first()) - edge_partition.major_range_first()) + *major_hypersparse_idx); } } else { - thrust::tie(indices0, weights0, local_degree0) = + thrust::tie(indices0, local_edge_offset0, local_degree0) = edge_partition.local_edges(edge_partition.major_offset_from_major_nocheck(major)); } } else { - thrust::tie(indices0, weights0, local_degree0) = + thrust::tie(indices0, local_edge_offset0, local_degree0) = edge_partition.local_edges(edge_partition.major_offset_from_major_nocheck(major)); } } else { @@ -368,7 +366,7 @@ struct copy_intersecting_nbrs_and_update_intersection_size_t { } vertex_t const* indices1{nullptr}; - [[maybe_unused]] thrust::optional weights1{thrust::nullopt}; + [[maybe_unused]] edge_t local_edge_offset1{0}; edge_t local_degree1{0}; if constexpr (std::is_same_v) { vertex_t major = thrust::get<1>(pair); @@ -378,16 +376,16 @@ struct copy_intersecting_nbrs_and_update_intersection_size_t { auto major_hypersparse_idx = edge_partition.major_hypersparse_idx_from_major_nocheck(major); if (major_hypersparse_idx) { - thrust::tie(indices1, weights1, local_degree1) = edge_partition.local_edges( + thrust::tie(indices1, local_edge_offset1, local_degree1) = edge_partition.local_edges( (*(edge_partition.major_hypersparse_first()) - edge_partition.major_range_first()) + *major_hypersparse_idx); } } else { - thrust::tie(indices1, weights1, local_degree1) = + thrust::tie(indices1, local_edge_offset1, local_degree1) = edge_partition.local_edges(edge_partition.major_offset_from_major_nocheck(major)); } } else { - thrust::tie(indices1, weights1, local_degree1) = + thrust::tie(indices1, local_edge_offset1, local_degree1) = edge_partition.local_edges(edge_partition.major_offset_from_major_nocheck(major)); } } else { @@ -558,7 +556,6 @@ nbr_intersection(raft::handle_t const& handle, { using vertex_t = typename GraphViewType::vertex_type; using edge_t = typename GraphViewType::edge_type; - using weight_t = typename GraphViewType::weight_type; static_assert(std::is_same_v::value_type, thrust::tuple>); @@ -742,7 +739,7 @@ nbr_intersection(raft::handle_t const& handle, local_degrees_for_rx_majors.resize(rx_majors.size(), handle.get_stream()); for (size_t i = 0; i < graph_view.number_of_local_edge_partitions(); ++i) { auto edge_partition = - edge_partition_device_view_t( + edge_partition_device_view_t( graph_view.local_edge_partition_view(i)); auto segment_offsets = graph_view.local_edge_partition_segment_offsets(i); auto reordered_idx_first = @@ -752,7 +749,7 @@ nbr_intersection(raft::handle_t const& handle, handle.get_thrust_policy(), thrust::make_counting_iterator(reordered_idx_first), thrust::make_counting_iterator(reordered_idx_last), - update_rx_major_local_degree_t{ + update_rx_major_local_degree_t{ row_comm_size, col_comm_size, edge_partition, @@ -778,7 +775,7 @@ nbr_intersection(raft::handle_t const& handle, local_nbr_offsets_for_rx_majors.back_element(handle.get_stream()), handle.get_stream()); for (size_t i = 0; i < graph_view.number_of_local_edge_partitions(); ++i) { auto edge_partition = - edge_partition_device_view_t( + edge_partition_device_view_t( graph_view.local_edge_partition_view(i)); auto segment_offsets = graph_view.local_edge_partition_segment_offsets(i); auto reordered_idx_first = @@ -789,7 +786,7 @@ nbr_intersection(raft::handle_t const& handle, handle.get_thrust_policy(), thrust::make_counting_iterator(reordered_idx_first), thrust::make_counting_iterator(reordered_idx_last), - update_rx_major_local_nbrs_t{ + update_rx_major_local_nbrs_t{ row_comm_size, col_comm_size, edge_partition, @@ -945,7 +942,7 @@ nbr_intersection(raft::handle_t const& handle, handle.get_stream()); auto edge_partition = - edge_partition_device_view_t( + edge_partition_device_view_t( graph_view.local_edge_partition_view(i)); auto segment_offsets = graph_view.local_edge_partition_segment_offsets(i); @@ -956,20 +953,17 @@ nbr_intersection(raft::handle_t const& handle, if (intersect_minor_nbr[0] && intersect_minor_nbr[1]) { auto second_element_to_idx_map = detail::kv_cuco_store_device_view_t((*major_to_idx_map_ptr)->view()); - thrust::transform(handle.get_thrust_policy(), - get_dataframe_buffer_begin(vertex_pair_buffer), - get_dataframe_buffer_end(vertex_pair_buffer), - rx_v_pair_nbr_intersection_sizes.begin(), - pick_min_degree_t{nullptr, - nullptr, - second_element_to_idx_map, - (*major_nbr_offsets).data(), - edge_partition}); + thrust::transform( + handle.get_thrust_policy(), + get_dataframe_buffer_begin(vertex_pair_buffer), + get_dataframe_buffer_end(vertex_pair_buffer), + rx_v_pair_nbr_intersection_sizes.begin(), + pick_min_degree_t{ + nullptr, + nullptr, + second_element_to_idx_map, + (*major_nbr_offsets).data(), + edge_partition}); } else { CUGRAPH_FAIL("unimplemented."); } @@ -998,7 +992,6 @@ nbr_intersection(raft::handle_t const& handle, decltype(get_dataframe_buffer_begin(vertex_pair_buffer)), vertex_t, edge_t, - weight_t, true>{nullptr, nullptr, nullptr, @@ -1217,7 +1210,7 @@ nbr_intersection(raft::handle_t const& handle, nbr_intersection_offsets.begin() + 1); } else { auto edge_partition = - edge_partition_device_view_t( + edge_partition_device_view_t( graph_view.local_edge_partition_view(size_t{0})); rmm::device_uvector nbr_intersection_sizes( @@ -1228,7 +1221,7 @@ nbr_intersection(raft::handle_t const& handle, vertex_pair_first, vertex_pair_first + input_size, nbr_intersection_sizes.begin(), - pick_min_degree_t{ + pick_min_degree_t{ nullptr, nullptr, nullptr, nullptr, edge_partition}); } else { CUGRAPH_FAIL("unimplemented."); @@ -1255,7 +1248,6 @@ nbr_intersection(raft::handle_t const& handle, decltype(vertex_pair_first), vertex_t, edge_t, - weight_t, false>{ nullptr, nullptr, diff --git a/cpp/src/prims/extract_if_e.cuh b/cpp/src/prims/extract_if_e.cuh index bddbf44fc39..fb0ea337397 100644 --- a/cpp/src/prims/extract_if_e.cuh +++ b/cpp/src/prims/extract_if_e.cuh @@ -20,6 +20,7 @@ #include #include +#include #include #include #include @@ -50,7 +51,6 @@ template edge_partition{}; EdgePartitionSrcValueInputWrapper edge_partition_src_value_input{}; @@ -60,15 +60,13 @@ struct call_e_op_t { template __device__ bool operator()(Edge e) const { - static_assert((thrust::tuple_size::value == 2) || (thrust::tuple_size::value == 3)); + static_assert(thrust::tuple_size::value == 2); using vertex_t = typename GraphViewType::vertex_type; - using weight_t = typename GraphViewType::weight_type; + using edge_t = typename GraphViewType::edge_type; - auto major = thrust::get<0>(e); - auto minor = thrust::get<1>(e); - weight_t weight{1.0}; - if constexpr (thrust::tuple_size::value == 3) { weight = thrust::get<2>(e); } + auto major = thrust::get<0>(e); + auto minor = thrust::get<1>(e); auto major_offset = edge_partition.major_offset_from_major_nocheck(major); auto minor_offset = edge_partition.minor_offset_from_minor_nocheck(minor); auto src = GraphViewType::is_storage_transposed ? minor : major; @@ -79,18 +77,21 @@ struct call_e_op_t { vertex_t, EdgePartitionSrcValueInputWrapper, EdgePartitionDstValueInputWrapper, + edge_partition_edge_dummy_property_device_view_t, EdgeOp>() .compute(src, dst, - weight, edge_partition_src_value_input.get(src_offset), edge_partition_dst_value_input.get(dst_offset), + thrust::nullopt, e_op); } }; } // namespace detail +// FIXME: better rename this primitive to extract_transform_e and update to return a vector of @p +// e_op outputs (matching extract_transform_v_frontier_outgoing_e). /** * @brief Iterate over the entire set of edges and return an edge list with the edges with @p * edge_op evaluated to be true. @@ -129,8 +130,7 @@ template std::tuple, - rmm::device_uvector, - std::optional>> + rmm::device_uvector> extract_if_e(raft::handle_t const& handle, GraphViewType const& graph_view, EdgeSrcValueInputWrapper edge_src_value_input, @@ -140,7 +140,7 @@ extract_if_e(raft::handle_t const& handle, { using vertex_t = typename GraphViewType::vertex_type; using edge_t = typename GraphViewType::edge_type; - using weight_t = typename GraphViewType::weight_type; + using weight_t = float; // dummy using edge_partition_src_input_device_view_t = std::conditional_t< std::is_same_v, @@ -177,15 +177,11 @@ extract_if_e(raft::handle_t const& handle, rmm::device_uvector edgelist_majors(number_of_local_edges, handle.get_stream()); rmm::device_uvector edgelist_minors(edgelist_majors.size(), handle.get_stream()); - auto edgelist_weights = graph_view.is_weighted() - ? std::make_optional>( - edgelist_majors.size(), handle.get_stream()) - : std::nullopt; size_t cur_size{0}; for (size_t i = 0; i < edgelist_edge_counts.size(); ++i) { auto edge_partition = - edge_partition_device_view_t( + edge_partition_device_view_t( graph_view.local_edge_partition_view(i)); edge_partition_src_input_device_view_t edge_partition_src_value_input{}; @@ -200,60 +196,40 @@ extract_if_e(raft::handle_t const& handle, edge_partition_dst_value_input = edge_partition_dst_input_device_view_t(edge_dst_value_input); } - detail::decompress_edge_partition_to_edgelist( + detail::decompress_edge_partition_to_edgelist( handle, edge_partition, + std::nullopt, edgelist_majors.data() + cur_size, edgelist_minors.data() + cur_size, - edgelist_weights ? std::optional{(*edgelist_weights).data() + cur_size} - : std::nullopt, + std::nullopt, graph_view.local_edge_partition_segment_offsets(i)); - if (edgelist_weights) { - auto edge_first = thrust::make_zip_iterator(thrust::make_tuple( - edgelist_majors.begin(), edgelist_minors.begin(), (*edgelist_weights).begin())); - cur_size += static_cast(thrust::distance( + auto edge_first = thrust::make_zip_iterator( + thrust::make_tuple(edgelist_majors.begin(), edgelist_minors.begin())); + cur_size += static_cast(thrust::distance( + edge_first + cur_size, + thrust::remove_if( + handle.get_thrust_policy(), edge_first + cur_size, - thrust::remove_if(handle.get_thrust_policy(), - edge_first + cur_size, - edge_first + cur_size + edgelist_edge_counts[i], - detail::call_e_op_t{edge_partition, - edge_partition_src_value_input, - edge_partition_dst_value_input, - e_op}))); - } else { - auto edge_first = thrust::make_zip_iterator( - thrust::make_tuple(edgelist_majors.begin(), edgelist_minors.begin())); - cur_size += static_cast(thrust::distance( - edge_first + cur_size, - thrust::remove_if(handle.get_thrust_policy(), - edge_first + cur_size, - edge_first + cur_size + edgelist_edge_counts[i], - detail::call_e_op_t{edge_partition, - edge_partition_src_value_input, - edge_partition_dst_value_input, - e_op}))); - } + edge_first + cur_size + edgelist_edge_counts[i], + detail::call_e_op_t{ + edge_partition, edge_partition_src_value_input, edge_partition_dst_value_input, e_op}))); } edgelist_majors.resize(cur_size, handle.get_stream()); edgelist_minors.resize(edgelist_majors.size(), handle.get_stream()); edgelist_majors.shrink_to_fit(handle.get_stream()); edgelist_minors.shrink_to_fit(handle.get_stream()); - if (edgelist_weights) { - (*edgelist_weights).resize(edgelist_majors.size(), handle.get_stream()); - (*edgelist_weights).shrink_to_fit(handle.get_stream()); - } return std::make_tuple( std::move(GraphViewType::is_storage_transposed ? edgelist_minors : edgelist_majors), - std::move(GraphViewType::is_storage_transposed ? edgelist_majors : edgelist_minors), - std::move(edgelist_weights)); + std::move(GraphViewType::is_storage_transposed ? edgelist_majors : edgelist_minors)); } } // namespace cugraph diff --git a/cpp/src/prims/extract_transform_v_frontier_outgoing_e.cuh b/cpp/src/prims/extract_transform_v_frontier_outgoing_e.cuh index 15373e2b2d5..11c6d5ae8c5 100644 --- a/cpp/src/prims/extract_transform_v_frontier_outgoing_e.cuh +++ b/cpp/src/prims/extract_transform_v_frontier_outgoing_e.cuh @@ -37,6 +37,7 @@ namespace cugraph { * @tparam GraphViewType Type of the passed non-owning graph object. * @tparam EdgeSrcValueInputWrapper Type of the wrapper for edge source property values. * @tparam EdgeDstValueInputWrapper Type of the wrapper for edge destination property values. + * @tparam EdgeValueInputWrapper Type of the wrapper for edge property values. * @tparam EdgeOp Type of the quaternary (or quinary) edge operator. * @param handle RAFT handle object to encapsulate resources (e.g. CUDA stream, communicator, and * handles to various CUDA libraries) to run graph algorithms. @@ -51,6 +52,10 @@ namespace cugraph { * cugraph::edge_dst_property_t::view() (if @p e_op needs to access destination property values) or * cugraph::edge_dst_dummy_property_t::view() (if @p e_op does not access destination property * values). Use update_edge_dst_property to fill the wrapper. + * @param edge_value_input Wrapper used to access edge input property values (for the edges assigned + * to this process in multi-GPU). Use either cugraph::edge_property_t::view() (if @p e_op needs to + * access edge property values) or cugraph::edge_dummy_property_t::view() (if @p e_op does not + * access edge property values). * @param e_op Quaternary (or quinary) operator takes edge source, edge destination, (optional edge * weight), property values for the source, and property values for the destination and returns a * thrust::nullopt (if the return value is to be discarded) or a valid @p e_op output to be @@ -62,12 +67,14 @@ template decltype( allocate_dataframe_buffer::result_type::value_type>( size_t{0}, rmm::cuda_stream_view{})) extract_transform_v_frontier_outgoing_e(raft::handle_t const& handle, @@ -75,6 +82,7 @@ extract_transform_v_frontier_outgoing_e(raft::handle_t const& handle, VertexFrontierBucketType const& frontier, EdgeSrcValueInputWrapper edge_src_value_input, EdgeDstValueInputWrapper edge_dst_value_input, + EdgeValueInputWrapper edge_value_input, EdgeOp e_op, bool do_expensive_check = false) { @@ -84,6 +92,7 @@ extract_transform_v_frontier_outgoing_e(raft::handle_t const& handle, typename VertexFrontierBucketType::key_type, EdgeSrcValueInputWrapper, EdgeDstValueInputWrapper, + EdgeValueInputWrapper, EdgeOp>::result_type; static_assert(!std::is_same_v); using payload_t = typename e_op_result_t::value_type; @@ -95,6 +104,7 @@ extract_transform_v_frontier_outgoing_e(raft::handle_t const& handle, frontier, edge_src_value_input, edge_dst_value_input, + edge_value_input, e_op, do_expensive_check); diff --git a/cpp/src/prims/per_v_pair_transform_dst_nbr_intersection.cuh b/cpp/src/prims/per_v_pair_transform_dst_nbr_intersection.cuh index 389b2c95d55..6f4d02c389c 100644 --- a/cpp/src/prims/per_v_pair_transform_dst_nbr_intersection.cuh +++ b/cpp/src/prims/per_v_pair_transform_dst_nbr_intersection.cuh @@ -103,7 +103,6 @@ template edge_partition{}; thrust::optional> unique_vertices; @@ -208,7 +207,6 @@ void per_v_pair_transform_dst_nbr_intersection( using vertex_t = typename GraphViewType::vertex_type; using edge_t = typename GraphViewType::edge_type; - using weight_t = typename GraphViewType::weight_type; using property_t = typename thrust::iterator_traits::value_type; using result_t = typename thrust::iterator_traits::value_type; @@ -297,7 +295,7 @@ void per_v_pair_transform_dst_nbr_intersection( for (size_t i = 0; i < graph_view.number_of_local_edge_partitions(); ++i) { auto edge_partition = - edge_partition_device_view_t( + edge_partition_device_view_t( graph_view.local_edge_partition_view(i)); auto edge_partition_vertex_pair_index_first = diff --git a/cpp/src/prims/per_v_random_select_transform_outgoing_e.cuh b/cpp/src/prims/per_v_random_select_transform_outgoing_e.cuh index 8a081bfbfad..cd69a9f4a91 100644 --- a/cpp/src/prims/per_v_random_select_transform_outgoing_e.cuh +++ b/cpp/src/prims/per_v_random_select_transform_outgoing_e.cuh @@ -18,6 +18,7 @@ #include #include +#include #include #include #include @@ -97,16 +98,15 @@ template struct transform_and_count_local_nbr_indices_t { using key_t = typename thrust::iterator_traits::value_type; using vertex_t = typename GraphViewType::vertex_type; using edge_t = typename GraphViewType::edge_type; - using weight_t = typename GraphViewType::weight_type; - edge_partition_device_view_t - edge_partition{}; + edge_partition_device_view_t edge_partition{}; UniqueKeyIdxIterator unique_key_idx_first{}; KeyIterator key_first{}; OffsetIterator offset_first{}; @@ -115,6 +115,7 @@ struct transform_and_count_local_nbr_indices_t { thrust::optional output_count_first{}; EdgePartitionSrcValueInputWrapper edge_partition_src_value_input; EdgePartitionDstValueInputWrapper edge_partition_dst_value_input; + EdgePartitionEdgeValueInputWrapper edge_partition_e_value_input; EdgeOp e_op{}; edge_t invalid_idx{}; thrust::optional invalid_value{thrust::nullopt}; @@ -131,22 +132,22 @@ struct transform_and_count_local_nbr_indices_t { } auto major_offset = edge_partition.major_offset_from_major_nocheck(major); vertex_t const* indices{nullptr}; - thrust::optional weights{thrust::nullopt}; + edge_t edge_offset{0}; [[maybe_unused]] edge_t local_degree{0}; if constexpr (GraphViewType::is_multi_gpu) { auto major_hypersparse_first = edge_partition.major_hypersparse_first(); if (major_hypersparse_first && (major >= *major_hypersparse_first)) { auto major_hypersparse_idx = edge_partition.major_hypersparse_idx_from_major_nocheck(major); if (major_hypersparse_idx) { - thrust::tie(indices, weights, local_degree) = edge_partition.local_edges( + thrust::tie(indices, edge_offset, local_degree) = edge_partition.local_edges( edge_partition.major_offset_from_major_nocheck(*major_hypersparse_first) + *major_hypersparse_idx); } } else { - thrust::tie(indices, weights, local_degree) = edge_partition.local_edges(major_offset); + thrust::tie(indices, edge_offset, local_degree) = edge_partition.local_edges(major_offset); } } else { - thrust::tie(indices, weights, local_degree) = edge_partition.local_edges(major_offset); + thrust::tie(indices, edge_offset, local_degree) = edge_partition.local_edges(major_offset); } auto start_offset = *(offset_first + i); auto end_offset = *(offset_first + (i + 1)); @@ -172,17 +173,19 @@ struct transform_and_count_local_nbr_indices_t { } auto src_offset = GraphViewType::is_storage_transposed ? minor_offset : major_offset; auto dst_offset = GraphViewType::is_storage_transposed ? major_offset : minor_offset; - *(output_value_first + i) = evaluate_edge_op() - .compute(key_or_src, - key_or_dst, - weights ? (*weights)[local_nbr_idx] : weight_t{1.0}, - edge_partition_src_value_input.get(src_offset), - edge_partition_dst_value_input.get(dst_offset), - e_op); + *(output_value_first + i) = + evaluate_edge_op() + .compute(key_or_src, + key_or_dst, + edge_partition_src_value_input.get(src_offset), + edge_partition_dst_value_input.get(dst_offset), + edge_partition_e_value_input.get(edge_offset + local_nbr_idx), + e_op); ++num_valid_local_nbr_indices; } else if (invalid_value) { *(output_value_first + i) = *invalid_value; @@ -220,6 +223,7 @@ template std::tuple>, @@ -229,10 +233,7 @@ per_v_random_select_transform_e(raft::handle_t const& handle, VertexFrontierBucketType const& frontier, EdgeSrcValueInputWrapper edge_src_value_input, EdgeDstValueInputWrapper edge_dst_value_input, -#if 0 // FIXME: This will be necessary to include edge IDs in the output. - // Primitives API should be updated to support this in a consistent way. - EdgeValueInputWrapper egde_value_input, -#endif + EdgeValueInputWrapper edge_value_input, EdgeOp e_op, raft::random::RngState& rng_state, size_t K, @@ -243,7 +244,6 @@ per_v_random_select_transform_e(raft::handle_t const& handle, #ifndef NO_CUGRAPH_OPS using vertex_t = typename GraphViewType::vertex_type; using edge_t = typename GraphViewType::edge_type; - using weight_t = typename GraphViewType::weight_type; using key_t = typename VertexFrontierBucketType::key_type; using key_buffer_t = decltype(allocate_dataframe_buffer(size_t{0}, rmm::cuda_stream_view{})); @@ -268,12 +268,19 @@ per_v_random_select_transform_e(raft::handle_t const& handle, edge_partition_endpoint_property_device_view_t< vertex_t, typename EdgeDstValueInputWrapper::value_iterator>>>; + using edge_partition_e_input_device_view_t = std::conditional_t< + std::is_same_v, + detail::edge_partition_edge_dummy_property_device_view_t, + detail::edge_partition_edge_property_device_view_t< + edge_t, + typename EdgeValueInputWrapper::value_iterator>>; static_assert(GraphViewType::is_storage_transposed == incoming); static_assert(std::is_same_v::result_type, T>); @@ -353,7 +360,7 @@ per_v_random_select_transform_e(raft::handle_t const& handle, rmm::device_uvector frontier_degrees(frontier.size(), handle.get_stream()); for (size_t i = 0; i < graph_view.number_of_local_edge_partitions(); ++i) { auto edge_partition = - edge_partition_device_view_t( + edge_partition_device_view_t( graph_view.local_edge_partition_view(i)); vertex_t const* edge_partition_frontier_major_first{nullptr}; @@ -515,7 +522,7 @@ per_v_random_select_transform_e(raft::handle_t const& handle, handle.get_stream()); for (size_t i = 0; i < graph_view.number_of_local_edge_partitions(); ++i) { auto edge_partition = - edge_partition_device_view_t( + edge_partition_device_view_t( graph_view.local_edge_partition_view(i)); auto edge_partition_frontier_key_first = @@ -539,6 +546,7 @@ per_v_random_select_transform_e(raft::handle_t const& handle, edge_partition_src_input_device_view_t(edge_src_value_input, i); edge_partition_dst_value_input = edge_partition_dst_input_device_view_t(edge_dst_value_input); } + auto edge_partition_e_value_input = edge_partition_e_input_device_view_t(edge_value_input, i); if constexpr (GraphViewType::is_multi_gpu) { thrust::sort_by_key(handle.get_thrust_policy(), @@ -584,6 +592,7 @@ per_v_random_select_transform_e(raft::handle_t const& handle, size_t*, edge_partition_src_input_device_view_t, edge_partition_dst_input_device_view_t, + edge_partition_e_input_device_view_t, EdgeOp, T>{edge_partition, unique_key_indices.begin(), @@ -594,6 +603,7 @@ per_v_random_select_transform_e(raft::handle_t const& handle, thrust::nullopt, edge_partition_src_value_input, edge_partition_dst_value_input, + edge_partition_e_value_input, e_op, cugraph::ops::gnn::graph::INVALID_ID, to_thrust_optional(invalid_value)}); @@ -614,6 +624,7 @@ per_v_random_select_transform_e(raft::handle_t const& handle, size_t*, edge_partition_src_input_device_view_t, edge_partition_dst_input_device_view_t, + edge_partition_e_input_device_view_t, EdgeOp, T>{edge_partition, thrust::make_counting_iterator(size_t{0}), @@ -624,6 +635,7 @@ per_v_random_select_transform_e(raft::handle_t const& handle, sample_counts ? thrust::optional((*sample_counts).data()) : thrust::nullopt, edge_partition_src_value_input, edge_partition_dst_value_input, + edge_partition_e_value_input, e_op, cugraph::ops::gnn::graph::INVALID_ID, to_thrust_optional(invalid_value)}); @@ -729,6 +741,7 @@ per_v_random_select_transform_e(raft::handle_t const& handle, * current (tagged-)vertex frontier. * @tparam EdgeSrcValueInputWrapper Type of the wrapper for edge source property values. * @tparam EdgeDstValueInputWrapper Type of the wrapper for edge destination property values. + * @tparam EdgeValueInputWrapper Type of the wrapper for edge property values. * @tparam EdgeBiasOp Type of the quaternary (or quinary) edge operator to set-up selection bias * values. * @tparam EdgeOp Type of the quaternary (or quinary) edge operator. @@ -748,12 +761,16 @@ per_v_random_select_transform_e(raft::handle_t const& handle, * cugraph::edge_dst_property_t::view() (if @p e_op needs to access destination property values) or * cugraph::edge_dst_dummy_property_t::view() (if @p e_op does not access destination property * values). Use update_edge_dst_property to fill the wrapper. - * @param e_bias_op Quaternary (or quinary) operator takes edge source, edge destination, (optional - * edge weight), property values for the source, and property values for the destination and returns - * a graph weight type bias value to be used in biased random selection. - * @param e_op Quaternary (or quinary) operator takes edge source, edge destination, (optional edge - * weight), property values for the source, and property values for the destination and returns a - * value to be collected in the output. This function is called only for the selected edges. + * @param edge_value_input Wrapper used to access edge input property values (for the edges assigned + * to this process in multi-GPU). Use either cugraph::edge_property_t::view() (if @p e_op needs to + * access edge property values) or cugraph::edge_dummy_property_t::view() (if @p e_op does not + * access edge property values). + * @param e_bias_op Quinary operator takes edge source, edge destination, property values for the + * source, destination, and edge and returns a floating point bias value to be used in biased random + * selection. + * @param e_op Quinary operator takes edge source, edge destination, property values for the source, + * destination, and edge and returns a value to be collected in the output. This function is called + * only for the selected edges. * @param K Number of outgoing edges to select per (tagged-)vertex. * @param with_replacement A flag to specify whether a single outgoing edge can be selected multiple * times (if @p with_replacement = true) or can be selected only once (if @p with_replacement = @@ -774,6 +791,7 @@ template @@ -784,10 +802,7 @@ per_v_random_select_transform_outgoing_e(raft::handle_t const& handle, VertexFrontierBucketType const& frontier, EdgeSrcValueInputWrapper edge_src_value_input, EdgeDstValueInputWrapper edge_dst_value_input, -#if 0 // FIXME: This will be necessary to include edge IDs in the output. - // Primitives API should be updated to support this in a consistent way. - EdgeValueInputWrapper egde_value_input, -#endif + EdgeValueInputWrapper egde_value_input, EdgeBiasOp e_bias_op, EdgeOp e_op, raft::random::RngState& rng_state, @@ -813,6 +828,7 @@ per_v_random_select_transform_outgoing_e(raft::handle_t const& handle, * current (tagged-)vertex frontier. * @tparam EdgeSrcValueInputWrapper Type of the wrapper for edge source property values. * @tparam EdgeDstValueInputWrapper Type of the wrapper for edge destination property values. + * @tparam EdgeValueInputWrapper Type of the wrapper for edge property values. * @tparam EdgeOp Type of the quaternary (or quinary) edge operator. * @tparam T Type of the selected and transformed edge output values. * @param handle RAFT handle object to encapsulate resources (e.g. CUDA stream, communicator, and @@ -830,9 +846,13 @@ per_v_random_select_transform_outgoing_e(raft::handle_t const& handle, * cugraph::edge_dst_property_t::view() (if @p e_op needs to access destination property values) or * cugraph::edge_dst_dummy_property_t::view() (if @p e_op does not access destination property * values). Use update_edge_dst_property to fill the wrapper. - * @param e_op Quaternary (or quinary) operator takes edge source, edge destination, (optional edge - * weight), property values for the source, and property values for the destination and returns a - * value to be collected in the output. This function is called only for the selected edges. + * @param edge_value_input Wrapper used to access edge input property values (for the edges assigned + * to this process in multi-GPU). Use either cugraph::edge_property_t::view() (if @p e_op needs to + * access edge property values) or cugraph::edge_dummy_property_t::view() (if @p e_op does not + * access edge property values). + * @param e_op Quinary operator takes edge source, edge destination, property values for the source, + * destination, and edge and returns a value to be collected in the output. This function is called + * only for the selected edges. * @param K Number of outgoing edges to select per (tagged-)vertex. * @param with_replacement A flag to specify whether a single outgoing edge can be selected multiple * times (if @p with_replacement = true) or can be selected only once (if @p with_replacement = @@ -853,6 +873,7 @@ template std::tuple>, @@ -862,10 +883,7 @@ per_v_random_select_transform_outgoing_e(raft::handle_t const& handle, VertexFrontierBucketType const& frontier, EdgeSrcValueInputWrapper edge_src_value_input, EdgeDstValueInputWrapper edge_dst_value_input, -#if 0 // FIXME: This will be necessary to include edge IDs in the output. - // Primitives API should be updated to support this in a consistent way. - EdgeValueInputWrapper egde_value_input, -#endif + EdgeValueInputWrapper edge_value_input, EdgeOp e_op, raft::random::RngState& rng_state, size_t K, @@ -878,6 +896,7 @@ per_v_random_select_transform_outgoing_e(raft::handle_t const& handle, frontier, edge_src_value_input, edge_dst_value_input, + edge_value_input, e_op, rng_state, K, diff --git a/cpp/src/prims/per_v_transform_reduce_dst_key_aggregated_outgoing_e.cuh b/cpp/src/prims/per_v_transform_reduce_dst_key_aggregated_outgoing_e.cuh index 947ce1233da..54f7fb4cf8c 100644 --- a/cpp/src/prims/per_v_transform_reduce_dst_key_aggregated_outgoing_e.cuh +++ b/cpp/src/prims/per_v_transform_reduce_dst_key_aggregated_outgoing_e.cuh @@ -80,12 +80,12 @@ struct rebase_offset_t { }; // a workaround for cudaErrorInvalidDeviceFunction error when device lambda is used -template +template struct triplet_to_col_rank_t { compute_gpu_id_from_ext_vertex_t key_func{}; int row_comm_size{}; __device__ int operator()( - thrust::tuple val /* major, minor key, weight */) const + thrust::tuple val /* major, minor key, edge value */) const { return key_func(thrust::get<1>(val)) / row_comm_size; } @@ -102,7 +102,7 @@ struct pair_to_binary_partition_id_t { // a workaround for cudaErrorInvalidDeviceFunction error when device lambda is used template val /* major, minor key, weight */) const + __device__ auto operator()(thrust::tuple + val /* major, minor key, aggregated edge value */) const { - auto major = thrust::get<0>(val); - auto key = thrust::get<1>(val); - auto w = thrust::get<2>(val); + auto major = thrust::get<0>(val); + auto key = thrust::get<1>(val); + auto aggregated_edge_value = thrust::get<2>(val); return key_aggregated_e_op( major, key, - w, edge_partition_src_value_input.get(edge_partition.major_offset_from_major_nocheck(major)), - kv_store_device_view.find(key)); + kv_store_device_view.find(key), + aggregated_edge_value); } }; @@ -175,6 +175,7 @@ struct reduce_with_init_t { * * @tparam GraphViewType Type of the passed non-owning graph object. * @tparam EdgeSrcValueInputWrapper Type of the wrapper for edge source property values. + * @tparam EdgeValueInputWrapper Type of the wrapper for edge property values. * @tparam EdgeDstKeyInputWrapper Type of the wrapper for edge destination key values. * @tparam VertexIterator Type of the iterator for keys in (key, value) pairs (key type should * coincide with vertex type). @@ -191,6 +192,10 @@ struct reduce_with_init_t { * (if @p e_op needs to access source property values) or cugraph::edge_src_dummy_property_t::view() * (if @p e_op does not access source property values). Use update_edge_src_property to fill the * wrapper. + * @param edge_value_input Wrapper used to access edge input property values (for the edges assigned + * to this process in multi-GPU). Use either cugraph::edge_property_t::view() (if @p e_op needs to + * access edge property values) or cugraph::edge_dummy_property_t::view() (if @p e_op does not + * access edge property values). * @param edge_dst_key_input Wrapper used to access destination input key values (for the edge * destinations assigned to this process in multi-GPU). Use cugraph::edge_dst_property_t::view(). * Use update_edge_dst_property to fill the wrapper. @@ -203,10 +208,10 @@ struct reduce_with_init_t { * @param map_value_first Iterator pointing to the first (inclusive) value in (key, value) pairs * (assigned to this process in multi-GPU). `map_value_last` (exclusive) is deduced as @p * map_value_first + thrust::distance(@p map_unique_key_first, @p map_unique_key_last). - * @param key_aggregated_e_op Quinary operator takes edge source, key, aggregated edge weight, *(@p - * edge_partition_src_value_input_first + i), and value for the key stored in the input (key, value) + * @param key_aggregated_e_op Quinary operator takes 1) edge source, 2) key, 3) *(@p + * edge_partition_src_value_input_first + i), 4) value for the key stored in the input (key, value) * pairs provided by @p map_unique_key_first, @p map_unique_key_last, and @p map_value_first - * (aggregated over the entire set of processes in multi-GPU). + * (aggregated over the entire set of processes in multi-GPU), and 5) aggregated edge value. * @param init Initial value to be reduced with the reduced value for each vertex. * @param reduce_op Binary operator that takes two input arguments and reduce the two values to one. * There are pre-defined reduction operators in src/prims/reduce_op.cuh. It is @@ -222,6 +227,7 @@ struct reduce_with_init_t { */ template ); static_assert(is_arithmetic_or_thrust_tuple_of_arithmetic::value); - using vertex_t = typename GraphViewType::vertex_type; - using edge_t = typename GraphViewType::edge_type; - using weight_t = typename GraphViewType::weight_type; - using value_t = typename KVStoreViewType::value_type; + using vertex_t = typename GraphViewType::vertex_type; + using edge_t = typename GraphViewType::edge_type; + using edge_value_t = typename EdgeValueInputWrapper::value_type; + using kv_pair_value_t = typename KVStoreViewType::value_type; + static_assert( + std::is_arithmetic_v, + "Currently only scalar values are supported, should be extended to support thrust::tuple of " + "arithmetic types and void (for dummy property values) to be consistent with other " + "primitives."); // this will also require a custom edge value aggregation op. using edge_partition_src_input_device_view_t = std::conditional_t< std::is_same_v, @@ -269,12 +281,26 @@ void per_v_transform_reduce_dst_key_aggregated_outgoing_e( detail::edge_partition_endpoint_property_device_view_t< vertex_t, typename EdgeDstKeyInputWrapper::value_iterator>>; + using edge_partition_e_input_device_view_t = std::conditional_t< + std::is_same_v, + detail::edge_partition_edge_dummy_property_device_view_t, + detail::edge_partition_edge_property_device_view_t< + edge_t, + typename EdgeValueInputWrapper::value_iterator>>; if (do_expensive_check) { /* currently, nothing to do */ } auto total_global_mem = handle.get_device_properties().totalGlobalMem; - auto element_size = sizeof(vertex_t) * 2 + sizeof(weight_t); + size_t element_size = sizeof(vertex_t) * 2; + if constexpr (!std::is_same_v) { + static_assert(is_arithmetic_or_thrust_tuple_of_arithmetic::value); + if constexpr (is_thrust_tuple_of_arithmetic::value) { + element_size += sum_thrust_tuple_element_sizes(); + } else { + element_size += sizeof(edge_value_t); + } + } auto constexpr mem_frugal_ratio = 0.1; // if the expected temporary buffer size exceeds the mem_frugal_ratio of the // total_global_mem, switch to the memory frugal approach @@ -287,13 +313,18 @@ void per_v_transform_reduce_dst_key_aggregated_outgoing_e( auto e_op_result_buffer = allocate_dataframe_buffer(0, handle.get_stream()); for (size_t i = 0; i < graph_view.number_of_local_edge_partitions(); ++i) { auto edge_partition = - edge_partition_device_view_t( + edge_partition_device_view_t( graph_view.local_edge_partition_view(i)); + auto edge_partition_src_value_input = + edge_partition_src_input_device_view_t(edge_src_value_input, i); + auto edge_partition_e_value_input = edge_partition_e_input_device_view_t(edge_value_input, i); + rmm::device_uvector tmp_majors(edge_partition.number_of_edges(), handle.get_stream()); rmm::device_uvector tmp_minor_keys(tmp_majors.size(), handle.get_stream()); - rmm::device_uvector tmp_key_aggregated_edge_weights(tmp_majors.size(), - handle.get_stream()); + // FIXME: this doesn't work if edge_value_t is thrust::tuple or void + rmm::device_uvector tmp_key_aggregated_edge_values(tmp_majors.size(), + handle.get_stream()); if (edge_partition.number_of_edges() > 0) { auto segment_offsets = graph_view.local_edge_partition_segment_offsets(i); @@ -329,8 +360,9 @@ void per_v_transform_reduce_dst_key_aggregated_outgoing_e( rmm::device_uvector unreduced_majors(max_chunk_size, handle.get_stream()); rmm::device_uvector unreduced_minor_keys(unreduced_majors.size(), handle.get_stream()); - rmm::device_uvector unreduced_key_aggregated_edge_weights( - graph_view.is_weighted() ? unreduced_majors.size() : size_t{0}, handle.get_stream()); + // FIXME: this doesn't work if edge_value_t is thrust::tuple or void + rmm::device_uvector unreduced_key_aggregated_edge_values( + unreduced_majors.size(), handle.get_stream()); rmm::device_uvector d_tmp_storage(0, handle.get_stream()); size_t reduced_size{0}; @@ -344,18 +376,19 @@ void per_v_transform_reduce_dst_key_aggregated_outgoing_e( auto offset_first = thrust::make_transform_iterator(edge_partition.offsets() + h_vertex_offsets[j], detail::rebase_offset_t{h_edge_offsets[j]}); - if (graph_view.is_weighted()) { - cub::DeviceSegmentedSort::SortPairs(static_cast(nullptr), - tmp_storage_bytes, - tmp_minor_keys.begin() + h_edge_offsets[j], - unreduced_minor_keys.begin(), - *(edge_partition.weights()) + h_edge_offsets[j], - unreduced_key_aggregated_edge_weights.begin(), - h_edge_offsets[j + 1] - h_edge_offsets[j], - h_vertex_offsets[j + 1] - h_vertex_offsets[j], - offset_first, - offset_first + 1, - handle.get_stream()); + if constexpr (!std::is_same_v) { + cub::DeviceSegmentedSort::SortPairs( + static_cast(nullptr), + tmp_storage_bytes, + tmp_minor_keys.begin() + h_edge_offsets[j], + unreduced_minor_keys.begin(), + edge_partition_e_value_input.value_first() + h_edge_offsets[j], + unreduced_key_aggregated_edge_values.begin(), + h_edge_offsets[j + 1] - h_edge_offsets[j], + h_vertex_offsets[j + 1] - h_vertex_offsets[j], + offset_first, + offset_first + 1, + handle.get_stream()); } else { cub::DeviceSegmentedSort::SortKeys(static_cast(nullptr), tmp_storage_bytes, @@ -370,18 +403,19 @@ void per_v_transform_reduce_dst_key_aggregated_outgoing_e( if (tmp_storage_bytes > d_tmp_storage.size()) { d_tmp_storage = rmm::device_uvector(tmp_storage_bytes, handle.get_stream()); } - if (graph_view.is_weighted()) { - cub::DeviceSegmentedSort::SortPairs(d_tmp_storage.data(), - tmp_storage_bytes, - tmp_minor_keys.begin() + h_edge_offsets[j], - unreduced_minor_keys.begin(), - *(edge_partition.weights()) + h_edge_offsets[j], - unreduced_key_aggregated_edge_weights.begin(), - h_edge_offsets[j + 1] - h_edge_offsets[j], - h_vertex_offsets[j + 1] - h_vertex_offsets[j], - offset_first, - offset_first + 1, - handle.get_stream()); + if constexpr (!std::is_same_v) { + cub::DeviceSegmentedSort::SortPairs( + d_tmp_storage.data(), + tmp_storage_bytes, + tmp_minor_keys.begin() + h_edge_offsets[j], + unreduced_minor_keys.begin(), + edge_partition_e_value_input.value_first() + h_edge_offsets[j], + unreduced_key_aggregated_edge_values.begin(), + h_edge_offsets[j + 1] - h_edge_offsets[j], + h_vertex_offsets[j + 1] - h_vertex_offsets[j], + offset_first, + offset_first + 1, + handle.get_stream()); } else { cub::DeviceSegmentedSort::SortKeys(d_tmp_storage.data(), tmp_storage_bytes, @@ -402,35 +436,35 @@ void per_v_transform_reduce_dst_key_aggregated_outgoing_e( thrust::make_tuple(unreduced_majors.begin(), unreduced_minor_keys.begin())); auto output_key_first = thrust::make_zip_iterator(thrust::make_tuple(tmp_majors.begin(), tmp_minor_keys.begin())); - if (graph_view.is_weighted()) { + if constexpr (!std::is_same_v) { reduced_size += thrust::distance(output_key_first + reduced_size, thrust::get<0>(thrust::reduce_by_key( handle.get_thrust_policy(), input_key_first, input_key_first + (h_edge_offsets[j + 1] - h_edge_offsets[j]), - unreduced_key_aggregated_edge_weights.begin(), + unreduced_key_aggregated_edge_values.begin(), output_key_first + reduced_size, - tmp_key_aggregated_edge_weights.begin() + reduced_size))); + tmp_key_aggregated_edge_values.begin() + reduced_size))); } else { reduced_size += thrust::distance(output_key_first + reduced_size, - thrust::get<0>(thrust::reduce_by_key( + thrust::get<0>(thrust::unique( handle.get_thrust_policy(), input_key_first, input_key_first + (h_edge_offsets[j + 1] - h_edge_offsets[j]), - thrust::make_constant_iterator(weight_t{1.0}), - output_key_first + reduced_size, - tmp_key_aggregated_edge_weights.begin() + reduced_size))); + output_key_first + reduced_size))); } } tmp_majors.resize(reduced_size, handle.get_stream()); tmp_minor_keys.resize(tmp_majors.size(), handle.get_stream()); - tmp_key_aggregated_edge_weights.resize(tmp_majors.size(), handle.get_stream()); + // FIXME: this doesn't work if edge_value_t is thrust::tuple or void + tmp_key_aggregated_edge_values.resize(tmp_majors.size(), handle.get_stream()); } - tmp_minor_keys.shrink_to_fit(handle.get_stream()); - tmp_key_aggregated_edge_weights.shrink_to_fit(handle.get_stream()); tmp_majors.shrink_to_fit(handle.get_stream()); + tmp_minor_keys.shrink_to_fit(handle.get_stream()); + // FIXME: this doesn't work if edge_value_t is thrust::tuple or void + tmp_key_aggregated_edge_values.shrink_to_fit(handle.get_stream()); if constexpr (GraphViewType::is_multi_gpu) { auto& comm = handle.get_comms(); @@ -440,12 +474,13 @@ void per_v_transform_reduce_dst_key_aggregated_outgoing_e( auto& col_comm = handle.get_subcomm(cugraph::partition_2d::key_naming_t().col_name()); auto const col_comm_size = col_comm.get_size(); + // FIXME: this doesn't work if edge_value_t is thrust::tuple or void auto triplet_first = thrust::make_zip_iterator(thrust::make_tuple( - tmp_majors.begin(), tmp_minor_keys.begin(), tmp_key_aggregated_edge_weights.begin())); + tmp_majors.begin(), tmp_minor_keys.begin(), tmp_key_aggregated_edge_values.begin())); auto d_tx_value_counts = cugraph::groupby_and_count( triplet_first, triplet_first + tmp_majors.size(), - detail::triplet_to_col_rank_t{ + detail::triplet_to_col_rank_t{ detail::compute_gpu_id_from_ext_vertex_t{comm_size}, row_comm_size}, col_comm_size, mem_frugal_threshold, @@ -460,7 +495,7 @@ void per_v_transform_reduce_dst_key_aggregated_outgoing_e( rmm::device_uvector rx_majors(0, handle.get_stream()); rmm::device_uvector rx_minor_keys(0, handle.get_stream()); - rmm::device_uvector rx_key_aggregated_edge_weights(0, handle.get_stream()); + rmm::device_uvector rx_key_aggregated_edge_values(0, handle.get_stream()); auto mem_frugal_flag = host_scalar_allreduce(col_comm, tmp_majors.size() > mem_frugal_threshold ? int{1} : int{0}, @@ -477,23 +512,20 @@ void per_v_transform_reduce_dst_key_aggregated_outgoing_e( tmp_minor_keys.resize(0, handle.get_stream()); tmp_minor_keys.shrink_to_fit(handle.get_stream()); - std::tie(rx_key_aggregated_edge_weights, std::ignore) = - shuffle_values(col_comm, - tmp_key_aggregated_edge_weights.begin(), - h_tx_value_counts, - handle.get_stream()); - tmp_key_aggregated_edge_weights.resize(0, handle.get_stream()); - tmp_key_aggregated_edge_weights.shrink_to_fit(handle.get_stream()); + std::tie(rx_key_aggregated_edge_values, std::ignore) = shuffle_values( + col_comm, tmp_key_aggregated_edge_values.begin(), h_tx_value_counts, handle.get_stream()); + tmp_key_aggregated_edge_values.resize(0, handle.get_stream()); + tmp_key_aggregated_edge_values.shrink_to_fit(handle.get_stream()); } else { - std::forward_as_tuple(std::tie(rx_majors, rx_minor_keys, rx_key_aggregated_edge_weights), + std::forward_as_tuple(std::tie(rx_majors, rx_minor_keys, rx_key_aggregated_edge_values), std::ignore) = shuffle_values(col_comm, triplet_first, h_tx_value_counts, handle.get_stream()); tmp_majors.resize(0, handle.get_stream()); tmp_majors.shrink_to_fit(handle.get_stream()); tmp_minor_keys.resize(0, handle.get_stream()); tmp_minor_keys.shrink_to_fit(handle.get_stream()); - tmp_key_aggregated_edge_weights.resize(0, handle.get_stream()); - tmp_key_aggregated_edge_weights.shrink_to_fit(handle.get_stream()); + tmp_key_aggregated_edge_values.resize(0, handle.get_stream()); + tmp_key_aggregated_edge_values.shrink_to_fit(handle.get_stream()); } auto key_pair_first = @@ -502,7 +534,7 @@ void per_v_transform_reduce_dst_key_aggregated_outgoing_e( auto second_first = detail::mem_frugal_partition(key_pair_first, key_pair_first + rx_majors.size(), - rx_key_aggregated_edge_weights.begin(), + rx_key_aggregated_edge_values.begin(), detail::pair_to_binary_partition_id_t{}, int{1}, handle.get_stream()); @@ -510,7 +542,7 @@ void per_v_transform_reduce_dst_key_aggregated_outgoing_e( thrust::sort_by_key(handle.get_thrust_policy(), key_pair_first, std::get<0>(second_first), - rx_key_aggregated_edge_weights.begin()); + rx_key_aggregated_edge_values.begin()); thrust::sort_by_key(handle.get_thrust_policy(), std::get<0>(second_first), @@ -520,7 +552,7 @@ void per_v_transform_reduce_dst_key_aggregated_outgoing_e( thrust::sort_by_key(handle.get_thrust_policy(), key_pair_first, key_pair_first + rx_majors.size(), - rx_key_aggregated_edge_weights.begin()); + rx_key_aggregated_edge_values.begin()); } auto num_uniques = thrust::count_if(handle.get_thrust_policy(), @@ -529,17 +561,17 @@ void per_v_transform_reduce_dst_key_aggregated_outgoing_e( detail::is_first_in_run_t{key_pair_first}); tmp_majors.resize(num_uniques, handle.get_stream()); tmp_minor_keys.resize(tmp_majors.size(), handle.get_stream()); - tmp_key_aggregated_edge_weights.resize(tmp_majors.size(), handle.get_stream()); + tmp_key_aggregated_edge_values.resize(tmp_majors.size(), handle.get_stream()); thrust::reduce_by_key( handle.get_thrust_policy(), key_pair_first, key_pair_first + rx_majors.size(), - rx_key_aggregated_edge_weights.begin(), + rx_key_aggregated_edge_values.begin(), thrust::make_zip_iterator(thrust::make_tuple(tmp_majors.begin(), tmp_minor_keys.begin())), - tmp_key_aggregated_edge_weights.begin()); + tmp_key_aggregated_edge_values.begin()); } - std::unique_ptr> + std::unique_ptr> multi_gpu_kv_map_ptr{nullptr}; if constexpr (GraphViewType::is_multi_gpu) { auto& comm = handle.get_comms(); @@ -557,7 +589,8 @@ void per_v_transform_reduce_dst_key_aggregated_outgoing_e( handle.get_stream()); unique_minor_keys.shrink_to_fit(handle.get_stream()); - auto values_for_unique_keys = allocate_dataframe_buffer(0, handle.get_stream()); + auto values_for_unique_keys = + allocate_dataframe_buffer(0, handle.get_stream()); std::tie(unique_minor_keys, values_for_unique_keys) = collect_values_for_unique_keys( comm, kv_store_view, @@ -566,14 +599,14 @@ void per_v_transform_reduce_dst_key_aggregated_outgoing_e( handle.get_stream()); if constexpr (KVStoreViewType::binary_search) { - multi_gpu_kv_map_ptr = - std::make_unique>(std::move(unique_minor_keys), - std::move(values_for_unique_keys), - kv_store_view.invalid_value, - false, - handle.get_stream()); + multi_gpu_kv_map_ptr = std::make_unique>( + std::move(unique_minor_keys), + std::move(values_for_unique_keys), + kv_store_view.invalid_value, + false, + handle.get_stream()); } else { - multi_gpu_kv_map_ptr = std::make_unique>( + multi_gpu_kv_map_ptr = std::make_unique>( unique_minor_keys.begin(), unique_minor_keys.begin() + unique_minor_keys.size(), get_dataframe_buffer_begin(values_for_unique_keys), @@ -586,11 +619,8 @@ void per_v_transform_reduce_dst_key_aggregated_outgoing_e( auto tmp_e_op_result_buffer = allocate_dataframe_buffer(tmp_majors.size(), handle.get_stream()); - auto edge_partition_src_value_input = - edge_partition_src_input_device_view_t(edge_src_value_input, i); - auto triplet_first = thrust::make_zip_iterator(thrust::make_tuple( - tmp_majors.begin(), tmp_minor_keys.begin(), tmp_key_aggregated_edge_weights.begin())); + tmp_majors.begin(), tmp_minor_keys.begin(), tmp_key_aggregated_edge_values.begin())); std::conditional_t, detail::kv_cuco_store_device_view_t> @@ -601,7 +631,7 @@ void per_v_transform_reduce_dst_key_aggregated_outgoing_e( triplet_first + tmp_majors.size(), get_dataframe_buffer_begin(tmp_e_op_result_buffer), detail::call_key_aggregated_e_op_t #include +#include #include #include #include @@ -74,6 +75,7 @@ template edge_partition, EdgePartitionSrcValueInputWrapper edge_partition_src_value_input, EdgePartitionDstValueInputWrapper edge_partition_dst_value_input, + EdgePartitionEdgeValueInputWrapper edge_partition_e_value_input, ResultValueOutputIteratorOrWrapper result_value_output, EdgeOp e_op, T init /* relevent only if update_major == true */) { using vertex_t = typename GraphViewType::vertex_type; using edge_t = typename GraphViewType::edge_type; - using weight_t = typename GraphViewType::weight_type; auto const tid = threadIdx.x + blockIdx.x * blockDim.x; auto major_start_offset = static_cast(*(edge_partition.major_hypersparse_first()) - @@ -110,20 +111,20 @@ __global__ void per_v_transform_reduce_e_hypersparse( auto major_idx = major_start_offset + idx; // major_offset != major_idx in the hypersparse region vertex_t const* indices{nullptr}; - thrust::optional weights{thrust::nullopt}; + edge_t edge_offset{}; edge_t local_degree{}; - thrust::tie(indices, weights, local_degree) = + thrust::tie(indices, edge_offset, local_degree) = edge_partition.local_edges(static_cast(major_idx)); auto transform_op = [&edge_partition, &edge_partition_src_value_input, &edge_partition_dst_value_input, + &edge_partition_e_value_input, &e_op, major, indices, - weights] __device__(auto i) { + edge_offset] __device__(auto i) { auto major_offset = edge_partition.major_offset_from_major_nocheck(major); auto minor = indices[i]; - auto weight = weights ? (*weights)[i] : weight_t{1.0}; auto minor_offset = edge_partition.minor_offset_from_minor_nocheck(minor); auto src = GraphViewType::is_storage_transposed ? minor : major; auto dst = GraphViewType::is_storage_transposed ? major : minor; @@ -133,12 +134,13 @@ __global__ void per_v_transform_reduce_e_hypersparse( vertex_t, EdgePartitionSrcValueInputWrapper, EdgePartitionDstValueInputWrapper, + EdgePartitionEdgeValueInputWrapper, EdgeOp>() .compute(src, dst, - weight, edge_partition_src_value_input.get(src_offset), edge_partition_dst_value_input.get(dst_offset), + edge_partition_e_value_input.get(edge_offset + i), e_op); }; @@ -184,6 +186,7 @@ template edge_partition, typename GraphViewType::vertex_type major_range_first, typename GraphViewType::vertex_type major_range_last, EdgePartitionSrcValueInputWrapper edge_partition_src_value_input, EdgePartitionDstValueInputWrapper edge_partition_dst_value_input, + EdgePartitionEdgeValueInputWrapper edge_partition_e_value_input, ResultValueOutputIteratorOrWrapper result_value_output, EdgeOp e_op, T init /* relevent only if update_major == true */) { using vertex_t = typename GraphViewType::vertex_type; using edge_t = typename GraphViewType::edge_type; - using weight_t = typename GraphViewType::weight_type; auto const tid = threadIdx.x + blockIdx.x * blockDim.x; auto major_start_offset = @@ -217,19 +219,19 @@ __global__ void per_v_transform_reduce_e_low_degree( while (idx < static_cast(major_range_last - major_range_first)) { auto major_offset = major_start_offset + idx; vertex_t const* indices{nullptr}; - thrust::optional weights{thrust::nullopt}; + edge_t edge_offset{}; edge_t local_degree{}; - thrust::tie(indices, weights, local_degree) = + thrust::tie(indices, edge_offset, local_degree) = edge_partition.local_edges(static_cast(major_offset)); auto transform_op = [&edge_partition, &edge_partition_src_value_input, &edge_partition_dst_value_input, + &edge_partition_e_value_input, &e_op, major_offset, indices, - weights] __device__(auto i) { + edge_offset] __device__(auto i) { auto minor = indices[i]; - auto weight = weights ? (*weights)[i] : weight_t{1.0}; auto minor_offset = edge_partition.minor_offset_from_minor_nocheck(minor); auto src = GraphViewType::is_storage_transposed ? minor @@ -245,12 +247,13 @@ __global__ void per_v_transform_reduce_e_low_degree( vertex_t, EdgePartitionSrcValueInputWrapper, EdgePartitionDstValueInputWrapper, + EdgePartitionEdgeValueInputWrapper, EdgeOp>() .compute(src, dst, - weight, edge_partition_src_value_input.get(src_offset), edge_partition_dst_value_input.get(dst_offset), + edge_partition_e_value_input.get(edge_offset + i), e_op); }; @@ -296,6 +299,7 @@ template edge_partition, typename GraphViewType::vertex_type major_range_first, typename GraphViewType::vertex_type major_range_last, EdgePartitionSrcValueInputWrapper edge_partition_src_value_input, EdgePartitionDstValueInputWrapper edge_partition_dst_value_input, + EdgePartitionEdgeValueInputWrapper edge_partition_e_value_input, ResultValueOutputIteratorOrWrapper result_value_output, EdgeOp e_op, T init /* relevent only if update_major == true */) { using vertex_t = typename GraphViewType::vertex_type; using edge_t = typename GraphViewType::edge_type; - using weight_t = typename GraphViewType::weight_type; using e_op_result_t = T; auto const tid = threadIdx.x + blockIdx.x * blockDim.x; @@ -337,14 +340,13 @@ __global__ void per_v_transform_reduce_e_mid_degree( while (idx < static_cast(major_range_last - major_range_first)) { auto major_offset = major_start_offset + idx; vertex_t const* indices{nullptr}; - thrust::optional weights{thrust::nullopt}; + edge_t edge_offset{}; edge_t local_degree{}; - thrust::tie(indices, weights, local_degree) = edge_partition.local_edges(major_offset); + thrust::tie(indices, edge_offset, local_degree) = edge_partition.local_edges(major_offset); [[maybe_unused]] auto e_op_result_sum = lane_id == 0 ? init : e_op_result_t{}; // relevent only if update_major == true for (edge_t i = lane_id; i < local_degree; i += raft::warp_size()) { auto minor = indices[i]; - auto weight = weights ? (*weights)[i] : weight_t{1.0}; auto minor_offset = edge_partition.minor_offset_from_minor_nocheck(minor); auto src = GraphViewType::is_storage_transposed ? minor @@ -360,12 +362,13 @@ __global__ void per_v_transform_reduce_e_mid_degree( vertex_t, EdgePartitionSrcValueInputWrapper, EdgePartitionDstValueInputWrapper, + EdgePartitionEdgeValueInputWrapper, EdgeOp>() .compute(src, dst, - weight, edge_partition_src_value_input.get(src_offset), edge_partition_dst_value_input.get(dst_offset), + edge_partition_e_value_input.get(edge_offset + i), e_op); if constexpr (update_major) { e_op_result_sum = edge_property_add(e_op_result_sum, e_op_result); @@ -391,6 +394,7 @@ template edge_partition, typename GraphViewType::vertex_type major_range_first, typename GraphViewType::vertex_type major_range_last, EdgePartitionSrcValueInputWrapper edge_partition_src_value_input, EdgePartitionDstValueInputWrapper edge_partition_dst_value_input, + EdgePartitionEdgeValueInputWrapper edge_partition_e_value_input, ResultValueOutputIteratorOrWrapper result_value_output, EdgeOp e_op, T init /* relevent only if update_major == true */) { using vertex_t = typename GraphViewType::vertex_type; using edge_t = typename GraphViewType::edge_type; - using weight_t = typename GraphViewType::weight_type; using e_op_result_t = T; auto major_start_offset = @@ -428,14 +431,13 @@ __global__ void per_v_transform_reduce_e_high_degree( while (idx < static_cast(major_range_last - major_range_first)) { auto major_offset = major_start_offset + idx; vertex_t const* indices{nullptr}; - thrust::optional weights{thrust::nullopt}; + edge_t edge_offset{}; edge_t local_degree{}; - thrust::tie(indices, weights, local_degree) = edge_partition.local_edges(major_offset); + thrust::tie(indices, edge_offset, local_degree) = edge_partition.local_edges(major_offset); [[maybe_unused]] auto e_op_result_sum = threadIdx.x == 0 ? init : e_op_result_t{}; // relevent only if update_major == true for (edge_t i = threadIdx.x; i < local_degree; i += blockDim.x) { auto minor = indices[i]; - auto weight = weights ? (*weights)[i] : weight_t{1.0}; auto minor_offset = edge_partition.minor_offset_from_minor_nocheck(minor); auto src = GraphViewType::is_storage_transposed ? minor @@ -451,12 +453,13 @@ __global__ void per_v_transform_reduce_e_high_degree( vertex_t, EdgePartitionSrcValueInputWrapper, EdgePartitionDstValueInputWrapper, + EdgePartitionEdgeValueInputWrapper, EdgeOp>() .compute(src, dst, - weight, edge_partition_src_value_input.get(src_offset), edge_partition_dst_value_input.get(dst_offset), + edge_partition_e_value_input.get(edge_offset + i), e_op); if constexpr (update_major) { e_op_result_sum = edge_property_add(e_op_result_sum, e_op_result); @@ -482,6 +485,7 @@ template @@ -489,6 +493,7 @@ void per_v_transform_reduce_e(raft::handle_t const& handle, GraphViewType const& graph_view, EdgeSrcValueInputWrapper edge_src_value_input, EdgeDstValueInputWrapper edge_dst_value_input, + EdgeValueInputWrapper edge_value_input, EdgeOp e_op, T init, VertexValueOutputIterator vertex_value_output_first) @@ -498,7 +503,6 @@ void per_v_transform_reduce_e(raft::handle_t const& handle, detail::num_sparse_segments_per_vertex_partition + size_t{1}; using vertex_t = typename GraphViewType::vertex_type; using edge_t = typename GraphViewType::edge_type; - using weight_t = typename GraphViewType::weight_type; using edge_partition_src_input_device_view_t = std::conditional_t< std::is_same_v, @@ -520,6 +524,12 @@ void per_v_transform_reduce_e(raft::handle_t const& handle, detail::edge_partition_endpoint_property_device_view_t< vertex_t, typename EdgeDstValueInputWrapper::value_iterator>>>; + using edge_partition_e_input_device_view_t = std::conditional_t< + std::is_same_v, + detail::edge_partition_edge_dummy_property_device_view_t, + detail::edge_partition_edge_property_device_view_t< + edge_t, + typename EdgeValueInputWrapper::value_iterator>>; static_assert(is_arithmetic_or_thrust_tuple_of_arithmetic::value); @@ -666,7 +676,7 @@ void per_v_transform_reduce_e(raft::handle_t const& handle, for (size_t i = 0; i < graph_view.number_of_local_edge_partitions(); ++i) { auto edge_partition = - edge_partition_device_view_t( + edge_partition_device_view_t( graph_view.local_edge_partition_view(i)); auto major_init = T{}; @@ -691,6 +701,7 @@ void per_v_transform_reduce_e(raft::handle_t const& handle, edge_partition_src_input_device_view_t(edge_src_value_input, i); edge_partition_dst_value_input = edge_partition_dst_input_device_view_t(edge_dst_value_input); } + auto edge_partition_e_value_input = edge_partition_e_input_device_view_t(edge_value_input, i); auto major_buffer_first = get_dataframe_buffer_begin(major_tmp_buffers[i % major_tmp_buffers.size()]); @@ -743,6 +754,7 @@ void per_v_transform_reduce_e(raft::handle_t const& handle, edge_partition, edge_partition_src_value_input, edge_partition_dst_value_input, + edge_partition_e_value_input, segment_output_buffer, e_op, major_init); @@ -765,6 +777,7 @@ void per_v_transform_reduce_e(raft::handle_t const& handle, edge_partition.major_range_first() + (*segment_offsets)[3], edge_partition_src_value_input, edge_partition_dst_value_input, + edge_partition_e_value_input, segment_output_buffer, e_op, major_init); @@ -786,6 +799,7 @@ void per_v_transform_reduce_e(raft::handle_t const& handle, edge_partition.major_range_first() + (*segment_offsets)[2], edge_partition_src_value_input, edge_partition_dst_value_input, + edge_partition_e_value_input, segment_output_buffer, e_op, major_init); @@ -805,6 +819,7 @@ void per_v_transform_reduce_e(raft::handle_t const& handle, edge_partition.major_range_first() + (*segment_offsets)[1], edge_partition_src_value_input, edge_partition_dst_value_input, + edge_partition_e_value_input, output_buffer, e_op, major_init); @@ -821,6 +836,7 @@ void per_v_transform_reduce_e(raft::handle_t const& handle, edge_partition.major_range_last(), edge_partition_src_value_input, edge_partition_dst_value_input, + edge_partition_e_value_input, output_buffer, e_op, major_init); @@ -1046,6 +1062,7 @@ void per_v_transform_reduce_e(raft::handle_t const& handle, * @tparam GraphViewType Type of the passed non-owning graph object. * @tparam EdgeSrcValueInputWrapper Type of the wrapper for edge source property values. * @tparam EdgeDstValueInputWrapper Type of the wrapper for edge destination property values. + * @tparam EdgeValueInputWrapper Type of the wrapper for edge property values. * @tparam EdgeOp Type of the quaternary (or quinary) edge operator. * @tparam T Type of the initial value for per-vertex reduction. * @tparam VertexValueOutputIterator Type of the iterator for vertex output property variables. @@ -1062,9 +1079,12 @@ void per_v_transform_reduce_e(raft::handle_t const& handle, * cugraph::edge_dst_property_t::view() (if @p e_op needs to access destination property values) or * cugraph::edge_dst_dummy_property_t::view() (if @p e_op does not access destination property * values). Use update_edge_dst_property to fill the wrapper. - * @param e_op Quaternary (or quinary) operator takes edge source, edge destination, (optional edge - * weight), property values for the source, and property values for the destination and returns a - * value to be reduced. + * @param edge_value_input Wrapper used to access edge input property values (for the edges assigned + * to this process in multi-GPU). Use either cugraph::edge_property_t::view() (if @p e_op needs to + * access edge property values) or cugraph::edge_dummy_property_t::view() (if @p e_op does not + * access edge property values). + * @param e_op Quinary operator takes edge source, edge destination, property values for the source, + * destination, and edge and returns a value to be reduced. * @param init Initial value to be added to the reduced @p e_op return values for each vertex. * @param vertex_value_output_first Iterator pointing to the vertex property variables for the first * (inclusive) vertex (assigned to this process in multi-GPU). `vertex_value_output_last` @@ -1075,6 +1095,7 @@ void per_v_transform_reduce_e(raft::handle_t const& handle, template @@ -1082,6 +1103,7 @@ void per_v_transform_reduce_incoming_e(raft::handle_t const& handle, GraphViewType const& graph_view, EdgeSrcValueInputWrapper edge_src_value_input, EdgeDstValueInputWrapper edge_dst_value_input, + EdgeValueInputWrapper edge_value_input, EdgeOp e_op, T init, VertexValueOutputIterator vertex_value_output_first, @@ -1095,6 +1117,7 @@ void per_v_transform_reduce_incoming_e(raft::handle_t const& handle, graph_view, edge_src_value_input, edge_dst_value_input, + edge_value_input, e_op, init, vertex_value_output_first); @@ -1108,6 +1131,7 @@ void per_v_transform_reduce_incoming_e(raft::handle_t const& handle, * @tparam GraphViewType Type of the passed non-owning graph object. * @tparam EdgeSrcValueInputWrapper Type of the wrapper for edge source property values. * @tparam EdgeDstValueInputWrapper Type of the wrapper for edge destination property values. + * @tparam EdgeValueInputWrapper Type of the wrapper for edge property values. * @tparam EdgeOp Type of the quaternary (or quinary) edge operator. * @tparam T Type of the initial value for per-vertex reduction. * @tparam VertexValueOutputIterator Type of the iterator for vertex output property variables. @@ -1124,9 +1148,12 @@ void per_v_transform_reduce_incoming_e(raft::handle_t const& handle, * cugraph::edge_dst_property_t::view() (if @p e_op needs to access destination property values) or * cugraph::edge_dst_dummy_property_t::view() (if @p e_op does not access destination property * values). Use update_edge_dst_property to fill the wrapper. - * @param e_op Quaternary (or quinary) operator takes edge source, edge destination, (optional edge - * weight), property values for the source, and property values for the destination and returns a - * value to be reduced. + * @param edge_value_input Wrapper used to access edge input property values (for the edges assigned + * to this process in multi-GPU). Use either cugraph::edge_property_t::view() (if @p e_op needs to + * access edge property values) or cugraph::edge_dummy_property_t::view() (if @p e_op does not + * access edge property values). + * @param e_op Quinary operator takes edge source, edge destination, property values for the source, + * destination, and edge and returns a value to be reduced. * @param init Initial value to be added to the reduced @p e_op return values for each vertex. * @param vertex_value_output_first Iterator pointing to the vertex property variables for the * first (inclusive) vertex (assigned to this process in multi-GPU). `vertex_value_output_last` @@ -1137,6 +1164,7 @@ void per_v_transform_reduce_incoming_e(raft::handle_t const& handle, template @@ -1144,6 +1172,7 @@ void per_v_transform_reduce_outgoing_e(raft::handle_t const& handle, GraphViewType const& graph_view, EdgeSrcValueInputWrapper edge_src_value_input, EdgeDstValueInputWrapper edge_dst_value_input, + EdgeValueInputWrapper edge_value_input, EdgeOp e_op, T init, VertexValueOutputIterator vertex_value_output_first, @@ -1157,6 +1186,7 @@ void per_v_transform_reduce_outgoing_e(raft::handle_t const& handle, graph_view, edge_src_value_input, edge_dst_value_input, + edge_value_input, e_op, init, vertex_value_output_first); diff --git a/cpp/src/prims/property_op_utils.cuh b/cpp/src/prims/property_op_utils.cuh index 43f504dba2e..fb1e88456de 100644 --- a/cpp/src/prims/property_op_utils.cuh +++ b/cpp/src/prims/property_op_utils.cuh @@ -40,47 +40,30 @@ namespace detail { template struct edge_op_result_type; template struct edge_op_result_type< key_t, vertex_t, - weight_t, src_value_t, dst_value_t, + e_value_t, EdgeOp, std::enable_if_t< - std::is_invocable_v>> { + std::is_invocable_v>> { using type = - typename std::invoke_result::type; -}; - -template -struct edge_op_result_type< - key_t, - vertex_t, - weight_t, - src_value_t, - dst_value_t, - EdgeOp, - std::enable_if_t>> { - using type = typename std::invoke_result::type; + typename std::invoke_result::type; }; template struct evaluate_edge_op { using vertex_type = typename GraphViewType::vertex_type; - using weight_type = typename GraphViewType::weight_type; using src_value_type = typename EdgePartitionSrcValueInputWrapper::value_type; using dst_value_type = typename EdgePartitionDstValueInputWrapper::value_type; + using e_value_type = typename EdgePartitionEdgeValueInputWrapper::value_type; using result_type = typename detail:: - edge_op_result_type:: + edge_op_result_type:: type; template - __device__ std::enable_if_t, - typename std::invoke_result::type> - compute(K s, V d, W w, SV sv, DV dv, E e) const + __device__ std::enable_if_t, + typename std::invoke_result::type> + compute(K s, V d, SV sv, DV dv, EV ev, E e) const { - return e(s, d, w, sv, dv); - } - - template - __device__ std::enable_if_t, - typename std::invoke_result::type> - compute(K s, V d, W w, SV sv, DV dv, E e) const - { - return e(s, d, sv, dv); + return e(s, d, sv, dv, ev); } }; @@ -189,7 +160,6 @@ template struct evaluate_intersection_op { using vertex_type = typename GraphViewType::vertex_type; - using weight_type = typename GraphViewType::weight_type; using result_type = typename detail:: intersection_op_result_type::type; @@ -210,40 +180,28 @@ template struct cast_edge_op_bool_to_integer { static_assert(std::is_integral::value); using vertex_type = typename GraphViewType::vertex_type; - using weight_type = typename GraphViewType::weight_type; using src_value_type = typename EdgePartitionSrcValueInputWrapper::value_type; using dst_value_type = typename EdgePartitionDstValueInputWrapper::value_type; + using e_value_type = typename EdgePartitionEdgeValueInputWrapper::value_type; EdgeOp e_op{}; - template - __device__ std::enable_if_t, T> operator()( - K s, V d, W w, SV sv, DV dv) const - { - return e_op(s, d, w, sv, dv) ? T{1} : T{0}; - } - template - __device__ std::enable_if_t, T> operator()(K s, - V d, - SV sv, - DV dv) const + __device__ std::enable_if_t, T> operator()( + K s, V d, SV sv, DV dv, EV ev) const { - return e_op(s, d, sv, dv) ? T{1} : T{0}; + return e_op(s, d, sv, dv, ev) ? T{1} : T{0}; } }; diff --git a/cpp/src/prims/transform_reduce_dst_nbr_intersection_of_e_endpoints_by_v.cuh b/cpp/src/prims/transform_reduce_dst_nbr_intersection_of_e_endpoints_by_v.cuh index 5267bf58488..88c6259ab56 100644 --- a/cpp/src/prims/transform_reduce_dst_nbr_intersection_of_e_endpoints_by_v.cuh +++ b/cpp/src/prims/transform_reduce_dst_nbr_intersection_of_e_endpoints_by_v.cuh @@ -69,7 +69,6 @@ template edge_partition{}; EdgePartitionSrcValueInputWrapper edge_partition_src_value_input{}; @@ -243,7 +242,7 @@ void transform_reduce_dst_nbr_intersection_of_e_endpoints_by_v( using vertex_t = typename GraphViewType::vertex_type; using edge_t = typename GraphViewType::edge_type; - using weight_t = typename GraphViewType::weight_type; + using weight_t = float; // dummy using edge_partition_src_input_device_view_t = std::conditional_t< std::is_same_v, @@ -277,7 +276,7 @@ void transform_reduce_dst_nbr_intersection_of_e_endpoints_by_v( for (size_t i = 0; i < graph_view.number_of_local_edge_partitions(); ++i) { auto edge_partition = - edge_partition_device_view_t( + edge_partition_device_view_t( graph_view.local_edge_partition_view(i)); edge_partition_src_input_device_view_t edge_partition_src_value_input{}; @@ -299,8 +298,13 @@ void transform_reduce_dst_nbr_intersection_of_e_endpoints_by_v( detail::decompress_edge_partition_to_edgelist( - handle, edge_partition, majors.data(), minors.data(), std::nullopt, segment_offsets); + GraphViewType::is_multi_gpu>(handle, + edge_partition, + std::nullopt, + majors.data(), + minors.data(), + std::nullopt, + segment_offsets); auto vertex_pair_first = thrust::make_zip_iterator(thrust::make_tuple(majors.begin(), minors.begin())); diff --git a/cpp/src/prims/transform_reduce_e.cuh b/cpp/src/prims/transform_reduce_e.cuh index 5fae5f35105..6e4c98b2986 100644 --- a/cpp/src/prims/transform_reduce_e.cuh +++ b/cpp/src/prims/transform_reduce_e.cuh @@ -18,6 +18,7 @@ #include #include +#include #include #include #include @@ -53,21 +54,21 @@ int32_t constexpr transform_reduce_e_kernel_block_size = 128; template __global__ void trasnform_reduce_e_hypersparse( edge_partition_device_view_t edge_partition, EdgePartitionSrcValueInputWrapper edge_partition_src_value_input, EdgePartitionDstValueInputWrapper edge_partition_dst_value_input, + EdgePartitionEdgeValueInputWrapper edge_partition_e_value_input, ResultIterator result_iter /* size 1 */, EdgeOp e_op) { using vertex_t = typename GraphViewType::vertex_type; using edge_t = typename GraphViewType::edge_type; - using weight_t = typename GraphViewType::weight_type; using e_op_result_t = typename std::iterator_traits::value_type; auto const tid = threadIdx.x + blockIdx.x * blockDim.x; @@ -88,23 +89,23 @@ __global__ void trasnform_reduce_e_hypersparse( auto major_idx = major_start_offset + idx; // major_offset != major_idx in the hypersparse region vertex_t const* indices{nullptr}; - thrust::optional weights{thrust::nullopt}; + edge_t edge_offset{}; edge_t local_degree{}; - thrust::tie(indices, weights, local_degree) = edge_partition.local_edges(major_idx); - auto sum = thrust::transform_reduce( + thrust::tie(indices, edge_offset, local_degree) = edge_partition.local_edges(major_idx); + auto sum = thrust::transform_reduce( thrust::seq, thrust::make_counting_iterator(edge_t{0}), thrust::make_counting_iterator(local_degree), [&edge_partition, &edge_partition_src_value_input, &edge_partition_dst_value_input, + &edge_partition_e_value_input, &e_op, major, indices, - weights] __device__(auto i) { + edge_offset] __device__(auto i) { auto major_offset = edge_partition.major_offset_from_major_nocheck(major); auto minor = indices[i]; - auto weight = weights ? (*weights)[i] : weight_t{1.0}; auto minor_offset = edge_partition.minor_offset_from_minor_nocheck(minor); auto src = GraphViewType::is_storage_transposed ? minor : major; auto dst = GraphViewType::is_storage_transposed ? major : minor; @@ -116,12 +117,13 @@ __global__ void trasnform_reduce_e_hypersparse( vertex_t, EdgePartitionSrcValueInputWrapper, EdgePartitionDstValueInputWrapper, + EdgePartitionEdgeValueInputWrapper, EdgeOp>() .compute(src, dst, - weight, edge_partition_src_value_input.get(src_offset), edge_partition_dst_value_input.get(dst_offset), + edge_partition_e_value_input.get(edge_offset + i), e_op); }, e_op_result_t{}, @@ -138,23 +140,23 @@ __global__ void trasnform_reduce_e_hypersparse( template __global__ void trasnform_reduce_e_low_degree( edge_partition_device_view_t edge_partition, typename GraphViewType::vertex_type major_range_first, typename GraphViewType::vertex_type major_range_last, EdgePartitionSrcValueInputWrapper edge_partition_src_value_input, EdgePartitionDstValueInputWrapper edge_partition_dst_value_input, + EdgePartitionEdgeValueInputWrapper edge_partition_e_value_input, ResultIterator result_iter /* size 1 */, EdgeOp e_op) { using vertex_t = typename GraphViewType::vertex_type; using edge_t = typename GraphViewType::edge_type; - using weight_t = typename GraphViewType::weight_type; using e_op_result_t = typename std::iterator_traits::value_type; auto const tid = threadIdx.x + blockIdx.x * blockDim.x; @@ -170,29 +172,29 @@ __global__ void trasnform_reduce_e_low_degree( while (idx < static_cast(major_range_last - major_range_first)) { auto major_offset = major_start_offset + idx; vertex_t const* indices{nullptr}; - thrust::optional weights{thrust::nullopt}; + edge_t edge_offset{}; edge_t local_degree{}; - thrust::tie(indices, weights, local_degree) = edge_partition.local_edges(major_offset); - auto sum = thrust::transform_reduce( + thrust::tie(indices, edge_offset, local_degree) = edge_partition.local_edges(major_offset); + auto sum = thrust::transform_reduce( thrust::seq, thrust::make_counting_iterator(edge_t{0}), thrust::make_counting_iterator(local_degree), [&edge_partition, &edge_partition_src_value_input, &edge_partition_dst_value_input, + &edge_partition_e_value_input, &e_op, major_offset, indices, - weights] __device__(auto i) { + edge_offset] __device__(auto i) { auto minor = indices[i]; - auto weight = weights ? (*weights)[i] : weight_t{1.0}; auto minor_offset = edge_partition.minor_offset_from_minor_nocheck(minor); auto src = GraphViewType::is_storage_transposed - ? minor - : edge_partition.major_from_major_offset_nocheck(major_offset); + ? minor + : edge_partition.major_from_major_offset_nocheck(major_offset); auto dst = GraphViewType::is_storage_transposed - ? edge_partition.major_from_major_offset_nocheck(major_offset) - : minor; + ? edge_partition.major_from_major_offset_nocheck(major_offset) + : minor; auto src_offset = GraphViewType::is_storage_transposed ? minor_offset : static_cast(major_offset); auto dst_offset = @@ -201,12 +203,13 @@ __global__ void trasnform_reduce_e_low_degree( vertex_t, EdgePartitionSrcValueInputWrapper, EdgePartitionDstValueInputWrapper, + EdgePartitionEdgeValueInputWrapper, EdgeOp>() .compute(src, dst, - weight, edge_partition_src_value_input.get(src_offset), edge_partition_dst_value_input.get(dst_offset), + edge_partition_e_value_input.get(edge_offset + i), e_op); }, e_op_result_t{}, @@ -223,23 +226,23 @@ __global__ void trasnform_reduce_e_low_degree( template __global__ void trasnform_reduce_e_mid_degree( edge_partition_device_view_t edge_partition, typename GraphViewType::vertex_type major_range_first, typename GraphViewType::vertex_type major_range_last, EdgePartitionSrcValueInputWrapper edge_partition_src_value_input, EdgePartitionDstValueInputWrapper edge_partition_dst_value_input, + EdgePartitionEdgeValueInputWrapper edge_partition_e_value_input, ResultIterator result_iter /* size 1 */, EdgeOp e_op) { using vertex_t = typename GraphViewType::vertex_type; using edge_t = typename GraphViewType::edge_type; - using weight_t = typename GraphViewType::weight_type; using e_op_result_t = typename std::iterator_traits::value_type; auto const tid = threadIdx.x + blockIdx.x * blockDim.x; @@ -256,12 +259,11 @@ __global__ void trasnform_reduce_e_mid_degree( while (idx < static_cast(major_range_last - major_range_first)) { auto major_offset = major_start_offset + idx; vertex_t const* indices{nullptr}; - thrust::optional weights{thrust::nullopt}; + edge_t edge_offset{}; edge_t local_degree{}; - thrust::tie(indices, weights, local_degree) = edge_partition.local_edges(major_offset); + thrust::tie(indices, edge_offset, local_degree) = edge_partition.local_edges(major_offset); for (edge_t i = lane_id; i < local_degree; i += raft::warp_size()) { auto minor = indices[i]; - auto weight = weights ? (*weights)[i] : weight_t{1.0}; auto minor_offset = edge_partition.minor_offset_from_minor_nocheck(minor); auto src = GraphViewType::is_storage_transposed ? minor @@ -277,12 +279,13 @@ __global__ void trasnform_reduce_e_mid_degree( vertex_t, EdgePartitionSrcValueInputWrapper, EdgePartitionDstValueInputWrapper, + EdgePartitionEdgeValueInputWrapper, EdgeOp>() .compute(src, dst, - weight, edge_partition_src_value_input.get(src_offset), edge_partition_dst_value_input.get(dst_offset), + edge_partition_e_value_input.get(edge_offset + i), e_op); e_op_result_sum = edge_property_add(e_op_result_sum, e_op_result); } @@ -296,23 +299,23 @@ __global__ void trasnform_reduce_e_mid_degree( template __global__ void trasnform_reduce_e_high_degree( edge_partition_device_view_t edge_partition, typename GraphViewType::vertex_type major_range_first, typename GraphViewType::vertex_type major_range_last, EdgePartitionSrcValueInputWrapper edge_partition_src_value_input, EdgePartitionDstValueInputWrapper edge_partition_dst_value_input, + EdgePartitionEdgeValueInputWrapper edge_partition_e_value_input, ResultIterator result_iter /* size 1 */, EdgeOp e_op) { using vertex_t = typename GraphViewType::vertex_type; using edge_t = typename GraphViewType::edge_type; - using weight_t = typename GraphViewType::weight_type; using e_op_result_t = typename std::iterator_traits::value_type; auto major_start_offset = @@ -326,12 +329,11 @@ __global__ void trasnform_reduce_e_high_degree( while (idx < static_cast(major_range_last - major_range_first)) { auto major_offset = major_start_offset + idx; vertex_t const* indices{nullptr}; - thrust::optional weights{thrust::nullopt}; + edge_t edge_offset{}; edge_t local_degree{}; - thrust::tie(indices, weights, local_degree) = edge_partition.local_edges(major_offset); + thrust::tie(indices, edge_offset, local_degree) = edge_partition.local_edges(major_offset); for (edge_t i = threadIdx.x; i < local_degree; i += blockDim.x) { auto minor = indices[i]; - auto weight = weights ? (*weights)[i] : weight_t{1.0}; auto minor_offset = edge_partition.minor_offset_from_minor_nocheck(minor); auto src = GraphViewType::is_storage_transposed ? minor @@ -347,12 +349,13 @@ __global__ void trasnform_reduce_e_high_degree( vertex_t, EdgePartitionSrcValueInputWrapper, EdgePartitionDstValueInputWrapper, + EdgePartitionEdgeValueInputWrapper, EdgeOp>() .compute(src, dst, - weight, edge_partition_src_value_input.get(src_offset), edge_partition_dst_value_input.get(dst_offset), + edge_partition_e_value_input.get(edge_offset + i), e_op); e_op_result_sum = edge_property_add(e_op_result_sum, e_op_result); } @@ -373,6 +376,7 @@ __global__ void trasnform_reduce_e_high_degree( * @tparam GraphViewType Type of the passed non-owning graph object. * @tparam EdgeSrcValueInputWrapper Type of the wrapper for edge source property values. * @tparam EdgeDstValueInputWrapper Type of the wrapper for edge destination property values. + * @tparam EdgeValueInputWrapper Type of the wrapper for edge property values. * @tparam EdgeOp Type of the quaternary (or quinary) edge operator. * @tparam T Type of the initial value. * @param handle RAFT handle object to encapsulate resources (e.g. CUDA stream, communicator, and @@ -388,9 +392,12 @@ __global__ void trasnform_reduce_e_high_degree( * cugraph::edge_dst_property_t::view() (if @p e_op needs to access destination property values) or * cugraph::edge_dst_dummy_property_t::view() (if @p e_op does not access destination property * values). Use update_edge_dst_property to fill the wrapper. - * @param e_op Quaternary (or quinary) operator takes edge source, edge destination, (optional edge - * weight), property values for the source, and property values for the destination and returns a - * value to be reduced. + * @param edge_value_input Wrapper used to access edge input property values (for the edges assigned + * to this process in multi-GPU). Use either cugraph::edge_property_t::view() (if @p e_op needs to + * access edge property values) or cugraph::edge_dummy_property_t::view() (if @p e_op does not + * access edge property values). + * @param e_op Quinary operator takes edge source, edge destination, property values for the source, + * destination, and edge and returns a value to be reduced. * @param init Initial value to be added to the reduced @p edge_op outputs. * @param do_expensive_check A flag to run expensive checks for input arguments (if set to `true`). * @return T Transform-reduced @p edge_op outputs. @@ -398,12 +405,14 @@ __global__ void trasnform_reduce_e_high_degree( template T transform_reduce_e(raft::handle_t const& handle, GraphViewType const& graph_view, EdgeSrcValueInputWrapper edge_src_value_input, EdgeDstValueInputWrapper edge_dst_value_input, + EdgeValueInputWrapper edge_value_input, EdgeOp e_op, T init, bool do_expensive_check = false) @@ -412,7 +421,6 @@ T transform_reduce_e(raft::handle_t const& handle, using vertex_t = typename GraphViewType::vertex_type; using edge_t = typename GraphViewType::edge_type; - using weight_t = typename GraphViewType::weight_type; using edge_partition_src_input_device_view_t = std::conditional_t< std::is_same_v, @@ -434,6 +442,12 @@ T transform_reduce_e(raft::handle_t const& handle, detail::edge_partition_endpoint_property_device_view_t< vertex_t, typename EdgeDstValueInputWrapper::value_iterator>>>; + using edge_partition_e_input_device_view_t = std::conditional_t< + std::is_same_v, + detail::edge_partition_edge_dummy_property_device_view_t, + detail::edge_partition_edge_property_device_view_t< + edge_t, + typename EdgeValueInputWrapper::value_iterator>>; if (do_expensive_check) { // currently, nothing to do @@ -449,7 +463,7 @@ T transform_reduce_e(raft::handle_t const& handle, for (size_t i = 0; i < graph_view.number_of_local_edge_partitions(); ++i) { auto edge_partition = - edge_partition_device_view_t( + edge_partition_device_view_t( graph_view.local_edge_partition_view(i)); edge_partition_src_input_device_view_t edge_partition_src_value_input{}; @@ -463,6 +477,7 @@ T transform_reduce_e(raft::handle_t const& handle, edge_partition_src_input_device_view_t(edge_src_value_input, i); edge_partition_dst_value_input = edge_partition_dst_input_device_view_t(edge_dst_value_input); } + auto edge_partition_e_value_input = edge_partition_e_input_device_view_t(edge_value_input, i); auto segment_offsets = graph_view.local_edge_partition_segment_offsets(i); if (segment_offsets) { @@ -481,6 +496,7 @@ T transform_reduce_e(raft::handle_t const& handle, edge_partition.major_range_first() + (*segment_offsets)[1], edge_partition_src_value_input, edge_partition_dst_value_input, + edge_partition_e_value_input, get_dataframe_buffer_begin(result_buffer), e_op); } @@ -495,6 +511,7 @@ T transform_reduce_e(raft::handle_t const& handle, edge_partition.major_range_first() + (*segment_offsets)[2], edge_partition_src_value_input, edge_partition_dst_value_input, + edge_partition_e_value_input, get_dataframe_buffer_begin(result_buffer), e_op); } @@ -509,6 +526,7 @@ T transform_reduce_e(raft::handle_t const& handle, edge_partition.major_range_first() + (*segment_offsets)[3], edge_partition_src_value_input, edge_partition_dst_value_input, + edge_partition_e_value_input, get_dataframe_buffer_begin(result_buffer), e_op); } @@ -521,6 +539,7 @@ T transform_reduce_e(raft::handle_t const& handle, edge_partition, edge_partition_src_value_input, edge_partition_dst_value_input, + edge_partition_e_value_input, get_dataframe_buffer_begin(result_buffer), e_op); } @@ -537,6 +556,7 @@ T transform_reduce_e(raft::handle_t const& handle, edge_partition.major_range_last(), edge_partition_src_value_input, edge_partition_dst_value_input, + edge_partition_e_value_input, get_dataframe_buffer_begin(result_buffer), e_op); } @@ -566,6 +586,7 @@ T transform_reduce_e(raft::handle_t const& handle, * @tparam GraphViewType Type of the passed non-owning graph object. * @tparam EdgeSrcValueInputWrapper Type of the wrapper for edge source property values. * @tparam EdgeDstValueInputWrapper Type of the wrapper for edge destination property values. + * @tparam EdgeValueInputWrapper Type of the wrapper for edge property values. * @tparam EdgeOp Type of the quaternary (or quinary) edge operator. * @param handle RAFT handle object to encapsulate resources (e.g. CUDA stream, communicator, and * handles to various CUDA libraries) to run graph algorithms. @@ -580,29 +601,34 @@ T transform_reduce_e(raft::handle_t const& handle, * cugraph::edge_dst_property_t::view() (if @p e_op needs to access destination property values) or * cugraph::edge_dst_dummy_property_t::view() (if @p e_op does not access destination property * values). Use update_edge_dst_property to fill the wrapper. - * @param e_op Quaternary (or quinary) operator takes edge source, edge destination, (optional edge - * weight), property values for the source, and property values for the destination and returns a - * value to be reduced. + * @param edge_value_input Wrapper used to access edge input property values (for the edges assigned + * to this process in multi-GPU). Use either cugraph::edge_property_t::view() (if @p e_op needs to + * access edge property values) or cugraph::edge_dummy_property_t::view() (if @p e_op does not + * access edge property values). + * @param e_op Quinary operator takes edge source, edge destination, property values for the source, + * destination, and edge and returns a value to be reduced. * @param do_expensive_check A flag to run expensive checks for input arguments (if set to `true`). * @return Transform-reduced @p edge_op outputs. */ template auto transform_reduce_e(raft::handle_t const& handle, GraphViewType const& graph_view, EdgeSrcValueInputWrapper edge_src_value_input, EdgeDstValueInputWrapper edge_dst_value_input, + EdgeValueInputWrapper edge_value_input, EdgeOp e_op, bool do_expensive_check = false) { using vertex_t = typename GraphViewType::vertex_type; - using weight_t = typename GraphViewType::weight_type; using src_value_t = typename EdgeSrcValueInputWrapper::value_type; using dst_value_t = typename EdgeDstValueInputWrapper::value_type; + using e_value_t = typename EdgeValueInputWrapper::value_type; using T = typename detail:: - edge_op_result_type::type; + edge_op_result_type::type; static_assert(!std::is_same_v); if (do_expensive_check) { @@ -610,7 +636,7 @@ auto transform_reduce_e(raft::handle_t const& handle, } return transform_reduce_e( - handle, graph_view, edge_src_value_input, edge_dst_value_input, e_op, T{}); + handle, graph_view, edge_src_value_input, edge_dst_value_input, edge_value_input, e_op, T{}); } } // namespace cugraph diff --git a/cpp/src/prims/transform_reduce_e_by_src_dst_key.cuh b/cpp/src/prims/transform_reduce_e_by_src_dst_key.cuh index 02e59d3a4dd..f81edf5bda3 100644 --- a/cpp/src/prims/transform_reduce_e_by_src_dst_key.cuh +++ b/cpp/src/prims/transform_reduce_e_by_src_dst_key.cuh @@ -50,23 +50,24 @@ template __device__ void update_buffer_element( edge_partition_device_view_t& edge_partition, typename GraphViewType::vertex_type major, typename GraphViewType::vertex_type minor, - typename GraphViewType::weight_type weight, + typename GraphViewType::edge_type edge_offset, EdgePartitionSrcValueInputWrapper edge_partition_src_value_input, EdgePartitionDstValueInputWrapper edge_partition_dst_value_input, + EdgePartitionEdgeValueInputWrapper edge_partition_e_value_input, EdgePartitionSrcDstKeyInputWrapper edge_partition_src_dst_key_input, EdgeOp e_op, typename GraphViewType::vertex_type* key, - ValueIterator value_iter) + ValueIterator value) { using vertex_t = typename GraphViewType::vertex_type; @@ -80,33 +81,35 @@ __device__ void update_buffer_element( *key = edge_partition_src_dst_key_input.get( ((GraphViewType::is_storage_transposed != edge_partition_src_key) ? major_offset : minor_offset)); - *value_iter = evaluate_edge_op() - .compute(src, - dst, - weight, - edge_partition_src_value_input.get(src_offset), - edge_partition_dst_value_input.get(dst_offset), - e_op); + *value = evaluate_edge_op() + .compute(src, + dst, + edge_partition_src_value_input.get(src_offset), + edge_partition_dst_value_input.get(dst_offset), + edge_partition_e_value_input.get(edge_offset), + e_op); } template __global__ void transform_reduce_by_src_dst_key_hypersparse( edge_partition_device_view_t edge_partition, EdgePartitionSrcValueInputWrapper edge_partition_src_value_input, EdgePartitionDstValueInputWrapper edge_partition_dst_value_input, + EdgePartitionEdgeValueInputWrapper edge_partition_e_value_input, EdgePartitionSrcDstKeyInputWrapper edge_partition_src_dst_key_input, EdgeOp e_op, typename GraphViewType::vertex_type* keys, @@ -114,7 +117,6 @@ __global__ void transform_reduce_by_src_dst_key_hypersparse( { using vertex_t = typename GraphViewType::vertex_type; using edge_t = typename GraphViewType::edge_type; - using weight_t = typename GraphViewType::weight_type; auto const tid = threadIdx.x + blockIdx.x * blockDim.x; auto major_start_offset = static_cast(*(edge_partition.major_hypersparse_first()) - @@ -129,23 +131,23 @@ __global__ void transform_reduce_by_src_dst_key_hypersparse( auto major_idx = major_start_offset + idx; // major_offset != major_idx in the hypersparse region vertex_t const* indices{nullptr}; - thrust::optional weights{thrust::nullopt}; + edge_t edge_offset{}; edge_t local_degree{}; - thrust::tie(indices, weights, local_degree) = + thrust::tie(indices, edge_offset, local_degree) = edge_partition.local_edges(static_cast(major_idx)); auto local_offset = edge_partition.local_offset(major_idx); for (edge_t i = 0; i < local_degree; ++i) { - update_buffer_element( - edge_partition, - major, - indices[i], - weights ? (*weights)[i] : weight_t{1.0}, - edge_partition_src_value_input, - edge_partition_dst_value_input, - edge_partition_src_dst_key_input, - e_op, - keys + local_offset + i, - value_iter + local_offset + i); + update_buffer_element(edge_partition, + major, + indices[i], + edge_offset + i, + edge_partition_src_value_input, + edge_partition_dst_value_input, + edge_partition_e_value_input, + edge_partition_src_dst_key_input, + e_op, + keys + local_offset + i, + value_iter + local_offset + i); } idx += gridDim.x * blockDim.x; @@ -156,18 +158,19 @@ template __global__ void transform_reduce_by_src_dst_key_low_degree( edge_partition_device_view_t edge_partition, typename GraphViewType::vertex_type major_range_first, typename GraphViewType::vertex_type major_range_last, EdgePartitionSrcValueInputWrapper edge_partition_src_value_input, EdgePartitionDstValueInputWrapper edge_partition_dst_value_input, + EdgePartitionEdgeValueInputWrapper edge_partition_e_value_input, EdgePartitionSrcDstKeyInputWrapper edge_partition_src_dst_key_input, EdgeOp e_op, typename GraphViewType::vertex_type* keys, @@ -175,7 +178,6 @@ __global__ void transform_reduce_by_src_dst_key_low_degree( { using vertex_t = typename GraphViewType::vertex_type; using edge_t = typename GraphViewType::edge_type; - using weight_t = typename GraphViewType::weight_type; auto const tid = threadIdx.x + blockIdx.x * blockDim.x; auto major_start_offset = @@ -187,23 +189,23 @@ __global__ void transform_reduce_by_src_dst_key_low_degree( auto major = edge_partition.major_from_major_offset_nocheck(static_cast(major_offset)); vertex_t const* indices{nullptr}; - thrust::optional weights{thrust::nullopt}; + edge_t edge_offset{}; edge_t local_degree{}; - thrust::tie(indices, weights, local_degree) = + thrust::tie(indices, edge_offset, local_degree) = edge_partition.local_edges(static_cast(major_offset)); auto local_offset = edge_partition.local_offset(major_offset); for (edge_t i = 0; i < local_degree; ++i) { - update_buffer_element( - edge_partition, - major, - indices[i], - weights ? (*weights)[i] : weight_t{1.0}, - edge_partition_src_value_input, - edge_partition_dst_value_input, - edge_partition_src_dst_key_input, - e_op, - keys + local_offset + i, - value_iter + local_offset + i); + update_buffer_element(edge_partition, + major, + indices[i], + edge_offset + i, + edge_partition_src_value_input, + edge_partition_dst_value_input, + edge_partition_e_value_input, + edge_partition_src_dst_key_input, + e_op, + keys + local_offset + i, + value_iter + local_offset + i); } idx += gridDim.x * blockDim.x; @@ -214,18 +216,19 @@ template __global__ void transform_reduce_by_src_dst_key_mid_degree( edge_partition_device_view_t edge_partition, typename GraphViewType::vertex_type major_range_first, typename GraphViewType::vertex_type major_range_last, EdgePartitionSrcValueInputWrapper edge_partition_src_value_input, EdgePartitionDstValueInputWrapper edge_partition_dst_value_input, + EdgePartitionEdgeValueInputWrapper edge_partition_e_value_input, EdgePartitionSrcDstKeyInputWrapper edge_partition_src_dst_key_input, EdgeOp e_op, typename GraphViewType::vertex_type* keys, @@ -233,7 +236,6 @@ __global__ void transform_reduce_by_src_dst_key_mid_degree( { using vertex_t = typename GraphViewType::vertex_type; using edge_t = typename GraphViewType::edge_type; - using weight_t = typename GraphViewType::weight_type; auto const tid = threadIdx.x + blockIdx.x * blockDim.x; static_assert(transform_reduce_e_by_src_dst_key_kernel_block_size % raft::warp_size() == 0); @@ -247,23 +249,23 @@ __global__ void transform_reduce_by_src_dst_key_mid_degree( auto major = edge_partition.major_from_major_offset_nocheck(static_cast(major_offset)); vertex_t const* indices{nullptr}; - thrust::optional weights{thrust::nullopt}; + edge_t edge_offset{}; edge_t local_degree{}; - thrust::tie(indices, weights, local_degree) = + thrust::tie(indices, edge_offset, local_degree) = edge_partition.local_edges(static_cast(major_offset)); auto local_offset = edge_partition.local_offset(major_offset); for (edge_t i = lane_id; i < local_degree; i += raft::warp_size()) { - update_buffer_element( - edge_partition, - major, - indices[i], - weights ? (*weights)[i] : weight_t{1.0}, - edge_partition_src_value_input, - edge_partition_dst_value_input, - edge_partition_src_dst_key_input, - e_op, - keys + local_offset + i, - value_iter + local_offset + i); + update_buffer_element(edge_partition, + major, + indices[i], + edge_offset + i, + edge_partition_src_value_input, + edge_partition_dst_value_input, + edge_partition_e_value_input, + edge_partition_src_dst_key_input, + e_op, + keys + local_offset + i, + value_iter + local_offset + i); } idx += gridDim.x * (blockDim.x / raft::warp_size()); @@ -274,18 +276,19 @@ template __global__ void transform_reduce_by_src_dst_key_high_degree( edge_partition_device_view_t edge_partition, typename GraphViewType::vertex_type major_range_first, typename GraphViewType::vertex_type major_range_last, EdgePartitionSrcValueInputWrapper edge_partition_src_value_input, EdgePartitionDstValueInputWrapper edge_partition_dst_value_input, + EdgePartitionEdgeValueInputWrapper edge_partition_e_value_input, EdgePartitionSrcDstKeyInputWrapper edge_partition_src_dst_key_input, EdgeOp e_op, typename GraphViewType::vertex_type* keys, @@ -293,7 +296,6 @@ __global__ void transform_reduce_by_src_dst_key_high_degree( { using vertex_t = typename GraphViewType::vertex_type; using edge_t = typename GraphViewType::edge_type; - using weight_t = typename GraphViewType::weight_type; auto major_start_offset = static_cast(major_range_first - edge_partition.major_range_first()); @@ -304,23 +306,23 @@ __global__ void transform_reduce_by_src_dst_key_high_degree( auto major = edge_partition.major_from_major_offset_nocheck(static_cast(major_offset)); vertex_t const* indices{nullptr}; - thrust::optional weights{thrust::nullopt}; + edge_t edge_offset{}; edge_t local_degree{}; - thrust::tie(indices, weights, local_degree) = + thrust::tie(indices, edge_offset, local_degree) = edge_partition.local_edges(static_cast(major_offset)); auto local_offset = edge_partition.local_offset(major_offset); for (edge_t i = threadIdx.x; i < local_degree; i += blockDim.x) { - update_buffer_element( - edge_partition, - major, - indices[i], - weights ? (*weights)[i] : weight_t{1.0}, - edge_partition_src_value_input, - edge_partition_dst_value_input, - edge_partition_src_dst_key_input, - e_op, - keys + local_offset + i, - value_iter + local_offset + i); + update_buffer_element(edge_partition, + major, + indices[i], + edge_offset + i, + edge_partition_src_value_input, + edge_partition_dst_value_input, + edge_partition_e_value_input, + edge_partition_src_dst_key_input, + e_op, + keys + local_offset + i, + value_iter + local_offset + i); } idx += gridDim.x; @@ -363,6 +365,7 @@ template , @@ -406,6 +409,12 @@ transform_reduce_e_by_src_dst_key(raft::handle_t const& handle, detail::edge_partition_endpoint_property_device_view_t< vertex_t, typename EdgeDstValueInputWrapper::value_iterator>>>; + using edge_partition_e_input_device_view_t = std::conditional_t< + std::is_same_v, + detail::edge_partition_edge_dummy_property_device_view_t, + detail::edge_partition_edge_property_device_view_t< + edge_t, + typename EdgeValueInputWrapper::value_iterator>>; using edge_partition_src_dst_key_device_view_t = std::conditional_t(0, handle.get_stream()); for (size_t i = 0; i < graph_view.number_of_local_edge_partitions(); ++i) { auto edge_partition = - edge_partition_device_view_t( + edge_partition_device_view_t( graph_view.local_edge_partition_view(i)); int comm_root_rank = 0; @@ -451,6 +460,7 @@ transform_reduce_e_by_src_dst_key(raft::handle_t const& handle, edge_partition_dst_value_input = edge_partition_dst_input_device_view_t(edge_dst_value_input); } + auto edge_partition_e_value_input = edge_partition_e_input_device_view_t(edge_value_input, i); edge_partition_src_dst_key_device_view_t edge_partition_src_dst_key_input{}; if constexpr (edge_src_key != GraphViewType::is_storage_transposed) { @@ -479,6 +489,7 @@ transform_reduce_e_by_src_dst_key(raft::handle_t const& handle, edge_partition.major_range_first() + (*segment_offsets)[1], edge_partition_src_value_input, edge_partition_dst_value_input, + edge_partition_e_value_input, edge_partition_src_dst_key_input, e_op, tmp_keys.data(), @@ -496,6 +507,7 @@ transform_reduce_e_by_src_dst_key(raft::handle_t const& handle, edge_partition.major_range_first() + (*segment_offsets)[2], edge_partition_src_value_input, edge_partition_dst_value_input, + edge_partition_e_value_input, edge_partition_src_dst_key_input, e_op, tmp_keys.data(), @@ -513,6 +525,7 @@ transform_reduce_e_by_src_dst_key(raft::handle_t const& handle, edge_partition.major_range_first() + (*segment_offsets)[3], edge_partition_src_value_input, edge_partition_dst_value_input, + edge_partition_e_value_input, edge_partition_src_dst_key_input, e_op, tmp_keys.data(), @@ -529,6 +542,7 @@ transform_reduce_e_by_src_dst_key(raft::handle_t const& handle, edge_partition, edge_partition_src_value_input, edge_partition_dst_value_input, + edge_partition_e_value_input, edge_partition_src_dst_key_input, e_op, tmp_keys.data(), @@ -547,6 +561,7 @@ transform_reduce_e_by_src_dst_key(raft::handle_t const& handle, edge_partition.major_range_last(), edge_partition_src_value_input, edge_partition_dst_value_input, + edge_partition_e_value_input, edge_partition_src_dst_key_input, e_op, tmp_keys.data(), @@ -621,6 +636,7 @@ transform_reduce_e_by_src_dst_key(raft::handle_t const& handle, * @tparam EdgeSrcValueInputWrapper Type of the wrapper for edge source property values. * @tparam EdgeDstValueInputWrapper Type of the wrapper for edge destination property values. * @tparam EdgeSrcKeyInputWrapper Type of the wrapper for edge source key values. + * @tparam EdgeValueInputWrapper Type of the wrapper for edge property values. * @tparam EdgeOp Type of the quaternary (or quinary) edge operator. * @tparam T Type of the values in (key, value) pairs. * @param handle RAFT handle object to encapsulate resources (e.g. CUDA stream, communicator, and @@ -639,9 +655,12 @@ transform_reduce_e_by_src_dst_key(raft::handle_t const& handle, * @param edge_src_key_input Wrapper used to access source input ke values (for the edge sources * assigned to this process in multi-GPU). Use cugraph::edge_src_property_t::view(). Use * update_edge_src_property to fill the wrapper. - * @param e_op Quaternary (or quinary) operator takes edge source, edge destination, (optional edge - * weight), property values for the source, and property values for the destination and returns a - * transformed value to be reduced to (source key, value) pairs. + * @param edge_value_input Wrapper used to access edge input property values (for the edges assigned + * to this process in multi-GPU). Use either cugraph::edge_property_t::view() (if @p e_op needs to + * access edge property values) or cugraph::edge_dummy_property_t::view() (if @p e_op does not + * access edge property values). + * @param e_op Quinary operator takes edge source, edge destination, property values for the source, + * destination, and edge and returns a value to be reduced to (source key, value) pairs. * @param init Initial value to be added to the value in each transform-reduced (source key, value) * pair. * @param reduce_op Binary operator that takes two input arguments and reduce the two values to one. @@ -659,6 +678,7 @@ transform_reduce_e_by_src_dst_key(raft::handle_t const& handle, template -struct call_e_op_with_w_t { +struct call_e_op_t { EdgeOp e_op{}; __device__ thrust::optional< std::conditional_t && !std::is_same_v, thrust::tuple, std::conditional_t, key_t, payload_t>>> - operator()(key_t key, vertex_t dst, weight_t w, src_value_t sv, dst_value_t dv) const + operator()(key_t key, vertex_t dst, src_value_t sv, dst_value_t dv, e_value_t ev) const { - auto e_op_result = e_op(key, dst, w, sv, dv); - if (e_op_result.has_value()) { - if constexpr (std::is_same_v && std::is_same_v) { - return dst; - } else if constexpr (std::is_same_v && !std::is_same_v) { - return thrust::make_tuple(dst, *e_op_result); - } else if constexpr (!std::is_same_v && std::is_same_v) { - return thrust::make_tuple(dst, *e_op_result); - } else { - return thrust::make_tuple(thrust::make_tuple(dst, thrust::get<0>(*e_op_result)), - thrust::get<1>(*e_op_result)); - } - } else { - return thrust::nullopt; - } - } -}; - -template -struct call_e_op_without_w_t { - EdgeOp e_op{}; - - __device__ thrust::optional< - std::conditional_t && !std::is_same_v, - thrust::tuple, - std::conditional_t, key_t, payload_t>>> - operator()(key_t key, vertex_t dst, src_value_t sv, dst_value_t dv) const - { - auto e_op_result = e_op(key, dst, sv, dv); + auto e_op_result = e_op(key, dst, sv, dv, ev); if (e_op_result.has_value()) { if constexpr (std::is_same_v && std::is_same_v) { return dst; @@ -219,7 +186,6 @@ size_t compute_num_out_nbrs_from_frontier(raft::handle_t const& handle, using vertex_t = typename GraphViewType::vertex_type; using edge_t = typename GraphViewType::edge_type; - using weight_t = typename GraphViewType::weight_type; using key_t = typename VertexFrontierBucketType::key_type; size_t ret{0}; @@ -240,7 +206,7 @@ size_t compute_num_out_nbrs_from_frontier(raft::handle_t const& handle, } for (size_t i = 0; i < graph_view.number_of_local_edge_partitions(); ++i) { auto edge_partition = - edge_partition_device_view_t( + edge_partition_device_view_t( graph_view.local_edge_partition_view(i)); if constexpr (GraphViewType::is_multi_gpu) { @@ -285,6 +251,7 @@ size_t compute_num_out_nbrs_from_frontier(raft::handle_t const& handle, * current (tagged-)vertex frontier. * @tparam EdgeSrcValueInputWrapper Type of the wrapper for edge source property values. * @tparam EdgeDstValueInputWrapper Type of the wrapper for edge destination property values. + * @tparam EdgeValueInputWrapper Type of the wrapper for edge property values. * @tparam EdgeOp Type of the quaternary (or quinary) edge operator. * @tparam ReduceOp Type of the binary reduction operator. * @param handle RAFT handle object to encapsulate resources (e.g. CUDA stream, communicator, and @@ -301,14 +268,17 @@ size_t compute_num_out_nbrs_from_frontier(raft::handle_t const& handle, * cugraph::edge_dst_property_t::view() (if @p e_op needs to access destination property values) or * cugraph::edge_dst_dummy_property_t::view() (if @p e_op does not access destination property * values). Use update_edge_dst_property to fill the wrapper. - * @param e_op Quaternary (or quinary) operator takes edge source, edge destination, (optional edge - * weight), property values for the source, and property values for the destination and returns - * 1) thrust::nullopt (if invalid and to be discarded); 2) dummy (but valid) thrust::optional object - * (e.g. thrust::optional{std::byte{0}}, if vertices are not tagged and - * ReduceOp::value_type is void); 3) a tag (if vertices are tagged and ReduceOp::value_type is - * void); 4) a value to be reduced using the @p reduce_op (if vertices are not tagged and - * ReduceOp::value_type is not void); or 5) a tuple of a tag and a value to be reduced (if vertices - * are tagged and ReduceOp::value_type is not void). + * @param edge_value_input Wrapper used to access edge input property values (for the edges assigned + * to this process in multi-GPU). Use either cugraph::edge_property_t::view() (if @p e_op needs to + * access edge property values) or cugraph::edge_dummy_property_t::view() (if @p e_op does not + * access edge property values). + * @param e_op Quinary operator takes edge source, edge destination, property values for the source, + * destination, and edge and returns 1) thrust::nullopt (if invalid and to be discarded); 2) dummy + * (but valid) thrust::optional object (e.g. thrust::optional{std::byte{0}}, if vertices + * are not tagged and ReduceOp::value_type is void); 3) a tag (if vertices are tagged and + * ReduceOp::value_type is void); 4) a value to be reduced using the @p reduce_op (if vertices are + * not tagged and ReduceOp::value_type is not void); or 5) a tuple of a tag and a value to be + * reduced (if vertices are tagged and ReduceOp::value_type is not void). * @param reduce_op Binary operator that takes two input arguments and reduce the two values to one. * There are pre-defined reduction operators in prims/reduce_op.cuh. It is * recommended to use the pre-defined reduction operators whenever possible as the current (and @@ -322,6 +292,7 @@ template std::conditional_t< @@ -337,6 +308,7 @@ transform_reduce_v_frontier_outgoing_e_by_dst(raft::handle_t const& handle, VertexFrontierBucketType const& frontier, EdgeSrcValueInputWrapper edge_src_value_input, EdgeDstValueInputWrapper edge_dst_value_input, + EdgeValueInputWrapper edge_value_input, EdgeOp e_op, ReduceOp reduce_op, bool do_expensive_check = false) @@ -346,7 +318,6 @@ transform_reduce_v_frontier_outgoing_e_by_dst(raft::handle_t const& handle, using vertex_t = typename GraphViewType::vertex_type; using edge_t = typename GraphViewType::edge_type; - using weight_t = typename GraphViewType::weight_type; using key_t = typename VertexFrontierBucketType::key_type; using payload_t = typename ReduceOp::value_type; @@ -356,25 +327,13 @@ transform_reduce_v_frontier_outgoing_e_by_dst(raft::handle_t const& handle, // 1. fill the buffer - std::conditional_t, - detail::call_e_op_with_w_t, - detail::call_e_op_without_w_t> + detail::call_e_op_t e_op_wrapper{e_op}; auto [key_buffer, payload_buffer] = @@ -383,6 +342,7 @@ transform_reduce_v_frontier_outgoing_e_by_dst(raft::handle_t const& handle, frontier, edge_src_value_input, edge_dst_value_input, + edge_value_input, e_op_wrapper, do_expensive_check); diff --git a/cpp/src/prims/update_edge_src_dst_property.cuh b/cpp/src/prims/update_edge_src_dst_property.cuh index 70c1fecff10..bf038c543c3 100644 --- a/cpp/src/prims/update_edge_src_dst_property.cuh +++ b/cpp/src/prims/update_edge_src_dst_property.cuh @@ -136,7 +136,6 @@ void update_edge_major_property(raft::handle_t const& handle, { using vertex_t = typename GraphViewType::vertex_type; using edge_t = typename GraphViewType::edge_type; - using weight_t = typename GraphViewType::weight_type; auto edge_partition_value_firsts = edge_major_property_output.value_firsts(); if constexpr (GraphViewType::is_multi_gpu) { @@ -166,7 +165,7 @@ void update_edge_major_property(raft::handle_t const& handle, auto edge_partition_keys = edge_major_property_output.keys(); for (int i = 0; i < col_comm_size; ++i) { auto edge_partition = - edge_partition_device_view_t( + edge_partition_device_view_t( graph_view.local_edge_partition_view(i)); if (i == col_comm_rank) { @@ -369,7 +368,6 @@ void update_edge_minor_property(raft::handle_t const& handle, { using vertex_t = typename GraphViewType::vertex_type; using edge_t = typename GraphViewType::edge_type; - using weight_t = typename GraphViewType::weight_type; auto edge_partition_value_first = edge_minor_property_output.value_first(); if constexpr (GraphViewType::is_multi_gpu) { @@ -404,7 +402,7 @@ void update_edge_minor_property(raft::handle_t const& handle, } auto edge_partition = - edge_partition_device_view_t( + edge_partition_device_view_t( graph_view.local_edge_partition_view(size_t{0})); auto edge_partition_keys = edge_minor_property_output.keys(); for (int i = 0; i < row_comm_size; ++i) { diff --git a/cpp/src/sampling/detail/graph_functions.hpp b/cpp/src/sampling/detail/graph_functions.hpp index 65621a506c5..d15f0cbaf29 100644 --- a/cpp/src/sampling/detail/graph_functions.hpp +++ b/cpp/src/sampling/detail/graph_functions.hpp @@ -66,14 +66,15 @@ count_and_remove_duplicates(raft::handle_t const& handle, * gpus in the column communicator * @return A tuple of device vector containing the majors, minors and weights gathered locally */ -template -std::tuple, - rmm::device_uvector, - std::optional>> +template +std::tuple, + rmm::device_uvector, + std::optional>> gather_one_hop_edgelist( raft::handle_t const& handle, - GraphViewType const& graph_view, - const rmm::device_uvector& active_majors, + graph_view_t const& graph_view, + std::optional> edge_weight_view, + const rmm::device_uvector& active_majors, bool do_expensive_check = false); /** @@ -91,14 +92,15 @@ gather_one_hop_edgelist( * @param invalid_vertex_id Value to use for an invalid vertex * @return A tuple of device vector containing the majors, minors and weights gathered locally */ -template -std::tuple, - rmm::device_uvector, - std::optional>> +template +std::tuple, + rmm::device_uvector, + std::optional>> sample_edges(raft::handle_t const& handle, - GraphViewType const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, raft::random::RngState& rng_state, - rmm::device_uvector const& active_majors, + rmm::device_uvector const& active_majors, size_t fanout, bool with_replacement); diff --git a/cpp/src/sampling/detail/sampling_utils_impl.cuh b/cpp/src/sampling/detail/sampling_utils_impl.cuh index 6a3bc6452fd..71cc565ab85 100644 --- a/cpp/src/sampling/detail/sampling_utils_impl.cuh +++ b/cpp/src/sampling/detail/sampling_utils_impl.cuh @@ -78,112 +78,152 @@ count_and_remove_duplicates(raft::handle_t const& handle, std::move(result_src), std::move(result_dst), std::move(result_wgt), std::move(result_count)); } -template +template struct return_all_edges_e_op { - using return_type = thrust::optional>; + template + __device__ + std::enable_if_t, thrust::optional>> + __device__ operator()( + vertex_t src, vertex_t dst, thrust::nullopt_t, thrust::nullopt_t, thrust::nullopt_t) + { + return thrust::make_optional(thrust::make_tuple(src, dst)); + } - return_type __device__ - operator()(vertex_t src, vertex_t dst, weight_t wgt, property_t, property_t) + template + __device__ std::enable_if_t, + thrust::optional>> + __device__ operator()(vertex_t src, vertex_t dst, thrust::nullopt_t, thrust::nullopt_t, W wgt) { return thrust::make_optional(thrust::make_tuple(src, dst, wgt)); } }; -template -std::tuple, - rmm::device_uvector, - std::optional>> +template +std::tuple, + rmm::device_uvector, + std::optional>> gather_one_hop_edgelist( raft::handle_t const& handle, - GraphViewType const& graph_view, - const rmm::device_uvector& active_majors, + graph_view_t const& graph_view, + std::optional> edge_weight_view, + const rmm::device_uvector& active_majors, bool do_expensive_check) { - using vertex_t = typename GraphViewType::vertex_type; - using edge_t = typename GraphViewType::edge_type; - using weight_t = typename GraphViewType::weight_type; - // FIXME: add as a template parameter using tag_t = void; - cugraph::vertex_frontier_t vertex_frontier( - handle, 1); + cugraph::vertex_frontier_t vertex_frontier(handle, 1); vertex_frontier.bucket(0).insert(active_majors.begin(), active_majors.end()); - // FIXME: Shouldn't there be a dummy property equivalent here? - using property_t = int32_t; - cugraph::edge_src_property_t src_properties(handle, graph_view); - cugraph::edge_dst_property_t dst_properties(handle, graph_view); - - auto [majors, minors, weights] = cugraph::extract_transform_v_frontier_outgoing_e( - handle, - graph_view, - vertex_frontier.bucket(0), - // edge_src_dummy_property_t{}, - // edge_dst_dummy_property_t{}, - src_properties.view(), - dst_properties.view(), - return_all_edges_e_op{}, - do_expensive_check); + rmm::device_uvector majors(0, handle.get_stream()); + rmm::device_uvector minors(0, handle.get_stream()); + std::optional> weights{std::nullopt}; + if (edge_weight_view) { + std::tie(majors, minors, weights) = + cugraph::extract_transform_v_frontier_outgoing_e(handle, + graph_view, + vertex_frontier.bucket(0), + edge_src_dummy_property_t{}.view(), + edge_dst_dummy_property_t{}.view(), + *edge_weight_view, + return_all_edges_e_op{}, + do_expensive_check); + } else { + std::tie(majors, minors) = + cugraph::extract_transform_v_frontier_outgoing_e(handle, + graph_view, + vertex_frontier.bucket(0), + edge_src_dummy_property_t{}.view(), + edge_dst_dummy_property_t{}.view(), + edge_dummy_property_t{}.view(), + return_all_edges_e_op{}, + do_expensive_check); + } - return std::make_tuple( - std::move(majors), std::move(minors), std::make_optional(std::move(weights))); + return std::make_tuple(std::move(majors), std::move(minors), std::move(weights)); } -template +template struct sample_edges_op_t { - using result_t = thrust::tuple; + using result_t = thrust::tuple; + + template + __device__ std::enable_if_t, thrust::tuple> + operator()( + vertex_t src, vertex_t dst, thrust::nullopt_t, thrust::nullopt_t, thrust::nullopt_t) const + { + return thrust::make_tuple(src, dst); + } - __device__ result_t operator()( - vertex_t src, vertex_t dst, weight_t wgt, property_t src_prop, property_t dst_prop) const + template + __device__ std::enable_if_t, thrust::tuple> + operator()(vertex_t src, vertex_t dst, thrust::nullopt_t, thrust::nullopt_t, W wgt) const { - return thrust::make_tuple(src, dst, wgt, src_prop, dst_prop); + return thrust::make_tuple(src, dst, wgt); } }; -template -std::tuple, - rmm::device_uvector, - std::optional>> +template +std::tuple, + rmm::device_uvector, + std::optional>> sample_edges(raft::handle_t const& handle, - GraphViewType const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, raft::random::RngState& rng_state, - rmm::device_uvector const& active_majors, + rmm::device_uvector const& active_majors, size_t fanout, bool with_replacement) { - using vertex_t = typename GraphViewType::vertex_type; - using weight_t = typename GraphViewType::weight_type; - // FIXME: add as a template parameter using tag_t = void; - cugraph::vertex_frontier_t vertex_frontier( - handle, 1); + cugraph::vertex_frontier_t vertex_frontier(handle, 1); vertex_frontier.bucket(0).insert(active_majors.begin(), active_majors.end()); - // FIXME: Shouldn't there be a dummy property equivalent here? - using property_t = int32_t; - cugraph::edge_src_property_t src_properties(handle, graph_view); - cugraph::edge_dst_property_t dst_properties(handle, graph_view); - - using result_t = thrust::tuple; - - auto [sample_offsets, sample_e_op_results] = cugraph::per_v_random_select_transform_outgoing_e( - handle, - graph_view, - vertex_frontier.bucket(0), - src_properties.view(), - dst_properties.view(), - sample_edges_op_t{}, - rng_state, - fanout, - with_replacement, - std::make_optional(result_t{cugraph::invalid_vertex_id::value, - cugraph::invalid_vertex_id::value}), - true); + rmm::device_uvector majors(0, handle.get_stream()); + rmm::device_uvector minors(0, handle.get_stream()); + std::optional> weights{std::nullopt}; + if (edge_weight_view) { + auto [sample_offsets, sample_e_op_results] = cugraph::per_v_random_select_transform_outgoing_e( + handle, + graph_view, + vertex_frontier.bucket(0), + edge_src_dummy_property_t{}.view(), + edge_dst_dummy_property_t{}.view(), + *edge_weight_view, + sample_edges_op_t{}, + rng_state, + fanout, + with_replacement, + std::make_optional>( + cugraph::invalid_vertex_id::value, + cugraph::invalid_vertex_id::value, + weight_t{}), + true); + majors = std::move(std::get<0>(sample_e_op_results)); + minors = std::move(std::get<1>(sample_e_op_results)); + weights = std::move(std::get<2>(sample_e_op_results)); + } else { + auto [sample_offsets, sample_e_op_results] = cugraph::per_v_random_select_transform_outgoing_e( + handle, + graph_view, + vertex_frontier.bucket(0), + edge_src_dummy_property_t{}.view(), + edge_dst_dummy_property_t{}.view(), + edge_dummy_property_t{}.view(), + sample_edges_op_t{}, + rng_state, + fanout, + with_replacement, + std::make_optional>( + cugraph::invalid_vertex_id::value, cugraph::invalid_vertex_id::value), + true); + majors = std::move(std::get<0>(sample_e_op_results)); + minors = std::move(std::get<1>(sample_e_op_results)); + } // // FIXME: Debugging status, EOD 9/18/22 @@ -193,29 +233,56 @@ sample_edges(raft::handle_t const& handle, // 3) Finally... can I switch to using cugraph::invalid_vertex_id instead of // number_of_vertices()? 4) I'm close, I should do the code cleanup. // - auto end_iter = thrust::copy_if(handle.get_thrust_policy(), - get_dataframe_buffer_begin(sample_e_op_results), - get_dataframe_buffer_end(sample_e_op_results), - get_dataframe_buffer_begin(sample_e_op_results), - [] __device__(auto tuple) { - auto v1 = thrust::get<0>(tuple); - auto v2 = thrust::get<1>(tuple); - - return ((v1 != cugraph::invalid_vertex_id::value) && - (v1 != cugraph::invalid_vertex_id::value)); - }); - - size_t new_size = thrust::distance(get_dataframe_buffer_begin(sample_e_op_results), end_iter); - - if (new_size != size_dataframe_buffer(sample_e_op_results)) { - resize_dataframe_buffer(sample_e_op_results, new_size, handle.get_stream()); - shrink_to_fit_dataframe_buffer(sample_e_op_results, handle.get_stream()); + if (weights) { + auto edge_first = thrust::make_zip_iterator( + thrust::make_tuple(majors.begin(), minors.begin(), (*weights).begin())); + auto end_iter = + thrust::remove_if(handle.get_thrust_policy(), + edge_first, + edge_first + majors.size(), + [] __device__(auto tuple) { + auto v1 = thrust::get<0>(tuple); + auto v2 = thrust::get<1>(tuple); + + return ((v1 == cugraph::invalid_vertex_id::value) || + (v1 == cugraph::invalid_vertex_id::value)); + }); + + size_t new_size = thrust::distance(edge_first, end_iter); + + if (new_size != majors.size()) { + majors.resize(new_size, handle.get_stream()); + majors.shrink_to_fit(handle.get_stream()); + minors.resize(new_size, handle.get_stream()); + minors.shrink_to_fit(handle.get_stream()); + (*weights).resize(new_size, handle.get_stream()); + (*weights).shrink_to_fit(handle.get_stream()); + } + } else { + auto edge_first = thrust::make_zip_iterator(thrust::make_tuple(majors.begin(), minors.begin())); + auto end_iter = + thrust::remove_if(handle.get_thrust_policy(), + edge_first, + edge_first + majors.size(), + [] __device__(auto tuple) { + auto v1 = thrust::get<0>(tuple); + auto v2 = thrust::get<1>(tuple); + + return ((v1 == cugraph::invalid_vertex_id::value) || + (v1 == cugraph::invalid_vertex_id::value)); + }); + + size_t new_size = thrust::distance(edge_first, end_iter); + + if (new_size != majors.size()) { + majors.resize(new_size, handle.get_stream()); + majors.shrink_to_fit(handle.get_stream()); + minors.resize(new_size, handle.get_stream()); + minors.shrink_to_fit(handle.get_stream()); + } } - auto& [majors, minors, weights, p1, p2] = sample_e_op_results; - - return std::make_tuple( - std::move(majors), std::move(minors), std::make_optional(std::move(weights))); + return std::make_tuple(std::move(majors), std::move(minors), std::move(weights)); } } // namespace detail diff --git a/cpp/src/sampling/detail/sampling_utils_mg.cu b/cpp/src/sampling/detail/sampling_utils_mg.cu index 19fca7e7042..33ee8d871ec 100644 --- a/cpp/src/sampling/detail/sampling_utils_mg.cu +++ b/cpp/src/sampling/detail/sampling_utils_mg.cu @@ -23,7 +23,8 @@ template std::tuple, rmm::device_uvector, std::optional>> gather_one_hop_edgelist(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, rmm::device_uvector const& active_majors, bool do_expensive_check); @@ -31,7 +32,8 @@ template std::tuple, rmm::device_uvector, std::optional>> gather_one_hop_edgelist(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, rmm::device_uvector const& active_majors, bool do_expensive_check); @@ -39,39 +41,47 @@ template std::tuple, rmm::device_uvector, std::optional>> gather_one_hop_edgelist(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, rmm::device_uvector const& active_majors, bool do_expensive_check); template std::tuple, rmm::device_uvector, std::optional>> -gather_one_hop_edgelist(raft::handle_t const& handle, - graph_view_t const& graph_view, - rmm::device_uvector const& active_majors, - bool do_expensive_check); +gather_one_hop_edgelist( + raft::handle_t const& handle, + graph_view_t const& graph_view, + std::optional> edge_weight_view, + rmm::device_uvector const& active_majors, + bool do_expensive_check); template std::tuple, rmm::device_uvector, std::optional>> -gather_one_hop_edgelist(raft::handle_t const& handle, - graph_view_t const& graph_view, - rmm::device_uvector const& active_majors, - bool do_expensive_check); +gather_one_hop_edgelist( + raft::handle_t const& handle, + graph_view_t const& graph_view, + std::optional> edge_weight_view, + rmm::device_uvector const& active_majors, + bool do_expensive_check); template std::tuple, rmm::device_uvector, std::optional>> -gather_one_hop_edgelist(raft::handle_t const& handle, - graph_view_t const& graph_view, - rmm::device_uvector const& active_majors, - bool do_expensive_check); +gather_one_hop_edgelist( + raft::handle_t const& handle, + graph_view_t const& graph_view, + std::optional> edge_weight_view, + rmm::device_uvector const& active_majors, + bool do_expensive_check); template std::tuple, rmm::device_uvector, std::optional>> sample_edges(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, raft::random::RngState& rng_state, rmm::device_uvector const& active_majors, size_t fanout, @@ -81,7 +91,8 @@ template std::tuple, rmm::device_uvector, std::optional>> sample_edges(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, raft::random::RngState& rng_state, rmm::device_uvector const& active_majors, size_t fanout, @@ -91,7 +102,8 @@ template std::tuple, rmm::device_uvector, std::optional>> sample_edges(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, raft::random::RngState& rng_state, rmm::device_uvector const& active_majors, size_t fanout, @@ -101,7 +113,8 @@ template std::tuple, rmm::device_uvector, std::optional>> sample_edges(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, raft::random::RngState& rng_state, rmm::device_uvector const& active_majors, size_t fanout, @@ -111,7 +124,8 @@ template std::tuple, rmm::device_uvector, std::optional>> sample_edges(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, raft::random::RngState& rng_state, rmm::device_uvector const& active_majors, size_t fanout, @@ -121,7 +135,8 @@ template std::tuple, rmm::device_uvector, std::optional>> sample_edges(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, raft::random::RngState& rng_state, rmm::device_uvector const& active_majors, size_t fanout, diff --git a/cpp/src/sampling/detail/sampling_utils_sg.cu b/cpp/src/sampling/detail/sampling_utils_sg.cu index dd0f9d76ca4..54ad43efe52 100644 --- a/cpp/src/sampling/detail/sampling_utils_sg.cu +++ b/cpp/src/sampling/detail/sampling_utils_sg.cu @@ -77,7 +77,8 @@ template std::tuple, rmm::device_uvector, std::optional>> gather_one_hop_edgelist(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, rmm::device_uvector const& active_majors, bool do_expensive_check); @@ -85,7 +86,8 @@ template std::tuple, rmm::device_uvector, std::optional>> gather_one_hop_edgelist(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, rmm::device_uvector const& active_majors, bool do_expensive_check); @@ -93,39 +95,47 @@ template std::tuple, rmm::device_uvector, std::optional>> gather_one_hop_edgelist(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, rmm::device_uvector const& active_majors, bool do_expensive_check); template std::tuple, rmm::device_uvector, std::optional>> -gather_one_hop_edgelist(raft::handle_t const& handle, - graph_view_t const& graph_view, - rmm::device_uvector const& active_majors, - bool do_expensive_check); +gather_one_hop_edgelist( + raft::handle_t const& handle, + graph_view_t const& graph_view, + std::optional> edge_weight_view, + rmm::device_uvector const& active_majors, + bool do_expensive_check); template std::tuple, rmm::device_uvector, std::optional>> -gather_one_hop_edgelist(raft::handle_t const& handle, - graph_view_t const& graph_view, - rmm::device_uvector const& active_majors, - bool do_expensive_check); +gather_one_hop_edgelist( + raft::handle_t const& handle, + graph_view_t const& graph_view, + std::optional> edge_weight_view, + rmm::device_uvector const& active_majors, + bool do_expensive_check); template std::tuple, rmm::device_uvector, std::optional>> -gather_one_hop_edgelist(raft::handle_t const& handle, - graph_view_t const& graph_view, - rmm::device_uvector const& active_majors, - bool do_expensive_check); +gather_one_hop_edgelist( + raft::handle_t const& handle, + graph_view_t const& graph_view, + std::optional> edge_weight_view, + rmm::device_uvector const& active_majors, + bool do_expensive_check); template std::tuple, rmm::device_uvector, std::optional>> sample_edges(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, raft::random::RngState& rng_state, rmm::device_uvector const& active_majors, size_t fanout, @@ -135,7 +145,8 @@ template std::tuple, rmm::device_uvector, std::optional>> sample_edges(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, raft::random::RngState& rng_state, rmm::device_uvector const& active_majors, size_t fanout, @@ -145,7 +156,8 @@ template std::tuple, rmm::device_uvector, std::optional>> sample_edges(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, raft::random::RngState& rng_state, rmm::device_uvector const& active_majors, size_t fanout, @@ -155,7 +167,8 @@ template std::tuple, rmm::device_uvector, std::optional>> sample_edges(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, raft::random::RngState& rng_state, rmm::device_uvector const& active_majors, size_t fanout, @@ -165,7 +178,8 @@ template std::tuple, rmm::device_uvector, std::optional>> sample_edges(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, raft::random::RngState& rng_state, rmm::device_uvector const& active_majors, size_t fanout, @@ -175,7 +189,8 @@ template std::tuple, rmm::device_uvector, std::optional>> sample_edges(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, raft::random::RngState& rng_state, rmm::device_uvector const& active_majors, size_t fanout, diff --git a/cpp/src/sampling/neighborhood.cu b/cpp/src/sampling/neighborhood.cu index 14e3fcb6cc3..0f97f04ae38 100644 --- a/cpp/src/sampling/neighborhood.cu +++ b/cpp/src/sampling/neighborhood.cu @@ -24,18 +24,17 @@ namespace cugraph { -template -std::tuple, - rmm::device_uvector> +template +std::tuple, rmm::device_uvector> sample_neighbors_adjacency_list(raft::handle_t const& handle, raft::random::RngState& rng_state, - graph_t const& graph, - typename graph_t::vertex_type const* ptr_d_start, + graph_view_t const& graph_view, + vertex_t const* ptr_d_start, size_t num_start_vertices, size_t sampling_size, ops::gnn::graph::SamplingAlgoT sampling_algo) { - const auto [ops_graph, max_degree] = detail::get_graph_and_max_degree(graph); + const auto [ops_graph, max_degree] = detail::get_graph_and_max_degree(graph_view); return ops::gnn::graph::uniform_sample_csr(rng_state, ops_graph, ptr_d_start, @@ -46,18 +45,17 @@ sample_neighbors_adjacency_list(raft::handle_t const& handle, handle.get_stream()); } -template -std::tuple, - rmm::device_uvector> -sample_neighbors_edgelist(raft::handle_t const& handle, - raft::random::RngState& rng_state, - graph_t const& graph, - typename graph_t::vertex_type const* ptr_d_start, - size_t num_start_vertices, - size_t sampling_size, - ops::gnn::graph::SamplingAlgoT sampling_algo) +template +std::tuple, rmm::device_uvector> sample_neighbors_edgelist( + raft::handle_t const& handle, + raft::random::RngState& rng_state, + graph_view_t const& graph_view, + vertex_t const* ptr_d_start, + size_t num_start_vertices, + size_t sampling_size, + ops::gnn::graph::SamplingAlgoT sampling_algo) { - const auto [ops_graph, max_degree] = detail::get_graph_and_max_degree(graph); + const auto [ops_graph, max_degree] = detail::get_graph_and_max_degree(graph_view); return ops::gnn::graph::uniform_sample_coo(rng_state, ops_graph, ptr_d_start, @@ -72,46 +70,42 @@ sample_neighbors_edgelist(raft::handle_t const& handle, // // CSR SG FP32{ template std::tuple, rmm::device_uvector> -sample_neighbors_adjacency_list>( - raft::handle_t const& handle, - raft::random::RngState& rng_state, - graph_view_t const& gview, - int32_t const* ptr_d_start, - size_t num_start_vertices, - size_t sampling_size, - ops::gnn::graph::SamplingAlgoT sampling_algo); +sample_neighbors_adjacency_list(raft::handle_t const& handle, + raft::random::RngState& rng_state, + graph_view_t const& gview, + int32_t const* ptr_d_start, + size_t num_start_vertices, + size_t sampling_size, + ops::gnn::graph::SamplingAlgoT sampling_algo); template std::tuple, rmm::device_uvector> -sample_neighbors_adjacency_list>( - raft::handle_t const& handle, - raft::random::RngState& rng_state, - graph_view_t const& gview, - int64_t const* ptr_d_start, - size_t num_start_vertices, - size_t sampling_size, - ops::gnn::graph::SamplingAlgoT sampling_algo); +sample_neighbors_adjacency_list(raft::handle_t const& handle, + raft::random::RngState& rng_state, + graph_view_t const& gview, + int64_t const* ptr_d_start, + size_t num_start_vertices, + size_t sampling_size, + ops::gnn::graph::SamplingAlgoT sampling_algo); //} // // COO SG FP32{ template std::tuple, rmm::device_uvector> -sample_neighbors_edgelist>( - raft::handle_t const& handle, - raft::random::RngState& rng_state, - graph_view_t const& gview, - int32_t const* ptr_d_start, - size_t num_start_vertices, - size_t sampling_size, - ops::gnn::graph::SamplingAlgoT sampling_algo); +sample_neighbors_edgelist(raft::handle_t const& handle, + raft::random::RngState& rng_state, + graph_view_t const& gview, + int32_t const* ptr_d_start, + size_t num_start_vertices, + size_t sampling_size, + ops::gnn::graph::SamplingAlgoT sampling_algo); template std::tuple, rmm::device_uvector> -sample_neighbors_edgelist>( - raft::handle_t const& handle, - raft::random::RngState& rng_state, - graph_view_t const& gview, - int64_t const* ptr_d_start, - size_t num_start_vertices, - size_t sampling_size, - ops::gnn::graph::SamplingAlgoT sampling_algo); +sample_neighbors_edgelist(raft::handle_t const& handle, + raft::random::RngState& rng_state, + graph_view_t const& gview, + int64_t const* ptr_d_start, + size_t num_start_vertices, + size_t sampling_size, + ops::gnn::graph::SamplingAlgoT sampling_algo); //} } // namespace cugraph diff --git a/cpp/src/sampling/random_walks.cu b/cpp/src/sampling/random_walks.cu index b5f6b95ecb1..0e612163715 100644 --- a/cpp/src/sampling/random_walks.cu +++ b/cpp/src/sampling/random_walks.cu @@ -25,7 +25,8 @@ namespace cugraph { template std:: tuple, rmm::device_uvector, rmm::device_uvector> random_walks(raft::handle_t const& handle, - graph_view_t const& gview, + graph_view_t const& gview, + std::optional> edge_weight_view, int32_t const* ptr_d_start, int32_t num_paths, int32_t max_depth, @@ -35,7 +36,8 @@ template std:: template std:: tuple, rmm::device_uvector, rmm::device_uvector> random_walks(raft::handle_t const& handle, - graph_view_t const& gview, + graph_view_t const& gview, + std::optional> edge_weight_view, int32_t const* ptr_d_start, int64_t num_paths, int64_t max_depth, @@ -45,7 +47,8 @@ template std:: template std:: tuple, rmm::device_uvector, rmm::device_uvector> random_walks(raft::handle_t const& handle, - graph_view_t const& gview, + graph_view_t const& gview, + std::optional> edge_weight_view, int64_t const* ptr_d_start, int64_t num_paths, int64_t max_depth, @@ -57,7 +60,8 @@ template std:: template std:: tuple, rmm::device_uvector, rmm::device_uvector> random_walks(raft::handle_t const& handle, - graph_view_t const& gview, + graph_view_t const& gview, + std::optional> edge_weight_view, int32_t const* ptr_d_start, int32_t num_paths, int32_t max_depth, @@ -67,7 +71,8 @@ template std:: template std:: tuple, rmm::device_uvector, rmm::device_uvector> random_walks(raft::handle_t const& handle, - graph_view_t const& gview, + graph_view_t const& gview, + std::optional> edge_weight_view, int32_t const* ptr_d_start, int64_t num_paths, int64_t max_depth, @@ -77,7 +82,8 @@ template std:: template std:: tuple, rmm::device_uvector, rmm::device_uvector> random_walks(raft::handle_t const& handle, - graph_view_t const& gview, + graph_view_t const& gview, + std::optional> edge_weight_view, int64_t const* ptr_d_start, int64_t num_paths, int64_t max_depth, diff --git a/cpp/src/sampling/random_walks.cuh b/cpp/src/sampling/random_walks.cuh index 506b1ab7385..7336863a0b7 100644 --- a/cpp/src/sampling/random_walks.cuh +++ b/cpp/src/sampling/random_walks.cuh @@ -21,6 +21,7 @@ #include #include #include +#include #include @@ -156,35 +157,21 @@ struct rrandom_gen_t { seed_t seed_; // seed to be used for current batch }; -// classes abstracting the next vertex extraction mechanism: -// -// primary template, purposely undefined -template -struct col_indx_extract_t; - -// specialization for single-gpu functionality: -// -template -struct col_indx_extract_t> { - using vertex_t = typename graph_t::vertex_type; - using edge_t = typename graph_t::edge_type; - using weight_t = typename graph_t::weight_type; - +template +struct col_indx_extract_t { col_indx_extract_t(raft::handle_t const& handle, - graph_t const& graph, + graph_view_t const& graph_view, + std::optional> edge_weight_view, edge_t* p_d_crt_out_degs, index_t* p_d_sizes, index_t num_paths, index_t max_depth) : handle_(handle), - col_indices_(graph.local_edge_partition_view().indices().data()), - row_offsets_(graph.local_edge_partition_view().offsets().data()), - values_( - graph.local_edge_partition_view().weights() - ? std::optional{(*(graph.local_edge_partition_view().weights())).data()} - : std::nullopt), + col_indices_(graph_view.local_edge_partition_view().indices().data()), + row_offsets_(graph_view.local_edge_partition_view().offsets().data()), + values_(edge_weight_view + ? std::optional{(*edge_weight_view).value_firsts()[0]} + : std::nullopt), out_degs_(p_d_crt_out_degs), sizes_(p_d_sizes), num_paths_(num_paths), @@ -349,14 +336,12 @@ struct col_indx_extract_t, - typename index_t = typename graph_t::edge_type> +template , + typename index_t = edge_t> struct random_walker_t { - using vertex_t = typename graph_t::vertex_type; - using edge_t = typename graph_t::edge_type; - using weight_t = typename graph_t::weight_type; using seed_t = typename random_engine_t::seed_type; using real_t = typename random_engine_t::real_type; using rnd_engine_t = random_engine_t; @@ -428,7 +413,8 @@ struct random_walker_t { // template void step( - graph_t const& graph, + graph_view_t const& graph_view, + std::optional> edge_weight_view, selector_t const& selector, seed_t seed, original::device_vec_t& d_coalesced_v, // crt coalesced vertex set @@ -447,12 +433,14 @@ struct random_walker_t { // dst extraction from dst indices: // (d_crt_out_degs to be maintained internally by col_extractor) // - col_indx_extract_t col_extractor(handle_, - graph, - original::raw_ptr(d_crt_out_degs), - original::raw_ptr(d_paths_sz), - num_paths_, - max_depth_); + col_indx_extract_t col_extractor( + handle_, + graph_view, + edge_weight_view, + original::raw_ptr(d_crt_out_degs), + original::raw_ptr(d_paths_sz), + num_paths_, + max_depth_); // The following steps update the next entry in each path, // except the paths that reached sinks; @@ -656,9 +644,10 @@ struct random_walker_t { [] __device__(auto crt_out_deg) { return crt_out_deg > 0; }); } - original::device_vec_t get_out_degs(graph_t const& graph) const + original::device_vec_t get_out_degs( + graph_view_t const& graph_view) const { - return graph.compute_out_degrees(handle_); + return graph_view.compute_out_degrees(handle_); } vertex_t get_vertex_padding_value(void) const { return vertex_padding_value_; } @@ -723,34 +712,32 @@ struct random_walker_t { * entries; */ template < - typename graph_t, + typename vertex_t, + typename edge_t, + typename weight_t, typename selector_t, - typename traversal_t = original::horizontal_traversal_t, - typename random_engine_t = - rrandom_gen_t, + typename traversal_t = original::horizontal_traversal_t, + typename random_engine_t = rrandom_gen_t, typename seeding_policy_t = original::clock_seeding_t, - typename index_t = typename graph_t::edge_type> -std::enable_if_t, - original::device_vec_t, - original::device_vec_t, - typename random_engine_t::seed_type>> + typename index_t = edge_t> +std::tuple, + original::device_vec_t, + original::device_vec_t, + typename random_engine_t::seed_type> random_walks_impl( raft::handle_t const& handle, - graph_t const& graph, - original::device_const_vector_view& d_v_start, + graph_view_t const& graph_view, + std::optional> edge_weight_view, + original::device_const_vector_view& d_v_start, index_t max_depth, selector_t const& selector, bool use_padding = false, seeding_policy_t seeder = original::clock_seeding_t{}) { - using vertex_t = typename graph_t::vertex_type; - using edge_t = typename graph_t::edge_type; - using weight_t = typename graph_t::weight_type; - using seed_t = typename random_engine_t::seed_type; - using real_t = typename random_engine_t::real_type; + using seed_t = typename random_engine_t::seed_type; + using real_t = typename random_engine_t::real_type; - vertex_t num_vertices = graph.number_of_vertices(); + vertex_t num_vertices = graph_view.number_of_vertices(); auto how_many_valid = thrust::count_if(handle.get_thrust_policy(), d_v_start.begin(), @@ -765,10 +752,11 @@ random_walks_impl( auto num_paths = d_v_start.size(); auto stream = handle.get_stream(); - random_walker_t rand_walker{handle, - graph.number_of_vertices(), - static_cast(num_paths), - static_cast(max_depth)}; + random_walker_t rand_walker{ + handle, + graph_view.number_of_vertices(), + static_cast(num_paths), + static_cast(max_depth)}; // pre-allocate num_paths * max_depth; // @@ -805,7 +793,8 @@ random_walks_impl( // traverse paths: // - traversor(graph, + traversor(graph_view, + edge_weight_view, rand_walker, selector, seed0, @@ -839,64 +828,6 @@ random_walks_impl( } } -/** - * @brief returns random walks (RW) from starting sources, where each path is of given maximum - * length. Multi-GPU specialization. - * - * @tparam graph_t Type of graph (view). - * @tparam traversal_t Traversal policy. Either horizontal (faster but requires more memory) or - * vertical. Defaults to horizontal. - * @tparam random_engine_t Type of random engine used to generate RW. - * @tparam seeding_policy_t Random engine seeding policy: variable or fixed (for reproducibility). - * Defaults to variable, clock dependent. - * @tparam index_t Indexing type. Defaults to edge_type. - * @param handle RAFT handle object to encapsulate resources (e.g. CUDA stream, communicator, and - * handles to various CUDA libraries) to run graph algorithms. - * @param graph Graph object to generate RW on. - * @param d_v_start Device (view) set of starting vertex indices for the RW. number(RW) == - * d_v_start.size(). - * @param max_depth maximum length of RWs. - * @param use_padding (optional) specifies if return uses padded format (true), or coalesced - * (compressed) format; when padding is used the output is a matrix of vertex paths and a matrix of - * edges paths (weights); in this case the matrices are stored in row major order; the vertex path - * matrix is padded with `num_vertices` values and the weight matrix is padded with `0` values; - * @param seeder (optional) is object providing the random seeding mechanism. Defaults to local - * clock time as initial seed. - * @return std::tuple, device_vec_t, - * device_vec_t> Triplet of either padded or coalesced RW paths; in the coalesced case - * (default), the return consists of corresponding vertex and edge weights for each, and - * corresponding path sizes. This is meant to minimize the number of DF's to be passed to the Python - * layer. The meaning of "coalesced" here is that a 2D array of paths of different sizes is - * represented as a 1D contiguous array. In the padded case the return is a matrix of num_paths x - * max_depth vertex paths; and num_paths x (max_depth-1) edge (weight) paths, with an empty array of - * sizes. Note: if the graph is un-weighted the edge (weight) paths consists of `weight_t{1}` - * entries; - */ -template < - typename graph_t, - typename selector_t, - typename traversal_t = original::horizontal_traversal_t, - typename random_engine_t = - rrandom_gen_t, - typename seeding_policy_t = original::clock_seeding_t, - typename index_t = typename graph_t::edge_type> -std::enable_if_t, - original::device_vec_t, - original::device_vec_t, - typename random_engine_t::seed_type>> -random_walks_impl( - raft::handle_t const& handle, - graph_t const& graph, - original::device_const_vector_view& d_v_start, - index_t max_depth, - selector_t const& selector, - bool use_padding = false, - seeding_policy_t seeder = original::clock_seeding_t{}) -{ - CUGRAPH_FAIL("Not implemented yet."); -} - // provides conversion to (coalesced) path to COO format: // (which in turn provides an API consistent with egonet) // @@ -1078,24 +1009,23 @@ struct coo_convertor_t { * sizes. Note: if the graph is un-weighted the edge (weight) paths consists of `weight_t{1}` * entries; */ -template -std::tuple, - rmm::device_uvector, - rmm::device_uvector> -random_walks(raft::handle_t const& handle, - graph_t const& graph, - typename graph_t::vertex_type const* ptr_d_start, - index_t num_paths, - index_t max_depth, - bool use_padding, - std::unique_ptr sampling_strategy) +template +std:: + tuple, rmm::device_uvector, rmm::device_uvector> + random_walks(raft::handle_t const& handle, + graph_view_t const& graph_view, + std::optional> edge_weight_view, + vertex_t const* ptr_d_start, + index_t num_paths, + index_t max_depth, + bool use_padding, + std::unique_ptr sampling_strategy) { - using vertex_t = typename graph_t::vertex_type; - using edge_t = typename graph_t::edge_type; - using weight_t = typename graph_t::weight_type; - using real_t = float; // random engine type; + using real_t = float; // random engine type; // FIXME: this should not be hardcoded; at least tag-dispatched + if constexpr (multi_gpu) { CUGRAPH_FAIL("unimplemented."); } + // 0-copy const device view: // detail::original::device_const_vector_view d_v_start{ptr_d_start, num_paths}; @@ -1138,11 +1068,17 @@ random_walks(raft::handle_t const& handle, if (use_vertical_strategy) { if (selector_type == static_cast(sampling_strategy_t::BIASED)) { - detail::original::biased_selector_t selector{handle, graph, real_t{0}}; - - auto quad_tuple = detail:: - random_walks_impl( - handle, graph, d_v_start, max_depth, selector, use_padding); + CUGRAPH_EXPECTS(edge_weight_view.has_value(), "biased selector requires edge weights."); + auto out_weight_sums = compute_out_weight_sums(handle, graph_view, *edge_weight_view); + detail::original::biased_selector_t selector{ + handle, graph_view, *edge_weight_view, real_t{0}, out_weight_sums.data()}; + + auto quad_tuple = detail::random_walks_impl( + handle, graph_view, edge_weight_view, d_v_start, max_depth, selector, use_padding); // ignore last element of the quad, seed, // since it's meant for testing / debugging, only: // @@ -1160,12 +1096,15 @@ random_walks(raft::handle_t const& handle, CUGRAPH_EXPECTS(q > roundoff, "node2vec q parameter is too small."); - detail::original::node2vec_selector_t selector{ - handle, graph, real_t{0}, p, q, alpha_num_paths}; + detail::original::node2vec_selector_t selector{ + handle, graph_view, edge_weight_view, real_t{0}, p, q, alpha_num_paths}; - auto quad_tuple = detail:: - random_walks_impl( - handle, graph, d_v_start, max_depth, selector, use_padding); + auto quad_tuple = detail::random_walks_impl( + handle, graph_view, edge_weight_view, d_v_start, max_depth, selector, use_padding); // ignore last element of the quad, seed, // since it's meant for testing / debugging, only: // @@ -1173,11 +1112,15 @@ random_walks(raft::handle_t const& handle, std::move(std::get<1>(quad_tuple)), std::move(std::get<2>(quad_tuple))); } else { - detail::original::uniform_selector_t selector{handle, graph, real_t{0}}; - - auto quad_tuple = detail:: - random_walks_impl( - handle, graph, d_v_start, max_depth, selector, use_padding); + detail::original::uniform_selector_t selector{ + handle, graph_view, edge_weight_view, real_t{0}}; + + auto quad_tuple = detail::random_walks_impl( + handle, graph_view, edge_weight_view, d_v_start, max_depth, selector, use_padding); // ignore last element of the quad, seed, // since it's meant for testing / debugging, only: // @@ -1187,10 +1130,13 @@ random_walks(raft::handle_t const& handle, } } else { // horizontal traversal strategy if (selector_type == static_cast(sampling_strategy_t::BIASED)) { - detail::original::biased_selector_t selector{handle, graph, real_t{0}}; + CUGRAPH_EXPECTS(edge_weight_view.has_value(), "biased selector requires edge weights."); + auto out_weight_sums = compute_out_weight_sums(handle, graph_view, *edge_weight_view); + detail::original::biased_selector_t selector{ + handle, graph_view, *edge_weight_view, real_t{0}, out_weight_sums.data()}; - auto quad_tuple = - detail::random_walks_impl(handle, graph, d_v_start, max_depth, selector, use_padding); + auto quad_tuple = detail::random_walks_impl( + handle, graph_view, edge_weight_view, d_v_start, max_depth, selector, use_padding); // ignore last element of the quad, seed, // since it's meant for testing / debugging, only: // @@ -1208,11 +1154,11 @@ random_walks(raft::handle_t const& handle, CUGRAPH_EXPECTS(q > roundoff, "node2vec q parameter is too small."); - detail::original::node2vec_selector_t selector{ - handle, graph, real_t{0}, p, q, alpha_num_paths}; + detail::original::node2vec_selector_t selector{ + handle, graph_view, edge_weight_view, real_t{0}, p, q, alpha_num_paths}; - auto quad_tuple = - detail::random_walks_impl(handle, graph, d_v_start, max_depth, selector, use_padding); + auto quad_tuple = detail::random_walks_impl( + handle, graph_view, edge_weight_view, d_v_start, max_depth, selector, use_padding); // ignore last element of the quad, seed, // since it's meant for testing / debugging, only: // @@ -1220,10 +1166,11 @@ random_walks(raft::handle_t const& handle, std::move(std::get<1>(quad_tuple)), std::move(std::get<2>(quad_tuple))); } else { - detail::original::uniform_selector_t selector{handle, graph, real_t{0}}; + detail::original::uniform_selector_t selector{ + handle, graph_view, edge_weight_view, real_t{0}}; - auto quad_tuple = - detail::random_walks_impl(handle, graph, d_v_start, max_depth, selector, use_padding); + auto quad_tuple = detail::random_walks_impl( + handle, graph_view, edge_weight_view, d_v_start, max_depth, selector, use_padding); // ignore last element of the quad, seed, // since it's meant for testing / debugging, only: // diff --git a/cpp/src/sampling/random_walks_impl.cuh b/cpp/src/sampling/random_walks_impl.cuh index 4fb703b48e7..d286738d014 100644 --- a/cpp/src/sampling/random_walks_impl.cuh +++ b/cpp/src/sampling/random_walks_impl.cuh @@ -51,17 +51,24 @@ inline uint64_t get_current_time_nanoseconds() return current_time.tv_sec * 1000000000 + current_time.tv_nsec; } -template +template struct sample_edges_op_t { - using result_t = thrust::tuple; + template + __device__ std::enable_if_t, vertex_t> operator()( + vertex_t, vertex_t dst, thrust::nullopt_t, thrust::nullopt_t, thrust::nullopt_t) const + { + return dst; + } - __device__ result_t operator()( - vertex_t src, vertex_t dst, weight_t wgt, property_t src_prop, property_t dst_prop) const + template + __device__ std::enable_if_t, thrust::tuple> operator()( + vertex_t, vertex_t dst, thrust::nullopt_t, thrust::nullopt_t, W w) const { - return thrust::make_tuple(src, dst, wgt, src_prop, dst_prop); + return thrust::make_tuple(dst, w); } }; +template struct uniform_selector { raft::random::RngState rng_state_; @@ -69,19 +76,15 @@ struct uniform_selector { template std::tuple, - std::optional>> + std::optional>> follow_random_edge( raft::handle_t const& handle, GraphViewType const& graph_view, + std::optional> + edge_weight_view, rmm::device_uvector const& current_vertices) { using vertex_t = typename GraphViewType::vertex_type; - using weight_t = typename GraphViewType::weight_type; - - // FIXME: Shouldn't there be a dummy property equivalent here? - using property_t = int32_t; - cugraph::edge_src_property_t src_properties(handle, graph_view); - cugraph::edge_dst_property_t dst_properties(handle, graph_view); // FIXME: add as a template parameter using tag_t = void; @@ -91,36 +94,59 @@ struct uniform_selector { vertex_frontier.bucket(0).insert(current_vertices.begin(), current_vertices.end()); - using result_t = thrust::tuple; - - auto [sample_offsets, sample_e_op_results] = cugraph::per_v_random_select_transform_outgoing_e( - handle, - graph_view, - vertex_frontier.bucket(0), - src_properties.view(), - dst_properties.view(), - sample_edges_op_t{}, - rng_state_, - size_t{1}, - true, - std::make_optional(result_t{cugraph::invalid_vertex_id::value, - cugraph::invalid_vertex_id::value})); - - auto& [majors, minors, weights, p1, p2] = sample_e_op_results; - - return std::make_tuple(std::move(minors), std::make_optional(std::move(weights))); + rmm::device_uvector minors(0, handle.get_stream()); + std::optional> weights{std::nullopt}; + if (edge_weight_view) { + auto [sample_offsets, sample_e_op_results] = + cugraph::per_v_random_select_transform_outgoing_e( + handle, + graph_view, + vertex_frontier.bucket(0), + edge_src_dummy_property_t{}.view(), + edge_dst_dummy_property_t{}.view(), + *edge_weight_view, + sample_edges_op_t{}, + rng_state_, + size_t{1}, + true, + std::make_optional( + thrust::make_tuple(cugraph::invalid_vertex_id::value, weight_t{0.0}))); + + minors = std::move(std::get<0>(sample_e_op_results)); + weights = std::move(std::get<1>(sample_e_op_results)); + } else { + auto [sample_offsets, sample_e_op_results] = + cugraph::per_v_random_select_transform_outgoing_e( + handle, + graph_view, + vertex_frontier.bucket(0), + edge_src_dummy_property_t{}.view(), + edge_dst_dummy_property_t{}.view(), + edge_dummy_property_t{}.view(), + sample_edges_op_t{}, + rng_state_, + size_t{1}, + true, + std::make_optional(vertex_t{cugraph::invalid_vertex_id::value})); + + minors = std::move(sample_e_op_results); + } + return std::make_tuple(std::move(minors), std::move(weights)); } }; +template struct biased_selector { uint64_t seed_{0}; template std::tuple, - std::optional>> + std::optional>> follow_random_edge( raft::handle_t const& handle, GraphViewType const& graph_view, + std::optional> + edge_weight_view, rmm::device_uvector const& current_vertices) { // To do biased sampling, I need out_weights instead of out_degrees. @@ -140,10 +166,12 @@ struct node2vec_selector { template std::tuple, - std::optional>> + std::optional>> follow_random_edge( raft::handle_t const& handle, GraphViewType const& graph_view, + std::optional> + edge_weight_view, rmm::device_uvector const& current_vertices) { // To do node2vec, I need the following: @@ -164,14 +192,15 @@ template std::tuple, std::optional>> random_walk_impl(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, raft::device_span start_vertices, size_t max_length, random_selector_t random_selector) { rmm::device_uvector result_vertices(start_vertices.size() * (max_length + 1), handle.get_stream()); - auto result_weights = graph_view.is_weighted() + auto result_weights = edge_weight_view ? std::make_optional>( start_vertices.size() * max_length, handle.get_stream()) : std::nullopt; @@ -186,7 +215,7 @@ random_walk_impl(raft::handle_t const& handle, rmm::device_uvector current_vertices(start_vertices.size(), handle.get_stream()); rmm::device_uvector current_position(0, handle.get_stream()); rmm::device_uvector current_gpu(0, handle.get_stream()); - auto new_weights = graph_view.is_weighted() + auto new_weights = edge_weight_view ? std::make_optional>(0, handle.get_stream()) : std::nullopt; @@ -241,7 +270,7 @@ random_walk_impl(raft::handle_t const& handle, } std::tie(current_vertices, new_weights) = - random_selector.follow_random_edge(handle, graph_view, current_vertices); + random_selector.follow_random_edge(handle, graph_view, edge_weight_view, current_vertices); if constexpr (multi_gpu) { // @@ -385,28 +414,32 @@ random_walk_impl(raft::handle_t const& handle, return std::make_tuple(std::move(result_vertices), std::move(result_weights)); } + } // namespace detail template std::tuple, std::optional>> uniform_random_walks(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, raft::device_span start_vertices, size_t max_length, uint64_t seed) { - return detail::random_walk_impl( - handle, - graph_view, - start_vertices, - max_length, - detail::uniform_selector((seed == 0 ? detail::get_current_time_nanoseconds() : seed))); + return detail::random_walk_impl(handle, + graph_view, + edge_weight_view, + start_vertices, + max_length, + detail::uniform_selector( + (seed == 0 ? detail::get_current_time_nanoseconds() : seed))); } template std::tuple, std::optional>> biased_random_walks(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view, raft::device_span start_vertices, size_t max_length, uint64_t seed) @@ -414,15 +447,17 @@ biased_random_walks(raft::handle_t const& handle, return detail::random_walk_impl( handle, graph_view, + std::optional>{edge_weight_view}, start_vertices, max_length, - detail::biased_selector{(seed == 0 ? detail::get_current_time_nanoseconds() : seed)}); + detail::biased_selector{(seed == 0 ? detail::get_current_time_nanoseconds() : seed)}); } template std::tuple, std::optional>> node2vec_random_walks(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, raft::device_span start_vertices, size_t max_length, weight_t p, @@ -432,6 +467,7 @@ node2vec_random_walks(raft::handle_t const& handle, return detail::random_walk_impl( handle, graph_view, + edge_weight_view, start_vertices, max_length, detail::node2vec_selector{ diff --git a/cpp/src/sampling/random_walks_mg.cu b/cpp/src/sampling/random_walks_mg.cu index c7c71d11be4..61da5559474 100644 --- a/cpp/src/sampling/random_walks_mg.cu +++ b/cpp/src/sampling/random_walks_mg.cu @@ -22,91 +22,104 @@ namespace cugraph { template std::tuple, std::optional>> uniform_random_walks(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, raft::device_span start_vertices, size_t max_length, uint64_t seed); template std::tuple, std::optional>> uniform_random_walks(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, raft::device_span start_vertices, size_t max_length, uint64_t seed); template std::tuple, std::optional>> uniform_random_walks(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, raft::device_span start_vertices, size_t max_length, uint64_t seed); template std::tuple, std::optional>> uniform_random_walks(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, raft::device_span start_vertices, size_t max_length, uint64_t seed); template std::tuple, std::optional>> uniform_random_walks(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, raft::device_span start_vertices, size_t max_length, uint64_t seed); template std::tuple, std::optional>> uniform_random_walks(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, raft::device_span start_vertices, size_t max_length, uint64_t seed); template std::tuple, std::optional>> biased_random_walks(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view, raft::device_span start_vertices, size_t max_length, uint64_t seed); template std::tuple, std::optional>> biased_random_walks(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view, raft::device_span start_vertices, size_t max_length, uint64_t seed); template std::tuple, std::optional>> biased_random_walks(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view, raft::device_span start_vertices, size_t max_length, uint64_t seed); template std::tuple, std::optional>> biased_random_walks(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view, raft::device_span start_vertices, size_t max_length, uint64_t seed); template std::tuple, std::optional>> biased_random_walks(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view, raft::device_span start_vertices, size_t max_length, uint64_t seed); template std::tuple, std::optional>> biased_random_walks(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view, raft::device_span start_vertices, size_t max_length, uint64_t seed); template std::tuple, std::optional>> node2vec_random_walks(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, raft::device_span start_vertices, size_t max_length, float p, @@ -115,7 +128,8 @@ node2vec_random_walks(raft::handle_t const& handle, template std::tuple, std::optional>> node2vec_random_walks(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, raft::device_span start_vertices, size_t max_length, float p, @@ -124,7 +138,8 @@ node2vec_random_walks(raft::handle_t const& handle, template std::tuple, std::optional>> node2vec_random_walks(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, raft::device_span start_vertices, size_t max_length, float p, @@ -133,7 +148,8 @@ node2vec_random_walks(raft::handle_t const& handle, template std::tuple, std::optional>> node2vec_random_walks(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, raft::device_span start_vertices, size_t max_length, double p, @@ -142,7 +158,8 @@ node2vec_random_walks(raft::handle_t const& handle, template std::tuple, std::optional>> node2vec_random_walks(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, raft::device_span start_vertices, size_t max_length, double p, @@ -151,7 +168,8 @@ node2vec_random_walks(raft::handle_t const& handle, template std::tuple, std::optional>> node2vec_random_walks(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, raft::device_span start_vertices, size_t max_length, double p, diff --git a/cpp/src/sampling/random_walks_sg.cu b/cpp/src/sampling/random_walks_sg.cu index fde8baccb1f..d37717f7485 100644 --- a/cpp/src/sampling/random_walks_sg.cu +++ b/cpp/src/sampling/random_walks_sg.cu @@ -22,91 +22,104 @@ namespace cugraph { template std::tuple, std::optional>> uniform_random_walks(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, raft::device_span start_vertices, size_t max_length, uint64_t seed); template std::tuple, std::optional>> uniform_random_walks(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, raft::device_span start_vertices, size_t max_length, uint64_t seed); template std::tuple, std::optional>> uniform_random_walks(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, raft::device_span start_vertices, size_t max_length, uint64_t seed); template std::tuple, std::optional>> uniform_random_walks(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, raft::device_span start_vertices, size_t max_length, uint64_t seed); template std::tuple, std::optional>> uniform_random_walks(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, raft::device_span start_vertices, size_t max_length, uint64_t seed); template std::tuple, std::optional>> uniform_random_walks(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, raft::device_span start_vertices, size_t max_length, uint64_t seed); template std::tuple, std::optional>> biased_random_walks(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view, raft::device_span start_vertices, size_t max_length, uint64_t seed); template std::tuple, std::optional>> biased_random_walks(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view, raft::device_span start_vertices, size_t max_length, uint64_t seed); template std::tuple, std::optional>> biased_random_walks(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view, raft::device_span start_vertices, size_t max_length, uint64_t seed); template std::tuple, std::optional>> biased_random_walks(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view, raft::device_span start_vertices, size_t max_length, uint64_t seed); template std::tuple, std::optional>> biased_random_walks(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view, raft::device_span start_vertices, size_t max_length, uint64_t seed); template std::tuple, std::optional>> biased_random_walks(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view, raft::device_span start_vertices, size_t max_length, uint64_t seed); template std::tuple, std::optional>> node2vec_random_walks(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, raft::device_span start_vertices, size_t max_length, float p, @@ -115,7 +128,8 @@ node2vec_random_walks(raft::handle_t const& handle, template std::tuple, std::optional>> node2vec_random_walks(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, raft::device_span start_vertices, size_t max_length, float p, @@ -124,7 +138,8 @@ node2vec_random_walks(raft::handle_t const& handle, template std::tuple, std::optional>> node2vec_random_walks(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, raft::device_span start_vertices, size_t max_length, float p, @@ -133,7 +148,8 @@ node2vec_random_walks(raft::handle_t const& handle, template std::tuple, std::optional>> node2vec_random_walks(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, raft::device_span start_vertices, size_t max_length, double p, @@ -142,7 +158,8 @@ node2vec_random_walks(raft::handle_t const& handle, template std::tuple, std::optional>> node2vec_random_walks(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, raft::device_span start_vertices, size_t max_length, double p, @@ -151,7 +168,8 @@ node2vec_random_walks(raft::handle_t const& handle, template std::tuple, std::optional>> node2vec_random_walks(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, raft::device_span start_vertices, size_t max_length, double p, diff --git a/cpp/src/sampling/rw_traversals.hpp b/cpp/src/sampling/rw_traversals.hpp index 20c08f31249..1055d719d3e 100644 --- a/cpp/src/sampling/rw_traversals.hpp +++ b/cpp/src/sampling/rw_traversals.hpp @@ -20,8 +20,6 @@ #include #include -#include -#include #include @@ -132,12 +130,8 @@ struct fixed_seeding_t { // Uniform RW selector logic: // -template +template struct uniform_selector_t { - using vertex_t = typename graph_type::vertex_type; - using edge_t = typename graph_type::edge_type; - using weight_t = typename graph_type::weight_type; - struct sampler_t { sampler_t(edge_t const* ro, vertex_t const* ci, @@ -178,14 +172,16 @@ struct uniform_selector_t { using sampler_type = sampler_t; - uniform_selector_t(raft::handle_t const& handle, graph_type const& graph, real_t tag) - : d_cache_out_degs_(graph.compute_out_degrees(handle)), - sampler_{graph.local_edge_partition_view().offsets().data(), - graph.local_edge_partition_view().indices().data(), - graph.local_edge_partition_view().weights() - ? (*(graph.local_edge_partition_view().weights())).data() - : static_cast(nullptr), - d_cache_out_degs_.data()} + uniform_selector_t(raft::handle_t const& handle, + graph_view_t const& graph_view, + std::optional> edge_weight_view, + real_t tag) + : d_cache_out_degs_(graph_view.compute_out_degrees(handle)), + sampler_{ + graph_view.local_edge_partition_view().offsets().data(), + graph_view.local_edge_partition_view().indices().data(), + edge_weight_view ? (*edge_weight_view).value_firsts()[0] : static_cast(nullptr), + d_cache_out_degs_.data()} { } @@ -200,102 +196,10 @@ struct uniform_selector_t { // because it ows a device_vec; }; -template > -struct visitor_aggregate_weights_t : visitors::visitor_t { - visitor_aggregate_weights_t( - raft::handle_t const& handle, - size_t num_vertices, - binary_op_t aggregate_op = thrust::plus{}, - weight_t initial_value = 0) // different aggregation ops require different initial values; - : handle_(handle), - d_aggregate_weights_(num_vertices, handle_.get_stream()), - aggregator_(aggregate_op), - initial_value_(initial_value) - { - } - - void visit_graph(graph_envelope_t::base_graph_t const& graph_v) override - { - auto const& graph_view = - static_cast const&>(graph_v); - - auto opt_weights = graph_view.local_edge_partition_view().weights(); - CUGRAPH_EXPECTS(opt_weights.has_value(), "Cannot aggregate weights of un-weighted graph."); - - size_t num_vertices = d_aggregate_weights_.size(); - - edge_t const* offsets = graph_view.local_edge_partition_view().offsets().data(); - - weight_t const* values = (*opt_weights).data(); - - // Determine temporary device storage requirements: - // - void* ptr_d_temp_storage{nullptr}; - size_t temp_storage_bytes = 0; - cub::DeviceSegmentedReduce::Reduce(ptr_d_temp_storage, - temp_storage_bytes, - values, - d_aggregate_weights_.data(), - num_vertices, - offsets, - offsets + 1, - aggregator_, - initial_value_, - handle_.get_stream()); - // Allocate temporary storage - // - rmm::device_uvector d_temp_storage(temp_storage_bytes, handle_.get_stream()); - ptr_d_temp_storage = d_temp_storage.data(); - - // Run reduction: - // - cub::DeviceSegmentedReduce::Reduce(ptr_d_temp_storage, - temp_storage_bytes, - values, - d_aggregate_weights_.data(), - num_vertices, - offsets, - offsets + 1, - aggregator_, - initial_value_, - handle_.get_stream()); - } - - // no need for type-erasure, as this is only used internally: - // - visitors::return_t const& get_result(void) const override { return ret_unused_; } - - visitors::return_t&& get_result(void) override { return std::move(ret_unused_); } - - rmm::device_uvector&& get_aggregated_weights(void) - { - return std::move(d_aggregate_weights_); - } - - rmm::device_uvector const& get_aggregated_weights(void) const - { - return d_aggregate_weights_; - } - - private: - raft::handle_t const& handle_; - rmm::device_uvector d_aggregate_weights_; - binary_op_t aggregator_; - weight_t initial_value_{0}; - visitors::return_t ret_unused_{}; // necessary to silence a concerning warning -}; - // Biased RW selection logic: // -template +template struct biased_selector_t { - using vertex_t = typename graph_type::vertex_type; - using edge_t = typename graph_type::edge_type; - using weight_t = typename graph_type::weight_type; - struct sampler_t { sampler_t(edge_t const* ro, vertex_t const* ci, @@ -347,24 +251,21 @@ struct biased_selector_t { using sampler_type = sampler_t; - biased_selector_t(raft::handle_t const& handle, graph_type const& graph, real_t tag) - : sum_calculator_(handle, graph.number_of_vertices()), - sampler_{graph.local_edge_partition_view().offsets().data(), - graph.local_edge_partition_view().indices().data(), - graph.local_edge_partition_view().weights() - ? (*(graph.local_edge_partition_view().weights())).data() - : static_cast(nullptr), - sum_calculator_.get_aggregated_weights().data()} + biased_selector_t(raft::handle_t const& handle, + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view, + real_t tag, + weight_t const* out_weight_sums) + : sampler_{graph_view.local_edge_partition_view().offsets().data(), + graph_view.local_edge_partition_view().indices().data(), + edge_weight_view.value_firsts()[0], + out_weight_sums} { - graph.apply(sum_calculator_); } sampler_t const& get_strategy(void) const { return sampler_; } - decltype(auto) get_sum_weights(void) const { return sum_calculator_.get_aggregated_weights(); } - private: - visitor_aggregate_weights_t sum_calculator_; sampler_t sampler_; }; @@ -377,12 +278,8 @@ struct biased_selector_t { // TODO: need to decide logic on very 1st step of traversal // (which has no `prev_v` vertex); // -template +template struct node2vec_selector_t { - using vertex_t = typename graph_type::vertex_type; - using edge_t = typename graph_type::edge_type; - using weight_t = typename graph_type::weight_type; - struct sampler_t { sampler_t(edge_t const* ro, vertex_t const* ci, @@ -573,23 +470,23 @@ struct node2vec_selector_t { using sampler_type = sampler_t; node2vec_selector_t(raft::handle_t const& handle, - graph_type const& graph, + graph_view_t const& graph_view, + std::optional> edge_weight_view, real_t tag, weight_t p, weight_t q, edge_t num_paths = 0) - : max_out_degree_(num_paths > 0 ? graph.compute_max_out_degree(handle) : 0), + : max_out_degree_(num_paths > 0 ? graph_view.compute_max_out_degree(handle) : 0), d_coalesced_alpha_{max_out_degree_ * num_paths, handle.get_stream()}, - sampler_{graph.local_edge_partition_view().offsets().data(), - graph.local_edge_partition_view().indices().data(), - graph.local_edge_partition_view().weights() - ? (*(graph.local_edge_partition_view().weights())).data() - : static_cast(nullptr), - p, - q, - static_cast(max_out_degree_), - num_paths, - raw_ptr(d_coalesced_alpha_)} + sampler_{ + graph_view.local_edge_partition_view().offsets().data(), + graph_view.local_edge_partition_view().indices().data(), + edge_weight_view ? (*edge_weight_view).value_firsts()[0] : static_cast(nullptr), + p, + q, + static_cast(max_out_degree_), + num_paths, + raw_ptr(d_coalesced_alpha_)} { } @@ -625,25 +522,26 @@ struct vertical_traversal_t { { } - template void operator()( - graph_t const& graph, // graph being traversed - random_walker_t const& rand_walker, // random walker object for which traversal is driven - selector_t const& selector, // sampling type (uniform, biased, etc.) - seed_t seed0, // initial seed value - device_vec_t& d_coalesced_v, // crt coalesced vertex set - device_vec_t& d_coalesced_w, // crt coalesced weight set - device_vec_t& d_paths_sz, // crt paths sizes - device_vec_t& - d_crt_out_degs, // crt out-degs for current set of vertices - device_vec_t& d_random, // crt set of random real values - device_vec_t& - d_col_indx) // crt col col indices to be used for retrieving next step + graph_view_t const& graph_view, // graph being traversed + std::optional> edge_weight_view, + random_walker_t const& rand_walker, // random walker object for which traversal is driven + selector_t const& selector, // sampling type (uniform, biased, etc.) + seed_t seed0, // initial seed value + device_vec_t& d_coalesced_v, // crt coalesced vertex set + device_vec_t& d_coalesced_w, // crt coalesced weight set + device_vec_t& d_paths_sz, // crt paths sizes + device_vec_t& d_crt_out_degs, // crt out-degs for current set of vertices + device_vec_t& d_random, // crt set of random real values + device_vec_t& d_col_indx) // crt col col indices to be used for retrieving next step const { auto const& handle = rand_walker.get_handle(); @@ -653,7 +551,8 @@ struct vertical_traversal_t { for (decltype(max_depth_) step_indx = 1; step_indx < max_depth_; ++step_indx) { // take one-step in-sync for each path in parallel: // - rand_walker.step(graph, + rand_walker.step(graph_view, + edge_weight_view, selector, seed0 + static_cast(step_indx), d_coalesced_v, @@ -690,31 +589,29 @@ struct horizontal_traversal_t { { } - template void operator()( - graph_t const& graph, // graph being traversed - random_walker_t const& rand_walker, // random walker object for which traversal is driven - selector_t const& selector, // sampling type (uniform, biased, etc.) - seed_t seed0, // initial seed value - device_vec_t& d_coalesced_v, // crt coalesced vertex set - device_vec_t& d_coalesced_w, // crt coalesced weight set - device_vec_t& d_paths_sz, // crt paths sizes - device_vec_t& - d_crt_out_degs, // ignored: out-degs for the current set of vertices - device_vec_t& d_random, // _entire_ set of random real values - device_vec_t& - d_col_indx) // ignored: crt col indices to be used for retrieving next step - // (Note: coalesced set updated on-the-go) + graph_view_t const& graph_view, // graph being traversed + std::optional> edge_weight_view, + random_walker_t const& rand_walker, // random walker object for which traversal is driven + selector_t const& selector, // sampling type (uniform, biased, etc.) + seed_t seed0, // initial seed value + device_vec_t& d_coalesced_v, // crt coalesced vertex set + device_vec_t& d_coalesced_w, // crt coalesced weight set + device_vec_t& d_paths_sz, // crt paths sizes + device_vec_t& d_crt_out_degs, // ignored: out-degs for the current set of vertices + device_vec_t& d_random, // _entire_ set of random real values + device_vec_t& d_col_indx) // ignored: crt col indices to be used for retrieving next + // step (Note: coalesced set updated on-the-go) const { - using vertex_t = typename graph_t::vertex_type; - using edge_t = typename graph_t::edge_type; - using weight_t = typename graph_t::weight_type; using random_engine_t = typename random_walker_t::rnd_engine_t; using sampler_t = typename selector_t::sampler_type; diff --git a/cpp/src/sampling/uniform_neighbor_sampling_impl.hpp b/cpp/src/sampling/uniform_neighbor_sampling_impl.hpp index f75ccaee793..35eedacee1c 100644 --- a/cpp/src/sampling/uniform_neighbor_sampling_impl.hpp +++ b/cpp/src/sampling/uniform_neighbor_sampling_impl.hpp @@ -29,22 +29,24 @@ namespace cugraph { namespace detail { -template -std::tuple, - rmm::device_uvector, - rmm::device_uvector, - rmm::device_uvector> -uniform_nbr_sample_impl(raft::handle_t const& handle, - graph_view_t const& graph_view, - rmm::device_uvector& d_in, - raft::host_span h_fan_out, - bool with_replacement, - uint64_t seed) +template +std::tuple, + rmm::device_uvector, + rmm::device_uvector, + rmm::device_uvector> +uniform_nbr_sample_impl( + raft::handle_t const& handle, + graph_view_t const& graph_view, + std::optional> edge_weight_view, + rmm::device_uvector& d_in, + raft::host_span h_fan_out, + bool with_replacement, + uint64_t seed) { - using vertex_t = typename graph_view_t::vertex_type; - using edge_t = typename graph_view_t::edge_type; - using weight_t = typename graph_view_t::weight_type; - #ifdef NO_CUGRAPH_OPS CUGRAPH_FAIL( "uniform_nbr_sampl_impl not supported in this configuration, built with NO_CUGRAPH_OPS"); @@ -52,40 +54,48 @@ uniform_nbr_sample_impl(raft::handle_t const& handle, CUGRAPH_EXPECTS(h_fan_out.size() > 0, "Invalid input argument: number of levels must be non-zero."); + CUGRAPH_EXPECTS( + edge_weight_view.has_value(), + "Invalid input argument: the current implementation does not support unweighted graphs."); rmm::device_uvector d_result_src(0, handle.get_stream()); rmm::device_uvector d_result_dst(0, handle.get_stream()); - auto d_result_indices = + auto d_result_weights = thrust::make_optional(rmm::device_uvector(0, handle.get_stream())); size_t level{0}; size_t comm_size{1}; - if constexpr (graph_view_t::is_multi_gpu) { + if constexpr (multi_gpu) { seed += handle.get_comms().get_rank(); comm_size = handle.get_comms().get_size(); } for (auto&& k_level : h_fan_out) { // prep step for extracting out-degs(sources): - if constexpr (graph_view_t::is_multi_gpu) { + if constexpr (multi_gpu) { d_in = shuffle_int_vertices_by_gpu_id( handle, std::move(d_in), graph_view.vertex_partition_range_lasts()); } rmm::device_uvector d_out_src(0, handle.get_stream()); rmm::device_uvector d_out_dst(0, handle.get_stream()); - auto d_out_indices = std::make_optional(rmm::device_uvector(0, handle.get_stream())); + auto d_out_weights = std::make_optional(rmm::device_uvector(0, handle.get_stream())); if (k_level > 0) { raft::random::RngState rng_state(seed); seed += d_in.size() * k_level * comm_size; - std::tie(d_out_src, d_out_dst, d_out_indices) = sample_edges( - handle, graph_view, rng_state, d_in, static_cast(k_level), with_replacement); + std::tie(d_out_src, d_out_dst, d_out_weights) = sample_edges(handle, + graph_view, + edge_weight_view, + rng_state, + d_in, + static_cast(k_level), + with_replacement); } else { - std::tie(d_out_src, d_out_dst, d_out_indices) = - gather_one_hop_edgelist(handle, graph_view, d_in); + std::tie(d_out_src, d_out_dst, d_out_weights) = + gather_one_hop_edgelist(handle, graph_view, edge_weight_view, d_in); } // resize accumulators: @@ -95,15 +105,15 @@ uniform_nbr_sample_impl(raft::handle_t const& handle, d_result_src.resize(new_sz, handle.get_stream()); d_result_dst.resize(new_sz, handle.get_stream()); - d_result_indices->resize(new_sz, handle.get_stream()); + d_result_weights->resize(new_sz, handle.get_stream()); raft::copy( d_result_src.begin() + old_sz, d_out_src.begin(), d_out_src.size(), handle.get_stream()); raft::copy( d_result_dst.begin() + old_sz, d_out_dst.begin(), d_out_dst.size(), handle.get_stream()); - raft::copy(d_result_indices->begin() + old_sz, - d_out_indices->begin(), - d_out_indices->size(), + raft::copy(d_result_weights->begin() + old_sz, + d_out_weights->begin(), + d_out_weights->size(), handle.get_stream()); d_in = std::move(d_out_dst); @@ -112,7 +122,7 @@ uniform_nbr_sample_impl(raft::handle_t const& handle, } return count_and_remove_duplicates( - handle, std::move(d_result_src), std::move(d_result_dst), std::move(*d_result_indices)); + handle, std::move(d_result_src), std::move(d_result_dst), std::move(*d_result_weights)); #endif } } // namespace detail @@ -126,20 +136,20 @@ std::tuple, rmm::device_uvector, rmm::device_uvector, rmm::device_uvector> -uniform_nbr_sample( - raft::handle_t const& handle, - graph_view_t const& graph_view, - raft::device_span starting_vertices, - raft::host_span fan_out, - bool with_replacement, - uint64_t seed) +uniform_nbr_sample(raft::handle_t const& handle, + graph_view_t const& graph_view, + std::optional> edge_weight_view, + raft::device_span starting_vertices, + raft::host_span fan_out, + bool with_replacement, + uint64_t seed) { rmm::device_uvector d_start_vs(starting_vertices.size(), handle.get_stream()); raft::copy( d_start_vs.data(), starting_vertices.data(), starting_vertices.size(), handle.get_stream()); return detail::uniform_nbr_sample_impl( - handle, graph_view, d_start_vs, fan_out, with_replacement, seed); + handle, graph_view, edge_weight_view, d_start_vs, fan_out, with_replacement, seed); } } // namespace cugraph diff --git a/cpp/src/sampling/uniform_neighbor_sampling_mg.cpp b/cpp/src/sampling/uniform_neighbor_sampling_mg.cpp index ad8d1a9f0f1..6041cfe61b0 100644 --- a/cpp/src/sampling/uniform_neighbor_sampling_mg.cpp +++ b/cpp/src/sampling/uniform_neighbor_sampling_mg.cpp @@ -25,7 +25,8 @@ template std::tuple, rmm::device_uvector, rmm::device_uvector> uniform_nbr_sample(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, raft::device_span starting_vertices, raft::host_span fan_out, bool with_replacement, @@ -36,7 +37,8 @@ template std::tuple, rmm::device_uvector, rmm::device_uvector> uniform_nbr_sample(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, raft::device_span starting_vertices, raft::host_span fan_out, bool with_replacement, @@ -47,7 +49,8 @@ template std::tuple, rmm::device_uvector, rmm::device_uvector> uniform_nbr_sample(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, raft::device_span starting_vertices, raft::host_span fan_out, bool with_replacement, @@ -58,7 +61,8 @@ template std::tuple, rmm::device_uvector, rmm::device_uvector> uniform_nbr_sample(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, raft::device_span starting_vertices, raft::host_span fan_out, bool with_replacement, @@ -69,7 +73,8 @@ template std::tuple, rmm::device_uvector, rmm::device_uvector> uniform_nbr_sample(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, raft::device_span starting_vertices, raft::host_span fan_out, bool with_replacement, @@ -80,7 +85,8 @@ template std::tuple, rmm::device_uvector, rmm::device_uvector> uniform_nbr_sample(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, raft::device_span starting_vertices, raft::host_span fan_out, bool with_replacement, diff --git a/cpp/src/sampling/uniform_neighbor_sampling_sg.cpp b/cpp/src/sampling/uniform_neighbor_sampling_sg.cpp index ad4442ecae1..82fae1d7bc3 100644 --- a/cpp/src/sampling/uniform_neighbor_sampling_sg.cpp +++ b/cpp/src/sampling/uniform_neighbor_sampling_sg.cpp @@ -25,7 +25,8 @@ template std::tuple, rmm::device_uvector, rmm::device_uvector> uniform_nbr_sample(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, raft::device_span starting_vertices, raft::host_span fan_out, bool with_replacement, @@ -36,7 +37,8 @@ template std::tuple, rmm::device_uvector, rmm::device_uvector> uniform_nbr_sample(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, raft::device_span starting_vertices, raft::host_span fan_out, bool with_replacement, @@ -47,7 +49,8 @@ template std::tuple, rmm::device_uvector, rmm::device_uvector> uniform_nbr_sample(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, raft::device_span starting_vertices, raft::host_span fan_out, bool with_replacement, @@ -58,7 +61,8 @@ template std::tuple, rmm::device_uvector, rmm::device_uvector> uniform_nbr_sample(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, raft::device_span starting_vertices, raft::host_span fan_out, bool with_replacement, @@ -69,7 +73,8 @@ template std::tuple, rmm::device_uvector, rmm::device_uvector> uniform_nbr_sample(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, raft::device_span starting_vertices, raft::host_span fan_out, bool with_replacement, @@ -80,7 +85,8 @@ template std::tuple, rmm::device_uvector, rmm::device_uvector> uniform_nbr_sample(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, raft::device_span starting_vertices, raft::host_span fan_out, bool with_replacement, diff --git a/cpp/src/structure/coarsen_graph_impl.cuh b/cpp/src/structure/coarsen_graph_impl.cuh index ed04a6f7cc5..d4551d7e0d7 100644 --- a/cpp/src/structure/coarsen_graph_impl.cuh +++ b/cpp/src/structure/coarsen_graph_impl.cuh @@ -20,6 +20,7 @@ #include #include +#include #include #include #include @@ -143,7 +144,9 @@ std::tuple, std::optional>> decompress_edge_partition_to_relabeled_and_grouped_and_coarsened_edgelist( raft::handle_t const& handle, - edge_partition_device_view_t const edge_partition, + edge_partition_device_view_t const edge_partition, + std::optional> + edge_partition_weight_view, vertex_t const* major_label_first, EdgeMinorLabelInputWrapper const minor_label_input, std::optional> const& segment_offsets, @@ -157,13 +160,14 @@ decompress_edge_partition_to_relabeled_and_grouped_and_coarsened_edgelist( rmm::device_uvector edgelist_majors(edge_partition.number_of_edges(), handle.get_stream()); rmm::device_uvector edgelist_minors(edgelist_majors.size(), handle.get_stream()); - auto edgelist_weights = edge_partition.weights() + auto edgelist_weights = edge_partition_weight_view ? std::make_optional>( edgelist_majors.size(), handle.get_stream()) : std::nullopt; detail::decompress_edge_partition_to_edgelist( handle, edge_partition, + edge_partition_weight_view, edgelist_majors.data(), edgelist_minors.data(), edgelist_weights ? std::optional{(*edgelist_weights).data()} : std::nullopt, @@ -237,15 +241,19 @@ template -std::enable_if_t, - std::optional>>> -coarsen_graph( - raft::handle_t const& handle, - graph_view_t const& graph_view, - vertex_t const* labels, - bool renumber, - bool do_expensive_check) +std::enable_if_t< + multi_gpu, + std::tuple< + graph_t, + std::optional< + edge_property_t, weight_t>>, + std::optional>>> +coarsen_graph(raft::handle_t const& handle, + graph_view_t const& graph_view, + std::optional> edge_weight_view, + vertex_t const* labels, + bool renumber, + bool do_expensive_check) { auto& comm = handle.get_comms(); auto const comm_size = comm.get_size(); @@ -272,10 +280,8 @@ coarsen_graph( std::conditional_t< store_transposed, - edge_src_property_t, - vertex_t>, - edge_dst_property_t, - vertex_t>> + edge_src_property_t, vertex_t>, + edge_dst_property_t, vertex_t>> edge_minor_labels(handle, graph_view); if constexpr (store_transposed) { update_edge_src_property(handle, graph_view, labels, edge_minor_labels); @@ -286,8 +292,8 @@ coarsen_graph( std::vector> coarsened_edgelist_majors{}; std::vector> coarsened_edgelist_minors{}; auto coarsened_edgelist_weights = - graph_view.is_weighted() ? std::make_optional>>({}) - : std::nullopt; + edge_weight_view ? std::make_optional>>({}) + : std::nullopt; coarsened_edgelist_majors.reserve(graph_view.number_of_local_edge_partitions()); coarsened_edgelist_minors.reserve(coarsened_edgelist_majors.size()); if (coarsened_edgelist_weights) { @@ -314,8 +320,13 @@ coarsen_graph( auto [edgelist_majors, edgelist_minors, edgelist_weights] = decompress_edge_partition_to_relabeled_and_grouped_and_coarsened_edgelist( handle, - edge_partition_device_view_t( + edge_partition_device_view_t( graph_view.local_edge_partition_view(i)), + edge_weight_view + ? std::make_optional< + detail::edge_partition_edge_property_device_view_t>( + *edge_weight_view, i) + : std::nullopt, major_labels.data(), edge_minor_labels.view(), graph_view.local_edge_partition_segment_offsets(i), @@ -500,9 +511,12 @@ coarsen_graph( // 4. create a graph - graph_t coarsened_graph(handle); + graph_t coarsened_graph(handle); + std::optional< + edge_property_t, weight_t>> + edge_weights{std::nullopt}; std::optional> renumber_map{std::nullopt}; - std::tie(coarsened_graph, std::ignore, renumber_map) = + std::tie(coarsened_graph, edge_weights, std::ignore, renumber_map) = create_graph_from_edgelist( handle, std::move(unique_labels), @@ -517,6 +531,7 @@ coarsen_graph( do_expensive_check); return std::make_tuple(std::move(coarsened_graph), + std::move(edge_weights), std::optional>{std::move(*renumber_map)}); } @@ -526,15 +541,19 @@ template -std::enable_if_t, - std::optional>>> -coarsen_graph( - raft::handle_t const& handle, - graph_view_t const& graph_view, - vertex_t const* labels, - bool renumber, - bool do_expensive_check) +std::enable_if_t< + !multi_gpu, + std::tuple< + graph_t, + std::optional< + edge_property_t, weight_t>>, + std::optional>>> +coarsen_graph(raft::handle_t const& handle, + graph_view_t const& graph_view, + std::optional> edge_weight_view, + vertex_t const* labels, + bool renumber, + bool do_expensive_check) { if (do_expensive_check) { if (!renumber) { @@ -554,8 +573,13 @@ coarsen_graph( auto [coarsened_edgelist_majors, coarsened_edgelist_minors, coarsened_edgelist_weights] = decompress_edge_partition_to_relabeled_and_grouped_and_coarsened_edgelist( handle, - edge_partition_device_view_t( + edge_partition_device_view_t( graph_view.local_edge_partition_view()), + edge_weight_view + ? std::make_optional< + detail::edge_partition_edge_property_device_view_t>( + *edge_weight_view, 0) + : std::nullopt, labels, detail::edge_minor_property_view_t(labels, vertex_t{0}), graph_view.local_edge_partition_segment_offsets(0), @@ -636,9 +660,12 @@ coarsen_graph( thrust::sequence(handle.get_thrust_policy(), vertices.begin(), vertices.end(), vertex_t{0}); } - graph_t coarsened_graph(handle); + graph_t coarsened_graph(handle); + std::optional< + edge_property_t, weight_t>> + edge_weights{std::nullopt}; std::optional> renumber_map{std::nullopt}; - std::tie(coarsened_graph, std::ignore, renumber_map) = + std::tie(coarsened_graph, edge_weights, std::ignore, renumber_map) = create_graph_from_edgelist( handle, std::optional>{std::move(vertices)}, @@ -652,7 +679,8 @@ coarsen_graph( renumber, do_expensive_check); - return std::make_tuple(std::move(coarsened_graph), std::move(*renumber_map)); + return std::make_tuple( + std::move(coarsened_graph), std::move(edge_weights), std::move(*renumber_map)); } } // namespace detail @@ -662,17 +690,20 @@ template -std::tuple, - std::optional>> -coarsen_graph( - raft::handle_t const& handle, - graph_view_t const& graph_view, - vertex_t const* labels, - bool renumber, - bool do_expensive_check) +std::tuple< + graph_t, + std::optional< + edge_property_t, weight_t>>, + std::optional>> +coarsen_graph(raft::handle_t const& handle, + graph_view_t const& graph_view, + std::optional> edge_weight_view, + vertex_t const* labels, + bool renumber, + bool do_expensive_check) { - do_expensive_check = true; - return detail::coarsen_graph(handle, graph_view, labels, renumber, do_expensive_check); + return detail::coarsen_graph( + handle, graph_view, edge_weight_view, labels, renumber, do_expensive_check); } } // namespace cugraph diff --git a/cpp/src/structure/coarsen_graph_mg.cu b/cpp/src/structure/coarsen_graph_mg.cu index bfd99b23542..39bdb58084f 100644 --- a/cpp/src/structure/coarsen_graph_mg.cu +++ b/cpp/src/structure/coarsen_graph_mg.cu @@ -19,98 +19,134 @@ namespace cugraph { // MG instantiation -template std::tuple, - std::optional>> +template std::tuple< + graph_t, + std::optional, float>>, + std::optional>> coarsen_graph(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, int32_t const* labels, bool renumber, bool do_expensive_check); -template std::tuple, - std::optional>> +template std::tuple< + graph_t, + std::optional, float>>, + std::optional>> coarsen_graph(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, int32_t const* labels, bool renumber, bool do_expensive_check); -template std::tuple, - std::optional>> +template std::tuple< + graph_t, + std::optional, float>>, + std::optional>> coarsen_graph(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, int32_t const* labels, bool renumber, bool do_expensive_check); -template std::tuple, - std::optional>> +template std::tuple< + graph_t, + std::optional, float>>, + std::optional>> coarsen_graph(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, int32_t const* labels, bool renumber, bool do_expensive_check); -template std::tuple, - std::optional>> +template std::tuple< + graph_t, + std::optional, float>>, + std::optional>> coarsen_graph(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, int64_t const* labels, bool renumber, bool do_expensive_check); -template std::tuple, - std::optional>> +template std::tuple< + graph_t, + std::optional, float>>, + std::optional>> coarsen_graph(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, int64_t const* labels, bool renumber, bool do_expensive_check); -template std::tuple, - std::optional>> +template std::tuple< + graph_t, + std::optional, double>>, + std::optional>> coarsen_graph(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, int32_t const* labels, bool renumber, bool do_expensive_check); -template std::tuple, - std::optional>> +template std::tuple< + graph_t, + std::optional, double>>, + std::optional>> coarsen_graph(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, int32_t const* labels, bool renumber, bool do_expensive_check); -template std::tuple, - std::optional>> +template std::tuple< + graph_t, + std::optional, double>>, + std::optional>> coarsen_graph(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, int32_t const* labels, bool renumber, bool do_expensive_check); -template std::tuple, - std::optional>> +template std::tuple< + graph_t, + std::optional, double>>, + std::optional>> coarsen_graph(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, int32_t const* labels, bool renumber, bool do_expensive_check); -template std::tuple, - std::optional>> +template std::tuple< + graph_t, + std::optional, double>>, + std::optional>> coarsen_graph(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, int64_t const* labels, bool renumber, bool do_expensive_check); -template std::tuple, - std::optional>> +template std::tuple< + graph_t, + std::optional, double>>, + std::optional>> coarsen_graph(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, int64_t const* labels, bool renumber, bool do_expensive_check); diff --git a/cpp/src/structure/coarsen_graph_sg.cu b/cpp/src/structure/coarsen_graph_sg.cu index 838cb0c68b1..7ddbecc33c5 100644 --- a/cpp/src/structure/coarsen_graph_sg.cu +++ b/cpp/src/structure/coarsen_graph_sg.cu @@ -19,98 +19,134 @@ namespace cugraph { // SG instantiation -template std::tuple, - std::optional>> +template std::tuple< + graph_t, + std::optional, float>>, + std::optional>> coarsen_graph(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, int32_t const* labels, bool renumber, bool do_expensive_check); -template std::tuple, - std::optional>> +template std::tuple< + graph_t, + std::optional, float>>, + std::optional>> coarsen_graph(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, int32_t const* labels, bool renumber, bool do_expensive_check); -template std::tuple, - std::optional>> +template std::tuple< + graph_t, + std::optional, float>>, + std::optional>> coarsen_graph(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, int32_t const* labels, bool renumber, bool do_expensive_check); -template std::tuple, - std::optional>> +template std::tuple< + graph_t, + std::optional, float>>, + std::optional>> coarsen_graph(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, int32_t const* labels, bool renumber, bool do_expensive_check); -template std::tuple, - std::optional>> +template std::tuple< + graph_t, + std::optional, float>>, + std::optional>> coarsen_graph(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, int64_t const* labels, bool renumber, bool do_expensive_check); -template std::tuple, - std::optional>> +template std::tuple< + graph_t, + std::optional, float>>, + std::optional>> coarsen_graph(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, int64_t const* labels, bool renumber, bool do_expensive_check); -template std::tuple, - std::optional>> +template std::tuple< + graph_t, + std::optional, double>>, + std::optional>> coarsen_graph(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, int32_t const* labels, bool renumber, bool do_expensive_check); -template std::tuple, - std::optional>> +template std::tuple< + graph_t, + std::optional, double>>, + std::optional>> coarsen_graph(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, int32_t const* labels, bool renumber, bool do_expensive_check); -template std::tuple, - std::optional>> +template std::tuple< + graph_t, + std::optional, double>>, + std::optional>> coarsen_graph(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, int32_t const* labels, bool renumber, bool do_expensive_check); -template std::tuple, - std::optional>> +template std::tuple< + graph_t, + std::optional, double>>, + std::optional>> coarsen_graph(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, int32_t const* labels, bool renumber, bool do_expensive_check); -template std::tuple, - std::optional>> +template std::tuple< + graph_t, + std::optional, double>>, + std::optional>> coarsen_graph(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, int64_t const* labels, bool renumber, bool do_expensive_check); -template std::tuple, - std::optional>> +template std::tuple< + graph_t, + std::optional, double>>, + std::optional>> coarsen_graph(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, int64_t const* labels, bool renumber, bool do_expensive_check); diff --git a/cpp/src/structure/create_graph_from_edgelist_impl.cuh b/cpp/src/structure/create_graph_from_edgelist_impl.cuh index 1a2aa1325dd..a4167df2400 100644 --- a/cpp/src/structure/create_graph_from_edgelist_impl.cuh +++ b/cpp/src/structure/create_graph_from_edgelist_impl.cuh @@ -246,11 +246,13 @@ template std::enable_if_t< multi_gpu, - std::tuple, - std::optional, - thrust::tuple>>, - std::optional>>> + std::tuple< + cugraph::graph_t, + std::optional< + edge_property_t, weight_t>>, + std::optional, + thrust::tuple>>, + std::optional>>> create_graph_from_edgelist_impl( raft::handle_t const& handle, std::optional>&& local_vertices, @@ -272,6 +274,14 @@ create_graph_from_edgelist_impl( "Invalid input arguments: edgelist_srcs.size() != edgelist_dsts.size()."); CUGRAPH_EXPECTS(!edgelist_weights || (edgelist_srcs.size() == (*edgelist_weights).size()), "Invalid input arguments: edgelist_srcs.size() != edgelist_weights.size()."); + CUGRAPH_EXPECTS(!edgelist_id_type_pairs || + (edgelist_srcs.size() == std::get<0>((*edgelist_id_type_pairs)).size()), + "Invalid input arguments: edgelist_srcs.size() != " + "std::get<0>((*edgelist_id_type_pairs)).size()."); + CUGRAPH_EXPECTS(!edgelist_id_type_pairs || + (edgelist_srcs.size() == std::get<1>((*edgelist_id_type_pairs)).size()), + "Invalid input arguments: edgelist_srcs.size() != " + "std::get<1>((*edgelist_id_type_pairs)).size()."); CUGRAPH_EXPECTS(renumber, "Invalid input arguments: renumber should be true if multi_gpu is true."); @@ -578,27 +588,35 @@ create_graph_from_edgelist_impl( // 5. create a graph and an edge_property_t object. std::optional< - edge_property_t, - thrust::tuple>> + edge_property_t, weight_t>> + edge_weights{std::nullopt}; + if (edge_partition_weights) { + edge_weights = + edge_property_t, weight_t>( + std::move(*edge_partition_weights)); + } + + std::optional, + thrust::tuple>> edge_id_type_pairs{std::nullopt}; if (edge_partition_id_type_pairs) { edge_id_type_pairs = - edge_property_t, + edge_property_t, thrust::tuple>(std::move(*edge_partition_id_type_pairs)); } return std::make_tuple( - cugraph::graph_t( + cugraph::graph_t( handle, std::move(edge_partition_offsets), std::move(edge_partition_indices), - std::move(edge_partition_weights), std::move(edge_partition_dcs_nzd_vertices), cugraph::graph_meta_t{meta.number_of_vertices, meta.number_of_edges, graph_properties, meta.partition, meta.edge_partition_segment_offsets}), + std::move(edge_weights), std::move(edge_id_type_pairs), std::optional>{std::move(renumber_map_labels)}); } @@ -611,11 +629,13 @@ template std::enable_if_t< !multi_gpu, - std::tuple, - std::optional, - thrust::tuple>>, - std::optional>>> + std::tuple< + cugraph::graph_t, + std::optional< + edge_property_t, weight_t>>, + std::optional, + thrust::tuple>>, + std::optional>>> create_graph_from_edgelist_impl( raft::handle_t const& handle, std::optional>&& vertices, @@ -796,30 +816,40 @@ create_graph_from_edgelist_impl( // create a graph and an edge_property_t object. std::optional< - edge_property_t, - thrust::tuple>> + edge_property_t, weight_t>> + edge_weights{std::nullopt}; + if (weights) { + std::vector> buffers{}; + buffers.push_back(std::move(*weights)); + edge_weights = + edge_property_t, weight_t>( + std::move(buffers)); + } + + std::optional, + thrust::tuple>> edge_id_type_pairs{std::nullopt}; if (id_type_pairs) { std::vector, rmm::device_uvector>> buffers{}; buffers.push_back(std::move(*id_type_pairs)); - *edge_id_type_pairs = - edge_property_t, + edge_id_type_pairs = + edge_property_t, thrust::tuple>(std::move(buffers)); } // graph_t constructor return std::make_tuple( - cugraph::graph_t( + cugraph::graph_t( handle, std::move(offsets), std::move(indices), - std::move(weights), cugraph::graph_meta_t{ num_vertices, graph_properties, renumber ? std::optional>{meta.segment_offsets} : std::nullopt}), + std::move(edge_weights), std::move(edge_id_type_pairs), std::move(renumber_map_labels)); } @@ -832,11 +862,13 @@ template -std::tuple, - std::optional< - edge_property_t, - thrust::tuple>>, - std::optional>> +std::tuple< + cugraph::graph_t, + std::optional< + edge_property_t, weight_t>>, + std::optional, + thrust::tuple>>, + std::optional>> create_graph_from_edgelist( raft::handle_t const& handle, std::optional>&& vertices, diff --git a/cpp/src/structure/create_graph_from_edgelist_mg.cu b/cpp/src/structure/create_graph_from_edgelist_mg.cu index f0d044319f0..4f7a4ed2983 100644 --- a/cpp/src/structure/create_graph_from_edgelist_mg.cu +++ b/cpp/src/structure/create_graph_from_edgelist_mg.cu @@ -19,11 +19,13 @@ namespace cugraph { // explicit instantiations -template std::tuple, - std::optional, - thrust::tuple>>, - std::optional>> +template std::tuple< + cugraph::graph_t, + std::optional< + cugraph::edge_property_t, float>>, + std::optional, + thrust::tuple>>, + std::optional>> create_graph_from_edgelist( raft::handle_t const& handle, std::optional>&& vertex_span, @@ -37,8 +39,10 @@ create_graph_from_edgelist( bool do_expensive_check); template std::tuple< - cugraph::graph_t, - std::optional, + cugraph::graph_t, + std::optional< + cugraph::edge_property_t, float>>, + std::optional, thrust::tuple>>, std::optional>> create_graph_from_edgelist( @@ -53,11 +57,13 @@ create_graph_from_edgelist( bool renumber, bool do_expensive_check); -template std::tuple, - std::optional, - thrust::tuple>>, - std::optional>> +template std::tuple< + cugraph::graph_t, + std::optional< + cugraph::edge_property_t, double>>, + std::optional, + thrust::tuple>>, + std::optional>> create_graph_from_edgelist( raft::handle_t const& handle, std::optional>&& vertex_span, @@ -70,11 +76,13 @@ create_graph_from_edgelist( bool renumber, bool do_expensive_check); -template std::tuple, - std::optional, - thrust::tuple>>, - std::optional>> +template std::tuple< + cugraph::graph_t, + std::optional< + cugraph::edge_property_t, double>>, + std::optional, + thrust::tuple>>, + std::optional>> create_graph_from_edgelist( raft::handle_t const& handle, std::optional>&& vertex_span, @@ -87,11 +95,13 @@ create_graph_from_edgelist( bool renumber, bool do_expensive_check); -template std::tuple, - std::optional, - thrust::tuple>>, - std::optional>> +template std::tuple< + cugraph::graph_t, + std::optional< + cugraph::edge_property_t, float>>, + std::optional, + thrust::tuple>>, + std::optional>> create_graph_from_edgelist( raft::handle_t const& handle, std::optional>&& vertex_span, @@ -105,8 +115,10 @@ create_graph_from_edgelist( bool do_expensive_check); template std::tuple< - cugraph::graph_t, - std::optional, + cugraph::graph_t, + std::optional< + cugraph::edge_property_t, float>>, + std::optional, thrust::tuple>>, std::optional>> create_graph_from_edgelist( @@ -121,11 +133,13 @@ create_graph_from_edgelist( bool renumber, bool do_expensive_check); -template std::tuple, - std::optional, - thrust::tuple>>, - std::optional>> +template std::tuple< + cugraph::graph_t, + std::optional< + cugraph::edge_property_t, double>>, + std::optional, + thrust::tuple>>, + std::optional>> create_graph_from_edgelist( raft::handle_t const& handle, std::optional>&& vertex_span, @@ -138,11 +152,13 @@ create_graph_from_edgelist( bool renumber, bool do_expensive_check); -template std::tuple, - std::optional, - thrust::tuple>>, - std::optional>> +template std::tuple< + cugraph::graph_t, + std::optional< + cugraph::edge_property_t, double>>, + std::optional, + thrust::tuple>>, + std::optional>> create_graph_from_edgelist( raft::handle_t const& handle, std::optional>&& vertex_span, @@ -155,11 +171,13 @@ create_graph_from_edgelist( bool renumber, bool do_expensive_check); -template std::tuple, - std::optional, - thrust::tuple>>, - std::optional>> +template std::tuple< + cugraph::graph_t, + std::optional< + cugraph::edge_property_t, float>>, + std::optional, + thrust::tuple>>, + std::optional>> create_graph_from_edgelist( raft::handle_t const& handle, std::optional>&& vertex_span, @@ -173,8 +191,10 @@ create_graph_from_edgelist( bool do_expensive_check); template std::tuple< - cugraph::graph_t, - std::optional, + cugraph::graph_t, + std::optional< + cugraph::edge_property_t, float>>, + std::optional, thrust::tuple>>, std::optional>> create_graph_from_edgelist( @@ -189,11 +209,13 @@ create_graph_from_edgelist( bool renumber, bool do_expensive_check); -template std::tuple, - std::optional, - thrust::tuple>>, - std::optional>> +template std::tuple< + cugraph::graph_t, + std::optional< + cugraph::edge_property_t, double>>, + std::optional, + thrust::tuple>>, + std::optional>> create_graph_from_edgelist( raft::handle_t const& handle, std::optional>&& vertex_span, @@ -206,11 +228,13 @@ create_graph_from_edgelist( bool renumber, bool do_expensive_check); -template std::tuple, - std::optional, - thrust::tuple>>, - std::optional>> +template std::tuple< + cugraph::graph_t, + std::optional< + cugraph::edge_property_t, double>>, + std::optional, + thrust::tuple>>, + std::optional>> create_graph_from_edgelist( raft::handle_t const& handle, std::optional>&& vertex_span, diff --git a/cpp/src/structure/create_graph_from_edgelist_sg.cu b/cpp/src/structure/create_graph_from_edgelist_sg.cu index 987ed949023..8438c053c64 100644 --- a/cpp/src/structure/create_graph_from_edgelist_sg.cu +++ b/cpp/src/structure/create_graph_from_edgelist_sg.cu @@ -19,11 +19,13 @@ namespace cugraph { // explicit instantiations -template std::tuple, - std::optional, - thrust::tuple>>, - std::optional>> +template std::tuple< + cugraph::graph_t, + std::optional< + cugraph::edge_property_t, float>>, + std::optional, + thrust::tuple>>, + std::optional>> create_graph_from_edgelist( raft::handle_t const& handle, std::optional>&& vertex_span, @@ -36,11 +38,13 @@ create_graph_from_edgelist( bool renumber, bool do_expensive_check); -template std::tuple, - std::optional, - thrust::tuple>>, - std::optional>> +template std::tuple< + cugraph::graph_t, + std::optional< + cugraph::edge_property_t, float>>, + std::optional, + thrust::tuple>>, + std::optional>> create_graph_from_edgelist( raft::handle_t const& handle, std::optional>&& vertex_span, @@ -53,11 +57,13 @@ create_graph_from_edgelist( bool renumber, bool do_expensive_check); -template std::tuple, - std::optional, - thrust::tuple>>, - std::optional>> +template std::tuple< + cugraph::graph_t, + std::optional< + cugraph::edge_property_t, double>>, + std::optional, + thrust::tuple>>, + std::optional>> create_graph_from_edgelist( raft::handle_t const& handle, std::optional>&& vertex_span, @@ -70,11 +76,13 @@ create_graph_from_edgelist( bool renumber, bool do_expensive_check); -template std::tuple, - std::optional, - thrust::tuple>>, - std::optional>> +template std::tuple< + cugraph::graph_t, + std::optional< + cugraph::edge_property_t, double>>, + std::optional, + thrust::tuple>>, + std::optional>> create_graph_from_edgelist( raft::handle_t const& handle, std::optional>&& vertex_span, @@ -87,11 +95,13 @@ create_graph_from_edgelist( bool renumber, bool do_expensive_check); -template std::tuple, - std::optional, - thrust::tuple>>, - std::optional>> +template std::tuple< + cugraph::graph_t, + std::optional< + cugraph::edge_property_t, float>>, + std::optional, + thrust::tuple>>, + std::optional>> create_graph_from_edgelist( raft::handle_t const& handle, std::optional>&& vertex_span, @@ -104,11 +114,13 @@ create_graph_from_edgelist( bool renumber, bool do_expensive_check); -template std::tuple, - std::optional, - thrust::tuple>>, - std::optional>> +template std::tuple< + cugraph::graph_t, + std::optional< + cugraph::edge_property_t, float>>, + std::optional, + thrust::tuple>>, + std::optional>> create_graph_from_edgelist( raft::handle_t const& handle, std::optional>&& vertex_span, @@ -121,11 +133,13 @@ create_graph_from_edgelist( bool renumber, bool do_expensive_check); -template std::tuple, - std::optional, - thrust::tuple>>, - std::optional>> +template std::tuple< + cugraph::graph_t, + std::optional< + cugraph::edge_property_t, double>>, + std::optional, + thrust::tuple>>, + std::optional>> create_graph_from_edgelist( raft::handle_t const& handle, std::optional>&& vertex_span, @@ -138,11 +152,13 @@ create_graph_from_edgelist( bool renumber, bool do_expensive_check); -template std::tuple, - std::optional, - thrust::tuple>>, - std::optional>> +template std::tuple< + cugraph::graph_t, + std::optional< + cugraph::edge_property_t, double>>, + std::optional, + thrust::tuple>>, + std::optional>> create_graph_from_edgelist( raft::handle_t const& handle, std::optional>&& vertex_span, @@ -155,11 +171,13 @@ create_graph_from_edgelist( bool renumber, bool do_expensive_check); -template std::tuple, - std::optional, - thrust::tuple>>, - std::optional>> +template std::tuple< + cugraph::graph_t, + std::optional< + cugraph::edge_property_t, float>>, + std::optional, + thrust::tuple>>, + std::optional>> create_graph_from_edgelist( raft::handle_t const& handle, std::optional>&& vertex_span, @@ -172,11 +190,13 @@ create_graph_from_edgelist( bool renumber, bool do_expensive_check); -template std::tuple, - std::optional, - thrust::tuple>>, - std::optional>> +template std::tuple< + cugraph::graph_t, + std::optional< + cugraph::edge_property_t, float>>, + std::optional, + thrust::tuple>>, + std::optional>> create_graph_from_edgelist( raft::handle_t const& handle, std::optional>&& vertex_span, @@ -189,11 +209,13 @@ create_graph_from_edgelist( bool renumber, bool do_expensive_check); -template std::tuple, - std::optional, - thrust::tuple>>, - std::optional>> +template std::tuple< + cugraph::graph_t, + std::optional< + cugraph::edge_property_t, double>>, + std::optional, + thrust::tuple>>, + std::optional>> create_graph_from_edgelist( raft::handle_t const& handle, std::optional>&& vertex_span, @@ -206,11 +228,13 @@ create_graph_from_edgelist( bool renumber, bool do_expensive_check); -template std::tuple, - std::optional, - thrust::tuple>>, - std::optional>> +template std::tuple< + cugraph::graph_t, + std::optional< + cugraph::edge_property_t, double>>, + std::optional, + thrust::tuple>>, + std::optional>> create_graph_from_edgelist( raft::handle_t const& handle, std::optional>&& vertex_span, diff --git a/cpp/src/structure/decompress_to_edgelist_impl.cuh b/cpp/src/structure/decompress_to_edgelist_impl.cuh index d18f7145e27..e940db49ac5 100644 --- a/cpp/src/structure/decompress_to_edgelist_impl.cuh +++ b/cpp/src/structure/decompress_to_edgelist_impl.cuh @@ -55,7 +55,8 @@ std::enable_if_t>>> decompress_to_edgelist_impl( raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, std::optional> renumber_map, bool do_expensive_check) { @@ -83,17 +84,21 @@ decompress_to_edgelist_impl( rmm::device_uvector edgelist_majors(number_of_local_edges, handle.get_stream()); rmm::device_uvector edgelist_minors(edgelist_majors.size(), handle.get_stream()); - auto edgelist_weights = graph_view.is_weighted() - ? std::make_optional>( - edgelist_majors.size(), handle.get_stream()) - : std::nullopt; + auto edgelist_weights = edge_weight_view ? std::make_optional>( + edgelist_majors.size(), handle.get_stream()) + : std::nullopt; size_t cur_size{0}; for (size_t i = 0; i < edgelist_edge_counts.size(); ++i) { detail::decompress_edge_partition_to_edgelist( handle, - edge_partition_device_view_t( + edge_partition_device_view_t( graph_view.local_edge_partition_view(i)), + edge_weight_view + ? std::make_optional< + detail::edge_partition_edge_property_device_view_t>( + (*edge_weight_view), i) + : std::nullopt, edgelist_majors.data() + cur_size, edgelist_minors.data() + cur_size, edgelist_weights ? std::optional{(*edgelist_weights).data() + cur_size} @@ -176,7 +181,8 @@ std::enable_if_t>>> decompress_to_edgelist_impl( raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, std::optional> renumber_map, bool do_expensive_check) { @@ -192,14 +198,18 @@ decompress_to_edgelist_impl( rmm::device_uvector edgelist_majors(graph_view.number_of_local_edge_partition_edges(), handle.get_stream()); rmm::device_uvector edgelist_minors(edgelist_majors.size(), handle.get_stream()); - auto edgelist_weights = graph_view.is_weighted() - ? std::make_optional>( - edgelist_majors.size(), handle.get_stream()) - : std::nullopt; + auto edgelist_weights = edge_weight_view ? std::make_optional>( + edgelist_majors.size(), handle.get_stream()) + : std::nullopt; detail::decompress_edge_partition_to_edgelist( handle, - edge_partition_device_view_t( + edge_partition_device_view_t( graph_view.local_edge_partition_view()), + edge_weight_view + ? std::make_optional< + detail::edge_partition_edge_property_device_view_t>( + (*edge_weight_view), 0) + : std::nullopt, edgelist_majors.data(), edgelist_minors.data(), edgelist_weights ? std::optional{(*edgelist_weights).data()} : std::nullopt, @@ -232,11 +242,13 @@ std::tuple, std::optional>> decompress_to_edgelist( raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, std::optional> renumber_map, bool do_expensive_check) { - return decompress_to_edgelist_impl(handle, graph_view, renumber_map, do_expensive_check); + return decompress_to_edgelist_impl( + handle, graph_view, edge_weight_view, renumber_map, do_expensive_check); } } // namespace cugraph diff --git a/cpp/src/structure/decompress_to_edgelist_mg.cu b/cpp/src/structure/decompress_to_edgelist_mg.cu index ce83b41f5e7..9f03570504b 100644 --- a/cpp/src/structure/decompress_to_edgelist_mg.cu +++ b/cpp/src/structure/decompress_to_edgelist_mg.cu @@ -24,7 +24,8 @@ template std::tuple, std::optional>> decompress_to_edgelist( raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, std::optional> renumber_map, bool do_expensive_check); @@ -33,7 +34,8 @@ template std::tuple, std::optional>> decompress_to_edgelist( raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, std::optional> renumber_map, bool do_expensive_check); @@ -42,7 +44,8 @@ template std::tuple, std::optional>> decompress_to_edgelist( raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, std::optional> renumber_map, bool do_expensive_check); @@ -51,7 +54,8 @@ template std::tuple, std::optional>> decompress_to_edgelist( raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, std::optional> renumber_map, bool do_expensive_check); @@ -60,7 +64,8 @@ template std::tuple, std::optional>> decompress_to_edgelist( raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, std::optional> renumber_map, bool do_expensive_check); @@ -69,7 +74,8 @@ template std::tuple, std::optional>> decompress_to_edgelist( raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, std::optional> renumber_map, bool do_expensive_check); @@ -78,7 +84,8 @@ template std::tuple, std::optional>> decompress_to_edgelist( raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, std::optional> renumber_map, bool do_expensive_check); @@ -87,7 +94,8 @@ template std::tuple, std::optional>> decompress_to_edgelist( raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, std::optional> renumber_map, bool do_expensive_check); @@ -96,7 +104,8 @@ template std::tuple, std::optional>> decompress_to_edgelist( raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, std::optional> renumber_map, bool do_expensive_check); @@ -105,7 +114,8 @@ template std::tuple, std::optional>> decompress_to_edgelist( raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, std::optional> renumber_map, bool do_expensive_check); @@ -114,7 +124,8 @@ template std::tuple, std::optional>> decompress_to_edgelist( raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, std::optional> renumber_map, bool do_expensive_check); @@ -123,7 +134,8 @@ template std::tuple, std::optional>> decompress_to_edgelist( raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, std::optional> renumber_map, bool do_expensive_check); diff --git a/cpp/src/structure/decompress_to_edgelist_sg.cu b/cpp/src/structure/decompress_to_edgelist_sg.cu index 51f377b29a4..296f39fdfd2 100644 --- a/cpp/src/structure/decompress_to_edgelist_sg.cu +++ b/cpp/src/structure/decompress_to_edgelist_sg.cu @@ -24,7 +24,8 @@ template std::tuple, std::optional>> decompress_to_edgelist( raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, std::optional> renumber_map, bool do_expensive_check); @@ -33,7 +34,8 @@ template std::tuple, std::optional>> decompress_to_edgelist( raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, std::optional> renumber_map, bool do_expensive_check); @@ -42,7 +44,8 @@ template std::tuple, std::optional>> decompress_to_edgelist( raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, std::optional> renumber_map, bool do_expensive_check); @@ -51,7 +54,8 @@ template std::tuple, std::optional>> decompress_to_edgelist( raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, std::optional> renumber_map, bool do_expensive_check); @@ -60,7 +64,8 @@ template std::tuple, std::optional>> decompress_to_edgelist( raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, std::optional> renumber_map, bool do_expensive_check); @@ -69,7 +74,8 @@ template std::tuple, std::optional>> decompress_to_edgelist( raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, std::optional> renumber_map, bool do_expensive_check); @@ -78,7 +84,8 @@ template std::tuple, std::optional>> decompress_to_edgelist( raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, std::optional> renumber_map, bool do_expensive_check); @@ -87,7 +94,8 @@ template std::tuple, std::optional>> decompress_to_edgelist( raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, std::optional> renumber_map, bool do_expensive_check); @@ -96,7 +104,8 @@ template std::tuple, std::optional>> decompress_to_edgelist( raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, std::optional> renumber_map, bool do_expensive_check); @@ -105,7 +114,8 @@ template std::tuple, std::optional>> decompress_to_edgelist( raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, std::optional> renumber_map, bool do_expensive_check); @@ -114,7 +124,8 @@ template std::tuple, std::optional>> decompress_to_edgelist( raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, std::optional> renumber_map, bool do_expensive_check); @@ -123,7 +134,8 @@ template std::tuple, std::optional>> decompress_to_edgelist( raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, std::optional> renumber_map, bool do_expensive_check); diff --git a/cpp/src/structure/graph_impl.cuh b/cpp/src/structure/graph_impl.cuh index 4b1e450a19e..45372c27dec 100644 --- a/cpp/src/structure/graph_impl.cuh +++ b/cpp/src/structure/graph_impl.cuh @@ -62,6 +62,12 @@ namespace cugraph { namespace { +template +struct edgelist_t { + raft::device_span srcs{}; + raft::device_span dsts{}; +}; + // can't use lambda due to nvcc limitations (The enclosing parent function ("graph_t") for an // extended __device__ lambda must allow its address to be taken) template @@ -127,26 +133,17 @@ struct rebase_offset_t { __device__ edge_t operator()(edge_t offset) const { return offset - base_offset; } }; -template +template bool check_symmetric(raft::handle_t const& handle, - std::vector> const& edgelists) + std::vector> const& edgelists) { size_t number_of_local_edges{0}; for (size_t i = 0; i < edgelists.size(); ++i) { number_of_local_edges += edgelists[i].srcs.size(); } - auto is_weighted = edgelists[0].weights.has_value(); - rmm::device_uvector org_srcs(number_of_local_edges, handle.get_stream()); rmm::device_uvector org_dsts(number_of_local_edges, handle.get_stream()); - auto org_weights = is_weighted ? std::make_optional>( - number_of_local_edges, handle.get_stream()) - : std::nullopt; size_t offset{0}; for (size_t i = 0; i < edgelists.size(); ++i) { thrust::copy(handle.get_thrust_policy(), @@ -157,95 +154,55 @@ bool check_symmetric(raft::handle_t const& handle, edgelists[i].dsts.begin(), edgelists[i].dsts.end(), org_dsts.begin() + offset); - if (is_weighted) { - thrust::copy(handle.get_thrust_policy(), - (*(edgelists[i].weights)).begin(), - (*(edgelists[i].weights)).end(), - (*org_weights).begin() + offset); - } offset += edgelists[i].srcs.size(); } if constexpr (multi_gpu) { std::tie( - store_transposed ? org_dsts : org_srcs, store_transposed ? org_srcs : org_dsts, org_weights) = + store_transposed ? org_dsts : org_srcs, store_transposed ? org_srcs : org_dsts, std::ignore) = detail::shuffle_edgelist_by_gpu_id(handle, std::move(store_transposed ? org_dsts : org_srcs), std::move(store_transposed ? org_srcs : org_dsts), - std::move(org_weights)); + std::nullopt); } rmm::device_uvector symmetrized_srcs(org_srcs.size(), handle.get_stream()); rmm::device_uvector symmetrized_dsts(org_dsts.size(), handle.get_stream()); - auto symmetrized_weights = org_weights ? std::make_optional>( - (*org_weights).size(), handle.get_stream()) - : std::nullopt; thrust::copy( handle.get_thrust_policy(), org_srcs.begin(), org_srcs.end(), symmetrized_srcs.begin()); thrust::copy( handle.get_thrust_policy(), org_dsts.begin(), org_dsts.end(), symmetrized_dsts.begin()); - if (org_weights) { - thrust::copy(handle.get_thrust_policy(), - (*org_weights).begin(), - (*org_weights).end(), - (*symmetrized_weights).begin()); - } - std::tie(symmetrized_srcs, symmetrized_dsts, symmetrized_weights) = - symmetrize_edgelist( - handle, - std::move(symmetrized_srcs), - std::move(symmetrized_dsts), - std::move(symmetrized_weights), - true); + std::tie(symmetrized_srcs, symmetrized_dsts, std::ignore) = + symmetrize_edgelist( + handle, std::move(symmetrized_srcs), std::move(symmetrized_dsts), std::nullopt, true); if (org_srcs.size() != symmetrized_srcs.size()) { return false; } - if (org_weights) { - auto org_edge_first = thrust::make_zip_iterator( - thrust::make_tuple(org_srcs.begin(), org_dsts.begin(), (*org_weights).begin())); - thrust::sort(handle.get_thrust_policy(), org_edge_first, org_edge_first + org_srcs.size()); - auto symmetrized_edge_first = thrust::make_zip_iterator(thrust::make_tuple( - symmetrized_srcs.begin(), symmetrized_dsts.begin(), (*symmetrized_weights).begin())); - thrust::sort(handle.get_thrust_policy(), - symmetrized_edge_first, - symmetrized_edge_first + symmetrized_srcs.size()); - - return thrust::equal(handle.get_thrust_policy(), - org_edge_first, - org_edge_first + org_srcs.size(), - symmetrized_edge_first); - } else { - auto org_edge_first = - thrust::make_zip_iterator(thrust::make_tuple(org_srcs.begin(), org_dsts.begin())); - thrust::sort(handle.get_thrust_policy(), org_edge_first, org_edge_first + org_srcs.size()); - auto symmetrized_edge_first = thrust::make_zip_iterator( - thrust::make_tuple(symmetrized_srcs.begin(), symmetrized_dsts.begin())); - thrust::sort(handle.get_thrust_policy(), - symmetrized_edge_first, - symmetrized_edge_first + symmetrized_srcs.size()); - - return thrust::equal(handle.get_thrust_policy(), - org_edge_first, - org_edge_first + org_srcs.size(), - symmetrized_edge_first); - } + auto org_edge_first = + thrust::make_zip_iterator(thrust::make_tuple(org_srcs.begin(), org_dsts.begin())); + thrust::sort(handle.get_thrust_policy(), org_edge_first, org_edge_first + org_srcs.size()); + auto symmetrized_edge_first = thrust::make_zip_iterator( + thrust::make_tuple(symmetrized_srcs.begin(), symmetrized_dsts.begin())); + thrust::sort(handle.get_thrust_policy(), + symmetrized_edge_first, + symmetrized_edge_first + symmetrized_srcs.size()); + + return thrust::equal(handle.get_thrust_policy(), + org_edge_first, + org_edge_first + org_srcs.size(), + symmetrized_edge_first); } -template +template bool check_no_parallel_edge(raft::handle_t const& handle, - std::vector> const& edgelists) + std::vector> const& edgelists) { size_t number_of_local_edges{0}; for (size_t i = 0; i < edgelists.size(); ++i) { number_of_local_edges += edgelists[i].srcs.size(); } - auto is_weighted = edgelists[0].weights.has_value(); - rmm::device_uvector edgelist_srcs(number_of_local_edges, handle.get_stream()); rmm::device_uvector edgelist_dsts(number_of_local_edges, handle.get_stream()); - auto edgelist_weights = is_weighted ? std::make_optional>( - number_of_local_edges, handle.get_stream()) - : std::nullopt; size_t offset{0}; for (size_t i = 0; i < edgelists.size(); ++i) { thrust::copy(handle.get_thrust_policy(), @@ -256,40 +213,21 @@ bool check_no_parallel_edge(raft::handle_t const& handle, edgelists[i].dsts.begin(), edgelists[i].dsts.end(), edgelist_dsts.begin() + offset); - if (is_weighted) { - thrust::copy(handle.get_thrust_policy(), - (*(edgelists[i].weights)).begin(), - (*(edgelists[i].weights)).end(), - (*edgelist_weights).begin() + offset); - } offset += edgelists[i].srcs.size(); } - if (edgelist_weights) { - auto edge_first = thrust::make_zip_iterator(thrust::make_tuple( - edgelist_srcs.begin(), edgelist_dsts.begin(), (*edgelist_weights).begin())); - thrust::sort(handle.get_thrust_policy(), edge_first, edge_first + edgelist_srcs.size()); - return thrust::unique(handle.get_thrust_policy(), - edge_first, - edge_first + edgelist_srcs.size()) == (edge_first + edgelist_srcs.size()); - } else { - auto edge_first = - thrust::make_zip_iterator(thrust::make_tuple(edgelist_srcs.begin(), edgelist_dsts.begin())); - thrust::sort(handle.get_thrust_policy(), edge_first, edge_first + edgelist_srcs.size()); - return thrust::unique(handle.get_thrust_policy(), - edge_first, - edge_first + edgelist_srcs.size()) == (edge_first + edgelist_srcs.size()); - } + auto edge_first = + thrust::make_zip_iterator(thrust::make_tuple(edgelist_srcs.begin(), edgelist_dsts.begin())); + thrust::sort(handle.get_thrust_policy(), edge_first, edge_first + edgelist_srcs.size()); + return thrust::unique(handle.get_thrust_policy(), + edge_first, + edge_first + edgelist_srcs.size()) == (edge_first + edgelist_srcs.size()); } -template +template std::enable_if_t check_graph_constructor_input_arguments( raft::handle_t const& handle, - std::vector> const& edgelists, + std::vector> const& edgelists, graph_meta_t meta, bool do_expensive_check) { @@ -309,17 +247,12 @@ std::enable_if_t check_graph_constructor_input_arguments( (detail::num_sparse_segments_per_vertex_partition + 3) * col_comm_size), "Invalid input argument: meta.edge_partition_segment_offsets.size() returns an invalid value."); - auto is_weighted = edgelists[0].weights.has_value(); - CUGRAPH_EXPECTS( std::any_of(edgelists.begin(), edgelists.end(), - [is_weighted](auto edgelist) { - return (edgelist.srcs.size() != edgelist.dsts.size()) || - (is_weighted && (edgelist.srcs.size() != (*(edgelist.weights)).size())); - }) == false, - "Invalid input argument: edgelists[].srcs.size() and edgelists[].dsts.size() should coincide, " - "if edgelists[].weights.has_value(), (*(edgelists[].weights)).size() should also coincide."); + [](auto edgelist) { return edgelist.srcs.size() != edgelist.dsts.size(); }) == + false, + "Invalid input argument: edgelists[].srcs.size() and edgelists[].dsts.size() should coincide."); // optional expensive checks @@ -358,8 +291,7 @@ std::enable_if_t check_graph_constructor_input_arguments( if (meta.properties.is_symmetric) { CUGRAPH_EXPECTS( - (check_symmetric(handle, - edgelists)), + (check_symmetric(handle, edgelists)), "Invalid input argument: meta.property.is_symmetric is true but the input edge list is not " "symmetric."); } @@ -372,26 +304,18 @@ std::enable_if_t check_graph_constructor_input_arguments( } } -template +template std::enable_if_t check_graph_constructor_input_arguments( raft::handle_t const& handle, - edgelist_t const& edgelist, + edgelist_t const& edgelist, graph_meta_t meta, bool do_expensive_check) { // cheap error checks - auto is_weighted = edgelist.weights.has_value(); - CUGRAPH_EXPECTS( - (edgelist.srcs.size() == edgelist.dsts.size()) && - (!is_weighted || (edgelist.srcs.size() == (*(edgelist.weights)).size())), - "Invalid input argument: edgelists.srcs.size() and edgelists.dsts.size() should coincide, if " - "edgelists.weights.has_value(), (*(edgelists.weights)).size() should also coincide."); + edgelist.srcs.size() == edgelist.dsts.size(), + "Invalid input argument: edgelists.srcs.size() and edgelists.dsts.size() should coincide."); CUGRAPH_EXPECTS( !meta.segment_offsets.has_value() || @@ -415,15 +339,14 @@ std::enable_if_t check_graph_constructor_input_arguments( if (meta.properties.is_symmetric) { CUGRAPH_EXPECTS( - (check_symmetric( - handle, std::vector>{edgelist})), + (check_symmetric( + handle, std::vector>{edgelist})), "Invalid input argument: meta.property.is_symmetric is true but the input edge list is not " "symmetric."); } if (!meta.properties.is_multigraph) { CUGRAPH_EXPECTS( - check_no_parallel_edge(handle, - std::vector>{edgelist}), + check_no_parallel_edge(handle, std::vector>{edgelist}), "Invalid input argument: meta.property.is_multigraph is false but the input edge list has " "parallel edges."); } @@ -687,187 +610,25 @@ update_local_sorted_unique_edge_majors_minors( } // namespace -template -graph_t>:: - graph_t(raft::handle_t const& handle, - std::vector> const& edgelists, - graph_meta_t meta, - bool do_expensive_check) - : detail::graph_base_t( - handle, meta.number_of_vertices, meta.number_of_edges, meta.properties), - partition_(meta.partition) -{ - auto& col_comm = handle.get_subcomm(cugraph::partition_2d::key_naming_t().col_name()); - auto const col_comm_size = col_comm.get_size(); - - auto is_weighted = edgelists[0].weights.has_value(); - auto num_segments_per_vertex_partition = - static_cast(meta.edge_partition_segment_offsets.size() / col_comm_size); - auto use_dcs = - num_segments_per_vertex_partition > (detail::num_sparse_segments_per_vertex_partition + 2); - - check_graph_constructor_input_arguments( - handle, edgelists, meta, do_expensive_check); - - edge_partition_segment_offsets_ = meta.edge_partition_segment_offsets; - - // compress edge list (COO) to CSR (or CSC) or CSR + DCSR (CSC + DCSC) hybrid - - edge_partition_offsets_.reserve(edgelists.size()); - edge_partition_indices_.reserve(edgelists.size()); - if (is_weighted) { - edge_partition_weights_ = std::vector>{}; - (*edge_partition_weights_).reserve(edgelists.size()); - } - if (use_dcs) { - edge_partition_dcs_nzd_vertices_ = std::vector>{}; - edge_partition_dcs_nzd_vertex_counts_ = std::vector{}; - (*edge_partition_dcs_nzd_vertices_).reserve(edgelists.size()); - (*edge_partition_dcs_nzd_vertex_counts_).reserve(edgelists.size()); - } - for (size_t i = 0; i < edgelists.size(); ++i) { - auto [major_range_first, major_range_last] = partition_.local_edge_partition_major_range(i); - auto [minor_range_first, minor_range_last] = partition_.local_edge_partition_minor_range(); - rmm::device_uvector offsets(size_t{0}, handle.get_stream()); - rmm::device_uvector indices(size_t{0}, handle.get_stream()); - std::optional> weights{std::nullopt}; - std::optional> dcs_nzd_vertices{std::nullopt}; - auto major_hypersparse_first = - use_dcs ? std::make_optional( - major_range_first + - edge_partition_segment_offsets_[num_segments_per_vertex_partition * i + - detail::num_sparse_segments_per_vertex_partition]) - : std::nullopt; - if (edgelists[i].weights) { - std::tie(offsets, indices, weights, dcs_nzd_vertices) = - detail::compress_edgelist(edgelists[i].srcs.begin(), - edgelists[i].srcs.end(), - edgelists[i].dsts.begin(), - (*(edgelists[i].weights)).begin(), - major_range_first, - major_hypersparse_first, - major_range_last, - minor_range_first, - minor_range_last, - handle.get_stream()); - } else { - std::tie(offsets, indices, dcs_nzd_vertices) = - detail::compress_edgelist(edgelists[i].srcs.begin(), - edgelists[i].srcs.end(), - edgelists[i].dsts.begin(), - major_range_first, - major_hypersparse_first, - major_range_last, - minor_range_first, - minor_range_last, - handle.get_stream()); - } - - edge_partition_offsets_.push_back(std::move(offsets)); - edge_partition_indices_.push_back(std::move(indices)); - if (is_weighted) { (*edge_partition_weights_).push_back(std::move(*weights)); } - if (use_dcs) { - auto dcs_nzd_vertex_count = static_cast((*dcs_nzd_vertices).size()); - (*edge_partition_dcs_nzd_vertices_).push_back(std::move(*dcs_nzd_vertices)); - (*edge_partition_dcs_nzd_vertex_counts_).push_back(dcs_nzd_vertex_count); - } - } - - // segmented sort neighbors - - for (size_t i = 0; i < edge_partition_offsets_.size(); ++i) { - if (edge_partition_weights_) { - detail::sort_adjacency_list( - handle, - raft::device_span(edge_partition_offsets_[i].data(), - edge_partition_offsets_[i].size()), - edge_partition_indices_[i].begin(), - edge_partition_indices_[i].end(), - (*edge_partition_weights_)[i].begin()); - } else { - detail::sort_adjacency_list( - handle, - raft::device_span(edge_partition_offsets_[i].data(), - edge_partition_offsets_[i].size()), - edge_partition_indices_[i].begin(), - edge_partition_indices_[i].end()); - } - } - - // update local sorted unique edge sources/destinations (only if key, value pair will be used) - - if constexpr (store_transposed) { - std::tie(local_sorted_unique_edge_dsts_, - local_sorted_unique_edge_dst_chunk_start_offsets_, - local_sorted_unique_edge_dst_chunk_size_, - local_sorted_unique_edge_srcs_, - local_sorted_unique_edge_src_chunk_start_offsets_, - local_sorted_unique_edge_src_chunk_size_, - local_sorted_unique_edge_src_vertex_partition_offsets_) = - update_local_sorted_unique_edge_majors_minors( - handle, - meta, - edge_partition_offsets_, - edge_partition_indices_, - edge_partition_dcs_nzd_vertices_, - edge_partition_dcs_nzd_vertex_counts_); - } else { - std::tie(local_sorted_unique_edge_srcs_, - local_sorted_unique_edge_src_chunk_start_offsets_, - local_sorted_unique_edge_src_chunk_size_, - local_sorted_unique_edge_dsts_, - local_sorted_unique_edge_dst_chunk_start_offsets_, - local_sorted_unique_edge_dst_chunk_size_, - local_sorted_unique_edge_dst_vertex_partition_offsets_) = - update_local_sorted_unique_edge_majors_minors( - handle, - meta, - edge_partition_offsets_, - edge_partition_indices_, - edge_partition_dcs_nzd_vertices_, - edge_partition_dcs_nzd_vertex_counts_); - } -} - -template -graph_t>:: - graph_t( - raft::handle_t const& handle, - std::vector>&& edge_partition_offsets, - std::vector>&& edge_partition_indices, - std::optional>>&& edge_partition_weights, - std::optional>>&& edge_partition_dcs_nzd_vertices, - graph_meta_t meta, - bool do_expensive_check) - : detail::graph_base_t( +template +graph_t>::graph_t( + raft::handle_t const& handle, + std::vector>&& edge_partition_offsets, + std::vector>&& edge_partition_indices, + std::optional>>&& edge_partition_dcs_nzd_vertices, + graph_meta_t meta, + bool do_expensive_check) + : detail::graph_base_t( handle, meta.number_of_vertices, meta.number_of_edges, meta.properties), partition_(meta.partition) { CUGRAPH_EXPECTS( edge_partition_offsets.size() == edge_partition_indices.size(), "Invalid input argument: edge_partition_offsets.size() != edge_partition_indices.size()."); - CUGRAPH_EXPECTS(!edge_partition_weights.has_value() || - (edge_partition_indices.size() == (*edge_partition_weights).size()), - "Invalid input argument: edge_partition_weights.has_value() && " - "edge_partition_indices.size() != (*edge_partition_weights).size()."); CUGRAPH_EXPECTS(!edge_partition_dcs_nzd_vertices.has_value() || (edge_partition_indices.size() == (*edge_partition_dcs_nzd_vertices).size()), "Invalid input argument: edge_partition_dcs_nzd_vertices.has_value() && " "edge_partition_indices.size() != (*edge_partition_dcs_nzd_vertices).size()."); - for (size_t i = 0; i < edge_partition_offsets.size(); ++i) { - CUGRAPH_EXPECTS(!edge_partition_weights.has_value() || - (edge_partition_indices[i].size() == (*edge_partition_weights)[i].size()), - "Invalid input argument: edge_partition_weights.has_value() && " - "edge_partition_indices[].size() != (*edge_partition_weights)[].size()."); - } edge_partition_segment_offsets_ = meta.edge_partition_segment_offsets; @@ -875,7 +636,6 @@ graph_t -graph_t>:: - graph_t(raft::handle_t const& handle, - edgelist_t const& edgelist, - graph_meta_t meta, - bool do_expensive_check) - : detail::graph_base_t( - handle, meta.number_of_vertices, static_cast(edgelist.srcs.size()), meta.properties), - offsets_(rmm::device_uvector(0, handle.get_stream())), - indices_(rmm::device_uvector(0, handle.get_stream())), - segment_offsets_(meta.segment_offsets) -{ - check_graph_constructor_input_arguments( - handle, edgelist, meta, do_expensive_check); - - // convert edge list (COO) to compressed sparse format (CSR or CSC) - - if (edgelist.weights) { - std::tie(offsets_, indices_, weights_, std::ignore) = - detail::compress_edgelist(edgelist.srcs.begin(), - edgelist.srcs.end(), - edgelist.dsts.begin(), - (*(edgelist.weights)).begin(), - vertex_t{0}, - std::optional{std::nullopt}, - this->number_of_vertices(), - vertex_t{0}, - this->number_of_vertices(), - handle.get_stream()); - } else { - std::tie(offsets_, indices_, std::ignore) = - detail::compress_edgelist(edgelist.srcs.begin(), - edgelist.srcs.end(), - edgelist.dsts.begin(), - vertex_t{0}, - std::optional{std::nullopt}, - this->number_of_vertices(), - vertex_t{0}, - this->number_of_vertices(), - handle.get_stream()); - } - - // segmented sort neighbors - - if (weights_) { - detail::sort_adjacency_list(handle, - raft::device_span(offsets_.data(), offsets_.size()), - indices_.begin(), - indices_.end(), - (*weights_).begin()); - } else { - detail::sort_adjacency_list(handle, - raft::device_span(offsets_.data(), offsets_.size()), - indices_.begin(), - indices_.end()); - } -} - -template -graph_t>:: - graph_t(raft::handle_t const& handle, - rmm::device_uvector&& offsets, - rmm::device_uvector&& indices, - std::optional>&& weights, - graph_meta_t meta, - bool do_expensive_check) - : detail::graph_base_t( +template +graph_t>::graph_t( + raft::handle_t const& handle, + rmm::device_uvector&& offsets, + rmm::device_uvector&& indices, + graph_meta_t meta, + bool do_expensive_check) + : detail::graph_base_t( handle, meta.number_of_vertices, static_cast(indices.size()), meta.properties), offsets_(std::move(offsets)), indices_(std::move(indices)), - weights_(std::move(weights)), segment_offsets_(meta.segment_offsets) { - CUGRAPH_EXPECTS( - !weights.has_value() || (indices.size() == (*weights).size()), - "Invalid input argument: weights.has_value() && indices.size() != (*weights).size()."); } } // namespace cugraph diff --git a/cpp/src/structure/graph_mg.cu b/cpp/src/structure/graph_mg.cu index bdadb0c45c0..293e464fd19 100644 --- a/cpp/src/structure/graph_mg.cu +++ b/cpp/src/structure/graph_mg.cu @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, NVIDIA CORPORATION. + * Copyright (c) 2021-2022, NVIDIA CORPORATION. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,17 +19,11 @@ namespace cugraph { // MG instantiation -template class graph_t; -template class graph_t; -template class graph_t; -template class graph_t; -template class graph_t; -template class graph_t; -template class graph_t; -template class graph_t; -template class graph_t; -template class graph_t; -template class graph_t; -template class graph_t; +template class graph_t; +template class graph_t; +template class graph_t; +template class graph_t; +template class graph_t; +template class graph_t; } // namespace cugraph diff --git a/cpp/src/structure/graph_sg.cu b/cpp/src/structure/graph_sg.cu index 69a44c4823d..bac0b3f0be9 100644 --- a/cpp/src/structure/graph_sg.cu +++ b/cpp/src/structure/graph_sg.cu @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, NVIDIA CORPORATION. + * Copyright (c) 2021-2022, NVIDIA CORPORATION. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,17 +19,11 @@ namespace cugraph { // SG instantiation -template class graph_t; -template class graph_t; -template class graph_t; -template class graph_t; -template class graph_t; -template class graph_t; -template class graph_t; -template class graph_t; -template class graph_t; -template class graph_t; -template class graph_t; -template class graph_t; +template class graph_t; +template class graph_t; +template class graph_t; +template class graph_t; +template class graph_t; +template class graph_t; } // namespace cugraph diff --git a/cpp/src/structure/graph_view_impl.cuh b/cpp/src/structure/graph_view_impl.cuh index eb028797699..e84506275b6 100644 --- a/cpp/src/structure/graph_view_impl.cuh +++ b/cpp/src/structure/graph_view_impl.cuh @@ -20,8 +20,8 @@ #include #include +#include #include -#include #include #include #include @@ -194,14 +194,10 @@ rmm::device_uvector compute_major_degrees(raft::handle_t const& handle, return degrees; } -template +template rmm::device_uvector compute_minor_degrees( raft::handle_t const& handle, - graph_view_t const& graph_view) + graph_view_t const& graph_view) { rmm::device_uvector minor_degrees(graph_view.local_vertex_partition_range_size(), handle.get_stream()); @@ -211,7 +207,8 @@ rmm::device_uvector compute_minor_degrees( graph_view, edge_src_dummy_property_t{}.view(), edge_dst_dummy_property_t{}.view(), - [] __device__(vertex_t, vertex_t, weight_t, auto, auto) { return edge_t{1}; }, + edge_dummy_property_t{}.view(), + [] __device__(vertex_t, vertex_t, auto, auto, auto) { return edge_t{1}; }, edge_t{0}, minor_degrees.data()); } else { @@ -220,7 +217,8 @@ rmm::device_uvector compute_minor_degrees( graph_view, edge_src_dummy_property_t{}.view(), edge_dst_dummy_property_t{}.view(), - [] __device__(vertex_t, vertex_t, weight_t, auto, auto) { return edge_t{1}; }, + edge_dummy_property_t{}.view(), + [] __device__(vertex_t, vertex_t, auto, auto, auto) { return edge_t{1}; }, edge_t{0}, minor_degrees.data()); } @@ -231,9 +229,9 @@ rmm::device_uvector compute_minor_degrees( // FIXME: block size requires tuning int32_t constexpr count_edge_partition_multi_edges_block_size = 1024; -template +template __global__ void for_all_major_for_all_nbr_mid_degree( - edge_partition_device_view_t edge_partition, + edge_partition_device_view_t edge_partition, vertex_t major_range_first, vertex_t major_range_last, edge_t* count) @@ -252,9 +250,9 @@ __global__ void for_all_major_for_all_nbr_mid_degree( while (idx < static_cast(major_range_last - major_range_first)) { auto major_offset = static_cast(major_start_offset + idx); vertex_t const* indices{nullptr}; - [[maybe_unused]] thrust::optional weights{thrust::nullopt}; + [[maybe_unused]] edge_t edge_offset{}; edge_t local_degree{}; - thrust::tie(indices, weights, local_degree) = edge_partition.local_edges(major_offset); + thrust::tie(indices, edge_offset, local_degree) = edge_partition.local_edges(major_offset); for (edge_t i = lane_id; i < local_degree; i += raft::warp_size()) { if ((i != 0) && (indices[i - 1] == indices[i])) { ++count_sum; } } @@ -265,9 +263,9 @@ __global__ void for_all_major_for_all_nbr_mid_degree( if (threadIdx.x == 0) { atomic_accumulate_edge_op_result(count, count_sum); } } -template +template __global__ void for_all_major_for_all_nbr_high_degree( - edge_partition_device_view_t edge_partition, + edge_partition_device_view_t edge_partition, vertex_t major_range_first, vertex_t major_range_last, edge_t* count) @@ -283,9 +281,9 @@ __global__ void for_all_major_for_all_nbr_high_degree( while (idx < static_cast(major_range_last - major_range_first)) { auto major_offset = major_start_offset + idx; vertex_t const* indices{nullptr}; - [[maybe_unused]] thrust::optional weights{thrust::nullopt}; + [[maybe_unused]] edge_t edge_offset{}; edge_t local_degree{}; - thrust::tie(indices, weights, local_degree) = + thrust::tie(indices, edge_offset, local_degree) = edge_partition.local_edges(static_cast(major_offset)); for (edge_t i = threadIdx.x; i < local_degree; i += blockDim.x) { if ((i != 0) && (indices[i - 1] == indices[i])) { ++count_sum; } @@ -297,10 +295,10 @@ __global__ void for_all_major_for_all_nbr_high_degree( if (threadIdx.x == 0) { atomic_accumulate_edge_op_result(count, count_sum); } } -template +template edge_t count_edge_partition_multi_edges( raft::handle_t const& handle, - edge_partition_device_view_t edge_partition, + edge_partition_device_view_t edge_partition, std::optional> const& segment_offsets) { auto execution_policy = handle.get_thrust_policy(); @@ -347,9 +345,10 @@ edge_t count_edge_partition_multi_edges( [edge_partition] __device__(auto major) { auto major_offset = edge_partition.major_offset_from_major_nocheck(major); vertex_t const* indices{nullptr}; - [[maybe_unused]] thrust::optional weights{thrust::nullopt}; + [[maybe_unused]] edge_t edge_offset{}; edge_t local_degree{}; - thrust::tie(indices, weights, local_degree) = edge_partition.local_edges(major_offset); + thrust::tie(indices, edge_offset, local_degree) = + edge_partition.local_edges(major_offset); edge_t count{0}; for (edge_t i = 1; i < local_degree; ++i) { // assumes neighbors are sorted if (indices[i - 1] == indices[i]) { ++count; } @@ -368,9 +367,9 @@ edge_t count_edge_partition_multi_edges( auto major_idx = major_start_offset + idx; // major_offset != major_idx in the hypersparse region vertex_t const* indices{nullptr}; - [[maybe_unused]] thrust::optional weights{thrust::nullopt}; + [[maybe_unused]] edge_t edge_offset{}; edge_t local_degree{}; - thrust::tie(indices, weights, local_degree) = edge_partition.local_edges(major_idx); + thrust::tie(indices, edge_offset, local_degree) = edge_partition.local_edges(major_idx); edge_t count{0}; for (edge_t i = 1; i < local_degree; ++i) { // assumes neighbors are sorted if (indices[i - 1] == indices[i]) { ++count; } @@ -391,9 +390,9 @@ edge_t count_edge_partition_multi_edges( [edge_partition] __device__(auto major) { auto major_offset = edge_partition.major_offset_from_major_nocheck(major); vertex_t const* indices{nullptr}; - [[maybe_unused]] thrust::optional weights{thrust::nullopt}; + [[maybe_unused]] edge_t edge_offset{}; edge_t local_degree{}; - thrust::tie(indices, weights, local_degree) = edge_partition.local_edges(major_offset); + thrust::tie(indices, edge_offset, local_degree) = edge_partition.local_edges(major_offset); edge_t count{0}; for (edge_t i = 1; i < local_degree; ++i) { // assumes neighbors are sorted if (indices[i - 1] == indices[i]) { ++count; } @@ -407,24 +406,18 @@ edge_t count_edge_partition_multi_edges( } // namespace -template -graph_view_t>:: +template +graph_view_t>:: graph_view_t(raft::handle_t const& handle, std::vector const& edge_partition_offsets, std::vector const& edge_partition_indices, - std::optional> const& edge_partition_weights, std::optional> const& edge_partition_dcs_nzd_vertices, std::optional> const& edge_partition_dcs_nzd_vertex_counts, graph_view_meta_t meta) - : detail::graph_base_t( + : detail::graph_base_t( handle, meta.number_of_vertices, meta.number_of_edges, meta.properties), edge_partition_offsets_(edge_partition_offsets), edge_partition_indices_(edge_partition_indices), - edge_partition_weights_(edge_partition_weights), edge_partition_dcs_nzd_vertices_(edge_partition_dcs_nzd_vertices), edge_partition_dcs_nzd_vertex_counts_(edge_partition_dcs_nzd_vertex_counts), edge_partition_number_of_edges_( @@ -453,16 +446,11 @@ graph_view_thandle_ptr()->get_subcomm(cugraph::partition_2d::key_naming_t().col_name()).get_size(); - auto is_weighted = edge_partition_weights.has_value(); - auto use_dcs = edge_partition_dcs_nzd_vertices.has_value(); + auto use_dcs = edge_partition_dcs_nzd_vertices.has_value(); CUGRAPH_EXPECTS(edge_partition_offsets.size() == edge_partition_indices.size(), "Internal Error: edge_partition_offsets.size() and " "edge_partition_indices.size() should coincide."); - CUGRAPH_EXPECTS( - !is_weighted || ((*edge_partition_weights).size() == edge_partition_offsets.size()), - "Internal Error: edge_partition_weights.size() should coincide with " - "edge_partition_offsets.size() (if weighted)."); CUGRAPH_EXPECTS(edge_partition_dcs_nzd_vertex_counts.has_value() == use_dcs, "edge_partition_dcs_nzd_vertices.has_value() and " "edge_partition_dcs_nzd_vertex_counts.has_value() should coincide"); @@ -486,27 +474,16 @@ graph_view_t -graph_view_t>:: +template +graph_view_t>:: graph_view_t(raft::handle_t const& handle, edge_t const* offsets, vertex_t const* indices, - std::optional weights, graph_view_meta_t meta) - : detail::graph_base_t( + : detail::graph_base_t( handle, meta.number_of_vertices, meta.number_of_edges, meta.properties), offsets_(offsets), indices_(indices), - weights_(weights), segment_offsets_(meta.segment_offsets) { // cheap error checks @@ -519,13 +496,9 @@ graph_view_t +template rmm::device_uvector -graph_view_t>:: +graph_view_t>:: compute_in_degrees(raft::handle_t const& handle) const { if (store_transposed) { @@ -540,18 +513,10 @@ graph_view_t +template rmm::device_uvector -graph_view_t>::compute_in_degrees(raft::handle_t const& handle) const +graph_view_t>:: + compute_in_degrees(raft::handle_t const& handle) const { if (store_transposed) { return compute_major_degrees(handle, this->offsets_, this->local_vertex_partition_range_size()); @@ -560,13 +525,9 @@ graph_view_t +template rmm::device_uvector -graph_view_t>:: +graph_view_t>:: compute_out_degrees(raft::handle_t const& handle) const { if (store_transposed) { @@ -581,18 +542,10 @@ graph_view_t +template rmm::device_uvector -graph_view_t>::compute_out_degrees(raft::handle_t const& handle) const +graph_view_t>:: + compute_out_degrees(raft::handle_t const& handle) const { if (store_transposed) { return compute_minor_degrees(handle, *this); @@ -601,13 +554,8 @@ graph_view_t -edge_t -graph_view_t>:: +template +edge_t graph_view_t>:: compute_max_in_degree(raft::handle_t const& handle) const { auto in_degrees = compute_in_degrees(handle); @@ -622,18 +570,9 @@ graph_view_t -edge_t graph_view_t>::compute_max_in_degree(raft::handle_t const& - handle) const +template +edge_t graph_view_t>:: + compute_max_in_degree(raft::handle_t const& handle) const { auto in_degrees = compute_in_degrees(handle); auto it = thrust::max_element(handle.get_thrust_policy(), in_degrees.begin(), in_degrees.end()); @@ -643,13 +582,8 @@ edge_t graph_view_t -edge_t -graph_view_t>:: +template +edge_t graph_view_t>:: compute_max_out_degree(raft::handle_t const& handle) const { auto out_degrees = compute_out_degrees(handle); @@ -664,18 +598,9 @@ graph_view_t -edge_t graph_view_t>::compute_max_out_degree(raft::handle_t const& - handle) const +template +edge_t graph_view_t>:: + compute_max_out_degree(raft::handle_t const& handle) const { auto out_degrees = compute_out_degrees(handle); auto it = thrust::max_element(handle.get_thrust_policy(), out_degrees.begin(), out_degrees.end()); @@ -685,13 +610,8 @@ edge_t graph_view_t -edge_t -graph_view_t>:: +template +edge_t graph_view_t>:: count_self_loops(raft::handle_t const& handle) const { return transform_reduce_e( @@ -699,43 +619,31 @@ graph_view_t -edge_t graph_view_t>::count_self_loops(raft::handle_t const& handle) - const +template +edge_t graph_view_t>:: + count_self_loops(raft::handle_t const& handle) const { return transform_reduce_e( handle, *this, edge_src_dummy_property_t{}.view(), edge_dst_dummy_property_t{}.view(), - [] __device__(vertex_t src, vertex_t dst, auto src_val, auto dst_val) { + edge_dummy_property_t{}.view(), + [] __device__(vertex_t src, vertex_t dst, auto, auto, auto) { return src == dst ? edge_t{1} : edge_t{0}; }, edge_t{0}); } -template -edge_t -graph_view_t>:: +template +edge_t graph_view_t>:: count_multi_edges(raft::handle_t const& handle) const { if (!this->is_multigraph()) { return edge_t{0}; } @@ -744,8 +652,7 @@ graph_view_tnumber_of_local_edge_partitions(); ++i) { count += count_edge_partition_multi_edges( handle, - edge_partition_device_view_t( - this->local_edge_partition_view(i)), + edge_partition_device_view_t(this->local_edge_partition_view(i)), this->local_edge_partition_segment_offsets(i)); } @@ -753,25 +660,15 @@ graph_view_t -edge_t graph_view_t>::count_multi_edges(raft::handle_t const& handle) - const +template +edge_t graph_view_t>:: + count_multi_edges(raft::handle_t const& handle) const { if (!this->is_multigraph()) { return edge_t{0}; } return count_edge_partition_multi_edges( handle, - edge_partition_device_view_t( - this->local_edge_partition_view()), + edge_partition_device_view_t(this->local_edge_partition_view()), this->local_edge_partition_segment_offsets()); } diff --git a/cpp/src/structure/graph_view_mg.cu b/cpp/src/structure/graph_view_mg.cu index ca9560d729d..6ccd0150fe0 100644 --- a/cpp/src/structure/graph_view_mg.cu +++ b/cpp/src/structure/graph_view_mg.cu @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021, NVIDIA CORPORATION. + * Copyright (c) 2020-2022, NVIDIA CORPORATION. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,17 +19,11 @@ namespace cugraph { // MG instantiation -template class graph_view_t; -template class graph_view_t; -template class graph_view_t; -template class graph_view_t; -template class graph_view_t; -template class graph_view_t; -template class graph_view_t; -template class graph_view_t; -template class graph_view_t; -template class graph_view_t; -template class graph_view_t; -template class graph_view_t; +template class graph_view_t; +template class graph_view_t; +template class graph_view_t; +template class graph_view_t; +template class graph_view_t; +template class graph_view_t; } // namespace cugraph diff --git a/cpp/src/structure/graph_view_sg.cu b/cpp/src/structure/graph_view_sg.cu index eb19a1cd9fe..0472d918d23 100644 --- a/cpp/src/structure/graph_view_sg.cu +++ b/cpp/src/structure/graph_view_sg.cu @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021, NVIDIA CORPORATION. + * Copyright (c) 2020-2022, NVIDIA CORPORATION. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,17 +19,11 @@ namespace cugraph { // SG instantiation -template class graph_view_t; -template class graph_view_t; -template class graph_view_t; -template class graph_view_t; -template class graph_view_t; -template class graph_view_t; -template class graph_view_t; -template class graph_view_t; -template class graph_view_t; -template class graph_view_t; -template class graph_view_t; -template class graph_view_t; +template class graph_view_t; +template class graph_view_t; +template class graph_view_t; +template class graph_view_t; +template class graph_view_t; +template class graph_view_t; } // namespace cugraph diff --git a/cpp/src/structure/graph_weight_utils_impl.cuh b/cpp/src/structure/graph_weight_utils_impl.cuh index cca66235c16..3c83cd84b62 100644 --- a/cpp/src/structure/graph_weight_utils_impl.cuh +++ b/cpp/src/structure/graph_weight_utils_impl.cuh @@ -44,7 +44,8 @@ template rmm::device_uvector compute_weight_sums( raft::handle_t const& handle, - graph_view_t const& graph_view) + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view) { rmm::device_uvector weight_sums(graph_view.local_vertex_partition_range_size(), handle.get_stream()); @@ -54,7 +55,8 @@ rmm::device_uvector compute_weight_sums( graph_view, edge_src_dummy_property_t{}.view(), edge_dst_dummy_property_t{}.view(), - [] __device__(vertex_t, vertex_t, weight_t w, auto, auto) { return w; }, + edge_weight_view, + [] __device__(vertex_t, vertex_t, auto, auto, weight_t w) { return w; }, weight_t{0.0}, weight_sums.data()); } else { @@ -63,7 +65,8 @@ rmm::device_uvector compute_weight_sums( graph_view, edge_src_dummy_property_t{}.view(), edge_dst_dummy_property_t{}.view(), - [] __device__(vertex_t, vertex_t, weight_t w, auto, auto) { return w; }, + edge_weight_view, + [] __device__(vertex_t, vertex_t, auto, auto, weight_t w) { return w; }, weight_t{0.0}, weight_sums.data()); } @@ -71,19 +74,6 @@ rmm::device_uvector compute_weight_sums( return weight_sums; } -template -typename graph_view_t::weight_type compute_graph_total_edge_weight(raft::handle_t const& handle, - graph_view_t const& graph_view) -{ - return transform_reduce_e( - handle, - graph_view, - edge_src_dummy_property_t{}.view(), - edge_dst_dummy_property_t{}.view(), - [] __device__(auto, auto, auto wt, auto, auto) { return wt; }, - typename graph_view_t::weight_type{0}); -} - } // namespace template rmm::device_uvector compute_in_weight_sums( raft::handle_t const& handle, - graph_view_t const& graph_view) + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view) { if (store_transposed) { - return compute_weight_sums(handle, graph_view); + return compute_weight_sums(handle, graph_view, edge_weight_view); } else { - return compute_weight_sums(handle, graph_view); + return compute_weight_sums(handle, graph_view, edge_weight_view); } } @@ -109,12 +100,13 @@ template rmm::device_uvector compute_out_weight_sums( raft::handle_t const& handle, - graph_view_t const& graph_view) + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view) { if (store_transposed) { - return compute_weight_sums(handle, graph_view); + return compute_weight_sums(handle, graph_view, edge_weight_view); } else { - return compute_weight_sums(handle, graph_view); + return compute_weight_sums(handle, graph_view, edge_weight_view); } } @@ -125,9 +117,10 @@ template weight_t compute_max_in_weight_sum( raft::handle_t const& handle, - graph_view_t const& graph_view) + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view) { - auto in_weight_sums = compute_in_weight_sums(handle, graph_view); + auto in_weight_sums = compute_in_weight_sums(handle, graph_view, edge_weight_view); auto it = thrust::max_element(handle.get_thrust_policy(), in_weight_sums.begin(), in_weight_sums.end()); weight_t ret{0.0}; @@ -148,9 +141,10 @@ template weight_t compute_max_out_weight_sum( raft::handle_t const& handle, - graph_view_t const& graph_view) + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view) { - auto out_weight_sums = compute_out_weight_sums(handle, graph_view); + auto out_weight_sums = compute_out_weight_sums(handle, graph_view, edge_weight_view); auto it = thrust::max_element(handle.get_thrust_policy(), out_weight_sums.begin(), out_weight_sums.end()); weight_t ret{0.0}; @@ -171,9 +165,17 @@ template weight_t compute_total_edge_weight( raft::handle_t const& handle, - graph_view_t const& graph_view) + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view) { - return compute_graph_total_edge_weight(handle, graph_view); + return transform_reduce_e( + handle, + graph_view, + edge_src_dummy_property_t{}.view(), + edge_dst_dummy_property_t{}.view(), + edge_weight_view, + [] __device__(auto, auto, auto, auto, weight_t w) { return w; }, + weight_t{0}); } } // namespace cugraph diff --git a/cpp/src/structure/graph_weight_utils_mg.cu b/cpp/src/structure/graph_weight_utils_mg.cu index 658c276dbe7..3e433cb41c0 100644 --- a/cpp/src/structure/graph_weight_utils_mg.cu +++ b/cpp/src/structure/graph_weight_utils_mg.cu @@ -23,250 +23,310 @@ namespace cugraph { template rmm::device_uvector compute_in_weight_sums( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); template rmm::device_uvector compute_in_weight_sums( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); template rmm::device_uvector compute_in_weight_sums( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); template rmm::device_uvector compute_in_weight_sums( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); template rmm::device_uvector compute_in_weight_sums( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); template rmm::device_uvector compute_in_weight_sums( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); template rmm::device_uvector compute_in_weight_sums( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); template rmm::device_uvector compute_in_weight_sums( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); template rmm::device_uvector compute_in_weight_sums( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); template rmm::device_uvector compute_in_weight_sums( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); template rmm::device_uvector compute_in_weight_sums( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); template rmm::device_uvector compute_in_weight_sums( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); // compute_out_weight_sums template rmm::device_uvector compute_out_weight_sums( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); template rmm::device_uvector compute_out_weight_sums( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); template rmm::device_uvector compute_out_weight_sums( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); template rmm::device_uvector compute_out_weight_sums( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); template rmm::device_uvector compute_out_weight_sums( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); template rmm::device_uvector compute_out_weight_sums( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); template rmm::device_uvector compute_out_weight_sums( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); template rmm::device_uvector compute_out_weight_sums( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); template rmm::device_uvector compute_out_weight_sums( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); template rmm::device_uvector compute_out_weight_sums( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); template rmm::device_uvector compute_out_weight_sums( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); template rmm::device_uvector compute_out_weight_sums( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); // compute_max_in_weight_sum template float compute_max_in_weight_sum( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); template float compute_max_in_weight_sum( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); template double compute_max_in_weight_sum( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); template double compute_max_in_weight_sum( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); template float compute_max_in_weight_sum( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); template float compute_max_in_weight_sum( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); template double compute_max_in_weight_sum( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); template double compute_max_in_weight_sum( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); template float compute_max_in_weight_sum( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); template float compute_max_in_weight_sum( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); template double compute_max_in_weight_sum( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); template double compute_max_in_weight_sum( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); // compute_max_out_weight_sum template float compute_max_out_weight_sum( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); template float compute_max_out_weight_sum( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); template double compute_max_out_weight_sum( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); template double compute_max_out_weight_sum( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); template float compute_max_out_weight_sum( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); template float compute_max_out_weight_sum( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); template double compute_max_out_weight_sum( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); template double compute_max_out_weight_sum( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); template float compute_max_out_weight_sum( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); template float compute_max_out_weight_sum( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); template double compute_max_out_weight_sum( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); template double compute_max_out_weight_sum( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); // compute_total_edge_weight template float compute_total_edge_weight( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); template float compute_total_edge_weight( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); template double compute_total_edge_weight( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); template double compute_total_edge_weight( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); template float compute_total_edge_weight( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); template float compute_total_edge_weight( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); template double compute_total_edge_weight( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); template double compute_total_edge_weight( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); template float compute_total_edge_weight( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); template float compute_total_edge_weight( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); template double compute_total_edge_weight( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); template double compute_total_edge_weight( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); } // namespace cugraph diff --git a/cpp/src/structure/graph_weight_utils_sg.cu b/cpp/src/structure/graph_weight_utils_sg.cu index acb8499bbce..1b076f08af6 100644 --- a/cpp/src/structure/graph_weight_utils_sg.cu +++ b/cpp/src/structure/graph_weight_utils_sg.cu @@ -23,253 +23,313 @@ namespace cugraph { template rmm::device_uvector compute_in_weight_sums( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); template rmm::device_uvector compute_in_weight_sums( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); template rmm::device_uvector compute_in_weight_sums( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); template rmm::device_uvector compute_in_weight_sums( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); template rmm::device_uvector compute_in_weight_sums( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); template rmm::device_uvector compute_in_weight_sums( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); template rmm::device_uvector compute_in_weight_sums( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); template rmm::device_uvector compute_in_weight_sums( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); template rmm::device_uvector compute_in_weight_sums( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); template rmm::device_uvector compute_in_weight_sums( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); template rmm::device_uvector compute_in_weight_sums( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); template rmm::device_uvector compute_in_weight_sums( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); // compute_out_weight_sums template rmm::device_uvector compute_out_weight_sums( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); template rmm::device_uvector compute_out_weight_sums( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); template rmm::device_uvector compute_out_weight_sums( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); template rmm::device_uvector compute_out_weight_sums( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); template rmm::device_uvector compute_out_weight_sums( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); template rmm::device_uvector compute_out_weight_sums( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); template rmm::device_uvector compute_out_weight_sums( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); template rmm::device_uvector compute_out_weight_sums( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); template rmm::device_uvector compute_out_weight_sums( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); template rmm::device_uvector compute_out_weight_sums( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); template rmm::device_uvector compute_out_weight_sums( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); template rmm::device_uvector compute_out_weight_sums( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); // compute_max_in_weight_sum template float compute_max_in_weight_sum( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); template float compute_max_in_weight_sum( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); template double compute_max_in_weight_sum( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); template double compute_max_in_weight_sum( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); template float compute_max_in_weight_sum( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); template float compute_max_in_weight_sum( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); template double compute_max_in_weight_sum( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); template double compute_max_in_weight_sum( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); template float compute_max_in_weight_sum( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); template float compute_max_in_weight_sum( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); template double compute_max_in_weight_sum( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); template double compute_max_in_weight_sum( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); // compute_max_out_weight_sum template float compute_max_out_weight_sum( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); template float compute_max_out_weight_sum( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); template double compute_max_out_weight_sum( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); template double compute_max_out_weight_sum( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); template float compute_max_out_weight_sum( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); template float compute_max_out_weight_sum( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); template double compute_max_out_weight_sum( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); template double compute_max_out_weight_sum( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); template float compute_max_out_weight_sum( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); template float compute_max_out_weight_sum( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); template double compute_max_out_weight_sum( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); template double compute_max_out_weight_sum( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); // compute_total_edge_weight template float compute_total_edge_weight( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); template float compute_total_edge_weight( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); template double compute_total_edge_weight( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); template double compute_total_edge_weight( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); template float compute_total_edge_weight( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); template float compute_total_edge_weight( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); template double compute_total_edge_weight( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); template double compute_total_edge_weight( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); template float compute_total_edge_weight( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); template float compute_total_edge_weight( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); template double compute_total_edge_weight( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); template double compute_total_edge_weight( raft::handle_t const& handle, - graph_view_t const& graph_view); + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view); } // namespace cugraph diff --git a/cpp/src/structure/induced_subgraph_impl.cuh b/cpp/src/structure/induced_subgraph_impl.cuh index b377cb2eab1..245fc6cc595 100644 --- a/cpp/src/structure/induced_subgraph_impl.cuh +++ b/cpp/src/structure/induced_subgraph_impl.cuh @@ -22,7 +22,7 @@ #include #include -#include +#include #include #include #include @@ -65,9 +65,9 @@ struct induced_subgraph_weighted_edge_op { return_type __device__ operator()(thrust::tuple tagged_src, vertex_t dst, - weight_t wgt, property_t sv, - property_t dv) + property_t dv, + weight_t wgt) { size_t subgraph = thrust::get<1>(tagged_src); return thrust::binary_search(thrust::seq, @@ -90,7 +90,8 @@ struct induced_subgraph_unweighted_edge_op { return_type __device__ operator()(thrust::tuple tagged_src, vertex_t dst, property_t sv, - property_t dv) + property_t dv, + thrust::nullopt_t) { size_t subgraph = thrust::get<1>(tagged_src); return thrust::binary_search(thrust::seq, @@ -115,7 +116,8 @@ std::tuple, rmm::device_uvector> extract_induced_subgraphs( raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + std::optional> edge_weight_view, raft::device_span subgraph_offsets, raft::device_span subgraph_vertices, bool do_expensive_check) @@ -240,7 +242,7 @@ extract_induced_subgraphs( std::optional> edge_weights{std::nullopt}; rmm::device_uvector subgraph_edge_graph_ids(0, handle.get_stream()); - if (graph_view.is_weighted()) { + if (edge_weight_view) { edge_weights = std::make_optional(rmm::device_uvector(0, handle.get_stream())); std::tie(edge_majors, edge_minors, *edge_weights, subgraph_edge_graph_ids) = @@ -250,6 +252,7 @@ extract_induced_subgraphs( vertex_frontier.bucket(0), edge_src_dummy_property_t{}.view(), edge_dst_dummy_property_t{}.view(), + *edge_weight_view, detail::induced_subgraph_weighted_edge_op{ dst_subgraph_offsets, dst_subgraph_vertices}, do_expensive_check); @@ -269,6 +272,7 @@ extract_induced_subgraphs( vertex_frontier.bucket(0), edge_src_dummy_property_t{}.view(), edge_dst_dummy_property_t{}.view(), + edge_dummy_property_t{}.view(), detail::induced_subgraph_unweighted_edge_op{ dst_subgraph_offsets, dst_subgraph_vertices}, do_expensive_check); diff --git a/cpp/src/structure/induced_subgraph_mg.cu b/cpp/src/structure/induced_subgraph_mg.cu index 6a5ef6338bc..c7b11ea38d3 100644 --- a/cpp/src/structure/induced_subgraph_mg.cu +++ b/cpp/src/structure/induced_subgraph_mg.cu @@ -23,60 +23,72 @@ template std::tuple, rmm::device_uvector, std::optional>, rmm::device_uvector> -extract_induced_subgraphs(raft::handle_t const& handle, - graph_view_t const& graph_view, - raft::device_span subgraph_offsets, - raft::device_span subgraph_vertices, - bool do_expensive_check); +extract_induced_subgraphs( + raft::handle_t const& handle, + graph_view_t const& graph_view, + std::optional> edge_weight_view, + raft::device_span subgraph_offsets, + raft::device_span subgraph_vertices, + bool do_expensive_check); template std::tuple, rmm::device_uvector, std::optional>, rmm::device_uvector> -extract_induced_subgraphs(raft::handle_t const& handle, - graph_view_t const& graph_view, - raft::device_span subgraph_offsets, - raft::device_span subgraph_vertices, - bool do_expensive_check); +extract_induced_subgraphs( + raft::handle_t const& handle, + graph_view_t const& graph_view, + std::optional> edge_weight_view, + raft::device_span subgraph_offsets, + raft::device_span subgraph_vertices, + bool do_expensive_check); template std::tuple, rmm::device_uvector, std::optional>, rmm::device_uvector> -extract_induced_subgraphs(raft::handle_t const& handle, - graph_view_t const& graph_view, - raft::device_span subgraph_offsets, - raft::device_span subgraph_vertices, - bool do_expensive_check); +extract_induced_subgraphs( + raft::handle_t const& handle, + graph_view_t const& graph_view, + std::optional> edge_weight_view, + raft::device_span subgraph_offsets, + raft::device_span subgraph_vertices, + bool do_expensive_check); template std::tuple, rmm::device_uvector, std::optional>, rmm::device_uvector> -extract_induced_subgraphs(raft::handle_t const& handle, - graph_view_t const& graph_view, - raft::device_span subgraph_offsets, - raft::device_span subgraph_vertices, - bool do_expensive_check); +extract_induced_subgraphs( + raft::handle_t const& handle, + graph_view_t const& graph_view, + std::optional> edge_weight_view, + raft::device_span subgraph_offsets, + raft::device_span subgraph_vertices, + bool do_expensive_check); template std::tuple, rmm::device_uvector, std::optional>, rmm::device_uvector> -extract_induced_subgraphs(raft::handle_t const& handle, - graph_view_t const& graph_view, - raft::device_span subgraph_offsets, - raft::device_span subgraph_vertices, - bool do_expensive_check); +extract_induced_subgraphs( + raft::handle_t const& handle, + graph_view_t const& graph_view, + std::optional> edge_weight_view, + raft::device_span subgraph_offsets, + raft::device_span subgraph_vertices, + bool do_expensive_check); template std::tuple, rmm::device_uvector, std::optional>, rmm::device_uvector> -extract_induced_subgraphs(raft::handle_t const& handle, - graph_view_t const& graph_view, - raft::device_span subgraph_offsets, - raft::device_span subgraph_vertices, - bool do_expensive_check); +extract_induced_subgraphs( + raft::handle_t const& handle, + graph_view_t const& graph_view, + std::optional> edge_weight_view, + raft::device_span subgraph_offsets, + raft::device_span subgraph_vertices, + bool do_expensive_check); } // namespace cugraph diff --git a/cpp/src/structure/induced_subgraph_sg.cu b/cpp/src/structure/induced_subgraph_sg.cu index 137e6b5e58f..2011a237790 100644 --- a/cpp/src/structure/induced_subgraph_sg.cu +++ b/cpp/src/structure/induced_subgraph_sg.cu @@ -23,60 +23,72 @@ template std::tuple, rmm::device_uvector, std::optional>, rmm::device_uvector> -extract_induced_subgraphs(raft::handle_t const& handle, - graph_view_t const& graph_view, - raft::device_span subgraph_offsets, - raft::device_span subgraph_vertices, - bool do_expensive_check); +extract_induced_subgraphs( + raft::handle_t const& handle, + graph_view_t const& graph_view, + std::optional> edge_weight_view, + raft::device_span subgraph_offsets, + raft::device_span subgraph_vertices, + bool do_expensive_check); template std::tuple, rmm::device_uvector, std::optional>, rmm::device_uvector> -extract_induced_subgraphs(raft::handle_t const& handle, - graph_view_t const& graph_view, - raft::device_span subgraph_offsets, - raft::device_span subgraph_vertices, - bool do_expensive_check); +extract_induced_subgraphs( + raft::handle_t const& handle, + graph_view_t const& graph_view, + std::optional> edge_weight_view, + raft::device_span subgraph_offsets, + raft::device_span subgraph_vertices, + bool do_expensive_check); template std::tuple, rmm::device_uvector, std::optional>, rmm::device_uvector> -extract_induced_subgraphs(raft::handle_t const& handle, - graph_view_t const& graph_view, - raft::device_span subgraph_offsets, - raft::device_span subgraph_vertices, - bool do_expensive_check); +extract_induced_subgraphs( + raft::handle_t const& handle, + graph_view_t const& graph_view, + std::optional> edge_weight_view, + raft::device_span subgraph_offsets, + raft::device_span subgraph_vertices, + bool do_expensive_check); template std::tuple, rmm::device_uvector, std::optional>, rmm::device_uvector> -extract_induced_subgraphs(raft::handle_t const& handle, - graph_view_t const& graph_view, - raft::device_span subgraph_offsets, - raft::device_span subgraph_vertices, - bool do_expensive_check); +extract_induced_subgraphs( + raft::handle_t const& handle, + graph_view_t const& graph_view, + std::optional> edge_weight_view, + raft::device_span subgraph_offsets, + raft::device_span subgraph_vertices, + bool do_expensive_check); template std::tuple, rmm::device_uvector, std::optional>, rmm::device_uvector> -extract_induced_subgraphs(raft::handle_t const& handle, - graph_view_t const& graph_view, - raft::device_span subgraph_offsets, - raft::device_span subgraph_vertices, - bool do_expensive_check); +extract_induced_subgraphs( + raft::handle_t const& handle, + graph_view_t const& graph_view, + std::optional> edge_weight_view, + raft::device_span subgraph_offsets, + raft::device_span subgraph_vertices, + bool do_expensive_check); template std::tuple, rmm::device_uvector, std::optional>, rmm::device_uvector> -extract_induced_subgraphs(raft::handle_t const& handle, - graph_view_t const& graph_view, - raft::device_span subgraph_offsets, - raft::device_span subgraph_vertices, - bool do_expensive_check); +extract_induced_subgraphs( + raft::handle_t const& handle, + graph_view_t const& graph_view, + std::optional> edge_weight_view, + raft::device_span subgraph_offsets, + raft::device_span subgraph_vertices, + bool do_expensive_check); } // namespace cugraph diff --git a/cpp/src/structure/symmetrize_edgelist_sg.cu b/cpp/src/structure/symmetrize_edgelist_sg.cu index 87afd7b7fa9..3dab0d801c7 100644 --- a/cpp/src/structure/symmetrize_edgelist_sg.cu +++ b/cpp/src/structure/symmetrize_edgelist_sg.cu @@ -17,7 +17,7 @@ namespace cugraph { -// MG instantiation +// SG instantiation template std::tuple, rmm::device_uvector, diff --git a/cpp/src/structure/symmetrize_graph_impl.cuh b/cpp/src/structure/symmetrize_graph_impl.cuh index b466e62e68d..71c9651fd65 100644 --- a/cpp/src/structure/symmetrize_graph_impl.cuh +++ b/cpp/src/structure/symmetrize_graph_impl.cuh @@ -39,14 +39,21 @@ template -std::enable_if_t, - std::optional>>> -symmetrize_graph_impl(raft::handle_t const& handle, - graph_t&& graph, - std::optional>&& renumber_map, - bool reciprocal, - bool do_expensive_check) +std::enable_if_t< + multi_gpu, + std::tuple< + graph_t, + std::optional< + edge_property_t, weight_t>>, + std::optional>>> +symmetrize_graph_impl( + raft::handle_t const& handle, + graph_t&& graph, + std::optional, + weight_t>>&& edge_weights, + std::optional>&& renumber_map, + bool reciprocal, + bool do_expensive_check) { auto graph_view = graph.view(); @@ -60,16 +67,21 @@ symmetrize_graph_impl(raft::handle_t const& handle, if (do_expensive_check) { /* currently, nothing to do */ } - if (graph.is_symmetric()) { return std::make_tuple(std::move(graph), std::move(renumber_map)); } + if (graph.is_symmetric()) { + return std::make_tuple(std::move(graph), std::move(edge_weights), std::move(renumber_map)); + } auto is_multigraph = graph.is_multigraph(); - auto [edgelist_srcs, edgelist_dsts, edgelist_weights] = - decompress_to_edgelist(handle, - graph_view, - std::make_optional>( - (*renumber_map).data(), (*renumber_map).size())); - graph = graph_t(handle); + auto [edgelist_srcs, edgelist_dsts, edgelist_weights] = decompress_to_edgelist( + handle, + graph_view, + edge_weights + ? std::optional>{(*edge_weights).view()} + : std::nullopt, + std::make_optional>((*renumber_map).data(), + (*renumber_map).size())); + graph = graph_t(handle); std::tie(edgelist_srcs, edgelist_dsts, edgelist_weights) = symmetrize_edgelist( @@ -79,9 +91,12 @@ symmetrize_graph_impl(raft::handle_t const& handle, std::move(edgelist_weights), reciprocal); - graph_t symmetrized_graph(handle); + graph_t symmetrized_graph(handle); + std::optional< + edge_property_t, weight_t>> + symmetrized_edge_weights{}; std::optional> new_renumber_map{std::nullopt}; - std::tie(symmetrized_graph, std::ignore, new_renumber_map) = + std::tie(symmetrized_graph, symmetrized_edge_weights, std::ignore, new_renumber_map) = create_graph_from_edgelist( handle, std::move(renumber_map), @@ -92,7 +107,8 @@ symmetrize_graph_impl(raft::handle_t const& handle, graph_properties_t{is_multigraph, true}, true); - return std::make_tuple(std::move(symmetrized_graph), std::move(new_renumber_map)); + return std::make_tuple( + std::move(symmetrized_graph), std::move(symmetrized_edge_weights), std::move(new_renumber_map)); } template -std::enable_if_t, - std::optional>>> -symmetrize_graph_impl(raft::handle_t const& handle, - graph_t&& graph, - std::optional>&& renumber_map, - bool reciprocal, - bool do_expensive_check) +std::enable_if_t< + !multi_gpu, + std::tuple< + graph_t, + std::optional< + edge_property_t, weight_t>>, + std::optional>>> +symmetrize_graph_impl( + raft::handle_t const& handle, + graph_t&& graph, + std::optional, + weight_t>>&& edge_weights, + std::optional>&& renumber_map, + bool reciprocal, + bool do_expensive_check) { auto graph_view = graph.view(); @@ -120,19 +143,24 @@ symmetrize_graph_impl(raft::handle_t const& handle, if (do_expensive_check) { /* currently, nothing to do */ } - if (graph.is_symmetric()) { return std::make_tuple(std::move(graph), std::move(renumber_map)); } + if (graph.is_symmetric()) { + return std::make_tuple(std::move(graph), std::move(edge_weights), std::move(renumber_map)); + } auto number_of_vertices = graph.number_of_vertices(); auto is_multigraph = graph.is_multigraph(); bool renumber = renumber_map.has_value(); - auto [edgelist_srcs, edgelist_dsts, edgelist_weights] = - decompress_to_edgelist(handle, - graph_view, - renumber_map ? std::make_optional>( - (*renumber_map).data(), (*renumber_map).size()) - : std::nullopt); - graph = graph_t(handle); + auto [edgelist_srcs, edgelist_dsts, edgelist_weights] = decompress_to_edgelist( + handle, + graph_view, + edge_weights + ? std::optional>{(*edge_weights).view()} + : std::nullopt, + renumber_map ? std::make_optional>((*renumber_map).data(), + (*renumber_map).size()) + : std::nullopt); + graph = graph_t(handle); std::tie(edgelist_srcs, edgelist_dsts, edgelist_weights) = symmetrize_edgelist( @@ -150,9 +178,12 @@ symmetrize_graph_impl(raft::handle_t const& handle, handle.get_thrust_policy(), (*vertices).begin(), (*vertices).end(), vertex_t{0}); } - graph_t symmetrized_graph(handle); + graph_t symmetrized_graph(handle); + std::optional< + edge_property_t, weight_t>> + symmetrized_edge_weights{}; std::optional> new_renumber_map{std::nullopt}; - std::tie(symmetrized_graph, std::ignore, new_renumber_map) = + std::tie(symmetrized_graph, symmetrized_edge_weights, std::ignore, new_renumber_map) = create_graph_from_edgelist( handle, std::move(vertices), @@ -163,7 +194,8 @@ symmetrize_graph_impl(raft::handle_t const& handle, graph_properties_t{is_multigraph, true}, renumber); - return std::make_tuple(std::move(symmetrized_graph), std::move(new_renumber_map)); + return std::make_tuple( + std::move(symmetrized_graph), std::move(symmetrized_edge_weights), std::move(new_renumber_map)); } } // namespace @@ -173,16 +205,26 @@ template -std::tuple, - std::optional>> -symmetrize_graph(raft::handle_t const& handle, - graph_t&& graph, - std::optional>&& renumber_map, - bool reciprocal, - bool do_expensive_check) +std::tuple< + graph_t, + std::optional< + edge_property_t, weight_t>>, + std::optional>> +symmetrize_graph( + raft::handle_t const& handle, + graph_t&& graph, + std::optional, + weight_t>>&& edge_weights, + std::optional>&& renumber_map, + bool reciprocal, + bool do_expensive_check) { - return symmetrize_graph_impl( - handle, std::move(graph), std::move(renumber_map), reciprocal, do_expensive_check); + return symmetrize_graph_impl(handle, + std::move(graph), + std::move(edge_weights), + std::move(renumber_map), + reciprocal, + do_expensive_check); } } // namespace cugraph diff --git a/cpp/src/structure/symmetrize_graph_mg.cu b/cpp/src/structure/symmetrize_graph_mg.cu index afce7e58f26..02f0c23805d 100644 --- a/cpp/src/structure/symmetrize_graph_mg.cu +++ b/cpp/src/structure/symmetrize_graph_mg.cu @@ -19,100 +19,151 @@ namespace cugraph { // MG instantiation -template std::tuple, - std::optional>> -symmetrize_graph(raft::handle_t const& handle, - graph_t&& graph, - std::optional>&& renumber_map, - bool reciprocal, - bool do_expensive_check); +template std::tuple< + graph_t, + std::optional, float>>, + std::optional>> +symmetrize_graph( + raft::handle_t const& handle, + graph_t&& graph, + std::optional, float>>&& edge_weights, + std::optional>&& renumber_map, + bool reciprocal, + bool do_expensive_check); -template std::tuple, - std::optional>> -symmetrize_graph(raft::handle_t const& handle, - graph_t&& graph, - std::optional>&& renumber_map, - bool reciprocal, - bool do_expensive_check); +template std::tuple< + graph_t, + std::optional, float>>, + std::optional>> +symmetrize_graph( + raft::handle_t const& handle, + graph_t&& graph, + std::optional, float>>&& edge_weights, + std::optional>&& renumber_map, + bool reciprocal, + bool do_expensive_check); -template std::tuple, - std::optional>> -symmetrize_graph(raft::handle_t const& handle, - graph_t&& graph, - std::optional>&& renumber_map, - bool reciprocal, - bool do_expensive_check); +template std::tuple< + graph_t, + std::optional, float>>, + std::optional>> +symmetrize_graph( + raft::handle_t const& handle, + graph_t&& graph, + std::optional, float>>&& edge_weights, + std::optional>&& renumber_map, + bool reciprocal, + bool do_expensive_check); -template std::tuple, - std::optional>> -symmetrize_graph(raft::handle_t const& handle, - graph_t&& graph, - std::optional>&& renumber_map, - bool reciprocal, - bool do_expensive_check); +template std::tuple< + graph_t, + std::optional, float>>, + std::optional>> +symmetrize_graph( + raft::handle_t const& handle, + graph_t&& graph, + std::optional, float>>&& edge_weights, + std::optional>&& renumber_map, + bool reciprocal, + bool do_expensive_check); -template std::tuple, - std::optional>> -symmetrize_graph(raft::handle_t const& handle, - graph_t&& graph, - std::optional>&& renumber_map, - bool reciprocal, - bool do_expensive_check); +template std::tuple< + graph_t, + std::optional, float>>, + std::optional>> +symmetrize_graph( + raft::handle_t const& handle, + graph_t&& graph, + std::optional, float>>&& edge_weights, + std::optional>&& renumber_map, + bool reciprocal, + bool do_expensive_check); -template std::tuple, - std::optional>> -symmetrize_graph(raft::handle_t const& handle, - graph_t&& graph, - std::optional>&& renumber_map, - bool reciprocal, - bool do_expensive_check); +template std::tuple< + graph_t, + std::optional, float>>, + std::optional>> +symmetrize_graph( + raft::handle_t const& handle, + graph_t&& graph, + std::optional, float>>&& edge_weights, + std::optional>&& renumber_map, + bool reciprocal, + bool do_expensive_check); -template std::tuple, - std::optional>> -symmetrize_graph(raft::handle_t const& handle, - graph_t&& graph, - std::optional>&& renumber_map, - bool reciprocal, - bool do_expensive_check); +template std::tuple< + graph_t, + std::optional, double>>, + std::optional>> +symmetrize_graph( + raft::handle_t const& handle, + graph_t&& graph, + std::optional, double>>&& edge_weights, + std::optional>&& renumber_map, + bool reciprocal, + bool do_expensive_check); -template std::tuple, - std::optional>> -symmetrize_graph(raft::handle_t const& handle, - graph_t&& graph, - std::optional>&& renumber_map, - bool reciprocal, - bool do_expensive_check); +template std::tuple< + graph_t, + std::optional, double>>, + std::optional>> +symmetrize_graph( + raft::handle_t const& handle, + graph_t&& graph, + std::optional, double>>&& + edge_weights, + std::optional>&& renumber_map, + bool reciprocal, + bool do_expensive_check); -template std::tuple, - std::optional>> -symmetrize_graph(raft::handle_t const& handle, - graph_t&& graph, - std::optional>&& renumber_map, - bool reciprocal, - bool do_expensive_check); +template std::tuple< + graph_t, + std::optional, double>>, + std::optional>> +symmetrize_graph( + raft::handle_t const& handle, + graph_t&& graph, + std::optional, double>>&& edge_weights, + std::optional>&& renumber_map, + bool reciprocal, + bool do_expensive_check); -template std::tuple, - std::optional>> -symmetrize_graph(raft::handle_t const& handle, - graph_t&& graph, - std::optional>&& renumber_map, - bool reciprocal, - bool do_expensive_check); +template std::tuple< + graph_t, + std::optional, double>>, + std::optional>> +symmetrize_graph( + raft::handle_t const& handle, + graph_t&& graph, + std::optional, double>>&& + edge_weights, + std::optional>&& renumber_map, + bool reciprocal, + bool do_expensive_check); -template std::tuple, - std::optional>> -symmetrize_graph(raft::handle_t const& handle, - graph_t&& graph, - std::optional>&& renumber_map, - bool reciprocal, - bool do_expensive_check); +template std::tuple< + graph_t, + std::optional, double>>, + std::optional>> +symmetrize_graph( + raft::handle_t const& handle, + graph_t&& graph, + std::optional, double>>&& edge_weights, + std::optional>&& renumber_map, + bool reciprocal, + bool do_expensive_check); -template std::tuple, - std::optional>> -symmetrize_graph(raft::handle_t const& handle, - graph_t&& graph, - std::optional>&& renumber_map, - bool reciprocal, - bool do_expensive_check); +template std::tuple< + graph_t, + std::optional, double>>, + std::optional>> +symmetrize_graph( + raft::handle_t const& handle, + graph_t&& graph, + std::optional, double>>&& + edge_weights, + std::optional>&& renumber_map, + bool reciprocal, + bool do_expensive_check); } // namespace cugraph diff --git a/cpp/src/structure/symmetrize_graph_sg.cu b/cpp/src/structure/symmetrize_graph_sg.cu index 19a0b99e2c0..4b903e8bbb2 100644 --- a/cpp/src/structure/symmetrize_graph_sg.cu +++ b/cpp/src/structure/symmetrize_graph_sg.cu @@ -19,100 +19,157 @@ namespace cugraph { // SG instantiation -template std::tuple, - std::optional>> -symmetrize_graph(raft::handle_t const& handle, - graph_t&& graph, - std::optional>&& renumber_map, - bool reciprocal, - bool do_expensive_check); +template std::tuple< + graph_t, + std::optional, float>>, + std::optional>> +symmetrize_graph( + raft::handle_t const& handle, + graph_t&& graph, + std::optional, float>>&& edge_weights, + std::optional>&& renumber_map, + bool reciprocal, + bool do_expensive_check); -template std::tuple, - std::optional>> -symmetrize_graph(raft::handle_t const& handle, - graph_t&& graph, - std::optional>&& renumber_map, - bool reciprocal, - bool do_expensive_check); +template std::tuple< + graph_t, + std::optional, float>>, + std::optional>> +symmetrize_graph( + raft::handle_t const& handle, + graph_t&& graph, + std::optional, float>>&& + edge_weights, + std::optional>&& renumber_map, + bool reciprocal, + bool do_expensive_check); -template std::tuple, - std::optional>> -symmetrize_graph(raft::handle_t const& handle, - graph_t&& graph, - std::optional>&& renumber_map, - bool reciprocal, - bool do_expensive_check); +template std::tuple< + graph_t, + std::optional, float>>, + std::optional>> +symmetrize_graph( + raft::handle_t const& handle, + graph_t&& graph, + std::optional, float>>&& edge_weights, + std::optional>&& renumber_map, + bool reciprocal, + bool do_expensive_check); -template std::tuple, - std::optional>> -symmetrize_graph(raft::handle_t const& handle, - graph_t&& graph, - std::optional>&& renumber_map, - bool reciprocal, - bool do_expensive_check); +template std::tuple< + graph_t, + std::optional, float>>, + std::optional>> +symmetrize_graph( + raft::handle_t const& handle, + graph_t&& graph, + std::optional, float>>&& + edge_weights, + std::optional>&& renumber_map, + bool reciprocal, + bool do_expensive_check); -template std::tuple, - std::optional>> -symmetrize_graph(raft::handle_t const& handle, - graph_t&& graph, - std::optional>&& renumber_map, - bool reciprocal, - bool do_expensive_check); +template std::tuple< + graph_t, + std::optional, float>>, + std::optional>> +symmetrize_graph( + raft::handle_t const& handle, + graph_t&& graph, + std::optional, float>>&& edge_weights, + std::optional>&& renumber_map, + bool reciprocal, + bool do_expensive_check); -template std::tuple, - std::optional>> -symmetrize_graph(raft::handle_t const& handle, - graph_t&& graph, - std::optional>&& renumber_map, - bool reciprocal, - bool do_expensive_check); +template std::tuple< + graph_t, + std::optional, float>>, + std::optional>> +symmetrize_graph( + raft::handle_t const& handle, + graph_t&& graph, + std::optional, float>>&& + edge_weights, + std::optional>&& renumber_map, + bool reciprocal, + bool do_expensive_check); -template std::tuple, - std::optional>> -symmetrize_graph(raft::handle_t const& handle, - graph_t&& graph, - std::optional>&& renumber_map, - bool reciprocal, - bool do_expensive_check); +template std::tuple< + graph_t, + std::optional, double>>, + std::optional>> +symmetrize_graph( + raft::handle_t const& handle, + graph_t&& graph, + std::optional, double>>&& + edge_weights, + std::optional>&& renumber_map, + bool reciprocal, + bool do_expensive_check); -template std::tuple, - std::optional>> -symmetrize_graph(raft::handle_t const& handle, - graph_t&& graph, - std::optional>&& renumber_map, - bool reciprocal, - bool do_expensive_check); +template std::tuple< + graph_t, + std::optional, double>>, + std::optional>> +symmetrize_graph( + raft::handle_t const& handle, + graph_t&& graph, + std::optional, double>>&& + edge_weights, + std::optional>&& renumber_map, + bool reciprocal, + bool do_expensive_check); -template std::tuple, - std::optional>> -symmetrize_graph(raft::handle_t const& handle, - graph_t&& graph, - std::optional>&& renumber_map, - bool reciprocal, - bool do_expensive_check); +template std::tuple< + graph_t, + std::optional, double>>, + std::optional>> +symmetrize_graph( + raft::handle_t const& handle, + graph_t&& graph, + std::optional, double>>&& + edge_weights, + std::optional>&& renumber_map, + bool reciprocal, + bool do_expensive_check); -template std::tuple, - std::optional>> -symmetrize_graph(raft::handle_t const& handle, - graph_t&& graph, - std::optional>&& renumber_map, - bool reciprocal, - bool do_expensive_check); +template std::tuple< + graph_t, + std::optional, double>>, + std::optional>> +symmetrize_graph( + raft::handle_t const& handle, + graph_t&& graph, + std::optional, double>>&& + edge_weights, + std::optional>&& renumber_map, + bool reciprocal, + bool do_expensive_check); -template std::tuple, - std::optional>> -symmetrize_graph(raft::handle_t const& handle, - graph_t&& graph, - std::optional>&& renumber_map, - bool reciprocal, - bool do_expensive_check); +template std::tuple< + graph_t, + std::optional, double>>, + std::optional>> +symmetrize_graph( + raft::handle_t const& handle, + graph_t&& graph, + std::optional, double>>&& + edge_weights, + std::optional>&& renumber_map, + bool reciprocal, + bool do_expensive_check); -template std::tuple, - std::optional>> -symmetrize_graph(raft::handle_t const& handle, - graph_t&& graph, - std::optional>&& renumber_map, - bool reciprocal, - bool do_expensive_check); +template std::tuple< + graph_t, + std::optional, double>>, + std::optional>> +symmetrize_graph( + raft::handle_t const& handle, + graph_t&& graph, + std::optional, double>>&& + edge_weights, + std::optional>&& renumber_map, + bool reciprocal, + bool do_expensive_check); } // namespace cugraph diff --git a/cpp/src/structure/transpose_graph_impl.cuh b/cpp/src/structure/transpose_graph_impl.cuh index 8a079a788c4..5106fa866ef 100644 --- a/cpp/src/structure/transpose_graph_impl.cuh +++ b/cpp/src/structure/transpose_graph_impl.cuh @@ -40,13 +40,20 @@ template -std::enable_if_t, - std::optional>>> -transpose_graph_impl(raft::handle_t const& handle, - graph_t&& graph, - std::optional>&& renumber_map, - bool do_expensive_check) +std::enable_if_t< + multi_gpu, + std::tuple< + graph_t, + std::optional< + edge_property_t, weight_t>>, + std::optional>>> +transpose_graph_impl( + raft::handle_t const& handle, + graph_t&& graph, + std::optional, + weight_t>>&& edge_weights, + std::optional>&& renumber_map, + bool do_expensive_check) { auto graph_view = graph.view(); @@ -60,16 +67,21 @@ transpose_graph_impl(raft::handle_t const& handle, if (do_expensive_check) { /* currently, nothing to do */ } - if (graph.is_symmetric()) { return std::make_tuple(std::move(graph), std::move(renumber_map)); } + if (graph.is_symmetric()) { + return std::make_tuple(std::move(graph), std::move(edge_weights), std::move(renumber_map)); + } auto is_multigraph = graph.is_multigraph(); - auto [edgelist_srcs, edgelist_dsts, edgelist_weights] = - decompress_to_edgelist(handle, - graph_view, - std::make_optional>( - (*renumber_map).data(), (*renumber_map).size())); - graph = graph_t(handle); + auto [edgelist_srcs, edgelist_dsts, edgelist_weights] = decompress_to_edgelist( + handle, + graph_view, + edge_weights + ? std::optional>{(*edge_weights).view()} + : std::nullopt, + std::make_optional>((*renumber_map).data(), + (*renumber_map).size())); + graph = graph_t(handle); std::tie(store_transposed ? edgelist_srcs : edgelist_dsts, store_transposed ? edgelist_dsts : edgelist_srcs, @@ -79,9 +91,12 @@ transpose_graph_impl(raft::handle_t const& handle, std::move(store_transposed ? edgelist_dsts : edgelist_srcs), std::move(edgelist_weights)); - graph_t transposed_graph(handle); + graph_t transposed_graph(handle); + std::optional< + edge_property_t, weight_t>> + transposed_edge_weights{}; std::optional> new_renumber_map{std::nullopt}; - std::tie(transposed_graph, std::ignore, new_renumber_map) = + std::tie(transposed_graph, transposed_edge_weights, std::ignore, new_renumber_map) = create_graph_from_edgelist( handle, std::move(renumber_map), @@ -92,7 +107,8 @@ transpose_graph_impl(raft::handle_t const& handle, graph_properties_t{false, is_multigraph}, true); - return std::make_tuple(std::move(transposed_graph), std::move(new_renumber_map)); + return std::make_tuple( + std::move(transposed_graph), std::move(transposed_edge_weights), std::move(new_renumber_map)); } template -std::enable_if_t, - std::optional>>> -transpose_graph_impl(raft::handle_t const& handle, - graph_t&& graph, - std::optional>&& renumber_map, - bool do_expensive_check) +std::enable_if_t< + !multi_gpu, + std::tuple< + graph_t, + std::optional< + edge_property_t, weight_t>>, + std::optional>>> +transpose_graph_impl( + raft::handle_t const& handle, + graph_t&& graph, + std::optional, + weight_t>>&& edge_weights, + std::optional>&& renumber_map, + bool do_expensive_check) { auto graph_view = graph.view(); @@ -119,19 +142,24 @@ transpose_graph_impl(raft::handle_t const& handle, if (do_expensive_check) { /* currently, nothing to do */ } - if (graph.is_symmetric()) { return std::make_tuple(std::move(graph), std::move(renumber_map)); } + if (graph.is_symmetric()) { + return std::make_tuple(std::move(graph), std::move(edge_weights), std::move(renumber_map)); + } auto number_of_vertices = graph.number_of_vertices(); auto is_multigraph = graph.is_multigraph(); bool renumber = renumber_map.has_value(); - auto [edgelist_srcs, edgelist_dsts, edgelist_weights] = - decompress_to_edgelist(handle, - graph_view, - renumber_map ? std::make_optional>( - (*renumber_map).data(), (*renumber_map).size()) - : std::nullopt); - graph = graph_t(handle); + auto [edgelist_srcs, edgelist_dsts, edgelist_weights] = decompress_to_edgelist( + handle, + graph_view, + edge_weights + ? std::optional>{(*edge_weights).view()} + : std::nullopt, + renumber_map ? std::make_optional>((*renumber_map).data(), + (*renumber_map).size()) + : std::nullopt); + graph = graph_t(handle); auto vertices = renumber ? std::move(renumber_map) : std::make_optional>(number_of_vertices, handle.get_stream()); @@ -140,9 +168,12 @@ transpose_graph_impl(raft::handle_t const& handle, handle.get_thrust_policy(), (*vertices).begin(), (*vertices).end(), vertex_t{0}); } - graph_t transposed_graph(handle); + graph_t transposed_graph(handle); + std::optional< + edge_property_t, weight_t>> + transposed_edge_weights{}; std::optional> new_renumber_map{std::nullopt}; - std::tie(transposed_graph, std::ignore, new_renumber_map) = + std::tie(transposed_graph, transposed_edge_weights, std::ignore, new_renumber_map) = create_graph_from_edgelist( handle, std::move(vertices), @@ -153,7 +184,8 @@ transpose_graph_impl(raft::handle_t const& handle, graph_properties_t{false, is_multigraph}, renumber); - return std::make_tuple(std::move(transposed_graph), std::move(new_renumber_map)); + return std::make_tuple( + std::move(transposed_graph), std::move(transposed_edge_weights), std::move(new_renumber_map)); } } // namespace @@ -163,15 +195,21 @@ template -std::tuple, - std::optional>> -transpose_graph(raft::handle_t const& handle, - graph_t&& graph, - std::optional>&& renumber_map, - bool do_expensive_check) +std::tuple< + graph_t, + std::optional< + edge_property_t, weight_t>>, + std::optional>> +transpose_graph( + raft::handle_t const& handle, + graph_t&& graph, + std::optional, + weight_t>>&& edge_weights, + std::optional>&& renumber_map, + bool do_expensive_check) { return transpose_graph_impl( - handle, std::move(graph), std::move(renumber_map), do_expensive_check); + handle, std::move(graph), std::move(edge_weights), std::move(renumber_map), do_expensive_check); } } // namespace cugraph diff --git a/cpp/src/structure/transpose_graph_mg.cu b/cpp/src/structure/transpose_graph_mg.cu index 5b8ab72daec..ce4c0e6edbc 100644 --- a/cpp/src/structure/transpose_graph_mg.cu +++ b/cpp/src/structure/transpose_graph_mg.cu @@ -19,88 +19,139 @@ namespace cugraph { // MG instantiation -template std::tuple, - std::optional>> -transpose_graph(raft::handle_t const& handle, - graph_t&& graph, - std::optional>&& renumber_map, - bool do_expensive_check); +template std::tuple< + graph_t, + std::optional, float>>, + std::optional>> +transpose_graph( + raft::handle_t const& handle, + graph_t&& graph, + std::optional, float>>&& edge_weights, + std::optional>&& renumber_map, + bool do_expensive_check); -template std::tuple, - std::optional>> -transpose_graph(raft::handle_t const& handle, - graph_t&& graph, - std::optional>&& renumber_map, - bool do_expensive_check); +template std::tuple< + graph_t, + std::optional, float>>, + std::optional>> +transpose_graph( + raft::handle_t const& handle, + graph_t&& graph, + std::optional, float>>&& edge_weights, + std::optional>&& renumber_map, + bool do_expensive_check); -template std::tuple, - std::optional>> -transpose_graph(raft::handle_t const& handle, - graph_t&& graph, - std::optional>&& renumber_map, - bool do_expensive_check); +template std::tuple< + graph_t, + std::optional, float>>, + std::optional>> +transpose_graph( + raft::handle_t const& handle, + graph_t&& graph, + std::optional, float>>&& edge_weights, + std::optional>&& renumber_map, + bool do_expensive_check); -template std::tuple, - std::optional>> -transpose_graph(raft::handle_t const& handle, - graph_t&& graph, - std::optional>&& renumber_map, - bool do_expensive_check); +template std::tuple< + graph_t, + std::optional, float>>, + std::optional>> +transpose_graph( + raft::handle_t const& handle, + graph_t&& graph, + std::optional, float>>&& edge_weights, + std::optional>&& renumber_map, + bool do_expensive_check); -template std::tuple, - std::optional>> -transpose_graph(raft::handle_t const& handle, - graph_t&& graph, - std::optional>&& renumber_map, - bool do_expensive_check); +template std::tuple< + graph_t, + std::optional, float>>, + std::optional>> +transpose_graph( + raft::handle_t const& handle, + graph_t&& graph, + std::optional, float>>&& edge_weights, + std::optional>&& renumber_map, + bool do_expensive_check); -template std::tuple, - std::optional>> -transpose_graph(raft::handle_t const& handle, - graph_t&& graph, - std::optional>&& renumber_map, - bool do_expensive_check); +template std::tuple< + graph_t, + std::optional, float>>, + std::optional>> +transpose_graph( + raft::handle_t const& handle, + graph_t&& graph, + std::optional, float>>&& edge_weights, + std::optional>&& renumber_map, + bool do_expensive_check); -template std::tuple, - std::optional>> -transpose_graph(raft::handle_t const& handle, - graph_t&& graph, - std::optional>&& renumber_map, - bool do_expensive_check); +template std::tuple< + graph_t, + std::optional, double>>, + std::optional>> +transpose_graph( + raft::handle_t const& handle, + graph_t&& graph, + std::optional, double>>&& edge_weights, + std::optional>&& renumber_map, + bool do_expensive_check); -template std::tuple, - std::optional>> -transpose_graph(raft::handle_t const& handle, - graph_t&& graph, - std::optional>&& renumber_map, - bool do_expensive_check); +template std::tuple< + graph_t, + std::optional, double>>, + std::optional>> +transpose_graph( + raft::handle_t const& handle, + graph_t&& graph, + std::optional, double>>&& + edge_weights, + std::optional>&& renumber_map, + bool do_expensive_check); -template std::tuple, - std::optional>> -transpose_graph(raft::handle_t const& handle, - graph_t&& graph, - std::optional>&& renumber_map, - bool do_expensive_check); +template std::tuple< + graph_t, + std::optional, double>>, + std::optional>> +transpose_graph( + raft::handle_t const& handle, + graph_t&& graph, + std::optional, double>>&& edge_weights, + std::optional>&& renumber_map, + bool do_expensive_check); -template std::tuple, - std::optional>> -transpose_graph(raft::handle_t const& handle, - graph_t&& graph, - std::optional>&& renumber_map, - bool do_expensive_check); +template std::tuple< + graph_t, + std::optional, double>>, + std::optional>> +transpose_graph( + raft::handle_t const& handle, + graph_t&& graph, + std::optional, double>>&& + edge_weights, + std::optional>&& renumber_map, + bool do_expensive_check); -template std::tuple, - std::optional>> -transpose_graph(raft::handle_t const& handle, - graph_t&& graph, - std::optional>&& renumber_map, - bool do_expensive_check); +template std::tuple< + graph_t, + std::optional, double>>, + std::optional>> +transpose_graph( + raft::handle_t const& handle, + graph_t&& graph, + std::optional, double>>&& edge_weights, + std::optional>&& renumber_map, + bool do_expensive_check); -template std::tuple, - std::optional>> -transpose_graph(raft::handle_t const& handle, - graph_t&& graph, - std::optional>&& renumber_map, - bool do_expensive_check); +template std::tuple< + graph_t, + std::optional, double>>, + std::optional>> +transpose_graph( + raft::handle_t const& handle, + graph_t&& graph, + std::optional, double>>&& + edge_weights, + std::optional>&& renumber_map, + bool do_expensive_check); } // namespace cugraph diff --git a/cpp/src/structure/transpose_graph_sg.cu b/cpp/src/structure/transpose_graph_sg.cu index 31bfcbae295..7360746211a 100644 --- a/cpp/src/structure/transpose_graph_sg.cu +++ b/cpp/src/structure/transpose_graph_sg.cu @@ -19,88 +19,145 @@ namespace cugraph { // SG instantiation -template std::tuple, - std::optional>> -transpose_graph(raft::handle_t const& handle, - graph_t&& graph, - std::optional>&& renumber_map, - bool do_expensive_check); +template std::tuple< + graph_t, + std::optional, float>>, + std::optional>> +transpose_graph( + raft::handle_t const& handle, + graph_t&& graph, + std::optional, float>>&& edge_weights, + std::optional>&& renumber_map, + bool do_expensive_check); -template std::tuple, - std::optional>> -transpose_graph(raft::handle_t const& handle, - graph_t&& graph, - std::optional>&& renumber_map, - bool do_expensive_check); +template std::tuple< + graph_t, + std::optional, float>>, + std::optional>> +transpose_graph( + raft::handle_t const& handle, + graph_t&& graph, + std::optional, float>>&& + edge_weights, + std::optional>&& renumber_map, + bool do_expensive_check); -template std::tuple, - std::optional>> -transpose_graph(raft::handle_t const& handle, - graph_t&& graph, - std::optional>&& renumber_map, - bool do_expensive_check); +template std::tuple< + graph_t, + std::optional, float>>, + std::optional>> +transpose_graph( + raft::handle_t const& handle, + graph_t&& graph, + std::optional, float>>&& edge_weights, + std::optional>&& renumber_map, + bool do_expensive_check); -template std::tuple, - std::optional>> -transpose_graph(raft::handle_t const& handle, - graph_t&& graph, - std::optional>&& renumber_map, - bool do_expensive_check); +template std::tuple< + graph_t, + std::optional, float>>, + std::optional>> +transpose_graph( + raft::handle_t const& handle, + graph_t&& graph, + std::optional, float>>&& + edge_weights, + std::optional>&& renumber_map, + bool do_expensive_check); -template std::tuple, - std::optional>> -transpose_graph(raft::handle_t const& handle, - graph_t&& graph, - std::optional>&& renumber_map, - bool do_expensive_check); +template std::tuple< + graph_t, + std::optional, float>>, + std::optional>> +transpose_graph( + raft::handle_t const& handle, + graph_t&& graph, + std::optional, float>>&& edge_weights, + std::optional>&& renumber_map, + bool do_expensive_check); -template std::tuple, - std::optional>> -transpose_graph(raft::handle_t const& handle, - graph_t&& graph, - std::optional>&& renumber_map, - bool do_expensive_check); +template std::tuple< + graph_t, + std::optional, float>>, + std::optional>> +transpose_graph( + raft::handle_t const& handle, + graph_t&& graph, + std::optional, float>>&& + edge_weights, + std::optional>&& renumber_map, + bool do_expensive_check); -template std::tuple, - std::optional>> -transpose_graph(raft::handle_t const& handle, - graph_t&& graph, - std::optional>&& renumber_map, - bool do_expensive_check); +template std::tuple< + graph_t, + std::optional, double>>, + std::optional>> +transpose_graph( + raft::handle_t const& handle, + graph_t&& graph, + std::optional, double>>&& + edge_weights, + std::optional>&& renumber_map, + bool do_expensive_check); -template std::tuple, - std::optional>> -transpose_graph(raft::handle_t const& handle, - graph_t&& graph, - std::optional>&& renumber_map, - bool do_expensive_check); +template std::tuple< + graph_t, + std::optional, double>>, + std::optional>> +transpose_graph( + raft::handle_t const& handle, + graph_t&& graph, + std::optional, double>>&& + edge_weights, + std::optional>&& renumber_map, + bool do_expensive_check); -template std::tuple, - std::optional>> -transpose_graph(raft::handle_t const& handle, - graph_t&& graph, - std::optional>&& renumber_map, - bool do_expensive_check); +template std::tuple< + graph_t, + std::optional, double>>, + std::optional>> +transpose_graph( + raft::handle_t const& handle, + graph_t&& graph, + std::optional, double>>&& + edge_weights, + std::optional>&& renumber_map, + bool do_expensive_check); -template std::tuple, - std::optional>> -transpose_graph(raft::handle_t const& handle, - graph_t&& graph, - std::optional>&& renumber_map, - bool do_expensive_check); +template std::tuple< + graph_t, + std::optional, double>>, + std::optional>> +transpose_graph( + raft::handle_t const& handle, + graph_t&& graph, + std::optional, double>>&& + edge_weights, + std::optional>&& renumber_map, + bool do_expensive_check); -template std::tuple, - std::optional>> -transpose_graph(raft::handle_t const& handle, - graph_t&& graph, - std::optional>&& renumber_map, - bool do_expensive_check); +template std::tuple< + graph_t, + std::optional, double>>, + std::optional>> +transpose_graph( + raft::handle_t const& handle, + graph_t&& graph, + std::optional, double>>&& + edge_weights, + std::optional>&& renumber_map, + bool do_expensive_check); -template std::tuple, - std::optional>> -transpose_graph(raft::handle_t const& handle, - graph_t&& graph, - std::optional>&& renumber_map, - bool do_expensive_check); +template std::tuple< + graph_t, + std::optional, double>>, + std::optional>> +transpose_graph( + raft::handle_t const& handle, + graph_t&& graph, + std::optional, double>>&& + edge_weights, + std::optional>&& renumber_map, + bool do_expensive_check); } // namespace cugraph diff --git a/cpp/src/structure/transpose_graph_storage_impl.cuh b/cpp/src/structure/transpose_graph_storage_impl.cuh index 7a5857452bb..c334b328450 100644 --- a/cpp/src/structure/transpose_graph_storage_impl.cuh +++ b/cpp/src/structure/transpose_graph_storage_impl.cuh @@ -40,12 +40,18 @@ template -std::enable_if_t, - std::optional>>> +std::enable_if_t< + multi_gpu, + std::tuple< + graph_t, + std::optional< + edge_property_t, weight_t>>, + std::optional>>> transpose_graph_storage_impl( raft::handle_t const& handle, - graph_t&& graph, + graph_t&& graph, + std::optional, + weight_t>>&& edge_weights, std::optional>&& renumber_map, bool do_expensive_check) { @@ -67,12 +73,15 @@ transpose_graph_storage_impl( // FIXME: if is_symmetric is true we can do this more efficiently, // since the graph contents should be exactly the same - auto [edgelist_srcs, edgelist_dsts, edgelist_weights] = - decompress_to_edgelist(handle, - graph_view, - std::make_optional>( - (*renumber_map).data(), (*renumber_map).size())); - graph = graph_t(handle); + auto [edgelist_srcs, edgelist_dsts, edgelist_weights] = decompress_to_edgelist( + handle, + graph_view, + edge_weights + ? std::optional>{(*edge_weights).view()} + : std::nullopt, + std::make_optional>((*renumber_map).data(), + (*renumber_map).size())); + graph = graph_t(handle); std::tie(!store_transposed ? edgelist_dsts : edgelist_srcs, !store_transposed ? edgelist_srcs : edgelist_dsts, @@ -82,10 +91,13 @@ transpose_graph_storage_impl( std::move(!store_transposed ? edgelist_srcs : edgelist_dsts), std::move(edgelist_weights)); - graph_t storage_transposed_graph( - handle); + graph_t storage_transposed_graph(handle); + std::optional< + edge_property_t, weight_t>> + storage_transposed_edge_weights{}; std::optional> new_renumber_map{std::nullopt}; - std::tie(storage_transposed_graph, std::ignore, new_renumber_map) = + std::tie( + storage_transposed_graph, storage_transposed_edge_weights, std::ignore, new_renumber_map) = create_graph_from_edgelist( handle, std::move(renumber_map), @@ -96,7 +108,9 @@ transpose_graph_storage_impl( graph_properties_t{is_symmetric, is_multigraph}, true); - return std::make_tuple(std::move(storage_transposed_graph), std::move(new_renumber_map)); + return std::make_tuple(std::move(storage_transposed_graph), + std::move(storage_transposed_edge_weights), + std::move(new_renumber_map)); } template -std::enable_if_t, - std::optional>>> +std::enable_if_t< + !multi_gpu, + std::tuple< + graph_t, + std::optional< + edge_property_t, weight_t>>, + std::optional>>> transpose_graph_storage_impl( raft::handle_t const& handle, - graph_t&& graph, + graph_t&& graph, + std::optional, + weight_t>>&& edge_weights, std::optional>&& renumber_map, bool do_expensive_check) { @@ -132,13 +152,16 @@ transpose_graph_storage_impl( // FIXME: if is_symmetric is true we can do this more efficiently, // since the graph contents should be exactly the same - auto [edgelist_srcs, edgelist_dsts, edgelist_weights] = - decompress_to_edgelist(handle, - graph_view, - renumber_map ? std::make_optional>( - (*renumber_map).data(), (*renumber_map).size()) - : std::nullopt); - graph = graph_t(handle); + auto [edgelist_srcs, edgelist_dsts, edgelist_weights] = decompress_to_edgelist( + handle, + graph_view, + edge_weights + ? std::optional>{(*edge_weights).view()} + : std::nullopt, + renumber_map ? std::make_optional>((*renumber_map).data(), + (*renumber_map).size()) + : std::nullopt); + graph = graph_t(handle); auto vertices = renumber ? std::move(renumber_map) : std::make_optional>(number_of_vertices, handle.get_stream()); @@ -147,10 +170,13 @@ transpose_graph_storage_impl( handle.get_thrust_policy(), (*vertices).begin(), (*vertices).end(), vertex_t{0}); } - graph_t storage_transposed_graph( - handle); + graph_t storage_transposed_graph(handle); + std::optional< + edge_property_t, weight_t>> + storage_transposed_edge_weights{}; std::optional> new_renumber_map{std::nullopt}; - std::tie(storage_transposed_graph, std::ignore, new_renumber_map) = + std::tie( + storage_transposed_graph, storage_transposed_edge_weights, std::ignore, new_renumber_map) = create_graph_from_edgelist( handle, std::move(vertices), @@ -161,7 +187,9 @@ transpose_graph_storage_impl( graph_properties_t{is_symmetric, is_multigraph}, renumber); - return std::make_tuple(std::move(storage_transposed_graph), std::move(new_renumber_map)); + return std::make_tuple(std::move(storage_transposed_graph), + std::move(storage_transposed_edge_weights), + std::move(new_renumber_map)); } } // namespace @@ -171,15 +199,21 @@ template -std::tuple, - std::optional>> -transpose_graph_storage(raft::handle_t const& handle, - graph_t&& graph, - std::optional>&& renumber_map, - bool do_expensive_check) +std::tuple< + graph_t, + std::optional< + edge_property_t, weight_t>>, + std::optional>> +transpose_graph_storage( + raft::handle_t const& handle, + graph_t&& graph, + std::optional, + weight_t>>&& edge_weights, + std::optional>&& renumber_map, + bool do_expensive_check) { return transpose_graph_storage_impl( - handle, std::move(graph), std::move(renumber_map), do_expensive_check); + handle, std::move(graph), std::move(edge_weights), std::move(renumber_map), do_expensive_check); } } // namespace cugraph diff --git a/cpp/src/structure/transpose_graph_storage_mg.cu b/cpp/src/structure/transpose_graph_storage_mg.cu index 2701b604b8c..5e5766130b7 100644 --- a/cpp/src/structure/transpose_graph_storage_mg.cu +++ b/cpp/src/structure/transpose_graph_storage_mg.cu @@ -19,88 +19,139 @@ namespace cugraph { // MG instantiation -template std::tuple, - std::optional>> -transpose_graph_storage(raft::handle_t const& handle, - graph_t&& graph, - std::optional>&& renumber_map, - bool do_expensive_check); +template std::tuple< + graph_t, + std::optional, float>>, + std::optional>> +transpose_graph_storage( + raft::handle_t const& handle, + graph_t&& graph, + std::optional, float>>&& edge_weights, + std::optional>&& renumber_map, + bool do_expensive_check); -template std::tuple, - std::optional>> -transpose_graph_storage(raft::handle_t const& handle, - graph_t&& graph, - std::optional>&& renumber_map, - bool do_expensive_check); +template std::tuple< + graph_t, + std::optional, float>>, + std::optional>> +transpose_graph_storage( + raft::handle_t const& handle, + graph_t&& graph, + std::optional, float>>&& edge_weights, + std::optional>&& renumber_map, + bool do_expensive_check); -template std::tuple, - std::optional>> -transpose_graph_storage(raft::handle_t const& handle, - graph_t&& graph, - std::optional>&& renumber_map, - bool do_expensive_check); +template std::tuple< + graph_t, + std::optional, float>>, + std::optional>> +transpose_graph_storage( + raft::handle_t const& handle, + graph_t&& graph, + std::optional, float>>&& edge_weights, + std::optional>&& renumber_map, + bool do_expensive_check); -template std::tuple, - std::optional>> -transpose_graph_storage(raft::handle_t const& handle, - graph_t&& graph, - std::optional>&& renumber_map, - bool do_expensive_check); +template std::tuple< + graph_t, + std::optional, float>>, + std::optional>> +transpose_graph_storage( + raft::handle_t const& handle, + graph_t&& graph, + std::optional, float>>&& edge_weights, + std::optional>&& renumber_map, + bool do_expensive_check); -template std::tuple, - std::optional>> -transpose_graph_storage(raft::handle_t const& handle, - graph_t&& graph, - std::optional>&& renumber_map, - bool do_expensive_check); +template std::tuple< + graph_t, + std::optional, float>>, + std::optional>> +transpose_graph_storage( + raft::handle_t const& handle, + graph_t&& graph, + std::optional, float>>&& edge_weights, + std::optional>&& renumber_map, + bool do_expensive_check); -template std::tuple, - std::optional>> -transpose_graph_storage(raft::handle_t const& handle, - graph_t&& graph, - std::optional>&& renumber_map, - bool do_expensive_check); +template std::tuple< + graph_t, + std::optional, float>>, + std::optional>> +transpose_graph_storage( + raft::handle_t const& handle, + graph_t&& graph, + std::optional, float>>&& edge_weights, + std::optional>&& renumber_map, + bool do_expensive_check); -template std::tuple, - std::optional>> -transpose_graph_storage(raft::handle_t const& handle, - graph_t&& graph, - std::optional>&& renumber_map, - bool do_expensive_check); +template std::tuple< + graph_t, + std::optional, double>>, + std::optional>> +transpose_graph_storage( + raft::handle_t const& handle, + graph_t&& graph, + std::optional, double>>&& edge_weights, + std::optional>&& renumber_map, + bool do_expensive_check); -template std::tuple, - std::optional>> -transpose_graph_storage(raft::handle_t const& handle, - graph_t&& graph, - std::optional>&& renumber_map, - bool do_expensive_check); +template std::tuple< + graph_t, + std::optional, double>>, + std::optional>> +transpose_graph_storage( + raft::handle_t const& handle, + graph_t&& graph, + std::optional, double>>&& + edge_weights, + std::optional>&& renumber_map, + bool do_expensive_check); -template std::tuple, - std::optional>> -transpose_graph_storage(raft::handle_t const& handle, - graph_t&& graph, - std::optional>&& renumber_map, - bool do_expensive_check); +template std::tuple< + graph_t, + std::optional, double>>, + std::optional>> +transpose_graph_storage( + raft::handle_t const& handle, + graph_t&& graph, + std::optional, double>>&& edge_weights, + std::optional>&& renumber_map, + bool do_expensive_check); -template std::tuple, - std::optional>> -transpose_graph_storage(raft::handle_t const& handle, - graph_t&& graph, - std::optional>&& renumber_map, - bool do_expensive_check); +template std::tuple< + graph_t, + std::optional, double>>, + std::optional>> +transpose_graph_storage( + raft::handle_t const& handle, + graph_t&& graph, + std::optional, double>>&& + edge_weights, + std::optional>&& renumber_map, + bool do_expensive_check); -template std::tuple, - std::optional>> -transpose_graph_storage(raft::handle_t const& handle, - graph_t&& graph, - std::optional>&& renumber_map, - bool do_expensive_check); +template std::tuple< + graph_t, + std::optional, double>>, + std::optional>> +transpose_graph_storage( + raft::handle_t const& handle, + graph_t&& graph, + std::optional, double>>&& edge_weights, + std::optional>&& renumber_map, + bool do_expensive_check); -template std::tuple, - std::optional>> -transpose_graph_storage(raft::handle_t const& handle, - graph_t&& graph, - std::optional>&& renumber_map, - bool do_expensive_check); +template std::tuple< + graph_t, + std::optional, double>>, + std::optional>> +transpose_graph_storage( + raft::handle_t const& handle, + graph_t&& graph, + std::optional, double>>&& + edge_weights, + std::optional>&& renumber_map, + bool do_expensive_check); } // namespace cugraph diff --git a/cpp/src/structure/transpose_graph_storage_sg.cu b/cpp/src/structure/transpose_graph_storage_sg.cu index 4d3c74f5a84..f352a8c8d28 100644 --- a/cpp/src/structure/transpose_graph_storage_sg.cu +++ b/cpp/src/structure/transpose_graph_storage_sg.cu @@ -19,88 +19,145 @@ namespace cugraph { // SG instantiation -template std::tuple, - std::optional>> -transpose_graph_storage(raft::handle_t const& handle, - graph_t&& graph, - std::optional>&& renumber_map, - bool do_expensive_check); +template std::tuple< + graph_t, + std::optional, float>>, + std::optional>> +transpose_graph_storage( + raft::handle_t const& handle, + graph_t&& graph, + std::optional, float>>&& edge_weights, + std::optional>&& renumber_map, + bool do_expensive_check); -template std::tuple, - std::optional>> -transpose_graph_storage(raft::handle_t const& handle, - graph_t&& graph, - std::optional>&& renumber_map, - bool do_expensive_check); +template std::tuple< + graph_t, + std::optional, float>>, + std::optional>> +transpose_graph_storage( + raft::handle_t const& handle, + graph_t&& graph, + std::optional, float>>&& + edge_weights, + std::optional>&& renumber_map, + bool do_expensive_check); -template std::tuple, - std::optional>> -transpose_graph_storage(raft::handle_t const& handle, - graph_t&& graph, - std::optional>&& renumber_map, - bool do_expensive_check); +template std::tuple< + graph_t, + std::optional, float>>, + std::optional>> +transpose_graph_storage( + raft::handle_t const& handle, + graph_t&& graph, + std::optional, float>>&& edge_weights, + std::optional>&& renumber_map, + bool do_expensive_check); -template std::tuple, - std::optional>> -transpose_graph_storage(raft::handle_t const& handle, - graph_t&& graph, - std::optional>&& renumber_map, - bool do_expensive_check); +template std::tuple< + graph_t, + std::optional, float>>, + std::optional>> +transpose_graph_storage( + raft::handle_t const& handle, + graph_t&& graph, + std::optional, float>>&& + edge_weights, + std::optional>&& renumber_map, + bool do_expensive_check); -template std::tuple, - std::optional>> -transpose_graph_storage(raft::handle_t const& handle, - graph_t&& graph, - std::optional>&& renumber_map, - bool do_expensive_check); +template std::tuple< + graph_t, + std::optional, float>>, + std::optional>> +transpose_graph_storage( + raft::handle_t const& handle, + graph_t&& graph, + std::optional, float>>&& edge_weights, + std::optional>&& renumber_map, + bool do_expensive_check); -template std::tuple, - std::optional>> -transpose_graph_storage(raft::handle_t const& handle, - graph_t&& graph, - std::optional>&& renumber_map, - bool do_expensive_check); +template std::tuple< + graph_t, + std::optional, float>>, + std::optional>> +transpose_graph_storage( + raft::handle_t const& handle, + graph_t&& graph, + std::optional, float>>&& + edge_weights, + std::optional>&& renumber_map, + bool do_expensive_check); -template std::tuple, - std::optional>> -transpose_graph_storage(raft::handle_t const& handle, - graph_t&& graph, - std::optional>&& renumber_map, - bool do_expensive_check); +template std::tuple< + graph_t, + std::optional, double>>, + std::optional>> +transpose_graph_storage( + raft::handle_t const& handle, + graph_t&& graph, + std::optional, double>>&& + edge_weights, + std::optional>&& renumber_map, + bool do_expensive_check); -template std::tuple, - std::optional>> -transpose_graph_storage(raft::handle_t const& handle, - graph_t&& graph, - std::optional>&& renumber_map, - bool do_expensive_check); +template std::tuple< + graph_t, + std::optional, double>>, + std::optional>> +transpose_graph_storage( + raft::handle_t const& handle, + graph_t&& graph, + std::optional, double>>&& + edge_weights, + std::optional>&& renumber_map, + bool do_expensive_check); -template std::tuple, - std::optional>> -transpose_graph_storage(raft::handle_t const& handle, - graph_t&& graph, - std::optional>&& renumber_map, - bool do_expensive_check); +template std::tuple< + graph_t, + std::optional, double>>, + std::optional>> +transpose_graph_storage( + raft::handle_t const& handle, + graph_t&& graph, + std::optional, double>>&& + edge_weights, + std::optional>&& renumber_map, + bool do_expensive_check); -template std::tuple, - std::optional>> -transpose_graph_storage(raft::handle_t const& handle, - graph_t&& graph, - std::optional>&& renumber_map, - bool do_expensive_check); +template std::tuple< + graph_t, + std::optional, double>>, + std::optional>> +transpose_graph_storage( + raft::handle_t const& handle, + graph_t&& graph, + std::optional, double>>&& + edge_weights, + std::optional>&& renumber_map, + bool do_expensive_check); -template std::tuple, - std::optional>> -transpose_graph_storage(raft::handle_t const& handle, - graph_t&& graph, - std::optional>&& renumber_map, - bool do_expensive_check); +template std::tuple< + graph_t, + std::optional, double>>, + std::optional>> +transpose_graph_storage( + raft::handle_t const& handle, + graph_t&& graph, + std::optional, double>>&& + edge_weights, + std::optional>&& renumber_map, + bool do_expensive_check); -template std::tuple, - std::optional>> -transpose_graph_storage(raft::handle_t const& handle, - graph_t&& graph, - std::optional>&& renumber_map, - bool do_expensive_check); +template std::tuple< + graph_t, + std::optional, double>>, + std::optional>> +transpose_graph_storage( + raft::handle_t const& handle, + graph_t&& graph, + std::optional, double>>&& + edge_weights, + std::optional>&& renumber_map, + bool do_expensive_check); } // namespace cugraph diff --git a/cpp/src/traversal/bfs_impl.cuh b/cpp/src/traversal/bfs_impl.cuh index 90ce118a4d8..d03ba9605ff 100644 --- a/cpp/src/traversal/bfs_impl.cuh +++ b/cpp/src/traversal/bfs_impl.cuh @@ -23,6 +23,7 @@ #include #include +#include #include #include #include @@ -62,10 +63,8 @@ struct e_op_t { // will eat-up more memory with no benefit in performance in large-scale). vertex_t dst_first{}; // relevant only if multi_gpu is true - __device__ thrust::optional operator()(vertex_t src, - vertex_t dst, - thrust::nullopt_t, - thrust::nullopt_t) const + __device__ thrust::optional operator()( + vertex_t src, vertex_t dst, thrust::nullopt_t, thrust::nullopt_t, thrust::nullopt_t) const { bool push{}; if constexpr (multi_gpu) { @@ -237,6 +236,7 @@ void bfs(raft::handle_t const& handle, vertex_frontier.bucket(bucket_idx_cur), edge_src_dummy_property_t{}.view(), edge_dst_dummy_property_t{}.view(), + edge_dummy_property_t{}.view(), #if 1 e_op, #else @@ -244,7 +244,7 @@ void bfs(raft::handle_t const& handle, // communication in updating dst_visited_flags (+ using atomics) vs reduced number of // pushes (leading to both less computation & communication in reduction) [vertex_partition, distances] __device__( - vertex_t src, vertex_t dst, auto src_val, auto dst_val) { + vertex_t src, vertex_t dst, auto, auto, auto) { auto push = true; if (vertex_partition.in_local_vertex_partition_range_nocheck(dst)) { auto distance = @@ -288,9 +288,9 @@ void bfs(raft::handle_t const& handle, } // namespace detail -template +template void bfs(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, vertex_t* distances, vertex_t* predecessors, vertex_t const* sources, diff --git a/cpp/src/traversal/bfs_mg.cu b/cpp/src/traversal/bfs_mg.cu index cbe2a7c0d16..3a28487ad71 100644 --- a/cpp/src/traversal/bfs_mg.cu +++ b/cpp/src/traversal/bfs_mg.cu @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, NVIDIA CORPORATION. + * Copyright (c) 2021-2022, NVIDIA CORPORATION. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,7 +21,7 @@ namespace cugraph { // MG instantiation template void bfs(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, int32_t* distances, int32_t* predecessors, int32_t const* sources, @@ -31,7 +31,7 @@ template void bfs(raft::handle_t const& handle, bool do_expensive_check); template void bfs(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, int32_t* distances, int32_t* predecessors, int32_t const* sources, @@ -41,37 +41,7 @@ template void bfs(raft::handle_t const& handle, bool do_expensive_check); template void bfs(raft::handle_t const& handle, - graph_view_t const& graph_view, - int32_t* distances, - int32_t* predecessors, - int32_t const* sources, - size_t n_sources, - bool direction_optimizing, - int32_t depth_limit, - bool do_expensive_check); - -template void bfs(raft::handle_t const& handle, - graph_view_t const& graph_view, - int32_t* distances, - int32_t* predecessors, - int32_t const* sources, - size_t n_sources, - bool direction_optimizing, - int32_t depth_limit, - bool do_expensive_check); - -template void bfs(raft::handle_t const& handle, - graph_view_t const& graph_view, - int64_t* distances, - int64_t* predecessors, - int64_t const* sources, - size_t n_sources, - bool direction_optimizing, - int64_t depth_limit, - bool do_expensive_check); - -template void bfs(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, int64_t* distances, int64_t* predecessors, int64_t const* sources, diff --git a/cpp/src/traversal/bfs_sg.cu b/cpp/src/traversal/bfs_sg.cu index 3a38a7208de..f9ef4f24d30 100644 --- a/cpp/src/traversal/bfs_sg.cu +++ b/cpp/src/traversal/bfs_sg.cu @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, NVIDIA CORPORATION. + * Copyright (c) 2021-2022, NVIDIA CORPORATION. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,7 +21,7 @@ namespace cugraph { // SG instantiation template void bfs(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, int32_t* distances, int32_t* predecessors, int32_t const* sources, @@ -31,7 +31,7 @@ template void bfs(raft::handle_t const& handle, bool do_expensive_check); template void bfs(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, int32_t* distances, int32_t* predecessors, int32_t const* sources, @@ -41,37 +41,7 @@ template void bfs(raft::handle_t const& handle, bool do_expensive_check); template void bfs(raft::handle_t const& handle, - graph_view_t const& graph_view, - int32_t* distances, - int32_t* predecessors, - int32_t const* sources, - size_t n_sources, - bool direction_optimizing, - int32_t depth_limit, - bool do_expensive_check); - -template void bfs(raft::handle_t const& handle, - graph_view_t const& graph_view, - int32_t* distances, - int32_t* predecessors, - int32_t const* sources, - size_t n_sources, - bool direction_optimizing, - int32_t depth_limit, - bool do_expensive_check); - -template void bfs(raft::handle_t const& handle, - graph_view_t const& graph_view, - int64_t* distances, - int64_t* predecessors, - int64_t const* sources, - size_t n_sources, - bool direction_optimizing, - int64_t depth_limit, - bool do_expensive_check); - -template void bfs(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, int64_t* distances, int64_t* predecessors, int64_t const* sources, diff --git a/cpp/src/traversal/extract_bfs_paths_impl.cuh b/cpp/src/traversal/extract_bfs_paths_impl.cuh index 5d6e30027a5..944b805864c 100644 --- a/cpp/src/traversal/extract_bfs_paths_impl.cuh +++ b/cpp/src/traversal/extract_bfs_paths_impl.cuh @@ -137,10 +137,10 @@ std::tuple, rmm::device_uvector> shrink_ex } // namespace detail -template +template std::tuple, vertex_t> extract_bfs_paths( raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, vertex_t const* distances, vertex_t const* predecessors, vertex_t const* destinations, diff --git a/cpp/src/traversal/extract_bfs_paths_mg.cu b/cpp/src/traversal/extract_bfs_paths_mg.cu index 44681409c75..931ead71be0 100644 --- a/cpp/src/traversal/extract_bfs_paths_mg.cu +++ b/cpp/src/traversal/extract_bfs_paths_mg.cu @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, NVIDIA CORPORATION. + * Copyright (c) 2021-2022, NVIDIA CORPORATION. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,7 +22,7 @@ namespace cugraph { template std::tuple, int32_t> extract_bfs_paths( raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, int32_t const* distances, int32_t const* predecessors, int32_t const* destinations, @@ -30,7 +30,7 @@ template std::tuple, int32_t> extract_bfs_paths( template std::tuple, int32_t> extract_bfs_paths( raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, int32_t const* distances, int32_t const* predecessors, int32_t const* destinations, @@ -38,31 +38,7 @@ template std::tuple, int32_t> extract_bfs_paths( template std::tuple, int64_t> extract_bfs_paths( raft::handle_t const& handle, - graph_view_t const& graph_view, - int64_t const* distances, - int64_t const* predecessors, - int64_t const* destinations, - size_t n_destinations); - -template std::tuple, int32_t> extract_bfs_paths( - raft::handle_t const& handle, - graph_view_t const& graph_view, - int32_t const* distances, - int32_t const* predecessors, - int32_t const* destinations, - size_t n_destinations); - -template std::tuple, int32_t> extract_bfs_paths( - raft::handle_t const& handle, - graph_view_t const& graph_view, - int32_t const* distances, - int32_t const* predecessors, - int32_t const* destinations, - size_t n_destinations); - -template std::tuple, int64_t> extract_bfs_paths( - raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, int64_t const* distances, int64_t const* predecessors, int64_t const* destinations, diff --git a/cpp/src/traversal/extract_bfs_paths_sg.cu b/cpp/src/traversal/extract_bfs_paths_sg.cu index b75bc06d7fc..c51dfc1f5c0 100644 --- a/cpp/src/traversal/extract_bfs_paths_sg.cu +++ b/cpp/src/traversal/extract_bfs_paths_sg.cu @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, NVIDIA CORPORATION. + * Copyright (c) 2021-2022, NVIDIA CORPORATION. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,7 +22,7 @@ namespace cugraph { template std::tuple, int32_t> extract_bfs_paths( raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, int32_t const* distances, int32_t const* predecessors, int32_t const* destinations, @@ -30,7 +30,7 @@ template std::tuple, int32_t> extract_bfs_paths( template std::tuple, int32_t> extract_bfs_paths( raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, int32_t const* distances, int32_t const* predecessors, int32_t const* destinations, @@ -38,31 +38,7 @@ template std::tuple, int32_t> extract_bfs_paths( template std::tuple, int64_t> extract_bfs_paths( raft::handle_t const& handle, - graph_view_t const& graph_view, - int64_t const* distances, - int64_t const* predecessors, - int64_t const* destinations, - size_t n_destinations); - -template std::tuple, int32_t> extract_bfs_paths( - raft::handle_t const& handle, - graph_view_t const& graph_view, - int32_t const* distances, - int32_t const* predecessors, - int32_t const* destinations, - size_t n_destinations); - -template std::tuple, int32_t> extract_bfs_paths( - raft::handle_t const& handle, - graph_view_t const& graph_view, - int32_t const* distances, - int32_t const* predecessors, - int32_t const* destinations, - size_t n_destinations); - -template std::tuple, int64_t> extract_bfs_paths( - raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, int64_t const* distances, int64_t const* predecessors, int64_t const* destinations, diff --git a/cpp/src/traversal/k_hop_nbrs_impl.cuh b/cpp/src/traversal/k_hop_nbrs_impl.cuh index 6f19aedb1ef..b891b8ea8c0 100644 --- a/cpp/src/traversal/k_hop_nbrs_impl.cuh +++ b/cpp/src/traversal/k_hop_nbrs_impl.cuh @@ -49,6 +49,7 @@ struct e_op_t { __device__ thrust::optional operator()(thrust::tuple tagged_src, vertex_t, thrust::nullopt_t, + thrust::nullopt_t, thrust::nullopt_t) const { return thrust::get<1>(tagged_src); @@ -149,6 +150,7 @@ k_hop_nbrs(raft::handle_t const& handle, frontier.bucket(bucket_idx_cur), edge_src_dummy_property_t{}.view(), edge_dst_dummy_property_t{}.view(), + edge_dummy_property_t{}.view(), e_op_t{}, reduce_op::null{}, do_expensive_check); @@ -221,10 +223,10 @@ k_hop_nbrs(raft::handle_t const& handle, } // namespace detail -template +template std::tuple, rmm::device_uvector> k_hop_nbrs( raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, raft::device_span start_vertices, size_t k, bool do_expensive_check) diff --git a/cpp/src/traversal/k_hop_nbrs_mg.cu b/cpp/src/traversal/k_hop_nbrs_mg.cu index 837eedd74af..15b3f1c3b7d 100644 --- a/cpp/src/traversal/k_hop_nbrs_mg.cu +++ b/cpp/src/traversal/k_hop_nbrs_mg.cu @@ -21,42 +21,21 @@ namespace cugraph { template std::tuple, rmm::device_uvector> k_hop_nbrs( raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, raft::device_span start_vertices, size_t k, bool do_expensive_check); template std::tuple, rmm::device_uvector> k_hop_nbrs( raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, raft::device_span start_vertices, size_t k, bool do_expensive_check); -template std::tuple, rmm::device_uvector> k_hop_nbrs( - raft::handle_t const& handle, - graph_view_t const& graph_view, - raft::device_span start_vertices, - size_t k, - bool do_expensive_check); - -template std::tuple, rmm::device_uvector> k_hop_nbrs( - raft::handle_t const& handle, - graph_view_t const& graph_view, - raft::device_span start_vertices, - size_t k, - bool do_expensive_check); - -template std::tuple, rmm::device_uvector> k_hop_nbrs( - raft::handle_t const& handle, - graph_view_t const& graph_view, - raft::device_span start_vertices, - size_t k, - bool do_expensive_check); - template std::tuple, rmm::device_uvector> k_hop_nbrs( raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, raft::device_span start_vertices, size_t k, bool do_expensive_check); diff --git a/cpp/src/traversal/k_hop_nbrs_sg.cu b/cpp/src/traversal/k_hop_nbrs_sg.cu index 94ec8979a92..3436594a8c9 100644 --- a/cpp/src/traversal/k_hop_nbrs_sg.cu +++ b/cpp/src/traversal/k_hop_nbrs_sg.cu @@ -21,42 +21,21 @@ namespace cugraph { template std::tuple, rmm::device_uvector> k_hop_nbrs( raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, raft::device_span start_vertices, size_t k, bool do_expensive_check); template std::tuple, rmm::device_uvector> k_hop_nbrs( raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, raft::device_span start_vertices, size_t k, bool do_expensive_check); -template std::tuple, rmm::device_uvector> k_hop_nbrs( - raft::handle_t const& handle, - graph_view_t const& graph_view, - raft::device_span start_vertices, - size_t k, - bool do_expensive_check); - -template std::tuple, rmm::device_uvector> k_hop_nbrs( - raft::handle_t const& handle, - graph_view_t const& graph_view, - raft::device_span start_vertices, - size_t k, - bool do_expensive_check); - -template std::tuple, rmm::device_uvector> k_hop_nbrs( - raft::handle_t const& handle, - graph_view_t const& graph_view, - raft::device_span start_vertices, - size_t k, - bool do_expensive_check); - template std::tuple, rmm::device_uvector> k_hop_nbrs( raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, raft::device_span start_vertices, size_t k, bool do_expensive_check); diff --git a/cpp/src/traversal/sssp_impl.cuh b/cpp/src/traversal/sssp_impl.cuh index 70ccbdffaac..1816d25d549 100644 --- a/cpp/src/traversal/sssp_impl.cuh +++ b/cpp/src/traversal/sssp_impl.cuh @@ -53,7 +53,7 @@ struct e_op_t { weight_t cutoff{}; __device__ thrust::optional> operator()( - vertex_t src, vertex_t dst, weight_t w, weight_t src_val, thrust::nullopt_t) const + vertex_t src, vertex_t dst, weight_t src_val, thrust::nullopt_t, weight_t w) const { auto push = true; auto new_distance = src_val + w; @@ -75,17 +75,17 @@ struct e_op_t { namespace detail { -template +template void sssp(raft::handle_t const& handle, GraphViewType const& push_graph_view, - typename GraphViewType::weight_type* distances, + edge_property_view_t edge_weight_view, + weight_t* distances, PredecessorIterator predecessor_first, typename GraphViewType::vertex_type source_vertex, - typename GraphViewType::weight_type cutoff, + weight_t cutoff, bool do_expensive_check) { using vertex_t = typename GraphViewType::vertex_type; - using weight_t = typename GraphViewType::weight_type; static_assert(std::is_integral::value, "GraphViewType::vertex_type should be integral."); @@ -104,9 +104,6 @@ void sssp(raft::handle_t const& handle, CUGRAPH_EXPECTS(push_graph_view.is_valid_vertex(source_vertex), "Invalid input argument: source vertex out-of-range."); - CUGRAPH_EXPECTS(push_graph_view.is_weighted(), - "Invalid input argument: an unweighted graph is passed to SSSP, BFS is more " - "efficient for unweighted graphs."); if (do_expensive_check) { auto num_negative_edge_weights = @@ -114,9 +111,10 @@ void sssp(raft::handle_t const& handle, push_graph_view, edge_src_dummy_property_t{}.view(), edge_dst_dummy_property_t{}.view(), - [] __device__(vertex_t, vertex_t, weight_t w, auto, auto) { return w < 0.0; }); + edge_weight_view, + [] __device__(vertex_t, vertex_t, auto, auto, weight_t w) { return w < 0.0; }); CUGRAPH_EXPECTS(num_negative_edge_weights == 0, - "Invalid input argument: input graph should have non-negative edge weights."); + "Invalid input argument: input edge weights should have non-negative values."); } // 2. initialize distances and predecessors @@ -147,7 +145,8 @@ void sssp(raft::handle_t const& handle, push_graph_view, edge_src_dummy_property_t{}.view(), edge_dst_dummy_property_t{}.view(), - [] __device__(vertex_t, vertex_t, weight_t w, auto, auto) { + edge_weight_view, + [] __device__(vertex_t, vertex_t, auto, auto, weight_t w) { return thrust::make_tuple(weight_t{1.0}, w); }, thrust::make_tuple(weight_t{0.0}, weight_t{0.0})); @@ -204,6 +203,7 @@ void sssp(raft::handle_t const& handle, ? edge_src_distances.view() : detail::edge_major_property_view_t(distances), edge_dst_dummy_property_t{}.view(), + edge_weight_view, e_op_t{ vertex_partition, distances, cutoff}, reduce_op::minimum>()); @@ -271,7 +271,8 @@ void sssp(raft::handle_t const& handle, template void sssp(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view, weight_t* distances, vertex_t* predecessors, vertex_t source_vertex, @@ -279,11 +280,18 @@ void sssp(raft::handle_t const& handle, bool do_expensive_check) { if (predecessors != nullptr) { - detail::sssp( - handle, graph_view, distances, predecessors, source_vertex, cutoff, do_expensive_check); + detail::sssp(handle, + graph_view, + edge_weight_view, + distances, + predecessors, + source_vertex, + cutoff, + do_expensive_check); } else { detail::sssp(handle, graph_view, + edge_weight_view, distances, thrust::make_discard_iterator(), source_vertex, diff --git a/cpp/src/traversal/sssp_mg.cu b/cpp/src/traversal/sssp_mg.cu index 641ddbfe3a5..0a67eb8c422 100644 --- a/cpp/src/traversal/sssp_mg.cu +++ b/cpp/src/traversal/sssp_mg.cu @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, NVIDIA CORPORATION. + * Copyright (c) 2021-2022, NVIDIA CORPORATION. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,7 +20,8 @@ namespace cugraph { // MG instantiation template void sssp(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view, float* distances, int32_t* predecessors, int32_t source_vertex, @@ -28,7 +29,8 @@ template void sssp(raft::handle_t const& handle, bool do_expensive_check); template void sssp(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view, double* distances, int32_t* predecessors, int32_t source_vertex, @@ -36,7 +38,8 @@ template void sssp(raft::handle_t const& handle, bool do_expensive_check); template void sssp(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view, float* distances, int32_t* predecessors, int32_t source_vertex, @@ -44,7 +47,8 @@ template void sssp(raft::handle_t const& handle, bool do_expensive_check); template void sssp(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view, double* distances, int32_t* predecessors, int32_t source_vertex, @@ -52,7 +56,8 @@ template void sssp(raft::handle_t const& handle, bool do_expensive_check); template void sssp(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view, float* distances, int64_t* predecessors, int64_t source_vertex, @@ -60,7 +65,8 @@ template void sssp(raft::handle_t const& handle, bool do_expensive_check); template void sssp(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view, double* distances, int64_t* predecessors, int64_t source_vertex, diff --git a/cpp/src/traversal/sssp_sg.cu b/cpp/src/traversal/sssp_sg.cu index e0c1ef3b681..83b457050fc 100644 --- a/cpp/src/traversal/sssp_sg.cu +++ b/cpp/src/traversal/sssp_sg.cu @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, NVIDIA CORPORATION. + * Copyright (c) 2021-2022, NVIDIA CORPORATION. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,7 +20,8 @@ namespace cugraph { // SG instantiation template void sssp(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view, float* distances, int32_t* predecessors, int32_t source_vertex, @@ -28,7 +29,8 @@ template void sssp(raft::handle_t const& handle, bool do_expensive_check); template void sssp(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view, double* distances, int32_t* predecessors, int32_t source_vertex, @@ -36,7 +38,8 @@ template void sssp(raft::handle_t const& handle, bool do_expensive_check); template void sssp(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view, float* distances, int32_t* predecessors, int32_t source_vertex, @@ -44,7 +47,8 @@ template void sssp(raft::handle_t const& handle, bool do_expensive_check); template void sssp(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view, double* distances, int32_t* predecessors, int32_t source_vertex, @@ -52,7 +56,8 @@ template void sssp(raft::handle_t const& handle, bool do_expensive_check); template void sssp(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view, float* distances, int64_t* predecessors, int64_t source_vertex, @@ -60,7 +65,8 @@ template void sssp(raft::handle_t const& handle, bool do_expensive_check); template void sssp(raft::handle_t const& handle, - graph_view_t const& graph_view, + graph_view_t const& graph_view, + edge_property_view_t edge_weight_view, double* distances, int64_t* predecessors, int64_t source_vertex, diff --git a/cpp/src/utilities/cugraph_ops_utils.hpp b/cpp/src/utilities/cugraph_ops_utils.hpp index ed0c8fa5478..1684b367cac 100644 --- a/cpp/src/utilities/cugraph_ops_utils.hpp +++ b/cpp/src/utilities/cugraph_ops_utils.hpp @@ -25,9 +25,9 @@ namespace cugraph { namespace detail { -template +template ops::gnn::graph::fg_csr get_graph( - graph_view_t const& gview) + graph_view_t const& gview) { ops::gnn::graph::fg_csr graph; graph.n_nodes = gview.number_of_vertices(); @@ -39,9 +39,9 @@ ops::gnn::graph::fg_csr get_graph( return graph; } -template +template std::tuple, NodeTypeT> get_graph_and_max_degree( - graph_view_t const& gview) + graph_view_t const& gview) { // FIXME this is sufficient for now, but if there is a fast (cached) way // of getting max degree, use that instead diff --git a/cpp/tests/CMakeLists.txt b/cpp/tests/CMakeLists.txt index 873c92d0cdc..5c9bc27bd4e 100644 --- a/cpp/tests/CMakeLists.txt +++ b/cpp/tests/CMakeLists.txt @@ -29,7 +29,6 @@ add_library(cugraphtestutil STATIC centrality/betweenness_centrality_validate.cu community/egonet_validate.cu structure/induced_subgraph_validate.cu - components/wcc_graphs.cu sampling/random_walks_check_sg.cu ../../thirdparty/mmio/mmio.c) diff --git a/cpp/tests/centrality/betweenness_centrality_test.cpp b/cpp/tests/centrality/betweenness_centrality_test.cpp index 3afc453b7a5..eb5f58f6698 100644 --- a/cpp/tests/centrality/betweenness_centrality_test.cpp +++ b/cpp/tests/centrality/betweenness_centrality_test.cpp @@ -70,7 +70,7 @@ class Tests_BetweennessCentrality hr_clock.start(); } - auto [graph, d_renumber_map_labels] = + auto [graph, edge_weights, d_renumber_map_labels] = cugraph::test::construct_graph( handle, input_usecase, betweenness_usecase.test_weighted, renumber); @@ -82,6 +82,8 @@ class Tests_BetweennessCentrality } auto graph_view = graph.view(); + auto edge_weight_view = + edge_weights ? std::make_optional((*edge_weights).view()) : std::nullopt; rmm::device_uvector d_seeds(graph_view.number_of_vertices(), handle.get_stream()); cugraph::detail::sequence_fill( @@ -98,6 +100,7 @@ class Tests_BetweennessCentrality auto d_centralities = cugraph::betweenness_centrality( handle, graph_view, + edge_weight_view, std::make_optional>>( raft::device_span{d_seeds.data(), d_seeds.size()}), betweenness_usecase.normalized, @@ -107,6 +110,7 @@ class Tests_BetweennessCentrality EXPECT_THROW(cugraph::betweenness_centrality( handle, graph_view, + edge_weight_view, std::make_optional>>( raft::device_span{d_seeds.data(), d_seeds.size()}), betweenness_usecase.normalized, @@ -124,7 +128,7 @@ class Tests_BetweennessCentrality if (betweenness_usecase.check_correctness) { #if 0 - auto [h_offsets, h_indices, h_wgt] = cugraph::test::graph_to_host_csr(handle, graph_view); + auto [h_offsets, h_indices, h_wgt] = cugraph::test::graph_to_host_csr(handle, graph_view, edge_weight_view); auto h_seeds = cugraph::test::to_host(handle, d_seeds); diff --git a/cpp/tests/centrality/edge_betweenness_centrality_test.cpp b/cpp/tests/centrality/edge_betweenness_centrality_test.cpp index 68d7cbb9f86..bd1db3704b6 100644 --- a/cpp/tests/centrality/edge_betweenness_centrality_test.cpp +++ b/cpp/tests/centrality/edge_betweenness_centrality_test.cpp @@ -70,7 +70,7 @@ class Tests_EdgeBetweennessCentrality hr_clock.start(); } - auto [graph, d_renumber_map_labels] = + auto [graph, edge_weights, d_renumber_map_labels] = cugraph::test::construct_graph( handle, input_usecase, betweenness_usecase.test_weighted, renumber); @@ -82,6 +82,8 @@ class Tests_EdgeBetweennessCentrality } auto graph_view = graph.view(); + auto edge_weight_view = + edge_weights ? std::make_optional((*edge_weights).view()) : std::nullopt; rmm::device_uvector d_seeds(graph_view.number_of_vertices(), handle.get_stream()); cugraph::detail::sequence_fill( @@ -98,6 +100,7 @@ class Tests_EdgeBetweennessCentrality auto d_centralities = cugraph::edge_betweenness_centrality( handle, graph_view, + edge_weight_view, std::make_optional>>( raft::device_span{d_seeds.data(), d_seeds.size()}), betweenness_usecase.normalized, @@ -106,6 +109,7 @@ class Tests_EdgeBetweennessCentrality EXPECT_THROW(cugraph::edge_betweenness_centrality( handle, graph_view, + edge_weight_view, std::make_optional>>( raft::device_span{d_seeds.data(), d_seeds.size()}), betweenness_usecase.normalized, @@ -122,7 +126,7 @@ class Tests_EdgeBetweennessCentrality if (betweenness_usecase.check_correctness) { #if 0 - auto [h_offsets, h_indices, h_wgt] = cugraph::test::graph_to_host_csr(handle, graph_view); + auto [h_offsets, h_indices, h_wgt] = cugraph::test::graph_to_host_csr(handle, graph_view, edge_weight_view); auto h_seeds = cugraph::test::to_host(handle, d_seeds); diff --git a/cpp/tests/centrality/eigenvector_centrality_test.cpp b/cpp/tests/centrality/eigenvector_centrality_test.cpp index f971502242b..8f7fba0b874 100644 --- a/cpp/tests/centrality/eigenvector_centrality_test.cpp +++ b/cpp/tests/centrality/eigenvector_centrality_test.cpp @@ -127,7 +127,7 @@ class Tests_EigenvectorCentrality hr_clock.start(); } - auto [graph, d_renumber_map_labels] = + auto [graph, edge_weights, d_renumber_map_labels] = cugraph::test::construct_graph( handle, input_usecase, eigenvector_usecase.test_weighted, renumber); @@ -139,6 +139,8 @@ class Tests_EigenvectorCentrality } auto graph_view = graph.view(); + auto edge_weight_view = + edge_weights ? std::make_optional((*edge_weights).view()) : std::nullopt; weight_t constexpr epsilon{1e-6}; @@ -153,6 +155,7 @@ class Tests_EigenvectorCentrality d_centralities = cugraph::eigenvector_centrality(handle, graph_view, + edge_weight_view, std::optional>{}, epsilon, eigenvector_usecase.max_iterations, @@ -167,7 +170,10 @@ class Tests_EigenvectorCentrality if (eigenvector_usecase.check_correctness) { auto [dst_v, src_v, opt_wgt_v] = cugraph::decompress_to_edgelist( - handle, graph_view, std::optional>{std::nullopt}); + handle, + graph_view, + edge_weight_view, + std::optional>{std::nullopt}); auto h_src = cugraph::test::to_host(handle, src_v); auto h_dst = cugraph::test::to_host(handle, dst_v); diff --git a/cpp/tests/centrality/katz_centrality_test.cpp b/cpp/tests/centrality/katz_centrality_test.cpp index c51963ba748..dbac16b4dd2 100644 --- a/cpp/tests/centrality/katz_centrality_test.cpp +++ b/cpp/tests/centrality/katz_centrality_test.cpp @@ -123,7 +123,7 @@ class Tests_KatzCentrality hr_clock.start(); } - auto [graph, d_renumber_map_labels] = + auto [graph, edge_weights, d_renumber_map_labels] = cugraph::test::construct_graph( handle, input_usecase, katz_usecase.test_weighted, renumber); @@ -135,6 +135,8 @@ class Tests_KatzCentrality } auto graph_view = graph.view(); + auto edge_weight_view = + edge_weights ? std::make_optional((*edge_weights).view()) : std::nullopt; auto degrees = graph_view.compute_in_degrees(handle); auto h_degrees = cugraph::test::to_host(handle, degrees); @@ -154,6 +156,7 @@ class Tests_KatzCentrality cugraph::katz_centrality(handle, graph_view, + edge_weight_view, static_cast(nullptr), d_katz_centralities.data(), alpha, @@ -171,20 +174,32 @@ class Tests_KatzCentrality } if (katz_usecase.check_correctness) { - cugraph::graph_t unrenumbered_graph(handle); + cugraph::graph_t unrenumbered_graph(handle); + std::optional< + cugraph::edge_property_t, weight_t>> + unrenumbered_edge_weights{std::nullopt}; if (renumber) { - std::tie(unrenumbered_graph, std::ignore) = + std::tie(unrenumbered_graph, unrenumbered_edge_weights, std::ignore) = cugraph::test::construct_graph( handle, input_usecase, katz_usecase.test_weighted, false); } auto unrenumbered_graph_view = renumber ? unrenumbered_graph.view() : graph_view; + auto unrenumbered_edge_weight_view = + renumber + ? (unrenumbered_edge_weights ? std::make_optional((*unrenumbered_edge_weights).view()) + : std::nullopt) + : edge_weight_view; auto h_offsets = cugraph::test::to_host( handle, unrenumbered_graph_view.local_edge_partition_view().offsets()); auto h_indices = cugraph::test::to_host( handle, unrenumbered_graph_view.local_edge_partition_view().indices()); auto h_weights = cugraph::test::to_host( - handle, unrenumbered_graph_view.local_edge_partition_view().weights()); + handle, + unrenumbered_edge_weight_view ? std::make_optional(raft::device_span( + (*unrenumbered_edge_weight_view).value_firsts()[0], + (*unrenumbered_edge_weight_view).edge_counts()[0])) + : std::nullopt); std::vector h_reference_katz_centralities( unrenumbered_graph_view.number_of_vertices()); diff --git a/cpp/tests/centrality/mg_betweenness_centrality_test.cpp b/cpp/tests/centrality/mg_betweenness_centrality_test.cpp index 6679b1c67c8..0c3dac6f49a 100644 --- a/cpp/tests/centrality/mg_betweenness_centrality_test.cpp +++ b/cpp/tests/centrality/mg_betweenness_centrality_test.cpp @@ -69,7 +69,7 @@ class Tests_MGBetweennessCentrality hr_clock.start(); } - auto [mg_graph, mg_renumber_map] = + auto [mg_graph, mg_edge_weights, mg_renumber_map] = cugraph::test::construct_graph( *handle_, input_usecase, betweenness_usecase.test_weighted, renumber); @@ -81,6 +81,8 @@ class Tests_MGBetweennessCentrality } auto mg_graph_view = mg_graph.view(); + auto mg_edge_weight_view = + mg_edge_weights ? std::make_optional((*mg_edge_weights).view()) : std::nullopt; rmm::device_uvector d_seeds(0, handle_->get_stream()); @@ -104,6 +106,7 @@ class Tests_MGBetweennessCentrality auto d_centralities = cugraph::betweenness_centrality( *handle_, mg_graph_view, + mg_edge_weight_view, std::make_optional>>( raft::device_span{d_seeds.data(), d_seeds.size()}), betweenness_usecase.normalized, @@ -113,6 +116,7 @@ class Tests_MGBetweennessCentrality EXPECT_THROW(cugraph::betweenness_centrality( *handle_, mg_graph_view, + mg_edge_weight_view, std::make_optional>>( raft::device_span{d_seeds.data(), d_seeds.size()}), betweenness_usecase.normalized, @@ -135,12 +139,13 @@ class Tests_MGBetweennessCentrality d_seeds = cugraph::test::device_gatherv( *handle_, raft::device_span{d_seeds.data(), d_seeds.size()}); - auto [sg_graph, sg_renumber_map] = + auto [sg_graph, sg_edge_weights, sg_renumber_map] = cugraph::test::mg_graph_to_sg_graph(*handle_, mg_graph_view, mg_renumber_map, true); auto d_reference_centralities = cugraph::betweenness_centrality( *handle_, sg_graph.view(), + sg_edge_weights ? std::make_optional((*sg_edge_weights).view()) : std::nullopt, std::optional{std::nullopt}, std::make_optional>(d_seeds.data(), d_seeds.size()), betweenness_usecase.normalized, diff --git a/cpp/tests/centrality/mg_edge_betweenness_centrality_test.cpp b/cpp/tests/centrality/mg_edge_betweenness_centrality_test.cpp index 9dfb6606f7c..7aa269a7433 100644 --- a/cpp/tests/centrality/mg_edge_betweenness_centrality_test.cpp +++ b/cpp/tests/centrality/mg_edge_betweenness_centrality_test.cpp @@ -69,7 +69,7 @@ class Tests_MGEdgeBetweennessCentrality hr_clock.start(); } - auto [graph, d_renumber_map_labels] = + auto [mg_graph, mg_edge_weights, d_renumber_map_labels] = cugraph::test::construct_graph( *handle_, input_usecase, betweenness_usecase.test_weighted, renumber); @@ -80,12 +80,15 @@ class Tests_MGEdgeBetweennessCentrality std::cout << "construct_graph took " << elapsed_time * 1e-6 << " s.\n"; } - auto graph_view = graph.view(); + auto mg_graph_view = mg_graph.view(); + auto mg_edge_weight_view = + mg_edge_weights ? std::make_optional((*mg_edge_weights).view()) : std::nullopt; rmm::device_uvector d_seeds(0, handle_->get_stream()); if (handle_->get_comms().get_rank() == 0) { - rmm::device_uvector d_seeds(graph_view.number_of_vertices(), handle_->get_stream()); + rmm::device_uvector d_seeds(mg_graph_view.number_of_vertices(), + handle_->get_stream()); cugraph::detail::sequence_fill( handle_->get_stream(), d_seeds.data(), d_seeds.size(), vertex_t{0}); @@ -102,7 +105,8 @@ class Tests_MGEdgeBetweennessCentrality #if 0 auto d_centralities = cugraph::edge_betweenness_centrality( *handle_, - graph_view, + mg_graph_view, + mg_edge_weight_view, std::make_optional>>( raft::device_span{d_seeds.data(), d_seeds.size()}), betweenness_usecase.normalized, @@ -110,7 +114,8 @@ class Tests_MGEdgeBetweennessCentrality #else EXPECT_THROW(cugraph::edge_betweenness_centrality( *handle_, - graph_view, + mg_graph_view, + mg_edge_weight_view, std::make_optional>>( raft::device_span{d_seeds.data(), d_seeds.size()}), betweenness_usecase.normalized, diff --git a/cpp/tests/centrality/mg_eigenvector_centrality_test.cpp b/cpp/tests/centrality/mg_eigenvector_centrality_test.cpp index 4f59b2dd718..b5d6c02e155 100644 --- a/cpp/tests/centrality/mg_eigenvector_centrality_test.cpp +++ b/cpp/tests/centrality/mg_eigenvector_centrality_test.cpp @@ -70,7 +70,7 @@ class Tests_MGEigenvectorCentrality hr_clock.start(); } - auto [mg_graph, d_mg_renumber_map_labels] = + auto [mg_graph, mg_edge_weights, d_mg_renumber_map_labels] = cugraph::test::construct_graph( *handle_, input_usecase, eigenvector_usecase.test_weighted, true); @@ -83,6 +83,8 @@ class Tests_MGEigenvectorCentrality } auto mg_graph_view = mg_graph.view(); + auto mg_edge_weight_view = + mg_edge_weights ? std::make_optional((*mg_edge_weights).view()) : std::nullopt; // 2. run MG Eigenvector Centrality @@ -100,6 +102,7 @@ class Tests_MGEigenvectorCentrality d_mg_centralities = cugraph::eigenvector_centrality( *handle_, mg_graph_view, + mg_edge_weight_view, std::optional>{}, // std::make_optional(raft::device_span{d_mg_centralities.data(), d_mg_centralities.size()}), @@ -131,11 +134,13 @@ class Tests_MGEigenvectorCentrality *handle_, d_mg_aggregate_renumber_map_labels, d_mg_aggregate_centralities); // 3-3. create SG graph - auto [sg_graph, d_sg_renumber_map_labels] = + auto [sg_graph, sg_edge_weights, d_sg_renumber_map_labels] = cugraph::test::construct_graph( *handle_, input_usecase, eigenvector_usecase.test_weighted, true); auto sg_graph_view = sg_graph.view(); + auto sg_edge_weight_view = + sg_edge_weights ? std::make_optional((*sg_edge_weights).view()) : std::nullopt; ASSERT_TRUE(mg_graph_view.number_of_vertices() == sg_graph_view.number_of_vertices()); @@ -146,6 +151,7 @@ class Tests_MGEigenvectorCentrality d_sg_centralities = cugraph::eigenvector_centrality( *handle_, sg_graph_view, + sg_edge_weight_view, std::optional>{}, // std::make_optional(raft::device_span{d_sg_centralities.data(), // d_sg_centralities.size()}), diff --git a/cpp/tests/centrality/mg_katz_centrality_test.cpp b/cpp/tests/centrality/mg_katz_centrality_test.cpp index e39cc61ef48..eac5bf8f71e 100644 --- a/cpp/tests/centrality/mg_katz_centrality_test.cpp +++ b/cpp/tests/centrality/mg_katz_centrality_test.cpp @@ -68,7 +68,7 @@ class Tests_MGKatzCentrality hr_clock.start(); } - auto [mg_graph, d_mg_renumber_map_labels] = + auto [mg_graph, mg_edge_weights, d_mg_renumber_map_labels] = cugraph::test::construct_graph( *handle_, input_usecase, katz_usecase.test_weighted, true); @@ -81,6 +81,8 @@ class Tests_MGKatzCentrality } auto mg_graph_view = mg_graph.view(); + auto mg_edge_weight_view = + mg_edge_weights ? std::make_optional((*mg_edge_weights).view()) : std::nullopt; // 2. compute max in-degree @@ -103,6 +105,7 @@ class Tests_MGKatzCentrality cugraph::katz_centrality(*handle_, mg_graph_view, + mg_edge_weight_view, static_cast(nullptr), d_mg_katz_centralities.data(), alpha, @@ -137,12 +140,17 @@ class Tests_MGKatzCentrality // 4-3. create SG graph - cugraph::graph_t sg_graph(*handle_); - std::tie(sg_graph, std::ignore) = + cugraph::graph_t sg_graph(*handle_); + std::optional< + cugraph::edge_property_t, weight_t>> + sg_edge_weights{std::nullopt}; + std::tie(sg_graph, sg_edge_weights, std::ignore) = cugraph::test::construct_graph( *handle_, input_usecase, katz_usecase.test_weighted, false); auto sg_graph_view = sg_graph.view(); + auto sg_edge_weight_view = + sg_edge_weights ? std::make_optional((*sg_edge_weights).view()) : std::nullopt; ASSERT_TRUE(mg_graph_view.number_of_vertices() == sg_graph_view.number_of_vertices()); @@ -153,6 +161,7 @@ class Tests_MGKatzCentrality cugraph::katz_centrality(*handle_, sg_graph_view, + sg_edge_weight_view, static_cast(nullptr), d_sg_katz_centralities.data(), alpha, diff --git a/cpp/tests/community/egonet_test.cpp b/cpp/tests/community/egonet_test.cpp index 57dc1384f40..0db2d21e4cb 100644 --- a/cpp/tests/community/egonet_test.cpp +++ b/cpp/tests/community/egonet_test.cpp @@ -68,7 +68,7 @@ class Tests_Egonet : public ::testing::TestWithParam( handle, input_usecase, egonet_usecase.test_weighted_, renumber); @@ -80,6 +80,8 @@ class Tests_Egonet : public ::testing::TestWithParam d_ego_sources(egonet_usecase.ego_sources_.size(), handle.get_stream()); @@ -105,6 +107,7 @@ class Tests_Egonet : public ::testing::TestWithParam{d_ego_sources.data(), egonet_usecase.ego_sources_.size()}, egonet_usecase.radius_); @@ -120,6 +123,7 @@ class Tests_Egonet : public ::testing::TestWithParam{d_ego_sources.data(), d_ego_sources.size()}, egonet_usecase.radius_); diff --git a/cpp/tests/community/egonet_validate.cu b/cpp/tests/community/egonet_validate.cu index c0b82f8036b..44b74090ec4 100644 --- a/cpp/tests/community/egonet_validate.cu +++ b/cpp/tests/community/egonet_validate.cu @@ -36,14 +36,19 @@ std::tuple, rmm::device_uvector, std::optional>, rmm::device_uvector> -egonet_reference(raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, - raft::device_span ego_sources, - int radius) +egonet_reference( + raft::handle_t const& handle, + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view, + raft::device_span ego_sources, + int radius) { #if 1 - auto [d_coo_src, d_coo_dst, d_coo_wgt] = cugraph::decompress_to_edgelist( - handle, graph_view, std::optional>{std::nullopt}); + auto [d_coo_src, d_coo_dst, d_coo_wgt] = + cugraph::decompress_to_edgelist(handle, + graph_view, + edge_weight_view, + std::optional>{std::nullopt}); #else // FIXME: This should be faster (smaller list of edges to operate on), but uniform_nbr_sample // doesn't preserve multi-edges (which is probably a bug) @@ -55,6 +60,7 @@ egonet_reference(raft::handle_t const& handle, auto [d_coo_src, d_coo_dst, d_coo_wgt, d_coo_counts] = cugraph::uniform_nbr_sample( handle, graph_view, + edge_weight_view, raft::device_span{local_ego_sources.data(), local_ego_sources.size()}, raft::host_span{fan_out.data(), fan_out.size()}, false); @@ -67,9 +73,8 @@ egonet_reference(raft::handle_t const& handle, rmm::device_uvector d_reference_dst(0, handle.get_stream()); auto d_reference_wgt = - graph_view.is_weighted() - ? std::make_optional(rmm::device_uvector(0, handle.get_stream())) - : std::nullopt; + edge_weight_view ? std::make_optional(rmm::device_uvector(0, handle.get_stream())) + : std::nullopt; std::vector h_reference_offsets; @@ -98,7 +103,7 @@ egonet_reference(raft::handle_t const& handle, d_reference_src.resize(old_size + new_entries, handle.get_stream()); d_reference_dst.resize(old_size + new_entries, handle.get_stream()); - if (graph_view.is_weighted()) { + if (edge_weight_view) { d_reference_wgt->resize(old_size + new_entries, handle.get_stream()); thrust::copy_if( @@ -172,7 +177,7 @@ egonet_reference(raft::handle_t const& handle, d_reference_src.resize(old_size + new_entries, handle.get_stream()); d_reference_dst.resize(old_size + new_entries, handle.get_stream()); - if (graph_view.is_weighted()) { + if (edge_weight_view) { d_reference_wgt->resize(old_size + new_entries, handle.get_stream()); thrust::copy_if( @@ -344,10 +349,12 @@ template std::tuple, rmm::device_uvector, std::optional>, rmm::device_uvector> -egonet_reference(raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, - raft::device_span ego_sources, - int radius); +egonet_reference( + raft::handle_t const& handle, + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view, + raft::device_span ego_sources, + int radius); template void egonet_validate(raft::handle_t const& handle, rmm::device_uvector& d_cugraph_egonet_src, @@ -378,6 +385,7 @@ std::tuple, rmm::device_uvector> egonet_reference(raft::handle_t const& handle, cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view, raft::device_span ego_sources, int radius); @@ -388,6 +396,7 @@ std::tuple, rmm::device_uvector> egonet_reference(raft::handle_t const& handle, cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view, raft::device_span ego_sources, int radius); @@ -398,6 +407,7 @@ std::tuple, rmm::device_uvector> egonet_reference(raft::handle_t const& handle, cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view, raft::device_span ego_sources, int radius); @@ -408,6 +418,7 @@ std::tuple, rmm::device_uvector> egonet_reference(raft::handle_t const& handle, cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view, raft::device_span ego_sources, int radius); @@ -418,6 +429,7 @@ std::tuple, rmm::device_uvector> egonet_reference(raft::handle_t const& handle, cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view, raft::device_span ego_sources, int radius); diff --git a/cpp/tests/community/egonet_validate.hpp b/cpp/tests/community/egonet_validate.hpp index 86046fb6a2f..7d34bea19a6 100644 --- a/cpp/tests/community/egonet_validate.hpp +++ b/cpp/tests/community/egonet_validate.hpp @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +#include #include #include @@ -30,10 +31,12 @@ std::tuple, rmm::device_uvector, std::optional>, rmm::device_uvector> -egonet_reference(raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, - raft::device_span ego_sources, - int radius); +egonet_reference( + raft::handle_t const& handle, + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view, + raft::device_span ego_sources, + int radius); template void egonet_validate(raft::handle_t const& handle, diff --git a/cpp/tests/community/louvain_test.cpp b/cpp/tests/community/louvain_test.cpp index 0fcf3e66a17..c2d41119a57 100644 --- a/cpp/tests/community/louvain_test.cpp +++ b/cpp/tests/community/louvain_test.cpp @@ -71,18 +71,18 @@ class Tests_Louvain RAFT_CUDA_TRY(cudaGetDeviceProperties(&device_prop, 0)); if (device_prop.major < 7) { - EXPECT_THROW(louvain(graph_view, - graph_view.get_number_of_vertices(), - louvain_usecase.check_correctness_, - louvain_usecase.expected_level_, - louvain_usecase.expected_modularity_), + EXPECT_THROW(louvain_legacy(graph_view, + graph_view.get_number_of_vertices(), + louvain_usecase.check_correctness_, + louvain_usecase.expected_level_, + louvain_usecase.expected_modularity_), cugraph::logic_error); } else { - louvain(graph_view, - graph_view.get_number_of_vertices(), - louvain_usecase.check_correctness_, - louvain_usecase.expected_level_, - louvain_usecase.expected_modularity_); + louvain_legacy(graph_view, + graph_view.get_number_of_vertices(), + louvain_usecase.check_correctness_, + louvain_usecase.expected_level_, + louvain_usecase.expected_modularity_); } } @@ -103,7 +103,7 @@ class Tests_Louvain hr_clock.start(); } - auto [graph, d_renumber_map_labels] = + auto [graph, edge_weights, d_renumber_map_labels] = cugraph::test::construct_graph( handle, input_usecase, true, renumber); @@ -115,6 +115,8 @@ class Tests_Louvain } auto graph_view = graph.view(); + auto edge_weight_view = + edge_weights ? std::make_optional((*edge_weights).view()) : std::nullopt; // "FIXME": remove this check once we drop support for Pascal // @@ -131,6 +133,7 @@ class Tests_Louvain if (device_prop.major < 7) { EXPECT_THROW(louvain(graph_view, + edge_weight_view, graph_view.local_vertex_partition_range_size(), louvain_usecase.check_correctness_, louvain_usecase.expected_level_, @@ -138,6 +141,7 @@ class Tests_Louvain cugraph::logic_error); } else { louvain(graph_view, + edge_weight_view, graph_view.local_vertex_partition_range_size(), louvain_usecase.check_correctness_, louvain_usecase.expected_level_, @@ -152,16 +156,13 @@ class Tests_Louvain } } - template - void louvain(graph_t const& graph_view, - typename graph_t::vertex_type num_vertices, - bool check_correctness, - int expected_level, - float expected_modularity) + template + void louvain_legacy(cugraph::legacy::GraphCSRView const& graph_view, + vertex_t num_vertices, + bool check_correctness, + int expected_level, + float expected_modularity) { - using vertex_t = typename graph_t::vertex_type; - using weight_t = typename graph_t::weight_type; - raft::handle_t handle{}; rmm::device_uvector clustering_v(num_vertices, handle.get_stream()); @@ -180,6 +181,34 @@ class Tests_Louvain ASSERT_EQ(level, expected_level); } } + + template + void louvain( + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view, + vertex_t num_vertices, + bool check_correctness, + int expected_level, + float expected_modularity) + { + raft::handle_t handle{}; + + rmm::device_uvector clustering_v(num_vertices, handle.get_stream()); + size_t level; + weight_t modularity; + + std::tie(level, modularity) = cugraph::louvain( + handle, graph_view, edge_weight_view, clustering_v.data(), size_t{100}, weight_t{1}); + + RAFT_CUDA_TRY(cudaDeviceSynchronize()); // for consistent performance measurement + + float compare_modularity = static_cast(modularity); + + if (check_correctness) { + ASSERT_FLOAT_EQ(compare_modularity, expected_modularity); + ASSERT_EQ(level, expected_level); + } + } }; // FIXME: add tests for type combinations diff --git a/cpp/tests/community/mg_egonet_test.cu b/cpp/tests/community/mg_egonet_test.cu index 442fd9d5bae..460202cf4e3 100644 --- a/cpp/tests/community/mg_egonet_test.cu +++ b/cpp/tests/community/mg_egonet_test.cu @@ -71,7 +71,7 @@ class Tests_MGEgonet hr_clock.start(); } - auto [mg_graph, d_renumber_map_labels] = + auto [mg_graph, mg_edge_weights, d_renumber_map_labels] = cugraph::test::construct_graph( *handle_, input_usecase, egonet_usecase.test_weighted_, true); @@ -84,6 +84,8 @@ class Tests_MGEgonet } auto mg_graph_view = mg_graph.view(); + auto mg_edge_weight_view = + mg_edge_weights ? std::make_optional((*mg_edge_weights).view()) : std::nullopt; int my_rank = handle_->get_comms().get_rank(); @@ -129,6 +131,7 @@ class Tests_MGEgonet cugraph::extract_ego( *handle_, mg_graph_view, + mg_edge_weight_view, raft::device_span{d_ego_sources.data(), d_ego_sources.size()}, static_cast(egonet_usecase.radius_)); @@ -185,8 +188,12 @@ class Tests_MGEgonet d_ego_edgelist_offsets = cugraph::detail::compute_sparse_offsets( graph_ids_v.begin(), graph_ids_v.end(), size_t{0}, offsets_size - 1, handle_->get_stream()); - auto [sg_graph, sg_number_map] = cugraph::test::mg_graph_to_sg_graph( - *handle_, mg_graph_view, std::optional>{std::nullopt}, false); + auto [sg_graph, sg_edge_weights, sg_number_map] = cugraph::test::mg_graph_to_sg_graph( + *handle_, + mg_graph_view, + mg_edge_weight_view, + std::optional>{std::nullopt}, + false); d_ego_sources = cugraph::test::device_gatherv( *handle_, raft::device_span(d_ego_sources.data(), d_ego_sources.size())); @@ -196,6 +203,7 @@ class Tests_MGEgonet cugraph::extract_ego( *handle_, sg_graph.view(), + sg_edge_weights ? std::make_optional((*sg_edge_weights).view()) : std::nullopt, raft::device_span{d_ego_sources.data(), d_ego_sources.size()}, static_cast(egonet_usecase.radius_)); diff --git a/cpp/tests/community/mg_louvain_test.cpp b/cpp/tests/community/mg_louvain_test.cpp index b474f353f3b..6d8cdecbc1d 100644 --- a/cpp/tests/community/mg_louvain_test.cpp +++ b/cpp/tests/community/mg_louvain_test.cpp @@ -87,7 +87,10 @@ class Tests_MGLouvain int rank, weight_t mg_modularity) { - cugraph::graph_t sg_graph(handle); + cugraph::graph_t sg_graph(handle); + std::optional< + cugraph::edge_property_t, weight_t>> + sg_edge_weights{std::nullopt}; rmm::device_uvector d_clustering_v(0, handle_->get_stream()); weight_t sg_modularity{-1.0}; @@ -106,7 +109,7 @@ class Tests_MGLouvain cugraph::test::single_gpu_renumber_edgelist_given_number_map( handle, d_edgelist_srcs, d_edgelist_dsts, d_renumber_map_gathered_v); - std::tie(sg_graph, std::ignore, std::ignore) = + std::tie(sg_graph, sg_edge_weights, std::ignore, std::ignore) = cugraph::create_graph_from_edgelist( handle, std::move(d_vertices), @@ -121,25 +124,37 @@ class Tests_MGLouvain std::for_each( thrust::make_counting_iterator(0), thrust::make_counting_iterator(dendrogram.num_levels()), - [&dendrogram, &sg_graph, &d_clustering_v, &sg_modularity, &handle, resolution, rank]( - size_t i) { + [&dendrogram, + &sg_graph, + &sg_edge_weights, + &d_clustering_v, + &sg_modularity, + &handle, + resolution, + rank](size_t i) { auto d_dendrogram_gathered_v = cugraph::test::device_gatherv( handle, dendrogram.get_level_ptr_nocheck(i), dendrogram.get_level_size_nocheck(i)); if (rank == 0) { - auto graph_view = sg_graph.view(); + auto sg_graph_view = sg_graph.view(); + auto sg_edge_weight_view = + sg_edge_weights ? std::make_optional((*sg_edge_weights).view()) : std::nullopt; - d_clustering_v.resize(graph_view.number_of_vertices(), handle_->get_stream()); + d_clustering_v.resize(sg_graph_view.number_of_vertices(), handle_->get_stream()); - std::tie(std::ignore, sg_modularity) = - cugraph::louvain(handle, graph_view, d_clustering_v.data(), size_t{1}, resolution); + std::tie(std::ignore, sg_modularity) = cugraph::louvain(handle, + sg_graph_view, + sg_edge_weight_view, + d_clustering_v.data(), + size_t{1}, + resolution); EXPECT_TRUE( cugraph::test::renumbered_vectors_same(handle, d_clustering_v, d_dendrogram_gathered_v)) << "(i = " << i << "), sg_modularity = " << sg_modularity; - std::tie(sg_graph, std::ignore) = - cugraph::coarsen_graph(handle, graph_view, d_dendrogram_gathered_v.data(), false); + std::tie(sg_graph, sg_edge_weights, std::ignore) = cugraph::coarsen_graph( + handle, sg_graph_view, sg_edge_weight_view, d_dendrogram_gathered_v.data(), false); } }); @@ -164,7 +179,7 @@ class Tests_MGLouvain hr_clock.start(); } - auto [mg_graph, d_renumber_map_labels] = + auto [mg_graph, mg_edge_weights, d_renumber_map_labels] = cugraph::test::construct_graph( *handle_, input_usecase, true, true); @@ -177,6 +192,8 @@ class Tests_MGLouvain } auto mg_graph_view = mg_graph.view(); + auto mg_edge_weight_view = + mg_edge_weights ? std::make_optional((*mg_edge_weights).view()) : std::nullopt; if (cugraph::test::g_perf) { RAFT_CUDA_TRY(cudaDeviceSynchronize()); // for consistent performance measurement @@ -184,8 +201,12 @@ class Tests_MGLouvain hr_clock.start(); } - auto [dendrogram, mg_modularity] = cugraph::louvain( - *handle_, mg_graph_view, louvain_usecase.max_level_, louvain_usecase.resolution_); + auto [dendrogram, mg_modularity] = + cugraph::louvain(*handle_, + mg_graph_view, + mg_edge_weight_view, + louvain_usecase.max_level_, + louvain_usecase.resolution_); if (cugraph::test::g_perf) { RAFT_CUDA_TRY(cudaDeviceSynchronize()); // for consistent performance measurement diff --git a/cpp/tests/community/mg_triangle_count_test.cpp b/cpp/tests/community/mg_triangle_count_test.cpp index 75f749a9649..f02b5b20ced 100644 --- a/cpp/tests/community/mg_triangle_count_test.cpp +++ b/cpp/tests/community/mg_triangle_count_test.cpp @@ -73,7 +73,9 @@ class Tests_MGTriangleCount hr_clock.start(); } - auto [mg_graph, d_mg_renumber_map_labels] = + cugraph::graph_t mg_graph(*handle_); + std::optional> d_mg_renumber_map_labels{std::nullopt}; + std::tie(mg_graph, std::ignore, d_mg_renumber_map_labels) = cugraph::test::construct_graph( *handle_, input_usecase, false, true, false, true); @@ -130,7 +132,7 @@ class Tests_MGTriangleCount hr_clock.start(); } - cugraph::triangle_count( + cugraph::triangle_count( *handle_, mg_graph_view, d_mg_vertices ? std::make_optional>( @@ -181,8 +183,8 @@ class Tests_MGTriangleCount // 4-3. create SG graph - cugraph::graph_t sg_graph(*handle_); - std::tie(sg_graph, std::ignore) = + cugraph::graph_t sg_graph(*handle_); + std::tie(sg_graph, std::ignore, std::ignore) = cugraph::test::construct_graph( *handle_, input_usecase, false, false, false, true); @@ -197,7 +199,7 @@ class Tests_MGTriangleCount : sg_graph_view.number_of_vertices(), handle_->get_stream()); - cugraph::triangle_count( + cugraph::triangle_count( *handle_, sg_graph_view, d_mg_aggregate_vertices diff --git a/cpp/tests/community/triangle_count_test.cpp b/cpp/tests/community/triangle_count_test.cpp index 703f605dd44..ff5e0d70093 100644 --- a/cpp/tests/community/triangle_count_test.cpp +++ b/cpp/tests/community/triangle_count_test.cpp @@ -123,7 +123,9 @@ class Tests_TriangleCount hr_clock.start(); } - auto [graph, d_renumber_map_labels] = + cugraph::graph_t graph(handle); + std::optional> d_renumber_map_labels{std::nullopt}; + std::tie(graph, std::ignore, d_renumber_map_labels) = cugraph::test::construct_graph( handle, input_usecase, false, renumber, false, true); @@ -170,7 +172,7 @@ class Tests_TriangleCount hr_clock.start(); } - cugraph::triangle_count( + cugraph::triangle_count( handle, graph_view, d_vertices ? std::make_optional>((*d_vertices).begin(), @@ -187,9 +189,9 @@ class Tests_TriangleCount } if (triangle_count_usecase.check_correctness) { - cugraph::graph_t unrenumbered_graph(handle); + cugraph::graph_t unrenumbered_graph(handle); if (renumber) { - std::tie(unrenumbered_graph, std::ignore) = + std::tie(unrenumbered_graph, std::ignore, std::ignore) = cugraph::test::construct_graph( handle, input_usecase, false, false, false, true); } diff --git a/cpp/tests/components/mg_weakly_connected_components_test.cpp b/cpp/tests/components/mg_weakly_connected_components_test.cpp index 3983bc09fc1..369eb103ff5 100644 --- a/cpp/tests/components/mg_weakly_connected_components_test.cpp +++ b/cpp/tests/components/mg_weakly_connected_components_test.cpp @@ -72,7 +72,9 @@ class Tests_MGWeaklyConnectedComponents hr_clock.start(); } - auto [mg_graph, d_mg_renumber_map_labels] = + cugraph::graph_t mg_graph(*handle_); + std::optional> d_mg_renumber_map_labels{std::nullopt}; + std::tie(mg_graph, std::ignore, d_mg_renumber_map_labels) = cugraph::test::construct_graph( *handle_, input_usecase, false, true); @@ -125,8 +127,8 @@ class Tests_MGWeaklyConnectedComponents // 3-3. create SG graph - cugraph::graph_t sg_graph(*handle_); - std::tie(sg_graph, std::ignore) = + cugraph::graph_t sg_graph(*handle_); + std::tie(sg_graph, std::ignore, std::ignore) = cugraph::test::construct_graph( *handle_, input_usecase, false, false); diff --git a/cpp/tests/components/wcc_graphs.cu b/cpp/tests/components/wcc_graphs.cu deleted file mode 100644 index 3c48fa9825f..00000000000 --- a/cpp/tests/components/wcc_graphs.cu +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (c) 2021-2022, NVIDIA CORPORATION. All rights reserved. - * - * NVIDIA CORPORATION and its licensors retain all intellectual property - * and proprietary rights in and to this software, related documentation - * and any modifications thereto. Any use, reproduction, disclosure or - * distribution of this software and related documentation without an express - * license agreement from NVIDIA CORPORATION is strictly prohibited. - * - */ - -#include -#include - -#include -#include - -#include - -#include -#include - -namespace cugraph { -namespace test { - -template -std::tuple, - std::optional>> -LineGraph_Usecase::construct_graph(raft::handle_t const& handle, - bool test_weighted, - bool renumber) const -{ - uint64_t seed{0}; - - edge_t num_edges = 2 * (num_vertices_ - 1); - - rmm::device_uvector vertices_v(num_vertices_, handle.get_stream()); - rmm::device_uvector src_v(num_edges, handle.get_stream()); - rmm::device_uvector dst_v(num_edges, handle.get_stream()); - rmm::device_uvector order_v(num_vertices_, handle.get_stream()); - - auto execution_policy = handle.get_thrust_policy(); - thrust::sequence(execution_policy, vertices_v.begin(), vertices_v.end(), vertex_t{0}); - - cugraph::detail::uniform_random_fill( - handle.get_stream(), order_v.data(), num_vertices_, double{0.0}, double{1.0}, seed); - - thrust::sort_by_key(execution_policy, order_v.begin(), order_v.end(), vertices_v.begin()); - - raft::copy(src_v.begin(), vertices_v.begin(), (num_vertices_ - 1), handle.get_stream()); - raft::copy(dst_v.begin(), vertices_v.begin() + 1, (num_vertices_ - 1), handle.get_stream()); - - raft::copy(src_v.begin() + (num_vertices_ - 1), - vertices_v.begin() + 1, - (num_vertices_ - 1), - handle.get_stream()); - raft::copy(dst_v.begin() + (num_vertices_ - 1), - vertices_v.begin(), - (num_vertices_ - 1), - handle.get_stream()); - - thrust::sequence(execution_policy, vertices_v.begin(), vertices_v.end(), vertex_t{0}); - - handle.sync_stream(); - - graph_t graph(handle); - std::optional> renumber_map{std::nullopt}; - std::tie(graph, std::ignore, renumber_map) = cugraph:: - create_graph_from_edgelist( - handle, - std::move(vertices_v), - std::move(src_v), - std::move(dst_v), - std::nullopt, - std::nullopt, - cugraph::graph_properties_t{true, false}, - false); - - return std::make_tuple(std::move(graph), std::move(renumber_map)); -} - -template std::tuple, - std::optional>> -LineGraph_Usecase::construct_graph(raft::handle_t const&, bool, bool) const; - -} // namespace test -} // namespace cugraph diff --git a/cpp/tests/components/wcc_graphs.hpp b/cpp/tests/components/wcc_graphs.hpp deleted file mode 100644 index 4746672c2b2..00000000000 --- a/cpp/tests/components/wcc_graphs.hpp +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2021, NVIDIA CORPORATION. All rights reserved. - * - * NVIDIA CORPORATION and its licensors retain all intellectual property - * and proprietary rights in and to this software, related documentation - * and any modifications thereto. Any use, reproduction, disclosure or - * distribution of this software and related documentation without an express - * license agreement from NVIDIA CORPORATION is strictly prohibited. - * - */ - -#include - -#include - -namespace cugraph { -namespace test { - -class LineGraph_Usecase { - public: - LineGraph_Usecase() = delete; - - LineGraph_Usecase(size_t num_vertices) : num_vertices_(num_vertices) {} - - template - std::tuple, - std::optional>> - construct_graph(raft::handle_t const& handle, bool test_weighted, bool renumber = true) const; - - private: - size_t num_vertices_{0}; -}; - -} // namespace test -} // namespace cugraph diff --git a/cpp/tests/components/weakly_connected_components_test.cpp b/cpp/tests/components/weakly_connected_components_test.cpp index b3f085e1b74..0f6c14530ad 100644 --- a/cpp/tests/components/weakly_connected_components_test.cpp +++ b/cpp/tests/components/weakly_connected_components_test.cpp @@ -112,7 +112,9 @@ class Tests_WeaklyConnectedComponent hr_clock.start(); } - auto [graph, d_renumber_map_labels] = + cugraph::graph_t graph(handle); + std::optional> d_renumber_map_labels{std::nullopt}; + std::tie(graph, std::ignore, d_renumber_map_labels) = cugraph::test::construct_graph( handle, input_usecase, false, renumber); @@ -145,9 +147,9 @@ class Tests_WeaklyConnectedComponent } if (weakly_connected_components_usecase.check_correctness) { - cugraph::graph_t unrenumbered_graph(handle); + cugraph::graph_t unrenumbered_graph(handle); if (renumber) { - std::tie(unrenumbered_graph, std::ignore) = + std::tie(unrenumbered_graph, std::ignore, std::ignore) = cugraph::test::construct_graph( handle, input_usecase, false, false); } diff --git a/cpp/tests/cores/core_number_test.cpp b/cpp/tests/cores/core_number_test.cpp index 7bccc216ce5..86186fde902 100644 --- a/cpp/tests/cores/core_number_test.cpp +++ b/cpp/tests/cores/core_number_test.cpp @@ -228,7 +228,9 @@ class Tests_CoreNumber hr_clock.start(); } - auto [graph, d_renumber_map_labels] = + cugraph::graph_t graph(handle); + std::optional> d_renumber_map_labels{std::nullopt}; + std::tie(graph, std::ignore, d_renumber_map_labels) = cugraph::test::construct_graph( handle, input_usecase, false, renumber, true, true); @@ -266,9 +268,9 @@ class Tests_CoreNumber } if (core_number_usecase.check_correctness) { - cugraph::graph_t unrenumbered_graph(handle); + cugraph::graph_t unrenumbered_graph(handle); if (renumber) { - std::tie(unrenumbered_graph, std::ignore) = + std::tie(unrenumbered_graph, std::ignore, std::ignore) = cugraph::test::construct_graph( handle, input_usecase, true, false, true, true); } diff --git a/cpp/tests/cores/k_core_test.cpp b/cpp/tests/cores/k_core_test.cpp index 08ec554fd1b..93fc8acfe65 100644 --- a/cpp/tests/cores/k_core_test.cpp +++ b/cpp/tests/cores/k_core_test.cpp @@ -115,7 +115,7 @@ class Tests_KCore : public ::testing::TestWithParam( handle, input_usecase, false, renumber, true, true); @@ -126,6 +126,8 @@ class Tests_KCore : public ::testing::TestWithParam d_core_numbers(graph_view.number_of_vertices(), handle.get_stream()); @@ -146,12 +148,15 @@ class Tests_KCore : public ::testing::TestWithParam mg_graph(*handle_); + std::optional> d_mg_renumber_map_labels{std::nullopt}; + std::tie(mg_graph, std::ignore, d_mg_renumber_map_labels) = cugraph::test::construct_graph( *handle_, input_usecase, false, true, true, true); @@ -135,8 +137,8 @@ class Tests_MGCoreNumber // 3-3. create SG graph - cugraph::graph_t sg_graph(*handle_); - std::tie(sg_graph, std::ignore) = + cugraph::graph_t sg_graph(*handle_); + std::tie(sg_graph, std::ignore, std::ignore) = cugraph::test::construct_graph( *handle_, input_usecase, false, false, true, true); diff --git a/cpp/tests/cores/mg_k_core_test.cpp b/cpp/tests/cores/mg_k_core_test.cpp index b4cae7b830d..b86f6a6cda5 100644 --- a/cpp/tests/cores/mg_k_core_test.cpp +++ b/cpp/tests/cores/mg_k_core_test.cpp @@ -89,12 +89,13 @@ struct KCore_Usecase { }; template -class Tests_KCore : public ::testing::TestWithParam> { +class Tests_MGKCore : public ::testing::TestWithParam> { public: - Tests_KCore() {} + Tests_MGKCore() {} - static void SetUpTestCase() {} - static void TearDownTestCase() {} + static void SetUpTestCase() { handle_ = cugraph::test::initialize_mg_handle(); } + + static void TearDownTestCase() { handle_.reset(); } virtual void SetUp() {} virtual void TearDown() {} @@ -107,7 +108,6 @@ class Tests_KCore : public ::testing::TestWithParam( - handle, input_usecase, false, renumber, true, true); + *handle_, input_usecase, false, renumber, true, true); if (cugraph::test::g_perf) { RAFT_CUDA_TRY(cudaDeviceSynchronize()); // for consistent performance measurement @@ -125,13 +125,16 @@ class Tests_KCore : public ::testing::TestWithParam d_core_numbers(graph_view.number_of_vertices(), - handle.get_stream()); + auto sg_graph_view = sg_graph.view(); + auto sg_edge_weight_view = + sg_edge_weights ? std::make_optional((*sg_edge_weights).view()) : std::nullopt; + + rmm::device_uvector d_core_numbers(sg_graph_view.number_of_vertices(), + handle_->get_stream()); - cugraph::core_number(handle, - graph_view, + cugraph::core_number(*handle_, + sg_graph_view, d_core_numbers.data(), k_core_usecase.degree_type, k_core_usecase.k, @@ -146,12 +149,15 @@ class Tests_KCore : public ::testing::TestWithParam handle_; }; -using Tests_KCore_File = Tests_KCore; -using Tests_KCore_Rmat = Tests_KCore; +template +std::unique_ptr Tests_MGKCore::handle_ = nullptr; + +using Tests_MGKCore_File = Tests_MGKCore; +using Tests_MGKCore_Rmat = Tests_MGKCore; -TEST_P(Tests_KCore_File, CheckInt32Int32) +TEST_P(Tests_MGKCore_File, CheckInt32Int32) { run_current_test(override_File_Usecase_with_cmd_line_arguments(GetParam())); } -TEST_P(Tests_KCore_Rmat, CheckInt32Int32) +TEST_P(Tests_MGKCore_Rmat, CheckInt32Int32) { run_current_test(override_Rmat_Usecase_with_cmd_line_arguments(GetParam())); } -TEST_P(Tests_KCore_Rmat, CheckInt32Int64) +TEST_P(Tests_MGKCore_Rmat, CheckInt32Int64) { run_current_test(override_Rmat_Usecase_with_cmd_line_arguments(GetParam())); } -TEST_P(Tests_KCore_Rmat, CheckInt64Int64) +TEST_P(Tests_MGKCore_Rmat, CheckInt64Int64) { run_current_test(override_Rmat_Usecase_with_cmd_line_arguments(GetParam())); } INSTANTIATE_TEST_SUITE_P( file_test, - Tests_KCore_File, + Tests_MGKCore_File, ::testing::Combine( // enable correctness checks testing::Values(KCore_Usecase{3, cugraph::k_core_degree_type_t::IN}, @@ -206,7 +218,7 @@ INSTANTIATE_TEST_SUITE_P( INSTANTIATE_TEST_SUITE_P( rmat_small_test, - Tests_KCore_Rmat, + Tests_MGKCore_Rmat, ::testing::Combine( // enable correctness checks testing::Values(KCore_Usecase{3, cugraph::k_core_degree_type_t::IN}, @@ -220,10 +232,10 @@ INSTANTIATE_TEST_SUITE_P( vertex & edge type combination) by command line arguments and do not include more than one Rmat_Usecase that differ only in scale or edge factor (to avoid running same benchmarks more than once) */ - Tests_KCore_Rmat, + Tests_MGKCore_Rmat, ::testing::Combine( // disable correctness checks for large graphs testing::Values(KCore_Usecase{3, cugraph::k_core_degree_type_t::OUT, false}), testing::Values(cugraph::test::Rmat_Usecase(20, 32, 0.57, 0.19, 0.19, 0, true, false)))); -CUGRAPH_TEST_PROGRAM_MAIN() +CUGRAPH_MG_TEST_PROGRAM_MAIN() diff --git a/cpp/tests/link_analysis/hits_test.cpp b/cpp/tests/link_analysis/hits_test.cpp index fcbe00ba7cd..5c40f77f57b 100644 --- a/cpp/tests/link_analysis/hits_test.cpp +++ b/cpp/tests/link_analysis/hits_test.cpp @@ -160,7 +160,9 @@ class Tests_Hits : public ::testing::TestWithParam graph(handle); + std::optional> d_renumber_map_labels{std::nullopt}; + std::tie(graph, std::ignore, d_renumber_map_labels) = cugraph::test::construct_graph( handle, input_usecase, false, renumber); @@ -214,8 +216,8 @@ class Tests_Hits : public ::testing::TestWithParam unrenumbered_graph(handle); - std::tie(unrenumbered_graph, std::ignore) = + cugraph::graph_t unrenumbered_graph(handle); + std::tie(unrenumbered_graph, std::ignore, std::ignore) = cugraph::test::construct_graph( handle, input_usecase, false, false); auto unrenumbered_graph_view = unrenumbered_graph.view(); diff --git a/cpp/tests/link_analysis/mg_hits_test.cpp b/cpp/tests/link_analysis/mg_hits_test.cpp index 59d2998701d..48fe90536eb 100644 --- a/cpp/tests/link_analysis/mg_hits_test.cpp +++ b/cpp/tests/link_analysis/mg_hits_test.cpp @@ -64,7 +64,9 @@ class Tests_MGHits : public ::testing::TestWithParam mg_graph(*handle_); + std::optional> d_mg_renumber_map_labels{std::nullopt}; + std::tie(mg_graph, std::ignore, d_mg_renumber_map_labels) = cugraph::test::construct_graph( *handle_, input_usecase, false, true); @@ -78,7 +80,8 @@ class Tests_MGHits : public ::testing::TestWithParam d_mg_hubs(mg_graph_view.local_vertex_partition_range_size(), @@ -158,8 +161,8 @@ class Tests_MGHits : public ::testing::TestWithParam sg_graph(*handle_); - std::tie(sg_graph, std::ignore) = + cugraph::graph_t sg_graph(*handle_); + std::tie(sg_graph, std::ignore, std::ignore) = cugraph::test::construct_graph( *handle_, input_usecase, false, false); diff --git a/cpp/tests/link_analysis/mg_pagerank_test.cpp b/cpp/tests/link_analysis/mg_pagerank_test.cpp index 797e8fa9709..f4cd974c8e9 100644 --- a/cpp/tests/link_analysis/mg_pagerank_test.cpp +++ b/cpp/tests/link_analysis/mg_pagerank_test.cpp @@ -69,7 +69,7 @@ class Tests_MGPageRank hr_clock.start(); } - auto [mg_graph, d_mg_renumber_map_labels] = + auto [mg_graph, mg_edge_weights, d_mg_renumber_map_labels] = cugraph::test::construct_graph( *handle_, input_usecase, pagerank_usecase.test_weighted, true); @@ -82,6 +82,8 @@ class Tests_MGPageRank } auto mg_graph_view = mg_graph.view(); + auto mg_edge_weight_view = + mg_edge_weights ? std::make_optional((*mg_edge_weights).view()) : std::nullopt; // 2. generate personalization vertex/value pairs @@ -148,6 +150,7 @@ class Tests_MGPageRank cugraph::pagerank( *handle_, mg_graph_view, + mg_edge_weight_view, std::nullopt, d_mg_personalization_vertices ? std::optional{(*d_mg_personalization_vertices).data()} @@ -216,12 +219,17 @@ class Tests_MGPageRank // 4-3. create SG graph - cugraph::graph_t sg_graph(*handle_); - std::tie(sg_graph, std::ignore) = + cugraph::graph_t sg_graph(*handle_); + std::optional< + cugraph::edge_property_t, weight_t>> + sg_edge_weights{std::nullopt}; + std::tie(sg_graph, sg_edge_weights, std::ignore) = cugraph::test::construct_graph( *handle_, input_usecase, pagerank_usecase.test_weighted, false); auto sg_graph_view = sg_graph.view(); + auto sg_edge_weight_view = + sg_edge_weights ? std::make_optional((*sg_edge_weights).view()) : std::nullopt; ASSERT_EQ(mg_graph_view.number_of_vertices(), sg_graph_view.number_of_vertices()); @@ -233,6 +241,7 @@ class Tests_MGPageRank cugraph::pagerank( *handle_, sg_graph_view, + sg_edge_weight_view, std::nullopt, d_mg_aggregate_personalization_vertices ? std::optional{(*d_mg_aggregate_personalization_vertices).data()} diff --git a/cpp/tests/link_analysis/pagerank_test.cpp b/cpp/tests/link_analysis/pagerank_test.cpp index fa961cfa34c..2dfe52e17a3 100644 --- a/cpp/tests/link_analysis/pagerank_test.cpp +++ b/cpp/tests/link_analysis/pagerank_test.cpp @@ -161,7 +161,7 @@ class Tests_PageRank hr_clock.start(); } - auto [graph, d_renumber_map_labels] = + auto [graph, edge_weights, d_renumber_map_labels] = cugraph::test::construct_graph( handle, input_usecase, pagerank_usecase.test_weighted, renumber); @@ -173,6 +173,8 @@ class Tests_PageRank } auto graph_view = graph.view(); + auto edge_weight_view = + edge_weights ? std::make_optional((*edge_weights).view()) : std::nullopt; std::optional> h_personalization_vertices{std::nullopt}; std::optional> h_personalization_values{std::nullopt}; @@ -238,6 +240,7 @@ class Tests_PageRank cugraph::pagerank( handle, graph_view, + edge_weight_view, std::nullopt, d_personalization_vertices ? std::optional{(*d_personalization_vertices).data()} @@ -261,20 +264,32 @@ class Tests_PageRank } if (pagerank_usecase.check_correctness) { - cugraph::graph_t unrenumbered_graph(handle); + cugraph::graph_t unrenumbered_graph(handle); + std::optional< + cugraph::edge_property_t, weight_t>> + unrenumbered_edge_weights{std::nullopt}; if (renumber) { - std::tie(unrenumbered_graph, std::ignore) = + std::tie(unrenumbered_graph, unrenumbered_edge_weights, std::ignore) = cugraph::test::construct_graph( handle, input_usecase, pagerank_usecase.test_weighted, false); } auto unrenumbered_graph_view = renumber ? unrenumbered_graph.view() : graph_view; + auto unrenumbered_edge_weight_view = + renumber + ? (unrenumbered_edge_weights ? std::make_optional((*unrenumbered_edge_weights).view()) + : std::nullopt) + : edge_weight_view; auto h_offsets = cugraph::test::to_host( handle, unrenumbered_graph_view.local_edge_partition_view().offsets()); auto h_indices = cugraph::test::to_host( handle, unrenumbered_graph_view.local_edge_partition_view().indices()); auto h_weights = cugraph::test::to_host( - handle, unrenumbered_graph_view.local_edge_partition_view().weights()); + handle, + unrenumbered_edge_weights ? std::make_optional>( + (*unrenumbered_edge_weights).view().value_firsts()[0], + (*unrenumbered_edge_weights).view().edge_counts()[0]) + : std::nullopt); std::optional> h_unrenumbered_personalization_vertices{std::nullopt}; std::optional> h_unrenumbered_personalization_values{std::nullopt}; diff --git a/cpp/tests/link_prediction/mg_similarity_test.cpp b/cpp/tests/link_prediction/mg_similarity_test.cpp index ac6c98a5d19..bbfdec85ce9 100644 --- a/cpp/tests/link_prediction/mg_similarity_test.cpp +++ b/cpp/tests/link_prediction/mg_similarity_test.cpp @@ -62,7 +62,7 @@ class Tests_MGSimilarity hr_clock.start(); } - auto [mg_graph, d_mg_renumber_map_labels] = + auto [mg_graph, mg_edge_weights, d_mg_renumber_map_labels] = cugraph::test::construct_graph( *handle_, input_usecase, false, true); @@ -77,6 +77,8 @@ class Tests_MGSimilarity // 2. run similarity auto mg_graph_view = mg_graph.view(); + auto mg_edge_weight_view = + mg_edge_weights ? std::make_optional((*mg_edge_weights).view()) : std::nullopt; if (cugraph::test::g_perf) { RAFT_CUDA_TRY(cudaDeviceSynchronize()); // for consistent performance measurement @@ -93,7 +95,8 @@ class Tests_MGSimilarity rmm::device_uvector d_v2(0, handle_->get_stream()); if (handle_->get_comms().get_rank() == 0) { - auto [src, dst, wgt] = cugraph::test::graph_to_host_coo(*handle_, mg_graph_view); + auto [src, dst, wgt] = + cugraph::test::graph_to_host_coo(*handle_, mg_graph_view, mg_edge_weight_view); size_t max_vertices = std::min(static_cast(mg_graph_view.number_of_vertices()), similarity_usecase.max_seeds); @@ -158,8 +161,8 @@ class Tests_MGSimilarity std::tuple, raft::device_span> vertex_pairs{ {d_v1.data(), d_v1.size()}, {d_v2.data(), d_v2.size()}}; - auto result_score = - test_functor.run(*handle_, mg_graph_view, vertex_pairs, similarity_usecase.use_weights); + auto result_score = test_functor.run( + *handle_, mg_graph_view, mg_edge_weight_view, vertex_pairs, similarity_usecase.use_weights); if (cugraph::test::g_perf) { RAFT_CUDA_TRY(cudaDeviceSynchronize()); // for consistent performance measurement @@ -172,7 +175,8 @@ class Tests_MGSimilarity // 3. compare SG & MG results if (similarity_usecase.check_correctness) { - auto [src, dst, wgt] = cugraph::test::graph_to_host_coo(*handle_, mg_graph_view); + auto [src, dst, wgt] = + cugraph::test::graph_to_host_coo(*handle_, mg_graph_view, mg_edge_weight_view); d_v1 = cugraph::test::device_gatherv(*handle_, d_v1.data(), d_v1.size()); d_v2 = cugraph::test::device_gatherv(*handle_, d_v2.data(), d_v2.size()); diff --git a/cpp/tests/link_prediction/similarity_compare.hpp b/cpp/tests/link_prediction/similarity_compare.hpp index cc3044bf47e..b3b7f7e94c9 100644 --- a/cpp/tests/link_prediction/similarity_compare.hpp +++ b/cpp/tests/link_prediction/similarity_compare.hpp @@ -35,14 +35,15 @@ struct test_jaccard_t { static_cast(u_size + v_size - intersection_count); } - template - auto run(raft::handle_t const& handle, - graph_view_t const& graph_view, - std::tuple, - raft::device_span> vertex_pairs, - bool use_weights) const + template + auto run( + raft::handle_t const& handle, + graph_view_t const& graph_view, + std::optional> edge_weight_view, + std::tuple, raft::device_span> vertex_pairs, + bool use_weights) const { - return cugraph::jaccard_coefficients(handle, graph_view, vertex_pairs, use_weights); + return cugraph::jaccard_coefficients(handle, graph_view, edge_weight_view, vertex_pairs); } }; @@ -55,14 +56,15 @@ struct test_sorensen_t { return static_cast(2 * intersection_count) / static_cast(u_size + v_size); } - template - auto run(raft::handle_t const& handle, - graph_view_t const& graph_view, - std::tuple, - raft::device_span> vertex_pairs, - bool use_weights) const + template + auto run( + raft::handle_t const& handle, + graph_view_t const& graph_view, + std::optional> edge_weight_view, + std::tuple, raft::device_span> vertex_pairs, + bool use_weights) const { - return cugraph::sorensen_coefficients(handle, graph_view, vertex_pairs, use_weights); + return cugraph::sorensen_coefficients(handle, graph_view, edge_weight_view, vertex_pairs); } }; @@ -76,14 +78,15 @@ struct test_overlap_t { static_cast(std::min(u_size, v_size)); } - template - auto run(raft::handle_t const& handle, - graph_view_t const& graph_view, - std::tuple, - raft::device_span> vertex_pairs, - bool use_weights) const + template + auto run( + raft::handle_t const& handle, + graph_view_t const& graph_view, + std::optional> edge_weight_view, + std::tuple, raft::device_span> vertex_pairs, + bool use_weights) const { - return cugraph::overlap_coefficients(handle, graph_view, vertex_pairs, use_weights); + return cugraph::overlap_coefficients(handle, graph_view, edge_weight_view, vertex_pairs); } }; diff --git a/cpp/tests/link_prediction/similarity_test.cpp b/cpp/tests/link_prediction/similarity_test.cpp index b8db9468b05..0fe7397a061 100644 --- a/cpp/tests/link_prediction/similarity_test.cpp +++ b/cpp/tests/link_prediction/similarity_test.cpp @@ -64,9 +64,9 @@ class Tests_Similarity hr_clock.start(); } - auto [graph, d_renumber_map_labels] = + auto [graph, edge_weights, d_renumber_map_labels] = cugraph::test::construct_graph( - handle, input_usecase, true, renumber); + handle, input_usecase, similarity_usecase.use_weights, renumber); if (cugraph::test::g_perf) { RAFT_CUDA_TRY(cudaDeviceSynchronize()); // for consistent performance measurement @@ -78,6 +78,8 @@ class Tests_Similarity // 3. run similarity auto graph_view = graph.view(); + auto edge_weight_view = + edge_weights ? std::make_optional((*edge_weights).view()) : std::nullopt; if (cugraph::test::g_perf) { RAFT_CUDA_TRY(cudaDeviceSynchronize()); // for consistent performance measurement @@ -93,7 +95,7 @@ class Tests_Similarity rmm::device_uvector d_v2(0, handle.get_stream()); { - auto [src, dst, wgt] = cugraph::test::graph_to_host_coo(handle, graph_view); + auto [src, dst, wgt] = cugraph::test::graph_to_host_coo(handle, graph_view, edge_weight_view); size_t max_vertices = std::min(static_cast(graph_view.number_of_vertices()), similarity_usecase.max_seeds); @@ -163,8 +165,8 @@ class Tests_Similarity std::tuple, raft::device_span> vertex_pairs{ {d_v1.data(), d_v1.size()}, {d_v2.data(), d_v2.size()}}; - auto result_score = - test_functor.run(handle, graph_view, vertex_pairs, similarity_usecase.use_weights); + auto result_score = test_functor.run( + handle, graph_view, edge_weight_view, vertex_pairs, similarity_usecase.use_weights); if (cugraph::test::g_perf) { RAFT_CUDA_TRY(cudaDeviceSynchronize()); // for consistent performance measurement @@ -174,7 +176,7 @@ class Tests_Similarity } if (similarity_usecase.check_correctness) { - auto [src, dst, wgt] = cugraph::test::graph_to_host_coo(handle, graph_view); + auto [src, dst, wgt] = cugraph::test::graph_to_host_coo(handle, graph_view, edge_weight_view); size_t check_size = std::min(d_v1.size(), similarity_usecase.max_vertex_pairs_to_check); diff --git a/cpp/tests/prims/mg_count_if_e.cu b/cpp/tests/prims/mg_count_if_e.cu index 5c96570c7d2..d397ab6d1be 100644 --- a/cpp/tests/prims/mg_count_if_e.cu +++ b/cpp/tests/prims/mg_count_if_e.cu @@ -87,7 +87,9 @@ class Tests_MGCountIfE handle_->get_comms().barrier(); hr_clock.start(); } - auto [mg_graph, d_mg_renumber_map_labels] = + cugraph::graph_t mg_graph(*handle_); + std::optional> d_mg_renumber_map_labels{std::nullopt}; + std::tie(mg_graph, std::ignore, d_mg_renumber_map_labels) = cugraph::test::construct_graph( *handle_, input_usecase, prims_usecase.test_weighted, true); @@ -123,7 +125,8 @@ class Tests_MGCountIfE mg_graph_view, mg_src_prop.view(), mg_dst_prop.view(), - [] __device__(auto row, auto col, weight_t wt, auto src_property, auto dst_property) { + cugraph::edge_dummy_property_t{}.view(), + [] __device__(auto row, auto col, auto src_property, auto dst_property, thrust::nullopt_t) { return src_property < dst_property; }); @@ -138,8 +141,8 @@ class Tests_MGCountIfE // 3. compare SG & MG results if (prims_usecase.check_correctness) { - cugraph::graph_t sg_graph(*handle_); - std::tie(sg_graph, std::ignore) = + cugraph::graph_t sg_graph(*handle_); + std::tie(sg_graph, std::ignore, std::ignore) = cugraph::test::construct_graph( *handle_, input_usecase, prims_usecase.test_weighted, false); auto sg_graph_view = sg_graph.view(); @@ -159,7 +162,8 @@ class Tests_MGCountIfE sg_graph_view, sg_src_prop.view(), sg_dst_prop.view(), - [] __device__(auto row, auto col, weight_t wt, auto src_property, auto dst_property) { + cugraph::edge_dummy_property_t{}.view(), + [] __device__(auto row, auto col, auto src_property, auto dst_property, thrust::nullopt_t) { return src_property < dst_property; }); ASSERT_TRUE(expected_result == result); diff --git a/cpp/tests/prims/mg_count_if_v.cu b/cpp/tests/prims/mg_count_if_v.cu index d5fd08ebdba..f06e62524c3 100644 --- a/cpp/tests/prims/mg_count_if_v.cu +++ b/cpp/tests/prims/mg_count_if_v.cu @@ -83,7 +83,9 @@ class Tests_MGCountIfV handle_->get_comms().barrier(); hr_clock.start(); } - auto [mg_graph, d_mg_renumber_map_labels] = + cugraph::graph_t mg_graph(*handle_); + std::optional> d_mg_renumber_map_labels{std::nullopt}; + std::tie(mg_graph, std::ignore, d_mg_renumber_map_labels) = cugraph::test::construct_graph( *handle_, input_usecase, true, true); @@ -122,8 +124,8 @@ class Tests_MGCountIfV // 3. compare SG & MG results if (prims_usecase.check_correctness) { - cugraph::graph_t sg_graph(*handle_); - std::tie(sg_graph, std::ignore) = + cugraph::graph_t sg_graph(*handle_); + std::tie(sg_graph, std::ignore, std::ignore) = cugraph::test::construct_graph( *handle_, input_usecase, true, false); auto sg_graph_view = sg_graph.view(); diff --git a/cpp/tests/prims/mg_extract_if_e.cu b/cpp/tests/prims/mg_extract_if_e.cu index 47ae30537bb..92d5f5e29a3 100644 --- a/cpp/tests/prims/mg_extract_if_e.cu +++ b/cpp/tests/prims/mg_extract_if_e.cu @@ -129,7 +129,9 @@ class Tests_MGExtractIfE hr_clock.start(); } - auto [mg_graph, d_mg_renumber_map_labels] = + cugraph::graph_t mg_graph(*handle_); + std::optional> d_mg_renumber_map_labels{std::nullopt}; + std::tie(mg_graph, std::ignore, d_mg_renumber_map_labels) = cugraph::test::construct_graph( *handle_, input_usecase, true, true); @@ -160,14 +162,14 @@ class Tests_MGExtractIfE hr_clock.start(); } - auto [mg_edgelist_srcs, mg_edgelist_dsts, mg_edgelist_weights] = - extract_if_e(*handle_, - mg_graph_view, - mg_src_prop.view(), - mg_dst_prop.view(), - [] __device__(vertex_t src, vertex_t dst, auto src_val, auto dst_val) { - return src_val < dst_val; - }); + auto [mg_edgelist_srcs, mg_edgelist_dsts] = extract_if_e( + *handle_, + mg_graph_view, + mg_src_prop.view(), + mg_dst_prop.view(), + [] __device__(vertex_t src, vertex_t dst, auto src_val, auto dst_val, thrust::nullopt_t) { + return src_val < dst_val; + }); if (cugraph::test::g_perf) { RAFT_CUDA_TRY(cudaDeviceSynchronize()); // for consistent performance measurement @@ -188,11 +190,6 @@ class Tests_MGExtractIfE cugraph::test::device_gatherv(*handle_, mg_edgelist_srcs.data(), mg_edgelist_srcs.size()); auto mg_aggregate_edgelist_dsts = cugraph::test::device_gatherv(*handle_, mg_edgelist_dsts.data(), mg_edgelist_dsts.size()); - std::optional> mg_aggregate_edgelist_weights{std::nullopt}; - if (mg_edgelist_weights) { - mg_aggregate_edgelist_weights = cugraph::test::device_gatherv( - *handle_, (*mg_edgelist_weights).data(), (*mg_edgelist_weights).size()); - } if (handle_->get_comms().get_rank() == int{0}) { // 3-2. unrenumber MG results @@ -212,10 +209,11 @@ class Tests_MGExtractIfE // 3-3. create SG graph - cugraph::graph_t sg_graph(*handle_); - std::tie(sg_graph, std::ignore) = + cugraph::graph_t sg_graph(*handle_); + std::tie(sg_graph, std::ignore, std::ignore) = cugraph::test::construct_graph( *handle_, input_usecase, true, false); + auto sg_graph_view = sg_graph.view(); // 3-4. run SG extract_if_e @@ -230,54 +228,33 @@ class Tests_MGExtractIfE auto sg_dst_prop = cugraph::test::generate::dst_property( *handle_, sg_graph_view, sg_vertex_prop); - auto [sg_edgelist_srcs, sg_edgelist_dsts, sg_edgelist_weights] = - extract_if_e(*handle_, - sg_graph_view, - sg_src_prop.view(), - sg_dst_prop.view(), - [] __device__(vertex_t src, vertex_t dst, auto src_val, auto dst_val) { - return src_val < dst_val; - }); + auto [sg_edgelist_srcs, sg_edgelist_dsts] = extract_if_e( + *handle_, + sg_graph_view, + sg_src_prop.view(), + sg_dst_prop.view(), + [] __device__(vertex_t src, vertex_t dst, auto src_val, auto dst_val, thrust::nullopt_t) { + return src_val < dst_val; + }); // 3-5. compare - if (mg_graph_view.is_weighted()) { - auto mg_edge_first = - thrust::make_zip_iterator(thrust::make_tuple(mg_aggregate_edgelist_srcs.begin(), - mg_aggregate_edgelist_dsts.begin(), - (*mg_aggregate_edgelist_weights).begin())); - auto sg_edge_first = thrust::make_zip_iterator(thrust::make_tuple( - sg_edgelist_srcs.begin(), sg_edgelist_dsts.begin(), (*sg_edgelist_weights).begin())); - thrust::sort(handle_->get_thrust_policy(), - mg_edge_first, - mg_edge_first + mg_aggregate_edgelist_srcs.size()); - thrust::sort( - handle_->get_thrust_policy(), sg_edge_first, sg_edge_first + sg_edgelist_srcs.size()); - ASSERT_TRUE(thrust::equal( - handle_->get_thrust_policy(), - mg_edge_first, - mg_edge_first + mg_aggregate_edgelist_srcs.size(), - sg_edge_first, - compare_equal_t< - typename thrust::iterator_traits::value_type>{})); - } else { - auto mg_edge_first = thrust::make_zip_iterator(thrust::make_tuple( - mg_aggregate_edgelist_srcs.begin(), mg_aggregate_edgelist_dsts.begin())); - auto sg_edge_first = thrust::make_zip_iterator( - thrust::make_tuple(sg_edgelist_srcs.begin(), sg_edgelist_dsts.begin())); - thrust::sort(handle_->get_thrust_policy(), - mg_edge_first, - mg_edge_first + mg_aggregate_edgelist_srcs.size()); - thrust::sort( - handle_->get_thrust_policy(), sg_edge_first, sg_edge_first + sg_edgelist_srcs.size()); - ASSERT_TRUE(thrust::equal( - handle_->get_thrust_policy(), - mg_edge_first, - mg_edge_first + mg_aggregate_edgelist_srcs.size(), - sg_edge_first, - compare_equal_t< - typename thrust::iterator_traits::value_type>{})); - } + auto mg_edge_first = thrust::make_zip_iterator(thrust::make_tuple( + mg_aggregate_edgelist_srcs.begin(), mg_aggregate_edgelist_dsts.begin())); + auto sg_edge_first = thrust::make_zip_iterator( + thrust::make_tuple(sg_edgelist_srcs.begin(), sg_edgelist_dsts.begin())); + thrust::sort(handle_->get_thrust_policy(), + mg_edge_first, + mg_edge_first + mg_aggregate_edgelist_srcs.size()); + thrust::sort( + handle_->get_thrust_policy(), sg_edge_first, sg_edge_first + sg_edgelist_srcs.size()); + ASSERT_TRUE(thrust::equal( + handle_->get_thrust_policy(), + mg_edge_first, + mg_edge_first + mg_aggregate_edgelist_srcs.size(), + sg_edge_first, + compare_equal_t< + typename thrust::iterator_traits::value_type>{})); } } } diff --git a/cpp/tests/prims/mg_extract_transform_v_frontier_outgoing_e.cu b/cpp/tests/prims/mg_extract_transform_v_frontier_outgoing_e.cu index 2be87bf2508..1353fc617a6 100644 --- a/cpp/tests/prims/mg_extract_transform_v_frontier_outgoing_e.cu +++ b/cpp/tests/prims/mg_extract_transform_v_frontier_outgoing_e.cu @@ -78,7 +78,8 @@ struct e_op_t { __device__ return_type operator()(key_t optionally_tagged_src, vertex_t dst, property_t src_val, - property_t dst_val) const + property_t dst_val, + thrust::nullopt_t) const { auto output_payload = static_cast(1); if constexpr (std::is_same_v) { @@ -169,7 +170,9 @@ class Tests_MGExtractTransformVFrontierOutgoingE hr_clock.start(); } - auto [mg_graph, d_mg_renumber_map_labels] = + cugraph::graph_t mg_graph(*handle_); + std::optional> d_mg_renumber_map_labels{std::nullopt}; + std::tie(mg_graph, std::ignore, d_mg_renumber_map_labels) = cugraph::test::construct_graph( *handle_, input_usecase, false, renumber); @@ -235,6 +238,7 @@ class Tests_MGExtractTransformVFrontierOutgoingE mg_vertex_frontier.bucket(bucket_idx_cur), mg_src_prop.view(), mg_dst_prop.view(), + cugraph::edge_dummy_property_t{}.view(), e_op_t{}); if (cugraph::test::g_perf) { @@ -286,11 +290,11 @@ class Tests_MGExtractTransformVFrontierOutgoingE cugraph::get_dataframe_buffer_begin(mg_aggregate_extract_transform_output_buffer), cugraph::get_dataframe_buffer_end(mg_aggregate_extract_transform_output_buffer)); - cugraph::graph_t sg_graph( - *handle_); - std::tie(sg_graph, std::ignore) = cugraph::test:: + cugraph::graph_t sg_graph(*handle_); + std::tie(sg_graph, std::ignore, std::ignore) = cugraph::test:: construct_graph( *handle_, input_usecase, false, false); + auto sg_graph_view = sg_graph.view(); auto sg_vertex_prop = cugraph::test::generate::vertex_property( @@ -333,6 +337,7 @@ class Tests_MGExtractTransformVFrontierOutgoingE sg_vertex_frontier.bucket(bucket_idx_cur), sg_src_prop.view(), sg_dst_prop.view(), + cugraph::edge_dummy_property_t{}.view(), e_op_t{}); thrust::sort(handle_->get_thrust_policy(), diff --git a/cpp/tests/prims/mg_per_v_pair_transform_dst_nbr_intersection.cu b/cpp/tests/prims/mg_per_v_pair_transform_dst_nbr_intersection.cu index 710b4cc83c3..a77aca2b09a 100644 --- a/cpp/tests/prims/mg_per_v_pair_transform_dst_nbr_intersection.cu +++ b/cpp/tests/prims/mg_per_v_pair_transform_dst_nbr_intersection.cu @@ -95,7 +95,9 @@ class Tests_MGPerVPairTransformDstNbrIntersection hr_clock.start(); } - auto [mg_graph, d_mg_renumber_map_labels] = + cugraph::graph_t mg_graph(*handle_); + std::optional> d_mg_renumber_map_labels{std::nullopt}; + std::tie(mg_graph, std::ignore, d_mg_renumber_map_labels) = cugraph::test::construct_graph( *handle_, input_usecase, false, true); @@ -195,8 +197,8 @@ class Tests_MGPerVPairTransformDstNbrIntersection (*d_mg_renumber_map_labels).data(), h_vertex_partition_range_lasts); - cugraph::graph_t unrenumbered_graph(*handle_); - std::tie(unrenumbered_graph, std::ignore) = + cugraph::graph_t unrenumbered_graph(*handle_); + std::tie(unrenumbered_graph, std::ignore, std::ignore) = cugraph::test::construct_graph( *handle_, input_usecase, false, false); diff --git a/cpp/tests/prims/mg_per_v_random_select_transform_outgoing_e.cu b/cpp/tests/prims/mg_per_v_random_select_transform_outgoing_e.cu index 7fde20e7cac..29cc58460ab 100644 --- a/cpp/tests/prims/mg_per_v_random_select_transform_outgoing_e.cu +++ b/cpp/tests/prims/mg_per_v_random_select_transform_outgoing_e.cu @@ -51,10 +51,8 @@ struct e_op_t { cugraph::to_thrust_tuple(property_t{}), cugraph::to_thrust_tuple(property_t{}))); - __device__ result_t operator()(vertex_t src, - vertex_t dst, - property_t src_prop, - property_t dst_prop) const + __device__ result_t operator()( + vertex_t src, vertex_t dst, property_t src_prop, property_t dst_prop, thrust::nullopt_t) const { if constexpr (cugraph::is_thrust_tuple_of_arithmetic::value) { static_assert(thrust::tuple_size::value == size_t{2}); @@ -108,7 +106,9 @@ class Tests_MGPerVRandomSelectTransformOutgoingE hr_clock.start(); } - auto [mg_graph, d_mg_renumber_map_labels] = + cugraph::graph_t mg_graph(*handle_); + std::optional> d_mg_renumber_map_labels{std::nullopt}; + std::tie(mg_graph, std::ignore, d_mg_renumber_map_labels) = cugraph::test::construct_graph( *handle_, input_usecase, prims_usecase.test_weighted, true); @@ -174,6 +174,7 @@ class Tests_MGPerVRandomSelectTransformOutgoingE mg_vertex_frontier.bucket(bucket_idx_cur), mg_src_prop.view(), mg_dst_prop.view(), + cugraph::edge_dummy_property_t{}.view(), e_op_t{}, rng_state, prims_usecase.K, @@ -196,8 +197,8 @@ class Tests_MGPerVRandomSelectTransformOutgoingE *handle_, (*d_mg_renumber_map_labels).data(), (*d_mg_renumber_map_labels).size()); auto out_degrees = mg_graph_view.compute_out_degrees(*handle_); - cugraph::graph_t unrenumbered_graph(*handle_); - std::tie(unrenumbered_graph, std::ignore) = + cugraph::graph_t unrenumbered_graph(*handle_); + std::tie(unrenumbered_graph, std::ignore, std::ignore) = cugraph::test::construct_graph( *handle_, input_usecase, prims_usecase.test_weighted, false); auto unrenumbered_graph_view = unrenumbered_graph.view(); diff --git a/cpp/tests/prims/mg_per_v_transform_reduce_incoming_outgoing_e.cu b/cpp/tests/prims/mg_per_v_transform_reduce_incoming_outgoing_e.cu index af5703b32ea..ba9223e806b 100644 --- a/cpp/tests/prims/mg_per_v_transform_reduce_incoming_outgoing_e.cu +++ b/cpp/tests/prims/mg_per_v_transform_reduce_incoming_outgoing_e.cu @@ -143,7 +143,9 @@ class Tests_MGPerVTransformReduceIncomingOutgoingE handle_->get_comms().barrier(); hr_clock.start(); } - auto [mg_graph, d_mg_renumber_map_labels] = + cugraph::graph_t mg_graph(*handle_); + std::optional> d_mg_renumber_map_labels{std::nullopt}; + std::tie(mg_graph, std::ignore, d_mg_renumber_map_labels) = cugraph::test::construct_graph( *handle_, input_usecase, prims_usecase.test_weighted, true); @@ -188,7 +190,8 @@ class Tests_MGPerVTransformReduceIncomingOutgoingE mg_graph_view, mg_src_prop.view(), mg_dst_prop.view(), - [] __device__(auto src, auto dst, weight_t wt, auto src_property, auto dst_property) { + cugraph::edge_dummy_property_t{}.view(), + [] __device__(auto src, auto dst, auto src_property, auto dst_property, thrust::nullopt_t) { if (src_property < dst_property) { return src_property; } else { @@ -217,7 +220,8 @@ class Tests_MGPerVTransformReduceIncomingOutgoingE mg_graph_view, mg_src_prop.view(), mg_dst_prop.view(), - [] __device__(auto src, auto dst, weight_t wt, auto src_property, auto dst_property) { + cugraph::edge_dummy_property_t{}.view(), + [] __device__(auto src, auto dst, auto src_property, auto dst_property, thrust::nullopt_t) { if (src_property < dst_property) { return src_property; } else { @@ -238,10 +242,11 @@ class Tests_MGPerVTransformReduceIncomingOutgoingE // 3. compare SG & MG results if (prims_usecase.check_correctness) { - cugraph::graph_t sg_graph(*handle_); - std::tie(sg_graph, std::ignore) = + cugraph::graph_t sg_graph(*handle_); + std::tie(sg_graph, std::ignore, std::ignore) = cugraph::test::construct_graph( *handle_, input_usecase, true, false); + auto sg_graph_view = sg_graph.view(); auto sg_vertex_prop = cugraph::test::generate::vertex_property( @@ -262,7 +267,8 @@ class Tests_MGPerVTransformReduceIncomingOutgoingE sg_graph_view, sg_src_prop.view(), sg_dst_prop.view(), - [] __device__(auto src, auto dst, weight_t wt, auto src_property, auto dst_property) { + cugraph::edge_dummy_property_t{}.view(), + [] __device__(auto src, auto dst, auto src_property, auto dst_property, thrust::nullopt_t) { if (src_property < dst_property) { return src_property; } else { @@ -279,7 +285,8 @@ class Tests_MGPerVTransformReduceIncomingOutgoingE sg_graph_view, sg_src_prop.view(), sg_dst_prop.view(), - [] __device__(auto src, auto dst, weight_t wt, auto src_property, auto dst_property) { + cugraph::edge_dummy_property_t{}.view(), + [] __device__(auto src, auto dst, auto src_property, auto dst_property, thrust::nullopt_t) { if (src_property < dst_property) { return src_property; } else { diff --git a/cpp/tests/prims/mg_reduce_v.cu b/cpp/tests/prims/mg_reduce_v.cu index 043dd4658da..76f50d16318 100644 --- a/cpp/tests/prims/mg_reduce_v.cu +++ b/cpp/tests/prims/mg_reduce_v.cu @@ -129,7 +129,9 @@ class Tests_MGReduceV hr_clock.start(); } - auto [mg_graph, d_mg_renumber_map_labels] = + cugraph::graph_t mg_graph(*handle_); + std::optional> d_mg_renumber_map_labels{std::nullopt}; + std::tie(mg_graph, std::ignore, d_mg_renumber_map_labels) = cugraph::test::construct_graph( *handle_, input_usecase, true, true); @@ -205,8 +207,8 @@ class Tests_MGReduceV // 3. compare SG & MG results if (prims_usecase.check_correctness) { - cugraph::graph_t sg_graph(*handle_); - std::tie(sg_graph, std::ignore) = + cugraph::graph_t sg_graph(*handle_); + std::tie(sg_graph, std::ignore, std::ignore) = cugraph::test::construct_graph( *handle_, input_usecase, true, false); auto sg_graph_view = sg_graph.view(); diff --git a/cpp/tests/prims/mg_transform_reduce_e.cu b/cpp/tests/prims/mg_transform_reduce_e.cu index 6935149b6d2..d607084f39c 100644 --- a/cpp/tests/prims/mg_transform_reduce_e.cu +++ b/cpp/tests/prims/mg_transform_reduce_e.cu @@ -125,7 +125,9 @@ class Tests_MGTransformReduceE handle_->get_comms().barrier(); hr_clock.start(); } - auto [mg_graph, d_mg_renumber_map_labels] = + cugraph::graph_t mg_graph(*handle_); + std::optional> d_mg_renumber_map_labels{std::nullopt}; + std::tie(mg_graph, std::ignore, d_mg_renumber_map_labels) = cugraph::test::construct_graph( *handle_, input_usecase, prims_usecase.test_weighted, true); @@ -164,7 +166,8 @@ class Tests_MGTransformReduceE mg_graph_view, mg_src_prop.view(), mg_dst_prop.view(), - [] __device__(auto src, auto dst, weight_t wt, auto src_property, auto dst_property) { + cugraph::edge_dummy_property_t{}.view(), + [] __device__(auto src, auto dst, auto src_property, auto dst_property, thrust::nullopt_t) { if (src_property < dst_property) { return src_property; } else { @@ -184,10 +187,11 @@ class Tests_MGTransformReduceE // 3. compare SG & MG results if (prims_usecase.check_correctness) { - cugraph::graph_t sg_graph(*handle_); - std::tie(sg_graph, std::ignore) = + cugraph::graph_t sg_graph(*handle_); + std::tie(sg_graph, std::ignore, std::ignore) = cugraph::test::construct_graph( *handle_, input_usecase, true, false); + auto sg_graph_view = sg_graph.view(); auto sg_vertex_prop = cugraph::test::generate::vertex_property( @@ -205,7 +209,8 @@ class Tests_MGTransformReduceE sg_graph_view, sg_src_prop.view(), sg_dst_prop.view(), - [] __device__(auto src, auto dst, weight_t wt, auto src_property, auto dst_property) { + cugraph::edge_dummy_property_t{}.view(), + [] __device__(auto src, auto dst, auto src_property, auto dst_property, thrust::nullopt_t) { if (src_property < dst_property) { return src_property; } else { diff --git a/cpp/tests/prims/mg_transform_reduce_v.cu b/cpp/tests/prims/mg_transform_reduce_v.cu index e4f2560f41b..14386444c99 100644 --- a/cpp/tests/prims/mg_transform_reduce_v.cu +++ b/cpp/tests/prims/mg_transform_reduce_v.cu @@ -135,7 +135,9 @@ class Tests_MGTransformReduceV handle_->get_comms().barrier(); hr_clock.start(); } - auto [mg_graph, d_mg_renumber_map_labels] = + cugraph::graph_t mg_graph(*handle_); + std::optional> d_mg_renumber_map_labels{std::nullopt}; + std::tie(mg_graph, std::ignore, d_mg_renumber_map_labels) = cugraph::test::construct_graph( *handle_, input_usecase, true, true); @@ -210,8 +212,8 @@ class Tests_MGTransformReduceV // 3. compare SG & MG results if (prims_usecase.check_correctness) { - cugraph::graph_t sg_graph(*handle_); - std::tie(sg_graph, std::ignore) = + cugraph::graph_t sg_graph(*handle_); + std::tie(sg_graph, std::ignore, std::ignore) = cugraph::test::construct_graph( *handle_, input_usecase, true, false); auto sg_graph_view = sg_graph.view(); diff --git a/cpp/tests/prims/mg_transform_reduce_v_frontier_outgoing_e_by_dst.cu b/cpp/tests/prims/mg_transform_reduce_v_frontier_outgoing_e_by_dst.cu index 25edd3b2748..da762c70e33 100644 --- a/cpp/tests/prims/mg_transform_reduce_v_frontier_outgoing_e_by_dst.cu +++ b/cpp/tests/prims/mg_transform_reduce_v_frontier_outgoing_e_by_dst.cu @@ -63,7 +63,8 @@ struct e_op_t { __device__ auto operator()(key_t optionally_tagged_src, vertex_t dst, property_t src_val, - property_t dst_val) const + property_t dst_val, + thrust::nullopt_t) const { if constexpr (std::is_same_v) { if constexpr (std::is_same_v) { @@ -138,7 +139,9 @@ class Tests_MGTransformReduceVFrontierOutgoingEByDst hr_clock.start(); } - auto [mg_graph, d_mg_renumber_map_labels] = + cugraph::graph_t mg_graph(*handle_); + std::optional> d_mg_renumber_map_labels{std::nullopt}; + std::tie(mg_graph, std::ignore, d_mg_renumber_map_labels) = cugraph::test::construct_graph( *handle_, input_usecase, false, renumber); @@ -210,6 +213,7 @@ class Tests_MGTransformReduceVFrontierOutgoingEByDst mg_vertex_frontier.bucket(bucket_idx_cur), mg_src_prop.view(), mg_dst_prop.view(), + cugraph::edge_dummy_property_t{}.view(), e_op_t{}, cugraph::reduce_op::null{}); } else { @@ -220,6 +224,7 @@ class Tests_MGTransformReduceVFrontierOutgoingEByDst mg_vertex_frontier.bucket(bucket_idx_cur), mg_src_prop.view(), mg_dst_prop.view(), + cugraph::edge_dummy_property_t{}.view(), e_op_t{}, cugraph::reduce_op::plus{}); } @@ -298,11 +303,11 @@ class Tests_MGTransformReduceVFrontierOutgoingEByDst cugraph::get_dataframe_buffer_begin(mg_aggregate_payload_buffer)); } - cugraph::graph_t sg_graph( - *handle_); - std::tie(sg_graph, std::ignore) = cugraph::test:: + cugraph::graph_t sg_graph(*handle_); + std::tie(sg_graph, std::ignore, std::ignore) = cugraph::test:: construct_graph( *handle_, input_usecase, false, false); + auto sg_graph_view = sg_graph.view(); auto sg_vertex_prop = cugraph::test::generate::vertex_property( @@ -350,6 +355,7 @@ class Tests_MGTransformReduceVFrontierOutgoingEByDst sg_vertex_frontier.bucket(bucket_idx_cur), sg_src_prop.view(), sg_dst_prop.view(), + cugraph::edge_dummy_property_t{}.view(), e_op_t{}, cugraph::reduce_op::null{}); } else { @@ -360,6 +366,7 @@ class Tests_MGTransformReduceVFrontierOutgoingEByDst sg_vertex_frontier.bucket(bucket_idx_cur), sg_src_prop.view(), sg_dst_prop.view(), + cugraph::edge_dummy_property_t{}.view(), e_op_t{}, cugraph::reduce_op::plus{}); } diff --git a/cpp/tests/sampling/detail/nbr_sampling_utils.cuh b/cpp/tests/sampling/detail/nbr_sampling_utils.cuh index e152fca3b3f..7ad235b8500 100644 --- a/cpp/tests/sampling/detail/nbr_sampling_utils.cuh +++ b/cpp/tests/sampling/detail/nbr_sampling_utils.cuh @@ -462,7 +462,7 @@ sg_gather_edges(raft::handle_t const& handle, auto edge_count = source_count * indices_per_source; rmm::device_uvector sources(edge_count, handle.get_stream()); rmm::device_uvector destinations(edge_count, handle.get_stream()); - auto edge_partition = cugraph::edge_partition_device_view_t( + auto edge_partition = cugraph::edge_partition_device_view_t( graph_view.local_edge_partition_view()); thrust::for_each(handle.get_thrust_policy(), thrust::make_counting_iterator(0), @@ -513,9 +513,8 @@ sg_gather_edges(raft::handle_t const& handle, static_assert(GraphViewType::is_storage_transposed == false); using vertex_t = typename GraphViewType::vertex_type; using edge_t = typename GraphViewType::edge_type; - using weight_t = typename GraphViewType::weight_type; - auto edge_partition = cugraph::edge_partition_device_view_t( + auto edge_partition = cugraph::edge_partition_device_view_t( graph_view.local_edge_partition_view()); rmm::device_uvector sources_out_degrees(sources.size(), handle.get_stream()); @@ -788,9 +787,9 @@ void validate_sampling_depth(raft::handle_t const& handle, rmm::device_uvector&& d_source_vertices, int max_depth) { - graph_t graph(handle); + graph_t graph(handle); std::optional> number_map{std::nullopt}; - std::tie(graph, std::ignore, number_map) = + std::tie(graph, std::ignore, std::ignore, number_map) = create_graph_from_edgelist( handle, std::nullopt, @@ -827,14 +826,14 @@ void validate_sampling_depth(raft::handle_t const& handle, for (size_t i = 0; i < d_source_vertices.size(); ++i) { if (h_source_vertices[i] != cugraph::invalid_vertex_id::value) { // Do BFS - cugraph::bfs(handle, - graph_view, - d_local_distances.data(), - nullptr, - d_source_vertices.data() + i, - size_t{1}, - bool{false}, - vertex_t{max_depth}); + cugraph::bfs(handle, + graph_view, + d_local_distances.data(), + nullptr, + d_source_vertices.data() + i, + size_t{1}, + bool{false}, + vertex_t{max_depth}); auto tuple_iter = thrust::make_zip_iterator( thrust::make_tuple(d_distances.begin(), d_local_distances.begin())); diff --git a/cpp/tests/sampling/mg_random_walks_test.cpp b/cpp/tests/sampling/mg_random_walks_test.cpp index 7818c8023cb..e960ab295d6 100644 --- a/cpp/tests/sampling/mg_random_walks_test.cpp +++ b/cpp/tests/sampling/mg_random_walks_test.cpp @@ -42,11 +42,13 @@ struct UniformRandomWalks_Usecase { template std::tuple, std::optional>> operator()(raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view, raft::device_span start_vertices, size_t max_depth) { - return cugraph::uniform_random_walks(handle, graph_view, start_vertices, max_depth, seed); + return cugraph::uniform_random_walks( + handle, graph_view, edge_weight_view, start_vertices, max_depth, seed); } bool expect_throw() { return false; } @@ -60,11 +62,15 @@ struct BiasedRandomWalks_Usecase { template std::tuple, std::optional>> operator()(raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view, raft::device_span start_vertices, size_t max_depth) { - return cugraph::biased_random_walks(handle, graph_view, start_vertices, max_depth, seed); + CUGRAPH_EXPECTS(edge_weight_view.has_value(), "Biased random walk requires edge weights."); + + return cugraph::biased_random_walks( + handle, graph_view, *edge_weight_view, start_vertices, max_depth, seed); } // FIXME: Not currently implemented @@ -81,12 +87,14 @@ struct Node2VecRandomWalks_Usecase { template std::tuple, std::optional>> operator()(raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view, raft::device_span start_vertices, size_t max_depth) { return cugraph::node2vec_random_walks(handle, graph_view, + edge_weight_view, start_vertices, max_depth, static_cast(p), @@ -123,7 +131,7 @@ class Tests_MGRandomWalks : public ::testing::TestWithParam { } bool renumber{true}; - auto [graph, d_renumber_map_labels] = + auto [mg_graph, mg_edge_weights, d_renumber_map_labels] = cugraph::test::construct_graph( *handle_, input_usecase, randomwalks_usecase.test_weighted, renumber); @@ -134,19 +142,22 @@ class Tests_MGRandomWalks : public ::testing::TestWithParam { std::cout << "construct_graph took " << elapsed_time * 1e-6 << " s.\n"; } - auto graph_view = graph.view(); + auto mg_graph_view = mg_graph.view(); + auto mg_edge_weight_view = + mg_edge_weights ? std::make_optional((*mg_edge_weights).view()) : std::nullopt; + edge_t num_paths = 10; edge_t max_length = 10; rmm::device_uvector d_start(0, handle_->get_stream()); - if (graph_view.local_vertex_partition_range_size() > 0) { - d_start.resize(std::min(10, graph_view.local_vertex_partition_range_size()), + if (mg_graph_view.local_vertex_partition_range_size() > 0) { + d_start.resize(std::min(10, mg_graph_view.local_vertex_partition_range_size()), handle_->get_stream()); cugraph::detail::sequence_fill(handle_->get_stream(), d_start.begin(), d_start.size(), - graph_view.local_vertex_partition_range_first()); + mg_graph_view.local_vertex_partition_range_first()); } if (cugraph::test::g_perf) { @@ -158,14 +169,16 @@ class Tests_MGRandomWalks : public ::testing::TestWithParam { // biased and node2vec currently throw since they are not implemented EXPECT_THROW( randomwalks_usecase(*handle_, - graph_view, + mg_graph_view, + mg_edge_weight_view, raft::device_span{d_start.data(), d_start.size()}, max_length), std::exception); } else { auto [d_vertices, d_weights] = randomwalks_usecase(*handle_, - graph_view, + mg_graph_view, + mg_edge_weight_view, raft::device_span{d_start.data(), d_start.size()}, max_length); @@ -178,7 +191,8 @@ class Tests_MGRandomWalks : public ::testing::TestWithParam { if (randomwalks_usecase.check_correctness) { cugraph::test::random_walks_validate(*handle_, - graph_view, + mg_graph_view, + mg_edge_weight_view, std::move(d_start), std::move(d_vertices), std::move(d_weights), diff --git a/cpp/tests/sampling/mg_uniform_neighbor_sampling.cu b/cpp/tests/sampling/mg_uniform_neighbor_sampling.cu index 83e63c1f6e7..8da9cf8b4c6 100644 --- a/cpp/tests/sampling/mg_uniform_neighbor_sampling.cu +++ b/cpp/tests/sampling/mg_uniform_neighbor_sampling.cu @@ -57,7 +57,7 @@ class Tests_MGNbrSampling constexpr bool sort_adjacency_list = true; - auto [mg_graph, mg_renumber_map_labels] = + auto [mg_graph, mg_edge_weights, mg_renumber_map_labels] = cugraph::test::construct_graph( *handle_, input_usecase, true, true, false, sort_adjacency_list); @@ -69,7 +69,10 @@ class Tests_MGNbrSampling std::cout << "MG construct_graph took " << elapsed_time * 1e-6 << " s.\n"; } - auto mg_graph_view = mg_graph.view(); + auto mg_graph_view = mg_graph.view(); + auto mg_edge_weight_view = + mg_edge_weights ? std::make_optional((*mg_edge_weights).view()) : std::nullopt; + constexpr edge_t indices_per_source = 2; constexpr vertex_t repetitions_per_vertex = 5; constexpr vertex_t source_sample_count = 3; @@ -91,6 +94,7 @@ class Tests_MGNbrSampling EXPECT_THROW(cugraph::uniform_nbr_sample( *handle_, mg_graph_view, + mg_edge_weight_view, raft::device_span(random_sources.data(), random_sources.size()), raft::host_span(h_fan_out.data(), h_fan_out.size()), prims_usecase.flag_replacement), @@ -99,6 +103,7 @@ class Tests_MGNbrSampling auto&& [d_src_out, d_dst_out, d_indices, d_counts] = cugraph::uniform_nbr_sample( *handle_, mg_graph_view, + mg_edge_weight_view, raft::device_span(random_sources.data(), random_sources.size()), raft::host_span(h_fan_out.data(), h_fan_out.size()), prims_usecase.flag_replacement); diff --git a/cpp/tests/sampling/random_walks_check.cuh b/cpp/tests/sampling/random_walks_check.cuh index 22b0d1a8205..4cd74f01bcb 100644 --- a/cpp/tests/sampling/random_walks_check.cuh +++ b/cpp/tests/sampling/random_walks_check.cuh @@ -27,22 +27,23 @@ namespace cugraph { namespace test { -template +template void random_walks_validate( raft::handle_t const& handle, - graph_view_type const& graph_view, - rmm::device_uvector&& d_start, - rmm::device_uvector&& d_vertices, - std::optional>&& d_weights, + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view, + rmm::device_uvector&& d_start, + rmm::device_uvector&& d_vertices, + std::optional>&& d_weights, size_t max_length) { - using vertex_t = typename graph_view_type::vertex_type; - using weight_t = typename graph_view_type::weight_type; + auto [d_src, d_dst, d_wgt] = + cugraph::decompress_to_edgelist(handle, + graph_view, + edge_weight_view, + std::optional>{std::nullopt}); - auto [d_src, d_dst, d_wgt] = cugraph::decompress_to_edgelist( - handle, graph_view, std::optional>{std::nullopt}); - - if constexpr (graph_view_type::is_multi_gpu) { + if constexpr (multi_gpu) { d_src = cugraph::test::device_gatherv( handle, raft::device_span(d_src.data(), d_src.size())); d_dst = cugraph::test::device_gatherv( diff --git a/cpp/tests/sampling/random_walks_check.hpp b/cpp/tests/sampling/random_walks_check.hpp index c1f5dac61c2..0939badf93b 100644 --- a/cpp/tests/sampling/random_walks_check.hpp +++ b/cpp/tests/sampling/random_walks_check.hpp @@ -15,18 +15,20 @@ */ #pragma once +#include #include namespace cugraph { namespace test { -template +template void random_walks_validate( raft::handle_t const& handle, - graph_view_type const& graph_view, - rmm::device_uvector&& d_start, - rmm::device_uvector&& d_vertices, - std::optional>&& d_weights, + cugraph::graph_view_t const& graph_view, + std::optional>, + rmm::device_uvector&& d_start, + rmm::device_uvector&& d_vertices, + std::optional>&& d_weights, size_t max_length); } // namespace test diff --git a/cpp/tests/sampling/random_walks_check_mg.cu b/cpp/tests/sampling/random_walks_check_mg.cu index 4536b3cc59c..eb712075b42 100644 --- a/cpp/tests/sampling/random_walks_check_mg.cu +++ b/cpp/tests/sampling/random_walks_check_mg.cu @@ -20,7 +20,8 @@ namespace test { template void random_walks_validate( raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, + cugraph::graph_view_t const& graph_view, + std::optional>, rmm::device_uvector&& d_start, rmm::device_uvector&& d_vertices, std::optional>&& d_weights, diff --git a/cpp/tests/sampling/random_walks_check_sg.cu b/cpp/tests/sampling/random_walks_check_sg.cu index 54c900a7933..ca0b1168fb3 100644 --- a/cpp/tests/sampling/random_walks_check_sg.cu +++ b/cpp/tests/sampling/random_walks_check_sg.cu @@ -20,7 +20,8 @@ namespace test { template void random_walks_validate( raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, + cugraph::graph_view_t const& graph_view, + std::optional>, rmm::device_uvector&& d_start, rmm::device_uvector&& d_vertices, std::optional>&& d_weights, diff --git a/cpp/tests/sampling/random_walks_profiling.cu b/cpp/tests/sampling/random_walks_profiling.cu deleted file mode 100644 index 5ad2e5c21c2..00000000000 --- a/cpp/tests/sampling/random_walks_profiling.cu +++ /dev/null @@ -1,401 +0,0 @@ -/* - * Copyright (c) 2021-2022, NVIDIA CORPORATION. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include // cugraph::test::create_memory_resource() -#include -#include - -#include -#include - -#include - -#include - -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -/** - * @internal - * @brief Populates the device vector d_start with the starting vertex indices - * to be used for each RW path specified. - */ -template -void fill_start(raft::handle_t const& handle, - rmm::device_uvector& d_start, - index_t num_vertices) -{ - index_t num_paths = d_start.size(); - - thrust::transform(handle.get_thrust_policy(), - thrust::make_counting_iterator(0), - thrust::make_counting_iterator(num_paths), - - d_start.begin(), - [num_vertices] __device__(auto indx) { return indx % num_vertices; }); -} - -namespace impl_details = cugraph::detail::original; - -enum class traversal_id_t : int { HORIZONTAL = 0, VERTICAL }; - -/** - * @internal - * @brief Calls the random_walks algorithm with specified traversal strategy and displays the time - * metrics (total time for all requested paths, average time for each path). - */ -template -void output_random_walks_time(graph_vt const& graph_view, - typename graph_vt::edge_type num_paths, - traversal_id_t trv_id, - int sampling_id) -{ - using vertex_t = typename graph_vt::vertex_type; - using edge_t = typename graph_vt::edge_type; - using weight_t = typename graph_vt::weight_type; - using real_t = float; - - raft::handle_t handle{}; - rmm::device_uvector d_start(num_paths, handle.get_stream()); - - vertex_t num_vertices = graph_view.number_of_vertices(); - fill_start(handle, d_start, num_vertices); - - // 0-copy const device view: - // - impl_details::device_const_vector_view d_start_view{d_start.data(), num_paths}; - - edge_t max_depth{10}; - - weight_t p{4}; - weight_t q{8}; - - HighResTimer hr_timer; - std::string label{}; - - if (trv_id == traversal_id_t::HORIZONTAL) { - if (sampling_id == 0) { - label = std::string("RandomWalks; Horizontal traversal; uniform sampling - "); - impl_details::uniform_selector_t selector{handle, graph_view, real_t{0}}; - - hr_timer.start(label); - cudaProfilerStart(); - - auto ret_tuple = cugraph::detail::random_walks_impl( - handle, // prevent clang-format to separate function name from its namespace - graph_view, - d_start_view, - max_depth, - selector); - - cudaProfilerStop(); - hr_timer.stop(); - } else if (sampling_id == 1) { - label = std::string("RandomWalks; Horizontal traversal; biased sampling - "); - impl_details::biased_selector_t selector{handle, graph_view, real_t{0}}; - - hr_timer.start(label); - cudaProfilerStart(); - - auto ret_tuple = cugraph::detail::random_walks_impl( - handle, // prevent clang-format to separate function name from its namespace - graph_view, - d_start_view, - max_depth, - selector); - - cudaProfilerStop(); - hr_timer.stop(); - } else if (sampling_id == 2) { - label = - std::string("RandomWalks; Horizontal traversal; node2vec sampling with alpha cache - "); - impl_details::node2vec_selector_t selector{ - handle, graph_view, real_t{0}, p, q, num_paths}; - - hr_timer.start(label); - cudaProfilerStart(); - - auto ret_tuple = cugraph::detail::random_walks_impl( - handle, // prevent clang-format to separate function name from its namespace - graph_view, - d_start_view, - max_depth, - selector); - - cudaProfilerStop(); - hr_timer.stop(); - } else { - label = - std::string("RandomWalks; Horizontal traversal; node2vec sampling without alpha cache - "); - impl_details::node2vec_selector_t selector{ - handle, graph_view, real_t{0}, p, q}; - - hr_timer.start(label); - cudaProfilerStart(); - - auto ret_tuple = cugraph::detail::random_walks_impl( - handle, // prevent clang-format to separate function name from its namespace - graph_view, - d_start_view, - max_depth, - selector); - - cudaProfilerStop(); - hr_timer.stop(); - } - } else { - if (sampling_id == 0) { - label = std::string("RandomWalks; Vertical traversal; uniform sampling - "); - impl_details::uniform_selector_t selector{handle, graph_view, real_t{0}}; - hr_timer.start(label); - cudaProfilerStart(); - - auto ret_tuple = cugraph::detail::random_walks_impl( - handle, // prevent clang-format to separate function name from its namespace - graph_view, - d_start_view, - max_depth, - selector); - - cudaProfilerStop(); - hr_timer.stop(); - } else if (sampling_id == 1) { - label = std::string("RandomWalks; Vertical traversal; biased sampling - "); - impl_details::biased_selector_t selector{handle, graph_view, real_t{0}}; - hr_timer.start(label); - cudaProfilerStart(); - - auto ret_tuple = cugraph::detail::random_walks_impl( - handle, // prevent clang-format to separate function name from its namespace - graph_view, - d_start_view, - max_depth, - selector); - - cudaProfilerStop(); - hr_timer.stop(); - } else if (sampling_id == 2) { - label = std::string("RandomWalks; Vertical traversal; node2vec sampling with alpha cache - "); - impl_details::node2vec_selector_t selector{ - handle, graph_view, real_t{0}, p, q, num_paths}; - - hr_timer.start(label); - cudaProfilerStart(); - - auto ret_tuple = cugraph::detail::random_walks_impl( - handle, // prevent clang-format to separate function name from its namespace - graph_view, - d_start_view, - max_depth, - selector); - - cudaProfilerStop(); - hr_timer.stop(); - } else { - label = - std::string("RandomWalks; Vertical traversal; node2vec sampling without alpha cache - "); - impl_details::node2vec_selector_t selector{ - handle, graph_view, real_t{0}, p, q}; - - hr_timer.start(label); - cudaProfilerStart(); - - auto ret_tuple = cugraph::detail::random_walks_impl( - handle, // prevent clang-format to separate function name from its namespace - graph_view, - d_start_view, - max_depth, - selector); - - cudaProfilerStop(); - hr_timer.stop(); - } - } - try { - auto runtime = hr_timer.get_average_runtime(label); - - std::cout << "RW for num_paths: " << num_paths - << ", runtime [ms] / path: " << runtime / num_paths << ":\n"; - - } catch (std::exception const& ex) { - std::cerr << ex.what() << '\n'; - return; - - } catch (...) { - std::cerr << "ERROR: Unknown exception on timer label search." << '\n'; - return; - } - hr_timer.display(std::cout); -} - -/** - * @struct RandomWalks_Usecase - * @brief Used to specify input to a random_walks benchmark/profile run - * - * @var RandomWalks_Usecase::graph_file_full_path Computed during construction - * to be an absolute path consisting of the value of the RAPIDS_DATASET_ROOT_DIR - * env var and the graph_file_path constructor arg. This is initialized to an - * empty string. - * - * @var RandomWalks_Usecase::test_weighted Bool representing if the specified - * graph is weighted or not. This is initialized to false (unweighted). - */ -struct RandomWalks_Usecase { - std::string graph_file_full_path{}; - bool test_weighted{false}; - - RandomWalks_Usecase(std::string const& graph_file_path, bool test_weighted) - : test_weighted(test_weighted) - { - if ((graph_file_path.length() > 0) && (graph_file_path[0] != '/')) { - graph_file_full_path = cugraph::test::get_rapids_dataset_root_dir() + "/" + graph_file_path; - } else { - graph_file_full_path = graph_file_path; - } - }; -}; - -/** - * @brief Runs random_walks on a specified input and outputs time metrics - * - * Creates a graph_t instance from the configuration specified in the - * RandomWalks_Usecase instance passed in (currently by reading a dataset to - * populate the graph_t), then runs random_walks to generate 1, 10, and 100 - * random paths and output statistics for each. - * - * @tparam vertex_t Type of vertex identifiers. - * @tparam edge_t Type of edge identifiers. - * @tparam weight_t Type of weight identifiers. - * - * @param[in] configuration RandomWalks_Usecase instance containing the input - * file to read for constructing the graph_t. - * @param[in] trv_id traversal strategy. - */ -template -void run(RandomWalks_Usecase const& configuration, traversal_id_t trv_id, int sampling_id) -{ - raft::handle_t handle{}; - - cugraph::graph_t graph(handle); - std::tie(graph, std::ignore) = - cugraph::test::read_graph_from_matrix_market_file( - handle, configuration.graph_file_full_path, configuration.test_weighted, false); - - auto graph_view = graph.view(); - - // FIXME: the num_paths vector might be better specified via the - // configuration input instead of hardcoding here. - std::vector v_np{1, 10, 100}; - for (auto&& num_paths : v_np) { - output_random_walks_time(graph_view, num_paths, trv_id, sampling_id); - } -} - -/** - * @brief Performs the random_walks benchmark/profiling run - * - * main function for performing the random_walks benchmark/profiling run. The - * resulting executable takes the following options: "rmm_mode" which can be one - * of "binning", "cuda", "pool", or "managed. "dataset" which is a path - * relative to the env var RAPIDS_DATASET_ROOT_DIR to a input .mtx file to use - * to populate the graph_t instance. - * - * To use the default values of rmm_mode=pool and - * dataset=test/datasets/karate.mtx: - * @code - * RANDOM_WALKS_PROFILING - * @endcode - * - * To specify managed memory and the netscience.mtx dataset (relative to a - * particular RAPIDS_DATASET_ROOT_DIR setting): - * @code - * RANDOM_WALKS_PROFILING --rmm_mode=managed --dataset=test/datasets/netscience.mtx - * @endcode - * - * @return An int representing a successful run. 0 indicates success. - */ -int main(int argc, char** argv) -{ - // Add command-line processing, provide defaults - cxxopts::Options options(argv[0], " - Random Walks benchmark command line options"); - options.add_options()( - "rmm_mode", "RMM allocation mode", cxxopts::value()->default_value("pool")); - options.add_options()( - "dataset", "dataset", cxxopts::value()->default_value("test/datasets/karate.mtx")); - auto const cmd_options = options.parse(argc, argv); - auto const rmm_mode = cmd_options["rmm_mode"].as(); - auto const dataset = cmd_options["dataset"].as(); - - // Configure RMM - auto resource = cugraph::test::create_memory_resource(rmm_mode); - rmm::mr::set_current_device_resource(resource.get()); - - // Run benchmarks - std::cout << "Using dataset: " << dataset << std::endl; - - std::cout << "##### Horizontal traversal strategy:\n"; - - std::cout << "### Uniform sampling strategy:\n"; - run(RandomWalks_Usecase(dataset, true), traversal_id_t::HORIZONTAL, 0); - - std::cout << "### Biased sampling strategy:\n"; - run(RandomWalks_Usecase(dataset, true), traversal_id_t::HORIZONTAL, 1); - - std::cout << "### Node2Vec sampling strategy:\n"; - run(RandomWalks_Usecase(dataset, true), traversal_id_t::HORIZONTAL, 2); - run(RandomWalks_Usecase(dataset, true), traversal_id_t::HORIZONTAL, 3); - - std::cout << "##### Vertical traversal strategy:\n"; - - std::cout << "### Uniform sampling strategy:\n"; - run(RandomWalks_Usecase(dataset, true), traversal_id_t::VERTICAL, 0); - - std::cout << "### Biased sampling strategy:\n"; - run(RandomWalks_Usecase(dataset, true), traversal_id_t::VERTICAL, 1); - - std::cout << "### Node2Vec sampling strategy:\n"; - run(RandomWalks_Usecase(dataset, true), traversal_id_t::VERTICAL, 2); - run(RandomWalks_Usecase(dataset, true), traversal_id_t::VERTICAL, 3); - - // FIXME: consider returning non-zero for situations that warrant it (eg. if - // the algo ran but the results are invalid, if a benchmark threshold is - // exceeded, etc.) - return 0; -} diff --git a/cpp/tests/sampling/random_walks_test.cu b/cpp/tests/sampling/random_walks_test.cu deleted file mode 100644 index 1015e21cc29..00000000000 --- a/cpp/tests/sampling/random_walks_test.cu +++ /dev/null @@ -1,283 +0,0 @@ -/* - * Copyright (c) 2021-2022, NVIDIA CORPORATION. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "cuda_profiler_api.h" -#include "gtest/gtest.h" - -#include -#include - -#include -#include -#include -#include - -#include -#include - -#include - -#include "random_walks_utils.cuh" - -#include -#include -#include -#include -#include -#include -#include - -namespace { // anonym. -template -void fill_start(raft::handle_t const& handle, - rmm::device_uvector& d_start, - index_t num_vertices) -{ - index_t num_paths = d_start.size(); - - thrust::transform(handle.get_thrust_policy(), - thrust::make_counting_iterator(0), - thrust::make_counting_iterator(num_paths), - - d_start.begin(), - [num_vertices] __device__(auto indx) { return indx % num_vertices; }); -} -} // namespace - -namespace impl_details = cugraph::detail::original; - -enum class traversal_id_t : int { HORIZONTAL = 0, VERTICAL }; - -struct RandomWalks_Usecase { - std::string graph_file_full_path{}; - bool test_weighted{false}; - - RandomWalks_Usecase(std::string const& graph_file_path, bool test_weighted) - : test_weighted(test_weighted) - { - if ((graph_file_path.length() > 0) && (graph_file_path[0] != '/')) { - graph_file_full_path = cugraph::test::get_rapids_dataset_root_dir() + "/" + graph_file_path; - } else { - graph_file_full_path = graph_file_path; - } - }; -}; - -class Tests_RandomWalks - : public ::testing::TestWithParam> { - public: - Tests_RandomWalks() {} - - static void SetUpTestCase() {} - static void TearDownTestCase() {} - - virtual void SetUp() {} - virtual void TearDown() {} - - template - void run_current_test(std::tuple const& configuration) - { - raft::handle_t handle{}; - - // debuf info: - // - // std::cout << "read graph file: " << configuration.graph_file_full_path << std::endl; - - traversal_id_t trv_id = std::get<0>(configuration); - int sampling_id = std::get<1>(configuration); - auto const& target = std::get<2>(configuration); - - cugraph::graph_t graph(handle); - std::tie(graph, std::ignore) = - cugraph::test::read_graph_from_matrix_market_file( - handle, target.graph_file_full_path, target.test_weighted, false); - - auto graph_view = graph.view(); - - // call random_walks: - start_random_walks(handle, graph_view, trv_id, sampling_id); - } - - template - void start_random_walks(raft::handle_t const& handle, - graph_vt const& graph_view, - traversal_id_t trv_id, - int sampling_id) - { - using vertex_t = typename graph_vt::vertex_type; - using edge_t = typename graph_vt::edge_type; - using weight_t = typename graph_vt::weight_type; - using real_t = float; - - edge_t num_paths = 10; - rmm::device_uvector d_start(num_paths, handle.get_stream()); - - vertex_t num_vertices = graph_view.number_of_vertices(); - fill_start(handle, d_start, num_vertices); - - // 0-copy const device view: - // - impl_details::device_const_vector_view d_start_view{d_start.data(), - num_paths}; - - edge_t max_depth{10}; - - weight_t p{4}; - weight_t q{8}; - - if (trv_id == traversal_id_t::HORIZONTAL) { - // `node2vec` without alpha buffer: - // - if (sampling_id == 2) { - auto ret_tuple = cugraph::random_walks( - handle, - graph_view, - d_start_view.begin(), - num_paths, - max_depth, - false, - std::make_unique(sampling_id, p, q, false)); - - // check results: - // - bool test_all_paths = cugraph::test::host_check_rw_paths(handle, - graph_view, - std::get<0>(ret_tuple), - std::get<1>(ret_tuple), - std::get<2>(ret_tuple)); - - ASSERT_TRUE(test_all_paths); - } - - // the alpha buffer case should also be tested for `node2vec` - // and for the others is irrelevant, so this block is necessary - // for any sampling method: - // - { - auto ret_tuple = cugraph::random_walks( - handle, - graph_view, - d_start_view.begin(), - num_paths, - max_depth, - false, - std::make_unique(sampling_id, p, q, true)); - - // check results: - // - bool test_all_paths = cugraph::test::host_check_rw_paths(handle, - graph_view, - std::get<0>(ret_tuple), - std::get<1>(ret_tuple), - std::get<2>(ret_tuple)); - - ASSERT_TRUE(test_all_paths); - } - } else { // VERTICAL: needs to be force-called via detail - if (sampling_id == 0) { - impl_details::uniform_selector_t selector{handle, graph_view, real_t{0}}; - - auto ret_tuple = cugraph::detail::random_walks_impl( - handle, // required to prevent clang-format to separate functin name from its namespace - graph_view, - d_start_view, - max_depth, - selector); - - // check results: - // - bool test_all_paths = cugraph::test::host_check_rw_paths(handle, - graph_view, - std::get<0>(ret_tuple), - std::get<1>(ret_tuple), - std::get<2>(ret_tuple)); - - if (!test_all_paths) - std::cout << "starting seed on failure: " << std::get<3>(ret_tuple) << '\n'; - - ASSERT_TRUE(test_all_paths); - } else if (sampling_id == 1) { - impl_details::biased_selector_t selector{handle, graph_view, real_t{0}}; - - auto ret_tuple = cugraph::detail::random_walks_impl( - handle, // required to prevent clang-format to separate functin name from its namespace - graph_view, - d_start_view, - max_depth, - selector); - - // check results: - // - bool test_all_paths = cugraph::test::host_check_rw_paths(handle, - graph_view, - std::get<0>(ret_tuple), - std::get<1>(ret_tuple), - std::get<2>(ret_tuple)); - - if (!test_all_paths) - std::cout << "starting seed on failure: " << std::get<3>(ret_tuple) << '\n'; - - ASSERT_TRUE(test_all_paths); - } else { - impl_details::node2vec_selector_t selector{ - handle, graph_view, real_t{0}, p, q, num_paths}; - - auto ret_tuple = cugraph::detail::random_walks_impl( - handle, // required to prevent clang-format to separate functin name from its namespace - graph_view, - d_start_view, - max_depth, - selector); - - // check results: - // - bool test_all_paths = cugraph::test::host_check_rw_paths(handle, - graph_view, - std::get<0>(ret_tuple), - std::get<1>(ret_tuple), - std::get<2>(ret_tuple)); - - if (!test_all_paths) - std::cout << "starting seed on failure: " << std::get<3>(ret_tuple) << '\n'; - - ASSERT_TRUE(test_all_paths); - } - } - } -}; - -TEST_P(Tests_RandomWalks, Initialize_i32_i32_f) -{ - run_current_test(GetParam()); -} - -INSTANTIATE_TEST_SUITE_P( - simple_test, - Tests_RandomWalks, - ::testing::Combine(::testing::Values(traversal_id_t::HORIZONTAL, traversal_id_t::VERTICAL), - ::testing::Values(int{0}, int{1}, int{2}), - ::testing::Values(RandomWalks_Usecase("test/datasets/karate.mtx", true), - RandomWalks_Usecase("test/datasets/web-Google.mtx", true), - RandomWalks_Usecase("test/datasets/ljournal-2008.mtx", true), - RandomWalks_Usecase("test/datasets/webbase-1M.mtx", true)))); - -CUGRAPH_TEST_PROGRAM_MAIN() diff --git a/cpp/tests/sampling/rw_low_level_test.cu b/cpp/tests/sampling/rw_low_level_test.cu deleted file mode 100644 index 7727ee20d86..00000000000 --- a/cpp/tests/sampling/rw_low_level_test.cu +++ /dev/null @@ -1,1512 +0,0 @@ -/* - * Copyright (c) 2021-2022, NVIDIA CORPORATION. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "cuda_profiler_api.h" -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include - -#include "random_walks_utils.cuh" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -template -using vector_test_t = cugraph::detail::original::device_vec_t; // for debug purposes - -namespace { // anonym. - -template -bool check_col_indices(raft::handle_t const& handle, - vector_test_t const& d_crt_out_degs, - vector_test_t const& d_col_indx, - index_t num_paths) -{ - bool all_indices_within_degs = thrust::all_of( - handle.get_thrust_policy(), - thrust::make_counting_iterator(0), - thrust::make_counting_iterator(num_paths), - [p_d_col_indx = cugraph::detail::original::raw_const_ptr(d_col_indx), - p_d_crt_out_degs = - cugraph::detail::original::raw_const_ptr(d_crt_out_degs)] __device__(auto indx) { - if (p_d_crt_out_degs[indx] > 0) - return ((p_d_col_indx[indx] >= 0) && (p_d_col_indx[indx] < p_d_crt_out_degs[indx])); - else - return true; - }); - return all_indices_within_degs; -} - -template -void next_biased(raft::handle_t const& handle, - vector_test_t const& d_src_v, - vector_test_t const& d_rnd, - vector_test_t& d_next_v, - selector_t const& selector) -{ - thrust::transform(handle.get_thrust_policy(), - d_src_v.begin(), - d_src_v.end(), - d_rnd.begin(), - d_next_v.begin(), - [sampler = selector.get_strategy()] __device__(auto src_v_indx, auto rnd_val) { - auto next_vw = sampler(src_v_indx, rnd_val); - return (next_vw.has_value() ? thrust::get<0>(*next_vw) : src_v_indx); - }); -} - -// simulates max_depth==1 traversal of multiple paths, -// where num_paths = distance(begin, end), below: -// -template -void next_node2vec(raft::handle_t const& handle, - vector_test_t const& d_src_v, - vector_test_t> const& d_prev_v, - vector_test_t const& d_rnd, - vector_test_t& d_next_v, - selector_t const& selector) -{ - size_t num_paths{d_src_v.size()}; - auto begin = thrust::make_zip_iterator(thrust::make_tuple( - d_src_v.begin(), d_prev_v.begin(), thrust::make_counting_iterator(0))); - auto end = thrust::make_zip_iterator(thrust::make_tuple( - d_src_v.end(), d_prev_v.end(), thrust::make_counting_iterator(num_paths))); - - thrust::transform(handle.get_thrust_policy(), - begin, - end, - d_rnd.begin(), - d_next_v.begin(), - [sampler = selector.get_strategy()] __device__(auto tpl, auto rnd_val) { - vertex_t src_v = thrust::get<0>(tpl); - - size_t path_index = thrust::get<2>(tpl); - - if (thrust::get<1>(tpl) != thrust::nullopt) { - vertex_t prev_v = *thrust::get<1>(tpl); - - auto next_vw = sampler(src_v, rnd_val, prev_v, path_index, false); - return (next_vw.has_value() ? thrust::get<0>(*next_vw) : src_v); - } else { - return src_v; - } - }); -} - -template -void alpha_node2vec(std::vector const& row_offsets, - std::vector const& col_indices, - std::vector& weights, // to be scaled! - std::vector> const& v_pred, - std::vector const& v_crt, - weight_t p, - weight_t q) -{ - auto num_vs = v_crt.size(); - for (size_t indx = 0; indx < num_vs; ++indx) { - auto src_v = v_crt[indx]; - - size_t num_neighbors = row_offsets[src_v + 1] - row_offsets[src_v]; - - if (num_neighbors == 0) { continue; } - - if (v_pred[indx].has_value()) { - auto pred_v = *(v_pred[indx]); - - for (auto offset_indx = row_offsets[src_v]; offset_indx < row_offsets[src_v + 1]; - ++offset_indx) { - auto next_v = col_indices[offset_indx]; - - weight_t alpha{0}; - - if (next_v == pred_v) { - alpha = 1.0 / p; - } else { - auto begin = col_indices.begin() + row_offsets[pred_v]; - auto end = col_indices.begin() + row_offsets[pred_v + 1]; - auto it_found = std::find(begin, end, next_v); - - if (it_found != end) { - alpha = 1.0; - } else { - alpha = 1.0 / q; - } - } - - weights[offset_indx] *= alpha; // scale weights - } - } - } -} - -} // namespace - -// FIXME (per rlratzel request): -// This test may be considered an e2e test -// which could be moved to a different test suite: -// -struct RandomWalksPrimsTest : public ::testing::Test { -}; - -TEST_F(RandomWalksPrimsTest, SimpleGraphRWStart) -{ - using namespace cugraph::detail; - - using vertex_t = int32_t; - using edge_t = vertex_t; - using weight_t = float; - using index_t = vertex_t; - - raft::handle_t handle{}; - - edge_t num_edges = 8; - vertex_t num_vertices = 6; - - std::vector v_src{0, 1, 1, 2, 2, 2, 3, 4}; - std::vector v_dst{1, 3, 4, 0, 1, 3, 5, 5}; - std::vector v_w{0.1, 1.1, 2.1, 3.1, 4.1, 5.1, 6.1, 7.1}; - - auto graph = cugraph::test::make_graph( - handle, v_src, v_dst, std::optional>{v_w}, num_vertices, num_edges); - - auto graph_view = graph.view(); - - std::vector v_ro = - cugraph::test::to_host(handle, graph_view.local_edge_partition_view().offsets()); - std::vector v_ci = - cugraph::test::to_host(handle, graph_view.local_edge_partition_view().indices()); - std::vector v_vs = - cugraph::test::to_host(handle, *(graph_view.local_edge_partition_view().weights())); - - std::vector v_ro_expected{0, 1, 3, 6, 7, 8, 8}; - std::vector v_ci_expected{1, 3, 4, 0, 1, 3, 5, 5}; - std::vector v_vs_expected{0.1, 1.1, 2.1, 3.1, 4.1, 5.1, 6.1, 7.1}; - - EXPECT_EQ(v_ro, v_ro_expected); - EXPECT_EQ(v_ci, v_ci_expected); - EXPECT_EQ(v_vs, v_vs_expected); - - index_t num_paths = 4; - index_t max_depth = 3; - index_t total_sz = num_paths * max_depth; - - std::vector v_coalesced(total_sz, -1); - std::vector w_coalesced(total_sz - num_paths, -1); - - vector_test_t d_coalesced_v(total_sz, handle.get_stream()); - vector_test_t d_coalesced_w(total_sz - num_paths, handle.get_stream()); - - raft::update_device( - d_coalesced_v.data(), v_coalesced.data(), d_coalesced_v.size(), handle.get_stream()); - raft::update_device( - d_coalesced_w.data(), w_coalesced.data(), d_coalesced_w.size(), handle.get_stream()); - - std::vector v_start{1, 0, 4, 2}; - vector_test_t d_start(num_paths, handle.get_stream()); - - raft::update_device(d_start.data(), v_start.data(), d_start.size(), handle.get_stream()); - - vector_test_t d_sizes(num_paths, handle.get_stream()); - - random_walker_t rand_walker{handle, num_vertices, num_paths, max_depth}; - - rand_walker.start(d_start, d_coalesced_v, d_sizes); - - std::vector v_coalesced_exp{1, -1, -1, 0, -1, -1, 4, -1, -1, 2, -1, -1}; - raft::update_host( - v_coalesced.data(), original::raw_const_ptr(d_coalesced_v), total_sz, handle.get_stream()); - EXPECT_EQ(v_coalesced, v_coalesced_exp); - - std::vector v_sizes{1, 1, 1, 1}; - std::vector v_sz_exp(num_paths); - raft::update_host( - v_sz_exp.data(), original::raw_const_ptr(d_sizes), num_paths, handle.get_stream()); - - EXPECT_EQ(v_sizes, v_sz_exp); -} - -TEST_F(RandomWalksPrimsTest, SimpleGraphCoalesceExperiments) -{ - using namespace cugraph::detail; - - using vertex_t = int32_t; - using edge_t = vertex_t; - using weight_t = float; - using index_t = vertex_t; - - raft::handle_t handle{}; - - edge_t num_edges = 8; - vertex_t num_vertices = 6; - - std::vector v_src{0, 1, 1, 2, 2, 2, 3, 4}; - std::vector v_dst{1, 3, 4, 0, 1, 3, 5, 5}; - std::vector v_w{0.1, 1.1, 2.1, 3.1, 4.1, 5.1, 6.1, 7.1}; - - auto graph = cugraph::test::make_graph( - handle, v_src, v_dst, std::optional>{v_w}, num_vertices, num_edges); - - auto graph_view = graph.view(); - - index_t num_paths = 4; - index_t max_depth = 3; - index_t total_sz = num_paths * max_depth; - - std::vector v_coalesced(total_sz, -1); - std::vector w_coalesced(total_sz - num_paths, -1); - - vector_test_t d_coalesced_v(total_sz, handle.get_stream()); - vector_test_t d_coalesced_w(total_sz - num_paths, handle.get_stream()); - - raft::update_device( - d_coalesced_v.data(), v_coalesced.data(), d_coalesced_v.size(), handle.get_stream()); - raft::update_device( - d_coalesced_w.data(), w_coalesced.data(), d_coalesced_w.size(), handle.get_stream()); - - std::vector v_start{1, 0, 4, 2}; - vector_test_t d_start(num_paths, handle.get_stream()); - - raft::update_device(d_start.data(), v_start.data(), d_start.size(), handle.get_stream()); - - vector_test_t d_sizes(num_paths, handle.get_stream()); - - random_walker_t rand_walker{handle, num_vertices, num_paths, max_depth}; - - auto d_out_degs = rand_walker.get_out_degs(graph_view); - EXPECT_EQ(static_cast(num_vertices), d_out_degs.size()); - - std::vector v_out_degs(num_vertices); - raft::update_host( - v_out_degs.data(), original::raw_const_ptr(d_out_degs), num_vertices, handle.get_stream()); - - std::vector v_out_degs_exp{1, 2, 3, 1, 1, 0}; - EXPECT_EQ(v_out_degs, v_out_degs_exp); - - rand_walker.start(d_start, d_coalesced_v, d_sizes); - - // update crt_out_degs: - // - vector_test_t d_crt_out_degs(num_paths, handle.get_stream()); - rand_walker.gather_from_coalesced( - d_coalesced_v, d_out_degs, d_sizes, d_crt_out_degs, max_depth, num_paths); - - std::vector v_crt_out_degs(num_paths); - raft::update_host( - v_crt_out_degs.data(), original::raw_const_ptr(d_crt_out_degs), num_paths, handle.get_stream()); - - std::vector v_crt_out_degs_exp{2, 1, 1, 3}; - EXPECT_EQ(v_crt_out_degs, v_crt_out_degs_exp); -} - -TEST_F(RandomWalksPrimsTest, SimpleGraphColExtraction) -{ - using namespace cugraph::detail; - - using vertex_t = int32_t; - using edge_t = vertex_t; - using weight_t = float; - using index_t = vertex_t; - - raft::handle_t handle{}; - - edge_t num_edges = 8; - vertex_t num_vertices = 6; - - std::vector v_src{0, 1, 1, 2, 2, 2, 3, 4}; - std::vector v_dst{1, 3, 4, 0, 1, 3, 5, 5}; - std::vector v_w{0.1, 1.1, 2.1, 3.1, 4.1, 5.1, 6.1, 7.1}; - - auto graph = cugraph::test::make_graph( - handle, v_src, v_dst, std::optional>{v_w}, num_vertices, num_edges); - - auto graph_view = graph.view(); - - index_t num_paths = 4; - index_t max_depth = 3; - index_t total_sz = num_paths * max_depth; - - std::vector v_coalesced(total_sz, -1); - std::vector w_coalesced(total_sz - num_paths, -1); - - vector_test_t d_coalesced_v(total_sz, handle.get_stream()); - vector_test_t d_coalesced_w(total_sz - num_paths, handle.get_stream()); - - raft::update_device( - d_coalesced_v.data(), v_coalesced.data(), d_coalesced_v.size(), handle.get_stream()); - raft::update_device( - d_coalesced_w.data(), w_coalesced.data(), d_coalesced_w.size(), handle.get_stream()); - - std::vector v_start{1, 0, 4, 2}; - vector_test_t d_start(num_paths, handle.get_stream()); - - raft::update_device(d_start.data(), v_start.data(), d_start.size(), handle.get_stream()); - - vector_test_t d_sizes(num_paths, handle.get_stream()); - - random_walker_t rand_walker{handle, num_vertices, num_paths, max_depth}; - - auto d_out_degs = rand_walker.get_out_degs(graph_view); - - rand_walker.start(d_start, d_coalesced_v, d_sizes); - - // update crt_out_degs: - // - vector_test_t d_crt_out_degs(num_paths, handle.get_stream()); - rand_walker.gather_from_coalesced( - d_coalesced_v, d_out_degs, d_sizes, d_crt_out_degs, max_depth, num_paths); - - col_indx_extract_t col_extractor{handle, - graph_view, - original::raw_ptr(d_crt_out_degs), - original::raw_ptr(d_sizes), - num_paths, - max_depth}; - - // typically given by random engine: - // - std::vector v_col_indx{1, 0, 0, 2}; - vector_test_t d_col_indx(num_paths, handle.get_stream()); - - raft::update_device(d_col_indx.data(), v_col_indx.data(), d_col_indx.size(), handle.get_stream()); - - vector_test_t d_next_v(num_paths, handle.get_stream()); - vector_test_t d_next_w(num_paths, handle.get_stream()); - - col_extractor(d_coalesced_v, d_col_indx, d_next_v, d_next_w); - - std::vector v_next_v(num_paths); - std::vector v_next_w(num_paths); - - raft::update_host( - v_next_v.data(), original::raw_const_ptr(d_next_v), num_paths, handle.get_stream()); - raft::update_host( - v_next_w.data(), original::raw_const_ptr(d_next_w), num_paths, handle.get_stream()); - - std::vector v_next_v_exp{4, 1, 5, 3}; - std::vector v_next_w_exp{2.1f, 0.1f, 7.1f, 5.1f}; - - EXPECT_EQ(v_next_v, v_next_v_exp); - EXPECT_EQ(v_next_w, v_next_w_exp); -} - -TEST_F(RandomWalksPrimsTest, SimpleGraphRndGenColIndx) -{ - using namespace cugraph::detail; - - using vertex_t = int32_t; - using edge_t = vertex_t; - using weight_t = float; - using index_t = vertex_t; - using real_t = float; - using seed_t = long; - - using random_engine_t = rrandom_gen_t; - - raft::handle_t handle{}; - - edge_t num_edges = 8; - vertex_t num_vertices = 6; - - std::vector v_src{0, 1, 1, 2, 2, 2, 3, 4}; - std::vector v_dst{1, 3, 4, 0, 1, 3, 5, 5}; - std::vector v_w{0.1, 1.1, 2.1, 3.1, 4.1, 5.1, 6.1, 7.1}; - - auto graph = cugraph::test::make_graph( - handle, v_src, v_dst, std::optional>{v_w}, num_vertices, num_edges); - - auto graph_view = graph.view(); - - index_t num_paths = 4; - index_t max_depth = 3; - index_t total_sz = num_paths * max_depth; - - std::vector v_coalesced(total_sz, -1); - std::vector w_coalesced(total_sz - num_paths, -1); - - vector_test_t d_coalesced_v(total_sz, handle.get_stream()); - vector_test_t d_coalesced_w(total_sz - num_paths, handle.get_stream()); - - raft::update_device( - d_coalesced_v.data(), v_coalesced.data(), d_coalesced_v.size(), handle.get_stream()); - raft::update_device( - d_coalesced_w.data(), w_coalesced.data(), d_coalesced_w.size(), handle.get_stream()); - - std::vector v_start{1, 0, 4, 2}; - vector_test_t d_start(num_paths, handle.get_stream()); - - raft::update_device(d_start.data(), v_start.data(), d_start.size(), handle.get_stream()); - - vector_test_t d_sizes(num_paths, handle.get_stream()); - - random_walker_t rand_walker{handle, num_vertices, num_paths, max_depth}; - - auto d_out_degs = rand_walker.get_out_degs(graph_view); - - rand_walker.start(d_start, d_coalesced_v, d_sizes); - - // update crt_out_degs: - // - vector_test_t d_crt_out_degs(num_paths, handle.get_stream()); - rand_walker.gather_from_coalesced( - d_coalesced_v, d_out_degs, d_sizes, d_crt_out_degs, max_depth, num_paths); - - // random engine generated: - // - vector_test_t d_col_indx(num_paths, handle.get_stream()); - vector_test_t d_random(num_paths, handle.get_stream()); - - seed_t seed = static_cast(std::time(nullptr)); - random_engine_t rgen(handle, num_paths, d_random, seed); - rgen.generate_col_indices(d_crt_out_degs, d_col_indx); - - bool all_indices_within_degs = check_col_indices(handle, d_crt_out_degs, d_col_indx, num_paths); - - ASSERT_TRUE(all_indices_within_degs); -} - -TEST_F(RandomWalksPrimsTest, SimpleGraphUpdatePathSizes) -{ - using namespace cugraph::detail; - - using vertex_t = int32_t; - using edge_t = vertex_t; - using weight_t = float; - using index_t = vertex_t; - using real_t = float; - using seed_t = long; - - raft::handle_t handle{}; - - edge_t num_edges = 8; - vertex_t num_vertices = 6; - - std::vector v_src{0, 1, 1, 2, 2, 2, 3, 4}; - std::vector v_dst{1, 3, 4, 0, 1, 3, 5, 5}; - std::vector v_w{0.1, 1.1, 2.1, 3.1, 4.1, 5.1, 6.1, 7.1}; - - auto graph = cugraph::test::make_graph( - handle, v_src, v_dst, std::optional>{v_w}, num_vertices, num_edges); - - auto graph_view = graph.view(); - - index_t num_paths = 4; - index_t max_depth = 3; - index_t total_sz = num_paths * max_depth; - - std::vector v_coalesced(total_sz, -1); - std::vector w_coalesced(total_sz - num_paths, -1); - - vector_test_t d_coalesced_v(total_sz, handle.get_stream()); - vector_test_t d_coalesced_w(total_sz - num_paths, handle.get_stream()); - - raft::update_device( - d_coalesced_v.data(), v_coalesced.data(), d_coalesced_v.size(), handle.get_stream()); - raft::update_device( - d_coalesced_w.data(), w_coalesced.data(), d_coalesced_w.size(), handle.get_stream()); - - std::vector v_start{1, 0, 4, 2}; - vector_test_t d_start(num_paths, handle.get_stream()); - - raft::update_device(d_start.data(), v_start.data(), d_start.size(), handle.get_stream()); - - vector_test_t d_sizes(num_paths, handle.get_stream()); - - random_walker_t rand_walker{handle, num_vertices, num_paths, max_depth}; - - auto d_out_degs = rand_walker.get_out_degs(graph_view); - - rand_walker.start(d_start, d_coalesced_v, d_sizes); - - // Fixed set of out-degs, as opposed to have them generated by the algorithm. - // That's because I want to test a certain functionality in isolation - // - std::vector v_crt_out_degs{2, 0, 1, 0}; - vector_test_t d_crt_out_degs(num_paths, handle.get_stream()); - raft::update_device( - d_crt_out_degs.data(), v_crt_out_degs.data(), d_crt_out_degs.size(), handle.get_stream()); - - rand_walker.update_path_sizes(d_crt_out_degs, d_sizes); - - std::vector v_sizes(num_paths); - raft::update_host( - v_sizes.data(), original::raw_const_ptr(d_sizes), num_paths, handle.get_stream()); - std::vector v_sizes_exp{2, 1, 2, 1}; - // i.e., corresponding 0-entries in crt-out-degs, don't get updated; - - EXPECT_EQ(v_sizes, v_sizes_exp); -} - -TEST_F(RandomWalksPrimsTest, SimpleGraphScatterUpdate) -{ - using namespace cugraph::detail; - - using vertex_t = int32_t; - using edge_t = vertex_t; - using weight_t = float; - using index_t = vertex_t; - - raft::handle_t handle{}; - - edge_t num_edges = 8; - vertex_t num_vertices = 6; - - std::vector v_src{0, 1, 1, 2, 2, 2, 3, 4}; - std::vector v_dst{1, 3, 4, 0, 1, 3, 5, 5}; - std::vector v_w{0.1, 1.1, 2.1, 3.1, 4.1, 5.1, 6.1, 7.1}; - - auto graph = cugraph::test::make_graph( - handle, v_src, v_dst, std::optional>{v_w}, num_vertices, num_edges); - - auto graph_view = graph.view(); - - index_t num_paths = 4; - index_t max_depth = 3; - index_t total_sz = num_paths * max_depth; - - std::vector v_coalesced(total_sz, -1); - std::vector w_coalesced(total_sz - num_paths, -1); - - vector_test_t d_coalesced_v(total_sz, handle.get_stream()); - vector_test_t d_coalesced_w(total_sz - num_paths, handle.get_stream()); - - raft::update_device( - d_coalesced_v.data(), v_coalesced.data(), d_coalesced_v.size(), handle.get_stream()); - raft::update_device( - d_coalesced_w.data(), w_coalesced.data(), d_coalesced_w.size(), handle.get_stream()); - - std::vector v_start{1, 0, 4, 2}; - vector_test_t d_start(num_paths, handle.get_stream()); - - raft::update_device(d_start.data(), v_start.data(), d_start.size(), handle.get_stream()); - - vector_test_t d_sizes(num_paths, handle.get_stream()); - - random_walker_t rand_walker{handle, num_vertices, num_paths, max_depth}; - - auto d_out_degs = rand_walker.get_out_degs(graph_view); - - rand_walker.start(d_start, d_coalesced_v, d_sizes); - - // update crt_out_degs: - // - vector_test_t d_crt_out_degs(num_paths, handle.get_stream()); - rand_walker.gather_from_coalesced( - d_coalesced_v, d_out_degs, d_sizes, d_crt_out_degs, max_depth, num_paths); - - col_indx_extract_t col_extractor{handle, - graph_view, - original::raw_ptr(d_crt_out_degs), - original::raw_ptr(d_sizes), - num_paths, - max_depth}; - - // typically given by random engine: - // - std::vector v_col_indx{1, 0, 0, 2}; - vector_test_t d_col_indx(num_paths, handle.get_stream()); - - raft::update_device(d_col_indx.data(), v_col_indx.data(), d_col_indx.size(), handle.get_stream()); - - vector_test_t d_next_v(num_paths, handle.get_stream()); - vector_test_t d_next_w(num_paths, handle.get_stream()); - - col_extractor(d_coalesced_v, d_col_indx, d_next_v, d_next_w); - - rand_walker.update_path_sizes(d_crt_out_degs, d_sizes); - - // check start(): - // - { - std::vector v_coalesced_exp{1, -1, -1, 0, -1, -1, 4, -1, -1, 2, -1, -1}; - raft::update_host( - v_coalesced.data(), original::raw_const_ptr(d_coalesced_v), total_sz, handle.get_stream()); - EXPECT_EQ(v_coalesced, v_coalesced_exp); - } - - // check crt_out_degs: - // - { - std::vector v_crt_out_degs(num_paths); - raft::update_host(v_crt_out_degs.data(), - original::raw_const_ptr(d_crt_out_degs), - num_paths, - handle.get_stream()); - std::vector v_crt_out_degs_exp{2, 1, 1, 3}; - EXPECT_EQ(v_crt_out_degs, v_crt_out_degs_exp); - } - - // check paths sizes update: - // - { - std::vector v_sizes(num_paths); - raft::update_host( - v_sizes.data(), original::raw_const_ptr(d_sizes), num_paths, handle.get_stream()); - std::vector v_sizes_exp{2, 2, 2, 2}; - // i.e., corresponding 0-entries in crt-out-degs, don't get updated; - EXPECT_EQ(v_sizes, v_sizes_exp); - } - - // check next step: - // - { - std::vector v_next_v(num_paths); - std::vector v_next_w(num_paths); - - raft::update_host( - v_next_v.data(), original::raw_const_ptr(d_next_v), num_paths, handle.get_stream()); - raft::update_host( - v_next_w.data(), original::raw_const_ptr(d_next_w), num_paths, handle.get_stream()); - - std::vector v_next_v_exp{4, 1, 5, 3}; - std::vector v_next_w_exp{2.1f, 0.1f, 7.1f, 5.1f}; - - EXPECT_EQ(v_next_v, v_next_v_exp); - EXPECT_EQ(v_next_w, v_next_w_exp); - } - - rand_walker.scatter_vertices(d_next_v, d_coalesced_v, d_crt_out_degs, d_sizes); - rand_walker.scatter_weights(d_next_w, d_coalesced_w, d_crt_out_degs, d_sizes); - - // check vertex/weight scatter: - // - { - raft::update_host( - v_coalesced.data(), original::raw_const_ptr(d_coalesced_v), total_sz, handle.get_stream()); - raft::update_host(w_coalesced.data(), - original::raw_const_ptr(d_coalesced_w), - total_sz - num_paths, - handle.get_stream()); - - std::vector v_coalesced_exp{1, 4, -1, 0, 1, -1, 4, 5, -1, 2, 3, -1}; - std::vector w_coalesced_exp{2.1, -1, 0.1, -1, 7.1, -1, 5.1, -1}; - - EXPECT_EQ(v_coalesced, v_coalesced_exp); - EXPECT_EQ(w_coalesced, w_coalesced_exp); - } -} - -TEST_F(RandomWalksPrimsTest, SimpleGraphCoalesceDefragment) -{ - using namespace cugraph::detail; - - using vertex_t = int32_t; - using edge_t = vertex_t; - using weight_t = float; - using index_t = vertex_t; - - raft::handle_t handle{}; - - edge_t num_edges = 8; - vertex_t num_vertices = 6; - - std::vector v_src{0, 1, 1, 2, 2, 2, 3, 4}; - std::vector v_dst{1, 3, 4, 0, 1, 3, 5, 5}; - std::vector v_w{0.1, 1.1, 2.1, 3.1, 4.1, 5.1, 6.1, 7.1}; - - auto graph = cugraph::test::make_graph( - handle, v_src, v_dst, std::optional>{v_w}, num_vertices, num_edges); - - auto graph_view = graph.view(); - - index_t num_paths = 4; - index_t max_depth = 3; - index_t total_sz = num_paths * max_depth; - - std::vector v_sizes{1, 2, 2, 1}; - vector_test_t d_sizes(num_paths, handle.get_stream()); - raft::update_device(d_sizes.data(), v_sizes.data(), d_sizes.size(), handle.get_stream()); - - std::vector v_coalesced(total_sz, -1); - v_coalesced[0] = 3; - v_coalesced[max_depth] = 5; - v_coalesced[max_depth + 1] = 2; - v_coalesced[2 * max_depth] = 4; - v_coalesced[2 * max_depth + 1] = 0; - v_coalesced[3 * max_depth] = 1; - - std::vector w_coalesced(total_sz - num_paths, -1); - w_coalesced[max_depth - 1] = 10.1; - w_coalesced[2 * max_depth - 2] = 11.2; - - vector_test_t d_coalesced_v(total_sz, handle.get_stream()); - vector_test_t d_coalesced_w(total_sz - num_paths, handle.get_stream()); - - raft::update_device( - d_coalesced_v.data(), v_coalesced.data(), d_coalesced_v.size(), handle.get_stream()); - raft::update_device( - d_coalesced_w.data(), w_coalesced.data(), d_coalesced_w.size(), handle.get_stream()); - - random_walker_t rand_walker{handle, num_vertices, num_paths, max_depth}; - - rand_walker.stop(d_coalesced_v, d_coalesced_w, d_sizes); - - // check vertex/weight defragment: - // - { - v_coalesced.resize(d_coalesced_v.size()); - w_coalesced.resize(d_coalesced_w.size()); - - raft::update_host(v_coalesced.data(), - original::raw_const_ptr(d_coalesced_v), - d_coalesced_v.size(), - handle.get_stream()); - raft::update_host(w_coalesced.data(), - original::raw_const_ptr(d_coalesced_w), - d_coalesced_w.size(), - handle.get_stream()); - - std::vector v_coalesced_exp{3, 5, 2, 4, 0, 1}; - std::vector w_coalesced_exp{10.1, 11.2}; - - EXPECT_EQ(v_coalesced, v_coalesced_exp); - EXPECT_EQ(w_coalesced, w_coalesced_exp); - } -} - -TEST_F(RandomWalksPrimsTest, SimpleGraphRandomWalk) -{ - using vertex_t = int32_t; - using edge_t = vertex_t; - using weight_t = float; - using index_t = vertex_t; - using real_t = float; - - raft::handle_t handle{}; - - edge_t num_edges = 8; - vertex_t num_vertices = 6; - - std::vector v_src{0, 1, 1, 2, 2, 2, 3, 4}; - std::vector v_dst{1, 3, 4, 0, 1, 3, 5, 5}; - std::vector v_w{0.1, 1.1, 2.1, 3.1, 4.1, 5.1, 6.1, 7.1}; - - auto graph = cugraph::test::make_graph( - handle, v_src, v_dst, std::optional>{v_w}, num_vertices, num_edges); - - auto graph_view = graph.view(); - - auto v_ro = cugraph::test::to_host(handle, graph_view.local_edge_partition_view().offsets()); - auto v_ci = cugraph::test::to_host(handle, graph_view.local_edge_partition_view().indices()); - auto v_vals = cugraph::test::to_host(handle, *(graph_view.local_edge_partition_view().weights())); - - std::vector v_start{1, 0, 4, 2}; - vector_test_t d_v_start(v_start.size(), handle.get_stream()); - raft::update_device(d_v_start.data(), v_start.data(), d_v_start.size(), handle.get_stream()); - - index_t num_paths = v_start.size(); - index_t max_depth = 5; - - // 0-copy const device view: - // - cugraph::detail::original::device_const_vector_view d_start_view{ - d_v_start.data(), num_paths}; - using graph_t = decltype(graph_view); - - cugraph::detail::original::uniform_selector_t selector{ - handle, graph_view, real_t{0}}; - - auto quad = - cugraph::detail::random_walks_impl(handle, graph_view, d_start_view, max_depth, selector); - - auto& d_coalesced_v = std::get<0>(quad); - auto& d_coalesced_w = std::get<1>(quad); - auto& d_sizes = std::get<2>(quad); - auto seed0 = std::get<3>(quad); - - bool test_all_paths = - cugraph::test::host_check_rw_paths(handle, graph_view, d_coalesced_v, d_coalesced_w, d_sizes); - - if (!test_all_paths) std::cout << "starting seed on failure: " << seed0 << '\n'; - - ASSERT_TRUE(test_all_paths); -} - -TEST(RandomWalksQuery, GraphRWQueryOffsets) -{ - using vertex_t = int32_t; - using edge_t = vertex_t; - using weight_t = float; - using index_t = vertex_t; - - raft::handle_t handle{}; - - edge_t num_edges = 8; - vertex_t num_vertices = 6; - - std::vector v_src{0, 1, 1, 2, 2, 2, 3, 4}; - std::vector v_dst{1, 3, 4, 0, 1, 3, 5, 5}; - std::vector v_w{0.1, 1.1, 2.1, 3.1, 4.1, 5.1, 6.1, 7.1}; - - auto graph = cugraph::test::make_graph( - handle, v_src, v_dst, std::optional>{v_w}, num_vertices, num_edges); - - auto graph_view = graph.view(); - - auto v_ro = cugraph::test::to_host(handle, graph_view.local_edge_partition_view().offsets()); - auto v_ci = cugraph::test::to_host(handle, graph_view.local_edge_partition_view().indices()); - auto v_vals = cugraph::test::to_host(handle, *(graph_view.local_edge_partition_view().weights())); - - std::vector v_start{1, 0, 4, 2}; - vector_test_t d_v_start(v_start.size(), handle.get_stream()); - raft::update_device(d_v_start.data(), v_start.data(), d_v_start.size(), handle.get_stream()); - - index_t num_paths = v_start.size(); - index_t max_depth = 5; - - // 0-copy const device view: - // - cugraph::detail::original::device_const_vector_view d_start_view{ - d_v_start.data(), num_paths}; - using graph_t = decltype(graph_view); - using real_t = float; - cugraph::detail::original::uniform_selector_t selector{ - handle, graph_view, real_t{0}}; - - auto quad = - cugraph::detail::random_walks_impl(handle, graph_view, d_start_view, max_depth, selector); - - auto& d_v_sizes = std::get<2>(quad); - auto seed0 = std::get<3>(quad); - - auto triplet = cugraph::query_rw_sizes_offsets( - handle, num_paths, cugraph::detail::original::raw_const_ptr(d_v_sizes)); - - auto& d_v_offsets = std::get<0>(triplet); - auto& d_w_sizes = std::get<1>(triplet); - auto& d_w_offsets = std::get<2>(triplet); - - bool test_paths_sz = - cugraph::test::host_check_query_rw(handle, d_v_sizes, d_v_offsets, d_w_sizes, d_w_offsets); - - if (!test_paths_sz) std::cout << "starting seed on failure: " << seed0 << '\n'; - - ASSERT_TRUE(test_paths_sz); -} - -TEST(RandomWalksSpecialCase, SingleRandomWalk) -{ - using vertex_t = int32_t; - using edge_t = vertex_t; - using weight_t = float; - using index_t = vertex_t; - - raft::handle_t handle{}; - - edge_t num_edges = 8; - vertex_t num_vertices = 6; - - std::vector v_src{0, 1, 1, 2, 2, 2, 3, 4}; - std::vector v_dst{1, 3, 4, 0, 1, 3, 5, 5}; - std::vector v_w{0.1, 1.1, 2.1, 3.1, 4.1, 5.1, 6.1, 7.1}; - - auto graph = cugraph::test::make_graph( - handle, v_src, v_dst, std::optional>{v_w}, num_vertices, num_edges); - - auto graph_view = graph.view(); - - auto v_ro = cugraph::test::to_host(handle, graph_view.local_edge_partition_view().offsets()); - auto v_ci = cugraph::test::to_host(handle, graph_view.local_edge_partition_view().indices()); - auto v_vals = cugraph::test::to_host(handle, *(graph_view.local_edge_partition_view().weights())); - - std::vector v_start{2}; - vector_test_t d_v_start(v_start.size(), handle.get_stream()); - raft::update_device(d_v_start.data(), v_start.data(), d_v_start.size(), handle.get_stream()); - - index_t num_paths = v_start.size(); - index_t max_depth = 5; - - // 0-copy const device view: - // - cugraph::detail::original::device_const_vector_view d_start_view{ - d_v_start.data(), num_paths}; - using graph_t = decltype(graph_view); - using real_t = float; - cugraph::detail::original::uniform_selector_t selector{ - handle, graph_view, real_t{0}}; - - auto quad = - cugraph::detail::random_walks_impl(handle, graph_view, d_start_view, max_depth, selector); - - auto& d_coalesced_v = std::get<0>(quad); - auto& d_coalesced_w = std::get<1>(quad); - auto& d_sizes = std::get<2>(quad); - auto seed0 = std::get<3>(quad); - - bool test_all_paths = - cugraph::test::host_check_rw_paths(handle, graph_view, d_coalesced_v, d_coalesced_w, d_sizes); - - if (!test_all_paths) std::cout << "starting seed on failure: " << seed0 << '\n'; - - ASSERT_TRUE(test_all_paths); -} - -TEST(RandomWalksSpecialCase, UnweightedGraph) -{ - using vertex_t = int32_t; - using edge_t = vertex_t; - using weight_t = float; - using index_t = vertex_t; - - raft::handle_t handle{}; - - edge_t num_edges = 8; - vertex_t num_vertices = 6; - - std::vector v_src{0, 1, 1, 2, 2, 2, 3, 4}; - std::vector v_dst{1, 3, 4, 0, 1, 3, 5, 5}; - - auto graph = cugraph::test::make_graph( - handle, v_src, v_dst, std::nullopt, num_vertices, num_edges); // un-weighted - - auto graph_view = graph.view(); - - auto v_ro = cugraph::test::to_host(handle, graph_view.local_edge_partition_view().offsets()); - auto v_ci = cugraph::test::to_host(handle, graph_view.local_edge_partition_view().indices()); - ASSERT_TRUE(graph_view.local_edge_partition_view().weights().has_value() == false); - - std::vector v_start{2}; - vector_test_t d_v_start(v_start.size(), handle.get_stream()); - raft::update_device(d_v_start.data(), v_start.data(), d_v_start.size(), handle.get_stream()); - - index_t num_paths = v_start.size(); - index_t max_depth = 5; - - // 0-copy const device view: - // - cugraph::detail::original::device_const_vector_view d_start_view{ - d_v_start.data(), num_paths}; - using graph_t = decltype(graph_view); - using real_t = float; - cugraph::detail::original::uniform_selector_t selector{ - handle, graph_view, real_t{0}}; - - auto quad = - cugraph::detail::random_walks_impl(handle, graph_view, d_start_view, max_depth, selector); - - auto& d_coalesced_v = std::get<0>(quad); - auto& d_coalesced_w = std::get<1>(quad); - auto& d_sizes = std::get<2>(quad); - auto seed0 = std::get<3>(quad); - - bool test_all_paths = - cugraph::test::host_check_rw_paths(handle, graph_view, d_coalesced_v, d_coalesced_w, d_sizes); - - if (!test_all_paths) std::cout << "starting seed on failure: " << seed0 << '\n'; - - ASSERT_TRUE(test_all_paths); -} - -TEST(RandomWalksPadded, SimpleGraph) -{ - using vertex_t = int32_t; - using edge_t = vertex_t; - using weight_t = float; - using index_t = vertex_t; - - raft::handle_t handle{}; - - edge_t num_edges = 8; - vertex_t num_vertices = 6; - - std::vector v_src{0, 1, 1, 2, 2, 2, 3, 4}; - std::vector v_dst{1, 3, 4, 0, 1, 3, 5, 5}; - std::vector v_w{0.1, 1.1, 2.1, 3.1, 4.1, 5.1, 6.1, 7.1}; - - auto graph = cugraph::test::make_graph( - handle, v_src, v_dst, std::optional>{v_w}, num_vertices, num_edges); - - auto graph_view = graph.view(); - - auto v_ro = cugraph::test::to_host(handle, graph_view.local_edge_partition_view().offsets()); - auto v_ci = cugraph::test::to_host(handle, graph_view.local_edge_partition_view().indices()); - auto v_vals = cugraph::test::to_host(handle, *(graph_view.local_edge_partition_view().weights())); - - std::vector v_start{2}; - vector_test_t d_v_start(v_start.size(), handle.get_stream()); - raft::update_device(d_v_start.data(), v_start.data(), d_v_start.size(), handle.get_stream()); - - index_t num_paths = v_start.size(); - index_t max_depth = 5; - - // 0-copy const device view: - // - cugraph::detail::original::device_const_vector_view d_start_view{ - d_v_start.data(), num_paths}; - bool use_padding{true}; - - using graph_t = decltype(graph_view); - using real_t = float; - cugraph::detail::original::uniform_selector_t selector{ - handle, graph_view, real_t{0}}; - - auto quad = cugraph::detail::random_walks_impl( - handle, graph_view, d_start_view, max_depth, selector, use_padding); - - auto& d_coalesced_v = std::get<0>(quad); - auto& d_coalesced_w = std::get<1>(quad); - auto& d_sizes = std::get<2>(quad); - auto seed0 = std::get<3>(quad); - - ASSERT_TRUE(d_sizes.size() == 0); - - bool test_all_paths = cugraph::test::host_check_rw_paths( - handle, graph_view, d_coalesced_v, d_coalesced_w, d_sizes, num_paths); - - if (!test_all_paths) std::cout << "starting seed on failure: " << seed0 << '\n'; - - ASSERT_TRUE(test_all_paths); -} - -TEST(RandomWalksUtility, PathsToCOO) -{ - using namespace cugraph::detail; - - using vertex_t = int32_t; - using edge_t = vertex_t; - using weight_t = float; - using index_t = vertex_t; - - raft::handle_t handle{}; - - std::vector v_sizes{2, 1, 3, 5, 1}; - std::vector v_coalesced{5, 3, 4, 9, 0, 1, 6, 2, 7, 3, 2, 5}; - std::vector w_coalesced{0.1, 2.1, 3.1, 4.1, 5.1, 6.1, 7.1}; - - auto num_paths = v_sizes.size(); - auto total_sz = v_coalesced.size(); - auto num_edges = w_coalesced.size(); - - ASSERT_TRUE(num_edges == total_sz - num_paths); - - vector_test_t d_coalesced_v(total_sz, handle.get_stream()); - vector_test_t d_sizes(num_paths, handle.get_stream()); - - raft::update_device( - d_coalesced_v.data(), v_coalesced.data(), d_coalesced_v.size(), handle.get_stream()); - raft::update_device(d_sizes.data(), v_sizes.data(), d_sizes.size(), handle.get_stream()); - - index_t coalesced_v_sz = d_coalesced_v.size(); - - auto tpl_coo_offsets = cugraph::convert_paths_to_coo(handle, - coalesced_v_sz, - static_cast(num_paths), - d_coalesced_v.release(), - d_sizes.release()); - - auto&& d_src = std::move(std::get<0>(tpl_coo_offsets)); - auto&& d_dst = std::move(std::get<1>(tpl_coo_offsets)); - auto&& d_offsets = std::move(std::get<2>(tpl_coo_offsets)); - - ASSERT_TRUE(d_src.size() == num_edges); - ASSERT_TRUE(d_dst.size() == num_edges); - - std::vector v_src(num_edges, 0); - std::vector v_dst(num_edges, 0); - std::vector v_offsets(d_offsets.size(), 0); - - raft::update_host( - v_src.data(), original::raw_const_ptr(d_src), d_src.size(), handle.get_stream()); - raft::update_host( - v_dst.data(), original::raw_const_ptr(d_dst), d_dst.size(), handle.get_stream()); - raft::update_host( - v_offsets.data(), original::raw_const_ptr(d_offsets), d_offsets.size(), handle.get_stream()); - - std::vector v_src_exp{5, 9, 0, 6, 2, 7, 3}; - std::vector v_dst_exp{3, 0, 1, 2, 7, 3, 2}; - std::vector v_offsets_exp{0, 1, 3}; - - EXPECT_EQ(v_src, v_src_exp); - EXPECT_EQ(v_dst, v_dst_exp); - EXPECT_EQ(v_offsets, v_offsets_exp); -} - -TEST(BiasedRandomWalks, SelectorSmallGraph) -{ - raft::handle_t handle{}; - - using vertex_t = int32_t; - using edge_t = vertex_t; - using weight_t = float; - using index_t = vertex_t; - using real_t = weight_t; - - edge_t num_edges = 8; - vertex_t num_vertices = 6; - - /* - 0 --(.1)--> 1 --(1.1)--> 4 - /|\ /\ | | - | / | | - (5.1) (3.1)(2.1) (3.2) - | / | | - | / \|/ \|/ - 2 --(4.1)-->3 --(7.2)--> 5 - */ - std::vector v_src{0, 1, 1, 2, 2, 2, 3, 4}; - std::vector v_dst{1, 3, 4, 0, 1, 3, 5, 5}; - std::vector v_w{0.1f, 2.1f, 1.1f, 5.1f, 3.1f, 4.1f, 7.2f, 3.2f}; - - auto graph = cugraph::test::make_graph( - handle, v_src, v_dst, std::optional>{v_w}, num_vertices, num_edges); - - std::vector v_rnd{0.0, - 1.0, - 0.2, // 0 - 0.0, - 1.0, - 0.8, // 1 - 0.0, - 1.0, - 0.5, // 2 - 0.0, - 1.0, // 3 - 0.0, - 1.0, // 4 - 0.0, - 1.0}; // 5 - - std::vector v_src_v{0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 4, 4, 5, 5}; - - vector_test_t d_rnd(v_rnd.size(), handle.get_stream()); - vector_test_t d_src_v(v_src_v.size(), handle.get_stream()); - - EXPECT_EQ(d_rnd.size(), d_src_v.size()); - - raft::update_device(d_rnd.data(), v_rnd.data(), d_rnd.size(), handle.get_stream()); - raft::update_device(d_src_v.data(), v_src_v.data(), d_src_v.size(), handle.get_stream()); - - auto graph_view = graph.view(); - - cugraph::detail::original::biased_selector_t selector{handle, graph_view, 0.0f}; - - std::vector h_correct_sum_w{0.1f, 3.2f, 12.3f, 7.2f, 3.2f, 0.0f}; - std::vector v_sum_weights(num_vertices); - - auto const& d_sum_weights = selector.get_sum_weights(); - - raft::update_host( - v_sum_weights.data(), d_sum_weights.data(), d_sum_weights.size(), handle.get_stream()); - - // test floating point equality between vectors: - // - weight_t eps = 1.0e-6f; - - auto end = - thrust::make_zip_iterator(thrust::make_tuple(v_sum_weights.end(), h_correct_sum_w.end())); - auto it = thrust::find_if( - thrust::host, - thrust::make_zip_iterator(thrust::make_tuple(v_sum_weights.begin(), h_correct_sum_w.begin())), - end, - [eps](auto const& tpl) { return std::abs(thrust::get<0>(tpl) - thrust::get<1>(tpl)) > eps; }); - - EXPECT_EQ(it, end); - - vector_test_t d_next_v(v_src_v.size(), handle.get_stream()); - - next_biased(handle, d_src_v, d_rnd, d_next_v, selector); - - std::vector v_next_v(v_src_v.size()); - - raft::update_host(v_next_v.data(), d_next_v.data(), v_src_v.size(), handle.get_stream()); - - std::vector h_next_v{1, - 1, - 1, /*<-0*/ - 3, - 4, - 4, /*<-1*/ - 0, - 3, - 1, /*<-2*/ - 5, - 5, /*<-3*/ - 5, - 5, /*<-4*/ - 5, - 5}; /*<-5*/ - - EXPECT_EQ(v_next_v, h_next_v); -} - -TEST(Node2VecRandomWalks, Node2VecSmallGraph) -{ - raft::handle_t handle{}; - - using vertex_t = int32_t; - using edge_t = vertex_t; - using weight_t = float; - using index_t = vertex_t; - using real_t = weight_t; - - weight_t p = 2.0; - weight_t q = 4.0; - - edge_t num_edges = 8; - vertex_t num_vertices = 6; - - // Step 1: graph construction: - // - /* - 0 --(.1)--> 1 --(1.1)--> 4 - /|\ /\ | | - | / | | - (5.1) (3.1)(2.1) (3.2) - | / | | - | / \|/ \|/ - 2 --(4.1)-->3 --(7.2)--> 5 - */ - std::vector v_src{0, 1, 1, 2, 2, 2, 3, 4}; - std::vector v_dst{1, 3, 4, 0, 1, 3, 5, 5}; - std::vector v_w(num_edges, 1.0); //{0.1f, 2.1f, 1.1f, 5.1f, 3.1f, 4.1f, 7.2f, 3.2f}; - - auto graph = cugraph::test::make_graph( - handle, v_src, v_dst, std::optional>{v_w}, num_vertices, num_edges); - - std::vector v_rnd{0.2, 0.5, 1.0, 0.1, 0.8}; - std::vector v_src_v{0, 1, 3, 4, 5}; - std::vector> v_pred_v{2, 0, 1, 1, 4}; - - vector_test_t d_rnd(v_rnd.size(), handle.get_stream()); - vector_test_t d_src_v(v_src_v.size(), handle.get_stream()); - - EXPECT_EQ(d_rnd.size(), d_src_v.size()); - - raft::update_device(d_rnd.data(), v_rnd.data(), d_rnd.size(), handle.get_stream()); - raft::update_device(d_src_v.data(), v_src_v.data(), d_src_v.size(), handle.get_stream()); - - auto graph_view = graph.view(); - - // Step 2: `node2vec` selection on original graph: - // - cugraph::detail::original::node2vec_selector_t n2v_selector{handle, graph_view, 0.0f, p, q}; - - vector_test_t> d_pred_v(v_pred_v.size(), handle.get_stream()); - - raft::update_device(d_pred_v.data(), v_pred_v.data(), v_pred_v.size(), handle.get_stream()); - - vector_test_t d_next_v(v_src_v.size(), handle.get_stream()); - - // `node2vec` stepping: - // - next_node2vec(handle, d_src_v, d_pred_v, d_rnd, d_next_v, n2v_selector); - - std::vector n2v_next_v(v_src_v.size()); - raft::update_host(n2v_next_v.data(), d_next_v.data(), v_src_v.size(), handle.get_stream()); - - EXPECT_EQ(n2v_next_v.size(), d_src_v.size()); - - // Step 3: construct similar graph, just with - // alpha scaled weights; - // - std::vector scaled_weights(v_w); - auto row_offsets = - cugraph::test::to_host(handle, graph_view.local_edge_partition_view().offsets()); - auto col_indices = - cugraph::test::to_host(handle, graph_view.local_edge_partition_view().indices()); - - std::vector v_ro{0, 1, 3, 6, 7, 8, 8}; - std::vector v_ci{1, 3, 4, 0, 1, 3, 5, 5}; - - EXPECT_EQ(row_offsets, v_ro); - EXPECT_EQ(col_indices, v_ci); - EXPECT_EQ(scaled_weights.size(), static_cast(num_edges)); - - alpha_node2vec(row_offsets, col_indices, scaled_weights, v_pred_v, v_src_v, p, q); - - auto scaled_graph = - cugraph::test::make_graph(handle, - v_src, - v_dst, - std::optional>{scaled_weights}, - num_vertices, - num_edges); - - auto scaled_graph_view = scaled_graph.view(); - - // Step 4: biased selection on alpha scaled graph: - // - cugraph::detail::original::biased_selector_t selector{handle, scaled_graph_view, 0.0f}; - - next_biased(handle, d_src_v, d_rnd, d_next_v, selector); - - std::vector biased_next_v(v_src_v.size()); - raft::update_host(biased_next_v.data(), d_next_v.data(), v_src_v.size(), handle.get_stream()); - - // Step 5: compare `node2vec` on original graph - // with biased on graph with alpha scaled weights: - // - EXPECT_EQ(biased_next_v, n2v_next_v); -} - -TEST(Node2VecRandomWalks, CachedNode2VecSmallGraph) -{ - raft::handle_t handle{}; - - using vertex_t = int32_t; - using edge_t = vertex_t; - using weight_t = float; - using index_t = vertex_t; - using real_t = weight_t; - - weight_t p = 2.0; - weight_t q = 4.0; - - edge_t num_edges = 8; - vertex_t num_vertices = 6; - - // Step 1: graph construction: - // - /* - 0 --(.1)--> 1 --(1.1)--> 4 - /|\ /\ | | - | / | | - (5.1) (3.1)(2.1) (3.2) - | / | | - | / \|/ \|/ - 2 --(4.1)-->3 --(7.2)--> 5 - */ - std::vector v_src{0, 1, 1, 2, 2, 2, 3, 4}; - std::vector v_dst{1, 3, 4, 0, 1, 3, 5, 5}; - std::vector v_w(num_edges, 1.0); //{0.1f, 2.1f, 1.1f, 5.1f, 3.1f, 4.1f, 7.2f, 3.2f}; - - auto graph = cugraph::test::make_graph( - handle, v_src, v_dst, std::optional>{v_w}, num_vertices, num_edges); - - std::vector v_rnd{0.2, 0.5, 1.0, 0.1, 0.8}; - std::vector v_src_v{0, 1, 3, 4, 5}; - std::vector> v_pred_v{2, 0, 1, 1, 4}; - - vector_test_t d_rnd(v_rnd.size(), handle.get_stream()); - vector_test_t d_src_v(v_src_v.size(), handle.get_stream()); - - EXPECT_EQ(d_rnd.size(), d_src_v.size()); - - raft::update_device(d_rnd.data(), v_rnd.data(), d_rnd.size(), handle.get_stream()); - raft::update_device(d_src_v.data(), v_src_v.data(), d_src_v.size(), handle.get_stream()); - - auto graph_view = graph.view(); - - // Step 2: `node2vec` selection on original graph: - // - // CAVEAT: next_node2vec(), steps in parallel, so it simulates - // traversing multiple paths (of size max_depth == 1); - // if ignored, this creates a data race on the cached - // alpha buffer! - // - edge_t num_paths(d_src_v.size()); - cugraph::detail::original::node2vec_selector_t n2v_selector{ - handle, graph_view, 0.0f, p, q, num_paths}; // use cached approach - - auto const& d_cached_alpha = n2v_selector.get_alpha_cache(); - - size_t expected_max_degree{3}; - EXPECT_EQ(d_cached_alpha.size(), expected_max_degree * num_paths); - - auto&& coalesced_alpha = n2v_selector.get_strategy().get_alpha_buffer(); - - ASSERT_TRUE(coalesced_alpha != thrust::nullopt); - - EXPECT_EQ(static_cast(thrust::get<0>(*coalesced_alpha)), expected_max_degree); - EXPECT_EQ(thrust::get<1>(*coalesced_alpha), num_paths); - EXPECT_EQ(thrust::get<2>(*coalesced_alpha), d_cached_alpha.data()); - - vector_test_t> d_pred_v(v_pred_v.size(), handle.get_stream()); - - raft::update_device(d_pred_v.data(), v_pred_v.data(), v_pred_v.size(), handle.get_stream()); - - vector_test_t d_next_v(v_src_v.size(), handle.get_stream()); - - // `node2vec` stepping: - // - // CAVEAT: next_node2vec(), steps in parallel, so it simulates - // traversing multiple paths (of size max_depth == 1); - // if ignored, this creates a data race on the cached - // alpha buffer! - // - next_node2vec(handle, d_src_v, d_pred_v, d_rnd, d_next_v, n2v_selector); - - std::vector n2v_next_v(v_src_v.size()); - raft::update_host(n2v_next_v.data(), d_next_v.data(), v_src_v.size(), handle.get_stream()); - - EXPECT_EQ(n2v_next_v.size(), d_src_v.size()); - - // Step 3: construct similar graph, just with - // alpha scaled weights; - // - std::vector scaled_weights(v_w); - auto row_offsets = - cugraph::test::to_host(handle, graph_view.local_edge_partition_view().offsets()); - auto col_indices = - cugraph::test::to_host(handle, graph_view.local_edge_partition_view().indices()); - - std::vector v_ro{0, 1, 3, 6, 7, 8, 8}; - std::vector v_ci{1, 3, 4, 0, 1, 3, 5, 5}; - - EXPECT_EQ(row_offsets, v_ro); - EXPECT_EQ(col_indices, v_ci); - EXPECT_EQ(scaled_weights.size(), static_cast(num_edges)); - - alpha_node2vec(row_offsets, col_indices, scaled_weights, v_pred_v, v_src_v, p, q); - - auto scaled_graph = - cugraph::test::make_graph(handle, - v_src, - v_dst, - std::optional>{scaled_weights}, - num_vertices, - num_edges); - - auto scaled_graph_view = scaled_graph.view(); - - // Step 4: biased selection on alpha scaled graph: - // - cugraph::detail::original::biased_selector_t selector{handle, scaled_graph_view, 0.0f}; - - next_biased(handle, d_src_v, d_rnd, d_next_v, selector); - - std::vector biased_next_v(v_src_v.size()); - raft::update_host(biased_next_v.data(), d_next_v.data(), v_src_v.size(), handle.get_stream()); - - // Step 5: compare `node2vec` on original graph - // with biased on graph with alpha scaled weights: - // - EXPECT_EQ(biased_next_v, n2v_next_v); -} diff --git a/cpp/tests/sampling/sg_random_walks_test.cpp b/cpp/tests/sampling/sg_random_walks_test.cpp index fecdd54c886..5a9bb6f1555 100644 --- a/cpp/tests/sampling/sg_random_walks_test.cpp +++ b/cpp/tests/sampling/sg_random_walks_test.cpp @@ -37,11 +37,13 @@ struct UniformRandomWalks_Usecase { template std::tuple, std::optional>> operator()(raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view, raft::device_span start_vertices, size_t num_paths) { - return cugraph::uniform_random_walks(handle, graph_view, start_vertices, num_paths, seed); + return cugraph::uniform_random_walks( + handle, graph_view, edge_weight_view, start_vertices, num_paths, seed); } bool expect_throw() { return false; } @@ -55,11 +57,15 @@ struct BiasedRandomWalks_Usecase { template std::tuple, std::optional>> operator()(raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view, raft::device_span start_vertices, size_t num_paths) { - return cugraph::biased_random_walks(handle, graph_view, start_vertices, num_paths, seed); + CUGRAPH_EXPECTS(edge_weight_view.has_value(), "Biased random walk requires edge weights."); + + return cugraph::biased_random_walks( + handle, graph_view, *edge_weight_view, start_vertices, num_paths, seed); } // FIXME: Not currently implemented @@ -76,12 +82,14 @@ struct Node2VecRandomWalks_Usecase { template std::tuple, std::optional>> operator()(raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view, raft::device_span start_vertices, size_t num_paths) { return cugraph::node2vec_random_walks(handle, graph_view, + edge_weight_view, start_vertices, num_paths, static_cast(p), @@ -117,7 +125,7 @@ class Tests_RandomWalks : public ::testing::TestWithParam { } bool renumber{true}; - auto [graph, d_renumber_map_labels] = + auto [graph, edge_weights, d_renumber_map_labels] = cugraph::test::construct_graph( handle, input_usecase, randomwalks_usecase.test_weighted, renumber); @@ -128,7 +136,10 @@ class Tests_RandomWalks : public ::testing::TestWithParam { std::cout << "construct_graph took " << elapsed_time * 1e-6 << " s.\n"; } - auto graph_view = graph.view(); + auto graph_view = graph.view(); + auto edge_weight_view = + edge_weights ? std::make_optional((*edge_weights).view()) : std::nullopt; + edge_t num_paths = std::min(edge_t{10}, graph_view.number_of_vertices()); edge_t max_length = 10; rmm::device_uvector d_start(num_paths, handle.get_stream()); @@ -145,6 +156,7 @@ class Tests_RandomWalks : public ::testing::TestWithParam { EXPECT_THROW( randomwalks_usecase(handle, graph_view, + edge_weight_view, raft::device_span{d_start.data(), d_start.size()}, max_length), std::exception); @@ -152,6 +164,7 @@ class Tests_RandomWalks : public ::testing::TestWithParam { auto [d_vertices, d_weights] = randomwalks_usecase(handle, graph_view, + edge_weight_view, raft::device_span{d_start.data(), d_start.size()}, max_length); @@ -165,6 +178,7 @@ class Tests_RandomWalks : public ::testing::TestWithParam { if (randomwalks_usecase.check_correctness) { cugraph::test::random_walks_validate(handle, graph_view, + edge_weight_view, std::move(d_start), std::move(d_vertices), std::move(d_weights), diff --git a/cpp/tests/sampling/sg_uniform_neighbor_sampling.cu b/cpp/tests/sampling/sg_uniform_neighbor_sampling.cu index ebe92738224..bdb6ded3b91 100644 --- a/cpp/tests/sampling/sg_uniform_neighbor_sampling.cu +++ b/cpp/tests/sampling/sg_uniform_neighbor_sampling.cu @@ -50,7 +50,7 @@ class Tests_Uniform_Neighbor_Sampling hr_clock.start(); } - auto [graph, renumber_map_labels] = + auto [graph, edge_weights, renumber_map_labels] = cugraph::test::construct_graph( handle, input_usecase, true, true); @@ -61,7 +61,10 @@ class Tests_Uniform_Neighbor_Sampling std::cout << "construct_graph took " << elapsed_time * 1e-6 << " s.\n"; } - auto graph_view = graph.view(); + auto graph_view = graph.view(); + auto edge_weight_view = + edge_weights ? std::make_optional((*edge_weights).view()) : std::nullopt; + constexpr edge_t indices_per_source = 2; constexpr vertex_t repetitions_per_vertex = 5; constexpr vertex_t source_sample_count = 3; @@ -85,6 +88,7 @@ class Tests_Uniform_Neighbor_Sampling EXPECT_THROW(cugraph::uniform_nbr_sample( handle, graph_view, + edge_weight_view, raft::device_span(random_sources.data(), random_sources.size()), raft::host_span(h_fan_out.data(), h_fan_out.size()), prims_usecase.flag_replacement), @@ -93,6 +97,7 @@ class Tests_Uniform_Neighbor_Sampling auto&& [d_src_out, d_dst_out, d_indices, d_counts] = cugraph::uniform_nbr_sample( handle, graph_view, + edge_weight_view, raft::device_span(random_sources.data(), random_sources.size()), raft::host_span(h_fan_out.data(), h_fan_out.size()), prims_usecase.flag_replacement); @@ -122,6 +127,7 @@ class Tests_Uniform_Neighbor_Sampling auto [d_src_in, d_dst_in, d_indices_in, d_ignore] = extract_induced_subgraphs( handle, graph_view, + edge_weight_view, raft::device_span(d_subgraph_offsets.data(), 2), raft::device_span(d_vertices.data(), d_vertices.size()), true); diff --git a/cpp/tests/structure/coarsen_graph_test.cpp b/cpp/tests/structure/coarsen_graph_test.cpp index 39b906e4833..a9a37873d3c 100644 --- a/cpp/tests/structure/coarsen_graph_test.cpp +++ b/cpp/tests/structure/coarsen_graph_test.cpp @@ -258,7 +258,7 @@ class Tests_CoarsenGraph hr_clock.start(); } - auto [graph, d_renumber_map_labels] = + auto [graph, edge_weights, d_renumber_map_labels] = cugraph::test::construct_graph( handle, input_usecase, coarsen_graph_usecase.test_weighted, renumber); @@ -270,6 +270,8 @@ class Tests_CoarsenGraph } auto graph_view = graph.view(); + auto edge_weight_view = + edge_weights ? std::make_optional((*edge_weights).view()) : std::nullopt; if (graph_view.number_of_vertices() == 0) { return; } @@ -294,8 +296,8 @@ class Tests_CoarsenGraph hr_clock.start(); } - auto [coarse_graph, coarse_vertices_to_labels] = - cugraph::coarsen_graph(handle, graph_view, d_labels.begin(), true); + auto [coarse_graph, coarse_edge_weights, coarse_vertices_to_labels] = + cugraph::coarsen_graph(handle, graph_view, edge_weight_view, d_labels.begin(), true); if (cugraph::test::g_perf) { RAFT_CUDA_TRY(cudaDeviceSynchronize()); // for consistent performance measurement @@ -309,17 +311,27 @@ class Tests_CoarsenGraph cugraph::test::to_host(handle, graph_view.local_edge_partition_view().offsets()); auto h_org_indices = cugraph::test::to_host(handle, graph_view.local_edge_partition_view().indices()); - auto h_org_weights = - cugraph::test::to_host(handle, graph_view.local_edge_partition_view().weights()); + auto h_org_weights = cugraph::test::to_host( + handle, + edge_weight_view + ? std::make_optional(raft::device_span( + (*edge_weight_view).value_firsts()[0], (*edge_weight_view).edge_counts()[0])) + : std::nullopt); auto coarse_graph_view = coarse_graph.view(); + auto coarse_edge_weight_view = + coarse_edge_weights ? std::make_optional((*coarse_edge_weights).view()) : std::nullopt; auto h_coarse_offsets = cugraph::test::to_host(handle, coarse_graph_view.local_edge_partition_view().offsets()); auto h_coarse_indices = cugraph::test::to_host(handle, coarse_graph_view.local_edge_partition_view().indices()); - auto h_coarse_weights = - cugraph::test::to_host(handle, coarse_graph_view.local_edge_partition_view().weights()); + auto h_coarse_weights = cugraph::test::to_host( + handle, + coarse_edge_weight_view ? std::make_optional(raft::device_span( + (*coarse_edge_weight_view).value_firsts()[0], + (*coarse_edge_weight_view).edge_counts()[0])) + : std::nullopt); auto h_coarse_vertices_to_labels = cugraph::test::to_host(handle, *coarse_vertices_to_labels); diff --git a/cpp/tests/structure/count_self_loops_and_multi_edges_test.cpp b/cpp/tests/structure/count_self_loops_and_multi_edges_test.cpp index d7f9658c87e..5b754badd0e 100644 --- a/cpp/tests/structure/count_self_loops_and_multi_edges_test.cpp +++ b/cpp/tests/structure/count_self_loops_and_multi_edges_test.cpp @@ -90,7 +90,9 @@ class Tests_CountSelfLoopsAndMultiEdges hr_clock.start(); } - auto [graph, d_renumber_map_labels] = + cugraph::graph_t graph(handle); + std::optional> d_renumber_map_labels{std::nullopt}; + std::tie(graph, std::ignore, d_renumber_map_labels) = cugraph::test::construct_graph( handle, input_usecase, false, renumber); @@ -132,10 +134,9 @@ class Tests_CountSelfLoopsAndMultiEdges } if (count_self_loops_and_multi_edges_usecase.check_correctness) { - cugraph::graph_t unrenumbered_graph( - handle); + cugraph::graph_t unrenumbered_graph(handle); if (renumber) { - std::tie(unrenumbered_graph, std::ignore) = + std::tie(unrenumbered_graph, std::ignore, std::ignore) = cugraph::test::construct_graph( handle, input_usecase, false, false); } diff --git a/cpp/tests/structure/degree_test.cpp b/cpp/tests/structure/degree_test.cpp index acb231b1006..17440078733 100644 --- a/cpp/tests/structure/degree_test.cpp +++ b/cpp/tests/structure/degree_test.cpp @@ -79,13 +79,15 @@ class Tests_Degree : public ::testing::TestWithParam { virtual void SetUp() {} virtual void TearDown() {} - template + template void run_current_test(Degree_Usecase const& configuration) { + using weight_t = float; // dummy + raft::handle_t handle{}; - cugraph::graph_t graph(handle); - std::tie(graph, std::ignore) = cugraph::test:: + cugraph::graph_t graph(handle); + std::tie(graph, std::ignore, std::ignore) = cugraph::test:: read_graph_from_matrix_market_file( handle, configuration.graph_file_full_path, false, false); auto graph_view = graph.view(); @@ -134,12 +136,12 @@ class Tests_Degree : public ::testing::TestWithParam { TEST_P(Tests_Degree, CheckInt32Int32FloatTransposeFalse) { - run_current_test(GetParam()); + run_current_test(GetParam()); } TEST_P(Tests_Degree, CheckInt32Int32FloatTransposeTrue) { - run_current_test(GetParam()); + run_current_test(GetParam()); } INSTANTIATE_TEST_SUITE_P(simple_test, diff --git a/cpp/tests/structure/induced_subgraph_test.cpp b/cpp/tests/structure/induced_subgraph_test.cpp index 1106d2cfd8c..e848edb4d99 100644 --- a/cpp/tests/structure/induced_subgraph_test.cpp +++ b/cpp/tests/structure/induced_subgraph_test.cpp @@ -115,7 +115,7 @@ class Tests_InducedSubgraph hr_clock.start(); } - auto [graph, d_renumber_map_labels] = + auto [graph, edge_weights, d_renumber_map_labels] = cugraph::test::construct_graph( handle, input_usecase, induced_subgraph_usecase.test_weighted, true); @@ -127,6 +127,8 @@ class Tests_InducedSubgraph } auto graph_view = graph.view(); + auto edge_weight_view = + edge_weights ? std::make_optional((*edge_weights).view()) : std::nullopt; // Construct random subgraph vertex lists std::vector h_subgraph_offsets(induced_subgraph_usecase.subgraph_sizes.size() + 1, 0); @@ -169,6 +171,7 @@ class Tests_InducedSubgraph cugraph::extract_induced_subgraphs( handle, graph_view, + edge_weight_view, raft::device_span(d_subgraph_offsets.data(), d_subgraph_offsets.size()), raft::device_span(d_subgraph_vertices.data(), d_subgraph_vertices.size()), do_expensive_check); @@ -183,7 +186,8 @@ class Tests_InducedSubgraph if (induced_subgraph_usecase.check_correctness) { auto h_subgraph_vertices = cugraph::test::to_host(handle, d_subgraph_vertices); - auto [h_offsets, h_indices, h_weights] = cugraph::test::graph_to_host_csr(handle, graph_view); + auto [h_offsets, h_indices, h_weights] = + cugraph::test::graph_to_host_csr(handle, graph_view, edge_weight_view); auto [h_reference_subgraph_edgelist_majors, h_reference_subgraph_edgelist_minors, diff --git a/cpp/tests/structure/mg_count_self_loops_and_multi_edges_test.cpp b/cpp/tests/structure/mg_count_self_loops_and_multi_edges_test.cpp index 29f0daa25b2..6f03b8018dd 100644 --- a/cpp/tests/structure/mg_count_self_loops_and_multi_edges_test.cpp +++ b/cpp/tests/structure/mg_count_self_loops_and_multi_edges_test.cpp @@ -73,7 +73,9 @@ class Tests_MGCountSelfLoopsAndMultiEdges hr_clock.start(); } - auto [mg_graph, d_mg_renumber_map_labels] = + cugraph::graph_t mg_graph(*handle_); + std::optional> d_mg_renumber_map_labels{std::nullopt}; + std::tie(mg_graph, std::ignore, d_mg_renumber_map_labels) = cugraph::test::construct_graph( *handle_, input_usecase, false, true); @@ -126,8 +128,8 @@ class Tests_MGCountSelfLoopsAndMultiEdges if (count_self_loops_and_multi_edges_usecase.check_correctness) { // 3-1. create SG graph - cugraph::graph_t sg_graph(*handle_); - std::tie(sg_graph, std::ignore) = + cugraph::graph_t sg_graph(*handle_); + std::tie(sg_graph, std::ignore, std::ignore) = cugraph::test::construct_graph( *handle_, input_usecase, false, false); diff --git a/cpp/tests/structure/mg_induced_subgraph_test.cu b/cpp/tests/structure/mg_induced_subgraph_test.cu index 6341cdd54d0..cccae48a329 100644 --- a/cpp/tests/structure/mg_induced_subgraph_test.cu +++ b/cpp/tests/structure/mg_induced_subgraph_test.cu @@ -73,7 +73,7 @@ class Tests_MGInducedSubgraph hr_clock.start(); } - auto [mg_graph, d_renumber_map_labels] = + auto [mg_graph, mg_edge_weights, d_renumber_map_labels] = cugraph::test::construct_graph( *handle_, input_usecase, induced_subgraph_usecase.test_weighted, true); @@ -85,6 +85,8 @@ class Tests_MGInducedSubgraph } auto mg_graph_view = mg_graph.view(); + auto mg_edge_weight_view = + mg_edge_weights ? std::make_optional((*mg_edge_weights).view()) : std::nullopt; int my_rank = handle_->get_comms().get_rank(); @@ -174,9 +176,10 @@ class Tests_MGInducedSubgraph cugraph::extract_induced_subgraphs( *handle_, mg_graph_view, + mg_edge_weight_view, raft::device_span(d_subgraph_offsets.data(), d_subgraph_offsets.size()), raft::device_span(d_subgraph_vertices.data(), d_subgraph_vertices.size()), - true); + false); if (cugraph::test::g_perf) { RAFT_CUDA_TRY(cudaDeviceSynchronize()); // for consistent performance measurement @@ -237,8 +240,12 @@ class Tests_MGInducedSubgraph size_t{d_subgraph_offsets.size() - 1}, handle_->get_stream()); - auto [sg_graph, sg_number_map] = cugraph::test::mg_graph_to_sg_graph( - *handle_, mg_graph_view, std::optional>{std::nullopt}, false); + auto [sg_graph, sg_edge_weights, sg_number_map] = cugraph::test::mg_graph_to_sg_graph( + *handle_, + mg_graph_view, + mg_edge_weight_view, + std::optional>{std::nullopt}, + false); if (my_rank == 0) { auto d_sg_subgraph_offsets = cugraph::test::to_device(*handle_, h_sg_subgraph_offsets); @@ -250,6 +257,7 @@ class Tests_MGInducedSubgraph cugraph::extract_induced_subgraphs( *handle_, sg_graph.view(), + sg_edge_weights ? std::make_optional((*sg_edge_weights).view()) : std::nullopt, raft::device_span(d_sg_subgraph_offsets.data(), d_sg_subgraph_offsets.size()), raft::device_span(d_sg_subgraph_vertices.data(), diff --git a/cpp/tests/structure/mg_symmetrize_test.cpp b/cpp/tests/structure/mg_symmetrize_test.cpp index 186996646c0..ced54425728 100644 --- a/cpp/tests/structure/mg_symmetrize_test.cpp +++ b/cpp/tests/structure/mg_symmetrize_test.cpp @@ -69,7 +69,7 @@ class Tests_MGSymmetrize hr_clock.start(); } - auto [mg_graph, d_mg_renumber_map_labels] = + auto [mg_graph, mg_edge_weights, d_mg_renumber_map_labels] = cugraph::test::construct_graph( *handle_, input_usecase, symmetrize_usecase.test_weighted, true); @@ -89,9 +89,10 @@ class Tests_MGSymmetrize hr_clock.start(); } - std::tie(mg_graph, d_mg_renumber_map_labels) = cugraph::symmetrize_graph( + std::tie(mg_graph, mg_edge_weights, d_mg_renumber_map_labels) = cugraph::symmetrize_graph( *handle_, std::move(mg_graph), + std::move(mg_edge_weights), d_mg_renumber_map_labels ? std::optional>(std::move(*d_mg_renumber_map_labels)) : std::nullopt, @@ -113,6 +114,7 @@ class Tests_MGSymmetrize auto [d_mg_srcs, d_mg_dsts, d_mg_weights] = cugraph::decompress_to_edgelist( *handle_, mg_graph.view(), + mg_edge_weights ? std::make_optional((*mg_edge_weights).view()) : std::nullopt, d_mg_renumber_map_labels ? std::make_optional>( (*d_mg_renumber_map_labels).data(), (*d_mg_renumber_map_labels).size()) @@ -133,17 +135,22 @@ class Tests_MGSymmetrize if (handle_->get_comms().get_rank() == int{0}) { // 3-3. create SG graph - cugraph::graph_t sg_graph(*handle_); - std::tie(sg_graph, std::ignore) = + cugraph::graph_t sg_graph(*handle_); + std::optional< + cugraph::edge_property_t, + weight_t>> + sg_edge_weights{std::nullopt}; + std::tie(sg_graph, sg_edge_weights, std::ignore) = cugraph::test::construct_graph( *handle_, input_usecase, symmetrize_usecase.test_weighted, false); // 3-4. run SG symmetrize std::optional> d_sg_renumber_map_labels{}; - std::tie(sg_graph, d_sg_renumber_map_labels) = + std::tie(sg_graph, sg_edge_weights, d_sg_renumber_map_labels) = cugraph::symmetrize_graph(*handle_, std::move(sg_graph), + std::move(sg_edge_weights), std::optional>{std::nullopt}, symmetrize_usecase.reciprocal); ASSERT_FALSE(d_sg_renumber_map_labels.has_value()); @@ -153,6 +160,7 @@ class Tests_MGSymmetrize auto [d_sg_srcs, d_sg_dsts, d_sg_weights] = cugraph::decompress_to_edgelist( *handle_, sg_graph.view(), + sg_edge_weights ? std::make_optional((*sg_edge_weights).view()) : std::nullopt, std::optional>{std::nullopt}); // 3-6. compare diff --git a/cpp/tests/structure/mg_transpose_storage_test.cpp b/cpp/tests/structure/mg_transpose_storage_test.cpp index af754cee99d..69c3e9fe233 100644 --- a/cpp/tests/structure/mg_transpose_storage_test.cpp +++ b/cpp/tests/structure/mg_transpose_storage_test.cpp @@ -68,7 +68,7 @@ class Tests_MGTransposeStorage hr_clock.start(); } - auto [mg_graph, d_mg_renumber_map_labels] = + auto [mg_graph, mg_edge_weights, d_mg_renumber_map_labels] = cugraph::test::construct_graph( *handle_, input_usecase, transpose_storage_usecase.test_weighted, true); @@ -91,12 +91,18 @@ class Tests_MGTransposeStorage hr_clock.start(); } - cugraph::graph_t - mg_storage_transposed_graph(*handle_); - std::tie(mg_storage_transposed_graph, d_mg_renumber_map_labels) = + cugraph::graph_t mg_storage_transposed_graph( + *handle_); + std::optional< + cugraph::edge_property_t, + weight_t>> + mg_storage_transposed_edge_weights{std::nullopt}; + std::tie( + mg_storage_transposed_graph, mg_storage_transposed_edge_weights, d_mg_renumber_map_labels) = cugraph::transpose_graph_storage( *handle_, std::move(mg_graph), + std::move(mg_edge_weights), d_mg_renumber_map_labels ? std::optional>{std::move(*d_mg_renumber_map_labels)} : std::nullopt); @@ -117,6 +123,9 @@ class Tests_MGTransposeStorage auto [d_mg_srcs, d_mg_dsts, d_mg_weights] = cugraph::decompress_to_edgelist( *handle_, mg_storage_transposed_graph.view(), + mg_storage_transposed_edge_weights + ? std::make_optional((*mg_storage_transposed_edge_weights).view()) + : std::nullopt, d_mg_renumber_map_labels ? std::make_optional>( (*d_mg_renumber_map_labels).data(), (*d_mg_renumber_map_labels).size()) @@ -137,8 +146,12 @@ class Tests_MGTransposeStorage if (handle_->get_comms().get_rank() == int{0}) { // 3-3. create SG graph - cugraph::graph_t sg_graph(*handle_); - std::tie(sg_graph, std::ignore) = + cugraph::graph_t sg_graph(*handle_); + std::optional< + cugraph::edge_property_t, + weight_t>> + sg_edge_weights{std::nullopt}; + std::tie(sg_graph, sg_edge_weights, std::ignore) = cugraph::test::construct_graph( *handle_, input_usecase, transpose_storage_usecase.test_weighted, false); @@ -147,6 +160,7 @@ class Tests_MGTransposeStorage auto [d_sg_srcs, d_sg_dsts, d_sg_weights] = cugraph::decompress_to_edgelist( *handle_, sg_graph.view(), + sg_edge_weights ? std::make_optional((*sg_edge_weights).view()) : std::nullopt, std::optional>{std::nullopt}); // 3-5. compare diff --git a/cpp/tests/structure/mg_transpose_test.cpp b/cpp/tests/structure/mg_transpose_test.cpp index 571de69246d..c78cd125953 100644 --- a/cpp/tests/structure/mg_transpose_test.cpp +++ b/cpp/tests/structure/mg_transpose_test.cpp @@ -68,7 +68,7 @@ class Tests_MGTranspose hr_clock.start(); } - auto [mg_graph, d_mg_renumber_map_labels] = + auto [mg_graph, mg_edge_weights, d_mg_renumber_map_labels] = cugraph::test::construct_graph( *handle_, input_usecase, transpose_usecase.test_weighted, true); @@ -88,9 +88,10 @@ class Tests_MGTranspose hr_clock.start(); } - std::tie(mg_graph, d_mg_renumber_map_labels) = cugraph::transpose_graph( + std::tie(mg_graph, mg_edge_weights, d_mg_renumber_map_labels) = cugraph::transpose_graph( *handle_, std::move(mg_graph), + std::move(mg_edge_weights), d_mg_renumber_map_labels ? std::optional>{std::move(*d_mg_renumber_map_labels)} : std::nullopt); @@ -111,6 +112,7 @@ class Tests_MGTranspose auto [d_mg_srcs, d_mg_dsts, d_mg_weights] = cugraph::decompress_to_edgelist( *handle_, mg_graph.view(), + mg_edge_weights ? std::make_optional((*mg_edge_weights).view()) : std::nullopt, d_mg_renumber_map_labels ? std::make_optional>( (*d_mg_renumber_map_labels).data(), (*d_mg_renumber_map_labels).size()) @@ -131,16 +133,21 @@ class Tests_MGTranspose if (handle_->get_comms().get_rank() == int{0}) { // 3-3. create SG graph - cugraph::graph_t sg_graph(*handle_); - std::tie(sg_graph, std::ignore) = + cugraph::graph_t sg_graph(*handle_); + std::optional< + cugraph::edge_property_t, + weight_t>> + sg_edge_weights{std::nullopt}; + std::tie(sg_graph, sg_edge_weights, std::ignore) = cugraph::test::construct_graph( *handle_, input_usecase, transpose_usecase.test_weighted, false); // 3-4. run SG transpose - std::tie(sg_graph, std::ignore) = + std::tie(sg_graph, sg_edge_weights, std::ignore) = cugraph::transpose_graph(*handle_, std::move(sg_graph), + std::move(sg_edge_weights), std::optional>{std::nullopt}); // 3-5. decompress SG results @@ -148,6 +155,7 @@ class Tests_MGTranspose auto [d_sg_srcs, d_sg_dsts, d_sg_weights] = cugraph::decompress_to_edgelist( *handle_, sg_graph.view(), + sg_edge_weights ? std::make_optional((*sg_edge_weights).view()) : std::nullopt, std::optional>{std::nullopt}); // 3-6. compare diff --git a/cpp/tests/structure/symmetrize_test.cpp b/cpp/tests/structure/symmetrize_test.cpp index a888208a060..7a6bea36d04 100644 --- a/cpp/tests/structure/symmetrize_test.cpp +++ b/cpp/tests/structure/symmetrize_test.cpp @@ -198,7 +198,7 @@ class Tests_Symmetrize hr_clock.start(); } - auto [graph, d_renumber_map_labels] = + auto [graph, edge_weights, d_renumber_map_labels] = cugraph::test::construct_graph( handle, input_usecase, symmetrize_usecase.test_weighted, renumber); @@ -216,6 +216,7 @@ class Tests_Symmetrize std::tie(d_org_srcs, d_org_dsts, d_org_weights) = cugraph::decompress_to_edgelist( handle, graph.view(), + edge_weights ? std::make_optional((*edge_weights).view()) : std::nullopt, d_renumber_map_labels ? std::make_optional>( (*d_renumber_map_labels).data(), (*d_renumber_map_labels).size()) : std::nullopt); @@ -226,8 +227,12 @@ class Tests_Symmetrize hr_clock.start(); } - std::tie(graph, d_renumber_map_labels) = cugraph::symmetrize_graph( - handle, std::move(graph), std::move(d_renumber_map_labels), symmetrize_usecase.reciprocal); + std::tie(graph, edge_weights, d_renumber_map_labels) = + cugraph::symmetrize_graph(handle, + std::move(graph), + std::move(edge_weights), + std::move(d_renumber_map_labels), + symmetrize_usecase.reciprocal); if (cugraph::test::g_perf) { RAFT_CUDA_TRY(cudaDeviceSynchronize()); // for consistent performance measurement @@ -240,6 +245,7 @@ class Tests_Symmetrize auto [d_symm_srcs, d_symm_dsts, d_symm_weights] = cugraph::decompress_to_edgelist( handle, graph.view(), + edge_weights ? std::make_optional((*edge_weights).view()) : std::nullopt, d_renumber_map_labels ? std::make_optional>( (*d_renumber_map_labels).data(), (*d_renumber_map_labels).size()) : std::nullopt); diff --git a/cpp/tests/structure/transpose_storage_test.cpp b/cpp/tests/structure/transpose_storage_test.cpp index 2ba77fc06c7..87c19fe1567 100644 --- a/cpp/tests/structure/transpose_storage_test.cpp +++ b/cpp/tests/structure/transpose_storage_test.cpp @@ -63,7 +63,7 @@ class Tests_TransposeStorage hr_clock.start(); } - auto [graph, d_renumber_map_labels] = + auto [graph, edge_weights, d_renumber_map_labels] = cugraph::test::construct_graph( handle, input_usecase, transpose_storage_usecase.test_weighted, renumber); @@ -81,6 +81,7 @@ class Tests_TransposeStorage std::tie(d_org_srcs, d_org_dsts, d_org_weights) = cugraph::decompress_to_edgelist( handle, graph.view(), + edge_weights ? std::make_optional((*edge_weights).view()) : std::nullopt, d_renumber_map_labels ? std::make_optional>( (*d_renumber_map_labels).data(), (*d_renumber_map_labels).size()) : std::nullopt); @@ -91,10 +92,14 @@ class Tests_TransposeStorage hr_clock.start(); } - cugraph::graph_t storage_transposed_graph( - handle); - std::tie(storage_transposed_graph, d_renumber_map_labels) = - transpose_graph_storage(handle, std::move(graph), std::move(d_renumber_map_labels)); + cugraph::graph_t storage_transposed_graph(handle); + std::optional< + cugraph::edge_property_t, + weight_t>> + storage_transposed_edge_weights{std::nullopt}; + std::tie(storage_transposed_graph, storage_transposed_edge_weights, d_renumber_map_labels) = + transpose_graph_storage( + handle, std::move(graph), std::move(edge_weights), std::move(d_renumber_map_labels)); if (cugraph::test::g_perf) { RAFT_CUDA_TRY(cudaDeviceSynchronize()); // for consistent performance measurement @@ -108,6 +113,9 @@ class Tests_TransposeStorage cugraph::decompress_to_edgelist( handle, storage_transposed_graph.view(), + storage_transposed_edge_weights + ? std::make_optional((*storage_transposed_edge_weights).view()) + : std::nullopt, d_renumber_map_labels ? std::make_optional>((*d_renumber_map_labels).data(), (*d_renumber_map_labels).size()) diff --git a/cpp/tests/structure/transpose_test.cpp b/cpp/tests/structure/transpose_test.cpp index 83111a860e4..23962082f3b 100644 --- a/cpp/tests/structure/transpose_test.cpp +++ b/cpp/tests/structure/transpose_test.cpp @@ -63,7 +63,7 @@ class Tests_Transpose hr_clock.start(); } - auto [graph, d_renumber_map_labels] = + auto [graph, edge_weights, d_renumber_map_labels] = cugraph::test::construct_graph( handle, input_usecase, transpose_usecase.test_weighted, renumber); @@ -81,6 +81,7 @@ class Tests_Transpose std::tie(d_org_srcs, d_org_dsts, d_org_weights) = cugraph::decompress_to_edgelist( handle, graph.view(), + edge_weights ? std::make_optional((*edge_weights).view()) : std::nullopt, d_renumber_map_labels ? std::make_optional>( (*d_renumber_map_labels).data(), (*d_renumber_map_labels).size()) : std::nullopt); @@ -91,8 +92,8 @@ class Tests_Transpose hr_clock.start(); } - std::tie(graph, d_renumber_map_labels) = - transpose_graph(handle, std::move(graph), std::move(d_renumber_map_labels)); + std::tie(graph, edge_weights, d_renumber_map_labels) = transpose_graph( + handle, std::move(graph), std::move(edge_weights), std::move(d_renumber_map_labels)); if (cugraph::test::g_perf) { RAFT_CUDA_TRY(cudaDeviceSynchronize()); // for consistent performance measurement @@ -106,6 +107,7 @@ class Tests_Transpose cugraph::decompress_to_edgelist( handle, graph.view(), + edge_weights ? std::make_optional((*edge_weights).view()) : std::nullopt, d_renumber_map_labels ? std::make_optional>((*d_renumber_map_labels).data(), (*d_renumber_map_labels).size()) diff --git a/cpp/tests/structure/weight_sum_test.cpp b/cpp/tests/structure/weight_sum_test.cpp index f113eccb041..213833037b5 100644 --- a/cpp/tests/structure/weight_sum_test.cpp +++ b/cpp/tests/structure/weight_sum_test.cpp @@ -87,18 +87,26 @@ class Tests_WeightSum : public ::testing::TestWithParam { { raft::handle_t handle{}; - cugraph::graph_t graph(handle); - std::tie(graph, std::ignore) = cugraph::test:: + cugraph::graph_t graph(handle); + std::optional< + cugraph::edge_property_t, + weight_t>> + edge_weights{std::nullopt}; + std::tie(graph, edge_weights, std::ignore) = cugraph::test:: read_graph_from_matrix_market_file( handle, configuration.graph_file_full_path, true, false); auto graph_view = graph.view(); + auto edge_weight_view = + edge_weights ? std::make_optional((*edge_weights).view()) : std::nullopt; auto h_offsets = cugraph::test::to_host(handle, graph_view.local_edge_partition_view().offsets()); auto h_indices = cugraph::test::to_host(handle, graph_view.local_edge_partition_view().indices()); - auto h_weights = - cugraph::test::to_host(handle, *(graph_view.local_edge_partition_view().weights())); + auto h_weights = cugraph::test::to_host( + handle, + raft::device_span((*edge_weight_view).value_firsts()[0], + (*edge_weight_view).edge_counts()[0])); std::vector h_reference_in_weight_sums(graph_view.number_of_vertices()); std::vector h_reference_out_weight_sums(graph_view.number_of_vertices()); @@ -119,8 +127,9 @@ class Tests_WeightSum : public ::testing::TestWithParam { RAFT_CUDA_TRY(cudaDeviceSynchronize()); // for consistent performance measurement - auto d_in_weight_sums = cugraph::compute_in_weight_sums(handle, graph_view); - auto d_out_weight_sums = cugraph::compute_out_weight_sums(handle, graph_view); + auto d_in_weight_sums = cugraph::compute_in_weight_sums(handle, graph_view, *edge_weight_view); + auto d_out_weight_sums = + cugraph::compute_out_weight_sums(handle, graph_view, *edge_weight_view); RAFT_CUDA_TRY(cudaDeviceSynchronize()); // for consistent performance measurement diff --git a/cpp/tests/traversal/bfs_test.cpp b/cpp/tests/traversal/bfs_test.cpp index 54c6568a834..63c54dc3305 100644 --- a/cpp/tests/traversal/bfs_test.cpp +++ b/cpp/tests/traversal/bfs_test.cpp @@ -109,7 +109,9 @@ class Tests_BFS : public ::testing::TestWithParam graph(handle); + std::optional> d_renumber_map_labels{std::nullopt}; + std::tie(graph, std::ignore, d_renumber_map_labels) = cugraph::test::construct_graph( handle, input_usecase, false, renumber); @@ -153,9 +155,9 @@ class Tests_BFS : public ::testing::TestWithParam unrenumbered_graph(handle); + cugraph::graph_t unrenumbered_graph(handle); if (renumber) { - std::tie(unrenumbered_graph, std::ignore) = + std::tie(unrenumbered_graph, std::ignore, std::ignore) = cugraph::test::construct_graph( handle, input_usecase, false, false); } diff --git a/cpp/tests/traversal/extract_bfs_paths_test.cu b/cpp/tests/traversal/extract_bfs_paths_test.cu index 93eb9a989b7..e2522ecb9b9 100644 --- a/cpp/tests/traversal/extract_bfs_paths_test.cu +++ b/cpp/tests/traversal/extract_bfs_paths_test.cu @@ -73,7 +73,9 @@ class Tests_ExtractBfsPaths hr_clock.start(); } - auto [graph, d_renumber_map_labels] = + cugraph::graph_t graph(handle); + std::optional> d_renumber_map_labels{std::nullopt}; + std::tie(graph, std::ignore, d_renumber_map_labels) = cugraph::test::construct_graph( handle, input_usecase, true, renumber); diff --git a/cpp/tests/traversal/k_hop_nbrs_test.cpp b/cpp/tests/traversal/k_hop_nbrs_test.cpp index fe76486ede0..c798dc837e9 100644 --- a/cpp/tests/traversal/k_hop_nbrs_test.cpp +++ b/cpp/tests/traversal/k_hop_nbrs_test.cpp @@ -129,7 +129,9 @@ class Tests_KHopNbrs hr_clock.start(); } - auto [graph, d_renumber_map_labels] = + cugraph::graph_t graph(handle); + std::optional> d_renumber_map_labels{std::nullopt}; + std::tie(graph, std::ignore, d_renumber_map_labels) = cugraph::test::construct_graph( handle, input_usecase, false, renumber); @@ -171,9 +173,9 @@ class Tests_KHopNbrs } if (k_hop_nbrs_usecase.check_correctness) { - cugraph::graph_t unrenumbered_graph(handle); + cugraph::graph_t unrenumbered_graph(handle); if (renumber) { - std::tie(unrenumbered_graph, std::ignore) = + std::tie(unrenumbered_graph, std::ignore, std::ignore) = cugraph::test::construct_graph( handle, input_usecase, false, false); } diff --git a/cpp/tests/traversal/mg_bfs_test.cpp b/cpp/tests/traversal/mg_bfs_test.cpp index 889336c2319..10524856b40 100644 --- a/cpp/tests/traversal/mg_bfs_test.cpp +++ b/cpp/tests/traversal/mg_bfs_test.cpp @@ -71,7 +71,9 @@ class Tests_MGBFS : public ::testing::TestWithParam mg_graph(*handle_); + std::optional> d_mg_renumber_map_labels{std::nullopt}; + std::tie(mg_graph, std::ignore, d_mg_renumber_map_labels) = cugraph::test::construct_graph( *handle_, input_usecase, false, true); @@ -154,8 +156,8 @@ class Tests_MGBFS : public ::testing::TestWithParam sg_graph(*handle_); - std::tie(sg_graph, std::ignore) = + cugraph::graph_t sg_graph(*handle_); + std::tie(sg_graph, std::ignore, std::ignore) = cugraph::test::construct_graph( *handle_, input_usecase, false, false); diff --git a/cpp/tests/traversal/mg_extract_bfs_paths_test.cu b/cpp/tests/traversal/mg_extract_bfs_paths_test.cu index b284e78e0c4..e55531e863b 100644 --- a/cpp/tests/traversal/mg_extract_bfs_paths_test.cu +++ b/cpp/tests/traversal/mg_extract_bfs_paths_test.cu @@ -78,7 +78,9 @@ class Tests_MGExtractBFSPaths hr_clock.start(); } - auto [mg_graph, d_mg_renumber_map_labels] = + cugraph::graph_t mg_graph(*handle_); + std::optional> d_mg_renumber_map_labels{std::nullopt}; + std::tie(mg_graph, std::ignore, d_mg_renumber_map_labels) = cugraph::test::construct_graph( *handle_, input_usecase, true, renumber); @@ -155,7 +157,9 @@ class Tests_MGExtractBFSPaths } if (extract_bfs_paths_usecase.check_correctness) { - auto [sg_graph, d_sg_renumber_map_labels] = + cugraph::graph_t sg_graph(*handle_); + std::optional> d_sg_renumber_map_labels{std::nullopt}; + std::tie(sg_graph, std::ignore, d_sg_renumber_map_labels) = cugraph::test::construct_graph( *handle_, input_usecase, true, false); diff --git a/cpp/tests/traversal/mg_k_hop_nbrs_test.cpp b/cpp/tests/traversal/mg_k_hop_nbrs_test.cpp index 0739f116db1..a1cf1a510ce 100644 --- a/cpp/tests/traversal/mg_k_hop_nbrs_test.cpp +++ b/cpp/tests/traversal/mg_k_hop_nbrs_test.cpp @@ -77,7 +77,9 @@ class Tests_MGKHopNbrs hr_clock.start(); } - auto [mg_graph, d_mg_renumber_map_labels] = + cugraph::graph_t mg_graph(*handle_); + std::optional> d_mg_renumber_map_labels{std::nullopt}; + std::tie(mg_graph, std::ignore, d_mg_renumber_map_labels) = cugraph::test::construct_graph( *handle_, input_usecase, false, true); @@ -177,8 +179,8 @@ class Tests_MGKHopNbrs // 3-3. create SG graph - cugraph::graph_t sg_graph(*handle_); - std::tie(sg_graph, std::ignore) = + cugraph::graph_t sg_graph(*handle_); + std::tie(sg_graph, std::ignore, std::ignore) = cugraph::test::construct_graph( *handle_, input_usecase, false, false); diff --git a/cpp/tests/traversal/mg_sssp_test.cpp b/cpp/tests/traversal/mg_sssp_test.cpp index 4002587dade..a2808dfebf1 100644 --- a/cpp/tests/traversal/mg_sssp_test.cpp +++ b/cpp/tests/traversal/mg_sssp_test.cpp @@ -69,7 +69,7 @@ class Tests_MGSSSP : public ::testing::TestWithParam( *handle_, input_usecase, true, true); @@ -82,6 +82,8 @@ class Tests_MGSSSP : public ::testing::TestWithParam(sssp_usecase.source) >= 0 && static_cast(sssp_usecase.source) < mg_graph_view.number_of_vertices()) @@ -102,6 +104,7 @@ class Tests_MGSSSP : public ::testing::TestWithParam(sssp_usecase.source), @@ -144,12 +147,17 @@ class Tests_MGSSSP : public ::testing::TestWithParam sg_graph(*handle_); - std::tie(sg_graph, std::ignore) = + cugraph::graph_t sg_graph(*handle_); + std::optional< + cugraph::edge_property_t, weight_t>> + sg_edge_weights{std::nullopt}; + std::tie(sg_graph, sg_edge_weights, std::ignore) = cugraph::test::construct_graph( *handle_, input_usecase, true, false); auto sg_graph_view = sg_graph.view(); + auto sg_edge_weight_view = + sg_edge_weights ? std::make_optional((*sg_edge_weights).view()) : std::nullopt; ASSERT_TRUE(mg_graph_view.number_of_vertices() == sg_graph_view.number_of_vertices()); @@ -168,6 +176,7 @@ class Tests_MGSSSP : public ::testing::TestWithParam((*sg_edge_weight_view).value_firsts()[0], + (*sg_edge_weight_view).edge_counts()[0])); auto h_mg_aggregate_distances = cugraph::test::to_host(*handle_, d_mg_aggregate_distances); auto h_mg_aggregate_predecessors = diff --git a/cpp/tests/traversal/ms_bfs_test.cu b/cpp/tests/traversal/ms_bfs_test.cu index 95ae3d4e0f6..cea72393954 100644 --- a/cpp/tests/traversal/ms_bfs_test.cu +++ b/cpp/tests/traversal/ms_bfs_test.cu @@ -150,14 +150,14 @@ class Tests_MsBfs : public ::testing::TestWithParam { raft::copy(d_sources.data(), h_sources.data(), h_sources.size(), handle.get_stream()); // create the graph - cugraph::graph_t graph(handle); + cugraph::graph_t graph(handle); rmm::device_uvector d_renumber_map_labels(0, handle.get_stream()); rmm::device_uvector d_vertices(n_vertices, handle.get_stream()); rmm::device_uvector d_weights(n_edges, handle.get_stream()); thrust::sequence( rmm::exec_policy(handle.get_stream()), d_vertices.begin(), d_vertices.end(), vertex_t{0}); - std::tie(graph, std::ignore, std::ignore) = + std::tie(graph, std::ignore, std::ignore, std::ignore) = cugraph::create_graph_from_edgelist( handle, std::move(d_vertices), diff --git a/cpp/tests/traversal/sssp_test.cpp b/cpp/tests/traversal/sssp_test.cpp index 98a2272b54a..0e575ff47c2 100644 --- a/cpp/tests/traversal/sssp_test.cpp +++ b/cpp/tests/traversal/sssp_test.cpp @@ -111,7 +111,7 @@ class Tests_SSSP : public ::testing::TestWithParam( handle, input_usecase, true, renumber); @@ -123,6 +123,8 @@ class Tests_SSSP : public ::testing::TestWithParam(sssp_usecase.source) >= 0 && static_cast(sssp_usecase.source) < graph_view.number_of_vertices()); @@ -138,6 +140,7 @@ class Tests_SSSP : public ::testing::TestWithParam(sssp_usecase.source), @@ -152,20 +155,30 @@ class Tests_SSSP : public ::testing::TestWithParam unrenumbered_graph(handle); + cugraph::graph_t unrenumbered_graph(handle); + std::optional< + cugraph::edge_property_t, weight_t>> + unrenumbered_edge_weights{std::nullopt}; if (renumber) { - std::tie(unrenumbered_graph, std::ignore) = + std::tie(unrenumbered_graph, unrenumbered_edge_weights, std::ignore) = cugraph::test::construct_graph( handle, input_usecase, true, false); } auto unrenumbered_graph_view = renumber ? unrenumbered_graph.view() : graph_view; + auto unrenumbered_edge_weight_view = + renumber + ? (unrenumbered_edge_weights ? std::make_optional((*unrenumbered_edge_weights).view()) + : std::nullopt) + : edge_weight_view; auto h_offsets = cugraph::test::to_host( handle, unrenumbered_graph_view.local_edge_partition_view().offsets()); auto h_indices = cugraph::test::to_host( handle, unrenumbered_graph_view.local_edge_partition_view().indices()); auto h_weights = cugraph::test::to_host( - handle, *(unrenumbered_graph_view.local_edge_partition_view().weights())); + handle, + raft::device_span((*unrenumbered_edge_weight_view).value_firsts()[0], + (*unrenumbered_edge_weight_view).edge_counts()[0])); auto unrenumbered_source = static_cast(sssp_usecase.source); if (renumber) { diff --git a/cpp/tests/utilities/csv_file_utilities.cu b/cpp/tests/utilities/csv_file_utilities.cu index fc0c412a731..72b84d1becd 100644 --- a/cpp/tests/utilities/csv_file_utilities.cu +++ b/cpp/tests/utilities/csv_file_utilities.cu @@ -274,7 +274,10 @@ template -std::tuple, +std::tuple, + std::optional< + cugraph::edge_property_t, + weight_t>>, std::optional>> read_graph_from_csv_file(raft::handle_t const& handle, std::string const& graph_file_full_path, @@ -285,9 +288,12 @@ read_graph_from_csv_file(raft::handle_t const& handle, read_edgelist_from_csv_file( handle, graph_file_full_path, test_weighted, store_transposed, multi_gpu); - graph_t graph(handle); + graph_t graph(handle); + std::optional< + cugraph::edge_property_t, weight_t>> + edge_weights{std::nullopt}; std::optional> renumber_map{std::nullopt}; - std::tie(graph, std::ignore, renumber_map) = cugraph:: + std::tie(graph, edge_weights, std::ignore, renumber_map) = cugraph:: create_graph_from_edgelist( handle, std::nullopt, @@ -298,7 +304,7 @@ read_graph_from_csv_file(raft::handle_t const& handle, cugraph::graph_properties_t{is_symmetric, false}, renumber); - return std::make_tuple(std::move(graph), std::move(renumber_map)); + return std::make_tuple(std::move(graph), std::move(edge_weights), std::move(renumber_map)); } // explicit instantiations @@ -313,192 +319,240 @@ read_edgelist_from_csv_file(raft::handle_t const& handle, bool store_transposed, bool multi_gpu); -template std::tuple, - std::optional>> +template std::tuple< + cugraph::graph_t, + std::optional, float>>, + std::optional>> read_graph_from_csv_file( raft::handle_t const& handle, std::string const& graph_file_full_path, bool test_weighted, bool renumber); -template std::tuple, - std::optional>> +template std::tuple< + cugraph::graph_t, + std::optional, float>>, + std::optional>> read_graph_from_csv_file( raft::handle_t const& handle, std::string const& graph_file_full_path, bool test_weighted, bool renumber); -template std::tuple, - std::optional>> +template std::tuple< + cugraph::graph_t, + std::optional, float>>, + std::optional>> read_graph_from_csv_file( raft::handle_t const& handle, std::string const& graph_file_full_path, bool test_weighted, bool renumber); -template std::tuple, - std::optional>> +template std::tuple< + cugraph::graph_t, + std::optional, float>>, + std::optional>> read_graph_from_csv_file( raft::handle_t const& handle, std::string const& graph_file_full_path, bool test_weighted, bool renumber); -template std::tuple, - std::optional>> +template std::tuple< + cugraph::graph_t, + std::optional, double>>, + std::optional>> read_graph_from_csv_file( raft::handle_t const& handle, std::string const& graph_file_full_path, bool test_weighted, bool renumber); -template std::tuple, - std::optional>> +template std::tuple< + cugraph::graph_t, + std::optional, double>>, + std::optional>> read_graph_from_csv_file( raft::handle_t const& handle, std::string const& graph_file_full_path, bool test_weighted, bool renumber); -template std::tuple, - std::optional>> +template std::tuple< + cugraph::graph_t, + std::optional, double>>, + std::optional>> read_graph_from_csv_file( raft::handle_t const& handle, std::string const& graph_file_full_path, bool test_weighted, bool renumber); -template std::tuple, - std::optional>> +template std::tuple< + cugraph::graph_t, + std::optional, double>>, + std::optional>> read_graph_from_csv_file( raft::handle_t const& handle, std::string const& graph_file_full_path, bool test_weighted, bool renumber); -template std::tuple, - std::optional>> +template std::tuple< + cugraph::graph_t, + std::optional, float>>, + std::optional>> read_graph_from_csv_file( raft::handle_t const& handle, std::string const& graph_file_full_path, bool test_weighted, bool renumber); -template std::tuple, - std::optional>> +template std::tuple< + cugraph::graph_t, + std::optional, float>>, + std::optional>> read_graph_from_csv_file( raft::handle_t const& handle, std::string const& graph_file_full_path, bool test_weighted, bool renumber); -template std::tuple, - std::optional>> +template std::tuple< + cugraph::graph_t, + std::optional, float>>, + std::optional>> read_graph_from_csv_file( raft::handle_t const& handle, std::string const& graph_file_full_path, bool test_weighted, bool renumber); -template std::tuple, - std::optional>> +template std::tuple< + cugraph::graph_t, + std::optional, float>>, + std::optional>> read_graph_from_csv_file( raft::handle_t const& handle, std::string const& graph_file_full_path, bool test_weighted, bool renumber); -template std::tuple, - std::optional>> +template std::tuple< + cugraph::graph_t, + std::optional, double>>, + std::optional>> read_graph_from_csv_file( raft::handle_t const& handle, std::string const& graph_file_full_path, bool test_weighted, bool renumber); -template std::tuple, - std::optional>> +template std::tuple< + cugraph::graph_t, + std::optional, double>>, + std::optional>> read_graph_from_csv_file( raft::handle_t const& handle, std::string const& graph_file_full_path, bool test_weighted, bool renumber); -template std::tuple, - std::optional>> +template std::tuple< + cugraph::graph_t, + std::optional, double>>, + std::optional>> read_graph_from_csv_file( raft::handle_t const& handle, std::string const& graph_file_full_path, bool test_weighted, bool renumber); -template std::tuple, - std::optional>> +template std::tuple< + cugraph::graph_t, + std::optional, double>>, + std::optional>> read_graph_from_csv_file( raft::handle_t const& handle, std::string const& graph_file_full_path, bool test_weighted, bool renumber); -template std::tuple, - std::optional>> +template std::tuple< + cugraph::graph_t, + std::optional, float>>, + std::optional>> read_graph_from_csv_file( raft::handle_t const& handle, std::string const& graph_file_full_path, bool test_weighted, bool renumber); -template std::tuple, - std::optional>> +template std::tuple< + cugraph::graph_t, + std::optional, float>>, + std::optional>> read_graph_from_csv_file( raft::handle_t const& handle, std::string const& graph_file_full_path, bool test_weighted, bool renumber); -template std::tuple, - std::optional>> +template std::tuple< + cugraph::graph_t, + std::optional, float>>, + std::optional>> read_graph_from_csv_file( raft::handle_t const& handle, std::string const& graph_file_full_path, bool test_weighted, bool renumber); -template std::tuple, - std::optional>> +template std::tuple< + cugraph::graph_t, + std::optional, float>>, + std::optional>> read_graph_from_csv_file( raft::handle_t const& handle, std::string const& graph_file_full_path, bool test_weighted, bool renumber); -template std::tuple, - std::optional>> +template std::tuple< + cugraph::graph_t, + std::optional, double>>, + std::optional>> read_graph_from_csv_file( raft::handle_t const& handle, std::string const& graph_file_full_path, bool test_weighted, bool renumber); -template std::tuple, - std::optional>> +template std::tuple< + cugraph::graph_t, + std::optional, double>>, + std::optional>> read_graph_from_csv_file( raft::handle_t const& handle, std::string const& graph_file_full_path, bool test_weighted, bool renumber); -template std::tuple, - std::optional>> +template std::tuple< + cugraph::graph_t, + std::optional, double>>, + std::optional>> read_graph_from_csv_file( raft::handle_t const& handle, std::string const& graph_file_full_path, bool test_weighted, bool renumber); -template std::tuple, - std::optional>> +template std::tuple< + cugraph::graph_t, + std::optional, double>>, + std::optional>> read_graph_from_csv_file( raft::handle_t const& handle, std::string const& graph_file_full_path, diff --git a/cpp/tests/utilities/matrix_market_file_utilities.cu b/cpp/tests/utilities/matrix_market_file_utilities.cu index 5d1f59fd8cd..f956ebdfbbc 100644 --- a/cpp/tests/utilities/matrix_market_file_utilities.cu +++ b/cpp/tests/utilities/matrix_market_file_utilities.cu @@ -398,7 +398,10 @@ template -std::tuple, +std::tuple, + std::optional< + cugraph::edge_property_t, + weight_t>>, std::optional>> read_graph_from_matrix_market_file(raft::handle_t const& handle, std::string const& graph_file_full_path, @@ -409,9 +412,12 @@ read_graph_from_matrix_market_file(raft::handle_t const& handle, read_edgelist_from_matrix_market_file( handle, graph_file_full_path, test_weighted, store_transposed, multi_gpu); - graph_t graph(handle); + graph_t graph(handle); + std::optional< + cugraph::edge_property_t, weight_t>> + edge_weights{std::nullopt}; std::optional> renumber_map{std::nullopt}; - std::tie(graph, std::ignore, renumber_map) = cugraph:: + std::tie(graph, edge_weights, std::ignore, renumber_map) = cugraph:: create_graph_from_edgelist( handle, std::move(d_vertices), @@ -422,7 +428,7 @@ read_graph_from_matrix_market_file(raft::handle_t const& handle, cugraph::graph_properties_t{is_symmetric, false}, renumber); - return std::make_tuple(std::move(graph), std::move(renumber_map)); + return std::make_tuple(std::move(graph), std::move(edge_weights), std::move(renumber_map)); } // explicit instantiations @@ -474,192 +480,240 @@ read_edgelist_from_matrix_market_file(raft::handle_t const& hand bool store_transposed, bool multi_gpu); -template std::tuple, - std::optional>> +template std::tuple< + cugraph::graph_t, + std::optional, float>>, + std::optional>> read_graph_from_matrix_market_file( raft::handle_t const& handle, std::string const& graph_file_full_path, bool test_weighted, bool renumber); -template std::tuple, - std::optional>> +template std::tuple< + cugraph::graph_t, + std::optional, float>>, + std::optional>> read_graph_from_matrix_market_file( raft::handle_t const& handle, std::string const& graph_file_full_path, bool test_weighted, bool renumber); -template std::tuple, - std::optional>> +template std::tuple< + cugraph::graph_t, + std::optional, float>>, + std::optional>> read_graph_from_matrix_market_file( raft::handle_t const& handle, std::string const& graph_file_full_path, bool test_weighted, bool renumber); -template std::tuple, - std::optional>> +template std::tuple< + cugraph::graph_t, + std::optional, float>>, + std::optional>> read_graph_from_matrix_market_file( raft::handle_t const& handle, std::string const& graph_file_full_path, bool test_weighted, bool renumber); -template std::tuple, - std::optional>> +template std::tuple< + cugraph::graph_t, + std::optional, double>>, + std::optional>> read_graph_from_matrix_market_file( raft::handle_t const& handle, std::string const& graph_file_full_path, bool test_weighted, bool renumber); -template std::tuple, - std::optional>> +template std::tuple< + cugraph::graph_t, + std::optional, double>>, + std::optional>> read_graph_from_matrix_market_file( raft::handle_t const& handle, std::string const& graph_file_full_path, bool test_weighted, bool renumber); -template std::tuple, - std::optional>> +template std::tuple< + cugraph::graph_t, + std::optional, double>>, + std::optional>> read_graph_from_matrix_market_file( raft::handle_t const& handle, std::string const& graph_file_full_path, bool test_weighted, bool renumber); -template std::tuple, - std::optional>> +template std::tuple< + cugraph::graph_t, + std::optional, double>>, + std::optional>> read_graph_from_matrix_market_file( raft::handle_t const& handle, std::string const& graph_file_full_path, bool test_weighted, bool renumber); -template std::tuple, - std::optional>> +template std::tuple< + cugraph::graph_t, + std::optional, float>>, + std::optional>> read_graph_from_matrix_market_file( raft::handle_t const& handle, std::string const& graph_file_full_path, bool test_weighted, bool renumber); -template std::tuple, - std::optional>> +template std::tuple< + cugraph::graph_t, + std::optional, float>>, + std::optional>> read_graph_from_matrix_market_file( raft::handle_t const& handle, std::string const& graph_file_full_path, bool test_weighted, bool renumber); -template std::tuple, - std::optional>> +template std::tuple< + cugraph::graph_t, + std::optional, float>>, + std::optional>> read_graph_from_matrix_market_file( raft::handle_t const& handle, std::string const& graph_file_full_path, bool test_weighted, bool renumber); -template std::tuple, - std::optional>> +template std::tuple< + cugraph::graph_t, + std::optional, float>>, + std::optional>> read_graph_from_matrix_market_file( raft::handle_t const& handle, std::string const& graph_file_full_path, bool test_weighted, bool renumber); -template std::tuple, - std::optional>> +template std::tuple< + cugraph::graph_t, + std::optional, double>>, + std::optional>> read_graph_from_matrix_market_file( raft::handle_t const& handle, std::string const& graph_file_full_path, bool test_weighted, bool renumber); -template std::tuple, - std::optional>> +template std::tuple< + cugraph::graph_t, + std::optional, double>>, + std::optional>> read_graph_from_matrix_market_file( raft::handle_t const& handle, std::string const& graph_file_full_path, bool test_weighted, bool renumber); -template std::tuple, - std::optional>> +template std::tuple< + cugraph::graph_t, + std::optional, double>>, + std::optional>> read_graph_from_matrix_market_file( raft::handle_t const& handle, std::string const& graph_file_full_path, bool test_weighted, bool renumber); -template std::tuple, - std::optional>> +template std::tuple< + cugraph::graph_t, + std::optional, double>>, + std::optional>> read_graph_from_matrix_market_file( raft::handle_t const& handle, std::string const& graph_file_full_path, bool test_weighted, bool renumber); -template std::tuple, - std::optional>> +template std::tuple< + cugraph::graph_t, + std::optional, float>>, + std::optional>> read_graph_from_matrix_market_file( raft::handle_t const& handle, std::string const& graph_file_full_path, bool test_weighted, bool renumber); -template std::tuple, - std::optional>> +template std::tuple< + cugraph::graph_t, + std::optional, float>>, + std::optional>> read_graph_from_matrix_market_file( raft::handle_t const& handle, std::string const& graph_file_full_path, bool test_weighted, bool renumber); -template std::tuple, - std::optional>> +template std::tuple< + cugraph::graph_t, + std::optional, float>>, + std::optional>> read_graph_from_matrix_market_file( raft::handle_t const& handle, std::string const& graph_file_full_path, bool test_weighted, bool renumber); -template std::tuple, - std::optional>> +template std::tuple< + cugraph::graph_t, + std::optional, float>>, + std::optional>> read_graph_from_matrix_market_file( raft::handle_t const& handle, std::string const& graph_file_full_path, bool test_weighted, bool renumber); -template std::tuple, - std::optional>> +template std::tuple< + cugraph::graph_t, + std::optional, double>>, + std::optional>> read_graph_from_matrix_market_file( raft::handle_t const& handle, std::string const& graph_file_full_path, bool test_weighted, bool renumber); -template std::tuple, - std::optional>> +template std::tuple< + cugraph::graph_t, + std::optional, double>>, + std::optional>> read_graph_from_matrix_market_file( raft::handle_t const& handle, std::string const& graph_file_full_path, bool test_weighted, bool renumber); -template std::tuple, - std::optional>> +template std::tuple< + cugraph::graph_t, + std::optional, double>>, + std::optional>> read_graph_from_matrix_market_file( raft::handle_t const& handle, std::string const& graph_file_full_path, bool test_weighted, bool renumber); -template std::tuple, - std::optional>> +template std::tuple< + cugraph::graph_t, + std::optional, double>>, + std::optional>> read_graph_from_matrix_market_file( raft::handle_t const& handle, std::string const& graph_file_full_path, diff --git a/cpp/tests/utilities/test_graphs.hpp b/cpp/tests/utilities/test_graphs.hpp index ad73b26bc35..50699667549 100644 --- a/cpp/tests/utilities/test_graphs.hpp +++ b/cpp/tests/utilities/test_graphs.hpp @@ -598,7 +598,10 @@ template -std::tuple, +std::tuple, + std::optional, + weight_t>>, std::optional>> construct_graph(raft::handle_t const& handle, input_usecase_t const& input_usecase, @@ -617,9 +620,12 @@ construct_graph(raft::handle_t const& handle, if (drop_multi_edges) { sort_and_remove_multi_edges(handle, d_src_v, d_dst_v, d_weights_v); } - graph_t graph(handle); + graph_t graph(handle); + std::optional< + edge_property_t, weight_t>> + edge_weights{std::nullopt}; std::optional> renumber_map{std::nullopt}; - std::tie(graph, std::ignore, renumber_map) = cugraph:: + std::tie(graph, edge_weights, std::ignore, renumber_map) = cugraph:: create_graph_from_edgelist( handle, std::move(d_vertices_v), @@ -630,7 +636,7 @@ construct_graph(raft::handle_t const& handle, cugraph::graph_properties_t{is_symmetric, drop_multi_edges ? false : true}, renumber); - return std::make_tuple(std::move(graph), std::move(renumber_map)); + return std::make_tuple(std::move(graph), std::move(edge_weights), std::move(renumber_map)); } namespace legacy { diff --git a/cpp/tests/utilities/test_utilities.hpp b/cpp/tests/utilities/test_utilities.hpp index 9f699d83b47..84d833abaf1 100644 --- a/cpp/tests/utilities/test_utilities.hpp +++ b/cpp/tests/utilities/test_utilities.hpp @@ -133,7 +133,10 @@ template -std::tuple, +std::tuple, + std::optional< + cugraph::edge_property_t, + weight_t>>, std::optional>> read_graph_from_matrix_market_file(raft::handle_t const& handle, std::string const& graph_file_full_path, @@ -175,8 +178,10 @@ decltype(auto) make_graph(raft::handle_t const& handle, raft::update_device((*d_w).data(), (*v_w).data(), (*d_w).size(), handle.get_stream()); } - cugraph::graph_t graph(handle); - std::tie(graph, std::ignore, std::ignore) = + cugraph::graph_t graph(handle); + std::optional, weight_t>> + edge_weights{std::nullopt}; + std::tie(graph, edge_weights, std::ignore, std::ignore) = cugraph::create_graph_from_edgelist( handle, std::nullopt, @@ -187,7 +192,7 @@ decltype(auto) make_graph(raft::handle_t const& handle, cugraph::graph_properties_t{false, false}, false); - return graph; + return std::make_tuple(std::move(graph), std::move(edge_weights)); } // compares single GPU CSR graph data: @@ -461,8 +466,8 @@ template , std::vector, std::optional>> graph_to_host_coo( raft::handle_t const& handle, - cugraph::graph_view_t const& - graph_view); + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view); template , std::vector, std::optional>> graph_to_host_csr( raft::handle_t const& handle, - cugraph::graph_view_t const& - graph_view); + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view); template -std::tuple, +std::tuple, + std::optional, + weight_t>>, std::optional>> mg_graph_to_sg_graph( raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view, std::optional> const& number_map, bool renumber); diff --git a/cpp/tests/utilities/test_utilities_impl.cuh b/cpp/tests/utilities/test_utilities_impl.cuh index 7f9247c499a..ceca6a7df57 100644 --- a/cpp/tests/utilities/test_utilities_impl.cuh +++ b/cpp/tests/utilities/test_utilities_impl.cuh @@ -34,11 +34,14 @@ template , std::vector, std::optional>> graph_to_host_coo( raft::handle_t const& handle, - cugraph::graph_view_t const& - graph_view) + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view) { - auto [d_src, d_dst, d_wgt] = cugraph::decompress_to_edgelist( - handle, graph_view, std::optional>{std::nullopt}); + auto [d_src, d_dst, d_wgt] = + cugraph::decompress_to_edgelist(handle, + graph_view, + edge_weight_view, + std::optional>{std::nullopt}); if constexpr (is_multi_gpu) { d_src = cugraph::test::device_gatherv( @@ -73,11 +76,14 @@ template , std::vector, std::optional>> graph_to_host_csr( raft::handle_t const& handle, - cugraph::graph_view_t const& - graph_view) + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view) { - auto [d_src, d_dst, d_wgt] = cugraph::decompress_to_edgelist( - handle, graph_view, std::optional>{std::nullopt}); + auto [d_src, d_dst, d_wgt] = + cugraph::decompress_to_edgelist(handle, + graph_view, + edge_weight_view, + std::optional>{std::nullopt}); if constexpr (is_multi_gpu) { d_src = cugraph::test::device_gatherv( @@ -136,17 +142,21 @@ graph_to_host_csr( } template -std::tuple, - std::optional>> +std::tuple< + cugraph::graph_t, + std::optional, weight_t>>, + std::optional>> mg_graph_to_sg_graph( raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view, std::optional> const& number_map, bool renumber) { auto [d_src, d_dst, d_wgt] = cugraph::decompress_to_edgelist( handle, graph_view, + edge_weight_view, number_map ? std::make_optional>((*number_map).data(), (*number_map).size()) : std::nullopt); @@ -159,9 +169,11 @@ mg_graph_to_sg_graph( *d_wgt = cugraph::test::device_gatherv( handle, raft::device_span{d_wgt->data(), d_wgt->size()}); - graph_t graph(handle); + graph_t graph(handle); + std::optional, weight_t>> + edge_weights{std::nullopt}; std::optional> new_number_map; - std::tie(graph, std::ignore, new_number_map) = cugraph:: + std::tie(graph, edge_weights, std::ignore, new_number_map) = cugraph:: create_graph_from_edgelist( handle, std::optional>{std::nullopt}, @@ -172,7 +184,7 @@ mg_graph_to_sg_graph( cugraph::graph_properties_t{graph_view.is_symmetric(), graph_view.is_multigraph()}, renumber); - return std::make_tuple(std::move(graph), std::move(new_number_map)); + return std::make_tuple(std::move(graph), std::move(edge_weights), std::move(new_number_map)); } } // namespace test diff --git a/cpp/tests/utilities/test_utilities_mg.cu b/cpp/tests/utilities/test_utilities_mg.cu index 6dec4710f14..b5a8e0d7c45 100644 --- a/cpp/tests/utilities/test_utilities_mg.cu +++ b/cpp/tests/utilities/test_utilities_mg.cu @@ -19,184 +19,280 @@ namespace cugraph { namespace test { template std::tuple, std::vector, std::optional>> -graph_to_host_coo(raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view); +graph_to_host_coo( + raft::handle_t const& handle, + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view); template std::tuple, std::vector, std::optional>> -graph_to_host_coo(raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view); +graph_to_host_coo( + raft::handle_t const& handle, + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view); template std::tuple, std::vector, std::optional>> -graph_to_host_coo(raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view); +graph_to_host_coo( + raft::handle_t const& handle, + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view); template std::tuple, std::vector, std::optional>> -graph_to_host_coo(raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view); +graph_to_host_coo( + raft::handle_t const& handle, + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view); template std::tuple, std::vector, std::optional>> -graph_to_host_coo(raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view); +graph_to_host_coo( + raft::handle_t const& handle, + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view); template std::tuple, std::vector, std::optional>> -graph_to_host_coo(raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view); +graph_to_host_coo( + raft::handle_t const& handle, + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view); template std::tuple, std::vector, std::optional>> -graph_to_host_coo(raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view); +graph_to_host_coo( + raft::handle_t const& handle, + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view); template std::tuple, std::vector, std::optional>> -graph_to_host_coo(raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view); +graph_to_host_coo( + raft::handle_t const& handle, + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view); template std::tuple, std::vector, std::optional>> -graph_to_host_coo(raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view); +graph_to_host_coo( + raft::handle_t const& handle, + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view); template std::tuple, std::vector, std::optional>> -graph_to_host_coo(raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view); +graph_to_host_coo( + raft::handle_t const& handle, + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view); template std::tuple, std::vector, std::optional>> -graph_to_host_coo(raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view); +graph_to_host_coo( + raft::handle_t const& handle, + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view); template std::tuple, std::vector, std::optional>> -graph_to_host_coo(raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view); +graph_to_host_coo( + raft::handle_t const& handle, + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view); template std::tuple, std::vector, std::optional>> -graph_to_host_csr(raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view); +graph_to_host_csr( + raft::handle_t const& handle, + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view); template std::tuple, std::vector, std::optional>> -graph_to_host_csr(raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view); +graph_to_host_csr( + raft::handle_t const& handle, + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view); template std::tuple, std::vector, std::optional>> -graph_to_host_csr(raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view); +graph_to_host_csr( + raft::handle_t const& handle, + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view); template std::tuple, std::vector, std::optional>> -graph_to_host_csr(raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view); +graph_to_host_csr( + raft::handle_t const& handle, + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view); template std::tuple, std::vector, std::optional>> -graph_to_host_csr(raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view); +graph_to_host_csr( + raft::handle_t const& handle, + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view); template std::tuple, std::vector, std::optional>> -graph_to_host_csr(raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view); +graph_to_host_csr( + raft::handle_t const& handle, + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view); template std::tuple, std::vector, std::optional>> -graph_to_host_csr(raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view); +graph_to_host_csr( + raft::handle_t const& handle, + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view); template std::tuple, std::vector, std::optional>> -graph_to_host_csr(raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view); +graph_to_host_csr( + raft::handle_t const& handle, + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view); template std::tuple, std::vector, std::optional>> -graph_to_host_csr(raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view); +graph_to_host_csr( + raft::handle_t const& handle, + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view); template std::tuple, std::vector, std::optional>> -graph_to_host_csr(raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view); +graph_to_host_csr( + raft::handle_t const& handle, + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view); template std::tuple, std::vector, std::optional>> -graph_to_host_csr(raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view); +graph_to_host_csr( + raft::handle_t const& handle, + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view); template std::tuple, std::vector, std::optional>> -graph_to_host_csr(raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view); - -template std::tuple, - std::optional>> -mg_graph_to_sg_graph(raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, - std::optional> const& number_map, - bool renumber); - -template std::tuple, - std::optional>> -mg_graph_to_sg_graph(raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, - std::optional> const& number_map, - bool renumber); - -template std::tuple, - std::optional>> -mg_graph_to_sg_graph(raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, - std::optional> const& number_map, - bool renumber); - -template std::tuple, - std::optional>> -mg_graph_to_sg_graph(raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, - std::optional> const& number_map, - bool renumber); - -template std::tuple, - std::optional>> -mg_graph_to_sg_graph(raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, - std::optional> const& number_map, - bool renumber); - -template std::tuple, - std::optional>> -mg_graph_to_sg_graph(raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, - std::optional> const& number_map, - bool renumber); - -template std::tuple, - std::optional>> -mg_graph_to_sg_graph(raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, - std::optional> const& number_map, - bool renumber); - -template std::tuple, - std::optional>> -mg_graph_to_sg_graph(raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, - std::optional> const& number_map, - bool renumber); - -template std::tuple, - std::optional>> -mg_graph_to_sg_graph(raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, - std::optional> const& number_map, - bool renumber); - -template std::tuple, - std::optional>> -mg_graph_to_sg_graph(raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, - std::optional> const& number_map, - bool renumber); - -template std::tuple, - std::optional>> -mg_graph_to_sg_graph(raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, - std::optional> const& number_map, - bool renumber); - -template std::tuple, - std::optional>> -mg_graph_to_sg_graph(raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, - std::optional> const& number_map, - bool renumber); +graph_to_host_csr( + raft::handle_t const& handle, + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view); + +template std::tuple< + cugraph::graph_t, + std::optional, float>>, + std::optional>> +mg_graph_to_sg_graph( + raft::handle_t const& handle, + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view, + std::optional> const& number_map, + bool renumber); + +template std::tuple< + cugraph::graph_t, + std::optional, float>>, + std::optional>> +mg_graph_to_sg_graph( + raft::handle_t const& handle, + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view, + std::optional> const& number_map, + bool renumber); + +template std::tuple< + cugraph::graph_t, + std::optional, float>>, + std::optional>> +mg_graph_to_sg_graph( + raft::handle_t const& handle, + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view, + std::optional> const& number_map, + bool renumber); + +template std::tuple< + cugraph::graph_t, + std::optional, double>>, + std::optional>> +mg_graph_to_sg_graph( + raft::handle_t const& handle, + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view, + std::optional> const& number_map, + bool renumber); + +template std::tuple< + cugraph::graph_t, + std::optional, double>>, + std::optional>> +mg_graph_to_sg_graph( + raft::handle_t const& handle, + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view, + std::optional> const& number_map, + bool renumber); + +template std::tuple< + cugraph::graph_t, + std::optional, double>>, + std::optional>> +mg_graph_to_sg_graph( + raft::handle_t const& handle, + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view, + std::optional> const& number_map, + bool renumber); + +template std::tuple< + cugraph::graph_t, + std::optional, float>>, + std::optional>> +mg_graph_to_sg_graph( + raft::handle_t const& handle, + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view, + std::optional> const& number_map, + bool renumber); + +template std::tuple< + cugraph::graph_t, + std::optional, float>>, + std::optional>> +mg_graph_to_sg_graph( + raft::handle_t const& handle, + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view, + std::optional> const& number_map, + bool renumber); + +template std::tuple< + cugraph::graph_t, + std::optional, float>>, + std::optional>> +mg_graph_to_sg_graph( + raft::handle_t const& handle, + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view, + std::optional> const& number_map, + bool renumber); + +template std::tuple< + cugraph::graph_t, + std::optional, double>>, + std::optional>> +mg_graph_to_sg_graph( + raft::handle_t const& handle, + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view, + std::optional> const& number_map, + bool renumber); + +template std::tuple< + cugraph::graph_t, + std::optional, double>>, + std::optional>> +mg_graph_to_sg_graph( + raft::handle_t const& handle, + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view, + std::optional> const& number_map, + bool renumber); + +template std::tuple< + cugraph::graph_t, + std::optional, double>>, + std::optional>> +mg_graph_to_sg_graph( + raft::handle_t const& handle, + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view, + std::optional> const& number_map, + bool renumber); } // namespace test } // namespace cugraph diff --git a/cpp/tests/utilities/test_utilities_sg.cu b/cpp/tests/utilities/test_utilities_sg.cu index bd20cf44ea1..874ac81ff57 100644 --- a/cpp/tests/utilities/test_utilities_sg.cu +++ b/cpp/tests/utilities/test_utilities_sg.cu @@ -19,100 +19,148 @@ namespace cugraph { namespace test { template std::tuple, std::vector, std::optional>> -graph_to_host_coo(raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view); +graph_to_host_coo( + raft::handle_t const& handle, + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view); template std::tuple, std::vector, std::optional>> -graph_to_host_coo(raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view); +graph_to_host_coo( + raft::handle_t const& handle, + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view); template std::tuple, std::vector, std::optional>> -graph_to_host_coo(raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view); +graph_to_host_coo( + raft::handle_t const& handle, + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view); template std::tuple, std::vector, std::optional>> -graph_to_host_coo(raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view); +graph_to_host_coo( + raft::handle_t const& handle, + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view); template std::tuple, std::vector, std::optional>> -graph_to_host_coo(raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view); +graph_to_host_coo( + raft::handle_t const& handle, + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view); template std::tuple, std::vector, std::optional>> -graph_to_host_coo(raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view); +graph_to_host_coo( + raft::handle_t const& handle, + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view); template std::tuple, std::vector, std::optional>> -graph_to_host_coo(raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view); +graph_to_host_coo( + raft::handle_t const& handle, + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view); template std::tuple, std::vector, std::optional>> -graph_to_host_coo(raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view); +graph_to_host_coo( + raft::handle_t const& handle, + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view); template std::tuple, std::vector, std::optional>> -graph_to_host_coo(raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view); +graph_to_host_coo( + raft::handle_t const& handle, + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view); template std::tuple, std::vector, std::optional>> -graph_to_host_coo(raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view); +graph_to_host_coo( + raft::handle_t const& handle, + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view); template std::tuple, std::vector, std::optional>> -graph_to_host_coo(raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view); +graph_to_host_coo( + raft::handle_t const& handle, + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view); template std::tuple, std::vector, std::optional>> -graph_to_host_coo(raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view); +graph_to_host_coo( + raft::handle_t const& handle, + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view); template std::tuple, std::vector, std::optional>> -graph_to_host_csr(raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view); +graph_to_host_csr( + raft::handle_t const& handle, + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view); template std::tuple, std::vector, std::optional>> -graph_to_host_csr(raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view); +graph_to_host_csr( + raft::handle_t const& handle, + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view); template std::tuple, std::vector, std::optional>> -graph_to_host_csr(raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view); +graph_to_host_csr( + raft::handle_t const& handle, + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view); template std::tuple, std::vector, std::optional>> -graph_to_host_csr(raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view); +graph_to_host_csr( + raft::handle_t const& handle, + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view); template std::tuple, std::vector, std::optional>> -graph_to_host_csr(raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view); +graph_to_host_csr( + raft::handle_t const& handle, + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view); template std::tuple, std::vector, std::optional>> -graph_to_host_csr(raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view); +graph_to_host_csr( + raft::handle_t const& handle, + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view); template std::tuple, std::vector, std::optional>> -graph_to_host_csr(raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view); +graph_to_host_csr( + raft::handle_t const& handle, + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view); template std::tuple, std::vector, std::optional>> -graph_to_host_csr(raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view); +graph_to_host_csr( + raft::handle_t const& handle, + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view); template std::tuple, std::vector, std::optional>> -graph_to_host_csr(raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view); +graph_to_host_csr( + raft::handle_t const& handle, + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view); template std::tuple, std::vector, std::optional>> -graph_to_host_csr(raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view); +graph_to_host_csr( + raft::handle_t const& handle, + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view); template std::tuple, std::vector, std::optional>> -graph_to_host_csr(raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view); +graph_to_host_csr( + raft::handle_t const& handle, + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view); template std::tuple, std::vector, std::optional>> -graph_to_host_csr(raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view); +graph_to_host_csr( + raft::handle_t const& handle, + cugraph::graph_view_t const& graph_view, + std::optional> edge_weight_view); } // namespace test } // namespace cugraph