chore: import upstream snapshot with attribution
This commit is contained in:
@@ -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.
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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]
|
||||
@@ -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
|
||||
@@ -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
@@ -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
|
||||
@@ -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
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
Reference in New Issue
Block a user