docstr: Run forward
  
  Parameters
  ----------
  data
      - layout = 'NT'
          Shape (batch_size, seq_length, C_in)
      - layout = 'TN'
          Shape (seq_length, batch_size, C_in)
  valid_length
      Shape (batch_size,)
  mem_data
      - layout = 'NT'
          Shape (batch_size, mem_length, C_mem)
      - layout = 'TN'
          Shape (mem_length, batch_size, C_mem)
  mem_valid_length
      Shape (batch_size,)
  
  Returns
  -------
  out
      - layout = 'NT'
          Shape (batch_size, seq_length, C_out)
      - layout = 'TN'
          Shape (seq_length, batch_size, C_out)
docstr_tok: ["Run","forward","Parameters","--","--","--","--","--","data","-","layout","=","'NT'","Shape","(","batch_size",",","seq_length",",","C_in",")","-","layout","=","'TN'","Shape","(","seq_length",",","batch_size",",","C_in",")","valid_length","Shape","(","batch_size",",",")","mem_data","-","layout","=","'NT'","Shape","(","batch_size",",","mem_length",",","C_mem",")","-","layout","=","'TN'","Shape","(","mem_length",",","batch_size",",","C_mem",")","mem_valid_length","Shape","(","batch_size",",",")","Returns","--","--","--","-","out","-","layout","=","'NT'","Shape","(","batch_size",",","seq_length",",","C_out",")","-","layout","=","'TN'","Shape","(","seq_length",",","batch_size",",","C_out",")"]
code: def forward(self, data, valid_length, mem_data, mem_valid_length):
      """Run forward
  
      Parameters
      ----------
      data
          - layout = 'NT'
              Shape (batch_size, seq_length, C_in)
          - layout = 'TN'
              Shape (seq_length, batch_size, C_in)
      valid_length
          Shape (batch_size,)
      mem_data
          - layout = 'NT'
              Shape (batch_size, mem_length, C_mem)
          - layout = 'TN'
              Shape (mem_length, batch_size, C_mem)
      mem_valid_length
          Shape (batch_size,)
  
      Returns
      -------
      out
          - layout = 'NT'
              Shape (batch_size, seq_length, C_out)
          - layout = 'TN'
              Shape (seq_length, batch_size, C_out)
      """
      # 1. Embed the data
      out = self.dropout_layer(data)
      if self._data_norm:
          out = self.ln_data(out)
      self_causal_mask = gen_self_attn_mask(
          data, valid_length, attn_type="causal", layout=self._layout
      )
      mem_attn_mask = gen_mem_attn_mask(
          mem_data,
          mem_valid_length,
          data,
          valid_length,
          layout=self._layout,
      )
      for i in range(self.num_layers):
          if self.recurrent:
              layer = self.layers[0]
          else:
              layer = self.layers[i]
          out = layer(out, mem_data, self_causal_mask, mem_attn_mask)
      if self._pre_norm:
          out = self.ln_final(out)
      return out
  
imports: from typing import Union, Optional, List
  from torch import nn
  import torch
  from ..layers import PositionwiseFFN
  from ..attention_cell import MultiHeadAttentionCell, gen_mem_attn_mask, gen_self_attn_mask
  from ..utils import to_torch_dtype
label_desc: Use image node_id 4 for calling the TransformerDecoder obj's underlying member method code with example usage: obj.forward(data, valid_length, mem_data, mem_valid_length) and returns: out