From 623117fe2454d27577716301831e28335ed5097b Mon Sep 17 00:00:00 2001 From: Anastasia Popova Date: Wed, 6 Oct 2021 23:15:45 +0300 Subject: [PATCH] Serialization of old API map in nGraph. (#7840) * Added serialization of old API map in ngraph. * Changed order type to int64_t. * Fixed uint64_t error, added comments. * Apply suggestions from code review Co-authored-by: Gleb Kazantaev * Added tests with undefined type and empty order. * Added set, get and has methods. * Fix in tests. * Apply suggestions from code review Co-authored-by: Ilya Churaev * Made inline methods, changed to shared_ptr. * Small fix. * Moved methods to header file. * Small fix. Co-authored-by: Gleb Kazantaev Co-authored-by: Ilya Churaev --- .../transformations/rt_info/attributes.hpp | 2 + .../rt_info/old_api_map_attribute.hpp | 124 ++++++++++++++++++ .../rt_info/old_api_map_attribute.cpp | 14 ++ .../rt_info_deserialization.cpp | 36 +++++ .../rt_info_serialization.cpp | 10 ++ .../frontend/ir/src/rt_info_deserializer.hpp | 10 ++ 6 files changed, 196 insertions(+) create mode 100644 inference-engine/src/transformations/include/transformations/rt_info/old_api_map_attribute.hpp create mode 100644 inference-engine/src/transformations/src/transformations/rt_info/old_api_map_attribute.cpp diff --git a/inference-engine/src/transformations/include/transformations/rt_info/attributes.hpp b/inference-engine/src/transformations/include/transformations/rt_info/attributes.hpp index 9b6904c02331e6..1207c3bd278250 100644 --- a/inference-engine/src/transformations/include/transformations/rt_info/attributes.hpp +++ b/inference-engine/src/transformations/include/transformations/rt_info/attributes.hpp @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -32,6 +33,7 @@ class TRANSFORMATIONS_API Attributes { register_factory(); register_factory(); register_factory(); + register_factory(); } Variant * create_by_type_info(const ov::DiscreteTypeInfo & type_info) { diff --git a/inference-engine/src/transformations/include/transformations/rt_info/old_api_map_attribute.hpp b/inference-engine/src/transformations/include/transformations/rt_info/old_api_map_attribute.hpp new file mode 100644 index 00000000000000..4ffe69b98edc23 --- /dev/null +++ b/inference-engine/src/transformations/include/transformations/rt_info/old_api_map_attribute.hpp @@ -0,0 +1,124 @@ +// Copyright (C) 2018-2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +/** + * @brief Defines old API map attribute + * @file old_api_map_attribute.hpp + */ + +#pragma once + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace ov { + +class OldApiMap; +/** + * @ingroup ie_runtime_attr_api + * @brief OldApiMapAttr class stores the value of OldApiMap class. + * + * OldApiMap stores the following information. + * Parameter: + * Order of the transpose which should be applied to Parameter with old API layout to + * obtain Parameter with new API layout. + * Element type of the Parameter in old API. + * + * Result: + * Order of the transpose which should be applied to Result with new API layout to + * obtain Result with old API layout. + * + */ +class TRANSFORMATIONS_API OldApiMapAttr { +private: + std::vector m_order; + ngraph::element::Type m_legacy_type = ngraph::element::Type_t::undefined; + +public: + friend class OldApiMap; + + /** + * A default constructor + */ + OldApiMapAttr() = default; + + /** + * @brief Constructs a new OldApiMapAttr object. + * @param[in] order Transpose order. + * @param[in] legacy_type Legacy type. + */ + explicit OldApiMapAttr(std::vector order, const ngraph::element::Type& legacy_type) + : m_order(std::move(order)), m_legacy_type(legacy_type) {} + + /** + * @brief Returns the transpose order that should be used for obtain a node with old API layout. + * @return transpose order. + */ + const std::vector & get_order() const { + return m_order; + } + + /** + * @brief Returns the legacy type of the node. + * @return legacy type. + */ + ngraph::element::Type get_type() const { + return m_legacy_type; + } +}; + +/** + * @ingroup ie_runtime_attr_api + * @brief OldApiMap class represents runtime info attribute that stores legacy type + * and order of the transpose that is required for obtaining IR in old API. + */ +class TRANSFORMATIONS_API OldApiMap : public VariantImpl { +public: + OPENVINO_RTTI("old_api_map", "0"); + + /** + * A default constructor + */ + OldApiMap() = default; + + /** + * Constructs a new OldApiMap object. + * @param[in] value The object that stores values of OldApiMap. + */ + OldApiMap(const value_type& value) : VariantImpl(value) {} + + bool is_copyable() const override { + return false; + } + + bool visit_attributes(AttributeVisitor& visitor) override; +}; + +inline bool has_old_api_map(const std::shared_ptr& node) { + const auto& rt_map = node->get_rt_info(); + return rt_map.count(OldApiMap::get_type_info_static()); +} + +inline OldApiMap get_old_api_map(const std::shared_ptr& node) { + const auto& rt_map = node->get_rt_info(); + const auto& var = rt_map.at(OldApiMap::get_type_info_static()); + return ngraph::as_type_ptr(var)->get(); +} + +inline void set_old_api_map(std::shared_ptr& node, const OldApiMap& old_api_map) { + auto& rt_map = node->get_rt_info(); + rt_map[OldApiMap::get_type_info_static()] = std::make_shared(old_api_map); +} + +} // namespace ov diff --git a/inference-engine/src/transformations/src/transformations/rt_info/old_api_map_attribute.cpp b/inference-engine/src/transformations/src/transformations/rt_info/old_api_map_attribute.cpp new file mode 100644 index 00000000000000..40f231ea9c1924 --- /dev/null +++ b/inference-engine/src/transformations/src/transformations/rt_info/old_api_map_attribute.cpp @@ -0,0 +1,14 @@ +// Copyright (C) 2018-2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include "transformations/rt_info/old_api_map_attribute.hpp" + +using namespace ov; + +bool OldApiMap::visit_attributes(AttributeVisitor& visitor) { + visitor.on_attribute("order", m_value.m_order); + visitor.on_attribute("element_type", m_value.m_legacy_type); + return true; +} + diff --git a/inference-engine/tests/functional/inference_engine/ir_serialization/rt_info_deserialization.cpp b/inference-engine/tests/functional/inference_engine/ir_serialization/rt_info_deserialization.cpp index 41493ccd6c0d21..22ff07c44345dd 100644 --- a/inference-engine/tests/functional/inference_engine/ir_serialization/rt_info_deserialization.cpp +++ b/inference-engine/tests/functional/inference_engine/ir_serialization/rt_info_deserialization.cpp @@ -9,6 +9,7 @@ #include #include +#include using namespace ngraph; @@ -205,6 +206,7 @@ TEST(RTInfoDeserialization, NodeV11) { + @@ -238,6 +240,9 @@ TEST(RTInfoDeserialization, NodeV11) { + + + 1 @@ -266,6 +271,15 @@ TEST(RTInfoDeserialization, NodeV11) { ASSERT_EQ(fused_names_attr->get().getNames(), names); }; + auto check_old_api_map = [](const RTMap & info, const std::vector & order, const ngraph::element::Type& type) { + const std::string & old_api_map_key = ov::OldApiMap::get_type_info_static(); + ASSERT_TRUE(info.count(old_api_map_key)); + auto old_api_map_attr = std::dynamic_pointer_cast(info.at(old_api_map_key)); + ASSERT_TRUE(old_api_map_attr); + auto old_api_map_attr_val = old_api_map_attr->get(); + ASSERT_EQ(old_api_map_attr_val.get_order(), order); + ASSERT_EQ(old_api_map_attr_val.get_type(), type); + }; auto check_version = [](const std::shared_ptr& f) { auto& rt_info = f->get_rt_info(); ASSERT_TRUE(rt_info.count("version")); @@ -277,8 +291,14 @@ TEST(RTInfoDeserialization, NodeV11) { auto param = f->get_parameters()[0]; check_fused_names(param->get_rt_info(), "in1"); + check_old_api_map(param->get_rt_info(), + std::vector({0, 2, 3, 1}), + ngraph::element::Type_t::f32); auto result = f->get_results()[0]; + check_old_api_map(result->get_rt_info(), + std::vector({0, 3, 1, 2}), + ngraph::element::Type_t::undefined); auto round = result->get_input_node_ptr(0); check_fused_names(round->get_rt_info(), "Round1,Round2"); } @@ -289,6 +309,9 @@ TEST(RTInfoDeserialization, InputAndOutputV11) { + + + @@ -376,8 +399,21 @@ TEST(RTInfoDeserialization, InputAndOutputV11) { ASSERT_EQ(fused_names_attr->get().getNames(), names); }; + auto check_old_api_map = [](const RTMap & info, const std::vector & order, ngraph::element::Type type) { + const std::string & old_api_map_key = ov::OldApiMap::get_type_info_static(); + ASSERT_TRUE(info.count(old_api_map_key)); + auto old_api_map_attr = std::dynamic_pointer_cast(info.at(old_api_map_key)); + ASSERT_TRUE(old_api_map_attr); + auto old_api_map_attr_val = old_api_map_attr->get(); + ASSERT_EQ(old_api_map_attr_val.get_order(), order); + ASSERT_EQ(old_api_map_attr_val.get_type(), type); + }; + auto param = f->get_parameters()[0]; check_fused_names(param->output(0).get_rt_info(), "test1,test2"); + check_old_api_map(param->get_rt_info(), + std::vector({}), + ngraph::element::Type_t::u8); auto result = f->get_results()[0]; check_fused_names(result->input(0).get_rt_info(), "test5,test6"); diff --git a/inference-engine/tests/functional/inference_engine/ir_serialization/rt_info_serialization.cpp b/inference-engine/tests/functional/inference_engine/ir_serialization/rt_info_serialization.cpp index 9187eb0c01f24d..a9e811dfd0ad9d 100644 --- a/inference-engine/tests/functional/inference_engine/ir_serialization/rt_info_serialization.cpp +++ b/inference-engine/tests/functional/inference_engine/ir_serialization/rt_info_serialization.cpp @@ -34,6 +34,8 @@ TEST_F(RTInfoSerializationTest, all_attributes_latest) { std::make_shared>(ngraph::FusedNames("add")); info[ov::PrimitivesPriority::get_type_info_static()] = std::make_shared("priority"); + info[ov::OldApiMap::get_type_info_static()] = std::make_shared( + ov::OldApiMapAttr(std::vector{0, 2, 3, 1}, ngraph::element::Type_t::f32)); }; std::shared_ptr function; @@ -67,6 +69,14 @@ TEST_F(RTInfoSerializationTest, all_attributes_latest) { auto primitives_priority_attr = std::dynamic_pointer_cast(info.at(pkey)); ASSERT_TRUE(primitives_priority_attr); ASSERT_EQ(primitives_priority_attr->get(), "priority"); + + const std::string & old_api_map_key = ov::OldApiMap::get_type_info_static(); + ASSERT_TRUE(info.count(old_api_map_key)); + auto old_api_map_attr = std::dynamic_pointer_cast(info.at(old_api_map_key)); + ASSERT_TRUE(old_api_map_attr); + auto old_api_map_attr_val = old_api_map_attr->get(); + ASSERT_EQ(old_api_map_attr_val.get_order(), std::vector({0, 2, 3, 1})); + ASSERT_EQ(old_api_map_attr_val.get_type(), ngraph::element::Type_t::f32); }; auto add = f->get_results()[0]->get_input_node_ptr(0); diff --git a/ngraph/frontend/ir/src/rt_info_deserializer.hpp b/ngraph/frontend/ir/src/rt_info_deserializer.hpp index fbe181c9cc2bd7..de9c708b78d5cb 100644 --- a/ngraph/frontend/ir/src/rt_info_deserializer.hpp +++ b/ngraph/frontend/ir/src/rt_info_deserializer.hpp @@ -94,6 +94,16 @@ class RTInfoDeserializer : public ngraph::AttributeVisitor { adapter.set(value); } + void on_adapter(const std::string& name, ngraph::ValueAccessor>& adapter) override { + check_attribute_name(name); + std::string val; + if (!getStrAttribute(m_node, name, val)) + return; + std::vector value; + str_to_container(val, value); + adapter.set(value); + } + void on_adapter(const std::string& name, ngraph::ValueAccessor>& adapter) override { check_attribute_name(name); std::string val;