diff --git a/docs/articles_en/openvino-workflow/running-inference/inference-devices-and-modes/cpu-device/performance-hint-and-thread-scheduling.rst b/docs/articles_en/openvino-workflow/running-inference/inference-devices-and-modes/cpu-device/performance-hint-and-thread-scheduling.rst index 46b541d84d4035..6cc211116d1199 100644 --- a/docs/articles_en/openvino-workflow/running-inference/inference-devices-and-modes/cpu-device/performance-hint-and-thread-scheduling.rst +++ b/docs/articles_en/openvino-workflow/running-inference/inference-devices-and-modes/cpu-device/performance-hint-and-thread-scheduling.rst @@ -63,19 +63,19 @@ the model precision and the ratio of P-cores and E-cores. Then the default settings for low-level performance properties on Windows and Linux are as follows: -+--------------------------------------+-----------------------------------------------------------------------+-----------------------------------------------------------------------+ -| Property | Windows | Linux | -+======================================+=======================================================================+=======================================================================+ -| ``ov::num_streams`` | 1 | 1 | -+--------------------------------------+-----------------------------------------------------------------------+-----------------------------------------------------------------------+ -| ``ov::inference_num_threads`` | is equal to the number of P-cores or P-cores+E-cores on one numa node | is equal to the number of P-cores or P-cores+E-cores on one numa node | -+--------------------------------------+-----------------------------------------------------------------------+-----------------------------------------------------------------------+ -| ``ov::hint::scheduling_core_type`` | :ref:`Core Type Table of Latency Hint ` | :ref:`Core Type Table of Latency Hint ` | -+--------------------------------------+-----------------------------------------------------------------------+-----------------------------------------------------------------------+ -| ``ov::hint::enable_hyper_threading`` | No | No | -+--------------------------------------+-----------------------------------------------------------------------+-----------------------------------------------------------------------+ -| ``ov::hint::enable_cpu_pinning`` | No / Not Supported | Yes except using P-cores and E-cores together | -+--------------------------------------+-----------------------------------------------------------------------+-----------------------------------------------------------------------+ ++--------------------------------------+--------------------------------------------------------------------+--------------------------------------------------------------------+ +| Property | Windows | Linux | ++======================================+====================================================================+====================================================================+ +| ``ov::num_streams`` | 1 | 1 | ++--------------------------------------+--------------------------------------------------------------------+--------------------------------------------------------------------+ +| ``ov::inference_num_threads`` | is equal to the number of P-cores or P-cores+E-cores on one socket | is equal to the number of P-cores or P-cores+E-cores on one socket | ++--------------------------------------+--------------------------------------------------------------------+--------------------------------------------------------------------+ +| ``ov::hint::scheduling_core_type`` | :ref:`Core Type Table of Latency Hint ` | :ref:`Core Type Table of Latency Hint ` | ++--------------------------------------+--------------------------------------------------------------------+--------------------------------------------------------------------+ +| ``ov::hint::enable_hyper_threading`` | No | No | ++--------------------------------------+--------------------------------------------------------------------+--------------------------------------------------------------------+ +| ``ov::hint::enable_cpu_pinning`` | No / Not Supported | Yes except using P-cores and E-cores together | ++--------------------------------------+--------------------------------------------------------------------+--------------------------------------------------------------------+ .. note:: @@ -96,7 +96,7 @@ Then the default settings for low-level performance properties on Windows and Li Starting from 5th Gen Intel Xeon Processors, new microarchitecture enabled new sub-NUMA clusters feature. A sub-NUMA cluster (SNC) can create two or more localization domains (numa nodes) within a socket by BIOS configuration. - By default OpenVINO with latency hint uses single NUMA node for inference. Although such + By default OpenVINO with latency hint uses single socket for inference. Although such behavior allows to achive best performance for most of the models, there might be corner cases which require manual tuning of ``ov::num_streams`` and ``ov::hint::enable_hyper_threading parameters``. Please find more detail about `Sub-NUMA Clustering `__ diff --git a/src/common/transformations/include/transformations/op_conversions/fake_convert_decomposition.hpp b/src/common/transformations/include/transformations/op_conversions/fake_convert_decomposition.hpp new file mode 100644 index 00000000000000..e149152b2bcf6d --- /dev/null +++ b/src/common/transformations/include/transformations/op_conversions/fake_convert_decomposition.hpp @@ -0,0 +1,32 @@ +// Copyright (C) 2024 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#pragma once + +#include "openvino/pass/matcher_pass.hpp" +#include "transformations_visibility.hpp" + +namespace ov { +namespace pass { + +class TRANSFORMATIONS_API FakeConvertDecomposition; + +} // namespace pass +} // namespace ov + +/** + * @ingroup ov_transformation_common_api + * @brief FakeConvertDecomposition transformation decomposes FakeConvert layer. + * f8: f8e4m3, f8e5m2 + * downconvert: f32->f8, f16->f8, bf16->f8 + * upconvert: f8->f32, f8->f16, f8->bf16 + * output = (upconvert(downconvert(input * scale - shift)) + shift) / scale + * + */ + +class ov::pass::FakeConvertDecomposition : public ov::pass::MatcherPass { +public: + OPENVINO_MATCHER_PASS_RTTI("FakeConvertDecomposition"); + FakeConvertDecomposition(); +}; diff --git a/src/common/transformations/src/transformations/op_conversions/fake_convert_decomposition.cpp b/src/common/transformations/src/transformations/op_conversions/fake_convert_decomposition.cpp new file mode 100644 index 00000000000000..7f0a44df6a151d --- /dev/null +++ b/src/common/transformations/src/transformations/op_conversions/fake_convert_decomposition.cpp @@ -0,0 +1,76 @@ +// Copyright (C) 2024 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include "transformations/op_conversions/fake_convert_decomposition.hpp" + +#include "itt.hpp" +#include "openvino/core/rt_info.hpp" +#include "openvino/op/add.hpp" +#include "openvino/op/constant.hpp" +#include "openvino/op/convert.hpp" +#include "openvino/op/divide.hpp" +#include "openvino/op/fake_convert.hpp" +#include "openvino/op/multiply.hpp" +#include "openvino/op/subtract.hpp" +#include "openvino/pass/pattern/op/wrap_type.hpp" + +ov::pass::FakeConvertDecomposition::FakeConvertDecomposition() { + MATCHER_SCOPE(FakeConvertDecomposition); + auto data = pattern::any_input(); + + auto fake_convert = ov::pass::pattern::wrap_type(); + + matcher_pass_callback callback = [OV_CAPTURE_CPY_AND_THIS](ov::pass::pattern::Matcher& m) { + auto& pattern_to_output = m.get_pattern_value_map(); + const auto fake_convert_node = + ov::as_type_ptr(pattern_to_output.at(fake_convert).get_node_shared_ptr()); + + if (fake_convert_node == nullptr || transformation_callback(fake_convert_node)) { + return false; + } + + Output data{fake_convert_node->input_value(0)}; + const Output input_scale{fake_convert_node->input_value(1)}; + auto input_type = data.get_element_type(); + + ov::pass::NodeRegistry decomp_ops; + if (input_type != input_scale.get_element_type()) { + input_type = input_scale.get_element_type(); + data = std::make_shared(data, input_type); + data = decomp_ops.add(data.get_node_shared_ptr()); + } + + std::shared_ptr result; + const auto scale = decomp_ops.make(data, input_scale); + if (fake_convert_node->get_input_size() == 2) { + const auto downconvert = + decomp_ops.make(scale, fake_convert_node->get_destination_element_type()); + const auto upconvert = decomp_ops.make(downconvert, input_type); + + result = decomp_ops.make(upconvert, input_scale); + } else { + const Output input_shift{fake_convert_node->input_value(2)}; + const auto shift = decomp_ops.make(scale, input_shift); + + const auto downconvert = + decomp_ops.make(shift, fake_convert_node->get_destination_element_type()); + const auto upconvert = decomp_ops.make(downconvert, input_type); + + const auto deshift = decomp_ops.make(upconvert, input_shift); + result = decomp_ops.make(deshift, input_scale); + } + + if (result->get_output_element_type(0) != fake_convert_node->get_output_element_type(0)) { + result = decomp_ops.make(result, fake_convert_node->get_output_element_type(0)); + } + + result->set_friendly_name(m.get_match_root()->get_friendly_name()); + ov::copy_runtime_info(fake_convert_node, decomp_ops.get()); + ov::replace_node(m.get_match_root(), result); + return true; + }; + + auto m = std::make_shared(fake_convert, matcher_name); + register_matcher(m, callback); +} diff --git a/src/common/transformations/tests/op_conversions/fake_convert_decomposition_test.cpp b/src/common/transformations/tests/op_conversions/fake_convert_decomposition_test.cpp new file mode 100644 index 00000000000000..33b167ace11e24 --- /dev/null +++ b/src/common/transformations/tests/op_conversions/fake_convert_decomposition_test.cpp @@ -0,0 +1,149 @@ +// Copyright (C) 2024 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include "transformations/op_conversions/fake_convert_decomposition.hpp" + +#include + +#include "common_test_utils/common_utils.hpp" +#include "common_test_utils/ov_test_utils.hpp" +#include "openvino/opsets/opset1.hpp" +#include "openvino/opsets/opset13.hpp" + +using namespace ov; + +using FakeConvertDecompositionParams = std::tuple; // default shift + +class FakeConvertDecompositionTest : public ov::test::TestsCommon, + public ::testing::WithParamInterface { +public: + static std::string getTestCaseName(::testing::TestParamInfo obj) { + FakeConvertDecompositionParams params = obj.param; + + Shape data_shape, scale_shape, shift_shape; + element::Type_t data_prec, dst_prec; + bool default_shift; + std::tie(data_shape, scale_shape, shift_shape, data_prec, dst_prec, default_shift) = params; + + std::ostringstream result; + result << "dataShape=" << ov::test::utils::vec2str(data_shape) << "_"; + result << "scaleShape=" << ov::test::utils::vec2str(scale_shape) << "_"; + result << "shiftShape=" << ov::test::utils::vec2str(shift_shape) << "_"; + result << "dataPrecision=" << element::Type(data_prec) << "_"; + result << "destinationPrecision=" << element::Type(dst_prec) << "_"; + if (default_shift) + result << "defaultShift=true"; + else + result << "defaultShift=false"; + return result.str(); + } +}; + +TEST_P(FakeConvertDecompositionTest, CompareFunctions) { + FakeConvertDecompositionParams params = this->GetParam(); + + Shape data_shape, scale_shape, shift_shape; + element::Type_t data_prec, dst_prec; + bool default_shift; + std::tie(data_shape, scale_shape, shift_shape, data_prec, dst_prec, default_shift) = params; + + std::shared_ptr model(nullptr); + { + const auto data = std::make_shared(data_prec, PartialShape(data_shape)); + const auto scale = std::make_shared(data_prec, scale_shape); + const auto shift = std::make_shared(data_prec, shift_shape); + + const auto fake_convert = default_shift ? std::make_shared(data, scale, dst_prec) + : std::make_shared(data, scale, shift, dst_prec); + model = std::make_shared(NodeVector{fake_convert}, ParameterVector{data}); + + pass::Manager manager; + manager.register_pass(); + manager.register_pass(); + manager.run_passes(model); + + OV_ASSERT_NO_THROW(check_rt_info(model)); + } + + std::shared_ptr model_ref(nullptr); + { + const auto input_data = std::make_shared(data_prec, PartialShape(data_shape)); + const auto input_scale = std::make_shared(data_prec, scale_shape); + const auto input_shift = std::make_shared(data_prec, shift_shape); + ParameterVector params; + params.push_back(input_data); + std::shared_ptr data = input_data; + + std::shared_ptr result; + const auto scale = std::make_shared(data, input_scale); + if (default_shift) { + const auto downconvert = std::make_shared(scale, dst_prec); + const auto upconvert = std::make_shared(downconvert, data_prec); + + result = std::make_shared(upconvert, input_scale); + } else { + const auto shift = std::make_shared(scale, input_shift); + + const auto downconvert = std::make_shared(shift, dst_prec); + const auto upconvert = std::make_shared(downconvert, data_prec); + + const auto deshift = std::make_shared(upconvert, input_shift); + result = std::make_shared(deshift, input_scale); + } + + model_ref = std::make_shared(NodeVector{result}, params); + } + + const auto res = compare_functions(model, model_ref); + ASSERT_TRUE(res.first) << res.second; +} + +const std::vector data_precisions = {element::Type_t::f32, + element::Type_t::f16, + element::Type_t::bf16}; + +const std::vector destination_precisions = {element::Type_t::f8e4m3, element::Type_t::f8e5m2}; + +const std::vector default_shift = {true, false}; + +const auto simple_fake_convert_params = ::testing::Combine(::testing::Values(Shape{2, 3, 4, 5}), + ::testing::Values(Shape{1}), + ::testing::Values(Shape{1}), + ::testing::ValuesIn(data_precisions), + ::testing::ValuesIn(destination_precisions), + ::testing::ValuesIn(default_shift)); + +const auto broadcast_fake_convert_params = ::testing::Combine(::testing::Values(Shape{2, 3, 4, 5}), + ::testing::Values(Shape{2, 3, 1, 1}), + ::testing::Values(Shape{2, 3, 1, 1}), + ::testing::ValuesIn(data_precisions), + ::testing::ValuesIn(destination_precisions), + ::testing::ValuesIn(default_shift)); + +const auto elementwise_fake_convert_params = ::testing::Combine(::testing::Values(Shape{2, 3, 4, 5}), + ::testing::Values(Shape{2, 3, 4, 5}), + ::testing::Values(Shape{2, 3, 4, 5}), + ::testing::ValuesIn(data_precisions), + ::testing::ValuesIn(destination_precisions), + ::testing::ValuesIn(default_shift)); + +INSTANTIATE_TEST_SUITE_P(SimpleFakeConvert_Decomposition, + FakeConvertDecompositionTest, + simple_fake_convert_params, + FakeConvertDecompositionTest::getTestCaseName); + +INSTANTIATE_TEST_SUITE_P(BroadcastFakeConvert_Decomposition, + FakeConvertDecompositionTest, + broadcast_fake_convert_params, + FakeConvertDecompositionTest::getTestCaseName); + +INSTANTIATE_TEST_SUITE_P(ElementwiseFakeConvert_Decomposition, + FakeConvertDecompositionTest, + elementwise_fake_convert_params, + FakeConvertDecompositionTest::getTestCaseName); diff --git a/src/frontends/paddle/src/default_opset.hpp b/src/frontends/paddle/src/default_opset.hpp index c3eed5b5653c92..a5dc374964d485 100644 --- a/src/frontends/paddle/src/default_opset.hpp +++ b/src/frontends/paddle/src/default_opset.hpp @@ -2,13 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 // -#include "openvino/opsets/opset9.hpp" +#include "openvino/opsets/opset14.hpp" namespace ov { namespace frontend { namespace paddle { namespace op { -namespace default_opset = ov::opset9; +namespace default_opset = ov::opset14; } // namespace op } // namespace paddle diff --git a/src/frontends/paddle/src/op/elu.cpp b/src/frontends/paddle/src/op/elu.cpp new file mode 100644 index 00000000000000..c51a2af6f9f176 --- /dev/null +++ b/src/frontends/paddle/src/op/elu.cpp @@ -0,0 +1,23 @@ +// Copyright (C) 2018-2024 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include "default_opset.hpp" +#include "openvino/frontend/paddle/node_context.hpp" +#include "openvino/frontend/paddle/visibility.hpp" + +namespace ov { +namespace frontend { +namespace paddle { +namespace op { +NamedOutputs elu(const NodeContext& node) { + auto data = node.get_input("X"); + auto alpha = node.get_attribute("alpha", 1.0); + const auto& elu_node = std::make_shared(data, alpha); + return node.default_single_output_mapping({elu_node}, {"Out"}); +} + +} // namespace op +} // namespace paddle +} // namespace frontend +} // namespace ov diff --git a/src/frontends/paddle/src/op/expand_v2.cpp b/src/frontends/paddle/src/op/expand_v2.cpp index d79e49db286c13..ea174efa3a9920 100644 --- a/src/frontends/paddle/src/op/expand_v2.cpp +++ b/src/frontends/paddle/src/op/expand_v2.cpp @@ -19,8 +19,16 @@ NamedOutputs expand_v2(const NodeContext& node) { auto inputs = node.get_ng_inputs("expand_shapes_tensor"); ov::NodeVector node_vec; for (auto& input : inputs) { + if (input.get_partial_shape().rank().get_length() == 0) { + // should unsqueeze the input with non-shape. + auto unsqueeze_scalar = default_opset::Constant::create(ov::element::i32, {}, {0}); + input = std::make_shared(input, unsqueeze_scalar); + } + PADDLE_OP_CHECK(node, + input.get_partial_shape().rank().get_length() == 1, + "the rank of conv input must == 1"); auto cast = std::make_shared(input, element::i32); - node_vec.push_back(cast); + node_vec.emplace_back(cast); } shape_expected_node = std::make_shared(node_vec, 0); } else { diff --git a/src/frontends/paddle/src/op/eye.cpp b/src/frontends/paddle/src/op/eye.cpp new file mode 100644 index 00000000000000..3734d6fab44817 --- /dev/null +++ b/src/frontends/paddle/src/op/eye.cpp @@ -0,0 +1,36 @@ +// Copyright (C) 2018-2024 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 eye(const NodeContext& node) { + auto row = node.get_attribute("num_rows"); + auto col = node.get_attribute("num_columns", row); + auto dtype = node.get_attribute("dtype", ov::element::f32); + + const auto& row_node = std::make_shared(ov::element::i64, Shape{}, (row)); + const auto& col_node = std::make_shared(ov::element::i64, Shape{}, (col)); + const auto& diagonal_index_node = std::make_shared(ov::element::i32, Shape{}, (0)); + + std::shared_ptr out_node; + if (dtype == ov::element::i32 || dtype == ov::element::i64) { + out_node = std::make_shared(row_node, col_node, diagonal_index_node, dtype); + } else { + const auto& eye_node = + std::make_shared(row_node, col_node, diagonal_index_node, ov::element::i32); + out_node = std::make_shared(eye_node, dtype); + } + + return node.default_single_output_mapping({out_node}, {"Out"}); +} + +} // namespace op +} // namespace paddle +} // namespace frontend +} // namespace ov diff --git a/src/frontends/paddle/src/op/fill_constant.cpp b/src/frontends/paddle/src/op/fill_constant.cpp index b066fdfbe7a0c7..4a674b61d10c86 100644 --- a/src/frontends/paddle/src/op/fill_constant.cpp +++ b/src/frontends/paddle/src/op/fill_constant.cpp @@ -29,6 +29,10 @@ NamedOutputs fill_constant(const NodeContext& node) { PADDLE_OP_CHECK(node, false, "fill_constant only supports i32, f32, i64"); } + if (shape.empty()) { + shape.emplace_back(1); + } + PADDLE_OP_CHECK(node, shape.size() > 0 || node.has_input("ShapeTensor") || node.has_input("ShapeTensorList"), "fill_constant shape not set"); diff --git a/src/frontends/paddle/src/op/interp.cpp b/src/frontends/paddle/src/op/interp.cpp index e7b317f2888a83..5ab551dc3bdde2 100644 --- a/src/frontends/paddle/src/op/interp.cpp +++ b/src/frontends/paddle/src/op/interp.cpp @@ -4,6 +4,7 @@ #include "default_opset.hpp" #include "openvino/frontend/paddle/node_context.hpp" +#include "openvino/opsets/opset4.hpp" namespace ov { namespace frontend { @@ -147,8 +148,9 @@ static NamedOutputs interpolate(const NodeContext& node, attrs.pads_begin = {0, 0, 0, 0}; attrs.pads_end = {0, 0, 0, 0}; - return node.default_single_output_mapping({std::make_shared(x, target_spatial_shape, scales, attrs)}, - {"Out"}); + return node.default_single_output_mapping( + {std::make_shared(x, target_spatial_shape, scales, attrs)}, + {"Out"}); } NamedOutputs linear_interp_v2(const NodeContext& node) { diff --git a/src/frontends/paddle/src/op/reduce_ops.hpp b/src/frontends/paddle/src/op/reduce_ops.hpp index 2b595160420282..954d1de425c924 100644 --- a/src/frontends/paddle/src/op/reduce_ops.hpp +++ b/src/frontends/paddle/src/op/reduce_ops.hpp @@ -31,6 +31,10 @@ NamedOutputs reduce_ops(const NodeContext& node) { dims = node.get_attribute>("dim"); } + std::transform(dims.begin(), dims.end(), dims.begin(), [&input_rank](int64_t value) { + return value >= 0 ? value : value + input_rank; + }); + int64_t axis_size = static_cast(dims.size()); reduce_all = reduce_all || (axis_size == input_rank || axis_size == 0); diff --git a/src/frontends/paddle/src/op_table.cpp b/src/frontends/paddle/src/op_table.cpp index 769492eb13d1b8..e092f16095abe0 100644 --- a/src/frontends/paddle/src/op_table.cpp +++ b/src/frontends/paddle/src/op_table.cpp @@ -39,9 +39,11 @@ OP_CONVERTER(elementwise_sub); OP_CONVERTER(equal); OP_CONVERTER(greater_equal); OP_CONVERTER(not_equal); +OP_CONVERTER(elu); OP_CONVERTER(embedding); OP_CONVERTER(exp); OP_CONVERTER(expand_v2); +OP_CONVERTER(eye); OP_CONVERTER(flip); OP_CONVERTER(flatten_contiguous_range); OP_CONVERTER(floor); @@ -173,9 +175,11 @@ std::map get_supported_ops() { {"elementwise_sub", op::elementwise_sub}, {"dropout", op::dropout}, {"elementwise_pow", op::elementwise_pow}, + {"elu", op::elu}, {"equal", op::equal}, {"exp", op::exp}, {"expand_v2", op::expand_v2}, + {"eye", op::eye}, {"fill_any_like", op::fill_any_like}, {"fill_constant", op::fill_constant}, {"fill_constant_batch_size_like", op::fill_constant_batch_size_like}, diff --git a/src/frontends/paddle/tests/op_fuzzy.cpp b/src/frontends/paddle/tests/op_fuzzy.cpp index 99357a3a336d01..53ea7852604376 100644 --- a/src/frontends/paddle/tests/op_fuzzy.cpp +++ b/src/frontends/paddle/tests/op_fuzzy.cpp @@ -188,6 +188,7 @@ static const std::vector models{ std::string("elementwise_floordiv_int64_2/elementwise_floordiv_int64_2.pdmodel"), std::string("elementwise_floordiv_int64_3/elementwise_floordiv_int64_3.pdmodel"), std::string("elementwise_mul_bool1/elementwise_mul_bool1.pdmodel"), + std::string("elu/elu.pdmodel"), std::string("embedding_0/embedding_0.pdmodel"), std::string("embedding_sparse/embedding_sparse.pdmodel"), std::string("embedding_none_weight/embedding_none_weight.pdmodel"), @@ -201,6 +202,9 @@ static const std::vector models{ std::string("expand_v2_tensor_list/expand_v2_tensor_list.pdmodel"), std::string("expand_v2_tensor_list2/expand_v2_tensor_list2.pdmodel"), std::string("exp_test_float32/exp_test_float32.pdmodel"), + std::string("eye/eye.pdmodel"), + std::string("eye_int32/eye_int32.pdmodel"), + std::string("eye_int64/eye_int64.pdmodel"), std::string("flip_1/flip_1.pdmodel"), std::string("flip_2/flip_2.pdmodel"), std::string("flip_3/flip_3.pdmodel"), diff --git a/src/frontends/paddle/tests/test_models/gen_scripts/generate_elu.py b/src/frontends/paddle/tests/test_models/gen_scripts/generate_elu.py new file mode 100644 index 00000000000000..4dc67b2051222b --- /dev/null +++ b/src/frontends/paddle/tests/test_models/gen_scripts/generate_elu.py @@ -0,0 +1,44 @@ +# Copyright (C) 2018-2024 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +# +# relu6 paddle model generator +# +import numpy as np +from save_model import saveModel +import paddle +import sys + + +def elu(name: str, x, alpha=None, data_type='float32'): + paddle.enable_static() + + with paddle.static.program_guard(paddle.static.Program(), paddle.static.Program()): + node_x = paddle.static.data(name='x', shape=x.shape, dtype=data_type) + + if paddle.__version__ >= '2.0.0': + out = paddle.nn.functional.elu(node_x, alpha, name='elu') + else: + out = paddle.fluid.layers.elu(node_x, alpha, name='elu') + 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}, + fetch_list=[out]) + + saveModel(name, exe, feed_vars=[node_x], fetchlist=[out], + inputs=[x], outputs=[outs[0]], target_dir=sys.argv[1]) + + return outs[0] + + +def main(): + data_type = 'float32' + data = np.random.randn(2, 3, 4).astype('float32') + elu("elu", data) + +if __name__ == "__main__": + main() diff --git a/src/frontends/paddle/tests/test_models/gen_scripts/generate_eye.py b/src/frontends/paddle/tests/test_models/gen_scripts/generate_eye.py new file mode 100644 index 00000000000000..9b1a4f668c3ab2 --- /dev/null +++ b/src/frontends/paddle/tests/test_models/gen_scripts/generate_eye.py @@ -0,0 +1,41 @@ +# Copyright (C) 2018-2024 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +# +# fill_const paddle model generator +# +import numpy as np +from save_model import saveModel +import paddle +import sys + + +def eye(name : str, rows, cols = None, dtype = None): + paddle.enable_static() + with paddle.static.program_guard(paddle.static.Program(), paddle.static.Program()): + if paddle.__version__ >= '2.0.0': + x1 = paddle.eye(num_rows=rows, num_columns=cols, dtype=dtype, name='fill') + x2 = paddle.eye(num_rows=rows, num_columns=cols, dtype=dtype, name='fill') + else: + x1 = paddle.fluid.layers.eye(num_rows=rows, num_columns=cols, dtype=dtype, name='fill_constant') + x2 = paddle.fluid.layers.eye(num_rows=rows, num_columns=cols, dtype=dtype, name='fill_constant') + out = paddle.add(x1, x2) + 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( + fetch_list=[out]) + + saveModel(name, exe, feed_vars=[], fetchlist=[out], inputs=[], outputs=[outs[0]], target_dir=sys.argv[1]) + + return outs[0] + +def main(): + eye("eye", 3) + eye("eye_int32", 2, 3, "int32") + eye("eye_int64", 2, 3, "int64") + +if __name__ == "__main__": + main() diff --git a/src/plugins/intel_cpu/src/transformations/transformation_pipeline.cpp b/src/plugins/intel_cpu/src/transformations/transformation_pipeline.cpp index fb9e0925bc89e2..4d7df9a335e98a 100644 --- a/src/plugins/intel_cpu/src/transformations/transformation_pipeline.cpp +++ b/src/plugins/intel_cpu/src/transformations/transformation_pipeline.cpp @@ -80,6 +80,7 @@ #include "transformations/op_conversions/detection_output_downgrade.hpp" #include "transformations/op_conversions/detection_output_upgrade.hpp" #include "transformations/op_conversions/eye_decomposition.hpp" +#include "transformations/op_conversions/fake_convert_decomposition.hpp" #include "transformations/op_conversions/fq_decomposition.hpp" #include "transformations/op_conversions/gelu7_downgrade.hpp" #include "transformations/op_conversions/group_normalization_decomposition.hpp" @@ -1293,6 +1294,7 @@ void Transformations::PostSnippets(void) { return node::FakeQuantize::isSupportedOperation(node, errMsg); }, ov::pass::FakeQuantizeDecomposition); + CPU_REGISTER_PASS_COMMON(postSnippetsManager, ov::pass::FakeConvertDecomposition); CPU_REGISTER_PASS_COMMON(postSnippetsManager, ov::pass::ConstantFolding); postSnippetsManager.run_passes(model); } diff --git a/src/plugins/intel_cpu/tests/functional/shared_tests_instances/single_layer_tests/fake_convert.cpp b/src/plugins/intel_cpu/tests/functional/shared_tests_instances/single_layer_tests/fake_convert.cpp new file mode 100644 index 00000000000000..a2f17ea72cbb3e --- /dev/null +++ b/src/plugins/intel_cpu/tests/functional/shared_tests_instances/single_layer_tests/fake_convert.cpp @@ -0,0 +1,59 @@ +// Copyright (C) 2024 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include "single_op_tests/fake_convert.hpp" + +namespace { +using ov::test::FakeConvertLayerTest; + +const std::vector> shapes = {{{2, 3, 4, 5}}}; + +const std::vector data_precisions = {ov::element::f32, ov::element::f16, ov::element::bf16}; + +const std::vector destination_precisions = {ov::element::f8e4m3, ov::element::f8e5m2}; + +const std::vector default_shift = {true, false}; + +const auto simple_fake_convert_params = + ::testing::Combine(::testing::ValuesIn(ov::test::static_shapes_to_test_representation(shapes)), + ::testing::Values(ov::Shape{1}), + ::testing::Values(ov::Shape{1}), + ::testing::ValuesIn(data_precisions), + ::testing::ValuesIn(destination_precisions), + ::testing::ValuesIn(default_shift), + ::testing::Values(ov::test::utils::DEVICE_CPU)); + +const auto broadcast_fake_convert_params = + ::testing::Combine(::testing::ValuesIn(ov::test::static_shapes_to_test_representation(shapes)), + ::testing::Values(ov::Shape{2, 3, 1, 1}), + ::testing::Values(ov::Shape{2, 3, 1, 1}), + ::testing::ValuesIn(data_precisions), + ::testing::ValuesIn(destination_precisions), + ::testing::ValuesIn(default_shift), + ::testing::Values(ov::test::utils::DEVICE_CPU)); + +const auto elementwise_fake_convert_params = + ::testing::Combine(::testing::ValuesIn(ov::test::static_shapes_to_test_representation(shapes)), + ::testing::Values(ov::Shape{2, 3, 4, 5}), + ::testing::Values(ov::Shape{2, 3, 4, 5}), + ::testing::ValuesIn(data_precisions), + ::testing::ValuesIn(destination_precisions), + ::testing::ValuesIn(default_shift), + ::testing::Values(ov::test::utils::DEVICE_CPU)); + +INSTANTIATE_TEST_SUITE_P(smoke_FakeConvert_simple, + FakeConvertLayerTest, + simple_fake_convert_params, + FakeConvertLayerTest::getTestCaseName); + +INSTANTIATE_TEST_SUITE_P(smoke_FakeConvert_broadcast, + FakeConvertLayerTest, + broadcast_fake_convert_params, + FakeConvertLayerTest::getTestCaseName); + +INSTANTIATE_TEST_SUITE_P(smoke_FakeConvert_elementwise, + FakeConvertLayerTest, + elementwise_fake_convert_params, + FakeConvertLayerTest::getTestCaseName); +} // namespace diff --git a/src/tests/functional/plugin/shared/include/single_op_tests/fake_convert.hpp b/src/tests/functional/plugin/shared/include/single_op_tests/fake_convert.hpp new file mode 100644 index 00000000000000..d22809e332b0a3 --- /dev/null +++ b/src/tests/functional/plugin/shared/include/single_op_tests/fake_convert.hpp @@ -0,0 +1,16 @@ +// Copyright (C) 2024 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#pragma once + +#include "shared_test_classes/single_op/fake_convert.hpp" + +namespace ov { +namespace test { + +TEST_P(FakeConvertLayerTest, Inference) { + run(); +} +} // namespace test +} // namespace ov diff --git a/src/tests/functional/shared_test_classes/include/shared_test_classes/single_op/fake_convert.hpp b/src/tests/functional/shared_test_classes/include/shared_test_classes/single_op/fake_convert.hpp new file mode 100644 index 00000000000000..ce6ad97aba1b5d --- /dev/null +++ b/src/tests/functional/shared_test_classes/include/shared_test_classes/single_op/fake_convert.hpp @@ -0,0 +1,28 @@ +// Copyright (C) 2024 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#pragma once + +#include "shared_test_classes/base/ov_subgraph.hpp" + +namespace ov { +namespace test { +using FakeConvertParams = std::tuple, // Data shape + Shape, // Scale shape + Shape, // Shift shape + ov::element::Type, // Input precision + ov::element::Type, // Ddestination precision + bool, // Default shift + std::string>; // Device name + +class FakeConvertLayerTest : public testing::WithParamInterface, + virtual public ov::test::SubgraphBaseTest { +public: + static std::string getTestCaseName(const testing::TestParamInfo& obj); + +protected: + void SetUp() override; +}; +} // namespace test +} // namespace ov diff --git a/src/tests/functional/shared_test_classes/src/single_op/fake_convert.cpp b/src/tests/functional/shared_test_classes/src/single_op/fake_convert.cpp new file mode 100644 index 00000000000000..d207a8dabfb883 --- /dev/null +++ b/src/tests/functional/shared_test_classes/src/single_op/fake_convert.cpp @@ -0,0 +1,64 @@ +// Copyright (C) 2024 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include "shared_test_classes/single_op/fake_convert.hpp" + +#include "openvino/opsets/opset1.hpp" +#include "openvino/opsets/opset13.hpp" + +namespace ov { +namespace test { +std::string FakeConvertLayerTest::getTestCaseName(const testing::TestParamInfo& obj) { + FakeConvertParams params = obj.param; + + std::vector data_shapes; + Shape scale_shape, shift_shape; + element::Type_t data_prec, dst_prec; + bool default_shift; + std::string target_device; + std::tie(data_shapes, scale_shape, shift_shape, data_prec, dst_prec, default_shift, target_device) = params; + + std::ostringstream result; + result << "IS=("; + for (const auto& shape : data_shapes) { + result << ov::test::utils::partialShape2str({shape.first}) << "_"; + } + result << ")_TS=("; + for (const auto& shape : data_shapes) { + for (const auto& item : shape.second) { + result << ov::test::utils::vec2str(item) << "_"; + } + } + result << ")_scaleShape=" << ov::test::utils::vec2str(scale_shape) << "_"; + result << "shiftShape=" << ov::test::utils::vec2str(shift_shape) << "_"; + result << "dataPrecision=" << element::Type(data_prec) << "_"; + result << "destinationPrecision=" << element::Type(dst_prec) << "_"; + if (default_shift) + result << "defaultShift=true"; + else + result << "defaultShift=false"; + return result.str(); +} + +void FakeConvertLayerTest::SetUp() { + FakeConvertParams params = this->GetParam(); + + std::vector data_shapes; + Shape scale_shape, shift_shape; + element::Type_t data_prec, dst_prec; + bool default_shift; + std::tie(data_shapes, scale_shape, shift_shape, data_prec, dst_prec, default_shift, targetDevice) = params; + + init_input_shapes(data_shapes); + + const auto data = std::make_shared(data_prec, inputDynamicShapes.front()); + const auto scale = std::make_shared(data_prec, scale_shape); + const auto shift = std::make_shared(data_prec, shift_shape); + + const auto fake_convert = default_shift ? std::make_shared(data, scale, dst_prec) + : std::make_shared(data, scale, shift, dst_prec); + function = std::make_shared(NodeVector{fake_convert}, ParameterVector{data}); +} +} // namespace test +} // namespace ov