class_docstr: Decoder based on "Convolutional Sequence to Sequence Learning"
  :cite:`DBLP:journals/corr/GehringAGYD17`.
  
  Consists of residual convolutional layers, with ConvMultiStepAttention.
class_docstr_tok: ["Decoder","based","on","``","Convolutional","Sequence","to","Sequence","Learning","''",":","cite",":","`","DBLP",":","journals\/corr\/GehringAGYD17","`",".","Consists","of","residual","convolutional","layers",",","with","ConvMultiStepAttention","."]
docstr: See :obj:`onmt.modules.RNNDecoderBase.forward()`
docstr_tok: ["See",":","obj",":","`","onmt.modules.RNNDecoderBase.forward","(",")","`"]
code: def forward(self, tgt, enc_out, step=None, **kwargs):
      """See :obj:`onmt.modules.RNNDecoderBase.forward()`"""
  
      if self.state["previous_input"] is not None:
          tgt = torch.cat([self.state["previous_input"], tgt], 1)
  
      dec_outs = []
      attns = {"std": []}
      if self.copy_attn is not None:
          attns["copy"] = []
  
      emb = self.embeddings(tgt)
      assert emb.dim() == 3  # batch x len x embedding_dim
  
      tgt_emb = emb
      # The output of CNNEncoder.
      enc_out_t = enc_out
      # The combination of output of CNNEncoder and source embeddings.
      enc_out_c = self.state["src"]
  
      emb_reshape = tgt_emb.view(tgt_emb.size(0) * tgt_emb.size(1), -1)
      linear_out = self.linear(emb_reshape)
      x = linear_out.view(tgt_emb.size(0), tgt_emb.size(1), -1)
      x = shape_transform(x)
  
      pad = torch.zeros(
          x.size(0), x.size(1), self.cnn_kernel_width - 1, 1
      )
  
      pad = pad.type_as(x)
      base_target_emb = x
  
      for conv, attention in zip(self.conv_layers, self.attn_layers):
          new_target_input = torch.cat([pad, x], 2)
          out = conv(new_target_input)
          c, attn = attention(
              base_target_emb, out, enc_out_t, enc_out_c
          )
          x = (x + (c + out) * SCALE_WEIGHT) * SCALE_WEIGHT
  
      dec_outs = x.squeeze(3).transpose(1, 2)
  
      # Process the result and update the attentions.
      if self.state["previous_input"] is not None:
          dec_outs = dec_outs[
              :, self.state["previous_input"].size(1) :, :
          ]
          attn = attn[
              :, self.state["previous_input"].size(1) :
          ].squeeze()
          attn = torch.stack([attn])
      attns["std"] = attn
      if self.copy_attn is not None:
          attns["copy"] = attn
  
      # Update the state.
      self.state["previous_input"] = tgt
      # TODO change the way attns is returned dict => list or tuple (onnx)
      return dec_outs, attns
  
file_path: OpenNMT-py/onmt/decoders/cnn_decoder.py
imports: import torch
  import torch.nn
  from onmt.modules import ConvMultiStepAttention, GlobalAttention
  from onmt.utils.cnn_factory import shape_transform, GatedConv
  from onmt.decoders.decoder import DecoderBase
label_desc: Use image node_id 6 for calling the CNNDecoder obj's underlying member method code with example usage: obj.forward(tgt, enc_out, step) and returns: dec_outs,  attns