pool_op.cc 22.5 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
  PADDLE_ENFORCE_GT(
      output_size, 0,
41 42 43 44
      "ShapeError: the output size must be greater than 0. But received: "
      "output_size = %d due to the settings of input_size(%d), padding(%d,%d), "
      "k_size(%d) and stride(%d). Please check again!",
      output_size, input_size, padding_1, padding_2, filter_size, stride);
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
  auto in_x_dims = ctx->GetInputDim("X");
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
  PADDLE_ENFORCE_EQ(
      in_x_dims.size() == 4 || in_x_dims.size() == 5, true,
      "ShapeError: the input of Op(pool) should be 4-D or 5-D Tensor. But "
      "received: %u-D Tensor and it's shape is [%s].",
      in_x_dims.size(), in_x_dims);

  PADDLE_ENFORCE_EQ(
      in_x_dims.size() - ksize.size(), 2U,
      "ShapeError: the dimension of input minus the size of "
      "Attr(ksize) must be euqal to 2 in Op(pool). "
      "But received: the dimension of input minus the size "
      "of Attr(ksize) is %d, the "
      "input's dimension is %d, the shape of input "
      "is [%s], the Attr(ksize)'s size is %d, the Attr(ksize) is [%s].",
      in_x_dims.size() - ksize.size(), in_x_dims.size(), in_x_dims,
      ksize.size(), framework::make_ddim(ksize));
82 83

  PADDLE_ENFORCE_EQ(ksize.size(), strides.size(),
84 85 86 87 88 89
                    "ShapeError: the size of Attr(ksize) and Attr(strides) in "
                    "Op(pool) must be equal. "
                    "But received: Attr(ksize)'s size is %d, Attr(strides)'s "
                    "size is %d, Attr(ksize) is [%s], Attr(strides)is [%s].",
                    ksize.size(), strides.size(), framework::make_ddim(ksize),
                    framework::make_ddim(strides));
90

91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107
  const bool channel_last = (data_format == "NHWC" || data_format == "NDHWC");

  // 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;
108 109 110
  if (adaptive) {
    output_shape.insert(output_shape.end(), ksize.begin(), ksize.end());
  } else {
111
    for (int i = 0; i < data_dims.size(); ++i) {
112
      if ((!ctx->IsRuntime()) && (data_dims[i] < 0)) {
113
        output_shape.push_back(data_dims[i]);
K
Kaipeng Deng 已提交
114
      } else {
115 116 117
        output_shape.push_back(
            PoolOutputSize(data_dims[i], ksize[i], paddings[2 * i],
                           paddings[2 * i + 1], strides[i], ceil_mode));
K
Kaipeng Deng 已提交
118
      }
119
    }
120
  }
121 122 123 124 125 126 127 128 129 130

  // 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]);
  }

131
  ctx->SetOutputDim("Out", framework::make_ddim(output_shape));
Y
Yang Yu 已提交
132
  ctx->ShareLoD("X", "Out");
133 134
}

135
framework::OpKernelType PoolOp::GetExpectedKernelType(
C
chengduo 已提交
136
    const framework::ExecutionContext& ctx) const {
137
  framework::LibraryType library_{framework::LibraryType::kPlain};
138
  std::string data_format = "AnyLayout";
M
mozga-intel 已提交
139 140
  framework::DataLayout layout_ = framework::StringToDataLayout(data_format);

C
chengduoZH 已提交
141
#ifdef PADDLE_WITH_CUDA
142 143
  if (platform::CanCUDNNBeUsed(ctx)) {
    library_ = framework::LibraryType::kCUDNN;
C
chengduoZH 已提交
144 145
  }
#endif
146 147 148 149
#ifdef PADDLE_WITH_MKLDNN
  if (library_ == framework::LibraryType::kPlain &&
      platform::CanMKLDNNBeUsed(ctx)) {
    library_ = framework::LibraryType::kMKLDNN;
M
mozga-intel 已提交
150
    layout_ = framework::DataLayout::kMKLDNN;
151
  }
152
#endif
153

154 155 156
  return framework::OpKernelType(
      OperatorWithKernel::IndicateVarDataType(ctx, "X"), ctx.GetPlace(),
      layout_, library_);
157 158
}

C
chengduo 已提交
159
void PoolOpGrad::InferShape(framework::InferShapeContext* ctx) const {
160 161 162
  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.");
163 164 165
  ctx->SetOutputDim(framework::GradVarName("X"), ctx->GetInputDim("X"));
}

