Unverified Commit 444becf0 authored by Minjie Wang's avatar Minjie Wang Committed by GitHub
Browse files

[Misc] Move many deprecated codes to the deprecate folder (#1893)

* some file movements

* move some codes to deprecated

* more deprecation

* lint

* remove useless test
parent 68a978d4
...@@ -278,7 +278,7 @@ std::vector<int64_t> InferBinaryFeatureShape( ...@@ -278,7 +278,7 @@ std::vector<int64_t> InferBinaryFeatureShape(
return CalcBcastInfo(op, lhs, rhs).real_out_shape; return CalcBcastInfo(op, lhs, rhs).real_out_shape;
} }
DGL_REGISTER_GLOBAL("kernel._CAPI_DGLKernelInferBinaryFeatureShape") DGL_REGISTER_GLOBAL("_deprecate.kernel._CAPI_DGLKernelInferBinaryFeatureShape")
.set_body([] (DGLArgs args, DGLRetValue* rv) { .set_body([] (DGLArgs args, DGLRetValue* rv) {
std::string op = args[0]; std::string op = args[0];
NDArray lhs = args[1]; NDArray lhs = args[1];
...@@ -354,7 +354,7 @@ void csrwrapper_switch(DGLArgValue argval, ...@@ -354,7 +354,7 @@ void csrwrapper_switch(DGLArgValue argval,
} }
} }
DGL_REGISTER_GLOBAL("kernel._CAPI_DGLKernelBinaryOpReduce") DGL_REGISTER_GLOBAL("_deprecate.kernel._CAPI_DGLKernelBinaryOpReduce")
.set_body([] (DGLArgs args, DGLRetValue* rv) { .set_body([] (DGLArgs args, DGLRetValue* rv) {
std::string reducer = args[0]; std::string reducer = args[0];
std::string op = args[1]; std::string op = args[1];
...@@ -427,7 +427,7 @@ void BackwardLhsBinaryOpReduce( ...@@ -427,7 +427,7 @@ void BackwardLhsBinaryOpReduce(
} }
} }
DGL_REGISTER_GLOBAL("kernel._CAPI_DGLKernelBackwardLhsBinaryOpReduce") DGL_REGISTER_GLOBAL("_deprecate.kernel._CAPI_DGLKernelBackwardLhsBinaryOpReduce")
.set_body([] (DGLArgs args, DGLRetValue* rv) { .set_body([] (DGLArgs args, DGLRetValue* rv) {
std::string reducer = args[0]; std::string reducer = args[0];
std::string op = args[1]; std::string op = args[1];
...@@ -503,7 +503,7 @@ void BackwardRhsBinaryOpReduce( ...@@ -503,7 +503,7 @@ void BackwardRhsBinaryOpReduce(
} }
} }
DGL_REGISTER_GLOBAL("kernel._CAPI_DGLKernelBackwardRhsBinaryOpReduce") DGL_REGISTER_GLOBAL("_deprecate.kernel._CAPI_DGLKernelBackwardRhsBinaryOpReduce")
.set_body([] (DGLArgs args, DGLRetValue* rv) { .set_body([] (DGLArgs args, DGLRetValue* rv) {
std::string reducer = args[0]; std::string reducer = args[0];
std::string op = args[1]; std::string op = args[1];
...@@ -552,7 +552,7 @@ void CopyReduce( ...@@ -552,7 +552,7 @@ void CopyReduce(
in_mapping, aten::NullArray(), out_mapping); in_mapping, aten::NullArray(), out_mapping);
} }
DGL_REGISTER_GLOBAL("kernel._CAPI_DGLKernelCopyReduce") DGL_REGISTER_GLOBAL("_deprecate.kernel._CAPI_DGLKernelCopyReduce")
.set_body([] (DGLArgs args, DGLRetValue* rv) { .set_body([] (DGLArgs args, DGLRetValue* rv) {
std::string reducer = args[0]; std::string reducer = args[0];
int target = args[2]; int target = args[2];
...@@ -600,7 +600,7 @@ void BackwardCopyReduce( ...@@ -600,7 +600,7 @@ void BackwardCopyReduce(
grad_in_data, aten::NullArray()); grad_in_data, aten::NullArray());
} }
DGL_REGISTER_GLOBAL("kernel._CAPI_DGLKernelBackwardCopyReduce") DGL_REGISTER_GLOBAL("_deprecate.kernel._CAPI_DGLKernelBackwardCopyReduce")
.set_body([] (DGLArgs args, DGLRetValue* rv) { .set_body([] (DGLArgs args, DGLRetValue* rv) {
std::string reducer = args[0]; std::string reducer = args[0];
int target = args[2]; int target = args[2];
......
...@@ -15,7 +15,7 @@ using dgl::runtime::NDArray; ...@@ -15,7 +15,7 @@ using dgl::runtime::NDArray;
namespace dgl { namespace dgl {
DGL_REGISTER_GLOBAL("runtime.degree_bucketing._CAPI_DGLDegreeBucketing") DGL_REGISTER_GLOBAL("_deprecate.runtime.degree_bucketing._CAPI_DGLDegreeBucketing")
.set_body([](DGLArgs args, DGLRetValue* rv) { .set_body([](DGLArgs args, DGLRetValue* rv) {
const IdArray msg_ids = args[0]; const IdArray msg_ids = args[0];
const IdArray vids = args[1]; const IdArray vids = args[1];
...@@ -28,7 +28,7 @@ DGL_REGISTER_GLOBAL("runtime.degree_bucketing._CAPI_DGLDegreeBucketing") ...@@ -28,7 +28,7 @@ DGL_REGISTER_GLOBAL("runtime.degree_bucketing._CAPI_DGLDegreeBucketing")
}); });
}); });
DGL_REGISTER_GLOBAL("runtime.degree_bucketing._CAPI_DGLGroupEdgeByNodeDegree") DGL_REGISTER_GLOBAL("_deprecate.runtime.degree_bucketing._CAPI_DGLGroupEdgeByNodeDegree")
.set_body([] (DGLArgs args, DGLRetValue* rv) { .set_body([] (DGLArgs args, DGLRetValue* rv) {
const IdArray uids = args[0]; const IdArray uids = args[0];
const IdArray vids = args[1]; const IdArray vids = args[1];
......
from dgl.graph import DGLGraph import dgl
import backend as F import backend as F
import numpy as np import numpy as np
def test_filter(): def test_filter():
g = DGLGraph() g = dgl.DGLGraph().to(F.ctx())
g.add_nodes(4) g.add_nodes(4)
g.add_edges([0,1,2,3], [1,2,3,0]) g.add_edges([0,1,2,3], [1,2,3,0])
......
...@@ -47,49 +47,3 @@ def test_dlpack(): ...@@ -47,49 +47,3 @@ def test_dlpack():
nd2th() nd2th()
th2nd() th2nd()
th2nd_incontiguous() th2nd_incontiguous()
def test_index():
ans = np.ones((10,), dtype=np.int64) * 10
# from np data
data = np.ones((10,), dtype=np.int64) * 10
idx = toindex(data)
y1 = idx.tonumpy()
y2 = F.asnumpy(idx.tousertensor())
y3 = idx.todgltensor().asnumpy()
assert np.allclose(ans, y1)
assert np.allclose(ans, y2)
assert np.allclose(ans, y3)
# from list
data = [10] * 10
idx = toindex(data)
y1 = idx.tonumpy()
y2 = F.asnumpy(idx.tousertensor())
y3 = idx.todgltensor().asnumpy()
assert np.allclose(ans, y1)
assert np.allclose(ans, y2)
assert np.allclose(ans, y3)
# from dl tensor
data = F.ones((10,), dtype=F.int64) * 10
idx = toindex(data)
y1 = idx.tonumpy()
y2 = F.asnumpy(idx.tousertensor())
y3 = idx.todgltensor().asnumpy()
assert np.allclose(ans, y1)
assert np.allclose(ans, y2)
assert np.allclose(ans, y3)
# from dgl.NDArray
data = dgl.ndarray.array(np.ones((10,), dtype=np.int64) * 10)
idx = toindex(data)
y1 = idx.tonumpy()
y2 = F.asnumpy(idx.tousertensor())
y3 = idx.todgltensor().asnumpy()
assert np.allclose(ans, y1)
assert np.allclose(ans, y2)
assert np.allclose(ans, y3)
if __name__ == '__main__':
test_dlpack()
test_index()
import numpy as np import numpy as np
from dgl.graph import DGLGraph import dgl
import backend as F import backend as F
import unittest
D = 5 D = 5
def generate_graph(grad=False, add_data=True): def generate_graph(grad=False, add_data=True):
g = DGLGraph() g = dgl.DGLGraph().to(F.ctx())
g.add_nodes(10) g.add_nodes(10)
# create a graph where 0 is the source and 9 is the sink # create a graph where 0 is the source and 9 is the sink
for i in range(1, 9): for i in range(1, 9):
...@@ -23,29 +24,25 @@ def generate_graph(grad=False, add_data=True): ...@@ -23,29 +24,25 @@ def generate_graph(grad=False, add_data=True):
g.edata['l'] = ecol g.edata['l'] = ecol
return g return g
def test_basics1(): @unittest.skipIf(F._default_context_str == 'gpu', reason="GPU not implemented")
def test_edge_subgraph():
# Test when the graph has no node data and edge data. # Test when the graph has no node data and edge data.
g = generate_graph(add_data=False) g = generate_graph(add_data=False)
eid = [0, 2, 3, 6, 7, 9] eid = [0, 2, 3, 6, 7, 9]
sg = g.edge_subgraph(eid) sg = g.edge_subgraph(eid)
sg.copy_from_parent()
sg.ndata['h'] = F.arange(0, sg.number_of_nodes()) sg.ndata['h'] = F.arange(0, sg.number_of_nodes())
sg.edata['h'] = F.arange(0, sg.number_of_edges()) sg.edata['h'] = F.arange(0, sg.number_of_edges())
def test_basics(): def test_subgraph():
g = generate_graph() g = generate_graph()
h = g.ndata['h'] h = g.ndata['h']
l = g.edata['l'] l = g.edata['l']
nid = [0, 2, 3, 6, 7, 9] nid = [0, 2, 3, 6, 7, 9]
sg = g.subgraph(nid) sg = g.subgraph(nid)
eid = {2, 3, 4, 5, 10, 11, 12, 13, 16} eid = {2, 3, 4, 5, 10, 11, 12, 13, 16}
assert set(F.zerocopy_to_numpy(sg.parent_eid)) == eid assert set(F.asnumpy(sg.edata[dgl.EID])) == eid
eid = F.tensor(sg.parent_eid) eid = sg.edata[dgl.EID]
# the subgraph is empty initially except for NID/EID field # the subgraph is empty initially except for NID/EID field
assert len(sg.ndata) == 1
assert len(sg.edata) == 1
# the data is copied after explict copy from
sg.copy_from_parent()
assert len(sg.ndata) == 2 assert len(sg.ndata) == 2
assert len(sg.edata) == 2 assert len(sg.edata) == 2
sh = sg.ndata['h'] sh = sg.ndata['h']
...@@ -76,43 +73,10 @@ def test_basics(): ...@@ -76,43 +73,10 @@ def test_basics():
sg.ndata['h'] = F.zeros((6, D)) sg.ndata['h'] = F.zeros((6, D))
assert F.allclose(h, g.ndata['h']) assert F.allclose(h, g.ndata['h'])
def test_map_to_subgraph(): def _test_map_to_subgraph():
g = DGLGraph() g = dgl.DGLGraph()
g.add_nodes(10) g.add_nodes(10)
g.add_edges(F.arange(0, 9), F.arange(1, 10)) g.add_edges(F.arange(0, 9), F.arange(1, 10))
h = g.subgraph([0, 1, 2, 5, 8]) h = g.subgraph([0, 1, 2, 5, 8])
v = h.map_to_subgraph_nid([0, 8, 2]) v = h.map_to_subgraph_nid([0, 8, 2])
assert np.array_equal(F.asnumpy(v), np.array([0, 4, 2])) assert np.array_equal(F.asnumpy(v), np.array([0, 4, 2]))
def test_merge():
# FIXME: current impl cannot handle this case!!!
# comment out for now to test CI
return
"""
g = generate_graph()
g.set_n_repr({'h' : th.zeros((10, D))})
g.set_e_repr({'l' : th.zeros((17, D))})
# subgraphs
sg1 = g.subgraph([0, 2, 3, 6, 7, 9])
sg1.set_n_repr({'h' : th.ones((6, D))})
sg1.set_e_repr({'l' : th.ones((9, D))})
sg2 = g.subgraph([0, 2, 3, 4])
sg2.set_n_repr({'h' : th.ones((4, D)) * 2})
sg3 = g.subgraph([5, 6, 7, 8, 9])
sg3.set_e_repr({'l' : th.ones((4, D)) * 3})
g.merge([sg1, sg2, sg3])
h = g.ndata['h'][:,0]
l = g.edata['l'][:,0]
assert U.allclose(h, th.tensor([3., 0., 3., 3., 2., 0., 1., 1., 0., 1.]))
assert U.allclose(l,
th.tensor([0., 0., 1., 1., 1., 1., 0., 0., 0., 3., 1., 4., 1., 4., 0., 3., 1.]))
"""
if __name__ == '__main__':
test_basics()
test_basics1()
#test_merge()
import backend as F
import numpy as np
from scipy import sparse as spsp
from dgl import DGLError
from dgl.utils import toindex
from dgl.graph_index import create_graph_index
from dgl.graph_index import from_scipy_sparse_matrix
def test_node_subgraph():
gi = create_graph_index(None, False)
gi.add_nodes(4)
gi.add_edge(0, 1)
gi.add_edge(0, 2)
gi.add_edge(0, 2)
gi.add_edge(0, 3)
sub2par_nodemap = [2, 0, 3]
sgi = gi.node_subgraph(toindex(sub2par_nodemap))
for s, d, e in zip(*sgi.graph.edges()):
assert sgi.induced_edges[e] in gi.edge_id(
sgi.induced_nodes[s], sgi.induced_nodes[d])
def test_edge_subgraph():
gi = create_graph_index(None, False)
gi.add_nodes(4)
gi.add_edge(0, 1)
gi.add_edge(0, 1)
gi.add_edge(0, 2)
gi.add_edge(2, 3)
sub2par_edgemap = [3, 2]
sgi = gi.edge_subgraph(toindex(sub2par_edgemap))
for s, d, e in zip(*sgi.graph.edges()):
assert sgi.induced_edges[e] in gi.edge_id(
sgi.induced_nodes[s], sgi.induced_nodes[d])
def test_edge_subgraph_preserve_nodes():
gi = create_graph_index(None, False)
gi.add_nodes(4)
gi.add_edge(0, 1)
gi.add_edge(0, 1)
gi.add_edge(0, 2)
gi.add_edge(2, 3)
sub2par_edgemap = [3, 2]
sgi = gi.edge_subgraph(toindex(sub2par_edgemap), preserve_nodes=True)
assert len(sgi.induced_nodes.tonumpy()) == 4
for s, d, e in zip(*sgi.graph.edges()):
assert sgi.induced_edges[e] in gi.edge_id(
sgi.induced_nodes[s], sgi.induced_nodes[d])
def test_immutable_edge_subgraph():
gi = create_graph_index(None, False)
gi.add_nodes(4)
gi.add_edge(0, 1)
gi.add_edge(0, 1)
gi.add_edge(0, 2)
gi.add_edge(2, 3)
gi.readonly() # Make the graph readonly
sub2par_edgemap = [3, 2]
sgi = gi.edge_subgraph(toindex(sub2par_edgemap))
for s, d, e in zip(*sgi.graph.edges()):
assert sgi.induced_edges[e] in gi.edge_id(
sgi.induced_nodes[s], sgi.induced_nodes[d])
def test_immutable_edge_subgraph_preserve_nodes():
gi = create_graph_index(None, False)
gi.add_nodes(4)
gi.add_edge(0, 1)
gi.add_edge(0, 1)
gi.add_edge(0, 2)
gi.add_edge(2, 3)
gi.readonly()
sub2par_edgemap = [3, 2]
sgi = gi.edge_subgraph(toindex(sub2par_edgemap), preserve_nodes=True)
assert len(sgi.induced_nodes.tonumpy()) == 4
for s, d, e in zip(*sgi.graph.edges()):
assert sgi.induced_edges[e] in gi.edge_id(
sgi.induced_nodes[s], sgi.induced_nodes[d])
def create_large_graph_index(num_nodes):
row = np.random.choice(num_nodes, num_nodes * 10)
col = np.random.choice(num_nodes, num_nodes * 10)
spm = spsp.coo_matrix((np.ones(len(row)), (row, col)))
return from_scipy_sparse_matrix(spm, True)
def test_node_subgraph_with_halo():
gi = create_large_graph_index(1000)
nodes = np.random.choice(gi.number_of_nodes(), 100, replace=False)
halo_subg, inner_node = gi.node_halo_subgraph(toindex(nodes), 2)
# Check if edges in the subgraph are in the original graph.
for s, d, e in zip(*halo_subg.graph.edges()):
assert halo_subg.induced_edges[e] in gi.edge_id(
halo_subg.induced_nodes[s], halo_subg.induced_nodes[d])
# Check if the inner node labels are correct.
inner_node = inner_node.asnumpy()
inner_node_ids = np.nonzero(inner_node)[0]
inner_node_ids = halo_subg.induced_nodes.tonumpy()[inner_node_ids]
assert np.all(np.sort(inner_node_ids) == np.sort(nodes))
if __name__ == '__main__':
test_node_subgraph()
test_node_subgraph_with_halo()
test_edge_subgraph()
test_edge_subgraph_preserve_nodes()
test_immutable_edge_subgraph()
test_immutable_edge_subgraph_preserve_nodes()
...@@ -389,7 +389,7 @@ ignored-classes=optparse.Values,thread._local,_thread._local ...@@ -389,7 +389,7 @@ ignored-classes=optparse.Values,thread._local,_thread._local
# (useful for modules/projects where namespaces are manipulated during runtime # (useful for modules/projects where namespaces are manipulated during runtime
# and thus existing member attributes cannot be deduced by static analysis. It # and thus existing member attributes cannot be deduced by static analysis. It
# supports qualified module names, as well as Unix pattern matching. # supports qualified module names, as well as Unix pattern matching.
ignored-modules=dgl.backend,dgl._api_internal ignored-modules=dgl.backend,dgl._api_internal,dgl._deprecate
# Show a hint with possible names when a member name was not found. The aspect # Show a hint with possible names when a member name was not found. The aspect
# of finding the hint is based on edit distance. # of finding the hint is based on edit distance.
......
import os
os.environ['DGLBACKEND'] = 'mxnet'
import mxnet as mx
import numpy as np
from dgl.graph import DGLGraph
import dgl
import scipy.sparse as spsp
D = 5
reduce_msg_shapes = set()
def check_eq(a, b):
assert a.shape == b.shape
assert mx.nd.sum(a == b).asnumpy() == int(np.prod(list(a.shape)))
def message_func(edges):
assert len(edges.src['h'].shape) == 2
assert edges.src['h'].shape[1] == D
return {'m' : edges.src['h']}
def reduce_func(nodes):
msgs = nodes.mailbox['m']
reduce_msg_shapes.add(tuple(msgs.shape))
assert len(msgs.shape) == 3
assert msgs.shape[2] == D
return {'m' : mx.nd.sum(msgs, 1)}
def apply_node_func(nodes):
return {'h' : nodes.data['h'] + nodes.data['m']}
def generate_graph(grad=False, readonly=False):
if readonly:
row_idx = []
col_idx = []
for i in range(1, 9):
row_idx.append(0)
col_idx.append(i)
row_idx.append(i)
col_idx.append(9)
row_idx.append(9)
col_idx.append(0)
ones = np.ones(shape=(len(row_idx)))
csr = spsp.csr_matrix((ones, (row_idx, col_idx)), shape=(10, 10))
g = DGLGraph(csr, readonly=True)
ncol = mx.nd.random.normal(shape=(10, D))
ecol = mx.nd.random.normal(shape=(17, D))
if grad:
ncol.attach_grad()
ecol.attach_grad()
g.ndata['h'] = ncol
g.edata['w'] = ecol
g.set_n_initializer(dgl.init.zero_initializer)
g.set_e_initializer(dgl.init.zero_initializer)
return g
else:
g = DGLGraph()
g.add_nodes(10) # 10 nodes.
# create a graph where 0 is the source and 9 is the sink
for i in range(1, 9):
g.add_edge(0, i)
g.add_edge(i, 9)
# add a back flow from 9 to 0
g.add_edge(9, 0)
ncol = mx.nd.random.normal(shape=(10, D))
ecol = mx.nd.random.normal(shape=(17, D))
if grad:
ncol.attach_grad()
ecol.attach_grad()
g.ndata['h'] = ncol
g.edata['w'] = ecol
g.set_n_initializer(dgl.init.zero_initializer)
g.set_e_initializer(dgl.init.zero_initializer)
return g
def test_batch_setter_getter():
def _pfc(x):
return list(x.asnumpy()[:,0])
g = generate_graph()
# set all nodes
g.set_n_repr({'h' : mx.nd.zeros((10, D))})
assert _pfc(g.ndata['h']) == [0.] * 10
# pop nodes
assert _pfc(g.pop_n_repr('h')) == [0.] * 10
assert len(g.ndata) == 0
g.set_n_repr({'h' : mx.nd.zeros((10, D))})
# set partial nodes
u = mx.nd.array([1, 3, 5], dtype='int64')
g.set_n_repr({'h' : mx.nd.ones((3, D))}, u)
assert _pfc(g.ndata['h']) == [0., 1., 0., 1., 0., 1., 0., 0., 0., 0.]
# get partial nodes
u = mx.nd.array([1, 2, 3], dtype='int64')
assert _pfc(g.get_n_repr(u)['h']) == [1., 0., 1.]
'''
s, d, eid
0, 1, 0
1, 9, 1
0, 2, 2
2, 9, 3
0, 3, 4
3, 9, 5
0, 4, 6
4, 9, 7
0, 5, 8
5, 9, 9
0, 6, 10
6, 9, 11
0, 7, 12
7, 9, 13
0, 8, 14
8, 9, 15
9, 0, 16
'''
# set all edges
g.edata['l'] = mx.nd.zeros((17, D))
assert _pfc(g.edata['l']) == [0.] * 17
# pop edges
old_len = len(g.edata)
assert _pfc(g.pop_e_repr('l')) == [0.] * 17
assert len(g.edata) == old_len - 1
g.edata['l'] = mx.nd.zeros((17, D))
# set partial edges (many-many)
u = mx.nd.array([0, 0, 2, 5, 9], dtype='int64')
v = mx.nd.array([1, 3, 9, 9, 0], dtype='int64')
g.edges[u, v].data['l'] = mx.nd.ones((5, D))
truth = [0.] * 17
truth[0] = truth[4] = truth[3] = truth[9] = truth[16] = 1.
assert _pfc(g.edata['l']) == truth
# set partial edges (many-one)
u = mx.nd.array([3, 4, 6], dtype='int64')
v = mx.nd.array([9], dtype='int64')
g.edges[u, v].data['l'] = mx.nd.ones((3, D))
truth[5] = truth[7] = truth[11] = 1.
assert _pfc(g.edata['l']) == truth
# set partial edges (one-many)
u = mx.nd.array([0], dtype='int64')
v = mx.nd.array([4, 5, 6], dtype='int64')
g.edges[u, v].data['l'] = mx.nd.ones((3, D))
truth[6] = truth[8] = truth[10] = 1.
assert _pfc(g.edata['l']) == truth
# get partial edges (many-many)
u = mx.nd.array([0, 6, 0], dtype='int64')
v = mx.nd.array([6, 9, 7], dtype='int64')
assert _pfc(g.edges[u, v].data['l']) == [1., 1., 0.]
# get partial edges (many-one)
u = mx.nd.array([5, 6, 7], dtype='int64')
v = mx.nd.array([9], dtype='int64')
assert _pfc(g.edges[u, v].data['l']) == [1., 1., 0.]
# get partial edges (one-many)
u = mx.nd.array([0], dtype='int64')
v = mx.nd.array([3, 4, 5], dtype='int64')
assert _pfc(g.edges[u, v].data['l']) == [1., 1., 1.]
def test_batch_setter_autograd():
with mx.autograd.record():
g = generate_graph(grad=True, readonly=True)
h1 = g.ndata['h']
h1.attach_grad()
# partial set
v = mx.nd.array([1, 2, 8], dtype='int64')
hh = mx.nd.zeros((len(v), D))
hh.attach_grad()
g.set_n_repr({'h' : hh}, v)
h2 = g.ndata['h']
h2.backward(mx.nd.ones((10, D)) * 2)
check_eq(h1.grad[:,0], mx.nd.array([2., 0., 0., 2., 2., 2., 2., 2., 0., 2.]))
check_eq(hh.grad[:,0], mx.nd.array([2., 2., 2.]))
def test_batch_send():
g = generate_graph()
def _fmsg(edges):
assert edges.src['h'].shape == (5, D)
return {'m' : edges.src['h']}
g.register_message_func(_fmsg)
# many-many send
u = mx.nd.array([0, 0, 0, 0, 0], dtype='int64')
v = mx.nd.array([1, 2, 3, 4, 5], dtype='int64')
g.send((u, v))
# one-many send
u = mx.nd.array([0], dtype='int64')
v = mx.nd.array([1, 2, 3, 4, 5], dtype='int64')
g.send((u, v))
# many-one send
u = mx.nd.array([1, 2, 3, 4, 5], dtype='int64')
v = mx.nd.array([9], dtype='int64')
g.send((u, v))
def check_batch_recv(readonly):
# basic recv test
g = generate_graph(readonly=readonly)
g.register_message_func(message_func)
g.register_reduce_func(reduce_func)
g.register_apply_node_func(apply_node_func)
u = mx.nd.array([0, 0, 0, 4, 5, 6], dtype='int64')
v = mx.nd.array([1, 2, 3, 9, 9, 9], dtype='int64')
reduce_msg_shapes.clear()
g.send((u, v))
#g.recv(th.unique(v))
#assert(reduce_msg_shapes == {(1, 3, D), (3, 1, D)})
#reduce_msg_shapes.clear()
def test_batch_recv():
check_batch_recv(True)
check_batch_recv(False)
def test_apply_nodes():
def _upd(nodes):
return {'h' : nodes.data['h'] * 2}
g = generate_graph()
g.register_apply_node_func(_upd)
old = g.ndata['h']
g.apply_nodes()
assert np.allclose((old * 2).asnumpy(), g.ndata['h'].asnumpy())
u = mx.nd.array([0, 3, 4, 6], dtype=np.int64)
g.apply_nodes(lambda nodes : {'h' : nodes.data['h'] * 0.}, u)
h = g.ndata['h'][u].asnumpy()
assert np.allclose(h, np.zeros(shape=(4, D), dtype=h.dtype))
def test_apply_edges():
def _upd(edges):
return {'w' : edges.data['w'] * 2}
g = generate_graph()
g.register_apply_edge_func(_upd)
old = g.edata['w']
g.apply_edges()
assert np.allclose((old * 2).asnumpy(), g.edata['w'].asnumpy())
u = mx.nd.array([0, 0, 0, 4, 5, 6], dtype=np.int64)
v = mx.nd.array([1, 2, 3, 9, 9, 9], dtype=np.int64)
g.apply_edges(lambda edges : {'w' : edges.data['w'] * 0.}, (u, v))
eid = g.edge_ids(u, v)
w = g.edata['w'][eid].asnumpy()
assert np.allclose(w, np.zeros(shape=(6, D), dtype=w.dtype))
def check_update_routines(readonly):
g = generate_graph(readonly=readonly)
g.register_message_func(message_func)
g.register_reduce_func(reduce_func)
g.register_apply_node_func(apply_node_func)
# send_and_recv
reduce_msg_shapes.clear()
u = mx.nd.array([0, 0, 0, 4, 5, 6], dtype='int64')
v = mx.nd.array([1, 2, 3, 9, 9, 9], dtype='int64')
g.send_and_recv((u, v))
assert(reduce_msg_shapes == {(1, 3, D), (3, 1, D)})
reduce_msg_shapes.clear()
# pull
v = mx.nd.array([1, 2, 3, 9], dtype='int64')
reduce_msg_shapes.clear()
g.pull(v)
assert(reduce_msg_shapes == {(1, 8, D), (3, 1, D)})
reduce_msg_shapes.clear()
# push
v = mx.nd.array([0, 1, 2, 3], dtype='int64')
reduce_msg_shapes.clear()
g.push(v)
assert(reduce_msg_shapes == {(1, 3, D), (8, 1, D)})
reduce_msg_shapes.clear()
# update_all
reduce_msg_shapes.clear()
g.update_all()
assert(reduce_msg_shapes == {(1, 8, D), (9, 1, D)})
reduce_msg_shapes.clear()
def test_update_routines():
check_update_routines(True)
check_update_routines(False)
def check_reduce_0deg(readonly):
if readonly:
row_idx = []
col_idx = []
for i in range(1, 5):
row_idx.append(i)
col_idx.append(0)
ones = np.ones(shape=(len(row_idx)))
csr = spsp.csr_matrix((ones, (row_idx, col_idx)), shape=(5, 5))
g = DGLGraph(csr, readonly=True)
else:
g = DGLGraph()
g.add_nodes(5)
g.add_edge(1, 0)
g.add_edge(2, 0)
g.add_edge(3, 0)
g.add_edge(4, 0)
def _message(edges):
return {'m' : edges.src['h']}
def _reduce(nodes):
return {'h' : nodes.data['h'] + nodes.mailbox['m'].sum(1)}
def _init2(shape, dtype, ctx, ids):
return 2 + mx.nd.zeros(shape, dtype=dtype, ctx=ctx)
g.set_n_initializer(_init2, 'h')
old_repr = mx.nd.random.normal(shape=(5, 5))
g.set_n_repr({'h': old_repr})
g.update_all(_message, _reduce)
new_repr = g.ndata['h']
assert np.allclose(new_repr[1:].asnumpy(), 2+np.zeros((4, 5)))
assert np.allclose(new_repr[0].asnumpy(), old_repr.sum(0).asnumpy())
def test_reduce_0deg():
check_reduce_0deg(True)
check_reduce_0deg(False)
def test_recv_0deg_newfld():
# test recv with 0deg nodes; the reducer also creates a new field
g = DGLGraph()
g.add_nodes(2)
g.add_edge(0, 1)
def _message(edges):
return {'m' : edges.src['h']}
def _reduce(nodes):
return {'h1' : nodes.data['h'] + mx.nd.sum(nodes.mailbox['m'], 1)}
def _apply(nodes):
return {'h1' : nodes.data['h1'] * 2}
def _init2(shape, dtype, ctx, ids):
return 2 + mx.nd.zeros(shape=shape, dtype=dtype, ctx=ctx)
g.register_message_func(_message)
g.register_reduce_func(_reduce)
g.register_apply_node_func(_apply)
# test#1: recv both 0deg and non-0deg nodes
old = mx.nd.random.normal(shape=(2, 5))
g.set_n_initializer(_init2, 'h1')
g.ndata['h'] = old
g.send((0, 1))
g.recv([0, 1])
new = g.ndata.pop('h1')
# 0deg check: initialized with the func and got applied
assert np.allclose(new[0].asnumpy(), np.full((5,), 4))
# non-0deg check
assert np.allclose(new[1].asnumpy(), mx.nd.sum(old, 0).asnumpy() * 2)
# test#2: recv only 0deg node
old = mx.nd.random.normal(shape=(2, 5))
g.ndata['h'] = old
g.ndata['h1'] = mx.nd.full((2, 5), -1) # this is necessary
g.send((0, 1))
g.recv(0)
new = g.ndata.pop('h1')
# 0deg check: fallback to apply
assert np.allclose(new[0].asnumpy(), np.full((5,), -2))
# non-0deg check: not changed
assert np.allclose(new[1].asnumpy(), np.full((5,), -1))
def test_update_all_0deg():
# test#1
g = DGLGraph()
g.add_nodes(5)
g.add_edge(1, 0)
g.add_edge(2, 0)
g.add_edge(3, 0)
g.add_edge(4, 0)
def _message(edges):
return {'m' : edges.src['h']}
def _reduce(nodes):
return {'h' : nodes.data['h'] + mx.nd.sum(nodes.mailbox['m'], 1)}
def _apply(nodes):
return {'h' : nodes.data['h'] * 2}
def _init2(shape, dtype, ctx, ids):
return 2 + mx.nd.zeros(shape, dtype=dtype, ctx=ctx)
g.set_n_initializer(_init2, 'h')
old_repr = mx.nd.random.normal(shape=(5, 5))
g.ndata['h'] = old_repr
g.update_all(_message, _reduce, _apply)
new_repr = g.ndata['h']
# the first row of the new_repr should be the sum of all the node
# features; while the 0-deg nodes should be initialized by the
# initializer and applied with UDF.
assert np.allclose(new_repr[1:].asnumpy(), 2*(2+np.zeros((4,5))))
assert np.allclose(new_repr[0].asnumpy(), 2 * mx.nd.sum(old_repr, 0).asnumpy())
# test#2: graph with no edge
g = DGLGraph()
g.add_nodes(5)
g.set_n_initializer(_init2, 'h')
g.ndata['h'] = old_repr
g.update_all(_message, _reduce, _apply)
new_repr = g.ndata['h']
# should fallback to apply
assert np.allclose(new_repr.asnumpy(), 2*old_repr.asnumpy())
def check_pull_0deg(readonly):
if readonly:
row_idx = []
col_idx = []
row_idx.append(0)
col_idx.append(1)
ones = np.ones(shape=(len(row_idx)))
csr = spsp.csr_matrix((ones, (row_idx, col_idx)), shape=(2, 2))
g = DGLGraph(csr, readonly=True)
else:
g = DGLGraph()
g.add_nodes(2)
g.add_edge(0, 1)
def _message(edges):
return {'m' : edges.src['h']}
def _reduce(nodes):
return {'h' : nodes.mailbox['m'].sum(1)}
def _apply(nodes):
return {'h' : nodes.data['h'] * 2}
def _init2(shape, dtype, ctx, ids):
return 2 + mx.nd.zeros(shape, dtype=dtype, ctx=ctx)
g.set_n_initializer(_init2, 'h')
old_repr = mx.nd.random.normal(shape=(2, 5))
# test#1: pull only 0-deg node
g.ndata['h'] = old_repr
g.pull(0, _message, _reduce, _apply)
new_repr = g.ndata['h']
# 0deg check: equal to apply_nodes
assert np.allclose(new_repr[0].asnumpy(), old_repr[0].asnumpy() * 2)
# non-0deg check: untouched
assert np.allclose(new_repr[1].asnumpy(), old_repr[1].asnumpy())
# test#2: pull only non-deg node
g.ndata['h'] = old_repr
g.pull(1, _message, _reduce, _apply)
new_repr = g.ndata['h']
# 0deg check: untouched
assert np.allclose(new_repr[0].asnumpy(), old_repr[0].asnumpy())
# non-0deg check: recved node0 and got applied
assert np.allclose(new_repr[1].asnumpy(), old_repr[0].asnumpy() * 2)
# test#3: pull only both nodes
g.ndata['h'] = old_repr
g.pull([0, 1], _message, _reduce, _apply)
new_repr = g.ndata['h']
# 0deg check: init and applied
t = mx.nd.zeros(shape=(2,5)) + 4
assert np.allclose(new_repr[0].asnumpy(), t.asnumpy())
# non-0deg check: recv node0 and applied
assert np.allclose(new_repr[1].asnumpy(), old_repr[0].asnumpy() * 2)
def test_pull_0deg():
check_pull_0deg(True)
check_pull_0deg(False)
def test_repr():
G = dgl.DGLGraph()
G.add_nodes(10)
G.add_edge(0, 1)
repr_string = G.__repr__()
G.ndata['x'] = mx.nd.zeros((10, 5))
G.add_edges([0, 1], 2)
G.edata['y'] = mx.nd.zeros((3, 4))
repr_string = G.__repr__()
if __name__ == '__main__':
test_batch_setter_getter()
test_batch_setter_autograd()
test_batch_send()
test_batch_recv()
test_apply_nodes()
test_apply_edges()
test_update_routines()
test_reduce_0deg()
test_recv_0deg_newfld()
test_update_all_0deg()
test_pull_0deg()
test_repr()
...@@ -16,7 +16,6 @@ SET DGL_DOWNLOAD_DIR=!CD! ...@@ -16,7 +16,6 @@ SET DGL_DOWNLOAD_DIR=!CD!
python -m pip install pytest || EXIT /B 1 python -m pip install pytest || EXIT /B 1
python -m pytest -v --junitxml=pytest_backend.xml tests\!DGLBACKEND! || EXIT /B 1 python -m pytest -v --junitxml=pytest_backend.xml tests\!DGLBACKEND! || EXIT /B 1
python -m pytest -v --junitxml=pytest_gindex.xml tests\graph_index || EXIT /B 1
python -m pytest -v --junitxml=pytest_compute.xml tests\compute || EXIT /B 1 python -m pytest -v --junitxml=pytest_compute.xml tests\compute || EXIT /B 1
ENDLOCAL ENDLOCAL
EXIT /B EXIT /B
...@@ -33,7 +33,6 @@ fi ...@@ -33,7 +33,6 @@ fi
conda activate ${DGLBACKEND}-ci conda activate ${DGLBACKEND}-ci
python3 -m pytest -v --junitxml=pytest_compute.xml tests/compute || fail "compute" python3 -m pytest -v --junitxml=pytest_compute.xml tests/compute || fail "compute"
python3 -m pytest -v --junitxml=pytest_gindex.xml tests/graph_index || fail "graph_index"
python3 -m pytest -v --junitxml=pytest_backend.xml tests/$DGLBACKEND || fail "backend-specific" python3 -m pytest -v --junitxml=pytest_backend.xml tests/$DGLBACKEND || fail "backend-specific"
export OMP_NUM_THREADS=1 export OMP_NUM_THREADS=1
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment