class_docstr: RNN with projection layer module.
  
  Args:
      idim: Input dimension.
      rnn_type: RNNP units type.
      elayers: Number of RNNP layers.
      eunits: Number of units ((2 * eunits) if bidirectional).
      eprojs: Number of projection units.
      subsample: Subsampling rate per layer.
      dropout_rate: Dropout rate for RNNP layers.
      aux_output_layers: Layer IDs for auxiliary RNNP output sequences.
class_docstr_tok: ["RNN","with","projection","layer","module",".","Args",":","idim",":","Input","dimension",".","rnn_type",":","RNNP","units","type",".","elayers",":","Number","of","RNNP","layers",".","eunits",":","Number","of","units","(","(","2","*","eunits",")","if","bidirectional",")",".","eprojs",":","Number","of","projection","units",".","subsample",":","Subsampling","rate","per","layer",".","dropout_rate",":","Dropout","rate","for","RNNP","layers",".","aux_output_layers",":","Layer","IDs","for","auxiliary","RNNP","output","sequences","."]
docstr: RNNP forward.
  
  Args:
      rnn_input: RNN input sequences. (B, T, D_in)
      rnn_len: RNN input sequences lengths. (B,)
      prev_states: RNN hidden states. [N x (B, T, D_proj)]
  
  Returns:
      rnn_output : RNN output sequences. (B, T, D_proj)
                   with or without intermediate RNN output sequences.
                   ((B, T, D_proj), [N x (B, T, D_proj)])
      rnn_len: RNN output sequences lengths. (B,)
      current_states: RNN hidden states. [N x (B, T, D_proj)]
docstr_tok: ["RNNP","forward",".","Args",":","rnn_input",":","RNN","input","sequences",".","(","B",",","T",",","D_in",")","rnn_len",":","RNN","input","sequences","lengths",".","(","B",",",")","prev_states",":","RNN","hidden","states",".","[","N","x","(","B",",","T",",","D_proj",")","]","Returns",":","rnn_output",":","RNN","output","sequences",".","(","B",",","T",",","D_proj",")","with","or","without","intermediate","RNN","output","sequences",".","(","(","B",",","T",",","D_proj",")",",","[","N","x","(","B",",","T",",","D_proj",")","]",")","rnn_len",":","RNN","output","sequences","lengths",".","(","B",",",")","current_states",":","RNN","hidden","states",".","[","N","x","(","B",",","T",",","D_proj",")","]"]
code: def forward(
      self,
      rnn_input: torch.Tensor,
      rnn_len: torch.Tensor,
      prev_states: Optional[List[torch.Tensor]] = None,
  ) -> Tuple[torch.Tensor, List[torch.Tensor], torch.Tensor]:
      """RNNP forward.
  
      Args:
          rnn_input: RNN input sequences. (B, T, D_in)
          rnn_len: RNN input sequences lengths. (B,)
          prev_states: RNN hidden states. [N x (B, T, D_proj)]
  
      Returns:
          rnn_output : RNN output sequences. (B, T, D_proj)
                       with or without intermediate RNN output sequences.
                       ((B, T, D_proj), [N x (B, T, D_proj)])
          rnn_len: RNN output sequences lengths. (B,)
          current_states: RNN hidden states. [N x (B, T, D_proj)]
  
      """
      aux_rnn_outputs = []
      aux_rnn_lens = []
      current_states = []
  
      for layer in range(self.elayers):
          if not isinstance(rnn_len, torch.Tensor):
              rnn_len = torch.tensor(rnn_len)
  
          pack_rnn_input = pack_padded_sequence(
              rnn_input, rnn_len.cpu(), batch_first=True
          )
          rnn = getattr(
              self, ("birnn" if self.bidir else "rnn") + str(layer)
          )
  
          if isinstance(rnn, (torch.nn.LSTM, torch.nn.GRU)):
              rnn.flatten_parameters()
  
          if prev_states is not None and rnn.bidirectional:
              prev_states = reset_backward_rnn_state(prev_states)
  
          pack_rnn_output, states = rnn(
              pack_rnn_input,
              hx=None if prev_states is None else prev_states[layer],
          )
          current_states.append(states)
  
          pad_rnn_output, rnn_len = pad_packed_sequence(
              pack_rnn_output, batch_first=True
          )
  
          sub = self.subsample[layer + 1]
          if sub > 1:
              pad_rnn_output = pad_rnn_output[:, ::sub]
              rnn_len = torch.tensor(
                  [int(i + 1) // sub for i in rnn_len]
              )
  
          projection_layer = getattr(self, "bt%d" % layer)
          proj_rnn_output = projection_layer(
              pad_rnn_output.contiguous().view(
                  -1, pad_rnn_output.size(2)
              )
          )
          rnn_output = proj_rnn_output.view(
              pad_rnn_output.size(0), pad_rnn_output.size(1), -1
          )
  
          if layer in self.aux_output_layers:
              aux_rnn_outputs.append(rnn_output)
              aux_rnn_lens.append(rnn_len)
  
          if layer < self.elayers - 1:
              rnn_output = torch.tanh(self.dropout(rnn_output))
  
          rnn_input = rnn_output
  
      if aux_rnn_outputs:
          return (
              (rnn_output, aux_rnn_outputs),
              (rnn_len, aux_rnn_lens),
              current_states,
          )
      else:
          return rnn_output, rnn_len, current_states
  
imports: from argparse import Namespace
  from typing import List, Optional, Tuple, Union
  import numpy
  import torch
  import torch.nn.functional
  from torch.nn.utils.rnn import pack_padded_sequence, pad_packed_sequence
  from espnet.nets.e2e_asr_common import get_vgg2l_odim
  from espnet.nets.pytorch_backend.nets_utils import make_pad_mask, to_device
label_desc: Use image node_id 2 for calling the RNNP obj's underlying member method code with example usage: obj.forward(rnn_input, rnn_len, prev_states) and returns: rnn_output,  aux_rnn_outputs,  rnn_len,  aux_rnn_lens,  current_states, rnn_output,  rnn_len,  current_states