dgl.DGLHeteroGraph.multi_send_and_recv

DGLHeteroGraph.multi_send_and_recv(etype_dict, cross_reducer, apply_node_func=None, inplace=False)[source]

Send and receive messages along multiple edge types and perform aggregation.

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

This is a convenient combination for performing multiple send along edges of different types and multi_recv for the destinations of all edges.

Parameters:
  • etype_dict (dict) –

    Mapping an edge type (str or tuple of str) to the type specific configuration (4-tuples). Each 4-tuple represents (edges, msg_func, reduce_func, apply_node_func):

    • edges: See send() for valid edge specification.
      Edges on which to pass messages.
    • msg_func: callable
      Message function on the edges. The function should be an Edge UDF.
    • reduce_func: callable
      Reduce function on the node. The function should be a Node UDF.
    • apply_node_func : callable, optional
      Apply function on the nodes. The function should be a Node UDF. (Default: None)
  • 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)

Examples

>>> 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])

Trigger send and recv separately.

>>> g.nodes['user'].data['h'] = torch.tensor([[1.], [2.]])
>>> g.nodes['game'].data['h'] = torch.tensor([[1.]])
>>> 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']
tensor([[0.],
        [2.]])

Trigger “send” and “receive” in one call.

>>> g.nodes['user'].data['h'] = torch.tensor([[1.], [2.]])
>>> g.nodes['game'].data['h'] = torch.tensor([[1.]])
>>> g.multi_send_and_recv(
>>>     {'follows': (g['follows'].edges(), fn.copy_src('h', 'm'), fn.sum('m', 'h')),
>>>      'attracts': (g['attracts'].edges(), fn.copy_src('h', 'm'), fn.sum('m', 'h'))},
>>> "sum")
>>> g.nodes['user'].data['h']
tensor([[0.],
        [2.]])