Skip to content

Commit

Permalink
resolve merge conflicts
Browse files Browse the repository at this point in the history
  • Loading branch information
seunghwak committed Mar 13, 2024
2 parents f6b9680 + 6b28aef commit 29601e0
Show file tree
Hide file tree
Showing 74 changed files with 4,769 additions and 680 deletions.
112 changes: 112 additions & 0 deletions benchmarks/nx-cugraph/pytest-based/bench_algos.py
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,28 @@ def get_highest_degree_node(graph_obj):
return max(degrees, key=lambda t: t[1])[0]


def build_personalization_dict(pagerank_dict):
"""
Returns a dictionary that can be used as the personalization value for a
call to nx.pagerank(). The pagerank_dict passed in is used as the initial
source of values for each node, and this function simply treats the list of
dict values as two halves (halves A and B) and swaps them so (most if not
all) nodes/keys are assigned a different value from the dictionary.
"""
num_half = len(pagerank_dict) // 2
A_half_items = list(pagerank_dict.items())[:num_half]
B_half_items = list(pagerank_dict.items())[num_half:]

# Support an odd number of items by initializing with B_half_items, which
# will always be one bigger if the number of items is odd. This will leave
# the one remainder (in the case of an odd number) unchanged.
pers_dict = dict(B_half_items)
pers_dict.update({A_half_items[i][0]: B_half_items[i][1] for i in range(num_half)})
pers_dict.update({B_half_items[i][0]: A_half_items[i][1] for i in range(num_half)})

return pers_dict


################################################################################
# Benchmarks
def bench_from_networkx(benchmark, graph_obj):
Expand Down Expand Up @@ -431,6 +453,26 @@ def bench_pagerank(benchmark, graph_obj, backend_wrapper):
assert type(result) is dict


def bench_pagerank_personalized(benchmark, graph_obj, backend_wrapper):
G = get_graph_obj_for_benchmark(graph_obj, backend_wrapper)

# FIXME: This will run for every combination of inputs, even if the
# graph/dataset does not change. Ideally this is run once per
# graph/dataset.
pagerank_dict = nx.pagerank(G)
personalization_dict = build_personalization_dict(pagerank_dict)

result = benchmark.pedantic(
target=backend_wrapper(nx.pagerank),
args=(G,),
kwargs={"personalization": personalization_dict},
rounds=rounds,
iterations=iterations,
warmup_rounds=warmup_rounds,
)
assert type(result) is dict


def bench_single_source_shortest_path_length(benchmark, graph_obj, backend_wrapper):
G = get_graph_obj_for_benchmark(graph_obj, backend_wrapper)
node = get_highest_degree_node(graph_obj)
Expand Down Expand Up @@ -804,3 +846,73 @@ def bench_weakly_connected_components(benchmark, graph_obj, backend_wrapper):
warmup_rounds=warmup_rounds,
)
assert type(result) is list


@pytest.mark.skip(reason="benchmark not implemented")
def bench_complete_bipartite_graph(benchmark, graph_obj, backend_wrapper):
pass


@pytest.mark.skip(reason="benchmark not implemented")
def bench_connected_components(benchmark, graph_obj, backend_wrapper):
pass


@pytest.mark.skip(reason="benchmark not implemented")
def bench_is_connected(benchmark, graph_obj, backend_wrapper):
pass


@pytest.mark.skip(reason="benchmark not implemented")
def bench_node_connected_component(benchmark, graph_obj, backend_wrapper):
pass


@pytest.mark.skip(reason="benchmark not implemented")
def bench_number_connected_components(benchmark, graph_obj, backend_wrapper):
pass


@pytest.mark.skip(reason="benchmark not implemented")
def bench_is_isolate(benchmark, graph_obj, backend_wrapper):
pass


@pytest.mark.skip(reason="benchmark not implemented")
def bench_isolates(benchmark, graph_obj, backend_wrapper):
pass


@pytest.mark.skip(reason="benchmark not implemented")
def bench_number_of_isolates(benchmark, graph_obj, backend_wrapper):
pass


@pytest.mark.skip(reason="benchmark not implemented")
def bench_complement(benchmark, graph_obj, backend_wrapper):
pass


