Skip to content

Commit 4d2dd27

Browse files
Biased Random Walks and Node2Vec implementation (#4645)
Replaces #4499 Closes #4499 @G-Cornett implemented biased random walks and node2vec during his internship. This PR includes his changes to implement those algorithms. Authors: - Chuck Hastings (https://github.com/ChuckHastings) - Garrett Cornett (https://github.com/G-Cornett) Approvers: - Joseph Nke (https://github.com/jnke2016) - Naim (https://github.com/naimnv) - Seunghwa Kang (https://github.com/seunghwak) URL: #4645
1 parent a4baa5b commit 4d2dd27

15 files changed

+899
-380
lines changed

cpp/include/cugraph/algorithms.hpp

+6-6
Original file line numberDiff line numberDiff line change
@@ -1579,11 +1579,11 @@ std::
15791579
template <typename vertex_t, typename edge_t, typename weight_t, bool multi_gpu>
15801580
std::tuple<rmm::device_uvector<vertex_t>, std::optional<rmm::device_uvector<weight_t>>>
15811581
uniform_random_walks(raft::handle_t const& handle,
1582+
raft::random::RngState& rng_state,
15821583
graph_view_t<vertex_t, edge_t, false, multi_gpu> const& graph_view,
15831584
std::optional<edge_property_view_t<edge_t, weight_t const*>> edge_weight_view,
15841585
raft::device_span<vertex_t const> start_vertices,
1585-
size_t max_length,
1586-
uint64_t seed = std::numeric_limits<uint64_t>::max());
1586+
size_t max_length);
15871587

