class_docstr: This class calculates Viterbi alignments in the forward method.
  
  It also records alignments and creates batches of them for use
  in Viterbi training.
  
  Arguments
  ---------
  states_per_phoneme : int
      Number of hidden states to use per phoneme.
  output_folder : str
      It is the folder that the alignments will be stored in when
      saved to disk. Not yet implemented.
  neg_inf : float
      The float used to represent a negative infinite log probability.
      Using `-float("Inf")` tends to give numerical instability.
      A number more negative than -1e5 also sometimes gave errors when
      the `genbmm` library was used (currently not in use). (default: -1e5)
  batch_reduction : string
      One of "none", "sum" or "mean".
      What kind of batch-level reduction to apply to the loss calculated
      in the forward method.
  input_len_norm : bool
      Whether to normalize the loss in the forward method by the length of
      the inputs.
  target_len_norm : bool
      Whether to normalize the loss in the forward method by the length of
      the targets.
  lexicon_path : string
      The location of the lexicon.
  
  Example
  -------
  >>> log_posteriors = torch.tensor([[[ -1., -10., -10.],
  ...                                 [-10.,  -1., -10.],
  ...                                 [-10., -10.,  -1.]],
  ...
  ...                                [[ -1., -10., -10.],
  ...                                 [-10.,  -1., -10.],
  ...                                 [-10., -10., -10.]]])
  >>> lens = torch.tensor([1., 0.66])
  >>> phns = torch.tensor([[0, 1, 2],
  ...                      [0, 1, 0]])
  >>> phn_lens = torch.tensor([1., 0.66])
  >>> aligner = HMMAligner()
  >>> forward_scores = aligner(
  ...        log_posteriors, lens, phns, phn_lens, 'forward'
  ... )
  >>> forward_scores.shape
  torch.Size([2])
  >>> viterbi_scores, alignments = aligner(
  ...        log_posteriors, lens, phns, phn_lens, 'viterbi'
  ... )
  >>> alignments
  [[0, 1, 2], [0, 1]]
  >>> viterbi_scores.shape
  torch.Size([2])
docstr: Calculates Viterbi alignment using dynamic programming.
  
  Arguments
  ---------
  pi_prob : torch.Tensor (batch, phn)
      Tensor containing initial (log) probabilities.
  trans_prob : torch.Tensor (batch, from, to)
      Tensor containing transition (log) probabilities.
  emiss_pred_useful : torch.Tensor (batch, phoneme in phn sequence, time)
      A 'useful' form of the posterior probabilities, rearranged
      into the order of phoneme appearance in phns.
  lens_abs : torch.Tensor (batch)
      The absolute length of each input to the acoustic model,
      i.e., the number of frames.
  phn_lens_abs : torch.Tensor (batch)
      The absolute length of each phoneme sequence in the batch.
  phns : torch.Tensor (batch, phoneme in phn sequence)
      The phonemes that are known/thought to be in each utterance.
  
  Returns
  -------
  z_stars : list of lists of int
      Viterbi alignments for the files in the batch.
  z_stars_loc : list of lists of int
      The locations of the Viterbi alignments for the files in the batch.
      e.g., for a batch with a single utterance with 5 phonemes,
      `z_stars_loc` will look like:
      [[0, 0, 0, 1, 1, 2, 3, 3, 3, 4, 4]].
  viterbi_scores : torch.Tensor (batch)
      The (log) likelihood of the Viterbi path for each utterance.