@pytest.mark.skip(reason="benchmark not implemented")
def bench_reverse(benchmark, graph_obj, backend_wrapper):
pass


@pytest.mark.skip(reason="benchmark not implemented")
def bench_is_arborescence(benchmark, graph_obj, backend_wrapper):
pass


@pytest.mark.skip(reason="benchmark not implemented")
def bench_is_branching(benchmark, graph_obj, backend_wrapper):
pass


@pytest.mark.skip(reason="benchmark not implemented")
def bench_is_forest(benchmark, graph_obj, backend_wrapper):
pass


@pytest.mark.skip(reason="benchmark not implemented")
def bench_is_tree(benchmark, graph_obj, backend_wrapper):
pass
14 changes: 10 additions & 4 deletions cpp/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -186,9 +186,9 @@ endif()
# which should give us a better parallel schedule.

set(CUGRAPH_SOURCES
src/detail/shuffle_vertices.cu
src/utilities/shuffle_vertices.cu
src/detail/permute_range.cu
src/detail/shuffle_vertex_pairs.cu
src/utilities/shuffle_vertex_pairs.cu
src/detail/collect_local_vertex_values.cu
src/detail/groupby_and_count.cu
src/detail/collect_comm_wrapper.cu
Expand All @@ -197,8 +197,8 @@ set(CUGRAPH_SOURCES
src/community/detail/common_methods_sg.cu
src/community/detail/refine_sg.cu
src/community/detail/refine_mg.cu
src/community/detail/mis_sg.cu
src/community/detail/mis_mg.cu
src/community/detail/maximal_independent_moves_sg.cu
src/community/detail/maximal_independent_moves_mg.cu
src/detail/utility_wrappers.cu
src/structure/graph_view_mg.cu
src/structure/remove_self_loops.cu
Expand Down Expand Up @@ -295,6 +295,10 @@ set(CUGRAPH_SOURCES
src/tree/legacy/mst.cu
src/components/weakly_connected_components_sg.cu
src/components/weakly_connected_components_mg.cu
src/components/mis_sg.cu
src/components/mis_mg.cu
src/components/vertex_coloring_sg.cu
src/components/vertex_coloring_mg.cu
src/structure/create_graph_from_edgelist_sg.cu
src/structure/create_graph_from_edgelist_mg.cu
src/structure/symmetrize_edgelist_sg.cu
Expand Down Expand Up @@ -411,6 +415,8 @@ endif()
add_library(cugraph_c
src/c_api/resource_handle.cpp
src/c_api/array.cpp
src/c_api/degrees.cu
src/c_api/degrees_result.cpp
src/c_api/error.cpp
src/c_api/graph_sg.cpp
src/c_api/graph_mg.cpp
Expand Down
30 changes: 28 additions & 2 deletions cpp/include/cugraph/algorithms.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2340,15 +2340,41 @@ std::tuple<rmm::device_uvector<size_t>, rmm::device_uvector<vertex_t>> k_hop_nbr
* handles to various CUDA libraries) to run graph algorithms.
* @param graph_view Graph view object.
* @param rng_state The RngState instance holding pseudo-random number generator state.
* @return A device vector containing vertices found in the maximal independent set
* @return A device vector containing vertices in the maximal independent set.
*/

template <typename vertex_t, typename edge_t, bool multi_gpu>
rmm::device_uvector<vertex_t> maximal_independent_set(
raft::handle_t const& handle,
graph_view_t<vertex_t, edge_t, false, multi_gpu> const& graph_view,
raft::random::RngState& rng_state);

/*
* @brief Find a Greedy Vertex Coloring
*
* A vertex coloring is an assignment of colors or labels to each vertex of a graph so that
* no two adjacent vertices have the same color or label. Finding the minimum number of colors
* needed to color the vertices of a graph is an NP-hard problem and therefore for practical
* use cases greedy coloring is used. Here we provide an implementation of greedy vertex
* coloring based on maximal independent set.
* See
* https://research.nvidia.com/sites/default/files/pubs/2015-05_Parallel-Graph-Coloring/nvr-2015-001.pdf
* for further information.
*
* @tparam vertex_t Type of vertex identifiers. Needs to be an integral type.
* @tparam edge_t Type of edge identifiers. Needs to be an integral type.
* @tparam multi_gpu Flag indicating whether template instantiation should target single-GPU (false)
* @param handle RAFT handle object to encapsulate resources (e.g. CUDA stream, communicator, and
* handles to various CUDA libraries) to run graph algorithms.
* @param graph_view Graph view object.
* @param rng_state The RngState instance holding pseudo-random number generator state.
* @return A device vector containing color for each vertex.
*/
template <typename vertex_t, typename edge_t, bool multi_gpu>
rmm::device_uvector<vertex_t> vertex_coloring(
raft::handle_t const& handle,
graph_view_t<vertex_t, edge_t, false, multi_gpu> const& graph_view,
raft::random::RngState& rng_state);

} // namespace cugraph

/**
Expand Down
63 changes: 63 additions & 0 deletions cpp/include/cugraph/graph_functions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1052,4 +1052,67 @@ remove_multi_edges(raft::handle_t const& handle,
std::optional<rmm::device_uvector<edge_type_t>>&& edgelist_edge_types,
bool keep_min_value_edge = false);

/**
* @brief Shuffle external vertex ids to the proper GPU.
*
* @tparam vertex_t Type of vertex identifiers. Needs to be an integral type.
*
* @param handle RAFT handle object to encapsulate resources (e.g. CUDA stream, communicator, and
* handles to various CUDA libraries) to run graph algorithms.
* @param vertices List of vertex ids
* @return Vector of vertex ids mapped to this GPU.
*/
template <typename vertex_t>
rmm::device_uvector<vertex_t> shuffle_external_vertices(raft::handle_t const& handle,
rmm::device_uvector<vertex_t>&& vertices);

/**
* @brief Shuffle external vertex ids and values to the proper GPU.
*
* @tparam vertex_t Type of vertex identifiers. Needs to be an integral type.
* @tparam value_t Type of values. currently supported types are int32_t,
* int64_t, size_t, float and double.
*
* @param handle RAFT handle object to encapsulate resources (e.g. CUDA stream, communicator, and
* handles to various CUDA libraries) to run graph algorithms.
* @param vertices List of vertex ids
* @param values List of values
* @return Tuple of vectors storing vertex ids and values mapped to this GPU.
*/
template <typename vertex_t, typename value_t>
std::tuple<rmm::device_uvector<vertex_t>, rmm::device_uvector<value_t>>
shuffle_external_vertex_value_pairs(raft::handle_t const& handle,
rmm::device_uvector<vertex_t>&& vertices,
rmm::device_uvector<value_t>&& values);

/**
* @brief Shuffle external edges to the proper GPU.
*
* @tparam vertex_t Type of vertex identifiers. Needs to be an integral type.
* @tparam edge_t Type of edge identifiers. Needs to be an integral type.
* @tparam weight_t Type of edge weight. Currently float and double are supported.
*
* @param handle RAFT handle object to encapsulate resources (e.g. CUDA stream, communicator, and
* handles to various CUDA libraries) to run graph algorithms.
* @param edge_srcs List of source vertex ids
* @param edge_dsts List of destination vertex ids
* @param edge_weights Optional list of edge weights
* @param edge_ids Optional list of edge ids
* @param edge_types Optional list of edge types
* @return Tuple of vectors storing edge sources, destinations, optional weights,
* optional edge ids, optional edge types mapped to this GPU.
*/
template <typename vertex_t, typename edge_t, typename weight_t, typename edge_type_t>
std::tuple<rmm::device_uvector<vertex_t>,
rmm::device_uvector<vertex_t>,
std::optional<rmm::device_uvector<weight_t>>,
std::optional<rmm::device_uvector<edge_t>>,
std::optional<rmm::device_uvector<edge_type_t>>>
shuffle_external_edges(raft::handle_t const& handle,
rmm::device_uvector<vertex_t>&& edge_srcs,
rmm::device_uvector<vertex_t>&& edge_dsts,
std::optional<rmm::device_uvector<weight_t>>&& edge_weights,
std::optional<rmm::device_uvector<edge_t>>&& edge_ids,
std::optional<rmm::device_uvector<edge_type_t>>&& edge_types);

} // namespace cugraph
Loading

0 comments on commit 29601e0

Please sign in to comment.