Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
OpenDAS
dgl
Commits
314a75f3
Commit
314a75f3
authored
Sep 24, 2018
by
Minjie Wang
Browse files
WIP: batched graph
parent
79f62400
Changes
7
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
301 additions
and
131 deletions
+301
-131
include/dgl/graph.h
include/dgl/graph.h
+22
-20
include/dgl/graph_op.h
include/dgl/graph_op.h
+40
-0
python/dgl/batch.py
python/dgl/batch.py
+107
-63
python/dgl/graph_index.py
python/dgl/graph_index.py
+43
-21
src/graph/graph.cc
src/graph/graph.cc
+30
-18
src/graph/graph_apis.cc
src/graph/graph_apis.cc
+40
-9
src/graph/graph_op.cc
src/graph/graph_op.cc
+19
-0
No files found.
include/dgl/graph.h
View file @
314a75f3
...
@@ -13,6 +13,8 @@ typedef tvm::runtime::NDArray DegreeArray;
...
@@ -13,6 +13,8 @@ typedef tvm::runtime::NDArray DegreeArray;
typedef
tvm
::
runtime
::
NDArray
BoolArray
;
typedef
tvm
::
runtime
::
NDArray
BoolArray
;
class
Graph
;
class
Graph
;
class
GraphOp
;
struct
Subgraph
;
/*!
/*!
* \brief Base dgl graph class.
* \brief Base dgl graph class.
...
@@ -246,7 +248,7 @@ class Graph {
...
@@ -246,7 +248,7 @@ class Graph {
* \param vids The vertices in the subgraph.
* \param vids The vertices in the subgraph.
* \return the induced subgraph
* \return the induced subgraph
*/
*/
G
raph
Subgraph
(
IdArray
vids
)
const
;
Subg
raph
Vertex
Subgraph
(
IdArray
vids
)
const
;
/*!
/*!
* \brief Construct the induced edge subgraph of the given edges.
* \brief Construct the induced edge subgraph of the given edges.
...
@@ -264,7 +266,7 @@ class Graph {
...
@@ -264,7 +266,7 @@ class Graph {
* \param vids The edges in the subgraph.
* \param vids The edges in the subgraph.
* \return the induced edge subgraph
* \return the induced edge subgraph
*/
*/
G
raph
EdgeSubgraph
(
IdArray
src
,
IdArray
dst
)
const
;
Subg
raph
EdgeSubgraph
(
IdArray
src
,
IdArray
dst
)
const
;
/*!
/*!
* \brief Return a new graph with all the edges reversed.
* \brief Return a new graph with all the edges reversed.
...
@@ -275,24 +277,8 @@ class Graph {
...
@@ -275,24 +277,8 @@ class Graph {
*/
*/
Graph
Reverse
()
const
;
Graph
Reverse
()
const
;
// TODO
protected:
std
::
vector
<
Graph
>
Split
(
std
::
vector
<
IdArray
>
vids_array
)
const
;
friend
class
GraphOp
;
/*!
* \brief Merge several graphs into one graph.
*
* The new graph will include all the nodes/edges in the given graphs.
* Nodes/Edges will be relabled by adding the cumsum of the previous graph sizes
* in the given sequence order. For example, giving input [g1, g2, g3], where
* they have 5, 6, 7 nodes respectively. Then node#2 of g2 will become node#7
* in the result graph. Edge ids are re-assigned similarly.
*
* \param graphs A list of input graphs to be merged.
* \return the merged graph
*/
static
Graph
Merge
(
std
::
vector
<
const
Graph
*>
graphs
);
private:
/*! \brief Internal edge list type */
/*! \brief Internal edge list type */
struct
EdgeList
{
struct
EdgeList
{
/*! \brief successor vertex list */
/*! \brief successor vertex list */
...
@@ -318,6 +304,22 @@ class Graph {
...
@@ -318,6 +304,22 @@ class Graph {
uint64_t
num_edges_
=
0
;
uint64_t
num_edges_
=
0
;
};
};
/*! \brief Subgraph data structure */
struct
Subgraph
{
/*! \brief The graph. */
Graph
graph
;
/*!
* \brief The induced vertex ids.
* \note This is also a map from the new vertex id to the vertex id in the parent graph.
*/
IdArray
induced_vertices
;
/*!
* \brief The induced edge ids.
* \note This is also a map from the new edge id to the edge id in the parent graph.
*/
IdArray
induced_edges
;
};
}
// namespace dgl
}
// namespace dgl
#endif // DGL_DGLGRAPH_H_
#endif // DGL_DGLGRAPH_H_
include/dgl/graph_op.h
0 → 100644
View file @
314a75f3
// Graph operations
#ifndef DGL_GRAPH_OP_H_
#define DGL_GRAPH_OP_H_
#include "graph.h"
namespace
dgl
{
class
GraphOp
{
public:
/*!
* \brief Return a disjoint union of the input graphs.
*
* The new graph will include all the nodes/edges in the given graphs.
* Nodes/Edges will be relabled by adding the cumsum of the previous graph sizes
* in the given sequence order. For example, giving input [g1, g2, g3], where
* they have 5, 6, 7 nodes respectively. Then node#2 of g2 will become node#7
* in the result graph. Edge ids are re-assigned similarly.
*
* \param graphs A list of input graphs to be unioned.
* \return the disjoint union of the graphs
*/
static
Graph
DisjointUnion
(
std
::
vector
<
const
Graph
*>
graphs
);
/*!
* \brief Partition the graph into several subgraphs.
*
* The graph will be partitioned by the node ids. Edges between partitions
* will be ignored. This requires the given number of partitions to evenly
* divides the number of nodes in the graph.
*
* \param num The number of partitions.
* \return a list of partitioned graphs
*/
static
std
::
vector
<
Graph
>
PartitionByNum
(
const
Graph
*
graph
,
size_t
num
);
};
}
// namespace dgl
#endif // DGL_GRAPH_OP_H_
python/dgl/batch.py
View file @
314a75f3
...
@@ -3,57 +3,88 @@ from __future__ import absolute_import
...
@@ -3,57 +3,88 @@ from __future__ import absolute_import
import
numpy
as
np
import
numpy
as
np
from
.base
import
ALL
,
is_all
from
.frame
import
FrameRef
from
.graph
import
DGLGraph
from
.graph
import
DGLGraph
from
.
import
graph_index
as
gi
from
.
import
backend
as
F
from
.
import
backend
as
F
class
BatchedDGLGraph
(
DGLGraph
):
class
BatchedDGLGraph
(
DGLGraph
):
def
__init__
(
self
,
graph_list
,
node_attrs
=
None
,
edge_attrs
=
None
,
**
attr
):
"""The batched DGL graph.
super
(
BatchedDGLGraph
,
self
).
__init__
(
**
attr
)
self
.
graph_list
=
graph_list
The batched graph is read-only.
self
.
graph_idx
=
{}
for
idx
,
g
in
enumerate
(
self
.
graph_list
):
self
.
graph_idx
[
g
]
=
idx
self
.
num_nodes
=
[
len
(
g
)
for
g
in
self
.
graph_list
]
self
.
num_edges
=
[
g
.
size
()
for
g
in
self
.
graph_list
]
# calc index offset
self
.
node_offset
=
np
.
cumsum
([
0
]
+
self
.
num_nodes
)
self
.
edge_offset
=
np
.
cumsum
([
0
]
+
self
.
num_edges
)
# in-order add relabeled nodes
self
.
add_nodes_from
(
range
(
self
.
node_offset
[
-
1
]))
# in-order add relabeled edges
self
.
new_edge_list
=
[
np
.
array
(
g
.
edge_list
)
+
offset
for
g
,
offset
in
zip
(
self
.
graph_list
,
self
.
node_offset
[:
-
1
])]
self
.
new_edges
=
np
.
concatenate
(
self
.
new_edge_list
)
self
.
add_edges_from
(
self
.
new_edges
)
assert
self
.
size
()
==
self
.
edge_offset
[
-
1
]
# set new node attr
if
node_attrs
:
attrs
=
{}
for
key
in
node_attrs
:
vals
=
[
g
.
pop_n_repr
(
key
)
for
g
in
self
.
graph_list
]
attrs
[
key
]
=
F
.
pack
(
vals
)
self
.
set_n_repr
(
attrs
)
else
:
for
g
in
self
.
graph_list
:
self
.
_node_frame
.
append
(
g
.
_node_frame
)
# set new edge attr
if
edge_attrs
:
attrs
=
{}
for
key
in
edge_attrs
:
vals
=
[
g
.
pop_e_repr
(
key
)
for
g
in
self
.
graph_list
]
attrs
[
key
]
=
F
.
pack
(
vals
)
self
.
set_e_repr
(
attrs
)
else
:
for
g
in
self
.
graph_list
:
self
.
_edge_frame
.
append
(
g
.
_edge_frame
)
Parameters
----------
graph_list : iterable
A list of DGLGraphs to be batched.
node_attrs : str or iterable
The node attributes to also be batched.
edge_attrs : str or iterable, optional
The edge attributes to also be batched.
"""
def
__init__
(
self
,
graph_list
,
node_attrs
,
edge_attrs
):
# TODO(minjie): handle the input is again a batched graph.
# create batched graph index
batched_index
=
gi
.
disjoint_union
([
g
.
_graph
for
g
in
graph_list
])
# create batched node and edge frames
# NOTE: following code will materialize the columns of the input graphs.
batched_node_frame
=
FrameRef
()
for
gr
in
graph_list
:
cols
=
{
gr
.
_node_frame
[
key
]
for
key
in
node_attrs
}
batched_node_frame
.
append
(
cols
)
batched_edge_frame
=
FrameRef
()
for
gr
in
graph_list
:
cols
=
{
gr
.
_edge_frame
[
key
]
for
key
in
edge_attrs
}
batched_edge_frame
.
append
(
cols
)
super
(
BatchedDGLGraph
,
self
).
__init__
(
graph_data
=
batched_index
,
node_frame
=
batched_node_frame
,
edge_frame
=
batched_edge_frame
)
# extra members
self
.
_batch_size
=
len
(
graph_list
)
self
.
_batch_num_nodes
=
[
gr
.
number_of_nodes
()
for
gr
in
graph_list
]
self
.
_batch_num_edges
=
[
gr
.
number_of_edges
()
for
gr
in
graph_list
]
@
property
def
batch_size
(
self
):
"""Number of graphs in this batch."""
return
self
.
_batch_size
@
property
def
batch_num_nodes
(
self
):
"""Number of nodes of each graph in this batch."""
return
self
.
_batch_num_nodes
@
property
def
batch_num_edges
(
self
):
"""Number of edges of each graph in this batch."""
return
self
.
_batch_num_edges
# override APIs
def
add_nodes
(
self
,
num
,
reprs
=
None
):
"""Add nodes."""
raise
RuntimeError
(
'Readonly graph. Mutation is not allowed.'
)
def
add_edge
(
self
,
u
,
v
,
reprs
=
None
):
"""Add one edge."""
raise
RuntimeError
(
'Readonly graph. Mutation is not allowed.'
)
def
add_edges
(
self
,
u
,
v
,
reprs
=
None
):
"""Add many edges."""
raise
RuntimeError
(
'Readonly graph. Mutation is not allowed.'
)
# new APIs
def
__getitem__
(
self
,
idx
):
"""Slice the batch and return the batch of graphs specified by the idx."""
pass
def
__setitem__
(
self
,
idx
,
val
):
"""Set the value of the slice. The graph size cannot be changed."""
pass
'''
def query_new_node(self, g, u):
def query_new_node(self, g, u):
idx = self.graph_idx[g]
idx = self.graph_idx[g]
offset = self.node_offset[idx]
offset = self.node_offset[idx]
...
@@ -76,7 +107,12 @@ class BatchedDGLGraph(DGLGraph):
...
@@ -76,7 +107,12 @@ class BatchedDGLGraph(DGLGraph):
def query_edge_start_offset(self):
def query_edge_start_offset(self):
return self.edge_offset[:-1].copy()
return self.edge_offset[:-1].copy()
'''
def
split
(
graph_batch
,
num_or_size_splits
):
"""Split the batch."""
# TODO(minjie): could follow torch.split syntax
pass
def
unbatch
(
graph_batch
):
def
unbatch
(
graph_batch
):
"""Unbatch the graph and return a list of subgraphs.
"""Unbatch the graph and return a list of subgraphs.
...
@@ -86,6 +122,7 @@ def unbatch(graph_batch):
...
@@ -86,6 +122,7 @@ def unbatch(graph_batch):
graph_batch : DGLGraph
graph_batch : DGLGraph
The batched graph.
The batched graph.
"""
"""
assert
False
,
"disabled for now"
graph_list
=
graph_batch
.
graph_list
graph_list
=
graph_batch
.
graph_list
num_graphs
=
len
(
graph_list
)
num_graphs
=
len
(
graph_list
)
# split and set node attrs
# split and set node attrs
...
@@ -108,29 +145,36 @@ def unbatch(graph_batch):
...
@@ -108,29 +145,36 @@ def unbatch(graph_batch):
return
graph_list
return
graph_list
def
batch
(
graph_list
,
node_attrs
=
ALL
,
edge_attrs
=
ALL
):
# FIXME (lingfan): Do we really need the batch API?
# Can't we let user call BatchedDGLGraph(graph_list) directly
# and make unbatch a member function of BatchedDGLGraph
def
batch
(
graph_list
,
node_attrs
=
None
,
edge_attrs
=
None
):
"""Batch a list of DGLGraphs into one single graph.
"""Batch a list of DGLGraphs into one single graph.
Once batch is called, the structure of both merged graph and graphs in graph_list
Once batch is called, the structure of both merged graph and graphs in graph_list
must not
b
be mutated, or unbatch's behavior will be undefined.
must not be mutated, or unbatch's behavior will be undefined.
Parameters
Parameters
----------
----------
graph_list : iterable
graph_list : iterable
A list of DGLGraphs to be batched.
A list of DGLGraphs to be batched.
node_attrs : str or iterable
node_attrs : str or iterable, optional
A list of node attributes needed for merged graph
The node attributes to also be batched. Specify None to not batch any attributes.
It's user's resposiblity to make sure node_attrs exists
edge_attrs : str or iterable, optional
edge_attrs : str or iterable
The edge attributes to also be batched. Specify None to not batch any attributes.
A list of edge attributes needed for merged graph
It's user's resposiblity to make sure edge_attrs exists
Returns
-------
Return
newgrh: BatchedDGLGraph
------
one single batched graph
newgrh: DGLGraph
one single merged graph
"""
"""
if
node_attrs
is
None
:
node_attrs
=
[]
elif
is_all
(
node_attrs
):
node_attrs
=
graph_list
[
0
].
node_attr_schemes
()
elif
if
isinstance
(
node_attrs
,
str
):
node_attrs
=
[
node_attrs
]
if
edge_attrs
is
None
:
edge_attrs
=
[]
elif
is_all
(
edge_attrs
):
edge_attrs
=
graph_list
[
0
].
edge_attr_schemes
()
elif
if
isinstance
(
edge_attrs
,
str
):
edge_attrs
=
[
edge_attrs
]
return
BatchedDGLGraph
(
graph_list
,
node_attrs
,
edge_attrs
)
return
BatchedDGLGraph
(
graph_list
,
node_attrs
,
edge_attrs
)
python/dgl/graph_index.py
View file @
314a75f3
...
@@ -367,6 +367,27 @@ class GraphIndex(object):
...
@@ -367,6 +367,27 @@ class GraphIndex(object):
v_array
=
v
.
todgltensor
()
v_array
=
v
.
todgltensor
()
return
utils
.
toindex
(
_CAPI_DGLGraphOutDegrees
(
self
.
_handle
,
v_array
))
return
utils
.
toindex
(
_CAPI_DGLGraphOutDegrees
(
self
.
_handle
,
v_array
))
def
node_subgraph
(
self
,
v
):
"""Return the induced node subgraph.
Parameters
----------
v : utils.Index
The nodes.
Returns
-------
GraphIndex
The subgraph index.
utils.Index
The induced edge ids. This is also a map from new edge id to parent edge id.
"""
v_array
=
v
.
todgltensor
()
rst
=
_CAPI_DGLGraphVertexSubgraph
(
self
.
_handle
,
v_array
)
gi
=
GraphIndex
(
rst
(
0
))
induced_edges
=
utils
.
toindex
(
rst
(
2
))
return
gi
,
induced_edges
def
adjacency_matrix
(
self
):
def
adjacency_matrix
(
self
):
"""Return the adjacency matrix representation of this graph.
"""Return the adjacency matrix representation of this graph.
...
@@ -438,9 +459,8 @@ class GraphIndex(object):
...
@@ -438,9 +459,8 @@ class GraphIndex(object):
dst
=
utils
.
toindex
(
dst
)
dst
=
utils
.
toindex
(
dst
)
self
.
add_edges
(
src
,
dst
)
self
.
add_edges
(
src
,
dst
)
@
staticmethod
def
disjoint_union
(
graphs
):
def
merge
(
graphs
):
"""Return a disjoint union of the input graphs.
"""Merge a list of graphs into one graph.
The new graph will include all the nodes/edges in the given graphs.
The new graph will include all the nodes/edges in the given graphs.
Nodes/Edges will be relabled by adding the cumsum of the previous graph sizes
Nodes/Edges will be relabled by adding the cumsum of the previous graph sizes
...
@@ -456,11 +476,11 @@ class GraphIndex(object):
...
@@ -456,11 +476,11 @@ class GraphIndex(object):
Returns
Returns
-------
-------
GraphIndex
GraphIndex
The merged graph
The disjoint union
"""
"""
inputs
=
c_array
(
GraphIndexHandle
,
[
gr
.
_handle
for
gr
in
graphs
])
inputs
=
c_array
(
GraphIndexHandle
,
[
gr
.
_handle
for
gr
in
graphs
])
inputs
=
ctypes
.
cast
(
inputs
,
ctypes
.
c_void_p
)
inputs
=
ctypes
.
cast
(
inputs
,
ctypes
.
c_void_p
)
handle
=
_CAPI_DGL
GraphMerge
(
inputs
,
len
(
graphs
))
handle
=
_CAPI_DGL
DisjointUnion
(
inputs
,
len
(
graphs
))
return
GraphIndex
(
handle
)
return
GraphIndex
(
handle
)
def
create_graph_index
(
graph_data
=
None
):
def
create_graph_index
(
graph_data
=
None
):
...
@@ -471,6 +491,8 @@ def create_graph_index(graph_data=None):
...
@@ -471,6 +491,8 @@ def create_graph_index(graph_data=None):
graph_data : graph data, optional
graph_data : graph data, optional
Data to initialize graph. Same as networkx's semantics.
Data to initialize graph. Same as networkx's semantics.
"""
"""
if
isinstance
(
graph_data
,
GraphIndex
):
return
graph_data
handle
=
_CAPI_DGLGraphCreate
()
handle
=
_CAPI_DGLGraphCreate
()
gi
=
GraphIndex
(
handle
)
gi
=
GraphIndex
(
handle
)
if
graph_data
is
not
None
:
if
graph_data
is
not
None
:
...
...
src/graph/graph.cc
View file @
314a75f3
// Graph class implementation
// Graph class implementation
#include <algorithm>
#include <algorithm>
#include <unordered_map>
#include <dgl/graph.h>
#include <dgl/graph.h>
namespace
dgl
{
namespace
dgl
{
...
@@ -345,14 +346,38 @@ DegreeArray Graph::OutDegrees(IdArray vids) const {
...
@@ -345,14 +346,38 @@ DegreeArray Graph::OutDegrees(IdArray vids) const {
return
rst
;
return
rst
;
}
}
Graph
Graph
::
Subgraph
(
IdArray
vids
)
const
{
Subgraph
Graph
::
VertexSubgraph
(
IdArray
vids
)
const
{
LOG
(
FATAL
)
<<
"not implemented"
;
CHECK
(
IsValidIdArray
(
vids
))
<<
"Invalid vertex id array."
;
return
*
this
;
const
auto
len
=
vids
->
shape
[
0
];
std
::
unordered_map
<
dgl_id_t
,
dgl_id_t
>
oldv2newv
;
std
::
vector
<
dgl_id_t
>
edges
;
const
int64_t
*
vid_data
=
static_cast
<
int64_t
*>
(
vids
->
data
);
for
(
int64_t
i
=
0
;
i
<
len
;
++
i
)
{
oldv2newv
[
vid_data
[
i
]]
=
i
;
}
Subgraph
rst
;
rst
.
induced_vertices
=
vids
;
rst
.
graph
.
AddVertices
(
len
);
for
(
int64_t
i
=
0
;
i
<
len
;
++
i
)
{
const
dgl_id_t
oldvid
=
vid_data
[
i
];
const
dgl_id_t
newvid
=
i
;
for
(
size_t
j
=
0
;
j
<
adjlist_
[
oldvid
].
succ
.
size
();
++
j
)
{
const
dgl_id_t
oldsucc
=
adjlist_
[
oldvid
].
succ
[
j
];
if
(
oldv2newv
.
count
(
oldsucc
))
{
const
dgl_id_t
newsucc
=
oldv2newv
[
oldsucc
];
edges
.
push_back
(
adjlist_
[
oldvid
].
edge_id
[
j
]);
rst
.
graph
.
AddEdge
(
newvid
,
newsucc
);
}
}
}
rst
.
induced_edges
=
IdArray
::
Empty
({
static_cast
<
int64_t
>
(
edges
.
size
())},
vids
->
dtype
,
vids
->
ctx
);
std
::
copy
(
edges
.
begin
(),
edges
.
end
(),
static_cast
<
int64_t
*>
(
rst
.
induced_edges
->
data
));
return
rst
;
}
}
G
raph
Graph
::
EdgeSubgraph
(
IdArray
src
,
IdArray
dst
)
const
{
Subg
raph
Graph
::
EdgeSubgraph
(
IdArray
src
,
IdArray
dst
)
const
{
LOG
(
FATAL
)
<<
"not implemented"
;
LOG
(
FATAL
)
<<
"not implemented"
;
return
*
this
;
return
Subgraph
()
;
}
}
Graph
Graph
::
Reverse
()
const
{
Graph
Graph
::
Reverse
()
const
{
...
@@ -360,17 +385,4 @@ Graph Graph::Reverse() const {
...
@@ -360,17 +385,4 @@ Graph Graph::Reverse() const {
return
*
this
;
return
*
this
;
}
}
Graph
Graph
::
Merge
(
std
::
vector
<
const
Graph
*>
graphs
)
{
Graph
rst
;
uint64_t
cumsum
=
0
;
for
(
const
Graph
*
gr
:
graphs
)
{
rst
.
AddVertices
(
gr
->
NumVertices
());
for
(
uint64_t
i
=
0
;
i
<
gr
->
NumEdges
();
++
i
)
{
rst
.
AddEdge
(
gr
->
all_edges_src_
[
i
]
+
cumsum
,
gr
->
all_edges_dst_
[
i
]
+
cumsum
);
}
cumsum
+=
gr
->
NumVertices
();
}
return
rst
;
}
}
// namespace dgl
}
// namespace dgl
src/graph/graph_apis.cc
View file @
314a75f3
#include <dgl/runtime/packed_func.h>
#include <dgl/runtime/packed_func.h>
#include <dgl/runtime/registry.h>
#include <dgl/runtime/registry.h>
#include <dgl/graph.h>
#include <dgl/graph.h>
#include <dgl/graph_op.h>
using
tvm
::
runtime
::
TVMArgs
;
using
tvm
::
runtime
::
TVMArgs
;
using
tvm
::
runtime
::
TVMArgValue
;
using
tvm
::
runtime
::
TVMArgValue
;
...
@@ -8,17 +9,21 @@ using tvm::runtime::TVMRetValue;
...
@@ -8,17 +9,21 @@ using tvm::runtime::TVMRetValue;
using
tvm
::
runtime
::
PackedFunc
;
using
tvm
::
runtime
::
PackedFunc
;
namespace
dgl
{
namespace
dgl
{
// Graph handler type
typedef
void
*
GraphHandle
;
namespace
{
namespace
{
/
*!\brief
Convert EdgeArray structure to PackedFunc
*/
/
/
Convert EdgeArray structure to PackedFunc
.
PackedFunc
ConvertEdgeArrayToPackedFunc
(
const
Graph
::
EdgeArray
&
ea
)
{
PackedFunc
ConvertEdgeArrayToPackedFunc
(
const
Graph
::
EdgeArray
&
ea
)
{
auto
body
=
[
ea
]
(
TVMArgs
args
,
TVMRetValue
*
rv
)
{
auto
body
=
[
ea
]
(
TVMArgs
args
,
TVMRetValue
*
rv
)
{
int
which
=
args
[
0
];
int
which
=
args
[
0
];
if
(
which
==
0
)
{
if
(
which
==
0
)
{
*
rv
=
ea
.
src
;
*
rv
=
std
::
move
(
ea
.
src
)
;
}
else
if
(
which
==
1
)
{
}
else
if
(
which
==
1
)
{
*
rv
=
ea
.
dst
;
*
rv
=
std
::
move
(
ea
.
dst
)
;
}
else
if
(
which
==
2
)
{
}
else
if
(
which
==
2
)
{
*
rv
=
ea
.
id
;
*
rv
=
std
::
move
(
ea
.
id
)
;
}
else
{
}
else
{
LOG
(
FATAL
)
<<
"invalid choice"
;
LOG
(
FATAL
)
<<
"invalid choice"
;
}
}
...
@@ -26,6 +31,27 @@ PackedFunc ConvertEdgeArrayToPackedFunc(const Graph::EdgeArray& ea) {
...
@@ -26,6 +31,27 @@ PackedFunc ConvertEdgeArrayToPackedFunc(const Graph::EdgeArray& ea) {
return
PackedFunc
(
body
);
return
PackedFunc
(
body
);
}
}
// Convert Subgraph structure to PackedFunc.
PackedFunc
ConvertSubgraphToPackedFunc
(
const
Subgraph
&
sg
)
{
auto
body
=
[
sg
]
(
TVMArgs
args
,
TVMRetValue
*
rv
)
{
int
which
=
args
[
0
];
if
(
which
==
0
)
{
Graph
*
gptr
=
new
Graph
();
*
gptr
=
std
::
move
(
sg
.
graph
);
GraphHandle
ghandle
=
gptr
;
*
rv
=
ghandle
;
}
else
if
(
which
==
1
)
{
*
rv
=
std
::
move
(
sg
.
induced_vertices
);
}
else
if
(
which
==
2
)
{
*
rv
=
std
::
move
(
sg
.
induced_edges
);
}
else
{
LOG
(
FATAL
)
<<
"invalid choice"
;
}
};
return
PackedFunc
(
body
);
}
// Convert the given DLTensor to a temporary DLManagedTensor that does not own memory.
DLManagedTensor
*
CreateTmpDLManagedTensor
(
const
TVMArgValue
&
arg
)
{
DLManagedTensor
*
CreateTmpDLManagedTensor
(
const
TVMArgValue
&
arg
)
{
const
DLTensor
*
dl_tensor
=
arg
;
const
DLTensor
*
dl_tensor
=
arg
;
DLManagedTensor
*
ret
=
new
DLManagedTensor
();
DLManagedTensor
*
ret
=
new
DLManagedTensor
();
...
@@ -37,9 +63,6 @@ DLManagedTensor* CreateTmpDLManagedTensor(const TVMArgValue& arg) {
...
@@ -37,9 +63,6 @@ DLManagedTensor* CreateTmpDLManagedTensor(const TVMArgValue& arg) {
}
// namespace
}
// namespace
// Graph handler type
typedef
void
*
GraphHandle
;
TVM_REGISTER_GLOBAL
(
"graph_index._CAPI_DGLGraphCreate"
)
TVM_REGISTER_GLOBAL
(
"graph_index._CAPI_DGLGraphCreate"
)
.
set_body
([]
(
TVMArgs
args
,
TVMRetValue
*
rv
)
{
.
set_body
([]
(
TVMArgs
args
,
TVMRetValue
*
rv
)
{
GraphHandle
ghandle
=
new
Graph
();
GraphHandle
ghandle
=
new
Graph
();
...
@@ -242,7 +265,15 @@ TVM_REGISTER_GLOBAL("graph_index._CAPI_DGLGraphOutDegrees")
...
@@ -242,7 +265,15 @@ TVM_REGISTER_GLOBAL("graph_index._CAPI_DGLGraphOutDegrees")
*
rv
=
gptr
->
OutDegrees
(
vids
);
*
rv
=
gptr
->
OutDegrees
(
vids
);
});
});
TVM_REGISTER_GLOBAL
(
"graph_index._CAPI_DGLGraphMerge"
)
TVM_REGISTER_GLOBAL
(
"graph_index._CAPI_DGLGraphVertexSubgraph"
)
.
set_body
([]
(
TVMArgs
args
,
TVMRetValue
*
rv
)
{
GraphHandle
ghandle
=
args
[
0
];
const
Graph
*
gptr
=
static_cast
<
Graph
*>
(
ghandle
);
const
IdArray
vids
=
IdArray
::
FromDLPack
(
CreateTmpDLManagedTensor
(
args
[
1
]));
*
rv
=
ConvertSubgraphToPackedFunc
(
gptr
->
VertexSubgraph
(
vids
));
});
TVM_REGISTER_GLOBAL
(
"graph_index._CAPI_DGLDisjointUnion"
)
.
set_body
([]
(
TVMArgs
args
,
TVMRetValue
*
rv
)
{
.
set_body
([]
(
TVMArgs
args
,
TVMRetValue
*
rv
)
{
void
*
list
=
args
[
0
];
void
*
list
=
args
[
0
];
GraphHandle
*
inhandles
=
static_cast
<
GraphHandle
*>
(
list
);
GraphHandle
*
inhandles
=
static_cast
<
GraphHandle
*>
(
list
);
...
@@ -253,7 +284,7 @@ TVM_REGISTER_GLOBAL("graph_index._CAPI_DGLGraphMerge")
...
@@ -253,7 +284,7 @@ TVM_REGISTER_GLOBAL("graph_index._CAPI_DGLGraphMerge")
graphs
.
push_back
(
gr
);
graphs
.
push_back
(
gr
);
}
}
Graph
*
gptr
=
new
Graph
();
Graph
*
gptr
=
new
Graph
();
*
gptr
=
Graph
::
Merge
(
std
::
move
(
graphs
));
*
gptr
=
Graph
Op
::
DisjointUnion
(
std
::
move
(
graphs
));
GraphHandle
ghandle
=
gptr
;
GraphHandle
ghandle
=
gptr
;
*
rv
=
ghandle
;
*
rv
=
ghandle
;
});
});
...
...
src/graph/graph_op.cc
0 → 100644
View file @
314a75f3
// Graph operation implementation
#include <dgl/graph_op.h>
namespace
dgl
{
Graph
GraphOp
::
DisjointUnion
(
std
::
vector
<
const
Graph
*>
graphs
)
{
Graph
rst
;
uint64_t
cumsum
=
0
;
for
(
const
Graph
*
gr
:
graphs
)
{
rst
.
AddVertices
(
gr
->
NumVertices
());
for
(
uint64_t
i
=
0
;
i
<
gr
->
NumEdges
();
++
i
)
{
rst
.
AddEdge
(
gr
->
all_edges_src_
[
i
]
+
cumsum
,
gr
->
all_edges_dst_
[
i
]
+
cumsum
);
}
cumsum
+=
gr
->
NumVertices
();
}
return
rst
;
}
}
// namespace dgl
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment