Caffe2 - C++ API
A deep learning, cross platform ML framework
relu_n_op.cc
1 #include "caffe2/operators/relu_n_op.h"
2 
3 #include <algorithm>
4 #include <functional>
5 #include <string>
6 
7 #include "caffe2/utils/eigen_utils.h"
8 
9 namespace caffe2 {
10 
11 template <>
12 template <typename T>
13 bool ReluNFunctor<CPUContext>::
14 operator()(const int N, const T* X, T* Y, CPUContext* /* context */) const {
15  EigenVectorMap<T>(Y, N) =
16  ConstEigenVectorMap<T>(X, N).cwiseMax(T(0)).cwiseMin(T(n));
17  return true;
18 }
19 
20 template <>
21 template <typename T>
22 bool ReluNGradientFunctor<CPUContext>::Forward(
23  const std::vector<int>& Y_dims,
24  const std::vector<int>& /* dY_dims */,
25  const T* Y,
26  const T* dY,
27  T* dX,
28  CPUContext* /* context */) const {
29  const int size = std::accumulate(
30  Y_dims.cbegin(), Y_dims.cend(), 1, std::multiplies<int>());
31  ConstEigenVectorArrayMap<T> Y_arr(Y, size);
32  EigenVectorArrayMap<T>(dX, size) =
33  (Y_arr > T(0) && Y_arr < T(n))
34  .select(ConstEigenVectorArrayMap<T>(dY, size), T(0));
35  return true;
36 }
37 
38 namespace {
39 
40 OpSchema::Cost CostInferenceForReluN(
41  const OperatorDef& def,
42  const vector<TensorShape>& in) {
43  struct OpSchema::Cost cost = PointwiseCostInference<2>(def, in);
44  cost.params_bytes = 0;
45  return cost;
46 }
47 
48 } // namespace
49 
50 REGISTER_CPU_OPERATOR(
51  ReluN,
52  UnaryElementwiseWithArgsOp<
53  TensorTypes<float>,
54  CPUContext,
55  ReluNFunctor<CPUContext>>);
56 REGISTER_CPU_OPERATOR(
57  ReluNGradient,
58  BinaryElementwiseWithArgsOp<
59  TensorTypes<float>,
60  CPUContext,
61  ReluNGradientFunctor<CPUContext>>);
62 
63 // Input: X, output: Y
64 OPERATOR_SCHEMA(ReluN)
65  .NumInputs(1)
66  .NumOutputs(1)
67  .Arg("n", "the cap of output")
68  .AllowInplace({{0, 0}})
69  .CostInferenceFunction(CostInferenceForReluN)
70  .IdenticalTypeAndShape()
71  .SetDoc(R"DOC(
72 Relu takes one input data (Tensor) and produces one output data
73 (Tensor) where the rectified linear function, y = min(max(0, x), n),
74 is applied to the tensor elementwise.
75 )DOC")
76  .Input(0, "X", "1D input tensor")
77  .Output(0, "Y", "1D input tensor");
78 
79 // Input: Y, dY, output: dX
80 OPERATOR_SCHEMA(ReluNGradient)
81  .NumInputs(2)
82  .NumOutputs(1)
83  .Arg("n", "the cap of forward op output")
84  .AllowInplace({{1, 0}})
85  .SetDoc(R"DOC(
86 ReluGradient takes both Y and dY and uses this to update dX according to the
87 chain rule and derivatives of the rectified linear function.
88 )DOC");
89 
90 namespace {
91 
92 class GetReluNGradient : public GradientMakerBase {
93  using GradientMakerBase::GradientMakerBase;
94  std::vector<OperatorDef> GetGradientDefs() override {
95  return SingleGradientDef(
96  def_.type() + "Gradient",
97  "",
98  std::vector<std::string>{O(0), GO(0)},
99  std::vector<std::string>{GI(0)});
100  }
101 };
102 
103 } // namespace
104 
105 REGISTER_GRADIENT(ReluN, GetReluNGradient);
106 
107 } // namespace caffe2
A global dictionary that holds information about what Caffe2 modules have been loaded in the current ...
Definition: blob.h:13