  static Status Compute(OpKernelContext* context,
                        const typename TTypes<T, 1>::ConstTensor& values,
                        const typename TTypes<T, 1>::ConstTensor& value_range,
                        int32_t nbins, typename TTypes<Tout, 1>::Tensor& out) {
    const CPUDevice& d = context->eigen_device<CPUDevice>();

    Tensor index_to_bin_tensor;

    TF_RETURN_IF_ERROR(context->forward_input_or_allocate_temp(
        {0}, DataTypeToEnum<int32>::value, TensorShape({values.size()}),
        &index_to_bin_tensor));
    auto index_to_bin = index_to_bin_tensor.flat<int32>();

    const double step = static_cast<double>(value_range(1) - value_range(0)) /
                        static_cast<double>(nbins);
    const double nbins_minus_1 = static_cast<double>(nbins - 1);

    // We cannot handle NANs in the algorithm below (due to the case to int32)
    const Eigen::Tensor<int32, 1, 1> nans_tensor =
        values.isnan().template cast<int32>();
    const Eigen::Tensor<int32, 0, 1> reduced_tensor = nans_tensor.sum();
    const int num_nans = reduced_tensor(0);
    if (num_nans > 0) {
      return errors::InvalidArgument("Histogram values must not contain NaN");
    }

    // The calculation is done by finding the slot of each value in `values`.
    // With [a, b]:
    //   step = (b - a) / nbins
    //   (x - a) / step
    // , then the entries are mapped to output.

    // Bug fix: Switch the order of cwiseMin and int32-casting to avoid
    // producing a negative index when casting an big int64 number to int32
    index_to_bin.device(d) =
        ((values.cwiseMax(value_range(0)) - values.constant(value_range(0)))
             .template cast<double>() /
         step)
            .cwiseMin(nbins_minus_1)
            .template cast<int32>();

    out.setZero();
    for (int32_t i = 0; i < index_to_bin.size(); i++) {
      out(index_to_bin(i)) += Tout(1);
    }
    return Status::OK();
  }
  static Status Compute(OpKernelContext* context,
                        const typename TTypes<T, 1>::ConstTensor& values,
                        const typename TTypes<T, 1>::ConstTensor& value_range,
                        int32_t nbins, typename TTypes<Tout, 1>::Tensor& out) {
    const CPUDevice& d = context->eigen_device<CPUDevice>();

    Tensor index_to_bin_tensor;

    TF_RETURN_IF_ERROR(context->forward_input_or_allocate_temp(
        {0}, DataTypeToEnum<int32>::value, TensorShape({values.size()}),
        &index_to_bin_tensor));
    auto index_to_bin = index_to_bin_tensor.flat<int32>();

    const double step = static_cast<double>(value_range(1) - value_range(0)) /
                        static_cast<double>(nbins);
    const double nbins_minus_1 = static_cast<double>(nbins - 1);

     
    const Eigen::Tensor<int32, 1, 1> nans_tensor =
        values.isnan().template cast<int32>();
    const Eigen::Tensor<int32, 0, 1> reduced_tensor = nans_tensor.sum();
    const int num_nans = reduced_tensor(0);
    if (num_nans > 0) {
      return errors::InvalidArgument("Histogram values must not contain NaN");
    }

     
     
     
     
     

     
     
    index_to_bin.device(d) =
        ((values.cwiseMax(value_range(0)) - values.constant(value_range(0)))
             .template cast<double>() /
         step)
            .cwiseMin(nbins_minus_1)
            .template cast<int32>();

    out.setZero();
    for (int32_t i = 0; i < index_to_bin.size(); i++) {
      out(index_to_bin(i)) += Tout(1);
    }
    return Status::OK();
  }