diff --git a/docs/MO_DG/prepare_model/Supported_Frameworks_Layers.md b/docs/MO_DG/prepare_model/Supported_Frameworks_Layers.md index e3311fb23d21b3..8a959a7d695923 100644 --- a/docs/MO_DG/prepare_model/Supported_Frameworks_Layers.md +++ b/docs/MO_DG/prepare_model/Supported_Frameworks_Layers.md @@ -771,6 +771,7 @@ paddlepaddle >= 2.1 multiclass_nms Only supports IE CPU plugin with "number of selected boxes" static shape (e.g.: ``min(min(num_boxes, nms_top_k) * num_classes_output, keep_top_k)``). nearest_interp ``NCW``, ``NWC``, ``NHWC``, ``NCDHW``, ``NDHWC`` data_layout are not supported. not_equal + one_hot_v2 p_norm pad3d ``Circular`` mode is not supported. pool2d ``NHWC`` data_layout is not supported. diff --git a/src/frontends/paddle/src/op/one_hot_v2.cpp b/src/frontends/paddle/src/op/one_hot_v2.cpp new file mode 100644 index 00000000000000..d63ad21dcb3b1c --- /dev/null +++ b/src/frontends/paddle/src/op/one_hot_v2.cpp @@ -0,0 +1,31 @@ +// 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 one_hot_v2(const NodeContext& node) { + auto data = node.get_input("X"); + Output depth; + if (node.has_input("depth_tensor")) { + auto depth_value = node.get_input("depth_tensor"); + depth = std::make_shared(depth_value); + } else { + const auto depth_value = node.get_attribute("depth"); + depth = default_opset::Constant::create(element::i32, Shape{}, {depth_value}); + } + auto on_value = default_opset::Constant::create(element::f32, Shape{}, {1}); + auto off_value = default_opset::Constant::create(element::f32, Shape{}, {0}); + const auto indices_axis = -1; + auto result = std::make_shared(data, depth, on_value, off_value, indices_axis); + return node.default_single_output_mapping({result}, {"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 835933c8a0640e..353d5042bc79cc 100644 --- a/src/frontends/paddle/src/op_table.cpp +++ b/src/frontends/paddle/src/op_table.cpp @@ -73,6 +73,7 @@ OP_CONVERTER(matrix_nms); OP_CONVERTER(meshgrid); OP_CONVERTER(multiclass_nms); OP_CONVERTER(nearest_interp_v2); +OP_CONVERTER(one_hot_v2); OP_CONVERTER(p_norm); OP_CONVERTER(pad3d); OP_CONVERTER(pow); @@ -195,6 +196,7 @@ std::map get_supported_ops() { {"nearest_interp_v2", op::nearest_interp_v2}, {"nearest_interp", op::nearest_interp_v2}, {"not_equal", op::elementwise_not_equal}, + {"one_hot_v2", op::one_hot_v2}, {"p_norm", op::p_norm}, {"pad3d", op::pad3d}, {"pow", op::pow}, diff --git a/src/frontends/paddle/tests/op_fuzzy.cpp b/src/frontends/paddle/tests/op_fuzzy.cpp index 55536297b54235..6aac0a05e15247 100644 --- a/src/frontends/paddle/tests/op_fuzzy.cpp +++ b/src/frontends/paddle/tests/op_fuzzy.cpp @@ -377,6 +377,9 @@ static const std::vector models{ std::string("not_equal_float32"), std::string("not_equal_int32"), std::string("not_equal_int64"), + std::string("one_hot_v2_1"), + std::string("one_hot_v2_2"), + std::string("one_hot_v2_3"), std::string("p_norm1"), std::string("p_norm2"), std::string("p_norm3"), diff --git a/src/frontends/paddle/tests/test_models/gen_scripts/generate_one_hot_v2.py b/src/frontends/paddle/tests/test_models/gen_scripts/generate_one_hot_v2.py new file mode 100644 index 00000000000000..c5d36d9c69084e --- /dev/null +++ b/src/frontends/paddle/tests/test_models/gen_scripts/generate_one_hot_v2.py @@ -0,0 +1,47 @@ +# Copyright (C) 2018-2023 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +# +# one_hot_v2 paddle model generator +# +import paddle +import numpy as np +from save_model import saveModel +import sys + + +def one_hot_v2(name: str, x, num_classes, is_tensor): + paddle.enable_static() + + with paddle.static.program_guard(paddle.static.Program(), paddle.static.Program()): + x_node = paddle.static.data(name="x", shape=x.shape, dtype=x.dtype) + depth_node = paddle.static.data(name="depth_tensor", shape=num_classes.shape, dtype=num_classes.dtype) if is_tensor else num_classes + out = paddle.nn.functional.one_hot(x_node, num_classes=depth_node) + place = paddle.CPUPlace() + exe = paddle.static.Executor(place) + feed_list = {"x": x, "depth_tensor": num_classes} if is_tensor else {"x": x} + outs = exe.run(feed=feed_list, fetch_list=[out]) + feedkey_list = ["x", "depth_tensor"] if is_tensor else ['x'] + input_list = [x, num_classes] if is_tensor else [x] + saveModel(name, exe, feedkeys=feedkey_list, fetchlist=[out], inputs=input_list, outputs=[outs[0]], target_dir=sys.argv[1]) + + return outs[0] + + +def main(): + # int 32 + data = np.array([1]).astype("int32") + num_classes = 4 + one_hot_v2("one_hot_v2_1", data, num_classes, is_tensor=False) + # rank 1 int64 + data = np.array([4, 1, 3, 3]).astype("int64") + num_classes = np.array([5]).astype("int32") + one_hot_v2("one_hot_v2_2", data, num_classes, is_tensor=True) + # rank 2 int64 + data = np.array([[4, 1, 3, 3], [1, 1, 3, 0]]).astype("int64") + num_classes = np.array([5]).astype("int32") + one_hot_v2("one_hot_v2_3", data, num_classes, is_tensor=True) + + +if __name__ == "__main__": + main()