From b71906c6729cff9d3e9f3dff57510c8d89a4ad7a Mon Sep 17 00:00:00 2001 From: Pavel Esir Date: Thu, 7 Dec 2023 12:23:03 +0100 Subject: [PATCH] [PT FE] [ONNX FE] Partially upcast random_normal to f32 (#21400) * upcast randn to fp32 * style fix * corrected tests * add layer tests with statistics * style-fix * move make_random_normal to cmmmon * style-fix * added randn layer tests; updated CMakeLists.txt * moved to inline * fix problem with _USE_MATH_DEFINES on Win * pass NodeRegistry as reference; some other minor corrections * adjust thresholds to avoid sporadicity * move random_normal_helper and hide from public api * fix install * fix install: 2nd try * Frontend common * remove last frontend_common::static * build fix * try to fix mock1 build: 2nd attempt * try to fix mock1 build: 3rd attempt * Update src/core/tests/CMakeLists.txt * Fixed build: attemp 2 * Update src/plugins/intel_cpu/tests/unit/CMakeLists.txt * Update CMakeLists.txt --------- Co-authored-by: Ilya Lavrenov --- .../frontends/frontends.cmake | 5 +- src/cmake/openvino.cmake | 2 +- src/core/tests/frontend/CMakeLists.txt | 2 +- src/frontends/common/CMakeLists.txt | 34 ++++---- .../frontend/common/random_normal_helper.hpp | 42 ++++++++++ .../include/openvino/frontend/visibility.hpp | 6 +- .../common/src/random_normal_helper.cpp | 77 +++++++++++++++++++ src/frontends/onnx/frontend/CMakeLists.txt | 4 +- .../onnx/frontend/src/op/random_normal.cpp | 12 +-- .../frontend/src/op/random_normal_like.cpp | 10 ++- .../onnx/frontend/src/utils/random_normal.cpp | 63 --------------- .../onnx/frontend/src/utils/random_normal.hpp | 29 ------- src/frontends/onnx/tests/onnx_import.in.cpp | 4 +- src/frontends/pytorch/src/CMakeLists.txt | 2 +- src/frontends/pytorch/src/op/rand.cpp | 41 ++-------- .../test_builtin_extensions/CMakeLists.txt | 2 +- src/inference/CMakeLists.txt | 2 - .../intel_cpu/tests/unit/CMakeLists.txt | 4 +- tests/layer_tests/pytorch_tests/test_rand.py | 54 +++++++++++++ 19 files changed, 229 insertions(+), 166 deletions(-) create mode 100644 src/frontends/common/dev_api/openvino/frontend/common/random_normal_helper.hpp create mode 100644 src/frontends/common/src/random_normal_helper.cpp delete mode 100644 src/frontends/onnx/frontend/src/utils/random_normal.cpp delete mode 100644 src/frontends/onnx/frontend/src/utils/random_normal.hpp diff --git a/cmake/developer_package/frontends/frontends.cmake b/cmake/developer_package/frontends/frontends.cmake index 1a037c5ab72309..fada615c843ec9 100644 --- a/cmake/developer_package/frontends/frontends.cmake +++ b/cmake/developer_package/frontends/frontends.cmake @@ -57,10 +57,10 @@ function(ov_generate_frontends_hpp) # for some reason dependency on source files does not work # so, we have to use explicit target and make it dependency for frontend_common add_custom_target(_ov_frontends_hpp DEPENDS ${ov_frontends_hpp}) - add_dependencies(frontend_common_obj _ov_frontends_hpp) + add_dependencies(openvino_frontend_common_obj _ov_frontends_hpp) # add dependency for object files - get_target_property(sources frontend_common_obj SOURCES) + get_target_property(sources openvino_frontend_common_obj SOURCES) foreach(source IN LISTS sources) if("${source}" MATCHES "\\$\\") # object library @@ -220,6 +220,7 @@ macro(ov_add_frontend) PUBLIC $ PRIVATE + $ ${frontend_root_dir}/src ${CMAKE_CURRENT_BINARY_DIR}) diff --git a/src/cmake/openvino.cmake b/src/cmake/openvino.cmake index ad73269d475748..a359549d9c0821 100644 --- a/src/cmake/openvino.cmake +++ b/src/cmake/openvino.cmake @@ -21,7 +21,7 @@ endif() add_library(${TARGET_NAME} $ $ - $ + $ $ $ $ diff --git a/src/core/tests/frontend/CMakeLists.txt b/src/core/tests/frontend/CMakeLists.txt index dd096fed759a94..a03ed97cac9ca9 100644 --- a/src/core/tests/frontend/CMakeLists.txt +++ b/src/core/tests/frontend/CMakeLists.txt @@ -12,7 +12,7 @@ target_compile_definitions(${MOCK1_FE_NAME} PRIVATE "-DMOCK_VARIANT=\"1\"") target_include_directories(${MOCK1_FE_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) -target_link_libraries(${MOCK1_FE_NAME} PRIVATE frontend_common) +target_link_libraries(${MOCK1_FE_NAME} PRIVATE openvino::frontend::common) add_dependencies(ov_core_unit_tests ${MOCK1_FE_NAME}) ov_add_clang_format_target(${MOCK1_FE_NAME}_clang FOR_TARGETS ${MOCK1_FE_NAME}) diff --git a/src/frontends/common/CMakeLists.txt b/src/frontends/common/CMakeLists.txt index 4fd41e6f4d3601..53f52bdc258af7 100644 --- a/src/frontends/common/CMakeLists.txt +++ b/src/frontends/common/CMakeLists.txt @@ -2,18 +2,33 @@ # SPDX-License-Identifier: Apache-2.0 # -set(TARGET_NAME "frontend_common") +set(TARGET_NAME "openvino_frontend_common") + +set(FRONTEND_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/include) +set(FRONTEND_DEV_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/dev_api) file(GLOB_RECURSE LIBRARY_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp) file(GLOB_RECURSE LIBRARY_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/src/*.hpp) file(GLOB_RECURSE LIBRARY_PUBLIC_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/include/*.hpp) -set(FRONTEND_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/include) - source_group("src" FILES ${LIBRARY_SRC}) source_group("include" FILES ${LIBRARY_HEADERS}) source_group("public include" FILES ${LIBRARY_PUBLIC_HEADERS}) +# create frontend common library + +add_library(${TARGET_NAME} INTERFACE) + +target_include_directories(${TARGET_NAME} INTERFACE + $ + $) + +target_link_libraries(${TARGET_NAME} INTERFACE openvino::runtime) + +add_library(openvino::frontend::common ALIAS ${TARGET_NAME}) + +ov_install_static_lib(${TARGET_NAME} ${OV_CPACK_COMP_CORE}) + # create library add_library(${TARGET_NAME}_obj OBJECT ${LIBRARY_SRC} ${LIBRARY_HEADERS} ${LIBRARY_PUBLIC_HEADERS}) @@ -23,7 +38,7 @@ target_include_directories(${TARGET_NAME}_obj $ PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src - $ + $ # for ov_frontends.hpp in static build ${CMAKE_CURRENT_BINARY_DIR}/src) @@ -60,17 +75,6 @@ ov_ncc_naming_style(FOR_TARGET ${TARGET_NAME}_obj ADDITIONAL_INCLUDE_DIRECTORIES $) -# INTERFACE library for BW compatibility - -add_library(${TARGET_NAME} INTERFACE) -target_link_libraries(${TARGET_NAME} INTERFACE openvino::runtime) -target_include_directories(${TARGET_NAME} INTERFACE $ - $>) - -add_library(ngraph::${TARGET_NAME} ALIAS ${TARGET_NAME}) -add_library(openvino::frontend::common ALIAS ${TARGET_NAME}) -add_library(${TARGET_NAME}::static ALIAS ${TARGET_NAME}) - # Installation rules header files install(DIRECTORY ${FRONTEND_INCLUDE_DIR}/openvino diff --git a/src/frontends/common/dev_api/openvino/frontend/common/random_normal_helper.hpp b/src/frontends/common/dev_api/openvino/frontend/common/random_normal_helper.hpp new file mode 100644 index 00000000000000..e88cf62354a148 --- /dev/null +++ b/src/frontends/common/dev_api/openvino/frontend/common/random_normal_helper.hpp @@ -0,0 +1,42 @@ +// Copyright (C) 2018-2023 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#pragma once + +#include "ngraph/output_vector.hpp" +#include "openvino/frontend/visibility.hpp" +#include "openvino/pass/graph_rewrite.hpp" + +namespace ov { +namespace frontend { + +/// \brief Creates a random normal tensor with the given shape and type. +/// \details Uses Box-Mueller algorithm to generate random numbers from a Gauassian distribution +/// \param sizes Shape of the output tensor +/// \param target_type Type of the output tensor +/// \param mean Mean of the distribution +/// \param scale Standard deviation of the distribution +/// \param seed Seed for the random number generator +FRONTEND_API OutputVector make_random_normal(pass::NodeRegistry& registry, + const Output& sizes, + element::Type target_type, + const Output& mean, + const Output& scale, + float seed); + +/// \brief Creates a random normal tensor with the given shape and type. +/// \details Uses Box-Mueller algorithm to generate random numbers from a Gauassian distribution +/// \param sizes Shape of the output tensor +/// \param target_type Type of the output tensor +/// \param mean Mean of the distribution +/// \param scale Standard deviation of the distribution +/// \param seed Seed for the random number generator +FRONTEND_API std::pair make_random_normal(const Output& sizes, + element::Type target_type, + const Output& mean, + const Output& scale, + float seed); + +} // namespace frontend +} // namespace ov diff --git a/src/frontends/common/include/openvino/frontend/visibility.hpp b/src/frontends/common/include/openvino/frontend/visibility.hpp index 4e07f3cedbbc17..ddc2d7eb6898e7 100644 --- a/src/frontends/common/include/openvino/frontend/visibility.hpp +++ b/src/frontends/common/include/openvino/frontend/visibility.hpp @@ -9,7 +9,7 @@ // Increment each time when FrontEnd/InputModel/Place interface is changed #define OV_FRONTEND_API_VERSION 1 -#if defined(USE_STATIC_FRONTEND_COMMON) || defined(OPENVINO_STATIC_LIBRARY) +#if defined(OPENVINO_STATIC_LIBRARY) # define FRONTEND_API # define FRONTEND_C_API #else @@ -20,5 +20,5 @@ # else # define FRONTEND_API OPENVINO_CORE_IMPORTS # define FRONTEND_C_API OPENVINO_EXTERN_C OPENVINO_CORE_IMPORTS -# endif // frontend_common_EXPORTS -#endif // USE_STATIC_FRONTEND_COMMON || OPENVINO_STATIC_LIBRARY +# endif // openvino_frontend_common_EXPORTS +#endif // OPENVINO_STATIC_LIBRARY diff --git a/src/frontends/common/src/random_normal_helper.cpp b/src/frontends/common/src/random_normal_helper.cpp new file mode 100644 index 00000000000000..5e789a9f72f2f5 --- /dev/null +++ b/src/frontends/common/src/random_normal_helper.cpp @@ -0,0 +1,77 @@ +// Copyright (C) 2018-2023 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include "openvino/frontend/common/random_normal_helper.hpp" + +#include "ngraph/output_vector.hpp" +#include "openvino/op/constant.hpp" +#include "openvino/opsets/opset12.hpp" +#include "openvino/pass/graph_rewrite.hpp" +#include "transformations/rt_info/disable_fp16_compression.hpp" +#define _USE_MATH_DEFINES +#include + +namespace ov { +namespace frontend { + +OutputVector make_random_normal(pass::NodeRegistry& registry, + const Output& sizes, + element::Type target_type, + const Output& mean, + const Output& scale, + float seed) { + // We start by generating two random series from a uniform distribution + const uint64_t global_seed = 0; + + // ONNX specifies the seed as a float, but OpenVINO uses uint64_t + const auto op_seed = static_cast(seed * 1000); + + // We need to use two op_seeds to make sure we get different results for two RandomUniform series + // But we also have to keep original logic and pass "0" (auto-generated seed) to RandomUniform + const uint64_t seed_1 = op_seed; + const uint64_t seed_2 = (op_seed == 0 ? op_seed : op_seed + 10000); + + auto min_val = registry.make(target_type, Shape{1}, std::numeric_limits::min()); + auto max_val = registry.make(target_type, Shape{1}, 1); + + auto uniform_1 = registry.make(sizes, min_val, max_val, target_type, global_seed, seed_1); + auto uniform_2 = registry.make(sizes, min_val, max_val, target_type, global_seed, seed_2); + + // Compute Box–Muller transform + // random_normal = scale * sqrt(-2.0 * log(uniform_1)) * cos(2.0 * pi * uniform_2) + mean + auto pi = registry.make(target_type, Shape{1}, M_PI); + auto minus_two = registry.make(target_type, Shape{1}, -2.0); + auto two = registry.make(target_type, Shape{1}, 2.0); + + auto log = registry.make(uniform_1); + auto multiply_minus_two_log = registry.make(log, minus_two); + auto sqrt = registry.make(multiply_minus_two_log); + + auto multiply_2pi = registry.make(two, pi); + auto multiply_2pi_uniform_2 = registry.make(multiply_2pi, uniform_2); + auto cos = registry.make(multiply_2pi_uniform_2); + + auto sqrt_x_cos = registry.make(sqrt, cos); + auto product = registry.make(scale, sqrt_x_cos); + auto sum = registry.make(product, mean); + + // if we don't disable down-casting then log(float32_min) gives -inf + disable_fp16_compression(uniform_1); + disable_fp16_compression(log); + + return {sum}; +} + +std::pair make_random_normal(const Output& sizes, + element::Type target_type, + const Output& mean, + const Output& scale, + float seed) { + pass::NodeRegistry registry; + OutputVector res = make_random_normal(registry, sizes, target_type, mean, scale, seed); + return std::make_pair(res, registry); +} + +} // namespace frontend +} // namespace ov diff --git a/src/frontends/onnx/frontend/CMakeLists.txt b/src/frontends/onnx/frontend/CMakeLists.txt index d4681b54b08f93..5c5eba49260e89 100644 --- a/src/frontends/onnx/frontend/CMakeLists.txt +++ b/src/frontends/onnx/frontend/CMakeLists.txt @@ -16,9 +16,7 @@ target_compile_definitions(${TARGET_NAME} PRIVATE ONNX_OPSET_VERSION=${ONNX_OPSE ov_ncc_naming_style(FOR_TARGET ${TARGET_NAME} SOURCE_DIRECTORIES "${${TARGET_NAME}_INCLUDE_DIR}" DEFINITIONS - $ - ADDITIONAL_INCLUDE_DIRECTORIES - $) + $) install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/onnx_import DESTINATION ${FRONTEND_INSTALL_INCLUDE}/ngraph/frontend diff --git a/src/frontends/onnx/frontend/src/op/random_normal.cpp b/src/frontends/onnx/frontend/src/op/random_normal.cpp index 35978df4dbf2ad..5b8ccb80e8e380 100644 --- a/src/frontends/onnx/frontend/src/op/random_normal.cpp +++ b/src/frontends/onnx/frontend/src/op/random_normal.cpp @@ -2,10 +2,10 @@ // SPDX-License-Identifier: Apache-2.0 // -#include "utils/random_normal.hpp" - #include "exceptions.hpp" #include "ngraph/shape.hpp" +#include "openvino/frontend/common/random_normal_helper.hpp" +#include "openvino/op/constant.hpp" #include "utils/common.hpp" OPENVINO_SUPPRESS_DEPRECATED_START @@ -23,11 +23,13 @@ OutputVector random_normal(const Node& node) { const auto mean = node.get_attribute_value("mean", 0.0f); const auto scale = node.get_attribute_value("scale", 1.0f); - const auto seed = node.get_attribute_value("seed", 0); + auto scale_node = ov::op::v0::Constant::create(target_type, Shape{1}, {scale}); + auto mean_node = ov::op::v0::Constant::create(target_type, Shape{1}, {mean}); + const auto seed = node.get_attribute_value("seed", 0); const auto shape = node.get_attribute_as_constant>("shape"); - - return detail::make_random_normal(shape, target_type, mean, scale, seed); + auto res = ov::frontend::make_random_normal(shape, target_type, mean_node, scale_node, seed); + return res.first; } } // namespace set_1 diff --git a/src/frontends/onnx/frontend/src/op/random_normal_like.cpp b/src/frontends/onnx/frontend/src/op/random_normal_like.cpp index 8d77d8055db16b..0df669b4ada2aa 100644 --- a/src/frontends/onnx/frontend/src/op/random_normal_like.cpp +++ b/src/frontends/onnx/frontend/src/op/random_normal_like.cpp @@ -4,8 +4,8 @@ #include "ngraph/shape.hpp" #include "op/random_uniform_like.hpp" +#include "openvino/frontend/common/random_normal_helper.hpp" #include "utils/common.hpp" -#include "utils/random_normal.hpp" OPENVINO_SUPPRESS_DEPRECATED_START namespace ngraph { @@ -25,11 +25,15 @@ OutputVector random_normal_like(const Node& node) { } const auto shape = std::make_shared(input); + const auto seed = node.get_attribute_value("seed", 0.0f); + const auto mean = node.get_attribute_value("mean", 0.0f); const auto scale = node.get_attribute_value("scale", 1.0f); - const auto seed = node.get_attribute_value("seed", 0.0f); + auto scale_node = ov::op::v0::Constant::create(target_type, Shape{1}, {scale}); + auto mean_node = ov::op::v0::Constant::create(target_type, Shape{1}, {mean}); - return detail::make_random_normal(shape, target_type, mean, scale, seed); + auto res = ov::frontend::make_random_normal(shape, target_type, mean_node, scale_node, seed); + return res.first; } } // namespace set_1 diff --git a/src/frontends/onnx/frontend/src/utils/random_normal.cpp b/src/frontends/onnx/frontend/src/utils/random_normal.cpp deleted file mode 100644 index 0905be6ddb1f8b..00000000000000 --- a/src/frontends/onnx/frontend/src/utils/random_normal.cpp +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright (C) 2018-2023 Intel Corporation -// SPDX-License-Identifier: Apache-2.0 -// - -#include "random_normal.hpp" - -#include "default_opset.hpp" -#include "ngraph/opsets/opset8.hpp" - -namespace ngraph { -namespace onnx_import { -namespace detail { - -OutputVector make_random_normal(const Output& shape, - element::Type target_type, - float mean, - float scale, - float seed) { - // We start by generating two random series from a uniform distribution - const uint64_t global_seed = 0; - - // ONNX specifies the seed as a float, but OpenVINO uses uint64_t - const auto op_seed = static_cast(seed * 1000); - - // We need to use two op_seeds to make sure we get different results for two RandomUniform series - // But we also have to keep original logic and pass "0" (auto-generated seed) to RandomUniform - const uint64_t seed_1 = op_seed; - const uint64_t seed_2 = (op_seed == 0 ? op_seed : op_seed + 10000); - - const auto min_val = default_opset::Constant::create(target_type, Shape{1}, {0}); - const auto max_val = default_opset::Constant::create(target_type, Shape{1}, {1}); - - const auto uniform_1 = - std::make_shared(shape, min_val, max_val, target_type, global_seed, seed_1); - const auto uniform_2 = - std::make_shared(shape, min_val, max_val, target_type, global_seed, seed_2); - - // Compute Box–Muller transform - // random_normal = scale * ng.sqrt(-2.0 * ng.log(uniform_1)) * ng.cos(2.0 * np.pi * uniform_2) + mean - const auto pi = default_opset::Constant::create(target_type, Shape{1}, {3.141592653589793}); - const auto minus_two = default_opset::Constant::create(target_type, Shape{1}, {-2.0}); - const auto two = default_opset::Constant::create(target_type, Shape{1}, {2.0}); - - const auto log = std::make_shared(uniform_1); - const auto multiply_minus_two_log = std::make_shared(log, minus_two); - const auto sqrt = std::make_shared(multiply_minus_two_log); - - const auto multiply_two_pi = std::make_shared(uniform_2, pi); - const auto multiply_two_pi_uniform_2 = std::make_shared(multiply_two_pi, uniform_2); - auto const cos = std::make_shared(multiply_two_pi_uniform_2); - - auto const scale_const = default_opset::Constant::create(target_type, Shape{1}, {scale}); - auto const mean_const = default_opset::Constant::create(target_type, Shape{1}, {mean}); - auto const product = - std::make_shared(scale_const, std::make_shared(sqrt, cos)); - auto const sum = std::make_shared(product, mean_const); - - return {sum}; -} - -} // namespace detail -} // namespace onnx_import -} // namespace ngraph diff --git a/src/frontends/onnx/frontend/src/utils/random_normal.hpp b/src/frontends/onnx/frontend/src/utils/random_normal.hpp deleted file mode 100644 index f581b2a01b393a..00000000000000 --- a/src/frontends/onnx/frontend/src/utils/random_normal.hpp +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright (C) 2018-2023 Intel Corporation -// SPDX-License-Identifier: Apache-2.0 -// - -#pragma once - -#include "ngraph/op/reshape.hpp" -#include "ngraph/output_vector.hpp" - -namespace ngraph { -namespace onnx_import { -namespace detail { - -/// \brief Creates a random normal tensor with the given shape and type. -/// \details Uses Box-Mueller algorithm to generate random numbers from a Gauassian distribution -/// \param shape Shape of the output tensor -/// \param type Type of the output tensor -/// \param mean Mean of the distribution -/// \param scale Standard deviation of the distribution -/// \param seed Seed for the random number generator -OutputVector make_random_normal(const Output& shape, - element::Type type, - float mean, - float scale, - float seed); - -} // namespace detail -} // namespace onnx_import -} // namespace ngraph diff --git a/src/frontends/onnx/tests/onnx_import.in.cpp b/src/frontends/onnx/tests/onnx_import.in.cpp index 10c8346c3dd833..dc302f500c4124 100644 --- a/src/frontends/onnx/tests/onnx_import.in.cpp +++ b/src/frontends/onnx/tests/onnx_import.in.cpp @@ -5366,7 +5366,7 @@ OPENVINO_TEST(${BACKEND_NAME}, onnx_model_random_normal) { file_util::path_join(ov::test::utils::getExecutableDirectory(), SERIALIZED_ZOO, "onnx/random_normal.onnx")); auto test_case = ov::test::TestCase(function, s_device); - test_case.add_expected_output(Shape{2, 2}, {13.459274f, 41.75028f, -19.311913f, 131.79282f}); + test_case.add_expected_output(Shape{2, 2}, {83.052017f, 55.496368f, 119.31188f, -3.6946249f}); test_case.run(); } @@ -5377,7 +5377,7 @@ OPENVINO_TEST(${BACKEND_NAME}, onnx_model_random_normal_like) { auto test_case = ov::test::TestCase(function, s_device); test_case.add_input(Shape{2, 2}, {0, 0, 0, 0}); - test_case.add_expected_output(Shape{2, 2}, {13.459274f, 41.75028f, -19.311913f, 131.79282f}); + test_case.add_expected_output(Shape{2, 2}, {83.052017f, 55.496368f, 119.31188f, -3.6946249f}); test_case.run(); } diff --git a/src/frontends/pytorch/src/CMakeLists.txt b/src/frontends/pytorch/src/CMakeLists.txt index f51dee59b761db..814d820b5c17aa 100644 --- a/src/frontends/pytorch/src/CMakeLists.txt +++ b/src/frontends/pytorch/src/CMakeLists.txt @@ -6,4 +6,4 @@ ov_add_frontend(NAME pytorch LINKABLE_FRONTEND SHUTDOWN_PROTOBUF FILEDESCRIPTION "FrontEnd to load and convert TorchScript models from PyTorch" - LINK_LIBRARIES openvino::util openvino::core::dev) \ No newline at end of file + LINK_LIBRARIES openvino::util openvino::core::dev) diff --git a/src/frontends/pytorch/src/op/rand.cpp b/src/frontends/pytorch/src/op/rand.cpp index 677a3e86a52ac0..d04b3bbd2780b7 100644 --- a/src/frontends/pytorch/src/op/rand.cpp +++ b/src/frontends/pytorch/src/op/rand.cpp @@ -3,6 +3,7 @@ // #include +#include "openvino/frontend/common/random_normal_helper.hpp" #include "openvino/frontend/pytorch/node_context.hpp" #include "openvino/op/add.hpp" #include "openvino/op/constant.hpp" @@ -15,6 +16,7 @@ #include "openvino/op/shape_of.hpp" #include "openvino/op/sqrt.hpp" #include "pt_framework_node.hpp" +#include "transformations/rt_info/disable_fp16_compression.hpp" #include "utils.hpp" namespace ov { @@ -32,40 +34,13 @@ OutputVector make_random_normal(const NodeContext& context, const Output& mean_const) { std::random_device rd; std::mt19937 gen(rd()); - std::uniform_int_distribution distrib(0, 9999); + std::uniform_real_distribution distrib(0.0f, 9999.0f); + float seed = distrib(gen); - const uint64_t global_seed = 0; - - const uint64_t seed_1 = distrib(gen); - const uint64_t seed_2 = distrib(gen); - - auto min_val = context.mark_node(v0::Constant::create(target_type, Shape{1}, {std::numeric_limits::min()})); - auto max_val = context.mark_node(v0::Constant::create(target_type, Shape{1}, {1})); - - auto uniform_1 = context.mark_node( - std::make_shared(sizes, min_val, max_val, target_type, global_seed, seed_1)); - auto uniform_2 = context.mark_node( - std::make_shared(sizes, min_val, max_val, target_type, global_seed, seed_2)); - - // Compute Box–Muller transform - // random_normal = scale * ng.sqrt(-2.0 * ng.log(uniform_1)) * ng.cos(2.0 * np.pi * uniform_2) + mean - auto pi = context.mark_node(v0::Constant::create(target_type, Shape{1}, {3.141592653589793})); - auto minus_two = context.mark_node(v0::Constant::create(target_type, Shape{1}, {-2.0})); - auto two = context.mark_node(v0::Constant::create(target_type, Shape{1}, {2.0})); - - auto log = context.mark_node(std::make_shared(uniform_1)); - auto multiply_minus_two_log = context.mark_node(std::make_shared(log, minus_two)); - auto sqrt = context.mark_node(std::make_shared(multiply_minus_two_log)); - - auto multiply_two_pi = context.mark_node(std::make_shared(uniform_2, pi)); - auto multiply_two_pi_uniform_2 = context.mark_node(std::make_shared(multiply_two_pi, uniform_2)); - auto cos = context.mark_node(std::make_shared(multiply_two_pi_uniform_2)); - - auto sqrt_x_cos = context.mark_node(std::make_shared(sqrt, cos)); - auto product = context.mark_node(std::make_shared(scale_const, sqrt_x_cos)); - auto sum = context.mark_node(std::make_shared(product, mean_const)); - - return {sum}; + pass::NodeRegistry registry; + auto res = ov::frontend::make_random_normal(registry, sizes, target_type, mean_const, scale_const, seed); + context.mark_nodes(registry.get()); + return res; } }; // namespace diff --git a/src/frontends/tests/frontend/shared/test_builtin_extensions/CMakeLists.txt b/src/frontends/tests/frontend/shared/test_builtin_extensions/CMakeLists.txt index 959834bbe0d15c..cc541e17b9017a 100644 --- a/src/frontends/tests/frontend/shared/test_builtin_extensions/CMakeLists.txt +++ b/src/frontends/tests/frontend/shared/test_builtin_extensions/CMakeLists.txt @@ -13,7 +13,7 @@ endif() file(GLOB LIBRARY_SRC ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp) file(GLOB LIBRARY_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/*.hpp) -set(DEPENDENCIES openvino::runtime::dev openvino::frontend::common) +set(DEPENDENCIES openvino::runtime::dev) if (ENABLE_OV_ONNX_FRONTEND) list(APPEND DEPENDENCIES openvino::frontend::onnx) diff --git a/src/inference/CMakeLists.txt b/src/inference/CMakeLists.txt index 11ad85b3740d6a..80b7f0a2974db9 100644 --- a/src/inference/CMakeLists.txt +++ b/src/inference/CMakeLists.txt @@ -137,13 +137,11 @@ target_compile_definitions(${TARGET_NAME}_obj PRIVATE IMPLEMENT_INFERENCE_ENGINE_API $<$:PROXY_PLUGIN_ENABLED> $ - $ $) target_include_directories(${TARGET_NAME}_obj SYSTEM PRIVATE $ $ - $ $<$:$> $<$:$>) diff --git a/src/plugins/intel_cpu/tests/unit/CMakeLists.txt b/src/plugins/intel_cpu/tests/unit/CMakeLists.txt index be9c4a1c5da408..6bb37da132021a 100644 --- a/src/plugins/intel_cpu/tests/unit/CMakeLists.txt +++ b/src/plugins/intel_cpu/tests/unit/CMakeLists.txt @@ -53,8 +53,6 @@ ov_add_test_target( gtest_main gmock dnnl - inference_engine_transformations - inference_engine_lp_transformations openvino::shape_inference inference_engine_s unit_test_utils @@ -62,6 +60,8 @@ ov_add_test_target( ov_snippets_models snippets_test_utils ${MLAS_LIBRARY} + inference_engine_transformations + inference_engine_lp_transformations ADD_CPPLINT LABELS OV UNIT CPU diff --git a/tests/layer_tests/pytorch_tests/test_rand.py b/tests/layer_tests/pytorch_tests/test_rand.py index 75677992fb6da2..08f6201cdb323c 100644 --- a/tests/layer_tests/pytorch_tests/test_rand.py +++ b/tests/layer_tests/pytorch_tests/test_rand.py @@ -88,3 +88,57 @@ def test_inplace_normal(self, model, inputs, ie_device, precision, ir_version): self.inputs = inputs self._test(model, None, "aten::normal", ie_device, precision, ir_version, custom_eps=1e30) + + +class TestStatistics(): + class aten_normal(torch.nn.Module): + def forward(self, mean, std): + return torch.normal(mean, std) + + class aten_randn(torch.nn.Module): + def forward(self, size): + return torch.randn(*size) + + @pytest.mark.nightly + @pytest.mark.precommit + @pytest.mark.parametrize("fw_model,inputs", [ + (aten_normal(), (0, 1, (1000000,))), + (aten_normal(), (0, 1, (10000, 100))), + (aten_normal(), (0, 3, (100000, 100))), + (aten_normal(), (1, 6, (100000, 100))), + (aten_normal(), (-20, 2, (10000, 100))), + (aten_normal(), (-20, 100, (10000, 100))), + + (aten_randn(), (0, 1, (1000000,))), + (aten_randn(), (0, 1, (10000, 100))), + (aten_randn(), (0, 1, (100000, 100))), + ]) + def test_normal_statistics(self, fw_model, inputs, ie_device, precision): + import numpy.testing as npt + import numpy as np + import openvino as ov + mean_scalar, std_scalar, size = inputs + mean = torch.full(size, mean_scalar, dtype=torch.float32) + std = torch.full(size, std_scalar, dtype=torch.float32) + + if isinstance(fw_model, self.aten_randn): + example_input = (torch.tensor(size), ) + input_size = [len(size)] + else: + example_input = (mean, std) + input_size = [size, size] + + ov_model = ov.convert_model(input_model=fw_model, example_input=example_input, input=input_size) + if ie_device == 'GPU' and precision == 'FP32': + config = {'INFERENCE_PRECISION_HINT': 'f32'} + else: + config = {} + compiled_model = ov.Core().compile_model(ov_model, ie_device, config) + + fw_res = fw_model(*example_input) + ov_res = compiled_model(example_input)[0] + + x_min, x_max = mean_scalar - 2 * std_scalar, mean_scalar + 2 * std_scalar + hist_fw, _ = np.histogram(fw_res.numpy(), bins=100, range=(x_min, x_max)) + hist_ov, _ = np.histogram(ov_res, bins=100, range=(x_min, x_max)) + npt.assert_allclose(hist_fw, hist_ov, atol=0.2, rtol=0.2)