def test_send_recv_after_conversion(): # test send and recv after converting from a graph with edges g = generate_graph() # nx graph nxg = g.to_networkx(node_attrs=['h']) g1 = DGLGraph() # some random node and edges g1.add_nodes(4) g1.add_edges([1, 2], [2, 3]) g1.set_n_initializer(dgl.init.zero_initializer) g1.from_networkx(nxg, node_attrs=['h']) # sparse matrix row, col = g.all_edges() data = range(len(row)) n = g.number_of_nodes() a = sp.coo_matrix( (data, (F.zerocopy_to_numpy(row), F.zerocopy_to_numpy(col))), shape=(n, n)) g2 = DGLGraph() # some random node and edges g2.add_nodes(5) g2.add_edges([1, 2, 4], [2, 3, 0]) g2.set_n_initializer(dgl.init.zero_initializer) g2.from_scipy_sparse_matrix(a) g2.ndata['h'] = g.ndata['h'] # on dgl graph g.send(message_func=message_func) g.recv([0, 1, 3, 5], reduce_func=reduce_func, apply_node_func=apply_node_func) g.recv([0, 2, 4, 8], reduce_func=reduce_func, apply_node_func=apply_node_func) # nx g1.send(message_func=message_func) g1.recv([0, 1, 3, 5], reduce_func=reduce_func, apply_node_func=apply_node_func) g1.recv([0, 2, 4, 8], reduce_func=reduce_func, apply_node_func=apply_node_func) # sparse matrix g2.send(message_func=message_func) g2.recv([0, 1, 3, 5], reduce_func=reduce_func, apply_node_func=apply_node_func) g2.recv([0, 2, 4, 8], reduce_func=reduce_func, apply_node_func=apply_node_func) assert F.allclose(g.ndata['h'], g1.ndata['h']) assert F.allclose(g.ndata['h'], g2.ndata['h'])
def _build_tree(self, qt): root = qt.logic_tree g = nx.DiGraph() def _rec_build(nid, root): for child in [root.left, root.mid, root.right]: if child: cid = g.number_of_nodes() try: # word = self.vocab.labelToIdx[child.val] word = self.featuretotensor(child.val) except: # print("unknown word", child.val) word = [0] * 150 word[0] = 1 g.add_node(cid, x=word, y=0) g.add_edge(cid, nid) _rec_build(cid, child) # add root solving_time = qt.gettime(self.time_selection) if self.task == "classification": if isinstance(solving_time, bool): result = 0 if solving_time else 1 else: result = 0 if solving_time > 60 else 1 else: result = solving_time if not result: result = 0.0 if result == None: result = 0 # g.add_node(0, x=self.vocab.labelToIdx[root.val], y=result) g.add_node(0, x=self.featuretotensor(root.val), y=result) _rec_build(0, root) ret = DGLGraph() ret.from_networkx(g, node_attrs=['x', 'y']) return ret
def test_nx_conversion(): # check conversion between networkx and DGLGraph def _check_nx_feature(nxg, nf, ef): # check node and edge feature of nxg # this is used to check to_networkx num_nodes = len(nxg) num_edges = nxg.size() if num_nodes > 0: node_feat = ddict(list) for nid, attr in nxg.nodes(data=True): assert len(attr) == len(nf) for k in nxg.nodes[nid]: node_feat[k].append(attr[k].unsqueeze(0)) for k in node_feat: feat = th.cat(node_feat[k], dim=0) assert U.allclose(feat, nf[k]) else: assert len(nf) == 0 if num_edges > 0: edge_feat = ddict(lambda: [0] * num_edges) for u, v, attr in nxg.edges(data=True): assert len(attr) == len(ef) + 1 # extra id eid = attr['id'] for k in ef: edge_feat[k][eid] = attr[k].unsqueeze(0) for k in edge_feat: feat = th.cat(edge_feat[k], dim=0) assert U.allclose(feat, ef[k]) else: assert len(ef) == 0 n1 = th.randn(5, 3) n2 = th.randn(5, 10) n3 = th.randn(5, 4) e1 = th.randn(4, 5) e2 = th.randn(4, 7) g = DGLGraph(multigraph=True) g.add_nodes(5) g.add_edges([0, 1, 3, 4], [2, 4, 0, 3]) g.ndata.update({'n1': n1, 'n2': n2, 'n3': n3}) g.edata.update({'e1': e1, 'e2': e2}) # convert to networkx nxg = g.to_networkx(node_attrs=['n1', 'n3'], edge_attrs=['e1', 'e2']) assert len(nxg) == 5 assert nxg.size() == 4 _check_nx_feature(nxg, {'n1': n1, 'n3': n3}, {'e1': e1, 'e2': e2}) # convert to DGLGraph, nx graph has id in edge feature # use id feature to test non-tensor copy g.from_networkx(nxg, node_attrs=['n1'], edge_attrs=['e1', 'id']) # check graph size assert g.number_of_nodes() == 5 assert g.number_of_edges() == 4 # check number of features # test with existing dglgraph (so existing features should be cleared) assert len(g.ndata) == 1 assert len(g.edata) == 2 # check feature values assert U.allclose(g.ndata['n1'], n1) # with id in nx edge feature, e1 should follow original order assert U.allclose(g.edata['e1'], e1) assert th.equal(g.get_e_repr()['id'], th.arange(4)) # test conversion after modifying DGLGraph g.pop_e_repr( 'id') # pop id so we don't need to provide id when adding edges new_n = th.randn(2, 3) new_e = th.randn(3, 5) g.add_nodes(2, data={'n1': new_n}) # add three edges, one is a multi-edge g.add_edges([3, 6, 0], [4, 5, 2], data={'e1': new_e}) n1 = th.cat((n1, new_n), dim=0) e1 = th.cat((e1, new_e), dim=0) # convert to networkx again nxg = g.to_networkx(node_attrs=['n1'], edge_attrs=['e1']) assert len(nxg) == 7 assert nxg.size() == 7 _check_nx_feature(nxg, {'n1': n1}, {'e1': e1}) # now test convert from networkx without id in edge feature # first pop id in edge feature for _, _, attr in nxg.edges(data=True): attr.pop('id') # test with a new graph g = DGLGraph(multigraph=True) g.from_networkx(nxg, node_attrs=['n1'], edge_attrs=['e1']) # check graph size assert g.number_of_nodes() == 7 assert g.number_of_edges() == 7 # check number of features assert len(g.ndata) == 1 assert len(g.edata) == 1 # check feature values assert U.allclose(g.ndata['n1'], n1) # edge feature order follows nxg.edges() edge_feat = [] for _, _, attr in nxg.edges(data=True): edge_feat.append(attr['e1'].unsqueeze(0)) edge_feat = th.cat(edge_feat, dim=0) assert U.allclose(g.edata['e1'], edge_feat)
def test_nx_conversion(): # check conversion between networkx and DGLGraph def _check_nx_feature(nxg, nf, ef): num_nodes = len(nxg) num_edges = nxg.size() if num_nodes > 0: node_feat = ddict(list) for nid, attr in nxg.nodes(data=True): assert len(attr) == len(nf) for k in nxg.nodes[nid]: node_feat[k].append(attr[k].unsqueeze(0)) for k in node_feat: feat = th.cat(node_feat[k], dim=0) assert U.allclose(feat, nf[k]) else: assert len(nf) == 0 if num_edges > 0: edge_feat = ddict(lambda: [0] * num_edges) for u, v, attr in nxg.edges(data=True): assert len(attr) == len(ef) + 1 # extra id eid = attr['id'] for k in ef: edge_feat[k][eid] = attr[k].unsqueeze(0) for k in edge_feat: feat = th.cat(edge_feat[k], dim=0) assert U.allclose(feat, ef[k]) else: assert len(ef) == 0 n1 = th.randn(5, 3) n2 = th.randn(5, 10) n3 = th.randn(5, 4) e1 = th.randn(4, 5) e2 = th.randn(4, 7) g = DGLGraph(multigraph=True) g.add_nodes(5) g.add_edges([0, 1, 3, 4], [2, 4, 0, 3]) g.ndata.update({'n1': n1, 'n2': n2, 'n3': n3}) g.edata.update({'e1': e1, 'e2': e2}) # convert to networkx nxg = g.to_networkx(node_attrs=['n1', 'n3'], edge_attrs=['e1', 'e2']) assert len(nxg) == 5 assert nxg.size() == 4 _check_nx_feature(nxg, {'n1': n1, 'n3': n3}, {'e1': e1, 'e2': e2}) # convert to DGLGraph # use id feature to test non-tensor copy g.from_networkx(nxg, node_attrs=['n1'], edge_attrs=['e1', 'id']) assert g.number_of_nodes() == 5 assert g.number_of_edges() == 4 assert U.allclose(g.get_n_repr()['n1'], n1) assert U.allclose(g.get_e_repr()['e1'], e1) assert th.equal(g.get_e_repr()['id'], th.arange(4)) g.pop_e_repr('id') # test modifying DGLGraph new_n = th.randn(2, 3) new_e = th.randn(3, 5) g.add_nodes(2, data={'n1': new_n}) # add three edges, one is a multi-edge g.add_edges([3, 6, 0], [4, 5, 2], data={'e1': new_e}) n1 = th.cat((n1, new_n), dim=0) e1 = th.cat((e1, new_e), dim=0) # convert to networkx again nxg = g.to_networkx(node_attrs=['n1'], edge_attrs=['e1']) assert len(nxg) == 7 assert nxg.size() == 7 _check_nx_feature(nxg, {'n1': n1}, {'e1': e1})