1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
|
#include "caffe2/operators/mod_op.h"
#include "caffe2/core/operator.h"
#include "caffe2/core/tensor.h"
namespace caffe2 {
template <>
template <typename T>
bool ModOp<CPUContext>::DoRunWithType() {
auto& data = Input(DATA);
auto N = data.numel();
const auto* data_ptr = data.template data<T>();
auto* output = Output(0, Input(DATA).sizes(), at::dtype<T>());
auto* output_ptr = output->template mutable_data<T>();
for (auto i = 0; i < N; i++) {
output_ptr[i] = data_ptr[i] % divisor_;
if (output_ptr[i] && sign_follow_divisor_ &&
((output_ptr[i] > 0) != (divisor_ > 0))) {
output_ptr[i] += divisor_;
}
}
return true;
}
namespace {
REGISTER_CPU_OPERATOR(Mod, ModOp<CPUContext>);
OPERATOR_SCHEMA(Mod)
.NumInputs(1)
.NumOutputs(1)
.Arg("divisor", "*(type: int; default: 0)* Divisor of the modulo operation (must be >= 1).")
.Arg(
"sign_follow_divisor",
"*(type: bool; default: False)* If true, sign of output matches divisor, else if false, sign follows dividend.")
.IdenticalTypeAndShape()
.AllowInplace({{0, 0}})
.SetDoc(R"DOC(
Element-wise modulo operation. Each element in the output is the modulo result
of the corresponding element in the input data. The divisor of the modulo is
provided by the `divisor` argument.
Github Link:
- https://github.com/pytorch/pytorch/blob/master/caffe2/operators/mod_op.cc
<details>
<summary> <b>Example</b> </summary>
**Code**
```
workspace.ResetWorkspace()
op = core.CreateOperator(
"Mod",
["X"],
["Y"],
divisor=10
)
workspace.FeedBlob("X", (np.random.randint(100, size=(5,5))))
print("X before running op:", workspace.FetchBlob("X"))
workspace.RunOperatorOnce(op)
print("X after running op:", workspace.FetchBlob("Y"))
```
**Result**
```
X before running op:
[[56 22 43 13 60]
[ 4 55 58 10 45]
[64 66 4 3 66]
[10 36 47 52 78]
[91 4 36 47 95]]
X after running op:
[[6 2 3 3 0]
[4 5 8 0 5]
[4 6 4 3 6]
[0 6 7 2 8]
[1 4 6 7 5]]
```
</details>
)DOC")
.Input(0, "X", "*(type: Tensor`<int>`)* Input tensor with int32 or int64 data.")
.Output(0, "Y", "*(type: Tensor`<int>`)* Output tensor of data with modulo operation applied.");
SHOULD_NOT_DO_GRADIENT(ModOp);
} // namespace
} // namespace caffe2
|