Skip to content

Commit

Permalink
Add node2vec to C API - API PR (#2059)
Browse files Browse the repository at this point in the history
This adds a new node2vec method to the C API.

Implementation will follow in a subsequent PR.

Authors:
  - Chuck Hastings (https://github.com/ChuckHastings)

Approvers:
  - Rick Ratzel (https://github.com/rlratzel)
  - Brad Rees (https://github.com/BradReesWork)

URL: #2059
  • Loading branch information
ChuckHastings authored Feb 10, 2022
1 parent aa68625 commit 5ca3b0c
Show file tree
Hide file tree
Showing 4 changed files with 155 additions and 4 deletions.
68 changes: 68 additions & 0 deletions cpp/include/cugraph_c/algorithms.h
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,74 @@ cugraph_type_erased_device_array_view_t* cugraph_extract_paths_result_get_paths(
*/
void cugraph_extract_paths_result_free(cugraph_extract_paths_result_t* result);

/**
* @brief Opaque extract_paths result type
*/
typedef struct {
int32_t align_;
} cugraph_random_walk_result_t;

/**
* @brief Compute random walks using the node2vec framework.
*
* @param [in] handle Handle for accessing resources
* @param [in] graph Pointer to graph. NOTE: Graph might be modified if the storage
* needs to be transposed
* @param [in] sources Array of source vertices
* @param [in] max_depth Maximum length of the generated path
* @param [in] p The return parameter
* @param [in] q The in/out parameter
* @param [in] result Output from the node2vec call
* @param [out] error Pointer to an error object storing details of any error. Will
* be populated if error code is not CUGRAPH_SUCCESS
* @return error code
*/
cugraph_error_code_t cugraph_node2vec(const cugraph_resource_handle_t* handle,
cugraph_graph_t* graph,
const cugraph_type_erased_device_array_view_t* sources,
size_t max_depth,
bool_t flag_use_padding,
double p,
double q,
cugraph_random_walk_result_t** result,
cugraph_error_t** error);

/**
* @brief Get the max path length from random walk result
*
* @param [in] result The result from random walks
* @return maximum path length
*/
size_t cugraph_random_walk_result_get_max_path_length(cugraph_random_walk_result_t* result);

// FIXME: Should this be the same as extract_paths_result_t? The only
// difference at the moment is that RW results contain weights
// and extract_paths results don't. But that's probably wrong.
/**
* @brief Get the matrix (row major order) of vertices in the paths
*
* @param [in] result The result from extract_paths
* @return type erased array pointing to the matrix in device memory
*/
cugraph_type_erased_device_array_view_t* cugraph_random_walk_result_get_paths(
cugraph_random_walk_result_t* result);

/**
* @brief Get the matrix (row major order) of edge weights in the paths
*
* @param [in] result The result from extract_paths
* @return type erased array pointing to the edge weights in device memory
*/
cugraph_type_erased_device_array_view_t* cugraph_random_walk_result_get_weights(
cugraph_random_walk_result_t* result);

/**
* @brief Free random walks result
*
* @param [in] result The result from random walks
*/
void cugraph_random_walk_result_free(cugraph_random_walk_result_t* result);

#ifdef __cplusplus
}
#endif
1 change: 1 addition & 0 deletions cpp/tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -615,6 +615,7 @@ ConfigureCTest(CAPI_PAGERANK_TEST c_api/pagerank_test.c)
ConfigureCTest(CAPI_BFS_TEST c_api/bfs_test.c)
ConfigureCTest(CAPI_SSSP_TEST c_api/sssp_test.c)
ConfigureCTest(CAPI_EXTRACT_PATHS_TEST c_api/extract_paths_test.c)
ConfigureCTest(CAPI_NODE2VEC_TEST c_api/node2vec_test.c)

###################################################################################################
### enable testing ################################################################################
Expand Down
8 changes: 4 additions & 4 deletions cpp/tests/c_api/bfs_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ int generic_bfs_test(vertex_t* h_src,
int test_ret_value = 0;

cugraph_error_code_t ret_code = CUGRAPH_SUCCESS;
cugraph_error_t* ret_error;
cugraph_error_t* ret_error = NULL;

cugraph_resource_handle_t* p_handle = NULL;
cugraph_graph_t* p_graph = NULL;
Expand Down Expand Up @@ -73,9 +73,9 @@ int generic_bfs_test(vertex_t* h_src,
p_handle, p_graph, p_source_view, FALSE, depth_limit, TRUE, FALSE, &p_result, &ret_error);
TEST_ASSERT(test_ret_value, ret_code == CUGRAPH_SUCCESS, "cugraph_bfs failed.");

cugraph_type_erased_device_array_t* vertices;
cugraph_type_erased_device_array_t* distances;
cugraph_type_erased_device_array_t* predecessors;
cugraph_type_erased_device_array_view_t* vertices;
cugraph_type_erased_device_array_view_t* distances;
cugraph_type_erased_device_array_view_t* predecessors;

vertices = cugraph_paths_result_get_vertices(p_result);
distances = cugraph_paths_result_get_distances(p_result);
Expand Down
82 changes: 82 additions & 0 deletions cpp/tests/c_api/node2vec_test.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
/*
* Copyright (c) 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 "c_test_utils.h" /* RUN_TEST */

#include <cugraph_c/algorithms.h>
#include <cugraph_c/graph.h>

#include <math.h>

typedef int32_t vertex_t;
typedef int32_t edge_t;
typedef float weight_t;

int generic_node2vec_test(vertex_t* h_src,
vertex_t* h_dst,
weight_t* h_wgt,
vertex_t* h_seeds,
size_t num_edges,
size_t num_seeds,
size_t max_depth,
bool_t store_transposed)
{
int test_ret_value = 0;

cugraph_error_code_t ret_code = CUGRAPH_SUCCESS;
cugraph_error_t* ret_error = NULL;

cugraph_resource_handle_t* p_handle = NULL;
cugraph_graph_t* p_graph = NULL;

p_handle = cugraph_create_resource_handle();
TEST_ASSERT(test_ret_value, p_handle != NULL, "resource handle creation failed.");

ret_code = create_test_graph(
p_handle, h_src, h_dst, h_wgt, num_edges, store_transposed, &p_graph, &ret_error);

// Populate this test.
// We can easily validate that the results of node2vec
// are feasible by converting the sparse (h_src,h_dst,h_wgt)
// into a dense host matrix and check each path.

cugraph_sg_graph_free(p_graph);
cugraph_free_resource_handle(p_handle);
cugraph_error_free(ret_error);

return test_ret_value;
}

int test_node2vec()
{
size_t num_edges = 8;
size_t num_vertices = 6;

vertex_t src[] = {0, 1, 1, 2, 2, 2, 3, 4};
vertex_t dst[] = {1, 3, 4, 0, 1, 3, 5, 5};
weight_t wgt[] = {0.1f, 2.1f, 1.1f, 5.1f, 3.1f, 4.1f, 7.2f, 3.2f};
vertex_t seeds[] = {0};
size_t max_depth = 4;

return generic_node2vec_test(src, dst, wgt, seeds, max_depth, num_edges, 1, FALSE);
}

int main(int argc, char** argv)
{
int result = 0;
result |= RUN_TEST(test_node2vec);
return result;
}

0 comments on commit 5ca3b0c

Please sign in to comment.