Fix Division with eps marking (#18932)
* improve Division with eps marking * delete obsolete empty files
This commit is contained in:
+12
-7
@@ -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});
|
||||
|
||||
+98
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user