15881588
/**
15891589
* @brief returns biased random walks from starting sources, where each path is of given
@@ -1623,11 +1623,11 @@ uniform_random_walks(raft::handle_t const& handle,
16231623
template <typename vertex_t, typename edge_t, typename weight_t, bool multi_gpu>
16241624
std::tuple<rmm::device_uvector<vertex_t>, std::optional<rmm::device_uvector<weight_t>>>
16251625
biased_random_walks(raft::handle_t const& handle,
1626+
raft::random::RngState& rng_state,
16261627
graph_view_t<vertex_t, edge_t, false, multi_gpu> const& graph_view,
16271628
edge_property_view_t<edge_t, weight_t const*> edge_weight_view,
16281629
raft::device_span<vertex_t const> start_vertices,
1629-
size_t max_length,
1630-
uint64_t seed = std::numeric_limits<uint64_t>::max());
1630+
size_t max_length);
16311631

16321632
/**
16331633
* @brief returns biased random walks with node2vec biases from starting sources,
@@ -1670,13 +1670,13 @@ biased_random_walks(raft::handle_t const& handle,
16701670
template <typename vertex_t, typename edge_t, typename weight_t, bool multi_gpu>
16711671
std::tuple<rmm::device_uvector<vertex_t>, std::optional<rmm::device_uvector<weight_t>>>
16721672
node2vec_random_walks(raft::handle_t const& handle,
1673+
raft::random::RngState& rng_state,
16731674
graph_view_t<vertex_t, edge_t, false, multi_gpu> const& graph_view,
16741675
std::optional<edge_property_view_t<edge_t, weight_t const*>> edge_weight_view,
16751676
raft::device_span<vertex_t const> start_vertices,
16761677
size_t max_length,
16771678
weight_t p,
1678-
weight_t q,
1679-
uint64_t seed = std::numeric_limits<uint64_t>::max());
1679+
weight_t q);
16801680

16811681
#ifndef NO_CUGRAPH_OPS
16821682
/**

cpp/src/c_api/random_walks.cpp

+25-9
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
#include "c_api/abstract_functor.hpp"
1818
#include "c_api/graph.hpp"
19+
#include "c_api/random.hpp"
1920
#include "c_api/resource_handle.hpp"
2021
#include "c_api/utils.hpp"
2122

@@ -153,10 +154,11 @@ namespace {
153154

154155
struct uniform_random_walks_functor : public cugraph::c_api::abstract_functor {
155156
raft::handle_t const& handle_;
157+
// FIXME: rng_state_ should be passed as a parameter
158+
cugraph::c_api::cugraph_rng_state_t* rng_state_{nullptr};
156159
cugraph::c_api::cugraph_graph_t* graph_{nullptr};
157160
cugraph::c_api::cugraph_type_erased_device_array_view_t const* start_vertices_{nullptr};
158161
size_t max_length_{0};
159-
size_t seed_{0};
160162
cugraph::c_api::cugraph_random_walk_result_t* result_{nullptr};
161163

162164
uniform_random_walks_functor(cugraph_resource_handle_t const* handle,
@@ -222,13 +224,17 @@ struct uniform_random_walks_functor : public cugraph::c_api::abstract_functor {
222224
graph_view.local_vertex_partition_range_last(),
223225
false);
224226

227+
// FIXME: remove once rng_state passed as parameter
228+
rng_state_ = reinterpret_cast<cugraph::c_api::cugraph_rng_state_t*>(
229+
new cugraph::c_api::cugraph_rng_state_t{raft::random::RngState{0}});
230+
225231
auto [paths, weights] = cugraph::uniform_random_walks(
226232
handle_,
233+
rng_state_->rng_state_,
227234
graph_view,
228235
(edge_weights != nullptr) ? std::make_optional(edge_weights->view()) : std::nullopt,
229236
raft::device_span<vertex_t const>{start_vertices.data(), start_vertices.size()},
230-
max_length_,
231-
seed_);
237+
max_length_);
232238

233239
//
234240
// Need to unrenumber the vertices in the resulting paths
@@ -255,11 +261,12 @@ struct uniform_random_walks_functor : public cugraph::c_api::abstract_functor {
255261

256262
struct biased_random_walks_functor : public cugraph::c_api::abstract_functor {
257263
raft::handle_t const& handle_;
264+
// FIXME: rng_state_ should be passed as a parameter
265+
cugraph::c_api::cugraph_rng_state_t* rng_state_{nullptr};
258266
cugraph::c_api::cugraph_graph_t* graph_{nullptr};
259267
cugraph::c_api::cugraph_type_erased_device_array_view_t const* start_vertices_{nullptr};
260268
size_t max_length_{0};
261269
cugraph::c_api::cugraph_random_walk_result_t* result_{nullptr};
262-
uint64_t seed_{0};
263270

264271
biased_random_walks_functor(cugraph_resource_handle_t const* handle,
265272
cugraph_graph_t* graph,
@@ -326,13 +333,17 @@ struct biased_random_walks_functor : public cugraph::c_api::abstract_functor {
326333
graph_view.local_vertex_partition_range_last(),
327334
false);
328335

336+
// FIXME: remove once rng_state passed as parameter
337+
rng_state_ = reinterpret_cast<cugraph::c_api::cugraph_rng_state_t*>(
338+
new cugraph::c_api::cugraph_rng_state_t{raft::random::RngState{0}});
339+
329340
auto [paths, weights] = cugraph::biased_random_walks(
330341
handle_,
342+
rng_state_->rng_state_,
331343
graph_view,
332344
edge_weights->view(),
333345
raft::device_span<vertex_t const>{start_vertices.data(), start_vertices.size()},
334-
max_length_,
335-
seed_);
346+
max_length_);
336347

337348
//
338349
// Need to unrenumber the vertices in the resulting paths
@@ -354,12 +365,13 @@ struct biased_random_walks_functor : public cugraph::c_api::abstract_functor {
354365

355366
struct node2vec_random_walks_functor : public cugraph::c_api::abstract_functor {
356367
raft::handle_t const& handle_;
368+
// FIXME: rng_state_ should be passed as a parameter
369+
cugraph::c_api::cugraph_rng_state_t* rng_state_{nullptr};
357370
cugraph::c_api::cugraph_graph_t* graph_{nullptr};
358371
cugraph::c_api::cugraph_type_erased_device_array_view_t const* start_vertices_{nullptr};
359372
size_t max_length_{0};
360373
double p_{0};
361374
double q_{0};
362-
uint64_t seed_{0};
363375
cugraph::c_api::cugraph_random_walk_result_t* result_{nullptr};
364376

365377
node2vec_random_walks_functor(cugraph_resource_handle_t const* handle,
@@ -431,15 +443,19 @@ struct node2vec_random_walks_functor : public cugraph::c_api::abstract_functor {
431443
graph_view.local_vertex_partition_range_last(),
432444
false);
433445

446+
// FIXME: remove once rng_state passed as parameter
447+
rng_state_ = reinterpret_cast<cugraph::c_api::cugraph_rng_state_t*>(
448+
new cugraph::c_api::cugraph_rng_state_t{raft::random::RngState{0}});
449+
434450
auto [paths, weights] = cugraph::node2vec_random_walks(
435451
handle_,
452+
rng_state_->rng_state_,
436453
graph_view,
437454
(edge_weights != nullptr) ? std::make_optional(edge_weights->view()) : std::nullopt,
438455
raft::device_span<vertex_t const>{start_vertices.data(), start_vertices.size()},
439456
max_length_,
440457
static_cast<weight_t>(p_),
441-
static_cast<weight_t>(q_),
442-
seed_);
458+
static_cast<weight_t>(q_));
443459

444460
// FIXME: Need to fix invalid_vtx issue here. We can't unrenumber max_vertex_id+1
445461
// properly...

cpp/src/prims/detail/sample_and_compute_local_nbr_indices.cuh

+5-6
Original file line numberDiff line numberDiff line change
@@ -392,11 +392,11 @@ compute_unique_keys(raft::handle_t const& handle,
392392
cuda::proclaim_return_type<size_t>(
393393
[unique_key_first = get_dataframe_buffer_begin(aggregate_local_frontier_unique_keys) +
394394
local_frontier_unique_key_displacements[i],
395-
num_unique_keys = local_frontier_unique_key_sizes[i]] __device__(key_t key) {
395+
unique_key_last = get_dataframe_buffer_begin(aggregate_local_frontier_unique_keys) +
396+
local_frontier_unique_key_displacements[i] +
397+
local_frontier_unique_key_sizes[i]] __device__(key_t key) {
396398
return static_cast<size_t>(thrust::distance(
397-
unique_key_first,
398-
thrust::lower_bound(
399-
thrust::seq, unique_key_first, unique_key_first + num_unique_keys, key)));
399+
unique_key_first, thrust::find(thrust::seq, unique_key_first, unique_key_last, key)));
400400
}));
401401
}
402402

@@ -1759,8 +1759,7 @@ biased_sample_and_compute_local_nbr_indices(
17591759
std::optional<rmm::device_uvector<size_t>> key_indices{std::nullopt};
17601760
std::vector<size_t> local_frontier_sample_offsets{};
17611761
if (with_replacement) {
1762-
// computet segmented inclusive sums (one segment per seed)
1763-
1762+
// compute segmented inclusive sums (one segment per seed)
17641763
auto unique_key_first = thrust::make_transform_iterator(
17651764
thrust::make_counting_iterator(size_t{0}),
17661765
cuda::proclaim_return_type<size_t>(

cpp/src/prims/per_v_random_select_transform_outgoing_e.cuh

+3-3
Original file line numberDiff line numberDiff line change
@@ -351,7 +351,7 @@ per_v_random_select_transform_e(raft::handle_t const& handle,
351351
uniform_sample_and_compute_local_nbr_indices(
352352
handle,
353353
graph_view,
354-
(minor_comm_size > 1) ? get_dataframe_buffer_begin(*aggregate_local_frontier)
354+
(minor_comm_size > 1) ? get_dataframe_buffer_cbegin(*aggregate_local_frontier)
355355
: frontier.begin(),
356356
local_frontier_displacements,
357357
local_frontier_sizes,
@@ -363,7 +363,7 @@ per_v_random_select_transform_e(raft::handle_t const& handle,
363363
biased_sample_and_compute_local_nbr_indices(
364364
handle,
365365
graph_view,
366-
(minor_comm_size > 1) ? get_dataframe_buffer_begin(*aggregate_local_frontier)
366+
(minor_comm_size > 1) ? get_dataframe_buffer_cbegin(*aggregate_local_frontier)
367367
: frontier.begin(),
368368
edge_bias_src_value_input,
369369
edge_bias_dst_value_input,
@@ -392,7 +392,7 @@ per_v_random_select_transform_e(raft::handle_t const& handle,
392392
graph_view.local_edge_partition_view(i));
393393

394394
auto edge_partition_frontier_key_first =
395-
((minor_comm_size > 1) ? get_dataframe_buffer_begin(*aggregate_local_frontier)
395+
((minor_comm_size > 1) ? get_dataframe_buffer_cbegin(*aggregate_local_frontier)
396396
: frontier.begin()) +
397397
local_frontier_displacements[i];
398398
auto edge_partition_sample_local_nbr_index_first =

0 commit comments

Comments
 (0)