class_docstr: LSTM decoder.
class_docstr_tok: ["LSTM","decoder","."]
code: def forward(
      self,
      prev_output_tokens,
      encoder_out_dict,
      incremental_state=None,
      lang_id=0,
  ):
      sentemb = encoder_out_dict["sentemb"]
      encoder_out = encoder_out_dict["encoder_out"]
  
      if incremental_state is not None:
          prev_output_tokens = prev_output_tokens[:, -1:]
      bsz, seqlen = prev_output_tokens.size()
  
      # get outputs from encoder
      encoder_outs, _, _ = encoder_out[:3]
      srclen = encoder_outs.size(0)
  
      # embed tokens
      x = self.embed_tokens(prev_output_tokens)
      x = F.dropout(x, p=self.dropout_in, training=self.training)
  
      # embed language identifier
      if self.embed_lang is not None:
          lang_ids = prev_output_tokens.data.new_full((bsz,), lang_id)
          langemb = self.embed_lang(lang_ids)
          # TODO Should we dropout here???
  
      # B x T x C -> T x B x C
      x = x.transpose(0, 1)
  
      # initialize previous states (or get from cache during incremental generation)
      cached_state = utils.get_incremental_state(
          self, incremental_state, "cached_state"
      )
      if cached_state is not None:
          prev_hiddens, prev_cells, input_feed = cached_state
      else:
          num_layers = len(self.layers)
          if self.sentemb2init is None:
              prev_hiddens = [
                  x.data.new(bsz, self.hidden_size).zero_()
                  for i in range(num_layers)
              ]
              prev_cells = [
                  x.data.new(bsz, self.hidden_size).zero_()
                  for i in range(num_layers)
              ]
          else:
              init = self.sentemb2init(sentemb)
              prev_hiddens = [
                  init[
                      :,
                      (2 * i)
                      * self.hidden_size : (2 * i + 1)
                      * self.hidden_size,
                  ]
                  for i in range(num_layers)
              ]
              prev_cells = [
                  init[
                      :,
                      (2 * i + 1)
                      * self.hidden_size : (2 * i + 2)
                      * self.hidden_size,
                  ]
                  for i in range(num_layers)
              ]
          input_feed = x.data.new(bsz, self.hidden_size).zero_()
  
      attn_scores = x.data.new(srclen, seqlen, bsz).zero_()
      outs = []
      for j in range(seqlen):
          if self.embed_lang is None:
              input = torch.cat((x[j, :, :], sentemb), dim=1)
          else:
              input = torch.cat((x[j, :, :], sentemb, langemb), dim=1)
  
          for i, rnn in enumerate(self.layers):
              # recurrent cell
              hidden, cell = rnn(
                  input, (prev_hiddens[i], prev_cells[i])
              )
  
              # hidden state becomes the input to the next layer
              input = F.dropout(
                  hidden, p=self.dropout_out, training=self.training
              )
  
              # save state for next time step
              prev_hiddens[i] = hidden
              prev_cells[i] = cell
  
          out = hidden
          out = F.dropout(
              out, p=self.dropout_out, training=self.training
          )
  
          # input feeding
          input_feed = out
  
          # save final output
          outs.append(out)
  
      # cache previous states (no-op except during incremental generation)
      utils.set_incremental_state(
          self,
          incremental_state,
          "cached_state",
          (prev_hiddens, prev_cells, input_feed),
      )
  
      # collect outputs across time steps
      x = torch.cat(outs, dim=0).view(seqlen, bsz, self.hidden_size)
  
      # T x B x C -> B x T x C
      x = x.transpose(1, 0)
  
      # srclen x tgtlen x bsz -> bsz x tgtlen x srclen
      attn_scores = attn_scores.transpose(0, 2)
  
      # project back to size of vocabulary
      if hasattr(self, "additional_fc"):
          x = self.additional_fc(x)
          x = F.dropout(x, p=self.dropout_out, training=self.training)
      x = self.fc_out(x)
  
      return x, attn_scores
  
imports: import torch
  import torch.nn
  import torch.nn.functional
  from fairseq import options, utils
  from fairseq.models import FairseqEncoder, FairseqIncrementalDecoder, FairseqEncoderDecoderModel, register_model, register_model_architecture
label_desc: Use image node_id 2 for calling the LSTMDecoder obj's underlying member method code with example usage: obj.forward(prev_output_tokens, encoder_out_dict, incremental_state, lang_id) and returns: x,  attn_scores