-
Notifications
You must be signed in to change notification settings - Fork 5
Add a few igraph algorithms to run via scripts/bench.py
#54
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
973fb1c
ec81bd1
4bcc817
8e58900
76ab622
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14,6 +14,7 @@ | |
import scipy.sparse | ||
|
||
import graphblas_algorithms as ga | ||
import igraph_impl | ||
import scipy_impl | ||
from graphblas_algorithms.interface import Dispatcher | ||
|
||
|
@@ -56,13 +57,20 @@ def readfile(filepath, is_symmetric, backend): | |
return ga.Graph(A) | ||
return ga.DiGraph(A) | ||
a = scipy.io.mmread(filepath) | ||
if backend == "networkx": | ||
if backend in {"networkx", "igraph"}: | ||
create_using = nx.Graph if is_symmetric else nx.DiGraph | ||
return nx.from_scipy_sparse_array(a, create_using=create_using) | ||
G = nx.from_scipy_sparse_array(a, create_using=create_using) | ||
if backend == "networkx": | ||
return G | ||
if backend == "igraph": | ||
# TODO: is there a better way for igraph to read MM files or scipy.sparse arrays? | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
You can use There is no direct support for reading MM files in igraph. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just what I was looking for, thanks! |
||
import igraph | ||
|
||
return igraph.Graph.from_networkx(G) | ||
if backend == "scipy": | ||
return scipy.sparse.csr_array(a) | ||
raise ValueError( | ||
f"Backend {backend!r} not understood; must be 'graphblas', 'networkx', or 'scipy'" | ||
f"Backend {backend!r} not understood; must be 'graphblas', 'networkx', 'igraph', or 'scipy'" | ||
) | ||
|
||
|
||
|
@@ -126,6 +134,8 @@ def getfunction(functionname, backend): | |
return getattr(Dispatcher, functionname) | ||
if backend == "scipy": | ||
return getattr(scipy_impl, functionname) | ||
if backend == "igraph": | ||
return getattr(igraph_impl, functionname) | ||
if functionname in functionpaths: | ||
func = nx | ||
for attr in functionpaths[functionname].split("."): | ||
|
@@ -149,7 +159,15 @@ def getgraph(dataname, backend="graphblas", functionname=None): | |
|
||
|
||
def main( | ||
dataname, backend, functionname, time=3.0, n=None, extra=None, display=True, enable_gc=False | ||
dataname, | ||
backend, | ||
functionname, | ||
time=3.0, | ||
n=None, | ||
min_n=None, | ||
extra=None, | ||
display=True, | ||
enable_gc=False, | ||
): | ||
G = getgraph(dataname, backend, functionname) | ||
func = getfunction(functionname, backend) | ||
|
@@ -193,6 +211,8 @@ def main( | |
n = 1 | ||
elif n is None: | ||
n = 2 ** max(0, int(np.ceil(np.log2(time / first_time)))) | ||
if min_n is not None: | ||
n = max(n, min_n) | ||
if display: | ||
print("Number of runs:", n) | ||
print("first: ", stime(first_time)) | ||
|
@@ -222,7 +242,7 @@ def main( | |
description=f"Example usage: python {sys.argv[0]} -b graphblas -f pagerank -d amazon0302" | ||
) | ||
parser.add_argument( | ||
"-b", "--backend", choices=["graphblas", "networkx", "scipy"], default="graphblas" | ||
"-b", "--backend", choices=["graphblas", "networkx", "scipy", "igraph"], default="graphblas" | ||
) | ||
parser.add_argument( | ||
"-t", "--time", type=float, default=3.0, help="Target minimum time to run benchmarks" | ||
|
@@ -232,6 +252,11 @@ def main( | |
type=int, | ||
help="The number of times to run the benchmark (the default is to run according to time)", | ||
) | ||
parser.add_argument( | ||
"--min-n", | ||
type=int, | ||
help="The minimum number of times to run the benchmark", | ||
) | ||
parser.add_argument( | ||
"-d", | ||
"--data", | ||
|
@@ -260,6 +285,7 @@ def main( | |
args.func, | ||
time=args.time, | ||
n=args.n, | ||
min_n=args.min_n, | ||
extra=args.extra, | ||
display=not args.json, | ||
enable_gc=args.gc, | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
def overall_reciprocity(G): | ||
return G.reciprocity() | ||
|
||
|
||
def pagerank( | ||
G, | ||
alpha=0.85, | ||
personalization=None, | ||
max_iter=100, | ||
tol=1e-06, | ||
nstart=None, | ||
weight="weight", | ||
dangling=None, | ||
*, | ||
vertices=None, | ||
directed=True, | ||
arpack_options=None, | ||
implementation="prpack", | ||
): | ||
if personalization is not None: | ||
raise NotImplementedError | ||
|
||
if nstart is not None: | ||
raise NotImplementedError | ||
if dangling is not None: | ||
raise NotImplementedError | ||
|
||
rv = G.pagerank( | ||
vertices=vertices, | ||
directed=directed, | ||
damping=alpha, | ||
weights=weight, | ||
arpack_options=arpack_options, | ||
implementation=implementation, | ||
) | ||
return rv | ||
|
||
|
||
def transitivity(G): | ||
return G.transitivity_undirected() | ||
|
||
|
||
def average_clustering(G, nodes=None, weight=None, count_zeros=True): | ||
if nodes is not None: | ||
raise NotImplementedError | ||
# TODO: check results when `count_zeros=False` | ||
mode = "zero" if count_zeros else "nan" | ||
Comment on lines
+44
to
+45
|
||
return G.transitivity_avglocal_undirected(mode=mode, weights=weight) | ||
|
||
|
||
def clustering(G, nodes=None, weight=None): | ||
mode = "zero" # or "nan" | ||
return G.transitivity_local_undirected(vertices=nodes, mode=mode, weights=weight) |