[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
This commit is contained in:
Pavel Esir
2022-11-29 09:55:06 +00:00
committed by GitHub
parent 97dd3e6a21
commit e648001b12
5 changed files with 86 additions and 2 deletions

View File

@@ -14,7 +14,7 @@ TRANSFORMATIONS_API void disable_fp16_compression(const std::shared_ptr<Node>& n
TRANSFORMATIONS_API void enable_fp16_compression(const std::shared_ptr<Node>& node);
TRANSFORMATIONS_API bool fp16_compression_is_disabled(const std::shared_ptr<Node>& node);
TRANSFORMATIONS_API bool fp16_compression_is_disabled(const std::shared_ptr<const Node>& node);
/**
* @ingroup ie_runtime_attr_api

View File

@@ -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<ov::pass::MarkPrecisionSensitiveSubgraphs>();
get_pass_config()->set_callback<ngraph::pass::ConvertPrecision>(
[](const std::shared_ptr<const Node>& 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<ngraph::pass::ConvertPrecision>(convert_precision_list);

View File

@@ -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);
}

View File

@@ -14,7 +14,7 @@ void ov::enable_fp16_compression(const std::shared_ptr<Node>& node) {
rt_info.erase(DisableFP16Compression::get_type_info_static());
}
bool ov::fp16_compression_is_disabled(const std::shared_ptr<Node>& node) {
bool ov::fp16_compression_is_disabled(const std::shared_ptr<const Node>& node) {
const auto& rt_info = node->get_rt_info();
return rt_info.count(DisableFP16Compression::get_type_info_static());
}

View File

@@ -20,6 +20,8 @@
#include <transformations/utils/utils.hpp>
#include <ngraph/pass/manager.hpp>
#include <ov_ops/type_relaxed.hpp>
#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<ngraph::element::Type_t::f16>(f));
}
TEST(TransformationTests, ConvertPrecision_skip_precision_sensitive) {
std::shared_ptr<ov::Model> model(nullptr);
std::shared_ptr<opset8::Interpolate> interpolate(nullptr);
{
auto input = std::make_shared<opset8::Parameter>(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<size_t>{0};
attrs.pads_end = std::vector<size_t>{0};
attrs.antialias = false;
attrs.coordinate_transformation_mode = opset8::Interpolate::CoordinateTransformMode::PYTORCH_HALF_PIXEL;
attrs.cube_coeff = -0.75f;
interpolate = std::make_shared<opset8::Interpolate>(input, sizes, scales, attrs);
model = std::make_shared<ov::Model>(NodeVector{interpolate}, ParameterVector{input});
pass::Manager manager;
manager.register_pass<ov::pass::MarkPrecisionSensitiveSubgraphs>();
manager.get_pass_config()->set_callback<ngraph::pass::ConvertPrecision>(
[](const std::shared_ptr<const Node>& node) -> bool {
return ov::fp16_compression_is_disabled(node) && node->get_element_type() == element::f32;
});
manager.register_pass<pass::ConvertPrecision>(precisions_array {{ element::f32, element::f16 }});
manager.run_passes(model);
}
ASSERT_TRUE(has_type<element::Type_t::f32>(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<ov::Model> model(nullptr);
std::shared_ptr<opset8::Interpolate> interpolate(nullptr);
{
auto input = std::make_shared<opset8::Parameter>(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<size_t>{0};
attrs.pads_end = std::vector<size_t>{0};
attrs.antialias = false;
attrs.coordinate_transformation_mode = opset8::Interpolate::CoordinateTransformMode::PYTORCH_HALF_PIXEL;
attrs.cube_coeff = -0.75f;
interpolate = std::make_shared<opset8::Interpolate>(input, sizes, scales, attrs);
model = std::make_shared<ov::Model>(NodeVector{interpolate}, ParameterVector{input});
pass::Manager manager;
manager.register_pass<ov::pass::MarkPrecisionSensitiveSubgraphs>();
manager.register_pass<pass::ConvertPrecision>(precisions_array {{ element::f32, element::f16 }});
manager.run_passes(model);
}
ASSERT_FALSE(has_type<element::Type_t::f32>(model));
ASSERT_TRUE(interpolate->input_value(2).get_element_type() == element::Type_t::f16);
}
template <typename From, typename To>
void constant_convert_test(element::Type type_from, element::Type type_to, const std::vector<From>& value, const std::vector<To>& expected) {
std::shared_ptr<ngraph::Function> f(nullptr);