Skip to content

Commit 1948210

Browse files
author
Pei Yang
authored
Bug Fix: Paddle-TRT cannot handle adaptive pooling in pool2d op converter and "num" attribute in split op converter (#20733) (#20902)
* fix pool2d trt converter, test=develop * add fix for split op converter, test=develop
1 parent 6fb04e8 commit 1948210

File tree

11 files changed

+174
-66
lines changed

11 files changed

+174
-66
lines changed

paddle/fluid/inference/analysis/ir_passes/tensorrt_subgraph_pass.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ void TensorRtSubgraphPass::CreateTensorRTOp(
213213
for (auto *x : node->inputs) {
214214
if (x->IsVar() && x->Var()) {
215215
framework::VarDesc *var = x->Var();
216-
SetAttr(op_desc->Proto(), var->Name() + "_shape", var->GetShape());
216+
op_desc->SetAttr(var->Name() + "_shape", var->GetShape());
217217
}
218218
}
219219

paddle/fluid/inference/api/analysis_predictor.cc

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -507,7 +507,6 @@ std::unique_ptr<PaddlePredictor> CreatePaddlePredictor<
507507
}
508508
}
509509
if (config.glog_info_disabled()) {
510-
google::InitGoogleLogging("Init");
511510
FLAGS_logtostderr = 1;
512511
FLAGS_minloglevel = google::WARNING;
513512
LOG(WARNING) << " - GLOG's LOG(INFO) is disabled.";

paddle/fluid/inference/tensorrt/convert/pool2d_op.cc

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ See the License for the specific language governing permissions and
1313
limitations under the License. */
1414

1515
#include "paddle/fluid/inference/tensorrt/convert/op_converter.h"
16-
#include "paddle/fluid/inference/tensorrt/plugin/avg_pool_op_plugin.h"
16+
#include "paddle/fluid/inference/tensorrt/plugin/pool_op_plugin.h"
1717

1818
namespace paddle {
1919
namespace inference {
@@ -75,12 +75,19 @@ class Pool2dOpConverter : public OpConverter {
7575
std::vector<int> paddings =
7676
boost::get<std::vector<int>>(op_desc.GetAttr("paddings"));
7777
bool ceil_mode = boost::get<bool>(op_desc.GetAttr("ceil_mode"));
78+
bool adaptive = false;
79+
if (op_desc.HasAttr("adaptive"))
80+
adaptive = boost::get<bool>(op_desc.GetAttr("adaptive"));
7881

7982
nvinfer1::PoolingType nv_pool_type = nvinfer1::PoolingType::kMAX;
83+
plugin::PoolPlugin::PoolType plugin_pool_type =
84+
plugin::PoolPlugin::PoolType::max;
8085
if (pool_type == "max") {
8186
nv_pool_type = nvinfer1::PoolingType::kMAX;
87+
plugin_pool_type = plugin::PoolPlugin::PoolType::max;
8288
} else if (pool_type == "avg") {
8389
nv_pool_type = nvinfer1::PoolingType::kAVERAGE;
90+
plugin_pool_type = plugin::PoolPlugin::PoolType::avg;
8491
} else {
8592
PADDLE_THROW("TensorRT unsupported pooling type!");
8693
}
@@ -108,7 +115,7 @@ class Pool2dOpConverter : public OpConverter {
108115
return;
109116
}
110117

111-
if (pool_type == "max") {
118+
if (!adaptive && pool_type == "max") {
112119
// Under ceil mode, the pre_pad and post_pad are used to
113120
// record the the padding size. In some ceil mode cases,
114121
// we do not need padding, so we initialize the two vars to 0.
@@ -141,10 +148,13 @@ class Pool2dOpConverter : public OpConverter {
141148
for (int i = 0; i < input_dims; i++) {
142149
input_shape_v.push_back(input_shape.d[i]);
143150
}
144-
plugin::AvgPoolPlugin *plugin = new plugin::AvgPoolPlugin(
145-
ceil_mode, ksize, strides, paddings, input_shape_v);
146-
auto *avg_pool_layer = engine_->AddPlugin(&input1, 1, plugin);
147-
layer = avg_pool_layer;
151+
plugin::PoolPlugin *plugin =
152+
new plugin::PoolPlugin(ceil_mode, plugin_pool_type, adaptive, ksize,
153+
strides, paddings, input_shape_v);
154+
PADDLE_ENFORCE_NOT_NULL(plugin->getPluginType(),
155+
"The plugin used must not be null");
156+
auto *pool_layer = engine_->AddPlugin(&input1, 1, plugin);
157+
layer = pool_layer;
148158
}
149159

150160
auto output_name = op_desc.Output("Out")[0];

paddle/fluid/inference/tensorrt/convert/split_op.cc

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,23 @@ class SplitOpConverter : public OpConverter {
3535
// Get Attrs
3636
PADDLE_ENFORCE(input_num == 1);
3737
int axis = boost::get<int>(op_desc.GetAttr("axis"));
38-
std::vector<int> output_lengths =
39-
boost::get<std::vector<int>>(op_desc.GetAttr("sections"));
4038
// split on batch is not supported in TensorRT
4139
PADDLE_ENFORCE(axis != 0);
4240
axis += (axis < 0) ? input_dims.nbDims : -1;
43-
41+
std::vector<int> output_lengths =
42+
boost::get<std::vector<int>>(op_desc.GetAttr("sections"));
43+
output_lengths.reserve(output_num);
44+
int num = boost::get<int>(op_desc.GetAttr("num"));
45+
if (num > 0) {
46+
int64_t in_axis_dim = input_dims.d[axis];
47+
PADDLE_ENFORCE_EQ(in_axis_dim % num, 0,
48+
"Tensor split does not result"
49+
" in an equal division");
50+
size_t out_axis_dim = in_axis_dim / num;
51+
for (size_t i = 0; i < output_num; ++i) {
52+
output_lengths.push_back(out_axis_dim);
53+
}
54+
}
4455
PADDLE_ENFORCE(output_lengths.size() == output_num);
4556
plugin::SplitPlugin* plugin = new plugin::SplitPlugin(axis, output_lengths);
4657
nvinfer1::IPluginLayer* layer =
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
nv_library(tensorrt_plugin
22
SRCS trt_plugin.cc split_op_plugin.cu elementwise_op_plugin.cu
33
prelu_op_plugin.cu trt_plugin_factory.cc
4-
avg_pool_op_plugin.cu swish_op_plugin.cu
4+
pool_op_plugin.cu swish_op_plugin.cu
55
DEPS enforce tensorrt_engine prelu)

paddle/fluid/inference/tensorrt/plugin/avg_pool_op_plugin.cu renamed to paddle/fluid/inference/tensorrt/plugin/pool_op_plugin.cu

Lines changed: 24 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15-
#include "paddle/fluid/inference/tensorrt/plugin/avg_pool_op_plugin.h"
15+
#include "paddle/fluid/inference/tensorrt/plugin/pool_op_plugin.h"
1616
#include "paddle/fluid/inference/tensorrt/plugin/trt_plugin_factory.h"
1717
#include "paddle/fluid/operators/math/pooling.h"
1818

@@ -21,14 +21,14 @@ namespace inference {
2121
namespace tensorrt {
2222
namespace plugin {
2323

24-
AvgPoolPlugin* CreateAvgPoolPluginDeserialize(const void* buffer,
25-
size_t length) {
26-
return new AvgPoolPlugin(buffer, length);
24+
PoolPlugin* CreatePoolPluginDeserialize(const void* buffer, size_t length) {
25+
return new PoolPlugin(buffer, length);
2726
}
28-
REGISTER_TRT_PLUGIN("avg_pool_plugin", CreateAvgPoolPluginDeserialize);
27+
REGISTER_TRT_PLUGIN("pool_plugin", CreatePoolPluginDeserialize);
2928

30-
nvinfer1::Dims AvgPoolPlugin::getOutputDimensions(
31-
int index, const nvinfer1::Dims* inputDims, int nbInputs) {
29+
nvinfer1::Dims PoolPlugin::getOutputDimensions(int index,
30+
const nvinfer1::Dims* inputDims,
31+
int nbInputs) {
3232
assert(nbInputs == 1);
3333
assert(index == 0);
3434
assert(inputDims[0].nbDims == 3);
@@ -41,26 +41,33 @@ nvinfer1::Dims AvgPoolPlugin::getOutputDimensions(
4141
return output_dims;
4242
}
4343

44-
int AvgPoolPlugin::enqueue(int batchSize, const void* const* inputs,
45-
void** outputs, void* workspace,
46-
cudaStream_t stream) {
44+
int PoolPlugin::enqueue(int batchSize, const void* const* inputs,
45+
void** outputs, void* workspace, cudaStream_t stream) {
4746
auto const& input_dims = this->getInputDims(0);
4847
int input_size = 0;
4948
float const* idata = reinterpret_cast<float const*>(inputs[0]);
5049
float** odatas = reinterpret_cast<float**>(outputs);
5150

52-
paddle::operators::math::AvgPool<float> pool_process;
53-
paddle::operators::math::Pool2dDirectCUDAFunctor<
54-
paddle::operators::math::AvgPool<float>, float>
55-
pool2d_forward;
56-
5751
std::vector<int> input_shape = input_shape_;
5852
std::vector<int> output_shape = output_shape_;
5953
input_shape.insert(input_shape.begin(), batchSize);
6054
output_shape.insert(output_shape.begin(), batchSize);
6155

62-
pool2d_forward(idata, input_shape, output_shape, ksize_, strides_, paddings_,
63-
pool_process, true, odatas[0], stream);
56+
if (pool_type_ == PoolType::max) {
57+
paddle::operators::math::MaxPool<float> pool_process;
58+
paddle::operators::math::Pool2dDirectCUDAFunctor<
59+
paddle::operators::math::MaxPool<float>, float>
60+
pool2d_forward;
61+
pool2d_forward(idata, input_shape, output_shape, ksize_, strides_,
62+
paddings_, pool_process, true, adaptive_, odatas[0], stream);
63+
} else if (pool_type_ == PoolType::avg) {
64+
paddle::operators::math::AvgPool<float> pool_process;
65+
paddle::operators::math::Pool2dDirectCUDAFunctor<
66+
paddle::operators::math::AvgPool<float>, float>
67+
pool2d_forward;
68+
pool2d_forward(idata, input_shape, output_shape, ksize_, strides_,
69+
paddings_, pool_process, true, adaptive_, odatas[0], stream);
70+
}
6471

6572
return cudaGetLastError() != cudaSuccess;
6673
}

paddle/fluid/inference/tensorrt/plugin/avg_pool_op_plugin.h renamed to paddle/fluid/inference/tensorrt/plugin/pool_op_plugin.h

Lines changed: 54 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@
1313
// limitations under the License.
1414

1515
#pragma once
16+
#include <stdio.h>
1617
#include <cassert>
18+
#include <string>
1719
#include <vector>
1820
#include "paddle/fluid/inference/tensorrt/plugin/trt_plugin.h"
1921

@@ -22,18 +24,11 @@ namespace inference {
2224
namespace tensorrt {
2325
namespace plugin {
2426

25-
class AvgPoolPlugin : public PluginTensorRT {
26-
private:
27-
bool ceil_mode_;
28-
std::vector<int> ksize_;
29-
std::vector<int> strides_;
30-
std::vector<int> paddings_;
31-
std::vector<int> input_shape_;
32-
std::vector<int> output_shape_;
33-
27+
class PoolPlugin : public PluginTensorRT {
3428
protected:
3529
size_t getSerializationSize() override {
3630
return SerializedSize(getPluginType()) + SerializedSize(ceil_mode_) +
31+
SerializedSize(pool_type_) + SerializedSize(adaptive_) +
3732
SerializedSize(ksize_) + SerializedSize(strides_) +
3833
SerializedSize(paddings_) + SerializedSize(input_shape_) +
3934
SerializedSize(output_shape_) + getBaseSerializationSize();
@@ -45,6 +40,8 @@ class AvgPoolPlugin : public PluginTensorRT {
4540
SerializeValue(&buffer, getPluginType());
4641
serializeBase(buffer);
4742
SerializeValue(&buffer, ceil_mode_);
43+
SerializeValue(&buffer, pool_type_);
44+
SerializeValue(&buffer, adaptive_);
4845
SerializeValue(&buffer, ksize_);
4946
SerializeValue(&buffer, strides_);
5047
SerializeValue(&buffer, paddings_);
@@ -53,60 +50,83 @@ class AvgPoolPlugin : public PluginTensorRT {
5350
}
5451

5552
public:
56-
AvgPoolPlugin() {}
57-
AvgPoolPlugin(bool ceil_mode, std::vector<int> ksize,
58-
std::vector<int> strides, std::vector<int> paddings,
59-
std::vector<int> input_shape)
53+
enum class PoolType {
54+
max = 0,
55+
avg,
56+
};
57+
PoolPlugin() {}
58+
PoolPlugin(bool ceil_mode, PoolType pool_type, bool adaptive,
59+
std::vector<int> ksize, std::vector<int> strides,
60+
std::vector<int> paddings, std::vector<int> input_shape)
6061
: ceil_mode_(ceil_mode),
62+
pool_type_(pool_type),
63+
adaptive_(adaptive),
6164
ksize_(ksize),
6265
strides_(strides),
6366
paddings_(paddings),
6467
input_shape_(input_shape) {
65-
int output_h, output_w;
6668
output_shape_ = input_shape_;
67-
if (!ceil_mode_) {
68-
output_h =
69-
(input_shape[1] - ksize_[0] + 2 * paddings_[0]) / strides_[0] + 1;
70-
output_w =
71-
(input_shape[2] - ksize_[1] + 2 * paddings_[1]) / strides_[1] + 1;
69+
if (adaptive_) {
70+
output_shape_[1] = ksize[0];
71+
output_shape_[2] = ksize[1];
7272
} else {
73-
output_h =
74-
(input_shape[1] - ksize_[0] + 2 * paddings_[0] + strides_[0] - 1) /
75-
strides_[0] +
76-
1;
77-
output_w =
78-
(input_shape[2] - ksize_[1] + 2 * paddings_[1] + strides_[1] - 1) /
79-
strides_[1] +
80-
1;
73+
int output_h, output_w;
74+
if (!ceil_mode_) {
75+
output_h =
76+
(input_shape[1] - ksize_[0] + 2 * paddings_[0]) / strides_[0] + 1;
77+
output_w =
78+
(input_shape[2] - ksize_[1] + 2 * paddings_[1]) / strides_[1] + 1;
79+
} else {
80+
output_h =
81+
(input_shape[1] - ksize_[0] + 2 * paddings_[0] + strides_[0] - 1) /
82+
strides_[0] +
83+
1;
84+
output_w =
85+
(input_shape[2] - ksize_[1] + 2 * paddings_[1] + strides_[1] - 1) /
86+
strides_[1] +
87+
1;
88+
}
89+
output_shape_[1] = output_h;
90+
output_shape_[2] = output_w;
8191
}
82-
output_shape_[1] = output_h;
83-
output_shape_[2] = output_w;
8492
}
8593

8694
// It was used for tensorrt deserialization.
8795
// It should not be called by users.
88-
AvgPoolPlugin(void const *serialData, size_t serialLength) {
96+
PoolPlugin(void const *serialData, size_t serialLength) {
8997
deserializeBase(serialData, serialLength);
9098
DeserializeValue(&serialData, &serialLength, &ceil_mode_);
99+
DeserializeValue(&serialData, &serialLength, &pool_type_);
100+
DeserializeValue(&serialData, &serialLength, &adaptive_);
91101
DeserializeValue(&serialData, &serialLength, &ksize_);
92102
DeserializeValue(&serialData, &serialLength, &strides_);
93103
DeserializeValue(&serialData, &serialLength, &paddings_);
94104
DeserializeValue(&serialData, &serialLength, &input_shape_);
95105
DeserializeValue(&serialData, &serialLength, &output_shape_);
96106
}
97107

98-
AvgPoolPlugin *clone() const override {
99-
return new AvgPoolPlugin(ceil_mode_, ksize_, strides_, paddings_,
100-
input_shape_);
108+
PoolPlugin *clone() const override {
109+
return new PoolPlugin(ceil_mode_, pool_type_, adaptive_, ksize_, strides_,
110+
paddings_, input_shape_);
101111
}
102112

103-
const char *getPluginType() const override { return "avg_pool_plugin"; }
113+
const char *getPluginType() const override { return "pool_plugin"; }
104114
int getNbOutputs() const override { return 1; }
105115
nvinfer1::Dims getOutputDimensions(int index, const nvinfer1::Dims *inputs,
106116
int nbInputDims) override;
107117
int initialize() override { return 0; }
108118
int enqueue(int batchSize, const void *const *inputs, void **outputs,
109119
void *workspace, cudaStream_t stream) override;
120+
121+
private:
122+
bool ceil_mode_;
123+
PoolType pool_type_;
124+
bool adaptive_;
125+
std::vector<int> ksize_;
126+
std::vector<int> strides_;
127+
std::vector<int> paddings_;
128+
std::vector<int> input_shape_;
129+
std::vector<int> output_shape_;
110130
};
111131

112132
} // namespace plugin

paddle/fluid/inference/tests/api/CMakeLists.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,10 @@ if(WITH_GPU AND TENSORRT_FOUND)
268268
if (NOT EXISTS ${TRT_MODEL_INSTALL_DIR})
269269
inference_download_and_uncompress(${TRT_MODEL_INSTALL_DIR} ${INFERENCE_URL}/tensorrt_test "trt_inference_test_models.tar.gz")
270270
endif()
271+
set(TEST_SPLIT_CONVERTER_MODEL "${TRT_MODEL_INSTALL_DIR}/trt_split_op_converter_test")
272+
if (NOT EXISTS ${TEST_SPLIT_CONVERTER_MODEL})
273+
inference_download_and_uncompress(${TEST_SPLIT_CONVERTER_MODEL} ${INFERENCE_URL}/tensorrt_test "split_converter.tgz")
274+
endif()
271275
inference_analysis_test(trt_mobilenet_test SRCS trt_mobilenet_test.cc
272276
EXTRA_DEPS ${INFERENCE_EXTRA_DEPS}
273277
ARGS --infer_model=${TRT_MODEL_INSTALL_DIR}/trt_inference_test_models)
@@ -283,6 +287,9 @@ if(WITH_GPU AND TENSORRT_FOUND)
283287
inference_analysis_test(trt_cascade_rcnn_test SRCS trt_cascade_rcnn_test.cc
284288
EXTRA_DEPS ${INFERENCE_EXTRA_DEPS}
285289
ARGS --infer_model=${TRT_MODEL_INSTALL_DIR}/trt_inference_test_models)
290+
inference_analysis_test(trt_split_converter_test SRCS trt_split_converter_test.cc
291+
EXTRA_DEPS ${INFERENCE_EXTRA_DEPS}
292+
ARGS --infer_model=${TEST_SPLIT_CONVERTER_MODEL}/)
286293
inference_analysis_test(test_analyzer_capi_gpu SRCS analyzer_capi_gpu_tester.cc
287294
EXTRA_DEPS ${INFERENCE_EXTRA_DEPS} paddle_fluid_c
288295
ARGS --infer_model=${TRT_MODEL_INSTALL_DIR}/trt_inference_test_models)

0 commit comments

Comments
 (0)