Caffe2 - C++ API
A deep learning, cross platform ML framework
tanh_op.cc
1 
17 #include <cmath>
18 
19 #include "caffe2/operators/elementwise_op.h"
20 #include "caffe2/utils/math.h"
21 
22 namespace caffe2 {
23 
25  template <typename T>
26  inline void
27  operator()(const int n, const T* x, T* y, CPUContext* /*device_context*/) {
28 #ifdef CAFFE2_USE_ACCELERATE
29  vvtanhf(y, x, &n);
30 #else
31  ConstEigenVectorArrayMap<T> x_arr(x, n);
32  EigenVectorMap<T>(y, n) = 1 - 2 * ((x_arr * 2).exp() + 1).inverse();
33 #endif
34  }
35 };
36 
38  template <typename T>
39  inline void Run(
40  const int n,
41  const T* y,
42  const T* dy,
43  T* dx,
44  CPUContext* /*device_context*/) {
45  ConstEigenVectorArrayMap<T> dy_arr(dy, n);
46  ConstEigenVectorArrayMap<T> y_arr(y, n);
47  EigenVectorMap<T>(dx, n) = dy_arr * (1 - y_arr * y_arr);
48  }
49 };
50 
51 REGISTER_CPU_OPERATOR(
53 REGISTER_CPU_OPERATOR(
54  TanhGradient,
57  CPUContext,
59 
60 OPERATOR_SCHEMA(Tanh)
61  .NumInputs(1)
62  .NumOutputs(1)
63  .AllowInplace({{0, 0}})
64  .IdenticalTypeAndShape()
65  .SetDoc(R"DOC(
66 Calculates the hyperbolic tangent of the given input tensor element-wise. This
67 operation can be done in an in-place fashion too, by providing the same input
68 and output blobs.
69 )DOC")
70  .Input(0, "input", "1-D input tensor")
71  .Output(0, "output", "The hyperbolic tangent values of the input tensor "
72  "computed element-wise");
73 
74 OPERATOR_SCHEMA(TanhGradient).NumInputs(2).NumOutputs(1).AllowInplace({{1, 0}});
75 
77  using GradientMakerBase::GradientMakerBase;
78  vector<OperatorDef> GetGradientDefs() override {
79  return SingleGradientDef(
80  "TanhGradient", "",
81  std::vector<string>{O(0), GO(0)},
82  std::vector<string>{GI(0)});
83  }
84 };
85 REGISTER_GRADIENT(Tanh, GetTanhGradient);
86 } // namespace caffe2
The CPU Context, representing the bare minimum of what a Context class in Caffe2 should implement...
Definition: context.h:82
Copyright (c) 2016-present, Facebook, Inc.
Performs a binary operation (e.g.