class_docstr: An accelerated relational graph convolution layer from `Modeling
  Relational Data with Graph Convolutional Networks
  <https://arxiv.org/abs/1703.06103>`__, with the sparse aggregation
  accelerated by cugraph-ops.
  
  Parameters
  ----------
  in_feats : int
      Input feature size.
  out_feats : int
      Output feature size.
  num_rels : int
      Number of relations.
  regularizer : str, optional
      Which weight regularizer to use ("basis" or ``None``):
       - "basis" is for basis-decomposition.
       - ``None`` applies no regularization.
      Default: ``None``.
  num_bases : int, optional
      Number of bases. It comes into effect when a regularizer is applied.
      Default: ``None``.
  bias : bool, optional
      True if bias is added. Default: ``True``.
  self_loop : bool, optional
      True to include self loop message. Default: ``True``.
  dropout : float, optional
      Dropout rate. Default: ``0.0``.
  apply_norm : bool, optional
      True to normalize aggregation output by the in-degree of the destination
      node per edge type, i.e. :math:`|\mathcal{N}^r_i|`. Default: ``True``.
  
  Examples
  --------
  >>> import dgl
  >>> import torch
  >>> from cugraph_dgl.nn import RelGraphConv
  ...
  >>> device = 'cuda'
  >>> g = dgl.graph(([0,1,2,3,2,5], [1,2,3,4,0,3])).to(device)
  >>> feat = torch.ones(6, 10).to(device)
  >>> conv = RelGraphConv(
  ...     10, 2, 3, regularizer='basis', num_bases=2).to(device)
  >>> etypes = torch.tensor([0,1,2,0,1,2]).to(device)
  >>> res = conv(g, feat, etypes)
  >>> res
  tensor([[-1.7774, -2.0184],
          [-1.4335, -2.3758],
          [-1.7774, -2.0184],
          [-0.4698, -3.0876],
          [-1.4335, -2.3758],
          [-1.4331, -2.3295]], device='cuda:0', grad_fn=<AddBackward0>)
docstr: Forward computation.
  
  Parameters
  ----------
  g : DGLGraph
      The graph.
  feat : torch.Tensor
      A 2D tensor of node features. Shape: :math:`(|V|, D_{in})`.
  etypes : torch.Tensor
      A 1D integer tensor of edge types. Shape: :math:`(|E|,)`.
      Note that cugraph-ops only accepts edge type tensors in int32,
      so any input of other integer types will be casted into int32,
      thus introducing some overhead. Pass in int32 tensors directly
      for best performance.
  max_in_degree : int
      Maximum in-degree of destination nodes. When :attr:`g` is generated
      from a neighbor sampler, the value should be set to the corresponding
      :attr:`fanout`. This option is used to invoke the MFG-variant of
      cugraph-ops kernel.
  
  Returns
  -------
  torch.Tensor
      New node features. Shape: :math:`(|V|, D_{out})`.
docstr_tok: ["Forward","computation",".","Parameters","--","--","--","--","--","g",":","DGLGraph","The","graph",".","feat",":","torch.Tensor","A","2D","tensor","of","node","features",".","Shape",":",":","math",":","`","(","|V|",",","D_","{","in","}",")","`",".","etypes",":","torch.Tensor","A","1D","integer","tensor","of","edge","types",".","Shape",":",":","math",":","`","(","|E|",",",")","`",".","Note","that","cugraph-ops","only","accepts","edge","type","tensors","in","int32",",","so","any","input","of","other","integer","types","will","be","casted","into","int32",",","thus","introducing","some","overhead",".","Pass","in","int32","tensors","directly","for","best","performance",".","max_in_degree",":","int","Maximum","in-degree","of","destination","nodes",".","When",":","attr",":","`","g","`","is","generated","from","a","neighbor","sampler",",","the","value","should","be","set","to","the","corresponding",":","attr",":","`","fanout","`",".","This","option","is","used","to","invoke","the","MFG-variant","of","cugraph-ops","kernel",".","Returns","--","--","--","-","torch.Tensor","New","node","features",".","Shape",":",":","math",":","`","(","|V|",",","D_","{","out","}",")","`","."]
code: def forward(
      self,
      g: Union[SparseGraph, dgl.DGLHeteroGraph],
      feat: torch.Tensor,
      etypes: torch.Tensor,
      max_in_degree: Optional[int] = None,
  ) -> torch.Tensor:
      r"""Forward computation.
  
      Parameters
      ----------
      g : DGLGraph
          The graph.
      feat : torch.Tensor
          A 2D tensor of node features. Shape: :math:`(|V|, D_{in})`.
      etypes : torch.Tensor
          A 1D integer tensor of edge types. Shape: :math:`(|E|,)`.
          Note that cugraph-ops only accepts edge type tensors in int32,
          so any input of other integer types will be casted into int32,
          thus introducing some overhead. Pass in int32 tensors directly
          for best performance.
      max_in_degree : int
          Maximum in-degree of destination nodes. When :attr:`g` is generated
          from a neighbor sampler, the value should be set to the corresponding
          :attr:`fanout`. This option is used to invoke the MFG-variant of
          cugraph-ops kernel.
  
      Returns
      -------
      torch.Tensor
          New node features. Shape: :math:`(|V|, D_{out})`.
      """
      _graph = self.get_cugraph_ops_HeteroCSC(
          g,
          num_edge_types=self.num_rels,
          etypes=etypes,
          is_bipartite=False,
          max_in_degree=max_in_degree,
      )
  
      h = ops_torch.operators.agg_hg_basis_n2n_post(
          feat,
          self.coeff,
          _graph,
          concat_own=self.self_loop,
          norm_by_out_degree=self.apply_norm,
      )[: g.num_dst_nodes()]
      h = h @ self.W.view(-1, self.out_feats)
      if self.bias is not None:
          h = h + self.bias
      h = self.dropout(h)
  
      return h
  
file_path: cugraph/python/cugraph-dgl/cugraph_dgl/nn/conv/relgraphconv.py
imports: import math
  from typing import Optional, Union
  from cugraph_dgl.nn.conv.base import BaseConv, SparseGraph
  from cugraph.utilities.utils import import_optional
label_desc: Use image node_id 3 for calling the RelGraphConv obj's underlying member method code with example usage: obj.forward(g, feat, etypes, max_in_degree) and returns: h