Skip to content

Commit

Permalink
C API for creating a graph (#1907)
Browse files Browse the repository at this point in the history
Partially addresses #1906

This PR defines the API for graph creation and the pagerank and bfs calls that we will use to experiment with transposing a graph.

Some notes on the design here.

1. The intention is that the C API will handle renumbering (when set to true on graph creation).  This means that the opaque cugraph_graph_t pointer being populated by cugraph_sg_graph_create will contain the renumbering device vector and that the C API implementation of algorithms (pagerank and bfs demonstrated here) will unrenumber the result before returning
2. The intention is that the C API will understand whether the algorithm wants `store_transposed=true` or `store_transposed=false` and will call the transpose method if required.

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

Approvers:
  - Andrei Schaffer (https://github.com/aschaffer)
  - Rick Ratzel (https://github.com/rlratzel)
  - Seunghwa Kang (https://github.com/seunghwak)

URL: #1907
  • Loading branch information
ChuckHastings authored Nov 5, 2021
1 parent b740286 commit 61e8bad
Show file tree
Hide file tree
Showing 19 changed files with 1,295 additions and 101 deletions.
6 changes: 6 additions & 0 deletions cpp/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,12 @@ endif()

add_library(cugraph_c SHARED
src/c_api/cugraph_api.cpp
src/c_api/array.cpp
src/c_api/error.cpp
src/c_api/graph_sg.cpp
src/c_api/graph_mg.cpp
src/c_api/pagerank.cpp
src/c_api/bfs.cpp
)
add_library(cugraph::cugraph_c ALIAS cugraph_c)

Expand Down
214 changes: 214 additions & 0 deletions cpp/include/cugraph_c/algorithms.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,214 @@
/*
* Copyright (c) 2021, 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.
*/

#pragma once

#include <cugraph_c/cugraph_api.h>
#include <cugraph_c/error.h>
#include <cugraph_c/graph.h>

#ifdef __cplusplus
extern "C" {
#endif

/**
* @brief Opaque pagerank result type
*/
typedef struct {
int align_;
} cugraph_pagerank_result_t;

/**
* @brief Get the vertex ids from the pagerank result
*
* @param [in] result The result from pagerank
* @return type erased array of vertex ids
*/
cugraph_type_erased_device_array_t* cugraph_pagerank_result_get_vertices(
cugraph_pagerank_result_t* result);

/**
* @brief Get the pagerank values from the pagerank result
*
* @param [in] result The result from pagerank
* @return type erased array of pagerank values
*/
cugraph_type_erased_device_array_t* cugraph_pagerank_result_get_pageranks(
cugraph_pagerank_result_t* result);

/**
* @brief Free pagerank result
*
* @param [in] result The result from pagerank
*/
void cugraph_pagerank_result_free(cugraph_pagerank_result_t* result);

/**
* @brief Compute pagerank
*
* @param [in] handle Handle for accessing resources
* @param [in] graph Pointer to graph
* @param [in] precomputed_vertex_out_weight_sums
* Optionally send in precomputed sume of vertex out weights
* (a performance optimization). Set to NULL if
* no value is passed.
* @param [in] alpha PageRank damping factor.
* @param [in] epsilon Error tolerance to check convergence. Convergence is assumed
* if the sum of the differences in PageRank values between two
* consecutive iterations is less than the number of vertices
* in the graph multiplied by @p epsilon.
* @param [in] max_iterations Maximum number of PageRank iterations.
* @param [in] has_initial_guess If set to `true`, values in the PageRank output array (pointed by
* @p pageranks) is used as initial PageRank values. If false, initial PageRank values are set
* to 1.0 divided by the number of vertices in the graph.
* @param do_expensive_check A flag to run expensive checks for input arguments (if set to `true`).
* @param [out] result Opaque pointer to pagerank results
* @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_pagerank(
const cugraph_resource_handle_t* handle,
const cugraph_graph_t* graph,
const cugraph_type_erased_device_array_t* precomputed_vertex_out_weight_sums,
double alpha,
double epsilon,
size_t max_iterations,
bool has_initial_guess,
bool do_expensive_check,
cugraph_pagerank_result_t** result,
cugraph_error_t** error);

/**
* @brief Compute personalized pagerank
*
* @param [in] handle Handle for accessing resources
* @param [in] graph Pointer to graph
* @param [in] precomputed_vertex_out_weight_sums
* Optionally send in precomputed sume of vertex out weights
* (a performance optimization). Set to NULL if
* no value is passed.
* @param [in] personalization_vertices Pointer to an array storing personalization vertex
* identifiers (compute personalized PageRank)
* @param [in] personalization_values Pointer to an array storing personalization values for the
* vertices in the personalization set.
* @param [in] alpha PageRank damping factor.
* @param [in] epsilon Error tolerance to check convergence. Convergence is assumed
* if the sum of the differences in PageRank values between two
* consecutive iterations is less than the number of vertices
* in the graph multiplied by @p epsilon.
* @param [in] max_iterations Maximum number of PageRank iterations.
* @param [in] has_initial_guess If set to `true`, values in the PageRank output array (pointed by
* @p pageranks) is used as initial PageRank values. If false, initial PageRank values are set
* to 1.0 divided by the number of vertices in the graph.
* @param do_expensive_check A flag to run expensive checks for input arguments (if set to `true`).
* @param [out] result Opaque pointer to pagerank results
* @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_personalized_pagerank(
const cugraph_resource_handle_t* handle,
const cugraph_graph_t* graph,
const cugraph_type_erased_device_array_t* precomputed_vertex_out_weight_sums,
const cugraph_type_erased_device_array_t* personalization_vertices,
const cugraph_type_erased_device_array_t* personalization_values,
double alpha,
double epsilon,
size_t max_iterations,
bool has_initial_guess,
bool do_expensive_check,
cugraph_pagerank_result_t** result,
cugraph_error_t** error);

/**
* @brief Opaque bfs result type
*/
typedef struct {
int align_;
} cugraph_bfs_result_t;

/**
* @brief Get the vertex ids from the bfs result
*
* @param [in] result The result from bfs
* @return type erased array of vertex ids
*/
cugraph_type_erased_device_array_t* cugraph_bfs_result_get_vertices(cugraph_bfs_result_t* result);

/**
* @brief Get the distances from the bfs result
*
* @param [in] result The result from bfs
* @return type erased array of distances
*/
cugraph_type_erased_device_array_t* cugraph_bfs_result_get_distances(cugraph_bfs_result_t* result);

/**
* @brief Get the predecessors from the bfs result
*
* @param [in] result The result from bfs
* @return type erased array of predecessors. Value will be NULL if
* compute_predecessors was FALSE in the call to bfs that
* produced this result.
*/
cugraph_type_erased_device_array_t* cugraph_bfs_result_get_predecessors(
cugraph_bfs_result_t* result);

/**
* @brief Free bfs result
*
* @param [in] result The result from bfs
*/
void cugraph_bfs_result_free(cugraph_bfs_result_t* result);

/**
* @brief Perform a breadth first search from a set of seed vertices.
*
* This function computes the distances (minimum number of hops to reach the vertex) from the source
* vertex. If @p predecessors is not NULL, this function calculates the predecessor of each
* vertex (parent vertex in the breadth-first search tree) as well.
*
* @param [in] handle Handle for accessing resources
* @param [in] graph Pointer to graph
* @param [in] sources Array of source vertices
* @param [in] direction_optimizing If set to true, this algorithm switches between the push based
* breadth-first search and pull based breadth-first search depending on the size of the
* breadth-first search frontier (currently unsupported). This option is valid only for symmetric
* input graphs.
* @param depth_limit Sets the maximum number of breadth-first search iterations. Any vertices
* 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`).
* @param [out] vertex_ids Returns device pointer to vertex ids
* @param [out] distances Returns device pointer to distance from the seeds
* @param [out] predecessors Returns device pointer to distance from the seeds
* @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_bfs(const cugraph_resource_handle_t* handle,
const cugraph_graph_t* graph,
const cugraph_type_erased_device_array_t* sources,
bool direction_optimizing,
size_t depth_limit,
bool do_expensive_check,
bool compute_predecessors,
cugraph_bfs_result_t** result,
cugraph_error_t** error);

#ifdef __cplusplus
}
#endif
164 changes: 164 additions & 0 deletions cpp/include/cugraph_c/array.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
/*
* Copyright (c) 2021, 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.
*/

#pragma once

#include <cugraph_c/cugraph_api.h>

#ifdef __cplusplus
extern "C" {
#endif

typedef struct {
int align_;
} cugraph_type_erased_device_array_t;

typedef struct {
int align_;
} cugraph_type_erased_host_array_t;

/**
* @brief Create a type erased device array
*
* @param [in] handle Handle for accessing resources
* @param [in] dtype The type of array to create
* @param [in] n_elems The number of elements in the array
* @param [out] array Pointer to the location to store the pointer to the device array
* @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_type_erased_device_array_create(
const cugraph_resource_handle_t* handle,
data_type_id_t dtype,
size_t n_elems,
cugraph_type_erased_device_array_t** array,
cugraph_error_t** error);

/**
* @brief Destroy a type erased device array
*
* @param [in] p Pointer to the type erased device array
*/
void cugraph_type_erased_device_array_free(cugraph_type_erased_device_array_t* p);

/**
* @brief Get the size of a type erased device array
*
* @param [in] p Pointer to the type erased device array
* @return The number of elements in the array
*/
size_t cugraph_type_erased_device_array_size(const cugraph_type_erased_device_array_t* p);

/**
* @brief Get the type of a type erased device array
*
* @param [in] p Pointer to the type erased device array
* @return The type of the elements in the array
*/
data_type_id_t cugraph_type_erased_device_array_type(const cugraph_type_erased_device_array_t* p);

/**
* @brief Get the raw pointer of the type erased device array
*
* @param [in] p Pointer to the type erased device array
* @return Pointer (device memory) for the data in the array
*/
void* cugraph_type_erased_device_array_pointer(const cugraph_type_erased_device_array_t* p);

/**
* @brief Create a type erased host array
*
* @param [in] handle Handle for accessing resources
* @param [in] dtype The type of array to create
* @param [in] n_elems The number of elements in the array
* @param [out] array Pointer to the location to store the pointer to the host array
* @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_type_erased_host_array_create(const cugraph_resource_handle_t* handle,
data_type_id_t dtype,
size_t n_elems,
cugraph_type_erased_host_array_t** array,
cugraph_error_t** error);

/**
* @brief Destroy a type erased host array
*
* @param [in] p Pointer to the type erased host array
*/
void cugraph_type_erased_host_array_free(cugraph_type_erased_host_array_t* p);

/**
* @brief Get the size of a type erased host array
*
* @param [in] p Pointer to the type erased host array
* @return The number of elements in the array
*/
size_t cugraph_type_erased_host_array_size(const cugraph_type_erased_host_array_t* p);

/**
* @brief Get the type of a type erased host array
*
* @param [in] p Pointer to the type erased host array
* @return The type of the elements in the array
*/
data_type_id_t cugraph_type_erased_host_array_type(const cugraph_type_erased_host_array_t* p);

/**
* @brief Get the raw pointer of the type erased host array
*
* @param [in] p Pointer to the type erased host array
* @return Pointer (host memory) for the data in the array
*/
void* cugraph_type_erased_host_array_pointer(const cugraph_type_erased_host_array_t* p);

/**
* @brief Copy data from host to a type erased device array
*
* @param [in] handle Handle for accessing resources
* @param [out] dst Pointer to the type erased device array
* @param [in] h_src Pointer to host array to copy into device memory
* @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_type_erased_device_array_copy_from_host(
const cugraph_resource_handle_t* handle,
cugraph_type_erased_device_array_t* dst,
const byte_t* h_src,
cugraph_error_t** error);

/**
* @brief Copy data from device to a type erased host array
*
* @param [in] handle Handle for accessing resources
* @param [out] h_dst Pointer to host array
* @param [in] src Pointer to the type erased device array to copy from
* @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_type_erased_device_array_copy_to_host(
const cugraph_resource_handle_t* handle,
byte_t* h_dst,
const cugraph_type_erased_device_array_t* src,
cugraph_error_t** error);

#ifdef __cplusplus
}
#endif
Loading

0 comments on commit 61e8bad

Please sign in to comment.