Skip to content

Commit 09961b0

Browse files
authored
【Paddle TensorRT】add Bool output type support for fill_any_like with tensorrt > 8.5 (#71718)
* add_fill_any_like_bool * fix codestyle * add bool test * fix * fix codestyle * Update test_trt_convert_fill_any_like.py * Update test_trt_convert_fill_any_like.py * Update CMakeLists.txt * fix codestyle * ban fill_any_like in win32
1 parent da36481 commit 09961b0

File tree

4 files changed

+170
-2
lines changed

4 files changed

+170
-2
lines changed

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,11 @@ class FillAnyLikeOpConverter : public OpConverter {
4040
"will be cast to int32.";
4141
value_tensor = Add1DConstantLayer(static_cast<int32_t>(value),
4242
output_name + "_value_tensor_");
43+
} else if (dtype == 0) {
44+
LOG(WARNING) << "the fill_any_like has int32 dtype and 0 dtype, it "
45+
"will be cast to bool.";
46+
value_tensor = Add1DConstantLayer(static_cast<bool>(value),
47+
output_name + "_value_tensor_");
4348
} else {
4449
value_tensor = Add1DConstantLayer(value, output_name + "_value_tensor_");
4550
}

paddle/fluid/inference/tensorrt/convert/op_converter.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -734,7 +734,7 @@ class OpConverter {
734734
bool scalar = false) {
735735
if (!(std::is_same<T, float>::value ||
736736
std::is_same<T, phi::dtype::float16>::value ||
737-
std::is_same<T, int32_t>::value)) {
737+
std::is_same<T, int32_t>::value || std::is_same<T, bool>::value)) {
738738
PADDLE_THROW(common::errors::InvalidArgument(
739739
"Unsupported data type (%s) for TensorRT AddConstantLayer, only "
740740
"supports float, half or int32_t."));
@@ -750,7 +750,9 @@ class OpConverter {
750750
engine_->SetWeights(weight_name, std::move(tmp_tensor));
751751

752752
nvinfer1::DataType trt_dtype = nvinfer1::DataType::kFLOAT;
753-
if (std::is_integral<T>::value) {
753+
if (std::is_same<T, bool>::value) {
754+
trt_dtype = nvinfer1::DataType::kBOOL;
755+
} else if (std::is_integral<T>::value) {
754756
trt_dtype = nvinfer1::DataType::kINT32;
755757
}
756758

test/ir/inference/CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,9 @@ if(WIN32)
7373
"test_trt_explicit_quantization_mobilenet")
7474
list(REMOVE_ITEM TEST_INFERENCE_IR_PASSES
7575
"test_trt_explicit_quantization_mobilenet")
76+
list(REMOVE_ITEM TEST_TRT_IR_PASSES "test_trt_convert_fill_any_like")
77+
list(REMOVE_ITEM TEST_INFERENCE_IR_PASSES "test_trt_convert_fill_any_like")
78+
list(REMOVE_ITEM TEST_TRT_CONVERTER "test_trt_convert_fill_any_like")
7679
endif()
7780

7881
foreach(TEST_INFERENCE_IR_PASS ${TEST_TRT_IR_PASSES})

test/ir/inference/test_trt_convert_fill_any_like.py

Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,5 +192,163 @@ def test(self):
192192
self.run_test(run_pir=True)
193193

194194

195+
class TrtConvertExpandV2BoolTest(TrtLayerAutoScanTest):
196+
def is_program_valid(self, program_config: ProgramConfig) -> bool:
197+
if self.dtype in [1, 4]:
198+
return False
199+
if self.dims != 4 and self.dtype != 2:
200+
return False
201+
return True
202+
203+
def sample_program_configs(self):
204+
def generate_input1(attrs: list[dict[str, Any]]):
205+
if self.dims == 4:
206+
self.input_shape = [1, 1, 4, 6]
207+
if self.dtype == 0:
208+
return np.random.random([1, 1, 4, 6]).astype(np.bool_)
209+
elif self.dims == 3:
210+
self.input_shape = [1, 8, 6]
211+
return np.random.random([1, 8, 6]).astype(np.int32)
212+
elif self.dims == 2:
213+
self.input_shape = [1, 48]
214+
return np.random.random([1, 48]).astype(np.int32)
215+
elif self.dims == 1:
216+
self.input_shape = [48]
217+
return np.random.random([48]).astype(np.int32)
218+
219+
def generate_weight1(attrs: list[dict[str, Any]]):
220+
return np.array([1, 48]).astype(np.int32)
221+
222+
def generate_shapeT1_data(attrs: list[dict[str, Any]]):
223+
return np.array([2]).astype(np.int32)
224+
225+
def generate_shapeT2_data(attrs: list[dict[str, Any]]):
226+
return np.array([24]).astype(np.int32)
227+
228+
for dims in [1, 2, 3, 4]:
229+
for value in [0, 1]:
230+
for dtype in [0]:
231+
dics = [
232+
{
233+
"value": value,
234+
"dtype": dtype,
235+
},
236+
]
237+
self.dims = dims
238+
self.dtype = dtype
239+
dics_input = [{"X": ["fill_any_like_input"]}]
240+
241+
ops_config = [
242+
{
243+
"op_type": "fill_any_like",
244+
"op_inputs": dics_input[0],
245+
"op_outputs": {"Out": ["fill_any_like_out"]},
246+
"op_attrs": dics[0],
247+
}
248+
]
249+
ops = self.generate_op_config(ops_config)
250+
program_config = ProgramConfig(
251+
ops=ops,
252+
weights={},
253+
inputs={
254+
"fill_any_like_input": TensorConfig(
255+
data_gen=partial(generate_input1, dics)
256+
)
257+
},
258+
outputs=["fill_any_like_out"],
259+
)
260+
261+
yield program_config
262+
263+
def sample_predictor_configs(
264+
self, program_config
265+
) -> tuple[paddle_infer.Config, list[int], int]:
266+
267+
def generate_dynamic_shape(attrs):
268+
if self.dims == 4:
269+
self.dynamic_shape.min_input_shape = {
270+
"fill_any_like_input": [1, 1, 4, 6]
271+
}
272+
self.dynamic_shape.max_input_shape = {
273+
"fill_any_like_input": [10, 1, 4, 6]
274+
}
275+
self.dynamic_shape.opt_input_shape = {
276+
"fill_any_like_input": [1, 1, 4, 6]
277+
}
278+
elif self.dims == 3:
279+
self.dynamic_shape.min_input_shape = {
280+
"fill_any_like_input": [1, 8, 6]
281+
}
282+
self.dynamic_shape.max_input_shape = {
283+
"fill_any_like_input": [4, 8, 6]
284+
}
285+
self.dynamic_shape.opt_input_shape = {
286+
"fill_any_like_input": [1, 8, 6]
287+
}
288+
elif self.dims == 2:
289+
self.dynamic_shape.min_input_shape = {
290+
"fill_any_like_input": [1, 48]
291+
}
292+
self.dynamic_shape.max_input_shape = {
293+
"fill_any_like_input": [4, 48]
294+
}
295+
self.dynamic_shape.opt_input_shape = {
296+
"fill_any_like_input": [1, 48]
297+
}
298+
elif self.dims == 1:
299+
self.dynamic_shape.min_input_shape = {
300+
"fill_any_like_input": [48]
301+
}
302+
self.dynamic_shape.max_input_shape = {
303+
"fill_any_like_input": [48]
304+
}
305+
self.dynamic_shape.opt_input_shape = {
306+
"fill_any_like_input": [48]
307+
}
308+
309+
def clear_dynamic_shape():
310+
self.dynamic_shape.min_input_shape = {}
311+
self.dynamic_shape.max_input_shape = {}
312+
self.dynamic_shape.opt_input_shape = {}
313+
314+
def generate_trt_nodes_num(attrs, dynamic_shape):
315+
if not dynamic_shape:
316+
return 0, 3
317+
else:
318+
return 1, 2
319+
320+
attrs = [
321+
program_config.ops[i].attrs for i in range(len(program_config.ops))
322+
]
323+
324+
clear_dynamic_shape()
325+
self.trt_param.precision = paddle_infer.PrecisionType.Float32
326+
yield self.create_inference_config(), generate_trt_nodes_num(
327+
attrs, False
328+
), 1e-5
329+
self.trt_param.precision = paddle_infer.PrecisionType.Half
330+
yield self.create_inference_config(), generate_trt_nodes_num(
331+
attrs, False
332+
), 1e-5
333+
334+
# for dynamic_shape
335+
generate_dynamic_shape(attrs)
336+
self.trt_param.precision = paddle_infer.PrecisionType.Float32
337+
yield self.create_inference_config(), generate_trt_nodes_num(
338+
attrs, True
339+
), 1e-5
340+
self.trt_param.precision = paddle_infer.PrecisionType.Half
341+
yield self.create_inference_config(), generate_trt_nodes_num(
342+
attrs, True
343+
), 1e-5
344+
345+
def add_skip_trt_case(self):
346+
pass
347+
348+
def test(self):
349+
self.add_skip_trt_case()
350+
self.run_test()
351+
352+
195353
if __name__ == "__main__":
196354
unittest.main()

0 commit comments

Comments
 (0)