Skip to content

Commit

Permalink
针对value 改用组网方式
Browse files Browse the repository at this point in the history
  • Loading branch information
zhink committed Jan 8, 2024
1 parent 1b931f0 commit 4ebb83c
Show file tree
Hide file tree
Showing 3 changed files with 158 additions and 91 deletions.
16 changes: 16 additions & 0 deletions paddle/fluid/inference/tensorrt/convert/op_converter.h
Original file line number Diff line number Diff line change
Expand Up @@ -651,6 +651,22 @@ class OpConverter {
->getOutput(0);
return tensor;
}

// Create an constant layer with shape_tensor and value
template <typename T>
nvinfer1::ITensor* FillConstantLayer(nvinfer1::ITensor* shape_tensor, int beta_len,
T value) {
auto fill_layer = TRT_ENGINE_ADD_LAYER(
engine_, Fill, nvinfer1::Dims{}, nvinfer1::FillOperation::kLINSPACE);
fill_layer->setInput(0, *shape_tensor);
std::vector<T> beta_vec(beta_len);
std::vector<T> value_vec(1, value);
fill_layer->setInput(1, *Add1DConstantLayer(value_vec, "value_vec", true));
fill_layer->setInput(2, *Add1DConstantLayer(beta_vec, "beta_vec", false));
auto tensor = fill_layer->getOutput(0);
return tensor;
}

