From 25233c2a9a0f6cf325aab894c4f5f3312a56ac45 Mon Sep 17 00:00:00 2001 From: Schefflera-Arboricola <1509aditi@gmail.com> Date: Tue, 24 Oct 2023 22:14:12 +0530 Subject: [PATCH 01/16] benchmarking-initial commit --- .gitignore | 4 +++ benchmarks/README.md | 7 ++++ benchmarks/asv.conf.json | 40 +++++++++++++++++++++++ benchmarks/benchmarks/__init__.py | 0 benchmarks/benchmarks/bench_centrality.py | 22 +++++++++++++ 5 files changed, 73 insertions(+) create mode 100644 benchmarks/README.md create mode 100644 benchmarks/asv.conf.json create mode 100644 benchmarks/benchmarks/__init__.py create mode 100644 benchmarks/benchmarks/bench_centrality.py diff --git a/.gitignore b/.gitignore index b6e4761..af44fdf 100644 --- a/.gitignore +++ b/.gitignore @@ -127,3 +127,7 @@ dmypy.json # Pyre type checker .pyre/ + +# asv +results/ +html/ \ No newline at end of file diff --git a/benchmarks/README.md b/benchmarks/README.md new file mode 100644 index 0000000..93a59fc --- /dev/null +++ b/benchmarks/README.md @@ -0,0 +1,7 @@ +## Preview benchmarks locally + +1. clone this repo +2. `cd benchmarks` +3. `asv run` will run the benchmarks on last commit (or `asv continuous base_commit_hash test_commit_hash` to run the benchmark to compare two commits) +4. `asv publish` will create a `html` folder with the results +5. `asv preview` will host the results locally at http://127.0.0.1:8080/ \ No newline at end of file diff --git a/benchmarks/asv.conf.json b/benchmarks/asv.conf.json new file mode 100644 index 0000000..3548a7e --- /dev/null +++ b/benchmarks/asv.conf.json @@ -0,0 +1,40 @@ +{ + "version": 1, + + "project": "nx-parallel", + + "project_url": "https://github.com/networkx/nx-parallel", + + "repo": "..", + + "branches": ["main"], + + "build_command": [ + "python -m pip install build hatchling", + "python -m build .", + "PIP_NO_BUILD_ISOLATION=false python -mpip wheel --no-deps --no-index -w {build_cache_dir} {build_dir}" + ], + + "install_command": ["in-dir={env_dir} python -mpip install {wheel_file}"], + + "dvcs": "git", + + "environment_type": "virtualenv", + + "show_commit_url": "https://github.com/networkx/nx-parallel/commit/", + + "matrix": { + "networkx":[], + "nx-parallel": [] + }, + + "benchmark_dir": "benchmarks", + + "env_dir": "env", + + "results_dir": "results", + + "html_dir": "html", + + "build_cache_size": 8 +} \ No newline at end of file diff --git a/benchmarks/benchmarks/__init__.py b/benchmarks/benchmarks/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/benchmarks/benchmarks/bench_centrality.py b/benchmarks/benchmarks/bench_centrality.py new file mode 100644 index 0000000..e483132 --- /dev/null +++ b/benchmarks/benchmarks/bench_centrality.py @@ -0,0 +1,22 @@ +import networkx as nx +import nx_parallel as nxp + + +class BetweennessCentralityBenchmark: + params = [("parallel", "normal")] + param_names = ["algo_type"] + + def setup(self, algo_type): + self.algo_type = algo_type + + def time_betweenness_centrality(self, algo_type): + num_nodes, edge_prob = 300, 0.5 + G = nx.fast_gnp_random_graph(num_nodes, edge_prob, directed=False) + if algo_type == "parallel": + H = nxp.ParallelGraph(G) + _ = nx.betweenness_centrality(H) + elif algo_type == "normal": + _ = nx.betweenness_centrality(G) + else: + raise ValueError("Unknown algo_type") + \ No newline at end of file From 7857b4a460f6ae3ba3409767acd34de730f99a7d Mon Sep 17 00:00:00 2001 From: Schefflera-Arboricola <1509aditi@gmail.com> Date: Fri, 3 Nov 2023 17:13:13 +0530 Subject: [PATCH 02/16] added common.py and parameters num_nodes and edge_prob(for betweenness_centrality) --- benchmarks/asv.conf.json | 4 +-- benchmarks/benchmarks/bench_centrality.py | 35 +++++++++-------------- benchmarks/benchmarks/common.py | 33 +++++++++++++++++++++ 3 files changed, 48 insertions(+), 24 deletions(-) create mode 100644 benchmarks/benchmarks/common.py diff --git a/benchmarks/asv.conf.json b/benchmarks/asv.conf.json index 3548a7e..a7432b1 100644 --- a/benchmarks/asv.conf.json +++ b/benchmarks/asv.conf.json @@ -23,9 +23,9 @@ "show_commit_url": "https://github.com/networkx/nx-parallel/commit/", - "matrix": { + "matrix": { "networkx":[], - "nx-parallel": [] + "nx-parallel": [] }, "benchmark_dir": "benchmarks", diff --git a/benchmarks/benchmarks/bench_centrality.py b/benchmarks/benchmarks/bench_centrality.py index e483132..6ab3a89 100644 --- a/benchmarks/benchmarks/bench_centrality.py +++ b/benchmarks/benchmarks/bench_centrality.py @@ -1,22 +1,13 @@ -import networkx as nx -import nx_parallel as nxp - - -class BetweennessCentralityBenchmark: - params = [("parallel", "normal")] - param_names = ["algo_type"] - - def setup(self, algo_type): - self.algo_type = algo_type - - def time_betweenness_centrality(self, algo_type): - num_nodes, edge_prob = 300, 0.5 - G = nx.fast_gnp_random_graph(num_nodes, edge_prob, directed=False) - if algo_type == "parallel": - H = nxp.ParallelGraph(G) - _ = nx.betweenness_centrality(H) - elif algo_type == "normal": - _ = nx.betweenness_centrality(G) - else: - raise ValueError("Unknown algo_type") - \ No newline at end of file +from .common import * + +class BetweennessCentralityBenchmark(Benchmark): + params = [ + (algo_types), + (num_nodes), + (edge_prob) + ] + param_names = ["algo_type","num_nodes","edge_prob"] + + def time_betweenness_centrality(self, algo_type, num_nodes, edge_prob): + G = get_graph(num_nodes, edge_prob) + standard_timing_func(G, algo_type, func = nx.betweenness_centrality) diff --git a/benchmarks/benchmarks/common.py b/benchmarks/benchmarks/common.py new file mode 100644 index 0000000..e517a5e --- /dev/null +++ b/benchmarks/benchmarks/common.py @@ -0,0 +1,33 @@ +from functools import lru_cache +from pathlib import Path + +import networkx as nx +import nx_parallel as nxp + + +CACHE_ROOT = Path(__file__).resolve().parent.parent / 'env' / 'nxp_benchdata' + +algo_types = ["parallel", "sequential"] +num_nodes = [10, 50, 100, 300, 500] +edge_prob = [1, 0.8, 0.6, 0.4, 0.2] + +@lru_cache(typed=True) +def get_graph(num_nodes, edge_prob): + G = nx.fast_gnp_random_graph(num_nodes, edge_prob, seed=42, directed=False) + return G + +def standard_timing_func(G, algo_type, func): + if algo_type == "parallel": + H = nxp.ParallelGraph(G) + _ = func(H) + elif algo_type == "sequential": + _ = func(G) + # if you want to use this then pls add "using_backend" in algo_types above in line 10 + #elif algo_type == "using_backend": + # _ = func(G, backend='parallel') + else: + raise ValueError("Unknown algo_type") + + +class Benchmark: + pass From 9f79e9a75566ec43c4b350f44ae30d7bfbcaea77 Mon Sep 17 00:00:00 2001 From: Schefflera-Arboricola <1509aditi@gmail.com> Date: Wed, 8 Nov 2023 15:57:44 +0530 Subject: [PATCH 03/16] some minor edits --- benchmarks/README.md | 4 +++- benchmarks/benchmarks/bench_centrality.py | 16 +++++++--------- benchmarks/benchmarks/common.py | 17 +++++++++++++---- 3 files changed, 23 insertions(+), 14 deletions(-) diff --git a/benchmarks/README.md b/benchmarks/README.md index 93a59fc..73d8088 100644 --- a/benchmarks/README.md +++ b/benchmarks/README.md @@ -2,6 +2,8 @@ 1. clone this repo 2. `cd benchmarks` -3. `asv run` will run the benchmarks on last commit (or `asv continuous base_commit_hash test_commit_hash` to run the benchmark to compare two commits) +3. `asv run` will run the benchmarks on last commit + - or use `asv continuous base_commit_hash test_commit_hash` to run the benchmark to compare two commits + - if you are running benchmarks for the first time, you would be asked to enter your machine information after this command. 4. `asv publish` will create a `html` folder with the results 5. `asv preview` will host the results locally at http://127.0.0.1:8080/ \ No newline at end of file diff --git a/benchmarks/benchmarks/bench_centrality.py b/benchmarks/benchmarks/bench_centrality.py index 6ab3a89..c6a89a7 100644 --- a/benchmarks/benchmarks/bench_centrality.py +++ b/benchmarks/benchmarks/bench_centrality.py @@ -1,13 +1,11 @@ from .common import * -class BetweennessCentralityBenchmark(Benchmark): - params = [ - (algo_types), - (num_nodes), - (edge_prob) - ] - param_names = ["algo_type","num_nodes","edge_prob"] +class BetweennessCentrality(Benchmark): + params = [(algo_types), + (num_nodes), + (edge_prob) + ] + param_names = ["algo_type", "num_nodes", "edge_prob"] def time_betweenness_centrality(self, algo_type, num_nodes, edge_prob): - G = get_graph(num_nodes, edge_prob) - standard_timing_func(G, algo_type, func = nx.betweenness_centrality) + timing_func(get_graph(num_nodes, edge_prob), algo_type, func = nx.betweenness_centrality) diff --git a/benchmarks/benchmarks/common.py b/benchmarks/benchmarks/common.py index e517a5e..75f67e9 100644 --- a/benchmarks/benchmarks/common.py +++ b/benchmarks/benchmarks/common.py @@ -1,5 +1,7 @@ from functools import lru_cache from pathlib import Path +import types +import random import networkx as nx import nx_parallel as nxp @@ -12,19 +14,26 @@ edge_prob = [1, 0.8, 0.6, 0.4, 0.2] @lru_cache(typed=True) -def get_graph(num_nodes, edge_prob): +def get_graph(num_nodes, edge_prob, is_weighted = False): G = nx.fast_gnp_random_graph(num_nodes, edge_prob, seed=42, directed=False) + if is_weighted: + random.seed(42) + for (u, v) in G.edges(): + G.edges[u, v]['weight'] = random.random() return G -def standard_timing_func(G, algo_type, func): +def timing_func(G, algo_type, func): if algo_type == "parallel": H = nxp.ParallelGraph(G) _ = func(H) + if type(_)==types.GeneratorType: d = dict(_) elif algo_type == "sequential": _ = func(G) - # if you want to use this then pls add "using_backend" in algo_types above in line 10 - #elif algo_type == "using_backend": + if type(_)==types.GeneratorType: d = dict(_) + # if you want to use the following, then pls add "using_kwargs" in `algo_types` above in line 12 + #elif algo_type == "using_kwargs": # _ = func(G, backend='parallel') + # if type(_)==types.GeneratorType: d = dict(_) else: raise ValueError("Unknown algo_type") From 31b504f8861aa2737983b8ea9b89195aaf2870df Mon Sep 17 00:00:00 2001 From: Schefflera-Arboricola <1509aditi@gmail.com> Date: Wed, 15 Nov 2023 10:12:20 +0530 Subject: [PATCH 04/16] added benchmarks for all other algos --- benchmarks/README.md | 1 + benchmarks/benchmarks/bench_centrality.py | 2 +- benchmarks/benchmarks/bench_efficiency_measures.py | 9 +++++++++ benchmarks/benchmarks/bench_isolate.py | 8 ++++++++ benchmarks/benchmarks/bench_tournament.py | 13 +++++++++++++ benchmarks/benchmarks/bench_vitality.py | 8 ++++++++ benchmarks/benchmarks/common.py | 8 ++++---- 7 files changed, 44 insertions(+), 5 deletions(-) create mode 100644 benchmarks/benchmarks/bench_efficiency_measures.py create mode 100644 benchmarks/benchmarks/bench_isolate.py create mode 100644 benchmarks/benchmarks/bench_tournament.py create mode 100644 benchmarks/benchmarks/bench_vitality.py diff --git a/benchmarks/README.md b/benchmarks/README.md index 73d8088..e81bb39 100644 --- a/benchmarks/README.md +++ b/benchmarks/README.md @@ -4,6 +4,7 @@ 2. `cd benchmarks` 3. `asv run` will run the benchmarks on last commit - or use `asv continuous base_commit_hash test_commit_hash` to run the benchmark to compare two commits + - or `asv run -b -k ` to run a particular benchmark. - if you are running benchmarks for the first time, you would be asked to enter your machine information after this command. 4. `asv publish` will create a `html` folder with the results 5. `asv preview` will host the results locally at http://127.0.0.1:8080/ \ No newline at end of file diff --git a/benchmarks/benchmarks/bench_centrality.py b/benchmarks/benchmarks/bench_centrality.py index c6a89a7..ec6e044 100644 --- a/benchmarks/benchmarks/bench_centrality.py +++ b/benchmarks/benchmarks/bench_centrality.py @@ -1,6 +1,6 @@ from .common import * -class BetweennessCentrality(Benchmark): +class Betweenness(Benchmark): params = [(algo_types), (num_nodes), (edge_prob) diff --git a/benchmarks/benchmarks/bench_efficiency_measures.py b/benchmarks/benchmarks/bench_efficiency_measures.py new file mode 100644 index 0000000..231e655 --- /dev/null +++ b/benchmarks/benchmarks/bench_efficiency_measures.py @@ -0,0 +1,9 @@ +from .common import * + +class EfficiencyMeasures(Benchmark): + params = [(algo_types), (num_nodes), (edge_prob)] + param_names = ["algo_type", "num_nodes", "edge_prob"] + + def time_local_efficiency(self, algotype, num_nodes, edge_prob): + timing_func(get_graph(num_nodes, edge_prob), algotype, func = nx.local_efficiency) + diff --git a/benchmarks/benchmarks/bench_isolate.py b/benchmarks/benchmarks/bench_isolate.py new file mode 100644 index 0000000..f2a7753 --- /dev/null +++ b/benchmarks/benchmarks/bench_isolate.py @@ -0,0 +1,8 @@ +from .common import * + +class Isolate(Benchmark): + params = [(algo_types), (num_nodes), (edge_prob)] + param_names = ["algo_type", "num_nodes", "edge_prob"] + + def time_number_of_isolates(self, algo_type, num_nodes, edge_prob): + timing_func(get_graph(num_nodes, edge_prob), algo_type, func = nx.number_of_isolates) diff --git a/benchmarks/benchmarks/bench_tournament.py b/benchmarks/benchmarks/bench_tournament.py new file mode 100644 index 0000000..8e1a0d2 --- /dev/null +++ b/benchmarks/benchmarks/bench_tournament.py @@ -0,0 +1,13 @@ +from .common import * + +def get_tournament_graph(num, seed = 42): + return nx.tournament.random_tournament(num, seed = seed) + + +class Tournament(Benchmark): + params = [(algo_types), (num_nodes)] + param_names = ["algo_type", "num_nodes"] + + def time_is_reachable(self, algo_type, num_nodes): + G = get_tournament_graph(num_nodes) + timing_func(G, algo_type, nx.tournament.is_reachable, 1, num_nodes) \ No newline at end of file diff --git a/benchmarks/benchmarks/bench_vitality.py b/benchmarks/benchmarks/bench_vitality.py new file mode 100644 index 0000000..27a2470 --- /dev/null +++ b/benchmarks/benchmarks/bench_vitality.py @@ -0,0 +1,8 @@ +from .common import * + +class Vitality(Benchmark): + params = [(algo_types), (num_nodes), (edge_prob)] + param_names = ["algo_type", "num_nodes", "edge_prob"] + + def time_closeness_vitality(self, algo_type, num_nodes, edge_prob): + timing_func(get_graph(num_nodes, edge_prob), algo_type, func = nx.closeness_vitality) diff --git a/benchmarks/benchmarks/common.py b/benchmarks/benchmarks/common.py index 75f67e9..9b2a672 100644 --- a/benchmarks/benchmarks/common.py +++ b/benchmarks/benchmarks/common.py @@ -22,17 +22,17 @@ def get_graph(num_nodes, edge_prob, is_weighted = False): G.edges[u, v]['weight'] = random.random() return G -def timing_func(G, algo_type, func): +def timing_func(G, algo_type, func, *args, **kwargs): if algo_type == "parallel": H = nxp.ParallelGraph(G) - _ = func(H) + _ = func(H, *args, **kwargs) if type(_)==types.GeneratorType: d = dict(_) elif algo_type == "sequential": - _ = func(G) + _ = func(G, *args, **kwargs) if type(_)==types.GeneratorType: d = dict(_) # if you want to use the following, then pls add "using_kwargs" in `algo_types` above in line 12 #elif algo_type == "using_kwargs": - # _ = func(G, backend='parallel') + # _ = func(G, *args, **kwargs, backend='parallel') # if type(_)==types.GeneratorType: d = dict(_) else: raise ValueError("Unknown algo_type") From c000f52b9401cb97e789c62f683a471bc42400cc Mon Sep 17 00:00:00 2001 From: Schefflera-Arboricola <1509aditi@gmail.com> Date: Sun, 26 Nov 2023 16:51:26 +0530 Subject: [PATCH 05/16] applied black and changed num_nodes and edge_prob --- benchmarks/asv.conf.json | 22 ++--------------- benchmarks/benchmarks/bench_centrality.py | 10 ++++---- .../benchmarks/bench_efficiency_measures.py | 4 ++-- benchmarks/benchmarks/bench_isolate.py | 5 +++- benchmarks/benchmarks/bench_tournament.py | 9 +++---- benchmarks/benchmarks/bench_vitality.py | 5 +++- benchmarks/benchmarks/common.py | 24 +++++++++++-------- 7 files changed, 36 insertions(+), 43 deletions(-) diff --git a/benchmarks/asv.conf.json b/benchmarks/asv.conf.json index a7432b1..af12fa9 100644 --- a/benchmarks/asv.conf.json +++ b/benchmarks/asv.conf.json @@ -1,40 +1,22 @@ { "version": 1, - "project": "nx-parallel", - "project_url": "https://github.com/networkx/nx-parallel", - "repo": "..", - "branches": ["main"], - "build_command": [ "python -m pip install build hatchling", "python -m build .", "PIP_NO_BUILD_ISOLATION=false python -mpip wheel --no-deps --no-index -w {build_cache_dir} {build_dir}" ], - "install_command": ["in-dir={env_dir} python -mpip install {wheel_file}"], - "dvcs": "git", - "environment_type": "virtualenv", - "show_commit_url": "https://github.com/networkx/nx-parallel/commit/", - - "matrix": { - "networkx":[], - "nx-parallel": [] - }, - + "matrix": {"networkx": [], "nx-parallel": []}, "benchmark_dir": "benchmarks", - "env_dir": "env", - "results_dir": "results", - "html_dir": "html", - "build_cache_size": 8 -} \ No newline at end of file +} diff --git a/benchmarks/benchmarks/bench_centrality.py b/benchmarks/benchmarks/bench_centrality.py index ec6e044..66f0e29 100644 --- a/benchmarks/benchmarks/bench_centrality.py +++ b/benchmarks/benchmarks/bench_centrality.py @@ -1,11 +1,11 @@ from .common import * + class Betweenness(Benchmark): - params = [(algo_types), - (num_nodes), - (edge_prob) - ] + params = [(algo_types), (num_nodes), (edge_prob)] param_names = ["algo_type", "num_nodes", "edge_prob"] def time_betweenness_centrality(self, algo_type, num_nodes, edge_prob): - timing_func(get_graph(num_nodes, edge_prob), algo_type, func = nx.betweenness_centrality) + timing_func( + get_graph(num_nodes, edge_prob), algo_type, func = nx.betweenness_centrality + ) diff --git a/benchmarks/benchmarks/bench_efficiency_measures.py b/benchmarks/benchmarks/bench_efficiency_measures.py index 231e655..0feac7d 100644 --- a/benchmarks/benchmarks/bench_efficiency_measures.py +++ b/benchmarks/benchmarks/bench_efficiency_measures.py @@ -1,9 +1,9 @@ from .common import * + class EfficiencyMeasures(Benchmark): params = [(algo_types), (num_nodes), (edge_prob)] param_names = ["algo_type", "num_nodes", "edge_prob"] def time_local_efficiency(self, algotype, num_nodes, edge_prob): - timing_func(get_graph(num_nodes, edge_prob), algotype, func = nx.local_efficiency) - + timing_func(get_graph(num_nodes, edge_prob), algotype, func=nx.local_efficiency) diff --git a/benchmarks/benchmarks/bench_isolate.py b/benchmarks/benchmarks/bench_isolate.py index f2a7753..cf0df5b 100644 --- a/benchmarks/benchmarks/bench_isolate.py +++ b/benchmarks/benchmarks/bench_isolate.py @@ -1,8 +1,11 @@ from .common import * + class Isolate(Benchmark): params = [(algo_types), (num_nodes), (edge_prob)] param_names = ["algo_type", "num_nodes", "edge_prob"] def time_number_of_isolates(self, algo_type, num_nodes, edge_prob): - timing_func(get_graph(num_nodes, edge_prob), algo_type, func = nx.number_of_isolates) + timing_func( + get_graph(num_nodes, edge_prob), algo_type, func=nx.number_of_isolates + ) diff --git a/benchmarks/benchmarks/bench_tournament.py b/benchmarks/benchmarks/bench_tournament.py index 8e1a0d2..3679845 100644 --- a/benchmarks/benchmarks/bench_tournament.py +++ b/benchmarks/benchmarks/bench_tournament.py @@ -1,13 +1,14 @@ from .common import * -def get_tournament_graph(num, seed = 42): - return nx.tournament.random_tournament(num, seed = seed) - +def get_tournament_graph(num, seed=42): + return nx.tournament.random_tournament(num, seed=seed) + + class Tournament(Benchmark): params = [(algo_types), (num_nodes)] param_names = ["algo_type", "num_nodes"] def time_is_reachable(self, algo_type, num_nodes): G = get_tournament_graph(num_nodes) - timing_func(G, algo_type, nx.tournament.is_reachable, 1, num_nodes) \ No newline at end of file + timing_func(G, algo_type, nx.tournament.is_reachable, 1, num_nodes) diff --git a/benchmarks/benchmarks/bench_vitality.py b/benchmarks/benchmarks/bench_vitality.py index 27a2470..684d144 100644 --- a/benchmarks/benchmarks/bench_vitality.py +++ b/benchmarks/benchmarks/bench_vitality.py @@ -1,8 +1,11 @@ from .common import * + class Vitality(Benchmark): params = [(algo_types), (num_nodes), (edge_prob)] param_names = ["algo_type", "num_nodes", "edge_prob"] def time_closeness_vitality(self, algo_type, num_nodes, edge_prob): - timing_func(get_graph(num_nodes, edge_prob), algo_type, func = nx.closeness_vitality) + timing_func( + get_graph(num_nodes, edge_prob), algo_type, func=nx.closeness_vitality + ) diff --git a/benchmarks/benchmarks/common.py b/benchmarks/benchmarks/common.py index 9b2a672..a00b321 100644 --- a/benchmarks/benchmarks/common.py +++ b/benchmarks/benchmarks/common.py @@ -7,35 +7,39 @@ import nx_parallel as nxp -CACHE_ROOT = Path(__file__).resolve().parent.parent / 'env' / 'nxp_benchdata' +CACHE_ROOT = Path(__file__).resolve().parent.parent / "env" / "nxp_benchdata" algo_types = ["parallel", "sequential"] -num_nodes = [10, 50, 100, 300, 500] -edge_prob = [1, 0.8, 0.6, 0.4, 0.2] +num_nodes = [50, 100, 200, 400, 800] +edge_prob = [0.8, 0.6, 0.4, 0.2] + @lru_cache(typed=True) -def get_graph(num_nodes, edge_prob, is_weighted = False): +def get_graph(num_nodes, edge_prob, is_weighted=False): G = nx.fast_gnp_random_graph(num_nodes, edge_prob, seed=42, directed=False) if is_weighted: random.seed(42) for (u, v) in G.edges(): - G.edges[u, v]['weight'] = random.random() + G.edges[u, v]["weight"] = random.random() return G + def timing_func(G, algo_type, func, *args, **kwargs): if algo_type == "parallel": - H = nxp.ParallelGraph(G) + H = nxp.ParallelGraph(G) _ = func(H, *args, **kwargs) - if type(_)==types.GeneratorType: d = dict(_) + if type(_) == types.GeneratorType: + d = dict(_) elif algo_type == "sequential": _ = func(G, *args, **kwargs) - if type(_)==types.GeneratorType: d = dict(_) + if type(_) == types.GeneratorType: + d = dict(_) # if you want to use the following, then pls add "using_kwargs" in `algo_types` above in line 12 - #elif algo_type == "using_kwargs": + # elif algo_type == "using_kwargs": # _ = func(G, *args, **kwargs, backend='parallel') # if type(_)==types.GeneratorType: d = dict(_) else: - raise ValueError("Unknown algo_type") + raise ValueError("Unknown algo_type") class Benchmark: From 2e9c8ab4d0423abbbc1dc7c1e3626248d5c2bca7 Mon Sep 17 00:00:00 2001 From: Schefflera-Arboricola <1509aditi@gmail.com> Date: Sun, 26 Nov 2023 18:00:33 +0530 Subject: [PATCH 06/16] updated init.py and common.py --- benchmarks/benchmarks/__init__.py | 1 + benchmarks/benchmarks/bench_centrality.py | 3 ++- benchmarks/benchmarks/bench_efficiency_measures.py | 1 + benchmarks/benchmarks/bench_isolate.py | 1 + benchmarks/benchmarks/bench_tournament.py | 1 + benchmarks/benchmarks/bench_vitality.py | 1 + benchmarks/benchmarks/common.py | 9 +++++++++ 7 files changed, 16 insertions(+), 1 deletion(-) diff --git a/benchmarks/benchmarks/__init__.py b/benchmarks/benchmarks/__init__.py index e69de29..55e5f84 100644 --- a/benchmarks/benchmarks/__init__.py +++ b/benchmarks/benchmarks/__init__.py @@ -0,0 +1 @@ +from .common import * diff --git a/benchmarks/benchmarks/bench_centrality.py b/benchmarks/benchmarks/bench_centrality.py index 66f0e29..825c50e 100644 --- a/benchmarks/benchmarks/bench_centrality.py +++ b/benchmarks/benchmarks/bench_centrality.py @@ -1,4 +1,5 @@ from .common import * +import networkx as nx class Betweenness(Benchmark): @@ -7,5 +8,5 @@ class Betweenness(Benchmark): def time_betweenness_centrality(self, algo_type, num_nodes, edge_prob): timing_func( - get_graph(num_nodes, edge_prob), algo_type, func = nx.betweenness_centrality + get_graph(num_nodes, edge_prob), algo_type, func=nx.betweenness_centrality ) diff --git a/benchmarks/benchmarks/bench_efficiency_measures.py b/benchmarks/benchmarks/bench_efficiency_measures.py index 0feac7d..3402d7a 100644 --- a/benchmarks/benchmarks/bench_efficiency_measures.py +++ b/benchmarks/benchmarks/bench_efficiency_measures.py @@ -1,4 +1,5 @@ from .common import * +import networkx as nx class EfficiencyMeasures(Benchmark): diff --git a/benchmarks/benchmarks/bench_isolate.py b/benchmarks/benchmarks/bench_isolate.py index cf0df5b..dcb6f06 100644 --- a/benchmarks/benchmarks/bench_isolate.py +++ b/benchmarks/benchmarks/bench_isolate.py @@ -1,4 +1,5 @@ from .common import * +import networkx as nx class Isolate(Benchmark): diff --git a/benchmarks/benchmarks/bench_tournament.py b/benchmarks/benchmarks/bench_tournament.py index 3679845..2b7350d 100644 --- a/benchmarks/benchmarks/bench_tournament.py +++ b/benchmarks/benchmarks/bench_tournament.py @@ -1,4 +1,5 @@ from .common import * +import networkx as nx def get_tournament_graph(num, seed=42): diff --git a/benchmarks/benchmarks/bench_vitality.py b/benchmarks/benchmarks/bench_vitality.py index 684d144..7bb0c67 100644 --- a/benchmarks/benchmarks/bench_vitality.py +++ b/benchmarks/benchmarks/bench_vitality.py @@ -1,4 +1,5 @@ from .common import * +import networkx as nx class Vitality(Benchmark): diff --git a/benchmarks/benchmarks/common.py b/benchmarks/benchmarks/common.py index a00b321..87ce0c4 100644 --- a/benchmarks/benchmarks/common.py +++ b/benchmarks/benchmarks/common.py @@ -6,6 +6,14 @@ import networkx as nx import nx_parallel as nxp +__all__ = [ + "get_graph", + "timing_func", + "Benchmark", + "algo_types", + "num_nodes", + "edge_prob", +] CACHE_ROOT = Path(__file__).resolve().parent.parent / "env" / "nxp_benchdata" @@ -16,6 +24,7 @@ @lru_cache(typed=True) def get_graph(num_nodes, edge_prob, is_weighted=False): + print("Generating graph") G = nx.fast_gnp_random_graph(num_nodes, edge_prob, seed=42, directed=False) if is_weighted: random.seed(42) From 77fedc5b7e7ed8384b3ee2cda2534fe0c4edbed6 Mon Sep 17 00:00:00 2001 From: Schefflera-Arboricola <1509aditi@gmail.com> Date: Mon, 27 Nov 2023 01:17:39 +0530 Subject: [PATCH 07/16] typo fix --- benchmarks/benchmarks/bench_efficiency_measures.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/benchmarks/benchmarks/bench_efficiency_measures.py b/benchmarks/benchmarks/bench_efficiency_measures.py index 3402d7a..1391b1d 100644 --- a/benchmarks/benchmarks/bench_efficiency_measures.py +++ b/benchmarks/benchmarks/bench_efficiency_measures.py @@ -6,5 +6,5 @@ class EfficiencyMeasures(Benchmark): params = [(algo_types), (num_nodes), (edge_prob)] param_names = ["algo_type", "num_nodes", "edge_prob"] - def time_local_efficiency(self, algotype, num_nodes, edge_prob): - timing_func(get_graph(num_nodes, edge_prob), algotype, func=nx.local_efficiency) + def time_local_efficiency(self, algo_type, num_nodes, edge_prob): + timing_func(get_graph(num_nodes, edge_prob), algo_type, func=nx.local_efficiency) From 26a4974374ac46e5fbec55a411fa1b6ba33500a3 Mon Sep 17 00:00:00 2001 From: Schefflera-Arboricola <1509aditi@gmail.com> Date: Mon, 27 Nov 2023 20:46:13 +0530 Subject: [PATCH 08/16] updateed README, removed timing_func, renamed algo_types to backends --- .gitignore | 2 +- benchmarks/README.md | 13 +++++++- benchmarks/benchmarks/bench_centrality.py | 11 ++++--- .../benchmarks/bench_efficiency_measures.py | 9 +++--- benchmarks/benchmarks/bench_isolate.py | 11 ++++--- benchmarks/benchmarks/bench_tournament.py | 14 ++++----- benchmarks/benchmarks/bench_vitality.py | 11 ++++--- benchmarks/benchmarks/common.py | 30 +++---------------- 8 files changed, 42 insertions(+), 59 deletions(-) diff --git a/.gitignore b/.gitignore index af44fdf..f300f72 100644 --- a/.gitignore +++ b/.gitignore @@ -130,4 +130,4 @@ dmypy.json # asv results/ -html/ \ No newline at end of file +html/ diff --git a/benchmarks/README.md b/benchmarks/README.md index e81bb39..4766e61 100644 --- a/benchmarks/README.md +++ b/benchmarks/README.md @@ -7,4 +7,15 @@ - or `asv run -b -k ` to run a particular benchmark. - if you are running benchmarks for the first time, you would be asked to enter your machine information after this command. 4. `asv publish` will create a `html` folder with the results -5. `asv preview` will host the results locally at http://127.0.0.1:8080/ \ No newline at end of file +5. `asv preview` will host the results locally at http://127.0.0.1:8080/ + +
+ +## Structure of benchmarks + +* Each `bench_` file corresponds to a folder/file in the [networkx/algorithms](https://github.com/networkx/networkx/tree/main/networkx/algorithms) directory in NetworkX +* Each class inside a `bench_` file corresponds to every file in a folder(one class if it’s a file) in networkx/algorithms +* The class name corresponds to the file name and the `x` in `bench_x` corresponds to the folder name(class name and `x` are same if it’s a file in networkx/algorithms) +* Each `time_` function corresponds to each function in the file. +* For other folders in [networkx/networkx](https://github.com/networkx/networkx/tree/main/networkx) like `generators`, `classes`, `linalg`, `utils` etc. we can have different `bench_` files for each of them having different classes corresponding to different files in each of these folders. +* For example : `bench_centrality.py` corresponds to `networkx/algorithms/centrality` folder in NetworkX and the `Betweenness` class inside it corresponds to `betweenness.py` file in `networkx/algorithms/centrality` folder in NetworkX. And the `time_betweenness_centrality` function corresponds to `betweenness_centrality` function. diff --git a/benchmarks/benchmarks/bench_centrality.py b/benchmarks/benchmarks/bench_centrality.py index 825c50e..fe55e2a 100644 --- a/benchmarks/benchmarks/bench_centrality.py +++ b/benchmarks/benchmarks/bench_centrality.py @@ -3,10 +3,9 @@ class Betweenness(Benchmark): - params = [(algo_types), (num_nodes), (edge_prob)] - param_names = ["algo_type", "num_nodes", "edge_prob"] + params = [(backends), (num_nodes), (edge_prob)] + param_names = ["backend", "num_nodes", "edge_prob"] - def time_betweenness_centrality(self, algo_type, num_nodes, edge_prob): - timing_func( - get_graph(num_nodes, edge_prob), algo_type, func=nx.betweenness_centrality - ) + def time_betweenness_centrality(self, backend, num_nodes, edge_prob): + G = get_graph(num_nodes, edge_prob) + _ = nx.betweenness_centrality(G, backend=backend) diff --git a/benchmarks/benchmarks/bench_efficiency_measures.py b/benchmarks/benchmarks/bench_efficiency_measures.py index 1391b1d..0cee54c 100644 --- a/benchmarks/benchmarks/bench_efficiency_measures.py +++ b/benchmarks/benchmarks/bench_efficiency_measures.py @@ -3,8 +3,9 @@ class EfficiencyMeasures(Benchmark): - params = [(algo_types), (num_nodes), (edge_prob)] - param_names = ["algo_type", "num_nodes", "edge_prob"] + params = [(backends), (num_nodes), (edge_prob)] + param_names = ["backend", "num_nodes", "edge_prob"] - def time_local_efficiency(self, algo_type, num_nodes, edge_prob): - timing_func(get_graph(num_nodes, edge_prob), algo_type, func=nx.local_efficiency) + def time_local_efficiency(self, backend, num_nodes, edge_prob): + G = get_graph(num_nodes, edge_prob) + _ = nx.local_efficiency(G, backend=backend) diff --git a/benchmarks/benchmarks/bench_isolate.py b/benchmarks/benchmarks/bench_isolate.py index dcb6f06..c6fe297 100644 --- a/benchmarks/benchmarks/bench_isolate.py +++ b/benchmarks/benchmarks/bench_isolate.py @@ -3,10 +3,9 @@ class Isolate(Benchmark): - params = [(algo_types), (num_nodes), (edge_prob)] - param_names = ["algo_type", "num_nodes", "edge_prob"] + params = [(backends), (num_nodes), (edge_prob)] + param_names = ["backend", "num_nodes", "edge_prob"] - def time_number_of_isolates(self, algo_type, num_nodes, edge_prob): - timing_func( - get_graph(num_nodes, edge_prob), algo_type, func=nx.number_of_isolates - ) + def time_number_of_isolates(self, backend, num_nodes, edge_prob): + G = get_graph(num_nodes, edge_prob) + _ = nx.number_of_isolates(G, backend=backend) diff --git a/benchmarks/benchmarks/bench_tournament.py b/benchmarks/benchmarks/bench_tournament.py index 2b7350d..1337b76 100644 --- a/benchmarks/benchmarks/bench_tournament.py +++ b/benchmarks/benchmarks/bench_tournament.py @@ -2,14 +2,10 @@ import networkx as nx -def get_tournament_graph(num, seed=42): - return nx.tournament.random_tournament(num, seed=seed) - - class Tournament(Benchmark): - params = [(algo_types), (num_nodes)] - param_names = ["algo_type", "num_nodes"] + params = [(backends), (num_nodes)] + param_names = ["backend", "num_nodes"] - def time_is_reachable(self, algo_type, num_nodes): - G = get_tournament_graph(num_nodes) - timing_func(G, algo_type, nx.tournament.is_reachable, 1, num_nodes) + def time_is_reachable(self, backend, num_nodes): + G = nx.tournament.random_tournament(num_nodes, seed=42) + _ = nx.tournament.is_reachable(G, 1, num_nodes, backend=backend) diff --git a/benchmarks/benchmarks/bench_vitality.py b/benchmarks/benchmarks/bench_vitality.py index 7bb0c67..8724138 100644 --- a/benchmarks/benchmarks/bench_vitality.py +++ b/benchmarks/benchmarks/bench_vitality.py @@ -3,10 +3,9 @@ class Vitality(Benchmark): - params = [(algo_types), (num_nodes), (edge_prob)] - param_names = ["algo_type", "num_nodes", "edge_prob"] + params = [(backends), (num_nodes), (edge_prob)] + param_names = ["backend", "num_nodes", "edge_prob"] - def time_closeness_vitality(self, algo_type, num_nodes, edge_prob): - timing_func( - get_graph(num_nodes, edge_prob), algo_type, func=nx.closeness_vitality - ) + def time_closeness_vitality(self, backend, num_nodes, edge_prob): + G = get_graph(num_nodes, edge_prob) + _ = nx.closeness_vitality(G, backend=backend) diff --git a/benchmarks/benchmarks/common.py b/benchmarks/benchmarks/common.py index 87ce0c4..4d6d4b7 100644 --- a/benchmarks/benchmarks/common.py +++ b/benchmarks/benchmarks/common.py @@ -1,30 +1,26 @@ from functools import lru_cache from pathlib import Path -import types import random import networkx as nx -import nx_parallel as nxp __all__ = [ - "get_graph", - "timing_func", - "Benchmark", - "algo_types", + "backends", "num_nodes", "edge_prob", + "get_graph", + "Benchmark", ] CACHE_ROOT = Path(__file__).resolve().parent.parent / "env" / "nxp_benchdata" -algo_types = ["parallel", "sequential"] +backends = ["parallel", None] num_nodes = [50, 100, 200, 400, 800] edge_prob = [0.8, 0.6, 0.4, 0.2] @lru_cache(typed=True) def get_graph(num_nodes, edge_prob, is_weighted=False): - print("Generating graph") G = nx.fast_gnp_random_graph(num_nodes, edge_prob, seed=42, directed=False) if is_weighted: random.seed(42) @@ -33,23 +29,5 @@ def get_graph(num_nodes, edge_prob, is_weighted=False): return G -def timing_func(G, algo_type, func, *args, **kwargs): - if algo_type == "parallel": - H = nxp.ParallelGraph(G) - _ = func(H, *args, **kwargs) - if type(_) == types.GeneratorType: - d = dict(_) - elif algo_type == "sequential": - _ = func(G, *args, **kwargs) - if type(_) == types.GeneratorType: - d = dict(_) - # if you want to use the following, then pls add "using_kwargs" in `algo_types` above in line 12 - # elif algo_type == "using_kwargs": - # _ = func(G, *args, **kwargs, backend='parallel') - # if type(_)==types.GeneratorType: d = dict(_) - else: - raise ValueError("Unknown algo_type") - - class Benchmark: pass From 06ef1aec1a5efece5c693a05bcf15a1f073389bd Mon Sep 17 00:00:00 2001 From: Schefflera-Arboricola <1509aditi@gmail.com> Date: Mon, 27 Nov 2023 21:25:11 +0530 Subject: [PATCH 09/16] renamed get_graph to get_cached_gnp_random_graph --- benchmarks/benchmarks/bench_centrality.py | 2 +- benchmarks/benchmarks/bench_efficiency_measures.py | 2 +- benchmarks/benchmarks/bench_isolate.py | 2 +- benchmarks/benchmarks/bench_vitality.py | 2 +- benchmarks/benchmarks/common.py | 4 ++-- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/benchmarks/benchmarks/bench_centrality.py b/benchmarks/benchmarks/bench_centrality.py index fe55e2a..3275bb7 100644 --- a/benchmarks/benchmarks/bench_centrality.py +++ b/benchmarks/benchmarks/bench_centrality.py @@ -7,5 +7,5 @@ class Betweenness(Benchmark): param_names = ["backend", "num_nodes", "edge_prob"] def time_betweenness_centrality(self, backend, num_nodes, edge_prob): - G = get_graph(num_nodes, edge_prob) + G = cached_gnp_random_graph(num_nodes, edge_prob) _ = nx.betweenness_centrality(G, backend=backend) diff --git a/benchmarks/benchmarks/bench_efficiency_measures.py b/benchmarks/benchmarks/bench_efficiency_measures.py index 0cee54c..7ca4e12 100644 --- a/benchmarks/benchmarks/bench_efficiency_measures.py +++ b/benchmarks/benchmarks/bench_efficiency_measures.py @@ -7,5 +7,5 @@ class EfficiencyMeasures(Benchmark): param_names = ["backend", "num_nodes", "edge_prob"] def time_local_efficiency(self, backend, num_nodes, edge_prob): - G = get_graph(num_nodes, edge_prob) + G = cached_gnp_random_graph(num_nodes, edge_prob) _ = nx.local_efficiency(G, backend=backend) diff --git a/benchmarks/benchmarks/bench_isolate.py b/benchmarks/benchmarks/bench_isolate.py index c6fe297..f0005b3 100644 --- a/benchmarks/benchmarks/bench_isolate.py +++ b/benchmarks/benchmarks/bench_isolate.py @@ -7,5 +7,5 @@ class Isolate(Benchmark): param_names = ["backend", "num_nodes", "edge_prob"] def time_number_of_isolates(self, backend, num_nodes, edge_prob): - G = get_graph(num_nodes, edge_prob) + G = cached_gnp_random_graph(num_nodes, edge_prob) _ = nx.number_of_isolates(G, backend=backend) diff --git a/benchmarks/benchmarks/bench_vitality.py b/benchmarks/benchmarks/bench_vitality.py index 8724138..56698d0 100644 --- a/benchmarks/benchmarks/bench_vitality.py +++ b/benchmarks/benchmarks/bench_vitality.py @@ -7,5 +7,5 @@ class Vitality(Benchmark): param_names = ["backend", "num_nodes", "edge_prob"] def time_closeness_vitality(self, backend, num_nodes, edge_prob): - G = get_graph(num_nodes, edge_prob) + G = cached_gnp_random_graph(num_nodes, edge_prob) _ = nx.closeness_vitality(G, backend=backend) diff --git a/benchmarks/benchmarks/common.py b/benchmarks/benchmarks/common.py index 4d6d4b7..9b71793 100644 --- a/benchmarks/benchmarks/common.py +++ b/benchmarks/benchmarks/common.py @@ -8,7 +8,7 @@ "backends", "num_nodes", "edge_prob", - "get_graph", + "cached_gnp_random_graph", "Benchmark", ] @@ -20,7 +20,7 @@ @lru_cache(typed=True) -def get_graph(num_nodes, edge_prob, is_weighted=False): +def cached_gnp_random_graph(num_nodes, edge_prob, is_weighted=False): G = nx.fast_gnp_random_graph(num_nodes, edge_prob, seed=42, directed=False) if is_weighted: random.seed(42) From f8e417d9204741bdea3ebf91d0635b3f23aef654 Mon Sep 17 00:00:00 2001 From: Schefflera-Arboricola <1509aditi@gmail.com> Date: Mon, 27 Nov 2023 22:12:48 +0530 Subject: [PATCH 10/16] renamed get_graph to get_cached_gnp_random_graph --- benchmarks/benchmarks/bench_centrality.py | 2 +- benchmarks/benchmarks/bench_efficiency_measures.py | 2 +- benchmarks/benchmarks/bench_isolate.py | 2 +- benchmarks/benchmarks/bench_vitality.py | 2 +- benchmarks/benchmarks/common.py | 4 ++-- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/benchmarks/benchmarks/bench_centrality.py b/benchmarks/benchmarks/bench_centrality.py index 3275bb7..885dd12 100644 --- a/benchmarks/benchmarks/bench_centrality.py +++ b/benchmarks/benchmarks/bench_centrality.py @@ -7,5 +7,5 @@ class Betweenness(Benchmark): param_names = ["backend", "num_nodes", "edge_prob"] def time_betweenness_centrality(self, backend, num_nodes, edge_prob): - G = cached_gnp_random_graph(num_nodes, edge_prob) + G = get_cached_gnp_random_graph(num_nodes, edge_prob) _ = nx.betweenness_centrality(G, backend=backend) diff --git a/benchmarks/benchmarks/bench_efficiency_measures.py b/benchmarks/benchmarks/bench_efficiency_measures.py index 7ca4e12..aa0659f 100644 --- a/benchmarks/benchmarks/bench_efficiency_measures.py +++ b/benchmarks/benchmarks/bench_efficiency_measures.py @@ -7,5 +7,5 @@ class EfficiencyMeasures(Benchmark): param_names = ["backend", "num_nodes", "edge_prob"] def time_local_efficiency(self, backend, num_nodes, edge_prob): - G = cached_gnp_random_graph(num_nodes, edge_prob) + G = get_cached_gnp_random_graph(num_nodes, edge_prob) _ = nx.local_efficiency(G, backend=backend) diff --git a/benchmarks/benchmarks/bench_isolate.py b/benchmarks/benchmarks/bench_isolate.py index f0005b3..a011847 100644 --- a/benchmarks/benchmarks/bench_isolate.py +++ b/benchmarks/benchmarks/bench_isolate.py @@ -7,5 +7,5 @@ class Isolate(Benchmark): param_names = ["backend", "num_nodes", "edge_prob"] def time_number_of_isolates(self, backend, num_nodes, edge_prob): - G = cached_gnp_random_graph(num_nodes, edge_prob) + G = get_cached_gnp_random_graph(num_nodes, edge_prob) _ = nx.number_of_isolates(G, backend=backend) diff --git a/benchmarks/benchmarks/bench_vitality.py b/benchmarks/benchmarks/bench_vitality.py index 56698d0..57ff402 100644 --- a/benchmarks/benchmarks/bench_vitality.py +++ b/benchmarks/benchmarks/bench_vitality.py @@ -7,5 +7,5 @@ class Vitality(Benchmark): param_names = ["backend", "num_nodes", "edge_prob"] def time_closeness_vitality(self, backend, num_nodes, edge_prob): - G = cached_gnp_random_graph(num_nodes, edge_prob) + G = get_cached_gnp_random_graph(num_nodes, edge_prob) _ = nx.closeness_vitality(G, backend=backend) diff --git a/benchmarks/benchmarks/common.py b/benchmarks/benchmarks/common.py index 9b71793..0d84f0b 100644 --- a/benchmarks/benchmarks/common.py +++ b/benchmarks/benchmarks/common.py @@ -8,7 +8,7 @@ "backends", "num_nodes", "edge_prob", - "cached_gnp_random_graph", + "get_cached_gnp_random_graph", "Benchmark", ] @@ -20,7 +20,7 @@ @lru_cache(typed=True) -def cached_gnp_random_graph(num_nodes, edge_prob, is_weighted=False): +def get_cached_gnp_random_graph(num_nodes, edge_prob, is_weighted=False): G = nx.fast_gnp_random_graph(num_nodes, edge_prob, seed=42, directed=False) if is_weighted: random.seed(42) From 8b04a871406d263444c92898ba96cf277d6c33e5 Mon Sep 17 00:00:00 2001 From: Schefflera-Arboricola <1509aditi@gmail.com> Date: Wed, 13 Dec 2023 08:52:17 +0530 Subject: [PATCH 11/16] added bench_shortest_paths.py --- benchmarks/benchmarks/bench_shortest_paths.py | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 benchmarks/benchmarks/bench_shortest_paths.py diff --git a/benchmarks/benchmarks/bench_shortest_paths.py b/benchmarks/benchmarks/bench_shortest_paths.py new file mode 100644 index 0000000..3f13014 --- /dev/null +++ b/benchmarks/benchmarks/bench_shortest_paths.py @@ -0,0 +1,11 @@ +from .common import * +import networkx as nx + + +class Weighted(Benchmark): + params = [(backends), (num_nodes), (edge_prob)] + param_names = ["backend", "num_nodes", "edge_prob"] + + def time_all_pairs_bellman_ford_path(self, backend, num_nodes, edge_prob): + G = get_cached_gnp_random_graph(num_nodes, edge_prob, is_weighted=True) + _ = nx.all_pairs_bellman_ford_path(G, backend=backend) From f80516975da7831afc21e59fcb8f564c9e61336a Mon Sep 17 00:00:00 2001 From: Aditi Juneja <91629733+Schefflera-Arboricola@users.noreply.github.com> Date: Mon, 18 Dec 2023 05:20:08 +0530 Subject: [PATCH 12/16] added dict() --- benchmarks/benchmarks/bench_shortest_paths.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/benchmarks/benchmarks/bench_shortest_paths.py b/benchmarks/benchmarks/bench_shortest_paths.py index 3f13014..dead06b 100644 --- a/benchmarks/benchmarks/bench_shortest_paths.py +++ b/benchmarks/benchmarks/bench_shortest_paths.py @@ -8,4 +8,4 @@ class Weighted(Benchmark): def time_all_pairs_bellman_ford_path(self, backend, num_nodes, edge_prob): G = get_cached_gnp_random_graph(num_nodes, edge_prob, is_weighted=True) - _ = nx.all_pairs_bellman_ford_path(G, backend=backend) + _ = dict(nx.all_pairs_bellman_ford_path(G, backend=backend)) From 6f8d0d3c61b64988a5d18125a6cece4c22dce7e2 Mon Sep 17 00:00:00 2001 From: Aditi Juneja <91629733+Schefflera-Arboricola@users.noreply.github.com> Date: Mon, 1 Jan 2024 17:19:34 +0530 Subject: [PATCH 13/16] Updated __init__.py --- benchmarks/benchmarks/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/benchmarks/benchmarks/__init__.py b/benchmarks/benchmarks/__init__.py index 55e5f84..8b13789 100644 --- a/benchmarks/benchmarks/__init__.py +++ b/benchmarks/benchmarks/__init__.py @@ -1 +1 @@ -from .common import * + From e40ac1e405badb2d5f3f12961c09bbf00133a81b Mon Sep 17 00:00:00 2001 From: Aditi Juneja <91629733+Schefflera-Arboricola@users.noreply.github.com> Date: Tue, 2 Jan 2024 17:45:43 +0530 Subject: [PATCH 14/16] Updated asv.conf.json --- benchmarks/asv.conf.json | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/benchmarks/asv.conf.json b/benchmarks/asv.conf.json index af12fa9..2cc72a7 100644 --- a/benchmarks/asv.conf.json +++ b/benchmarks/asv.conf.json @@ -5,15 +5,13 @@ "repo": "..", "branches": ["main"], "build_command": [ - "python -m pip install build hatchling", - "python -m build .", - "PIP_NO_BUILD_ISOLATION=false python -mpip wheel --no-deps --no-index -w {build_cache_dir} {build_dir}" + "python -m pip install build", + "python -m build --wheel -o {build_cache_dir} {build_dir}" ], - "install_command": ["in-dir={env_dir} python -mpip install {wheel_file}"], "dvcs": "git", "environment_type": "virtualenv", "show_commit_url": "https://github.com/networkx/nx-parallel/commit/", - "matrix": {"networkx": [], "nx-parallel": []}, + "matrix": {"networkx": ["3.2"], "nx-parallel": []}, "benchmark_dir": "benchmarks", "env_dir": "env", "results_dir": "results", From c3d6b7fb12e69f682bb8a810985263ceb168a071 Mon Sep 17 00:00:00 2001 From: Aditi Juneja <91629733+Schefflera-Arboricola@users.noreply.github.com> Date: Tue, 2 Jan 2024 18:42:48 +0530 Subject: [PATCH 15/16] replaced networkx.plugins with networkx.backends and updated readme (#26) * replaced networkx.plugins with networkx.backends * Updated README.md --- README.md | 18 ++++++++---------- pyproject.toml | 2 +- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index ac3240c..5291894 100644 --- a/README.md +++ b/README.md @@ -1,20 +1,18 @@ ## nx-parallel -nx-parallel is a NetworkX backend plugin that uses joblib and multiprocessing for parallelization. This project aims to provide parallelized implementations of various NetworkX functions to improve performance. +nx-parallel is a NetworkX backend that uses joblib for parallelization. This project aims to provide parallelized implementations of various NetworkX functions to improve performance. ## Features nx-parallel provides parallelized implementations for the following NetworkX functions: -``` -├── centrality -│ ├── betweenness_centrality -│ ├── closeness_vitality -├── tournament -│ ├── is_reachable -├── efficiency_measures -│ ├── local_efficiency -``` +- [betweeness_centrality](https://github.com/networkx/nx-parallel/blob/main/nx_parallel/algorithms/centrality/betweenness.py#L17) +- [local_efficiency](https://github.com/networkx/nx-parallel/blob/main/nx_parallel/algorithms/efficiency_measures.py#L12) +- [number_of_isolates](https://github.com/networkx/nx-parallel/blob/main/nx_parallel/algorithms/isolate.py#L9) +- [all_pairs_bellman_ford_path](https://github.com/networkx/nx-parallel/blob/main/nx_parallel/algorithms/shortest_paths/weighted.py#L9) +- [is_reachable](https://github.com/networkx/nx-parallel/blob/main/nx_parallel/algorithms/tournament.py#L11) +- [tournament_is_strongly_connected](https://github.com/networkx/nx-parallel/blob/main/nx_parallel/algorithms/tournament.py#L103) +- [closeness_vitality](https://github.com/networkx/nx-parallel/blob/main/nx_parallel/algorithms/vitality.py#L9) ![alt text](timing/heatmap_all_functions.png) diff --git a/pyproject.toml b/pyproject.toml index 5f09069..61e12ab 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -30,7 +30,7 @@ developer = [ 'pytest', ] -[project.entry-points."networkx.plugins"] +[project.entry-points."networkx.backends"] parallel = "nx_parallel.interface:Dispatcher" [tool.setuptools] From 5aba95e90758e7cda94a6f76b749f16475b463b8 Mon Sep 17 00:00:00 2001 From: Aditi Juneja <91629733+Schefflera-Arboricola@users.noreply.github.com> Date: Fri, 5 Jan 2024 20:31:09 +0530 Subject: [PATCH 16/16] Updated README.md --- benchmarks/README.md | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/benchmarks/README.md b/benchmarks/README.md index 4766e61..4097852 100644 --- a/benchmarks/README.md +++ b/benchmarks/README.md @@ -2,12 +2,13 @@ 1. clone this repo 2. `cd benchmarks` -3. `asv run` will run the benchmarks on last commit +3. If you are working on a different branch then update the `branches` in the `asv.conf.json` file. +4. `asv run` will run the benchmarks on the last commit - or use `asv continuous base_commit_hash test_commit_hash` to run the benchmark to compare two commits - or `asv run -b -k ` to run a particular benchmark. - - if you are running benchmarks for the first time, you would be asked to enter your machine information after this command. -4. `asv publish` will create a `html` folder with the results -5. `asv preview` will host the results locally at http://127.0.0.1:8080/ + - if you are running benchmarks for the first time, you will be asked to enter your machine information after this command. +5. `asv publish` will create a `html` folder with the results +6. `asv preview` will host the results locally at http://127.0.0.1:8080/
@@ -15,7 +16,7 @@ * Each `bench_` file corresponds to a folder/file in the [networkx/algorithms](https://github.com/networkx/networkx/tree/main/networkx/algorithms) directory in NetworkX * Each class inside a `bench_` file corresponds to every file in a folder(one class if it’s a file) in networkx/algorithms -* The class name corresponds to the file name and the `x` in `bench_x` corresponds to the folder name(class name and `x` are same if it’s a file in networkx/algorithms) +* The class name corresponds to the file name and the `x` in `bench_x` corresponds to the folder name(class name and `x` are the same if it’s a file in networkx/algorithms) * Each `time_` function corresponds to each function in the file. * For other folders in [networkx/networkx](https://github.com/networkx/networkx/tree/main/networkx) like `generators`, `classes`, `linalg`, `utils` etc. we can have different `bench_` files for each of them having different classes corresponding to different files in each of these folders. -* For example : `bench_centrality.py` corresponds to `networkx/algorithms/centrality` folder in NetworkX and the `Betweenness` class inside it corresponds to `betweenness.py` file in `networkx/algorithms/centrality` folder in NetworkX. And the `time_betweenness_centrality` function corresponds to `betweenness_centrality` function. +* For example: `bench_centrality.py` corresponds to `networkx/algorithms/centrality` folder in NetworkX and the `Betweenness` class inside it corresponds to the `betweenness.py` file in `networkx/algorithms/centrality` folder in NetworkX. And the `time_betweenness_centrality` function corresponds to the `betweenness_centrality` function.