Skip to content

Commit 229bae8

Browse files
author
feng_shuai
authored
Pool3d 2.0 (#36545)
1 parent cea1ba8 commit 229bae8

File tree

11 files changed

+1248
-1
lines changed

11 files changed

+1248
-1
lines changed

paddle/fluid/inference/api/analysis_predictor.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1415,6 +1415,7 @@ USE_TRT_CONVERTER(tile);
14151415
USE_TRT_CONVERTER(conv3d);
14161416
USE_TRT_CONVERTER(conv3d_transpose);
14171417
USE_TRT_CONVERTER(mish);
1418+
USE_TRT_CONVERTER(pool3d)
14181419
#endif
14191420

14201421
namespace paddle_infer {

paddle/fluid/inference/tensorrt/convert/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ nv_library(tensorrt_converter
1919
conv3d_op.cc
2020
mish_op.cc
2121
nearest_interp_v2_op.cc
22+
pool3d_op.cc
2223
DEPS tensorrt_engine tensorrt_plugin operator scope framework_proto op_registry)
2324

2425
nv_test(test_op_converter SRCS test_op_converter.cc DEPS
Lines changed: 228 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,228 @@
1+
/* Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved.
2+
3+
Licensed under the Apache License, Version 2.0 (the "License");
4+
you may not use this file except in compliance with the License.
5+
You may obtain a copy of the License at
6+
7+
http://www.apache.org/licenses/LICENSE-2.0
8+
9+
Unless required by applicable law or agreed to in writing, software
10+
distributed under the License is distributed on an "AS IS" BASIS,
11+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
See the License for the specific language governing permissions and
13+
limitations under the License. */
14+
#include "paddle/fluid/inference/tensorrt/convert/op_converter.h"
15+
#include "paddle/fluid/inference/tensorrt/plugin/pool3d_op_plugin.h"
16+
17+
namespace paddle {
18+
namespace framework {
19+
class Scope;
20+
21+
namespace proto {
22+
class OpDesc;
23+
} // namespace proto
24+
} // namespace framework
25+
} // namespace paddle
26+
27+
namespace paddle {
28+
namespace inference {
29+
namespace tensorrt {
30+
31+
inline void DealCeilMode(const nvinfer1::Dims &input_shape,
32+
std::vector<int> ksize, std::vector<int> strides,
33+
std::vector<int> paddings, nvinfer1::DimsCHW *pre_pad,
34+
nvinfer1::DimsCHW *post_pad, int input_dims) {
35+
int input_depth = input_shape.d[input_dims - 3];
36+
int input_height = input_shape.d[input_dims - 2];
37+
int input_width = input_shape.d[input_dims - 1];
38+
39+
int floor_d_output_size =
40+
(input_depth - ksize[0] + 2 * paddings[0]) / strides[0] + 1;
41+
int ceil_d_output_size =
42+
(input_depth - ksize[0] + 2 * paddings[0] + strides[0] - 1) / strides[0] +
43+
1;
44+
45+
int floor_h_output_size =
46+
(input_height - ksize[1] + 2 * paddings[1]) / strides[1] + 1;
47+
int ceil_h_output_size =
48+
(input_height - ksize[1] + 2 * paddings[1] + strides[1] - 1) /
49+
strides[1] +
50+
1;
51+
52+
int floor_w_output_size =
53+
(input_width - ksize[2] + 2 * paddings[2]) / strides[2] + 1;
54+
int ceil_w_output_size =
55+
(input_width - ksize[2] + 2 * paddings[2] + strides[2] - 1) / strides[2] +
56+
1;
57+
58+
if (floor_d_output_size != ceil_d_output_size) {
59+
post_pad->c() = strides[0] - 1;
60+
}
61+
62+
if (floor_h_output_size != ceil_h_output_size) {
63+
post_pad->h() = strides[1] - 1;
64+
}
65+
66+
if (floor_w_output_size != ceil_w_output_size) {
67+
post_pad->w() = strides[2] - 1;
68+
}
69+
}
70+
71+
class Pool3dOpConverter : public OpConverter {
72+
public:
73+
void operator()(const framework::proto::OpDesc &op,
74+
const framework::Scope &scope, bool test_mode) override {
75+
VLOG(4)
76+
<< "convert a fluid pool3d op to tensorrt pool3d layer without bias";
77+
framework::OpDesc op_desc(op, nullptr);
78+
auto *input1 = engine_->GetITensor(op_desc.Input("X")[0]);
79+
nvinfer1::Dims input_shape = input1->getDimensions();
80+
int input_dims = input_shape.nbDims;
81+
82+
bool global_pooling =
83+
BOOST_GET_CONST(bool, op_desc.GetAttr("global_pooling"));
84+
std::string pool_type =
85+
BOOST_GET_CONST(std::string, op_desc.GetAttr("pooling_type"));
86+
std::vector<int> ksize =
87+
BOOST_GET_CONST(std::vector<int>, op_desc.GetAttr("ksize"));
88+
std::vector<int> strides =
89+
BOOST_GET_CONST(std::vector<int>, op_desc.GetAttr("strides"));
90+
std::vector<int> paddings =
91+
BOOST_GET_CONST(std::vector<int>, op_desc.GetAttr("paddings"));
92+
bool exclusive = op_desc.HasAttr("exclusive")
93+
? BOOST_GET_CONST(bool, op_desc.GetAttr("exclusive"))
94+
: true;
95+
bool ceil_mode = BOOST_GET_CONST(bool, op_desc.GetAttr("ceil_mode"));
96+
bool adaptive = false;
97+
if (op_desc.HasAttr("adaptive"))
98+
adaptive = BOOST_GET_CONST(bool, op_desc.GetAttr("adaptive"));
99+
std::string padding_algorithm = "EXPLICIT";
100+
if (op_desc.HasAttr("padding_algorithm"))
101+
padding_algorithm =
102+
BOOST_GET_CONST(std::string, op_desc.GetAttr("padding_algorithm"));
103+
if (padding_algorithm == "VALID" || padding_algorithm == "SAME") {
104+
std::fill(paddings.begin(), paddings.end(), 0);
105+
}
106+
107+
nvinfer1::PoolingType nv_pool_type = nvinfer1::PoolingType::kMAX;
108+
nvinfer1::ReduceOperation reduce_operation =
109+
nvinfer1::ReduceOperation::kMAX;
110+
plugin::Pool3DPlugin::Pool3DType plugin_pool_type =
111+
plugin::Pool3DPlugin::Pool3DType::max;
112+
if (pool_type == "max") {
113+
nv_pool_type = nvinfer1::PoolingType::kMAX;
114+
reduce_operation = nvinfer1::ReduceOperation::kMAX;
115+
plugin_pool_type = plugin::Pool3DPlugin::Pool3DType::max;
116+
} else if (pool_type == "avg") {
117+
nv_pool_type = nvinfer1::PoolingType::kAVERAGE;
118+
reduce_operation = nvinfer1::ReduceOperation::kAVG;
119+
plugin_pool_type = plugin::Pool3DPlugin::Pool3DType::avg;
120+
}
121+
nvinfer1::DimsCHW nv_ksize(ksize[0], ksize[1], ksize[2]);
122+
nvinfer1::DimsCHW nv_strides(strides[0], strides[1], strides[2]);
123+
nvinfer1::DimsCHW nv_paddings(paddings[0], paddings[1], paddings[2]);
124+
nvinfer1::ILayer *layer = nullptr;
125+
if (op_desc.HasAttr("enable_int8")) {
126+
CHECK(op_desc.HasAttr("X_scale"));
127+
float input_scale = BOOST_GET_CONST(float, op_desc.GetAttr("X_scale"));
128+
engine_->SetTensorDynamicRange(input1, input_scale);
129+
}
130+
131+
if (engine_->with_dynamic_shape()) {
132+
if (!adaptive && !global_pooling && !ceil_mode) {
133+
auto *pool_layer = TRT_ENGINE_ADD_LAYER(engine_, PoolingNd, *input1,
134+
nv_pool_type, nv_ksize);
135+
pool_layer->setStrideNd(nv_strides);
136+
pool_layer->setPaddingNd(nv_paddings);
137+
pool_layer->setAverageCountExcludesPadding(exclusive);
138+
layer = pool_layer;
139+
} else if (global_pooling) {
140+
auto *reduce_layer = TRT_ENGINE_ADD_LAYER(engine_, Reduce, *input1,
141+
reduce_operation, 28, true);
142+
layer = reduce_layer;
143+
} else {
144+
plugin::Pool3DPluginDynamic *plugin = new plugin::Pool3DPluginDynamic(
145+
ceil_mode, pool_type, adaptive, ksize, strides, paddings,
146+
global_pooling);
147+
layer = engine_->AddDynamicPlugin(&input1, 1, plugin);
148+
}
149+
auto output_name = op_desc.Output("Out")[0];
150+
layer->setName(("pool3d (Output: " + output_name + ")").c_str());
151+
layer->getOutput(0)->setName(output_name.c_str());
152+
engine_->SetITensor(output_name, layer->getOutput(0));
153+
if (test_mode) {
154+
engine_->DeclareOutput(output_name);
155+
}
156+
return;
157+
}
158+
159+
if (global_pooling == true) {
160+
auto *reduce_layer = TRT_ENGINE_ADD_LAYER(engine_, Reduce, *input1,
161+
reduce_operation, 14, true);
162+
layer = reduce_layer;
163+
auto output_name = op_desc.Output("Out")[0];
164+
layer->setName(("pool3d (Output: " + output_name + ")").c_str());
165+
layer->getOutput(0)->setName(output_name.c_str());
166+
engine_->SetITensor(output_name, layer->getOutput(0));
167+
if (test_mode) {
168+
engine_->DeclareOutput(output_name);
169+
}
170+
return;
171+
}
172+
173+
if (!adaptive) {
174+
if (!ceil_mode) {
175+
auto *pool_layer = TRT_ENGINE_ADD_LAYER(engine_, PoolingNd, *input1,
176+
nv_pool_type, nv_ksize);
177+
PADDLE_ENFORCE_NOT_NULL(
178+
pool_layer,
179+
platform::errors::Fatal(
180+
"trt pool layer in converter could not be created."));
181+
pool_layer->setStrideNd(nv_strides);
182+
pool_layer->setPaddingNd(nv_paddings);
183+
pool_layer->setAverageCountExcludesPadding(exclusive);
184+
layer = pool_layer;
185+
} else {
186+
std::vector<int> input_shape_v;
187+
for (int i = 0; i < input_dims; i++) {
188+
input_shape_v.push_back(input_shape.d[i]);
189+
}
190+
plugin::Pool3DPlugin *plugin =
191+
new plugin::Pool3DPlugin(ceil_mode, plugin_pool_type, adaptive,
192+
ksize, strides, paddings, input_shape_v);
193+
auto *pool_layer = engine_->AddPluginV2Ext(&input1, 1, plugin);
194+
PADDLE_ENFORCE_NOT_NULL(
195+
pool_layer,
196+
platform::errors::Fatal(
197+
"trt pool3d plugin layer in converter could not be created."));
198+
layer = pool_layer;
199+
}
200+
} else {
201+
// Average pooling needs to exclude the padding pixels from the average
202+
// mean.
203+
// It is not supported well by TRT, we use a plugin here.
204+
std::vector<int> input_shape_v;
205+
for (int i = 0; i < input_dims; i++) {
206+
input_shape_v.push_back(input_shape.d[i]);
207+
}
208+
plugin::Pool3DPlugin *plugin =
209+
new plugin::Pool3DPlugin(ceil_mode, plugin_pool_type, adaptive, ksize,
210+
strides, paddings, input_shape_v);
211+
auto *pool_layer = engine_->AddPluginV2Ext(&input1, 1, plugin);
212+
PADDLE_ENFORCE_NOT_NULL(
213+
pool_layer,
214+
platform::errors::Fatal(
215+
"trt pool3d plugin layer in converter could not be created."));
216+
layer = pool_layer;
217+
}
218+
auto output_name = op_desc.Output("Out")[0];
219+
RreplenishLayerAndOutput(layer, "pool3d", {output_name}, test_mode);
220+
}
221+
};
222+
223+
} // namespace tensorrt
224+
} // namespace inference
225+
} // namespace paddle
226+
227+
USE_OP(pool3d);
228+
REGISTER_TRT_OP_CONVERTER(pool3d, Pool3dOpConverter);

paddle/fluid/inference/tensorrt/op_teller.cc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,8 @@ struct SimpleOpTypeSetTeller : public Teller {
142142
"conv3d",
143143
"conv3d_transpose",
144144
"mish",
145-
"nearest_interp_v2"};
145+
"nearest_interp_v2",
146+
"pool3d"};
146147
};
147148

148149
bool OpTeller::Tell(const framework::ir::Node* node, bool use_no_calib_int8,

paddle/fluid/inference/tensorrt/plugin/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ nv_library(tensorrt_plugin
1010
roi_align_op_plugin.cu
1111
gather_nd_op_plugin.cu
1212
mish_op_plugin.cu
13+
pool3d_op_plugin.cu
1314
DEPS enforce tensorrt_engine prelu tensor bert_encoder_functor)
1415

1516
nv_test(test_split_plugin SRCS test_split_plugin.cc DEPS

0 commit comments

Comments
 (0)