Skip to content

Commit

Permalink
Merge branch 'branch-24.04' into bug_edge_masking
Browse files Browse the repository at this point in the history
  • Loading branch information
nv-rliu authored Mar 7, 2024
2 parents 8dfc337 + 92daf6e commit 36c975f
Show file tree
Hide file tree
Showing 24 changed files with 723 additions and 111 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/pr.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ jobs:
with:
build_type: pull-request
script: ci/test_wheel_cugraph-pyg.sh
matrix_filter: map(select(.ARCH == "amd64" and .CUDA_VER == "11.8.0"))
matrix_filter: map(select(.ARCH == "amd64"))
wheel-build-cugraph-equivariant:
secrets: inherit
uses: rapidsai/shared-workflows/.github/workflows/[email protected]
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ jobs:
date: ${{ inputs.date }}
sha: ${{ inputs.sha }}
script: ci/test_wheel_cugraph-pyg.sh
matrix_filter: map(select(.ARCH == "amd64" and .CUDA_VER == "11.8.0"))
matrix_filter: map(select(.ARCH == "amd64"))
wheel-tests-cugraph-equivariant:
secrets: inherit
uses: rapidsai/shared-workflows/.github/workflows/[email protected]
Expand Down
2 changes: 1 addition & 1 deletion ci/test_python.sh
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ if [[ "${RAPIDS_CUDA_VERSION}" == "11.8.0" ]]; then
pylibcugraphops \
cugraph \
cugraph-dgl \
'dgl>=1.1.0.cu*' \
'dgl>=1.1.0.cu*,<=2.0.0.cu*' \
'pytorch>=2.0' \
'pytorch-cuda>=11.8'

Expand Down
2 changes: 1 addition & 1 deletion ci/test_wheel_cugraph-dgl.sh
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,6 @@ DGL_URL="https://data.dgl.ai/wheels/cu${PYTORCH_CUDA_VER}/repo.html"

rapids-logger "Installing PyTorch and DGL"
rapids-retry python -m pip install torch --index-url ${PYTORCH_URL}
rapids-retry python -m pip install dgl --find-links ${DGL_URL}
rapids-retry python -m pip install dgl==2.0.0 --find-links ${DGL_URL}

