class_docstr: Zeroes out(cuts) random continuous horisontal or
  vertical segments of the spectrogram as described in
  SpecAugment (https://arxiv.org/abs/1904.08779).
  
  Utilizes a Numba CUDA kernel to perform inplace edit of the input without loops.
  Parallelize over freq and time axis, parallel threads over batch.
  Sequential over masks (adaptive in time).
  
  Args:
      freq_masks - how many frequency segments should be cut
      time_masks - how many time segments should be cut
      freq_width - maximum number of frequencies to be cut in one segment
      time_width - maximum number of time steps to be cut in one segment.
          Can be a positive integer or a float value in the range [0, 1].
          If positive integer value, defines maximum number of time steps
          to be cut in one segment.
          If a float value, defines maximum percentage of timesteps that
          are cut adaptively.
      rng: Ignored.
class_docstr_tok: ["Zeroes","out","(","cuts",")","random","continuous","horisontal","or","vertical","segments","of","the","spectrogram","as","described","in","SpecAugment","(","https",":","\/\/arxiv.org\/abs\/1904.08779",")",".","Utilizes","a","Numba","CUDA","kernel","to","perform","inplace","edit","of","the","input","without","loops",".","Parallelize","over","freq","and","time","axis",",","parallel","threads","over","batch",".","Sequential","over","masks","(","adaptive","in","time",")",".","Args",":","freq_masks","-","how","many","frequency","segments","should","be","cut","time_masks","-","how","many","time","segments","should","be","cut","freq_width","-","maximum","number","of","frequencies","to","be","cut","in","one","segment","time_width","-","maximum","number","of","time","steps","to","be","cut","in","one","segment",".","Can","be","a","positive","integer","or","a","float","value","in","the","range","[","0",",","1","]",".","If","positive","integer","value",",","defines","maximum","number","of","time","steps","to","be","cut","in","one","segment",".","If","a","float","value",",","defines","maximum","percentage","of","timesteps","that","are","cut","adaptively",".","rng",":","Ignored","."]
code: def forward(self, input_spec, length):
      sh = input_spec.shape
      bs = sh[0]
  
      # Construct the freq and time masks as well as start positions
      if self.freq_masks > 0:
          freq_starts = torch.randint(
              0,
              sh[1] - self.freq_width + 1,
              size=[bs, self.freq_masks],
              device=input_spec.device,
          )
          freq_lengths = torch.randint(
              0,
              self.freq_width + 1,
              size=[bs, self.freq_masks],
              device=input_spec.device,
          )
      else:
          freq_starts = torch.zeros(
              [bs, 1], dtype=torch.int64, device=input_spec.device
          )
          freq_lengths = torch.zeros(
              [bs, 1], dtype=torch.int64, device=input_spec.device
          )
  
      if self.time_masks > 0:
          if self.adaptive_temporal_width:
              time_width = (length * self.time_width).int().clamp(min=1)
          else:
              time_width = (
                  torch.tensor(
                      self.time_width,
                      dtype=torch.int32,
                      device=input_spec.device,
                  )
                  .unsqueeze(0)
                  .repeat(sh[0])
              )
  
          time_starts = []
          time_lengths = []
          for idx in range(sh[0]):
              time_starts.append(
                  torch.randint(
                      0,
                      max(1, length[idx] - time_width[idx]),
                      size=[1, self.time_masks],
                      device=input_spec.device,
                  )
              )
              time_lengths.append(
                  torch.randint(
                      0,
                      time_width[idx] + 1,
                      size=[1, self.time_masks],
                      device=input_spec.device,
                  )
              )
  
          time_starts = torch.cat(time_starts, 0)
          time_lengths = torch.cat(time_lengths, 0)
  
      else:
          time_starts = torch.zeros(
              [bs, 1], dtype=torch.int64, device=input_spec.device
          )
          time_lengths = torch.zeros(
              [bs, 1], dtype=torch.int64, device=input_spec.device
          )
  
      x = launch_spec_augment_kernel(
          input_spec,
          length,
          freq_starts=freq_starts,
          freq_lengths=freq_lengths,
          time_starts=time_starts,
          time_lengths=time_lengths,
          freq_masks=self.freq_masks,
          time_masks=self.time_masks,
          mask_value=self.mask_value,
      )
  
      return x
  
file_path: NeMo/nemo/collections/asr/parts/numba/spec_augment/spec_aug_numba.py
imports: import torch
  import torch.nn
  from numba import cuda
  from nemo.core.classes import Typing, typecheck
  from nemo.core.neural_types import LengthsType, NeuralType, SpectrogramType
  from nemo.utils import logging
label_desc: Use image node_id 4 for calling the SpecAugmentNumba obj's underlying member method code with example usage: obj.forward(input_spec, length) and returns: x