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:
1 parent
c541208d43
commit
b3341defce
2 files changed
+60
-10
No files matched your search
+21
-9
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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>());
|
||||
}
|
||||
Reference in new issue
Block a user