dgl.reverse(g, copy_ndata=True, copy_edata=False, *, share_ndata=None, share_edata=None)[source]

Return a new graph with every edges being the reverse ones in the input graph.

The reverse (also called converse, transpose) of a graph with edges \((i_1, j_1), (i_2, j_2), \cdots\) of type (U, E, V) is a new graph with edges \((j_1, i_1), (j_2, i_2), \cdots\) of type (V, E, U).

The returned graph shares the data structure with the original graph, i.e. dgl.reverse will not create extra storage for the reversed graph.

  • g (DGLGraph) – The input graph.

  • copy_ndata (bool, optional) – If True, the node features of the reversed graph are copied from the original graph. If False, the reversed graph will not have any node features. (Default: True)

  • copy_edata (bool, optional) – If True, the edge features of the reversed graph are copied from the original graph. If False, the reversed graph will not have any edge features. (Default: False)


The reversed graph.

Return type



If copy_ndata or copy_edata is True, the resulting graph will share the node or edge feature tensors with the input graph. Hence, users should try to avoid in-place operations which will be visible to both graphs.

This function discards the batch information. Please use dgl.DGLGraph.set_batch_num_nodes() and dgl.DGLGraph.set_batch_num_edges() on the transformed graph to maintain the information.


Homogeneous graphs

Create a graph to reverse.

>>> import dgl
>>> import torch as th
>>> g = dgl.graph((th.tensor([0, 1, 2]), th.tensor([1, 2, 0])))
>>> g.ndata['h'] = th.tensor([[0.], [1.], [2.]])
>>> g.edata['h'] = th.tensor([[3.], [4.], [5.]])

Reverse the graph.

>>> rg = dgl.reverse(g, copy_edata=True)
>>> rg.ndata['h']

The i-th edge in the reversed graph corresponds to the i-th edge in the original graph. When copy_edata is True, they have the same features.

>>> rg.edges()
(tensor([1, 2, 0]), tensor([0, 1, 2]))
>>> rg.edata['h']

Heterogenenous graphs

>>> g = dgl.heterograph({
...     ('user', 'follows', 'user'): (th.tensor([0, 2]), th.tensor([1, 2])),
...     ('user', 'plays', 'game'): (th.tensor([1, 2, 1]), th.tensor([2, 1, 1]))
... })
>>> g.nodes['game'].data['hv'] = th.ones(3, 1)
>>> g.edges['plays'].data['he'] = th.zeros(3, 1)

The resulting graph will have edge types ('user', 'follows', 'user) and ('game', 'plays', 'user').

>>> rg = dgl.reverse(g, copy_ndata=True)
>>> rg
Graph(num_nodes={'game': 3, 'user': 3},
      num_edges={('user', 'follows', 'user'): 2, ('game', 'plays', 'user'): 3},
      metagraph=[('user', 'user'), ('game', 'user')])
>>> rg.edges(etype='follows')
(tensor([1, 2]), tensor([0, 2]))
>>> rg.edges(etype='plays')
(tensor([2, 1, 1]), tensor([1, 2, 1]))
>>> rg.nodes['game'].data['hv']
>>> rg.edges['plays'].data