1 #include "caffe2/operators/reduction_front_back_ops.h" 2 #include "caffe2/core/operator_gradient.h" 13 void SumReduceDimsOp<CPUContext, true, false>::Compute(
17 const int32_t* lengths_data,
19 for (
int j = 0; j < cols; j++) {
21 int length = lengths_data ==
nullptr ? rows : lengths_data[j];
22 for (
int i = 1; i < length; i++) {
23 sum += in_data[i * cols + j];
32 void SumReduceDimsOp<CPUContext, false, false>::Compute(
36 const int32_t* lengths_data,
38 for (
int i = 0; i < rows; i++) {
39 int offset = i * cols;
40 T sum = in_data[offset];
41 int length = lengths_data ==
nullptr ? cols : lengths_data[i];
42 for (
int j = 1; j < length; j++) {
43 sum += in_data[offset + j];
52 void SumReduceDimsGradientOp<CPUContext, true, false>::Compute(
56 const int* lengths_data,
58 for (
int i = 0; i < rows * cols; i++) {
61 if (lengths_data ==
nullptr || row < lengths_data[col]) {
62 dXdata[i] = dYdata[col];
72 void SumReduceDimsGradientOp<CPUContext, false, false>::Compute(
76 const int* lengths_data,
78 for (
int i = 0; i < rows * cols; i++) {
81 if (lengths_data ==
nullptr || col < lengths_data[row]) {
82 dXdata[i] = dYdata[row];
89 REGISTER_CPU_OPERATOR(ReduceFrontSum, SumReduceDimsOp<CPUContext, true, false>);
90 REGISTER_CPU_OPERATOR(
91 ReduceFrontSumGradient,
92 SumReduceDimsGradientOp<CPUContext, true, false>);
95 using GradientMakerBase::GradientMakerBase;
96 vector<OperatorDef> GetGradientDefs()
override {
97 vector<string> grad_in = {GO(0), I(0)};
98 if (def_.input_size() == 2) {
99 grad_in.push_back(I(1));
102 "ReduceFrontSumGradient",
"", grad_in, vector<string>{GI(0)});
109 REGISTER_CPU_OPERATOR(
110 ReduceBackSumGradient,
114 using GradientMakerBase::GradientMakerBase;
115 vector<OperatorDef> GetGradientDefs()
override {
116 vector<string> grad_in = {GO(0), I(0)};
117 if (def_.input_size() == 2) {
118 grad_in.push_back(I(1));
121 "ReduceBackSumGradient",
"", grad_in, vector<string>{GI(0)});
127 #define REDUCTION_OP_SHAPE_INFERENCE(is_front_reducer) \ 128 CAFFE_ENFORCE_LE(1, in.size()); \ 129 CAFFE_ENFORCE_GE(2, in.size()); \ 130 ArgumentHelper helper(def); \ 131 int num_reduce_dims = helper.GetSingleArgument<int>("num_reduce_dim", 1); \ 132 int start_index = is_front_reducer ? num_reduce_dims : 0; \ 133 int end_index = is_front_reducer ? in[0].dims_size() \ 134 : in[0].dims_size() - num_reduce_dims; \ 135 vector<int> output_shape; \ 136 for (int i = start_index; i < end_index; ++i) { \ 137 output_shape.push_back(in[0].dims(i)); \ 139 return vector<TensorShape>{ \ 140 CreateTensorShape(output_shape, in[0].data_type())}; 142 OPERATOR_SCHEMA(ReduceFrontSum)
145 .Arg(
"num_reduce_dims",
"Number of dimensions to reduce.")
147 Reduces the input tensor along the first dimension of the input 148 tensor by applying 'Sum'. When lengths is given, sum is only computed 149 with subsets of elements correspondingly. 151 .Input(0, "data_in",
"(T<D1..., Dn>) Input data.")
155 "Num of elements in each sample, should have size D2 x D3 x ... x Dn.")
156 .TensorInferenceFunction([](
const OperatorDef& def,
157 const vector<TensorShape>& in) {
158 REDUCTION_OP_SHAPE_INFERENCE(
true)
160 OPERATOR_SCHEMA(ReduceFrontSumGradient).NumInputs(2, 3).NumOutputs(1);
162 OPERATOR_SCHEMA(ReduceBackSum)
165 .Arg(
"num_reduce_dims",
"Number of dimensions to reduce.")
167 Reduces the input tensor along the last dimension of the 168 input tensor by applying 'Sum'. When lengths is given, sum is only computed 169 with subsets of elements correspondingly. 171 .Input(0, "data_in",
"(T<D1..., Dn>) Input data.")
175 "Num of elements in each sample, should have size D1 x D2 x ... x D(n-1).")
176 .TensorInferenceFunction([](
const OperatorDef& def,
177 const vector<TensorShape>& in) {
178 REDUCTION_OP_SHAPE_INFERENCE(
false)
180 OPERATOR_SCHEMA(ReduceBackSumGradient).NumInputs(2, 3).NumOutputs(1);
188 template <
typename T>
193 const int32_t* lengths_data,
195 for (
int j = 0; j < cols; j++) {
197 int length = lengths_data ==
nullptr ? rows : lengths_data[j];
198 for (
int i = 1; i < length; i++) {
199 sum += in_data[i * cols + j];
201 out_data[j] = sum / length;
207 template <
typename T>
212 const int32_t* lengths_data,
214 for (
int i = 0; i < rows; i++) {
215 int offset = i * cols;
216 T sum = in_data[offset];
217 int length = lengths_data ==
nullptr ? cols : lengths_data[i];
218 for (
int j = 1; j < length; j++) {
219 sum += in_data[offset + j];
221 out_data[i] = sum / length;
227 template <
typename T>
232 const int* lengths_data,
234 for (
int i = 0; i < rows * cols; i++) {
237 if (lengths_data ==
nullptr) {
238 dXdata[i] = dYdata[col] / rows;
239 }
else if (row < lengths_data[col]) {
240 dXdata[i] = dYdata[col] / lengths_data[col];
249 template <
typename T>
254 const int* lengths_data,
256 for (
int i = 0; i < rows * cols; i++) {
259 if (lengths_data ==
nullptr) {
260 dXdata[i] = dYdata[row] / cols;
261 }
else if (col < lengths_data[row]) {
262 dXdata[i] = dYdata[row] / lengths_data[row];
270 REGISTER_CPU_OPERATOR(
271 ReduceFrontMeanGradient,
275 using GradientMakerBase::GradientMakerBase;
276 vector<OperatorDef> GetGradientDefs()
override {
277 vector<string> grad_in = {GO(0), I(0)};
278 if (def_.input_size() == 2) {
279 grad_in.push_back(I(1));
282 "ReduceFrontMeanGradient",
"", grad_in, vector<string>{GI(0)});
288 OPERATOR_SCHEMA(ReduceFrontMean)
291 .Arg(
"num_reduce_dims",
"Number of dimensions to reduce.")
293 Reduces the input tensor along the first dimension of the input 294 tensor by applying 'Mean'. When lengths is given, mean is only computed 295 with subsets of elements correspondingly. 297 .Input(0, "data_in",
"(T<D1..., Dn>) Input data.")
301 "Num of elements in each sample, should have size D2 x D3 x ... x Dn.")
302 .TensorInferenceFunction([](
const OperatorDef& def,
303 const vector<TensorShape>& in) {
304 REDUCTION_OP_SHAPE_INFERENCE(
true)
306 OPERATOR_SCHEMA(ReduceFrontMeanGradient).NumInputs(2, 3).NumOutputs(1);
309 REGISTER_CPU_OPERATOR(
310 ReduceBackMeanGradient,
314 using GradientMakerBase::GradientMakerBase;
315 vector<OperatorDef> GetGradientDefs()
override {
316 vector<string> grad_in = {GO(0), I(0)};
317 if (def_.input_size() == 2) {
318 grad_in.push_back(I(1));
321 "ReduceBackMeanGradient",
"", grad_in, vector<string>{GI(0)});
327 OPERATOR_SCHEMA(ReduceBackMean)
330 .Arg(
"num_reduce_dims",
"Number of dimensions to reduce.")
332 Reduces the input tensor along the last dimension of the input 333 tensor by applying 'Mean'. When lengths is given, mean is only computed 334 with subsets of elements correspondingly. 336 .Input(0, "data_in",
"(T<D1..., Dn>) Input data.")
340 "Num of elements in each sample, should have size D1 x D2 x ... x D(n-1).")
341 .TensorInferenceFunction([](
const OperatorDef& def,
342 const vector<TensorShape>& in) {
343 REDUCTION_OP_SHAPE_INFERENCE(
false)
345 OPERATOR_SCHEMA(ReduceBackMeanGradient).NumInputs(2, 3).NumOutputs(1);
357 const int32_t* lengths_data,
359 for (
int i = 0; i < cols; i++) {
361 int length = lengths_data ==
nullptr ? rows : lengths_data[i];
362 for (
int j = 1; j < length; j++) {
363 mx = std::max(mx, data[j * cols + i]);
375 const int32_t* lengths_data,
377 for (
int i = 0; i < rows; i++) {
378 float mx = data[i * cols];
379 int length = lengths_data ==
nullptr ? cols : lengths_data[i];
380 for (
int j = 1; j < length; j++) {
381 mx = std::max(mx, data[i * cols + j]);
395 const int32_t* lengths_data,
397 int len = cols * rows;
398 for (
int i = 0; i < len; i++) {
401 if (lengths_data !=
nullptr && row >= lengths_data[col]) {
404 dXdata[i] = Xdata[i] == Ydata[col] ? dYdata[col] : 0.0f;
417 const int32_t* lengths_data,
419 int len = cols * rows;
420 for (
int i = 0; i < len; i++) {
423 if (lengths_data ==
nullptr || col < lengths_data[row]) {
424 dXdata[i] = Xdata[i] == Ydata[row] ? dYdata[row] : 0.0f;
432 REGISTER_CPU_OPERATOR(
433 ReduceFrontMaxGradient,
437 REGISTER_CPU_OPERATOR(
438 ReduceBackMaxGradient,
442 using GradientMakerBase::GradientMakerBase;
443 vector<OperatorDef> GetGradientDefs()
override {
444 vector<string> grad_in = {GO(0), I(0), O(0)};
445 if (def_.input_size() == 2) {
446 grad_in.push_back(I(1));
449 "ReduceFrontMaxGradient",
"", grad_in, vector<string>{GI(0)});
456 using GradientMakerBase::GradientMakerBase;
457 vector<OperatorDef> GetGradientDefs()
override {
458 vector<string> grad_in = {GO(0), I(0), O(0)};
459 if (def_.input_size() == 2) {
460 grad_in.push_back(I(1));
463 "ReduceBackMaxGradient",
"", grad_in, vector<string>{GI(0)});
469 OPERATOR_SCHEMA(ReduceFrontMax)
472 .Arg(
"num_reduce_dims",
"Number of dimensions to reduce")
474 Reduces the input tensor along the first dimension of the input 475 tensor by applying 'Max'. When lengths is given, max is only computed 476 with subsets of elements correspondingly. 478 .Input(0, "data_in",
"(T<D1..., Dn>) Input data.")
482 "Num of elements in each sample, should have size D2 x D3 ... x Dn.")
483 .TensorInferenceFunction([](
const OperatorDef& def,
484 const vector<TensorShape>& in) {
485 REDUCTION_OP_SHAPE_INFERENCE(
true)
487 OPERATOR_SCHEMA(ReduceFrontMaxGradient).NumInputs(3, 4).NumOutputs(1);
489 OPERATOR_SCHEMA(ReduceBackMax)
492 .Arg(
"num_reduce_dims",
"Number of dimensions to reduce")
494 Reduces the input tensor along the last dimension of the 495 input tensor by applying 'Max'. When lengths is given, max is only computed 496 with subsets of elements correspondingly. 498 .Input(0, "data_in",
"(T<D1..., Dn>) Input data.")
502 "Num of elements in each sample, should have size D1 x D2 x ... x D(n-1).")
503 .TensorInferenceFunction([](
const OperatorDef& def,
504 const vector<TensorShape>& in) {
505 REDUCTION_OP_SHAPE_INFERENCE(
false)
507 OPERATOR_SCHEMA(ReduceBackMaxGradient).NumInputs(3, 4).NumOutputs(1);
509 #undef REDUCTION_OP_SHAPE_INFERENCE
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 ...