166
framework::OpKernelType PoolOpGrad::GetExpectedKernelType(
C
chengduo 已提交
167
    const framework::ExecutionContext& ctx) const {
168
  framework::LibraryType library_{framework::LibraryType::kPlain};
169
  std::string data_format = "AnyLayout";
M
mozga-intel 已提交
170 171
  framework::DataLayout layout_ = framework::StringToDataLayout(data_format);

C
chengduoZH 已提交
172
#ifdef PADDLE_WITH_CUDA
173 174
  if (platform::CanCUDNNBeUsed(ctx)) {
    library_ = framework::LibraryType::kCUDNN;
C
chengduoZH 已提交
175 176
  }
#endif
177 178 179 180
#ifdef PADDLE_WITH_MKLDNN
  if (library_ == framework::LibraryType::kPlain &&
      platform::CanMKLDNNBeUsed(ctx)) {
    library_ = framework::LibraryType::kMKLDNN;
M
mozga-intel 已提交
181
    layout_ = framework::DataLayout::kMKLDNN;
182
  }
183
#endif
184

185
  auto input_data_type = OperatorWithKernel::IndicateVarDataType(ctx, "X");
K
Kexin Zhao 已提交
186 187 188 189 190 191
  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_);
192 193
}

Y
Yu Yang 已提交
194
void Pool2dOpMaker::Make() {
195 196
  AddInput(
      "X",
C
chengduoZH 已提交
197
      "(Tensor) The input tensor of pooling operator. "
K
kexinzhao 已提交
198 199 200
      "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.");
201
  AddOutput("Out",
K
kexinzhao 已提交
202 203 204 205
            "(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, "
206
            "and W is the width of the feature.");
207

C
chengduoZH 已提交
208
  AddAttr<std::string>("pooling_type",
C
chengduoZH 已提交
209 210
                       "(string), pooling type, can be \"max\" for max-pooling "
                       "and \"avg\" for average-pooling.")
211
      .InEnum({"max", "avg"});
C
fix bug  
chengduoZH 已提交
212
  AddAttr<std::vector<int>>("ksize",
K
kexinzhao 已提交
213 214
                            "(vector<int>) The pooling window "
                            "size(height, width) of the pooling operator. "
C
chengduoZH 已提交
215
                            "If global_pooling = true, ksize and paddings will "
C
fix bug  
chengduoZH 已提交
216 217
                            "be ignored.");  // TODO(Chengduo): Add checker.
                                             // (Currently,
C
fix doc  
chengduoZH 已提交
218
  // TypedAttrChecker don't support vector type.)
219 220
  AddAttr<bool>(
      "global_pooling",
K
Kaipeng Deng 已提交
221 222 223
      "(bool) Whether to use the global pooling. "
      "If global_pooling = true, kernel size and paddings will be ignored. "
      "Default False.")
224
      .SetDefault(false);
K
kexinzhao 已提交
225 226 227
  AddAttr<std::vector<int>>("strides",
                            "(vector<int>, default {1, 1}), strides(height, "
                            "width) of pooling operator.")
228 229
      .SetDefault({1, 1});
  // TODO(Chengduo): Add checker. (Currently,
C
fix doc  
chengduoZH 已提交
230 231 232
  // TypedAttrChecker don't support vector type.)
  AddAttr<std::vector<int>>(
      "paddings",
233 234
      "(vector<int>, default {0,0}), paddings(height_top, height_bottom, "
      "width_left, wifth_right) of pooling operator."
235
      "If global_pooling = true, paddings and kernel size will be ignored.")
236
      .SetDefault({0, 0});
237 238
  AddAttr<bool>(
      "exclusive",
K
Kaipeng Deng 已提交
239
      "(bool) When true, will exclude the zero-padding in the "
240
      "averaging calculating, otherwise, include the zero-padding. Note, it "
K
Kaipeng Deng 已提交
241 242
      "is only used when pooling_type is avg. The default is True. "
      "Default True.")
243
      .SetDefault(true);
244 245
  AddAttr<bool>(
      "adaptive",
K
Kaipeng Deng 已提交
246
      "(bool) When true, will perform adaptive pooling instead, "
247 248
      "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 "
K
Kaipeng Deng 已提交
249 250
      "pooling in each grid area to get output pooling value. "
      "Default False.")
251 252
      .SetDefault(false);

253 254
  AddAttr<bool>(
      "use_cudnn",
K
Kaipeng Deng 已提交
255
      "(bool) Only used in cudnn kernel, need install cudnn. Default False")
256
      .SetDefault(false);
257 258
  AddAttr<bool>(
      "ceil_mode",
K
Kaipeng Deng 已提交
259
      "(bool) Whether to use the ceil function to calculate "
W
wanghaoshuang 已提交
260
      "output height and width. False is the default. If it is set to False, "
K
Kaipeng Deng 已提交
261
      "the floor function will be used. Default False")
262
      .SetDefault(false);
263
  AddAttr<bool>("use_mkldnn",
K
Kaipeng Deng 已提交
264
                "(bool) Only used in mkldnn kernel. Default False")
265
      .SetDefault(false);
266
  AddAttr<bool>("use_quantizer",
K
Kaipeng Deng 已提交
267
                "(bool) "
268 269
                "Set to true for operators that should be quantized and use "
                "int8 kernel. "
K
Kaipeng Deng 已提交
270
                "Only used on CPU. Default False")
271
      .SetDefault(false);
272 273 274 275 276 277
  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. ")
278
      .SetDefault("NCHW");
279 280 281 282 283
  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);

