From b98c48aa1e537c68ad66b87100d237abe0e69ce5 Mon Sep 17 00:00:00 2001 From: Chuck Hastings Date: Fri, 1 Apr 2022 13:35:18 -0400 Subject: [PATCH 1/8] C API changes for labeling algorithms 1) Add C API definition/implementation/testing for WCC 2) Add C API definition for SCC 3) Update test utilities to support symmetric graph property --- cpp/CMakeLists.txt | 2 + cpp/include/cugraph_c/algorithms.h | 2 + cpp/include/cugraph_c/labeling_algorithms.h | 103 ++++++++++++ cpp/src/c_api/labeling_result.cpp | 45 +++++ cpp/src/c_api/labeling_result.hpp | 31 ++++ cpp/src/c_api/weakly_connected_components.cpp | 105 ++++++++++++ cpp/tests/CMakeLists.txt | 2 + cpp/tests/c_api/bfs_test.c | 10 +- cpp/tests/c_api/c_test_utils.h | 1 + cpp/tests/c_api/extract_paths_test.c | 2 +- cpp/tests/c_api/hits_test.c | 2 +- cpp/tests/c_api/mg_hits_test.c | 44 +++-- cpp/tests/c_api/mg_pagerank_test.c | 10 +- cpp/tests/c_api/mg_test_utils.cpp | 3 +- cpp/tests/c_api/mg_test_utils.h | 1 + .../mg_weakly_connected_components_test.c | 156 ++++++++++++++++++ cpp/tests/c_api/node2vec_test.c | 2 +- cpp/tests/c_api/pagerank_test.c | 2 +- cpp/tests/c_api/sssp_test.c | 2 +- cpp/tests/c_api/test_utils.cpp | 3 +- .../c_api/weakly_connected_components_test.c | 128 ++++++++++++++ 21 files changed, 625 insertions(+), 31 deletions(-) create mode 100644 cpp/include/cugraph_c/labeling_algorithms.h create mode 100644 cpp/src/c_api/labeling_result.cpp create mode 100644 cpp/src/c_api/labeling_result.hpp create mode 100644 cpp/src/c_api/weakly_connected_components.cpp create mode 100644 cpp/tests/c_api/mg_weakly_connected_components_test.c create mode 100644 cpp/tests/c_api/weakly_connected_components_test.c diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt index 950e9ddc823..8824ceb902f 100644 --- a/cpp/CMakeLists.txt +++ b/cpp/CMakeLists.txt @@ -361,6 +361,8 @@ add_library(cugraph_c SHARED src/c_api/extract_paths.cpp src/c_api/random_walks.cpp src/c_api/uniform_neighbor_sampling.cpp + src/c_api/labeling_result.cpp + src/c_api/weakly_connected_components.cpp ) add_library(cugraph::cugraph_c ALIAS cugraph_c) diff --git a/cpp/include/cugraph_c/algorithms.h b/cpp/include/cugraph_c/algorithms.h index c156a72ec35..1f4fcbd0386 100644 --- a/cpp/include/cugraph_c/algorithms.h +++ b/cpp/include/cugraph_c/algorithms.h @@ -584,3 +584,5 @@ void cugraph_sample_result_free(cugraph_sample_result_t* result); #ifdef __cplusplus } #endif + +#include diff --git a/cpp/include/cugraph_c/labeling_algorithms.h b/cpp/include/cugraph_c/labeling_algorithms.h new file mode 100644 index 00000000000..57ded366c31 --- /dev/null +++ b/cpp/include/cugraph_c/labeling_algorithms.h @@ -0,0 +1,103 @@ +/* + * 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. + */ + +#pragma once + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Opaque labeling result type + */ +typedef struct { + int32_t align_; +} cugraph_labeling_result_t; + +/** + * @brief Get the vertex ids from the labeling result + * + * @param [in] result The result from a labeling algorithm + * @return type erased array of vertex ids + */ +cugraph_type_erased_device_array_view_t* cugraph_labeling_result_get_vertices( + cugraph_labeling_result_t* result); + +/** + * @brief Get the label values from the labeling result + * + * @param [in] result The result from a labeling algorithm + * @return type erased array of label values + */ +cugraph_type_erased_device_array_view_t* cugraph_labeling_result_get_labels( + cugraph_labeling_result_t* result); + +/** + * @brief Free labeling result + * + * @param [in] result The result from a labeling algorithm + */ +void cugraph_labeling_result_free(cugraph_labeling_result_t* result); + +/** + * @brief Labels each vertex in the input graph with its (weakly-connected-)component ID + * + * The input graph must be symmetric. Component IDs can be arbitrary integers (they can be + * non-consecutive and are not ordered by component size or any other criterion). + * + * @param [in] handle Handle for accessing resources + * @param [in] graph Pointer to graph + * @param [in] do_expensive_check A flag to run expensive checks for input arguments (if set to + * `true`). + * @param [out] result Opaque pointer to labeling results + * @param [out] error Pointer to an error object storing details of any error. Will + * be populated if error code is not CUGRAPH_SUCCESS + */ +cugraph_error_code_t cugraph_weakly_connected_components( + const cugraph_resource_handle_t* handle, + cugraph_graph_t* graph, + bool_t do_expensive_check, + cugraph_labeling_result_t** result, + cugraph_error_t** error); + +/** + * @brief Labels each vertex in the input graph with its (strongly-connected-)component ID + * + * The input graph may be asymmetric. Component IDs can be arbitrary integers (they can be + * non-consecutive and are not ordered by component size or any other criterion). + * + * @param [in] handle Handle for accessing resources + * @param [in] graph Pointer to graph + * @param [in] do_expensive_check A flag to run expensive checks for input arguments (if set to + * `true`). + * @param [out] result Opaque pointer to labeling results + * @param [out] error Pointer to an error object storing details of any error. Will + * be populated if error code is not CUGRAPH_SUCCESS + */ +cugraph_error_code_t cugraph_strongly_connected_components( + const cugraph_resource_handle_t* handle, + cugraph_graph_t* graph, + bool_t do_expensive_check, + cugraph_labeling_result_t** result, + cugraph_error_t** error); + +#ifdef __cplusplus +} +#endif diff --git a/cpp/src/c_api/labeling_result.cpp b/cpp/src/c_api/labeling_result.cpp new file mode 100644 index 00000000000..7f31514775b --- /dev/null +++ b/cpp/src/c_api/labeling_result.cpp @@ -0,0 +1,45 @@ +/* + * 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 + +#include + +extern "C" cugraph_type_erased_device_array_view_t* cugraph_labeling_result_get_vertices( + cugraph_labeling_result_t* result) +{ + auto internal_pointer = reinterpret_cast(result); + return reinterpret_cast( + internal_pointer->vertex_ids_->view()); +} + +extern "C" cugraph_type_erased_device_array_view_t* cugraph_labeling_result_get_labels( + cugraph_labeling_result_t* result) +{ + auto internal_pointer = reinterpret_cast(result); + return reinterpret_cast( + internal_pointer->labels_->view()); +} + +extern "C" void cugraph_labeling_result_free(cugraph_labeling_result_t* result) +{ + auto internal_pointer = reinterpret_cast(result); + delete internal_pointer->vertex_ids_; + delete internal_pointer->labels_; + delete internal_pointer; +} + + diff --git a/cpp/src/c_api/labeling_result.hpp b/cpp/src/c_api/labeling_result.hpp new file mode 100644 index 00000000000..cce6f15063d --- /dev/null +++ b/cpp/src/c_api/labeling_result.hpp @@ -0,0 +1,31 @@ +/* + * 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. + */ + +#pragma once + +#include + +namespace cugraph { +namespace c_api { + +struct cugraph_labeling_result_t { + cugraph_type_erased_device_array_t* vertex_ids_; + cugraph_type_erased_device_array_t* labels_; +}; + +} // namespace c_api +} // namespace cugraph + diff --git a/cpp/src/c_api/weakly_connected_components.cpp b/cpp/src/c_api/weakly_connected_components.cpp new file mode 100644 index 00000000000..543c92f2ff2 --- /dev/null +++ b/cpp/src/c_api/weakly_connected_components.cpp @@ -0,0 +1,105 @@ +/* + * 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 + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +namespace { + +struct wcc_functor : public cugraph::c_api::abstract_functor { + raft::handle_t const& handle_; + cugraph::c_api::cugraph_graph_t* graph_; + bool do_expensive_check_; + cugraph::c_api::cugraph_labeling_result_t* result_{}; + + wcc_functor(::cugraph_resource_handle_t const* handle, + ::cugraph_graph_t* graph, + bool do_expensive_check) + : abstract_functor(), + handle_(*reinterpret_cast(handle)->handle_), + graph_(reinterpret_cast(graph)), + do_expensive_check_(do_expensive_check) + { + } + + template + void operator()() + { + // FIXME: Think about how to handle SG vice MG + if constexpr (!cugraph::is_candidate::value) { + unsupported(); + } else { + // WCC expects store_transposed == false + if constexpr (store_transposed) { + error_code_ = cugraph::c_api:: + transpose_storage( + handle_, graph_, error_.get()); + if (error_code_ != CUGRAPH_SUCCESS) return; + } + + auto graph = reinterpret_cast*>( + graph_->graph_); + + auto graph_view = graph->view(); + + auto number_map = reinterpret_cast*>(graph_->number_map_); + + rmm::device_uvector components(graph_view.get_number_of_local_vertices(), + handle_.get_stream()); + + cugraph::weakly_connected_components( + handle_, graph_view, components.data(), do_expensive_check_); + + rmm::device_uvector vertex_ids(graph_view.get_number_of_local_vertices(), + handle_.get_stream()); + raft::copy(vertex_ids.data(), number_map->data(), vertex_ids.size(), handle_.get_stream()); + + result_ = new cugraph::c_api::cugraph_labeling_result_t{ + new cugraph::c_api::cugraph_type_erased_device_array_t(vertex_ids, graph_->vertex_type_), + new cugraph::c_api::cugraph_type_erased_device_array_t(components, graph_->vertex_type_)}; + } + } +}; + +} // namespace + +extern "C" cugraph_error_code_t cugraph_weakly_connected_components( + const cugraph_resource_handle_t* handle, + cugraph_graph_t* graph, + bool_t do_expensive_check, + cugraph_labeling_result_t** result, + cugraph_error_t** error) +{ + wcc_functor functor(handle, graph, do_expensive_check); + + return cugraph::c_api::run_algorithm(graph, functor, result, error); +} diff --git a/cpp/tests/CMakeLists.txt b/cpp/tests/CMakeLists.txt index 1482f4f810f..19150bfa23a 100644 --- a/cpp/tests/CMakeLists.txt +++ b/cpp/tests/CMakeLists.txt @@ -620,6 +620,7 @@ if(BUILD_CUGRAPH_MG_TESTS) # - MG C API tests ------------------------------------------------------------------------ ConfigureCTestMG(MG_CAPI_CREATE_GRAPH c_api/mg_create_graph_test.c c_api/mg_test_utils.cpp) ConfigureCTestMG(MG_CAPI_PAGERANK c_api/mg_pagerank_test.c c_api/mg_test_utils.cpp) + ConfigureCTestMG(MG_CAPI_WEAKLY_CONNECTED_COMPONENTS c_api/mg_weakly_connected_components_test.c c_api/mg_test_utils.cpp) ConfigureCTestMG(MG_CAPI_HITS c_api/mg_hits_test.c c_api/mg_test_utils.cpp) else() message(FATAL_ERROR "OpenMPI NOT found, cannot build MG tests.") @@ -666,6 +667,7 @@ 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) +ConfigureCTest(CAPI_WEAKLY_CONNECTED_COMPONENTS c_api/weakly_connected_components_test.c) ################################################################################################### ### enable testing ################################################################################ diff --git a/cpp/tests/c_api/bfs_test.c b/cpp/tests/c_api/bfs_test.c index 8709e70c8d3..6f13f125df6 100644 --- a/cpp/tests/c_api/bfs_test.c +++ b/cpp/tests/c_api/bfs_test.c @@ -42,17 +42,17 @@ int generic_bfs_test(vertex_t* h_src, 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; - cugraph_paths_result_t* p_result = NULL; - cugraph_type_erased_device_array_t* p_sources = NULL; + cugraph_resource_handle_t* p_handle = NULL; + cugraph_graph_t* p_graph = NULL; + cugraph_paths_result_t* p_result = NULL; + cugraph_type_erased_device_array_t* p_sources = NULL; cugraph_type_erased_device_array_view_t* p_source_view = NULL; p_handle = cugraph_create_resource_handle(NULL); 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, FALSE, &p_graph, &ret_error); + p_handle, h_src, h_dst, h_wgt, num_edges, store_transposed, FALSE, FALSE, &p_graph, &ret_error); /* * FIXME: in create_graph_test.c, variables are defined but then hard-coded to diff --git a/cpp/tests/c_api/c_test_utils.h b/cpp/tests/c_api/c_test_utils.h index 08d4d25e8ba..206036323a3 100644 --- a/cpp/tests/c_api/c_test_utils.h +++ b/cpp/tests/c_api/c_test_utils.h @@ -50,6 +50,7 @@ int create_test_graph(const cugraph_resource_handle_t* p_handle, size_t num_edges, bool_t store_transposed, bool_t renumber, + bool_t is_symmetric, cugraph_graph_t** p_graph, cugraph_error_t** ret_error); diff --git a/cpp/tests/c_api/extract_paths_test.c b/cpp/tests/c_api/extract_paths_test.c index 65ede81238d..5b87c3151c7 100644 --- a/cpp/tests/c_api/extract_paths_test.c +++ b/cpp/tests/c_api/extract_paths_test.c @@ -57,7 +57,7 @@ int generic_bfs_test_with_extract_paths(vertex_t* h_src, 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, FALSE, &p_graph, &ret_error); + p_handle, h_src, h_dst, h_wgt, num_edges, store_transposed, FALSE, FALSE, &p_graph, &ret_error); ret_code = cugraph_type_erased_device_array_create(p_handle, num_seeds, INT32, &p_sources, &ret_error); diff --git a/cpp/tests/c_api/hits_test.c b/cpp/tests/c_api/hits_test.c index aa53c8e62fc..c275d883d11 100644 --- a/cpp/tests/c_api/hits_test.c +++ b/cpp/tests/c_api/hits_test.c @@ -54,7 +54,7 @@ int generic_hits_test(vertex_t* h_src, 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, renumber, &p_graph, &ret_error); + p_handle, h_src, h_dst, h_wgt, num_edges, store_transposed, renumber, FALSE, &p_graph, &ret_error); TEST_ASSERT(test_ret_value, ret_code == CUGRAPH_SUCCESS, "create_test_graph failed."); TEST_ASSERT(test_ret_value, ret_code == CUGRAPH_SUCCESS, cugraph_error_message(ret_error)); diff --git a/cpp/tests/c_api/mg_hits_test.c b/cpp/tests/c_api/mg_hits_test.c index d69d25a77c7..fb1a7c5451e 100644 --- a/cpp/tests/c_api/mg_hits_test.c +++ b/cpp/tests/c_api/mg_hits_test.c @@ -50,14 +50,22 @@ int generic_hits_test(const cugraph_resource_handle_t* p_handle, cugraph_hits_result_t* p_result = NULL; ret_code = create_mg_test_graph( - p_handle, h_src, h_dst, h_wgt, num_edges, store_transposed, &p_graph, &ret_error); + p_handle, h_src, h_dst, h_wgt, num_edges, store_transposed, FALSE, &p_graph, &ret_error); TEST_ASSERT(test_ret_value, ret_code == CUGRAPH_SUCCESS, "create_mg_test_graph failed."); TEST_ASSERT(test_ret_value, ret_code == CUGRAPH_SUCCESS, cugraph_error_message(ret_error)); if (h_initial_vertices == NULL) { - ret_code = cugraph_hits( - p_handle, p_graph, epsilon, max_iterations, NULL, NULL, normalize, FALSE, &p_result, &ret_error); + ret_code = cugraph_hits(p_handle, + p_graph, + epsilon, + max_iterations, + NULL, + NULL, + normalize, + FALSE, + &p_result, + &ret_error); } else { int rank = cugraph_resource_handle_get_rank(p_handle); @@ -90,8 +98,16 @@ int generic_hits_test(const cugraph_resource_handle_t* p_handle, p_handle, initial_hubs_view, (byte_t*)h_initial_hubs, &ret_error); TEST_ASSERT(test_ret_value, ret_code == CUGRAPH_SUCCESS, "src copy_from_host failed."); - ret_code = cugraph_hits( - p_handle, p_graph, epsilon, max_iterations, initial_vertices_view, initial_hubs_view, normalize, FALSE, &p_result, &ret_error); + ret_code = cugraph_hits(p_handle, + p_graph, + epsilon, + max_iterations, + initial_vertices_view, + initial_hubs_view, + normalize, + FALSE, + &p_result, + &ret_error); } TEST_ASSERT(test_ret_value, ret_code == CUGRAPH_SUCCESS, "cugraph_hits failed."); @@ -212,17 +228,17 @@ int test_hits_with_transpose(const cugraph_resource_handle_t* handle) int test_hits_with_initial(const cugraph_resource_handle_t* handle) { - size_t num_edges = 8; - size_t num_vertices = 6; + size_t num_edges = 8; + size_t num_vertices = 6; size_t num_initial_hubs = 5; - vertex_t h_src[] = {0, 1, 1, 2, 2, 2, 3, 4}; - vertex_t h_dst[] = {1, 3, 4, 0, 1, 3, 5, 5}; - weight_t h_wgt[] = {0.1f, 2.1f, 1.1f, 5.1f, 3.1f, 4.1f, 7.2f, 3.2f}; - weight_t h_hubs[] = {0.347296, 0.532089, 1, 0.00000959, 0.00000959, 0}; - weight_t h_authorities[] = {0.652704, 0.879385, 0, 1, 0.347296, 0.00002428}; - vertex_t h_initial_vertices[] = { 0, 1, 2, 3, 4 }; - weight_t h_initial_hubs[] = {0.347296, 0.532089, 1, 0.00003608, 0.00003608}; + vertex_t h_src[] = {0, 1, 1, 2, 2, 2, 3, 4}; + vertex_t h_dst[] = {1, 3, 4, 0, 1, 3, 5, 5}; + weight_t h_wgt[] = {0.1f, 2.1f, 1.1f, 5.1f, 3.1f, 4.1f, 7.2f, 3.2f}; + weight_t h_hubs[] = {0.347296, 0.532089, 1, 0.00000959, 0.00000959, 0}; + weight_t h_authorities[] = {0.652704, 0.879385, 0, 1, 0.347296, 0.00002428}; + vertex_t h_initial_vertices[] = {0, 1, 2, 3, 4}; + weight_t h_initial_hubs[] = {0.347296, 0.532089, 1, 0.00003608, 0.00003608}; double epsilon = 0.0001; size_t max_iterations = 20; diff --git a/cpp/tests/c_api/mg_pagerank_test.c b/cpp/tests/c_api/mg_pagerank_test.c index 941e5e09c73..98054976aef 100644 --- a/cpp/tests/c_api/mg_pagerank_test.c +++ b/cpp/tests/c_api/mg_pagerank_test.c @@ -46,7 +46,7 @@ int generic_pagerank_test(const cugraph_resource_handle_t* handle, cugraph_pagerank_result_t* p_result = NULL; ret_code = create_mg_test_graph( - handle, h_src, h_dst, h_wgt, num_edges, store_transposed, &p_graph, &ret_error); + handle, h_src, h_dst, h_wgt, num_edges, store_transposed, FALSE, &p_graph, &ret_error); TEST_ASSERT(test_ret_value, ret_code == CUGRAPH_SUCCESS, "create_mg_test_graph failed."); @@ -64,8 +64,10 @@ int generic_pagerank_test(const cugraph_resource_handle_t* handle, vertices = cugraph_pagerank_result_get_vertices(p_result); pageranks = cugraph_pagerank_result_get_pageranks(p_result); - vertex_t h_vertices[num_vertices]; - weight_t h_pageranks[num_vertices]; + size_t num_local_vertices = cugraph_type_erased_device_array_view_size(vertices); + + vertex_t h_vertices[num_local_vertices]; + weight_t h_pageranks[num_local_vertices]; ret_code = cugraph_type_erased_device_array_view_copy_to_host( handle, (byte_t*)h_vertices, vertices, &ret_error); @@ -75,8 +77,6 @@ int generic_pagerank_test(const cugraph_resource_handle_t* handle, handle, (byte_t*)h_pageranks, pageranks, &ret_error); TEST_ASSERT(test_ret_value, ret_code == CUGRAPH_SUCCESS, "copy_to_host failed."); - size_t num_local_vertices = cugraph_type_erased_device_array_view_size(vertices); - for (int i = 0; (i < num_local_vertices) && (test_ret_value == 0); ++i) { TEST_ASSERT(test_ret_value, nearlyEqual(h_result[h_vertices[i]], h_pageranks[i], 0.001), diff --git a/cpp/tests/c_api/mg_test_utils.cpp b/cpp/tests/c_api/mg_test_utils.cpp index 9539e73cf18..41bdcefaf3a 100644 --- a/cpp/tests/c_api/mg_test_utils.cpp +++ b/cpp/tests/c_api/mg_test_utils.cpp @@ -103,6 +103,7 @@ extern "C" int create_mg_test_graph(const cugraph_resource_handle_t* handle, float* h_wgt, size_t num_edges, bool_t store_transposed, + bool_t is_symmetric, cugraph_graph_t** p_graph, cugraph_error_t** ret_error) { @@ -110,7 +111,7 @@ extern "C" int create_mg_test_graph(const cugraph_resource_handle_t* handle, cugraph_error_code_t ret_code; cugraph_graph_properties_t properties; - properties.is_symmetric = FALSE; + properties.is_symmetric = is_symmetric; properties.is_multigraph = FALSE; data_type_id_t vertex_tid = INT32; diff --git a/cpp/tests/c_api/mg_test_utils.h b/cpp/tests/c_api/mg_test_utils.h index 0425d8cf74b..827cfa5c885 100644 --- a/cpp/tests/c_api/mg_test_utils.h +++ b/cpp/tests/c_api/mg_test_utils.h @@ -63,5 +63,6 @@ int create_mg_test_graph(const cugraph_resource_handle_t* p_handle, float* h_wgt, size_t num_edges, bool_t store_transposed, + bool_t is_symmetric, cugraph_graph_t** p_graph, cugraph_error_t** ret_error); diff --git a/cpp/tests/c_api/mg_weakly_connected_components_test.c b/cpp/tests/c_api/mg_weakly_connected_components_test.c new file mode 100644 index 00000000000..d0422c8540f --- /dev/null +++ b/cpp/tests/c_api/mg_weakly_connected_components_test.c @@ -0,0 +1,156 @@ +/* + * 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 "mg_test_utils.h" /* RUN_TEST */ + +#include +#include + +#include + +typedef int32_t vertex_t; +typedef int32_t edge_t; +typedef float weight_t; + +int generic_wcc_test(const cugraph_resource_handle_t* handle, + vertex_t* h_src, + vertex_t* h_dst, + weight_t* h_wgt, + vertex_t* h_result, + size_t num_vertices, + size_t num_edges, + bool_t store_transposed) +{ + int test_ret_value = 0; + + cugraph_error_code_t ret_code = CUGRAPH_SUCCESS; + cugraph_error_t* ret_error; + + cugraph_graph_t* p_graph = NULL; + cugraph_labeling_result_t* p_result = NULL; + + ret_code = create_mg_test_graph( + handle, h_src, h_dst, h_wgt, num_edges, store_transposed, TRUE, &p_graph, &ret_error); + + TEST_ASSERT(test_ret_value, ret_code == CUGRAPH_SUCCESS, "create_mg_test_graph failed."); + + ret_code = cugraph_weakly_connected_components(handle, p_graph, FALSE, &p_result, &ret_error); + TEST_ASSERT( + test_ret_value, ret_code == CUGRAPH_SUCCESS, "cugraph_weakly_connected_components failed."); + + // NOTE: Because we get back vertex ids and components, we can simply compare + // the returned values with the expected results for the entire + // graph. Each GPU will have a subset of the total vertices, so + // they will do a subset of the comparisons. + cugraph_type_erased_device_array_view_t* vertices; + cugraph_type_erased_device_array_view_t* components; + + vertices = cugraph_labeling_result_get_vertices(p_result); + components = cugraph_labeling_result_get_labels(p_result); + + size_t num_local_vertices = cugraph_type_erased_device_array_view_size(vertices); + + vertex_t h_vertices[num_local_vertices]; + vertex_t h_components[num_local_vertices]; + + ret_code = cugraph_type_erased_device_array_view_copy_to_host( + handle, (byte_t*)h_vertices, vertices, &ret_error); + TEST_ASSERT(test_ret_value, ret_code == CUGRAPH_SUCCESS, "copy_to_host failed."); + + ret_code = cugraph_type_erased_device_array_view_copy_to_host( + handle, (byte_t*)h_components, components, &ret_error); + TEST_ASSERT(test_ret_value, ret_code == CUGRAPH_SUCCESS, "copy_to_host failed."); + + vertex_t component_check[num_vertices]; + for (vertex_t i = 0; i < num_vertices; ++i) { + component_check[i] = num_vertices; + } + + vertex_t num_errors = 0; + for (vertex_t i = 0; i < num_local_vertices; ++i) { + if (component_check[h_components[i]] == num_vertices) { + component_check[h_components[i]] = h_result[h_vertices[i]]; + } else if (component_check[h_components[i]] != h_result[h_vertices[i]]) { + ++num_errors; + } + } + + TEST_ASSERT(test_ret_value, num_errors == 0, "weakly connected components results don't match"); + + cugraph_type_erased_device_array_view_free(components); + cugraph_type_erased_device_array_view_free(vertices); + cugraph_labeling_result_free(p_result); + cugraph_mg_graph_free(p_graph); + cugraph_error_free(ret_error); + + return test_ret_value; +} + +int test_weakly_connected_components(const cugraph_resource_handle_t* handle) +{ + size_t num_edges = 32; + size_t num_vertices = 12; + + vertex_t h_src[] = {0, 1, 1, 2, 2, 2, 3, 4, 6, 7, 7, 8, 8, 8, 9, 10, + 1, 3, 4, 0, 1, 3, 5, 5, 7, 9, 10, 6, 7, 9, 11, 11}; + vertex_t h_dst[] = {1, 3, 4, 0, 1, 3, 5, 5, 7, 9, 10, 6, 7, 9, 11, 11, + 0, 1, 1, 2, 2, 2, 3, 4, 6, 7, 7, 8, 8, 8, 9, 10}; + weight_t h_wgt[] = {1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, + 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, + 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0}; + vertex_t h_result[] = {0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1}; + + // WCC wants store_transposed = FALSE + return generic_wcc_test(handle, h_src, h_dst, h_wgt, h_result, num_vertices, num_edges, FALSE); +} + +/******************************************************************************/ + +int main(int argc, char** argv) +{ + // Set up MPI: + int comm_rank; + int comm_size; + int num_gpus_per_node; + cudaError_t status; + int mpi_status; + int result = 0; + cugraph_resource_handle_t* handle = NULL; + cugraph_error_t* ret_error; + cugraph_error_code_t ret_code = CUGRAPH_SUCCESS; + int prows = 1; + + C_MPI_TRY(MPI_Init(&argc, &argv)); + C_MPI_TRY(MPI_Comm_rank(MPI_COMM_WORLD, &comm_rank)); + C_MPI_TRY(MPI_Comm_size(MPI_COMM_WORLD, &comm_size)); + C_CUDA_TRY(cudaGetDeviceCount(&num_gpus_per_node)); + C_CUDA_TRY(cudaSetDevice(comm_rank % num_gpus_per_node)); + + void* raft_handle = create_raft_handle(prows); + handle = cugraph_create_resource_handle(raft_handle); + + if (result == 0) { + result |= RUN_MG_TEST(test_weakly_connected_components, handle); + + cugraph_free_resource_handle(handle); + } + + free_raft_handle(raft_handle); + + C_MPI_TRY(MPI_Finalize()); + + return result; +} diff --git a/cpp/tests/c_api/node2vec_test.c b/cpp/tests/c_api/node2vec_test.c index 8f13c8dafb0..5ac2af3ce8c 100644 --- a/cpp/tests/c_api/node2vec_test.c +++ b/cpp/tests/c_api/node2vec_test.c @@ -55,7 +55,7 @@ int generic_node2vec_test(vertex_t* h_src, 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, FALSE, &p_graph, &ret_error); + p_handle, h_src, h_dst, h_wgt, num_edges, store_transposed, FALSE, FALSE, &p_graph, &ret_error); TEST_ASSERT(test_ret_value, ret_code == CUGRAPH_SUCCESS, "graph creation failed."); ret_code = diff --git a/cpp/tests/c_api/pagerank_test.c b/cpp/tests/c_api/pagerank_test.c index 60ac9ddf5e4..46b803f1438 100644 --- a/cpp/tests/c_api/pagerank_test.c +++ b/cpp/tests/c_api/pagerank_test.c @@ -49,7 +49,7 @@ int generic_pagerank_test(vertex_t* h_src, 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, FALSE, &p_graph, &ret_error); + p_handle, h_src, h_dst, h_wgt, num_edges, store_transposed, FALSE, FALSE, &p_graph, &ret_error); TEST_ASSERT(test_ret_value, ret_code == CUGRAPH_SUCCESS, "create_test_graph failed."); TEST_ASSERT(test_ret_value, ret_code == CUGRAPH_SUCCESS, cugraph_error_message(ret_error)); diff --git a/cpp/tests/c_api/sssp_test.c b/cpp/tests/c_api/sssp_test.c index f585cdb5fa6..dc9f7a23f47 100644 --- a/cpp/tests/c_api/sssp_test.c +++ b/cpp/tests/c_api/sssp_test.c @@ -52,7 +52,7 @@ int generic_sssp_test(vertex_t* h_src, 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, FALSE, &p_graph, &ret_error); + p_handle, h_src, h_dst, h_wgt, num_edges, store_transposed, FALSE, FALSE, &p_graph, &ret_error); ret_code = cugraph_sssp( p_handle, p_graph, source, cutoff, TRUE, FALSE, &p_result, &ret_error); diff --git a/cpp/tests/c_api/test_utils.cpp b/cpp/tests/c_api/test_utils.cpp index 4dcc79eed9d..539e6869ec5 100644 --- a/cpp/tests/c_api/test_utils.cpp +++ b/cpp/tests/c_api/test_utils.cpp @@ -36,6 +36,7 @@ extern "C" int create_test_graph(const cugraph_resource_handle_t* p_handle, size_t num_edges, bool_t store_transposed, bool_t renumber, + bool_t is_symmetric, cugraph_graph_t** p_graph, cugraph_error_t** ret_error) { @@ -43,7 +44,7 @@ extern "C" int create_test_graph(const cugraph_resource_handle_t* p_handle, cugraph_error_code_t ret_code; cugraph_graph_properties_t properties; - properties.is_symmetric = FALSE; + properties.is_symmetric = is_symmetric; properties.is_multigraph = FALSE; data_type_id_t vertex_tid = INT32; diff --git a/cpp/tests/c_api/weakly_connected_components_test.c b/cpp/tests/c_api/weakly_connected_components_test.c new file mode 100644 index 00000000000..ec3e0b0cb97 --- /dev/null +++ b/cpp/tests/c_api/weakly_connected_components_test.c @@ -0,0 +1,128 @@ +/* + * 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 +#include + +#include + +typedef int32_t vertex_t; +typedef int32_t edge_t; +typedef float weight_t; + +int generic_wcc_test(vertex_t* h_src, + vertex_t* h_dst, + weight_t* h_wgt, + vertex_t* h_result, + size_t num_vertices, + size_t num_edges, + bool_t store_transposed) +{ + int test_ret_value = 0; + + cugraph_error_code_t ret_code = CUGRAPH_SUCCESS; + cugraph_error_t* ret_error; + + cugraph_resource_handle_t* p_handle = NULL; + cugraph_graph_t* p_graph = NULL; + cugraph_labeling_result_t* p_result = NULL; + + p_handle = cugraph_create_resource_handle(NULL); + 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, FALSE, TRUE, &p_graph, &ret_error); + + TEST_ASSERT(test_ret_value, ret_code == CUGRAPH_SUCCESS, "create_test_graph failed."); + TEST_ASSERT(test_ret_value, ret_code == CUGRAPH_SUCCESS, cugraph_error_message(ret_error)); + + ret_code = cugraph_weakly_connected_components(p_handle, p_graph, FALSE, &p_result, &ret_error); + TEST_ASSERT(test_ret_value, ret_code == CUGRAPH_SUCCESS, cugraph_error_message(ret_error)); + TEST_ASSERT( + test_ret_value, ret_code == CUGRAPH_SUCCESS, "cugraph_weakly_connected_components failed."); + + cugraph_type_erased_device_array_view_t* vertices; + cugraph_type_erased_device_array_view_t* components; + + vertices = cugraph_labeling_result_get_vertices(p_result); + components = cugraph_labeling_result_get_labels(p_result); + + vertex_t h_vertices[num_vertices]; + vertex_t h_components[num_vertices]; + + ret_code = cugraph_type_erased_device_array_view_copy_to_host( + p_handle, (byte_t*)h_vertices, vertices, &ret_error); + TEST_ASSERT(test_ret_value, ret_code == CUGRAPH_SUCCESS, "copy_to_host failed."); + + ret_code = cugraph_type_erased_device_array_view_copy_to_host( + p_handle, (byte_t*)h_components, components, &ret_error); + TEST_ASSERT(test_ret_value, ret_code == CUGRAPH_SUCCESS, "copy_to_host failed."); + + vertex_t component_check[num_vertices]; + for (vertex_t i = 0; i < num_vertices; ++i) { + component_check[i] = num_vertices; + } + + vertex_t num_errors = 0; + for (vertex_t i = 0; i < num_vertices; ++i) { + if (component_check[h_components[i]] == num_vertices) { + component_check[h_components[i]] = h_result[h_vertices[i]]; + } else if (component_check[h_components[i]] != h_result[h_vertices[i]]) { + ++num_errors; + } + } + + TEST_ASSERT(test_ret_value, num_errors == 0, "weakly connected components results don't match"); + + cugraph_type_erased_device_array_view_free(components); + cugraph_type_erased_device_array_view_free(vertices); + cugraph_labeling_result_free(p_result); + cugraph_sg_graph_free(p_graph); + cugraph_free_resource_handle(p_handle); + cugraph_error_free(ret_error); + + return test_ret_value; +} + +int test_weakly_connected_components() +{ + size_t num_edges = 32; + size_t num_vertices = 12; + + vertex_t h_src[] = {0, 1, 1, 2, 2, 2, 3, 4, 6, 7, 7, 8, 8, 8, 9, 10, + 1, 3, 4, 0, 1, 3, 5, 5, 7, 9, 10, 6, 7, 9, 11, 11}; + vertex_t h_dst[] = {1, 3, 4, 0, 1, 3, 5, 5, 7, 9, 10, 6, 7, 9, 11, 11, + 0, 1, 1, 2, 2, 2, 3, 4, 6, 7, 7, 8, 8, 8, 9, 10}; + weight_t h_wgt[] = {1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, + 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, + 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0}; + vertex_t h_result[] = {0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1}; + + // WCC wants store_transposed = FALSE + return generic_wcc_test(h_src, h_dst, h_wgt, h_result, num_vertices, num_edges, FALSE); + // return generic_wcc_test(h_src, h_dst, NULL, h_result, num_vertices, num_edges, FALSE); +} + +/******************************************************************************/ + +int main(int argc, char** argv) +{ + int result = 0; + result |= RUN_TEST(test_weakly_connected_components); + return result; +} From ac0300906ec2d7bd2a65d699597e6cb4418add46 Mon Sep 17 00:00:00 2001 From: Chuck Hastings Date: Fri, 1 Apr 2022 13:37:09 -0400 Subject: [PATCH 2/8] fix clang-format issues --- cpp/include/cugraph_c/labeling_algorithms.h | 22 +++++++++---------- cpp/src/c_api/labeling_result.cpp | 2 -- cpp/src/c_api/labeling_result.hpp | 1 - cpp/src/c_api/weakly_connected_components.cpp | 7 +++--- 4 files changed, 14 insertions(+), 18 deletions(-) diff --git a/cpp/include/cugraph_c/labeling_algorithms.h b/cpp/include/cugraph_c/labeling_algorithms.h index 57ded366c31..1ad835e2593 100644 --- a/cpp/include/cugraph_c/labeling_algorithms.h +++ b/cpp/include/cugraph_c/labeling_algorithms.h @@ -70,12 +70,11 @@ void cugraph_labeling_result_free(cugraph_labeling_result_t* result); * @param [out] error Pointer to an error object storing details of any error. Will * be populated if error code is not CUGRAPH_SUCCESS */ -cugraph_error_code_t cugraph_weakly_connected_components( - const cugraph_resource_handle_t* handle, - cugraph_graph_t* graph, - bool_t do_expensive_check, - cugraph_labeling_result_t** result, - cugraph_error_t** error); +cugraph_error_code_t cugraph_weakly_connected_components(const cugraph_resource_handle_t* handle, + cugraph_graph_t* graph, + bool_t do_expensive_check, + cugraph_labeling_result_t** result, + cugraph_error_t** error); /** * @brief Labels each vertex in the input graph with its (strongly-connected-)component ID @@ -91,12 +90,11 @@ cugraph_error_code_t cugraph_weakly_connected_components( * @param [out] error Pointer to an error object storing details of any error. Will * be populated if error code is not CUGRAPH_SUCCESS */ -cugraph_error_code_t cugraph_strongly_connected_components( - const cugraph_resource_handle_t* handle, - cugraph_graph_t* graph, - bool_t do_expensive_check, - cugraph_labeling_result_t** result, - cugraph_error_t** error); +cugraph_error_code_t cugraph_strongly_connected_components(const cugraph_resource_handle_t* handle, + cugraph_graph_t* graph, + bool_t do_expensive_check, + cugraph_labeling_result_t** result, + cugraph_error_t** error); #ifdef __cplusplus } diff --git a/cpp/src/c_api/labeling_result.cpp b/cpp/src/c_api/labeling_result.cpp index 7f31514775b..f4fb3e324fd 100644 --- a/cpp/src/c_api/labeling_result.cpp +++ b/cpp/src/c_api/labeling_result.cpp @@ -41,5 +41,3 @@ extern "C" void cugraph_labeling_result_free(cugraph_labeling_result_t* result) delete internal_pointer->labels_; delete internal_pointer; } - - diff --git a/cpp/src/c_api/labeling_result.hpp b/cpp/src/c_api/labeling_result.hpp index cce6f15063d..4adeb5c3219 100644 --- a/cpp/src/c_api/labeling_result.hpp +++ b/cpp/src/c_api/labeling_result.hpp @@ -28,4 +28,3 @@ struct cugraph_labeling_result_t { } // namespace c_api } // namespace cugraph - diff --git a/cpp/src/c_api/weakly_connected_components.cpp b/cpp/src/c_api/weakly_connected_components.cpp index 543c92f2ff2..9194e2ece0d 100644 --- a/cpp/src/c_api/weakly_connected_components.cpp +++ b/cpp/src/c_api/weakly_connected_components.cpp @@ -66,15 +66,16 @@ struct wcc_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 number_map = reinterpret_cast*>(graph_->number_map_); rmm::device_uvector components(graph_view.get_number_of_local_vertices(), - handle_.get_stream()); + handle_.get_stream()); cugraph::weakly_connected_components( handle_, graph_view, components.data(), do_expensive_check_); From f68e243514cff71f688e4ea6f28f234ed1f71a24 Mon Sep 17 00:00:00 2001 From: Chuck Hastings Date: Mon, 4 Apr 2022 14:43:47 -0400 Subject: [PATCH 3/8] add tests for SCC --- cpp/CMakeLists.txt | 1 + .../c_api/strongly_connected_components.cpp | 87 ++++++++++ cpp/tests/CMakeLists.txt | 2 + .../mg_strongly_connected_components_test.c | 159 ++++++++++++++++++ .../strongly_connected_components_test.c | 131 +++++++++++++++ .../c_api/weakly_connected_components_test.c | 1 - 6 files changed, 380 insertions(+), 1 deletion(-) create mode 100644 cpp/src/c_api/strongly_connected_components.cpp create mode 100644 cpp/tests/c_api/mg_strongly_connected_components_test.c create mode 100644 cpp/tests/c_api/strongly_connected_components_test.c diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt index 8824ceb902f..191ba102e92 100644 --- a/cpp/CMakeLists.txt +++ b/cpp/CMakeLists.txt @@ -363,6 +363,7 @@ add_library(cugraph_c SHARED src/c_api/uniform_neighbor_sampling.cpp src/c_api/labeling_result.cpp src/c_api/weakly_connected_components.cpp + src/c_api/strongly_connected_components.cpp ) add_library(cugraph::cugraph_c ALIAS cugraph_c) diff --git a/cpp/src/c_api/strongly_connected_components.cpp b/cpp/src/c_api/strongly_connected_components.cpp new file mode 100644 index 00000000000..287c222c1fe --- /dev/null +++ b/cpp/src/c_api/strongly_connected_components.cpp @@ -0,0 +1,87 @@ +/* + * 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 + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +namespace { + +struct scc_functor : public cugraph::c_api::abstract_functor { + raft::handle_t const& handle_; + cugraph::c_api::cugraph_graph_t* graph_; + bool do_expensive_check_; + cugraph::c_api::cugraph_labeling_result_t* result_{}; + + scc_functor(::cugraph_resource_handle_t const* handle, + ::cugraph_graph_t* graph, + bool do_expensive_check) + : abstract_functor(), + handle_(*reinterpret_cast(handle)->handle_), + graph_(reinterpret_cast(graph)), + do_expensive_check_(do_expensive_check) + { + } + + template + void operator()() + { + // FIXME: Think about how to handle SG vice MG + if constexpr (!cugraph::is_candidate::value) { + unsupported(); + } else { + // WCC expects store_transposed == false + if constexpr (store_transposed) { + error_code_ = cugraph::c_api:: + transpose_storage( + handle_, graph_, error_.get()); + if (error_code_ != CUGRAPH_SUCCESS) return; + } + + error_code_ = CUGRAPH_NOT_IMPLEMENTED; + error_->error_message_ = "SCC Not currently implemented"; + } + } +}; + +} // namespace + +extern "C" cugraph_error_code_t cugraph_strongly_connected_components( + const cugraph_resource_handle_t* handle, + cugraph_graph_t* graph, + bool_t do_expensive_check, + cugraph_labeling_result_t** result, + cugraph_error_t** error) +{ + scc_functor functor(handle, graph, do_expensive_check); + + return cugraph::c_api::run_algorithm(graph, functor, result, error); +} diff --git a/cpp/tests/CMakeLists.txt b/cpp/tests/CMakeLists.txt index 19150bfa23a..9cf94fd8933 100644 --- a/cpp/tests/CMakeLists.txt +++ b/cpp/tests/CMakeLists.txt @@ -621,6 +621,7 @@ if(BUILD_CUGRAPH_MG_TESTS) ConfigureCTestMG(MG_CAPI_CREATE_GRAPH c_api/mg_create_graph_test.c c_api/mg_test_utils.cpp) ConfigureCTestMG(MG_CAPI_PAGERANK c_api/mg_pagerank_test.c c_api/mg_test_utils.cpp) ConfigureCTestMG(MG_CAPI_WEAKLY_CONNECTED_COMPONENTS c_api/mg_weakly_connected_components_test.c c_api/mg_test_utils.cpp) + ConfigureCTestMG(MG_CAPI_STRONGLY_CONNECTED_COMPONENTS c_api/mg_strongly_connected_components_test.c c_api/mg_test_utils.cpp) ConfigureCTestMG(MG_CAPI_HITS c_api/mg_hits_test.c c_api/mg_test_utils.cpp) else() message(FATAL_ERROR "OpenMPI NOT found, cannot build MG tests.") @@ -668,6 +669,7 @@ 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) ConfigureCTest(CAPI_WEAKLY_CONNECTED_COMPONENTS c_api/weakly_connected_components_test.c) +ConfigureCTest(CAPI_STRONGLY_CONNECTED_COMPONENTS c_api/strongly_connected_components_test.c) ################################################################################################### ### enable testing ################################################################################ diff --git a/cpp/tests/c_api/mg_strongly_connected_components_test.c b/cpp/tests/c_api/mg_strongly_connected_components_test.c new file mode 100644 index 00000000000..f7659b8023a --- /dev/null +++ b/cpp/tests/c_api/mg_strongly_connected_components_test.c @@ -0,0 +1,159 @@ +/* + * 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 "mg_test_utils.h" /* RUN_TEST */ + +#include +#include + +#include + +typedef int32_t vertex_t; +typedef int32_t edge_t; +typedef float weight_t; + +int generic_scc_test(const cugraph_resource_handle_t* handle, + vertex_t* h_src, + vertex_t* h_dst, + weight_t* h_wgt, + vertex_t* h_result, + size_t num_vertices, + size_t num_edges, + bool_t store_transposed) +{ + int test_ret_value = 0; + + cugraph_error_code_t ret_code = CUGRAPH_SUCCESS; + cugraph_error_t* ret_error; + + cugraph_graph_t* p_graph = NULL; + cugraph_labeling_result_t* p_result = NULL; + + ret_code = create_mg_test_graph( + handle, h_src, h_dst, h_wgt, num_edges, store_transposed, FALSE, &p_graph, &ret_error); + + TEST_ASSERT(test_ret_value, ret_code == CUGRAPH_SUCCESS, "create_mg_test_graph failed."); + + ret_code = cugraph_strongly_connected_components(handle, p_graph, FALSE, &p_result, &ret_error); + TEST_ASSERT(test_ret_value, ret_code == CUGRAPH_NOT_IMPLEMENTED, "SCC should not be implemented, but is"); + +#if 0 + // FIXME: Actual implementation will be something like this + TEST_ASSERT( + test_ret_value, ret_code == CUGRAPH_SUCCESS, "cugraph_strongly_connected_components failed."); + + // NOTE: Because we get back vertex ids and components, we can simply compare + // the returned values with the expected results for the entire + // graph. Each GPU will have a subset of the total vertices, so + // they will do a subset of the comparisons. + cugraph_type_erased_device_array_view_t* vertices; + cugraph_type_erased_device_array_view_t* components; + + vertices = cugraph_labeling_result_get_vertices(p_result); + components = cugraph_labeling_result_get_labels(p_result); + + size_t num_local_vertices = cugraph_type_erased_device_array_view_size(vertices); + + vertex_t h_vertices[num_local_vertices]; + vertex_t h_components[num_local_vertices]; + + ret_code = cugraph_type_erased_device_array_view_copy_to_host( + handle, (byte_t*)h_vertices, vertices, &ret_error); + TEST_ASSERT(test_ret_value, ret_code == CUGRAPH_SUCCESS, "copy_to_host failed."); + + ret_code = cugraph_type_erased_device_array_view_copy_to_host( + handle, (byte_t*)h_components, components, &ret_error); + TEST_ASSERT(test_ret_value, ret_code == CUGRAPH_SUCCESS, "copy_to_host failed."); + + vertex_t component_check[num_vertices]; + for (vertex_t i = 0; i < num_vertices; ++i) { + component_check[i] = num_vertices; + } + + vertex_t num_errors = 0; + for (vertex_t i = 0; i < num_local_vertices; ++i) { + if (component_check[h_components[i]] == num_vertices) { + component_check[h_components[i]] = h_result[h_vertices[i]]; + } else if (component_check[h_components[i]] != h_result[h_vertices[i]]) { + ++num_errors; + } + } + + TEST_ASSERT(test_ret_value, num_errors == 0, "strongly connected components results don't match"); + + cugraph_type_erased_device_array_view_free(components); + cugraph_type_erased_device_array_view_free(vertices); + cugraph_labeling_result_free(p_result); +#endif + + cugraph_mg_graph_free(p_graph); + cugraph_error_free(ret_error); + + return test_ret_value; +} + +int test_strongly_connected_components(const cugraph_resource_handle_t* handle) +{ + size_t num_edges = 16; + size_t num_vertices = 12; + + vertex_t h_src[] = {0, 1, 1, 2, 2, 2, 3, 4, 6, 7, 7, 8, 8, 8, 9, 10}; + vertex_t h_dst[] = {1, 3, 4, 0, 1, 3, 5, 5, 7, 9, 10, 6, 7, 9, 11, 11}; + weight_t h_wgt[] = { + 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0}; + vertex_t h_result[] = {0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1}; + + // SCC wants store_transposed = FALSE + return generic_scc_test(handle, h_src, h_dst, h_wgt, h_result, num_vertices, num_edges, FALSE); +} + +/******************************************************************************/ + +int main(int argc, char** argv) +{ + // Set up MPI: + int comm_rank; + int comm_size; + int num_gpus_per_node; + cudaError_t status; + int mpi_status; + int result = 0; + cugraph_resource_handle_t* handle = NULL; + cugraph_error_t* ret_error; + cugraph_error_code_t ret_code = CUGRAPH_SUCCESS; + int prows = 1; + + C_MPI_TRY(MPI_Init(&argc, &argv)); + C_MPI_TRY(MPI_Comm_rank(MPI_COMM_WORLD, &comm_rank)); + C_MPI_TRY(MPI_Comm_size(MPI_COMM_WORLD, &comm_size)); + C_CUDA_TRY(cudaGetDeviceCount(&num_gpus_per_node)); + C_CUDA_TRY(cudaSetDevice(comm_rank % num_gpus_per_node)); + + void* raft_handle = create_raft_handle(prows); + handle = cugraph_create_resource_handle(raft_handle); + + if (result == 0) { + result |= RUN_MG_TEST(test_strongly_connected_components, handle); + + cugraph_free_resource_handle(handle); + } + + free_raft_handle(raft_handle); + + C_MPI_TRY(MPI_Finalize()); + + return result; +} diff --git a/cpp/tests/c_api/strongly_connected_components_test.c b/cpp/tests/c_api/strongly_connected_components_test.c new file mode 100644 index 00000000000..51e27e4f469 --- /dev/null +++ b/cpp/tests/c_api/strongly_connected_components_test.c @@ -0,0 +1,131 @@ +/* + * 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 +#include + +#include + +typedef int32_t vertex_t; +typedef int32_t edge_t; +typedef float weight_t; + +int generic_scc_test(vertex_t* h_src, + vertex_t* h_dst, + weight_t* h_wgt, + vertex_t* h_result, + size_t num_vertices, + size_t num_edges, + bool_t store_transposed) +{ + int test_ret_value = 0; + + cugraph_error_code_t ret_code = CUGRAPH_SUCCESS; + cugraph_error_t* ret_error; + + cugraph_resource_handle_t* p_handle = NULL; + cugraph_graph_t* p_graph = NULL; + cugraph_labeling_result_t* p_result = NULL; + + p_handle = cugraph_create_resource_handle(NULL); + 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, FALSE, FALSE, &p_graph, &ret_error); + + TEST_ASSERT(test_ret_value, ret_code == CUGRAPH_SUCCESS, "create_test_graph failed."); + TEST_ASSERT(test_ret_value, ret_code == CUGRAPH_SUCCESS, cugraph_error_message(ret_error)); + + ret_code = cugraph_strongly_connected_components(p_handle, p_graph, FALSE, &p_result, &ret_error); + TEST_ASSERT(test_ret_value, ret_code == CUGRAPH_NOT_IMPLEMENTED, "SCC should not be implemented, but is"); + +#if 0 + // FIXME: Actual implementation will be something like this + TEST_ASSERT(test_ret_value, ret_code == CUGRAPH_SUCCESS, cugraph_error_message(ret_error)); + TEST_ASSERT( + test_ret_value, ret_code == CUGRAPH_SUCCESS, "cugraph_strongly_connected_components failed."); + + cugraph_type_erased_device_array_view_t* vertices; + cugraph_type_erased_device_array_view_t* components; + + vertices = cugraph_labeling_result_get_vertices(p_result); + components = cugraph_labeling_result_get_labels(p_result); + + vertex_t h_vertices[num_vertices]; + vertex_t h_components[num_vertices]; + + ret_code = cugraph_type_erased_device_array_view_copy_to_host( + p_handle, (byte_t*)h_vertices, vertices, &ret_error); + TEST_ASSERT(test_ret_value, ret_code == CUGRAPH_SUCCESS, "copy_to_host failed."); + + ret_code = cugraph_type_erased_device_array_view_copy_to_host( + p_handle, (byte_t*)h_components, components, &ret_error); + TEST_ASSERT(test_ret_value, ret_code == CUGRAPH_SUCCESS, "copy_to_host failed."); + + vertex_t component_check[num_vertices]; + for (vertex_t i = 0; i < num_vertices; ++i) { + component_check[i] = num_vertices; + } + + vertex_t num_errors = 0; + for (vertex_t i = 0; i < num_vertices; ++i) { + if (component_check[h_components[i]] == num_vertices) { + component_check[h_components[i]] = h_result[h_vertices[i]]; + } else if (component_check[h_components[i]] != h_result[h_vertices[i]]) { + ++num_errors; + } + } + + TEST_ASSERT(test_ret_value, num_errors == 0, "strongly connected components results don't match"); + + cugraph_type_erased_device_array_view_free(components); + cugraph_type_erased_device_array_view_free(vertices); + cugraph_labeling_result_free(p_result); +#endif + + cugraph_sg_graph_free(p_graph); + cugraph_free_resource_handle(p_handle); + cugraph_error_free(ret_error); + + return test_ret_value; +} + +int test_strongly_connected_components() +{ + size_t num_edges = 16; + size_t num_vertices = 12; + + vertex_t h_src[] = {0, 1, 1, 2, 2, 2, 3, 4, 6, 7, 7, 8, 8, 8, 9, 10}; + vertex_t h_dst[] = {1, 3, 4, 0, 1, 3, 5, 5, 7, 9, 10, 6, 7, 9, 11, 11}; + weight_t h_wgt[] = { + 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0}; + + vertex_t h_result[] = {0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1}; + + // SCC wants store_transposed = FALSE + return generic_scc_test(h_src, h_dst, h_wgt, h_result, num_vertices, num_edges, FALSE); +} + +/******************************************************************************/ + +int main(int argc, char** argv) +{ + int result = 0; + result |= RUN_TEST(test_strongly_connected_components); + return result; +} diff --git a/cpp/tests/c_api/weakly_connected_components_test.c b/cpp/tests/c_api/weakly_connected_components_test.c index ec3e0b0cb97..4f711b4fcde 100644 --- a/cpp/tests/c_api/weakly_connected_components_test.c +++ b/cpp/tests/c_api/weakly_connected_components_test.c @@ -115,7 +115,6 @@ int test_weakly_connected_components() // WCC wants store_transposed = FALSE return generic_wcc_test(h_src, h_dst, h_wgt, h_result, num_vertices, num_edges, FALSE); - // return generic_wcc_test(h_src, h_dst, NULL, h_result, num_vertices, num_edges, FALSE); } /******************************************************************************/ From cffc9df1cc5ba1346a893ea6381bcf5d8e0c615d Mon Sep 17 00:00:00 2001 From: Chuck Hastings Date: Wed, 6 Apr 2022 11:53:40 -0400 Subject: [PATCH 4/8] missed change in merges --- .../c_api/mg_eigenvector_centrality_test.c | 49 ++++++++++--------- 1 file changed, 25 insertions(+), 24 deletions(-) diff --git a/cpp/tests/c_api/mg_eigenvector_centrality_test.c b/cpp/tests/c_api/mg_eigenvector_centrality_test.c index d8bf291edef..967f3467963 100644 --- a/cpp/tests/c_api/mg_eigenvector_centrality_test.c +++ b/cpp/tests/c_api/mg_eigenvector_centrality_test.c @@ -26,33 +26,34 @@ typedef int32_t edge_t; typedef float weight_t; int generic_eigenvector_centrality_test(const cugraph_resource_handle_t* handle, - vertex_t* h_src, - vertex_t* h_dst, - weight_t* h_wgt, - weight_t* h_result, - size_t num_vertices, - size_t num_edges, - bool_t store_transposed, - double alpha, - double epsilon, - size_t max_iterations) + vertex_t* h_src, + vertex_t* h_dst, + weight_t* h_wgt, + weight_t* h_result, + size_t num_vertices, + size_t num_edges, + bool_t store_transposed, + double alpha, + double epsilon, + size_t max_iterations) { int test_ret_value = 0; cugraph_error_code_t ret_code = CUGRAPH_SUCCESS; cugraph_error_t* ret_error; - cugraph_graph_t* p_graph = NULL; + cugraph_graph_t* p_graph = NULL; cugraph_centrality_result_t* p_result = NULL; ret_code = create_mg_test_graph( - handle, h_src, h_dst, h_wgt, num_edges, store_transposed, &p_graph, &ret_error); + handle, h_src, h_dst, h_wgt, num_edges, store_transposed, FALSE, &p_graph, &ret_error); TEST_ASSERT(test_ret_value, ret_code == CUGRAPH_SUCCESS, "create_mg_test_graph failed."); ret_code = cugraph_eigenvector_centrality( handle, p_graph, epsilon, max_iterations, FALSE, &p_result, &ret_error); - TEST_ASSERT(test_ret_value, ret_code == CUGRAPH_SUCCESS, "cugraph_eigenvector_centrality failed."); + TEST_ASSERT( + test_ret_value, ret_code == CUGRAPH_SUCCESS, "cugraph_eigenvector_centrality failed."); // NOTE: Because we get back vertex ids and centralities, we can simply compare // the returned values with the expected results for the entire @@ -61,7 +62,7 @@ int generic_eigenvector_centrality_test(const cugraph_resource_handle_t* handle, cugraph_type_erased_device_array_view_t* vertices; cugraph_type_erased_device_array_view_t* centralities; - vertices = cugraph_centrality_result_get_vertices(p_result); + vertices = cugraph_centrality_result_get_vertices(p_result); centralities = cugraph_centrality_result_get_values(p_result); vertex_t h_vertices[num_vertices]; @@ -106,16 +107,16 @@ int test_eigenvector_centrality(const cugraph_resource_handle_t* handle) // Pagerank wants store_transposed = TRUE return generic_eigenvector_centrality_test(handle, - h_src, - h_dst, - h_wgt, - h_result, - num_vertices, - num_edges, - TRUE, - alpha, - epsilon, - max_iterations); + h_src, + h_dst, + h_wgt, + h_result, + num_vertices, + num_edges, + TRUE, + alpha, + epsilon, + max_iterations); } /******************************************************************************/ From 8af57e5ffd01486d13a2ca5d55b35110bd97813d Mon Sep 17 00:00:00 2001 From: Chuck Hastings Date: Wed, 6 Apr 2022 12:19:11 -0400 Subject: [PATCH 5/8] missed a few more files in last commit --- cpp/tests/c_api/eigenvector_centrality_test.c | 2 +- cpp/tests/c_api/mg_uniform_neighbor_sample_test.c | 2 +- cpp/tests/c_api/uniform_neighbor_sample_test.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cpp/tests/c_api/eigenvector_centrality_test.c b/cpp/tests/c_api/eigenvector_centrality_test.c index 5e82449b7f4..7127c949d98 100644 --- a/cpp/tests/c_api/eigenvector_centrality_test.c +++ b/cpp/tests/c_api/eigenvector_centrality_test.c @@ -49,7 +49,7 @@ int generic_eigenvector_centrality_test(vertex_t* h_src, 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, FALSE, &p_graph, &ret_error); + p_handle, h_src, h_dst, h_wgt, num_edges, store_transposed, FALSE, FALSE, &p_graph, &ret_error); TEST_ASSERT(test_ret_value, ret_code == CUGRAPH_SUCCESS, "create_test_graph failed."); TEST_ASSERT(test_ret_value, ret_code == CUGRAPH_SUCCESS, cugraph_error_message(ret_error)); diff --git a/cpp/tests/c_api/mg_uniform_neighbor_sample_test.c b/cpp/tests/c_api/mg_uniform_neighbor_sample_test.c index 6b867652801..057242d052e 100644 --- a/cpp/tests/c_api/mg_uniform_neighbor_sample_test.c +++ b/cpp/tests/c_api/mg_uniform_neighbor_sample_test.c @@ -54,7 +54,7 @@ int generic_uniform_neighbor_sample_test(const cugraph_resource_handle_t* handle cugraph_type_erased_host_array_view_t* h_fan_out_view = NULL; ret_code = create_mg_test_graph( - handle, h_src, h_dst, h_wgt, num_edges, store_transposed, &graph, &ret_error); + handle, h_src, h_dst, h_wgt, num_edges, store_transposed, FALSE, &graph, &ret_error); TEST_ASSERT(test_ret_value, ret_code == CUGRAPH_SUCCESS, "graph creation failed."); ret_code = diff --git a/cpp/tests/c_api/uniform_neighbor_sample_test.c b/cpp/tests/c_api/uniform_neighbor_sample_test.c index b844220677b..d7cbb2e17a8 100644 --- a/cpp/tests/c_api/uniform_neighbor_sample_test.c +++ b/cpp/tests/c_api/uniform_neighbor_sample_test.c @@ -58,7 +58,7 @@ int generic_uniform_neighbor_sample_test(vertex_t* h_src, TEST_ASSERT(test_ret_value, handle != NULL, "resource handle creation failed."); ret_code = create_test_graph( - handle, h_src, h_dst, h_wgt, num_edges, store_transposed, renumber, &graph, &ret_error); + handle, h_src, h_dst, h_wgt, num_edges, store_transposed, renumber, FALSE, &graph, &ret_error); TEST_ASSERT(test_ret_value, ret_code == CUGRAPH_SUCCESS, "graph creation failed."); ret_code = From 47bef061e807139e6217b2afaabb49aa3ab2d870 Mon Sep 17 00:00:00 2001 From: Chuck Hastings Date: Wed, 6 Apr 2022 17:15:43 -0400 Subject: [PATCH 6/8] review feedback --- cpp/src/c_api/strongly_connected_components.cpp | 7 +++---- cpp/src/c_api/weakly_connected_components.cpp | 9 ++++----- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/cpp/src/c_api/strongly_connected_components.cpp b/cpp/src/c_api/strongly_connected_components.cpp index 287c222c1fe..e8bbfcb3886 100644 --- a/cpp/src/c_api/strongly_connected_components.cpp +++ b/cpp/src/c_api/strongly_connected_components.cpp @@ -33,8 +33,8 @@ namespace { struct scc_functor : public cugraph::c_api::abstract_functor { raft::handle_t const& handle_; - cugraph::c_api::cugraph_graph_t* graph_; - bool do_expensive_check_; + cugraph::c_api::cugraph_graph_t* graph_{}; + bool do_expensive_check_{}; cugraph::c_api::cugraph_labeling_result_t* result_{}; scc_functor(::cugraph_resource_handle_t const* handle, @@ -54,11 +54,10 @@ struct scc_functor : public cugraph::c_api::abstract_functor { bool multi_gpu> void operator()() { - // FIXME: Think about how to handle SG vice MG if constexpr (!cugraph::is_candidate::value) { unsupported(); } else { - // WCC expects store_transposed == false + // SCC expects store_transposed == false if constexpr (store_transposed) { error_code_ = cugraph::c_api:: transpose_storage( diff --git a/cpp/src/c_api/weakly_connected_components.cpp b/cpp/src/c_api/weakly_connected_components.cpp index 9194e2ece0d..2c11370ccf6 100644 --- a/cpp/src/c_api/weakly_connected_components.cpp +++ b/cpp/src/c_api/weakly_connected_components.cpp @@ -33,12 +33,12 @@ namespace { struct wcc_functor : public cugraph::c_api::abstract_functor { raft::handle_t const& handle_; - cugraph::c_api::cugraph_graph_t* graph_; - bool do_expensive_check_; + cugraph::c_api::cugraph_graph_t* graph_{}; + bool do_expensive_check_{}; cugraph::c_api::cugraph_labeling_result_t* result_{}; - wcc_functor(::cugraph_resource_handle_t const* handle, - ::cugraph_graph_t* graph, + wcc_functor(cugraph_resource_handle_t const* handle, + cugraph_graph_t* graph, bool do_expensive_check) : abstract_functor(), handle_(*reinterpret_cast(handle)->handle_), @@ -54,7 +54,6 @@ struct wcc_functor : public cugraph::c_api::abstract_functor { bool multi_gpu> void operator()() { - // FIXME: Think about how to handle SG vice MG if constexpr (!cugraph::is_candidate::value) { unsupported(); } else { From 85c55901b0f1d27305607ebb49a054228e64a04d Mon Sep 17 00:00:00 2001 From: Chuck Hastings Date: Tue, 12 Apr 2022 23:50:13 -0400 Subject: [PATCH 7/8] fix calls that changed from a merged PR --- cpp/src/c_api/katz.cpp | 2 +- cpp/src/c_api/weakly_connected_components.cpp | 4 ++-- cpp/tests/c_api/katz_test.c | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cpp/src/c_api/katz.cpp b/cpp/src/c_api/katz.cpp index 960bae505bc..e9b92f7f758 100644 --- a/cpp/src/c_api/katz.cpp +++ b/cpp/src/c_api/katz.cpp @@ -98,7 +98,7 @@ struct katz_functor : public cugraph::c_api::abstract_functor { cugraph::detail::sequence_fill(handle_.get_stream(), betas_vertex_ids.data(), betas_vertex_ids.size(), - graph_view.local_vertex_partition_range_size()); + graph_view.local_vertex_partition_range_first()); betas.resize(graph_view.local_vertex_partition_range_size(), handle_.get_stream()); diff --git a/cpp/src/c_api/weakly_connected_components.cpp b/cpp/src/c_api/weakly_connected_components.cpp index 2c11370ccf6..9625ad129a5 100644 --- a/cpp/src/c_api/weakly_connected_components.cpp +++ b/cpp/src/c_api/weakly_connected_components.cpp @@ -73,13 +73,13 @@ struct wcc_functor : public cugraph::c_api::abstract_functor { auto number_map = reinterpret_cast*>(graph_->number_map_); - rmm::device_uvector components(graph_view.get_number_of_local_vertices(), + rmm::device_uvector components(graph_view.local_vertex_partition_range_size(), handle_.get_stream()); cugraph::weakly_connected_components( handle_, graph_view, components.data(), do_expensive_check_); - rmm::device_uvector vertex_ids(graph_view.get_number_of_local_vertices(), + rmm::device_uvector vertex_ids(graph_view.local_vertex_partition_range_size(), handle_.get_stream()); raft::copy(vertex_ids.data(), number_map->data(), vertex_ids.size(), handle_.get_stream()); diff --git a/cpp/tests/c_api/katz_test.c b/cpp/tests/c_api/katz_test.c index d5ca6a46643..4ee61b2b806 100644 --- a/cpp/tests/c_api/katz_test.c +++ b/cpp/tests/c_api/katz_test.c @@ -52,7 +52,7 @@ int generic_katz_test(vertex_t* h_src, 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, FALSE, &p_graph, &ret_error); + p_handle, h_src, h_dst, h_wgt, num_edges, store_transposed, FALSE, FALSE, &p_graph, &ret_error); TEST_ASSERT(test_ret_value, ret_code == CUGRAPH_SUCCESS, "create_test_graph failed."); TEST_ASSERT(test_ret_value, ret_code == CUGRAPH_SUCCESS, cugraph_error_message(ret_error)); From 644401c8812a5bd6da7927d570cfe0b07fa3b87a Mon Sep 17 00:00:00 2001 From: Chuck Hastings Date: Wed, 13 Apr 2022 00:49:42 -0400 Subject: [PATCH 8/8] missed the MG test in last commit --- cpp/tests/c_api/mg_katz_test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/tests/c_api/mg_katz_test.c b/cpp/tests/c_api/mg_katz_test.c index c8de4f135ea..ca2de1bb194 100644 --- a/cpp/tests/c_api/mg_katz_test.c +++ b/cpp/tests/c_api/mg_katz_test.c @@ -48,7 +48,7 @@ int generic_katz_test(const cugraph_resource_handle_t* handle, cugraph_type_erased_device_array_view_t* betas_view = NULL; ret_code = create_mg_test_graph( - handle, h_src, h_dst, h_wgt, num_edges, store_transposed, &p_graph, &ret_error); + handle, h_src, h_dst, h_wgt, num_edges, store_transposed, FALSE, &p_graph, &ret_error); TEST_ASSERT(test_ret_value, ret_code == CUGRAPH_SUCCESS, "create_mg_test_graph failed.");