Skip to content

Commit

Permalink
Adds nx-cugraph benchmarks for APIs added to prior releases that were…
Browse files Browse the repository at this point in the history
… never benchmarked (#4228)

* Adds benchmark for nx-cugraph `pagerank` with a personalization dict (see results below)
* Adds several placeholder benchmarks for other nx-cugraph APIs added to prior releases that were never benchmarked.

![image](https://github.com/rapidsai/cugraph/assets/3039903/4692e2a2-e14a-489d-84f7-772eda6fc316)

Authors:
  - Rick Ratzel (https://github.com/rlratzel)
  - Ralph Liu (https://github.com/nv-rliu)

Approvers:
  - Erik Welch (https://github.com/eriknw)

URL: #4228
  • Loading branch information
rlratzel authored Mar 13, 2024
1 parent 120e5b8 commit 6c88281
Showing 1 changed file with 112 additions and 0 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

0 comments on commit 6c88281

Please sign in to comment.