aten/src/ATen/native/LossCTC.cpp
// this wrapper function dispatches to the native and cudnn implementations and hides the alpha/grad from the user (by just returning the loss)
// the gradient is implemented for _cudnn_ctc_loss (just in derivatives.yaml) and _ctc_loss and this function has automatic gradients
// it also handles the reduction if desired
this wrapper function dispatches to the native and cudnn implementations and hides the alpha/grad from the user (by just returning the loss)
the gradient is implemented for _cudnn_ctc_loss (just in derivatives.yaml) and _ctc_loss and this function has automatic gradients
it also handles the reduction if desired
this wrapper function dispatches to the native and cudnn implementations and hides the alpha / grad from the user ( by just returning the loss ) the gradient is implemented for _cudnn_ctc_loss ( just in derivatives . yaml ) and _ctc_loss and this function has automatic gradients it also handles the reduction if desired
Tensor ctc_loss(const Tensor& log_probs, const Tensor& targets, IntList input_lengths, IntList target_lengths, int64_t BLANK, int64_t reduction) {
  auto& ctx = at::globalContext();
  bool use_cudnn =
    detail::getCUDAHooks().compiledWithCuDNN() &&
    (detail::getCUDAHooks().versionCuDNN() >= 7000) &&
    ctx.userEnabledCuDNN() &&
    (BLANK == 0) && (targets.dim()==1) &&
    (log_probs.type().scalarType() == at::kFloat) &&
    (targets.type().scalarType() == at::kInt) &&
    (log_probs.type().backend() == Backend::CUDA);
  if (use_cudnn) {
    int64_t max_input_length = log_probs.size(0);
    for (int64_t b = 0; b < input_lengths.size(); b++) {
      use_cudnn &= (input_lengths[b] == max_input_length);
    }
    for (int64_t b = 0; b < target_lengths.size(); b++) {
      use_cudnn &= (target_lengths[b] <= 256);
    }
  }
  Tensor res;
  if (use_cudnn) {
    res = std::get<0>(at::_cudnn_ctc_loss(log_probs, targets, input_lengths, target_lengths, BLANK, ctx.deterministicCuDNN()));
  } else {
    res = std::get<0>(at::_ctc_loss(log_probs, targets, input_lengths, target_lengths, BLANK));
  }
  if (reduction == Reduction::ElementwiseMean) {
    auto target_lengths_t = at::tensor(target_lengths, res.options().device(at::Device(at::Device::Type::CPU)).dtype(kLong)).toType(res.type());
    return (res / target_lengths_t).mean();
  } else if (reduction == Reduction::Sum) {
    return res.sum();
  }
  return res;
}
Tensor ctc_loss ( const Tensor & log_probs , const Tensor & targets , IntList input_lengths , IntList target_lengths , int64_t BLANK , int64_t reduction ) { auto & ctx = at :: globalContext ( ) ; bool use_cudnn = detail :: getCUDAHooks ( ) . compiledWithCuDNN ( ) && ( detail :: getCUDAHooks ( ) . versionCuDNN ( ) >= 7000 ) && ctx . userEnabledCuDNN ( ) && ( BLANK == 0 ) && ( targets . dim ( ) == 1 ) && ( log_probs . type ( ) . scalarType ( ) == at :: kFloat ) && ( targets . type ( ) . scalarType ( ) == at :: kInt ) && ( log_probs . type ( ) . backend ( ) == Backend :: CUDA ) ; if ( use_cudnn ) { int64_t max_input_length = log_probs . size ( 0 ) ; for ( int64_t b = 0 ; b < input_lengths . size ( ) ; b ++ ) { use_cudnn &= ( input_lengths [ b ] == max_input_length ) ; } for ( int64_t b = 0 ; b < target_lengths . size ( ) ; b ++ ) { use_cudnn &= ( target_lengths [ b ] <= 256 ) ; } } Tensor res ; if ( use_cudnn ) { res = std :: get < 0 > ( at :: _cudnn_ctc_loss ( log_probs , targets , input_lengths , target_lengths , BLANK , ctx . deterministicCuDNN ( ) ) ) ; } else { res = std :: get < 0 > ( at :: _ctc_loss ( log_probs , targets , input_lengths , target_lengths , BLANK ) ) ; } if ( reduction == Reduction :: ElementwiseMean ) { auto target_lengths_t = at :: tensor ( target_lengths , res . options ( ) . device ( at :: Device ( at :: Device :: Type :: CPU ) ) . dtype ( kLong ) ) . toType ( res . type ( ) ) ; return ( res / target_lengths_t ) . mean ( ) ; } else if ( reduction == Reduction :: Sum ) { return res . sum ( ) ; } return res ; }
this wrapper function dispatches to the native and cudnn implementations and hides the alpha/grad from the user (by just returning the loss)
the gradient is implemented for _cudnn_ctc_loss (just in derivatives.yaml) and _ctc_loss and this function has automatic gradients
it also handles the reduction if desired
this wrapper function dispatches to the native and cudnn implementations and hides the alpha / grad from the user ( by just returning the loss ) the gradient is implemented for _cudnn_ctc_loss ( just in derivatives . yaml ) and _ctc_loss and this function has automatic gradients it also handles the reduction if desired
// we don't know that input_lengths and target_lengths have the same size (they should, but we didn't check yet)