class_docstr: Invertible Convolution with input splitting as in GlowTTS paper.
  https://arxiv.org/pdf/1811.00002.pdf
  
  Args:
      channels (int): input and output channels.
      num_splits (int): number of splits, also H and W of conv layer.
      no_jacobian (bool): enable/disable jacobian computations.
  
  Note:
      Split the input into groups of size self.num_splits and
      perform 1x1 convolution separately. Cast 1x1 conv operation
      to 2d by reshaping the input for efficiency.
class_docstr_tok: ["Invertible","Convolution","with","input","splitting","as","in","GlowTTS","paper",".","https",":","\/\/arxiv.org\/pdf\/1811.00002.pdf","Args",":","channels","(","int",")",":","input","and","output","channels",".","num_splits","(","int",")",":","number","of","splits",",","also","H","and","W","of","conv","layer",".","no_jacobian","(","bool",")",":","enable\/disable","jacobian","computations",".","Note",":","Split","the","input","into","groups","of","size","self.num_splits","and","perform","1x1","convolution","separately",".","Cast","1x1","conv","operation","to","2d","by","reshaping","the","input","for","efficiency","."]
docstr: Shapes:
      x: B x C x T
      x_mask: B x 1 x T
docstr_tok: ["Shapes",":","x",":","B","x","C","x","T","x_mask",":","B","x","1","x","T"]
code: def forward(
      self, x, x_mask=None, reverse=False, **kwargs
  ):  # pylint: disable=unused-argument
      """
      Shapes:
          x: B x C x T
          x_mask: B x 1 x T
      """
  
      b, c, t = x.size()
      assert c % self.num_splits == 0
      if x_mask is None:
          x_mask = 1
          x_len = torch.ones((b,), dtype=x.dtype, device=x.device) * t
      else:
          x_len = torch.sum(x_mask, [1, 2])
  
      x = x.view(b, 2, c // self.num_splits, self.num_splits // 2, t)
      x = (
          x.permute(0, 1, 3, 2, 4)
          .contiguous()
          .view(b, self.num_splits, c // self.num_splits, t)
      )
  
      if reverse:
          if self.weight_inv is not None:
              weight = self.weight_inv
          else:
              weight = torch.inverse(self.weight.float()).to(
                  dtype=self.weight.dtype
              )
          logdet = None
      else:
          weight = self.weight
          if self.no_jacobian:
              logdet = 0
          else:
              logdet = (
                  torch.logdet(self.weight)
                  * (c / self.num_splits)
                  * x_len
              )  # [b]
  
      weight = weight.view(self.num_splits, self.num_splits, 1, 1)
      z = F.conv2d(x, weight)
  
      z = z.view(b, 2, self.num_splits // 2, c // self.num_splits, t)
      z = z.permute(0, 1, 3, 2, 4).contiguous().view(b, c, t) * x_mask
      return z, logdet
  
file_path: TTS/TTS/tts/layers/glow_tts/glow.py
imports: import torch
  from torch import nn
  from torch.nn import functional
  from TTS.tts.layers.generic.wavenet import WN
  from ..generic.normalization import LayerNorm
label_desc: Use image node_id 2 for calling the InvConvNear obj's underlying member method code with example usage: obj.forward(x, x_mask, reverse) and returns: z,  logdet