From 3e58ccbce7758eb797c0b972813ef111ff63a2ce Mon Sep 17 00:00:00 2001 From: Ilya Churaev Date: Thu, 31 Mar 2022 07:47:49 +0300 Subject: [PATCH] Fixed evaluate for ov::Tensor (#11354) * Fixed evaluate for ov::Tensor * Fixed old ops with EvaluationContext --- docs/template_extension/new/identity.cpp | 2 +- src/core/src/node.cpp | 4 +- src/core/tests/extension.cpp | 59 ++++++++++++++++++++++++ 3 files changed, 63 insertions(+), 2 deletions(-) diff --git a/docs/template_extension/new/identity.cpp b/docs/template_extension/new/identity.cpp index 442753c1f5c..9443d394289 100644 --- a/docs/template_extension/new/identity.cpp +++ b/docs/template_extension/new/identity.cpp @@ -38,7 +38,7 @@ bool Identity::evaluate(ov::TensorVector& outputs, const ov::TensorVector& input auto in = inputs[0]; auto out = outputs[0]; out.set_shape(in.get_shape()); - memcpy(out.data(), in.data(), in.get_size()); + memcpy(out.data(), in.data(), in.get_byte_size()); return true; } diff --git a/src/core/src/node.cpp b/src/core/src/node.cpp index d8164ba336e..68bbbd8b841 100644 --- a/src/core/src/node.cpp +++ b/src/core/src/node.cpp @@ -743,13 +743,15 @@ bool ov::Node::evaluate(ov::TensorVector& output_values, const ov::TensorVector& bool ov::Node::evaluate(ov::TensorVector& output_values, const ov::TensorVector& input_values, const ov::EvaluationContext& evaluationContext) const { + // Call evaluate for old implementation with EvaluationContext HostTensorVector output = create_tmp_tensors(output_values); HostTensorVector input = create_tmp_tensors(input_values); OPENVINO_SUPPRESS_DEPRECATED_START bool sts = evaluate(output, input, evaluationContext); OPENVINO_SUPPRESS_DEPRECATED_END update_output_tensors(output_values, output); - return sts; + // Call evaluate for ov::Tensor if op doesn't have evaluate with EvaluationContext + return sts ? sts : evaluate(output_values, input_values); } bool ov::Node::evaluate_lower(ov::TensorVector& output_values) const { diff --git a/src/core/tests/extension.cpp b/src/core/tests/extension.cpp index 187fa3e9481..4bc5961fd68 100644 --- a/src/core/tests/extension.cpp +++ b/src/core/tests/extension.cpp @@ -8,6 +8,7 @@ #include "openvino/core/graph_util.hpp" #include "openvino/core/op_extension.hpp" +#include "openvino/opsets/opset9.hpp" #include "openvino/util/file_util.hpp" #include "so_extension.hpp" @@ -36,3 +37,61 @@ TEST(extension, load_extension_and_cast) { EXPECT_NE(nullptr, std::dynamic_pointer_cast(extensions[0])); extensions.clear(); } + +namespace { +class DummyAdapter : public ov::AttributeVisitor { +public: + void on_adapter(const std::string& name, ov::ValueAccessor& adapter) override {} +}; +} // namespace + +TEST(extension, create_model_from_extension) { + std::vector so_extensions = ov::detail::load_extensions(get_extension_path()); + ASSERT_LE(1, so_extensions.size()); + std::vector extensions; + std::vector> so; + for (const auto& ext : so_extensions) { + if (auto so_ext = std::dynamic_pointer_cast(ext)) { + extensions.emplace_back(so_ext->extension()); + so.emplace_back(so_ext->shared_object()); + } + } + so_extensions.clear(); + EXPECT_LE(1, extensions.size()); + auto op_extension = std::dynamic_pointer_cast(extensions[0]); + EXPECT_NE(nullptr, op_extension); + { + // Create model to check evaluate for custom operation + std::shared_ptr model; + { + auto parameter = std::make_shared(ov::element::i32, ov::Shape{1, 2, 2, 2}); + + DummyAdapter visitor; + + auto outputs = op_extension->create(ov::OutputVector{parameter}, visitor); + + EXPECT_EQ(1, outputs.size()); + EXPECT_NE(nullptr, outputs[0].get_node()); + const std::string ref_name = "Identity"; + EXPECT_EQ(ref_name, outputs[0].get_node()->get_type_info().name); + auto result = std::make_shared(outputs[0]); + model = std::make_shared(ov::ResultVector{result}, ov::ParameterVector{parameter}); + } + + auto fill_tensor = [](ov::Tensor& tensor) { + int32_t* data = tensor.data(); + for (size_t i = 0; i < tensor.get_size(); i++) + data[i] = i; + }; + + ov::TensorVector inputs; + inputs.emplace_back(ov::Tensor(ov::element::i32, ov::Shape{1, 2, 2, 2})); + fill_tensor(*inputs.begin()); + ov::TensorVector outputs; + outputs.emplace_back(ov::Tensor(ov::element::i32, ov::Shape{1, 2, 2, 2})); + EXPECT_NE(std::memcmp(inputs.begin()->data(), outputs.begin()->data(), inputs.begin()->get_byte_size()), 0); + model->evaluate(outputs, inputs); + EXPECT_EQ(std::memcmp(inputs.begin()->data(), outputs.begin()->data(), inputs.begin()->get_byte_size()), 0); + } + extensions.clear(); +}