Skip to content

Commit

Permalink
Update API for node2vec and biased random walks (#4841)
Browse files Browse the repository at this point in the history
This PR

1. Add MG support for node2vec random walks on the C, PLC and Python API
2. Fix renumbering bug in the CAPI for node2vec and biased random walks
3. Enable and fix bug in the MG C tests
4. Deprecate legacy node2vec and uniform random walks
5. Add SG and MG support for Biased random walks
6. Add multi GPU support for ECG in the python API

closes #3277 
closes #2558
closes #2559 
closes #2560 
closes #2561 
closes #2853 
closes #4843

Authors:
  - Joseph Nke (https://github.com/jnke2016)

Approvers:
  - Chuck Hastings (https://github.com/ChuckHastings)
  - Rick Ratzel (https://github.com/rlratzel)

URL: #4841
  • Loading branch information
jnke2016 authored Feb 5, 2025
1 parent 9d8fbd6 commit dfdc73a
Show file tree
Hide file tree
Showing 39 changed files with 3,416 additions and 113 deletions.
8 changes: 7 additions & 1 deletion cpp/include/cugraph_c/sampling_algorithms.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2021-2024, NVIDIA CORPORATION.
* Copyright (c) 2021-2025, NVIDIA CORPORATION.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -41,6 +41,7 @@ typedef struct {
* @brief Compute uniform random walks
*
* @param [in] handle Handle for accessing resources
* @param [in,out] rng_state State of the random number generator, updated with each call
* @param [in] graph Pointer to graph. NOTE: Graph might be modified if the storage
* needs to be transposed
* @param [in] start_vertices Array of source vertices
Expand All @@ -52,6 +53,7 @@ typedef struct {
*/
cugraph_error_code_t cugraph_uniform_random_walks(
const cugraph_resource_handle_t* handle,
cugraph_rng_state_t* rng_state,
cugraph_graph_t* graph,
const cugraph_type_erased_device_array_view_t* start_vertices,
size_t max_length,
Expand All @@ -62,6 +64,7 @@ cugraph_error_code_t cugraph_uniform_random_walks(
* @brief Compute biased random walks
*
* @param [in] handle Handle for accessing resources
* @param [in,out] rng_state State of the random number generator, updated with each call
* @param [in] graph Pointer to graph. NOTE: Graph might be modified if the storage
* needs to be transposed
* @param [in] start_vertices Array of source vertices
Expand All @@ -73,6 +76,7 @@ cugraph_error_code_t cugraph_uniform_random_walks(
*/
cugraph_error_code_t cugraph_biased_random_walks(
const cugraph_resource_handle_t* handle,
cugraph_rng_state_t* rng_state,
cugraph_graph_t* graph,
const cugraph_type_erased_device_array_view_t* start_vertices,
size_t max_length,
Expand All @@ -83,6 +87,7 @@ cugraph_error_code_t cugraph_biased_random_walks(
* @brief Compute random walks using the node2vec framework.
*
* @param [in] handle Handle for accessing resources
* @param [in,out] rng_state State of the random number generator, updated with each call
* @param [in] graph Pointer to graph. NOTE: Graph might be modified if the storage
* needs to be transposed
* @param [in] start_vertices Array of source vertices
Expand All @@ -98,6 +103,7 @@ cugraph_error_code_t cugraph_biased_random_walks(
*/
cugraph_error_code_t cugraph_node2vec_random_walks(
const cugraph_resource_handle_t* handle,
cugraph_rng_state_t* rng_state,
cugraph_graph_t* graph,
const cugraph_type_erased_device_array_view_t* start_vertices,
size_t max_length,
Expand Down
54 changes: 27 additions & 27 deletions cpp/src/c_api/random_walks.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2022-2024, NVIDIA CORPORATION.
* Copyright (c) 2022-2025, NVIDIA CORPORATION.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -154,19 +154,20 @@ namespace {

struct uniform_random_walks_functor : public cugraph::c_api::abstract_functor {
raft::handle_t const& handle_;
// FIXME: rng_state_ should be passed as a parameter
cugraph::c_api::cugraph_rng_state_t* rng_state_{nullptr};
cugraph::c_api::cugraph_graph_t* graph_{nullptr};
cugraph::c_api::cugraph_type_erased_device_array_view_t const* start_vertices_{nullptr};
size_t max_length_{0};
cugraph::c_api::cugraph_random_walk_result_t* result_{nullptr};

uniform_random_walks_functor(cugraph_resource_handle_t const* handle,
cugraph_rng_state_t* rng_state,
cugraph_graph_t* graph,
cugraph_type_erased_device_array_view_t const* start_vertices,
size_t max_length)
: abstract_functor(),
handle_(*reinterpret_cast<cugraph::c_api::cugraph_resource_handle_t const*>(handle)->handle_),
rng_state_(reinterpret_cast<cugraph::c_api::cugraph_rng_state_t*>(rng_state)),
graph_(reinterpret_cast<cugraph::c_api::cugraph_graph_t*>(graph)),
start_vertices_(
reinterpret_cast<cugraph::c_api::cugraph_type_erased_device_array_view_t const*>(
Expand Down Expand Up @@ -224,10 +225,6 @@ struct uniform_random_walks_functor : public cugraph::c_api::abstract_functor {
graph_view.local_vertex_partition_range_last(),
false);

// FIXME: remove once rng_state passed as parameter
rng_state_ = reinterpret_cast<cugraph::c_api::cugraph_rng_state_t*>(
new cugraph::c_api::cugraph_rng_state_t{raft::random::RngState{0}});

auto [paths, weights] = cugraph::uniform_random_walks(
handle_,
rng_state_->rng_state_,
Expand Down Expand Up @@ -261,19 +258,20 @@ struct uniform_random_walks_functor : public cugraph::c_api::abstract_functor {

struct biased_random_walks_functor : public cugraph::c_api::abstract_functor {
raft::handle_t const& handle_;
// FIXME: rng_state_ should be passed as a parameter
cugraph::c_api::cugraph_rng_state_t* rng_state_{nullptr};
cugraph::c_api::cugraph_graph_t* graph_{nullptr};
cugraph::c_api::cugraph_type_erased_device_array_view_t const* start_vertices_{nullptr};
size_t max_length_{0};
cugraph::c_api::cugraph_random_walk_result_t* result_{nullptr};

biased_random_walks_functor(cugraph_resource_handle_t const* handle,
cugraph_rng_state_t* rng_state,
cugraph_graph_t* graph,
cugraph_type_erased_device_array_view_t const* start_vertices,
size_t max_length)
: abstract_functor(),
handle_(*reinterpret_cast<cugraph::c_api::cugraph_resource_handle_t const*>(handle)->handle_),
rng_state_(reinterpret_cast<cugraph::c_api::cugraph_rng_state_t*>(rng_state)),
graph_(reinterpret_cast<cugraph::c_api::cugraph_graph_t*>(graph)),
start_vertices_(
reinterpret_cast<cugraph::c_api::cugraph_type_erased_device_array_view_t const*>(
Expand All @@ -293,8 +291,6 @@ struct biased_random_walks_functor : public cugraph::c_api::abstract_functor {
// FIXME: Think about how to handle SG vice MG
if constexpr (!cugraph::is_candidate<vertex_t, edge_t, weight_t>::value) {
unsupported();
} else if constexpr (multi_gpu) {
unsupported();
} else {
// random walks expects store_transposed == false
if constexpr (store_transposed) {
Expand Down Expand Up @@ -333,10 +329,6 @@ struct biased_random_walks_functor : public cugraph::c_api::abstract_functor {
graph_view.local_vertex_partition_range_last(),
false);

// FIXME: remove once rng_state passed as parameter
rng_state_ = reinterpret_cast<cugraph::c_api::cugraph_rng_state_t*>(
new cugraph::c_api::cugraph_rng_state_t{raft::random::RngState{0}});

auto [paths, weights] = cugraph::biased_random_walks(
handle_,
rng_state_->rng_state_,
Expand All @@ -348,8 +340,13 @@ struct biased_random_walks_functor : public cugraph::c_api::abstract_functor {
//
// Need to unrenumber the vertices in the resulting paths
//
cugraph::unrenumber_local_int_vertices<vertex_t>(
handle_, paths.data(), paths.size(), number_map->data(), 0, paths.size() - 1, false);
cugraph::unrenumber_int_vertices<vertex_t, multi_gpu>(
handle_,
paths.data(),
paths.size(),
number_map->data(),
graph_view.vertex_partition_range_lasts(),
false);

result_ = new cugraph::c_api::cugraph_random_walk_result_t{
false,
Expand All @@ -365,7 +362,6 @@ struct biased_random_walks_functor : public cugraph::c_api::abstract_functor {

struct node2vec_random_walks_functor : public cugraph::c_api::abstract_functor {
raft::handle_t const& handle_;
// FIXME: rng_state_ should be passed as a parameter
cugraph::c_api::cugraph_rng_state_t* rng_state_{nullptr};
cugraph::c_api::cugraph_graph_t* graph_{nullptr};
cugraph::c_api::cugraph_type_erased_device_array_view_t const* start_vertices_{nullptr};
Expand All @@ -375,13 +371,15 @@ struct node2vec_random_walks_functor : public cugraph::c_api::abstract_functor {
cugraph::c_api::cugraph_random_walk_result_t* result_{nullptr};

node2vec_random_walks_functor(cugraph_resource_handle_t const* handle,
cugraph_rng_state_t* rng_state,
cugraph_graph_t* graph,
cugraph_type_erased_device_array_view_t const* start_vertices,
size_t max_length,
double p,
double q)
: abstract_functor(),
handle_(*reinterpret_cast<cugraph::c_api::cugraph_resource_handle_t const*>(handle)->handle_),
rng_state_(reinterpret_cast<cugraph::c_api::cugraph_rng_state_t*>(rng_state)),
graph_(reinterpret_cast<cugraph::c_api::cugraph_graph_t*>(graph)),
start_vertices_(
reinterpret_cast<cugraph::c_api::cugraph_type_erased_device_array_view_t const*>(
Expand All @@ -403,8 +401,6 @@ struct node2vec_random_walks_functor : public cugraph::c_api::abstract_functor {
// FIXME: Think about how to handle SG vice MG
if constexpr (!cugraph::is_candidate<vertex_t, edge_t, weight_t>::value) {
unsupported();
} else if constexpr (multi_gpu) {
unsupported();
} else {
// random walks expects store_transposed == false
if constexpr (store_transposed) {
Expand Down Expand Up @@ -443,10 +439,6 @@ struct node2vec_random_walks_functor : public cugraph::c_api::abstract_functor {
graph_view.local_vertex_partition_range_last(),
false);

// FIXME: remove once rng_state passed as parameter
rng_state_ = reinterpret_cast<cugraph::c_api::cugraph_rng_state_t*>(
new cugraph::c_api::cugraph_rng_state_t{raft::random::RngState{0}});

auto [paths, weights] = cugraph::node2vec_random_walks(
handle_,
rng_state_->rng_state_,
Expand All @@ -464,8 +456,13 @@ struct node2vec_random_walks_functor : public cugraph::c_api::abstract_functor {
//
// Need to unrenumber the vertices in the resulting paths
//
cugraph::unrenumber_local_int_vertices<vertex_t>(
handle_, paths.data(), paths.size(), number_map->data(), 0, paths.size(), false);
cugraph::unrenumber_int_vertices<vertex_t, multi_gpu>(
handle_,
paths.data(),
paths.size(),
number_map->data(),
graph_view.vertex_partition_range_lasts(),
false);

result_ = new cugraph::c_api::cugraph_random_walk_result_t{
false,
Expand Down Expand Up @@ -546,6 +543,7 @@ void cugraph_random_walk_result_free(cugraph_random_walk_result_t* result)

cugraph_error_code_t cugraph_uniform_random_walks(
const cugraph_resource_handle_t* handle,
cugraph_rng_state_t* rng_state,
cugraph_graph_t* graph,
const cugraph_type_erased_device_array_view_t* start_vertices,
size_t max_length,
Expand All @@ -560,13 +558,14 @@ cugraph_error_code_t cugraph_uniform_random_walks(
"vertex type of graph and start_vertices must match",
*error);

uniform_random_walks_functor functor(handle, graph, start_vertices, max_length);
uniform_random_walks_functor functor(handle, rng_state, graph, start_vertices, max_length);

return cugraph::c_api::run_algorithm(graph, functor, result, error);
}

cugraph_error_code_t cugraph_biased_random_walks(
const cugraph_resource_handle_t* handle,
cugraph_rng_state_t* rng_state,
cugraph_graph_t* graph,
const cugraph_type_erased_device_array_view_t* start_vertices,
size_t max_length,
Expand All @@ -581,13 +580,14 @@ cugraph_error_code_t cugraph_biased_random_walks(
"vertex type of graph and start_vertices must match",
*error);

biased_random_walks_functor functor(handle, graph, start_vertices, max_length);
biased_random_walks_functor functor(handle, rng_state, graph, start_vertices, max_length);

return cugraph::c_api::run_algorithm(graph, functor, result, error);
}

cugraph_error_code_t cugraph_node2vec_random_walks(
const cugraph_resource_handle_t* handle,
cugraph_rng_state_t* rng_state,
cugraph_graph_t* graph,
const cugraph_type_erased_device_array_view_t* start_vertices,
size_t max_length,
Expand All @@ -604,7 +604,7 @@ cugraph_error_code_t cugraph_node2vec_random_walks(
"vertex type of graph and start_vertices must match",
*error);

node2vec_random_walks_functor functor(handle, graph, start_vertices, max_length, p, q);
node2vec_random_walks_functor functor(handle, rng_state, graph, start_vertices, max_length, p, q);

return cugraph::c_api::run_algorithm(graph, functor, result, error);
}
Loading

0 comments on commit dfdc73a

Please sign in to comment.