Method Node::constant_fold uses new evaluate method with TensorVector (#12423)

* Method Node::constant_fold uses new evaluate method with TensorVector

* Simplify conditions for creating tensor

* Add test for evaluate with TensorVector

* Add line at EOF
This commit is contained in:
Artur Kulikowski authored and GitHub committed 2022-08-08 11:22:55 +03:00
1 parent c541208d43
commit b3341defce
2 files changed
+60 -10

No files matched your search

+21 -9
View File
@@ -701,6 +701,15 @@ protected:
}
};
inline ov::Tensor create_tensor_from_output(const ov::Output<ov::Node>& output) {
if (output.get_element_type().is_dynamic()) {
return ov::Tensor();
} else if (output.get_partial_shape().is_dynamic()) {
return ov::Tensor(output.get_element_type(), {0});
}
return ov::Tensor(output.get_element_type(), output.get_shape());
}
inline ngraph::HostTensorVector create_tmp_tensors(const ov::TensorVector& tensors) {
ngraph::HostTensorVector result;
result.reserve(tensors.size());
@@ -814,22 +823,25 @@ bool ov::Node::constant_fold(OutputVector& output_values, const OutputVector& in
if (!all_constants)
return false;
HostTensorVector input_tensors;
TensorVector input_tensors;
for (const auto& input : input_values) {
auto host_tensor = make_shared<ngraph::runtime::HostTensor>(
ov::as_type_ptr<ngraph::op::v0::Constant>(input.get_node_shared_ptr()));
input_tensors.push_back(host_tensor);
auto constant = ov::as_type_ptr<ngraph::op::v0::Constant>(input.get_node_shared_ptr());
auto tensor = ov::Tensor(input.get_element_type(), input.get_shape());
std::copy_n(constant->get_data_ptr<uint8_t>(), constant->get_byte_size(), static_cast<uint8_t*>(tensor.data()));
input_tensors.push_back(tensor);
}
HostTensorVector output_tensors;
OutputVector output_constants;
TensorVector output_tensors;
for (const auto& output : outputs()) {
auto tensor = make_shared<HostTensor>(output.get_element_type(), output.get_partial_shape());
output_tensors.push_back(tensor);
output_tensors.push_back(create_tensor_from_output(output));
}
OPENVINO_SUPPRESS_DEPRECATED_START
if (evaluate(output_tensors, input_tensors)) {
for (size_t i = 0; i < output_tensors.size(); ++i) {
output_values[i] = make_shared<ngraph::op::Constant>(output_tensors[i]);
output_values[i] = make_shared<ngraph::op::Constant>(output_tensors[i].get_element_type(),
output_tensors[i].get_shape(),
output_tensors[i].data());
}
return true;
}
+39 -1
View File
@@ -7,7 +7,7 @@
#include <transformations/utils/utils.hpp>
#include "common_test_utils/ngraph_test_utils.hpp"
#include "gtest/gtest.h"
#include "gmock/gmock.h"
#include "ngraph/ngraph.hpp"
#include "ngraph/opsets/opset1.hpp"
#include "ngraph/opsets/opset5.hpp"
@@ -3455,3 +3455,41 @@ TEST(constant_folding, fold_convert_like_but_node_is_not_foldable) {
ASSERT_EQ(count_ops_of_type<op::v1::ConvertLike>(model), 1);
}
class MockAddOp : public ov::op::v1::Add {
public:
MockAddOp(
const Output<Node>& arg0,
const Output<Node>& arg1,
const ov::op::AutoBroadcastSpec& auto_broadcast = ov::op::AutoBroadcastSpec(ov::op::AutoBroadcastType::NUMPY))
: ov::op::v1::Add(arg0, arg1, auto_broadcast) {
ON_CALL(*this, evaluate).WillByDefault([this](ov::TensorVector& outputs, const ov::TensorVector& inputs) {
return ov::Node::evaluate(outputs, inputs);
});
}
MOCK_METHOD(bool,
evaluate,
(ov::TensorVector & output_values, const ov::TensorVector& input_values),
(const, override));
};
TEST(constant_folding, evaluate_on_tensor_vector) {
vector<int> values_a{1, 2, 3, 4};
vector<int> values_b{1, 2, 3, 4};
auto data_shape = Shape{2, 2};
auto a = make_shared<op::Constant>(element::i32, data_shape, values_a);
auto b = make_shared<op::Constant>(element::i32, data_shape, values_b);
auto mock = std::make_shared<::testing::StrictMock<MockAddOp>>(a, b);
EXPECT_CALL(*mock, evaluate).Times(1);
auto model = std::make_shared<ov::Model>(NodeVector{mock}, ParameterVector{});
pass::Manager pass_manager;
pass_manager.register_pass<pass::ConstantFolding>();
pass_manager.run_passes(model);
vector<int> add_expected{2, 4, 6, 8};
auto result_node = ov::as_type_ptr<op::Constant>(model->get_results().at(0)->input_value(0).get_node_shared_ptr());
ASSERT_TRUE(result_node);
ASSERT_EQ(data_shape, result_node->get_output_shape(0));
ASSERT_EQ(add_expected, result_node->cast_vector<int>());
}