1 #include "caffe2/operators/reduction_ops.h" 5 REGISTER_CPU_OPERATOR(SumElements, SumElementsOp<float, CPUContext>);
6 REGISTER_CPU_OPERATOR(SumElementsInt, SumElementsIntOp<int, CPUContext>);
7 REGISTER_CPU_OPERATOR(SumSqrElements, SumSqrElementsOp<CPUContext>);
11 SumElementsGradientOp<float, CPUContext>);
13 REGISTER_CPU_OPERATOR(RowwiseMax, MaxReductionOp<float, CPUContext, true>);
14 REGISTER_CPU_OPERATOR(
16 MaxReductionGradientOp<float, CPUContext, true>);
17 REGISTER_CPU_OPERATOR(
19 MaxReductionGradientOp<float, CPUContext, false>);
20 REGISTER_CPU_OPERATOR(ColwiseMax, MaxReductionOp<float, CPUContext, false>);
22 OPERATOR_SCHEMA(SumElements)
25 .ScalarType(TensorProto::FLOAT)
27 Sums the elements of the input tensor. Tensor type must be float32. 30 - https://github.com/pytorch/pytorch/blob/master/caffe2/operators/reduction_ops.cc 34 <summary> <b>Example</b> </summary> 40 workspace.ResetWorkspace() 42 sum_op = core.CreateOperator( 48 avg_op = core.CreateOperator( 55 workspace.FeedBlob("X", np.random.randint(10, size=(3,3)).astype(np.float32)) 56 print("X:\n", workspace.FetchBlob("X")) 57 workspace.RunOperatorOnce(sum_op) 58 print("Y (sum_op):", workspace.FetchBlob("Y")) 59 workspace.RunOperatorOnce(avg_op) 60 print("Y (avg_op):", workspace.FetchBlob("Y")) 80 .Arg("average",
"(*bool*): set to True to compute the average of the elements rather than the sum")
81 .Input(0,
"X",
"(*Tensor`<float>`*): blob pointing to an instance of a counter")
82 .Output(0,
"sum",
"(*Tensor`<float>`*): Scalar tensor containing the sum (or average)");
84 OPERATOR_SCHEMA(SumElementsInt)
87 .ScalarType(TensorProto::INT32)
88 .SetDoc(
"Sums the integer elements of the input tensor.")
89 .Input(0,
"X",
"Tensor to sum up")
90 .Output(0,
"sum",
"Scalar sum");
91 SHOULD_NOT_DO_GRADIENT(SumElementsInt);
93 OPERATOR_SCHEMA(SumSqrElements)
96 .ScalarType(TensorProto::FLOAT)
97 .SetDoc(
"Sums the squares elements of the input tensor.")
98 .Arg(
"average",
"whether to average or not")
99 .Input(0,
"X",
"Tensor to sum up")
100 .Output(0,
"sum",
"Scalar sum of squares");
102 OPERATOR_SCHEMA(SumElementsGradient).NumInputs(2).NumOutputs(1);
105 using GradientMakerBase::GradientMakerBase;
106 vector<OperatorDef> GetGradientDefs()
override {
108 "SumElementsGradient",
110 vector<string>{I(0), GO(0)},
111 vector<string>{GI(0)});
116 OPERATOR_SCHEMA(RowwiseMax)
120 Compute row-wise max reduction of the input tensor. This op takes one input, $X$, of shape $BxMxN$, where $B$ is the batch size, $M$ is number of rows, and $N$ is number of columns. The output of this op, $Y$, is a matrix of shape $BxM$, with one row for each element of the batch, and the same number of columns as the number of rows of the input tensor. 123 - https://github.com/pytorch/pytorch/blob/master/caffe2/operators/reduction_ops.h 124 - https://github.com/pytorch/pytorch/blob/master/caffe2/operators/reduction_ops.cc 128 <summary> <b>Example</b> </summary> 134 workspace.ResetWorkspace() 136 op = core.CreateOperator( 142 // Create X, simulating a batch of 2, 4x4 matricies 143 X = np.random.randint(0,high=20,size=(2,4,4)) 146 // Feed X into workspace 147 workspace.FeedBlob("X", X.astype(np.float32)) 150 workspace.RunOperatorOnce(op) 153 print("Y:\n", workspace.FetchBlob("Y")) 183 "A tensor of dimensions $B x M x N$ to compute rowwise-max. Here, $B$ is batch size, and $M$ and $N$ are the number of rows and columns of each element of the batch, respectively.")
187 "The output tensor of shape $B x M$, where each row represents the row-wise maximums for that element of the input batch.");
189 OPERATOR_SCHEMA(RowwiseMaxGradient).NumInputs(3).NumOutputs(1);
191 using GradientMakerBase::GradientMakerBase;
192 vector<OperatorDef> GetGradientDefs()
override {
194 "RowwiseMaxGradient",
196 vector<string>{I(0), O(0), GO(0)},
197 vector<string>{GI(0)});
200 REGISTER_GRADIENT(RowwiseMax, GetRowwiseMaxGradient);
202 OPERATOR_SCHEMA(ColwiseMaxGradient);
204 OPERATOR_SCHEMA(ColwiseMax)
208 Compute column-wise max reduction of the input tensor. This op takes one input, $X$, of shape $BxMxN$, where $B$ is the batch size, $M$ is number of rows, and $N$ is number of columns. The output of this op, $Y$, is a matrix of shape $BxN$, with one row for each element of the batch, and the same number of columns as the input tensor. 211 - https://github.com/pytorch/pytorch/blob/master/caffe2/operators/reduction_ops.h 212 - https://github.com/pytorch/pytorch/blob/master/caffe2/operators/reduction_ops.cc 216 <summary> <b>Example</b> </summary> 221 workspace.ResetWorkspace() 223 op = core.CreateOperator( 229 // Create X, simulating a batch of 2, 4x4 matricies 230 X = np.random.randint(0,high=20,size=(2,4,4)) 233 // Feed X into workspace 234 workspace.FeedBlob("X", X.astype(np.float32)) 237 workspace.RunOperatorOnce(op) 240 print("Y:\n", workspace.FetchBlob("Y")) 270 "A tensor of dimensions $B x M x N$ to compute columnwise-max. Here, $B$ is batch size, and $M$ and $N$ are the number of rows and columns of each element of the batch, respectively.")
274 "The output tensor of shape $B x N$, where each row represents the column-wise maximums for that element of the input batch.");
276 OPERATOR_SCHEMA(ColumnMaxGradient).NumInputs(3).NumOutputs(1);
278 using GradientMakerBase::GradientMakerBase;
279 vector<OperatorDef> GetGradientDefs()
override {
281 "ColwiseMaxGradient",
283 vector<string>{I(0), O(0), GO(0)},
284 vector<string>{GI(0)});
287 REGISTER_GRADIENT(ColwiseMax, GetColwiseMaxGradient);
289 template <
typename T,
class Context>
292 #if defined(__has_feature) 293 #if __has_feature(__address_sanitizer__) 294 __attribute__((__no_sanitize__(
"float-divide-by-zero")))
299 Tensor sum_grad(Input(1), CPU);
301 auto* dX = Output(0, X.sizes(), at::dtype<T>());
302 DCHECK_EQ(sum_grad.numel(), 1);
303 math::Set<T, Context>(
306 sum_grad.template data<T>()[0] * (average_ ? 1.0 / X.numel() : 1)),
307 dX->template mutable_data<T>(),
312 template <
typename T,
class Context,
bool ROWWISE>
318 auto* dX = Output(0, X.sizes(), at::dtype<T>());
320 CAFFE_ENFORCE_EQ(X.dim(), 3);
322 const int batch_size = X.dim32(0);
323 const int M = X.dim32(1);
324 const int N = X.dim32(2);
326 const T* Xdata = X.template data<T>();
327 const T* Ydata = Y.template data<T>();
328 const T* dYdata = dY.template data<T>();
329 T* dXdata = dX->template mutable_data<T>();
331 const int input_size = M * N;
332 for (
int i = 0; i < batch_size; ++i) {
333 const T* Xdata_i = Xdata + i * input_size;
334 T* dXdata_i = dXdata + i * input_size;
336 const T* Ydata_i = Ydata + i * M;
337 const T* dYdata_i = dYdata + i * M;
338 for (
int m = 0; m < M; ++m) {
339 const T* Xdata_m = Xdata_i + m * N;
340 T* dXdata_m = dXdata_i + m * N;
341 for (
int n = 0; n < N; ++n) {
342 if (Xdata_m[n] == Ydata_i[m]) {
343 dXdata_m[n] = dYdata_i[m];
345 dXdata_m[n] =
static_cast<T>(0);
350 const T* Ydata_i = Ydata + i * N;
351 const T* dYdata_i = dYdata + i * N;
352 for (
int n = 0; n < N; ++n) {
353 for (
int m = 0; m < M; ++m) {
354 const T* Xdata_m = Xdata_i + m * N;
355 T* dXdata_m = dXdata_i + m * N;
356 if (Xdata_m[n] == Ydata_i[n]) {
357 dXdata_m[n] = dYdata_i[n];
359 dXdata_m[n] =
static_cast<T>(0);
A global dictionary that holds information about what Caffe2 modules have been loaded in the current ...
static vector< OperatorDef > SingleGradientDef(const Args &...args)
a helper function to allow one to create one single operator def, which is usually the case for many ...