[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 <ilya.lavrenov@intel.com>
This commit is contained in:
parent
c61de14c66
commit
b71906c672
|
|
@ -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 "\\$\\<TARGET_OBJECTS\\:([A-Za-z0-9_]*)\\>")
|
||||
# object library
|
||||
|
|
@ -220,6 +220,7 @@ macro(ov_add_frontend)
|
|||
PUBLIC
|
||||
$<BUILD_INTERFACE:${${TARGET_NAME}_INCLUDE_DIR}>
|
||||
PRIVATE
|
||||
$<TARGET_PROPERTY:openvino::frontend::common,INTERFACE_INCLUDE_DIRECTORIES>
|
||||
${frontend_root_dir}/src
|
||||
${CMAKE_CURRENT_BINARY_DIR})
|
||||
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ endif()
|
|||
add_library(${TARGET_NAME}
|
||||
$<TARGET_OBJECTS:ngraph_obj>
|
||||
$<TARGET_OBJECTS:ngraph_obj_version>
|
||||
$<TARGET_OBJECTS:frontend_common_obj>
|
||||
$<TARGET_OBJECTS:openvino_frontend_common_obj>
|
||||
$<TARGET_OBJECTS:inference_engine_obj>
|
||||
$<TARGET_OBJECTS:inference_engine_obj_version>
|
||||
$<TARGET_OBJECTS:inference_engine_transformations_obj>
|
||||
|
|
|
|||
|
|
@ -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})
|
||||
|
|
|
|||
|
|
@ -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
|
||||
$<BUILD_INTERFACE:${FRONTEND_DEV_INCLUDE_DIR}>
|
||||
$<BUILD_INTERFACE:${FRONTEND_INCLUDE_DIR}>)
|
||||
|
||||
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
|
|||
$<BUILD_INTERFACE:${FRONTEND_INCLUDE_DIR}>
|
||||
PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src
|
||||
$<TARGET_PROPERTY:ngraph,INTERFACE_INCLUDE_DIRECTORIES>
|
||||
$<TARGET_PROPERTY:openvino::frontend::common,INTERFACE_INCLUDE_DIRECTORIES>
|
||||
# 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
|
||||
$<TARGET_PROPERTY:ngraph,INTERFACE_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 $<BUILD_INTERFACE:${FRONTEND_INCLUDE_DIR}>
|
||||
$<BUILD_INTERFACE:$<TARGET_PROPERTY:ngraph,INTERFACE_INCLUDE_DIRECTORIES>>)
|
||||
|
||||
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
|
||||
|
|
|
|||
|
|
@ -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<Node>& sizes,
|
||||
element::Type target_type,
|
||||
const Output<Node>& mean,
|
||||
const Output<Node>& 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<OutputVector, pass::NodeRegistry> make_random_normal(const Output<Node>& sizes,
|
||||
element::Type target_type,
|
||||
const Output<Node>& mean,
|
||||
const Output<Node>& scale,
|
||||
float seed);
|
||||
|
||||
} // namespace frontend
|
||||
} // namespace ov
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 <math.h>
|
||||
|
||||
namespace ov {
|
||||
namespace frontend {
|
||||
|
||||
OutputVector make_random_normal(pass::NodeRegistry& registry,
|
||||
const Output<Node>& sizes,
|
||||
element::Type target_type,
|
||||
const Output<Node>& mean,
|
||||
const Output<Node>& 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<uint64_t>(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<op::v0::Constant>(target_type, Shape{1}, std::numeric_limits<float>::min());
|
||||
auto max_val = registry.make<op::v0::Constant>(target_type, Shape{1}, 1);
|
||||
|
||||
auto uniform_1 = registry.make<op::v8::RandomUniform>(sizes, min_val, max_val, target_type, global_seed, seed_1);
|
||||
auto uniform_2 = registry.make<op::v8::RandomUniform>(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<op::v0::Constant>(target_type, Shape{1}, M_PI);
|
||||
auto minus_two = registry.make<op::v0::Constant>(target_type, Shape{1}, -2.0);
|
||||
auto two = registry.make<op::v0::Constant>(target_type, Shape{1}, 2.0);
|
||||
|
||||
auto log = registry.make<op::v0::Log>(uniform_1);
|
||||
auto multiply_minus_two_log = registry.make<op::v1::Multiply>(log, minus_two);
|
||||
auto sqrt = registry.make<op::v0::Sqrt>(multiply_minus_two_log);
|
||||
|
||||
auto multiply_2pi = registry.make<op::v1::Multiply>(two, pi);
|
||||
auto multiply_2pi_uniform_2 = registry.make<op::v1::Multiply>(multiply_2pi, uniform_2);
|
||||
auto cos = registry.make<op::v0::Cos>(multiply_2pi_uniform_2);
|
||||
|
||||
auto sqrt_x_cos = registry.make<op::v1::Multiply>(sqrt, cos);
|
||||
auto product = registry.make<op::v1::Multiply>(scale, sqrt_x_cos);
|
||||
auto sum = registry.make<op::v1::Add>(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<OutputVector, pass::NodeRegistry> make_random_normal(const Output<Node>& sizes,
|
||||
element::Type target_type,
|
||||
const Output<Node>& mean,
|
||||
const Output<Node>& 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
|
||||
|
|
@ -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
|
||||
$<TARGET_PROPERTY:onnx,INTERFACE_COMPILE_DEFINITIONS>
|
||||
ADDITIONAL_INCLUDE_DIRECTORIES
|
||||
$<TARGET_PROPERTY:frontend_common::static,INTERFACE_INCLUDE_DIRECTORIES>)
|
||||
$<TARGET_PROPERTY:onnx,INTERFACE_COMPILE_DEFINITIONS>)
|
||||
|
||||
install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/onnx_import
|
||||
DESTINATION ${FRONTEND_INSTALL_INCLUDE}/ngraph/frontend
|
||||
|
|
|
|||
|
|
@ -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<float>("mean", 0.0f);
|
||||
const auto scale = node.get_attribute_value<float>("scale", 1.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});
|
||||
|
||||
const auto seed = node.get_attribute_value<float>("seed", 0);
|
||||
|
||||
const auto shape = node.get_attribute_as_constant<std::vector<int64_t>>("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
|
||||
|
|
|
|||
|
|
@ -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<default_opset::ShapeOf>(input);
|
||||
const auto mean = node.get_attribute_value<float>("mean", 0.0f);
|
||||
const auto scale = node.get_attribute_value<float>("scale", 1.0f);
|
||||
const auto seed = node.get_attribute_value<float>("seed", 0.0f);
|
||||
|
||||
return detail::make_random_normal(shape, target_type, mean, scale, seed);
|
||||
const auto mean = node.get_attribute_value<float>("mean", 0.0f);
|
||||
const auto scale = node.get_attribute_value<float>("scale", 1.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});
|
||||
|
||||
auto res = ov::frontend::make_random_normal(shape, target_type, mean_node, scale_node, seed);
|
||||
return res.first;
|
||||
}
|
||||
|
||||
} // namespace set_1
|
||||
|
|
|
|||
|
|
@ -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<ngraph::Node>& 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<uint64_t>(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<ngraph::opset8::RandomUniform>(shape, min_val, max_val, target_type, global_seed, seed_1);
|
||||
const auto uniform_2 =
|
||||
std::make_shared<ngraph::opset8::RandomUniform>(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<default_opset::Log>(uniform_1);
|
||||
const auto multiply_minus_two_log = std::make_shared<default_opset::Multiply>(log, minus_two);
|
||||
const auto sqrt = std::make_shared<default_opset::Sqrt>(multiply_minus_two_log);
|
||||
|
||||
const auto multiply_two_pi = std::make_shared<default_opset::Multiply>(uniform_2, pi);
|
||||
const auto multiply_two_pi_uniform_2 = std::make_shared<default_opset::Multiply>(multiply_two_pi, uniform_2);
|
||||
auto const cos = std::make_shared<default_opset::Cos>(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<default_opset::Multiply>(scale_const, std::make_shared<default_opset::Multiply>(sqrt, cos));
|
||||
auto const sum = std::make_shared<default_opset::Add>(product, mean_const);
|
||||
|
||||
return {sum};
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
} // namespace onnx_import
|
||||
} // namespace ngraph
|
||||
|
|
@ -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<ngraph::Node>& shape,
|
||||
element::Type type,
|
||||
float mean,
|
||||
float scale,
|
||||
float seed);
|
||||
|
||||
} // namespace detail
|
||||
} // namespace onnx_import
|
||||
} // namespace ngraph
|
||||
|
|
@ -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<float>(Shape{2, 2}, {13.459274f, 41.75028f, -19.311913f, 131.79282f});
|
||||
test_case.add_expected_output<float>(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<float>(Shape{2, 2}, {0, 0, 0, 0});
|
||||
test_case.add_expected_output<float>(Shape{2, 2}, {13.459274f, 41.75028f, -19.311913f, 131.79282f});
|
||||
test_case.add_expected_output<float>(Shape{2, 2}, {83.052017f, 55.496368f, 119.31188f, -3.6946249f});
|
||||
test_case.run();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
LINK_LIBRARIES openvino::util openvino::core::dev)
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
//
|
||||
#include <random>
|
||||
|
||||
#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<Node>& mean_const) {
|
||||
std::random_device rd;
|
||||
std::mt19937 gen(rd());
|
||||
std::uniform_int_distribution<uint64_t> distrib(0, 9999);
|
||||
std::uniform_real_distribution<float> 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<float>::min()}));
|
||||
auto max_val = context.mark_node(v0::Constant::create(target_type, Shape{1}, {1}));
|
||||
|
||||
auto uniform_1 = context.mark_node(
|
||||
std::make_shared<v8::RandomUniform>(sizes, min_val, max_val, target_type, global_seed, seed_1));
|
||||
auto uniform_2 = context.mark_node(
|
||||
std::make_shared<v8::RandomUniform>(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<v0::Log>(uniform_1));
|
||||
auto multiply_minus_two_log = context.mark_node(std::make_shared<v1::Multiply>(log, minus_two));
|
||||
auto sqrt = context.mark_node(std::make_shared<v0::Sqrt>(multiply_minus_two_log));
|
||||
|
||||
auto multiply_two_pi = context.mark_node(std::make_shared<v1::Multiply>(uniform_2, pi));
|
||||
auto multiply_two_pi_uniform_2 = context.mark_node(std::make_shared<v1::Multiply>(multiply_two_pi, uniform_2));
|
||||
auto cos = context.mark_node(std::make_shared<v0::Cos>(multiply_two_pi_uniform_2));
|
||||
|
||||
auto sqrt_x_cos = context.mark_node(std::make_shared<v1::Multiply>(sqrt, cos));
|
||||
auto product = context.mark_node(std::make_shared<v1::Multiply>(scale_const, sqrt_x_cos));
|
||||
auto sum = context.mark_node(std::make_shared<v1::Add>(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
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -137,13 +137,11 @@ target_compile_definitions(${TARGET_NAME}_obj PRIVATE
|
|||
IMPLEMENT_INFERENCE_ENGINE_API
|
||||
$<$<TARGET_EXISTS:openvino_proxy_plugin_obj>:PROXY_PLUGIN_ENABLED>
|
||||
$<TARGET_PROPERTY:ngraph,INTERFACE_COMPILE_DEFINITIONS>
|
||||
$<TARGET_PROPERTY:frontend_common::static,INTERFACE_COMPILE_DEFINITIONS>
|
||||
$<TARGET_PROPERTY:openvino_gapi_preproc,INTERFACE_COMPILE_DEFINITIONS>)
|
||||
|
||||
target_include_directories(${TARGET_NAME}_obj SYSTEM PRIVATE
|
||||
$<TARGET_PROPERTY:ngraph,INTERFACE_INCLUDE_DIRECTORIES>
|
||||
$<TARGET_PROPERTY:openvino::pugixml,INTERFACE_INCLUDE_DIRECTORIES>
|
||||
$<TARGET_PROPERTY:frontend_common::static,INTERFACE_INCLUDE_DIRECTORIES>
|
||||
$<$<TARGET_EXISTS:openvino_proxy_plugin_obj>:$<TARGET_PROPERTY:openvino_proxy_plugin_obj,INTERFACE_INCLUDE_DIRECTORIES>>
|
||||
$<$<TARGET_EXISTS:xbyak::xbyak>:$<TARGET_PROPERTY:xbyak::xbyak,INTERFACE_INCLUDE_DIRECTORIES>>)
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -88,3 +88,57 @@ class TestNormal(PytorchLayerTest):
|
|||
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)
|
||||
|
|
|
|||
Loading…
Reference in New Issue