284 285 286 287 288 289
  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");
290
  // TODO(dzhwinter): need to registered layout transform function
291 292

  AddComment(R"DOC(
K
Kaipeng Deng 已提交
293 294 295
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 已提交
296
number of channels, H is the height of the feature, and W is the width of the feature.
K
Kaipeng Deng 已提交
297
Parameters(pool_size, pool_stride, pool_padding) hold two integer elements.
C
fix doc  
chengduoZH 已提交
298
These two elements represent height and width, respectively.
C
chengduoZH 已提交
299 300
The input(X) size and output(Out) size may be different.

301
Example:
F
fengjiayi 已提交
302

C
chengduoZH 已提交
303
  Input:
F
fengjiayi 已提交
304

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

C
chengduoZH 已提交
307
  Output:
F
fengjiayi 已提交
308

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

311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326
  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]}
       $$

327 328
  For ceil_mode = false:
       $$
329
       H_{out} = \\frac{(H_{in} - ksize[0] + pad_height_top + pad_height_bottom}{strides[0]} + 1
F
fengjiayi 已提交
330 331
       $$
       $$
332
       W_{out} = \\frac{(W_{in} - ksize[1] + pad_width_left + pad_width_right}{strides[1]} + 1
K
kexinzhao 已提交
333
       $$
334

335 336
  For ceil_mode = true:
       $$
337
       H_{out} = \\frac{(H_{in} - ksize[0] + pad_height_top + pad_height_bottom + strides[0] - 1)}{strides[0]} + 1
F
fengjiayi 已提交
338 339
       $$
       $$
340
       W_{out} = \\frac{(W_{in} - ksize[1] + pad_width_left + pad_width_right + strides[1] - 1)}{strides[1]} + 1
341
       $$
K
kexinzhao 已提交
342

343
  For exclusive = false:
344
       $$
345
       hstart = i * strides[0] - pad_height_top
346 347 348 349 350
       $$
       $$
       hend = hstart + ksize[0]
       $$
       $$
351
       wstart = j * strides[1] - pad_width_left
352 353 354 355 356 357 358
       $$
       $$
       wend = wstart + ksize[1]
       $$
       $$
       Output(i ,j) = \\frac{sum(Input[hstart:hend, wstart:wend])}{ksize[0] * ksize[1]}
       $$
359

360
  For exclusive = true:
361
       $$
362
       hstart = max(0, i * strides[0] - pad_height_top)
363 364 365 366 367
       $$
       $$
       hend = min(H, hstart + ksize[0])
       $$
       $$
368
       wstart = max(0, j * strides[1] - pad_width_left)
369 370 371 372 373 374 375
       $$
       $$
       wend = min(W, wstart + ksize[1])
       $$
       $$
       Output(i ,j) = \\frac{sum(Input[hstart:hend, wstart:wend])}{(hend - hstart) * (wend - wstart)}
       $$
376

377
)DOC");
378 379
}

