class_docstr: RNN module
  
  :param int idim: dimension of inputs
  :param int elayers: number of encoder layers
  :param int cdim: number of rnn units (resulted in cdim * 2 if bidirectional)
  :param int hdim: number of final projection units
  :param float dropout: dropout rate
  :param str typ: The RNN type
docstr: RNN forward
  
  :param torch.Tensor xs_pad: batch of padded input sequences (B, Tmax, D)
  :param torch.Tensor ilens: batch of lengths of input sequences (B)
  :param torch.Tensor prev_state: batch of previous RNN states
  :return: batch of hidden state sequences (B, Tmax, eprojs)
  :rtype: torch.Tensor
docstr_tok: ["RNN","forward",":","param","torch.Tensor","xs_pad",":","batch","of","padded","input","sequences","(","B",",","Tmax",",","D",")",":","param","torch.Tensor","ilens",":","batch","of","lengths","of","input","sequences","(","B",")",":","param","torch.Tensor","prev_state",":","batch","of","previous","RNN","states",":","return",":","batch","of","hidden","state","sequences","(","B",",","Tmax",",","eprojs",")",":","rtype",":","torch.Tensor"]
code: def forward(self, xs_pad, ilens, prev_state=None):
      """RNN forward
  
      :param torch.Tensor xs_pad: batch of padded input sequences (B, Tmax, D)
      :param torch.Tensor ilens: batch of lengths of input sequences (B)
      :param torch.Tensor prev_state: batch of previous RNN states
      :return: batch of hidden state sequences (B, Tmax, eprojs)
      :rtype: torch.Tensor
      """
      logging.debug(
          self.__class__.__name__ + " input lengths: " + str(ilens)
      )
      if not isinstance(ilens, torch.Tensor):
          ilens = torch.tensor(ilens)
      xs_pack = pack_padded_sequence(
          xs_pad, ilens.cpu(), batch_first=True
      )
      if self.training:
          self.nbrnn.flatten_parameters()
      if prev_state is not None and self.nbrnn.bidirectional:
          # We assume that when previous state is passed,
          # it means that we're streaming the input
          # and therefore cannot propagate backward BRNN state
          # (otherwise it goes in the wrong direction)
          prev_state = reset_backward_rnn_state(prev_state)
      ys, states = self.nbrnn(xs_pack, hx=prev_state)
      # ys: utt list of frame x cdim x 2 (2: means bidirectional)
      ys_pad, ilens = pad_packed_sequence(ys, batch_first=True)
      # (sum _utt frame_utt) x dim
      projected = torch.tanh(
          self.l_last(ys_pad.contiguous().view(-1, ys_pad.size(2)))
      )
      xs_pad = projected.view(ys_pad.size(0), ys_pad.size(1), -1)
      return xs_pad, ilens, states
  
imports: import logging
  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 RNN obj's underlying member method code with example usage: obj.forward(xs_pad, ilens, prev_state) and returns: xs_pad,  ilens,  states