Moved MVN reference to ov::core. (#13327)

* Moved MVN reference to ov::core.

* Code style.

* Applied comments.

* Code style.

* Returned evaluate in evaluates_map()

* Added constant folding test.

* Use new API.

* Use new API.

* Use new API.

Co-authored-by: Evgenya Stepyreva <evgenya.stepyreva@intel.com>
This commit is contained in:
Anastasiia PnevskaiaandEvgenya Stepyreva authored and GitHub committed 2022-10-19 16:46:28 +03:00
1 parent eb0dd26e4b
commit c95b3e5138
4 files changed
+132

No files matched your search

+4
View File
@@ -125,6 +125,10 @@ public:
std::shared_ptr<Node> clone_with_new_inputs(const OutputVector& new_args) const override;
bool evaluate(ov::TensorVector& output_values, const ov::TensorVector& input_values) const override;
bool has_evaluate() const override;
float get_eps() const {
return m_eps;
}
@@ -86,6 +86,25 @@ void mvn_6(const T* arg,
divide(out, tmp_buffer.data(), out, in_shape, reduced_shape, op::AutoBroadcastType::NUMPY, true);
}
}
template <typename T>
AxisSet mvn_6_reduction_axes(const ov::Tensor& axes_input, size_t rank) {
T* a = axes_input.data<T>();
auto v = std::vector<T>(a, a + axes_input.get_shape()[0]);
std::vector<size_t> axes(v.size(), 0);
for (size_t i = 0; i < v.size(); i++) {
if (v[i] < 0) {
if (rank + v[i] < 0) {
throw ov::Exception("Unexpected axis");
}
axes[i] = (size_t)(rank + v[i]);
} else {
axes[i] = (size_t)(v[i]);
}
}
return AxisSet(axes);
}
} // namespace reference
} // namespace runtime
} // namespace ngraph
+62
View File
@@ -7,6 +7,7 @@
#include <algorithm>
#include "itt.hpp"
#include "ngraph/runtime/reference/mvn.hpp"
using namespace std;
using namespace ngraph;
@@ -135,3 +136,64 @@ bool op::v6::MVN::visit_attributes(AttributeVisitor& visitor) {
visitor.on_attribute("eps_mode", m_eps_mode);
return true;
}
namespace mvn {
namespace {
template <element::Type_t ET>
bool evaluate(ov::TensorVector& outputs,
const ov::TensorVector& inputs,
bool normalize_variance,
float eps,
ov::op::MVNEpsMode eps_mode) {
using T = typename element_type_traits<ET>::value_type;
AxisSet reduction_axes;
auto rank = inputs[0].get_shape().size();
if (inputs[1].get_element_type() == element::i64) {
reduction_axes = runtime::reference::mvn_6_reduction_axes<int64_t>(inputs[1], rank);
} else if (inputs[1].get_element_type() == element::i32) {
reduction_axes = runtime::reference::mvn_6_reduction_axes<int32_t>(inputs[1], rank);
} else {
throw ov::Exception("Unexpected indices type");
}
runtime::reference::mvn_6<T>(inputs[0].data<T>(),
outputs[0].data<T>(),
inputs[0].get_shape(),
reduction_axes,
normalize_variance,
eps,
eps_mode);
return true;
}
bool evaluate_mvn(ov::TensorVector& outputs,
const ov::TensorVector& inputs,
bool normalize_variance,
float eps,
ov::op::MVNEpsMode eps_mode) {
bool rc = true;
switch (inputs[0].get_element_type()) {
NGRAPH_TYPE_CASE(evaluate_mvn, f32, outputs, inputs, normalize_variance, eps, eps_mode);
default:
rc = false;
break;
}
return rc;
}
} // namespace
} // namespace mvn
bool op::v6::MVN::evaluate(ov::TensorVector& outputs, const ov::TensorVector& inputs) const {
OV_OP_SCOPE(v6_MVN_evaluate);
return mvn::evaluate_mvn(outputs, inputs, get_normalize_variance(), get_eps(), get_eps_mode());
}
bool op::v6::MVN::has_evaluate() const {
OV_OP_SCOPE(v6_MVN_has_evaluate);
switch (get_input_element_type(0)) {
case ov::element::f32:
return true;
default:
break;
}
return false;
}
@@ -0,0 +1,47 @@
// Copyright (C) 2018-2022 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#include <gtest/gtest.h>
#include "common_test_utils/test_common.hpp"
#include "common_test_utils/graph_comparator.hpp"
#include "openvino/opsets/opset10.hpp"
#include "openvino/pass/constant_folding.hpp"
#include "openvino/pass/manager.hpp"
#include "openvino/pass/pattern/op/wrap_type.hpp"
#include "openvino/core/validation_util.hpp"
using namespace testing;
using namespace std;
using namespace ov;
TEST(TransformationTests, ConstFoldingMVN) {
shared_ptr<ov::Model> fun(nullptr);
{
const auto in = make_shared<opset10::Parameter>(element::f32, Shape{6});
const auto mvn_in = make_shared<opset10::Constant>(element::f32, Shape{6}, vector<float>(6, 0.0));
const auto axes = make_shared<opset10::Constant>(element::i32, Shape{1}, vector<int> {0});
auto mvn = make_shared<opset10::MVN>(mvn_in, axes, false, 1e-9, op::MVNEpsMode::OUTSIDE_SQRT);
auto add = make_shared<opset10::Add>(in, mvn);
fun = make_shared<ov::Model>(NodeVector {add}, ParameterVector {in});
ov::pass::Manager manager;
manager.register_pass<ov::pass::ConstantFolding>();
manager.run_passes(fun);
}
shared_ptr<ov::Model> f_ref(nullptr);
{
const auto in = make_shared<opset10::Parameter>(element::f32, Shape{6});
const auto mvn_const = make_shared<opset10::Constant>(element::f32, Shape{6}, vector<float>(6, 0.0));
auto add = make_shared<opset10::Add>(in, mvn_const);
f_ref = make_shared<ov::Model>(NodeVector {add}, ParameterVector {in});
}
auto res = compare_functions(fun, f_ref);
ASSERT_TRUE(res.first) << res.second;
}