"...git@developer.sourcefind.cn:renzhc/diffusers_dcu.git" did not exist on "ea5b0575f8f91b76f32fb6f6930c0bc30e42865e"
Unverified Commit be444e52 authored by Mufei Li's avatar Mufei Li Committed by GitHub
Browse files

[Doc/Feature] Refactor, doc update and behavior fix for graphs (#1983)



* Update graph

* Fix for dgl.graph

* from_scipy

* Replace canonical_etypes with relations

* from_networkx

* Update for hetero_from_relations

* Roll back the change of canonical_etypes to relations

* heterograph

* bipartite

* Update doc

* Fix lint

* Fix lint

* Fix test cases

* Fix

* Fix

* Fix

* Fix

* Fix

* Fix

* Update

* Fix test

* Fix

* Update

* Use DGLError

* Update

* Update

* Update

* Update

* Fix

* Fix

* Fix

* Fix

* Fix

* Fix

* Fix

* Fix

* Update

* Fix

* Update

* Fix

* Fix

* Fix

* Update

* Fix

* Update

* Fix

* Update

* Update

* Update

* Update

* Update

* Update

* Update

* Fix

* Fix

* Update

* Update

* Update

* Update

* Update

* Update

* rewrite sanity checks

* delete unnecessary checks

* Update

* Update

* Update

* Update

* Update

* Update

* Update

* Update

* Fix

* Update

* Update

* Update

* Fix

* Fix

* Fix

* Update

* Fix

* Update

* Fix

* Fix

* Update

* Fix

* Update

* Fix
Co-authored-by: default avatarxiang song(charlie.song) <classicxsong@gmail.com>
Co-authored-by: default avatarMinjie Wang <wmjlyjemaine@gmail.com>
Co-authored-by: default avatarQuan Gan <coin2028@hotmail.com>
parent 0afc3cf8
.. _apigraph: .. _apigraph:
dgl.DGLHeteroGraph dgl.DGLGraph
===================================================== =====================================================
.. currentmodule:: dgl .. currentmodule:: dgl
.. autoclass:: DGLHeteroGraph .. class:: DGLGraph
Querying metagraph structure Querying metagraph structure
---------------------------- ----------------------------
...@@ -12,13 +12,15 @@ Querying metagraph structure ...@@ -12,13 +12,15 @@ Querying metagraph structure
.. autosummary:: .. autosummary::
:toctree: ../../generated/ :toctree: ../../generated/
DGLHeteroGraph.ntypes DGLGraph.ntypes
DGLHeteroGraph.etypes DGLGraph.etypes
DGLHeteroGraph.canonical_etypes DGLGraph.srctypes
DGLHeteroGraph.metagraph DGLGraph.dsttypes
DGLHeteroGraph.to_canonical_etype DGLGraph.canonical_etypes
DGLHeteroGraph.get_ntype_id DGLGraph.metagraph
DGLHeteroGraph.get_etype_id DGLGraph.to_canonical_etype
DGLGraph.get_ntype_id
DGLGraph.get_etype_id
Querying graph structure Querying graph structure
------------------------ ------------------------
...@@ -26,20 +28,27 @@ Querying graph structure ...@@ -26,20 +28,27 @@ Querying graph structure
.. autosummary:: .. autosummary::
:toctree: ../../generated/ :toctree: ../../generated/
DGLHeteroGraph.number_of_nodes DGLGraph.num_nodes
DGLHeteroGraph.number_of_edges DGLGraph.number_of_nodes
DGLHeteroGraph.is_multigraph DGLGraph.num_edges
DGLHeteroGraph.has_nodes DGLGraph.number_of_edges
DGLHeteroGraph.has_edges_between DGLGraph.num_src_nodes
DGLHeteroGraph.predecessors DGLGraph.number_of_src_nodes
DGLHeteroGraph.successors DGLGraph.num_dst_nodes
DGLHeteroGraph.edge_ids DGLGraph.number_of_dst_nodes
DGLHeteroGraph.find_edges DGLGraph.is_unibipartite
DGLHeteroGraph.in_edges DGLGraph.is_multigraph
DGLHeteroGraph.out_edges DGLGraph.is_homogeneous
DGLHeteroGraph.all_edges DGLGraph.has_nodes
DGLHeteroGraph.in_degrees DGLGraph.has_edges_between
DGLHeteroGraph.out_degrees DGLGraph.predecessors
DGLGraph.successors
DGLGraph.edge_ids
DGLGraph.find_edges
DGLGraph.in_edges
DGLGraph.out_edges
DGLGraph.in_degrees
DGLGraph.out_degrees
Querying and manipulating sparse format Querying and manipulating sparse format
--------------------------------------- ---------------------------------------
...@@ -47,9 +56,8 @@ Querying and manipulating sparse format ...@@ -47,9 +56,8 @@ Querying and manipulating sparse format
.. autosummary:: .. autosummary::
:toctree: ../../generated/ :toctree: ../../generated/
DGLHeteroGraph.format_in_use DGLGraph.formats
DGLHeteroGraph.restrict_format DGLGraph.create_format_
DGLHeteroGraph.to_format
Querying and manipulating index data type Querying and manipulating index data type
----------------------------------------- -----------------------------------------
...@@ -57,9 +65,9 @@ Querying and manipulating index data type ...@@ -57,9 +65,9 @@ Querying and manipulating index data type
.. autosummary:: .. autosummary::
:toctree: ../../generated/ :toctree: ../../generated/
DGLHeteroGraph.idtype DGLGraph.idtype
DGLHeteroGraph.long DGLGraph.long
DGLHeteroGraph.int DGLGraph.int
Using Node/edge features Using Node/edge features
------------------------ ------------------------
...@@ -67,59 +75,86 @@ Using Node/edge features ...@@ -67,59 +75,86 @@ Using Node/edge features
.. autosummary:: .. autosummary::
:toctree: ../../generated/ :toctree: ../../generated/
DGLHeteroGraph.nodes DGLGraph.nodes
DGLHeteroGraph.ndata DGLGraph.ndata
DGLHeteroGraph.edges DGLGraph.edges
DGLHeteroGraph.edata DGLGraph.edata
DGLHeteroGraph.node_attr_schemes DGLGraph.node_attr_schemes
DGLHeteroGraph.edge_attr_schemes DGLGraph.edge_attr_schemes
DGLHeteroGraph.set_n_initializer DGLGraph.srcnodes
DGLHeteroGraph.set_e_initializer DGLGraph.dstnodes
DGLHeteroGraph.local_var DGLGraph.srcdata
DGLHeteroGraph.local_scope DGLGraph.dstdata
DGLGraph.local_var
DGLGraph.local_scope
Using Node/edge features for blocks Transforming graph
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ------------------
Please refer to :ref:`guide-minibatch` for the definition of blocks.
.. autosummary:: .. autosummary::
:toctree: ../../generated/ :toctree: ../../generated/
DGLHeteroGraph.number_of_src_nodes DGLGraph.subgraph
DGLHeteroGraph.number_of_dst_nodes DGLGraph.edge_subgraph
DGLHeteroGraph.srcnodes DGLGraph.node_type_subgraph
DGLHeteroGraph.srcdata DGLGraph.edge_type_subgraph
DGLHeteroGraph.dstnodes DGLGraph.__getitem__
DGLHeteroGraph.dstdata
Transforming graph Converting to other formats
------------------ ---------------------------
.. autosummary:: .. autosummary::
:toctree: ../../generated/ :toctree: ../../generated/
DGLHeteroGraph.subgraph DGLGraph.adj
DGLHeteroGraph.edge_subgraph DGLGraph.adjacency_matrix
DGLHeteroGraph.node_type_subgraph DGLGraph.inc
DGLHeteroGraph.edge_type_subgraph DGLGraph.incidence_matrix
DGLHeteroGraph.__getitem__
Computing with DGLHeteroGraph Computing with DGLGraph
----------------------------- -----------------------------
.. autosummary:: .. autosummary::
:toctree: ../../generated/ :toctree: ../../generated/
DGLHeteroGraph.apply_nodes DGLGraph.apply_nodes
DGLHeteroGraph.apply_edges DGLGraph.apply_edges
DGLHeteroGraph.send_and_recv DGLGraph.send_and_recv
DGLHeteroGraph.pull DGLGraph.pull
DGLHeteroGraph.push DGLGraph.push
DGLHeteroGraph.update_all DGLGraph.update_all
DGLHeteroGraph.multi_update_all DGLGraph.multi_update_all
DGLHeteroGraph.prop_nodes DGLGraph.prop_nodes
DGLHeteroGraph.prop_edges DGLGraph.prop_edges
DGLHeteroGraph.filter_nodes DGLGraph.filter_nodes
DGLHeteroGraph.filter_edges DGLGraph.filter_edges
DGLHeteroGraph.to
Querying batch summary
----------------------
.. autosummary::
:toctree: ../../generated/
DGLGraph.batch_size
DGLGraph.batch_num_nodes
DGLGraph.batch_num_edges
Mutating topology
-----------------
.. autosummary::
:toctree: ../../generated/
DGLGraph.add_nodes
DGLGraph.add_edges
DGLGraph.remove_nodes
DGLGraph.remove_edges
Device Control
--------------
.. autosummary::
:toctree: ../../generated/
DGLGraph.to
DGLGraph.device
...@@ -81,7 +81,7 @@ here, you can enjoy the same convenience on other frameworks by similar usage): ...@@ -81,7 +81,7 @@ here, you can enjoy the same convenience on other frameworks by similar usage):
>>> F.u_mul_e_sum(g, x, y1).shape # (2,), (4, 2) -> (4, 2) >>> F.u_mul_e_sum(g, x, y1).shape # (2,), (4, 2) -> (4, 2)
torch.Size([3, 4, 2]) torch.Size([3, 4, 2])
For all operators, the input graph could either be a homograph or a bipartite For all operators, the input graph could either be a homogeneous or a bipartite
graph. graph.
.. autosummary:: .. autosummary::
...@@ -228,7 +228,7 @@ The following is an example showing how GSDDMM works: ...@@ -228,7 +228,7 @@ The following is an example showing how GSDDMM works:
copy_u copy_u
copy_v copy_v
Like GSpMM, GSDDMM operators support both homograph and bipartite graph. Like GSpMM, GSDDMM operators support both homogeneous and bipartite graph.
Edge Softmax module Edge Softmax module
------------------- -------------------
......
...@@ -62,8 +62,8 @@ Graph Transform Routines ...@@ -62,8 +62,8 @@ Graph Transform Routines
to_simple to_simple
to_block to_block
compact_graphs compact_graphs
to_hetero to_heterogeneous
to_homo to_homogeneous
to_networkx to_networkx
line_graph line_graph
khop_graph khop_graph
......
...@@ -12,6 +12,8 @@ please `create an issue <https://github.com/dmlc/dgl/issues>`_ started with "[Fe ...@@ -12,6 +12,8 @@ please `create an issue <https://github.com/dmlc/dgl/issues>`_ started with "[Fe
If you want to contribute a NN module, please `create a pull request <https://github.com/dmlc/dgl/pulls>`_ started If you want to contribute a NN module, please `create a pull request <https://github.com/dmlc/dgl/pulls>`_ started
with "[NN] XXXModel in PyTorch NN Modules" and our team member would review this PR. with "[NN] XXXModel in PyTorch NN Modules" and our team member would review this PR.
.. _apinn-pytorch-conv:
Conv Layers Conv Layers
---------------------------------------- ----------------------------------------
...@@ -136,6 +138,7 @@ DotGatConv ...@@ -136,6 +138,7 @@ DotGatConv
:members: forward :members: forward
:show-inheritance: :show-inheritance:
.. _apinn-pytorch-dense-conv:
Dense Conv Layers Dense Conv Layers
---------------------------------------- ----------------------------------------
...@@ -161,6 +164,8 @@ DenseChebConv ...@@ -161,6 +164,8 @@ DenseChebConv
:members: forward :members: forward
:show-inheritance: :show-inheritance:
.. _apinn-pytorch-pooling:
Global Pooling Layers Global Pooling Layers
---------------------------------------- ----------------------------------------
...@@ -232,6 +237,8 @@ HeteroGraphConv ...@@ -232,6 +237,8 @@ HeteroGraphConv
:members: :members:
:show-inheritance: :show-inheritance:
.. _apinn-pytorch-util:
Utility Modules Utility Modules
---------------------------------------- ----------------------------------------
......
...@@ -267,7 +267,7 @@ The message passing on heterographs can be split into two parts: ...@@ -267,7 +267,7 @@ The message passing on heterographs can be split into two parts:
relationships. relationships.
DGL’s interface to call message passing on heterographs is DGL’s interface to call message passing on heterographs is
`multi_update_all() <https://docs.dgl.ai/generated/dgl.DGLHeteroGraph.multi_update_all.html>`__. :meth:`~dgl.DGLGraph.multi_update_all`.
``multi_update_all`` takes a dictionary containing the parameters for ``multi_update_all`` takes a dictionary containing the parameters for
``update_all`` within each relation using relation as the key, and a ``update_all`` within each relation using relation as the key, and a
string represents the cross type reducer. The reducer can be one of string represents the cross type reducer. The reducer can be one of
......
...@@ -13,15 +13,12 @@ framework code. The major difference lies in the message passing ...@@ -13,15 +13,12 @@ framework code. The major difference lies in the message passing
operations that are unique in DGL. operations that are unique in DGL.
DGL has integrated many commonly used DGL has integrated many commonly used
`Sparse_GraphConvs <https://docs.dgl.ai/api/python/nn.pytorch.html#module-dgl.nn.pytorch.conv>`__, :ref:`apinn-pytorch-conv`, :ref:`apinn-pytorch-dense-conv`, :ref:`apinn-pytorch-pooling`,
`Dense_GraphConvs <https://docs.dgl.ai/api/python/nn.pytorch.html#dense-conv-layers>`__,
`Graph_Poolings <https://docs.dgl.ai/api/python/nn.pytorch.html#module-dgl.nn.pytorch.glob>`__,
and and
`Utility <https://docs.dgl.ai/api/python/nn.pytorch.html#utility-modules>`__ :ref:`apinn-pytorch-util`. We welcome your contribution!
NN modules. We welcome your contribution!
In this section, we will use In this section, we will use
`dgl.nn.conv.SAGEConv <https://github.com/sneakerkg/dgl/blob/nn_doc_refactor/python/dgl/nn/pytorch/conv/sageconv.py>`__ :class:`~dgl.nn.pytorch.conv.SAGEConv`
with Pytorch backend as an example to introduce how to build your own with Pytorch backend as an example to introduce how to build your own
DGL NN Module. DGL NN Module.
...@@ -289,7 +286,7 @@ object construction phase. ...@@ -289,7 +286,7 @@ object construction phase.
Heterogeneous GraphConv Module Heterogeneous GraphConv Module
------------------------------ ------------------------------
`HeteroGraphConv <https://github.com/dmlc/dgl/blob/master/python/dgl/nn/pytorch/hetero.py>`__ :class:`dgl.nn.pytorch.HeteroGraphConv`
is a module-level encapsulation to run DGL NN module on heterogeneous is a module-level encapsulation to run DGL NN module on heterogeneous
graph. The implementation logic is the same as message passing level API graph. The implementation logic is the same as message passing level API
``multi_update_all()``: ``multi_update_all()``:
......
...@@ -237,21 +237,19 @@ class MovieLens(object): ...@@ -237,21 +237,19 @@ class MovieLens(object):
def _generate_enc_graph(self, rating_pairs, rating_values, add_support=False): def _generate_enc_graph(self, rating_pairs, rating_values, add_support=False):
user_movie_R = np.zeros((self._num_user, self._num_movie), dtype=np.float32) user_movie_R = np.zeros((self._num_user, self._num_movie), dtype=np.float32)
user_movie_R[rating_pairs] = rating_values user_movie_R[rating_pairs] = rating_values
movie_user_R = user_movie_R.transpose()
rating_graphs = [] data_dict = dict()
num_nodes_dict = {'user': self._num_user, 'movie': self._num_movie}
rating_row, rating_col = rating_pairs rating_row, rating_col = rating_pairs
for rating in self.possible_rating_values: for rating in self.possible_rating_values:
ridx = np.where(rating_values == rating) ridx = np.where(rating_values == rating)
rrow = rating_row[ridx] rrow = rating_row[ridx]
rcol = rating_col[ridx] rcol = rating_col[ridx]
bg = dgl.bipartite((rrow, rcol), 'user', str(rating), 'movie', data_dict.update({
num_nodes=(self._num_user, self._num_movie)) ('user', str(rating), 'movie'): (rrow, rcol),
rev_bg = dgl.bipartite((rcol, rrow), 'movie', 'rev-%s' % str(rating), 'user', ('movie', 'rev-%s' % str(rating), 'user'): (rcol, rrow)
num_nodes=(self._num_movie, self._num_user)) })
rating_graphs.append(bg) graph = dgl.heterograph(data_dict, num_nodes_dict=num_nodes_dict)
rating_graphs.append(rev_bg)
graph = dgl.hetero_from_relations(rating_graphs)
# sanity check # sanity check
assert len(rating_pairs[0]) == sum([graph.number_of_edges(et) for et in graph.etypes]) // 2 assert len(rating_pairs[0]) == sum([graph.number_of_edges(et) for et in graph.etypes]) // 2
...@@ -294,7 +292,8 @@ class MovieLens(object): ...@@ -294,7 +292,8 @@ class MovieLens(object):
user_movie_ratings_coo = sp.coo_matrix( user_movie_ratings_coo = sp.coo_matrix(
(ones, rating_pairs), (ones, rating_pairs),
shape=(self.num_user, self.num_movie), dtype=np.float32) shape=(self.num_user, self.num_movie), dtype=np.float32)
return dgl.bipartite(user_movie_ratings_coo, 'user', 'rate', 'movie') g = dgl.bipartite_from_scipy(user_movie_ratings_coo, utype='_U', etype='_E', vtype='_V')
return dgl.heterograph({('user', 'rate', 'movie'): g.edges()})
@property @property
def num_links(self): def num_links(self):
......
...@@ -55,7 +55,6 @@ def main(args): ...@@ -55,7 +55,6 @@ def main(args):
hg = dataset[0] hg = dataset[0]
num_rels = len(hg.canonical_etypes) num_rels = len(hg.canonical_etypes)
num_of_ntype = len(hg.ntypes)
category = dataset.predict_category category = dataset.predict_category
num_classes = dataset.num_classes num_classes = dataset.num_classes
train_mask = hg.nodes[category].data.pop('train_mask') train_mask = hg.nodes[category].data.pop('train_mask')
...@@ -86,7 +85,7 @@ def main(args): ...@@ -86,7 +85,7 @@ def main(args):
if ntype == category: if ntype == category:
category_id = i category_id = i
g = dgl.to_homo(hg) g = dgl.to_homogeneous(hg, edata=['norm'])
num_nodes = g.number_of_nodes() num_nodes = g.number_of_nodes()
node_ids = mx.nd.arange(num_nodes) node_ids = mx.nd.arange(num_nodes)
edge_norm = g.edata['norm'] edge_norm = g.edata['norm']
......
...@@ -10,7 +10,6 @@ from dgl.data import register_data_args, load_data ...@@ -10,7 +10,6 @@ from dgl.data import register_data_args, load_data
class GraphData: class GraphData:
def __init__(self, csr, num_feats, graph_name): def __init__(self, csr, num_feats, graph_name):
num_nodes = csr.shape[0] num_nodes = csr.shape[0]
num_edges = mx.nd.contrib.getnnz(csr).asnumpy()[0]
self.graph = dgl.graph_index.from_csr(csr.indptr, csr.indices, False, 'in') self.graph = dgl.graph_index.from_csr(csr.indptr, csr.indices, False, 'in')
self.graph = self.graph.copyto_shared_mem(dgl.contrib.graph_store._get_graph_path(graph_name)) self.graph = self.graph.copyto_shared_mem(dgl.contrib.graph_store._get_graph_path(graph_name))
self.features = mx.nd.random.normal(shape=(csr.shape[0], num_feats)) self.features = mx.nd.random.normal(shape=(csr.shape[0], num_feats))
......
...@@ -32,7 +32,10 @@ def get_graph(network_data, vocab): ...@@ -32,7 +32,10 @@ def get_graph(network_data, vocab):
a heterogenous graph, with one node type and different edge types a heterogenous graph, with one node type and different edge types
''' '''
graphs = [] graphs = []
num_nodes = len(vocab)
node_type = '_N' # '_N' can be replaced by an arbitrary name
data_dict = dict()
num_nodes_dict = {node_type: len(vocab)}
for edge_type in network_data: for edge_type in network_data:
tmp_data = network_data[edge_type] tmp_data = network_data[edge_type]
...@@ -40,9 +43,8 @@ def get_graph(network_data, vocab): ...@@ -40,9 +43,8 @@ def get_graph(network_data, vocab):
for edge in tmp_data: for edge in tmp_data:
edges.append((vocab[edge[0]], vocab[edge[1]])) edges.append((vocab[edge[0]], vocab[edge[1]]))
edges.append((vocab[edge[1]], vocab[edge[0]])) edges.append((vocab[edge[1]], vocab[edge[0]]))
g = dgl.graph(edges, etype=edge_type, num_nodes=num_nodes) data_dict[(node_type, edge_type, node_type)] = zip(*edges)
graphs.append(g) graph = dgl.heterograph(data_dict, num_nodes_dict)
graph = dgl.hetero_from_relations(graphs)
return graph return graph
......
...@@ -76,8 +76,9 @@ class NodeSampler(object): ...@@ -76,8 +76,9 @@ class NodeSampler(object):
yield self.seeds[batches[i]], batches[i] yield self.seeds[batches[i]], batches[i]
def create_nodeflow(layer_mappings, block_mappings, block_aux_data, rel_graphs, seed_map): def create_nodeflow(layer_mappings, block_mappings, block_aux_data,
hg = dgl.hetero_from_relations(rel_graphs) data_dict, num_nodes_dict, seed_map):
hg = dgl.heterograph(data_dict, num_nodes_dict=num_nodes_dict)
hg.layer_mappings = layer_mappings hg.layer_mappings = layer_mappings
hg.block_mappings = block_mappings hg.block_mappings = block_mappings
hg.block_aux_data = block_aux_data hg.block_aux_data = block_aux_data
...@@ -135,7 +136,8 @@ class AdaptGenerator(object): ...@@ -135,7 +136,8 @@ class AdaptGenerator(object):
layer_mappings = [] # Mapping from layer node ID to parent node ID layer_mappings = [] # Mapping from layer node ID to parent node ID
block_mappings = [] # Mapping from block edge ID to parent edge ID, or -1 if nonexistent block_mappings = [] # Mapping from block edge ID to parent edge ID, or -1 if nonexistent
block_aux_data = [] block_aux_data = []
rel_graphs = [] data_dict = dict()
num_nodes_dict = dict()
if self.coalesce: if self.coalesce:
curr_frontier = torch.LongTensor(np.unique(seeds.numpy())) curr_frontier = torch.LongTensor(np.unique(seeds.numpy()))
...@@ -163,11 +165,13 @@ class AdaptGenerator(object): ...@@ -163,11 +165,13 @@ class AdaptGenerator(object):
aux_result = aux_result[[nodes_idx_map[i] for i in prev_frontier]] aux_result = aux_result[[nodes_idx_map[i] for i in prev_frontier]]
block_dsts = np.arange(len(curr_frontier)).repeat(num_neighbors) block_dsts = np.arange(len(curr_frontier)).repeat(num_neighbors)
rel_graphs.insert(0, dgl.bipartite( data_dict.update({
(block_srcs, block_dsts), ('layer%d' % i, 'block%d' % i, 'layer%d' % (i + 1)): (block_srcs, block_dsts)
'layer%d' % i, 'block%d' % i, 'layer%d' % (i + 1), })
(len(prev_frontier), len(curr_frontier)) num_nodes_dict.update({
)) 'layer%d' % i: len(prev_frontier),
'layer%d' % (i + 1): len(curr_frontier)
})
layer_mappings.insert(0, prev_frontier) layer_mappings.insert(0, prev_frontier)
block_mappings.insert(0, prev_frontier_edges) block_mappings.insert(0, prev_frontier_edges)
...@@ -179,7 +183,8 @@ class AdaptGenerator(object): ...@@ -179,7 +183,8 @@ class AdaptGenerator(object):
layer_mappings=layer_mappings, layer_mappings=layer_mappings,
block_mappings=block_mappings, block_mappings=block_mappings,
block_aux_data=block_aux_data, block_aux_data=block_aux_data,
rel_graphs=rel_graphs, data_dict=data_dict,
num_nodes_dict=num_nodes_dict,
seed_map=seed_map) seed_map=seed_map)
def stepback(self, curr_frontier, layer_index, *auxiliary): def stepback(self, curr_frontier, layer_index, *auxiliary):
......
...@@ -245,22 +245,20 @@ class MovieLens(object): ...@@ -245,22 +245,20 @@ class MovieLens(object):
def _generate_enc_graph(self, rating_pairs, rating_values, add_support=False): def _generate_enc_graph(self, rating_pairs, rating_values, add_support=False):
user_movie_R = np.zeros((self._num_user, self._num_movie), dtype=np.float32) user_movie_R = np.zeros((self._num_user, self._num_movie), dtype=np.float32)
user_movie_R[rating_pairs] = rating_values user_movie_R[rating_pairs] = rating_values
movie_user_R = user_movie_R.transpose()
rating_graphs = [] data_dict = dict()
num_nodes_dict = {'user': self._num_user, 'movie': self._num_movie}
rating_row, rating_col = rating_pairs rating_row, rating_col = rating_pairs
for rating in self.possible_rating_values: for rating in self.possible_rating_values:
ridx = np.where(rating_values == rating) ridx = np.where(rating_values == rating)
rrow = rating_row[ridx] rrow = rating_row[ridx]
rcol = rating_col[ridx] rcol = rating_col[ridx]
rating = to_etype_name(rating) rating = to_etype_name(rating)
bg = dgl.bipartite((rrow, rcol), 'user', rating, 'movie', data_dict.update({
num_nodes=(self._num_user, self._num_movie)) ('user', str(rating), 'movie'): (rrow, rcol),
rev_bg = dgl.bipartite((rcol, rrow), 'movie', 'rev-%s' % rating, 'user', ('movie', 'rev-%s' % str(rating), 'user'): (rcol, rrow)
num_nodes=(self._num_movie, self._num_user)) })
rating_graphs.append(bg) graph = dgl.heterograph(data_dict, num_nodes_dict=num_nodes_dict)
rating_graphs.append(rev_bg)
graph = dgl.hetero_from_relations(rating_graphs)
# sanity check # sanity check
assert len(rating_pairs[0]) == sum([graph.number_of_edges(et) for et in graph.etypes]) // 2 assert len(rating_pairs[0]) == sum([graph.number_of_edges(et) for et in graph.etypes]) // 2
...@@ -303,7 +301,8 @@ class MovieLens(object): ...@@ -303,7 +301,8 @@ class MovieLens(object):
user_movie_ratings_coo = sp.coo_matrix( user_movie_ratings_coo = sp.coo_matrix(
(ones, rating_pairs), (ones, rating_pairs),
shape=(self.num_user, self.num_movie), dtype=np.float32) shape=(self.num_user, self.num_movie), dtype=np.float32)
return dgl.bipartite(user_movie_ratings_coo, 'user', 'rate', 'movie') g = dgl.bipartite_from_scipy(user_movie_ratings_coo, utype='_U', etype='_E', vtype='_V')
return dgl.heterograph({('user', 'rate', 'movie'): g.edges()})
@property @property
def num_links(self): def num_links(self):
......
...@@ -136,8 +136,8 @@ def load_acm(remove_self_loop): ...@@ -136,8 +136,8 @@ def load_acm(remove_self_loop):
# Adjacency matrices for meta path based neighbors # Adjacency matrices for meta path based neighbors
# (Mufei): I verified both of them are binary adjacency matrices with self loops # (Mufei): I verified both of them are binary adjacency matrices with self loops
author_g = dgl.graph(data['PAP'], ntype='paper', etype='author') author_g = dgl.from_scipy(data['PAP'])
subject_g = dgl.graph(data['PLP'], ntype='paper', etype='subject') subject_g = dgl.from_scipy(data['PLP'])
gs = [author_g, subject_g] gs = [author_g, subject_g]
train_idx = torch.from_numpy(data['train_idx']).long().squeeze(0) train_idx = torch.from_numpy(data['train_idx']).long().squeeze(0)
...@@ -186,11 +186,12 @@ def load_acm_raw(remove_self_loop): ...@@ -186,11 +186,12 @@ def load_acm_raw(remove_self_loop):
p_vs_t = p_vs_t[p_selected] p_vs_t = p_vs_t[p_selected]
p_vs_c = p_vs_c[p_selected] p_vs_c = p_vs_c[p_selected]
pa = dgl.bipartite(p_vs_a, 'paper', 'pa', 'author') hg = dgl.heterograph({
ap = dgl.bipartite(p_vs_a.transpose(), 'author', 'ap', 'paper') ('paper', 'pa', 'author'): p_vs_a.nonzero(),
pl = dgl.bipartite(p_vs_l, 'paper', 'pf', 'field') ('author', 'ap', 'paper'): p_vs_a.transpose.nonzero(),
lp = dgl.bipartite(p_vs_l.transpose(), 'field', 'fp', 'paper') ('paper', 'pf', 'field'): p_vs_l.nonzero(),
hg = dgl.hetero_from_relations([pa, ap, pl, lp]) ('field', 'fp', 'paper'): p_vs_l.transpose().nonzero()
})
features = torch.FloatTensor(p_vs_t.toarray()) features = torch.FloatTensor(p_vs_t.toarray())
......
...@@ -80,12 +80,12 @@ def train(model, G): ...@@ -80,12 +80,12 @@ def train(model, G):
device = torch.device("cuda:0") device = torch.device("cuda:0")
G = dgl.heterograph({ G = dgl.heterograph({
('paper', 'written-by', 'author') : data['PvsA'], ('paper', 'written-by', 'author') : data['PvsA'].nonzero(),
('author', 'writing', 'paper') : data['PvsA'].transpose(), ('author', 'writing', 'paper') : data['PvsA'].transpose().nonzero(),
('paper', 'citing', 'paper') : data['PvsP'], ('paper', 'citing', 'paper') : data['PvsP'].nonzero(),
('paper', 'cited', 'paper') : data['PvsP'].transpose(), ('paper', 'cited', 'paper') : data['PvsP'].transpose().nonzero(),
('paper', 'is-about', 'subject') : data['PvsL'], ('paper', 'is-about', 'subject') : data['PvsL'].nonzero(),
('subject', 'has', 'paper') : data['PvsL'].transpose(), ('subject', 'has', 'paper') : data['PvsL'].transpose().nonzero(),
}) })
print(G) print(G)
......
...@@ -32,7 +32,7 @@ A = grid_graph(28, 8, metric) ...@@ -32,7 +32,7 @@ A = grid_graph(28, 8, metric)
coarsening_levels = 4 coarsening_levels = 4
L, perm = coarsen(A, coarsening_levels) L, perm = coarsen(A, coarsening_levels)
g_arr = [dgl.graph(csr) for csr in L] g_arr = [dgl.from_scipy(csr) for csr in L]
coordinate_arr = get_coordinates(g_arr, grid_side, coarsening_levels, perm) coordinate_arr = get_coordinates(g_arr, grid_side, coarsening_levels, perm)
for g, coordinate_arr in zip(g_arr, coordinate_arr): for g, coordinate_arr in zip(g_arr, coordinate_arr):
......
...@@ -59,7 +59,6 @@ def main(args): ...@@ -59,7 +59,6 @@ def main(args):
hg = dataset[0] hg = dataset[0]
num_rels = len(hg.canonical_etypes) num_rels = len(hg.canonical_etypes)
num_of_ntype = len(hg.ntypes)
category = dataset.predict_category category = dataset.predict_category
num_classes = dataset.num_classes num_classes = dataset.num_classes
train_mask = hg.nodes[category].data.pop('train_mask') train_mask = hg.nodes[category].data.pop('train_mask')
...@@ -90,7 +89,7 @@ def main(args): ...@@ -90,7 +89,7 @@ def main(args):
if ntype == category: if ntype == category:
category_id = i category_id = i
g = dgl.to_homo(hg) g = dgl.to_homogeneous(hg, edata=['norm'])
num_nodes = g.number_of_nodes() num_nodes = g.number_of_nodes()
node_ids = torch.arange(num_nodes) node_ids = torch.arange(num_nodes)
edge_norm = g.edata['norm'] edge_norm = g.edata['norm']
......
...@@ -484,7 +484,7 @@ def main(args, devices): ...@@ -484,7 +484,7 @@ def main(args, devices):
if ntype == category: if ntype == category:
category_id = i category_id = i
g = dgl.to_homo(hg) g = dgl.to_homogeneous(hg, edata=['norm'])
if args.global_norm: if args.global_norm:
u, v, eid = g.all_edges(form='all') u, v, eid = g.all_edges(form='all')
_, inverse_index, count = th.unique(v, return_inverse=True, return_counts=True) _, inverse_index, count = th.unique(v, return_inverse=True, return_counts=True)
......
...@@ -135,7 +135,7 @@ def build_graph_from_triplets(num_nodes, num_rels, triplets): ...@@ -135,7 +135,7 @@ def build_graph_from_triplets(num_nodes, num_rels, triplets):
This function also generates edge type and normalization factor This function also generates edge type and normalization factor
(reciprocal of node incoming degree) (reciprocal of node incoming degree)
""" """
g = dgl.graph([]) g = dgl.graph(([], []))
g.add_nodes(num_nodes) g.add_nodes(num_nodes)
src, rel, dst = triplets src, rel, dst = triplets
src, dst = np.concatenate((src, dst)), np.concatenate((dst, src)) src, dst = np.concatenate((src, dst)), np.concatenate((dst, src))
......
...@@ -19,7 +19,7 @@ class GraphPool: ...@@ -19,7 +19,7 @@ class GraphPool:
print('start creating graph pool...') print('start creating graph pool...')
tic = time.time() tic = time.time()
self.n, self.m = n, m self.n, self.m = n, m
g_pool = [[dgl.graph([]) for _ in range(m)] for _ in range(n)] g_pool = [[dgl.graph(([], [])) for _ in range(m)] for _ in range(n)]
num_edges = { num_edges = {
'ee': np.zeros((n, n)).astype(int), 'ee': np.zeros((n, n)).astype(int),
'ed': np.zeros((n, m)).astype(int), 'ed': np.zeros((n, m)).astype(int),
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
* Author's code for link prediction: [https://github.com/MichSchli/RelationPrediction](https://github.com/MichSchli/RelationPrediction) * Author's code for link prediction: [https://github.com/MichSchli/RelationPrediction](https://github.com/MichSchli/RelationPrediction)
### Dependencies ### Dependencies
* Tensorflow 2.1+ * Tensorflow 2.2+
* requests * requests
* rdflib * rdflib
* pandas * pandas
......
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