class_docstr: The relational graph convolutional operator from the `"Modeling
  Relational Data with Graph Convolutional Networks"
  <https://arxiv.org/abs/1703.06103>`_ paper.
  
  .. math::
      \mathbf{x}^{\prime}_i = \mathbf{\Theta}_{\textrm{root}} \cdot
      \mathbf{x}_i + \sum_{r \in \mathcal{R}} \sum_{j \in \mathcal{N}_r(i)}
      \frac{1}{|\mathcal{N}_r(i)|} \mathbf{\Theta}_r \cdot \mathbf{x}_j,
  
  where :math:`\mathcal{R}` denotes the set of relations, *i.e.* edge types.
  Edge type needs to be a one-dimensional :obj:`torch.long` tensor which
  stores a relation identifier
  :math:`\in \{ 0, \ldots, |\mathcal{R}| - 1\}` for each edge.
  
  .. note::
      This implementation is as memory-efficient as possible by iterating
      over each individual relation type.
      Therefore, it may result in low GPU utilization in case the graph has a
      large number of relations.
      As an alternative approach, :class:`FastRGCNConv` does not iterate over
      each individual type, but may consume a large amount of memory to
      compensate.
      We advise to check out both implementations to see which one fits your
      needs.
  
  .. note::
      :class:`RGCNConv` can use `dynamic shapes
      <https://docs.nvidia.com/deeplearning/tensorrt/developer-guide/index
      .html#work_dynamic_shapes>`_, which means that the shape of the interim
      tensors can be determined at runtime.
      If your device doesn't support dynamic shapes, use
      :class:`FastRGCNConv` instead.
  
  Args:
      in_channels (int or tuple): Size of each input sample. A tuple
          corresponds to the sizes of source and target dimensionalities.
          In case no input features are given, this argument should
          correspond to the number of nodes in your graph.
      out_channels (int): Size of each output sample.
      num_relations (int): Number of relations.
      num_bases (int, optional): If set, this layer will use the
          basis-decomposition regularization scheme where :obj:`num_bases`
          denotes the number of bases to use. (default: :obj:`None`)
      num_blocks (int, optional): If set, this layer will use the
          block-diagonal-decomposition regularization scheme where
          :obj:`num_blocks` denotes the number of blocks to use.
          (default: :obj:`None`)
      aggr (str, optional): The aggregation scheme to use
          (:obj:`"add"`, :obj:`"mean"`, :obj:`"max"`).
          (default: :obj:`"mean"`)
      root_weight (bool, optional): If set to :obj:`False`, the layer will
          not add transformed root node features to the output.
          (default: :obj:`True`)
      is_sorted (bool, optional): If set to :obj:`True`, assumes that
          :obj:`edge_index` is sorted by :obj:`edge_type`. This avoids
          internal re-sorting of the data and can improve runtime and memory
          efficiency. (default: :obj:`False`)
      bias (bool, optional): If set to :obj:`False`, the layer will not learn
          an additive bias. (default: :obj:`True`)
      **kwargs (optional): Additional arguments of
          :class:`torch_geometric.nn.conv.MessagePassing`.
