def test_1neighbor_sampler_all(): g = generate_rand_graph(100) # In this case, NeighborSampling simply gets the neighborhood of a single vertex. for subg, aux in dgl.contrib.sampling.NeighborSampler(g, 1, 100, neighbor_type='in', num_workers=4, return_seed_id=True): seed_ids = aux['seeds'] assert len(seed_ids) == 1 src, dst, eid = g.in_edges(seed_ids, form='all') # Test if there is a self loop self_loop = F.asnumpy(F.sum(src == dst, 0)) == 1 if self_loop: assert subg.number_of_nodes() == len(src) else: assert subg.number_of_nodes() == len(src) + 1 assert subg.number_of_edges() >= len(src) child_ids = subg.map_to_subgraph_nid(seed_ids) child_src, child_dst, child_eid = subg.in_edges(child_ids, form='all') child_src1 = subg.map_to_subgraph_nid(src) assert F.asnumpy(F.sum(child_src1 == child_src, 0)) == len(src)
def check_dist_emb(g, num_clients, num_nodes, num_edges): from dgl.distributed.optim import SparseAdagrad from dgl.distributed import DistEmbedding # Test sparse emb try: emb = DistEmbedding(g.number_of_nodes(), 1, 'emb1', emb_init) nids = F.arange(0, int(g.number_of_nodes())) lr = 0.001 optimizer = SparseAdagrad([emb], lr=lr) with F.record_grad(): feats = emb(nids) assert np.all(F.asnumpy(feats) == np.zeros((len(nids), 1))) loss = F.sum(feats + 1, 0) loss.backward() optimizer.step() feats = emb(nids) if num_clients == 1: assert_almost_equal(F.asnumpy(feats), np.ones((len(nids), 1)) * -lr) rest = np.setdiff1d(np.arange(g.number_of_nodes()), F.asnumpy(nids)) feats1 = emb(rest) assert np.all(F.asnumpy(feats1) == np.zeros((len(rest), 1))) policy = dgl.distributed.PartitionPolicy('node', g.get_partition_book()) grad_sum = dgl.distributed.DistTensor((g.number_of_nodes(), 1), F.float32, 'emb1_sum', policy) if num_clients == 1: assert np.all( F.asnumpy(grad_sum[nids]) == np.ones((len(nids), 1)) * num_clients) assert np.all(F.asnumpy(grad_sum[rest]) == np.zeros((len(rest), 1))) emb = DistEmbedding(g.number_of_nodes(), 1, 'emb2', emb_init) with F.no_grad(): feats1 = emb(nids) assert np.all(F.asnumpy(feats1) == 0) optimizer = SparseAdagrad([emb], lr=lr) with F.record_grad(): feats1 = emb(nids) feats2 = emb(nids) feats = F.cat([feats1, feats2], 0) assert np.all(F.asnumpy(feats) == np.zeros((len(nids) * 2, 1))) loss = F.sum(feats + 1, 0) loss.backward() optimizer.step() with F.no_grad(): feats = emb(nids) if num_clients == 1: assert_almost_equal(F.asnumpy(feats), np.ones((len(nids), 1)) * 1 * -lr) rest = np.setdiff1d(np.arange(g.number_of_nodes()), F.asnumpy(nids)) feats1 = emb(rest) assert np.all(F.asnumpy(feats1) == np.zeros((len(rest), 1))) except NotImplementedError as e: pass except Exception as e: print(e) sys.exit(-1)
def check_basic(g, nf): num_nodes = 0 for i in range(nf.num_layers): num_nodes += nf.layer_size(i) assert nf.number_of_nodes() == num_nodes num_edges = 0 for i in range(nf.num_blocks): num_edges += nf.block_size(i) assert nf.number_of_edges() == num_edges assert len(nf) == num_nodes assert nf.is_readonly assert not nf.is_multigraph assert np.all(F.asnumpy(nf.has_nodes(list(range(num_nodes))))) for i in range(num_nodes): assert nf.has_node(i) assert np.all( F.asnumpy(nf.has_nodes(list(range(num_nodes, 2 * num_nodes)))) == 0) for i in range(num_nodes, 2 * num_nodes): assert not nf.has_node(i) for block_id in range(nf.num_blocks): u, v, eid = nf.block_edges(block_id) assert np.all(F.asnumpy(nf.has_edges_between(u, v))) deg = nf.layer_in_degree(0) assert_array_equal(F.asnumpy(deg), np.zeros((nf.layer_size(0)), np.int64)) deg = nf.layer_out_degree(-1) assert_array_equal(F.asnumpy(deg), np.zeros((nf.layer_size(-1)), np.int64)) nf.copy_from_parent() for i in range(1, nf.num_layers): in_deg = nf.layer_in_degree(i) out_deg = nf.layer_out_degree(i - 1) assert F.asnumpy(F.sum(in_deg, 0) == F.sum(out_deg, 0)) nids = nf.layer_nid(i) parent_nids = nf.map_to_parent_nid(nids) nids1 = nf.map_from_parent_nid(i, parent_nids) assert_array_equal(F.asnumpy(nids), F.asnumpy(nids1)) data = nf.layers[i].data['h1'] data1 = g.nodes[nf.layer_parent_nid(i)].data['h1'] assert_array_equal(F.asnumpy(data), F.asnumpy(data1)) for i in range(nf.num_blocks): data = nf.blocks[i].data['h2'] data1 = g.edges[nf.block_parent_eid(i)].data['h2'] assert_array_equal(F.asnumpy(data), F.asnumpy(data1)) # negative layer Ids. for i in range(-1, -nf.num_layers, -1): in_deg = nf.layer_in_degree(i) out_deg = nf.layer_out_degree(i - 1) assert F.asnumpy(F.sum(in_deg, 0) == F.sum(out_deg, 0))
def test_simple_readout(): g1 = dgl.DGLGraph() g1.add_nodes(3) g2 = dgl.DGLGraph() g2.add_nodes(4) # no edges g1.add_edges([0, 1, 2], [2, 0, 1]) n1 = F.randn((3, 5)) n2 = F.randn((4, 5)) e1 = F.randn((3, 5)) s1 = F.sum(n1, 0) # node sums s2 = F.sum(n2, 0) se1 = F.sum(e1, 0) # edge sums m1 = F.mean(n1, 0) # node means m2 = F.mean(n2, 0) me1 = F.mean(e1, 0) # edge means w1 = F.randn((3, )) w2 = F.randn((4, )) max1 = F.max(n1, 0) max2 = F.max(n2, 0) maxe1 = F.max(e1, 0) ws1 = F.sum(n1 * F.unsqueeze(w1, 1), 0) ws2 = F.sum(n2 * F.unsqueeze(w2, 1), 0) wm1 = F.sum(n1 * F.unsqueeze(w1, 1), 0) / F.sum(F.unsqueeze(w1, 1), 0) wm2 = F.sum(n2 * F.unsqueeze(w2, 1), 0) / F.sum(F.unsqueeze(w2, 1), 0) g1.ndata['x'] = n1 g2.ndata['x'] = n2 g1.ndata['w'] = w1 g2.ndata['w'] = w2 g1.edata['x'] = e1 assert F.allclose(dgl.sum_nodes(g1, 'x'), s1) assert F.allclose(dgl.sum_nodes(g1, 'x', 'w'), ws1) assert F.allclose(dgl.sum_edges(g1, 'x'), se1) assert F.allclose(dgl.mean_nodes(g1, 'x'), m1) assert F.allclose(dgl.mean_nodes(g1, 'x', 'w'), wm1) assert F.allclose(dgl.mean_edges(g1, 'x'), me1) assert F.allclose(dgl.max_nodes(g1, 'x'), max1) assert F.allclose(dgl.max_edges(g1, 'x'), maxe1) g = dgl.batch([g1, g2]) s = dgl.sum_nodes(g, 'x') m = dgl.mean_nodes(g, 'x') max_bg = dgl.max_nodes(g, 'x') assert F.allclose(s, F.stack([s1, s2], 0)) assert F.allclose(m, F.stack([m1, m2], 0)) assert F.allclose(max_bg, F.stack([max1, max2], 0)) ws = dgl.sum_nodes(g, 'x', 'w') wm = dgl.mean_nodes(g, 'x', 'w') assert F.allclose(ws, F.stack([ws1, ws2], 0)) assert F.allclose(wm, F.stack([wm1, wm2], 0)) s = dgl.sum_edges(g, 'x') m = dgl.mean_edges(g, 'x') max_bg_e = dgl.max_edges(g, 'x') assert F.allclose(s, F.stack([se1, F.zeros(5)], 0)) assert F.allclose(m, F.stack([me1, F.zeros(5)], 0)) assert F.allclose(max_bg_e, F.stack([maxe1, F.zeros(5)], 0))
def test_pull_0deg(index_dtype): g = dgl.graph([(0, 1)], index_dtype=index_dtype) def _message(edges): return {'m': edges.src['h']} def _reduce(nodes): return {'h': nodes.data['h'] + F.sum(nodes.mailbox['m'], 1)} def _apply(nodes): return {'h': nodes.data['h'] * 2} def _init2(shape, dtype, ctx, ids): return 2 + F.zeros(shape, dtype, ctx) g.set_n_initializer(_init2, 'h') # test#1: pull both 0deg and non-0deg nodes old = F.randn((2, 5)) g.ndata['h'] = old g.pull([0, 1], _message, _reduce, _apply) new = g.ndata.pop('h') # 0deg check: initialized with the func and got applied assert F.allclose(new[0], F.full_1d(5, 4, dtype=F.float32)) # non-0deg check assert F.allclose(new[1], F.sum(old, 0) * 2) # test#2: pull only 0deg node old = F.randn((2, 5)) g.ndata['h'] = old g.pull(0, _message, _reduce, _apply) new = g.ndata.pop('h') # 0deg check: fallback to apply assert F.allclose(new[0], 2 * old[0]) # non-0deg check: not touched assert F.allclose(new[1], old[1])
def test_hvp2(backendopt): for datatype in backendopt: T.set_backend(datatype) x = ad.Variable(name="x", shape=[3, 1]) H = ad.Variable(name="H", shape=[3, 3]) v = ad.Variable(name="v", shape=[3, 1]) y = ad.sum( ad.einsum("ab,bc->ac", ad.einsum("ab,bc->ac", ad.transpose(x), H), x)) grad_x, = ad.gradients(y, [x]) Hv, = ad.hvp(output_node=y, node_list=[x], vector_list=[v]) executor = ad.Executor([y, grad_x, Hv]) x_val = T.tensor([[1.], [2.], [3]]) # 3x1 v_val = T.tensor([[1.], [2.], [3]]) # 3x1 H_val = T.tensor([[2., 0., 0.], [0., 2., 0.], [0., 0., 2.]]) # 3x3 y_val, grad_x_val, Hv_val = executor.run(feed_dict={ x: x_val, H: H_val, v: v_val }) expected_yval = T.sum(T.transpose(x_val) @ H_val @ x_val) expected_grad_x_val = 2 * H_val @ x_val expected_hv_val = T.tensor([[4.], [8.], [12.]]) assert isinstance(y, ad.Node) assert T.array_equal(y_val, expected_yval) assert T.array_equal(grad_x_val, expected_grad_x_val) assert T.array_equal(Hv_val, expected_hv_val)
def test_einsum(backendopt): for datatype in backendopt: T.set_backend(datatype) x2 = ad.Variable(name="x2", shape=[3, 2]) x3 = ad.Variable(name="x3", shape=[2, 3]) matmul = ad.einsum('ik,kj->ij', x2, x3) y = ad.sum(matmul) grad_x2, grad_x3 = ad.gradients(y, [x2, x3]) executor = ad.Executor([y, grad_x2, grad_x3]) x2_val = T.tensor([[1, 2], [3, 4], [5, 6]]) # 3x2 x3_val = T.tensor([[7, 8, 9], [10, 11, 12]]) # 2x3 y_val, grad_x2_val, grad_x3_val = executor.run(feed_dict={ x2: x2_val, x3: x3_val }) expected_grad_sum = T.ones_like(T.dot(x2_val, x3_val)) expected_yval = T.sum(T.dot(x2_val, x3_val)) expected_grad_x2_val = T.dot(expected_grad_sum, T.transpose(x3_val)) expected_grad_x3_val = T.dot(T.transpose(x2_val), expected_grad_sum) assert isinstance(y, ad.Node) assert T.array_equal(y_val, expected_yval) assert T.array_equal(grad_x2_val, expected_grad_x2_val) assert T.array_equal(grad_x3_val, expected_grad_x3_val)
def test_add_mul_mix_3(backendopt): for datatype in backendopt: T.set_backend(datatype) x2 = ad.Variable(name="x2", shape=[3]) x3 = ad.Variable(name="x3", shape=[3]) z = x2 * x2 + x2 + x3 + 3 y = ad.sum(z * z + x3) grad_x2, grad_x3 = ad.gradients(y, [x2, x3]) executor = ad.Executor([y, grad_x2, grad_x3]) x2_val = 2 * T.ones(3) x3_val = 3 * T.ones(3) y_val, grad_x2_val, grad_x3_val = executor.run(feed_dict={ x2: x2_val, x3: x3_val }) z_val = x2_val * x2_val + x2_val + x3_val + 3 expected_yval = z_val * z_val + x3_val expected_grad_x2_val = 2 * \ (x2_val * x2_val + x2_val + x3_val + 3) * (2 * x2_val + 1) expected_grad_x3_val = 2 * (x2_val * x2_val + x2_val + x3_val + 3) + 1 assert isinstance(y, ad.Node) assert T.array_equal(y_val, T.sum(expected_yval)) assert T.array_equal(grad_x2_val, expected_grad_x2_val) assert T.array_equal(grad_x3_val, expected_grad_x3_val)
def test_add_mul_mix_2(backendopt): for datatype in backendopt: T.set_backend(datatype) x1 = ad.Variable(name="x1", shape=[3]) x2 = ad.Variable(name="x2", shape=[3]) x3 = ad.Variable(name="x3", shape=[3]) x4 = ad.Variable(name="x4", shape=[3]) y = ad.sum(x1 + x2 * x3 * x4) grad_x1, grad_x2, grad_x3, grad_x4 = ad.gradients(y, [x1, x2, x3, x4]) executor = ad.Executor([y, grad_x1, grad_x2, grad_x3, grad_x4]) x1_val = 1 * T.ones(3) x2_val = 2 * T.ones(3) x3_val = 3 * T.ones(3) x4_val = 4 * T.ones(3) y_val, grad_x1_val, grad_x2_val, grad_x3_val, grad_x4_val = executor.run( feed_dict={ x1: x1_val, x2: x2_val, x3: x3_val, x4: x4_val }) assert isinstance(y, ad.Node) assert T.array_equal(y_val, T.sum(x1_val + x2_val * x3_val * x4_val)) assert T.array_equal(grad_x1_val, T.ones_like(x1_val)) assert T.array_equal(grad_x2_val, x3_val * x4_val) assert T.array_equal(grad_x3_val, x2_val * x4_val) assert T.array_equal(grad_x4_val, x2_val * x3_val)
def test_update_all_0deg(index_dtype): # test#1 g = dgl.graph([(1, 0), (2, 0), (3, 0), (4, 0)], index_dtype=index_dtype) def _message(edges): return {'m': edges.src['h']} def _reduce(nodes): return {'h': nodes.data['h'] + F.sum(nodes.mailbox['m'], 1)} def _apply(nodes): return {'h': nodes.data['h'] * 2} def _init2(shape, dtype, ctx, ids): return 2 + F.zeros(shape, dtype, ctx) g.set_n_initializer(_init2, 'h') old_repr = F.randn((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 F.allclose(new_repr[1:], 2 * (2 + F.zeros((4, 5)))) assert F.allclose(new_repr[0], 2 * F.sum(old_repr, 0)) # test#2: g = dgl.graph([], num_nodes=5, index_dtype=index_dtype) 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 F.allclose(new_repr, 2 * old_repr)
def test_recv_0deg_newfld(): # test recv with 0deg nodes; the reducer also creates a new field g = dgl.graph([(0,1)]) def _message(edges): return {'m' : edges.src['h']} def _reduce(nodes): return {'h1' : nodes.data['h'] + F.sum(nodes.mailbox['m'], 1)} def _apply(nodes): return {'h1' : nodes.data['h1'] * 2} def _init2(shape, dtype, ctx, ids): return 2 + F.zeros(shape, dtype=dtype, ctx=ctx) # test#1: recv both 0deg and non-0deg nodes old = F.randn((2, 5)) g.set_n_initializer(_init2, 'h1') g.ndata['h'] = old g.send((0, 1), _message) g.recv([0, 1], _reduce, _apply) new = g.ndata.pop('h1') # 0deg check: initialized with the func and got applied assert F.allclose(new[0], F.full_1d(5, 4, dtype=F.float32)) # non-0deg check assert F.allclose(new[1], F.sum(old, 0) * 2) # test#2: recv only 0deg node old = F.randn((2, 5)) g.ndata['h'] = old g.ndata['h1'] = F.full((2, 5), -1, F.int64) # this is necessary g.send((0, 1), _message) g.recv(0, _reduce, _apply) new = g.ndata.pop('h1') # 0deg check: fallback to apply assert F.allclose(new[0], F.full_1d(5, -2, F.int64)) # non-0deg check: not changed assert F.allclose(new[1], F.full_1d(5, -1, F.int64))
def test_batch_propagate(): t1 = tree1() t2 = tree2() bg = dgl.batch([t1, t2]) bg.register_message_func(lambda edges: {'m': edges.src['h']}) bg.register_reduce_func(lambda nodes: {'h': F.sum(nodes.mailbox['m'], 1)}) # get leaves. order = [] # step 1 u = [3, 4, 2 + 5, 0 + 5] v = [1, 1, 4 + 5, 4 + 5] order.append((u, v)) # step 2 u = [1, 2, 4 + 5, 3 + 5] v = [0, 0, 1 + 5, 1 + 5] order.append((u, v)) bg.prop_edges(order) t1, t2 = dgl.unbatch(bg) assert F.asnumpy(t1.ndata['h'][0]) == 9 assert F.asnumpy(t2.ndata['h'][1]) == 5
def test_recv_0deg(): # test recv with 0deg nodes; g = dgl.graph([(0,1)]) def _message(edges): return {'m' : edges.src['h']} def _reduce(nodes): return {'h' : nodes.data['h'] + F.sum(nodes.mailbox['m'], 1)} def _apply(nodes): return {'h' : nodes.data['h'] * 2} def _init2(shape, dtype, ctx, ids): return 2 + F.zeros(shape, dtype, ctx) g.set_n_initializer(_init2, 'h') # test#1: recv both 0deg and non-0deg nodes old = F.randn((2, 5)) g.ndata['h'] = old g.send((0, 1), _message) g.recv([0, 1], _reduce, _apply) new = g.ndata.pop('h') # 0deg check: initialized with the func and got applied assert F.allclose(new[0], F.full_1d(5, 4, F.float32)) # non-0deg check assert F.allclose(new[1], F.sum(old, 0) * 2) # test#2: recv only 0deg node is equal to apply old = F.randn((2, 5)) g.ndata['h'] = old g.send((0, 1), _message) g.recv(0, _reduce, _apply) new = g.ndata.pop('h') # 0deg check: equal to apply_nodes assert F.allclose(new[0], 2 * old[0]) # non-0deg check: untouched assert F.allclose(new[1], old[1])
def test_subgraph_message_passing(): # Unit test for PR #2055 g = dgl.graph(([0, 1, 2], [2, 3, 4])).to(F.cpu()) g.ndata['x'] = F.copy_to(F.randn((5, 6)), F.cpu()) sg = g.subgraph([1, 2, 3]).to(F.ctx()) sg.update_all(lambda edges: {'x': edges.src['x']}, lambda nodes: {'y': F.sum(nodes.mailbox['x'], 1)})
def test_batch_propagate(idtype): t1 = tree1(idtype) t2 = tree2(idtype) bg = dgl.batch([t1, t2]) _mfunc = lambda edges: {'m': edges.src['h']} _rfunc = lambda nodes: {'h': F.sum(nodes.mailbox['m'], 1)} # get leaves. order = [] # step 1 u = [3, 4, 2 + 5, 0 + 5] v = [1, 1, 4 + 5, 4 + 5] order.append((u, v)) # step 2 u = [1, 2, 4 + 5, 3 + 5] v = [0, 0, 1 + 5, 1 + 5] order.append((u, v)) bg.prop_edges(order, _mfunc, _rfunc) t1, t2 = dgl.unbatch(bg) assert F.asnumpy(t1.ndata['h'][0]) == 9 assert F.asnumpy(t2.ndata['h'][1]) == 5
def test_node_subgraph(): num_vertices = 100 g, ig = generate_rand_graph(num_vertices) # node_subgraph randv1 = np.random.randint(0, num_vertices, 20) randv = np.unique(randv1) subg = g.node_subgraph(utils.toindex(randv)) subig = ig.node_subgraph(utils.toindex(randv)) check_basics(subg, subig) check_graph_equal(subg, subig) assert F.sum( map_to_subgraph_nid(subg, utils.toindex( randv1[0:10])).tousertensor() == map_to_subgraph_nid( subig, utils.toindex(randv1[0:10])).tousertensor(), 0) == 10 # node_subgraphs randvs = [] subgs = [] for i in range(4): randv = np.unique(np.random.randint(0, num_vertices, 20)) randvs.append(utils.toindex(randv)) subgs.append(g.node_subgraph(utils.toindex(randv))) subigs = ig.node_subgraphs(randvs) for i in range(4): check_basics(subg, subig) check_graph_equal(subgs[i], subigs[i])
def test_update_all_0deg(idtype): # test#1 g = dgl.graph(([1, 2, 3, 4], [0, 0, 0, 0]), idtype=idtype, device=F.ctx()) def _message(edges): return {'m': edges.src['h']} def _reduce(nodes): return {'x': nodes.data['h'] + F.sum(nodes.mailbox['m'], 1)} def _apply(nodes): return {'x': nodes.data['x'] * 2} def _init2(shape, dtype, ctx, ids): return 2 + F.zeros(shape, dtype, ctx) g.set_n_initializer(_init2, 'x') old_repr = F.randn((5, 5)) g.ndata['h'] = old_repr g.update_all(_message, _reduce, _apply) new_repr = g.ndata['x'] # 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 F.allclose(new_repr[1:], 2 * (2 + F.zeros((4, 5)))) assert F.allclose(new_repr[0], 2 * F.sum(old_repr, 0)) # test#2: graph with no edge g = dgl.graph(([], []), num_nodes=5, idtype=idtype, device=F.ctx()) g.ndata['h'] = old_repr g.update_all(_message, _reduce, lambda nodes: {'h': nodes.data['h'] * 2}) new_repr = g.ndata['h'] # should fallback to apply assert F.allclose(new_repr, 2 * old_repr)
def check_basic(g, nf): num_nodes = 0 for i in range(nf.num_layers): num_nodes += nf.layer_size(i) assert nf.number_of_nodes() == num_nodes num_edges = 0 for i in range(nf.num_blocks): num_edges += nf.block_size(i) assert nf.number_of_edges() == num_edges deg = nf.layer_in_degree(0) assert F.array_equal(deg, F.zeros((nf.layer_size(0)), F.int64)) deg = nf.layer_out_degree(-1) assert F.array_equal(deg, F.zeros((nf.layer_size(-1)), F.int64)) for i in range(1, nf.num_layers): in_deg = nf.layer_in_degree(i) out_deg = nf.layer_out_degree(i - 1) assert F.asnumpy(F.sum(in_deg, 0) == F.sum(out_deg, 0))
def test_summation_einsum_2(backendopt): for datatype in backendopt: T.set_backend(datatype) x = ad.Variable(name="x", shape=[2, 2]) y = ad.Variable(name="y", shape=[2, 2]) out = ad.sum(ad.einsum('ij,ab->ab', x, y)) grad_x, = ad.gradients(out, [x]) executor = ad.Executor([out, grad_x]) x_val = T.tensor([[1., 2.], [3., 4.]]) y_val = T.tensor([[5., 6.], [7., 8.]]) out_val, grad_x_val = executor.run(feed_dict={x: x_val, y: y_val}) expected_out_val = T.sum(T.einsum('ij,ab->ab', x_val, y_val)) expected_grad_x_val = T.sum(y_val) * T.ones_like(x_val) assert T.array_equal(out_val, expected_out_val) assert T.array_equal(grad_x_val, expected_grad_x_val)
def _test(group_by): g.group_apply_edges(group_by=group_by, func=edge_udf) if group_by == 'src': u, v, eid = g.out_edges(1, form='all') else: u, v, eid = g.in_edges(5, form='all') out_feat = g.edges[eid].data['norm_feat'] result = (g.nodes[u].data['h'] + g.nodes[v].data['h']) * g.edges[eid].data['feat'] result = F.softmax(F.sum(result, dim=1), dim=0) assert F.allclose(out_feat, result)
def softmax(x): ndim = K.ndim(x) if ndim == 2: return K.softmax(x) elif ndim == 3: e = K.exp(x - K.max(x, axis=-1, keepdims=True)) s = K.sum(e, axis=-1, keepdims=True) return e / s else: raise ValueError('Cannot apply softmax to a tensor ' 'that is not 2D or 3D. ' 'Here, ndim=' + str(ndim))
def test_simple_pool(): ctx = F.ctx() g = dgl.DGLGraph(nx.path_graph(15)) sum_pool = nn.SumPooling() avg_pool = nn.AvgPooling() max_pool = nn.MaxPooling() sort_pool = nn.SortPooling(10) # k = 10 print(sum_pool, avg_pool, max_pool, sort_pool) # test#1: basic h0 = F.randn((g.number_of_nodes(), 5)) if F.gpu_ctx(): sum_pool = sum_pool.to(ctx) avg_pool = avg_pool.to(ctx) max_pool = max_pool.to(ctx) sort_pool = sort_pool.to(ctx) h0 = h0.to(ctx) h1 = sum_pool(g, h0) assert F.allclose(h1, F.sum(h0, 0)) h1 = avg_pool(g, h0) assert F.allclose(h1, F.mean(h0, 0)) h1 = max_pool(g, h0) assert F.allclose(h1, F.max(h0, 0)) h1 = sort_pool(g, h0) assert h1.shape[0] == 10 * 5 and h1.dim() == 1 # test#2: batched graph g_ = dgl.DGLGraph(nx.path_graph(5)) bg = dgl.batch([g, g_, g, g_, g]) h0 = F.randn((bg.number_of_nodes(), 5)) if F.gpu_ctx(): h0 = h0.to(ctx) h1 = sum_pool(bg, h0) truth = th.stack([F.sum(h0[:15], 0), F.sum(h0[15:20], 0), F.sum(h0[20:35], 0), F.sum(h0[35:40], 0), F.sum(h0[40:55], 0)], 0) assert F.allclose(h1, truth) h1 = avg_pool(bg, h0) truth = th.stack([F.mean(h0[:15], 0), F.mean(h0[15:20], 0), F.mean(h0[20:35], 0), F.mean(h0[35:40], 0), F.mean(h0[40:55], 0)], 0) assert F.allclose(h1, truth) h1 = max_pool(bg, h0) truth = th.stack([F.max(h0[:15], 0), F.max(h0[15:20], 0), F.max(h0[20:35], 0), F.max(h0[35:40], 0), F.max(h0[40:55], 0)], 0) assert F.allclose(h1, truth) h1 = sort_pool(bg, h0) assert h1.shape[0] == 5 and h1.shape[1] == 10 * 5 and h1.dim() == 2
def test_multi_recv_0deg(): # test recv with 0deg nodes; g = DGLGraph() def _message(edges): return {'m': edges.src['h']} def _reduce(nodes): return {'h': nodes.data['h'] + F.sum(nodes.mailbox['m'], 1)} def _apply(nodes): return {'h': nodes.data['h'] * 2} def _init2(shape, dtype, ctx, ids): return 2 + F.zeros(shape, dtype=dtype, ctx=ctx) g.register_message_func(_message) g.register_reduce_func(_reduce) g.register_apply_node_func(_apply) g.set_n_initializer(_init2) g.add_nodes(2) g.add_edge(0, 1) # recv both 0deg and non-0deg nodes old = F.randn((2, 5)) g.ndata['h'] = old g.send((0, 1)) g.recv([0, 1]) new = g.ndata['h'] # 0deg check: initialized with the func and got applied assert F.allclose(new[0], F.full((5, ), 4, F.float32)) # non-0deg check assert F.allclose(new[1], F.sum(old, 0) * 2) # recv again on zero degree node g.recv([0]) assert F.allclose(g.nodes[0].data['h'], F.full((5, ), 8, F.float32)) # recv again on node with no incoming message g.recv([1]) assert F.allclose(g.nodes[1].data['h'], F.sum(old, 0) * 4)
def call(self, x, mask=None): b, xb = 0., 0. if self.data_format == 'channels_first': kernel_sum_axes = [1, 2, 3] if self.use_bias: b = K.reshape(self.b, (self.filters, 1, 1, 1)) xb = 1. elif self.data_format == 'channels_last': kernel_sum_axes = [0, 1, 2] if self.use_bias: b = K.reshape(self.b, (1, 1, 1, self.filters)) xb = 1. Wnorm = K.sqrt( K.sum(K.square(self.W), axis=kernel_sum_axes, keepdims=True) + K.square(b) + K.epsilon()) xnorm = K.sqrt( K.conv2d(K.square(x), self.kernel_norm, strides=self.strides, padding=self.padding, data_format=self.data_format, filter_shape=self.kernel_norm_shape) + xb + K.epsilon()) W = self.W / Wnorm output = K.conv2d(x, W, strides=self.strides, padding=self.padding, data_format=self.data_format, filter_shape=self.kernel_shape) if K.backend() == 'theano': xnorm = K.pattern_broadcast(xnorm, [False, True, False, False]) output /= xnorm if self.use_bias: b /= Wnorm if self.data_format == 'channels_first': b = K.reshape(b, (1, self.filters, 1, 1)) elif self.data_format == 'channels_last': b = K.reshape(b, (1, 1, 1, self.filters)) else: raise ValueError('Invalid data_format:', self.data_format) b /= xnorm output += b output = self.activation(output) return output
def binary_op(msg, x, y): if msg == 'add': return x + y elif msg == 'sub': return x - y elif msg == 'mul': return x * y elif msg == 'div': return x / y elif msg == 'dot': return F.sum(x * y, -1, keepdims=True) elif msg == 'copy_lhs': return x elif msg == 'copy_rhs': return y
def test_batch_send_and_recv(): t1 = tree1() t2 = tree2() bg = dgl.batch([t1, t2]) bg.register_message_func(lambda edges: {'m': edges.src['h']}) bg.register_reduce_func(lambda nodes: {'h': F.sum(nodes.mailbox['m'], 1)}) u = [3, 4, 2 + 5, 0 + 5] v = [1, 1, 4 + 5, 4 + 5] bg.send_and_recv((u, v)) t1, t2 = dgl.unbatch(bg) assert F.asnumpy(t1.ndata['h'][1]) == 7 assert F.asnumpy(t2.ndata['h'][4]) == 2
def test_batch_send_and_recv(idtype): t1 = tree1(idtype) t2 = tree2(idtype) bg = dgl.batch([t1, t2]) _mfunc = lambda edges: {'m': edges.src['h']} _rfunc = lambda nodes: {'h': F.sum(nodes.mailbox['m'], 1)} u = [3, 4, 2 + 5, 0 + 5] v = [1, 1, 4 + 5, 4 + 5] bg.send_and_recv((u, v), _mfunc, _rfunc) t1, t2 = dgl.unbatch(bg) assert F.asnumpy(t1.ndata['h'][1]) == 7 assert F.asnumpy(t2.ndata['h'][4]) == 2
def test_batch_send_then_recv(): t1 = tree1() t2 = tree2() bg = dgl.batch([t1, t2]) bg.register_message_func(lambda edges: {'m': edges.src['h']}) bg.register_reduce_func(lambda nodes: {'h': F.sum(nodes.mailbox['m'], 1)}) u = [3, 4, 2 + 5, 0 + 5] v = [1, 1, 4 + 5, 4 + 5] bg.send((u, v)) bg.recv([1, 9]) # assuming recv takes in unique nodes t1, t2 = dgl.unbatch(bg) assert t1.ndata['h'][1] == 7 assert t2.ndata['h'][4] == 2
def test_negative(backendopt): for datatype in backendopt: T.set_backend(datatype) x2 = ad.Variable(name="x2", shape=[3]) y = ad.sum(-x2) grad_x2, = ad.gradients(y, [x2]) executor = ad.Executor([y, grad_x2]) x2_val = 2 * T.ones(3) y_val, grad_x2_val = executor.run(feed_dict={x2: x2_val}) assert isinstance(y, ad.Node) assert T.array_equal(y_val, T.sum(-x2_val)) assert T.array_equal(grad_x2_val, -T.ones_like(x2_val))
def test_10neighbor_sampler_all(): g = generate_rand_graph(100) # In this case, NeighborSampling simply gets the neighborhood of a single vertex. for subg, aux in dgl.contrib.sampling.NeighborSampler(g, 10, 100, neighbor_type='in', num_workers=4, return_seed_id=True): seed_ids = aux['seeds'] src, dst, eid = g.in_edges(seed_ids, form='all') child_ids = subg.map_to_subgraph_nid(seed_ids) child_src, child_dst, child_eid = subg.in_edges(child_ids, form='all') child_src1 = subg.map_to_subgraph_nid(src) assert F.asnumpy(F.sum(child_src1 == child_src, 0)) == len(src)
def __call__(self, loss): loss += K.sum(K.abs(self.p)) * self.l1 / 2. loss += K.sum(K.square(self.p)) * self.l2 / 2. return loss
def get_reg( self, params ): return self._l1_ * K.sum( [ K.sum( K.abs( param ) ) for param in params ] )
def get_reg( self, params ): reg = self._l1_ * K.sum( [ K.sum( K.abs( param ) ) for param in params ] ) + \ self._l2_ * K.sum( [ K.sum( K.sqr( param ) ) for param in params ] ) return reg
def get_reg( self, params ): return self._l2_ * K.sum( [ K.sum( K.sqr( param ) ) for param in params ] )
def __call__(self, loss): output = self.layer.get_output(True) loss += self.l1 * K.sum(K.mean(K.abs(output), axis=0)) loss += self.l2 * K.sum(K.mean(K.square(output), axis=0)) return loss
def norm_lp(y_pred, y_gt, norm): return K.mean(K.sum(K.power(K.abs(y_pred - y_gt), norm), axis=-1))
def kl_divergence(y_pred, y_gt): y_pred = K.clip(y_pred, _EPSILON, np.inf) y_gt = K.clip(y_gt, _EPSILON, np.inf) kl_mat = y_gt * K.log(y_gt / y_pred) - y_gt + y_pred return K.mean(K.sum(kl_mat, axis=-1))
def is_divergence(y_pred, y_gt): y_pred = K.clip(y_pred, _EPSILON, np.inf) y_gt = K.clip(y_gt, _EPSILON, np.inf) is_mat = y_gt / y_pred - K.log(y_gt / y_pred) - 1 return K.mean(K.sum(is_mat, axis=-1))
def beta_divergence(y_pred, y_gt, beta): y_pred = K.clip(y_pred, _EPSILON, np.inf) y_gt = K.clip(y_gt, _EPSILON, np.inf) beta_mat = 1. / (beta*(beta-1)) * (K.power(y_gt, beta) + (beta-1) * K.power(y_pred, beta) - beta * y_gt * K.power(y_pred, (beta-1))) return K.mean(K.sum(beta_mat, axis=-1))