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

【Paddle Hackathon 5th No.93】add paddle pool3d op #21536

Merged
merged 11 commits into from
Jan 11, 2024
218 changes: 218 additions & 0 deletions src/frontends/paddle/src/op/pool3d.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,218 @@
//*****************************************************************************
// Copyright (C) 2018-2023 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
//*****************************************************************************

#include <string>

#include "default_opset.hpp"
#include "openvino/frontend/paddle/node_context.hpp"

namespace ov {
namespace frontend {
namespace paddle {
namespace op {
// helper func - get pad_begin and pad_end
static void get_paddings(const NodeContext& node,
ov::Shape& pad_begin,
ov::Shape& pad_end,
ov::op::PadType& auto_pad,
std::string& data_format) {
if (node.has_attribute("padding_algorithm")) {
auto pad_algo = node.get_attribute<std::string>("padding_algorithm");
if (pad_algo == "SAME") {
auto_pad = ov::op::PadType::SAME_UPPER;
} else if (pad_algo == "VALID") {
auto_pad = ov::op::PadType::VALID;
} else if (pad_algo == "EXPLICIT") {
auto_pad = ov::op::PadType::EXPLICIT;
} else {
throw std::runtime_error("Unsupported pooling padding_algorithm " + pad_algo);
}
} else {
// adaptive_maxpool with no such attr.
auto_pad = ov::op::PadType::EXPLICIT;
}

/*If pool padding size is a tuple or list, it could be in three forms:
[pad_depth, pad_height, pad_width] or [pad_depth_front, pad_depth_back,
pad_height_top, pad_height_bottom, pad_width_left, pad_width_right],
and when data_format is “NCDHW”, pool_padding can
be in the form [[0,0], [0,0], [pad_depth_front, pad_depth_back], [pad_height_top,
pad_height_bottom], [pad_width_left, pad_width_right]]. when
data_format is “NDHWC”, pool_padding can be in the form
[[0,0], [pad_depth_front, pad_depth_back], [pad_height_top,
pad_height_bottom], [pad_width_left, pad_width_right], [0,0]].
Otherwise, the pool padding size will be a square of an int.*/
auto paddings = node.get_attribute<std::vector<int32_t>>("paddings");

switch (paddings.size()) {
case 3:
pad_begin =
Shape{static_cast<size_t>(paddings[0]), static_cast<size_t>(paddings[1]), static_cast<size_t>(paddings[2])};
pad_end = pad_begin;
break;
case 6:
pad_begin =
Shape{static_cast<size_t>(paddings[0]), static_cast<size_t>(paddings[2]), static_cast<size_t>(paddings[4])};
pad_end = Shape{
static_cast<size_t>(paddings[1]),
static_cast<size_t>(paddings[3]),
static_cast<size_t>(paddings[5]),
};
break;
default:
throw std::runtime_error("Unsupported pooling paddings " + std::to_string(paddings.size()));
}
}

NamedOutputs pool3d(const NodeContext& node) {
auto data = node.get_input("X");

auto pooling_type = node.get_attribute<std::string>("pooling_type", {});
auto global_pooling = node.get_attribute<bool>("global_pooling");
auto adaptive = node.get_attribute<bool>("adaptive");
auto kernel_shape = node.get_attribute<std::vector<int32_t>>("ksize");

auto rounding_type =
node.get_attribute<bool>("ceil_mode", false) ? ov::op::RoundingType::CEIL : ov::op::RoundingType::FLOOR;

if (pooling_type.empty()) {
pooling_type = "max";
}

PADDLE_OP_CHECK(node, (pooling_type == "max") || (pooling_type == "avg"), "pool3d: not supported pooling type !");
PADDLE_OP_CHECK(node, kernel_shape.size() == 1 || kernel_shape.size() == 3, "pool3d: ksize must be 1 or 3!");

PartialShape input_shape = data.get_partial_shape();

int32_t input_rank = static_cast<int32_t>(input_shape.rank().get_length());
PADDLE_OP_CHECK(node, input_rank >= 2, "input tensor rank must be greater than 2");

auto auto_pad = ov::op::PadType::EXPLICIT;
ov::Shape pad_begin, pad_end;
std::string data_format = node.get_attribute<std::string>("data_format", "NCDHW");

get_paddings(node, pad_begin, pad_end, auto_pad, data_format);

if (data_format == "NDHWC") {
data = std::make_shared<default_opset::Transpose>(
data,
std::make_shared<default_opset::Constant>(ov::element::i64, Shape{5}, std::vector<int64_t>{0, 4, 1, 2, 3}));
input_shape = data.get_partial_shape();
}

std::vector<Output<Node>> pool_outputs;
if (global_pooling || (adaptive && std::any_of(kernel_shape.begin(), kernel_shape.end(), [](int32_t i) {
meiyang-intel marked this conversation as resolved.
Show resolved Hide resolved
return i == 1;
}))) {
if (pooling_type == "max") {
auto axes = default_opset::Constant::create(ov::element::i64,
{3},
{input_rank - 3, input_rank - 2, input_rank - 1});
pool_outputs = std::make_shared<default_opset::ReduceMax>(data, axes, true)->outputs();
} else {
auto axes = default_opset::Constant::create(ov::element::i64,
{3},
{input_rank - 3, input_rank - 2, input_rank - 1});
pool_outputs = std::make_shared<default_opset::ReduceMean>(data, axes, true)->outputs();
}
} else if (adaptive) {
meiyang-intel marked this conversation as resolved.
Show resolved Hide resolved
auto pool_size = std::vector<int64_t>(3, 0);

if (kernel_shape.size() == 1) {
// Not tested: implemented according to spec, but can't generate real
// model to test
pool_size[0] = pool_size[1] = pool_size[2] = kernel_shape[0];
} else {
pool_size[0] = kernel_shape[0];
pool_size[1] = kernel_shape[1];
pool_size[2] = kernel_shape[2];
}

const Output<ov::Node> output_shape =
default_opset::Constant::create(ov::element::i64, {pool_size.size()}, pool_size);

if (pooling_type == "max") {
pool_outputs =
std::make_shared<default_opset::AdaptiveMaxPool>(data, output_shape, ov::element::i32)->outputs();
} else {
pool_outputs = std::make_shared<default_opset::AdaptiveAvgPool>(data, output_shape)->outputs();
}
} else {
auto strides = node.get_attribute<std::vector<int32_t>>("strides");

size_t kernel_d, kernel_h, kernel_w;
if (kernel_shape.size() == 1) {
// Not tested: implemented according to spec, but can't generate real
// model to test
kernel_d = kernel_h = kernel_w = kernel_shape[0];
} else {
kernel_d = kernel_shape[0];
kernel_h = kernel_shape[1];
kernel_w = kernel_shape[2];
}

PADDLE_OP_CHECK(node,
kernel_d > 0 && kernel_h > 0 && kernel_w > 0,
"pool3d kernel shape must be greater than 0");

// Note: this shape check is only valid when the spatial dim of input_shape
// is static.
if (input_shape[2].is_static() && input_shape[3].is_static() && input_shape[4].is_static()) {
uint64_t input_d = input_shape[input_rank - 3].get_length();
uint64_t input_h = input_shape[input_rank - 2].get_length();
uint64_t input_w = input_shape[input_rank - 1].get_length();
if ((input_d > 0) && (input_d + pad_begin[0] + pad_end[0] < kernel_d)) {
kernel_d = input_d + pad_begin[0] + pad_end[0];
}
if ((input_h > 0) && (input_h + pad_begin[1] + pad_end[1] < kernel_h)) {
kernel_h = input_h + pad_begin[1] + pad_end[1];
}
if ((input_w > 0) && (input_w + pad_begin[2] + pad_end[2] < kernel_w)) {
kernel_w = input_w + pad_begin[2] + pad_end[2];
}
}

if (pooling_type == "max") {
pool_outputs = std::make_shared<default_opset::MaxPool>(data,
ov::Strides(strides.begin(), strides.end()),
ov::Strides{1, 1, 1},
pad_begin,
pad_end,
ov::Shape{kernel_d, kernel_h, kernel_w},
rounding_type,
auto_pad)
->outputs();
} else {
bool exclude_pad = node.get_attribute<bool>("exclusive", false);
pool_outputs = std::make_shared<default_opset::AvgPool>(data,
ov::Strides(strides.begin(), strides.end()),
pad_begin,
pad_end,
ov::Shape{kernel_d, kernel_h, kernel_w},
exclude_pad,
rounding_type,
auto_pad)
->outputs();
}
}

if (data_format == "NDHWC") {
pool_outputs[0] = std::make_shared<default_opset::Transpose>(
pool_outputs[0],
std::make_shared<default_opset::Constant>(ov::element::i64, Shape{5}, std::vector<int64_t>{0, 2, 3, 4, 1}));
}

if (pool_outputs.size() == 1) {
meiyang-intel marked this conversation as resolved.
Show resolved Hide resolved
return NamedOutputs{{"Out", {pool_outputs[0]}}};
} else {
return NamedOutputs{{"Out", {pool_outputs[0]}}, {"Mask", {pool_outputs[1]}}};
meiyang-intel marked this conversation as resolved.
Show resolved Hide resolved
}
}

} // namespace op
} // namespace paddle
} // namespace frontend
} // namespace ov
3 changes: 3 additions & 0 deletions src/frontends/paddle/src/op_table.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ OP_CONVERTER(p_norm);
OP_CONVERTER(pad3d);
OP_CONVERTER(pow);
OP_CONVERTER(pool2d);
OP_CONVERTER(pool3d);
OP_CONVERTER(prior_box);
OP_CONVERTER(quantize_linear);
OP_CONVERTER(range);
Expand Down Expand Up @@ -197,6 +198,7 @@ std::map<std::string, CreatorFunction> get_supported_ops() {
{"matmul", op::matmul},
{"matmul_v2", op::matmul_v2},
{"max_pool2d_with_index", op::pool2d},
{"max_pool3d_with_index", op::pool3d},
{"matrix_nms", op::matrix_nms},
{"meshgrid", op::meshgrid},
{"multiclass_nms3", op::multiclass_nms},
Expand All @@ -208,6 +210,7 @@ std::map<std::string, CreatorFunction> get_supported_ops() {
{"pad3d", op::pad3d},
{"pow", op::pow},
{"pool2d", op::pool2d},
{"pool3d", op::pool3d},
{"prior_box", op::prior_box},
{"quantize_linear", op::quantize_linear},
{"range", op::range},
Expand Down
27 changes: 27 additions & 0 deletions src/frontends/paddle/tests/op_fuzzy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,19 @@ static const std::vector<std::string> models{
std::string("avgPool_test7"),
std::string("avgPool_test8"),
std::string("avgPool_test9"),
std::string("avgAdaptivePool3D_test1"),
std::string("avgAdaptivePool3D_test2"),
std::string("avgAdaptivePool3D_test3"),
std::string("avg3dPool_test1"),
std::string("avg3dPool_test2"),
std::string("avg3dPool_test3"),
std::string("avg3dPool_test4"),
std::string("avg3dPool_test5"),
std::string("avg3dPool_test6"),
std::string("avg3dPool_test7"),
std::string("avg3dPool_test8"),
std::string("avg3dPool_test9"),
std::string("avg3dPool_test10"),
std::string("batch_norm_nchw/batch_norm_nchw.pdmodel"),
std::string("batch_norm_nhwc/batch_norm_nhwc.pdmodel"),
std::string("bicubic_downsample_false_0/bicubic_downsample_false_0.pdmodel"),
Expand Down Expand Up @@ -330,6 +343,20 @@ static const std::vector<std::string> models{
std::string("maxPool_test7"),
std::string("maxPool_test8"),
std::string("maxPool_test9"),
std::string("maxAdaptivePool3D_test1"),
std::string("maxAdaptivePool3D_test2"),
std::string("maxAdaptivePool3D_test3"),
std::string("max3dPool_test1"),
std::string("max3dPool_test2"),
std::string("max3dPool_test3"),
std::string("max3dPool_test4"),
std::string("max3dPool_test5"),
std::string("max3dPool_test6"),
std::string("max3dPool_test7"),
std::string("max3dPool_test8"),
std::string("max3dPool_test9"),
std::string("max3dPool_test10"),
std::string("max3dRetureMask"),
std::string("meshgrid/meshgrid.pdmodel"),
std::string("multiclass_nms_by_background"),
std::string("multiclass_nms_by_class_id"),
Expand Down