code: def forward(
      self,
      x: ComplexTensor,
      ilens: Union[torch.LongTensor, numpy.ndarray, List[int]],
  ) -> Tuple[ComplexTensor, torch.LongTensor, Optional[ComplexTensor]]:
      assert len(x) == len(ilens), (len(x), len(ilens))
      # (B, T, F) or (B, T, C, F)
      if x.dim() not in (3, 4):
          raise ValueError(f"Input dim must be 3 or 4: {x.dim()}")
      if not torch.is_tensor(ilens):
          ilens = torch.from_numpy(numpy.asarray(ilens)).to(x.device)
  
      mask = None
      h = x
      if h.dim() == 4:
          if self.training:
              choices = (
                  [(False, False)]
                  if not self.use_frontend_for_all
                  else []
              )
              if self.use_wpe:
                  choices.append((True, False))
  
              if self.use_beamformer:
                  choices.append((False, True))
  
              use_wpe, use_beamformer = choices[
                  numpy.random.randint(len(choices))
              ]
  
          else:
              use_wpe = self.use_wpe
              use_beamformer = self.use_beamformer
  
          # 1. WPE
          if use_wpe:
              # h: (B, T, C, F) -> h: (B, T, C, F)
              h, ilens, mask, power = self.wpe(h, ilens)
  
          # 2. Beamformer
          if use_beamformer:
              # h: (B, T, C, F) -> h: (B, T, F)
              h, ilens, mask = self.beamformer(h, ilens)
  
      return h, ilens, mask
  
file_path: espnet/espnet/nets/pytorch_backend/frontends/frontend.py
imports: from typing import List, Optional, Tuple, Union
  import numpy
  import torch
  import torch.nn
  from torch_complex.tensor import ComplexTensor
  from espnet2.enh.layers.dnn_beamformer import DNN_Beamformer
  from espnet2.enh.layers.dnn_wpe import DNN_WPE
label_desc: Use image node_id 2 for calling the Frontend obj's underlying member method code with example usage: obj.forward(x, ilens) and returns: h,  ilens,  mask