class_docstr: Initialize the Lightseq Transformer Decoder Layer.
  
  Static variable:
      layer_id: The layer-index counter starting from 0 and incrementing by 1 every time a layer object is instantiated,
      e.g. if a model has 24 transformer layers, layer_id goes from 0 to 23.
  Arguments:
      config: An object of LSTransformerDecoderLayer config, see get_config
  
      initial_weights: Optional: Only used for unit test
  
      initial_biases: Optional: Only used for unit test
docstr: decoder_states, [batch_size, trg_len, hidden_size] or [batch_size * beam_size, 1, hidden_size]
  encoder_out, [src_len, batch_size, hidden_size]
  encoder_padding_mask, [batch_size, src_len], 0 for non-pad, 1 for padding
  cache, dict, {"dec_self_k": [batch*beam, nh, step, hd],
                "dec_self_v": [batch*beam, nh, step, hd],
                "encdec_kv": [n_dec_layer * 2, batch_size, nhead, src_seq_len, head_dim]
                }
docstr_tok: ["decoder_states",",","[","batch_size",",","trg_len",",","hidden_size","]","or","[","batch_size","*","beam_size",",","1",",","hidden_size","]","encoder_out",",","[","src_len",",","batch_size",",","hidden_size","]","encoder_padding_mask",",","[","batch_size",",","src_len","]",",","0","for","non-pad",",","1","for","padding","cache",",","dict",",","{","``","dec_self_k","''",":","[","batch","*","beam",",","nh",",","step",",","hd","]",",","``","dec_self_v","''",":","[","batch","*","beam",",","nh",",","step",",","hd","]",",","``","encdec_kv","''",":","[","n_dec_layer","*","2",",","batch_size",",","nhead",",","src_seq_len",",","head_dim","]","}"]
code: def forward(
      self,
      decoder_states,
      encoder_out,
      encoder_padding_mask,
      cache=None,
      **kwargs,
  ):
      """
      decoder_states, [batch_size, trg_len, hidden_size] or [batch_size * beam_size, 1, hidden_size]
      encoder_out, [src_len, batch_size, hidden_size]
      encoder_padding_mask, [batch_size, src_len], 0 for non-pad, 1 for padding
      cache, dict, {"dec_self_k": [batch*beam, nh, step, hd],
                    "dec_self_v": [batch*beam, nh, step, hd],
                    "encdec_kv": [n_dec_layer * 2, batch_size, nhead, src_seq_len, head_dim]
                    }
      """
      self.config.training = self.training
      self.config.is_grad_enabled = torch.is_grad_enabled()
      self.config.quant_mode = self.quant_mode
  
      decoder_states = decoder_states.contiguous()
      # [s, b, h] -> [b, s, h]
      encoder_out = encoder_out.transpose(0, 1).contiguous()
      encoder_padding_mask = (
          (encoder_padding_mask * -1e8)
          .type_as(decoder_states)
          .contiguous()
      )
  
      if self.config.fp16 and self.para.dtype != torch.half:
          if hasattr(self, "para_16"):
              self.para_16.copy_(self.para.to(torch.half))
          else:
              self.register_buffer(
                  "para_16", self.para.clone().detach().half()
              )
  
      if self.config.fp16:
          decoder_states = decoder_states.to(torch.half)
          encoder_out = encoder_out.to(torch.half)
          encoder_padding_mask = encoder_padding_mask.to(torch.half)
  
      self.__assign_layer_weight_grad()
      cache_list = []
      if cache is not None:
          # predict
          batch_beams = decoder_states.shape[0]
          if cache:
              # non-empty dict, step 1-n
              step = cache["dec_self_k"].shape[2]
              # Thanks to fengjiangtao@bytedance.com
              # for helping us find this bug.
              cache_list = [
                  cache["dec_self_k"].contiguous(),
                  cache["dec_self_v"].contiguous(),
              ]
          else:
              # empty dict, step 0
              step = 0
          if self.config.layer_id == 0:
              if step == 0:
                  shape = (
                      self.config.nlayer * 2,
                      encoder_out.shape[0],
                      encoder_out.shape[1] * self.config.hidden_size,
                  )
                  encdec_kv = torch.zeros(
                      shape,
                      dtype=decoder_states.dtype,
                      device=decoder_states.device,
                  ).contiguous()
                  cache["encdec_kv"] = encdec_kv
              cache_list.append(cache["encdec_kv"])
          head_dim = int(self.config.hidden_size / self.config.nhead)
          shape = (batch_beams, self.config.nhead, step + 1, head_dim)
          new_k = torch.zeros(
              shape,
              dtype=decoder_states.dtype,
              device=decoder_states.device,
          ).contiguous()
          new_v = torch.zeros(
              shape,
              dtype=decoder_states.dtype,
              device=decoder_states.device,
          ).contiguous()
          cache_list = [new_k, new_v] + cache_list
          cache["dec_self_k"] = new_k
          cache["dec_self_v"] = new_v
          self.config.training = False
      bs, sl, dim = decoder_states.size()
      if bs * sl > self.config.max_batch_tokens:
          raise ValueError(
              f"Batch token numbers {bs * sl} exceeds the limit"
              f" {self.config.max_batch_tokens}."
          )
      if sl > self.config.max_seq_len:
          raise ValueError(
              f"Sequence length {sl} exceeds the limit {self.config.max_seq_len}."
          )
      if len(encoder_padding_mask.size()) == 1:
          assert encoder_out.size(0) == 1 and encoder_out.size(
              1
          ) == encoder_padding_mask.size(0)
      else:
          assert encoder_out.size(0) == encoder_padding_mask.size(
              0
          ) and encoder_out.size(1) == encoder_padding_mask.size(1)
      if cache is None:
          assert bs == encoder_out.size(0)
      else:
          assert bs % encoder_out.size(0) == 0
      output = LSTransformerDecoderFunc.apply(
          decoder_states,
          encoder_out,
          encoder_padding_mask,
          self.para,
          self.config,
          cache_list,
      )
      return output.to(self.para)
  
imports: from itertools import zip_longest
  import math
  from dataclasses import dataclass
  import copy
  import torch
  from torch import nn
  from torch.autograd import Function
  from lightseq.training.ops.pytorch import TransformerBuilder
  from lightseq.training.ops.pytorch.builder import TransformerBuilder
  from lightseq.training.ops.pytorch.util import copy_para, state_dict, MODEL_ARCH, check_config, calc_offset
  from lightseq.training.ops.pytorch.quantization import weight_quant_config, act_quant_config, relu_quant_config
  from lightseq.training.ops.pytorch.layer_base import TransformerDecoderLayerBase
label_desc: Use image node_id 9 for calling the LSTransformerDecoderLayer obj's underlying member method code with example usage: obj.forward(decoder_states, encoder_out, encoder_padding_mask, cache) and returns: output