docstr: Grouped LSTM forward.
  
  Args:
      x (torch.Tensor): (B, C, T, D)
  Returns:
      out (torch.Tensor): (B, C, T, D)
docstr_tok: ["Grouped","LSTM","forward",".","Args",":","x","(","torch.Tensor",")",":","(","B",",","C",",","T",",","D",")","Returns",":","out","(","torch.Tensor",")",":","(","B",",","C",",","T",",","D",")"]
code: def forward(self, x):
      """Grouped LSTM forward.
  
      Args:
          x (torch.Tensor): (B, C, T, D)
      Returns:
          out (torch.Tensor): (B, C, T, D)
      """
      out = x
      out = out.transpose(1, 2).contiguous()
      B, T = out.size(0), out.size(1)
      out = out.view(B, T, -1).contiguous()
  
      out = torch.chunk(out, self.groups, dim=-1)
      out = torch.stack(
          [self.lstm_list[0][i](out[i])[0] for i in range(self.groups)],
          dim=-1,
      )
      out = torch.flatten(out, start_dim=-2, end_dim=-1)
      out = self.ln[0](out)
  
      for layer in range(1, self.layers):
          if self.rearrange:
              out = (
                  out.reshape(B, T, self.groups, -1)
                  .transpose(-1, -2)
                  .contiguous()
                  .view(B, T, -1)
              )
          out = torch.chunk(out, self.groups, dim=-1)
          out = torch.cat(
              [
                  self.lstm_list[layer][i](out[i])[0]
                  for i in range(self.groups)
              ],
              dim=-1,
          )
          out = self.ln[layer](out)
  
      out = out.view(
          out.size(0), out.size(1), x.size(1), -1
      ).contiguous()
      out = out.transpose(1, 2).contiguous()
  
      return out
  
imports: from typing import List
  import torch
  import torch.nn
  from espnet2.enh.layers.conv_utils import conv2d_output_shape, convtransp2d_output_shape
label_desc: Use image node_id 2 for calling the GLSTM obj's underlying member method code with example usage: obj.forward(x) and returns: out