C
chengduo 已提交
380 381 382 383 384 385 386 387
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 已提交
388
void Pool3dOpMaker::Make() {
K
kexinzhao 已提交
389 390
  AddInput("X",
           "(Tensor) The input tensor of pooling operator. "
391 392
           "The format of input tensor is NCDHW or NDHWC, where N is batch "
           "size, C is "
K
kexinzhao 已提交
393 394 395
           "the number of channels, and D, H and W is the depth, height and "
           "width of "
           "the feature, respectively.");
396
  AddOutput("Out",
C
chengduoZH 已提交
397
            "(Tensor) The output tensor of pooling operator."
398
            "The format of output tensor is also NCDHW or NDHWC, "
K
kexinzhao 已提交
399 400
            "where N is batch size, C is "
            "the number of channels, and D, H and W is the depth, height and "
401
            "width of the feature, respectively.");
402

C
chengduoZH 已提交
403
  AddAttr<std::string>("pooling_type",
K
kexinzhao 已提交
404
                       "(string) Pooling type, can be \"max\" for max-pooling "
C
chengduoZH 已提交
405
                       "and \"avg\" for average-pooling.")
406
      .InEnum({"max", "avg"});
K
kexinzhao 已提交
407 408 409 410
  AddAttr<std::vector<int>>(
      "ksize",
      "(vector<int>) The pooling window size(depth, height, "
      "width) of pooling operator. "
C
chengduoZH 已提交
411
      "If global_pooling = true, ksize and paddings will "
K
kexinzhao 已提交
412 413
      "be ignored.");  // TODO(Chengduo): Add checker.
                       // (Currently,
C
fix bug  
chengduoZH 已提交
414
  // TypedAttrChecker don't support vector type.)
C
chengduoZH 已提交
415 416
  AddAttr<bool>(
      "global_pooling",
K
Kaipeng Deng 已提交
417 418 419
      "(bool) Whether to use the global pooling. "
      "If global_pooling = true, kernel size and paddings will be ignored. "
      "Default False")
420
      .SetDefault(false);
K
kexinzhao 已提交
421 422 423 424
  AddAttr<std::vector<int>>(
      "strides",
      "(vector<int>, default {1,1,1}) Strides(depth, height, "
      "width) of the pooling operator.")
425 426
      .SetDefault({1, 1, 1});  // TODO(Chengduo): Add checker. (Currently,
                               // TypedAttrChecker don't support vector type.)
C
fix bug  
chengduoZH 已提交
427 428
  AddAttr<std::vector<int>>(
      "paddings",
429 430 431 432
      "(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 已提交
433
      "If global_pooling = true, ksize and paddings will be ignored.")
434 435
      .SetDefault({0, 0, 0});  // TODO(Chengduo): Add checker. (Currently,
                               // TypedAttrChecker don't support vector type.)
436 437
  AddAttr<bool>(
      "exclusive",
K
Kaipeng Deng 已提交
438
      "(bool) When true, will exclude the zero-padding in the "
439
      "averaging calculating, otherwise, include the zero-padding. Note, it "
K
Kaipeng Deng 已提交
440 441
      "is only used when pooling_type is avg. The default is True. "
      "Default True")
442
      .SetDefault(true);
443 444
  AddAttr<bool>(
      "adaptive",
K
Kaipeng Deng 已提交
445
      "(bool) When true, will perform adaptive pooling instead, "
446 447
      "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 "
K
Kaipeng Deng 已提交
448 449
      "pooling in each grid area to get output pooling value. "
      "Default False")
450
      .SetDefault(false);
451

452 453
  AddAttr<bool>(
      "use_cudnn",
K
Kaipeng Deng 已提交
454
      "(bool) Only used in cudnn kernel, need install cudnn. Default False")
455
      .SetDefault(false);
456 457
  AddAttr<bool>(
      "ceil_mode",
K
Kaipeng Deng 已提交
458
      "(bool) Whether to use the ceil function to calculate "
W
wanghaoshuang 已提交
459
      "output height and width. False is the default. If it is set to False, "
K
Kaipeng Deng 已提交
460
      "the floor function will be used. Default False")
461
      .SetDefault(false);
462
  AddAttr<bool>("use_mkldnn",
K
Kaipeng Deng 已提交
463
                "(bool) Only used in mkldnn kernel. Default False")
464
      .SetDefault(false);
465 466
  AddAttr<std::string>(
      "data_format",
467 468 469
      "(string, default NCDHW) Only used in "
      "An optional string from: \"NDHWC\", \"NCDHW\". "
      "Defaults to \"NDHWC\". Specify the data format of the output data, "
470
      "the input will be transformed automatically. ")
471 472 473 474 475 476 477
      .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");
478 479
  // TODO(dzhwinter): need to registered layout transform function

480
  AddComment(R"DOC(
K
Kaipeng Deng 已提交
481 482
This operation calculates the output based on
the input, pooling_type, pool_size, pool_stride, and pool_padding parameters.
483
Input(X) and output(Out) are in NCDHW or NDHWC format, where N is batch
K
kexinzhao 已提交
484
size, C is the number of channels, and D, H and W are the depth, height and
K
Kaipeng Deng 已提交
485 486
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 已提交
487
width, respectively. The input(X) size and output(Out) size may be different.
C
chengduoZH 已提交
488 489 490

Example:
  Input:
K
kexinzhao 已提交
491
       X shape: $(N, C, D_{in}, H_{in}, W_{in})$
C
chengduoZH 已提交
492
  Output:
K
kexinzhao 已提交
493
       Out shape: $(N, C, D_{out}, H_{out}, W_{out})$
494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516

  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]}
       $$

