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

【PIR】Improved the mechanism, added the conversion of some ops, and fixed some issues. #1444

Open
wants to merge 14 commits into
base: test_pir
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
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
5 changes: 2 additions & 3 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ endif()

# Set max opset version for onnx if you build from other version of onnx this
# should be modified.
add_definitions(-DMAX_ONNX_OPSET_VERSION=19)
add_definitions(-DMAX_ONNX_OPSET_VERSION=23)
add_definitions(-DPADDLE2ONNX_LIB)

# Internal flags for convert.h.in
Expand Down Expand Up @@ -95,8 +95,7 @@ else()
message(STATUS "Python site-packages directory: ${PYTHON_SITE_PACKAGES}")

# set(PADDLE_LIB ${PYTHON_SITE_PACKAGES}/paddle/base/libpaddle.so)
set(PADDLE_LIB
"${PYTHON_SITE_PACKAGES}/paddle/base/libpaddle.so")
set(PADDLE_LIB "${PYTHON_SITE_PACKAGES}/paddle/base/libpaddle.so")
if(EXISTS ${PADDLE_LIB})
message(STATUS "found libpaddle.so : ${PADDLE_LIB}")
else()
Expand Down
3 changes: 3 additions & 0 deletions paddle2onnx/mapper/activation/activation.cc
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ REGISTER_MAPPER(asin, ActivationMapper)
REGISTER_MAPPER(atan, ActivationMapper)
REGISTER_MAPPER(brelu, BReluMapper)
REGISTER_MAPPER(ceil, ActivationMapper)
REGISTER_PIR_MAPPER(ceil, ActivationMapper)
REGISTER_MAPPER(cos, ActivationMapper)
REGISTER_PIR_MAPPER(cos, ActivationMapper)
REGISTER_MAPPER(elu, EluMapper)
Expand All @@ -47,6 +48,7 @@ REGISTER_MAPPER(logsigmoid, LogSigmoidMapper)
REGISTER_MAPPER(log_softmax, LogSoftmaxMapper)
REGISTER_MAPPER(mish, MishMapper)
REGISTER_MAPPER(prelu, PReluMapper)
REGISTER_PIR_MAPPER(prelu, PReluMapper)
REGISTER_MAPPER(reciprocal, ActivationMapper)
REGISTER_MAPPER(relu, ActivationMapper)
REGISTER_PIR_MAPPER(relu, ActivationMapper)
Expand All @@ -70,6 +72,7 @@ REGISTER_PIR_MAPPER(sqrt, ActivationMapper)
REGISTER_MAPPER(square, SquareMapper)
REGISTER_MAPPER(tan, ActivationMapper)
REGISTER_MAPPER(tanh, ActivationMapper)
REGISTER_PIR_MAPPER(tanh, ActivationMapper)
REGISTER_MAPPER(tanh_shrink, TanhShrinkMapper)
REGISTER_MAPPER(thresholded_relu, ThresholdedReluMapper)

Expand Down
6 changes: 6 additions & 0 deletions paddle2onnx/mapper/activation/activation.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,12 @@ class PReluMapper : public Mapper {
int64_t op_id)
: Mapper(p, helper, block_id, op_id) {}

PReluMapper(const PaddlePirParser& p,
OnnxHelper* helper,
int64_t op_id,
bool if_in_cf_block)
: Mapper(p, helper, op_id, if_in_cf_block) {}

