From e648001b12fcc19c3cdbbc4070d02727e8f0eb8f Mon Sep 17 00:00:00 2001 From: Pavel Esir Date: Tue, 29 Nov 2022 09:55:06 +0000 Subject: [PATCH] [IE] keep constants in shape subgraphs in f32 (#14204) * keep constants in shape subgraphs in f32 * added unit-test without callback; added comment in convert_compression_only_to_legacy.cpp --- .../rt_info/disable_fp16_compression.hpp | 2 +- .../convert_compression_only_to_legacy.cpp | 10 +++ .../src/transformations/convert_precision.cpp | 3 + .../rt_info/disable_fp16_compression.cpp | 2 +- .../tests/utils/convert_precision.cpp | 71 +++++++++++++++++++ 5 files changed, 86 insertions(+), 2 deletions(-) diff --git a/src/common/transformations/include/transformations/rt_info/disable_fp16_compression.hpp b/src/common/transformations/include/transformations/rt_info/disable_fp16_compression.hpp index d245ce23d0c..1f9cdc5c924 100644 --- a/src/common/transformations/include/transformations/rt_info/disable_fp16_compression.hpp +++ b/src/common/transformations/include/transformations/rt_info/disable_fp16_compression.hpp @@ -14,7 +14,7 @@ TRANSFORMATIONS_API void disable_fp16_compression(const std::shared_ptr& n TRANSFORMATIONS_API void enable_fp16_compression(const std::shared_ptr& node); -TRANSFORMATIONS_API bool fp16_compression_is_disabled(const std::shared_ptr& node); +TRANSFORMATIONS_API bool fp16_compression_is_disabled(const std::shared_ptr& node); /** * @ingroup ie_runtime_attr_api diff --git a/src/common/transformations/src/transformations/common_optimizations/convert_compression_only_to_legacy.cpp b/src/common/transformations/src/transformations/common_optimizations/convert_compression_only_to_legacy.cpp index 424d34be65c..4645fe0c69a 100644 --- a/src/common/transformations/src/transformations/common_optimizations/convert_compression_only_to_legacy.cpp +++ b/src/common/transformations/src/transformations/common_optimizations/convert_compression_only_to_legacy.cpp @@ -7,7 +7,9 @@ #include "itt.hpp" #include "openvino/opsets/opset8.hpp" #include "openvino/pass/manager.hpp" +#include "transformations/common_optimizations/mark_precision_sensitive_subgraphs.hpp" #include "transformations/convert_precision.hpp" +#include "transformations/rt_info/disable_fp16_compression.hpp" #include "transformations/utils/utils.hpp" using namespace ov; @@ -32,6 +34,14 @@ bool ov::pass::ConvertCompressedOnlyToLegacy::run_on_model(const std::shared_ptr RUN_ON_MODEL_SCOPE(ConvertCompressedOnlyToLegacy); if (ngraph::op::util::has_decompression_converts(f)) { Manager manager(get_pass_config()); + // Skip precision sensitive nodes with marking and pass_callback: + // callback skips (returns true) for nodes marked as precision sensitive/disabled_f16_compression. + // Skipping was done by callback in order to impact behavior of ConvertPrecision as little as possible + manager.register_pass(); + get_pass_config()->set_callback( + [](const std::shared_ptr& node) -> bool { + return ov::fp16_compression_is_disabled(node) && node->get_element_type() == element::f32; + }); const precisions_array convert_precision_list{{ov::element::f32, ov::element::f16}}; manager.register_pass(convert_precision_list); diff --git a/src/common/transformations/src/transformations/convert_precision.cpp b/src/common/transformations/src/transformations/convert_precision.cpp index e1f6f454c94..f46f882a058 100644 --- a/src/common/transformations/src/transformations/convert_precision.cpp +++ b/src/common/transformations/src/transformations/convert_precision.cpp @@ -196,6 +196,9 @@ bool convert_precision(ov::pass::PassBase& pass, bool is_output_precision_changed = false; for (auto& node : ops) { + // skip precision sensitive nodes + if (pass.transformation_callback(node)) + continue; is_output_precision_changed |= convert_node_output_precision(node); } diff --git a/src/common/transformations/src/transformations/rt_info/disable_fp16_compression.cpp b/src/common/transformations/src/transformations/rt_info/disable_fp16_compression.cpp index 4d1b4dd5344..8639c88c30a 100644 --- a/src/common/transformations/src/transformations/rt_info/disable_fp16_compression.cpp +++ b/src/common/transformations/src/transformations/rt_info/disable_fp16_compression.cpp @@ -14,7 +14,7 @@ void ov::enable_fp16_compression(const std::shared_ptr& node) { rt_info.erase(DisableFP16Compression::get_type_info_static()); } -bool ov::fp16_compression_is_disabled(const std::shared_ptr& node) { +bool ov::fp16_compression_is_disabled(const std::shared_ptr& node) { const auto& rt_info = node->get_rt_info(); return rt_info.count(DisableFP16Compression::get_type_info_static()); } diff --git a/src/common/transformations/tests/utils/convert_precision.cpp b/src/common/transformations/tests/utils/convert_precision.cpp index 8fb431018a9..6fc61c17126 100644 --- a/src/common/transformations/tests/utils/convert_precision.cpp +++ b/src/common/transformations/tests/utils/convert_precision.cpp @@ -20,6 +20,8 @@ #include #include #include +#include "transformations/rt_info/disable_fp16_compression.hpp" +#include "transformations/common_optimizations/mark_precision_sensitive_subgraphs.hpp" #include "common_test_utils/ngraph_test_utils.hpp" @@ -800,6 +802,75 @@ TEST(TransformationTests, ConvertPrecision_Variables) { ASSERT_FALSE(has_type(f)); } +TEST(TransformationTests, ConvertPrecision_skip_precision_sensitive) { + std::shared_ptr model(nullptr); + std::shared_ptr interpolate(nullptr); + { + auto input = std::make_shared(element::f32, Shape{1, 3, 720, 1280}); + auto sizes = opset8::Constant::create(element::i64, Shape{4}, {1, 3, 288, 512}); + auto scales = opset8::Constant::create(element::f32, Shape{4}, {1.0f, 1.0f, 0.4f, 0.4f}); + opset8::Interpolate::InterpolateAttrs attrs; + + attrs.mode = opset8::Interpolate::InterpolateMode::LINEAR_ONNX; + attrs.shape_calculation_mode = opset8::Interpolate::ShapeCalcMode::SCALES; + attrs.nearest_mode = opset8::Interpolate::NearestMode::FLOOR; + attrs.pads_begin = std::vector{0}; + attrs.pads_end = std::vector{0}; + attrs.antialias = false; + attrs.coordinate_transformation_mode = opset8::Interpolate::CoordinateTransformMode::PYTORCH_HALF_PIXEL; + attrs.cube_coeff = -0.75f; + + interpolate = std::make_shared(input, sizes, scales, attrs); + model = std::make_shared(NodeVector{interpolate}, ParameterVector{input}); + + pass::Manager manager; + + manager.register_pass(); + manager.get_pass_config()->set_callback( + [](const std::shared_ptr& node) -> bool { + return ov::fp16_compression_is_disabled(node) && node->get_element_type() == element::f32; + }); + + manager.register_pass(precisions_array {{ element::f32, element::f16 }}); + manager.run_passes(model); + } + + ASSERT_TRUE(has_type(model)); + ASSERT_TRUE(interpolate->input_value(2).get_element_type() == element::Type_t::f32); +} + +TEST(TransformationTests, ConvertPrecision_without_callback) { + // without callback all nodes should be converted to f16 regardless even they are marked + std::shared_ptr model(nullptr); + std::shared_ptr interpolate(nullptr); + { + auto input = std::make_shared(element::f32, Shape{1, 3, 720, 1280}); + auto sizes = opset8::Constant::create(element::i64, Shape{4}, {1, 3, 288, 512}); + auto scales = opset8::Constant::create(element::f32, Shape{4}, {1.0f, 1.0f, 0.4f, 0.4f}); + opset8::Interpolate::InterpolateAttrs attrs; + + attrs.mode = opset8::Interpolate::InterpolateMode::LINEAR_ONNX; + attrs.shape_calculation_mode = opset8::Interpolate::ShapeCalcMode::SCALES; + attrs.nearest_mode = opset8::Interpolate::NearestMode::FLOOR; + attrs.pads_begin = std::vector{0}; + attrs.pads_end = std::vector{0}; + attrs.antialias = false; + attrs.coordinate_transformation_mode = opset8::Interpolate::CoordinateTransformMode::PYTORCH_HALF_PIXEL; + attrs.cube_coeff = -0.75f; + + interpolate = std::make_shared(input, sizes, scales, attrs); + model = std::make_shared(NodeVector{interpolate}, ParameterVector{input}); + pass::Manager manager; + + manager.register_pass(); + manager.register_pass(precisions_array {{ element::f32, element::f16 }}); + manager.run_passes(model); + } + + ASSERT_FALSE(has_type(model)); + ASSERT_TRUE(interpolate->input_value(2).get_element_type() == element::Type_t::f16); +} + template void constant_convert_test(element::Type type_from, element::Type type_to, const std::vector& value, const std::vector& expected) { std::shared_ptr f(nullptr);