docstr_tok: ["Calculates","Viterbi","alignment","using","dynamic","programming",".","Arguments","--","--","--","--","-","pi_prob",":","torch.Tensor","(","batch",",","phn",")","Tensor","containing","initial","(","log",")","probabilities",".","trans_prob",":","torch.Tensor","(","batch",",","from",",","to",")","Tensor","containing","transition","(","log",")","probabilities",".","emiss_pred_useful",":","torch.Tensor","(","batch",",","phoneme","in","phn","sequence",",","time",")","A","'useful","'","form","of","the","posterior","probabilities",",","rearranged","into","the","order","of","phoneme","appearance","in","phns",".","lens_abs",":","torch.Tensor","(","batch",")","The","absolute","length","of","each","input","to","the","acoustic","model",",","i.e.",",","the","number","of","frames",".","phn_lens_abs",":","torch.Tensor","(","batch",")","The","absolute","length","of","each","phoneme","sequence","in","the","batch",".","phns",":","torch.Tensor","(","batch",",","phoneme","in","phn","sequence",")","The","phonemes","that","are","known\/thought","to","be","in","each","utterance",".","Returns","--","--","--","-","z_stars",":","list","of","lists","of","int","Viterbi","alignments","for","the","files","in","the","batch",".","z_stars_loc",":","list","of","lists","of","int","The","locations","of","the","Viterbi","alignments","for","the","files","in","the","batch",".","e.g.",",","for","a","batch","with","a","single","utterance","with","5","phonemes",",","`","z_stars_loc","`","will","look","like",":","[","[","0",",","0",",","0",",","1",",","1",",","2",",","3",",","3",",","3",",","4",",","4","]","]",".","viterbi_scores",":","torch.Tensor","(","batch",")","The","(","log",")","likelihood","of","the","Viterbi","path","for","each","utterance","."]
code: def _dp_viterbi(
      self,
      pi_prob,
      trans_prob,
      emiss_pred_useful,
      lens_abs,
      phn_lens_abs,
      phns,
      final_states,
  ):
      """Calculates Viterbi alignment using dynamic programming.
  
      Arguments
      ---------
      pi_prob : torch.Tensor (batch, phn)
          Tensor containing initial (log) probabilities.
      trans_prob : torch.Tensor (batch, from, to)
          Tensor containing transition (log) probabilities.
      emiss_pred_useful : torch.Tensor (batch, phoneme in phn sequence, time)
          A 'useful' form of the posterior probabilities, rearranged
          into the order of phoneme appearance in phns.
      lens_abs : torch.Tensor (batch)
          The absolute length of each input to the acoustic model,
          i.e., the number of frames.
      phn_lens_abs : torch.Tensor (batch)
          The absolute length of each phoneme sequence in the batch.
      phns : torch.Tensor (batch, phoneme in phn sequence)
          The phonemes that are known/thought to be in each utterance.
  
      Returns
      -------
      z_stars : list of lists of int
          Viterbi alignments for the files in the batch.
      z_stars_loc : list of lists of int
          The locations of the Viterbi alignments for the files in the batch.
          e.g., for a batch with a single utterance with 5 phonemes,
          `z_stars_loc` will look like:
          [[0, 0, 0, 1, 1, 2, 3, 3, 3, 4, 4]].
      viterbi_scores : torch.Tensor (batch)
          The (log) likelihood of the Viterbi path for each utterance.
      """
  
      # useful values
      batch_size = len(phn_lens_abs)
      U_max = phn_lens_abs.max()
      fb_max_length = lens_abs.max()
      device = emiss_pred_useful.device
  
      pi_prob = pi_prob.to(device)
      trans_prob = trans_prob.to(device)
  
      v_matrix = self.neg_inf * torch.ones(
          [batch_size, U_max, fb_max_length], device=device
      )
      backpointers = -99 * torch.ones(
          [batch_size, U_max, fb_max_length], device=device
      )
  
      # initialise
      v_matrix[:, :, 0] = pi_prob + emiss_pred_useful[:, :, 0]
  
      for t in range(1, fb_max_length):
          x, argmax = batch_log_maxvecmul(
              trans_prob.permute(0, 2, 1), v_matrix[:, :, t - 1]
          )
          v_matrix[:, :, t] = x + emiss_pred_useful[:, :, t]
  
          backpointers[:, :, t] = argmax.type(torch.FloatTensor)
  
      z_stars = []
      z_stars_loc = []
  
      for utterance_in_batch in range(batch_size):
          len_abs = lens_abs[utterance_in_batch]
  
          if final_states is not None:
              final_states_utter = final_states[utterance_in_batch]
              # Pick most probable of the final states
              viterbi_finals = v_matrix[
                  utterance_in_batch, final_states_utter, len_abs - 1
              ]
              final_state_chosen = torch.argmax(viterbi_finals).item()
              U = final_states_utter[final_state_chosen]
          else:
              U = phn_lens_abs[utterance_in_batch].long().item() - 1
  
          z_star_i_loc = [U]
          z_star_i = [phns[utterance_in_batch, z_star_i_loc[0]].item()]
          for time_step in range(len_abs, 1, -1):
              current_best_loc = z_star_i_loc[0]
  
              earlier_best_loc = (
                  backpointers[
                      utterance_in_batch,
                      current_best_loc,
                      time_step - 1,
                  ]
                  .long()
                  .item()
              )
              earlier_z_star = phns[
                  utterance_in_batch, earlier_best_loc
              ].item()
  
              z_star_i_loc.insert(0, earlier_best_loc)
              z_star_i.insert(0, earlier_z_star)
          z_stars.append(z_star_i)
          z_stars_loc.append(z_star_i_loc)
  
      # picking out viterbi_scores
      viterbi_scores = v_matrix[
          torch.arange(batch_size), phn_lens_abs - 1, lens_abs - 1
      ]
  
      return z_stars, z_stars_loc, viterbi_scores
  
imports: import torch
  import random
  from speechbrain.utils.checkpoints import register_checkpoint_hooks
  from speechbrain.utils.checkpoints import mark_as_saver
  from speechbrain.utils.checkpoints import mark_as_loader
  from speechbrain.utils.data_utils import undo_padding
label_desc: Use image node_id 8 for calling the HMMAligner obj's underlying member method code with example usage: obj._dp_viterbi(pi_prob, trans_prob, emiss_pred_useful, lens_abs, phn_lens_abs, phns, final_states) and returns: z_stars,  z_stars_loc,  viterbi_scores