class_docstr: The GATv2 operator from the `"How Attentive are Graph Attention
  Networks?" <https://arxiv.org/abs/2105.14491>`_ paper, which fixes the
  static attention problem of the standard
  :class:`~torch_geometric.conv.GATConv` layer.
  Since the linear layers in the standard GAT are applied right after each
  other, the ranking of attended nodes is unconditioned on the query node.
  In contrast, in :class:`GATv2`, every node can attend to any other node.
  
  .. math::
      \mathbf{x}^{\prime}_i = \alpha_{i,i}\mathbf{\Theta}\mathbf{x}_{i} +
      \sum_{j \in \mathcal{N}(i)} \alpha_{i,j}\mathbf{\Theta}\mathbf{x}_{j},
  
  where the attention coefficients :math:`\alpha_{i,j}` are computed as
  
  .. math::
      \alpha_{i,j} =
      \frac{
      \exp\left(\mathbf{a}^{\top}\mathrm{LeakyReLU}\left(\mathbf{\Theta}
      [\mathbf{x}_i \, \Vert \, \mathbf{x}_j]
      \right)\right)}
      {\sum_{k \in \mathcal{N}(i) \cup \{ i \}}
      \exp\left(\mathbf{a}^{\top}\mathrm{LeakyReLU}\left(\mathbf{\Theta}
      [\mathbf{x}_i \, \Vert \, \mathbf{x}_k]
      \right)\right)}.
  
  If the graph has multi-dimensional edge features :math:`\mathbf{e}_{i,j}`,
  the attention coefficients :math:`\alpha_{i,j}` are computed as
  
  .. math::
      \alpha_{i,j} =
      \frac{
      \exp\left(\mathbf{a}^{\top}\mathrm{LeakyReLU}\left(\mathbf{\Theta}
      [\mathbf{x}_i \, \Vert \, \mathbf{x}_j \, \Vert \, \mathbf{e}_{i,j}]
      \right)\right)}
      {\sum_{k \in \mathcal{N}(i) \cup \{ i \}}
      \exp\left(\mathbf{a}^{\top}\mathrm{LeakyReLU}\left(\mathbf{\Theta}
      [\mathbf{x}_i \, \Vert \, \mathbf{x}_k \, \Vert \, \mathbf{e}_{i,k}]
      \right)\right)}.
  
  Args:
      in_channels (int or tuple): Size of each input sample, or :obj:`-1` to
          derive the size from the first input(s) to the forward method.
          A tuple corresponds to the sizes of source and target
          dimensionalities.
      out_channels (int): Size of each output sample.
      heads (int, optional): Number of multi-head-attentions.
          (default: :obj:`1`)
      concat (bool, optional): If set to :obj:`False`, the multi-head
          attentions are averaged instead of concatenated.
          (default: :obj:`True`)
      negative_slope (float, optional): LeakyReLU angle of the negative
          slope. (default: :obj:`0.2`)
      edge_dim (int, optional): Edge feature dimensionality (in case
          there are any). (default: :obj:`None`)
      bias (bool, optional): If set to :obj:`False`, the layer will not learn
          an additive bias. (default: :obj:`True`)
      share_weights (bool, optional): If set to :obj:`True`, the same matrix
          will be applied to the source and the target node of every edge.
          (default: :obj:`False`)
docstr: Runs the forward pass of the module.
  
  Args:
      x (torch.Tensor or tuple): The node features. Can be a tuple of
          tensors denoting source and destination node features.
      csc ((torch.Tensor, torch.Tensor, int)): A tuple containing the CSC
          representation of a graph, given as a tuple of
          :obj:`(row, colptr, num_src_nodes)`. Use the
          :meth:`to_csc` method to convert an :obj:`edge_index`
          representation to the desired format.
      edge_attr: (torch.Tensor, optional) The edge features.
code: def forward(
      self,
      x: Union[torch.Tensor, Tuple[torch.Tensor, torch.Tensor]],
      csc: Tuple[torch.Tensor, torch.Tensor, int],
      edge_attr: Optional[torch.Tensor] = None,
  ) -> torch.Tensor:
      r"""Runs the forward pass of the module.
  
      Args:
          x (torch.Tensor or tuple): The node features. Can be a tuple of
              tensors denoting source and destination node features.
          csc ((torch.Tensor, torch.Tensor, int)): A tuple containing the CSC
              representation of a graph, given as a tuple of
              :obj:`(row, colptr, num_src_nodes)`. Use the
              :meth:`to_csc` method to convert an :obj:`edge_index`
              representation to the desired format.
          edge_attr: (torch.Tensor, optional) The edge features.
      """
      bipartite = (
          not isinstance(x, torch.Tensor) or not self.share_weights
      )
      graph = self.get_cugraph(csc, bipartite=bipartite)
  
      if edge_attr is not None:
          if self.lin_edge is None:
              raise RuntimeError(
                  f"{self.__class__.__name__}.edge_dim must be set to accept "
                  f"edge features."
              )
          if edge_attr.dim() == 1:
              edge_attr = edge_attr.view(-1, 1)
          edge_attr = self.lin_edge(edge_attr)
  
      if bipartite:
          if isinstance(x, torch.Tensor):
              x = (x, x)
          x_src = self.lin_src(x[0])
          x_dst = self.lin_dst(x[1])
      else:
          x = self.lin_src(x)
  
      out = mha_gat_v2_n2n(
          (x_src, x_dst) if bipartite else x,
          self.att,
          graph,
          num_heads=self.heads,
          activation="LeakyReLU",
          negative_slope=self.negative_slope,
          concat_heads=self.concat,
          edge_feat=edge_attr,
      )
  
      if self.bias is not None:
          out = out + self.bias
  
      return out
  
file_path: cugraph/python/cugraph-pyg/cugraph_pyg/nn/conv/gatv2_conv.py
imports: from typing import Optional, Tuple, Union
  from cugraph.utilities.utils import import_optional
  from pylibcugraphops.pytorch.operators import mha_gat_v2_n2n
  from .base import BaseConv
label_desc: Use image node_id 3 for calling the GATv2Conv obj's underlying member method code with example usage: obj.forward(x, csc, edge_attr) and returns: out