DGLGraph.recv(v='__ALL__', reduce_func='default', apply_node_func='default', inplace=False)[source]

Receive and reduce incoming messages and update the features of node(s) \(v\).

Optionally, apply a function to update the node features after receive.

  • reduce_func will be skipped for nodes with no incoming message.
  • If all v have no incoming message, this will downgrade to an apply_nodes().
  • If some v have no incoming message, their new feature value will be calculated by the column initializer (see set_n_initializer()). The feature shapes and dtypes will be inferred.

The node features will be updated by the result of the reduce_func.

Messages are consumed once received.

The provided UDF maybe called multiple times so it is recommended to provide function with no side effect.

  • v (node, container or tensor, optional) – The node to be updated. Default is receiving all the nodes.
  • reduce_func (callable, optional) – Reduce function on the node. The function should be a Node UDF.
  • apply_node_func (callable) – Apply function on the nodes. The function should be a Node UDF.
  • inplace (bool, optional) – If True, update will be done in place, but autograd will break.


Create a graph object for demo.


Here we use pytorch syntax for demo. The general idea applies to other frameworks with minor syntax change (e.g. replace torch.tensor with mxnet.ndarray).

>>> import torch as th
>>> g = dgl.DGLGraph()
>>> g.add_nodes(3)
>>> g.ndata['x'] = th.tensor([[1.], [2.], [3.]])
>>> g.add_edges([0, 1], [1, 2])
>>> # Define the function for sending node features as messages.
>>> def send_source(edges): return {'m': edges.src['x']}
>>> # Set the function defined to be the default message function.
>>> g.register_message_func(send_source)
>>> # Sum the messages received and use this to replace the original node feature.
>>> def simple_reduce(nodes): return {'x': nodes.mailbox['m'].sum(1)}
>>> # Set the function defined to be the default message reduce function.
>>> g.register_reduce_func(simple_reduce)

Send and receive messages. Note that although node \(0\) has no incoming edges, its feature gets changed from \(1\) to \(0\) as it is also included in g.nodes().

>>> g.send(g.edges())
>>> g.recv(g.nodes())
>>> g.ndata['x']

Once messages are received, one will need another call of send() again before another call of recv(). Otherwise, nothing will happen.

>>> g.recv(g.nodes())
>>> g.ndata['x']