diff --git a/conda/environments/cugraph_dev_cuda11.2.yml b/conda/environments/cugraph_dev_cuda11.2.yml index 01dbc05db12..8bbc224a415 100644 --- a/conda/environments/cugraph_dev_cuda11.2.yml +++ b/conda/environments/cugraph_dev_cuda11.2.yml @@ -25,7 +25,7 @@ dependencies: - networkx>=2.5.1 - clang=11.1.0 - clang-tools=11.1.0 -- cmake>=3.20.1,<3.23 +- cmake>=3.20.1,!=3.23.0 - python>=3.6,<3.9 - notebook>=0.5.0 - boost diff --git a/conda/environments/cugraph_dev_cuda11.4.yml b/conda/environments/cugraph_dev_cuda11.4.yml index d30d5f8cff9..99e42db4973 100644 --- a/conda/environments/cugraph_dev_cuda11.4.yml +++ b/conda/environments/cugraph_dev_cuda11.4.yml @@ -25,7 +25,7 @@ dependencies: - networkx>=2.5.1 - clang=11.1.0 - clang-tools=11.1.0 -- cmake>=3.20.1,<3.23 +- cmake>=3.20.1,!=3.23.0 - python>=3.6,<3.9 - notebook>=0.5.0 - boost diff --git a/conda/environments/cugraph_dev_cuda11.5.yml b/conda/environments/cugraph_dev_cuda11.5.yml index af6c05bf937..dc80bdac95e 100644 --- a/conda/environments/cugraph_dev_cuda11.5.yml +++ b/conda/environments/cugraph_dev_cuda11.5.yml @@ -25,7 +25,7 @@ dependencies: - networkx>=2.5.1 - clang=11.1.0 - clang-tools=11.1.0 -- cmake>=3.20.1,<3.23 +- cmake>=3.20.1,!=3.23.0 - python>=3.6,<3.9 - notebook>=0.5.0 - boost diff --git a/conda/recipes/libcugraph/conda_build_config.yaml b/conda/recipes/libcugraph/conda_build_config.yaml index 63adb7b63cb..203f6f20f7b 100644 --- a/conda/recipes/libcugraph/conda_build_config.yaml +++ b/conda/recipes/libcugraph/conda_build_config.yaml @@ -1,5 +1,5 @@ cmake_version: - - ">=3.20.1,<3.23" + - ">=3.20.1,!=3.23.0" doxygen_version: - ">=1.8.11" diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt index f04ba70abef..14440e20892 100644 --- a/cpp/CMakeLists.txt +++ b/cpp/CMakeLists.txt @@ -366,6 +366,9 @@ add_library(cugraph_c 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 + src/c_api/strongly_connected_components.cpp ) add_library(cugraph::cugraph_c ALIAS cugraph_c) diff --git a/cpp/include/cugraph/prims/copy_v_transform_reduce_in_out_nbr.cuh b/cpp/include/cugraph/prims/copy_v_transform_reduce_in_out_nbr.cuh index b8f63e1d8bb..0f944a178e9 100644 --- a/cpp/include/cugraph/prims/copy_v_transform_reduce_in_out_nbr.cuh +++ b/cpp/include/cugraph/prims/copy_v_transform_reduce_in_out_nbr.cuh @@ -914,7 +914,7 @@ void copy_v_transform_reduce_nbr(raft::handle_t const& handle, * value to be reduced. * @param init Initial value to be added to the reduced @p e_op return values for each vertex. * @param vertex_value_output_first Iterator pointing to the vertex property variables for the first - * (inclusive) vertex (assigned to tihs process in multi-GPU). `vertex_value_output_last` + * (inclusive) vertex (assigned to this process in multi-GPU). `vertex_value_output_last` * (exclusive) is deduced as @p vertex_value_output_first + @p * graph_view.local_vertex_partition_range_size(). */ @@ -975,7 +975,7 @@ void copy_v_transform_reduce_in_nbr( * value to be reduced. * @param init Initial value to be added to the reduced @p e_op return values for each vertex. * @param vertex_value_output_first Iterator pointing to the vertex property variables for the - * first (inclusive) vertex (assigned to tihs process in multi-GPU). `vertex_value_output_last` + * first (inclusive) vertex (assigned to this process in multi-GPU). `vertex_value_output_last` * (exclusive) is deduced as @p vertex_value_output_first + @p * graph_view.local_vertex_partition_range_size(). */ diff --git a/cpp/include/cugraph/prims/copy_v_transform_reduce_key_aggregated_out_nbr.cuh b/cpp/include/cugraph/prims/copy_v_transform_reduce_key_aggregated_out_nbr.cuh index 37de44ffe19..ec92081f6b8 100644 --- a/cpp/include/cugraph/prims/copy_v_transform_reduce_key_aggregated_out_nbr.cuh +++ b/cpp/include/cugraph/prims/copy_v_transform_reduce_key_aggregated_out_nbr.cuh @@ -191,7 +191,7 @@ struct reduce_with_init_t { * @param reduce_op Binary operator takes two input arguments and reduce the two variables to one. * @param init Initial value to be added to the reduced @p reduce_op return values for each vertex. * @param vertex_value_output_first Iterator pointing to the vertex property variables for the - * first (inclusive) vertex (assigned to tihs process in multi-GPU). `vertex_value_output_last` + * first (inclusive) vertex (assigned to this process in multi-GPU). `vertex_value_output_last` * (exclusive) is deduced as @p vertex_value_output_first + @p * graph_view.local_vertex_partition_range_size(). */ diff --git a/cpp/include/cugraph/prims/update_frontier_v_push_if_out_nbr.cuh b/cpp/include/cugraph/prims/update_frontier_v_push_if_out_nbr.cuh index fa96c9db3e0..fe2d632a342 100644 --- a/cpp/include/cugraph/prims/update_frontier_v_push_if_out_nbr.cuh +++ b/cpp/include/cugraph/prims/update_frontier_v_push_if_out_nbr.cuh @@ -976,12 +976,12 @@ typename GraphViewType::edge_type compute_num_out_nbrs_from_frontier( * (inclusive) vertex (assigned to this process in multi-GPU). `vertex_value_input_last` (exclusive) * is deduced as @p vertex_value_input_first + @p graph_view.local_vertex_partition_range_size(). * @param vertex_value_output_first Iterator pointing to the vertex property variables for the first - * (inclusive) vertex (assigned to tihs process in multi-GPU). `vertex_value_output_last` + * (inclusive) vertex (assigned to this process in multi-GPU). `vertex_value_output_last` * (exclusive) is deduced as @p vertex_value_output_first + @p * graph_view.local_vertex_partition_range_size(). * @param v_op Ternary operator takes (tagged-)vertex ID, *(@p vertex_value_input_first + i) (where * i is [0, @p graph_view.local_vertex_partition_range_size())) and reduced value of the @p e_op - * outputs for this vertex and returns the target bucket index (for frontier update) and new verrtex + * outputs for this vertex and returns the target bucket index (for frontier update) and new vertex * property values (to update *(@p vertex_value_output_first + i)). The target bucket index should * either be VertexFrontierType::kInvalidBucketIdx or an index in @p next_frontier_bucket_indices. */ diff --git a/cpp/include/cugraph_c/algorithms.h b/cpp/include/cugraph_c/algorithms.h index 8e1c4558887..aa4ff518603 100644 --- a/cpp/include/cugraph_c/algorithms.h +++ b/cpp/include/cugraph_c/algorithms.h @@ -373,3 +373,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..1ad835e2593 --- /dev/null +++ b/cpp/include/cugraph_c/labeling_algorithms.h @@ -0,0 +1,101 @@ +/* + * 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/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/labeling_result.cpp b/cpp/src/c_api/labeling_result.cpp new file mode 100644 index 00000000000..f4fb3e324fd --- /dev/null +++ b/cpp/src/c_api/labeling_result.cpp @@ -0,0 +1,43 @@ +/* + * 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..4adeb5c3219 --- /dev/null +++ b/cpp/src/c_api/labeling_result.hpp @@ -0,0 +1,30 @@ +/* + * 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/strongly_connected_components.cpp b/cpp/src/c_api/strongly_connected_components.cpp new file mode 100644 index 00000000000..e8bbfcb3886 --- /dev/null +++ b/cpp/src/c_api/strongly_connected_components.cpp @@ -0,0 +1,86 @@ +/* + * 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()() + { + if constexpr (!cugraph::is_candidate::value) { + unsupported(); + } else { + // SCC 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/src/c_api/weakly_connected_components.cpp b/cpp/src/c_api/weakly_connected_components.cpp new file mode 100644 index 00000000000..9625ad129a5 --- /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()() + { + 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.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.local_vertex_partition_range_size(), + 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 a0665f4e29e..2b3caf5ee49 100644 --- a/cpp/tests/CMakeLists.txt +++ b/cpp/tests/CMakeLists.txt @@ -620,6 +620,8 @@ 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_STRONGLY_CONNECTED_COMPONENTS c_api/mg_strongly_connected_components_test.c c_api/mg_test_utils.cpp) ConfigureCTestMG(MG_CAPI_KATZ c_api/mg_katz_test.c c_api/mg_test_utils.cpp) ConfigureCTestMG(MG_CAPI_EIGENVECTOR_CENTRALITY c_api/mg_eigenvector_centrality_test.c c_api/mg_test_utils.cpp) ConfigureCTestMG(MG_CAPI_HITS c_api/mg_hits_test.c c_api/mg_test_utils.cpp) @@ -671,6 +673,8 @@ 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) +ConfigureCTest(CAPI_STRONGLY_CONNECTED_COMPONENTS c_api/strongly_connected_components_test.c) ConfigureCTest(CAPI_UNIFORM_NEIGHBOR_SAMPLE c_api/uniform_neighbor_sample_test.c) ################################################################################################### 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/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/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/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)); 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); } /******************************************************************************/ 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_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."); diff --git a/cpp/tests/c_api/mg_pagerank_test.c b/cpp/tests/c_api/mg_pagerank_test.c index e7ead863c4d..7c557d7bed8 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_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."); @@ -64,8 +64,10 @@ int generic_pagerank_test(const cugraph_resource_handle_t* handle, vertices = cugraph_centrality_result_get_vertices(p_result); pageranks = cugraph_centrality_result_get_values(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_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/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_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/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 979e5a7a82b..701d4923fe1 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 715692aaa0d..b985fb428e6 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/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/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/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 = 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..4f711b4fcde --- /dev/null +++ b/cpp/tests/c_api/weakly_connected_components_test.c @@ -0,0 +1,127 @@ +/* + * 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); +} + +/******************************************************************************/ + +int main(int argc, char** argv) +{ + int result = 0; + result |= RUN_TEST(test_weakly_connected_components); + return result; +} diff --git a/notebooks/link_analysis/Pagerank.ipynb b/notebooks/link_analysis/Pagerank.ipynb index 3debb9fab9a..30b637613b5 100755 --- a/notebooks/link_analysis/Pagerank.ipynb +++ b/notebooks/link_analysis/Pagerank.ipynb @@ -2,7 +2,9 @@ "cells": [ { "cell_type": "markdown", - "metadata": {}, + "metadata": { + "tags": [] + }, "source": [ "# PageRank\n", "\n", @@ -11,13 +13,13 @@ "Notebook Credits\n", "* Original Authors: Bradley Rees and James Wyles\n", "* Created: 08/13/2019\n", - "* Updated: 01/17/2021\n", + "* Updated: 04/06/2022\n", "\n", - "RAPIDS Versions: 0.14 \n", + "RAPIDS Versions: 22.04 \n", "\n", "Test Hardware\n", "\n", - "* GV100 32G, CUDA 10.0\n", + "* GV100 32G, CUDA 11.5\n", "\n", "\n", "## Introduction\n", @@ -75,9 +77,12 @@ "name": "stdout", "output_type": "stream", "text": [ - "Requirement already satisfied: networkx in /home/brad/anaconda3/envs/cugraph_dev/lib/python3.8/site-packages (2.6.2)\n", - "Requirement already satisfied: scipy in /home/brad/anaconda3/envs/cugraph_dev/lib/python3.8/site-packages (1.7.0)\n", - "Requirement already satisfied: numpy<1.23.0,>=1.16.5 in /home/brad/anaconda3/envs/cugraph_dev/lib/python3.8/site-packages (from scipy) (1.21.1)\n" + "Requirement already satisfied: networkx in /opt/conda/envs/rapids/lib/python3.9/site-packages (2.6.3)\n", + "\u001b[33mWARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv\u001b[0m\u001b[33m\n", + "\u001b[0mRequirement already satisfied: scipy in /opt/conda/envs/rapids/lib/python3.9/site-packages (1.6.0)\n", + "Requirement already satisfied: numpy>=1.16.5 in /opt/conda/envs/rapids/lib/python3.9/site-packages (from scipy) (1.21.5)\n", + "\u001b[33mWARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv\u001b[0m\u001b[33m\n", + "\u001b[0m" ] } ], @@ -270,7 +275,16 @@ "cell_type": "code", "execution_count": 10, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/opt/conda/envs/rapids/lib/python3.9/site-packages/cudf/core/indexed_frame.py:2271: FutureWarning: append is deprecated and will be removed in a future version. Use concat instead.\n", + " warnings.warn(\n" + ] + } + ], "source": [ "# create a Graph using the source (src) and destination (dst) vertex pairs from the Dataframe \n", "G = cugraph.from_edgelist(gdf, source='src', destination='dst')" @@ -315,7 +329,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "Best vertex is 34 with score of 0.10091734\n" + "Best vertex is 34 with score of 0.100917324\n" ] } ], @@ -373,7 +387,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "Best vertex is 34 with score of 0.10091734\n" + "Best vertex is 34 with score of 0.100917324\n" ] } ], @@ -433,17 +447,17 @@ " \n", " \n", " \n", - " 2\n", + " 16\n", " 0.100917\n", " 34\n", " \n", " \n", - " 3\n", + " 17\n", " 0.096999\n", " 1\n", " \n", " \n", - " 4\n", + " 18\n", " 0.071692\n", " 33\n", " \n", @@ -452,10 +466,10 @@ "" ], "text/plain": [ - " pagerank vertex\n", - "2 0.100917 34\n", - "3 0.096999 1\n", - "4 0.071692 33" + " pagerank vertex\n", + "16 0.100917 34\n", + "17 0.096999 1\n", + "18 0.071692 33" ] }, "execution_count": 17, @@ -517,39 +531,32 @@ " \n", " \n", " \n", - " 2\n", + " 16\n", " 17\n", " 17\n", " 34\n", " \n", " \n", - " 3\n", + " 17\n", " 16\n", " 16\n", " 1\n", " \n", " \n", - " 4\n", + " 18\n", " 12\n", " 12\n", " 33\n", " \n", - " \n", - " 5\n", - " 10\n", - " 10\n", - " 3\n", - " \n", " \n", "\n", "" ], "text/plain": [ - " in_degree out_degree vertex\n", - "2 17 17 34\n", - "3 16 16 1\n", - "4 12 12 33\n", - "5 10 10 3" + " in_degree out_degree vertex\n", + "16 17 17 34\n", + "17 16 16 1\n", + "18 12 12 33" ] }, "execution_count": 19, @@ -558,7 +565,7 @@ } ], "source": [ - "d.sort_values('out_degree', ascending=False).head(4)" + "d.sort_values('out_degree', ascending=False).head(3)" ] }, { @@ -585,7 +592,7 @@ }, { "cell_type": "code", - "execution_count": 26, + "execution_count": 20, "metadata": {}, "outputs": [], "source": [ @@ -597,7 +604,7 @@ }, { "cell_type": "code", - "execution_count": 27, + "execution_count": 21, "metadata": {}, "outputs": [], "source": [ @@ -606,7 +613,7 @@ }, { "cell_type": "code", - "execution_count": 28, + "execution_count": 22, "metadata": {}, "outputs": [ { @@ -636,17 +643,17 @@ " \n", " \n", " \n", - " 22\n", + " 4\n", " 0.121756\n", " 26\n", " \n", " \n", - " 28\n", + " 10\n", " 0.085409\n", " 17\n", " \n", " \n", - " 3\n", + " 17\n", " 0.077714\n", " 1\n", " \n", @@ -656,12 +663,12 @@ ], "text/plain": [ " pagerank vertex\n", - "22 0.121756 26\n", - "28 0.085409 17\n", - "3 0.077714 1" + "4 0.121756 26\n", + "10 0.085409 17\n", + "17 0.077714 1" ] }, - "execution_count": 28, + "execution_count": 22, "metadata": {}, "output_type": "execute_result" } @@ -672,7 +679,7 @@ }, { "cell_type": "code", - "execution_count": 29, + "execution_count": 23, "metadata": {}, "outputs": [ { @@ -702,33 +709,39 @@ " \n", " \n", " \n", - " 22\n", + " 4\n", " 0.021006\n", " 26\n", " \n", " \n", - " 28\n", + " 10\n", " 0.016785\n", " 17\n", " \n", + " \n", + " 17\n", + " 0.096999\n", + " 1\n", + " \n", " \n", "\n", "" ], "text/plain": [ " pagerank vertex\n", - "22 0.021006 26\n", - "28 0.016785 17" + "4 0.021006 26\n", + "10 0.016785 17\n", + "17 0.096999 1" ] }, - "execution_count": 29, + "execution_count": 23, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# looking at the initial PageRank values\n", - "gdf_page[gdf_page['vertex'].isin([17,26])]" + "gdf_page[gdf_page['vertex'].isin([26,17,1])]" ] }, { @@ -747,9 +760,9 @@ ], "metadata": { "kernelspec": { - "display_name": "cugraph_dev", + "display_name": "Python 3 (ipykernel)", "language": "python", - "name": "cugraph_dev" + "name": "python3" }, "language_info": { "codemirror_mode": { @@ -761,7 +774,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.8.10" + "version": "3.9.7" } }, "nbformat": 4,