diff --git a/paddle/fluid/inference/tensorrt/op_teller.cc b/paddle/fluid/inference/tensorrt/op_teller.cc index 72f20790f3524..4b2d1937db269 100644 --- a/paddle/fluid/inference/tensorrt/op_teller.cc +++ b/paddle/fluid/inference/tensorrt/op_teller.cc @@ -532,6 +532,15 @@ bool OpTeller::Tell(const framework::ir::Node* node, bool use_no_calib_int8, return false; } } + } else { + for (size_t i = 0; i < axes.size(); i++) { + if (starts[i] < 0 || ends[i] < 0) { + VLOG(3) << "Invalid slice attribute 'starts' or 'ends'. " + "Negative starts or ends not supported in TensorRT " + "when running in dynamic shape mode."; + return false; + } + } } } } diff --git a/paddle/fluid/inference/tensorrt/plugin/slice_op_plugin.cu b/paddle/fluid/inference/tensorrt/plugin/slice_op_plugin.cu index 6d367712eabc5..cbd6e3a2e4ffe 100644 --- a/paddle/fluid/inference/tensorrt/plugin/slice_op_plugin.cu +++ b/paddle/fluid/inference/tensorrt/plugin/slice_op_plugin.cu @@ -253,7 +253,16 @@ nvinfer1::DimsExprs SlicePluginDynamic::getOutputDimensions( for (size_t i = 0; i < axes_.size(); i++) { int start = starts_[i]; int end = ends_[i]; +#if IS_TRT_VERSION_GE(7200) + ret.d[axes_[i]] = expr_builder.operation( + nvinfer1::DimensionOperation::kSUB, + *expr_builder.operation(nvinfer1::DimensionOperation::kMIN, + *expr_builder.constant(ends_[i]), + *in_dims.d[axes_[i]]), + *expr_builder.constant(start)); +#else ret.d[axes_[i]] = expr_builder.constant(end - start); +#endif } return ret; } diff --git a/python/paddle/fluid/tests/unittests/ir/inference/CMakeLists.txt b/python/paddle/fluid/tests/unittests/ir/inference/CMakeLists.txt index 8b4a0ee98fa54..92a0aedf7a1c7 100644 --- a/python/paddle/fluid/tests/unittests/ir/inference/CMakeLists.txt +++ b/python/paddle/fluid/tests/unittests/ir/inference/CMakeLists.txt @@ -19,7 +19,14 @@ if(WITH_GPU AND TENSORRT_FOUND) endforeach() foreach(target ${TEST_TRT_IR_PASSES}) - py_test_modules(${target} MODULES ${target}) + if(${target} STREQUAL "test_trt_slice_dynamic_plugin") + if("${TENSORRT_MAJOR_VERSION}.${TENSORRT_MINOR_VERSION}" VERSION_GREATER "7.1") + py_test_modules(${target} MODULES ${target}) + set_tests_properties(${target} PROPERTIES TIMEOUT 60) + endif() + else() + py_test_modules(${target} MODULES ${target}) + endif() endforeach() foreach(target ${TEST_TRT_CONVERTER}) diff --git a/python/paddle/fluid/tests/unittests/ir/inference/test_trt_slice_dynamic_plugin.py b/python/paddle/fluid/tests/unittests/ir/inference/test_trt_slice_dynamic_plugin.py new file mode 100644 index 0000000000000..7b4b84724e8b3 --- /dev/null +++ b/python/paddle/fluid/tests/unittests/ir/inference/test_trt_slice_dynamic_plugin.py @@ -0,0 +1,101 @@ +# 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 AnalysisConfig + + +#normal starts && ends +class SlicePluginTRTDynamicTest(InferencePassTest): + def setUpSliceParams(self): + self.params_axes = [1, 3] + self.params_starts = [0, 1] + self.params_ends = [2, 3] + + def setUpTensorRTParams(self): + self.trt_parameters = SlicePluginTRTDynamicTest.TensorRTParam( + 1 << 30, 32, 1, AnalysisConfig.Precision.Float32, False, False) + self.enable_trt = True + self.dynamic_shape_params = SlicePluginTRTDynamicTest.DynamicShapeParam( + { + 'data': [1, 1, 1, 1] + }, {'data': [8, 8, 8, 8]}, {'data': [8, 8, 8, 8]}, False) + + def setUp(self): + self.setUpSliceParams() + self.setUpTensorRTParams() + with fluid.program_guard(self.main_program, self.startup_program): + data = fluid.data(name="data", shape=[3, 3, 3, 3], dtype="float32") + axes = self.params_axes + starts = self.params_starts + ends = self.params_ends + slice_out = fluid.layers.slice( + data, axes=axes, starts=starts, ends=ends) + + self.feeds = { + "data": np.random.random((3, 3, 3, 3)).astype("float32"), + } + self.fetch_list = [slice_out] + + def test_check_output(self): + use_gpu = [False] + if core.is_compiled_with_cuda(): + use_gpu.append(True) + for i in range(len(use_gpu)): + atol = 1e-5 + if self.trt_parameters.precision == AnalysisConfig.Precision.Half: + atol = 1e-3 + self.check_output_with_option(use_gpu[i], atol) + + +class SlicePluginTRTDynamicBoundTest(SlicePluginTRTDynamicTest): + def setUpSliceParams(self): + self.params_axes = [1, 3] + self.params_starts = [0, 1] + self.params_ends = [2, 1000] + + def setUpTensorRTParams(self): + self.trt_parameters = SlicePluginTRTDynamicBoundTest.TensorRTParam( + 1 << 30, 32, 1, AnalysisConfig.Precision.Half, False, False) + self.enable_trt = True + self.dynamic_shape_params = SlicePluginTRTDynamicBoundTest.DynamicShapeParam( + { + 'data': [1, 1, 1, 1] + }, {'data': [8, 8, 8, 8]}, {'data': [8, 8, 8, 8]}, False) + + +class SlicePluginTRTDynamicNegativeBoundTest(SlicePluginTRTDynamicTest): + def setUpSliceParams(self): + self.params_axes = [1, 3] + self.params_starts = [-5, 1] + self.params_ends = [2, 1000] + + def setUpTensorRTParams(self): + self.trt_parameters = SlicePluginTRTDynamicNegativeBoundTest.TensorRTParam( + 1 << 30, 32, 1, AnalysisConfig.Precision.Half, False, False) + self.enable_trt = True + self.dynamic_shape_params = SlicePluginTRTDynamicNegativeBoundTest.DynamicShapeParam( + { + 'data': [1, 1, 1, 1] + }, {'data': [8, 8, 8, 8]}, {'data': [8, 8, 8, 8]}, False) + + +if __name__ == "__main__": + unittest.main()