pool_op.cc 22.0 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 78 79 80 81 82 83 84 85 86 87 88 89 90
  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;
91 92 93
  if (adaptive) {
    output_shape.insert(output_shape.end(), ksize.begin(), ksize.end());
  } else {
94 95
    for (size_t i = 0; i < data_dims.size(); ++i) {
      if ((!ctx->IsRuntime()) && (data_dims[i] < 0)) {
96
        output_shape.push_back(data_dims[i]);
K
Kaipeng Deng 已提交
97
      } else {
98 99 100
        output_shape.push_back(
            PoolOutputSize(data_dims[i], ksize[i], paddings[2 * i],
                           paddings[2 * i + 1], strides[i], ceil_mode));
K
Kaipeng Deng 已提交
101
      }
102
    }
103
  }
104 105 106 107 108 109 110 111 112 113

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

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

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

C
chengduoZH 已提交
124
#ifdef PADDLE_WITH_CUDA
125 126
  if (platform::CanCUDNNBeUsed(ctx)) {
    library_ = framework::LibraryType::kCUDNN;
C
chengduoZH 已提交
127 128
  }
#endif
129 130 131
#ifdef PADDLE_WITH_MKLDNN
  if (library_ == framework::LibraryType::kPlain &&
      platform::CanMKLDNNBeUsed(ctx)) {
132 133 134 135 136 137
    // 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"));
138
    library_ = framework::LibraryType::kMKLDNN;
M
mozga-intel 已提交
139
    layout_ = framework::DataLayout::kMKLDNN;
140
  }
141
#endif
142

143 144 145
  return framework::OpKernelType(
      OperatorWithKernel::IndicateVarDataType(ctx, "X"), ctx.GetPlace(),
      layout_, library_);
146 147
}

C
chengduo 已提交
148
void PoolOpGrad::InferShape(framework::InferShapeContext* ctx) const {
149 150 151
  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.");
152 153 154
  ctx->SetOutputDim(framework::GradVarName("X"), ctx->GetInputDim("X"));
}

155
framework::OpKernelType PoolOpGrad::GetExpectedKernelType(
C
chengduo 已提交
156
    const framework::ExecutionContext& ctx) const {
157
  framework::LibraryType library_{framework::LibraryType::kPlain};
158
  std::string data_format = "AnyLayout";
M
mozga-intel 已提交
159 160
  framework::DataLayout layout_ = framework::StringToDataLayout(data_format);

C
chengduoZH 已提交
161
#ifdef PADDLE_WITH_CUDA
162 163
  if (platform::CanCUDNNBeUsed(ctx)) {
    library_ = framework::LibraryType::kCUDNN;
C
chengduoZH 已提交
164 165
  }
#endif
166 167 168
#ifdef PADDLE_WITH_MKLDNN
  if (library_ == framework::LibraryType::kPlain &&
      platform::CanMKLDNNBeUsed(ctx)) {
169 170 171 172 173 174
    // 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"));
175
    library_ = framework::LibraryType::kMKLDNN;
M
mozga-intel 已提交
176
    layout_ = framework::DataLayout::kMKLDNN;
177
  }
178
#endif
179

180
  auto input_data_type = OperatorWithKernel::IndicateVarDataType(ctx, "X");
K
Kexin Zhao 已提交
181 182 183 184 185 186
  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_);
187 188
}

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

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

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

279 280 281 282 283 284
  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");
285
  // TODO(dzhwinter): need to registered layout transform function
286 287

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

296
Example:
F
fengjiayi 已提交
297

C
chengduoZH 已提交
298
  Input:
F
fengjiayi 已提交
299

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

C
chengduoZH 已提交
302
  Output:
F
fengjiayi 已提交
303

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

306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321
  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]}
       $$

322 323
  For ceil_mode = false:
       $$
324
       H_{out} = \\frac{(H_{in} - ksize[0] + pad_height_top + pad_height_bottom}{strides[0]} + 1
F
fengjiayi 已提交
325 326
       $$
       $$
327
       W_{out} = \\frac{(W_{in} - ksize[1] + pad_width_left + pad_width_right}{strides[1]} + 1
K
kexinzhao 已提交
328
       $$
329

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

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

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

372
)DOC");
373 374
}

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

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

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

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

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

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

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

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

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

579
)DOC");
580
}
581 582 583 584 585
}  // namespace operators
}  // namespace paddle

namespace ops = paddle::operators;

Y
Yang Yang 已提交
586
REGISTER_OPERATOR(pool2d, ops::PoolOp, ops::Pool2dOpMaker,
C
chengduo 已提交
587
                  ops::PoolOpInferVarType,
588 589
                  paddle::framework::DefaultGradOpDescMaker<true>);
REGISTER_OPERATOR(pool2d_grad, ops::PoolOpGrad);
590

Q
QI JUN 已提交
591 592 593 594 595
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>,
596
    ops::PoolGradKernel<paddle::platform::CPUDeviceContext, double>);
597

Y
Yang Yang 已提交
598
REGISTER_OPERATOR(pool3d, ops::PoolOp, ops::Pool3dOpMaker,
C
chengduo 已提交
599
                  ops::PoolOpInferVarType,
600 601
                  paddle::framework::DefaultGradOpDescMaker<true>);
REGISTER_OPERATOR(pool3d_grad, ops::PoolOpGrad);
602

Q
QI JUN 已提交
603 604 605 606 607 608
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>);