Fix Division with eps marking (#18932)

* improve Division with eps marking

* delete obsolete empty files
This commit is contained in:
Pavel Esir
2023-08-04 13:23:15 +04:00
committed by GitHub
parent 28ce25421a
commit aeffdec5b2
4 changed files with 110 additions and 7 deletions
@@ -285,18 +285,23 @@ public:
MATCHER_SCOPE(MarkDivWithEps);
// to detect the following patterns where eps is used to prevent division by zero:
// input_1/Maximum(input_2, eps)
// input_1/Add(input_2, eps)
// input_1/Sqrt(Maximum(input_2, eps))
// input_1/Sqrt(Add(input_2, eps))
// input_1*Pow(Maximum(input_2, eps), -z)
// input_1*Pow(Add(input_2, eps), -z)
// input_1 / Maximum(input_2, eps)
// input_1 / Add(input_2, eps)
// input_1 / Sqrt(Maximum(input_2, eps))
// input_1 / Sqrt(Add(input_2, eps))
// input_1 * Pow(Maximum(input_2, eps), -z)
// input_1 * Pow(Add(input_2, eps), -z)
auto input_1 = pattern::any_input();
auto input_2 = pattern::any_input();
auto eps_const_pattern = pattern::wrap_type<ov::op::v0::Constant>();
auto convert_eps_pattern = pattern::wrap_type<ov::op::v0::Convert>({eps_const_pattern});
auto eps_const_or_convert =
std::make_shared<pattern::op::Or>(OutputVector{eps_const_pattern, convert_eps_pattern});
auto max_or_add =
pattern::wrap_type<ov::op::v1::Maximum, ov::op::v1::Add>(OutputVector{input_2, eps_const_pattern});
pattern::wrap_type<ov::op::v1::Maximum, ov::op::v1::Add>(OutputVector{input_2, eps_const_or_convert});
auto sqrt = std::make_shared<ov::op::v0::Sqrt>(max_or_add);
auto sqrt_or_max_add = std::make_shared<pattern::op::Or>(OutputVector{max_or_add, sqrt});
@@ -453,6 +453,49 @@ TEST(TransformationTests, DivisionByZeroMinimalPattern) {
ASSERT_TRUE(result.valid) << result.message;
}
TEST(TransformationTests, DivisionByZeroEpsWithConvert) {
shared_ptr<Model> model, model_ref;
pass::Manager manager;
const float eps_value = 1.0e-5f;
{
auto input_1 = std::make_shared<Parameter>(element::f32, PartialShape::dynamic(3));
auto input_2 = std::make_shared<Parameter>(element::f32, PartialShape::dynamic(3));
auto eps_const = Constant::create(element::f16, Shape{1}, {eps_value});
auto convert_eps = std::make_shared<Convert>(eps_const, element::f32);
auto add = std::make_shared<Add>(input_2, convert_eps);
auto divide = std::make_shared<Divide>(input_1, add);
model = std::make_shared<Model>(NodeVector{divide}, ParameterVector{input_1, input_2});
manager.register_pass<pass::MarkSugraphsToKeepInMixedPrecision>();
manager.run_passes(model);
}
{
auto input_1 = std::make_shared<Parameter>(element::f32, PartialShape::dynamic(3));
auto input_2 = std::make_shared<Parameter>(element::f32, PartialShape::dynamic(3));
auto eps_const = Constant::create(element::f16, Shape{1}, {eps_value});
auto convert_eps = std::make_shared<Convert>(eps_const, element::f32);
auto add = std::make_shared<Add>(input_2, convert_eps);
auto divide = std::make_shared<Divide>(input_1, add);
disable_fp16_compression(divide);
disable_fp16_compression(eps_const);
disable_fp16_compression(convert_eps);
disable_fp16_compression(add);
model_ref = std::make_shared<Model>(NodeVector{divide}, ParameterVector{input_1, input_2});
}
const FunctionsComparator func_comparator =
FunctionsComparator::with_default().enable(FunctionsComparator::RUNTIME_KEYS);
// need to compare twice to ensure that no extra nodes are marked
FunctionsComparator::Result result = func_comparator(model_ref, model);
ASSERT_TRUE(result.valid) << result.message;
result = func_comparator(model, model_ref);
ASSERT_TRUE(result.valid) << result.message;
}
TEST(TransformationTests, PowWithNegativeExponent) {
shared_ptr<Model> model, model_ref;
pass::Manager manager;
@@ -605,6 +648,61 @@ TEST(TransformationTests, DivisionByZeroInL2NormWithSqrtAndWithMax) {
ASSERT_TRUE(result.valid) << result.message;
}
TEST(TransformationTests, DivisionByZeroMaxAndEpsWithConvert) {
shared_ptr<Model> model, model_ref;
pass::Manager manager;
const float eps_value = 1.0e-5f;
{
auto input = std::make_shared<Parameter>(element::f32, PartialShape::dynamic(3));
auto exp = Constant::create(element::f32, Shape{}, {2.f});
auto pow = std::make_shared<Power>(input, exp);
auto axes_const = Constant::create(element::i64, Shape{2}, {0, 1});
auto reduce_sum = std::make_shared<ReduceSum>(pow, axes_const);
auto eps_const = Constant::create(element::f16, Shape{}, {eps_value});
auto convert_eps = std::make_shared<Convert>(eps_const, element::f32);
auto max = std::make_shared<Maximum>(reduce_sum, convert_eps);
auto sqrt = std::make_shared<Sqrt>(max);
auto divide = std::make_shared<Divide>(input, sqrt);
model = std::make_shared<Model>(NodeVector{divide}, ParameterVector{input});
manager.register_pass<pass::MarkSugraphsToKeepInMixedPrecision>();
manager.run_passes(model);
}
{
auto input = std::make_shared<Parameter>(element::f32, PartialShape::dynamic(3));
auto exp = Constant::create(element::f32, Shape{}, {2.f});
auto pow = std::make_shared<Power>(input, exp);
auto axes_const = Constant::create(element::i64, Shape{2}, {0, 1});
auto reduce_sum = std::make_shared<ReduceSum>(pow, axes_const);
auto eps_const = Constant::create(element::f16, Shape{}, {eps_value});
auto convert_eps = std::make_shared<Convert>(eps_const, element::f32);
auto max = std::make_shared<Maximum>(reduce_sum, convert_eps);
auto sqrt = std::make_shared<Sqrt>(max);
auto divide = std::make_shared<Divide>(input, sqrt);
// marking nodes to be kept in fp32 for mixed precision
disable_fp16_compression(exp);
disable_fp16_compression(pow);
disable_fp16_compression(reduce_sum);
disable_fp16_compression(max);
disable_fp16_compression(eps_const);
disable_fp16_compression(convert_eps);
disable_fp16_compression(sqrt);
disable_fp16_compression(divide);
model_ref = std::make_shared<Model>(NodeVector{divide}, ParameterVector{input});
}
const FunctionsComparator func_comparator =
FunctionsComparator::with_default().enable(FunctionsComparator::RUNTIME_KEYS);
// need to compare twice to ensure that no extra nodes are marked
FunctionsComparator::Result result = func_comparator(model_ref, model);
ASSERT_TRUE(result.valid) << result.message;
result = func_comparator(model, model_ref);
ASSERT_TRUE(result.valid) << result.message;
}
TEST(TransformationTests, DivisionByZeroInL2NormWithSqrtAndWithAdd) {
shared_ptr<Model> model, model_ref;
pass::Manager manager;