Caffe2 - C++ API
A deep learning, cross platform ML framework
elementwise_logical_ops.cc
1 #include "caffe2/operators/elementwise_logical_ops.h"
2 
3 namespace caffe2 {
4 namespace {
5 
6 REGISTER_CPU_OPERATOR(Where, WhereOp<CPUContext>);
7 
8 // Input: C, X, Y, output: Z
9 OPERATOR_SCHEMA(Where)
10  .NumInputs(3)
11  .NumOutputs(1)
12  .AllowInplace({{1, 2}})
13  .IdenticalTypeAndShapeOfInput(1)
14  .SetDoc(R"DOC(
15 Operator Where takes three input data (Tensor, Tensor, Tensor) and
16 produces one output data (Tensor) where z = c ? x : y is applied elementwise.
17 )DOC")
18  .Input(0, "C", "input tensor containing booleans")
19  .Input(1, "X", "input tensor")
20  .Input(2, "Y", "input tensor")
21  .Output(0, "Z", "output tensor");
22 
23 SHOULD_NOT_DO_GRADIENT(Where);
24 
25 REGISTER_CPU_OPERATOR(IsMemberOf, IsMemberOfOp<CPUContext>);
26 
27 // Input: X, output: Y
28 OPERATOR_SCHEMA(IsMemberOf)
29  .NumInputs(1)
30  .NumOutputs(1)
31  .TensorInferenceFunction(
32  [](const OperatorDef&, const vector<TensorShape>& input_types) {
33  vector<TensorShape> out(1);
34  out[0] = input_types[0];
35  out[0].set_data_type(TensorProto_DataType::TensorProto_DataType_BOOL);
36  return out;
37  })
38  .Arg("value", "*(type: []; default: -)* List of values to check for membership.")
39  .Arg("dtype", "*(type: TensorProto_DataType; default: -)* The data type for the elements of the output tensor. Strictly must be one of the types from DataType enum in TensorProto.")
40  .SetDoc(R"DOC(
41 The *IsMemberOf* op takes an input tensor *X* and a list of values as argument, and produces one output data tensor *Y*. The output tensor is the same shape as *X* and contains booleans. The output is calculated as the function *f(x) = x in value* and is applied to *X* elementwise.
42 
43 Github Links:
44 
45 - https://github.com/caffe2/caffe2/blob/master/caffe2/operators/elementwise_logical_ops.cc
46 - https://github.com/caffe2/caffe2/blob/master/caffe2/operators/elementwise_logical_ops.h
47 
48 
49 <details>
50 
51 <summary> <b>Example</b> </summary>
52 
53 **Code**
54 
55 ```
56 
57 workspace.ResetWorkspace()
58 
59 op = core.CreateOperator(
60  "IsMemberOf",
61  ["X"],
62  ["Y"],
63  value=[0,2,4,6,8],
64 )
65 
66 // Use a not-empty tensor
67 workspace.FeedBlob("X", np.array([0,1,2,3,4,5,6,7,8]).astype(np.int32))
68 print("X:\n", workspace.FetchBlob("X"))
69 
70 workspace.RunOperatorOnce(op)
71 print("Y: \n", workspace.FetchBlob("Y"))
72 
73 ```
74 
75 **Result**
76 
77 ```
78 // value=[0,2,4,6,8]
79 
80 X:
81  [0 1 2 3 4 5 6 7 8]
82 Y:
83  [ True False True False True False True False True]
84 
85 ```
86 
87 </details>
88 
89 )DOC")
90  .Input(0, "X", "Input tensor of any shape")
91  .Output(0, "Y", "Output tensor (same size as X containing booleans)");
92 
93 SHOULD_NOT_DO_GRADIENT(IsMemberOf);
94 
95 } // namespace
96 
97 template <>
98 std::unordered_set<int32_t>& IsMemberOfValueHolder::get<int32_t>() {
99  return int32_values_;
100 }
101 
102 template <>
103 std::unordered_set<int64_t>& IsMemberOfValueHolder::get<int64_t>() {
104  return int64_values_;
105 }
106 
107 template <>
108 std::unordered_set<bool>& IsMemberOfValueHolder::get<bool>() {
109  return bool_values_;
110 }
111 
112 template <>
113 std::unordered_set<string>& IsMemberOfValueHolder::get<string>() {
114  return string_values_;
115 }
116 
117 } // namespace caffe2
A global dictionary that holds information about what Caffe2 modules have been loaded in the current ...
Definition: blob.h:13