517
  For ceil_mode = false:
518
       $$
519
       D_{out} = \\frac{(D_{in} - ksize[0] + pad_depth_front + pad_depth_back)}{strides[0]} + 1
520 521
       $$
       $$
522
       H_{out} = \\frac{(H_{in} - ksize[1] + pad_height_top + pad_height_bottom)}{strides[1]} + 1
523 524
       $$
       $$
525
       W_{out} = \\frac{(W_{in} - ksize[2] + pad_width_left + pad_width_right)}{strides[2]} + 1
526
       $$
527
  For ceil_mode = true:
528
       $$
529
       D_{out} = \\frac{(D_{in} - ksize[0] + pad_depth_front + pad_depth_back + strides[0] -1)}{strides[0]} + 1
530 531
       $$
       $$
532
       H_{out} = \\frac{(H_{in} - ksize[1] + pad_height_top + pad_height_bottom + strides[1] -1)}{strides[1]} + 1
533 534
       $$
       $$
535
       W_{out} = \\frac{(W_{in} - ksize[2] + pad_width_left + pad_width_right + strides[2] -1)}{strides[2]} + 1
536
       $$
D
dengkaipeng 已提交
537

538
  For exclusive = false:
539
       $$
540
       dstart = i * strides[0] - pad_depth_front
541 542 543 544 545
       $$
       $$
       dend = dstart + ksize[0]
       $$
       $$
546
       hstart = j * strides[1] - pad_height_top
547 548 549 550 551
       $$
       $$
       hend = hstart + ksize[1]
       $$
       $$
552
       wstart = k * strides[2] -  pad_width_left
553 554 555 556 557 558 559
       $$
       $$
       wend = wstart + ksize[2]
       $$
       $$
       Output(i ,j, k) = \\frac{sum(Input[dstart:dend, hstart:hend, wstart:wend])}{ksize[0] * ksize[1] * ksize[2]}
       $$
560

561
  For exclusive = true:
562
       $$
563
       dstart = max(0, i * strides[0] - pad_depth_front)
564 565 566 567 568
       $$
       $$
       dend = min(D, dstart + ksize[0])
       $$
       $$
569 570 571
       hstart = max(0, j * strides[1] - pad_height_top)
       $$
       $$
572 573 574
       hend = min(H, hstart + ksize[1])
       $$
       $$
575
       wstart = max(0, k * strides[2] - pad_width_left)
576 577 578 579 580 581 582
       $$
       $$
       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 已提交
583

584
)DOC");
585
}
586 587 588 589 590
}  // namespace operators
}  // namespace paddle

namespace ops = paddle::operators;

H
hong 已提交
591 592 593 594
REGISTER_OPERATOR(
    pool2d, ops::PoolOp, ops::Pool2dOpMaker, ops::PoolOpInferVarType,
    paddle::framework::DefaultGradOpMaker<paddle::framework::OpDesc, true>,
    paddle::framework::DefaultGradOpMaker<paddle::imperative::OpBase, true>);
595
REGISTER_OPERATOR(pool2d_grad, ops::PoolOpGrad);
596

Q
QI JUN 已提交
597 598 599 600 601
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>,
602
    ops::PoolGradKernel<paddle::platform::CPUDeviceContext, double>);
603

H
hong 已提交
604 605 606 607
REGISTER_OPERATOR(
    pool3d, ops::PoolOp, ops::Pool3dOpMaker, ops::PoolOpInferVarType,
    paddle::framework::DefaultGradOpMaker<paddle::framework::OpDesc, true>,
    paddle::framework::DefaultGradOpMaker<paddle::imperative::OpBase, true>);
608
REGISTER_OPERATOR(pool3d_grad, ops::PoolOpGrad);
609

Q
QI JUN 已提交
610 611 612 613 614 615
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>);