未验证 提交 a9869297 编写于 作者: W Wangzheee 提交者: GitHub

add trt convert op: reshape (#33188)

* add trt convert op: reshape

* reshape

* fix

* input: Shape,ShapeTensor

* Add some comments
上级 cbe45abf
...@@ -1197,6 +1197,7 @@ USE_TRT_CONVERTER(roi_align); ...@@ -1197,6 +1197,7 @@ USE_TRT_CONVERTER(roi_align);
USE_TRT_CONVERTER(affine_channel); USE_TRT_CONVERTER(affine_channel);
USE_TRT_CONVERTER(multiclass_nms); USE_TRT_CONVERTER(multiclass_nms);
USE_TRT_CONVERTER(nearest_interp); USE_TRT_CONVERTER(nearest_interp);
USE_TRT_CONVERTER(reshape);
#endif #endif
namespace paddle_infer { namespace paddle_infer {
......
...@@ -12,6 +12,7 @@ nv_library(tensorrt_converter ...@@ -12,6 +12,7 @@ nv_library(tensorrt_converter
affine_channel_op.cc affine_channel_op.cc
multiclass_nms_op.cc multiclass_nms_op.cc
nearest_interp_op.cc nearest_interp_op.cc
reshape_op.cc
DEPS tensorrt_engine tensorrt_plugin operator scope framework_proto op_registry) DEPS tensorrt_engine tensorrt_plugin operator scope framework_proto op_registry)
nv_test(test_op_converter SRCS test_op_converter.cc DEPS nv_test(test_op_converter SRCS test_op_converter.cc DEPS
......
...@@ -127,6 +127,13 @@ class OpConverter { ...@@ -127,6 +127,13 @@ class OpConverter {
it, platform::errors::Unimplemented("no OpConverter for optype [%s]", it, platform::errors::Unimplemented("no OpConverter for optype [%s]",
op_desc.Type())); op_desc.Type()));
} }
// reshape2 == reshape
if (op_desc.Type() == "reshape2") {
it = Registry<OpConverter>::Global().Lookup("reshape");
PADDLE_ENFORCE_NOT_NULL(
it, platform::errors::Unimplemented("no OpConverter for optype [%s]",
op_desc.Type()));
}
if (!it) { if (!it) {
it = Registry<OpConverter>::Global().Lookup(op_desc.Type()); it = Registry<OpConverter>::Global().Lookup(op_desc.Type());
} }
......
/* Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved.
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. */
#include "paddle/fluid/inference/tensorrt/convert/op_converter.h"
namespace paddle {
namespace framework {
class Scope;
namespace proto {
class OpDesc;
} // namespace proto
} // namespace framework
} // namespace paddle
namespace paddle {
namespace inference {
namespace tensorrt {
/*
* ReshapeOp
*/
class ReshapeOpConverter : public OpConverter {
public:
void operator()(const framework::proto::OpDesc& op,
const framework::Scope& scope, bool test_mode) override {
framework::OpDesc op_desc(op, nullptr);
// Declare inputs
auto* input = engine_->GetITensor(op_desc.Input("X")[0]);
const std::vector<int>& shape =
BOOST_GET_CONST(std::vector<int>, op_desc.GetAttr("shape"));
int nbDims_num = shape.size();
nvinfer1::Dims reshape_dim;
if (engine_->with_dynamic_shape()) { // running the TRT Dynamic Shape mode
reshape_dim.nbDims = nbDims_num;
for (int i = 0; i < nbDims_num; ++i) {
reshape_dim.d[i] = shape[i];
}
} else { // running the TRT Static Shape mode
reshape_dim.nbDims = nbDims_num - 1;
for (int i = 0; i < nbDims_num - 1; ++i) {
reshape_dim.d[i] = shape[i + 1];
}
}
auto* layer = TRT_ENGINE_ADD_LAYER(engine_, Shuffle, *input);
layer->setReshapeDimensions(reshape_dim);
auto output_name = op_desc.Output("Out")[0];
RreplenishLayerAndOutput(layer, "reshape", {output_name}, test_mode);
}
};
} // namespace tensorrt
} // namespace inference
} // namespace paddle
REGISTER_TRT_OP_CONVERTER(reshape, ReshapeOpConverter);
...@@ -49,6 +49,10 @@ struct SimpleOpTypeSetTeller : public Teller { ...@@ -49,6 +49,10 @@ struct SimpleOpTypeSetTeller : public Teller {
#endif #endif
#if IS_TRT_VERSION_GE(7130) #if IS_TRT_VERSION_GE(7130)
teller_set.insert("group_norm"); teller_set.insert("group_norm");
#endif
#if CUDA_VERSION >= 10200
teller_set.insert("reshape");
teller_set.insert("reshape2");
#endif #endif
} }
...@@ -667,7 +671,19 @@ bool OpTeller::Tell(const framework::ir::Node* node, bool use_no_calib_int8, ...@@ -667,7 +671,19 @@ bool OpTeller::Tell(const framework::ir::Node* node, bool use_no_calib_int8,
return false; return false;
} }
} }
if (op_type == "reshape" || op_type == "reshape2") {
if (!desc.HasAttr("shape")) {
return false;
// Paddle-TRT does not support the input tensors: Shape and ShapeTensor
} else if (desc.Input("Shape").size() >= 1 ||
desc.Input("ShapeTensor").size() >= 1) {
return false;
} else {
std::vector<int> shape =
BOOST_GET_CONST(std::vector<int>, desc.GetAttr("shape"));
if (shape.size() >= nvinfer1::Dims::MAX_DIMS) return false;
}
}
if ((*teller)(op_type, desc, use_no_calib_int8)) return true; if ((*teller)(op_type, desc, use_no_calib_int8)) return true;
} }
return false; return false;
......
...@@ -8,6 +8,7 @@ foreach(TEST_INFERENCE_IR_PASS ${TEST_TRT_IR_PASSES}) ...@@ -8,6 +8,7 @@ foreach(TEST_INFERENCE_IR_PASS ${TEST_TRT_IR_PASSES})
endforeach() endforeach()
if(WITH_GPU AND TENSORRT_FOUND) if(WITH_GPU AND TENSORRT_FOUND)
list(REMOVE_ITEM TEST_TRT_IR_PASSES test_trt_multiclass_nms_op)
foreach(target ${TEST_TRT_IR_PASSES}) foreach(target ${TEST_TRT_IR_PASSES})
py_test_modules(${target} MODULES ${target}) py_test_modules(${target} MODULES ${target})
endforeach() endforeach()
...@@ -32,6 +33,6 @@ if(WITH_GPU AND TENSORRT_FOUND) ...@@ -32,6 +33,6 @@ if(WITH_GPU AND TENSORRT_FOUND)
set_tests_properties(test_trt_subgraph_pass PROPERTIES TIMEOUT 120) set_tests_properties(test_trt_subgraph_pass PROPERTIES TIMEOUT 120)
set_tests_properties(test_trt_activation_pass PROPERTIES TIMEOUT 120) set_tests_properties(test_trt_activation_pass PROPERTIES TIMEOUT 120)
set_tests_properties(test_trt_conv_pass PROPERTIES TIMEOUT 120) set_tests_properties(test_trt_conv_pass PROPERTIES TIMEOUT 120)
set_tests_properties(test_trt_multiclass_nms_op PROPERTIES TIMEOUT 200) #set_tests_properties(test_trt_multiclass_nms_op PROPERTIES TIMEOUT 200)
set_tests_properties(test_trt_dynamic_shape PROPERTIES TIMEOUT 120) set_tests_properties(test_trt_dynamic_shape PROPERTIES TIMEOUT 120)
endif() endif()
# Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserved.
#
# 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.
from __future__ import print_function
import unittest
import numpy as np
from inference_pass_test import InferencePassTest
import paddle.fluid as fluid
import paddle.fluid.core as core
from paddle.fluid.core import PassVersionChecker
from paddle.fluid.core import AnalysisConfig
class TRTReshapeTest(InferencePassTest):
def setUp(self):
self.bs = 1
self.input_shape = [32, 15, 24]
self.reshape = [-1, 8, 20, 72]
self.data_shape = [
self.bs, self.input_shape[0], self.input_shape[1],
self.input_shape[2]
]
with fluid.program_guard(self.main_program, self.startup_program):
data = fluid.data(
name='data', shape=self.data_shape, dtype='float32')
reshape_out = self.append_reshape(data, self.reshape)
out = fluid.layers.batch_norm(reshape_out, is_test=True)
self.feeds = {
'data': np.random.random(self.data_shape).astype('float32'),
}
self.enable_trt = True
self.trt_parameters = TRTReshapeTest.TensorRTParam(
1 << 30, self.bs, 1, AnalysisConfig.Precision.Float32, False, False)
self.fetch_list = [out]
def append_reshape(self, data, reshape):
return fluid.layers.reshape(data, reshape)
def test_check_output(self):
if core.is_compiled_with_cuda():
use_gpu = True
self.check_output_with_option(use_gpu)
self.assertTrue(
PassVersionChecker.IsCompatible('tensorrt_subgraph_pass'))
class TRTReshapeTest1(TRTReshapeTest):
def setUp(self):
self.bs = 2
self.input_shape = [23, 13, 24]
self.reshape = [2, 0, -1, 12]
self.data_shape = [
self.bs, self.input_shape[0], self.input_shape[1],
self.input_shape[2]
]
with fluid.program_guard(self.main_program, self.startup_program):
data = fluid.data(
name='data', shape=self.data_shape, dtype='float32')
reshape_out = self.append_reshape(data, self.reshape)
out = fluid.layers.batch_norm(reshape_out, is_test=True)
self.feeds = {
'data': np.random.random(self.data_shape).astype('float32'),
}
self.enable_trt = True
self.trt_parameters = TRTReshapeTest.TensorRTParam(
1 << 30, self.bs, 1, AnalysisConfig.Precision.Float32, False, False)
self.fetch_list = [out]
class TRTReshapeTest2(TRTReshapeTest):
def setUp(self):
self.bs = 1
self.input_shape = [14, 48, 27]
self.reshape = [1, 24, 28, 0]
self.data_shape = [
self.bs, self.input_shape[0], self.input_shape[1],
self.input_shape[2]
]
with fluid.program_guard(self.main_program, self.startup_program):
data = fluid.data(
name='data', shape=self.data_shape, dtype='float32')
bn_out = fluid.layers.batch_norm(data, is_test=True)
out = self.append_reshape(bn_out, self.reshape)
self.feeds = {
'data': np.random.random(self.data_shape).astype('float32'),
}
self.enable_trt = True
self.trt_parameters = TRTReshapeTest.TensorRTParam(
1 << 30, self.bs, 1, AnalysisConfig.Precision.Float32, False, False)
self.dynamic_shape_params = TRTReshapeTest.DynamicShapeParam({
'data': [1, 3, 8, 8]
}, {'data': [5, 100, 100, 100]}, {'data': [1, 3, 16, 16]}, False)
self.fetch_list = [out]
if __name__ == "__main__":
unittest.main()
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册