test_graph.py 5.6 KB
Newer Older
1
2
3
4
import time
import math
import numpy as np
import scipy.sparse as sp
5
import networkx as nx
6
import dgl
7
import backend as F
8
from dgl import DGLError
9
10
11
12
13

def test_graph_creation():
    g = dgl.DGLGraph()
    # test add nodes with data
    g.add_nodes(5)
14
15
16
17
18
    g.add_nodes(5, {'h' : F.ones((5, 2))})
    ans = F.cat([F.zeros((5, 2)), F.ones((5, 2))], 0)
    assert F.allclose(ans, g.ndata['h'])
    g.ndata['w'] = 2 * F.ones((10, 2))
    assert F.allclose(2 * F.ones((10, 2)), g.ndata['w'])
19
20
    # test add edges with data
    g.add_edges([2, 3], [3, 4])
21
22
23
    g.add_edges([0, 1], [1, 2], {'m' : F.ones((2, 2))})
    ans = F.cat([F.zeros((2, 2)), F.ones((2, 2))], 0)
    assert F.allclose(ans, g.edata['m'])
24
25
26
    # test clear and add again
    g.clear()
    g.add_nodes(5)
27
28
    g.ndata['h'] = 3 * F.ones((5, 2))
    assert F.allclose(3 * F.ones((5, 2)), g.ndata['h'])
29

30
31
32
33
34
35
def test_create_from_elist():
    elist = [(2, 1), (1, 0), (2, 0), (3, 0), (0, 2)]
    g = dgl.DGLGraph(elist)
    for i, (u, v) in enumerate(elist):
        assert g.edge_id(u, v) == i
    # immutable graph
Minjie Wang's avatar
Minjie Wang committed
36
37
38
39
    # XXX: not enabled for pytorch
    #g = dgl.DGLGraph(elist, readonly=True)
    #for i, (u, v) in enumerate(elist):
    #    assert g.edge_id(u, v) == i
40

41
def test_adjmat_cache():
42
43
44
45
46
47
    n = 1000
    p = 10 * math.log(n) / n
    a = sp.random(n, n, p, data_rvs=lambda n: np.ones(n))
    g = dgl.DGLGraph(a)
    # the first call should contruct the adj
    t0 = time.time()
48
    adj1 = g.adjacency_matrix()
49
50
51
    dur1 = time.time() - t0
    # the second call should be cached and should be very fast
    t0 = time.time()
52
    adj2 = g.adjacency_matrix()
53
    dur2 = time.time() - t0
54
55
    print('first time {}, second time {}'.format(dur1, dur2))
    assert dur2 < dur1
56
57
58
59
60
61
62
63
64
65
66
67
    assert id(adj1) == id(adj2)
    # different arg should result in different cache
    adj3 = g.adjacency_matrix(transpose=True)
    assert id(adj3) != id(adj2)
    # manually clear the cache
    g.clear_cache()
    adj35 = g.adjacency_matrix()
    assert id(adj35) != id(adj2)
    # mutating the graph should invalidate the cache
    g.add_nodes(10)
    adj4 = g.adjacency_matrix()
    assert id(adj4) != id(adj35)
68
69
70
71
72
73
74
75
76

def test_incmat():
    g = dgl.DGLGraph()
    g.add_nodes(4)
    g.add_edge(0, 1) # 0
    g.add_edge(0, 2) # 1
    g.add_edge(0, 3) # 2
    g.add_edge(2, 3) # 3
    g.add_edge(1, 1) # 4
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
    inc_in = F.sparse_to_numpy(g.incidence_matrix('in'))
    inc_out = F.sparse_to_numpy(g.incidence_matrix('out'))
    inc_both = F.sparse_to_numpy(g.incidence_matrix('both'))
    print(inc_in)
    print(inc_out)
    print(inc_both)
    assert np.allclose(
            inc_in,
            np.array([[0., 0., 0., 0., 0.],
                      [1., 0., 0., 0., 1.],
                      [0., 1., 0., 0., 0.],
                      [0., 0., 1., 1., 0.]]))
    assert np.allclose(
            inc_out,
            np.array([[1., 1., 1., 0., 0.],
                      [0., 0., 0., 0., 1.],
                      [0., 0., 0., 1., 0.],
                      [0., 0., 0., 0., 0.]]))
    assert np.allclose(
            inc_both,
            np.array([[-1., -1., -1., 0., 0.],
                      [1., 0., 0., 0., 0.],
                      [0., 1., 0., -1., 0.],
                      [0., 0., 1., 1., 0.]]))
101

102
def test_incmat_cache():
103
    n = 1000
104
    p = 10 * math.log(n) / n
105
106
    a = sp.random(n, n, p, data_rvs=lambda n: np.ones(n))
    g = dgl.DGLGraph(a)
107
    # the first call should contruct the inc
108
    t0 = time.time()
109
    inc1 = g.incidence_matrix("in")
110
111
112
    dur1 = time.time() - t0
    # the second call should be cached and should be very fast
    t0 = time.time()
113
    inc2 = g.incidence_matrix("in")
114
    dur2 = time.time() - t0
115
    print('first time {}, second time {}'.format(dur1, dur2))
116
    assert dur2 < dur1
117
118
    assert id(inc1) == id(inc2)
    # different arg should result in different cache
Minjie Wang's avatar
Minjie Wang committed
119
    inc3 = g.incidence_matrix("both")
120
121
122
123
124
125
126
127
128
    assert id(inc3) != id(inc2)
    # manually clear the cache
    g.clear_cache()
    inc35 = g.incidence_matrix("in")
    assert id(inc35) != id(inc2)
    # mutating the graph should invalidate the cache
    g.add_nodes(10)
    inc4 = g.incidence_matrix("in")
    assert id(inc4) != id(inc35)
129

130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
def test_readonly():
    g = dgl.DGLGraph()
    g.add_nodes(5)
    g.add_edges([0, 1, 2, 3], [1, 2, 3, 4])
    g.ndata['x'] = F.zeros((5, 3))
    g.edata['x'] = F.zeros((4, 4))

    g.readonly(False)
    assert g._graph.is_readonly() == False
    assert g.number_of_nodes() == 5
    assert g.number_of_edges() == 4

    g.readonly()
    assert g._graph.is_readonly() == True 
    assert g.number_of_nodes() == 5
    assert g.number_of_edges() == 4

    try:
        g.add_nodes(5)
        fail = False
    except DGLError:
        fail = True
    finally:
        assert fail

    g.readonly()
    assert g._graph.is_readonly() == True 
    assert g.number_of_nodes() == 5
    assert g.number_of_edges() == 4

    try:
        g.add_nodes(5)
        fail = False
    except DGLError:
        fail = True
    finally:
        assert fail

    g.readonly(False)
    assert g._graph.is_readonly() == False
    assert g.number_of_nodes() == 5
    assert g.number_of_edges() == 4

    try:
        g.add_nodes(10)
        g.add_edges([4, 5, 6, 7, 8, 9, 10, 11, 12, 13],
                    [5, 6, 7, 8, 9, 10, 11, 12, 13, 14])
        fail = False
    except DGLError:
        fail = True
    finally:
        assert not fail
        assert g.number_of_nodes() == 15
        assert F.shape(g.ndata['x']) == (15, 3)
        assert g.number_of_edges() == 14
        assert F.shape(g.edata['x']) == (14, 4)

187
if __name__ == '__main__':
188
    test_graph_creation()
189
    test_create_from_elist()
190
    test_adjmat_cache()
191
    test_incmat()
192
    test_incmat_cache()
193
    test_readonly()