From d95967ec521f90d2fe5aa9715528dd7650ab8b4a Mon Sep 17 00:00:00 2001 From: jnke2016 Date: Sat, 9 Nov 2024 01:27:34 -0800 Subject: [PATCH 01/26] expose decompress_to_edgelist to the CAPI --- cpp/CMakeLists.txt | 1 + cpp/include/cugraph_c/graph_functions.h | 19 +++ cpp/src/c_api/decompress_to_edgelist.cpp | 145 +++++++++++++++++++++++ 3 files changed, 165 insertions(+) create mode 100644 cpp/src/c_api/decompress_to_edgelist.cpp diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt index fc3dbb57e1f..a3f6c0725f2 100644 --- a/cpp/CMakeLists.txt +++ b/cpp/CMakeLists.txt @@ -560,6 +560,7 @@ add_library(cugraph_c src/c_api/weakly_connected_components.cpp src/c_api/strongly_connected_components.cpp src/c_api/allgather.cpp + src/c_api/decompress_to_edgelist.cpp ) add_library(cugraph::cugraph_c ALIAS cugraph_c) diff --git a/cpp/include/cugraph_c/graph_functions.h b/cpp/include/cugraph_c/graph_functions.h index ff7e439232a..44fdeacea97 100644 --- a/cpp/include/cugraph_c/graph_functions.h +++ b/cpp/include/cugraph_c/graph_functions.h @@ -324,6 +324,25 @@ cugraph_error_code_t cugraph_degrees(const cugraph_resource_handle_t* handle, cugraph_degrees_result_t** result, cugraph_error_t** error); +/** + * @brief Construct the edge list from the graph view object. + * + * @param [in] handle Handle for accessing resources + * @param [in] graph Graph to operate on + * @param [in] do_expensive_check A flag to run expensive checks for input arguments (if set to + * true) + * @param [out] result Opaque pointer to induced subgraph result + * @param [out] error Pointer to an error object storing details of any error. Will + * be populated if error code is not CUGRAPH_SUCCESS + * @return error code + */ +cugraph_error_code_t cugraph_decompress_to_edgelist( + const cugraph_resource_handle_t* handle, + cugraph_graph_t* graph, + bool_t do_expensive_check, + cugraph_induced_subgraph_result_t** result, + cugraph_error_t** error); + /** * @brief Get the vertex ids * diff --git a/cpp/src/c_api/decompress_to_edgelist.cpp b/cpp/src/c_api/decompress_to_edgelist.cpp new file mode 100644 index 00000000000..62a3b69aef3 --- /dev/null +++ b/cpp/src/c_api/decompress_to_edgelist.cpp @@ -0,0 +1,145 @@ +/* + * Copyright (c) 2022-2024, 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_api/abstract_functor.hpp" +#include "c_api/core_result.hpp" +#include "c_api/graph.hpp" +#include "c_api/induced_subgraph_result.hpp" +#include "c_api/resource_handle.hpp" +#include "c_api/utils.hpp" + +#include + +#include +#include // FIXME: mihgt remove the shuffle headers because they are unsued +#include +#include + +#include + +namespace { + +struct decompress_to_edgelist_functor : public cugraph::c_api::abstract_functor { + raft::handle_t const& handle_; + cugraph::c_api::cugraph_graph_t* graph_{}; + + cugraph::c_api::cugraph_core_result_t const* core_result_{}; + bool do_expensive_check_{}; + cugraph::c_api::cugraph_induced_subgraph_result_t* result_{}; + + decompress_to_edgelist_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 { + if constexpr (store_transposed) { + error_code_ = cugraph::c_api:: + transpose_storage( + handle_, graph_, error_.get()); + if (error_code_ != CUGRAPH_SUCCESS) + ; + } + // FIXME: Transpose_storage may have a bug, since if store_transposed is True it can reverse + // the bool value of is_symmetric + auto graph = + reinterpret_cast*>(graph_->graph_); + + auto graph_view = graph->view(); + + auto edge_weights = reinterpret_cast< + cugraph::edge_property_t, + weight_t>*>(graph_->edge_weights_); + + auto edge_ids = reinterpret_cast< + cugraph::edge_property_t, + edge_t>*>(graph_->edge_ids_); + + auto edge_types = reinterpret_cast< + cugraph::edge_property_t, + edge_type_type_t>*>(graph_->edge_types_); + + auto number_map = reinterpret_cast*>(graph_->number_map_); + + + auto [result_src, result_dst, result_wgt, edge_id, edge_type] = + cugraph::decompress_to_edgelist( + handle_, + graph_view, + (edge_weights != nullptr) ? std::make_optional(edge_weights->view()) : std::nullopt, + (edge_ids != nullptr) ? std::make_optional(edge_ids->view()) : std::nullopt, + (edge_types != nullptr) ? std::make_optional(edge_types->view()) : std::nullopt, + (number_map != nullptr) ? std::make_optional>( + number_map->data(), number_map->size()) + : std::nullopt, + do_expensive_check_); + + // FIXME: Is it neccessary to un-renumber here after passing number_map to deomcpress_to_edge_list + cugraph::unrenumber_int_vertices( + handle_, + result_src.data(), + result_src.size(), + number_map->data(), + graph_view.vertex_partition_range_lasts(), + do_expensive_check_); + + cugraph::unrenumber_int_vertices( + handle_, + result_dst.data(), + result_dst.size(), + number_map->data(), + graph_view.vertex_partition_range_lasts(), + do_expensive_check_); + + result_ = new cugraph::c_api::cugraph_induced_subgraph_result_t{ + new cugraph::c_api::cugraph_type_erased_device_array_t(result_src, graph_->vertex_type_), + new cugraph::c_api::cugraph_type_erased_device_array_t(result_dst, graph_->vertex_type_), + result_wgt ? new cugraph::c_api::cugraph_type_erased_device_array_t(*result_wgt, graph_->weight_type_) + : NULL, + NULL, // FIXME: replace by edge_ids + NULL, // FIXME: replace by edge_types + NULL}; + } + } +}; + +} // namespace + +extern "C" cugraph_error_code_t cugraph_decompress_to_edgelist(const cugraph_resource_handle_t* handle, + cugraph_graph_t* graph, + bool_t do_expensive_check, + cugraph_induced_subgraph_result_t** result, + cugraph_error_t** error) +{ + decompress_to_edgelist_functor functor(handle, graph, do_expensive_check); + + return cugraph::c_api::run_algorithm(graph, functor, result, error); +} From 426c7ed77da852beb8c3c660027330dbffec7b00 Mon Sep 17 00:00:00 2001 From: jnke2016 Date: Sat, 9 Nov 2024 01:28:44 -0800 Subject: [PATCH 02/26] expose decompress to edgelist to the PLC API --- .../pylibcugraph/pylibcugraph/CMakeLists.txt | 1 + python/pylibcugraph/pylibcugraph/__init__.py | 2 + .../_cugraph_c/graph_functions.pxd | 11 ++ .../pylibcugraph/decompress_to_edgelist.pyx | 169 ++++++++++++++++++ 4 files changed, 183 insertions(+) create mode 100644 python/pylibcugraph/pylibcugraph/decompress_to_edgelist.pyx diff --git a/python/pylibcugraph/pylibcugraph/CMakeLists.txt b/python/pylibcugraph/pylibcugraph/CMakeLists.txt index 3a53c7d16c3..7d39874f3b4 100644 --- a/python/pylibcugraph/pylibcugraph/CMakeLists.txt +++ b/python/pylibcugraph/pylibcugraph/CMakeLists.txt @@ -66,6 +66,7 @@ set(cython_sources all_pairs_overlap_coefficients.pyx all_pairs_cosine_coefficients.pyx edge_id_lookup_table.pyx + decompress_to_edgelist.pyx ) set(linked_libraries cugraph::cugraph;cugraph::cugraph_c) diff --git a/python/pylibcugraph/pylibcugraph/__init__.py b/python/pylibcugraph/pylibcugraph/__init__.py index 9c04a528fd8..d9385091ba6 100644 --- a/python/pylibcugraph/pylibcugraph/__init__.py +++ b/python/pylibcugraph/pylibcugraph/__init__.py @@ -113,6 +113,8 @@ from pylibcugraph.degrees import in_degrees, out_degrees, degrees +from pylibcugraph.decompress_to_edgelist import decompress_to_edgelist + from pylibcugraph import exceptions diff --git a/python/pylibcugraph/pylibcugraph/_cugraph_c/graph_functions.pxd b/python/pylibcugraph/pylibcugraph/_cugraph_c/graph_functions.pxd index b8f16cb94c8..1e8b9da12d2 100644 --- a/python/pylibcugraph/pylibcugraph/_cugraph_c/graph_functions.pxd +++ b/python/pylibcugraph/pylibcugraph/_cugraph_c/graph_functions.pxd @@ -250,3 +250,14 @@ cdef extern from "cugraph_c/graph_functions.h": cugraph_degrees_result_free( cugraph_degrees_result_t* degrees_result ) + + ########################################################################### + # decompress to edgelist + cdef cugraph_error_code_t \ + cugraph_decompress_to_edgelist( + const cugraph_resource_handle_t* handle, + cugraph_graph_t* graph, + bool_t do_expensive_check, + cugraph_induced_subgraph_result_t** result, + cugraph_error_t** error + ) diff --git a/python/pylibcugraph/pylibcugraph/decompress_to_edgelist.pyx b/python/pylibcugraph/pylibcugraph/decompress_to_edgelist.pyx new file mode 100644 index 00000000000..38afa706dc5 --- /dev/null +++ b/python/pylibcugraph/pylibcugraph/decompress_to_edgelist.pyx @@ -0,0 +1,169 @@ +# Copyright (c) 2023-2024, 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. + +# Have cython use python 3 syntax +# cython: language_level = 3 + + +from pylibcugraph._cugraph_c.types cimport ( + bool_t, +) +from pylibcugraph._cugraph_c.resource_handle cimport ( + cugraph_resource_handle_t, +) +from pylibcugraph._cugraph_c.error cimport ( + cugraph_error_code_t, + cugraph_error_t, +) +from pylibcugraph._cugraph_c.array cimport ( + cugraph_type_erased_device_array_view_t, +) +from pylibcugraph._cugraph_c.graph cimport ( + cugraph_graph_t, +) +from pylibcugraph._cugraph_c.graph_functions cimport ( + cugraph_induced_subgraph_result_t, + cugraph_decompress_to_edgelist, + cugraph_induced_subgraph_get_sources, + cugraph_induced_subgraph_get_destinations, + cugraph_induced_subgraph_get_edge_weights, + cugraph_induced_subgraph_get_edge_ids, + cugraph_induced_subgraph_get_edge_type_ids, + cugraph_induced_subgraph_get_subgraph_offsets, + cugraph_induced_subgraph_result_free, +) + +from pylibcugraph.resource_handle cimport ( + ResourceHandle, +) +from pylibcugraph.graphs cimport ( + _GPUGraph, +) +from pylibcugraph.utils cimport ( + assert_success, + copy_to_cupy_array, + create_cugraph_type_erased_device_array_view_from_py_obj, +) + + +def decompress_to_edgelist(ResourceHandle resource_handle, + _GPUGraph graph, + bool_t do_expensive_check): + """ + extract a the edgelist from a graph + + Parameters + ---------- + resource_handle : ResourceHandle + Handle to the underlying device resources needed for referencing data + and running algorithms. + + graph : SGGraph or MGGraph + The input graph. + + do_expensive_check : bool_t + If True, performs more extensive tests on the inputs to ensure + validitity, at the expense of increased run time. + + Returns + ------- + A tuple of device arrays containing the sources, destinations and if applicable + edge_weights, edge_ids and/or edge_type_ids. + + Examples + -------- + >>> import pylibcugraph, cupy, numpy + >>> srcs = cupy.asarray([0, 1, 1, 2, 2, 2, 3, 4], dtype=numpy.int32) + >>> dsts = cupy.asarray([1, 3, 4, 0, 1, 3, 5, 5], dtype=numpy.int32) + >>> weights = cupy.asarray( + ... [0.1, 2.1, 1.1, 5.1, 3.1, 4.1, 7.2, 3.2], dtype=numpy.float32) + >>> resource_handle = pylibcugraph.ResourceHandle() + >>> graph_props = pylibcugraph.GraphProperties( + ... is_symmetric=False, is_multigraph=False) + >>> G = pylibcugraph.SGGraph( + ... resource_handle, graph_props, srcs, dsts, weight_array=weights, + ... store_transposed=False, renumber=False, do_expensive_check=False) + >>> (sources, destinations, edge_weights, _, _) = + ... pylibcugraph.induced_subgraph( + ... resource_handle, G, False) + >>> sources + [0, 1, 1, 2, 2, 2, 3, 4] + >>> destinations + [1, 3, 4, 0, 1, 3, 5, 5] + >>> edge_weights + [0.1, 2.1, 1.1, 5.1, 3.1, 4.1, 7.2, 3.2] + """ + + cdef cugraph_resource_handle_t* c_resource_handle_ptr = \ + resource_handle.c_resource_handle_ptr + cdef cugraph_graph_t* c_graph_ptr = graph.c_graph_ptr + cdef cugraph_induced_subgraph_result_t* result_ptr + cdef cugraph_error_code_t error_code + cdef cugraph_error_t* error_ptr + + error_code = cugraph_decompress_to_edgelist(c_resource_handle_ptr, + c_graph_ptr, + do_expensive_check, + &result_ptr, + &error_ptr) + assert_success(error_code, error_ptr, "cugraph_decompress_to_edgelist") + + # Extract individual device array pointers from result and copy to cupy + # arrays for returning. + cdef cugraph_type_erased_device_array_view_t* sources_ptr = \ + cugraph_induced_subgraph_get_sources(result_ptr) + cdef cugraph_type_erased_device_array_view_t* destinations_ptr = \ + cugraph_induced_subgraph_get_destinations(result_ptr) + cdef cugraph_type_erased_device_array_view_t* edge_weights_ptr = \ + cugraph_induced_subgraph_get_edge_weights(result_ptr) + + cdef cugraph_type_erased_device_array_view_t* edge_ids_ptr = \ + cugraph_induced_subgraph_get_edge_ids(result_ptr) + cdef cugraph_type_erased_device_array_view_t* edge_type_ids_ptr = \ + cugraph_induced_subgraph_get_edge_type_ids(result_ptr) + + + """ + cdef cugraph_type_erased_device_array_view_t* subgraph_offsets_ptr = \ + cugraph_induced_subgraph_get_subgraph_offsets(result_ptr) + """ + + # FIXME: Get ownership of the result data instead of performing a copy + # for perfomance improvement + cupy_edge_weights = None + cupy_edge_ids = None + cupy_edge_type_ids = None + cupy_sources = copy_to_cupy_array( + c_resource_handle_ptr, sources_ptr) + cupy_destinations = copy_to_cupy_array( + c_resource_handle_ptr, destinations_ptr) + if edge_weights_ptr != NULL: + cupy_edge_weights = copy_to_cupy_array( + c_resource_handle_ptr, edge_weights_ptr) + if edge_ids_ptr != NULL: + cupy_edge_weights = copy_to_cupy_array( + c_resource_handle_ptr, edge_ids_ptr) + if edge_type_ids_ptr != NULL: + cupy_edge_weights = copy_to_cupy_array( + c_resource_handle_ptr, edge_type_ids_ptr) + + """ + cupy_subgraph_offsets = copy_to_cupy_array( + c_resource_handle_ptr, subgraph_offsets_ptr) + """ + + # Free pointer + cugraph_induced_subgraph_result_free(result_ptr) + + return (cupy_sources, cupy_destinations, + cupy_edge_weights, cupy_edge_ids, cupy_edge_type_ids) From dd734b1afa5a6b14a5d5670a58a070767d67f56f Mon Sep 17 00:00:00 2001 From: jnke2016 Date: Sat, 9 Nov 2024 01:30:23 -0800 Subject: [PATCH 03/26] expose decompress to edgelist to the python API --- python/cugraph/cugraph/structure/__init__.py | 1 + .../structure/decompress_to_edgelist.py | 87 +++++++++++++++++++ 2 files changed, 88 insertions(+) create mode 100644 python/cugraph/cugraph/structure/decompress_to_edgelist.py diff --git a/python/cugraph/cugraph/structure/__init__.py b/python/cugraph/cugraph/structure/__init__.py index 94f34fd23f3..5e4971cc8fb 100644 --- a/python/cugraph/cugraph/structure/__init__.py +++ b/python/cugraph/cugraph/structure/__init__.py @@ -30,6 +30,7 @@ replicate_cudf_dataframe, replicate_cudf_series, ) +from cugraph.structure.decompress_to_edgelist import decompress_to_edgelist from cugraph.structure.convert_matrix import ( from_edgelist, from_cudf_edgelist, diff --git a/python/cugraph/cugraph/structure/decompress_to_edgelist.py b/python/cugraph/cugraph/structure/decompress_to_edgelist.py new file mode 100644 index 00000000000..cf34493424c --- /dev/null +++ b/python/cugraph/cugraph/structure/decompress_to_edgelist.py @@ -0,0 +1,87 @@ +# Copyright (c) 2019-2024, 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. + +import cudf +from pylibcugraph import ResourceHandle +from pylibcugraph import decompress_to_edgelist as pylibcugraph_decompress_to_edgelist + +from cugraph.structure import Graph + + +def decompress_to_edgelist( + G: Graph, + do_expensive_check: bool +) -> cudf.DataFrame: + """ + Compute a subgraph of the existing graph including only the specified + vertices. This algorithm works with both directed and undirected graphs + and does not actually traverse the edges, but instead simply pulls out any + edges that are incident on vertices that are both contained in the vertices + list. + + If no subgraph can be extracted from the vertices provided, a 'None' value + will be returned. + + Parameters + ---------- + G : cugraph.Graph or networkx.Graph + The current implementation only supports weighted graphs. + + do_expensive_check: bool + + Returns + ------- + edge_lists : cudf.DataFrame + Distributed GPU data frame containing all sources identifiers, + destination identifiers and if applicable edge weights, edge ids and + edge types + + Examples + -------- + >>> from cugraph.datasets import karate + >>> G = karate.get_graph(download=True) + >>> verts = np.zeros(3, dtype=np.int32) + >>> verts[0] = 0 + >>> verts[1] = 1 + >>> verts[2] = 2 + >>> sverts = cudf.Series(verts) + >>> edgelist = cugraph.decompress_to_edgelist(G, False) + + """ + + + do_expensive_check = False + source, destination, weight, edge_ids, edge_type_ids = pylibcugraph_decompress_to_edgelist( + resource_handle=ResourceHandle(), + graph=G._plc_graph, + do_expensive_check=do_expensive_check + ) + + print("source = ", source) + print("detaination = ", destination) + + df = cudf.DataFrame() + df["src"] = source + df["dst"] = destination + if weight is not None: + df["weight"] = weight + if edge_ids is not None: + df["edge_ids"] = edge_ids + if edge_type_ids is not None: + df["edge_type_ids"] = edge_type_ids + + if G.renumbered: + df, _ = G.unrenumber(df, "src", get_column_names=True) + df, _ = G.unrenumber(df, "dst", get_column_names=True) + + return df From 8dc23fe54050367c54127f346c28976be4f24374 Mon Sep 17 00:00:00 2001 From: jnke2016 Date: Sun, 10 Nov 2024 06:37:56 -0800 Subject: [PATCH 04/26] remove debug print --- python/cugraph/cugraph/structure/decompress_to_edgelist.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/python/cugraph/cugraph/structure/decompress_to_edgelist.py b/python/cugraph/cugraph/structure/decompress_to_edgelist.py index cf34493424c..d8f64ca7800 100644 --- a/python/cugraph/cugraph/structure/decompress_to_edgelist.py +++ b/python/cugraph/cugraph/structure/decompress_to_edgelist.py @@ -67,9 +67,6 @@ def decompress_to_edgelist( do_expensive_check=do_expensive_check ) - print("source = ", source) - print("detaination = ", destination) - df = cudf.DataFrame() df["src"] = source df["dst"] = destination From ee14ff68ad6322666ea2d6e1ccf20c5885c551ea Mon Sep 17 00:00:00 2001 From: jnke2016 Date: Sun, 10 Nov 2024 06:38:35 -0800 Subject: [PATCH 05/26] fix typo --- python/pylibcugraph/pylibcugraph/decompress_to_edgelist.pyx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python/pylibcugraph/pylibcugraph/decompress_to_edgelist.pyx b/python/pylibcugraph/pylibcugraph/decompress_to_edgelist.pyx index 38afa706dc5..7fd769babf4 100644 --- a/python/pylibcugraph/pylibcugraph/decompress_to_edgelist.pyx +++ b/python/pylibcugraph/pylibcugraph/decompress_to_edgelist.pyx @@ -151,10 +151,10 @@ def decompress_to_edgelist(ResourceHandle resource_handle, cupy_edge_weights = copy_to_cupy_array( c_resource_handle_ptr, edge_weights_ptr) if edge_ids_ptr != NULL: - cupy_edge_weights = copy_to_cupy_array( + cupy_edge_ids = copy_to_cupy_array( c_resource_handle_ptr, edge_ids_ptr) if edge_type_ids_ptr != NULL: - cupy_edge_weights = copy_to_cupy_array( + cupy_edge_type_ids = copy_to_cupy_array( c_resource_handle_ptr, edge_type_ids_ptr) """ From 37caab7ddab38a3dbc5dbe044d0dae3ecaa0520c Mon Sep 17 00:00:00 2001 From: jnke2016 Date: Sun, 10 Nov 2024 06:39:28 -0800 Subject: [PATCH 06/26] remove unsued code and support edge ids and types --- cpp/src/c_api/decompress_to_edgelist.cpp | 24 +++++------------------- 1 file changed, 5 insertions(+), 19 deletions(-) diff --git a/cpp/src/c_api/decompress_to_edgelist.cpp b/cpp/src/c_api/decompress_to_edgelist.cpp index 62a3b69aef3..c24c630ba6f 100644 --- a/cpp/src/c_api/decompress_to_edgelist.cpp +++ b/cpp/src/c_api/decompress_to_edgelist.cpp @@ -90,7 +90,7 @@ struct decompress_to_edgelist_functor : public cugraph::c_api::abstract_functor auto number_map = reinterpret_cast*>(graph_->number_map_); - auto [result_src, result_dst, result_wgt, edge_id, edge_type] = + auto [result_src, result_dst, result_wgt, result_edge_id, result_edge_type] = cugraph::decompress_to_edgelist( handle_, graph_view, @@ -102,30 +102,16 @@ struct decompress_to_edgelist_functor : public cugraph::c_api::abstract_functor : std::nullopt, do_expensive_check_); - // FIXME: Is it neccessary to un-renumber here after passing number_map to deomcpress_to_edge_list - cugraph::unrenumber_int_vertices( - handle_, - result_src.data(), - result_src.size(), - number_map->data(), - graph_view.vertex_partition_range_lasts(), - do_expensive_check_); - - cugraph::unrenumber_int_vertices( - handle_, - result_dst.data(), - result_dst.size(), - number_map->data(), - graph_view.vertex_partition_range_lasts(), - do_expensive_check_); result_ = new cugraph::c_api::cugraph_induced_subgraph_result_t{ new cugraph::c_api::cugraph_type_erased_device_array_t(result_src, graph_->vertex_type_), new cugraph::c_api::cugraph_type_erased_device_array_t(result_dst, graph_->vertex_type_), result_wgt ? new cugraph::c_api::cugraph_type_erased_device_array_t(*result_wgt, graph_->weight_type_) : NULL, - NULL, // FIXME: replace by edge_ids - NULL, // FIXME: replace by edge_types + result_edge_id ? new cugraph::c_api::cugraph_type_erased_device_array_t(*result_edge_id, graph_->edge_type_) + : NULL, + result_edge_type ? new cugraph::c_api::cugraph_type_erased_device_array_t(*result_edge_type, graph_->edge_type_id_type_) + : NULL, NULL}; } } From 230f23919d423551d4a8a3dc8a569a88936f6b68 Mon Sep 17 00:00:00 2001 From: jnke2016 Date: Sun, 10 Nov 2024 21:30:03 -0800 Subject: [PATCH 07/26] add mg implementation of decompress_to_edgelist --- python/cugraph/cugraph/dask/__init__.py | 1 + .../dask/structure/decompress_to_edgelist.py | 110 ++++++++++++++++++ .../structure/mg_decompress_to_edgelist.py | 110 ++++++++++++++++++ 3 files changed, 221 insertions(+) create mode 100644 python/cugraph/cugraph/dask/structure/decompress_to_edgelist.py create mode 100644 python/cugraph/cugraph/dask/structure/mg_decompress_to_edgelist.py diff --git a/python/cugraph/cugraph/dask/__init__.py b/python/cugraph/cugraph/dask/__init__.py index b1588008bc6..1c52bcd58d6 100644 --- a/python/cugraph/cugraph/dask/__init__.py +++ b/python/cugraph/cugraph/dask/__init__.py @@ -28,6 +28,7 @@ from .components.connectivity import weakly_connected_components from .sampling.uniform_neighbor_sample import uniform_neighbor_sample from .sampling.random_walks import random_walks +from .structure.decompress_to_edgelist import decompress_to_edgelist from .centrality.eigenvector_centrality import eigenvector_centrality from .cores.core_number import core_number from .centrality.betweenness_centrality import betweenness_centrality diff --git a/python/cugraph/cugraph/dask/structure/decompress_to_edgelist.py b/python/cugraph/cugraph/dask/structure/decompress_to_edgelist.py new file mode 100644 index 00000000000..11e7494dcda --- /dev/null +++ b/python/cugraph/cugraph/dask/structure/decompress_to_edgelist.py @@ -0,0 +1,110 @@ +# Copyright (c) 2022-2024, 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. +# + +from dask.distributed import wait, default_client + +import cugraph.dask.comms.comms as Comms +import dask_cudf +import cudf +import cupy as cp + +from typing import Tuple + +from pylibcugraph import ( + ResourceHandle, + decompress_to_edgelist as pylibcugraph_decompress_to_edgelist +) + + +def _call_decompress_to_edgelist( + sID: bytes, + mg_graph_x, + do_expensive_check: bool, +) -> Tuple[cp.ndarray, cp.ndarray, cp.ndarray, cp.ndarray]: + return pylibcugraph_decompress_to_edgelist( + resource_handle=ResourceHandle(Comms.get_handle(sID).getHandle()), + graph=mg_graph_x, + do_expensive_check=do_expensive_check, + ) + + +def convert_to_cudf(cp_arrays: cp.ndarray) -> cudf.DataFrame: + cp_src, cp_dst, cp_weight, cp_edge_ids, cp_edge_type_ids = cp_arrays + + df = cudf.DataFrame() + df["src"] = cp_src + df["dst"] = cp_dst + if cp_weight is not None: + df["weight"] = cp_weight + if cp_edge_ids is not None: + df["edge_ids"] = cp_edge_ids + if cp_edge_type_ids is not None: + df["edge_type_ids"] = cp_edge_type_ids + + return df + + +def decompress_to_edgelist( + input_graph, + do_expensive_check: bool +) -> dask_cudf.DataFrame: + """ + Extract a the edgelist from a graph. + + Parameters + ---------- + G : cugraph.Graph or networkx.Graph + Graph or matrix object, which should contain the connectivity + information. Edge weights, if present, should be single or double + precision floating point values. + + do_expensive_check: bool + + Returns + ------- + ego_edge_lists : dask_cudf.DataFrame + Distributed GPU data frame containing all induced sources identifiers, + destination identifiers, and if applicable edge weights, edge ids and + edge types + """ + + # Initialize dask client + client = default_client() + + do_expensive_check = False + + result = [ + client.submit( + _call_decompress_to_edgelist, + Comms.get_session_id(), + input_graph._plc_graph[w], + do_expensive_check + ) + for w in Comms.get_workers() + ] + wait(result) + + cudf_result = [client.submit(convert_to_cudf, cp_arrays) for cp_arrays in result] + + wait(cudf_result) + + ddf = dask_cudf.from_delayed(cudf_result).persist() + wait(ddf) + + if input_graph.renumbered: + ddf = input_graph.unrenumber(ddf, "src") + ddf = input_graph.unrenumber(ddf, "dst") + + return ddf diff --git a/python/cugraph/cugraph/dask/structure/mg_decompress_to_edgelist.py b/python/cugraph/cugraph/dask/structure/mg_decompress_to_edgelist.py new file mode 100644 index 00000000000..11e7494dcda --- /dev/null +++ b/python/cugraph/cugraph/dask/structure/mg_decompress_to_edgelist.py @@ -0,0 +1,110 @@ +# Copyright (c) 2022-2024, 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. +# + +from dask.distributed import wait, default_client + +import cugraph.dask.comms.comms as Comms +import dask_cudf +import cudf +import cupy as cp + +from typing import Tuple + +from pylibcugraph import ( + ResourceHandle, + decompress_to_edgelist as pylibcugraph_decompress_to_edgelist +) + + +def _call_decompress_to_edgelist( + sID: bytes, + mg_graph_x, + do_expensive_check: bool, +) -> Tuple[cp.ndarray, cp.ndarray, cp.ndarray, cp.ndarray]: + return pylibcugraph_decompress_to_edgelist( + resource_handle=ResourceHandle(Comms.get_handle(sID).getHandle()), + graph=mg_graph_x, + do_expensive_check=do_expensive_check, + ) + + +def convert_to_cudf(cp_arrays: cp.ndarray) -> cudf.DataFrame: + cp_src, cp_dst, cp_weight, cp_edge_ids, cp_edge_type_ids = cp_arrays + + df = cudf.DataFrame() + df["src"] = cp_src + df["dst"] = cp_dst + if cp_weight is not None: + df["weight"] = cp_weight + if cp_edge_ids is not None: + df["edge_ids"] = cp_edge_ids + if cp_edge_type_ids is not None: + df["edge_type_ids"] = cp_edge_type_ids + + return df + + +def decompress_to_edgelist( + input_graph, + do_expensive_check: bool +) -> dask_cudf.DataFrame: + """ + Extract a the edgelist from a graph. + + Parameters + ---------- + G : cugraph.Graph or networkx.Graph + Graph or matrix object, which should contain the connectivity + information. Edge weights, if present, should be single or double + precision floating point values. + + do_expensive_check: bool + + Returns + ------- + ego_edge_lists : dask_cudf.DataFrame + Distributed GPU data frame containing all induced sources identifiers, + destination identifiers, and if applicable edge weights, edge ids and + edge types + """ + + # Initialize dask client + client = default_client() + + do_expensive_check = False + + result = [ + client.submit( + _call_decompress_to_edgelist, + Comms.get_session_id(), + input_graph._plc_graph[w], + do_expensive_check + ) + for w in Comms.get_workers() + ] + wait(result) + + cudf_result = [client.submit(convert_to_cudf, cp_arrays) for cp_arrays in result] + + wait(cudf_result) + + ddf = dask_cudf.from_delayed(cudf_result).persist() + wait(ddf) + + if input_graph.renumbered: + ddf = input_graph.unrenumber(ddf, "src") + ddf = input_graph.unrenumber(ddf, "dst") + + return ddf From e0fd0b5e68483bdfabd2c24651f8e18d79157507 Mon Sep 17 00:00:00 2001 From: jnke2016 Date: Sun, 10 Nov 2024 21:33:31 -0800 Subject: [PATCH 08/26] rename file --- .../structure/mg_decompress_to_edgelist.py | 110 ------------------ 1 file changed, 110 deletions(-) delete mode 100644 python/cugraph/cugraph/dask/structure/mg_decompress_to_edgelist.py diff --git a/python/cugraph/cugraph/dask/structure/mg_decompress_to_edgelist.py b/python/cugraph/cugraph/dask/structure/mg_decompress_to_edgelist.py deleted file mode 100644 index 11e7494dcda..00000000000 --- a/python/cugraph/cugraph/dask/structure/mg_decompress_to_edgelist.py +++ /dev/null @@ -1,110 +0,0 @@ -# Copyright (c) 2022-2024, 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. -# - -from dask.distributed import wait, default_client - -import cugraph.dask.comms.comms as Comms -import dask_cudf -import cudf -import cupy as cp - -from typing import Tuple - -from pylibcugraph import ( - ResourceHandle, - decompress_to_edgelist as pylibcugraph_decompress_to_edgelist -) - - -def _call_decompress_to_edgelist( - sID: bytes, - mg_graph_x, - do_expensive_check: bool, -) -> Tuple[cp.ndarray, cp.ndarray, cp.ndarray, cp.ndarray]: - return pylibcugraph_decompress_to_edgelist( - resource_handle=ResourceHandle(Comms.get_handle(sID).getHandle()), - graph=mg_graph_x, - do_expensive_check=do_expensive_check, - ) - - -def convert_to_cudf(cp_arrays: cp.ndarray) -> cudf.DataFrame: - cp_src, cp_dst, cp_weight, cp_edge_ids, cp_edge_type_ids = cp_arrays - - df = cudf.DataFrame() - df["src"] = cp_src - df["dst"] = cp_dst - if cp_weight is not None: - df["weight"] = cp_weight - if cp_edge_ids is not None: - df["edge_ids"] = cp_edge_ids - if cp_edge_type_ids is not None: - df["edge_type_ids"] = cp_edge_type_ids - - return df - - -def decompress_to_edgelist( - input_graph, - do_expensive_check: bool -) -> dask_cudf.DataFrame: - """ - Extract a the edgelist from a graph. - - Parameters - ---------- - G : cugraph.Graph or networkx.Graph - Graph or matrix object, which should contain the connectivity - information. Edge weights, if present, should be single or double - precision floating point values. - - do_expensive_check: bool - - Returns - ------- - ego_edge_lists : dask_cudf.DataFrame - Distributed GPU data frame containing all induced sources identifiers, - destination identifiers, and if applicable edge weights, edge ids and - edge types - """ - - # Initialize dask client - client = default_client() - - do_expensive_check = False - - result = [ - client.submit( - _call_decompress_to_edgelist, - Comms.get_session_id(), - input_graph._plc_graph[w], - do_expensive_check - ) - for w in Comms.get_workers() - ] - wait(result) - - cudf_result = [client.submit(convert_to_cudf, cp_arrays) for cp_arrays in result] - - wait(cudf_result) - - ddf = dask_cudf.from_delayed(cudf_result).persist() - wait(ddf) - - if input_graph.renumbered: - ddf = input_graph.unrenumber(ddf, "src") - ddf = input_graph.unrenumber(ddf, "dst") - - return ddf From 946b033b9a0993e4237e7a5e0027d0a0342d384a Mon Sep 17 00:00:00 2001 From: jnke2016 Date: Sun, 10 Nov 2024 21:34:20 -0800 Subject: [PATCH 09/26] update docstrings --- .../cugraph/structure/decompress_to_edgelist.py | 15 ++++----------- .../pylibcugraph/decompress_to_edgelist.pyx | 2 +- 2 files changed, 5 insertions(+), 12 deletions(-) diff --git a/python/cugraph/cugraph/structure/decompress_to_edgelist.py b/python/cugraph/cugraph/structure/decompress_to_edgelist.py index d8f64ca7800..3d60fcf7738 100644 --- a/python/cugraph/cugraph/structure/decompress_to_edgelist.py +++ b/python/cugraph/cugraph/structure/decompress_to_edgelist.py @@ -23,19 +23,13 @@ def decompress_to_edgelist( do_expensive_check: bool ) -> cudf.DataFrame: """ - Compute a subgraph of the existing graph including only the specified - vertices. This algorithm works with both directed and undirected graphs - and does not actually traverse the edges, but instead simply pulls out any - edges that are incident on vertices that are both contained in the vertices - list. - - If no subgraph can be extracted from the vertices provided, a 'None' value - will be returned. + Extract a the edgelist from a graph. Parameters ---------- - G : cugraph.Graph or networkx.Graph - The current implementation only supports weighted graphs. + G : cugraph.Graph + cuGraph graph descriptor, should contain the connectivity information + as an edge list. do_expensive_check: bool @@ -54,7 +48,6 @@ def decompress_to_edgelist( >>> verts[0] = 0 >>> verts[1] = 1 >>> verts[2] = 2 - >>> sverts = cudf.Series(verts) >>> edgelist = cugraph.decompress_to_edgelist(G, False) """ diff --git a/python/pylibcugraph/pylibcugraph/decompress_to_edgelist.pyx b/python/pylibcugraph/pylibcugraph/decompress_to_edgelist.pyx index 7fd769babf4..a2fc561c760 100644 --- a/python/pylibcugraph/pylibcugraph/decompress_to_edgelist.pyx +++ b/python/pylibcugraph/pylibcugraph/decompress_to_edgelist.pyx @@ -60,7 +60,7 @@ def decompress_to_edgelist(ResourceHandle resource_handle, _GPUGraph graph, bool_t do_expensive_check): """ - extract a the edgelist from a graph + Extract a the edgelist from a graph Parameters ---------- From 17e21233748db60483114f09225f36c3d9bfd09b Mon Sep 17 00:00:00 2001 From: jnke2016 Date: Mon, 11 Nov 2024 12:13:47 -0800 Subject: [PATCH 10/26] remove argument --- .../cugraph/cugraph/dask/structure/decompress_to_edgelist.py | 5 +---- python/cugraph/cugraph/structure/decompress_to_edgelist.py | 5 +---- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/python/cugraph/cugraph/dask/structure/decompress_to_edgelist.py b/python/cugraph/cugraph/dask/structure/decompress_to_edgelist.py index 11e7494dcda..99827143569 100644 --- a/python/cugraph/cugraph/dask/structure/decompress_to_edgelist.py +++ b/python/cugraph/cugraph/dask/structure/decompress_to_edgelist.py @@ -57,8 +57,7 @@ def convert_to_cudf(cp_arrays: cp.ndarray) -> cudf.DataFrame: def decompress_to_edgelist( - input_graph, - do_expensive_check: bool + input_graph ) -> dask_cudf.DataFrame: """ Extract a the edgelist from a graph. @@ -70,8 +69,6 @@ def decompress_to_edgelist( information. Edge weights, if present, should be single or double precision floating point values. - do_expensive_check: bool - Returns ------- ego_edge_lists : dask_cudf.DataFrame diff --git a/python/cugraph/cugraph/structure/decompress_to_edgelist.py b/python/cugraph/cugraph/structure/decompress_to_edgelist.py index 3d60fcf7738..78ea6e66343 100644 --- a/python/cugraph/cugraph/structure/decompress_to_edgelist.py +++ b/python/cugraph/cugraph/structure/decompress_to_edgelist.py @@ -19,8 +19,7 @@ def decompress_to_edgelist( - G: Graph, - do_expensive_check: bool + G: Graph ) -> cudf.DataFrame: """ Extract a the edgelist from a graph. @@ -31,8 +30,6 @@ def decompress_to_edgelist( cuGraph graph descriptor, should contain the connectivity information as an edge list. - do_expensive_check: bool - Returns ------- edge_lists : cudf.DataFrame From fe9a277c468b53f64a111ac30283be6127879575 Mon Sep 17 00:00:00 2001 From: jnke2016 Date: Mon, 11 Nov 2024 14:22:55 -0800 Subject: [PATCH 11/26] remove 'legacy_renum_only' flag and move the function 'decompress_to_edgelist' --- python/cugraph/cugraph/dask/__init__.py | 1 - .../dask/structure/decompress_to_edgelist.py | 107 ------------------ python/cugraph/cugraph/structure/__init__.py | 1 - .../structure/decompress_to_edgelist.py | 74 ------------ .../cugraph/structure/graph_classes.py | 41 +------ .../simpleDistributedGraph.py | 98 +++++++++++++--- 6 files changed, 86 insertions(+), 236 deletions(-) delete mode 100644 python/cugraph/cugraph/dask/structure/decompress_to_edgelist.py delete mode 100644 python/cugraph/cugraph/structure/decompress_to_edgelist.py diff --git a/python/cugraph/cugraph/dask/__init__.py b/python/cugraph/cugraph/dask/__init__.py index 1c52bcd58d6..b1588008bc6 100644 --- a/python/cugraph/cugraph/dask/__init__.py +++ b/python/cugraph/cugraph/dask/__init__.py @@ -28,7 +28,6 @@ from .components.connectivity import weakly_connected_components from .sampling.uniform_neighbor_sample import uniform_neighbor_sample from .sampling.random_walks import random_walks -from .structure.decompress_to_edgelist import decompress_to_edgelist from .centrality.eigenvector_centrality import eigenvector_centrality from .cores.core_number import core_number from .centrality.betweenness_centrality import betweenness_centrality diff --git a/python/cugraph/cugraph/dask/structure/decompress_to_edgelist.py b/python/cugraph/cugraph/dask/structure/decompress_to_edgelist.py deleted file mode 100644 index 99827143569..00000000000 --- a/python/cugraph/cugraph/dask/structure/decompress_to_edgelist.py +++ /dev/null @@ -1,107 +0,0 @@ -# Copyright (c) 2022-2024, 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. -# - -from dask.distributed import wait, default_client - -import cugraph.dask.comms.comms as Comms -import dask_cudf -import cudf -import cupy as cp - -from typing import Tuple - -from pylibcugraph import ( - ResourceHandle, - decompress_to_edgelist as pylibcugraph_decompress_to_edgelist -) - - -def _call_decompress_to_edgelist( - sID: bytes, - mg_graph_x, - do_expensive_check: bool, -) -> Tuple[cp.ndarray, cp.ndarray, cp.ndarray, cp.ndarray]: - return pylibcugraph_decompress_to_edgelist( - resource_handle=ResourceHandle(Comms.get_handle(sID).getHandle()), - graph=mg_graph_x, - do_expensive_check=do_expensive_check, - ) - - -def convert_to_cudf(cp_arrays: cp.ndarray) -> cudf.DataFrame: - cp_src, cp_dst, cp_weight, cp_edge_ids, cp_edge_type_ids = cp_arrays - - df = cudf.DataFrame() - df["src"] = cp_src - df["dst"] = cp_dst - if cp_weight is not None: - df["weight"] = cp_weight - if cp_edge_ids is not None: - df["edge_ids"] = cp_edge_ids - if cp_edge_type_ids is not None: - df["edge_type_ids"] = cp_edge_type_ids - - return df - - -def decompress_to_edgelist( - input_graph -) -> dask_cudf.DataFrame: - """ - Extract a the edgelist from a graph. - - Parameters - ---------- - G : cugraph.Graph or networkx.Graph - Graph or matrix object, which should contain the connectivity - information. Edge weights, if present, should be single or double - precision floating point values. - - Returns - ------- - ego_edge_lists : dask_cudf.DataFrame - Distributed GPU data frame containing all induced sources identifiers, - destination identifiers, and if applicable edge weights, edge ids and - edge types - """ - - # Initialize dask client - client = default_client() - - do_expensive_check = False - - result = [ - client.submit( - _call_decompress_to_edgelist, - Comms.get_session_id(), - input_graph._plc_graph[w], - do_expensive_check - ) - for w in Comms.get_workers() - ] - wait(result) - - cudf_result = [client.submit(convert_to_cudf, cp_arrays) for cp_arrays in result] - - wait(cudf_result) - - ddf = dask_cudf.from_delayed(cudf_result).persist() - wait(ddf) - - if input_graph.renumbered: - ddf = input_graph.unrenumber(ddf, "src") - ddf = input_graph.unrenumber(ddf, "dst") - - return ddf diff --git a/python/cugraph/cugraph/structure/__init__.py b/python/cugraph/cugraph/structure/__init__.py index 5e4971cc8fb..94f34fd23f3 100644 --- a/python/cugraph/cugraph/structure/__init__.py +++ b/python/cugraph/cugraph/structure/__init__.py @@ -30,7 +30,6 @@ replicate_cudf_dataframe, replicate_cudf_series, ) -from cugraph.structure.decompress_to_edgelist import decompress_to_edgelist from cugraph.structure.convert_matrix import ( from_edgelist, from_cudf_edgelist, diff --git a/python/cugraph/cugraph/structure/decompress_to_edgelist.py b/python/cugraph/cugraph/structure/decompress_to_edgelist.py deleted file mode 100644 index 78ea6e66343..00000000000 --- a/python/cugraph/cugraph/structure/decompress_to_edgelist.py +++ /dev/null @@ -1,74 +0,0 @@ -# Copyright (c) 2019-2024, 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. - -import cudf -from pylibcugraph import ResourceHandle -from pylibcugraph import decompress_to_edgelist as pylibcugraph_decompress_to_edgelist - -from cugraph.structure import Graph - - -def decompress_to_edgelist( - G: Graph -) -> cudf.DataFrame: - """ - Extract a the edgelist from a graph. - - Parameters - ---------- - G : cugraph.Graph - cuGraph graph descriptor, should contain the connectivity information - as an edge list. - - Returns - ------- - edge_lists : cudf.DataFrame - Distributed GPU data frame containing all sources identifiers, - destination identifiers and if applicable edge weights, edge ids and - edge types - - Examples - -------- - >>> from cugraph.datasets import karate - >>> G = karate.get_graph(download=True) - >>> verts = np.zeros(3, dtype=np.int32) - >>> verts[0] = 0 - >>> verts[1] = 1 - >>> verts[2] = 2 - >>> edgelist = cugraph.decompress_to_edgelist(G, False) - - """ - - - do_expensive_check = False - source, destination, weight, edge_ids, edge_type_ids = pylibcugraph_decompress_to_edgelist( - resource_handle=ResourceHandle(), - graph=G._plc_graph, - do_expensive_check=do_expensive_check - ) - - df = cudf.DataFrame() - df["src"] = source - df["dst"] = destination - if weight is not None: - df["weight"] = weight - if edge_ids is not None: - df["edge_ids"] = edge_ids - if edge_type_ids is not None: - df["edge_type_ids"] = edge_type_ids - - if G.renumbered: - df, _ = G.unrenumber(df, "src", get_column_names=True) - df, _ = G.unrenumber(df, "dst", get_column_names=True) - - return df diff --git a/python/cugraph/cugraph/structure/graph_classes.py b/python/cugraph/cugraph/structure/graph_classes.py index 84234f7e904..c8dc0a2b8fe 100644 --- a/python/cugraph/cugraph/structure/graph_classes.py +++ b/python/cugraph/cugraph/structure/graph_classes.py @@ -115,7 +115,6 @@ def from_cudf_edgelist( edge_type=None, renumber=True, store_transposed=False, - legacy_renum_only=False, symmetrize=None, ): """ @@ -168,13 +167,6 @@ def from_cudf_edgelist( If True, stores the transpose of the adjacency matrix. Required for certain algorithms. - legacy_renum_only : bool, optional (default=False) - If True, skips the C++ renumbering step. Must be true for - pylibcugraph algorithms. Must be false for algorithms - not yet converted to the pylibcugraph C API. - - This parameter is deprecated and will be removed. - symmetrize: bool, optional (default=None) If True, symmetrize the edge list for an undirected graph. Setting this flag to True for a directed graph returns an error. The default @@ -210,7 +202,6 @@ def from_cudf_edgelist( edge_type=edge_type, renumber=renumber, store_transposed=store_transposed, - legacy_renum_only=legacy_renum_only, symmetrize=symmetrize, ) @@ -305,8 +296,7 @@ def from_dask_cudf_edgelist( edge_id=None, edge_type=None, renumber=True, - store_transposed=False, - legacy_renum_only=False, + store_transposed=False ): """ Initializes the distributed graph from the dask_cudf.DataFrame @@ -353,13 +343,6 @@ def from_dask_cudf_edgelist( If True, stores the transpose of the adjacency matrix. Required for certain algorithms. - legacy_renum_only : bool, optional (default=False) - If True, skips the C++ renumbering step. Must be true for - pylibcugraph algorithms. Must be false for algorithms - not yet converted to the pylibcugraph C API. - - This parameter is deprecated and will be removed. - """ if self._Impl is None: @@ -377,8 +360,7 @@ def from_dask_cudf_edgelist( edge_id=edge_id, edge_type=edge_type, renumber=renumber, - store_transposed=store_transposed, - legacy_renum_only=legacy_renum_only, + store_transposed=store_transposed ) # Move to Compat Module @@ -868,8 +850,7 @@ def from_cudf_edgelist( destination="destination", edge_attr=None, renumber=True, - store_transposed=False, - legacy_renum_only=False, + store_transposed=False ): """ Initialize a graph from the edge list. It is an error to call this @@ -909,13 +890,6 @@ def from_cudf_edgelist( If True, stores the transpose of the adjacency matrix. Required for certain algorithms. - legacy_renum_only : bool, optional (default=False) - If True, skips the C++ renumbering step. Must be true for - pylibcugraph algorithms. Must be false for algorithms - not yet converted to the pylibcugraph C API. - - This parameter is deprecated and will be removed. - Examples -------- >>> df = cudf.read_csv(datasets_path / 'karate.csv', delimiter=' ', @@ -944,8 +918,7 @@ def from_dask_cudf_edgelist( destination="destination", edge_attr=None, renumber=True, - store_transposed=False, - legacy_renum_only=False, + store_transposed=False ): """ Initializes the distributed graph from the dask_cudf.DataFrame @@ -980,12 +953,6 @@ def from_dask_cudf_edgelist( If True, stores the transpose of the adjacency matrix. Required for certain algorithms. - legacy_renum_only : bool, optional (default=False) - If True, skips the C++ renumbering step. Must be true for - pylibcugraph algorithms. Must be false for algorithms - not yet converted to the pylibcugraph C API. - - This parameter is deprecated and will be removed. """ raise TypeError("Distributed N-partite graph not supported") diff --git a/python/cugraph/cugraph/structure/graph_implementation/simpleDistributedGraph.py b/python/cugraph/cugraph/structure/graph_implementation/simpleDistributedGraph.py index 83dad234287..460c0755113 100644 --- a/python/cugraph/cugraph/structure/graph_implementation/simpleDistributedGraph.py +++ b/python/cugraph/cugraph/structure/graph_implementation/simpleDistributedGraph.py @@ -14,6 +14,7 @@ import gc from typing import Union, Iterable import warnings +from typing import Tuple import cudf import cupy as cp @@ -31,6 +32,7 @@ degrees as pylibcugraph_degrees, in_degrees as pylibcugraph_in_degrees, out_degrees as pylibcugraph_out_degrees, + decompress_to_edgelist as pylibcugraph_decompress_to_edgelist ) from cugraph.structure.number_map import NumberMap @@ -172,7 +174,6 @@ def __from_edgelist( edge_type=None, renumber=True, store_transposed=False, - legacy_renum_only=False, symmetrize=None, ): if not isinstance(input_ddf, dask_cudf.DataFrame): @@ -334,7 +335,7 @@ def __from_edgelist( # C++ renumbering is enabled by default for algorithms that # support it (but only called if renumbering is on) self.compute_renumber_edge_list( - transposed=store_transposed, legacy_renum_only=legacy_renum_only + transposed=store_transposed ) if renumber is False: @@ -979,6 +980,83 @@ def convert_to_cudf(cp_arrays): return ddf + def decompress_to_edgelist( + self, + original: bool = True + ) -> dask_cudf.DataFrame: + """ + Extract a the edgelist from a graph. + + Parameters + ---------- + original : bool (default=True) + Flag determining whether to return the original input edgelist + if 'True' or the renumbered one of 'False' and the edgelist was + renumbered. + + Returns + ------- + ego_edge_lists : dask_cudf.DataFrame + Distributed GPU data frame containing all induced sources identifiers, + destination identifiers, and if applicable edge weights, edge ids and + edge types + """ + + # Initialize dask client + client = default_client() + + do_expensive_check = False + + def _call_decompress_to_edgelist( + sID: bytes, + mg_graph_x, + do_expensive_check: bool, + ) -> Tuple[cp.ndarray, cp.ndarray, cp.ndarray, cp.ndarray]: + return pylibcugraph_decompress_to_edgelist( + resource_handle=ResourceHandle(Comms.get_handle(sID).getHandle()), + graph=mg_graph_x, + do_expensive_check=do_expensive_check, + ) + + result = [ + client.submit( + _call_decompress_to_edgelist, + Comms.get_session_id(), + self._plc_graph[w], + do_expensive_check + ) + for w in Comms.get_workers() + ] + wait(result) + + def convert_to_cudf(cp_arrays: cp.ndarray) -> cudf.DataFrame: + cp_src, cp_dst, cp_weight, cp_edge_ids, cp_edge_type_ids = cp_arrays + + df = cudf.DataFrame() + df["src"] = cp_src + df["dst"] = cp_dst + if cp_weight is not None: + df["weight"] = cp_weight + if cp_edge_ids is not None: + df["edge_ids"] = cp_edge_ids + if cp_edge_type_ids is not None: + df["edge_type_ids"] = cp_edge_type_ids + + return df + + cudf_result = [client.submit(convert_to_cudf, cp_arrays) for cp_arrays in result] + + wait(cudf_result) + + ddf = dask_cudf.from_delayed(cudf_result).persist() + wait(ddf) + + if self.properties.renumbered and original: + ddf = self.renumber_map.unrenumber(ddf, "src") + ddf = self.renumber_map.unrenumber(ddf, "dst") + + return ddf + def select_random_vertices( self, random_state: int = None, num_vertices: int = None ) -> Union[dask_cudf.Series, dask_cudf.DataFrame]: @@ -1214,7 +1292,7 @@ def neighbors(self, n): ddf = self.edgelist.edgelist_df return ddf[ddf["src"] == n]["dst"].reset_index(drop=True) - def compute_renumber_edge_list(self, transposed=False, legacy_renum_only=False): + def compute_renumber_edge_list(self, transposed=False): """ Compute a renumbered edge list This function works in the MNMG pipeline and will transform @@ -1237,20 +1315,9 @@ def compute_renumber_edge_list(self, transposed=False, legacy_renum_only=False): structure. If False, renumber with the intent to make a CSR-like structure. Defaults to False. - legacy_renum_only : (optional) bool - if True, The C++ renumbering will not be triggered. - This parameter is added for new algos following the - C/Pylibcugraph path - This parameter is deprecated and will be removed. """ - if legacy_renum_only: - warning_msg = ( - "The parameter 'legacy_renum_only' is deprecated and will be removed." - ) - warnings.warn(warning_msg, DeprecationWarning) - if not self.properties.renumber: self.edgelist = self.EdgeList(self.input_df) self.renumber_map = None @@ -1268,8 +1335,7 @@ def compute_renumber_edge_list(self, transposed=False, legacy_renum_only=False): self.input_df, self.source_columns, self.destination_columns, - store_transposed=transposed, - legacy_renum_only=legacy_renum_only, + store_transposed=transposed ) self.edgelist = self.EdgeList(renumbered_ddf) From 1182ff52b2f60dc8c5bda5ec9332bbfbe4963b70 Mon Sep 17 00:00:00 2001 From: jnke2016 Date: Tue, 19 Nov 2024 06:10:46 -0800 Subject: [PATCH 12/26] rename variable and update docstrings --- .../graph_implementation/simpleDistributedGraph.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/python/cugraph/cugraph/structure/graph_implementation/simpleDistributedGraph.py b/python/cugraph/cugraph/structure/graph_implementation/simpleDistributedGraph.py index 460c0755113..7430df89f4c 100644 --- a/python/cugraph/cugraph/structure/graph_implementation/simpleDistributedGraph.py +++ b/python/cugraph/cugraph/structure/graph_implementation/simpleDistributedGraph.py @@ -982,21 +982,21 @@ def convert_to_cudf(cp_arrays): def decompress_to_edgelist( self, - original: bool = True + return_unrenumbered_edgelist: bool = True ) -> dask_cudf.DataFrame: """ Extract a the edgelist from a graph. Parameters ---------- - original : bool (default=True) - Flag determining whether to return the original input edgelist - if 'True' or the renumbered one of 'False' and the edgelist was - renumbered. + return_unrenumbered_edgelist : bool (default=True) + Flag determining whether to return the original input edgelist + if 'True' or the renumbered one of 'False' and the edgelist was + renumbered. Returns ------- - ego_edge_lists : dask_cudf.DataFrame + df : dask_cudf.cudf.DataFrame Distributed GPU data frame containing all induced sources identifiers, destination identifiers, and if applicable edge weights, edge ids and edge types @@ -1051,7 +1051,7 @@ def convert_to_cudf(cp_arrays: cp.ndarray) -> cudf.DataFrame: ddf = dask_cudf.from_delayed(cudf_result).persist() wait(ddf) - if self.properties.renumbered and original: + if self.properties.renumbered and return_unrenumbered_edgelist: ddf = self.renumber_map.unrenumber(ddf, "src") ddf = self.renumber_map.unrenumber(ddf, "dst") From 6b701b5b44c1aac3a52b3b02db4dc991314b2d14 Mon Sep 17 00:00:00 2001 From: jnke2016 Date: Tue, 19 Nov 2024 06:12:39 -0800 Subject: [PATCH 13/26] fix typo --- python/pylibcugraph/pylibcugraph/decompress_to_edgelist.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/pylibcugraph/pylibcugraph/decompress_to_edgelist.pyx b/python/pylibcugraph/pylibcugraph/decompress_to_edgelist.pyx index a2fc561c760..709a43d93bf 100644 --- a/python/pylibcugraph/pylibcugraph/decompress_to_edgelist.pyx +++ b/python/pylibcugraph/pylibcugraph/decompress_to_edgelist.pyx @@ -94,7 +94,7 @@ def decompress_to_edgelist(ResourceHandle resource_handle, ... resource_handle, graph_props, srcs, dsts, weight_array=weights, ... store_transposed=False, renumber=False, do_expensive_check=False) >>> (sources, destinations, edge_weights, _, _) = - ... pylibcugraph.induced_subgraph( + ... pylibcugraph.decompress_to_edgelist( ... resource_handle, G, False) >>> sources [0, 1, 1, 2, 2, 2, 3, 4] From 73eb5752d39e5f29e484cd5948dfc8dba92de2f3 Mon Sep 17 00:00:00 2001 From: jnke2016 Date: Tue, 19 Nov 2024 07:36:38 -0800 Subject: [PATCH 14/26] add test for the edge extraction functionality --- .../cugraph/tests/structure/test_graph.py | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/python/cugraph/cugraph/tests/structure/test_graph.py b/python/cugraph/cugraph/tests/structure/test_graph.py index b3e517100e1..9add5edb36e 100644 --- a/python/cugraph/cugraph/tests/structure/test_graph.py +++ b/python/cugraph/cugraph/tests/structure/test_graph.py @@ -46,6 +46,15 @@ def setup_function(): gc.collect() +# ============================================================================= +# Parameters +# ============================================================================= + + +IS_DIRECTED = [True, False] +RENUMBER = [True, False] + + def compare_series(series_1, series_2): assert len(series_1) == len(series_2) df = cudf.DataFrame({"series_1": series_1, "series_2": series_2}) @@ -179,6 +188,52 @@ def test_add_edge_list_to_adj_list(graph_file): assert values_cu is None +@pytest.mark.sg +@pytest.mark.parametrize("graph_file", utils.DATASETS) +@pytest.mark.parametrize("is_directed", IS_DIRECTED) +@pytest.mark.parametrize("renumber", RENUMBER) +def test_decompress_to_edgelist(graph_file, is_directed, renumber): + input_df = utils.read_csv_file(graph_file) + input_df = input_df.rename(columns={'0': 'src', '1': 'dst', '2': 'weight'}) + + G = cugraph.Graph(directed=is_directed) + input_df_ = cudf.DataFrame() + if renumber: + input_df_["src_0"] = cudf.Series(input_df["src"]) + input_df_["dst_0"] = cudf.Series(input_df["dst"]) + input_df_["weight"] = cudf.Series(input_df["weight"]) + input_df_["src_1"] = input_df_["src_0"] + 1000 + input_df_["dst_1"] = input_df_["dst_0"] + 1000 + + input_df = input_df_ + source = ["src_0", "src_1"] + destination = ["dst_0", "dst_1"] + else: + source = "src" + destination = "dst" + + G.from_cudf_edgelist( + input_df, source=source, destination=destination, + weight="weight", renumber=True) + + extracted_df = G.decompress_to_edgelist( + return_unrenumbered_edgelist = True + ) + + if renumber: + extracted_df = extracted_df.rename( + columns={'0_src': 'src_0', '1_src': 'src_1', '0_dst': 'dst_0', '1_dst': 'dst_1'}) + extracted_df = extracted_df.sort_values( + ["src_0", "src_1", "dst_0", "dst_1"]).reset_index(drop=True) + input_df = input_df.sort_values( + ["src_0", "src_1", "dst_0", "dst_1"]).reset_index(drop=True) + else: + extracted_df = extracted_df.sort_values(["src", "dst"]).reset_index(drop=True) + input_df = input_df.sort_values(["src", "dst"]).reset_index(drop=True) + + assert_frame_equal(input_df, extracted_df, check_dtype=False, check_like=True) + + # Test @pytest.mark.sg @pytest.mark.parametrize("graph_file", utils.DATASETS) From 88bd56183a656d991e941aa71a430bd3f429e9a5 Mon Sep 17 00:00:00 2001 From: jnke2016 Date: Tue, 19 Nov 2024 07:58:00 -0800 Subject: [PATCH 15/26] add test for the edge extraction functionality on mg graph --- .../cugraph/tests/structure/test_graph_mg.py | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/python/cugraph/cugraph/tests/structure/test_graph_mg.py b/python/cugraph/cugraph/tests/structure/test_graph_mg.py index f2cc1583f93..3a62eec913b 100644 --- a/python/cugraph/cugraph/tests/structure/test_graph_mg.py +++ b/python/cugraph/cugraph/tests/structure/test_graph_mg.py @@ -420,3 +420,51 @@ def test_graph_creation_properties(dask_client, graph_file, directed, renumber): assert sG.number_of_nodes() == mG.number_of_nodes() assert sG.number_of_edges() == mG.number_of_edges() assert_frame_equal(sG_edgelist_view, mG_edgelist_view, check_dtype=False) + + +@pytest.mark.parametrize("directed", [True, False]) +@pytest.mark.parametrize("renumber", [True, False]) +@pytest.mark.parametrize("graph_file", datasets) +def test_decompress_to_edgelist(dask_client, graph_file, directed, renumber): + input_df = utils.read_csv_file(graph_file) + input_df = input_df.rename(columns={'0': 'src', '1': 'dst', '2': 'weight'}) + + G = cugraph.Graph(directed=directed) + input_df_ = cudf.DataFrame() + if renumber: + input_df_["src_0"] = cudf.Series(input_df["src"]) + input_df_["dst_0"] = cudf.Series(input_df["dst"]) + input_df_["weight"] = cudf.Series(input_df["weight"]) + input_df_["src_1"] = input_df_["src_0"] + 1000 + input_df_["dst_1"] = input_df_["dst_0"] + 1000 + + input_df = input_df_ + source = ["src_0", "src_1"] + destination = ["dst_0", "dst_1"] + else: + source = "src" + destination = "dst" + num_workers = len(Comms.get_workers()) + + input_ddf = dask_cudf.from_cudf(input_df, npartitions=num_workers) + + G = cugraph.Graph(directed=True) + G.from_dask_cudf_edgelist( + input_ddf, + source=source, + destination=destination, + weight="weight" + ) + + extracted_df = G.decompress_to_edgelist( + return_unrenumbered_edgelist = True + ).compute().reset_index(drop=True) + + if renumber: + extracted_df = extracted_df.rename( + columns={'0_src': 'src_0', '1_src': 'src_1', + '0_dst': 'dst_0', '1_dst': 'dst_1'}) + extracted_df = extracted_df.sort_values( + ["src_0", "src_1", "dst_0", "dst_1"]).reset_index(drop=True) + input_df = input_df.sort_values( + ["src_0", "src_1", "dst_0", "dst_1"]).reset_index(drop=True) From 6af846be2ea7401f168603ef37a659109bfa2237 Mon Sep 17 00:00:00 2001 From: jnke2016 Date: Tue, 19 Nov 2024 08:06:32 -0800 Subject: [PATCH 16/26] add method to extract the edgelist from an SG graph --- .../graph_implementation/simpleGraph.py | 67 ++++++++++++++++--- 1 file changed, 57 insertions(+), 10 deletions(-) diff --git a/python/cugraph/cugraph/structure/graph_implementation/simpleGraph.py b/python/cugraph/cugraph/structure/graph_implementation/simpleGraph.py index 858b114ebdc..e3067312ccf 100644 --- a/python/cugraph/cugraph/structure/graph_implementation/simpleGraph.py +++ b/python/cugraph/cugraph/structure/graph_implementation/simpleGraph.py @@ -14,6 +14,7 @@ from cugraph.structure import graph_primtypes_wrapper from cugraph.structure.replicate_edgelist import replicate_cudf_dataframe from cugraph.structure.symmetrize import symmetrize as symmetrize_df +from pylibcugraph import decompress_to_edgelist as pylibcugraph_decompress_to_edgelist from cugraph.structure.number_map import NumberMap import cugraph.dask.common.mg_utils as mg_utils import cudf @@ -132,17 +133,9 @@ def __from_edgelist( edge_id=None, edge_type=None, renumber=True, - legacy_renum_only=False, store_transposed=False, symmetrize=None, ): - if legacy_renum_only: - warning_msg = ( - "The parameter 'legacy_renum_only' is deprecated and will be removed." - ) - warnings.warn( - warning_msg, - ) if self.properties.directed and symmetrize: raise ValueError( @@ -269,8 +262,7 @@ def __from_edgelist( elist, source, destination, - store_transposed=False, - legacy_renum_only=legacy_renum_only, + store_transposed=False ) source = renumber_map.renumbered_src_col_name destination = renumber_map.renumbered_dst_col_name @@ -312,6 +304,8 @@ def __from_edgelist( # FIXME: if the user calls self.edgelist.edgelist_df after creating a # symmetric graph, return the symmetric edgelist? + # FIXME: For better memory footprint, avoid storing this edgelist and instead + # call decompress_to_edgelist to extract the edgelist from the graph self.edgelist = simpleGraphImpl.EdgeList( elist[source], elist[destination], value_col ) @@ -804,6 +798,59 @@ def get_two_hop_neighbors(self, start_vertices=None): return df + def decompress_to_edgelist( + self, + return_unrenumbered_edgelist: bool = True + ) -> cudf.DataFrame: + """ + Extract a the edgelist from a graph. + + Parameters + ---------- + return_unrenumbered_edgelist : bool (default=True) + Flag determining whether to return the original input edgelist + if 'True' or the renumbered one of 'False' and the edgelist was + renumbered. + + Returns + ------- + + df : cudf.DataFrame + GPU data frame containing all sources identifiers, + destination identifiers and if applicable edge weights, edge ids and + edge types + + Examples + -------- + >>> from cugraph.datasets import karate + >>> G = karate.get_graph(download=True) + >>> edgelist = G.decompress_to_edgelist() + + """ + + do_expensive_check = False + source, destination, weight, edge_ids, edge_type_ids = pylibcugraph_decompress_to_edgelist( + resource_handle=ResourceHandle(), + graph=self._plc_graph, + do_expensive_check=do_expensive_check + ) + + df = cudf.DataFrame() + df["src"] = source + df["dst"] = destination + if weight is not None: + df["weight"] = weight + if edge_ids is not None: + df["edge_ids"] = edge_ids + if edge_type_ids is not None: + df["edge_type_ids"] = edge_type_ids + + if self.properties.renumbered and return_unrenumbered_edgelist: + df, _ = self.renumber_map.unrenumber(df, "src", get_column_names=True) + df, _ = self.renumber_map.unrenumber(df, "dst", get_column_names=True) + + return df + def select_random_vertices( self, random_state: int = None, From f34070cbea11259131052bde1bac7e0e1bd66fdb Mon Sep 17 00:00:00 2001 From: jnke2016 Date: Tue, 19 Nov 2024 08:07:24 -0800 Subject: [PATCH 17/26] remove deprecated flag --- python/cugraph/cugraph/structure/number_map.py | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/python/cugraph/cugraph/structure/number_map.py b/python/cugraph/cugraph/structure/number_map.py index b0118fee960..771c7713d4f 100644 --- a/python/cugraph/cugraph/structure/number_map.py +++ b/python/cugraph/cugraph/structure/number_map.py @@ -466,8 +466,7 @@ def renumber_and_segment( src_col_names, dst_col_names, preserve_order=False, - store_transposed=False, - legacy_renum_only=False, + store_transposed=False ): """ Given an input dataframe with its column names, this function returns the @@ -475,11 +474,6 @@ def renumber_and_segment( to external vertex IDs. the parameter 'preserve_order' ensures that the order of the edges is preserved during renumbering. """ - if legacy_renum_only: - warning_msg = ( - "The parameter 'legacy_renum_only' is deprecated and will be removed." - ) - warnings.warn(warning_msg, DeprecationWarning) renumbered = False @@ -588,16 +582,14 @@ def renumber( src_col_names, dst_col_names, preserve_order=False, - store_transposed=False, - legacy_renum_only=False, + store_transposed=False ): return NumberMap.renumber_and_segment( df, src_col_names, dst_col_names, preserve_order, - store_transposed, - legacy_renum_only, + store_transposed )[0:2] def unrenumber(self, df, column_name, preserve_order=False, get_column_names=False): From 3b978d5e92e8ef665a916a8a2dbbcc28ab8954e7 Mon Sep 17 00:00:00 2001 From: jnke2016 Date: Tue, 19 Nov 2024 08:08:55 -0800 Subject: [PATCH 18/26] remove global test variables --- python/cugraph/cugraph/tests/structure/test_graph.py | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/python/cugraph/cugraph/tests/structure/test_graph.py b/python/cugraph/cugraph/tests/structure/test_graph.py index 9add5edb36e..12fe1cd5fda 100644 --- a/python/cugraph/cugraph/tests/structure/test_graph.py +++ b/python/cugraph/cugraph/tests/structure/test_graph.py @@ -46,14 +46,6 @@ def setup_function(): gc.collect() -# ============================================================================= -# Parameters -# ============================================================================= - - -IS_DIRECTED = [True, False] -RENUMBER = [True, False] - def compare_series(series_1, series_2): assert len(series_1) == len(series_2) @@ -190,8 +182,8 @@ def test_add_edge_list_to_adj_list(graph_file): @pytest.mark.sg @pytest.mark.parametrize("graph_file", utils.DATASETS) -@pytest.mark.parametrize("is_directed", IS_DIRECTED) -@pytest.mark.parametrize("renumber", RENUMBER) +@pytest.mark.parametrize("is_directed", [True, False]) +@pytest.mark.parametrize("renumber", [True, False]) def test_decompress_to_edgelist(graph_file, is_directed, renumber): input_df = utils.read_csv_file(graph_file) input_df = input_df.rename(columns={'0': 'src', '1': 'dst', '2': 'weight'}) From 48452414ce818e69281c20b15644d5b56e285312 Mon Sep 17 00:00:00 2001 From: jnke2016 Date: Tue, 19 Nov 2024 08:23:32 -0800 Subject: [PATCH 19/26] fix style --- cpp/include/cugraph_c/graph_functions.h | 11 ++-- cpp/src/c_api/decompress_to_edgelist.cpp | 64 +++++++++++-------- .../cugraph/structure/graph_classes.py | 8 +-- .../simpleDistributedGraph.py | 29 ++++----- .../graph_implementation/simpleGraph.py | 18 +++--- .../cugraph/cugraph/structure/number_map.py | 18 +----- .../cugraph/tests/structure/test_graph.py | 31 +++++---- .../cugraph/tests/structure/test_graph_mg.py | 32 ++++++---- .../_cugraph_c/graph_functions.pxd | 2 +- .../pylibcugraph/decompress_to_edgelist.pyx | 8 +-- 10 files changed, 114 insertions(+), 107 deletions(-) diff --git a/cpp/include/cugraph_c/graph_functions.h b/cpp/include/cugraph_c/graph_functions.h index 44fdeacea97..a86a256f217 100644 --- a/cpp/include/cugraph_c/graph_functions.h +++ b/cpp/include/cugraph_c/graph_functions.h @@ -336,12 +336,11 @@ cugraph_error_code_t cugraph_degrees(const cugraph_resource_handle_t* handle, * be populated if error code is not CUGRAPH_SUCCESS * @return error code */ -cugraph_error_code_t cugraph_decompress_to_edgelist( - const cugraph_resource_handle_t* handle, - cugraph_graph_t* graph, - bool_t do_expensive_check, - cugraph_induced_subgraph_result_t** result, - cugraph_error_t** error); +cugraph_error_code_t cugraph_decompress_to_edgelist(const cugraph_resource_handle_t* handle, + cugraph_graph_t* graph, + bool_t do_expensive_check, + cugraph_induced_subgraph_result_t** result, + cugraph_error_t** error); /** * @brief Get the vertex ids diff --git a/cpp/src/c_api/decompress_to_edgelist.cpp b/cpp/src/c_api/decompress_to_edgelist.cpp index c24c630ba6f..4a17324ec04 100644 --- a/cpp/src/c_api/decompress_to_edgelist.cpp +++ b/cpp/src/c_api/decompress_to_edgelist.cpp @@ -24,7 +24,7 @@ #include #include -#include // FIXME: mihgt remove the shuffle headers because they are unsued +#include #include #include @@ -71,47 +71,54 @@ struct decompress_to_edgelist_functor : public cugraph::c_api::abstract_functor // FIXME: Transpose_storage may have a bug, since if store_transposed is True it can reverse // the bool value of is_symmetric auto graph = - reinterpret_cast*>(graph_->graph_); + reinterpret_cast*>( + graph_->graph_); auto graph_view = graph->view(); - auto edge_weights = reinterpret_cast< - cugraph::edge_property_t, - weight_t>*>(graph_->edge_weights_); - - auto edge_ids = reinterpret_cast< - cugraph::edge_property_t, - edge_t>*>(graph_->edge_ids_); - - auto edge_types = reinterpret_cast< - cugraph::edge_property_t, - edge_type_type_t>*>(graph_->edge_types_); + auto edge_weights = reinterpret_cast, + weight_t>*>(graph_->edge_weights_); - auto number_map = reinterpret_cast*>(graph_->number_map_); + auto edge_ids = reinterpret_cast, + edge_t>*>(graph_->edge_ids_); + + auto edge_types = reinterpret_cast, + edge_type_type_t>*>(graph_->edge_types_); + auto number_map = reinterpret_cast*>(graph_->number_map_); auto [result_src, result_dst, result_wgt, result_edge_id, result_edge_type] = - cugraph::decompress_to_edgelist( + cugraph::decompress_to_edgelist( handle_, graph_view, (edge_weights != nullptr) ? std::make_optional(edge_weights->view()) : std::nullopt, (edge_ids != nullptr) ? std::make_optional(edge_ids->view()) : std::nullopt, (edge_types != nullptr) ? std::make_optional(edge_types->view()) : std::nullopt, (number_map != nullptr) ? std::make_optional>( - number_map->data(), number_map->size()) + number_map->data(), number_map->size()) : std::nullopt, do_expensive_check_); - result_ = new cugraph::c_api::cugraph_induced_subgraph_result_t{ new cugraph::c_api::cugraph_type_erased_device_array_t(result_src, graph_->vertex_type_), new cugraph::c_api::cugraph_type_erased_device_array_t(result_dst, graph_->vertex_type_), - result_wgt ? new cugraph::c_api::cugraph_type_erased_device_array_t(*result_wgt, graph_->weight_type_) - : NULL, - result_edge_id ? new cugraph::c_api::cugraph_type_erased_device_array_t(*result_edge_id, graph_->edge_type_) - : NULL, - result_edge_type ? new cugraph::c_api::cugraph_type_erased_device_array_t(*result_edge_type, graph_->edge_type_id_type_) - : NULL, + result_wgt ? new cugraph::c_api::cugraph_type_erased_device_array_t(*result_wgt, + graph_->weight_type_) + : NULL, + result_edge_id ? new cugraph::c_api::cugraph_type_erased_device_array_t(*result_edge_id, + graph_->edge_type_) + : NULL, + result_edge_type ? new cugraph::c_api::cugraph_type_erased_device_array_t( + *result_edge_type, graph_->edge_type_id_type_) + : NULL, NULL}; } } @@ -119,11 +126,12 @@ struct decompress_to_edgelist_functor : public cugraph::c_api::abstract_functor } // namespace -extern "C" cugraph_error_code_t cugraph_decompress_to_edgelist(const cugraph_resource_handle_t* handle, - cugraph_graph_t* graph, - bool_t do_expensive_check, - cugraph_induced_subgraph_result_t** result, - cugraph_error_t** error) +extern "C" cugraph_error_code_t cugraph_decompress_to_edgelist( + const cugraph_resource_handle_t* handle, + cugraph_graph_t* graph, + bool_t do_expensive_check, + cugraph_induced_subgraph_result_t** result, + cugraph_error_t** error) { decompress_to_edgelist_functor functor(handle, graph, do_expensive_check); diff --git a/python/cugraph/cugraph/structure/graph_classes.py b/python/cugraph/cugraph/structure/graph_classes.py index c8dc0a2b8fe..90f809fa6c1 100644 --- a/python/cugraph/cugraph/structure/graph_classes.py +++ b/python/cugraph/cugraph/structure/graph_classes.py @@ -296,7 +296,7 @@ def from_dask_cudf_edgelist( edge_id=None, edge_type=None, renumber=True, - store_transposed=False + store_transposed=False, ): """ Initializes the distributed graph from the dask_cudf.DataFrame @@ -360,7 +360,7 @@ def from_dask_cudf_edgelist( edge_id=edge_id, edge_type=edge_type, renumber=renumber, - store_transposed=store_transposed + store_transposed=store_transposed, ) # Move to Compat Module @@ -850,7 +850,7 @@ def from_cudf_edgelist( destination="destination", edge_attr=None, renumber=True, - store_transposed=False + store_transposed=False, ): """ Initialize a graph from the edge list. It is an error to call this @@ -918,7 +918,7 @@ def from_dask_cudf_edgelist( destination="destination", edge_attr=None, renumber=True, - store_transposed=False + store_transposed=False, ): """ Initializes the distributed graph from the dask_cudf.DataFrame diff --git a/python/cugraph/cugraph/structure/graph_implementation/simpleDistributedGraph.py b/python/cugraph/cugraph/structure/graph_implementation/simpleDistributedGraph.py index 7430df89f4c..e18b238923a 100644 --- a/python/cugraph/cugraph/structure/graph_implementation/simpleDistributedGraph.py +++ b/python/cugraph/cugraph/structure/graph_implementation/simpleDistributedGraph.py @@ -32,7 +32,7 @@ degrees as pylibcugraph_degrees, in_degrees as pylibcugraph_in_degrees, out_degrees as pylibcugraph_out_degrees, - decompress_to_edgelist as pylibcugraph_decompress_to_edgelist + decompress_to_edgelist as pylibcugraph_decompress_to_edgelist, ) from cugraph.structure.number_map import NumberMap @@ -334,9 +334,7 @@ def __from_edgelist( # the edgelist_df and not do any renumbering. # C++ renumbering is enabled by default for algorithms that # support it (but only called if renumbering is on) - self.compute_renumber_edge_list( - transposed=store_transposed - ) + self.compute_renumber_edge_list(transposed=store_transposed) if renumber is False: self.properties.renumbered = False @@ -981,8 +979,7 @@ def convert_to_cudf(cp_arrays): return ddf def decompress_to_edgelist( - self, - return_unrenumbered_edgelist: bool = True + self, return_unrenumbered_edgelist: bool = True ) -> dask_cudf.DataFrame: """ Extract a the edgelist from a graph. @@ -1011,19 +1008,19 @@ def _call_decompress_to_edgelist( sID: bytes, mg_graph_x, do_expensive_check: bool, - ) -> Tuple[cp.ndarray, cp.ndarray, cp.ndarray, cp.ndarray]: - return pylibcugraph_decompress_to_edgelist( - resource_handle=ResourceHandle(Comms.get_handle(sID).getHandle()), - graph=mg_graph_x, - do_expensive_check=do_expensive_check, - ) + ) -> Tuple[cp.ndarray, cp.ndarray, cp.ndarray, cp.ndarray]: + return pylibcugraph_decompress_to_edgelist( + resource_handle=ResourceHandle(Comms.get_handle(sID).getHandle()), + graph=mg_graph_x, + do_expensive_check=do_expensive_check, + ) result = [ client.submit( _call_decompress_to_edgelist, Comms.get_session_id(), self._plc_graph[w], - do_expensive_check + do_expensive_check, ) for w in Comms.get_workers() ] @@ -1044,7 +1041,9 @@ def convert_to_cudf(cp_arrays: cp.ndarray) -> cudf.DataFrame: return df - cudf_result = [client.submit(convert_to_cudf, cp_arrays) for cp_arrays in result] + cudf_result = [ + client.submit(convert_to_cudf, cp_arrays) for cp_arrays in result + ] wait(cudf_result) @@ -1335,7 +1334,7 @@ def compute_renumber_edge_list(self, transposed=False): self.input_df, self.source_columns, self.destination_columns, - store_transposed=transposed + store_transposed=transposed, ) self.edgelist = self.EdgeList(renumbered_ddf) diff --git a/python/cugraph/cugraph/structure/graph_implementation/simpleGraph.py b/python/cugraph/cugraph/structure/graph_implementation/simpleGraph.py index e3067312ccf..4523b7f13b8 100644 --- a/python/cugraph/cugraph/structure/graph_implementation/simpleGraph.py +++ b/python/cugraph/cugraph/structure/graph_implementation/simpleGraph.py @@ -259,10 +259,7 @@ def __from_edgelist( if renumber: # FIXME: Should SG do lazy evaluation like MG? elist, renumber_map = NumberMap.renumber( - elist, - source, - destination, - store_transposed=False + elist, source, destination, store_transposed=False ) source = renumber_map.renumbered_src_col_name destination = renumber_map.renumbered_dst_col_name @@ -799,8 +796,7 @@ def get_two_hop_neighbors(self, start_vertices=None): return df def decompress_to_edgelist( - self, - return_unrenumbered_edgelist: bool = True + self, return_unrenumbered_edgelist: bool = True ) -> cudf.DataFrame: """ Extract a the edgelist from a graph. @@ -829,10 +825,16 @@ def decompress_to_edgelist( """ do_expensive_check = False - source, destination, weight, edge_ids, edge_type_ids = pylibcugraph_decompress_to_edgelist( + ( + source, + destination, + weight, + edge_ids, + edge_type_ids, + ) = pylibcugraph_decompress_to_edgelist( resource_handle=ResourceHandle(), graph=self._plc_graph, - do_expensive_check=do_expensive_check + do_expensive_check=do_expensive_check, ) df = cudf.DataFrame() diff --git a/python/cugraph/cugraph/structure/number_map.py b/python/cugraph/cugraph/structure/number_map.py index 771c7713d4f..83dde0347d1 100644 --- a/python/cugraph/cugraph/structure/number_map.py +++ b/python/cugraph/cugraph/structure/number_map.py @@ -462,11 +462,7 @@ def from_internal_vertex_id( @staticmethod def renumber_and_segment( - df, - src_col_names, - dst_col_names, - preserve_order=False, - store_transposed=False + df, src_col_names, dst_col_names, preserve_order=False, store_transposed=False ): """ Given an input dataframe with its column names, this function returns the @@ -578,18 +574,10 @@ def renumber_and_segment( @staticmethod def renumber( - df, - src_col_names, - dst_col_names, - preserve_order=False, - store_transposed=False + df, src_col_names, dst_col_names, preserve_order=False, store_transposed=False ): return NumberMap.renumber_and_segment( - df, - src_col_names, - dst_col_names, - preserve_order, - store_transposed + df, src_col_names, dst_col_names, preserve_order, store_transposed )[0:2] def unrenumber(self, df, column_name, preserve_order=False, get_column_names=False): diff --git a/python/cugraph/cugraph/tests/structure/test_graph.py b/python/cugraph/cugraph/tests/structure/test_graph.py index 12fe1cd5fda..6fcfef726b1 100644 --- a/python/cugraph/cugraph/tests/structure/test_graph.py +++ b/python/cugraph/cugraph/tests/structure/test_graph.py @@ -46,7 +46,6 @@ def setup_function(): gc.collect() - def compare_series(series_1, series_2): assert len(series_1) == len(series_2) df = cudf.DataFrame({"series_1": series_1, "series_2": series_2}) @@ -186,8 +185,8 @@ def test_add_edge_list_to_adj_list(graph_file): @pytest.mark.parametrize("renumber", [True, False]) def test_decompress_to_edgelist(graph_file, is_directed, renumber): input_df = utils.read_csv_file(graph_file) - input_df = input_df.rename(columns={'0': 'src', '1': 'dst', '2': 'weight'}) - + input_df = input_df.rename(columns={"0": "src", "1": "dst", "2": "weight"}) + G = cugraph.Graph(directed=is_directed) input_df_ = cudf.DataFrame() if renumber: @@ -205,21 +204,27 @@ def test_decompress_to_edgelist(graph_file, is_directed, renumber): destination = "dst" G.from_cudf_edgelist( - input_df, source=source, destination=destination, - weight="weight", renumber=True) - - extracted_df = G.decompress_to_edgelist( - return_unrenumbered_edgelist = True + input_df, source=source, destination=destination, weight="weight", renumber=True ) - + + extracted_df = G.decompress_to_edgelist(return_unrenumbered_edgelist=True) + if renumber: extracted_df = extracted_df.rename( - columns={'0_src': 'src_0', '1_src': 'src_1', '0_dst': 'dst_0', '1_dst': 'dst_1'}) + columns={ + "0_src": "src_0", + "1_src": "src_1", + "0_dst": "dst_0", + "1_dst": "dst_1", + } + ) extracted_df = extracted_df.sort_values( - ["src_0", "src_1", "dst_0", "dst_1"]).reset_index(drop=True) + ["src_0", "src_1", "dst_0", "dst_1"] + ).reset_index(drop=True) input_df = input_df.sort_values( - ["src_0", "src_1", "dst_0", "dst_1"]).reset_index(drop=True) - else: + ["src_0", "src_1", "dst_0", "dst_1"] + ).reset_index(drop=True) + else: extracted_df = extracted_df.sort_values(["src", "dst"]).reset_index(drop=True) input_df = input_df.sort_values(["src", "dst"]).reset_index(drop=True) diff --git a/python/cugraph/cugraph/tests/structure/test_graph_mg.py b/python/cugraph/cugraph/tests/structure/test_graph_mg.py index 3a62eec913b..e5eeb0f653b 100644 --- a/python/cugraph/cugraph/tests/structure/test_graph_mg.py +++ b/python/cugraph/cugraph/tests/structure/test_graph_mg.py @@ -427,8 +427,8 @@ def test_graph_creation_properties(dask_client, graph_file, directed, renumber): @pytest.mark.parametrize("graph_file", datasets) def test_decompress_to_edgelist(dask_client, graph_file, directed, renumber): input_df = utils.read_csv_file(graph_file) - input_df = input_df.rename(columns={'0': 'src', '1': 'dst', '2': 'weight'}) - + input_df = input_df.rename(columns={"0": "src", "1": "dst", "2": "weight"}) + G = cugraph.Graph(directed=directed) input_df_ = cudf.DataFrame() if renumber: @@ -450,21 +450,27 @@ def test_decompress_to_edgelist(dask_client, graph_file, directed, renumber): G = cugraph.Graph(directed=True) G.from_dask_cudf_edgelist( - input_ddf, - source=source, - destination=destination, - weight="weight" + input_ddf, source=source, destination=destination, weight="weight" ) - extracted_df = G.decompress_to_edgelist( - return_unrenumbered_edgelist = True - ).compute().reset_index(drop=True) + extracted_df = ( + G.decompress_to_edgelist(return_unrenumbered_edgelist=True) + .compute() + .reset_index(drop=True) + ) if renumber: extracted_df = extracted_df.rename( - columns={'0_src': 'src_0', '1_src': 'src_1', - '0_dst': 'dst_0', '1_dst': 'dst_1'}) + columns={ + "0_src": "src_0", + "1_src": "src_1", + "0_dst": "dst_0", + "1_dst": "dst_1", + } + ) extracted_df = extracted_df.sort_values( - ["src_0", "src_1", "dst_0", "dst_1"]).reset_index(drop=True) + ["src_0", "src_1", "dst_0", "dst_1"] + ).reset_index(drop=True) input_df = input_df.sort_values( - ["src_0", "src_1", "dst_0", "dst_1"]).reset_index(drop=True) + ["src_0", "src_1", "dst_0", "dst_1"] + ).reset_index(drop=True) diff --git a/python/pylibcugraph/pylibcugraph/_cugraph_c/graph_functions.pxd b/python/pylibcugraph/pylibcugraph/_cugraph_c/graph_functions.pxd index 1e8b9da12d2..c8e271d8e00 100644 --- a/python/pylibcugraph/pylibcugraph/_cugraph_c/graph_functions.pxd +++ b/python/pylibcugraph/pylibcugraph/_cugraph_c/graph_functions.pxd @@ -250,7 +250,7 @@ cdef extern from "cugraph_c/graph_functions.h": cugraph_degrees_result_free( cugraph_degrees_result_t* degrees_result ) - + ########################################################################### # decompress to edgelist cdef cugraph_error_code_t \ diff --git a/python/pylibcugraph/pylibcugraph/decompress_to_edgelist.pyx b/python/pylibcugraph/pylibcugraph/decompress_to_edgelist.pyx index 709a43d93bf..0941fd97128 100644 --- a/python/pylibcugraph/pylibcugraph/decompress_to_edgelist.pyx +++ b/python/pylibcugraph/pylibcugraph/decompress_to_edgelist.pyx @@ -126,13 +126,13 @@ def decompress_to_edgelist(ResourceHandle resource_handle, cugraph_induced_subgraph_get_destinations(result_ptr) cdef cugraph_type_erased_device_array_view_t* edge_weights_ptr = \ cugraph_induced_subgraph_get_edge_weights(result_ptr) - + cdef cugraph_type_erased_device_array_view_t* edge_ids_ptr = \ cugraph_induced_subgraph_get_edge_ids(result_ptr) cdef cugraph_type_erased_device_array_view_t* edge_type_ids_ptr = \ cugraph_induced_subgraph_get_edge_type_ids(result_ptr) - - + + """ cdef cugraph_type_erased_device_array_view_t* subgraph_offsets_ptr = \ cugraph_induced_subgraph_get_subgraph_offsets(result_ptr) @@ -156,7 +156,7 @@ def decompress_to_edgelist(ResourceHandle resource_handle, if edge_type_ids_ptr != NULL: cupy_edge_type_ids = copy_to_cupy_array( c_resource_handle_ptr, edge_type_ids_ptr) - + """ cupy_subgraph_offsets = copy_to_cupy_array( c_resource_handle_ptr, subgraph_offsets_ptr) From 326d76aabf4180de0c7e1ceed32dedce24aeea5e Mon Sep 17 00:00:00 2001 From: jnke2016 Date: Tue, 19 Nov 2024 09:33:18 -0800 Subject: [PATCH 20/26] fix style --- .../graph_implementation/simpleDistributedGraph.py | 8 ++++---- python/cugraph/cugraph/structure/number_map.py | 1 - 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/python/cugraph/cugraph/structure/graph_implementation/simpleDistributedGraph.py b/python/cugraph/cugraph/structure/graph_implementation/simpleDistributedGraph.py index e18b238923a..ced72a6bbe2 100644 --- a/python/cugraph/cugraph/structure/graph_implementation/simpleDistributedGraph.py +++ b/python/cugraph/cugraph/structure/graph_implementation/simpleDistributedGraph.py @@ -986,10 +986,10 @@ def decompress_to_edgelist( Parameters ---------- - return_unrenumbered_edgelist : bool (default=True) - Flag determining whether to return the original input edgelist - if 'True' or the renumbered one of 'False' and the edgelist was - renumbered. + return_unrenumbered_edgelist : bool (default=True) + Flag determining whether to return the original + input edgelist if 'True' or the renumbered one + of 'False' and the edgelist was renumbered. Returns ------- diff --git a/python/cugraph/cugraph/structure/number_map.py b/python/cugraph/cugraph/structure/number_map.py index 83dde0347d1..39738daff36 100644 --- a/python/cugraph/cugraph/structure/number_map.py +++ b/python/cugraph/cugraph/structure/number_map.py @@ -18,7 +18,6 @@ import dask_cudf import numpy as np import cudf -import warnings class NumberMap: From 767af09d52c9087392d5e322caf1b5fb427ad624 Mon Sep 17 00:00:00 2001 From: jnke2016 Date: Tue, 19 Nov 2024 11:17:47 -0800 Subject: [PATCH 21/26] add missing return statement --- cpp/src/c_api/decompress_to_edgelist.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/cpp/src/c_api/decompress_to_edgelist.cpp b/cpp/src/c_api/decompress_to_edgelist.cpp index 4a17324ec04..49423100696 100644 --- a/cpp/src/c_api/decompress_to_edgelist.cpp +++ b/cpp/src/c_api/decompress_to_edgelist.cpp @@ -65,11 +65,9 @@ struct decompress_to_edgelist_functor : public cugraph::c_api::abstract_functor error_code_ = cugraph::c_api:: transpose_storage( handle_, graph_, error_.get()); - if (error_code_ != CUGRAPH_SUCCESS) - ; + if (error_code_ != CUGRAPH_SUCCESS) return; } - // FIXME: Transpose_storage may have a bug, since if store_transposed is True it can reverse - // the bool value of is_symmetric + auto graph = reinterpret_cast*>( graph_->graph_); From 335729c46aaf3584cbe7f9249f5c8d5fbc9ab7c8 Mon Sep 17 00:00:00 2001 From: jnke2016 Date: Wed, 20 Nov 2024 06:35:41 -0800 Subject: [PATCH 22/26] deprecate old API --- cpp/include/cugraph_c/graph_functions.h | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/cpp/include/cugraph_c/graph_functions.h b/cpp/include/cugraph_c/graph_functions.h index a86a256f217..77f4be71a2c 100644 --- a/cpp/include/cugraph_c/graph_functions.h +++ b/cpp/include/cugraph_c/graph_functions.h @@ -104,6 +104,8 @@ cugraph_error_code_t cugraph_two_hop_neighbors( /** * @brief Opaque induced subgraph type + * + * @deprecated This API will be deleted, use cugraph_edgelist_t */ typedef struct { int32_t align_; @@ -112,6 +114,8 @@ typedef struct { /** * @brief Get the source vertex ids * + * @deprecated This API will be deleted, use cugraph_edgelist_get_sources + * * @param [in] induced_subgraph Opaque pointer to induced subgraph * @return type erased array view of source vertex ids */ @@ -121,6 +125,8 @@ cugraph_type_erased_device_array_view_t* cugraph_induced_subgraph_get_sources( /** * @brief Get the destination vertex ids * + * @deprecated This API will be deleted, use cugraph_edgelist_get_destinations + * * @param [in] induced_subgraph Opaque pointer to induced subgraph * @return type erased array view of destination vertex ids */ @@ -130,6 +136,8 @@ cugraph_type_erased_device_array_view_t* cugraph_induced_subgraph_get_destinatio /** * @brief Get the edge weights * + * @deprecated This API will be deleted, use cugraph_edgelist_get_edge_weights + * * @param [in] induced_subgraph Opaque pointer to induced subgraph * @return type erased array view of edge weights */ @@ -139,6 +147,8 @@ cugraph_type_erased_device_array_view_t* cugraph_induced_subgraph_get_edge_weigh /** * @brief Get the edge ids * + * @deprecated This API will be deleted, use cugraph_edgelist_get_edge_ids + * * @param [in] induced_subgraph Opaque pointer to induced subgraph * @return type erased array view of edge ids */ @@ -148,6 +158,7 @@ cugraph_type_erased_device_array_view_t* cugraph_induced_subgraph_get_edge_ids( /** * @brief Get the edge types * + * @deprecated This API will be deleted, use cugraph_edgelist_get_edge_type_ids * @param [in] induced_subgraph Opaque pointer to induced subgraph * @return type erased array view of edge types */ @@ -157,6 +168,8 @@ cugraph_type_erased_device_array_view_t* cugraph_induced_subgraph_get_edge_type_ /** * @brief Get the subgraph offsets * + * @deprecated This API will be deleted, use cugraph_edgelist_get_edge_offsets + * * @param [in] induced_subgraph Opaque pointer to induced subgraph * @return type erased array view of subgraph identifiers */ @@ -166,6 +179,8 @@ cugraph_type_erased_device_array_view_t* cugraph_induced_subgraph_get_subgraph_o /** * @brief Free induced subgraph * + * @deprecated This API will be deleted, use cugraph_edgelist_free + * * @param [in] induced subgraph Opaque pointer to induced subgraph */ void cugraph_induced_subgraph_result_free(cugraph_induced_subgraph_result_t* induced_subgraph); From abb695eb7386ada0273415ec93e5eea3b501174e Mon Sep 17 00:00:00 2001 From: jnke2016 Date: Wed, 20 Nov 2024 07:21:36 -0800 Subject: [PATCH 23/26] add new API to retrieve the edgelist from a graph --- cpp/CMakeLists.txt | 1 + cpp/include/cugraph_c/graph_functions.h | 70 +++++++++++++++++++ cpp/src/c_api/edgelist.cpp | 91 +++++++++++++++++++++++++ cpp/src/c_api/edgelist.hpp | 34 +++++++++ 4 files changed, 196 insertions(+) create mode 100644 cpp/src/c_api/edgelist.cpp create mode 100644 cpp/src/c_api/edgelist.hpp diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt index bd0b4b71a28..65772b4f5dd 100644 --- a/cpp/CMakeLists.txt +++ b/cpp/CMakeLists.txt @@ -539,6 +539,7 @@ add_library(cugraph_c src/c_api/strongly_connected_components.cpp src/c_api/allgather.cpp src/c_api/decompress_to_edgelist.cpp + src/c_api/edgelist.cpp ) add_library(cugraph::cugraph_c ALIAS cugraph_c) diff --git a/cpp/include/cugraph_c/graph_functions.h b/cpp/include/cugraph_c/graph_functions.h index 77f4be71a2c..a3e468a2c51 100644 --- a/cpp/include/cugraph_c/graph_functions.h +++ b/cpp/include/cugraph_c/graph_functions.h @@ -159,6 +159,7 @@ cugraph_type_erased_device_array_view_t* cugraph_induced_subgraph_get_edge_ids( * @brief Get the edge types * * @deprecated This API will be deleted, use cugraph_edgelist_get_edge_type_ids + * * @param [in] induced_subgraph Opaque pointer to induced subgraph * @return type erased array view of edge types */ @@ -394,6 +395,75 @@ cugraph_type_erased_device_array_view_t* cugraph_degrees_result_get_out_degrees( */ void cugraph_degrees_result_free(cugraph_degrees_result_t* degrees_result); +/** + * @brief Opaque edgelist type + * + */ +typedef struct { + int32_t align_; +} cugraph_edgelist_t; + +/** + * @brief Get the source vertex ids + * + * @param [in] edgelist Opaque pointer to edgelist + * @return type erased array view of source vertex ids + */ +cugraph_type_erased_device_array_view_t* cugraph_edgelist_get_sources( + cugraph_edgelist_t* edgelist); + +/** + * @brief Get the destination vertex ids + * + * @param [in] edgelist Opaque pointer to edgelist + * @return type erased array view of destination vertex ids + */ +cugraph_type_erased_device_array_view_t* cugraph_edgelist_get_destinations( + cugraph_edgelist_t* edgelist); + +/** + * @brief Get the edge weights + * + * @param [in] edgelist Opaque pointer to edgelist + * @return type erased array view of edge weights + */ +cugraph_type_erased_device_array_view_t* cugraph_edgelist_get_edge_weights( + cugraph_edgelist_t* edgelist); + +/** + * @brief Get the edge ids + * + * @param [in] edgelist Opaque pointer to edgelist + * @return type erased array view of edge ids + */ +cugraph_type_erased_device_array_view_t* cugraph_edgelist_get_edge_ids( + cugraph_edgelist_t* edgelist); + +/** + * @brief Get the edge types + * + * @param [in] edgelist Opaque pointer to edgelist + * @return type erased array view of edge types + */ +cugraph_type_erased_device_array_view_t* cugraph_edgelist_get_edge_type_ids( + cugraph_edgelist_t* edgelist); + +/** + * @brief Get the edge offsets + * + * @param [in] edgelist Opaque pointer to edgelist + * @return type erased array view of subgraph identifiers + */ +cugraph_type_erased_device_array_view_t* cugraph_edgelist_get_edge_offsets( + cugraph_edgelist_t* edgelist); + +/** + * @brief Free edgelist + * + * @param [in] edgelist Opaque pointer to edgelist + */ +void cugraph_edgelist_free(cugraph_edgelist_t* edgelist); + #ifdef __cplusplus } #endif diff --git a/cpp/src/c_api/edgelist.cpp b/cpp/src/c_api/edgelist.cpp new file mode 100644 index 00000000000..47cfabdb9fc --- /dev/null +++ b/cpp/src/c_api/edgelist.cpp @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2022-2024, 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_api/edgelist.hpp" + +#include + +extern "C" cugraph_type_erased_device_array_view_t* cugraph_edgelist_get_sources( + cugraph_edgelist_t* edgelist) +{ + auto internal_pointer = + reinterpret_cast(edgelist); + return reinterpret_cast(internal_pointer->src_->view()); +} + +extern "C" cugraph_type_erased_device_array_view_t* cugraph_edgelist_get_destinations( + cugraph_edgelist_t* edgelist) +{ + auto internal_pointer = + reinterpret_cast(edgelist); + return reinterpret_cast(internal_pointer->dst_->view()); +} + +extern "C" cugraph_type_erased_device_array_view_t* cugraph_edgelist_get_edge_weights( + cugraph_edgelist_t* edgelist) +{ + auto internal_pointer = + reinterpret_cast(edgelist); + return (internal_pointer->wgt_ == nullptr) + ? NULL + : reinterpret_cast( + internal_pointer->wgt_->view()); +} + +extern "C" cugraph_type_erased_device_array_view_t* cugraph_edgelist_get_edge_ids( + cugraph_edgelist_t* edgelist) +{ + auto internal_pointer = + reinterpret_cast(edgelist); + return (internal_pointer->edge_ids_ == nullptr) + ? NULL + : reinterpret_cast( + internal_pointer->edge_ids_->view()); +} + +extern "C" cugraph_type_erased_device_array_view_t* cugraph_edgelist_get_edge_type_ids( + cugraph_edgelist_t* edgelist) +{ + auto internal_pointer = + reinterpret_cast(edgelist); + return (internal_pointer->edge_type_ids_ == nullptr) + ? NULL + : reinterpret_cast( + internal_pointer->edge_type_ids_->view()); +} + +extern "C" cugraph_type_erased_device_array_view_t* cugraph_edgelist_get_edge_offsets( + cugraph_edgelist_t* edgelist) +{ + auto internal_pointer = + reinterpret_cast(edgelist); + return reinterpret_cast( + internal_pointer->subgraph_offsets_->view()); +} + +extern "C" void cugraph_edgelist_free( + cugraph_edgelist_t* edgelist) +{ + auto internal_pointer = + reinterpret_cast(edgelist); + delete internal_pointer->src_; + delete internal_pointer->dst_; + delete internal_pointer->wgt_; + delete internal_pointer->edge_ids_; + delete internal_pointer->edge_type_ids_; + delete internal_pointer->subgraph_offsets_; + delete internal_pointer; +} diff --git a/cpp/src/c_api/edgelist.hpp b/cpp/src/c_api/edgelist.hpp new file mode 100644 index 00000000000..bc0f2d337f1 --- /dev/null +++ b/cpp/src/c_api/edgelist.hpp @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2023-2024, 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 "c_api/array.hpp" + +namespace cugraph { +namespace c_api { + +struct cugraph_edgelist_t { + cugraph_type_erased_device_array_t* src_{}; + cugraph_type_erased_device_array_t* dst_{}; + cugraph_type_erased_device_array_t* wgt_{}; + cugraph_type_erased_device_array_t* edge_ids_{}; + cugraph_type_erased_device_array_t* edge_type_ids_{}; + cugraph_type_erased_device_array_t* subgraph_offsets_{}; +}; + +} // namespace c_api +} // namespace cugraph From b84bdd8a754162bc3cf2e4d1b532ed1bcd2a919c Mon Sep 17 00:00:00 2001 From: jnke2016 Date: Wed, 20 Nov 2024 07:50:36 -0800 Subject: [PATCH 24/26] re-order function declaration and fix typo --- cpp/include/cugraph_c/graph_functions.h | 36 ++++++++++++------------ cpp/src/c_api/decompress_to_edgelist.cpp | 8 +++--- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/cpp/include/cugraph_c/graph_functions.h b/cpp/include/cugraph_c/graph_functions.h index a3e468a2c51..5140f4068c6 100644 --- a/cpp/include/cugraph_c/graph_functions.h +++ b/cpp/include/cugraph_c/graph_functions.h @@ -340,24 +340,6 @@ cugraph_error_code_t cugraph_degrees(const cugraph_resource_handle_t* handle, cugraph_degrees_result_t** result, cugraph_error_t** error); -/** - * @brief Construct the edge list from the graph view object. - * - * @param [in] handle Handle for accessing resources - * @param [in] graph Graph to operate on - * @param [in] do_expensive_check A flag to run expensive checks for input arguments (if set to - * true) - * @param [out] result Opaque pointer to induced subgraph result - * @param [out] error Pointer to an error object storing details of any error. Will - * be populated if error code is not CUGRAPH_SUCCESS - * @return error code - */ -cugraph_error_code_t cugraph_decompress_to_edgelist(const cugraph_resource_handle_t* handle, - cugraph_graph_t* graph, - bool_t do_expensive_check, - cugraph_induced_subgraph_result_t** result, - cugraph_error_t** error); - /** * @brief Get the vertex ids * @@ -464,6 +446,24 @@ cugraph_type_erased_device_array_view_t* cugraph_edgelist_get_edge_offsets( */ void cugraph_edgelist_free(cugraph_edgelist_t* edgelist); +/** + * @brief Construct the edge list from the graph view object. + * + * @param [in] handle Handle for accessing resources + * @param [in] graph Graph to operate on + * @param [in] do_expensive_check A flag to run expensive checks for input arguments (if set to + * true) + * @param [out] result Opaque pointer to edgelist + * @param [out] error Pointer to an error object storing details of any error. Will + * be populated if error code is not CUGRAPH_SUCCESS + * @return error code + */ +cugraph_error_code_t cugraph_decompress_to_edgelist(const cugraph_resource_handle_t* handle, + cugraph_graph_t* graph, + bool_t do_expensive_check, + cugraph_edgelist_t** result, + cugraph_error_t** error); + #ifdef __cplusplus } #endif diff --git a/cpp/src/c_api/decompress_to_edgelist.cpp b/cpp/src/c_api/decompress_to_edgelist.cpp index 49423100696..2fa823c3242 100644 --- a/cpp/src/c_api/decompress_to_edgelist.cpp +++ b/cpp/src/c_api/decompress_to_edgelist.cpp @@ -17,7 +17,7 @@ #include "c_api/abstract_functor.hpp" #include "c_api/core_result.hpp" #include "c_api/graph.hpp" -#include "c_api/induced_subgraph_result.hpp" +#include "c_api/edgelist.hpp" #include "c_api/resource_handle.hpp" #include "c_api/utils.hpp" @@ -38,7 +38,7 @@ struct decompress_to_edgelist_functor : public cugraph::c_api::abstract_functor cugraph::c_api::cugraph_core_result_t const* core_result_{}; bool do_expensive_check_{}; - cugraph::c_api::cugraph_induced_subgraph_result_t* result_{}; + cugraph::c_api::cugraph_edgelist_t* result_{}; decompress_to_edgelist_functor(cugraph_resource_handle_t const* handle, cugraph_graph_t* graph, @@ -105,7 +105,7 @@ struct decompress_to_edgelist_functor : public cugraph::c_api::abstract_functor : std::nullopt, do_expensive_check_); - result_ = new cugraph::c_api::cugraph_induced_subgraph_result_t{ + result_ = new cugraph::c_api::cugraph_edgelist_t{ new cugraph::c_api::cugraph_type_erased_device_array_t(result_src, graph_->vertex_type_), new cugraph::c_api::cugraph_type_erased_device_array_t(result_dst, graph_->vertex_type_), result_wgt ? new cugraph::c_api::cugraph_type_erased_device_array_t(*result_wgt, @@ -128,7 +128,7 @@ extern "C" cugraph_error_code_t cugraph_decompress_to_edgelist( const cugraph_resource_handle_t* handle, cugraph_graph_t* graph, bool_t do_expensive_check, - cugraph_induced_subgraph_result_t** result, + cugraph_edgelist_t** result, cugraph_error_t** error) { decompress_to_edgelist_functor functor(handle, graph, do_expensive_check); From 4145cc926200fdf8de64f3b1813db634899685dc Mon Sep 17 00:00:00 2001 From: jnke2016 Date: Wed, 20 Nov 2024 07:51:58 -0800 Subject: [PATCH 25/26] add mew API to extract edgelist and deprecate old API --- .../_cugraph_c/graph_functions.pxd | 56 ++++++++++++++++--- .../pylibcugraph/decompress_to_edgelist.pyx | 32 +++++------ 2 files changed, 63 insertions(+), 25 deletions(-) diff --git a/python/pylibcugraph/pylibcugraph/_cugraph_c/graph_functions.pxd b/python/pylibcugraph/pylibcugraph/_cugraph_c/graph_functions.pxd index c8e271d8e00..b27a7230a13 100644 --- a/python/pylibcugraph/pylibcugraph/_cugraph_c/graph_functions.pxd +++ b/python/pylibcugraph/pylibcugraph/_cugraph_c/graph_functions.pxd @@ -122,41 +122,41 @@ cdef extern from "cugraph_c/graph_functions.h": ########################################################################### # induced_subgraph - ctypedef struct cugraph_induced_subgraph_result_t: + ctypedef struct cugraph_induced_subgraph_result_t: # Deprecated pass cdef cugraph_type_erased_device_array_view_t* \ - cugraph_induced_subgraph_get_sources( + cugraph_induced_subgraph_get_sources( # Deprecated cugraph_induced_subgraph_result_t* induced_subgraph ) cdef cugraph_type_erased_device_array_view_t* \ - cugraph_induced_subgraph_get_destinations( + cugraph_induced_subgraph_get_destinations( # Deprecated cugraph_induced_subgraph_result_t* induced_subgraph ) cdef cugraph_type_erased_device_array_view_t* \ - cugraph_induced_subgraph_get_edge_weights( + cugraph_induced_subgraph_get_edge_weights( # Deprecated cugraph_induced_subgraph_result_t* induced_subgraph ) cdef cugraph_type_erased_device_array_view_t* \ - cugraph_induced_subgraph_get_edge_ids( + cugraph_induced_subgraph_get_edge_ids( # Deprecated cugraph_induced_subgraph_result_t* induced_subgraph ) cdef cugraph_type_erased_device_array_view_t* \ - cugraph_induced_subgraph_get_edge_type_ids( + cugraph_induced_subgraph_get_edge_type_ids( # Deprecated cugraph_induced_subgraph_result_t* induced_subgraph ) cdef cugraph_type_erased_device_array_view_t* \ - cugraph_induced_subgraph_get_subgraph_offsets( + cugraph_induced_subgraph_get_subgraph_offsets( # Deprecated cugraph_induced_subgraph_result_t* induced_subgraph ) cdef void \ - cugraph_induced_subgraph_result_free( + cugraph_induced_subgraph_result_free( # Deprecated cugraph_induced_subgraph_result_t* induced_subgraph ) @@ -253,11 +253,49 @@ cdef extern from "cugraph_c/graph_functions.h": ########################################################################### # decompress to edgelist + ctypedef struct cugraph_edgelist_t: + pass + + cdef cugraph_type_erased_device_array_view_t* \ + cugraph_edgelist_get_sources( + cugraph_edgelist_t* edgelist + ) + + cdef cugraph_type_erased_device_array_view_t* \ + cugraph_edgelist_get_destinations( + cugraph_edgelist_t* edgelist + ) + + cdef cugraph_type_erased_device_array_view_t* \ + cugraph_edgelist_get_edge_weights( + cugraph_edgelist_t* edgelist + ) + + cdef cugraph_type_erased_device_array_view_t* \ + cugraph_edgelist_get_edge_ids( + cugraph_edgelist_t* edgelist + ) + + cdef cugraph_type_erased_device_array_view_t* \ + cugraph_edgelist_get_edge_type_ids( + cugraph_edgelist_t* edgelist + ) + + cdef cugraph_type_erased_device_array_view_t* \ + cugraph_edgelist_get_edge_offsets( + cugraph_edgelist_t* edgelist + ) + + cdef void \ + cugraph_edgelist_free( + cugraph_edgelist_t* edgelist + ) + cdef cugraph_error_code_t \ cugraph_decompress_to_edgelist( const cugraph_resource_handle_t* handle, cugraph_graph_t* graph, bool_t do_expensive_check, - cugraph_induced_subgraph_result_t** result, + cugraph_edgelist_t** result, cugraph_error_t** error ) diff --git a/python/pylibcugraph/pylibcugraph/decompress_to_edgelist.pyx b/python/pylibcugraph/pylibcugraph/decompress_to_edgelist.pyx index 0941fd97128..58c29940aba 100644 --- a/python/pylibcugraph/pylibcugraph/decompress_to_edgelist.pyx +++ b/python/pylibcugraph/pylibcugraph/decompress_to_edgelist.pyx @@ -32,15 +32,15 @@ from pylibcugraph._cugraph_c.graph cimport ( cugraph_graph_t, ) from pylibcugraph._cugraph_c.graph_functions cimport ( - cugraph_induced_subgraph_result_t, + cugraph_edgelist_t, cugraph_decompress_to_edgelist, - cugraph_induced_subgraph_get_sources, - cugraph_induced_subgraph_get_destinations, - cugraph_induced_subgraph_get_edge_weights, - cugraph_induced_subgraph_get_edge_ids, - cugraph_induced_subgraph_get_edge_type_ids, - cugraph_induced_subgraph_get_subgraph_offsets, - cugraph_induced_subgraph_result_free, + cugraph_edgelist_get_sources, + cugraph_edgelist_get_destinations, + cugraph_edgelist_get_edge_weights, + cugraph_edgelist_get_edge_ids, + cugraph_edgelist_get_edge_type_ids, + cugraph_edgelist_get_edge_offsets, + cugraph_edgelist_free, ) from pylibcugraph.resource_handle cimport ( @@ -107,7 +107,7 @@ def decompress_to_edgelist(ResourceHandle resource_handle, cdef cugraph_resource_handle_t* c_resource_handle_ptr = \ resource_handle.c_resource_handle_ptr cdef cugraph_graph_t* c_graph_ptr = graph.c_graph_ptr - cdef cugraph_induced_subgraph_result_t* result_ptr + cdef cugraph_edgelist_t* result_ptr cdef cugraph_error_code_t error_code cdef cugraph_error_t* error_ptr @@ -121,21 +121,21 @@ def decompress_to_edgelist(ResourceHandle resource_handle, # Extract individual device array pointers from result and copy to cupy # arrays for returning. cdef cugraph_type_erased_device_array_view_t* sources_ptr = \ - cugraph_induced_subgraph_get_sources(result_ptr) + cugraph_edgelist_get_sources(result_ptr) cdef cugraph_type_erased_device_array_view_t* destinations_ptr = \ - cugraph_induced_subgraph_get_destinations(result_ptr) + cugraph_edgelist_get_destinations(result_ptr) cdef cugraph_type_erased_device_array_view_t* edge_weights_ptr = \ - cugraph_induced_subgraph_get_edge_weights(result_ptr) + cugraph_edgelist_get_edge_weights(result_ptr) cdef cugraph_type_erased_device_array_view_t* edge_ids_ptr = \ - cugraph_induced_subgraph_get_edge_ids(result_ptr) + cugraph_edgelist_get_edge_ids(result_ptr) cdef cugraph_type_erased_device_array_view_t* edge_type_ids_ptr = \ - cugraph_induced_subgraph_get_edge_type_ids(result_ptr) + cugraph_edgelist_get_edge_type_ids(result_ptr) """ cdef cugraph_type_erased_device_array_view_t* subgraph_offsets_ptr = \ - cugraph_induced_subgraph_get_subgraph_offsets(result_ptr) + cugraph_edgelist_get_edge_offsets(result_ptr) """ # FIXME: Get ownership of the result data instead of performing a copy @@ -163,7 +163,7 @@ def decompress_to_edgelist(ResourceHandle resource_handle, """ # Free pointer - cugraph_induced_subgraph_result_free(result_ptr) + cugraph_edgelist_free(result_ptr) return (cupy_sources, cupy_destinations, cupy_edge_weights, cupy_edge_ids, cupy_edge_type_ids) From 2b47fe3f7764d8888722e119f188be85b9902e4b Mon Sep 17 00:00:00 2001 From: jnke2016 Date: Wed, 20 Nov 2024 08:02:35 -0800 Subject: [PATCH 26/26] fix style --- cpp/include/cugraph_c/graph_functions.h | 33 ++++++++++++------------ cpp/src/c_api/decompress_to_edgelist.cpp | 2 +- cpp/src/c_api/edgelist.cpp | 24 ++++++----------- 3 files changed, 25 insertions(+), 34 deletions(-) diff --git a/cpp/include/cugraph_c/graph_functions.h b/cpp/include/cugraph_c/graph_functions.h index 5140f4068c6..964b2f2c8d6 100644 --- a/cpp/include/cugraph_c/graph_functions.h +++ b/cpp/include/cugraph_c/graph_functions.h @@ -104,7 +104,7 @@ cugraph_error_code_t cugraph_two_hop_neighbors( /** * @brief Opaque induced subgraph type - * + * * @deprecated This API will be deleted, use cugraph_edgelist_t */ typedef struct { @@ -115,7 +115,7 @@ typedef struct { * @brief Get the source vertex ids * * @deprecated This API will be deleted, use cugraph_edgelist_get_sources - * + * * @param [in] induced_subgraph Opaque pointer to induced subgraph * @return type erased array view of source vertex ids */ @@ -126,7 +126,7 @@ cugraph_type_erased_device_array_view_t* cugraph_induced_subgraph_get_sources( * @brief Get the destination vertex ids * * @deprecated This API will be deleted, use cugraph_edgelist_get_destinations - * + * * @param [in] induced_subgraph Opaque pointer to induced subgraph * @return type erased array view of destination vertex ids */ @@ -137,7 +137,7 @@ cugraph_type_erased_device_array_view_t* cugraph_induced_subgraph_get_destinatio * @brief Get the edge weights * * @deprecated This API will be deleted, use cugraph_edgelist_get_edge_weights - * + * * @param [in] induced_subgraph Opaque pointer to induced subgraph * @return type erased array view of edge weights */ @@ -148,7 +148,7 @@ cugraph_type_erased_device_array_view_t* cugraph_induced_subgraph_get_edge_weigh * @brief Get the edge ids * * @deprecated This API will be deleted, use cugraph_edgelist_get_edge_ids - * + * * @param [in] induced_subgraph Opaque pointer to induced subgraph * @return type erased array view of edge ids */ @@ -170,7 +170,7 @@ cugraph_type_erased_device_array_view_t* cugraph_induced_subgraph_get_edge_type_ * @brief Get the subgraph offsets * * @deprecated This API will be deleted, use cugraph_edgelist_get_edge_offsets - * + * * @param [in] induced_subgraph Opaque pointer to induced subgraph * @return type erased array view of subgraph identifiers */ @@ -181,7 +181,7 @@ cugraph_type_erased_device_array_view_t* cugraph_induced_subgraph_get_subgraph_o * @brief Free induced subgraph * * @deprecated This API will be deleted, use cugraph_edgelist_free - * + * * @param [in] induced subgraph Opaque pointer to induced subgraph */ void cugraph_induced_subgraph_result_free(cugraph_induced_subgraph_result_t* induced_subgraph); @@ -379,7 +379,7 @@ void cugraph_degrees_result_free(cugraph_degrees_result_t* degrees_result); /** * @brief Opaque edgelist type - * + * */ typedef struct { int32_t align_; @@ -387,16 +387,15 @@ typedef struct { /** * @brief Get the source vertex ids - * + * * @param [in] edgelist Opaque pointer to edgelist * @return type erased array view of source vertex ids */ -cugraph_type_erased_device_array_view_t* cugraph_edgelist_get_sources( - cugraph_edgelist_t* edgelist); +cugraph_type_erased_device_array_view_t* cugraph_edgelist_get_sources(cugraph_edgelist_t* edgelist); /** * @brief Get the destination vertex ids - * + * * @param [in] edgelist Opaque pointer to edgelist * @return type erased array view of destination vertex ids */ @@ -405,7 +404,7 @@ cugraph_type_erased_device_array_view_t* cugraph_edgelist_get_destinations( /** * @brief Get the edge weights - * + * * @param [in] edgelist Opaque pointer to edgelist * @return type erased array view of edge weights */ @@ -414,7 +413,7 @@ cugraph_type_erased_device_array_view_t* cugraph_edgelist_get_edge_weights( /** * @brief Get the edge ids - * + * * @param [in] edgelist Opaque pointer to edgelist * @return type erased array view of edge ids */ @@ -423,7 +422,7 @@ cugraph_type_erased_device_array_view_t* cugraph_edgelist_get_edge_ids( /** * @brief Get the edge types - * + * * @param [in] edgelist Opaque pointer to edgelist * @return type erased array view of edge types */ @@ -432,7 +431,7 @@ cugraph_type_erased_device_array_view_t* cugraph_edgelist_get_edge_type_ids( /** * @brief Get the edge offsets - * + * * @param [in] edgelist Opaque pointer to edgelist * @return type erased array view of subgraph identifiers */ @@ -441,7 +440,7 @@ cugraph_type_erased_device_array_view_t* cugraph_edgelist_get_edge_offsets( /** * @brief Free edgelist - * + * * @param [in] edgelist Opaque pointer to edgelist */ void cugraph_edgelist_free(cugraph_edgelist_t* edgelist); diff --git a/cpp/src/c_api/decompress_to_edgelist.cpp b/cpp/src/c_api/decompress_to_edgelist.cpp index 2fa823c3242..75bf0c0fd60 100644 --- a/cpp/src/c_api/decompress_to_edgelist.cpp +++ b/cpp/src/c_api/decompress_to_edgelist.cpp @@ -16,8 +16,8 @@ #include "c_api/abstract_functor.hpp" #include "c_api/core_result.hpp" -#include "c_api/graph.hpp" #include "c_api/edgelist.hpp" +#include "c_api/graph.hpp" #include "c_api/resource_handle.hpp" #include "c_api/utils.hpp" diff --git a/cpp/src/c_api/edgelist.cpp b/cpp/src/c_api/edgelist.cpp index 47cfabdb9fc..640b2bf2853 100644 --- a/cpp/src/c_api/edgelist.cpp +++ b/cpp/src/c_api/edgelist.cpp @@ -21,24 +21,21 @@ extern "C" cugraph_type_erased_device_array_view_t* cugraph_edgelist_get_sources( cugraph_edgelist_t* edgelist) { - auto internal_pointer = - reinterpret_cast(edgelist); + auto internal_pointer = reinterpret_cast(edgelist); return reinterpret_cast(internal_pointer->src_->view()); } extern "C" cugraph_type_erased_device_array_view_t* cugraph_edgelist_get_destinations( cugraph_edgelist_t* edgelist) { - auto internal_pointer = - reinterpret_cast(edgelist); + auto internal_pointer = reinterpret_cast(edgelist); return reinterpret_cast(internal_pointer->dst_->view()); } extern "C" cugraph_type_erased_device_array_view_t* cugraph_edgelist_get_edge_weights( cugraph_edgelist_t* edgelist) { - auto internal_pointer = - reinterpret_cast(edgelist); + auto internal_pointer = reinterpret_cast(edgelist); return (internal_pointer->wgt_ == nullptr) ? NULL : reinterpret_cast( @@ -48,8 +45,7 @@ extern "C" cugraph_type_erased_device_array_view_t* cugraph_edgelist_get_edge_we extern "C" cugraph_type_erased_device_array_view_t* cugraph_edgelist_get_edge_ids( cugraph_edgelist_t* edgelist) { - auto internal_pointer = - reinterpret_cast(edgelist); + auto internal_pointer = reinterpret_cast(edgelist); return (internal_pointer->edge_ids_ == nullptr) ? NULL : reinterpret_cast( @@ -59,8 +55,7 @@ extern "C" cugraph_type_erased_device_array_view_t* cugraph_edgelist_get_edge_id extern "C" cugraph_type_erased_device_array_view_t* cugraph_edgelist_get_edge_type_ids( cugraph_edgelist_t* edgelist) { - auto internal_pointer = - reinterpret_cast(edgelist); + auto internal_pointer = reinterpret_cast(edgelist); return (internal_pointer->edge_type_ids_ == nullptr) ? NULL : reinterpret_cast( @@ -70,17 +65,14 @@ extern "C" cugraph_type_erased_device_array_view_t* cugraph_edgelist_get_edge_ty extern "C" cugraph_type_erased_device_array_view_t* cugraph_edgelist_get_edge_offsets( cugraph_edgelist_t* edgelist) { - auto internal_pointer = - reinterpret_cast(edgelist); + auto internal_pointer = reinterpret_cast(edgelist); return reinterpret_cast( internal_pointer->subgraph_offsets_->view()); } -extern "C" void cugraph_edgelist_free( - cugraph_edgelist_t* edgelist) +extern "C" void cugraph_edgelist_free(cugraph_edgelist_t* edgelist) { - auto internal_pointer = - reinterpret_cast(edgelist); + auto internal_pointer = reinterpret_cast(edgelist); delete internal_pointer->src_; delete internal_pointer->dst_; delete internal_pointer->wgt_;