class_docstr: Convolutional subsampling which supports VGGNet and striding approach introduced in:
  VGGNet Subsampling: Transformer-transducer: end-to-end speech recognition with self-attention (https://arxiv.org/pdf/1910.12977.pdf)
  Striding Subsampling: "Speech-Transformer: A No-Recurrence Sequence-to-Sequence Model for Speech Recognition" by Linhao Dong et al. (https://ieeexplore.ieee.org/document/8462506)
  Args:
      subsampling (str): The subsampling technique from {"vggnet", "striding", "dw-striding"}
      subsampling_factor (int): The subsampling factor which should be a power of 2
      subsampling_conv_chunking_factor (int): Input chunking factor which can be -1 (no chunking) 
      1 (auto) or a power of 2. Default is 1
      feat_in (int): size of the input features
      feat_out (int): size of the output features
      conv_channels (int): Number of channels for the convolution layers.
      activation (Module): activation function, default is nn.ReLU()
class_docstr_tok: ["Convolutional","subsampling","which","supports","VGGNet","and","striding","approach","introduced","in",":","VGGNet","Subsampling",":","Transformer-transducer",":","end-to-end","speech","recognition","with","self-attention","(","https",":","\/\/arxiv.org\/pdf\/1910.12977.pdf",")","Striding","Subsampling",":","``","Speech-Transformer",":","A","No-Recurrence","Sequence-to-Sequence","Model","for","Speech","Recognition","''","by","Linhao","Dong","et","al",".","(","https",":","\/\/ieeexplore.ieee.org\/document\/8462506",")","Args",":","subsampling","(","str",")",":","The","subsampling","technique","from","{","``","vggnet","''",",","``","striding","''",",","``","dw-striding","''","}","subsampling_factor","(","int",")",":","The","subsampling","factor","which","should","be","a","power","of","2","subsampling_conv_chunking_factor","(","int",")",":","Input","chunking","factor","which","can","be","-1","(","no","chunking",")","1","(","auto",")","or","a","power","of","2",".","Default","is","1","feat_in","(","int",")",":","size","of","the","input","features","feat_out","(","int",")",":","size","of","the","output","features","conv_channels","(","int",")",":","Number","of","channels","for","the","convolution","layers",".","activation","(","Module",")",":","activation","function",",","default","is","nn.ReLU","(",")"]
code: def forward(self, x, lengths):
      lengths = calc_length(
          lengths,
          all_paddings=self._left_padding + self._right_padding,
          kernel_size=self._kernel_size,
          stride=self._stride,
          ceil_mode=self._ceil_mode,
          repeat_num=self._sampling_num,
      )
  
      # Unsqueeze Channel Axis
      if self.conv2d_subsampling:
          x = x.unsqueeze(1)
      # Transpose to Channel First mode
      else:
          x = x.transpose(1, 2)
  
      # split inputs if chunking_factor is set
      if (
          self.subsampling_conv_chunking_factor != -1
          and self.conv2d_subsampling
      ):
          if self.subsampling_conv_chunking_factor == 1:
              # if subsampling_conv_chunking_factor is 1, we split only if needed
              # avoiding a bug / feature limiting indexing of tensors to 2**31
              # see https://github.com/pytorch/pytorch/issues/80020
              x_ceil = (
                  2**31
                  / self._conv_channels
                  * self._stride
                  * self._stride
              )
              if torch.numel(x) > x_ceil:
                  need_to_split = True
              else:
                  need_to_split = False
          else:
              # if subsampling_conv_chunking_factor > 1 we always split
              need_to_split = True
  
          if need_to_split:
              x, success = self.conv_split_by_batch(x)
              if (
                  not success
              ):  # if unable to split by batch, try by channel
                  if self._subsampling == "dw_striding":
                      x = self.conv_split_by_channel(x)
                  else:
                      x = self.conv(x)  # try anyway
          else:
              x = self.conv(x)
      else:
          x = self.conv(x)
  
      # Flatten Channel and Frequency Axes
      if self.conv2d_subsampling:
          b, c, t, f = x.size()
          x = self.out(x.transpose(1, 2).reshape(b, t, -1))
      # Transpose to Channel Last mode
      else:
          x = x.transpose(1, 2)
  
      return x, lengths
  
imports: import math
  import torch
  import torch.nn
  from torch.nn import LayerNorm
  from nemo.collections.asr.parts.submodules.causal_convs import CausalConv1D, CausalConv2D
  from nemo.utils import logging
label_desc: Use image node_id 4 for calling the ConvSubsampling obj's underlying member method code with example usage: obj.forward(x, lengths) and returns: x,  lengths