DGLHeteroGraph.multi_recv(v, reducer_dict, cross_reducer, apply_node_func=None, inplace=False)[source]

Receive messages from multiple edge types and perform aggregation.

It calculates:

\[\begin{split}\begin{align} h_{v, t}^{new} &= f\left(\left\{m_{uv} | u\in\mathcal{N}_{t}(v)\right\}\right)\\ h_v^{new} &= \sigma\left(g\left(\left\{h_{v, t}^{new} | t\in T_e\right\}\right)\right) \end{align}\end{split}\]
  • per_type_reducer is a dictionary mapping edge type (str or tuple of str) to reduce functions \(f\) of each type.
  • cross_reducer specifies \(g\).
  • apply_node_func specifies \(\sigma\).
  • v (int, container or tensor) – The node(s) to be updated.
  • reducer_dict (dict of callable) – Mapping edge type (str or tuple of str) to reduce function (Node UDF).
  • cross_reducer (str) – Cross type reducer. One of "sum", "min", "max", "mean", "stack".
  • apply_node_func (callable) – Apply function on the nodes. The function should be a Node UDF. (Default: None)
  • inplace (bool, optional) – If True, update will be done in place, but autograd will break. (Default: False)


>>> import dgl
>>> import dgl.function as fn
>>> import torch

Instantiate a heterograph.

>>> g1 = dgl.graph([(0, 1)], 'user', 'follows')
>>> g2 = dgl.bipartite([(0, 1)], 'game', 'attracts', 'user')
>>> g = dgl.hetero_from_relations([g1, g2])
>>> g.nodes['user'].data['h'] = torch.tensor([[1.], [2.]])
>>> g.nodes['game'].data['h'] = torch.tensor([[1.]])

Send and receive.

>>> g.send(g['follows'].edges(), fn.copy_src('h', 'm'), etype='follows')
>>> g.send(g['attracts'].edges(), fn.copy_src('h', 'm'), etype='attracts')
>>> g.multi_recv(g.nodes('user'), {'follows': fn.sum('m', 'h'),
>>>              'attracts': fn.sum('m', 'h')}, "sum")
>>> g.nodes['user'].data['h']