class_docstr: GTN CTC module.
docstr: Forward computation.
  
  :param torch.tensor log_probs: batched log softmax probabilities (B, Tmax, oDim)
  :param list targets: batched target sequences, list of lists
  :param int blank_idx: index of blank token
  :return: ctc loss value
  :rtype: torch.Tensor
docstr_tok: ["Forward","computation",".",":","param","torch.tensor","log_probs",":","batched","log","softmax","probabilities","(","B",",","Tmax",",","oDim",")",":","param","list","targets",":","batched","target","sequences",",","list","of","lists",":","param","int","blank_idx",":","index","of","blank","token",":","return",":","ctc","loss","value",":","rtype",":","torch.Tensor"]
code: def forward(
      ctx, log_probs, targets, ilens, blank_idx=0, reduction="none"
  ):
      """Forward computation.
  
      :param torch.tensor log_probs: batched log softmax probabilities (B, Tmax, oDim)
      :param list targets: batched target sequences, list of lists
      :param int blank_idx: index of blank token
      :return: ctc loss value
      :rtype: torch.Tensor
      """
      B, _, C = log_probs.shape
      losses = [None] * B
      scales = [None] * B
      emissions_graphs = [None] * B
  
      def process(b):
          # create emission graph
          T = ilens[b]
          g_emissions = gtn.linear_graph(T, C, log_probs.requires_grad)
          cpu_data = log_probs[b][:T].cpu().contiguous()
          g_emissions.set_weights(cpu_data.data_ptr())
  
          # create criterion graph
          g_criterion = GTNCTCLossFunction.create_ctc_graph(
              targets[b], blank_idx
          )
          # compose the graphs
          g_loss = gtn.negate(
              gtn.forward_score(gtn.intersect(g_emissions, g_criterion))
          )
  
          scale = 1.0
          if reduction == "mean":
              L = len(targets[b])
              scale = 1.0 / L if L > 0 else scale
          elif reduction != "none":
              raise ValueError(
                  "invalid value for reduction '" + str(reduction) + "'"
              )
  
          # Save for backward:
          losses[b] = g_loss
          scales[b] = scale
          emissions_graphs[b] = g_emissions
  
      gtn.parallel_for(process, range(B))
  
      ctx.auxiliary_data = (
          losses,
          scales,
          emissions_graphs,
          log_probs.shape,
          ilens,
      )
      loss = torch.tensor(
          [losses[b].item() * scales[b] for b in range(B)]
      )
      return torch.mean(loss.cuda() if log_probs.is_cuda else loss)
  
imports: import gtn
  import torch
label_desc: Use image node_id 2 for calling the GTNCTCLossFunction obj's underlying member method code with example usage: obj.forward(ctx, log_probs, targets, ilens, blank_idx, reduction) and returns: torch