forked from rapidsai/cugraph
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request rapidsai#47 from jwyles/bfs_first
BFS imported and python bindings added.
- Loading branch information
Showing
12 changed files
with
2,575 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
from c_bfs cimport * | ||
from libcpp cimport bool | ||
from libc.stdint cimport uintptr_t | ||
from libc.stdlib cimport calloc, malloc, free | ||
import cudf | ||
from librmm_cffi import librmm as rmm | ||
#from pygdf import Column | ||
import numpy as np | ||
|
||
cpdef bfs(G, start, directed=True): | ||
""" | ||
Find the distances and predecessors for a breadth first traversal of a graph. | ||
Parameters | ||
---------- | ||
G : cugraph.graph | ||
cuGraph graph descriptor, should contain the connectivity information as an | ||
adjacency list. | ||
start : Integer | ||
The index of the graph vertex from which the traversal begins | ||
directed : bool | ||
Indicates whether the graph in question is a directed graph, or whether | ||
each edge has a corresponding reverse edge. (Allows optimizations if the | ||
graph is undirected) | ||
Returns | ||
------- | ||
df : cudf.DataFrame | ||
df['vertex'][i] gives the vertex id of the i'th vertex | ||
df['distance'][i] gives the path distance for the i'th vertex from the starting vertex | ||
df['predecessor'][i] gives for the i'th vertex the vertex it was reached from in the traversal | ||
Examples | ||
-------- | ||
>>> M = ReadMtxFile(graph_file) | ||
>>> sources = cudf.Series(M.row) | ||
>>> destinations = cudf.Series(M.col) | ||
>>> G = cuGraph.Graph() | ||
>>> G.add_edge_list(sources,destinations,none) | ||
>>> dist, pred = cuGraph.bfs(G, 0, false) | ||
""" | ||
|
||
cdef uintptr_t graph = G.graph_ptr | ||
cdef gdf_graph* g = <gdf_graph*>graph | ||
num_verts = g.adjList.offsets.size - 1 | ||
|
||
df = cudf.DataFrame() | ||
df['vertex'] = cudf.Series(np.zeros(num_verts, dtype=np.int32)) | ||
cdef uintptr_t vertex_ptr = create_column(df['vertex']) | ||
df['distance'] = cudf.Series(np.zeros(num_verts, dtype=np.int32)) | ||
cdef uintptr_t distances_ptr = create_column(df['distance']) | ||
df['predecessor'] = cudf.Series(np.zeros(num_verts, dtype=np.int32)) | ||
cdef uintptr_t predecessors_ptr = create_column(df['predecessor']) | ||
|
||
err = g.adjList.get_vertex_identifiers(<gdf_column*>vertex_ptr) | ||
cudf.bindings.cudf_cpp.check_gdf_error(err) | ||
|
||
gdf_bfs(<gdf_graph*>g, <gdf_column*>distances_ptr, <gdf_column*>predecessors_ptr, <int>start, <bool>directed) | ||
return df |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
from c_graph cimport * | ||
from libcpp cimport bool | ||
|
||
cdef extern from "cugraph.h": | ||
|
||
cdef gdf_error gdf_bfs(gdf_graph *graph, gdf_column *distances, gdf_column *predecessors, int start_node, bool directed) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
import cugraph | ||
import cudf | ||
import time | ||
from scipy.io import mmread | ||
import pytest | ||
import numpy as np | ||
|
||
def ReadMtxFile(mmFile): | ||
print('Reading ' + str(mmFile) + '...') | ||
return mmread(mmFile).asfptype() | ||
|
||
|
||
def cugraph_Call(M, start_vertex): | ||
|
||
# Device data | ||
M = M.tocsr() | ||
sources = cudf.Series(M.indptr) | ||
destinations = cudf.Series(M.indices) | ||
values = cudf.Series(M.data) | ||
|
||
G = cugraph.Graph() | ||
G.add_adj_list(sources, destinations, values) | ||
|
||
t1 = time.time() | ||
df = cugraph.bfs(G, start_vertex) | ||
t2 = time.time() - t1 | ||
print('Time : '+str(t2)) | ||
|
||
# Return distances as np.array() | ||
return np.array(df['distance']) | ||
|
||
|
||
def base_Call(M, start_vertex): | ||
intMax = 2147483647 | ||
M = M.tocsr() | ||
offsets = M.indptr | ||
indices = M.indices | ||
num_verts = len(offsets) - 1 | ||
dist = np.zeros(num_verts, dtype=np.int32) | ||
|
||
for i in range(num_verts): | ||
dist[i] = intMax | ||
import queue | ||
q = queue.Queue() | ||
q.put(start_vertex) | ||
dist[start_vertex] = 0 | ||
while(not q.empty()): | ||
u = q.get() | ||
for iCol in range(offsets[u],offsets[u + 1]): | ||
v = indices[iCol] | ||
if (dist[v] == intMax): | ||
dist[v] = dist[u] + 1 | ||
q.put(v) | ||
return dist | ||
|
||
datasets = ['/datasets/networks/dolphins.mtx', | ||
'/datasets/networks/karate.mtx', | ||
'/datasets/golden_data/graphs/dblp.mtx'] | ||
|
||
@pytest.mark.parametrize('graph_file', datasets) | ||
def test_bfs(graph_file): | ||
|
||
M = ReadMtxFile(graph_file) | ||
base_dist = base_Call(M, 0) | ||
dist = cugraph_Call(M, 0) | ||
|
||
assert len(base_dist) == len(dist) | ||
for i in range(len(dist)): | ||
assert base_dist[i] == dist[i] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.