Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Hackathon NO.74] 为 Paddle-TRT 添加 grid_sampler 算子 #50934

Merged
merged 3 commits into from
Mar 2, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions paddle/fluid/inference/api/analysis_predictor.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2560,6 +2560,9 @@ USE_TRT_CONVERTER(preln_groupnorm_act)
USE_TRT_CONVERTER(flash_multihead_matmul)
USE_TRT_CONVERTER(cross_multihead_matmul)
#endif
#if IS_TRT_VERSION_GE(8500)
USE_TRT_CONVERTER(grid_sampler)
#endif
#if IS_TRT_VERSION_GE(8200)
USE_TRT_CONVERTER(set_value)
#endif
Expand Down
1 change: 1 addition & 0 deletions paddle/fluid/inference/tensorrt/convert/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ list(
multihead_matmul_roformer_op.cc
flash_multihead_matmul_op.cc
cross_multihead_matmul_op.cc
grid_sampler_op.cc
shuffle_channel_op.cc
fill_any_like_op.cc
where_op.cc
Expand Down
93 changes: 93 additions & 0 deletions paddle/fluid/inference/tensorrt/convert/grid_sampler_op.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
/* Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.

gzy19990617 marked this conversation as resolved.
Show resolved Hide resolved
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. */

#include "paddle/fluid/inference/tensorrt/convert/op_converter.h"

namespace paddle {
namespace framework {
class Scope;

namespace proto {
class OpDesc;
} // namespace proto
} // namespace framework
} // namespace paddle
gzy19990617 marked this conversation as resolved.
Show resolved Hide resolved

namespace paddle {
namespace inference {
namespace tensorrt {

/*
* GridSampler Op
*/
class GridSamplerOpConverter : public OpConverter {
public:
Comment on lines +24 to +25
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这个类在trt 8.5以下会有编译问题,可以参考one_hot处理方式

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

已增加宏,防止编译出错

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR-CI-Coverage,没有过,这个CI无法点击重新运行,应该怎么重新跑呢

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR-CI-Coverage,没有过,这个CI无法点击重新运行,应该怎么重新跑呢

这个ci Coverage问题,由于单测环境没有trt 8.5,可以在本地用trt8.5验证下python python/paddle/fluid/tests/unittests/ir/inference/test_trt_convert_grid_sampler.py。并附上正确结果截图

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

本地验证单测通过,"in in in"为grid_sampler.cc中的验证打印信息,可见成功进入grid_sampler.cc中进行TRT layer的转换,在PR describe中也补充了一下。
image

void operator()(const framework::proto::OpDesc& op,
const framework::Scope& scope,
bool test_mode) override {
VLOG(3) << "convert a fluid grid_sampler op to tensorrt GridSample layer";
framework::OpDesc op_desc(op, nullptr);
std::string input_x_name = op_desc.Input("X").front();
std::string input_grid_name = op_desc.Input("Grid").front();
std::string output_name = op_desc.Output("Output").front();
auto* input_x_tensor = engine_->GetITensor(input_x_name);
int32_t const inputRank = input_x_tensor->getDimensions().nbDims;
auto* input_grid_tensor = engine_->GetITensor(input_grid_name);
int32_t const gridRank = input_grid_tensor->getDimensions().nbDims;

if (inputRank != gridRank) {
PADDLE_THROW(platform::errors::InvalidArgument(
"The input tensor and the grid tensor must have the same rank"));
}

auto* layer = TRT_ENGINE_ADD_LAYER(
engine_, GridSample, *input_x_tensor, *input_grid_tensor);

const std::string mode =
PADDLE_GET_CONST(std::string, op_desc.GetAttr("mode"));
const std::string padding_mode =
PADDLE_GET_CONST(std::string, op_desc.GetAttr("padding_mode"));
const bool align_corners =
PADDLE_GET_CONST(bool, op_desc.GetAttr("align_corners"));

nvinfer1::InterpolationMode interpolationMode{
nvinfer1::InterpolationMode::kNEAREST};
if (mode == "nearest") {
interpolationMode = nvinfer1::ResizeMode::kNEAREST;
} else if (mode == "bilinear") {
interpolationMode = nvinfer1::ResizeMode::kLINEAR;
}

nvinfer1::SampleMode sampleMode{nvinfer1::SampleMode::kFILL};
if (padding_mode == "zeros") {
sampleMode = nvinfer1::SampleMode::kFILL;
} else if (padding_mode == "border") {
sampleMode = nvinfer1::SampleMode::kCLAMP;
} else if (padding_mode == "reflection") {
sampleMode = nvinfer1::SampleMode::kREFLECT;
}

layer->setInterpolationMode(interpolationMode);
layer->setSampleMode(sampleMode);
layer->setAlignCorners(align_corners);

RreplenishLayerAndOutput(layer, "grid_sampler", {output_name}, test_mode);
}
};

} // namespace tensorrt
} // namespace inference
} // namespace paddle

REGISTER_TRT_OP_CONVERTER(grid_sampler, GridSamplerOpConverter);
4 changes: 4 additions & 0 deletions paddle/fluid/inference/tensorrt/dynamic_shape_infermeta.cc
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,7 @@ nvinfer1::DimsExprs PNormInferMeta(
return output;
}

#if !IS_TRT_VERSION_GE(8500)
gzy19990617 marked this conversation as resolved.
Show resolved Hide resolved
nvinfer1::DimsExprs GridSamplerInferMeta(
int output_index,
const nvinfer1::DimsExprs* inputs,
Expand All @@ -386,6 +387,7 @@ nvinfer1::DimsExprs GridSamplerInferMeta(
}
return output;
}
#endif

PD_REGISTER_DYNAMIC_INFER_META_FN(gather_nd, GatherNdInferMeta);
PD_REGISTER_DYNAMIC_INFER_META_FN(yolo_box, YoloBoxInferMeta);
Expand All @@ -395,7 +397,9 @@ PD_REGISTER_DYNAMIC_INFER_META_FN(scatter_nd_add, ScatterNdAddInferMeta);
PD_REGISTER_DYNAMIC_INFER_META_FN(inverse, UnchangedInferMeta);
PD_REGISTER_DYNAMIC_INFER_META_FN(moe, MoeInferMeta);
PD_REGISTER_DYNAMIC_INFER_META_FN(pad3d, Pad3dInferMeta);
#if !IS_TRT_VERSION_GE(8500)
gzy19990617 marked this conversation as resolved.
Show resolved Hide resolved
PD_REGISTER_DYNAMIC_INFER_META_FN(grid_sampler, GridSamplerInferMeta);
#endif
} // namespace tensorrt
} // namespace inference
} // namespace paddle
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#pragma once

