pool_op.cc 22.9 KB
Newer Older
1
/* Copyright (c) 2016 PaddlePaddle Authors. All Rights Reserved.
2 3 4 5 6 7 8 9 10 11 12 13 14

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. */

Y
Yi Wang 已提交
15
#include "paddle/fluid/operators/pool_op.h"
16
#include <unordered_map>
17 18 19 20 21 22
#ifdef PADDLE_WITH_CUDA
#include "paddle/fluid/platform/cudnn_helper.h"
#endif
#ifdef PADDLE_WITH_MKLDNN
#include "paddle/fluid/platform/mkldnn_helper.h"
#endif
23 24 25 26

namespace paddle {
namespace operators {

27 28
int PoolOutputSize(int input_size, int filter_size, int padding_1,
                   int padding_2, int stride, bool ceil_mode) {
29 30
  int output_size;
  if (!ceil_mode) {
31 32
    output_size =
        (input_size - filter_size + padding_1 + padding_2) / stride + 1;
33 34
  } else {
    output_size =
35 36 37
        (input_size - filter_size + padding_1 + padding_2 + stride - 1) /
            stride +
        1;
38
  }
39 40 41 42 43 44
  PADDLE_ENFORCE_GT(
      output_size, 0,
      "Due to the settings of padding(%d,%d), filter_size(%d) and "
      "stride(%d), the output size is less than 0, please check "
      "again. Input_size:%d",
      padding_1, padding_2, filter_size, stride, input_size);
45 46 47
  return output_size;
}

C
chengduo 已提交
48
void PoolOp::InferShape(framework::InferShapeContext* ctx) const {
49 50 51 52
  PADDLE_ENFORCE_EQ(ctx->HasInput("X"), true,
                    "X(Input) of Pooling should not be null.");
  PADDLE_ENFORCE_EQ(ctx->HasOutput("Out"), true,
                    "Out(Output) of Pooling should not be null.");
53

C
chengduoZH 已提交
54
  std::string pooling_type = ctx->Attrs().Get<std::string>("pooling_type");
55 56 57
  std::vector<int> ksize = ctx->Attrs().Get<std::vector<int>>("ksize");
  std::vector<int> strides = ctx->Attrs().Get<std::vector<int>>("strides");
  std::vector<int> paddings = ctx->Attrs().Get<std::vector<int>>("paddings");
58
  bool ceil_mode = ctx->Attrs().Get<bool>("ceil_mode");
59
  bool adaptive = ctx->Attrs().Get<bool>("adaptive");
60 61 62 63
  bool global_pooling = ctx->Attrs().Get<bool>("global_pooling");
  std::string data_format = ctx->Attrs().Get<std::string>("data_format");
  std::string padding_algorithm =
      ctx->Attrs().Get<std::string>("padding_algorithm");
64

65 66 67
  auto in_x_dims = ctx->GetInputDim("X");
  PADDLE_ENFORCE_EQ(in_x_dims.size() == 4 || in_x_dims.size() == 5, true,
                    "Pooling intput should be 4-D or 5-D tensor.");
68

69 70
  PADDLE_ENFORCE_EQ(in_x_dims.size() - ksize.size(), 2U,
                    "Input size and pooling size should be consistent.");
71 72 73
  PADDLE_ENFORCE_EQ(ksize.size(), strides.size(),
                    "Strides size and pooling size should be the same.");

74 75 76 77
  // MKL-DNN Kernels are using NCHW order of dims description
  // so we ignore data_format consideration for MKL-DNN kernel
  const bool channel_last = (this->IsMKLDNNType() == false) &&
                            (data_format == "NHWC" || data_format == "NDHWC");
78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93

  // update paddings if "SAME" or global_pooling
  framework::DDim data_dims;
  if (channel_last) {
    data_dims = framework::slice_ddim(in_x_dims, 1, in_x_dims.size() - 1);
  } else {
    data_dims = framework::slice_ddim(in_x_dims, 2, in_x_dims.size());
  }
  UpdatePadding(&paddings, global_pooling, adaptive, padding_algorithm,
                data_dims, strides, ksize);

  if (global_pooling) {
    UpdateKsize(&ksize, data_dims);
  }

  std::vector<int64_t> output_shape;
94 95 96
  if (adaptive) {
    output_shape.insert(output_shape.end(), ksize.begin(), ksize.end());
  } else {
97 98
    for (size_t i = 0; i < data_dims.size(); ++i) {
      if ((!ctx->IsRuntime()) && (data_dims[i] < 0)) {
99
        output_shape.push_back(data_dims[i]);
K
Kaipeng Deng 已提交
100
      } else {
101 102 103
        output_shape.push_back(
            PoolOutputSize(data_dims[i], ksize[i], paddings[2 * i],
                           paddings[2 * i + 1], strides[i], ceil_mode));
K
Kaipeng Deng 已提交
104
      }
105
    }
106
  }
107 108 109 110 111 112 113 114 115 116

  // output_N = input_N
  output_shape.insert(output_shape.begin(), in_x_dims[0]);
  // output_C = input_C
  if (channel_last) {
    output_shape.push_back(in_x_dims[in_x_dims.size() - 1]);
  } else {
    output_shape.insert(output_shape.begin() + 1, in_x_dims[1]);
  }

117
  ctx->SetOutputDim("Out", framework::make_ddim(output_shape));
Y
Yang Yu 已提交
118
  ctx->ShareLoD("X", "Out");
119 120
}

121
framework::OpKernelType PoolOp::GetExpectedKernelType(
C
chengduo 已提交
122
    const framework::ExecutionContext& ctx) const {
123
  framework::LibraryType library_{framework::LibraryType::kPlain};
124
  std::string data_format = "AnyLayout";
M
mozga-intel 已提交
125 126
  framework::DataLayout layout_ = framework::StringToDataLayout(data_format);

C
chengduoZH 已提交
127
#ifdef PADDLE_WITH_CUDA
128 129
  if (platform::CanCUDNNBeUsed(ctx)) {
    library_ = framework::LibraryType::kCUDNN;
C
chengduoZH 已提交
130 131
  }
#endif
132 133 134 135
#ifdef PADDLE_WITH_MKLDNN
  if (library_ == framework::LibraryType::kPlain &&
      platform::CanMKLDNNBeUsed(ctx)) {
    library_ = framework::LibraryType::kMKLDNN;
M
mozga-intel 已提交
136
    layout_ = framework::DataLayout::kMKLDNN;
137
  }
138
#endif
139

140 141 142
  return framework::OpKernelType(
      OperatorWithKernel::IndicateVarDataType(ctx, "X"), ctx.GetPlace(),
      layout_, library_);
143 144
}

145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166
framework::OpKernelType PoolOp::GetKernelTypeForVar(
    const std::string& var_name, const Tensor& tensor,
    const framework::OpKernelType& expected_kernel_type) const {
#ifdef PADDLE_WITH_MKLDNN
  if ((expected_kernel_type.data_layout_ == framework::DataLayout::kMKLDNN) &&
      (tensor.layout() != framework::DataLayout::kMKLDNN)) {
    auto attrs = Attrs();
    auto ar = paddle::framework::AttrReader(attrs);
    const std::string data_format = ar.Get<std::string>("data_format");
    auto dl = framework::StringToDataLayout(data_format);
    // Some models may have intentionally set "AnyLayout" for pool
    // op. Treat this as NCHW (default data_format value)
    if (dl != framework::DataLayout::kAnyLayout) {
      return framework::OpKernelType(expected_kernel_type.data_type_,
                                     tensor.place(), dl);
    }
  }
#endif
  return framework::OpKernelType(expected_kernel_type.data_type_,
                                 tensor.place(), tensor.layout());
}

C
chengduo 已提交
167
void PoolOpGrad::InferShape(framework::InferShapeContext* ctx) const {
168 169 170
  PADDLE_ENFORCE_EQ(ctx->HasInput("X"), true, "Input(X) must not be null.");
  PADDLE_ENFORCE_EQ(ctx->HasOutput(framework::GradVarName("X")), true,
                    "Input(X@GRAD) should not be null.");
171 172 173
  ctx->SetOutputDim(framework::GradVarName("X"), ctx->GetInputDim("X"));
}

174
framework::OpKernelType PoolOpGrad::GetExpectedKernelType(
C
chengduo 已提交
175
    const framework::ExecutionContext& ctx) const {
176
  framework::LibraryType library_{framework::LibraryType::kPlain};
177
  std::string data_format = "AnyLayout";
M
mozga-intel 已提交
178 179
  framework::DataLayout layout_ = framework::StringToDataLayout(data_format);

C
chengduoZH 已提交
180
#ifdef PADDLE_WITH_CUDA
181 182
  if (platform::CanCUDNNBeUsed(ctx)) {
    library_ = framework::LibraryType::kCUDNN;
C
chengduoZH 已提交
183 184
  }
#endif
185 186 187
#ifdef PADDLE_WITH_MKLDNN
  if (library_ == framework::LibraryType::kPlain &&
      platform::CanMKLDNNBeUsed(ctx)) {
188 189 190 191 192 193
    // TODO(jczaja): Add support for NHWC
    const std::string data_format = ctx.Attr<std::string>("data_format");
    PADDLE_ENFORCE_NE(
        data_format, "NHWC",
        platform::errors::Unimplemented(
            "Pool MKLDNN grad does not support NHWC data format yet"));
194
    library_ = framework::LibraryType::kMKLDNN;
M
mozga-intel 已提交
195
    layout_ = framework::DataLayout::kMKLDNN;
196
  }
197
#endif
198

199
  auto input_data_type = OperatorWithKernel::IndicateVarDataType(ctx, "X");
K
Kexin Zhao 已提交
200 201 202 203 204 205
  if (input_data_type == framework::proto::VarType::FP16) {
    PADDLE_ENFORCE_EQ(library_, framework::LibraryType::kCUDNN,
                      "float16 can only be used when CUDNN is used");
  }
  return framework::OpKernelType(input_data_type, ctx.GetPlace(), layout_,
                                 library_);
206 207
}

Y
Yu Yang 已提交
208
void Pool2dOpMaker::Make() {
209 210
  AddInput(
      "X",
C
chengduoZH 已提交
211
      "(Tensor) The input tensor of pooling operator. "
K
kexinzhao 已提交
212 213 214
      "The format of input tensor is NCHW, where N is batch size, C is the "
      "number of channels, H is the height of the feature, "
      "and W is the width of the feature.");
215
  AddOutput("Out",
K
kexinzhao 已提交
216 217 218 219
            "(Tensor) The output tensor of pooling operator. "
            "The format of output tensor is also NCHW, "
            "where N is batch size, C is the number of channels, "
            "H is the height of the feature, "
220
            "and W is the width of the feature.");
221

C
chengduoZH 已提交
222
  AddAttr<std::string>("pooling_type",
C
chengduoZH 已提交
223 224
                       "(string), pooling type, can be \"max\" for max-pooling "
                       "and \"avg\" for average-pooling.")
225
      .InEnum({"max", "avg"});
C
fix bug  
chengduoZH 已提交
226
  AddAttr<std::vector<int>>("ksize",
K
kexinzhao 已提交
227 228
                            "(vector<int>) The pooling window "
                            "size(height, width) of the pooling operator. "
C
chengduoZH 已提交
229
                            "If global_pooling = true, ksize and paddings will "
C
fix bug  
chengduoZH 已提交
230 231
                            "be ignored.");  // TODO(Chengduo): Add checker.
                                             // (Currently,
C
fix doc  
chengduoZH 已提交
232
  // TypedAttrChecker don't support vector type.)
233 234
  AddAttr<bool>(
      "global_pooling",
235 236 237
      "(bool) Whether to use the global pooling. "
      "If global_pooling = true, kernel size and paddings will be ignored. "
      "Default False.")
238
      .SetDefault(false);
K
kexinzhao 已提交
239 240 241
  AddAttr<std::vector<int>>("strides",
                            "(vector<int>, default {1, 1}), strides(height, "
                            "width) of pooling operator.")
242 243
      .SetDefault({1, 1});
  // TODO(Chengduo): Add checker. (Currently,
C
fix doc  
chengduoZH 已提交
244 245 246
  // TypedAttrChecker don't support vector type.)
  AddAttr<std::vector<int>>(
      "paddings",
247 248
      "(vector<int>, default {0,0}), paddings(height_top, height_bottom, "
      "width_left, wifth_right) of pooling operator."
249
      "If global_pooling = true, paddings and kernel size will be ignored.")
250
      .SetDefault({0, 0});
251 252
  AddAttr<bool>(
      "exclusive",
253
      "(bool) When true, will exclude the zero-padding in the "
254
      "averaging calculating, otherwise, include the zero-padding. Note, it "
255 256
      "is only used when pooling_type is avg. The default is True. "
      "Default True.")
257
      .SetDefault(true);
258 259
  AddAttr<bool>(
      "adaptive",
260
      "(bool) When true, will perform adaptive pooling instead, "
261 262
      "output shape in H and W dimensions will be same as ksize, input data "
      "will be divided into grids specify by ksize averagely and perform "
263 264
      "pooling in each grid area to get output pooling value. "
      "Default False.")
265 266
      .SetDefault(false);

267 268
  AddAttr<bool>(
      "use_cudnn",
269
      "(bool) Only used in cudnn kernel, need install cudnn. Default False")
270
      .SetDefault(false);
271 272
  AddAttr<bool>(
      "ceil_mode",
273
      "(bool) Whether to use the ceil function to calculate "
W
wanghaoshuang 已提交
274
      "output height and width. False is the default. If it is set to False, "
275
      "the floor function will be used. Default False")
276
      .SetDefault(false);
277
  AddAttr<bool>("use_mkldnn",
278
                "(bool) Only used in mkldnn kernel. Default False")
279
      .SetDefault(false);
280
  AddAttr<bool>("use_quantizer",
281
                "(bool) "
282 283
                "Set to true for operators that should be quantized and use "
                "int8 kernel. "
284
                "Only used on CPU. Default False")
285
      .SetDefault(false);
286 287 288 289 290 291
  AddAttr<std::string>(
      "data_format",
      "(string, default NCHW) Only used in "
      "An optional string from: \"NHWC\", \"NCHW\". "
      "Defaults to \"NHWC\". Specify the data format of the output data, "
      "the input will be transformed automatically. ")
292
      .SetDefault("NCHW");
293 294 295 296 297
  AddAttr<bool>("is_test",
                "(bool, default false) Set to true for inference only, false "
                "for training. Some layers may run faster when this is true.")
      .SetDefault(false);

298 299 300 301 302 303
  AddAttr<std::string>(
      "padding_algorithm",
      "(string, default \"EXPLICIT\") An optional string from: \"EXPLICIT\","
      "\"SAME\",\"VALID\". Set to \"EXPLICIT\" for explicit padding. "
      "Set to \"SAME\" or \"VALID\" for algorithm of padding. ")
      .SetDefault("EXPLICIT");
304
  // TODO(dzhwinter): need to registered layout transform function
305 306

  AddComment(R"DOC(
307 308 309
This operation calculates the pooling output based on
the input, pooling_type and pool_size, pool_stride, pool_padding parameters.
Input(X) and Output(Out) are in NCHW or NHWC format, where N is batch size, C is the
K
kexinzhao 已提交
310
number of channels, H is the height of the feature, and W is the width of the feature.
311
Parameters(pool_size, pool_stride, pool_padding) hold two integer elements.
C
fix doc  
chengduoZH 已提交
312
These two elements represent height and width, respectively.
C
chengduoZH 已提交
313 314
The input(X) size and output(Out) size may be different.

315
Example:
F
fengjiayi 已提交
316

C
chengduoZH 已提交
317
  Input:
F
fengjiayi 已提交
318

K
kexinzhao 已提交
319
       X shape: $(N, C, H_{in}, W_{in})$
F
fengjiayi 已提交
320

C
chengduoZH 已提交
321
  Output:
F
fengjiayi 已提交
322

K
kexinzhao 已提交
323
       Out shape: $(N, C, H_{out}, W_{out})$
F
fengjiayi 已提交
324

325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340
  For pool_padding = "SAME":
       $$
       H_{out} = \\frac{(H_{in} + strides[0] - 1)}{strides[0]}
       $$
       $$
       W_{out} = \\frac{(W_{in} + strides[1] - 1)}{strides[1]}
       $$

  For pool_padding = "VALID":
       $$
       H_{out} = \\frac{(H_{in} - ksize[0] + strides[0])}{strides[0]}
       $$
       $$
       W_{out} = \\frac{(W_{in} - ksize[1] + strides[1])}{strides[1]}
       $$

341 342
  For ceil_mode = false:
       $$
343
       H_{out} = \\frac{(H_{in} - ksize[0] + pad_height_top + pad_height_bottom}{strides[0]} + 1
F
fengjiayi 已提交
344 345
       $$
       $$
346
       W_{out} = \\frac{(W_{in} - ksize[1] + pad_width_left + pad_width_right}{strides[1]} + 1
K
kexinzhao 已提交
347
       $$
348

349 350
  For ceil_mode = true:
       $$
351
       H_{out} = \\frac{(H_{in} - ksize[0] + pad_height_top + pad_height_bottom + strides[0] - 1)}{strides[0]} + 1
F
fengjiayi 已提交
352 353
       $$
       $$
354
       W_{out} = \\frac{(W_{in} - ksize[1] + pad_width_left + pad_width_right + strides[1] - 1)}{strides[1]} + 1
355
       $$
K
kexinzhao 已提交
356

357
  For exclusive = false:
358
       $$
359
       hstart = i * strides[0] - pad_height_top
360 361 362 363 364
       $$
       $$
       hend = hstart + ksize[0]
       $$
       $$
365
       wstart = j * strides[1] - pad_width_left
366 367 368 369 370 371 372
       $$
       $$
       wend = wstart + ksize[1]
       $$
       $$
       Output(i ,j) = \\frac{sum(Input[hstart:hend, wstart:wend])}{ksize[0] * ksize[1]}
       $$
373

374
  For exclusive = true:
375
       $$
376
       hstart = max(0, i * strides[0] - pad_height_top)
377 378 379 380 381
       $$
       $$
       hend = min(H, hstart + ksize[0])
       $$
       $$
382
       wstart = max(0, j * strides[1] - pad_width_left)
383 384 385 386 387 388 389
       $$
       $$
       wend = min(W, wstart + ksize[1])
       $$
       $$
       Output(i ,j) = \\frac{sum(Input[hstart:hend, wstart:wend])}{(hend - hstart) * (wend - wstart)}
       $$
390

391
)DOC");
392 393
}

C
chengduo 已提交
394 395 396 397 398 399 400 401
class PoolOpInferVarType : public framework::PassInDtypeAndVarTypeToOutput {
 protected:
  std::unordered_map<std::string, std::string> GetInputOutputWithSameType()
      const override {
    return std::unordered_map<std::string, std::string>{{"X", /*->*/ "Out"}};
  }
};

Y
Yu Yang 已提交
402
void Pool3dOpMaker::Make() {
K
kexinzhao 已提交
403 404
  AddInput("X",
           "(Tensor) The input tensor of pooling operator. "
405 406
           "The format of input tensor is NCDHW or NDHWC, where N is batch "
           "size, C is "
K
kexinzhao 已提交
407 408 409
           "the number of channels, and D, H and W is the depth, height and "
           "width of "
           "the feature, respectively.");
410
  AddOutput("Out",
C
chengduoZH 已提交
411
            "(Tensor) The output tensor of pooling operator."
412
            "The format of output tensor is also NCDHW or NDHWC, "
K
kexinzhao 已提交
413 414
            "where N is batch size, C is "
            "the number of channels, and D, H and W is the depth, height and "
415
            "width of the feature, respectively.");
416

C
chengduoZH 已提交
417
  AddAttr<std::string>("pooling_type",
K
kexinzhao 已提交
418
                       "(string) Pooling type, can be \"max\" for max-pooling "
C
chengduoZH 已提交
419
                       "and \"avg\" for average-pooling.")
420
      .InEnum({"max", "avg"});
K
kexinzhao 已提交
421 422 423 424
  AddAttr<std::vector<int>>(
      "ksize",
      "(vector<int>) The pooling window size(depth, height, "
      "width) of pooling operator. "
C
chengduoZH 已提交
425
      "If global_pooling = true, ksize and paddings will "
K
kexinzhao 已提交
426 427
      "be ignored.");  // TODO(Chengduo): Add checker.
                       // (Currently,
C
fix bug  
chengduoZH 已提交
428
  // TypedAttrChecker don't support vector type.)
C
chengduoZH 已提交
429 430
  AddAttr<bool>(
      "global_pooling",
431 432 433
      "(bool) Whether to use the global pooling. "
      "If global_pooling = true, kernel size and paddings will be ignored. "
      "Default False")
434
      .SetDefault(false);
K
kexinzhao 已提交
435 436 437 438
  AddAttr<std::vector<int>>(
      "strides",
      "(vector<int>, default {1,1,1}) Strides(depth, height, "
      "width) of the pooling operator.")
439 440
      .SetDefault({1, 1, 1});  // TODO(Chengduo): Add checker. (Currently,
                               // TypedAttrChecker don't support vector type.)
C
fix bug  
chengduoZH 已提交
441 442
  AddAttr<std::vector<int>>(
      "paddings",
443 444 445 446
      "(vector<int>, default {0,0,0}), paddings(pad_depth_front, "
      "pad_depth_back, "
      "pad_height_top, pad_height_bottom, pad_width_left, pad_width_right"
      ") of pooling operator. "
C
chengduoZH 已提交
447
      "If global_pooling = true, ksize and paddings will be ignored.")
448 449
      .SetDefault({0, 0, 0});  // TODO(Chengduo): Add checker. (Currently,
                               // TypedAttrChecker don't support vector type.)
450 451
  AddAttr<bool>(
      "exclusive",
452
      "(bool) When true, will exclude the zero-padding in the "
453
      "averaging calculating, otherwise, include the zero-padding. Note, it "
454 455
      "is only used when pooling_type is avg. The default is True. "
      "Default True")
456
      .SetDefault(true);
457 458
  AddAttr<bool>(
      "adaptive",
459
      "(bool) When true, will perform adaptive pooling instead, "
460 461
      "output shape in H and W dimensions will be same as ksize, input data "
      "will be divided into grids specify by ksize averagely and perform "
462 463
      "pooling in each grid area to get output pooling value. "
      "Default False")
464
      .SetDefault(false);
465

466 467
  AddAttr<bool>(
      "use_cudnn",
468
      "(bool) Only used in cudnn kernel, need install cudnn. Default False")
469
      .SetDefault(false);
470 471
  AddAttr<bool>(
      "ceil_mode",
472
      "(bool) Whether to use the ceil function to calculate "
W
wanghaoshuang 已提交
473
      "output height and width. False is the default. If it is set to False, "
474
      "the floor function will be used. Default False")
475
      .SetDefault(false);
476
  AddAttr<bool>("use_mkldnn",
477
                "(bool) Only used in mkldnn kernel. Default False")
478
      .SetDefault(false);
479 480
  AddAttr<std::string>(
      "data_format",
481 482 483
      "(string, default NCDHW) Only used in "
      "An optional string from: \"NDHWC\", \"NCDHW\". "
      "Defaults to \"NDHWC\". Specify the data format of the output data, "
484
      "the input will be transformed automatically. ")
485 486 487 488 489 490 491
      .SetDefault("NCDHW");
  AddAttr<std::string>(
      "padding_algorithm",
      "(string, default \"EXPLICIT\") An optional string from: \"EXPLICIT\","
      "\"SAME\",\"VALID\". Set to \"EXPLICIT\" for explicit padding. "
      "Set to \"SAME\" or \"VALID\" for algorithm of padding. ")
      .SetDefault("EXPLICIT");
492 493
  // TODO(dzhwinter): need to registered layout transform function

494
  AddComment(R"DOC(
495 496
This operation calculates the output based on
the input, pooling_type, pool_size, pool_stride, and pool_padding parameters.
497
Input(X) and output(Out) are in NCDHW or NDHWC format, where N is batch
K
kexinzhao 已提交
498
size, C is the number of channels, and D, H and W are the depth, height and
499 500
width of the feature, respectively. Parameters(pool_size, pool_stride, pool_padding)
hold three integer elements. These three elements represent depth, height and
K
kexinzhao 已提交
501
width, respectively. The input(X) size and output(Out) size may be different.
C
chengduoZH 已提交
502 503 504

Example:
  Input:
K
kexinzhao 已提交
505
       X shape: $(N, C, D_{in}, H_{in}, W_{in})$
C
chengduoZH 已提交
506
  Output:
K
kexinzhao 已提交
507
       Out shape: $(N, C, D_{out}, H_{out}, W_{out})$
508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530

  For pool_padding = "SAME":
       $$
       D_{out} = \\frac{(D_{in} + strides[0] - 1)}{strides[0]}
       $$
       $$
       H_{out} = \\frac{(H_{in} + strides[1] - 1)}{strides[1]}
       $$
       $$
       W_{out} = \\frac{(W_{in} + strides[2] - 1)}{strides[2]}
       $$

  For pool_padding = "VALID":
       $$
       D_{out} = \\frac{(D_{in} - ksize[0] + strides[0])}{strides[0]}
       $$
       $$
       H_{out} = \\frac{(H_{in} - ksize[1] + strides[1])}{strides[1]}
       $$
       $$
       W_{out} = \\frac{(W_{in} - ksize[2] + strides[2])}{strides[2]}
       $$

531
  For ceil_mode = false:
532
       $$
533
       D_{out} = \\frac{(D_{in} - ksize[0] + pad_depth_front + pad_depth_back)}{strides[0]} + 1
534 535
       $$
       $$
536
       H_{out} = \\frac{(H_{in} - ksize[1] + pad_height_top + pad_height_bottom)}{strides[1]} + 1
537 538
       $$
       $$
539
       W_{out} = \\frac{(W_{in} - ksize[2] + pad_width_left + pad_width_right)}{strides[2]} + 1
540
       $$
541
  For ceil_mode = true:
542
       $$
543
       D_{out} = \\frac{(D_{in} - ksize[0] + pad_depth_front + pad_depth_back + strides[0] -1)}{strides[0]} + 1
544 545
       $$
       $$
546
       H_{out} = \\frac{(H_{in} - ksize[1] + pad_height_top + pad_height_bottom + strides[1] -1)}{strides[1]} + 1
547 548
       $$
       $$
549
       W_{out} = \\frac{(W_{in} - ksize[2] + pad_width_left + pad_width_right + strides[2] -1)}{strides[2]} + 1
550
       $$
D
dengkaipeng 已提交
551

552
  For exclusive = false:
553
       $$
554
       dstart = i * strides[0] - pad_depth_front
555 556 557 558 559
       $$
       $$
       dend = dstart + ksize[0]
       $$
       $$
560
       hstart = j * strides[1] - pad_height_top
561 562 563 564 565
       $$
       $$
       hend = hstart + ksize[1]
       $$
       $$
566
       wstart = k * strides[2] -  pad_width_left
567 568 569 570 571 572 573
       $$
       $$
       wend = wstart + ksize[2]
       $$
       $$
       Output(i ,j, k) = \\frac{sum(Input[dstart:dend, hstart:hend, wstart:wend])}{ksize[0] * ksize[1] * ksize[2]}
       $$
574

575
  For exclusive = true:
576
       $$
577
       dstart = max(0, i * strides[0] - pad_depth_front)
578 579 580 581 582
       $$
       $$
       dend = min(D, dstart + ksize[0])
       $$
       $$
583 584 585
       hstart = max(0, j * strides[1] - pad_height_top)
       $$
       $$
586 587 588
       hend = min(H, hstart + ksize[1])
       $$
       $$
589
       wstart = max(0, k * strides[2] - pad_width_left)
590 591 592 593 594 595 596
       $$
       $$
       wend = min(W, wstart + ksize[2])
       $$
       $$
       Output(i ,j, k) = \\frac{sum(Input[dstart:dend, hstart:hend, wstart:wend])}{(dend - dstart) * (hend - hstart) * (wend - wstart)}
       $$
K
kexinzhao 已提交
597

598
)DOC");
599
}
600 601 602 603 604
}  // namespace operators
}  // namespace paddle

namespace ops = paddle::operators;

Y
Yang Yang 已提交
605
REGISTER_OPERATOR(pool2d, ops::PoolOp, ops::Pool2dOpMaker,
C
chengduo 已提交
606
                  ops::PoolOpInferVarType,
607 608
                  paddle::framework::DefaultGradOpDescMaker<true>);
REGISTER_OPERATOR(pool2d_grad, ops::PoolOpGrad);
609

Q
QI JUN 已提交
610 611 612 613 614
REGISTER_OP_CPU_KERNEL(
    pool2d, ops::PoolKernel<paddle::platform::CPUDeviceContext, float>,
    ops::PoolKernel<paddle::platform::CPUDeviceContext, double>);
REGISTER_OP_CPU_KERNEL(
    pool2d_grad, ops::PoolGradKernel<paddle::platform::CPUDeviceContext, float>,
615
    ops::PoolGradKernel<paddle::platform::CPUDeviceContext, double>);
616

Y
Yang Yang 已提交
617
REGISTER_OPERATOR(pool3d, ops::PoolOp, ops::Pool3dOpMaker,
C
chengduo 已提交
618
                  ops::PoolOpInferVarType,
619 620
                  paddle::framework::DefaultGradOpDescMaker<true>);
REGISTER_OPERATOR(pool3d_grad, ops::PoolOpGrad);
621

Q
QI JUN 已提交
622 623 624 625 626 627
REGISTER_OP_CPU_KERNEL(
    pool3d, ops::PoolKernel<paddle::platform::CPUDeviceContext, float>,
    ops::PoolKernel<paddle::platform::CPUDeviceContext, double>);
REGISTER_OP_CPU_KERNEL(
    pool3d_grad, ops::PoolGradKernel<paddle::platform::CPUDeviceContext, float>,
    ops::PoolGradKernel<paddle::platform::CPUDeviceContext, double>);