From 0c8b9272d14f70712af4ac7cefae900fde2a1b13 Mon Sep 17 00:00:00 2001 From: jnke2016 Date: Tue, 10 Sep 2024 07:51:13 -0700 Subject: [PATCH] implement symmetrize_edgelist in the CAPI --- cpp/CMakeLists.txt | 1 + cpp/src/c_api/symmetrize_edgelist.cpp | 182 ++++++++++++++++++++++++++ 2 files changed, 183 insertions(+) diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt index b8eaba9d575..f2eec1786b4 100644 --- a/cpp/CMakeLists.txt +++ b/cpp/CMakeLists.txt @@ -666,6 +666,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/symmetrize_edgelist.cpp ) add_library(cugraph::cugraph_c ALIAS cugraph_c) diff --git a/cpp/src/c_api/symmetrize_edgelist.cpp b/cpp/src/c_api/symmetrize_edgelist.cpp index e69de29bb2d..a0cd82f857f 100644 --- a/cpp/src/c_api/symmetrize_edgelist.cpp +++ b/cpp/src/c_api/symmetrize_edgelist.cpp @@ -0,0 +1,182 @@ +/* + * Copyright (c) 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/graph.hpp" +#include "c_api/induced_subgraph_result.hpp" +#include "c_api/resource_handle.hpp" +#include "c_api/utils.hpp" + +#include +//#include + +#include +//#include +//#include +#include +#include + +namespace { + +struct create_allgather_functor : public cugraph::c_api::abstract_functor { + raft::handle_t const& handle_; + cugraph::c_api::cugraph_type_erased_device_array_view_t const* src_; + cugraph::c_api::cugraph_type_erased_device_array_view_t const* dst_; + cugraph::c_api::cugraph_type_erased_device_array_view_t const* weights_; + bool_t reciprocal_; + cugraph::c_api::cugraph_induced_subgraph_result_t* result_{}; + + create_allgather_functor( + raft::handle_t const& handle, + cugraph::c_api::cugraph_type_erased_device_array_view_t const* src, + cugraph::c_api::cugraph_type_erased_device_array_view_t const* dst, + cugraph::c_api::cugraph_type_erased_device_array_view_t const* weights, + bool_t reciprocal) + : abstract_functor(), + handle_(handle), + src_(src), + dst_(dst), + weights_(weights), + reciprocal_(reciprocal) + { + } + + template + void operator()() + { + + rmm::device_uvector edgelist_srcs(src_->size_, handle_.get_stream()); + rmm::device_uvector edgelist_dsts(dst_->size_, handle_.get_stream()); + + raft::copy( + edgelist_srcs.data(), src_->as_type(), src_->size_, handle_.get_stream()); + raft::copy( + edgelist_dsts.data(), dst_->as_type(), dst_->size_, handle_.get_stream()); + + std::optional> edgelist_weights = + weights_ + ? std::make_optional(rmm::device_uvector(weights_->size_, handle_.get_stream())) + : std::nullopt; + + if (edgelist_weights) { + raft::copy(edgelist_weights->data(), + weights_->as_type(), + weights_->size_, + handle_.get_stream()); + } + + cugraph::detail::symmetrize_edgelist( + edgelist_srcs, + edgelist_dsts, + edgelist_weights, + reciprocal + ); + + + + + + + + + } +}; + +} // namespace + + +extern "C" cugraph_error_code_t symmetrize_edgelist( + const cugraph_resource_handle_t* handle, + const cugraph_type_erased_device_array_view_t* src, + const cugraph_type_erased_device_array_view_t* dst, + const cugraph_type_erased_device_array_view_t* weights, + bool_t reciprocal, + cugraph_induced_subgraph_result_t** edgelist, + cugraph_error_t** error) +{ + *edgelist = nullptr; + *error = nullptr; + + auto p_handle = reinterpret_cast(handle); + auto p_src = + reinterpret_cast(src); + auto p_dst = + reinterpret_cast(dst); + auto p_weights = + reinterpret_cast(weights); + + CAPI_EXPECTS((dst == nullptr) || (src == nullptr) || p_src->size_ == p_dst->size_, + CUGRAPH_INVALID_INPUT, + "Invalid input arguments: src size != dst size.", + *error); + CAPI_EXPECTS((dst == nullptr) || (src == nullptr) || p_src->type_ == p_dst->type_, + CUGRAPH_INVALID_INPUT, + "Invalid input arguments: src type != dst type.", + *error); + + CAPI_EXPECTS((weights == nullptr) || (src == nullptr) || (p_weights->size_ == p_src->size_), + CUGRAPH_INVALID_INPUT, + "Invalid input arguments: src size != weights size.", + *error); + + cugraph_data_type_id_t vertex_type; + cugraph_data_type_id_t weight_type; + + cugraph_data_type_id_t edge_type = cugraph_data_type_id_t::INT32; + cugraph_data_type_id_t edge_type_id_type = cugraph_data_type_id_t::INT32; + + if (src != nullptr) { + vertex_type = p_src->type_; + } else { + vertex_type = cugraph_data_type_id_t::INT32; + } + + if (weights != nullptr) { + weight_type = p_weights->type_; + } else { + weight_type = cugraph_data_type_id_t::FLOAT32; + } + + constexpr bool multi_gpu = false; + constexpr bool store_transposed = false; + + ::symmetrize_edgelist_functor functor( + *p_handle->handle_, p_src, p_dst, p_weights); + + + try { + cugraph::c_api::vertex_dispatcher( + vertex_type, edge_type, weight_type, edge_type_id_type, store_transposed, multi_gpu, functor); + + if (functor.error_code_ != CUGRAPH_SUCCESS) { + *error = reinterpret_cast(functor.error_.release()); + return functor.error_code_; + } + + *edgelist = reinterpret_cast(functor.result_); + } catch (std::exception const& ex) { + *error = reinterpret_cast(new cugraph::c_api::cugraph_error_t{ex.what()}); + return CUGRAPH_UNKNOWN_ERROR; + } + + + +} \ No newline at end of file