class_docstr: RNN with projection layer 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 projection units
  :param np.ndarray subsample: list of subsampling numbers
  :param float dropout: dropout rate
  :param str typ: The RNN type
code: def __init__(
      self, idim, elayers, cdim, hdim, subsample, dropout, typ="blstm"
  ):
      super(RNNP, self).__init__()
      bidir = typ[0] == "b"
      for i in range(elayers):
          if i == 0:
              inputdim = idim
          else:
              inputdim = hdim
  
          RNN = torch.nn.LSTM if "lstm" in typ else torch.nn.GRU
          rnn = RNN(
              inputdim,
              cdim,
              num_layers=1,
              bidirectional=bidir,
              batch_first=True,
          )
  
          setattr(self, "%s%d" % ("birnn" if bidir else "rnn", i), rnn)
  
          # bottleneck layer to merge
          if bidir:
              setattr(self, "bt%d" % i, torch.nn.Linear(2 * cdim, hdim))
          else:
              setattr(self, "bt%d" % i, torch.nn.Linear(cdim, hdim))
  
      self.elayers = elayers
      self.cdim = cdim
      self.subsample = subsample
      self.typ = typ
      self.bidir = bidir
      self.dropout = dropout
  
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 1 to create a new RNNP object from inherited base classes: torch.nn with example: obj = RNNP(idim, elayers, cdim, hdim, subsample, dropout, typ)