class_docstr: Base class for creating message passing layers of the form
  
  .. math::
      \mathbf{x}_i^{\prime} = \gamma_{\mathbf{\Theta}} \left( \mathbf{x}_i,
      \square_{j \in \mathcal{N}(i)} \, \phi_{\mathbf{\Theta}}
      \left(\mathbf{x}_i, \mathbf{x}_j,\mathbf{e}_{j,i}\right) \right),
  
  where :math:`\square` denotes a differentiable, permutation invariant
  function, *e.g.*, sum, mean or max, and :math:`\gamma_{\mathbf{\Theta}}`
  and :math:`\phi_{\mathbf{\Theta}}` denote differentiable functions such as
  MLPs.
  See `here <https://pytorch-geometric.readthedocs.io/en/latest/notes/
  create_gnn.html>`__ for the accompanying tutorial.
  
  Args:
      aggr (string, optional): The aggregation scheme to use
          (:obj:`"add"`, :obj:`"mean"`, :obj:`"max"` or :obj:`None`).
          (default: :obj:`"add"`)
      flow (string, optional): The flow direction of message passing
          (:obj:`"source_to_target"` or :obj:`"target_to_source"`).
          (default: :obj:`"source_to_target"`)
      node_dim (int, optional): The axis along which to propagate.
          (default: :obj:`-2`)
code: def __init__(
      self,
      aggr: Optional[str] = "add",
      flow: str = "source_to_target",
      node_dim: int = -2,
  ):
      super(MessagePassing, self).__init__()
  
      self.aggr = aggr
      assert self.aggr in ["add", "mean", "max", None]
  
      self.flow = flow
      assert self.flow in ["source_to_target", "target_to_source"]
  
      self.node_dim = node_dim
  
      self.inspector = Inspector(self)
      self.inspector.inspect(self.message)
      self.inspector.inspect(self.aggregate, pop_first=True)
      self.inspector.inspect(self.message_and_aggregate, pop_first=True)
      self.inspector.inspect(self.update, pop_first=True)
  
      self.__user_args__ = self.inspector.keys(
          ["message", "aggregate", "update"]
      ).difference(self.special_args)
      self.__fused_user_args__ = self.inspector.keys(
          ["message_and_aggregate", "update"]
      ).difference(self.special_args)
  
      # Support for "fused" message passing.
      self.fuse = self.inspector.implements("message_and_aggregate")
  
      # Support for GNNExplainer.
      self.__explain__ = False
      self.__edge_mask__ = None
  
imports: import os
  import re
  import inspect
  import os.path
  from uuid import uuid1
  from itertools import chain
  from inspect import Parameter
  from typing import List, Optional, Set
  from torch_geometric.typing import Adj, Size
  import torch
  from torch import Tensor
  from jinja2 import Template
  from torch_sparse import SparseTensor
  from torch_scatter import gather_csr, scatter, segment_csr
  from .utils.helpers import expand_left
  from .utils.jit import class_from_module_repr
  from .utils.typing import sanitize, split_types_repr, parse_types, resolve_types
  from .utils.inspector import Inspector, func_header_repr, func_body_repr
label_desc: Use image node_id 1 to create a new MessagePassing object from inherited base classes: torch.nn with example: obj = MessagePassing(aggr, flow, node_dim)