int32_t GetMinOpsetVersion(bool verbose) override;
void Opset7() override;
};
Expand Down
16 changes: 13 additions & 3 deletions paddle2onnx/mapper/detection/multiclass_nms.cc
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
namespace paddle2onnx {

REGISTER_MAPPER(multiclass_nms3, NMSMapper);
REGISTER_PIR_MAPPER(multiclass_nms3, NMSMapper);

int32_t NMSMapper::GetMinOpsetVersion(bool verbose) {
auto boxes_info = GetInput("BBoxes");
Expand Down Expand Up @@ -133,9 +134,18 @@ void NMSMapper::KeepTopK(const std::string& selected_indices) {
helper_->Constant({1}, ONNX_NAMESPACE::TensorProto::INT64, keep_top_k_);
auto ensemble_value = helper_->MakeNode("Concat", {num_of_boxes, top_k});
AddAttribute(ensemble_value, "axis", int64_t(0));
auto new_top_k =
helper_->MakeNode("ReduceMin", {ensemble_value->output(0)});
AddAttribute(new_top_k, "axes", std::vector<int64_t>(1, 0));

std::shared_ptr<ONNX_NAMESPACE::NodeProto> new_top_k;
if (OnnxHelper::GetOpsetVersion() > 13) {
std::string reduce_min_axis = helper_->Constant(
{1}, ONNX_NAMESPACE::TensorProto::INT64, static_cast<int64_t>(0));
new_top_k = helper_->MakeNode(
"ReduceMin", {ensemble_value->output(0), reduce_min_axis});

} else {
new_top_k = helper_->MakeNode("ReduceMin", {ensemble_value->output(0)});
AddAttribute(new_top_k, "axes", std::vector<int64_t>(1, 0));
}
AddAttribute(new_top_k, "keepdims", int64_t(1));

// the output is topk_scores, topk_score_indices
Expand Down
21 changes: 21 additions & 0 deletions paddle2onnx/mapper/detection/multiclass_nms.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,27 @@ class NMSMapper : public Mapper {
GetAttr("keep_top_k", &keep_top_k_);
}

NMSMapper(const PaddlePirParser& p, OnnxHelper* helper, int64_t op_id,
bool if_in_cf_block)
: Mapper(p, helper, op_id, if_in_cf_block) {
// NMS is a post process operators for object detection
// We have found there're difference between `multi_class_nms3` in
// PaddlePaddle and `NonMaxSuppresion` in ONNX
MarkAsExperimentalOp();
GetAttr("normalized", &normalized_);
GetAttr("nms_threshold", &nms_threshold_);
GetAttr("score_threshold", &score_threshold_);
GetAttr("nms_eta", &nms_eta_);
// The `nms_top_k` in Paddle and `max_output_boxes_per_class` in ONNX share
// the same meaning But the filter process may not be same Since NMS is just
// a post process for Detection, we are not going to export it with exactly
// same result. We will make a precision performance in COCO or Pascal VOC
// data later.
GetAttr("nms_top_k", &nms_top_k_);
GetAttr("background_label", &background_label_);
GetAttr("keep_top_k", &keep_top_k_);
}

int32_t GetMinOpsetVersion(bool verbose) override;
void KeepTopK(const std::string& selected_indices);
void Opset10() override;
Expand Down
70 changes: 40 additions & 30 deletions paddle2onnx/mapper/detection/yolo_box.cc
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
namespace paddle2onnx {

REGISTER_MAPPER(yolo_box, YoloBoxMapper)
REGISTER_PIR_MAPPER(yolo_box, YoloBoxMapper)

int32_t YoloBoxMapper::GetMinOpsetVersion(bool verbose) {
Logger(verbose, 11) << RequireOpset(11) << std::endl;
Expand All @@ -29,8 +30,8 @@ void YoloBoxMapper::Opset11() {
// handle the float64 input
auto x_info = x_info_ori;
if (x_info_ori[0].dtype != P2ODataType::FP32) {
x_info[0].name = helper_->AutoCast(x_info_ori[0].name, x_info_ori[0].dtype,
P2ODataType::FP32);
x_info[0].name = helper_->AutoCast(
x_info_ori[0].name, x_info_ori[0].dtype, P2ODataType::FP32);
x_info[0].dtype = P2ODataType::FP32;
}

Expand Down Expand Up @@ -58,7 +59,9 @@ void YoloBoxMapper::Opset11() {
// ends This is a standared definition in ONNX However not sure all the
// inference engines implements `Slice` this way Let's handle this issue
// later
x_name = helper_->Slice(x_name, {0, 1, 2, 3}, {0, 0, 0, 0},
x_name = helper_->Slice(x_name,
{0, 1, 2, 3},
{0, 0, 0, 0},
{max_int, anchor_num, max_int, max_int});
}

Expand All @@ -76,10 +79,10 @@ void YoloBoxMapper::Opset11() {

// grid_x = np.tile(np.arange(w).reshape((1, w)), (h, 1))
// grid_y = np.tile(np.arange(h).reshape((h, 1)), (1, w))
auto float_value_0 =
helper_->Constant({}, GetOnnxDtype(x_info[0].dtype), float(0.0));
auto float_value_1 =
helper_->Constant({}, GetOnnxDtype(x_info[0].dtype), float(1.0));
auto float_value_0 = helper_->Constant(
{}, GetOnnxDtype(x_info[0].dtype), static_cast<float>(0.0));
auto float_value_1 = helper_->Constant(
{}, GetOnnxDtype(x_info[0].dtype), static_cast<float>(1.0));
auto scalar_float_w = helper_->Squeeze(float_w, {});
auto scalar_float_h = helper_->Squeeze(float_h, {});
auto grid_x_0 = helper_->MakeNode(
Expand All @@ -90,8 +93,8 @@ void YoloBoxMapper::Opset11() {
"Tile", {grid_x_0->output(0), nchw[2]}); // shape is [w*h]
auto grid_y_1 = helper_->MakeNode(
"Tile", {grid_y_0->output(0), nchw[3]}); // shape is [h*w]
auto int_value_1 =
helper_->Constant({1}, ONNX_NAMESPACE::TensorProto::INT64, float(1.0));
auto int_value_1 = helper_->Constant(
{1}, ONNX_NAMESPACE::TensorProto::INT64, static_cast<float>(1.0));
auto grid_shape_x =
helper_->MakeNode("Concat", {nchw[2], nchw[3], int_value_1});
auto grid_shape_y =
Expand All @@ -115,9 +118,10 @@ void YoloBoxMapper::Opset11() {
// pred_box[:, :, :, :, 0] = (grid_x + sigmoid(pred_box[:, :, :, :, 0]) *
// scale_x_y + bias_x_y) / w pred_box[:, :, :, :, 1] = (grid_y +
// sigmoid(pred_box[:, :, :, :, 1]) * scale_x_y + bias_x_y) / h
auto pred_box_xy =
helper_->Slice(transposed_x->output(0), {0, 1, 2, 3, 4}, {0, 0, 0, 0, 0},
{max_int, max_int, max_int, max_int, 2});
auto pred_box_xy = helper_->Slice(transposed_x->output(0),
{0, 1, 2, 3, 4},
{0, 0, 0, 0, 0},
{max_int, max_int, max_int, max_int, 2});
auto scale_x_y =
helper_->Constant({1}, GetOnnxDtype(x_info[0].dtype), scale_x_y_);
float bias_x_y_value = (1.0 - scale_x_y_) / 2.0;
Expand Down Expand Up @@ -157,9 +161,10 @@ void YoloBoxMapper::Opset11() {
// anchor_w pred_box[:, :, :, :, 3] = np.exp(pred_box[:, :, :, :, 3]) *
// anchor_h
anchors = helper_->Reshape(anchors, {1, anchor_num, 1, 1, 2});
auto pred_box_wh =
helper_->Slice(transposed_x->output(0), {0, 1, 2, 3, 4}, {0, 0, 0, 0, 2},
{max_int, max_int, max_int, max_int, 4});
auto pred_box_wh = helper_->Slice(transposed_x->output(0),
{0, 1, 2, 3, 4},
{0, 0, 0, 0, 2},
{max_int, max_int, max_int, max_int, 4});
pred_box_wh = helper_->MakeNode("Exp", {pred_box_wh})->output(0);
pred_box_wh = helper_->MakeNode("Mul", {pred_box_wh, anchors})->output(0);

Expand All @@ -168,20 +173,23 @@ void YoloBoxMapper::Opset11() {
// 1 - iou_aware_factor) * sigmoid(ioup)**iou_aware_factor
// else:
// pred_conf = sigmoid(x[:, :, :, :, 4:5])
auto confidence =
helper_->Slice(transposed_x->output(0), {0, 1, 2, 3, 4}, {0, 0, 0, 0, 4},
{max_int, max_int, max_int, max_int, 5});
auto confidence = helper_->Slice(transposed_x->output(0),
{0, 1, 2, 3, 4},
{0, 0, 0, 0, 4},
{max_int, max_int, max_int, max_int, 5});
std::string pred_conf = helper_->MakeNode("Sigmoid", {confidence})->output(0);
if (iou_aware_) {
auto ioup = helper_->Slice(x_info[0].name, {0, 1, 2, 3}, {0, 0, 0, 0},
auto ioup = helper_->Slice(x_info[0].name,
{0, 1, 2, 3},
{0, 0, 0, 0},
{max_int, anchor_num, max_int, max_int});
ioup = helper_->Unsqueeze(ioup, {4});
ioup = helper_->MakeNode("Sigmoid", {ioup})->output(0);
float power_value_0 = 1 - iou_aware_factor_;
auto power_0 =
helper_->Constant({1}, GetOnnxDtype(x_info[0].dtype), power_value_0);
auto power_1 = helper_->Constant({1}, GetOnnxDtype(x_info[0].dtype),
iou_aware_factor_);
auto power_1 = helper_->Constant(
{1}, GetOnnxDtype(x_info[0].dtype), iou_aware_factor_);
ioup = helper_->MakeNode("Pow", {ioup, power_1})->output(0);
pred_conf = helper_->MakeNode("Pow", {pred_conf, power_0})->output(0);
pred_conf = helper_->MakeNode("Mul", {pred_conf, ioup})->output(0);
Expand All @@ -190,8 +198,8 @@ void YoloBoxMapper::Opset11() {
// pred_conf[pred_conf < conf_thresh] = 0.
// pred_score = sigmoid(x[:, :, :, :, 5:]) * pred_conf
// pred_box = pred_box * (pred_conf > 0.).astype('float32')
auto value_2 =
helper_->Constant({1}, GetOnnxDtype(x_info[0].dtype), float(2.0));
auto value_2 = helper_->Constant(
{1}, GetOnnxDtype(x_info[0].dtype), static_cast<float>(2.0));
auto center = helper_->MakeNode("Div", {pred_box_wh, value_2})->output(0);
auto min_xy = helper_->MakeNode("Sub", {pred_box_xy, center})->output(0);
auto max_xy = helper_->MakeNode("Add", {pred_box_xy, center})->output(0);
Expand All @@ -203,7 +211,9 @@ void YoloBoxMapper::Opset11() {
filter = helper_->AutoCast(filter, P2ODataType::BOOL, x_info[0].dtype);
pred_conf = helper_->MakeNode("Mul", {pred_conf, filter})->output(0);
auto pred_score =
helper_->Slice(transposed_x->output(0), {0, 1, 2, 3, 4}, {0, 0, 0, 0, 5},
helper_->Slice(transposed_x->output(0),
{0, 1, 2, 3, 4},
{0, 0, 0, 0, 5},
{max_int, max_int, max_int, max_int, max_int});
pred_score = helper_->MakeNode("Sigmoid", {pred_score})->output(0);
pred_score = helper_->MakeNode("Mul", {pred_score, pred_conf})->output(0);
Expand All @@ -226,8 +236,8 @@ void YoloBoxMapper::Opset11() {

if (!clip_bbox_) {
auto out = helper_->MakeNode("Mul", {pred_box, im_whwh})->output(0);
helper_->AutoCast(out, boxes_info[0].name, x_info[0].dtype,
boxes_info[0].dtype);
helper_->AutoCast(
out, boxes_info[0].name, x_info[0].dtype, boxes_info[0].dtype);
} else {
pred_box = helper_->MakeNode("Mul", {pred_box, im_whwh})->output(0);
auto im_wh = helper_->Concat({split_im_hw[1], split_im_hw[0]}, 2);
Expand All @@ -238,8 +248,8 @@ void YoloBoxMapper::Opset11() {
pred_box_xymin_xymax[1] =
helper_->MakeNode("Min", {pred_box_xymin_xymax[1], im_wh})->output(0);
auto out = helper_->Concat(pred_box_xymin_xymax, 2);
helper_->AutoCast(out, boxes_info[0].name, x_info[0].dtype,
boxes_info[0].dtype);
helper_->AutoCast(
out, boxes_info[0].name, x_info[0].dtype, boxes_info[0].dtype);
}

auto class_num =
Expand All @@ -248,7 +258,7 @@ void YoloBoxMapper::Opset11() {
helper_->Concat({nchw[0], value_neg_1, class_num}, int64_t(0));
auto score_out =
helper_->MakeNode("Reshape", {pred_score, score_out_shape})->output(0);
helper_->AutoCast(score_out, scores_info[0].name, x_info[0].dtype,
scores_info[0].dtype);
helper_->AutoCast(
score_out, scores_info[0].name, x_info[0].dtype, scores_info[0].dtype);
}
} // namespace paddle2onnx
14 changes: 14 additions & 0 deletions paddle2onnx/mapper/detection/yolo_box.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,20 @@ class YoloBoxMapper : public Mapper {
GetAttr("anchors", &anchors_);
}

YoloBoxMapper(const PaddlePirParser& p, OnnxHelper* helper, int64_t op_id,
bool if_in_cf_block)
: Mapper(p, helper, op_id, if_in_cf_block) {
MarkAsExperimentalOp();
GetAttr("clip_bbox", &clip_bbox_);
GetAttr("iou_aware", &iou_aware_);
GetAttr("conf_thresh", &conf_thresh_);
GetAttr("iou_aware_factor", &iou_aware_factor_);
GetAttr("class_num", &class_num_);
GetAttr("downsample_ratio", &downsample_ratio_);
GetAttr("scale_x_y", &scale_x_y_);
GetAttr("anchors", &anchors_);
}

int32_t GetMinOpsetVersion(bool verbose) override;
void Opset11() override;

Expand Down
29 changes: 25 additions & 4 deletions paddle2onnx/mapper/exporter.cc
Original file line number Diff line number Diff line change
Expand Up @@ -203,9 +203,9 @@ void ModelExporter::SetOpsetVersion(const PaddlePirParser& pir_parser,
bool opset_is_legal = true;
// here
int32_t min_opset = GetMinOpsetVersion(pir_parser);
if (min_opset < 7 || min_opset >= MAX_ONNX_OPSET_VERSION) {
if (min_opset < 7 || min_opset > MAX_ONNX_OPSET_VERSION) {
P2OLogger(verbose_) << "The Opset Version must be between 7 and "
<< MAX_ONNX_OPSET_VERSION - 1 << std::endl;
<< MAX_ONNX_OPSET_VERSION << std::endl;
opset_is_legal = false;
}
if (!auto_upgrade_opset) {
Expand Down Expand Up @@ -387,11 +387,18 @@ ONNX_NAMESPACE::GraphProto ModelExporter::ExportIfBlock(
// get cf.yeild op input
pir::Operation* cf_yield_op = pir_parser.sub_blocks_ops.back();
// std::vector<std::string> sub_block_outpus;
for (auto oprand : cf_yield_op->operands()) {
pir::Value value = oprand.source();
for(int32_t idx = 0; idx < cf_yield_op->num_operands(); ++idx) {
pir::Value value = cf_yield_op->operand(idx).source();
auto cond_info = pir_parser.GetSubBlockValueTensorInfo(value);
// sub_block_outpus.push_back(cond_info[0].name);
temp_outputs.push_back(std::move(MakeValueInfo(cond_info[0])));
if (value.defining_op() == nullptr) {
value =
pir::Value(pir_parser.while_op_input_value_map[&(*(value.impl()))]);
}
if(value.defining_op()->GetParent() != &block) {
temp_inputs.push_back(std::move(MakeValueInfo(cond_info[0])));
}
}
} else {
// sub_blocks_ops is empty
Expand Down Expand Up @@ -524,6 +531,20 @@ ONNX_NAMESPACE::GraphProto ModelExporter::ExportBlock(
if_in_subblock,
verbose_);
}
if(if_in_subblock && !is_while_block) {
for (auto& input_item : inputs) {
for(int32_t idx = 0; idx < outputs.size(); ++idx) {
auto output_item = outputs[idx];
if(output_item->name() == input_item->name()) {
output_item->set_name(pir_parser.GenOpInputOutputName("yeild"));
temp_helper.MakeNode("Identity", {input_item->name()},
{output_item->name()});
outputs[idx] = std::move(output_item);
}
}
}
inputs.clear();
}
for (auto& item : parameters) {
*(graph.add_node()) = *(item.get());
}
Expand Down
Loading