class_docstr: Global attention takes a matrix and a query vector. It
  then computes a parameterized convex combination of the matrix
  based on the input query.
  
  Constructs a unit mapping a query `q` of size `dim`
  and a source matrix `H` of size `n x dim`, to an output
  of size `dim`.
  
  
  .. mermaid::
  
     graph BT
        A[Query]
        subgraph RNN
          C[H 1]
          D[H 2]
          E[H N]
        end
        F[Attn]
        G[Output]
        A --> F
        C --> F
        D --> F
        E --> F
        C -.-> G
        D -.-> G
        E -.-> G
        F --> G
  
  All models compute the output as
  :math:`c = \sum_{j=1}^{\text{SeqLength}} a_j H_j` where
  :math:`a_j` is the softmax of a score function.
  Then then apply a projection layer to [q, c].
  
  However they
  differ on how they compute the attention score.
  
  * Luong Attention (dot, general):
     * dot: :math:`\text{score}(H_j,q) = H_j^T q`
     * general: :math:`\text{score}(H_j, q) = H_j^T W_a q`
  
  
  * Bahdanau Attention (mlp):
     * :math:`\text{score}(H_j, q) = v_a^T \text{tanh}(W_a q + U_a h_j)`
  
  
  Args:
     dim (int): dimensionality of query and key
     coverage (bool): use coverage term
     attn_type (str): type of attention to use, options [dot,general,mlp]
     attn_func (str): attention function to use, options [softmax,sparsemax]
docstr: Args:
    src (FloatTensor): query vectors ``(batch, tgt_len, dim)``
    enc_out (FloatTensor): encoder out vectors ``(batch, src_len, dim)``
    src_len (LongTensor): source context lengths ``(batch,)``
    coverage (FloatTensor): None (not supported yet)
  
  Returns:
    (FloatTensor, FloatTensor):
  
    * Computed vector ``(batch, tgt_len, dim)``
    * Attention distribtutions for each query
      ``(batch, tgt_len, src_len)``
docstr_tok: ["Args",":","src","(","FloatTensor",")",":","query","vectors","``","(","batch",",","tgt_len",",","dim",")","``","enc_out","(","FloatTensor",")",":","encoder","out","vectors","``","(","batch",",","src_len",",","dim",")","``","src_len","(","LongTensor",")",":","source","context","lengths","``","(","batch",",",")","``","coverage","(","FloatTensor",")",":","None","(","not","supported","yet",")","Returns",":","(","FloatTensor",",","FloatTensor",")",":","*","Computed","vector","``","(","batch",",","tgt_len",",","dim",")","``","*","Attention","distribtutions","for","each","query","``","(","batch",",","tgt_len",",","src_len",")","``"]
code: def forward(self, src, enc_out, src_len=None, coverage=None):
      """
  
      Args:
        src (FloatTensor): query vectors ``(batch, tgt_len, dim)``
        enc_out (FloatTensor): encoder out vectors ``(batch, src_len, dim)``
        src_len (LongTensor): source context lengths ``(batch,)``
        coverage (FloatTensor): None (not supported yet)
  
      Returns:
        (FloatTensor, FloatTensor):
  
        * Computed vector ``(batch, tgt_len, dim)``
        * Attention distribtutions for each query
          ``(batch, tgt_len, src_len)``
      """
  
      # one step input
      if src.dim() == 2:
          one_step = True
          src = src.unsqueeze(1)
      else:
          one_step = False
  
      batch, src_l, dim = enc_out.size()
      batch_, target_l, dim_ = src.size()
      if coverage is not None:
          batch_, src_l_ = coverage.size()
  
      if coverage is not None:
          cover = coverage.view(-1).unsqueeze(1)
          enc_out += self.linear_cover(cover).view_as(enc_out)
          enc_out = torch.tanh(enc_out)
  
      # compute attention scores, as in Luong et al.
      align = self.score(src, enc_out)
  
      if src_len is not None:
          mask = ~sequence_mask(src_len, max_len=align.size(-1))
          mask = mask.unsqueeze(1)  # Make it broadcastable.
          align.masked_fill_(~mask, -float("inf"))
  
      # Softmax or sparsemax to normalize attention weights
      if self.attn_func == "softmax":
          align_vectors = F.softmax(
              align.view(batch * target_l, src_l), -1
          )
      else:
          align_vectors = sparsemax(
              align.view(batch * target_l, src_l), -1
          )
      align_vectors = align_vectors.view(batch, target_l, src_l)
  
      # each context vector c_t is the weighted average
      # over all the source hidden states
      c = torch.bmm(align_vectors, enc_out)
  
      # concatenate
      concat_c = torch.cat([c, src], 2).view(batch * target_l, dim * 2)
      attn_h = self.linear_out(concat_c).view(batch, target_l, dim)
      if self.attn_type in ["general", "dot"]:
          attn_h = torch.tanh(attn_h)
  
      if one_step:
          attn_h = attn_h.squeeze(1)
          align_vectors = align_vectors.squeeze(1)
  
      return attn_h, align_vectors
  
file_path: OpenNMT-py/onmt/modules/global_attention.py
imports: import torch
  import torch.nn
  import torch.nn.functional
  from onmt.modules.sparse_activations import sparsemax
  from onmt.utils.misc import sequence_mask
label_desc: Use image node_id 3 for calling the GlobalAttention obj's underlying member method code with example usage: obj.forward(src, enc_out, src_len, coverage) and returns: attn_h,  align_vectors