#include "paddle/fluid/inference/tensorrt/dynamic_shape_infermeta_factory.h"
#include "paddle/fluid/inference/tensorrt/helper.h"

namespace paddle {
namespace inference {
Expand All @@ -27,7 +28,9 @@ USE_TRT_DYNAMIC_INFER_META_FN(unfold);
USE_TRT_DYNAMIC_INFER_META_FN(scatter_nd_add);
USE_TRT_DYNAMIC_INFER_META_FN(pad3d);
USE_TRT_DYNAMIC_INFER_META_FN(inverse);
#if !IS_TRT_VERSION_GE(8500)
USE_TRT_DYNAMIC_INFER_META_FN(grid_sampler);
#endif
gzy19990617 marked this conversation as resolved.
Show resolved Hide resolved
} // namespace tensorrt
} // namespace inference
} // namespace paddle
34 changes: 32 additions & 2 deletions paddle/fluid/inference/tensorrt/op_teller.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2542,6 +2542,34 @@ struct SimpleOpTypeSetTeller : public Teller {
}
}

if (op_type == "grid_sampler") {
#if !IS_TRT_VERSION_GE(8500)
VLOG(3) << "grid_sampler is not supported when TensorRT < 8.5";
return false;
#else
if (!with_dynamic_shape) {
VLOG(3) << "the grid_sampler does not support "
"static shape yet";
return false;
}

if (!desc.HasAttr("mode") || !desc.HasAttr("padding_mode") ||
!desc.HasAttr("align_corners")) {
VLOG(3) << "grid_sampler need attributes : mode, padding_mode, "
"align_corners";
return false;
}

auto* block = desc.Block();
if (block == nullptr) {
VLOG(3) << "The block desc is nullptr, we can't continue to analyze. "
"Developers need to check whether block_desc is passed in "
"the pass.";
return false;
}
#endif
}

if (use_no_calib_int8) {
return int8_teller_set.count(op_type);
} else {
Expand Down Expand Up @@ -2701,7 +2729,8 @@ struct SimpleOpTypeSetTeller : public Teller {
"expand_v2",
"fuse_eleadd_transpose",
"skip_groupnorm_act",
"preln_groupnorm_act"};
"preln_groupnorm_act",
"grid_sampler"};

std::unordered_set<std::string> teller_set{
"mul",
Expand Down Expand Up @@ -2853,7 +2882,8 @@ struct SimpleOpTypeSetTeller : public Teller {
"expand_v2",
"fuse_eleadd_transpose",
"skip_groupnorm_act",
"preln_groupnorm_act"};
"preln_groupnorm_act",
"grid_sampler"};
};

struct GenericPluginTeller : public Teller {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@

class TrtConvertGridSampler(TrtLayerAutoScanTest):
def is_program_valid(self, program_config: ProgramConfig) -> bool:
self.trt_param.workspace_size = 1073741824
ver = paddle_infer.get_trt_compile_version()
if ver[0] * 1000 + ver[1] * 100 + ver[2] * 10 < 8500:
return False
gzy19990617 marked this conversation as resolved.
Show resolved Hide resolved
return True

def sample_program_configs(self):
Expand All @@ -34,6 +38,12 @@ def generate_input1():
def generate_input2():
return np.random.random([1, 3, 3, 2]).astype(np.float32)

desc = {
"mode": "bilinear",
"padding_mode": "border",
"align_corners": True,
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

已补充,所有属性的四维和五维的单侧通过。
0b914f72b223e89c5169a51fc46306d5
另外TRT8.5中,gird_sampler layer只支持四维,在op_teller中加入了判断,如果input和grid不为四维,就return false,通过通用plugin的方式,通用plugin的grid_sampler中还有一个小bug,一起修改了。
image

ops_config = [
{
"op_type": "grid_sampler",
Expand All @@ -42,7 +52,7 @@ def generate_input2():
"Grid": ["grid_data"],
},
"op_outputs": {"Output": ["output_data"]},
"op_attrs": {},
"op_attrs": desc,
}
]

Expand Down