chore: import upstream snapshot with attribution

This commit is contained in:
wehub-resource-sync
2026-07-13 12:40:42 +08:00
commit e25996e7db
15472 changed files with 3536181 additions and 0 deletions
+13
View File
@@ -0,0 +1,13 @@
# Copyright (c) 2024 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.
+548
View File
@@ -0,0 +1,548 @@
# Copyright (c) 2024 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.
import numpy as np
import tensorrt as trt
from paddle.tensorrt.converter_utils import (
add_1D_constant_layer,
add_constant_layer,
set_layer_name,
trt_concat,
trt_div,
trt_min,
trt_pow,
trt_prod,
trt_sub,
trt_sum,
)
from paddle.tensorrt.register import converter_registry
activation_type_map = {
"pd_op.tanh": trt.ActivationType.TANH,
"pd_op.relu": trt.ActivationType.RELU,
"pd_op.sigmoid": trt.ActivationType.SIGMOID,
"pd_op.silu": trt.ActivationType.SIGMOID,
"pd_op.swish": trt.ActivationType.SIGMOID,
}
@converter_registry.register("pd_op.relu")
@converter_registry.register("pd_op.tanh")
@converter_registry.register("pd_op.sigmoid")
def activation_converter(network, paddle_op, inputs):
layer = network.add_activation(
inputs[0], activation_type_map[paddle_op.name()]
)
set_layer_name(layer, paddle_op)
return layer.get_output(0)
@converter_registry.register("pd_op.logsigmoid")
def logsigmoid_converter(network, paddle_op, inputs):
sigmoid_layer = network.add_activation(
inputs[0], trt.ActivationType.SIGMOID
)
set_layer_name(sigmoid_layer, paddle_op)
layer = network.add_unary(
sigmoid_layer.get_output(0), trt.UnaryOperation.LOG
)
set_layer_name(layer, paddle_op)
return layer.get_output(0)
@converter_registry.register("pd_op.relu6")
def relu6_converter(network, paddle_op, inputs):
layer = network.add_activation(inputs[0], trt.ActivationType.CLIP)
layer.alpha = 0.0
layer.beta = 6.0
set_layer_name(layer, paddle_op)
return layer.get_output(0)
@converter_registry.register("pd_op.softmax")
def softmax_converter(network, paddle_op, inputs):
from paddle.tensorrt.util import support_fp32_mix_precision
input1 = inputs[0]
input_shape = input1.shape
input_dims = len(input_shape)
axis = paddle_op.attrs().get("axis", -1)
# support 0 or 1 dims input
is_0_dims = input_dims == 0
is_1_dims = input_dims == 1
if is_0_dims or is_1_dims:
reshaped_layer = network.add_shuffle(input1)
reshaped_dims = (1, 1 if is_0_dims else input_shape[0])
reshaped_layer.reshape_dims = reshaped_dims
set_layer_name(reshaped_layer, paddle_op)
input1 = reshaped_layer.get_output(0)
input_shape = input1.shape
input_dims = len(input_shape)
axis = -1
layer = network.add_softmax(input1)
set_layer_name(layer, paddle_op)
support_fp32_mix_precision(paddle_op.name(), layer)
axes = max(0, input_dims - 3)
# Handle padded dimensions
padded_dims = 0
explicit_batch = 1
for i in range(input_dims - 1, explicit_batch, -1):
if input_shape[i] == 1:
padded_dims += 1
else:
break
if axis < 0:
axes = input_dims + axis
else:
axes = axis
layer.axes = 1 << axes
# Support 0 or 1 dims input
if is_0_dims or is_1_dims:
reshaped_layer = network.add_shuffle(layer.get_output(0))
reshaped_layer.reshape_dims = inputs[0].shape
layer = reshaped_layer
set_layer_name(layer, paddle_op)
return layer.get_output(0)
@converter_registry.register("pd_op.gelu")
def gelu_converter(network, paddle_op, inputs):
input_val = inputs[0]
approximate = paddle_op.attrs()["approximate"]
const_shape = [1] * len(input_val.shape)
if approximate:
constant_layer_pow = add_constant_layer(
network,
[3.0],
const_shape,
np.float32,
name=[paddle_op.name(), "constant_layer_pow"],
)
constant_layer_multiply = add_constant_layer(
network,
[0.044715],
const_shape,
np.float32,
name=[paddle_op.name(), "constant_layer_multiply"],
)
constant_layer_sqrt = add_constant_layer(
network,
[0.79788456080286535587989211986876],
const_shape,
np.float32,
name=[paddle_op.name(), "constant_layer_sqrt"],
)
constant_layer_one = add_constant_layer(
network,
[1.0],
const_shape,
np.float32,
name=[paddle_op.name(), "constant_layer_one"],
)
constant_layer_half = add_constant_layer(
network,
[0.5],
const_shape,
np.float32,
name=[paddle_op.name(), "constant_layer_half"],
)
layer_pow = trt_pow(
network,
input_val,
constant_layer_pow,
name=[paddle_op.name(), "layer_pow"],
)
layer_mul = trt_prod(
network,
layer_pow,
constant_layer_multiply,
name=[paddle_op.name(), "layer_mul"],
)
layer_add = trt_sum(
network, layer_mul, input_val, name=[paddle_op.name(), "layer_add"]
)
layer_sqrt = trt_prod(
network,
layer_add,
constant_layer_sqrt,
name=[paddle_op.name(), "layer_sqrt"],
)
layer_tanh = network.add_activation(layer_sqrt, trt.ActivationType.TANH)
set_layer_name(layer_tanh, paddle_op)
layer_one = trt_sum(
network,
layer_tanh.get_output(0),
constant_layer_one,
name=[paddle_op.name(), "layer_one"],
)
layer_cdf = trt_prod(
network,
layer_one,
constant_layer_half,
name=[paddle_op.name(), "layer_cdf"],
)
y = trt_prod(
network, layer_cdf, input_val, name=[paddle_op.name(), "y"]
)
return y
else:
constant_layer_one = add_constant_layer(
network,
[1.0],
const_shape,
np.float32,
name=[paddle_op.name(), "constant_layer_one"],
)
constant_layer_half = add_constant_layer(
network,
[0.5],
const_shape,
np.float32,
name=[paddle_op.name(), "constant_layer_half"],
)
constant_layer_rsqrt2 = add_constant_layer(
network,
[0.70710678118],
const_shape,
np.float32,
name=[paddle_op.name(), "constant_layer_rsqrt2"],
)
layer_mul = trt_prod(
network,
input_val,
constant_layer_rsqrt2,
name=[paddle_op.name(), "layer_mul"],
)
layer_erf = network.add_unary(layer_mul, trt.UnaryOperation.ERF)
set_layer_name(layer_erf, paddle_op)
layer_add = trt_sum(
network,
layer_erf.get_output(0),
constant_layer_one,
name=[paddle_op.name(), "layer_add"],
)
layer_cdf = trt_prod(
network,
layer_add,
constant_layer_half,
name=[paddle_op.name(), "layer_cdf"],
)
y = trt_prod(
network, layer_cdf, input_val, name=[paddle_op.name(), "y"]
)
return y
@converter_registry.register("pd_op.hardsigmoid")
def hardsigmoid_converter(network, paddle_op, inputs):
x = inputs[0]
slope = paddle_op.attrs()["slope"]
offset = paddle_op.attrs()["offset"]
hardsigmoid_layer = network.add_activation(
x, trt.ActivationType.HARD_SIGMOID
)
hardsigmoid_layer.alpha = slope
hardsigmoid_layer.beta = offset
set_layer_name(hardsigmoid_layer, paddle_op)
return hardsigmoid_layer.get_output(0)
@converter_registry.register("pd_op.hardswish")
def hardswish_converter(network, paddle_op, inputs):
x = inputs[0]
scale = 6.0
offset = 3.0
hardsigmoid_layer = network.add_activation(
x, trt.ActivationType.HARD_SIGMOID
)
hardsigmoid_layer.alpha = 1.0 / scale
hardsigmoid_layer.beta = offset / scale
set_layer_name(hardsigmoid_layer, paddle_op)
hardswish_layer = network.add_elementwise(
x, hardsigmoid_layer.get_output(0), trt.ElementWiseOperation.PROD
)
set_layer_name(hardswish_layer, paddle_op)
return hardswish_layer.get_output(0)
@converter_registry.register("pd_op.elu")
@converter_registry.register("pd_op.elu_")
def elu_converter(network, paddle_op, inputs):
x = inputs[0]
alpha = paddle_op.attrs()["alpha"]
elu_layer = network.add_activation(x, trt.ActivationType.ELU)
elu_layer.alpha = alpha
set_layer_name(elu_layer, paddle_op)
return elu_layer.get_output(0)
@converter_registry.register("pd_op.softplus")
def softplus_converter(network, paddle_op, inputs):
x = inputs[0]
beta = paddle_op.attrs()["beta"]
threshold = paddle_op.attrs()["threshold"]
layer_clip = network.add_activation(x, trt.ActivationType.CLIP)
layer_clip.alpha = -3.40282e038
layer_clip.beta = threshold / beta
set_layer_name(layer_clip, paddle_op)
softplus_layer = network.add_activation(
layer_clip.get_output(0), trt.ActivationType.SOFTPLUS
)
softplus_layer.alpha = 1.0 / beta
softplus_layer.beta = beta
set_layer_name(softplus_layer, paddle_op)
return softplus_layer.get_output(0)
@converter_registry.register("pd_op.swish")
@converter_registry.register("pd_op.silu")
def swish_silu_converter(network, paddle_op, inputs):
layer_output = network.add_activation(
inputs[0], activation_type_map[paddle_op.name()]
)
set_layer_name(layer_output, paddle_op)
return trt_prod(
network,
inputs[0],
layer_output.get_output(0),
name=[paddle_op.name(), "trt_prod"],
)
@converter_registry.register("pd_op.tanh_shrink")
def tanh_shrink_converter(network, paddle_op, inputs):
x = inputs[0]
tanh_layer = network.add_activation(x, trt.ActivationType.TANH)
set_layer_name(tanh_layer, paddle_op)
subtract_layer = network.add_elementwise(
x, tanh_layer.get_output(0), trt.ElementWiseOperation.SUB
)
set_layer_name(subtract_layer, paddle_op)
return subtract_layer.get_output(0)
@converter_registry.register("pd_op.stanh")
def stanh_converter(network, paddle_op, inputs):
x = inputs[0]
scale_a = paddle_op.attrs()["scale_a"]
scale_b = paddle_op.attrs()["scale_b"]
stanh_layer = network.add_activation(x, trt.ActivationType.SCALED_TANH)
stanh_layer.alpha = scale_b
stanh_layer.beta = scale_a
set_layer_name(stanh_layer, paddle_op)
return stanh_layer.get_output(0)
@converter_registry.register("pd_op.mish")
def mish_converter(network, paddle_op, inputs):
x = inputs[0]
softplus_layer = network.add_activation(x, trt.ActivationType.SOFTPLUS)
set_layer_name(softplus_layer, paddle_op)
softplus_output = softplus_layer.get_output(0)
tanh_layer = network.add_activation(
softplus_output, trt.ActivationType.TANH
)
set_layer_name(tanh_layer, paddle_op)
tanh_output = tanh_layer.get_output(0)
return trt_prod(
network, x, tanh_output, name=[paddle_op.name(), "trt_prod"]
)
@converter_registry.register("pd_op.celu")
def celu_converter(network, paddle_op, inputs):
input_tensor = inputs[0]
alpha = paddle_op.attrs()["alpha"]
input_rank = len(input_tensor.shape)
constant_shape = trt.Dims([1] * input_rank)
alpha_data = add_constant_layer(
network,
[alpha],
constant_shape,
dtype="float32",
name=[paddle_op.name(), "alpha_data"],
)
constant_zero_data = add_constant_layer(
network,
[0.0],
constant_shape,
dtype="float32",
name=[paddle_op.name(), "constant_zero_data"],
)
constant_one_data = add_constant_layer(
network,
[1.0],
constant_shape,
dtype="float32",
name=[paddle_op.name(), "constant_one_data"],
)
input_div_with_alpha = trt_div(
network,
input_tensor,
alpha_data,
name=[paddle_op.name(), "input_div_with_alpha"],
)
input_exp_layer = network.add_unary(
input_div_with_alpha, trt.UnaryOperation.EXP
)
set_layer_name(input_exp_layer, paddle_op)
input_sub_with_one = trt_sub(
network,
input_exp_layer.get_output(0),
constant_one_data,
name=[paddle_op.name(), "input_sub_with_one"],
)
input_prod_with_alpha = trt_prod(
network,
input_sub_with_one,
alpha_data,
name=[paddle_op.name(), "input_prod_with_alpha"],
)
min_input = trt_min(
network,
input_prod_with_alpha,
constant_zero_data,
name=[paddle_op.name(), "min_input"],
)
relu_layer = network.add_activation(input_tensor, trt.ActivationType.RELU)
set_layer_name(relu_layer, paddle_op)
output_tensor = trt_sum(
network,
relu_layer.get_output(0),
min_input,
name=[paddle_op.name(), "output_tensor"],
)
return output_tensor
@converter_registry.register("pd_op.thresholded_relu")
def thresholded_relu_converter(network, paddle_op, inputs):
x = inputs[0]
threshold = paddle_op.attrs()["threshold"]
thresholded_relu_layer = network.add_activation(
x, trt.ActivationType.THRESHOLDED_RELU
)
thresholded_relu_layer.alpha = threshold
set_layer_name(thresholded_relu_layer, paddle_op)
return thresholded_relu_layer.get_output(0)
@converter_registry.register("pd_op.leaky_relu")
@converter_registry.register("pd_op.leaky_relu_")
def leaky_relu_converter(network, paddle_op, inputs):
x = inputs[0]
negative_slope = paddle_op.attrs()["negative_slope"]
leaky_relu_layer = network.add_activation(x, trt.ActivationType.LEAKY_RELU)
leaky_relu_layer.alpha = negative_slope
set_layer_name(leaky_relu_layer, paddle_op)
return leaky_relu_layer.get_output(0)
@converter_registry.register("pd_op.selu")
def selu_converter(network, paddle_op, inputs):
x = inputs[0]
alpha = paddle_op.attrs()["alpha"]
scale = paddle_op.attrs()["scale"]
selu_layer = network.add_activation(x, trt.ActivationType.SELU)
selu_layer.alpha = alpha
selu_layer.beta = scale
set_layer_name(selu_layer, paddle_op)
return selu_layer.get_output(0)
@converter_registry.register("pd_op.prelu")
def prelu_converter(network, paddle_op, inputs):
input, alpha_data = inputs
input_dims = input.shape
data_format = paddle_op.attrs().get("data_format", "NCHW")
w_dims = trt.Dims(paddle_op.operands()[1].source().shape)
trt_w_dims = w_dims
alpha_tensor = network.add_constant(trt_w_dims, alpha_data)
set_layer_name(alpha_tensor, paddle_op)
alpha_tensor = alpha_tensor.get_output(0)
alpha_dims = alpha_tensor.shape
real_alpha_tensor = alpha_tensor
if len(alpha_dims) != len(input_dims):
reshape_layer = network.add_shuffle(alpha_tensor)
set_layer_name(reshape_layer, paddle_op)
c = alpha_dims[0]
n_tensor = add_1D_constant_layer(
network, [1], name=[paddle_op.name(), "n_tensor"]
)
c_tensor = add_1D_constant_layer(
network, [c], name=[paddle_op.name(), "c_tensor"]
)
hw_tensor = None
if len(input_dims) - 2 > 0:
hw_tensor = add_1D_constant_layer(
network,
[1] * (len(input_dims) - 2),
name=[paddle_op.name(), "hw_tensor"],
)
if data_format == "NCHW":
if hw_tensor:
shape_tensor = trt_concat(
network,
[n_tensor, c_tensor, hw_tensor],
name=[paddle_op.name(), "shape_tensor"],
)
else:
shape_tensor = trt_concat(
network,
[n_tensor, c_tensor],
name=[paddle_op.name(), "shape_tensor"],
)
else:
if hw_tensor:
shape_tensor = trt_concat(
network,
[n_tensor, hw_tensor, c_tensor],
name=[paddle_op.name(), "shape_tensor"],
)
else:
shape_tensor = trt_concat(
network,
[n_tensor, c_tensor],
name=[paddle_op.name(), "shape_tensor"],
)
reshape_layer.set_input(1, shape_tensor)
real_alpha_tensor = reshape_layer.get_output(0)
layer = network.add_parametric_relu(input, real_alpha_tensor)
set_layer_name(layer, paddle_op)
return layer.get_output(0)
+29
View File
@@ -0,0 +1,29 @@
# Copyright (c) 2024 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 paddle.tensorrt.converter_utils import set_layer_name, trt_shape
from paddle.tensorrt.register import converter_registry
@converter_registry.register("pd_op.shape")
def shape_converter(network, paddle_op, inputs):
return trt_shape(network, inputs[0], name=[paddle_op.name(), 'trt_shape'])
@converter_registry.register("pd_op.shape64")
def shape64_converter(network, paddle_op, inputs):
input_tensor = inputs[0]
shape_layer = network.add_shape(input_tensor)
set_layer_name(shape_layer, paddle_op)
return shape_layer.get_output(0)
+556
View File
@@ -0,0 +1,556 @@
# Copyright (c) 2024 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.
import numpy as np
import tensorrt as trt
from paddle import pir
from paddle.tensorrt.converter_utils import (
add_1D_constant_layer,
get_input_constant_value,
get_shape_tensor_element,
set_layer_name,
trt_concat,
trt_reshape,
trt_shape,
)
from paddle.tensorrt.register import converter_registry
from paddle.tensorrt.util import get_trt_version_list
@converter_registry.register("pd_op.dropout")
def dropout_converter(network, paddle_op, inputs):
input_x = inputs[0]
dropout_prob = get_input_constant_value(paddle_op, inputs, 2)[0]
downgrade_in_infer = paddle_op.attrs().get("mode")
if downgrade_in_infer == "upscale_in_train":
shuffle_layer = network.add_shuffle(input_x)
set_layer_name(shuffle_layer, paddle_op)
return shuffle_layer.get_output(0)
weight_data = np.array([1 - dropout_prob]).astype("float32")
scale_weights = trt.Weights(weight_data)
shift_weights = trt.Weights(np.array([0]).astype("float32"))
power_weights = trt.Weights(np.array([1]).astype("float32"))
scale_layer = network.add_scale(
input_x,
mode=trt.ScaleMode.UNIFORM,
shift=shift_weights,
scale=scale_weights,
power=power_weights,
)
set_layer_name(scale_layer, paddle_op)
return scale_layer.get_output(0)
@converter_registry.register("pd_op.bilinear_interp")
def bilinear_interp_converter(network, paddle_op, inputs):
input_tensor = inputs[0]
input_shape_tensor = network.add_shape(input_tensor)
set_layer_name(input_shape_tensor, paddle_op)
input_shape_tensor = input_shape_tensor.get_output(0)
input_rank = input_shape_tensor.shape # The reason is unknown that adding this unused code make input_shape_tensor maintain the correct result.
data_format = paddle_op.attrs().get("data_format")
interp_method = paddle_op.attrs().get("interp_method")
align_corners = paddle_op.attrs().get("align_corners")
align_mode = paddle_op.attrs().get("align_mode")
out_h = paddle_op.attrs().get("out_h")
out_w = paddle_op.attrs().get("out_w")
out_d = paddle_op.attrs().get("out_d")
scale_attr = paddle_op.attrs().get("scale")
trt_major = get_trt_version_list()[0]
trt_minor = get_trt_version_list()[1]
trt_version_float = float(f"{trt_major}.{trt_minor}")
resize_layer = network.add_resize(input_tensor)
set_layer_name(resize_layer, paddle_op)
# Set resize mode to LINEAR unconditionally
if trt_version_float >= 8.6:
resize_layer.resize_mode = trt.InterpolationMode.LINEAR
else:
resize_layer.resize_mode = trt.ResizeMode.LINEAR
# Set coordinate transformation based on align_corners and align_mode
if align_corners:
resize_layer.coordinate_transformation = (
trt.ResizeCoordinateTransformation.ALIGN_CORNERS
)
else:
if align_mode == 0:
resize_layer.coordinate_transformation = (
trt.ResizeCoordinateTransformation.HALF_PIXEL
)
else: # align_mode == 1
resize_layer.coordinate_transformation = (
trt.ResizeCoordinateTransformation.ASYMMETRIC
)
if data_format == "NCHW":
h_axis = 2
w_axis = 3
elif data_format == "NHWC":
h_axis = 1
w_axis = 2
in_dim = input_tensor.shape
outsize_tensor = None
if trt_version_float >= 8.2:
if not pir.is_fake_value(paddle_op.operands()[1].source()):
size_tensor_operand = paddle_op.operands()[1].source()
if len(inputs) > 1 and inputs[1] is not None:
outsize_tensor = inputs[1]
elif not pir.is_fake_value(paddle_op.operands()[2].source()):
size_tensor_operand = paddle_op.operands()[2].source()
size_tensor = inputs[2]
if size_tensor_operand.is_combine():
size_tensors = []
if not isinstance(size_tensor, list):
size_tensors = [size_tensor]
else:
size_tensors = size_tensor
if len(size_tensors) >= 2:
# Extract the first two elements representing height and width
outsize_h = size_tensors[0]
outsize_w = size_tensors[1]
outsize_tensor = network.add_concatenation(
[outsize_h, outsize_w]
)
set_layer_name(outsize_tensor, paddle_op)
outsize_tensor = outsize_tensor.get_output(0)
else:
size_tensor_shape = size_tensor_operand.source().shape
if size_tensor_shape.size >= 2:
outsize_h = network.add_slice(
size_tensor, start=[0], shape=[1], stride=[1]
)
set_layer_name(outsize_h, paddle_op)
outsize_h = outsize_h.get_output(0)
outsize_w = network.add_slice(
size_tensor, start=[1], shape=[1], stride=[1]
)
set_layer_name(outsize_w, paddle_op)
outsize_w = outsize_w.get_output(0)
outsize_tensor = network.add_concatenation(
[outsize_h, outsize_w]
)
set_layer_name(outsize_tensor, paddle_op)
outsize_tensor = outsize_tensor.get_output(0)
use_scales = True
if outsize_tensor is not None:
use_scales = False
if outsize_tensor is None and len(scale_attr) == 0:
use_scales = False
if use_scales:
scale_h = -1.0
scale_w = -1.0
if scale_attr and len(scale_attr) > 1:
scale_h = scale_attr[0]
scale_w = scale_attr[1]
elif scale_attr and len(scale_attr) == 1:
scale_h = scale_w = scale_attr[0]
if scale_w > 0 and scale_h > 0:
if in_dim[h_axis] > 0 and in_dim[w_axis] > 0:
out_h = int(in_dim[h_axis] * scale_h)
out_w = int(in_dim[w_axis] * scale_w)
else:
if out_h > 0 and out_w > 0 and not (scale_w > 0 and scale_h > 0):
if in_dim[h_axis] > 0 and in_dim[w_axis] > 0:
scale_h = float(out_h) / float(in_dim[h_axis])
scale_w = float(out_w) / float(in_dim[w_axis])
scales = [1.0] * len(input_tensor.shape)
if data_format == "NCHW":
scales[2] = scale_h
scales[3] = scale_w
elif data_format == "NHWC":
scales[1] = scale_h
scales[2] = scale_w
resize_layer.scales = scales
else:
if outsize_tensor is not None:
outsize_itensors = []
batch_dim = get_shape_tensor_element(
network,
input_shape_tensor,
0,
name=[paddle_op.name(), "batch_dim"],
)
outsize_itensors.append(batch_dim)
if data_format == "NCHW":
channel_dim = get_shape_tensor_element(
network,
input_shape_tensor,
1,
name=[paddle_op.name(), "channel_dim"],
)
outsize_itensors.append(channel_dim)
outsize_itensors.append(outsize_tensor)
elif data_format == "NHWC":
channel_dim = get_shape_tensor_element(
network,
input_shape_tensor,
3,
name=[paddle_op.name(), "channel_dim"],
)
outsize_itensors.append(outsize_tensor)
outsize_itensors.append(channel_dim)
output_size_tensor = network.add_concatenation(outsize_itensors)
set_layer_name(output_size_tensor, paddle_op)
output_size_tensor = output_size_tensor.get_output(0)
resize_layer.set_input(1, output_size_tensor)
else:
if data_format == "NCHW":
shape_layer = network.add_shape(input_tensor)
shape_output = shape_layer.get_output(0)
# Get N and C from slice_layer output
slice_layer = network.add_slice(
shape_output, start=[0], shape=[2], stride=[1]
)
# Create H and W
hw_constant = network.add_constant(
shape=(2,),
weights=trt.Weights(
np.array([out_h, out_w], dtype=np.int32)
),
).get_output(0)
# Create output shape(NCHW)
concat_layer = network.add_concatenation(
[slice_layer.get_output(0), hw_constant]
)
concat_layer.axis = 0
resize_layer.set_input(1, concat_layer.get_output(0))
elif data_format == "NHWC":
shape_layer = network.add_shape(input_tensor)
shape_output = shape_layer.get_output(0)
# Get N and C from slice_layer output
n_layer = network.add_slice(
shape_output, start=[0], shape=[1], stride=[1]
)
c_layer = network.add_slice(
shape_output, start=[3], shape=[1], stride=[1]
)
# Create H and W
hw_constant = network.add_constant(
shape=(2,),
weights=trt.Weights(
np.array([out_h, out_w], dtype=np.int32)
),
).get_output(0)
# Create output shape(NHWC)
concat_layer = network.add_concatenation(
[n_layer.get_output(0), hw_constant, c_layer.get_output(0)]
)
concat_layer.axis = 0
resize_layer.set_input(1, concat_layer.get_output(0))
else:
raise NotImplementedError(
"Converter for bilinear_interp not support data_format {}.",
data_format,
)
return resize_layer.get_output(0)
@converter_registry.register("pd_op.embedding")
def embedding_converter(network, paddle_op, inputs):
x = inputs[0]
weight = inputs[1]
gather_layer = network.add_gather(weight, x, 0)
set_layer_name(gather_layer, paddle_op)
return gather_layer.get_output(0)
@converter_registry.register("pd_op.unbind")
def unbind_converter(network, paddle_op, inputs):
x = inputs[0]
input_shape = x.shape
axis = paddle_op.attrs().get("axis")
rank = len(input_shape)
if axis < 0:
axis += rank
axis = int(axis)
# Input for the add_slice layer
start_tensors = []
size_tensors = []
# Input for the add_shuffle layer
new_shape_tensors = []
for i in range(rank):
if axis == i:
size_tensors.append(
add_1D_constant_layer(
network, 1, name=[paddle_op.name(), "size_tensor"]
)
)
else:
size_tensors.append(
get_shape_tensor_element(
network,
trt_shape(network, x, name=[paddle_op.name(), "trt_shape"]),
i,
name=[paddle_op.name(), f"size_tensor_{i}"],
)
)
new_shape_tensors.append(
get_shape_tensor_element(
network,
trt_shape(network, x, name=[paddle_op.name(), "trt_shape"]),
i,
name=[paddle_op.name(), f"new_shape_tensor_{i}"],
)
)
start_tensors.append(
add_1D_constant_layer(
network, 0, name=[paddle_op.name(), "start_tensor"]
)
)
new_shape_tensor = trt_concat(
network, new_shape_tensors, name=[paddle_op.name(), "new_shape_tensor"]
)
stride = trt.Dims([1] * rank)
outputs = []
output_size = len(paddle_op.results()[0].type().as_vec_type().as_list())
for i in range(output_size):
start_tensors[axis] = add_1D_constant_layer(
network, i, name=[paddle_op.name(), f"start_{i}_tensor"]
)
# Create Slice layer
slice_layer = network.add_slice(
x,
stride,
stride,
stride,
)
slice_layer.set_input(1, trt_concat(network, start_tensors))
slice_layer.set_input(2, trt_concat(network, size_tensors))
set_layer_name(slice_layer, paddle_op)
shuffle_layer = trt_reshape(
network,
slice_layer.get_output(0),
new_shape_tensor,
is_shape_tensor=True,
name=[paddle_op.name(), f"shuffle_tensor_{i}"],
)
outputs.append(shuffle_layer)
return outputs
@converter_registry.register("pd_op.nearest_interp")
def nearest_interp_converter(network, paddle_op, inputs):
input_tensor = inputs[0]
input_shape_tensor = network.add_shape(input_tensor)
set_layer_name(input_shape_tensor, paddle_op)
input_shape_tensor = input_shape_tensor.get_output(0)
input_rank = input_shape_tensor.shape # The reason is unknown that adding this unused code make input_shape_tensor maintain the correct result.
data_format = paddle_op.attrs().get("data_format")
interp_method = paddle_op.attrs().get("interp_method")
align_corners = paddle_op.attrs().get("align_corners")
out_h = paddle_op.attrs().get("out_h")
out_w = paddle_op.attrs().get("out_w")
out_d = paddle_op.attrs().get("out_d")
scale_attr = paddle_op.attrs().get("scale")
# Parse TensorRT version
trt_major = get_trt_version_list()[0]
trt_minor = get_trt_version_list()[1]
trt_version_float = float(f"{trt_major}.{trt_minor}")
# Create Resize layer
resize_layer = network.add_resize(input_tensor)
set_layer_name(resize_layer, paddle_op)
if trt_version_float >= 8.6:
if align_corners:
resize_layer.coordinate_transformation = (
trt.ResizeCoordinateTransformation.ASYMMETRIC
)
else:
resize_layer.coordinate_transformation = (
trt.ResizeCoordinateTransformation.ASYMMETRIC
)
in_dim = input_tensor.shape
scale_h = 1.0
scale_w = 1.0
if scale_attr is not None and len(scale_attr) >= 2:
scale_h = scale_attr[0]
scale_w = scale_attr[1]
else:
if out_h > 0 and out_w > 0:
if data_format == "NCHW":
h_axis = 2
w_axis = 3
elif data_format == "NHWC":
h_axis = 1
w_axis = 2
scale_h = float(out_h) / float(in_dim[h_axis])
scale_w = float(out_w) / float(in_dim[w_axis])
outsize_tensor = None
if inputs[2] is not None:
outsize_tensor = network.add_concatenation(inputs[2])
set_layer_name(outsize_tensor, paddle_op)
outsize_tensor = outsize_tensor.get_output(0)
scales = [1.0] * len(input_tensor.shape)
if data_format == "NCHW":
scales[1] = 1.0
scales[2] = scale_h
scales[3] = scale_w
elif data_format == "NHWC":
scales[1] = scale_h
scales[2] = scale_w
scales[3] = 1.0
else:
raise ValueError(
f"Unsupported data format {data_format}, only NCHW or NHWC are supported."
)
if outsize_tensor is not None:
outsize_itensors = []
batch_dim = get_shape_tensor_element(
network, input_shape_tensor, 0, name=[paddle_op.name(), "batch_dim"]
)
outsize_itensors.append(batch_dim)
if data_format == "NCHW":
channel_dim = get_shape_tensor_element(
network,
input_shape_tensor,
1,
name=[paddle_op.name(), "channel_dim"],
)
outsize_itensors.append(channel_dim)
outsize_itensors.append(outsize_tensor)
elif data_format == "NHWC":
channel_dim = get_shape_tensor_element(
network,
input_shape_tensor,
3,
name=[paddle_op.name(), "channel_dim"],
)
outsize_itensors.append(outsize_tensor)
outsize_itensors.append(channel_dim)
resize_layer.set_input(
1, network.add_concatenation(outsize_itensors).get_output(0)
)
else:
resize_layer.scales = scales
return resize_layer.get_output(0)
@converter_registry.register("pd_op.linear_interp")
def linear_interp_converter(network, paddle_op, inputs):
input_tensor = inputs[0]
data_layout = paddle_op.attrs().get("data_format")
interp_method = paddle_op.attrs().get("interp_method")
align_corners = paddle_op.attrs().get("align_corners")
out_w = paddle_op.attrs().get("out_w")
scale_attr = paddle_op.attrs().get("scale")
layer = network.add_resize(input_tensor)
set_layer_name(layer, paddle_op)
trt_major = get_trt_version_list()[0]
trt_minor = get_trt_version_list()[1]
trt_version_float = float(f"{trt_major}.{trt_minor}")
if trt_version_float >= 8.6:
layer.resize_mode = trt.InterpolationMode.LINEAR
else:
layer.resize_mode = trt.ResizeMode.LINEAR
if align_corners:
layer.coordinate_transformation = (
trt.ResizeCoordinateTransformation.ALIGN_CORNERS
)
else:
layer.coordinate_transformation = (
trt.ResizeCoordinateTransformation.HALF_PIXEL
)
in_dim = input_tensor.shape
scale_w = -1.0
if scale_attr and len(scale_attr) > 0:
scale_w = scale_attr[0]
w_axis = 2 if data_layout == "NCHW" else 1
if float(scale_w) > 0.0:
out_w = int(in_dim[w_axis] * scale_w)
outsize_tensor = None
if len(inputs) > 1 and inputs[1] is not None:
outsize_tensor = inputs[1]
if outsize_tensor is None:
if len(inputs) > 2 and inputs[2] is not None:
outsize_tensor = inputs[2][0]
if out_w > 0 and scale_w <= 0:
scale_w = float(out_w) / float(in_dim[w_axis])
scales = [1.0]
if data_layout == "NCHW":
scales.append(1.0)
scales.append(scale_w)
elif data_layout == "NHWC":
scales.append(scale_w)
scales.append(1.0)
if outsize_tensor is not None:
outsize_itensors = []
input_shape = trt_shape(
network, input_tensor, name=[paddle_op.name(), "input_shape"]
)
batch_dim = get_shape_tensor_element(
network, input_shape, 0, name=[paddle_op.name(), "batch_dim"]
)
outsize_itensors.append(batch_dim)
if data_layout == "NCHW":
channel_dim = get_shape_tensor_element(
network, input_shape, 1, name=[paddle_op.name(), "channel_dim"]
)
outsize_itensors.append(channel_dim)
outsize_itensors.append(outsize_tensor)
elif data_layout == "NHWC":
outsize_itensors.append(outsize_tensor)
channel_dim = get_shape_tensor_element(
network, input_shape, 2, name=[paddle_op.name(), "channel_dim"]
)
outsize_itensors.append(channel_dim)
layer.set_input(
1,
trt_concat(
network,
outsize_itensors,
name=[paddle_op.name(), "outsize_itensors"],
),
)
else:
layer.scales = scales
return layer.get_output(0)
+35
View File
@@ -0,0 +1,35 @@
# Copyright (c) 2024 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 paddle.tensorrt.converter_utils import (
convert_conv2d,
convert_conv3d,
)
from paddle.tensorrt.register import converter_registry
@converter_registry.register("pd_op.depthwise_conv2d")
@converter_registry.register("pd_op.conv2d")
@converter_registry.register("pd_op.fused_conv2d_add_act")
@converter_registry.register("pd_op.conv2d_transpose")
@converter_registry.register("pd_op.depthwise_conv2d_transpose")
def conv2d_converter(network, paddle_op, inputs):
return convert_conv2d(network, paddle_op, inputs)
@converter_registry.register("pd_op.conv3d_transpose")
@converter_registry.register("pd_op.conv3d")
def conv3d_converter(network, paddle_op, inputs):
return convert_conv3d(network, paddle_op, inputs)
+441
View File
@@ -0,0 +1,441 @@
# Copyright (c) 2024 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.
import numpy as np
import tensorrt as trt
import paddle
from paddle.pir.core import datatype_to_str
from paddle.tensorrt.converter_utils import (
add_1D_constant_layer,
get_input_constant_value,
resize_to_1d,
set_layer_name,
trt_cast,
trt_floor_div,
trt_max,
trt_min,
trt_reduce_to_scalar,
trt_reshape,
trt_shape,
trt_sub,
)
from paddle.tensorrt.register import converter_registry
@converter_registry.register("pd_op.full_int_array")
def full_int_array_converter(network, paddle_op, inputs):
value = paddle_op.attrs()["value"]
if len(value) == 0:
return ()
value_weight = trt.Weights(np.array(value, dtype=np.int32))
full_int_array_layer = network.add_constant([len(value)], value_weight)
set_layer_name(full_int_array_layer, paddle_op)
return full_int_array_layer.get_output(0)
@converter_registry.register("pd_op.full")
def full_converter(network, paddle_op, inputs):
shape = paddle_op.attrs()["shape"]
value = paddle_op.attrs().get("value", 1.0)
dtype = paddle_op.attrs().get("dtype")
out_dtype = np.dtype(datatype_to_str[dtype])
if out_dtype == np.dtype("float64"):
out_dtype = np.dtype("float32")
if out_dtype == np.dtype("int64"):
out_dtype = np.dtype("int32")
full_layer = network.add_constant(
shape, np.full(shape, value, dtype=out_dtype)
)
set_layer_name(full_layer, paddle_op)
return full_layer.get_output(0)
@converter_registry.register("pd_op.assign")
@converter_registry.register("pd_op.assign_out_")
def assign_converter(network, paddle_op, inputs):
input_tensor = inputs[0]
identity_layer = network.add_identity(input_tensor)
set_layer_name(identity_layer, paddle_op)
return identity_layer.get_output(0)
@converter_registry.register("pd_op.assign_value")
@converter_registry.register("pd_op.assign_value_")
def assign_value_converter(network, paddle_op, inputs):
attrs = paddle_op.attrs()
shape = attrs['shape']
dtype = attrs['dtype']
values = attrs['values']
paddle_to_np_dtype_map = {
paddle.float16: np.float16,
paddle.float32: np.float32,
paddle.float64: np.float64,
paddle.int32: np.int32,
paddle.int64: np.int64,
}
if dtype not in paddle_to_np_dtype_map:
raise ValueError(
f"Unsupported dtype {dtype} for assign_value op in TRT converter."
)
np_dtype = paddle_to_np_dtype_map[dtype]
arr = np.array(values, dtype=np_dtype).reshape(shape)
if np_dtype == np.int64:
arr = arr.astype(np.int32)
const_layer = network.add_constant(tuple(shape), arr)
set_layer_name(const_layer, paddle_op)
if const_layer is None:
raise RuntimeError("Failed to create constant layer for assign_value.")
return const_layer.get_output(0)
@converter_registry.register("pd_op.arange")
def arange_converter(network, paddle_op, inputs):
start, end, step = inputs
zero_tensor = add_1D_constant_layer(
network, 0, name=[paddle_op.name(), 'zero_tensor']
)
delta = trt_sub(network, start, end, name=[paddle_op.name(), 'delta'])
f_quotient_tensor = trt_floor_div(
network, delta, step, name=[paddle_op.name(), 'f_quotient_tensor']
)
dtype = paddle_op.attrs().get("dtype")
if start.dtype == trt.DataType.FLOAT:
quotient_tensor = trt_cast(
network,
f_quotient_tensor,
trt.int32,
name=[paddle_op.name(), 'quotient_tensor'],
)
else:
quotient_tensor = f_quotient_tensor
delta_1 = trt_sub(
network,
zero_tensor,
quotient_tensor,
name=[paddle_op.name(), 'delta_1'],
)
number_tensor = trt_max(
network, delta_1, zero_tensor, name=[paddle_op.name(), 'number_tensor']
)
start1 = inputs[0]
start1 = trt_reshape(network, start1, (), name=[paddle_op.name(), 'start1'])
fill_layer = network.add_fill(shape=(), op=trt.FillOperation.LINSPACE)
fill_layer.set_input(0, number_tensor)
fill_layer.set_input(1, start1)
fill_layer.set_input(2, step)
set_layer_name(fill_layer, paddle_op)
output_tensor = fill_layer.get_output(0)
if dtype == paddle.int64 or dtype == paddle.int32:
output_tensor = trt_cast(
network,
output_tensor,
trt.int32,
name=[paddle_op.name(), 'output_tensor'],
)
return output_tensor
@converter_registry.register("pd_op.full_like")
def full_like_converter(network, paddle_op, inputs):
input_tensor = inputs[0]
shape = input_tensor.shape
ndims = len(shape)
dtype = int(paddle_op.attrs().get("dtype", -1))
dtype_map = {
0: None, # Undefined
1: trt.bool, # bool
2: trt.int32, # int32
3: trt.int32, # int64 -> int32
4: trt.int32, # int16 -> int32
5: trt.float32, # float16 -> float32
6: trt.float32, # float64 -> float32
7: trt.float32, # float32
8: trt.int32, # uint8 -> int32
11: trt.float32, # float32
}
target_dtype = dtype_map.get(dtype, None)
if target_dtype is None:
target_dtype = input_tensor.dtype
value = get_input_constant_value(paddle_op, inputs, 1)
if value is not None:
if isinstance(value, (list, tuple)):
value = value[0] if value else 0
if target_dtype == trt.int32:
value_tensor = add_1D_constant_layer(
network,
int(value),
np.int32,
name=[paddle_op.name(), 'value_tensor'],
)
else:
value_tensor = add_1D_constant_layer(
network,
float(value),
np.float32,
name=[paddle_op.name(), 'value_tensor'],
)
else:
value_tensor = inputs[1]
if value_tensor.dtype != target_dtype:
value_tensor = trt_cast(
network,
value_tensor,
target_dtype,
name=[paddle_op.name(), 'value_tensor'],
)
shape_tensor = trt_shape(
network, input_tensor, name=[paddle_op.name(), 'shape_tensor']
)
one_rank_tensor = add_1D_constant_layer(
network, [1] * ndims, name=[paddle_op.name(), 'one_rank_tensor']
)
input_shape_tensor = one_rank_tensor
shuffle_layer = network.add_shuffle(value_tensor)
shuffle_layer.set_input(1, input_shape_tensor)
set_layer_name(shuffle_layer, paddle_op)
start = trt.Dims([0] * ndims)
size = trt.Dims([1] * ndims)
stride = trt.Dims([1] * ndims)
starts_tensor = add_1D_constant_layer(
network, [0] * ndims, name=[paddle_op.name(), 'starts_tensor']
)
one_tensor = add_1D_constant_layer(
network, 1, name=[paddle_op.name(), 'one_tensor']
)
sizes_tensor = trt_max(
network,
input_shape_tensor,
shape_tensor,
name=[paddle_op.name(), 'sizes_tensor'],
)
input_sub_tensor = trt_sub(
network,
input_shape_tensor,
one_tensor,
name=[paddle_op.name(), 'input_sub_tensor'],
)
strides_tensor = trt_min(
network,
one_tensor,
input_sub_tensor,
name=[paddle_op.name(), 'strides_tensor'],
)
layer = network.add_slice(shuffle_layer.get_output(0), start, size, stride)
layer.set_input(1, starts_tensor)
layer.set_input(2, sizes_tensor)
layer.set_input(3, strides_tensor)
set_layer_name(layer, paddle_op)
output = layer.get_output(0)
if output.dtype != target_dtype:
output = trt_cast(
network, output, target_dtype, name=[paddle_op.name(), 'output']
)
return output
@converter_registry.register("pd_op.full_with_tensor")
def full_with_tensor_converter(network, paddle_op, inputs):
value_input = inputs[0]
shape_tensor = None
dtype = paddle_op.attrs()["dtype"]
operands = paddle_op.operands()
num_operands = len(operands)
if num_operands >= 2:
shape_tensor = inputs[1]
if isinstance(shape_tensor, list):
shape_tensor_list = shape_tensor
else:
shape_tensor_list = [shape_tensor]
shape_val = get_input_constant_value(paddle_op, inputs, 1)
if shape_val is not None:
shape_tensor = shape_val
else:
shape_tensor = inputs[1]
tensor_rank = 0
if isinstance(shape_tensor, trt.ITensor):
shapes_tensor = shape_tensor
elif isinstance(shape_tensor, (list, tuple)):
shapes_tensor = shape_tensor
else:
raise TypeError(f"Unsupported shape_tensor type: {type(shape_tensor)}")
if shape_tensor is not None and len(shape_tensor_list) == 1:
is_dynamic_shape = True
elif len(shape_tensor_list) >= 1:
is_dynamic_shape = True
else:
is_dynamic_shape = False
if is_dynamic_shape:
if len(shape_tensor_list) == 1:
shape_tensor = shape_tensor_list[0]
if not isinstance(shape_tensor, trt.ITensor):
raise TypeError("shape_tensor must be an ITensor")
tensor_rank = shape_tensor.shape[0]
shapes_tensor = shape_tensor
else:
shape_tensors = []
for tensor in shape_tensor_list:
if len(tensor.shape) == 0:
tensor = trt_reshape(
network, tensor, (1,), name=[paddle_op.name(), "tensor"]
)
shape_tensors.append(tensor)
concat_layer = network.add_concatenation(shape_tensors)
set_layer_name(concat_layer, paddle_op)
shapes_tensor = concat_layer.get_output(0)
tensor_rank = len(shape_tensors)
shapes_tensor = resize_to_1d(
network, shapes_tensor, name=[paddle_op.name(), "shapes_tensor"]
)
fill_layer = network.add_fill(shape=(), op=trt.FillOperation.LINSPACE)
fill_layer.set_input(0, shapes_tensor)
if dtype == paddle.int32 or dtype == paddle.int64:
beta_vec = [0] * tensor_rank
value_input = trt_reduce_to_scalar(
network, value_input, name=[paddle_op.name(), 'value_input']
)
fill_layer.set_input(1, value_input)
fill_layer.set_input(
2, add_1D_constant_layer(network, beta_vec, np.int32)
)
elif dtype == paddle.float32:
beta_vec = [0.0] * tensor_rank
value_input = trt_reduce_to_scalar(
network,
value_input,
trt.float32,
name=[paddle_op.name(), 'value_input'],
)
fill_layer.set_input(1, value_input)
fill_layer.set_input(
2, add_1D_constant_layer(network, beta_vec, np.float32)
)
else:
raise ValueError(f"Unsupported dtype for full_with_tensor: {dtype}")
set_layer_name(fill_layer, paddle_op)
output_tensor = fill_layer.get_output(0)
return output_tensor
@converter_registry.register("pd_op.meshgrid")
def meshgrid_converter(network, paddle_op, vec_inputs):
inputs = vec_inputs[0]
n = len(inputs)
outputs = []
# get all input dims (all input is 1-dim)
input_dims = [network.add_shape(inp).get_output(0) for inp in inputs]
for k in range(n):
# --------------------------------
# step1:reshape k input as [1,..,Dk,..,1]
# --------------------------------
x = inputs[k]
reshape_dims = [] # init dims as 1
for i in range(n):
one = add_1D_constant_layer(
network,
1,
dtype=np.int32,
is_scalar=False,
name=[paddle_op.name(), f'one_{k}'],
)
reshape_dims.append(one)
# replace k-th input dim as Dk
reshape_dims[k] = input_dims[k]
dim_concat = network.add_concatenation(reshape_dims)
set_layer_name(dim_concat, paddle_op)
x_reshaped = network.add_shuffle(x)
x_reshaped.set_input(1, dim_concat.get_output(0))
# --------------------------------
# step2: create tensor([D1, D2, ..., 1, ..., Dn]) that filled with 1
# --------------------------------
ones_shape = []
for i in range(n):
ones_shape.append(input_dims[i])
ones_shape[k] = add_1D_constant_layer(
network,
1,
dtype=np.int32,
is_scalar=False,
name=[paddle_op.name(), f'ones_shape_{k}'],
)
dim_concat = network.add_concatenation(ones_shape)
set_layer_name(dim_concat, paddle_op)
# Fill constant 1
fill_layer = network.add_fill(shape=(), op=trt.FillOperation.LINSPACE)
fill_layer.set_input(0, dim_concat.get_output(0))
value_input = add_1D_constant_layer(
network,
1,
dtype=np.float32,
is_scalar=True,
name=[paddle_op.name(), 'one_for_fill'],
)
fill_layer.set_input(1, value_input)
beta_vec = [0] * n
fill_layer.set_input(
2, add_1D_constant_layer(network, beta_vec, np.float32)
)
# --------------------------------
# step3: element wise multiplication
# --------------------------------
grid = network.add_elementwise(
x_reshaped.get_output(0),
fill_layer.get_output(0),
trt.ElementWiseOperation.PROD,
).get_output(0)
outputs.append(grid)
return outputs
+27
View File
@@ -0,0 +1,27 @@
# Copyright (c) 2024 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 paddle.tensorrt.converter_utils import set_layer_name
from paddle.tensorrt.register import converter_registry
@converter_registry.register("pd_op.einsum")
def convert_einsum(network, paddle_op, inputs):
equation = paddle_op.attrs().get("equation", "")
layer = network.add_einsum(inputs[0], equation)
set_layer_name(layer, paddle_op)
output_tensor = layer.get_output(0)
return output_tensor
+85
View File
@@ -0,0 +1,85 @@
# Copyright (c) 2024 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.
import numpy as np
import tensorrt as trt
from paddle.tensorrt.converter_utils import (
add_1D_constant_layer,
cast_tensor,
set_layer_name,
)
from paddle.tensorrt.register import converter_registry
@converter_registry.register(
"pd_op.one_hot", trt_version="trt_version_ge=8.5.1"
)
def one_hot_converter(network, paddle_op, inputs):
input_tensor, num_classes_tensor = inputs
input_type = input_tensor.dtype
trt_dtype_map = {
trt.DataType.INT32: trt.int32,
}
trt_dtype = trt_dtype_map.get(input_type, None)
trt_dtype = trt_dtype_map[input_type]
if trt_dtype == trt.int32:
values_data = [0, 1]
np_dtype = np.int32
# trt version>10 support int64
elif trt_dtype == trt.int64:
values_data = [0, 1]
np_dtype = np.int64
else:
raise ValueError(f"Unsupported trt_dtype for one_hot: {trt_dtype}")
values_tensor = add_1D_constant_layer(
network,
values_data,
dtype=np_dtype,
name=[paddle_op.name(), 'values_tensor'],
)
if isinstance(num_classes_tensor, trt.Weights):
num_classes_tensor = network.add_constant(
paddle_op.operands()[1].source().shape, num_classes_tensor
)
set_layer_name(num_classes_tensor, paddle_op)
num_classes_tensor = num_classes_tensor.get_output(0)
reshape_layer = network.add_shuffle(num_classes_tensor)
set_layer_name(reshape_layer, paddle_op)
reshape_layer.reshape_dims = ()
depth_tensor = reshape_layer.get_output(0)
depth_tensor = cast_tensor(
network,
depth_tensor,
trt.int32,
name=[paddle_op.name(), 'depth_tensor'],
)
one_hot_layer = network.add_one_hot(
input_tensor, values_tensor, depth_tensor, axis=-1
)
set_layer_name(one_hot_layer, paddle_op)
one_hot_layer.set_output_type(0, trt_dtype)
output_tensor = one_hot_layer.get_output(0)
return [output_tensor]
+178
View File
@@ -0,0 +1,178 @@
# Copyright (c) 2024 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.
import tensorrt as trt
from paddle.tensorrt.converter_utils import (
add_1D_constant_layer,
broadcast,
get_shape_tensor_element,
set_layer_name,
trt_shape,
trt_sum,
)
from paddle.tensorrt.register import converter_registry
from paddle.tensorrt.util import support_fp32_mix_precision
@converter_registry.register("pd_op.matmul")
def matmul_converter(network, paddle_op, inputs):
weight_shape = paddle_op.operands()[1].source().shape
transpose_x = paddle_op.attrs()["transpose_x"]
transpose_y = paddle_op.attrs()["transpose_y"]
self_matrix_op = (
trt.MatrixOperation.TRANSPOSE
if transpose_x
else trt.MatrixOperation.NONE
)
other_matrix_op = (
trt.MatrixOperation.TRANSPOSE
if transpose_y
else trt.MatrixOperation.NONE
)
weight_tensor = inputs[1]
if type(inputs[1]) == trt.Weights:
weight_tensor = network.add_constant(weight_shape, inputs[1])
set_layer_name(weight_tensor, paddle_op)
weight_tensor = weight_tensor.get_output(0)
if len(weight_shape) == 1:
layer = network.add_shuffle(weight_tensor)
layer.reshape_dims = (*tuple(weight_shape), 1)
set_layer_name(layer, paddle_op)
weight_tensor = layer.get_output(0)
lhs_val, rhs_val = broadcast(
network,
inputs[0],
weight_tensor,
inputs[0].name,
"weight_tensor_broadcast",
paddle_op,
)
out = network.add_matrix_multiply(
lhs_val, self_matrix_op, rhs_val, other_matrix_op
)
support_fp32_mix_precision(paddle_op.name(), out)
set_layer_name(out, paddle_op)
return out.get_output(0)
@converter_registry.register("pd_op.transpose")
def transpose_converter(network, paddle_op, inputs):
perm = paddle_op.attrs()["perm"]
transposed_tensor = network.add_shuffle(inputs[0])
transposed_tensor.second_transpose = perm
set_layer_name(transposed_tensor, paddle_op)
return transposed_tensor.get_output(0)
@converter_registry.register("pd_op.bmm")
def bmm_converter(network, paddle_op, inputs):
out = network.add_matrix_multiply(
inputs[0], trt.MatrixOperation.NONE, inputs[1], trt.MatrixOperation.NONE
)
set_layer_name(out, paddle_op)
return out.get_output(0)
@converter_registry.register("pd_op.flip")
def flip_converter(network, paddle_op, inputs):
input_tensor = inputs[0]
input_dims = input_tensor.shape
rank = len(input_dims)
axis = paddle_op.attrs()["axis"]
axis = [a + rank if a < 0 else a for a in axis]
shape_tensor = trt_shape(
network, input_tensor, name=[paddle_op.name(), 'shape_tensor']
)
def get_axis_length(axis_idx, name=None):
dim_val = input_dims[axis_idx]
if dim_val >= 0:
return add_1D_constant_layer(
network,
[dim_val],
is_scalar=True,
name=[paddle_op.name(), name],
)
else:
return get_shape_tensor_element(
network,
shape_tensor,
axis_idx,
is_scalar=True,
name=[paddle_op.name(), name],
)
for axis_idx in axis:
loop_layer = network.add_loop()
trip_limit = get_axis_length(axis_idx, f'trip_limit_{axis_idx}')
loop_layer.add_trip_limit(trip_limit, trt.TripLimit.COUNT)
iterator = loop_layer.add_iterator(input_tensor, axis_idx, reverse=True)
set_layer_name(iterator, paddle_op)
zero_tensor = add_1D_constant_layer(
network, [0], name=[paddle_op.name(), 'zero_tensor']
)
one_tensor = add_1D_constant_layer(
network, [1], name=[paddle_op.name(), 'one_tensor']
)
iRec_layer = loop_layer.add_recurrence(zero_tensor)
set_layer_name(iRec_layer, paddle_op)
iCur = iRec_layer.get_output(0)
iNext_layer = trt_sum(
network, iCur, one_tensor, name=[paddle_op.name(), 'iNext_layer']
)
iRec_layer.set_input(1, iNext_layer)
loop_out_layer = loop_layer.add_loop_output(
iterator.get_output(0), trt.LoopOutput.CONCATENATE, axis_idx
)
loop_out_layer.set_input(1, trip_limit)
set_layer_name(loop_out_layer, paddle_op)
input_tensor = loop_out_layer.get_output(0)
identity_layer = network.add_identity(input_tensor)
set_layer_name(identity_layer, paddle_op)
return identity_layer.get_output(0)
@converter_registry.register("pd_op.p_norm")
def p_norm_converter(network, paddle_op, inputs):
input_tensor = inputs[0]
input_dims = input_tensor.shape
axis = paddle_op.attrs().get("axis", -1)
keepdim = paddle_op.attrs().get("keepdim", False)
axis = axis if axis >= 0 else axis + len(input_dims)
axis_mask = 1 << axis
prod_layer = network.add_elementwise(
input_tensor, input_tensor, trt.ElementWiseOperation.PROD
)
set_layer_name(prod_layer, paddle_op)
prod_tensor = prod_layer.get_output(0)
reduce_layer = network.add_reduce(
prod_tensor, trt.ReduceOperation.SUM, axis_mask, keepdim
)
set_layer_name(reduce_layer, paddle_op)
reduced_tensor = reduce_layer.get_output(0)
sqrt_layer = network.add_unary(reduced_tensor, trt.UnaryOperation.SQRT)
set_layer_name(sqrt_layer, paddle_op)
output_tensor = sqrt_layer.get_output(0)
return output_tensor
+100
View File
@@ -0,0 +1,100 @@
# Copyright (c) 2024 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.
import numpy as np
import tensorrt as trt
from paddle.tensorrt.converter_utils import (
add_elementwise_layer,
set_layer_name,
unary_op_converter,
)
from paddle.tensorrt.register import converter_registry
logic_type_map = {
"pd_op.greater_than": trt.ElementWiseOperation.GREATER,
"pd_op.less_than": trt.ElementWiseOperation.LESS,
"pd_op.equal": trt.ElementWiseOperation.EQUAL,
"pd_op.bitwise_and": trt.ElementWiseOperation.AND,
"pd_op.bitwise_or": trt.ElementWiseOperation.OR,
"pd_op.logical_xor": trt.ElementWiseOperation.XOR,
"pd_op.logical_or": trt.ElementWiseOperation.OR,
"pd_op.logical_or_": trt.ElementWiseOperation.OR,
"pd_op.logical_and": trt.ElementWiseOperation.AND,
}
@converter_registry.register("pd_op.greater_than")
@converter_registry.register("pd_op.less_than")
@converter_registry.register("pd_op.equal")
@converter_registry.register("pd_op.bitwise_and")
@converter_registry.register("pd_op.bitwise_or")
@converter_registry.register("pd_op.logical_xor")
@converter_registry.register("pd_op.logical_or")
@converter_registry.register("pd_op.logical_or_")
@converter_registry.register("pd_op.logical_and")
def logic_converter(network, paddle_op, inputs):
layer_output = add_elementwise_layer(
network, paddle_op, inputs, logic_type_map[paddle_op.name()]
)
return layer_output
@converter_registry.register("pd_op.not_equal")
def not_equal_converter(network, paddle_op, inputs):
layer_output = add_elementwise_layer(
network, paddle_op, inputs, trt.ElementWiseOperation.EQUAL
)
not_layer = network.add_unary(layer_output, trt.UnaryOperation.NOT)
set_layer_name(not_layer, paddle_op)
layer_output = not_layer.get_output(0)
return layer_output
@converter_registry.register("pd_op.bitwise_not")
def bitwise_not_converter(network, paddle_op, inputs):
input_tensor = inputs[0]
if input_tensor.dtype == trt.bool:
bitwise_not_layer = network.add_unary(
input_tensor, trt.UnaryOperation.NOT
)
set_layer_name(bitwise_not_layer, paddle_op)
layer_output = bitwise_not_layer.get_output(0)
else:
neg_one_tensor_dims = trt.Dims([1] * len(input_tensor.shape))
neg_one_value = np.array([-1], dtype=np.int32)
neg_one_weights = trt.Weights(neg_one_value)
neg_one_tensor = network.add_constant(
neg_one_tensor_dims, neg_one_weights
)
set_layer_name(neg_one_tensor, paddle_op)
neg_one_tensor = neg_one_tensor.get_output(0)
mul_neg_one = network.add_elementwise(
input_tensor, neg_one_tensor, trt.ElementWiseOperation.PROD
)
set_layer_name(mul_neg_one, paddle_op)
mul_neg_one = mul_neg_one.get_output(0)
layer_output = network.add_elementwise(
mul_neg_one, neg_one_tensor, trt.ElementWiseOperation.SUM
)
set_layer_name(layer_output, paddle_op)
layer_output = layer_output.get_output(0)
return layer_output
@converter_registry.register("pd_op.logical_not")
@converter_registry.register("pd_op.logical_not_")
def logic_not_converter(network, paddle_op, inputs):
layer_output = unary_op_converter(network, paddle_op, inputs)
return layer_output
File diff suppressed because it is too large Load Diff
+581
View File
@@ -0,0 +1,581 @@
# Copyright (c) 2024 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.
import numpy as np
import tensorrt as trt
from paddle.tensorrt.converter_utils import (
add_1D_constant_layer,
add_cast_reduce_layer,
add_constant_layer,
add_elementwise_layer,
add_reduce_layer,
broadcast,
cast_tensor,
fill_constant_layer,
get_axes_for_reduce_op,
get_axis_length,
get_input_constant_value,
get_shape_tensor_element,
set_layer_name,
trt_cast,
trt_concat,
trt_equal,
trt_expand,
trt_max,
trt_reshape,
trt_shape,
)
from paddle.tensorrt.register import converter_registry
@converter_registry.register("pd_op.add")
@converter_registry.register("pd_op.add_")
def add_converter(network, paddle_op, inputs):
return add_elementwise_layer(
network, paddle_op, inputs, trt.ElementWiseOperation.SUM
)
@converter_registry.register("pd_op.scale")
def scale_converter(network, paddle_op, inputs):
x = inputs[0]
bias = paddle_op.attrs().get("bias", 0.0)
bias_after_scale = paddle_op.attrs().get("bias_after_scale", True)
is_int = x.dtype == trt.DataType.INT32
if is_int:
bias_tensor = add_1D_constant_layer(
network,
int(bias + 0.5) if bias > 0 else int(bias - 0.5),
name=[paddle_op.name(), "bias_tensor"],
)
else:
bias_tensor = add_1D_constant_layer(
network,
bias,
dtype=np.float32,
name=[paddle_op.name(), "bias_tensor"],
)
is_bias_0 = bias == 0
bias_shapes = [1] * len(x.shape)
bias_shapes_tensor = add_1D_constant_layer(
network, bias_shapes, name=[paddle_op.name(), "bias_shapes_tensor"]
)
reshape_layer_bias = network.add_shuffle(bias_tensor)
reshape_layer_bias.set_input(1, bias_shapes_tensor)
set_layer_name(reshape_layer_bias, paddle_op)
scale = get_input_constant_value(paddle_op, inputs, 1)
if scale is not None:
scale = scale[0]
has_scale_tensor = False
if is_int:
scale_tensor = add_1D_constant_layer(
network,
int(scale + 0.5 if scale > 0 else scale - 0.5),
name=[paddle_op.name(), "scale_tensor"],
)
else:
scale_tensor = add_1D_constant_layer(
network,
scale,
dtype=np.float32,
name=[paddle_op.name(), "scale_tensor"],
)
is_scale_1 = scale == 1
else:
has_scale_tensor = True
scale_tensor = inputs[1]
is_scale_1 = False
scale_shapes = [1] * len(x.shape)
scale_shapes_tensor = add_1D_constant_layer(
network, scale_shapes, name=[paddle_op.name(), "scale_shapes_tensor"]
)
reshape_layer_scale = network.add_shuffle(scale_tensor)
reshape_layer_scale.set_input(1, scale_shapes_tensor)
set_layer_name(reshape_layer_scale, paddle_op)
# Initialize the layer variable to ensure it's defined in all branches
layer = None
if not has_scale_tensor and is_scale_1 and is_bias_0:
layer = network.add_identity(x)
set_layer_name(layer, paddle_op)
else:
if bias_after_scale:
if not is_scale_1:
layer = network.add_elementwise(
x,
reshape_layer_scale.get_output(0),
trt.ElementWiseOperation.PROD,
)
set_layer_name(layer, paddle_op)
x = layer.get_output(0)
if not is_bias_0:
layer = network.add_elementwise(
x,
reshape_layer_bias.get_output(0),
trt.ElementWiseOperation.SUM,
)
set_layer_name(layer, paddle_op)
else:
if not is_bias_0:
layer = network.add_elementwise(
x,
reshape_layer_bias.get_output(0),
trt.ElementWiseOperation.SUM,
)
set_layer_name(layer, paddle_op)
x = layer.get_output(0)
if not is_scale_1:
layer = network.add_elementwise(
x,
reshape_layer_scale.get_output(0),
trt.ElementWiseOperation.PROD,
)
set_layer_name(layer, paddle_op)
return layer.get_output(0)
@converter_registry.register("pd_op.max")
def max_converter(network, paddle_op, inputs):
input_tensor = inputs[0]
axis = get_input_constant_value(paddle_op, inputs, 1)
input_shape = input_tensor.shape
keepdim = paddle_op.attrs()["keepdim"]
if network.has_implicit_batch_dimension:
assert axis != 0, (
"can't reduce on axis == 0 when network has implicit batch dimension"
)
if len(axis) == 0:
axis = list(range(len(input_shape)))
for i in range(len(axis)):
if axis[i] < 0:
axis[i] = len(input_shape) + axis[i]
layer = network.add_reduce(
input_tensor,
trt.ReduceOperation.MAX,
axes=get_axes_for_reduce_op(axis),
keep_dims=keepdim,
)
set_layer_name(layer, paddle_op)
return layer.get_output(0)
@converter_registry.register("pd_op.divide")
def divide_converter(network, paddle_op, inputs):
return add_elementwise_layer(
network, paddle_op, inputs, trt.ElementWiseOperation.DIV
)
@converter_registry.register("pd_op.subtract")
def subtract_converter(network, paddle_op, inputs):
return add_elementwise_layer(
network, paddle_op, inputs, trt.ElementWiseOperation.SUB
)
@converter_registry.register("pd_op.multiply")
def multiply_converter(network, paddle_op, inputs):
return add_elementwise_layer(
network, paddle_op, inputs, trt.ElementWiseOperation.PROD
)
@converter_registry.register("pd_op.clip")
def clip_converter(network, paddle_op, inputs):
def _get_constant_or_expand_tensor(
value, constant_inputs, input_shape_tensor, rank, name=None
):
if value is not None:
return fill_constant_layer(
network,
input_shape_tensor,
rank,
value,
input_tensor.dtype,
name=name,
)
else:
expanded_tensor = trt_expand(
network, constant_inputs, 1, input_shape_tensor, rank, name=name
)
if expanded_tensor.dtype != input_tensor.dtype:
expanded_tensor = cast_tensor(
network, expanded_tensor, input_tensor.dtype, name=name
)
return expanded_tensor
input_tensor = inputs[0]
input_shape = input_tensor.shape
rank = len(input_shape)
input_shape_tensor = network.add_shape(input_tensor)
set_layer_name(input_shape_tensor, paddle_op)
input_shape_tensor = input_shape_tensor.get_output(0)
# handle min operation
min_value = get_input_constant_value(paddle_op, inputs, 1)
alpha_t = _get_constant_or_expand_tensor(
min_value, inputs[1], input_shape_tensor, rank
)
# handle max operation
max_value = get_input_constant_value(paddle_op, inputs, 2)
beta_t = _get_constant_or_expand_tensor(
max_value,
inputs[2],
input_shape_tensor,
rank,
name=[paddle_op.name(), 'beta_t'],
)
# run the clip operation
lower_clip = trt_max(
network, input_tensor, alpha_t, name=[paddle_op.name(), 'lower_clip']
)
layer = network.add_elementwise(
lower_clip, beta_t, trt.ElementWiseOperation.MIN
)
set_layer_name(layer, paddle_op)
return layer.get_output(0)
@converter_registry.register("pd_op.pow")
def pow_converter(network, paddle_op, inputs):
from paddle.tensorrt.util import support_fp32_mix_precision
x = inputs[0]
factor = paddle_op.attrs()["y"]
dims_x = x.shape
trt_dims_y = trt.Dims([1] * len(dims_x))
w_data = [factor]
y = add_constant_layer(
network, w_data, trt_dims_y, np.float32, name=[paddle_op.name(), 'y']
)
layer = network.add_elementwise(x, y, trt.ElementWiseOperation.POW)
set_layer_name(layer, paddle_op)
support_fp32_mix_precision(paddle_op.name(), layer)
return layer.get_output(0)
@converter_registry.register("pd_op.remainder")
@converter_registry.register("pd_op.remainder_")
def remainder_converter(network, paddle_op, inputs):
from paddle.tensorrt.util import support_fp32_mix_precision
weight_shape = paddle_op.operands()[1].source().shape
input_shape = inputs[0].shape
weight_tensor = inputs[1]
input_tensor = inputs[0]
if type(inputs[1]) == trt.Weights:
weight_tensor = network.add_constant(weight_shape, inputs[1])
set_layer_name(weight_tensor, paddle_op)
weight_tensor = weight_tensor.get_output(0)
if type(inputs[0]) == trt.Weights:
input_tensor = network.add_constant(input_shape, inputs[0])
set_layer_name(input_tensor, paddle_op)
input_tensor = input_tensor.get_output(0)
lhs_val, rhs_val = broadcast(
network,
input_tensor,
weight_tensor,
"input_tensor_broadcast",
"weight_tensor_broadcast",
paddle_op,
)
is_floor_div = input_tensor.dtype != trt.DataType.INT32
if is_floor_div:
quotient_layer = network.add_elementwise(
lhs_val, rhs_val, trt.ElementWiseOperation.FLOOR_DIV
)
else:
quotient_layer = network.add_elementwise(
lhs_val, rhs_val, trt.ElementWiseOperation.DIV
)
set_layer_name(quotient_layer, paddle_op)
quotient = quotient_layer.get_output(0)
support_fp32_mix_precision(paddle_op.name(), quotient_layer)
# Multiply rhs by the quotient
product_layer = network.add_elementwise(
rhs_val, quotient, trt.ElementWiseOperation.PROD
)
set_layer_name(product_layer, paddle_op)
product = product_layer.get_output(0)
support_fp32_mix_precision(paddle_op.name(), product_layer)
remainder_layer = network.add_elementwise(
lhs_val, product, trt.ElementWiseOperation.SUB
)
set_layer_name(remainder_layer, paddle_op)
remainder = remainder_layer.get_output(0)
support_fp32_mix_precision(paddle_op.name(), remainder_layer)
return remainder
@converter_registry.register("pd_op.min")
def min_converter(network, paddle_op, inputs):
return add_reduce_layer(network, paddle_op, inputs, trt.ReduceOperation.MIN)
@converter_registry.register("pd_op.sum")
def sum_converter(network, paddle_op, inputs):
return add_reduce_layer(network, paddle_op, inputs, trt.ReduceOperation.SUM)
@converter_registry.register("pd_op.mean")
def mean_converter(network, paddle_op, inputs):
return add_reduce_layer(network, paddle_op, inputs, trt.ReduceOperation.AVG)
@converter_registry.register("pd_op.any")
def any_converter(network, paddle_op, inputs):
return add_cast_reduce_layer(
network, paddle_op, inputs, trt.ReduceOperation.MAX
)
@converter_registry.register("pd_op.all")
def all_converter(network, paddle_op, inputs):
return add_cast_reduce_layer(
network, paddle_op, inputs, trt.ReduceOperation.MIN
)
@converter_registry.register("pd_op.cumsum")
def cumsum_converter(network, paddle_op, inputs):
input_tensor = inputs[0]
dtype = input_tensor.dtype
axis = get_input_constant_value(paddle_op, inputs, 1)[0]
input_shape = input_tensor.shape
rank = len(input_shape)
if axis < 0:
axis += rank
axis = int(axis)
# Obtain the number of cycles
if input_shape[axis] > 0:
trip_limit = add_1D_constant_layer(
network,
input_shape[axis],
is_scalar=True,
name=[paddle_op.name(), 'trip_limit'],
)
else:
dynamic_shape = trt_shape(
network, input_tensor, name=[paddle_op.name(), 'dynamic_shape']
)
trip_limit = get_shape_tensor_element(
network,
dynamic_shape,
axis,
True,
name=[paddle_op.name(), 'trip_limit'],
)
# Obtain the slice shape
shape_list = []
for i in range(rank):
if i == axis:
shape_list.append(
add_1D_constant_layer(
network, [1], name=[paddle_op.name(), f'shape_list_{i}']
)
)
else:
shape_list.append(
get_axis_length(
network,
input_tensor,
i,
name=[paddle_op.name(), f'shape_list_{i}'],
)
)
slice_shape = trt_concat(
network, shape_list, name=[paddle_op.name(), 'slice_shape']
)
start = [0] * rank
size = [1] * rank
stride = [1] * rank
input_sliced = network.add_slice(input_tensor, start, size, stride)
input_sliced.set_input(2, slice_shape)
set_layer_name(input_sliced, paddle_op)
# squeeze axis
if rank > 1:
shape_list.pop(axis)
new_shape = trt_concat(
network, shape_list, name=[paddle_op.name(), 'new_shape']
)
squeeze_output = trt_reshape(
network,
input_sliced.get_output(0),
new_shape,
is_shape_tensor=True,
name=[paddle_op.name(), 'squeeze_output'],
)
loop = network.add_loop()
loop.add_trip_limit(trip_limit, trt.TripLimit.COUNT)
iterator = loop.add_iterator(input_tensor, axis)
set_layer_name(iterator, paddle_op)
data = iterator.get_output(0)
# create zero tensor
zero_vec = np.array([0.0], dtype=np.float32)
zero = add_1D_constant_layer(
network, zero_vec, name=[paddle_op.name(), 'zero']
)
lhs_val, rhs_val = broadcast(
network,
squeeze_output,
zero,
"squeeze_output_broadcast",
"zero_output_broadcast",
paddle_op,
)
cast_tensor = trt_cast(
network, rhs_val, dtype, name=[paddle_op.name(), 'cast_tensor']
)
zero_tensor = network.add_elementwise(
lhs_val, cast_tensor, trt.ElementWiseOperation.PROD
)
set_layer_name(zero_tensor, paddle_op)
zero_tensor = zero_tensor.get_output(0)
# Set as scalar
if rank == 1:
zero_tensor = trt_reshape(
network, zero_tensor, (), name=[paddle_op.name(), 'zero_tensor']
)
# Cycle and add according to the axis
running_sum = loop.add_recurrence(zero_tensor)
running_sum_tensor = running_sum.get_output(0)
cur_sum = network.add_elementwise(
data, running_sum_tensor, trt.ElementWiseOperation.SUM
)
set_layer_name(cur_sum, paddle_op)
cur_sum = cur_sum.get_output(0)
running_sum.set_input(1, cur_sum)
set_layer_name(running_sum, paddle_op)
reverse_flag = trt.LoopOutput.CONCATENATE
loop_out = loop.add_loop_output(cur_sum, reverse_flag, axis)
loop_out.set_input(1, trip_limit)
set_layer_name(loop_out, paddle_op)
return loop_out.get_output(0)
@converter_registry.register("pd_op.floor_divide")
def floor_divide_converter(network, paddle_op, inputs):
return add_elementwise_layer(
network, paddle_op, inputs, trt.ElementWiseOperation.FLOOR_DIV
)
@converter_registry.register("pd_op.log")
def log_converter(network, paddle_op, inputs):
input_tensor = trt_cast(
network, inputs[0], trt.float32, name=[paddle_op.name(), 'input_tensor']
)
layer = network.add_unary(input_tensor, trt.UnaryOperation.LOG)
set_layer_name(layer, paddle_op)
return layer.get_output(0)
@converter_registry.register("pd_op.elementwise_pow")
def elementwise_pow_converter(network, paddle_op, inputs):
return add_elementwise_layer(
network, paddle_op, inputs, trt.ElementWiseOperation.POW
)
@converter_registry.register("pd_op.isnan")
def isnan_converter(network, paddle_op, inputs):
input_tensor = inputs[0]
equal_tensor = trt_equal(
network,
input_tensor,
input_tensor,
name=[paddle_op.name(), 'equal_tensor'],
)
layer = network.add_unary(equal_tensor, trt.UnaryOperation.NOT)
set_layer_name(layer, paddle_op)
return layer.get_output(0)
@converter_registry.register("pd_op.minimum")
def minimum_converter(network, paddle_op, inputs):
min_layer = add_elementwise_layer(
network, paddle_op, inputs, trt.ElementWiseOperation.MIN
)
return min_layer
@converter_registry.register("pd_op.maximum")
def maximum_converter(network, paddle_op, inputs):
max_layer = add_elementwise_layer(
network, paddle_op, inputs, trt.ElementWiseOperation.MAX
)
return max_layer
@converter_registry.register("pd_op.greater_equal")
@converter_registry.register("pd_op.greater_equal_")
def greater_equal_converter(network, paddle_op, inputs):
greater_layer_output = add_elementwise_layer(
network, paddle_op, inputs, trt.ElementWiseOperation.GREATER
)
equal_layer_output = add_elementwise_layer(
network, paddle_op, inputs, trt.ElementWiseOperation.EQUAL
)
or_layer = add_elementwise_layer(
network,
paddle_op,
[greater_layer_output, equal_layer_output],
trt.ElementWiseOperation.OR,
)
return or_layer
@converter_registry.register("pd_op.less_equal")
@converter_registry.register("pd_op.less_equal_")
def less_equal_converter(network, paddle_op, inputs):
less_layer_output = add_elementwise_layer(
network, paddle_op, inputs, trt.ElementWiseOperation.LESS
)
equal_layer_output = add_elementwise_layer(
network, paddle_op, inputs, trt.ElementWiseOperation.EQUAL
)
or_layer = add_elementwise_layer(
network,
paddle_op,
[less_layer_output, equal_layer_output],
trt.ElementWiseOperation.OR,
)
return or_layer
+371
View File
@@ -0,0 +1,371 @@
# Copyright (c) 2024 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.
import logging
import numpy as np
import tensorrt as trt
from paddle.base.log_helper import get_logger
from paddle.tensorrt.converter_utils import (
WithFp16,
add_1D_constant_layer,
get_axes_for_reduce_op,
get_dynamic_dims,
get_trt_plugin,
has_dynamic_shape,
set_layer_name,
trt_expand,
trt_prod,
trt_reshape,
trt_sum,
)
from paddle.tensorrt.register import converter_registry
from paddle.tensorrt.util import (
RefitManager,
RefitRole,
TensorRTConstantManager,
support_fp32_mix_precision,
)
_logger = get_logger(
__name__, logging.INFO, fmt='%(asctime)s-%(levelname)s: %(message)s'
)
@converter_registry.register(
"pd_op.layer_norm", trt_version="trt_version_ge=8.6"
)
def layernorm_converter(network, paddle_op, inputs):
input_a, scale, bias = inputs
begin_norm_axis = paddle_op.attrs().get("begin_norm_axis", 0)
epsilon = paddle_op.attrs().get("epsilon", 1e-5)
assert len(paddle_op.operands()) == 3
scale_shape = paddle_op.operands()[1].source().shape
if isinstance(scale, trt.Weights):
scale_tensor = network.add_constant(scale_shape, scale)
set_layer_name(scale_tensor, paddle_op)
scale_tensor = scale_tensor.get_output(0)
bias_shape = paddle_op.operands()[2].source().shape
bias_tensor = network.add_constant(bias_shape, bias)
set_layer_name(bias_tensor, paddle_op)
bias_tensor = bias_tensor.get_output(0)
else:
scale_tensor = scale
bias_tensor = bias
dims = list(range(len(input_a.shape)))[begin_norm_axis:]
axes = get_axes_for_reduce_op(dims)
broadcast_shape = [1] * begin_norm_axis
normalized_shape = list(input_a.shape)[begin_norm_axis:]
broadcast_shape.extend(normalized_shape)
scale_reshape = network.add_shuffle(scale_tensor)
scale_reshape.reshape_dims = tuple(broadcast_shape)
set_layer_name(scale_reshape, [paddle_op.name(), "scale_reshape"])
scale_tensor = scale_reshape.get_output(0)
bias_reshape = network.add_shuffle(bias_tensor)
bias_reshape.reshape_dims = tuple(broadcast_shape)
set_layer_name(bias_reshape, [paddle_op.name(), "bias_reshape"])
bias_tensor = bias_reshape.get_output(0)
layer_norm = network.add_normalization(
input_a, scale_tensor, bias_tensor, axes
)
layer_norm.epsilon = epsilon
set_layer_name(layer_norm, paddle_op)
support_fp32_mix_precision(paddle_op.name(), layer_norm)
layer_norm.compute_precision = trt.float32
return layer_norm.get_output(0)
@converter_registry.register("pd_op.batch_norm")
@converter_registry.register("pd_op.batch_norm_")
def batch_norm_converter(network, paddle_op, inputs):
constant_manager = TensorRTConstantManager()
refit_manager = RefitManager()
input_tensor, mean, variance, scale, bias = inputs
scale_shape = paddle_op.operands()[3].source().shape
eps = paddle_op.attrs().get("epsilon", 1e-8)
scale_name = None
bias_name = None
if isinstance(mean, trt.ITensor):
mean_name = (
paddle_op.operands()[1]
.source()
.get_defining_op()
.attrs()['parameter_name']
)
variance_name = (
paddle_op.operands()[2]
.source()
.get_defining_op()
.attrs()['parameter_name']
)
scale_name = (
paddle_op.operands()[3]
.source()
.get_defining_op()
.attrs()['parameter_name']
)
bias_name = (
paddle_op.operands()[4]
.source()
.get_defining_op()
.attrs()['parameter_name']
)
mean_np = constant_manager.get_constant_value(mean_name)
variance_np = constant_manager.get_constant_value(variance_name)
scale_np = constant_manager.get_constant_value(scale_name)
bias_np = constant_manager.get_constant_value(bias_name)
else:
mean_np = mean.numpy()
variance_np = variance.numpy()
scale_np = scale.numpy()
bias_np = bias.numpy()
actual_scale_np = scale_np / np.sqrt(variance_np + eps)
actual_bias_np = bias_np - mean_np * actual_scale_np
bias = trt.Weights(actual_bias_np)
scale = trt.Weights(actual_scale_np)
power = trt.Weights(np.ones(scale_shape, dtype='float32'))
input_tensor_shape = paddle_op.operands()[0].source().shape
if has_dynamic_shape(input_tensor_shape):
assert input_tensor.shape[1] != -1, (
"Channel dim can't be dynamic for batch norm."
)
output_shape = input_tensor_shape
if not network.has_implicit_batch_dimension and len(input_tensor_shape) < 4:
assert len(get_dynamic_dims(input_tensor.shape)) <= 1, (
"BatchNorm1D with more than one dynamic dims is not currently supported."
)
reshape_layer = network.add_shuffle(input_tensor)
if len(input_tensor_shape) == 2:
reshape_layer.reshape_dims = (
input_tensor_shape[0],
input_tensor_shape[1],
1,
1,
)
else: # len(input_tensor_shape) ==3
reshape_layer.reshape_dims = (
input_tensor_shape[0],
input_tensor_shape[1],
input_tensor_shape[2],
1,
)
set_layer_name(reshape_layer, paddle_op)
input_tensor = reshape_layer.get_output(0)
batch_norm_layer = network.add_scale(
input_tensor, trt.ScaleMode.CHANNEL, bias, scale, power
)
support_fp32_mix_precision(paddle_op.name(), batch_norm_layer)
set_layer_name(batch_norm_layer, paddle_op)
if isinstance(mean, trt.ITensor):
refit_manager.set_mapping(
bias_name, batch_norm_layer.name, RefitRole.SHIFT
)
refit_manager.set_mapping(
scale_name, batch_norm_layer.name, RefitRole.SCALE
)
if not network.has_implicit_batch_dimension and len(output_shape) < 4:
reshape_output_layer = network.add_shuffle(
batch_norm_layer.get_output(0)
)
reshape_output_layer.reshape_dims = tuple(output_shape)
batch_norm_layer = reshape_output_layer
set_layer_name(batch_norm_layer, paddle_op)
return batch_norm_layer.get_output(0)
@converter_registry.register("pd_op.instance_norm")
def instance_norm_converter(network, paddle_op, inputs):
eps = paddle_op.attrs().get("epsilon", 1e-8)
instance_norm_inputs = [inputs[0], inputs[1], inputs[2]]
plugin_fields = [
trt.PluginField(
"epsilon",
np.array(eps, dtype=np.float32),
trt.PluginFieldType.FLOAT32,
),
]
plugin_field_collection = trt.PluginFieldCollection(plugin_fields)
plugin_name = "pir_instance_norm"
plugin_version = "1"
plugin = get_trt_plugin(
plugin_name, plugin_field_collection, plugin_version
)
instance_norm_layer = network.add_plugin_v2(instance_norm_inputs, plugin)
set_layer_name(instance_norm_layer, paddle_op)
return instance_norm_layer.get_output(0)
@converter_registry.register(
"pd_op.fused_bias_dropout_residual_layer_norm",
trt_version="trt_version_ge=8.0",
)
def fused_bias_dropout_residual_layer_norm_converter(
network, paddle_op, inputs
):
input1, input2, ele_bias, scale, bias = inputs
if isinstance(ele_bias, trt.ITensor):
refit_manager = RefitManager
ele_bias = refit_manager.get_trt_weight_tensor(ele_bias.name)
scale = refit_manager.get_trt_weight_tensor(scale.name)
bias = refit_manager.get_trt_weight_tensor(bias.name)
else:
ele_bias = ele_bias
scale = scale
bias = bias
has_bias = ele_bias is not None
bias_size = bias.size
scale_size = scale.size
ele_bias_size = ele_bias.size if has_bias else 0
epsilon = paddle_op.attrs().get("ln_epsilon", 1e-5)
with_fp16 = int(WithFp16())
# TODO: FusedBiasDropoutResidualLayerNorm will support FP16 UT in the future.
if with_fp16 == 1:
raise NotImplementedError(
"FusedBiasDropoutResidualLayerNorm will support FP16 UT in the future."
)
ele_bias_data = (
ele_bias.numpy().astype('float16') if with_fp16 else ele_bias.numpy()
)
plugin_fields = [
trt.PluginField("bias", bias.numpy(), trt.PluginFieldType.FLOAT32),
trt.PluginField("scale", scale.numpy(), trt.PluginFieldType.FLOAT32),
trt.PluginField(
"ele_bias",
ele_bias_data,
(
trt.PluginFieldType.FLOAT16
if with_fp16
else trt.PluginFieldType.FLOAT32
),
),
trt.PluginField(
"bias_size",
np.array([bias_size], dtype=np.int32),
trt.PluginFieldType.INT32,
),
trt.PluginField(
"scale_size",
np.array([scale_size], dtype=np.int32),
trt.PluginFieldType.INT32,
),
trt.PluginField(
"ele_bias_size",
np.array([ele_bias_size], dtype=np.int32),
trt.PluginFieldType.INT32,
),
trt.PluginField(
"epsilon",
np.array([epsilon], dtype=np.float32),
trt.PluginFieldType.FLOAT32,
),
trt.PluginField(
"with_fp16",
np.array([with_fp16], dtype=np.bool_),
trt.PluginFieldType.INT32,
),
]
plugin_field_collection = trt.PluginFieldCollection(plugin_fields)
plugin_name = "pir_preln_residual_bias_plugin_dynamic"
plugin_version = "1"
plugin = get_trt_plugin(
plugin_name, plugin_field_collection, plugin_version
)
plugin_inputs = [input1, input2]
layer = network.add_plugin_v2(plugin_inputs, plugin)
set_layer_name(layer, paddle_op)
return layer.get_output(0)
@converter_registry.register(
"pd_op.group_norm", trt_version="trt_version_ge=8.6"
)
def group_norm_converter(network, paddle_op, inputs):
x, scale, bias = inputs
groups = paddle_op.attrs().get("groups", 1)
eps = paddle_op.attrs().get("epsilon", 1e-05)
axes_mask = 0
x_shape = paddle_op.operands()[0].source().shape
rank_x = len(x_shape)
fake_shape = [1, groups] + [1] * (rank_x - 2)
broadcast_shape = [1, x_shape[1]] + [1] * (rank_x - 2)
for d in range(2, rank_x):
axes_mask |= 1 << d
weight_one = add_1D_constant_layer(
network, 1.0, np.float32, name=[paddle_op.name(), 'weight_one']
)
bias_zero = add_1D_constant_layer(
network, 0.0, np.float32, name=[paddle_op.name(), 'bias_zero']
)
fake_shape = add_1D_constant_layer(
network, fake_shape, np.int32, name=[paddle_op.name(), 'fake_shape']
)
weight_one = trt_expand(
network,
weight_one,
1,
fake_shape,
rank_x,
name=[paddle_op.name(), 'weight_one'],
)
bias_zero = trt_expand(
network,
bias_zero,
1,
fake_shape,
rank_x,
name=[paddle_op.name(), 'bias_zero'],
)
layer = network.add_normalization(x, weight_one, bias_zero, axes_mask)
layer.num_groups = groups
layer.epsilon = eps
set_layer_name(layer, paddle_op)
output = layer.get_output(0)
if scale is not None:
scale = trt_reshape(
network, scale, broadcast_shape, name=[paddle_op.name(), 'scale']
)
output = trt_prod(
network, output, scale, name=[paddle_op.name(), 'output']
)
if bias is not None:
bias = trt_reshape(
network, bias, broadcast_shape, name=[paddle_op.name(), 'bias']
)
output = trt_sum(
network, output, bias, name=[paddle_op.name(), 'output']
)
return output
+276
View File
@@ -0,0 +1,276 @@
# Copyright (c) 2024 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.
import numpy as np
import tensorrt as trt
from paddle.tensorrt.converter_utils import (
WithFp16,
get_trt_plugin,
set_layer_name,
unary_op_converter,
)
from paddle.tensorrt.register import converter_registry
from paddle.tensorrt.util import (
TensorRTConstantManager,
)
@converter_registry.register("pd_op.sqrt")
@converter_registry.register("pd_op.sqrt_")
@converter_registry.register("pd_op.floor")
@converter_registry.register("pd_op.exp")
@converter_registry.register("pd_op.abs")
@converter_registry.register("pd_op.abs_")
@converter_registry.register("pd_op.sin")
@converter_registry.register("pd_op.cos")
@converter_registry.register("pd_op.sinh")
@converter_registry.register("pd_op.cosh")
@converter_registry.register("pd_op.asinh")
@converter_registry.register("pd_op.acosh")
@converter_registry.register("pd_op.atanh")
@converter_registry.register("pd_op.ceil")
@converter_registry.register("pd_op.tan")
@converter_registry.register("pd_op.asin")
@converter_registry.register("pd_op.acos")
@converter_registry.register("pd_op.atan")
@converter_registry.register("pd_op.reciprocal")
@converter_registry.register("pd_op.erf")
@converter_registry.register("pd_op.rsqrt")
@converter_registry.register("pd_op.sign", trt_version="trt_version_ge=8.2")
@converter_registry.register("pd_op.round", trt_version="trt_version_ge=8.2")
def UnaryOpConverter(network, paddle_op, inputs):
layer_output = unary_op_converter(network, paddle_op, inputs)
return layer_output
@converter_registry.register("pd_op.roi_align")
def roi_align_converter(network, paddle_op, inputs):
x = inputs[0]
rois = inputs[1]
pooled_height = paddle_op.attrs().get("pooled_height")
pooled_width = paddle_op.attrs().get("pooled_width")
spatial_scale = paddle_op.attrs().get("spatial_scale")
sampling_ratio = paddle_op.attrs().get("sampling_ratio")
aligned = paddle_op.attrs().get("aligned")
type_id = int(WithFp16())
plugin_fields = [
trt.PluginField(
"type_id",
np.array([type_id], dtype=np.int32),
trt.PluginFieldType.INT32,
),
trt.PluginField(
"pooled_height",
np.array(pooled_height, dtype=np.int32),
trt.PluginFieldType.INT32,
),
trt.PluginField(
"pooled_width",
np.array(pooled_width, dtype=np.int32),
trt.PluginFieldType.INT32,
),
trt.PluginField(
"spatial_scale",
np.array(spatial_scale, dtype=np.float32),
trt.PluginFieldType.FLOAT32,
),
trt.PluginField(
"sampling_ratio",
np.array(sampling_ratio, dtype=np.int32),
trt.PluginFieldType.INT32,
),
trt.PluginField(
"aligned",
np.array(aligned, dtype=np.bool_),
trt.PluginFieldType.INT32,
),
]
plugin_field_collection = trt.PluginFieldCollection(plugin_fields)
plugin_name = "pir_roi_align_plugin_dynamic"
plugin_version = "2"
plugin = get_trt_plugin(
plugin_name, plugin_field_collection, plugin_version
)
roi_align_inputs = [x, rois]
roi_align_layer = network.add_plugin_v2(roi_align_inputs, plugin)
set_layer_name(roi_align_layer, paddle_op)
return roi_align_layer.get_output(0)
@converter_registry.register("pd_op.yolo_box")
def YoloBoxOpConverter(network, paddle_op, inputs):
x, imgSize = inputs
class_num = paddle_op.attrs().get("class_num")
anchors = paddle_op.attrs().get("anchors")
downsample_ratio = paddle_op.attrs().get("downsample_ratio")
conf_thresh = paddle_op.attrs().get("conf_thresh")
clip_bbox = paddle_op.attrs().get("clip_bbox")
scale_x_y = paddle_op.attrs().get("scale_x_y")
iou_aware = paddle_op.attrs().get("iou_aware")
iou_aware_factor = paddle_op.attrs().get("iou_aware_factor")
type_id = int(WithFp16())
anchors = np.array(anchors, dtype=np.int32)
plugin_fields = [
trt.PluginField(
"type_id",
np.array([type_id], dtype=np.int32),
trt.PluginFieldType.INT32,
),
trt.PluginField(
"anchors",
anchors,
trt.PluginFieldType.INT32,
),
trt.PluginField(
"class_num",
np.array(class_num, dtype=np.int32),
trt.PluginFieldType.INT32,
),
trt.PluginField(
"conf_thresh",
np.array(conf_thresh, dtype=np.float32),
trt.PluginFieldType.FLOAT32,
),
trt.PluginField(
"downsample_ratio",
np.array(downsample_ratio, dtype=np.int32),
trt.PluginFieldType.INT32,
),
trt.PluginField(
"clip_bbox",
np.array(clip_bbox, dtype=np.bool_),
trt.PluginFieldType.INT32,
),
trt.PluginField(
"scale_x_y",
np.array(scale_x_y, dtype=np.float32),
trt.PluginFieldType.FLOAT32,
),
trt.PluginField(
"iou_aware",
np.array(iou_aware, dtype=np.bool_),
trt.PluginFieldType.INT32,
),
trt.PluginField(
"iou_aware_factor",
np.array(iou_aware_factor, dtype=np.float32),
trt.PluginFieldType.FLOAT32,
),
]
plugin_field_collection = trt.PluginFieldCollection(plugin_fields)
plugin_name = "yolo_box_plugin_dynamic"
plugin_version = "1"
plugin = get_trt_plugin(
plugin_name, plugin_field_collection, plugin_version
)
yolo_box_inputs = [x, imgSize]
yolo_box_layer = network.add_plugin_v2(yolo_box_inputs, plugin)
set_layer_name(yolo_box_layer, paddle_op)
out0 = yolo_box_layer.get_output(0)
out1 = yolo_box_layer.get_output(1)
return (out0, out1)
@converter_registry.register(
"pd_op.deformable_conv", trt_version="trt_version_ge=8.5"
)
def deformable_conv_converter(network, paddle_op, inputs):
input = inputs[0]
constant_manager = TensorRTConstantManager()
offset = inputs[1]
filter = inputs[2]
mask = inputs[3]
if isinstance(filter, trt.ITensor):
filter_name = (
paddle_op.operands()[2]
.source()
.get_defining_op()
.attrs()['parameter_name']
)
filter = constant_manager.get_constant_value(filter_name)
else:
filter = filter.numpy()
groups = paddle_op.attrs().get("groups")
deformable_groups = paddle_op.attrs().get("deformable_groups")
im2col_step = paddle_op.attrs().get("im2col_step")
strides = paddle_op.attrs().get("strides")
paddings = paddle_op.attrs().get("paddings")
dilations = paddle_op.attrs().get("dilations")
kernel_dims = paddle_op.operands()[2].source().shape
plugin_fields = [
trt.PluginField(
"with_fp16",
np.array([False], dtype=np.bool_),
trt.PluginFieldType.INT32,
),
trt.PluginField(
"weights",
filter,
trt.PluginFieldType.FLOAT32,
),
trt.PluginField(
"kernel_dims",
np.array(kernel_dims, dtype=np.int32),
trt.PluginFieldType.INT32,
),
trt.PluginField(
"strides",
np.array(strides, dtype=np.int32),
trt.PluginFieldType.INT32,
),
trt.PluginField(
"paddings",
np.array(paddings, dtype=np.int32),
trt.PluginFieldType.INT32,
),
trt.PluginField(
"dilations",
np.array(dilations, dtype=np.int32),
trt.PluginFieldType.INT32,
),
trt.PluginField(
"groups",
np.array(groups, dtype=np.int32),
trt.PluginFieldType.INT32,
),
trt.PluginField(
"deformable_groups",
np.array(deformable_groups, dtype=np.int32),
trt.PluginFieldType.INT32,
),
trt.PluginField(
"im2col_step",
np.array(im2col_step, dtype=np.int32),
trt.PluginFieldType.INT32,
),
]
plugin_field_collection = trt.PluginFieldCollection(plugin_fields)
plugin_name = "pir_deformable_conv_plugin"
plugin_version = "1"
plugin = get_trt_plugin(
plugin_name, plugin_field_collection, plugin_version
)
deformable_conv_layer = network.add_plugin_v2(
[inputs[0], inputs[1], inputs[3]], plugin
)
set_layer_name(deformable_conv_layer, paddle_op)
return deformable_conv_layer.get_output(0)
+717
View File
@@ -0,0 +1,717 @@
# Copyright (c) 2024 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.
import logging
import numpy as np
import tensorrt as trt
from paddle.base.log_helper import get_logger
from paddle.tensorrt.converter_utils import (
add_1D_constant_layer,
fill_constant_layer,
get_input_constant_value,
get_shape_tensor_element,
get_trt_plugin,
set_layer_name,
trt_concat,
trt_div,
trt_gather,
trt_prod,
trt_shape,
trt_sub,
trt_sum,
trt_unsqueeze,
)
from paddle.tensorrt.register import converter_registry
from paddle.tensorrt.util import RefitManager
_logger = get_logger(
__name__, logging.INFO, fmt='%(asctime)s-%(levelname)s: %(message)s'
)
@converter_registry.register("pd_op.multiclass_nms3")
def multiclass_nms3_converter(network, paddle_op, inputs):
bboxes = inputs[0]
scores = inputs[1]
background_label = paddle_op.attrs().get("background_label")
score_threshold = paddle_op.attrs().get("score_threshold")
nms_top_k = paddle_op.attrs().get("nms_top_k")
nms_threshold = paddle_op.attrs().get("nms_threshold")
keep_top_k = paddle_op.attrs().get("keep_top_k")
normalized = paddle_op.attrs().get("normalized")
num_classes = scores.shape[1]
bboxes_dims = bboxes.shape
bboxes_expand_dims = [bboxes_dims[0], bboxes_dims[1], 1, bboxes_dims[2]]
bboxes_expand_layer = network.add_shuffle(bboxes)
bboxes_expand_layer.reshape_dims = trt.Dims(bboxes_expand_dims)
set_layer_name(bboxes_expand_layer, paddle_op)
scores_transpose_layer = network.add_shuffle(scores)
scores_transpose_layer.first_transpose = (0, 2, 1)
set_layer_name(scores_transpose_layer, paddle_op)
# create multiclass num3 plugin
batch_nms_inputs = [
bboxes_expand_layer.get_output(0),
scores_transpose_layer.get_output(0),
]
plugin_fields = [
trt.PluginField(
"shareLocation",
np.array([1], dtype=np.int32),
trt.PluginFieldType.INT32,
),
trt.PluginField(
"backgroundLabelId",
np.array(background_label, dtype=np.int32),
trt.PluginFieldType.INT32,
),
trt.PluginField(
"numClasses",
np.array(num_classes, dtype=np.int32),
trt.PluginFieldType.INT32,
),
trt.PluginField(
"topK",
np.array(nms_top_k, dtype=np.int32),
trt.PluginFieldType.INT32,
),
trt.PluginField(
"keepTopK",
np.array(keep_top_k, dtype=np.int32),
trt.PluginFieldType.INT32,
),
trt.PluginField(
"scoreThreshold",
np.array(score_threshold, dtype=np.float32),
trt.PluginFieldType.FLOAT32,
),
trt.PluginField(
"iouThreshold",
np.array(nms_threshold, dtype=np.float32),
trt.PluginFieldType.FLOAT32,
),
trt.PluginField(
"isNormalized",
np.array(normalized, dtype=np.int32),
trt.PluginFieldType.INT32,
),
trt.PluginField(
"clipBoxes",
np.array([0], dtype=np.int32),
trt.PluginFieldType.INT32,
),
]
plugin_field_collection = trt.PluginFieldCollection(plugin_fields)
plugin_name = "BatchedNMSDynamic_TRT"
plugin_version = "1"
plugin = get_trt_plugin(
plugin_name, plugin_field_collection, plugin_version
)
batch_nms_layer = network.add_plugin_v2(batch_nms_inputs, plugin)
set_layer_name(batch_nms_layer, paddle_op)
# dynamic shape: [bs, keep_topk, 4], [bs, keep_topk], [bs, keep_topk]
nmsed_boxes = batch_nms_layer.get_output(1)
nmsed_scores = batch_nms_layer.get_output(2)
nmsed_classes = batch_nms_layer.get_output(3)
nmsed_scores_transpose_layer = network.add_shuffle(nmsed_scores)
set_layer_name(nmsed_scores_transpose_layer, paddle_op)
nmsed_classes_reshape_layer = network.add_shuffle(nmsed_classes)
set_layer_name(nmsed_classes_reshape_layer, paddle_op)
nmsed_scores_transpose_layer.reshape_dims = trt.Dims(
[bboxes_dims[0], keep_top_k, 1]
)
nmsed_classes_reshape_layer.reshape_dims = trt.Dims(
[bboxes_dims[0], keep_top_k, 1]
)
concat_inputs = [
nmsed_classes_reshape_layer.get_output(0),
nmsed_scores_transpose_layer.get_output(0),
nmsed_boxes,
]
nms_concat_layer = network.add_concatenation(inputs=concat_inputs)
nms_concat_layer.axis = 2
set_layer_name(nms_concat_layer, paddle_op)
nms_concat_output = nms_concat_layer.get_output(0)
nms_shuffle_layer = network.add_shuffle(nms_concat_output)
nms_shuffle_layer.reshape_dims = trt.Dims(
[bboxes_dims[0], nms_concat_output.shape[-1]]
)
set_layer_name(nms_shuffle_layer, paddle_op)
# add fake index as output to be consistent with the outputs of multiclass_nms3
shape_weight = trt.Weights(np.array([0], dtype=np.int32))
constant_layer = network.add_constant([1, 1], shape_weight)
set_layer_name(constant_layer, paddle_op)
return (
nms_shuffle_layer.get_output(0),
constant_layer.get_output(0),
batch_nms_layer.get_output(0),
)
@converter_registry.register("pd_op.set_value")
@converter_registry.register("pd_op.set_value_")
@converter_registry.register("pd_op.set_value_with_tensor")
@converter_registry.register("pd_op.set_value_with_tensor_")
def set_value_converter(network, paddle_op, inputs):
x = inputs[0]
if (
paddle_op.name() == "pd_op.set_value"
or paddle_op.name() == "pd_op.set_value_"
):
starts = get_input_constant_value(paddle_op, inputs, 1)[0]
ends = get_input_constant_value(paddle_op, inputs, 2)[0]
steps = get_input_constant_value(paddle_op, inputs, 3)[0]
else:
starts = get_input_constant_value(paddle_op, inputs, 2)[0]
ends = get_input_constant_value(paddle_op, inputs, 3)[0]
steps = get_input_constant_value(paddle_op, inputs, 4)[0]
axes = paddle_op.attrs()["axes"][0]
input_dims = x.shape
# check params and refill
if axes < 0:
axes += len(input_dims)
if ends < 0:
ends += input_dims[axes]
if ends >= input_dims[axes]:
ends = input_dims[axes]
if (
paddle_op.name() == "pd_op.set_value_with_tensor"
or paddle_op.name() == "pd_op.set_value_with_tensor_"
):
updates = inputs[1]
else:
value = paddle_op.attrs().get("values")
input_shape_tensor = trt_shape(
network, x, name=[paddle_op.name(), 'input_shape_tensor']
)
vec_tensor = []
for i in range(len(input_dims)):
vec_tensor.append(
get_shape_tensor_element(
network,
input_shape_tensor,
i,
name=[paddle_op.name(), f'vec_tensor_{i}'],
)
)
axes_vec = [(ends - 1 - starts) / steps + 1]
vec_tensor[axes] = add_1D_constant_layer(
network, axes_vec, name=[paddle_op.name(), f'vec_tensor_{axes}']
)
output_shape_tensor = trt_concat(
network,
vec_tensor,
0,
name=[paddle_op.name(), 'output_shape_tensor'],
)
updates = fill_constant_layer(
network,
output_shape_tensor,
len(x.shape),
value,
x.dtype,
name=[paddle_op.name(), 'updates'],
)
_logger.info(f"Set_value_op: input's dimension is {input_dims}")
decrease_axes = paddle_op.attrs()["decrease_axes"]
if len(decrease_axes) > 0 and len(updates.shape) != len(x.shape):
updates = trt_unsqueeze(
network,
updates,
decrease_axes,
name=[paddle_op.name(), 'decrease_axes'],
)
value_rank = len(updates.shape)
input_rank = len(x.shape)
assert value_rank == input_rank, (
"value's rank is not equal to input's rank, "
'you should modify trt_config(a TensorRTConfig object) and set trt_config.disable_ops = ["{op_name}"] to forbid this op '
)
_logger.info(f"Set_value_op: updates tensor's simension is {updates.shape}")
# calculate dims
update_dims = updates.shape
assert update_dims[axes] > 0, (
"the update value shape[{axes}] must be greater than 0, but received {update_dims[axes]}"
)
assert input_dims[axes] > 0, (
"the input shape[{axes}] must be greater than 0, but received {input_dims[axes]}"
)
input_dims_rank = len(input_dims)
assert axes <= input_dims_rank, (
"The axes {axes} is larger than total axes {input_dims_rank}"
)
assert starts <= input_dims[axes], (
"The start {starts} of dim {axes} is larger than origin shape {input_dims[axes]}"
)
target_update_dim = (ends - 1 - starts) / steps + 1
assert update_dims[axes] == target_update_dim, (
"the {axes}th axis of update dim error, should be {target_update_dim}, but we got {update_dims[axes]}"
)
shape_0 = [1] * len(update_dims)
shape_weight = trt.Weights(np.array([0], dtype=np.float32))
zero_tensor = network.add_constant(shape_0, shape_weight)
set_layer_name(zero_tensor, paddle_op)
zero_tensor = zero_tensor.get_output(0)
indice_tensor = trt_prod(
network, zero_tensor, updates, name=[paddle_op.name(), 'indice_tensor']
)
cast_layer = network.add_identity(indice_tensor)
set_layer_name(cast_layer, paddle_op)
cast_layer.set_output_type(0, trt.int32)
indice_tensor = cast_layer.get_output(0)
shape_1 = [1] * len(update_dims)
shape_1[axes] = update_dims[axes]
tmp_1 = []
for i in range(starts, ends, steps):
tmp_1.append(i)
shape_weight = trt.Weights(np.array(tmp_1, dtype=np.int32))
one_tensor = network.add_constant(shape_1, shape_weight)
set_layer_name(one_tensor, paddle_op)
one_tensor = one_tensor.get_output(0)
indice_tensor = trt_sum(
network,
indice_tensor,
one_tensor,
name=[paddle_op.name(), 'indice_tensor'],
)
layer = network.add_scatter(
x, indice_tensor, updates, trt.ScatterMode.ELEMENT
)
set_layer_name(layer, paddle_op)
layer.axis = axes
return layer.get_output(0)
@converter_registry.register("pd_op.share_data")
@converter_registry.register("pd_op.share_data_")
def share_data_converter(network, paddle_op, inputs):
x = inputs[0]
identity_layer = network.add_identity(x)
set_layer_name(identity_layer, paddle_op)
return identity_layer.get_output(0)
@converter_registry.register("pd_op.temporal_shift")
def temporal_shift_converter(network, paddle_op, inputs):
input_tensor = inputs[0]
# Add a small bias to shift_ratio to mitigate floating point precision errors
shift_ratio = paddle_op.attrs()["shift_ratio"] + 1e-7
T = paddle_op.attrs()["seg_num"]
data_format = paddle_op.attrs().get("data_format", "NCHW")
if data_format == "NHWC":
# Transpose input to [N, C, H, W]
transpose_layer = network.add_shuffle(input_tensor)
transpose_layer.first_transpose = trt.Permutation([0, 3, 1, 2])
set_layer_name(transpose_layer, paddle_op)
input_tensor = transpose_layer.get_output(0)
input_dims = input_tensor.shape
C, H, W = input_dims[1], input_dims[2], input_dims[3]
# Reshape input to [N, T, C, H, W]
reshape_layer = network.add_shuffle(input_tensor)
reshape_layer.reshape_dims = trt.Dims([-1, T, C, H, W])
set_layer_name(reshape_layer, paddle_op)
input_tensor = reshape_layer.get_output(0)
# Pad input to [N, T + 2, C, H, W]
pre_pad = add_1D_constant_layer(
network, [0, 1, 0, 0, 0], name=[paddle_op.name(), 'pre_pad']
)
post_pad = add_1D_constant_layer(
network, [0, 1, 0, 0, 0], name=[paddle_op.name(), 'post_pad']
)
dims = 5
zeros = add_1D_constant_layer(
network, [0] * dims, name=[paddle_op.name(), 'zeros']
)
start = trt_sub(network, zeros, pre_pad, name=[paddle_op.name(), 'start'])
total_padding = trt_sum(
network, pre_pad, post_pad, name=[paddle_op.name(), 'total_padding']
)
input_shape = trt_shape(
network, input_tensor, name=[paddle_op.name(), 'input_shape']
)
size = trt_sum(
network, input_shape, total_padding, name=[paddle_op.name(), 'size']
)
stride = [1] * dims
dummy = stride
slice_layer = network.add_slice(input_tensor, dummy, dummy, stride)
slice_layer.set_input(1, start)
slice_layer.set_input(2, size)
set_layer_name(slice_layer, paddle_op)
trt_version = trt.__version__.split('.')
if int(trt_version[0]) > 8 or (
int(trt_version[0]) == 8 and int(trt_version[1]) >= 5
):
slice_layer.mode = trt.SampleMode.FILL
else:
slice_layer.mode = trt.SliceMode.FILL
slice_c = int(C * shift_ratio)
slice_c2 = int(C * shift_ratio * 2)
slice_start1 = zeros
slice_start2 = add_1D_constant_layer(
network, [0, 2, slice_c, 0, 0], name=[paddle_op.name(), 'slice_start2']
)
slice_start3 = add_1D_constant_layer(
network, [0, 1, slice_c2, 0, 0], name=[paddle_op.name(), 'slice_start3']
)
slice_size_base = trt_shape(
network, input_tensor, name=[paddle_op.name(), 'slice_size_base']
)
sub_size1 = add_1D_constant_layer(
network, [0, 0, C - slice_c, 0, 0], name=[paddle_op.name(), 'sub_size1']
)
sub_size2 = add_1D_constant_layer(
network,
[0, 0, C + slice_c - slice_c2, 0, 0],
name=[paddle_op.name(), 'sub_size2'],
)
sub_size3 = add_1D_constant_layer(
network, [0, 0, slice_c2, 0, 0], name=[paddle_op.name(), 'sub_size3']
)
slice_size1 = trt_sub(
network,
slice_size_base,
sub_size1,
name=[paddle_op.name(), 'slice_size1'],
)
slice_size2 = trt_sub(
network,
slice_size_base,
sub_size2,
name=[paddle_op.name(), 'slice_size2'],
)
slice_size3 = trt_sub(
network,
slice_size_base,
sub_size3,
name=[paddle_op.name(), 'slice_size3'],
)
slice1_layer = network.add_slice(
slice_layer.get_output(0), start=dummy, shape=dummy, stride=stride
)
slice1_layer.set_input(1, slice_start1)
slice1_layer.set_input(2, slice_size1)
set_layer_name(slice1_layer, paddle_op)
slice2_layer = network.add_slice(
slice_layer.get_output(0), start=dummy, shape=dummy, stride=stride
)
slice2_layer.set_input(1, slice_start2)
slice2_layer.set_input(2, slice_size2)
set_layer_name(slice2_layer, paddle_op)
slice3_layer = network.add_slice(
slice_layer.get_output(0), start=dummy, shape=dummy, stride=stride
)
slice3_layer.set_input(1, slice_start3)
slice3_layer.set_input(2, slice_size3)
set_layer_name(slice3_layer, paddle_op)
concat_inputs = [slice2_layer.get_output(0), slice3_layer.get_output(0)]
if slice_c == 0:
concat_layer = network.add_concatenation(concat_inputs)
concat_layer.axis = 2
set_layer_name(concat_layer, paddle_op)
else:
concat_inputs = [
slice1_layer.get_output(0),
slice2_layer.get_output(0),
slice3_layer.get_output(0),
]
concat_layer = network.add_concatenation(concat_inputs)
concat_layer.axis = 2
set_layer_name(concat_layer, paddle_op)
# Reshape output to [N*T,C,H,W]
reshape_layer3 = network.add_shuffle(concat_layer.get_output(0))
reshape_layer3.reshape_dims = trt.Dims([-1, C, H, W])
set_layer_name(reshape_layer3, paddle_op)
if data_format == "NHWC":
transpose_layer2 = network.add_shuffle(reshape_layer3.get_output(0))
transpose_layer2.first_transpose = trt.Permutation([0, 2, 3, 1])
set_layer_name(transpose_layer2, paddle_op)
output_tensor = transpose_layer2.get_output(0)
else:
output_tensor = reshape_layer3.get_output(0)
return output_tensor
@converter_registry.register("pd_op.anchor_generator")
def anchor_generator_converter(network, paddle_op, inputs):
inputs = inputs[0]
input_dims = inputs.shape
anchor_sizes = paddle_op.attrs().get("anchor_sizes")
aspect_ratios = paddle_op.attrs().get("aspect_ratios")
stride = paddle_op.attrs().get("stride")
variances = paddle_op.attrs().get("variances")
offset = paddle_op.attrs().get("offset")
num_anchors = len(aspect_ratios) * len(anchor_sizes)
height = input_dims[1]
width = input_dims[2]
plugin_fields = [
trt.PluginField(
"anchor_sizes",
np.array(anchor_sizes, dtype=np.float32),
trt.PluginFieldType.FLOAT32,
),
trt.PluginField(
"aspect_ratios",
np.array(aspect_ratios, dtype=np.float32),
trt.PluginFieldType.FLOAT32,
),
trt.PluginField(
"stride",
np.array(stride, dtype=np.float32),
trt.PluginFieldType.FLOAT32,
),
trt.PluginField(
"variances",
np.array(variances, dtype=np.float32),
trt.PluginFieldType.FLOAT32,
),
trt.PluginField(
"offset",
np.array(offset, dtype=np.float32),
trt.PluginFieldType.FLOAT32,
),
trt.PluginField(
"num_anchors",
np.array(num_anchors, dtype=np.int32),
trt.PluginFieldType.INT32,
),
]
plugin_field_collection = trt.PluginFieldCollection(plugin_fields)
plugin_name = "pir_anchor_generator_plugin_dynamic"
plugin_version = "1"
plugin = get_trt_plugin(
plugin_name, plugin_field_collection, plugin_version
)
anchor_generator_layer = network.add_plugin_v2([inputs], plugin)
set_layer_name(anchor_generator_layer, paddle_op)
out0 = anchor_generator_layer.get_output(0)
out1 = anchor_generator_layer.get_output(1)
return (out0, out1)
@converter_registry.register("pd_op.affine_channel")
def affine_channel_converter(network, paddle_op, inputs):
x, scale, bias = inputs
data_layout = paddle_op.attrs().get("data_layout")
if isinstance(scale, trt.ITensor):
refit_manager = RefitManager()
scale_weights = refit_manager.get_trt_weight_tensor(scale.name)
bias_weights = refit_manager.get_trt_weight_tensor(bias.name)
else:
scale_weights = scale
bias_weights = bias
if data_layout == "NCHW":
channel_axis = 1
x_input = x
elif data_layout == "NHWC":
# Permute NHWC to NCHW
shuffle_layer1 = network.add_shuffle(x)
shuffle_layer1.first_transpose = (0, 3, 1, 2)
set_layer_name(shuffle_layer1, paddle_op)
x_input = shuffle_layer1.get_output(0)
channel_axis = 1
else:
raise ValueError(f"affine_channel: Unsupported layout: {data_layout}")
if scale_weights.size != bias_weights.size:
raise ValueError(
f"affine_channel: scale.size({scale_weights.size}) != bias.size({bias_weights.size})"
)
power_array = np.ones((scale_weights.size,), dtype=np.float32)
power_weights = trt.Weights(power_array)
layer = network.add_scale_nd(
input=x_input,
mode=trt.ScaleMode.CHANNEL,
shift=bias_weights,
scale=scale_weights,
power=power_weights,
channel_axis=channel_axis,
)
set_layer_name(layer, paddle_op)
if not layer:
raise RuntimeError("affine_channel: add_scale_nd failed.")
out_tensor = layer.get_output(0)
if data_layout == "NHWC":
shuffle_layer2 = network.add_shuffle(out_tensor)
shuffle_layer2.first_transpose = (0, 2, 3, 1)
set_layer_name(shuffle_layer2, paddle_op)
out_tensor = shuffle_layer2.get_output(0)
return out_tensor
@converter_registry.register("pd_op.shuffle_channel")
def shuffle_channel_converter(network, paddle_op, inputs):
input = inputs[0]
group = paddle_op.attrs().get("group")
input_shape_tensor = trt_shape(
network, input, name=[paddle_op.name(), 'input_shape_tensor']
)
batch_shape_tensor = get_shape_tensor_element(
network,
input_shape_tensor,
0,
name=[paddle_op.name(), 'batch_shape_tensor'],
)
channel_shape_tensor = get_shape_tensor_element(
network,
input_shape_tensor,
1,
name=[paddle_op.name(), 'channel_shape_tensor'],
)
group_tensor = add_1D_constant_layer(
network, group, name=[paddle_op.name(), 'group_tensor']
)
new_channel_shape_tensor = trt_div(
network,
channel_shape_tensor,
group_tensor,
name=[paddle_op.name(), 'new_channel_shape_tensor'],
)
shape_dim2 = [2, 3]
shape_dim2_tensor = trt_gather(
network,
input_shape_tensor,
shape_dim2,
name=[paddle_op.name(), 'shape_dim2_tensor'],
)
itensors = [
batch_shape_tensor,
group_tensor,
new_channel_shape_tensor,
shape_dim2_tensor,
]
reshape_tensor = trt_concat(
network, itensors, name=[paddle_op.name(), 'reshape_tensor']
)
layer = network.add_shuffle(input)
layer.set_input(1, reshape_tensor)
transpose_embed = trt.Permutation([0, 2, 1, 3, 4])
layer.second_transpose = transpose_embed
set_layer_name(layer, paddle_op)
output = layer.get_output(0)
output_layer = network.add_shuffle(output)
output_layer.set_input(1, input_shape_tensor)
set_layer_name(output_layer, paddle_op)
return output_layer.get_output(0)
@converter_registry.register("pd_op.full_batch_size_like")
def full_batch_size_like_converter(network, paddle_op, inputs):
input = inputs[0]
input_dim_idx = paddle_op.attrs().get("input_dim_idx")
output_dim_idx = paddle_op.attrs().get("output_dim_idx")
value = paddle_op.attrs().get("value")
shape = paddle_op.attrs().get("shape")
value = float(value)
input_shape_tensor = trt_shape(
network, input, name=[paddle_op.name(), 'input_shape_tensor']
)
batch_tensor = get_shape_tensor_element(
network,
input_shape_tensor,
input_dim_idx,
name=[paddle_op.name(), 'batch_tensor'],
)
shape_attr_tensor = add_1D_constant_layer(
network, shape, name=[paddle_op.name(), 'shape_attr_tensor']
)
gather_output_shape_indices = [
len(shape) if i == output_dim_idx else i for i in range(len(shape))
]
concat_inputs = [shape_attr_tensor, batch_tensor]
concat_tensor = trt_concat(
network, concat_inputs, name=[paddle_op.name(), 'concat_tensor']
)
out_shape_tensor = trt_gather(
network,
concat_tensor,
gather_output_shape_indices,
name=[paddle_op.name(), 'out_shape_tensor'],
)
layer = network.add_fill(shape=(), op=trt.FillOperation.LINSPACE)
value_tensor = add_1D_constant_layer(
network,
[value],
is_scalar=True,
name=[paddle_op.name(), 'value_tensor'],
)
beta_vec = [0.0] * len(shape)
beta_tensor = add_1D_constant_layer(
network,
beta_vec,
is_scalar=False,
name=[paddle_op.name(), 'beta_tensor'],
)
layer.set_input(0, out_shape_tensor)
layer.set_input(1, value_tensor)
layer.set_input(2, beta_tensor)
set_layer_name(layer, paddle_op)
return layer.get_output(0)
+393
View File
@@ -0,0 +1,393 @@
# Copyright (c) 2024 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.
import numpy as np
import tensorrt as trt
from paddle.tensorrt.converter_utils import (
get_input_constant_value,
get_trt_plugin,
set_layer_name,
)
from paddle.tensorrt.register import converter_registry
@converter_registry.register("pd_op.pool2d")
def pool2d_converter(network, paddle_op, inputs):
input_tensor = inputs[0]
input_shape = paddle_op.operands()[0].source().shape
input_dims = len(input_shape)
global_pooling = paddle_op.attrs().get("global_pooling", False)
pool_type = paddle_op.attrs().get("pooling_type", "avg")
strides = paddle_op.attrs().get("strides", [1, 1])
paddings = paddle_op.attrs().get("paddings", [0, 0])
exclusive = paddle_op.attrs().get("exclusive", True)
ceil_mode = paddle_op.attrs().get("ceil_mode", False)
adaptive = paddle_op.attrs().get("adaptive", False)
padding_algorithm = paddle_op.attrs().get("padding_algorithm", "EXPLICIT")
if not paddle_op.attrs().get("kernel_size") and len(inputs) == 2:
kernel_size = get_input_constant_value(paddle_op, inputs, 1)
if kernel_size is None:
raise Exception(
"The defining op of kernel size must be builtin.constant/pd_op.full_int_array"
)
else:
kernel_size = paddle_op.attrs().get("kernel_size", [1, 1])
def create_pool_plugin(
network,
input_tensor,
ceil_mode,
pool_type,
adaptive,
exclusive,
kernel_size,
strides,
paddings,
global_pooling,
):
plugin_fields = [
trt.PluginField(
"ceil_mode",
np.array([ceil_mode], dtype=np.bool_),
trt.PluginFieldType.INT32,
),
trt.PluginField(
"pool_type",
np.array(list(pool_type), dtype=np.bytes_),
trt.PluginFieldType.CHAR,
),
trt.PluginField(
"adaptive",
np.array([adaptive], dtype=np.bool_),
trt.PluginFieldType.INT32,
),
trt.PluginField(
"exclusive",
np.array([exclusive], dtype=np.bool_),
trt.PluginFieldType.INT32,
),
trt.PluginField(
"ksize",
np.array(kernel_size, dtype=np.int32),
trt.PluginFieldType.INT32,
),
trt.PluginField(
"strides",
np.array(strides, dtype=np.int32),
trt.PluginFieldType.INT32,
),
trt.PluginField(
"paddings",
np.array(paddings, dtype=np.int32),
trt.PluginFieldType.INT32,
),
trt.PluginField(
"global_pooling",
np.array([global_pooling], dtype=np.bool_),
trt.PluginFieldType.INT32,
),
]
plugin_field_collection = trt.PluginFieldCollection(plugin_fields)
plugin_name = "pir_pool_plugin_dynamic"
plugin_version = "1"
plugin = get_trt_plugin(
plugin_name, plugin_field_collection, plugin_version
)
layer = network.add_plugin_v2([input_tensor], plugin)
set_layer_name(layer, paddle_op)
return layer
reduce_operation = trt.ReduceOperation.MAX
nv_pool_type = trt.PoolingType.MAX
if pool_type == "max":
nv_pool_type = trt.PoolingType.MAX
reduce_operation = trt.ReduceOperation.MAX
elif pool_type == "avg":
nv_pool_type = trt.PoolingType.AVERAGE
reduce_operation = trt.ReduceOperation.AVG
else:
raise ValueError(f"Unsupported pooling type: {pool_type}")
if global_pooling or adaptive:
paddings = [0, 0, 0, 0]
if padding_algorithm == "VALID":
paddings = [0] * len(paddings)
nv_paddings = trt.DimsHW(paddings[0], paddings[1])
nv_ksize = trt.DimsHW(kernel_size[0], kernel_size[1])
nv_strides = trt.DimsHW(strides[0], strides[1])
layer = None
g_pre_pad = trt.DimsHW(0, 0)
g_post_pad = trt.DimsHW(0, 0)
if input_shape[input_dims - 2] - kernel_size[0] + 2 * paddings[0] < 0:
g_post_pad.h = strides[0] - 1
if input_shape[input_dims - 1] - kernel_size[1] + 2 * paddings[1] < 0:
g_post_pad.w = strides[1] - 1
real_paddings = paddings.copy()
for i in range(2):
copy_pad = paddings[i]
real_paddings.insert(2 * i + 1, copy_pad)
if padding_algorithm == "SAME":
for i in range(2):
copy_pad = paddings[2 * i]
paddings.insert(2 * i + 1, copy_pad)
for i in range(2):
out_size = (input_shape[2 + i] + strides[i] - 1) // strides[i]
pad_sum = max(
(out_size - 1) * strides[i]
+ kernel_size[i]
- input_shape[2 + i],
0,
)
pad_0 = pad_sum // 2
pad_1 = pad_sum - pad_0
paddings[2 * i] = pad_0
paddings[2 * i + 1] = pad_1
real_paddings = paddings.copy()
paddings = [paddings[i] for i in range(len(paddings)) if i % 2 == 0]
if adaptive and pool_type == "avg":
output_h, output_w = kernel_size
if output_h == 1 and output_w == 1:
reduce_axes = (1 << (input_dims - 2)) | (1 << (input_dims - 1))
reduce_layer = network.add_reduce(
input=input_tensor,
op=trt.ReduceOperation.AVG,
axes=reduce_axes,
keep_dims=True,
)
if reduce_layer is None:
raise RuntimeError("Failed to add reduce layer in TensorRT.")
layer = reduce_layer
set_layer_name(layer, paddle_op)
else:
input_h = input_shape[input_dims - 2]
input_w = input_shape[input_dims - 1]
if input_h < 0 or input_w < 0:
layer = create_pool_plugin(
network,
input_tensor,
ceil_mode,
pool_type,
adaptive,
exclusive,
kernel_size,
strides,
paddings,
global_pooling,
)
else:
stride_h = input_h // output_h
stride_w = input_w // output_w
kernel_h = input_h - (output_h - 1) * stride_h
kernel_w = input_w - (output_w - 1) * stride_w
if stride_h <= 0 or stride_w <= 0:
raise ValueError(
"Calculated stride is non-positive, which is invalid."
)
nv_ksize = trt.DimsHW(kernel_h, kernel_w)
nv_strides = trt.DimsHW(stride_h, stride_w)
nv_paddings = trt.DimsHW(0, 0)
pooling_layer = network.add_pooling_nd(
input=input_tensor,
type=nv_pool_type,
window_size=nv_ksize,
)
if pooling_layer is None:
raise RuntimeError(
"Failed to add pooling layer in TensorRT."
)
pooling_layer.stride_nd = nv_strides
pooling_layer.padding_nd = nv_paddings
pooling_layer.average_count_excludes_padding = exclusive
layer = pooling_layer
set_layer_name(layer, paddle_op)
elif not adaptive and not global_pooling and not ceil_mode:
if padding_algorithm != "SAME" and (
(g_post_pad.h > 0 and input_shape[input_dims - 2] > 0)
or (g_post_pad.w > 0 and input_shape[input_dims - 1] > 0)
):
pad_layer = network.add_padding_nd(
input=input_tensor,
pre_padding=(g_pre_pad.h, g_pre_pad.w),
post_padding=(g_post_pad.h, g_post_pad.w),
)
if pad_layer is None:
raise RuntimeError("Failed to add padding layer in TensorRT.")
set_layer_name(pad_layer, paddle_op)
input_tensor = pad_layer.get_output(0)
pooling_layer = network.add_pooling_nd(
input=input_tensor, type=nv_pool_type, window_size=nv_ksize
)
if pooling_layer is None:
raise RuntimeError("Failed to add pooling layer in TensorRT.")
pooling_layer.stride_nd = nv_strides
pooling_layer.padding_nd = nv_paddings
pooling_layer.average_count_excludes_padding = exclusive
if padding_algorithm == "SAME":
pooling_layer.padding_mode = trt.PaddingMode.SAME_UPPER
layer = pooling_layer
set_layer_name(layer, paddle_op)
elif not adaptive and not global_pooling and ceil_mode:
pooling_layer = network.add_pooling_nd(
input=input_tensor, type=nv_pool_type, window_size=nv_ksize
)
if pooling_layer is None:
raise RuntimeError("Failed to add pooling layer in TensorRT.")
pooling_layer.stride_nd = nv_strides
pooling_layer.padding_nd = nv_paddings
pooling_layer.average_count_excludes_padding = exclusive
if padding_algorithm == "SAME":
pooling_layer.padding_mode = trt.PaddingMode.SAME_UPPER
else:
pooling_layer.padding_mode = trt.PaddingMode.EXPLICIT_ROUND_UP
layer = pooling_layer
set_layer_name(layer, paddle_op)
elif global_pooling and not adaptive:
reduce_layer = network.add_reduce(
input_tensor, reduce_operation, 12, True
)
layer = reduce_layer
set_layer_name(layer, paddle_op)
else:
layer = create_pool_plugin(
network,
input_tensor,
ceil_mode,
pool_type,
adaptive,
exclusive,
kernel_size,
strides,
paddings,
global_pooling,
)
if layer is None:
raise RuntimeError("Failed to create pooling layer in TensorRT.")
return layer.get_output(0)
@converter_registry.register("pd_op.pool3d")
def pool3d_converter(network, paddle_op, inputs):
input_tensor = inputs[0]
global_pooling = paddle_op.attrs()["global_pooling"]
pooling_type = paddle_op.attrs()["pooling_type"]
ksize = paddle_op.attrs()["kernel_size"]
strides = paddle_op.attrs()["strides"]
paddings = paddle_op.attrs()["paddings"]
exclusive = paddle_op.attrs().get("exclusive", True)
ceil_mode = paddle_op.attrs()["ceil_mode"]
adaptive = paddle_op.attrs().get("adaptive", False)
padding_algorithm = paddle_op.attrs().get("padding_algorithm", "EXPLICIT")
if padding_algorithm == "VALID" or padding_algorithm == "SAME":
paddings = [0] * len(paddings)
nv_pool_type = trt.PoolingType.MAX
reduce_operation = trt.ReduceOperation.MAX
if pooling_type == "max":
nv_pool_type = trt.PoolingType.MAX
reduce_operation = trt.ReduceOperation.MAX
elif pooling_type == "avg":
nv_pool_type = trt.PoolingType.AVERAGE
reduce_operation = trt.ReduceOperation.AVG
nv_ksize = trt.Dims3(ksize[0], ksize[1], ksize[2])
nv_strides = trt.Dims3(strides[0], strides[1], strides[2])
nv_paddings = trt.Dims3(paddings[0], paddings[1], paddings[2])
layer = None
if not adaptive and not global_pooling and not ceil_mode:
pool_layer = network.add_pooling_nd(
input_tensor, nv_pool_type, nv_ksize
)
pool_layer.stride_nd = nv_strides
pool_layer.padding_nd = nv_paddings
pool_layer.average_count_excludes_padding = exclusive
set_layer_name(pool_layer, paddle_op)
layer = pool_layer
elif global_pooling:
reduce_layer = network.add_reduce(
input_tensor, reduce_operation, 28, True
)
set_layer_name(reduce_layer, paddle_op)
layer = reduce_layer
else:
plugin_fields = [
trt.PluginField(
"ceil_mode",
np.array([ceil_mode], dtype=np.bool_),
trt.PluginFieldType.INT32,
),
trt.PluginField(
"pool3d_type",
np.array(list(pooling_type), dtype=np.bytes_),
trt.PluginFieldType.CHAR,
),
trt.PluginField(
"adaptive",
np.array([adaptive], dtype=np.bool_),
trt.PluginFieldType.INT32,
),
trt.PluginField(
"ksize",
np.array(ksize, dtype=np.int32),
trt.PluginFieldType.INT32,
),
trt.PluginField(
"strides",
np.array(strides, dtype=np.int32),
trt.PluginFieldType.INT32,
),
trt.PluginField(
"paddings",
np.array(paddings, dtype=np.int32),
trt.PluginFieldType.INT32,
),
trt.PluginField(
"is_global",
np.array([global_pooling], dtype=np.bool_),
trt.PluginFieldType.INT32,
),
]
plugin_field_collection = trt.PluginFieldCollection(plugin_fields)
plugin_name = "pir_pool3d_plugin_dynamic"
plugin_version = "1"
plugin = get_trt_plugin(
plugin_name, plugin_field_collection, plugin_version
)
layer = network.add_plugin_v2([input_tensor], plugin)
set_layer_name(layer, paddle_op)
return layer.get_output(0)
+285
View File
@@ -0,0 +1,285 @@
# Copyright (c) 2024 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.
import tensorrt as trt
from paddle.tensorrt.converter_utils import (
generic_plugin_converter,
get_input_constant_value,
get_shape_tensor_element,
set_layer_name,
squeeze_trt,
trt_cast,
trt_gather,
trt_reshape,
trt_shape,
trt_unsqueeze,
)
from paddle.tensorrt.register import converter_registry
@converter_registry.register("pd_op.nonzero")
def non_zero_converter(network, paddle_op, inputs):
input_tensor = inputs[0]
cast_layer = network.add_cast(input_tensor, trt.float32)
set_layer_name(cast_layer, paddle_op)
non_zero_layer = network.add_non_zero(cast_layer.get_output(0))
nonzero_output = non_zero_layer.get_output(0)
set_layer_name(non_zero_layer, paddle_op)
shuffle_layer = network.add_shuffle(input=nonzero_output)
shuffle_layer.first_transpose = (1, 0)
transposed_output = shuffle_layer.get_output(0)
set_layer_name(shuffle_layer, paddle_op)
return transposed_output
@converter_registry.register("pd_op.argmax")
def argmax_converter(network, paddle_op, inputs):
x = inputs[0]
input_dims = x.shape
rank = len(input_dims)
axis = int(get_input_constant_value(paddle_op, inputs, 1)[0])
keepdims = paddle_op.attrs()["keepdims"]
if axis < 0:
axis += rank
topk_layer = network.add_topk(
input=x, op=trt.TopKOperation.MAX, k=1, axes=(1 << axis)
)
set_layer_name(topk_layer, paddle_op)
if keepdims:
return topk_layer.get_output(1)
else:
topk_out = topk_layer.get_output(1)
topk_out_shape_size = len(topk_out.shape)
# Mark which dimensions to squeeze
should_squeeze = [False] * topk_out_shape_size
should_squeeze[axis] = True
# Get dimensions to keep
gather_indices = [
i for i, squeeze in enumerate(should_squeeze) if not squeeze
]
# Add Shuffle layer
layer = network.add_shuffle(topk_out)
shape_tensor = trt_shape(
network, topk_out, name=[paddle_op.name(), 'shape_tensor']
)
real_shape_tensor = trt_gather(
network,
shape_tensor,
gather_indices,
name=[paddle_op.name(), 'real_shape_tensor'],
)
layer.set_input(1, real_shape_tensor)
set_layer_name(layer, paddle_op)
return layer.get_output(0)
@converter_registry.register("pd_op.argmin")
def argmin_converter(network, paddle_op, inputs):
x = inputs[0]
input_dims = x.shape
rank = len(input_dims)
axis = int(get_input_constant_value(paddle_op, inputs, 1)[0])
keepdims = paddle_op.attrs()["keepdims"]
if axis < 0:
axis += rank
topk_layer = network.add_topk(
input=x, op=trt.TopKOperation.MIN, k=1, axes=(1 << axis)
)
set_layer_name(topk_layer, paddle_op)
if keepdims:
return topk_layer.get_output(1)
else:
squeeze_layer = network.add_shuffle(topk_layer.get_output(1))
set_layer_name(squeeze_layer, paddle_op)
output_dims = []
for i in range(len(input_dims)):
if i == axis:
continue
output_dims.append(input_dims[i])
squeeze_layer.reshape_dims = tuple(output_dims)
return squeeze_layer.get_output(0)
@converter_registry.register("pd_op.argsort")
def argsort_converter(network, paddle_op, inputs):
input_tensor = inputs[0]
input_shape = input_tensor.shape
in_type = input_tensor.dtype
in_rank = len(input_shape)
axis = paddle_op.attrs()["axis"]
descending = paddle_op.attrs()["descending"]
if input_shape[axis] > 3840:
layer = generic_plugin_converter(network, paddle_op, inputs)
out0 = layer.get_output(0)
out1 = layer.get_output(1)
return out0, out1
else:
if axis < 0:
axis += len(input_shape)
topk_op = trt.TopKOperation.MAX if descending else trt.TopKOperation.MIN
need_cast = True if in_type != trt.DataType.FLOAT else False
if in_rank == 1:
unsqueeze_shape = trt.Dims([1, -1])
input_tensor = trt_reshape(
network,
input_tensor,
unsqueeze_shape,
is_shape_tensor=False,
name=[paddle_op.name(), 'input_tensor'],
)
axis = 1
if need_cast:
input_tensor = trt_cast(
network,
input_tensor,
trt.DataType.FLOAT,
name=[paddle_op.name(), 'input_tensor'],
)
topk_layer = network.add_topk(input_tensor, topk_op, 1, 1 << axis)
shape = trt_shape(
network, input_tensor, name=[paddle_op.name(), 'shape']
)
k_tensor = get_shape_tensor_element(
network, shape, axis, True, name=[paddle_op.name(), 'k_tensor']
)
topk_layer.set_input(1, k_tensor)
set_layer_name(topk_layer, paddle_op)
out = topk_layer.get_output(0)
indices = topk_layer.get_output(1)
if in_rank == 1:
squeeze_shape = trt.Dims([-1])
out = trt_reshape(
network,
out,
squeeze_shape,
is_shape_tensor=False,
name=[paddle_op.name(), 'out'],
)
indices = trt_reshape(
network,
indices,
squeeze_shape,
is_shape_tensor=False,
name=[paddle_op.name(), 'indices'],
)
out_tensor = trt_cast(
network, out, in_type, name=[paddle_op.name(), 'out_tensor']
)
indices_tensor = trt_cast(
network,
indices,
indices.dtype,
name=[paddle_op.name(), 'indices_tensor'],
)
return out_tensor, indices_tensor
@converter_registry.register("pd_op.where")
def where_converter(network, paddle_op, inputs):
condition = inputs[0]
x = inputs[1]
y = inputs[2]
select_layer = network.add_select(condition, x, y)
set_layer_name(select_layer, paddle_op)
return select_layer.get_output(0)
@converter_registry.register("pd_op.topk")
def topk_converter(network, paddle_op, inputs):
input_tensor = inputs[0]
input_shape = input_tensor.shape
axis = paddle_op.attrs().get("axis", -1)
largest = paddle_op.attrs().get("largest", True)
flag = trt.TopKOperation.MAX if largest else trt.TopKOperation.MIN
k_list = get_input_constant_value(paddle_op, inputs, 1)
if k_list is None:
raise NotImplementedError("Dynamic k is not supported in TensorRT.")
k = k_list[0]
input_rank = len(input_shape)
expand_to_2d = input_rank == 1
if expand_to_2d:
input_tensor = trt_unsqueeze(
network, input_tensor, [1], name=[paddle_op.name(), 'input_tensor']
)
input_type = input_tensor.dtype
if input_type == trt.DataType.INT32:
input_tensor = trt_cast(
network,
input_tensor,
trt.DataType.FLOAT,
name=[paddle_op.name(), 'input_tensor'],
)
if axis < 0:
axis += input_rank
layer = network.add_topk(input_tensor, flag, int(k), 1 << axis)
set_layer_name(layer, paddle_op)
values = layer.get_output(0)
indices = layer.get_output(1)
if expand_to_2d:
values = squeeze_trt(
network, values, [1], name=[paddle_op.name(), 'values']
)
indices = squeeze_trt(
network, indices, [1], name=[paddle_op.name(), 'indices']
)
if input_type == trt.DataType.INT32:
values = trt_cast(
network,
values,
trt.DataType.INT32,
name=[paddle_op.name(), 'values'],
)
return values, indices
@converter_registry.register("pd_op.index_select")
def index_select_converter(network, paddle_op, inputs):
input_tensor = inputs[0]
index_tensor = inputs[1]
axis = paddle_op.attrs().get("axis", 0)
reshape_layer = network.add_shuffle(index_tensor)
reshape_layer.reshape_dims = (-1,)
set_layer_name(reshape_layer, paddle_op)
gather_layer = network.add_gather(
input_tensor, reshape_layer.get_output(0), axis
)
set_layer_name(gather_layer, paddle_op)
return gather_layer.get_output(0)
+34
View File
@@ -0,0 +1,34 @@
# Copyright (c) 2024 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.
# import tensorrt as trt
# from paddle.tensorrt.converter_utils import get_axes_for_reduce_op, set_layer_name
# from paddle.tensorrt.register import converter_registry
# @converter_registry.register("pd_op.mean")
# def mean_converter(network, paddle_op, inputs):
# input_tensor = inputs[0]
# keep_dim = paddle_op.attrs().get("keepdim")
# dim = paddle_op.attrs().get("axis")
# mean_layer = network.add_reduce(
# input_tensor,
# trt.ReduceOperation.AVG,
# axes=get_axes_for_reduce_op(dim, network.has_implicit_batch_dimension),
# keep_dims=keep_dim,
# )
# set_layer_name(mean_layer, paddle_op)
# return mean_layer.get_output(0)
+48
View File
@@ -0,0 +1,48 @@
# Copyright (c) 2024 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.
import tensorrt as trt
from paddle.tensorrt.converter_utils import set_layer_name
from paddle.tensorrt.register import converter_registry
@converter_registry.register("pd_op.grid_sample")
def grid_sample_converter(network, paddle_op, inputs):
input_tensor, grid_tensor = inputs
padding = paddle_op.attrs().get("paddings", [0, 0])
mode = paddle_op.attrs().get("mode", "bilinear")
padding_mode = paddle_op.attrs().get("padding_mode", "zeros")
align_corners = paddle_op.attrs().get("align_corners", True)
if padding_mode == "zeros":
sample_mode = trt.SampleMode.FILL
elif padding_mode == "border":
sample_mode = trt.SampleMode.CLAMP
elif padding_mode == "reflection":
sample_mode = trt.SampleMode.REFLECT
if mode == "nearest":
interpolation_mode = trt.InterpolationMode.NEAREST
elif mode == "bilinear":
interpolation_mode = trt.InterpolationMode.LINEAR
grid_sample_layer = network.add_grid_sample(input_tensor, grid_tensor)
grid_sample_layer.interpolation_mode = interpolation_mode
grid_sample_layer.align_corners = align_corners
grid_sample_layer.sample_mode = sample_mode
set_layer_name(grid_sample_layer, paddle_op)
return grid_sample_layer.get_output(0)