class_docstr: The graph transformer layer from the `"Masked Label Prediction:
  Unified Message Passing Model for Semi-Supervised Classification"
  <https://arxiv.org/abs/2009.03509>`_ paper.
  
  Parameters
  ----------
  in_node_feats : int or pair of ints
      Input feature size. A pair denotes feature sizes of source and
      destination nodes.
  out_node_feats : int
      Output feature size.
  num_heads : int
      Number of multi-head-attentions.
  concat : bool, optional
      If False, the multi-head attentions are averaged instead of concatenated.
      Default: ``True``.
  beta : bool, optional
      If True, use a gated residual connection. Default: ``True``.
  edge_feats: int, optional
      Edge feature size. Default: ``None``.
  bias: bool, optional
      If True, learns a bias term. Default: ``True``.
  root_weight: bool, optional
      If False, will skip to learn a root weight matrix. Default: ``True``.
docstr: Forward computation.
  
  Parameters
  ----------
  g: DGLGraph
      The graph.
  nfeat: torch.Tensor or a pair of torch.Tensor
      Node feature tensor. A pair denotes features for source and
      destination nodes, respectively.
  efeat: torch.Tensor, optional
      Edge feature tensor. Default: ``None``.
docstr_tok: ["Forward","computation",".","Parameters","--","--","--","--","--","g",":","DGLGraph","The","graph",".","nfeat",":","torch.Tensor","or","a","pair","of","torch.Tensor","Node","feature","tensor",".","A","pair","denotes","features","for","source","and","destination","nodes",",","respectively",".","efeat",":","torch.Tensor",",","optional","Edge","feature","tensor",".","Default",":","``","None","``","."]
code: def forward(
      self,
      g: Union[SparseGraph, dgl.DGLHeteroGraph],
      nfeat: Union[torch.Tensor, Tuple[torch.Tensor, torch.Tensor]],
      efeat: Optional[torch.Tensor] = None,
  ) -> torch.Tensor:
      """Forward computation.
  
      Parameters
      ----------
      g: DGLGraph
          The graph.
      nfeat: torch.Tensor or a pair of torch.Tensor
          Node feature tensor. A pair denotes features for source and
          destination nodes, respectively.
      efeat: torch.Tensor, optional
          Edge feature tensor. Default: ``None``.
      """
      feat_bipartite = isinstance(nfeat, (list, tuple))
      if not feat_bipartite:
          nfeat = (nfeat, nfeat)
  
      _graph = self.get_cugraph_ops_CSC(g, is_bipartite=True)
  
      query = self.lin_query(nfeat[1][: g.num_dst_nodes()])
      key = self.lin_key(nfeat[0])
      value = self.lin_value(nfeat[0])
  
      if efeat is not None:
          if self.lin_edge is None:
              raise RuntimeError(
                  f"{self.__class__.__name__}.edge_feats must be set to allow "
                  f"edge features."
              )
          efeat = self.lin_edge(efeat)
  
      out = ops_torch.operators.mha_simple_n2n(
          key_emb=key,
          query_emb=query,
          value_emb=value,
          graph=_graph,
          num_heads=self.num_heads,
          concat_heads=self.concat,
          edge_emb=efeat,
          norm_by_dim=True,
          score_bias=None,
      )[: g.num_dst_nodes()]
  
      if self.root_weight:
          res = self.lin_skip(nfeat[1][: g.num_dst_nodes()])
          if self.lin_beta is not None:
              beta = self.lin_beta(
                  torch.cat([out, res, out - res], dim=-1)
              )
              beta = beta.sigmoid()
              out = beta * res + (1 - beta) * out
          else:
              out = out + res
  
      return out
  
imports: from typing import Optional, Tuple, 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 TransformerConv obj's underlying member method code with example usage: obj.forward(g, nfeat, efeat) and returns: out