python -m pytest python/cugraph-dgl/tests
1 change: 1 addition & 0 deletions cpp/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -423,6 +423,7 @@ add_library(cugraph_c
src/c_api/core_number.cpp
src/c_api/core_result.cpp
src/c_api/extract_ego.cpp
src/c_api/ecg.cpp
src/c_api/k_core.cpp
src/c_api/hierarchical_clustering_result.cpp
src/c_api/induced_subgraph.cpp
Expand Down
49 changes: 42 additions & 7 deletions cpp/include/cugraph_c/community_algorithms.h
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,41 @@ double cugraph_hierarchical_clustering_result_get_modularity(
*/
void cugraph_hierarchical_clustering_result_free(cugraph_hierarchical_clustering_result_t* result);

/**
* @brief Compute ECG clustering
*
* @param [in] handle Handle for accessing resources
* @param [in/out] rng_state State of the random number generator, updated with each call
* @param [in] graph Pointer to graph. NOTE: Graph might be modified if the storage
* needs to be transposed
* @param [in] min_weight Minimum edge weight in final graph
* @param [in] ensemble_size The number of Louvain iterations to run
* @param [in] max_level Maximum level in hierarchy for final Louvain
* @param [in] threshold Threshold parameter, defines convergence at each level of hierarchy
* for final Louvain
* @param [in] resolution Resolution parameter (gamma) in modularity formula.
* This changes the size of the communities. Higher resolutions
* lead to more smaller communities, lower resolutions lead to
* fewer larger communities.
* @param [in] do_expensive_check
* A flag to run expensive checks for input arguments (if set to true)
* @param [out] result Output from the Louvain call
* @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_ecg(const cugraph_resource_handle_t* handle,
cugraph_rng_state_t* rng_state,
cugraph_graph_t* graph,
double min_weight,
size_t ensemble_size,
size_t max_level,
double threshold,
double resolution,
bool_t do_expensive_check,
cugraph_hierarchical_clustering_result_t** result,
cugraph_error_t** error);

/**
* @brief Compute ECG clustering of the given graph
*
Expand All @@ -200,13 +235,13 @@ void cugraph_hierarchical_clustering_result_free(cugraph_hierarchical_clustering
* be populated if error code is not CUGRAPH_SUCCESS
* @return error code
*/
cugraph_error_code_t cugraph_ecg(const cugraph_resource_handle_t* handle,
cugraph_graph_t* graph,
double min_weight,
size_t ensemble_size,
bool_t do_expensive_check,
cugraph_hierarchical_clustering_result_t** result,
cugraph_error_t** error);
cugraph_error_code_t cugraph_legacy_ecg(const cugraph_resource_handle_t* handle,
cugraph_graph_t* graph,
double min_weight,
size_t ensemble_size,
bool_t do_expensive_check,
cugraph_hierarchical_clustering_result_t** result,
cugraph_error_t** error);

/**
* @brief Extract ego graphs
Expand Down
154 changes: 154 additions & 0 deletions cpp/src/c_api/ecg.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
/*
* 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 <cugraph_c/community_algorithms.h>

#include <cugraph/algorithms.hpp>
#include <cugraph/detail/shuffle_wrappers.hpp>
#include <cugraph/detail/utility_wrappers.hpp>
#include <cugraph/graph_functions.hpp>

#include <c_api/abstract_functor.hpp>
#include <c_api/graph.hpp>
#include <c_api/graph_helper.hpp>
#include <c_api/hierarchical_clustering_result.hpp>
#include <c_api/random.hpp>
#include <c_api/resource_handle.hpp>
#include <c_api/utils.hpp>

#include <optional>

namespace {

struct ecg_functor : public cugraph::c_api::abstract_functor {
raft::handle_t const& handle_;
cugraph::c_api::cugraph_rng_state_t* rng_state_{nullptr};
cugraph::c_api::cugraph_graph_t* graph_{nullptr};
double min_weight_{0.1};
size_t ensemble_size_{10};
size_t max_level_{0};
double threshold_{0.001};
double resolution_{1};
bool do_expensive_check_{false};
cugraph::c_api::cugraph_hierarchical_clustering_result_t* result_{};

ecg_functor(::cugraph_resource_handle_t const* handle,
::cugraph_rng_state_t* rng_state,
::cugraph_graph_t* graph,
double min_weight,
size_t ensemble_size,
size_t max_level,
double threshold,
double resolution,
bool do_expensive_check)
: abstract_functor(),
handle_(*reinterpret_cast<cugraph::c_api::cugraph_resource_handle_t const*>(handle)->handle_),
rng_state_(reinterpret_cast<cugraph::c_api::cugraph_rng_state_t*>(rng_state)),
graph_(reinterpret_cast<cugraph::c_api::cugraph_graph_t*>(graph)),
max_level_(max_level),
threshold_(threshold),
resolution_(resolution),
do_expensive_check_(do_expensive_check)
{
}

template <typename vertex_t,
typename edge_t,
typename weight_t,
typename edge_type_type_t,
bool store_transposed,
bool multi_gpu>
void operator()()
{
if constexpr (!cugraph::is_candidate<vertex_t, edge_t, weight_t>::value) {
unsupported();
} else {
// ecg expects store_transposed == false
if constexpr (store_transposed) {
error_code_ = cugraph::c_api::
transpose_storage<vertex_t, edge_t, weight_t, store_transposed, multi_gpu>(
handle_, graph_, error_.get());
if (error_code_ != CUGRAPH_SUCCESS) return;
}

auto graph =
reinterpret_cast<cugraph::graph_t<vertex_t, edge_t, false, multi_gpu>*>(graph_->graph_);

auto graph_view = graph->view();

auto edge_weights = reinterpret_cast<
cugraph::edge_property_t<cugraph::graph_view_t<vertex_t, edge_t, false, multi_gpu>,
weight_t>*>(graph_->edge_weights_);

auto number_map = reinterpret_cast<rmm::device_uvector<vertex_t>*>(graph_->number_map_);

rmm::device_uvector<vertex_t> clusters(0, handle_.get_stream());

weight_t modularity;

std::tie(clusters, std::ignore, modularity) =
cugraph::ecg(handle_,
rng_state_->rng_state_,
graph_view,
(edge_weights != nullptr)
? std::make_optional(edge_weights->view())
: std::make_optional(cugraph::c_api::create_constant_edge_property(
handle_, graph_view, weight_t{1})
.view()),
static_cast<weight_t>(min_weight_),
ensemble_size_,
max_level_,
static_cast<weight_t>(threshold_),
static_cast<weight_t>(resolution_));

rmm::device_uvector<vertex_t> vertices(graph_view.local_vertex_partition_range_size(),
handle_.get_stream());
raft::copy(vertices.data(), number_map->data(), vertices.size(), handle_.get_stream());

result_ = new cugraph::c_api::cugraph_hierarchical_clustering_result_t{
modularity,
new cugraph::c_api::cugraph_type_erased_device_array_t(vertices, graph_->vertex_type_),
new cugraph::c_api::cugraph_type_erased_device_array_t(clusters, graph_->vertex_type_)};
}
}
};

} // namespace

extern "C" cugraph_error_code_t cugraph_ecg(const cugraph_resource_handle_t* handle,
cugraph_rng_state_t* rng_state,
cugraph_graph_t* graph,
double min_weight,
size_t ensemble_size,
size_t max_level,
double threshold,
double resolution,
bool_t do_expensive_check,
cugraph_hierarchical_clustering_result_t** result,
cugraph_error_t** error)
{
ecg_functor functor(handle,
rng_state,
graph,
min_weight,
ensemble_size,
max_level,
threshold,
resolution,
do_expensive_check);

return cugraph::c_api::run_algorithm(graph, functor, result, error);
}
29 changes: 15 additions & 14 deletions cpp/src/c_api/legacy_ecg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,19 +31,19 @@

namespace {

struct ecg_functor : public cugraph::c_api::abstract_functor {
struct legacy_ecg_functor : public cugraph::c_api::abstract_functor {
raft::handle_t const& handle_;
cugraph::c_api::cugraph_graph_t* graph_;
double min_weight_;
size_t ensemble_size_;
bool do_expensive_check_;
cugraph::c_api::cugraph_hierarchical_clustering_result_t* result_{};

ecg_functor(::cugraph_resource_handle_t const* handle,
::cugraph_graph_t* graph,
double min_weight,
size_t ensemble_size,
bool do_expensive_check)
legacy_ecg_functor(::cugraph_resource_handle_t const* handle,
::cugraph_graph_t* graph,
double min_weight,
size_t ensemble_size,
bool do_expensive_check)
: abstract_functor(),
handle_(*reinterpret_cast<cugraph::c_api::cugraph_resource_handle_t const*>(handle)->handle_),
graph_(reinterpret_cast<cugraph::c_api::cugraph_graph_t*>(graph)),
Expand Down Expand Up @@ -120,15 +120,16 @@ struct ecg_functor : public cugraph::c_api::abstract_functor {

} // namespace

extern "C" cugraph_error_code_t cugraph_ecg(const cugraph_resource_handle_t* handle,
cugraph_graph_t* graph,
double min_weight,
size_t ensemble_size,
bool_t do_expensive_check,
cugraph_hierarchical_clustering_result_t** result,
cugraph_error_t** error)
extern "C" cugraph_error_code_t cugraph_legacy_ecg(
const cugraph_resource_handle_t* handle,
cugraph_graph_t* graph,
double min_weight,
size_t ensemble_size,
bool_t do_expensive_check,
cugraph_hierarchical_clustering_result_t** result,
cugraph_error_t** error)
{
ecg_functor functor(handle, graph, min_weight, ensemble_size, do_expensive_check);
legacy_ecg_functor functor(handle, graph, min_weight, ensemble_size, do_expensive_check);

return cugraph::c_api::run_algorithm(graph, functor, result, error);
}
Loading

0 comments on commit 36c975f

Please sign in to comment.