text: #include <caffe2/ideep/ideep_utils.h>
  
  using namespace caffe2;
  
  namespace {
  
  class IDEEPReluOp final : public IDEEPOperator {
   public:
    USE_IDEEP_DEF_ALIASES();
    USE_IDEEP_OPERATOR_FUNCTIONS();
  
    IDEEPReluOp(const OperatorDef& operator_def, Workspace* ws)
        : IDEEPOperator(operator_def, ws), alpha_(0.0) {
      // Figure out the Relu descriptor.
      if (operator_def.type().substr(0, 4) == "Relu") {
        alpha_ = 0.0;
      // NOLINTNEXTLINE(cppcoreguidelines-avoid-magic-numbers)
      } else if (operator_def.type().substr(0, 9) == "LeakyRelu") {
        if (HasArgument("alpha")) {
          alpha_ = static_cast<float>(
              // NOLINTNEXTLINE(cppcoreguidelines-avoid-magic-numbers)
              OperatorBase::GetSingleArgument<float>("alpha", 0.01));
        }
      } else {
        LOG(FATAL) << "Unsupported Relu method: " << operator_def.type();
      }
    }
    // NOLINTNEXTLINE(modernize-use-equals-default)
    ~IDEEPReluOp() override {}
  
    bool RunOnDevice() override {
      const auto& X = Input(INPUT);
      auto* Y = Output(OUTPUT);
  
      ideep::eltwise_forward::compute(
          X, *Y, ialgo::eltwise_relu, iprop::forward_training, alpha_);
  
      return true;
    }
  
   private:
    float alpha_;
  
    INPUT_TAGS(INPUT);
    OUTPUT_TAGS(OUTPUT);
  };
  
  class IDEEPReluGradientOp final : public IDEEPOperator {
   public:
    USE_IDEEP_DEF_ALIASES();
    USE_IDEEP_OPERATOR_FUNCTIONS();
  
    IDEEPReluGradientOp(const OperatorDef& operator_def, Workspace* ws)
        : IDEEPOperator(operator_def, ws), alpha_(0.0) {
      // Figure out the Relu descriptor.
      // NOLINTNEXTLINE(cppcoreguidelines-avoid-magic-numbers)
      if (operator_def.type().substr(0, 12) == "ReluGradient") {
        alpha_ = 0.0;
      // NOLINTNEXTLINE(cppcoreguidelines-avoid-magic-numbers)
      } else if (operator_def.type().substr(0, 17) == "LeakyReluGradient") {
        if (HasArgument("alpha")) {
          alpha_ = static_cast<float>(
              // NOLINTNEXTLINE(cppcoreguidelines-avoid-magic-numbers)
              OperatorBase::GetSingleArgument<float>("alpha", 0.01));
        }
      } else {
        LOG(FATAL) << "Unsupported Relu method: " << operator_def.type();
      }
    }
    // NOLINTNEXTLINE(modernize-use-equals-default)
    ~IDEEPReluGradientOp() override {}
  
    bool RunOnDevice() override {
      const auto& Y = Input(OUTPUT);
      const auto& dY = Input(OUTPUT_GRAD);
      auto* dX = Output(INPUT_GRAD);
  
      ideep::eltwise_backward::compute(Y, dY, *dX, ialgo::eltwise_relu, alpha_);
  
      return true;
    }
  
   private:
    float alpha_;
  
    INPUT_TAGS(OUTPUT, OUTPUT_GRAD);
    OUTPUT_TAGS(INPUT_GRAD);
  };
  
  // NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
  REGISTER_IDEEP_OPERATOR(Relu, IDEEPReluOp);
  // NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
  REGISTER_IDEEP_OPERATOR(ReluGradient, IDEEPReluGradientOp);
  
  // NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
  REGISTER_IDEEP_OPERATOR(LeakyRelu, IDEEPReluOp);
  // NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
  REGISTER_IDEEP_OPERATOR(LeakyReluGradient, IDEEPReluGradientOp);
  
  } // namespace
  