From 93727d1448956d844687b9f74573812639843022 Mon Sep 17 00:00:00 2001 From: Asthestarsfalll <72954905+Asthestarsfalll@users.noreply.github.com> Date: Mon, 8 Jan 2024 10:17:28 +0800 Subject: [PATCH] =?UTF-8?q?=E3=80=90Hackathon=205th=20No.94=E3=80=91add=20?= =?UTF-8?q?paddle=20partial=5Fop=20(#20103)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * add partial_concat and partial_sum * add static_cast * merge into partial_ops * update * add shape check * support for paddle2.4 --------- Co-authored-by: cecilia peng Co-authored-by: Yu Xu --- src/frontends/paddle/src/op/partial_ops.cpp | 23 +++++++ src/frontends/paddle/src/op/partial_ops.hpp | 43 ++++++++++++ src/frontends/paddle/src/op_table.cpp | 4 ++ src/frontends/paddle/tests/op_fuzzy.cpp | 6 ++ .../gen_scripts/generate_partial_concat.py | 66 ++++++++++++++++++ .../gen_scripts/generate_partial_sum.py | 68 +++++++++++++++++++ 6 files changed, 210 insertions(+) create mode 100644 src/frontends/paddle/src/op/partial_ops.cpp create mode 100644 src/frontends/paddle/src/op/partial_ops.hpp create mode 100644 src/frontends/paddle/tests/test_models/gen_scripts/generate_partial_concat.py create mode 100644 src/frontends/paddle/tests/test_models/gen_scripts/generate_partial_sum.py diff --git a/src/frontends/paddle/src/op/partial_ops.cpp b/src/frontends/paddle/src/op/partial_ops.cpp new file mode 100644 index 00000000000000..eea6c58db04c5d --- /dev/null +++ b/src/frontends/paddle/src/op/partial_ops.cpp @@ -0,0 +1,23 @@ +// Copyright (C) 2018-2023 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include "partial_ops.hpp" + +namespace ov { +namespace frontend { +namespace paddle { +namespace op { + +NamedOutputs partial_sum(const NodeContext& node) { + return partial_ops(node, "sum"); +} + +NamedOutputs partial_concat(const NodeContext& node) { + return partial_ops(node, "concat"); +} + +} // namespace op +} // namespace paddle +} // namespace frontend +} // namespace ov diff --git a/src/frontends/paddle/src/op/partial_ops.hpp b/src/frontends/paddle/src/op/partial_ops.hpp new file mode 100644 index 00000000000000..c82cffbb99bce0 --- /dev/null +++ b/src/frontends/paddle/src/op/partial_ops.hpp @@ -0,0 +1,43 @@ +// Copyright (C) 2018-2023 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include "default_opset.hpp" +#include "openvino/frontend/paddle/node_context.hpp" + +namespace ov { +namespace frontend { +namespace paddle { +namespace op { + +NamedOutputs partial_ops(const NodeContext& node, const std::string type) { + auto x = node.get_ng_inputs("X"); + const auto start_index = node.get_attribute("start_index"); + const auto length = node.get_attribute("length"); + PADDLE_OP_CHECK(node, x[0].get_partial_shape().rank().get_length() == 2, "partial ops only support 2-D Tensor"); + + int end_index; + if (length < 0) { + // Negative values for all elements after start_index on second dim. + end_index = static_cast(x[0].get_shape()[1]); + } else { + end_index = start_index + length; + } + + const auto start_node = std::make_shared(element::i32, Shape{1}, start_index); + const auto end_node = std::make_shared(element::i32, Shape{1}, end_index); + const auto one_node = std::make_shared(element::i32, Shape{1}, 1); + + auto left = std::make_shared(x[0], start_node, end_node, one_node, one_node); + auto right = std::make_shared(x[1], start_node, end_node, one_node, one_node); + + if (type == "sum") + return node.default_single_output_mapping({std::make_shared(left, right)}, {"Out"}); + return node.default_single_output_mapping({std::make_shared(NodeVector{left, right}, 1)}, + {"Out"}); +} + +} // namespace op +} // namespace paddle +} // namespace frontend +} // namespace ov diff --git a/src/frontends/paddle/src/op_table.cpp b/src/frontends/paddle/src/op_table.cpp index 858e1beed4fe33..f39b5f63128a76 100644 --- a/src/frontends/paddle/src/op_table.cpp +++ b/src/frontends/paddle/src/op_table.cpp @@ -77,6 +77,8 @@ OP_CONVERTER(nearest_interp_v2); OP_CONVERTER(one_hot_v2); OP_CONVERTER(p_norm); OP_CONVERTER(pad3d); +OP_CONVERTER(partial_concat); +OP_CONVERTER(partial_sum); OP_CONVERTER(pow); OP_CONVERTER(pool2d); OP_CONVERTER(prior_box); @@ -208,6 +210,8 @@ std::map get_supported_ops() { {"one_hot_v2", op::one_hot_v2}, {"p_norm", op::p_norm}, {"pad3d", op::pad3d}, + {"partial_concat", op::partial_concat}, + {"partial_sum", op::partial_sum}, {"pow", op::pow}, {"pool2d", op::pool2d}, {"prior_box", op::prior_box}, diff --git a/src/frontends/paddle/tests/op_fuzzy.cpp b/src/frontends/paddle/tests/op_fuzzy.cpp index 907253bbf26afb..13bcacb8e319c5 100644 --- a/src/frontends/paddle/tests/op_fuzzy.cpp +++ b/src/frontends/paddle/tests/op_fuzzy.cpp @@ -391,6 +391,12 @@ static const std::vector models{ std::string("pad3d_test1"), std::string("pad3d_test2"), std::string("pad3d_test3"), + std::string("partial_concat_1"), + std::string("partial_concat_2"), + std::string("partial_concat_3"), + std::string("partial_sum_1"), + std::string("partial_sum_2"), + std::string("partial_sum_3"), // pad3d_test4, std::string("pow_float32"), std::string("pow_int32"), diff --git a/src/frontends/paddle/tests/test_models/gen_scripts/generate_partial_concat.py b/src/frontends/paddle/tests/test_models/gen_scripts/generate_partial_concat.py new file mode 100644 index 00000000000000..c6d50dfdec679e --- /dev/null +++ b/src/frontends/paddle/tests/test_models/gen_scripts/generate_partial_concat.py @@ -0,0 +1,66 @@ +# Copyright (C) 2018-2023 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +# +# partial_concat paddle model generator +# +import numpy as np +from save_model import saveModel +import paddle +import sys + +def partial_concat(name: str, x, y, start_index=0, length=-1): + paddle.enable_static() + + with paddle.static.program_guard(paddle.static.Program(), paddle.static.Program()): + x_data = paddle.static.data(name="x", shape=x.shape, dtype=x.dtype) + y_data = paddle.static.data(name="y", shape=x.shape, dtype=y.dtype) + + if paddle.__version__ >= '2.5.1': + out = paddle.incubate.layers.nn.partial_concat( + [x_data, y_data], start_index=start_index, length=length + ) + else: + out = paddle.fluid.contrib.layers.partial_concat( + [x_data, y_data], start_index=start_index, length=length + ) + + cpu = paddle.static.cpu_places(1) + exe = paddle.static.Executor(cpu[0]) + # startup program will call initializer to initialize the parameters. + exe.run(paddle.static.default_startup_program()) + + outs = exe.run(feed={"x": x, "y": y}, fetch_list=[out]) + + saveModel( + name, + exe, + feedkeys=["x", "y"], + fetchlist=[out], + inputs=[x, y], + outputs=[outs[0]], + target_dir=sys.argv[1], + ) + + return outs[0] + + +def main(): + dtype = 'float32' + x = np.random.randn(6, 4).astype(dtype) + y = np.random.randn(6, 4).astype(dtype) + partial_concat("partial_concat_1", x, y, start_index=2, length=2) + + + dtype = 'int32' + x = np.random.randint(-10, 10, [5, 3]).astype(dtype) + y = np.random.randint(-10, 10, [5, 3]).astype(dtype) + partial_concat("partial_concat_2", x, y, start_index=1, length=-1) + + dtype = 'int64' + x = np.random.randint(-10, 10, [8, 10]).astype(dtype) + y = np.random.randint(-10, 10, [8, 10]).astype(dtype) + partial_concat("partial_concat_3", x, y, start_index=1, length=5) + +if __name__ == "__main__": + main() diff --git a/src/frontends/paddle/tests/test_models/gen_scripts/generate_partial_sum.py b/src/frontends/paddle/tests/test_models/gen_scripts/generate_partial_sum.py new file mode 100644 index 00000000000000..8d813ec3815f53 --- /dev/null +++ b/src/frontends/paddle/tests/test_models/gen_scripts/generate_partial_sum.py @@ -0,0 +1,68 @@ +# Copyright (C) 2018-2023 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +# +# partial_sum paddle model generator +# +import numpy as np +from save_model import saveModel +import paddle +import sys + + +def partial_sum(name: str, x, y, start_index=0, length=-1): + paddle.enable_static() + + with paddle.static.program_guard(paddle.static.Program(), paddle.static.Program()): + x_data = paddle.static.data(name="x", shape=x.shape, dtype=x.dtype) + y_data = paddle.static.data(name="y", shape=x.shape, dtype=y.dtype) + + if paddle.__version__ >= '2.5.1': + out = paddle.incubate.layers.nn.partial_sum( + [x_data, y_data], start_index=start_index, length=length + ) + else: + out = paddle.fluid.contrib.layers.partial_sum( + [x_data, y_data], start_index=start_index, length=length + ) + + + cpu = paddle.static.cpu_places(1) + exe = paddle.static.Executor(cpu[0]) + # startup program will call initializer to initialize the parameters. + exe.run(paddle.static.default_startup_program()) + + outs = exe.run(feed={"x": x, "y": y}, fetch_list=[out]) + + saveModel( + name, + exe, + feedkeys=["x", "y"], + fetchlist=[out], + inputs=[x, y], + outputs=[outs[0]], + target_dir=sys.argv[1], + ) + + return outs[0] + + +def main(): + dtype = 'float32' + x = np.random.randn(6, 4).astype(dtype) + y = np.random.randn(6, 4).astype(dtype) + partial_sum("partial_sum_1", x, y, start_index=2, length=2) + + + dtype = 'int32' + x = np.random.randint(-10, 10, [5, 3]).astype(dtype) + y = np.random.randint(-10, 10, [5, 3]).astype(dtype) + partial_sum("partial_sum_2", x, y, start_index=1, length=-1) + + dtype = 'int64' + x = np.random.randint(-10, 10, [8, 10]).astype(dtype) + y = np.random.randint(-10, 10, [8, 10]).astype(dtype) + partial_sum("partial_sum_3", x, y, start_index=1, length=5) + +if __name__ == "__main__": + main()