template <typename T>
// Create and add Multi-D constant float/int32 layer
nvinfer1::ITensor* AddConstantLayer(const T* data,
Expand Down
94 changes: 51 additions & 43 deletions paddle/fluid/inference/tensorrt/convert/set_value_op.cc
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,46 @@ class SetValueConverter : public OpConverter {
bool test_mode) override {
VLOG(3) << "convert a set value op to tensorrt";
framework::OpDesc op_desc(op, nullptr);
int64_t axes = 0;
int64_t starts = 0;
int64_t steps = 1;
int64_t ends = 0;
GET_ATTR_FROM_VECTOR(axes);
GET_ATTR_FROM_VECTOR(starts);
GET_ATTR_FROM_VECTOR(steps);
GET_ATTR_FROM_VECTOR(ends);

VLOG(3) << "axes is: " << axes;
VLOG(3) << "starts is: " << starts;
VLOG(3) << "steps is: " << steps;
VLOG(3) << "ends is: " << ends;

auto* inputs = engine_->GetITensor(op_desc.Input("Input")[0]);

auto input_dims = inputs->getDimensions();

// check params and refill
if (axes < 0) {
axes += input_dims.nbDims;
}

if (ends < 0) {
ends += input_dims.d[axes];
}
if (ends >= input_dims.d[axes]) {
ends = input_dims.d[axes];
}

VLOG(3) << "after standardization" << axes;
VLOG(3) << "axes is: " << axes;
VLOG(3) << "starts is: " << starts;
VLOG(3) << "steps is: " << steps;
VLOG(3) << "ends is: " << ends;

auto output_name = op_desc.Output("Out")[0];
nvinfer1::ITensor* updates;
if (op_desc.Input("ValueTensor").size() > 0) {
if (op_desc.HasInput("ValueTensor") &&
op_desc.Input("ValueTensor").size() > 0) {
updates = engine_->GetITensor(op_desc.Input("ValueTensor")[0]);
} else {
int dtype = PADDLE_GET_CONST(int, op_desc.GetAttr("dtype"));
Expand All @@ -64,26 +99,32 @@ class SetValueConverter : public OpConverter {
"set_value OP dtype must be float"));
float value = PADDLE_GET_CONST(std::vector<paddle::experimental::Scalar>,
op_desc.GetAttr("values"))[0]
.to<int>();
.to<float>();
VLOG(3) << "the attribute value is: " << value;
nvinfer1::Dims tmp_dim;
tmp_dim.nbDims = inputs->getDimensions().nbDims;
for (int i = 0; i < tmp_dim.nbDims; i++) tmp_dim.d[i] = 1;
updates = AddConstantLayer(&value, tmp_dim);

nvinfer1::ITensor* input_shape_tensor = Shape(inputs);
std::vector<nvinfer1::ITensor*> vec_tensor;
for (int32_t i = 0; i < input_dims.nbDims; ++i) {
vec_tensor.push_back(GetEleTensorOfShape(input_shape_tensor, i));
}
std::vector<int32_t> axes_vec(1, (ends - 1 - starts) / steps + 1);
vec_tensor[axes] = Add1DConstantLayer(axes_vec, "axes_vec", false);
nvinfer1::ITensor* output_shape_tensor = Concat(vec_tensor, 0);
updates = FillConstantLayer(
output_shape_tensor, inputs->getDimensions().nbDims, value);
}

// for log
{
nvinfer1::Dims tmp_dims = inputs->getDimensions();
std::vector<int> tmp_vec;
for (int i = 0; i < tmp_dims.nbDims; i++)
tmp_vec.push_back(tmp_dims.d[i]);
for (int i = 0; i < input_dims.nbDims; i++)
tmp_vec.push_back(input_dims.d[i]);
VLOG(3) << "Input(Name:" << op_desc.Input("Input")[0] << ")"
<< "'s dimension is :[" << string::join_strings(tmp_vec, ',')
<< "]";

tmp_vec.clear();
tmp_dims = updates->getDimensions();
nvinfer1::Dims tmp_dims = updates->getDimensions();
for (int i = 0; i < tmp_dims.nbDims; i++)
tmp_vec.push_back(tmp_dims.d[i]);
VLOG(3) << "updates tensor"
Expand Down Expand Up @@ -129,22 +170,7 @@ class SetValueConverter : public OpConverter {
<< "]";
}

int64_t axes = 0;
int64_t starts = 0;
int64_t steps = 1;
int64_t ends = 0;
GET_ATTR_FROM_VECTOR(axes);
GET_ATTR_FROM_VECTOR(starts);
GET_ATTR_FROM_VECTOR(steps);
GET_ATTR_FROM_VECTOR(ends);

VLOG(3) << "axes is: " << axes;
VLOG(3) << "starts is: " << starts;
VLOG(3) << "steps is: " << steps;
VLOG(3) << "ends is: " << ends;

// calculate dims
auto input_dims = inputs->getDimensions();
auto update_dims = updates->getDimensions();

PADDLE_ENFORCE_GT(
Expand All @@ -163,24 +189,6 @@ class SetValueConverter : public OpConverter {
axes,
update_dims.d[axes]));

// check params and refill
if (axes < 0) {
axes += input_dims.nbDims;
}

if (ends < 0) {
ends += input_dims.d[axes];
}
if (ends >= input_dims.d[axes]) {
ends = input_dims.d[axes];
}

VLOG(3) << "after standardization" << axes;
VLOG(3) << "axes is: " << axes;
VLOG(3) << "starts is: " << starts;
VLOG(3) << "steps is: " << steps;
VLOG(3) << "ends is: " << ends;

PADDLE_ENFORCE_LE(axes,
input_dims.nbDims,
platform::errors::InvalidArgument(
Expand Down
139 changes: 91 additions & 48 deletions test/ir/inference/test_trt_convert_set_value.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,58 +33,96 @@ def generate_input1():
def generate_input2():
return np.random.random([2, 2, 3]).astype(np.float32)

ops_config = [
{
"op_type": "set_value",
"op_inputs": {
for update_scalar in [True, False]:
self.update_scalar = update_scalar
set_value_inputs = {}
if update_scalar:
set_value_inputs = {
"Input": ["input_data"],
}
else:
set_value_inputs = {
"Input": ["input_data"],
"ValueTensor": ["update_data"],
}
ops_config = [
{
"op_type": "set_value",
"op_inputs": set_value_inputs,
"op_outputs": {"Out": ["input_data"]},
"op_attrs": {
"axes": [1],
"starts": [0],
"ends": [2],
"steps": [1],
"decrease_axes": [],
"values": [0.0],
},
},
"op_outputs": {"Out": ["input_data"]},
"op_attrs": {
"axes": [1],
"starts": [0],
"ends": [2],
"steps": [1],
"decrease_axes": [],
},
},
{
"op_type": "relu",
"op_inputs": {
"X": ["input_data"],
{
"op_type": "relu",
"op_inputs": {
"X": ["input_data"],
},
"op_outputs": {"Out": ["output_data"]},
"op_attrs": {},
},
"op_outputs": {"Out": ["output_data"]},
"op_attrs": {},
},
]
ops = self.generate_op_config(ops_config)
program_config = ProgramConfig(
ops=ops,
weights={},
inputs={
"input_data": TensorConfig(data_gen=partial(generate_input1)),
"update_data": TensorConfig(data_gen=partial(generate_input2)),
},
outputs=["output_data"],
)

yield program_config
]

ops = self.generate_op_config(ops_config)
if update_scalar:
program_config = ProgramConfig(
ops=ops,
weights={},
inputs={
"input_data": TensorConfig(
data_gen=partial(generate_input1)
),
},
outputs=["output_data"],
)
else:
program_config = ProgramConfig(
ops=ops,
weights={},
inputs={
"input_data": TensorConfig(
data_gen=partial(generate_input1)
),
"update_data": TensorConfig(
data_gen=partial(generate_input2)
),
},
outputs=["output_data"],
)

yield program_config

def sample_predictor_configs(self, program_config):
def generate_dynamic_shape(attrs):
self.dynamic_shape.min_input_shape = {
"input_data": [2, 3, 3],
"update_data": [2, 2, 3],
}
self.dynamic_shape.max_input_shape = {
"input_data": [3, 3, 4],
"update_data": [3, 2, 4],
}
self.dynamic_shape.opt_input_shape = {
"input_data": [3, 3, 3],
"update_data": [3, 2, 3],
}
if self.update_scalar:
self.dynamic_shape.min_input_shape = {
"input_data": [2, 3, 3],
}
self.dynamic_shape.max_input_shape = {
"input_data": [3, 3, 4],
}
self.dynamic_shape.opt_input_shape = {
"input_data": [3, 3, 3],
}
else:
self.dynamic_shape.min_input_shape = {
"input_data": [2, 3, 3],
"update_data": [2, 2, 3],
}
self.dynamic_shape.max_input_shape = {
"input_data": [3, 3, 4],
"update_data": [3, 2, 4],
}
self.dynamic_shape.opt_input_shape = {
"input_data": [3, 3, 3],
"update_data": [3, 2, 3],
}

def clear_dynamic_shape():
self.dynamic_shape.max_input_shape = {}
Expand All @@ -94,9 +132,14 @@ def clear_dynamic_shape():
def generate_trt_nodes_num(attrs, dynamic_shape):
if dynamic_shape:
ver = paddle_infer.get_trt_compile_version()
if ver[0] * 1000 + ver[1] * 100 + ver[2] * 10 < 8200:
return 1, 4
return 1, 3
if self.update_scalar:
if ver[0] * 1000 + ver[1] * 100 + ver[2] * 10 < 8200:
return 1, 3
return 1, 2
else:
if ver[0] * 1000 + ver[1] * 100 + ver[2] * 10 < 8200:
return 1, 4
return 1, 3

attrs = [
program_config.ops[i].attrs for i in range(len(program_config.ops))
Expand Down

0 comments on commit 4ebb83c

Please sign in to comment.