Caffe2 - C++ API
A deep learning, cross platform ML framework
elementwise_ops.cc
1 #include "caffe2/operators/elementwise_ops.h"
2 #include "caffe2/utils/eigen_utils.h"
3 
4 #include <algorithm>
5 
6 namespace caffe2 {
7 
8 REGISTER_CPU_OPERATOR(
9  Not,
10  UnaryElementwiseOp<BoolTypes, CPUContext, NotFunctor<CPUContext>>);
11 REGISTER_CPU_OPERATOR(
12  Sign,
13  UnaryElementwiseOp<NumericTypes, CPUContext, SignFunctor<CPUContext>>);
14 
15 #define REGISTER_CPU_COMPARE_OPERATOR(Op) \
16  REGISTER_CPU_OPERATOR( \
17  Op, \
18  BinaryElementwiseOp< \
19  TensorTypes<bool, int32_t, int64_t, float, double>, \
20  CPUContext, \
21  Op##Functor<CPUContext>, \
22  FixedType<bool>>)
23 
24 REGISTER_CPU_COMPARE_OPERATOR(EQ);
25 REGISTER_CPU_COMPARE_OPERATOR(NE);
26 REGISTER_CPU_COMPARE_OPERATOR(LT);
27 REGISTER_CPU_COMPARE_OPERATOR(LE);
28 REGISTER_CPU_COMPARE_OPERATOR(GT);
29 REGISTER_CPU_COMPARE_OPERATOR(GE);
30 
31 #undef REGISTER_CPU_COMPARE_OPERATOR
32 
33 #define REGISTER_CPU_LOGICAL_BINARY_OPERATOR(Op) \
34  REGISTER_CPU_OPERATOR( \
35  Op, BinaryElementwiseOp<BoolTypes, CPUContext, Op##Functor<CPUContext>>)
36 
37 REGISTER_CPU_LOGICAL_BINARY_OPERATOR(And);
38 REGISTER_CPU_LOGICAL_BINARY_OPERATOR(Or);
39 REGISTER_CPU_LOGICAL_BINARY_OPERATOR(Xor);
40 
41 #undef REGISTER_CPU_LOGICAL_BINARY_OPERATOR
42 
43 #define REGISTER_CPU_BITWISE_BINARY_OPERATOR(Op) \
44  REGISTER_CPU_OPERATOR( \
45  Op, \
46  BinaryElementwiseOp<IntBoolTypes, CPUContext, Op##Functor<CPUContext>>)
47 
48 REGISTER_CPU_BITWISE_BINARY_OPERATOR(BitwiseAnd);
49 REGISTER_CPU_BITWISE_BINARY_OPERATOR(BitwiseOr);
50 REGISTER_CPU_BITWISE_BINARY_OPERATOR(BitwiseXor);
51 
52 #undef REGISTER_CPU_BITWISE_BINARY_OPERATOR
53 
54 template <typename T>
55 void SRLHelper::sum2one(const T* x, T* y, size_t n) {
56  *y = ConstEigenArrayMap<T>(x, n, 1).sum();
57 }
58 
59 template <typename T>
60 void SRLHelper::RunWithBroadcastFront(
61  const T* x,
62  T* y,
63  size_t pre,
64  size_t n,
65  CPUContext*) {
66  EigenArrayMap<T>(y, n, 1) = ConstEigenArrayMap<T>(x, n, pre).rowwise().sum();
67 }
68 
69 template <typename T>
70 void SRLHelper::RunWithBroadcastBack(
71  const T* x,
72  T* y,
73  size_t post,
74  size_t n,
75  CPUContext*) {
76  EigenArrayMap<T>(y, 1, n) = ConstEigenArrayMap<T>(x, post, n).colwise().sum();
77 }
78 
79 template <typename T>
80 void SRLHelper::RunWithBroadcast2(
81  const T* a,
82  T* y,
83  size_t pre,
84  size_t n,
85  size_t post,
86  CPUContext*) {
87  for (int i = 0; i < n; ++i) {
88  y[i] = 0;
89  for (int j = 0; j < pre; ++j) {
90  for (int k = 0; k < post; ++k) {
91  y[i] += a[(j * n + i) * post + k];
92  }
93  }
94  }
95 }
96 
97 template <>
98 template <typename T>
99 bool SumReduceLikeOp<CPUContext>::DoRunWithType() {
100  const auto& A = Input(0);
101  const auto& B = Input(1);
102 
103  CAFFE_ENFORCE(!IsInputOutputAlias(1, 0), "In-place is not allowed.");
104  auto* C = Output(0, B.sizes(), at::dtype<T>());
105  const T* Adata = A.template data<T>();
106  auto* Cdata = C->template mutable_data<T>();
107  if (B.numel() == 1) {
108  auto count = A.numel();
109  SRLHelper::sum2one<T>(Adata, Cdata, count);
110  } else {
111  size_t pre, n, post;
112  std::tie(pre, n, post) =
113  elementwise_ops_utils::ComputeLegacyBroadcastSizes(A, B, axis_);
114  if (post == 1) {
115  SRLHelper::RunWithBroadcastFront<T>(Adata, Cdata, pre, n, &context_);
116  } else if (pre == 1) {
117  SRLHelper::RunWithBroadcastBack<T>(Adata, Cdata, post, n, &context_);
118  } else {
119  SRLHelper::RunWithBroadcast2<T>(Adata, Cdata, pre, n, post, &context_);
120  }
121  }
122  return true;
123 }
124 
125 REGISTER_CPU_OPERATOR(SumReduceLike, SumReduceLikeOp<CPUContext>);
126 
127 } // namespace caffe2
Definition: static.cpp:52
A global dictionary that holds information about what Caffe2 modules have been loaded in the current ...
Definition: blob.h:13
Definition: static.cpp:64
Definition: static.cpp:58