TfLiteStatus EqualEval(TfLiteContext* context, TfLiteNode* node) {
  const TfLiteTensor* input1;
  TF_LITE_ENSURE_OK(context,
                    GetInputSafe(context, node, kInputTensor1, &input1));
  const TfLiteTensor* input2;
  TF_LITE_ENSURE_OK(context,
                    GetInputSafe(context, node, kInputTensor2, &input2));
  TfLiteTensor* output;
  TF_LITE_ENSURE_OK(context,
                    GetOutputSafe(context, node, kOutputTensor, &output));
  bool requires_broadcast = !HaveSameShapes(input1, input2);
  switch (input1->type) {
    case kTfLiteBool:
      Comparison<bool, reference_ops::EqualFn>(input1, input2, output,
                                               requires_broadcast);
      break;
    case kTfLiteFloat32:
      Comparison<float, reference_ops::EqualFn>(input1, input2, output,
                                                requires_broadcast);
      break;
    case kTfLiteInt32:
      Comparison<int32_t, reference_ops::EqualFn>(input1, input2, output,
                                                  requires_broadcast);
      break;
    case kTfLiteInt64:
      Comparison<int64_t, reference_ops::EqualFn>(input1, input2, output,
                                                  requires_broadcast);
      break;
    case kTfLiteUInt8:
      ComparisonQuantized<uint8_t, reference_ops::EqualFn>(
          input1, input2, output, requires_broadcast);
      break;
    case kTfLiteInt8:
      ComparisonQuantized<int8_t, reference_ops::EqualFn>(
          input1, input2, output, requires_broadcast);
      break;
    case kTfLiteString:
      ComparisonString(reference_ops::StringRefEqualFn, input1, input2, output,
                       requires_broadcast);
      break;
    default:
      context->ReportError(
          context,
          "Does not support type %d, requires bool|float|int|uint8|string",
          input1->type);
      return kTfLiteError;
  }
  return kTfLiteOk;
}
TfLiteStatus EqualEval(TfLiteContext* context, TfLiteNode* node) {
  const TfLiteTensor* input1;
  TF_LITE_ENSURE_OK(context,
                    GetInputSafe(context, node, kInputTensor1, &input1));
  const TfLiteTensor* input2;
  TF_LITE_ENSURE_OK(context,
                    GetInputSafe(context, node, kInputTensor2, &input2));
  TfLiteTensor* output;
  TF_LITE_ENSURE_OK(context,
                    GetOutputSafe(context, node, kOutputTensor, &output));
  bool requires_broadcast = !HaveSameShapes(input1, input2);
  switch (input1->type) {
    case kTfLiteBool:
      Comparison<bool, reference_ops::EqualFn>(input1, input2, output,
                                               requires_broadcast);
      break;
    case kTfLiteFloat32:
      Comparison<float, reference_ops::EqualFn>(input1, input2, output,
                                                requires_broadcast);
      break;
    case kTfLiteInt32:
      Comparison<int32_t, reference_ops::EqualFn>(input1, input2, output,
                                                  requires_broadcast);
      break;
    case kTfLiteInt64:
      Comparison<int64_t, reference_ops::EqualFn>(input1, input2, output,
                                                  requires_broadcast);
      break;
    case kTfLiteUInt8:
      ComparisonQuantized<uint8_t, reference_ops::EqualFn>(
          input1, input2, output, requires_broadcast);
      break;
    case kTfLiteInt8:
      ComparisonQuantized<int8_t, reference_ops::EqualFn>(
          input1, input2, output, requires_broadcast);
      break;
    case kTfLiteString:
      ComparisonString(reference_ops::StringRefEqualFn, input1, input2, output,
                       requires_broadcast);
      break;
    default:
      context->ReportError(
          context,
          "Does not support type %d, requires bool|float|int|uint8|string",
          input1->type);
      return kTfLiteError;
  }
  return kTfLiteOk;
}