class_docstr_tok: ["The","relational","graph","convolutional","operator","from","the","`","``","Modeling","Relational","Data","with","Graph","Convolutional","Networks","''","<","https",":","\/\/arxiv.org\/abs\/1703.06103",">","`","_","paper",".","..","math",":",":","\\mathbf","{","x","}","^","{","\\prime","}","_i","=","\\mathbf","{","\\Theta","}","_","{","\\textrm","{","root","}","}","\\cdot","\\mathbf","{","x","}","_i","+","\\sum_","{","r","\\in","\\mathcal","{","R","}","}","\\sum_","{","j","\\in","\\mathcal","{","N","}","_r","(","i",")","}","\\frac","{","1","}","{","|\\mathcal","{","N","}","_r","(","i",")","|","}","\\mathbf","{","\\Theta","}","_r","\\cdot","\\mathbf","{","x","}","_j",",","where",":","math",":","`","\\mathcal","{","R","}","`","denotes","the","set","of","relations",",","*","i.e",".","*","edge","types",".","Edge","type","needs","to","be","a","one-dimensional",":","obj",":","`","torch.long","`","tensor","which","stores","a","relation","identifier",":","math",":","`","\\in","\\","{","0",",","\\ldots",",","|\\mathcal","{","R","}","|","-","1\\","}","`","for","each","edge",".","..","note",":",":","This","implementation","is","as","memory-efficient","as","possible","by","iterating","over","each","individual","relation","type",".","Therefore",",","it","may","result","in","low","GPU","utilization","in","case","the","graph","has","a","large","number","of","relations",".","As","an","alternative","approach",",",":","class",":","`","FastRGCNConv","`","does","not","iterate","over","each","individual","type",",","but","may","consume","a","large","amount","of","memory","to","compensate",".","We","advise","to","check","out","both","implementations","to","see","which","one","fits","your","needs",".","..","note",":",":",":","class",":","`","RGCNConv","`","can","use","`","dynamic","shapes","<","https",":","\/\/docs.nvidia.com\/deeplearning\/tensorrt\/developer-guide\/index",".html","#","work_dynamic_shapes",">","`","_",",","which","means","that","the","shape","of","the","interim","tensors","can","be","determined","at","runtime",".","If","your","device","does","n't","support","dynamic","shapes",",","use",":","class",":","`","FastRGCNConv","`","instead",".","Args",":","in_channels","(","int","or","tuple",")",":","Size","of","each","input","sample",".","A","tuple","corresponds","to","the","sizes","of","source","and","target","dimensionalities",".","In","case","no","input","features","are","given",",","this","argument","should","correspond","to","the","number","of","nodes","in","your","graph",".","out_channels","(","int",")",":","Size","of","each","output","sample",".","num_relations","(","int",")",":","Number","of","relations",".","num_bases","(","int",",","optional",")",":","If","set",",","this","layer","will","use","the","basis-decomposition","regularization","scheme","where",":","obj",":","`","num_bases","`","denotes","the","number","of","bases","to","use",".","(","default",":",":","obj",":","`","None","`",")","num_blocks","(","int",",","optional",")",":","If","set",",","this","layer","will","use","the","block-diagonal-decomposition","regularization","scheme","where",":","obj",":","`","num_blocks","`","denotes","the","number","of","blocks","to","use",".","(","default",":",":","obj",":","`","None","`",")","aggr","(","str",",","optional",")",":","The","aggregation","scheme","to","use","(",":","obj",":","`","``","add","''","`",",",":","obj",":","`","``","mean","''","`",",",":","obj",":","`","``","max","''","`",")",".","(","default",":",":","obj",":","`","``","mean","''","`",")","root_weight","(","bool",",","optional",")",":","If","set","to",":","obj",":","`","False","`",",","the","layer","will","not","add","transformed","root","node","features","to","the","output",".","(","default",":",":","obj",":","`","True","`",")","is_sorted","(","bool",",","optional",")",":","If","set","to",":","obj",":","`","True","`",",","assumes","that",":","obj",":","`","edge_index","`","is","sorted","by",":","obj",":","`","edge_type","`",".","This","avoids","internal","re-sorting","of","the","data","and","can","improve","runtime","and","memory","efficiency",".","(","default",":",":","obj",":","`","False","`",")","bias","(","bool",",","optional",")",":","If","set","to",":","obj",":","`","False","`",",","the","layer","will","not","learn","an","additive","bias",".","(","default",":",":","obj",":","`","True","`",")","*","*","kwargs","(","optional",")",":","Additional","arguments","of",":","class",":","`","torch_geometric.nn.conv.MessagePassing","`","."]
code: def message(self, x_j: Tensor, edge_type_ptr: OptTensor) -> Tensor:
      if (
          torch_geometric.typing.WITH_SEGMM
          and not is_compiling()
          and edge_type_ptr is not None
      ):
          # TODO Re-weight according to edge type degree for `aggr=mean`.
          return pyg_lib.ops.segment_matmul(
              x_j, edge_type_ptr, self.weight
          )
  
      return x_j
  
imports: from typing import Optional, Tuple, Union
  import torch
  from torch import Tensor
  from torch.nn import Parameter
  from torch.nn import Parameter
  import torch_geometric.backend
  import torch_geometric.typing
  from torch_geometric import is_compiling
  from torch_geometric.nn.conv import MessagePassing
  from torch_geometric.nn.inits import glorot, zeros
  from torch_geometric.typing import Adj, OptTensor, SparseTensor, pyg_lib, torch_sparse
  from torch_geometric.utils import index_sort, one_hot, scatter, spmm
  from torch_geometric.utils.sparse import index2ptr
label_desc: Use image node_id 4 for calling the RGCNConv obj's underlying member method code with example usage: obj.message(x_j, edge_type_ptr) and returns: x_j, pyg_lib