diff --git a/inference-engine/src/readers/ir_reader/ie_ir_parser.cpp b/inference-engine/src/readers/ir_reader/ie_ir_parser.cpp index c3e405a7beb922..34ff1d8b2ba9a3 100644 --- a/inference-engine/src/readers/ir_reader/ie_ir_parser.cpp +++ b/inference-engine/src/readers/ir_reader/ie_ir_parser.cpp @@ -47,33 +47,34 @@ IRParser::IRParser(size_t version, const std::vector V10Parser::XmlDeserializer::map_type_in_function(const pugi::xml_node& node, - const std::string map_type) { - std::map type_id_in_function; - uint64_t map_type_number = 0; +V10Parser::XmlDeserializer::IoMap V10Parser::XmlDeserializer::updated_io_map(const pugi::xml_node& node) { auto body_node = node.child("body"); if (body_node.empty()) { THROW_IE_EXCEPTION << "Missing body part."; } - // Fill map: parameter/result id to parameter/result number in Function + + auto extend_io_map = io_map; + FOREACH_CHILD(layer, body_node.child("layers"), "layer") { auto type = XMLParseUtils::GetStrAttr(layer, "type"); - if (type == map_type) { + if (type == "Parameter") { + auto id = XMLParseUtils::GetUIntAttr(layer, "id"); + extend_io_map.inputs.insert({id, -1}); // try add as unconnected + } else if (type == "Result") { auto id = XMLParseUtils::GetUIntAttr(layer, "id"); - type_id_in_function.emplace(id, map_type_number); - map_type_number++; + extend_io_map.outputs.insert({id, -1}); // try add as unconnected } } - return type_id_in_function; + return extend_io_map; } + std::vector> V10Parser::XmlDeserializer::parseInputDescription(const pugi::xml_node& node) { std::vector> inputs; - std::map param_id_in_function = map_type_in_function(node, "Parameter"); - std::map result_id_in_function = map_type_in_function(node, "Result"); + const auto up_io_map = updated_io_map(node); // Parse PortMap: external_port_id for inputs does not always appear in consecutive order std::map input_map; @@ -96,9 +97,11 @@ std::vector> V10 int64_t end = XMLParseUtils::GetInt64Attr(xml_input, "end", -1); int64_t part_size = XMLParseUtils::GetInt64Attr(xml_input, "part_size", 1); + const auto input_index = up_io_map.inputs.at(body_parameter_index); + inputs.push_back(std::make_shared (ti_input_index, - param_id_in_function[body_parameter_index], + input_index, start, stride, part_size, @@ -112,10 +115,14 @@ std::vector> V10 if (to_layer == body_parameter_index) { size_t from_layer = XMLParseUtils::GetUIntAttr(xml_edge, "from-layer"); + + const auto input_index = up_io_map.inputs.at(body_parameter_index); + const auto output_index = up_io_map.outputs.at(from_layer); + inputs.push_back(std::make_shared (ti_input_index, - param_id_in_function[body_parameter_index], - result_id_in_function[from_layer])); + input_index, + output_index)); is_back_edge_exist = true; break; @@ -125,9 +132,11 @@ std::vector> V10 // ti_input_index = -1 means that Parameter of the body is not connected to inputs of TensorIterator // and is used only for internal needs. if (!is_back_edge_exist && ti_input_index >= 0) { + const auto input_index = up_io_map.inputs.at(body_parameter_index); + inputs.push_back(std::make_shared (ti_input_index, - param_id_in_function[body_parameter_index])); + input_index)); } } } @@ -136,7 +145,7 @@ std::vector> V10 std::vector> V10Parser::XmlDeserializer::parseOutputDescription(const pugi::xml_node& node) { std::vector> outputs; - std::map result_id_in_function = map_type_in_function(node, "Result"); + const auto up_io_map = updated_io_map(node); // Parse PortMap: outputs std::map output_map; @@ -162,8 +171,10 @@ std::vector> V1 int64_t end = XMLParseUtils::GetInt64Attr(xml_output, "end", -1); int64_t part_size = XMLParseUtils::GetInt64Attr(xml_output, "part_size", 1); + const auto output_index = up_io_map.outputs.at(body_result_index); + outputs.push_back(std::make_shared - (result_id_in_function[body_result_index], + (output_index, output_number, start, stride, @@ -172,8 +183,10 @@ std::vector> V1 axis)); } else { // otherwise create ngraph::TensorIterator::BodyOutput. -1 means last iteration. + const auto output_index = up_io_map.outputs.at(body_result_index); + outputs.push_back(std::make_shared - (result_id_in_function[body_result_index], + (output_index, output_number, -1)); } @@ -185,10 +198,10 @@ std::vector> V1 ngraph::op::v5::Loop::SpecialBodyPorts V10Parser::XmlDeserializer::parsePurposeAttribute(const pugi::xml_node& node) { ngraph::op::v5::Loop::SpecialBodyPorts result = {-1, -1}; - std::map params = map_type_in_function(node, "Parameter"); - std::map results = map_type_in_function(node, "Result"); + const auto up_io_map = updated_io_map(node); - NGRAPH_CHECK(!params.empty() || !results.empty(), "No parameters or results found in body Function."); + NGRAPH_CHECK(!up_io_map.inputs.empty() || !up_io_map.outputs.empty(), + "No parameters or results found in body Function."); // Parse PortMap: external_port_id for inputs/outputs does not always appear in consecutive order std::map input_map; @@ -207,7 +220,7 @@ ngraph::op::v5::Loop::SpecialBodyPorts V10Parser::XmlDeserializer::parsePurposeA auto purpose = XMLParseUtils::GetStrAttr(xml_input, "purpose", ""); size_t body_parameter_index = XMLParseUtils::GetUIntAttr(xml_input, "internal_layer_id"); if (purpose == "current_iteration") { - result.current_iteration_input_idx = params[body_parameter_index]; + result.current_iteration_input_idx = up_io_map.inputs.at(body_parameter_index); } } @@ -216,7 +229,7 @@ ngraph::op::v5::Loop::SpecialBodyPorts V10Parser::XmlDeserializer::parsePurposeA auto purpose = XMLParseUtils::GetStrAttr(xml_output, "purpose", ""); size_t body_parameter_index = XMLParseUtils::GetUIntAttr(xml_output, "internal_layer_id"); if (purpose == "execution_condition") { - result.body_condition_output_idx = results[body_parameter_index]; + result.body_condition_output_idx = up_io_map.outputs.at(body_parameter_index); } } @@ -316,13 +329,18 @@ void V10Parser::XmlDeserializer::on_adapter(const std::string& name, ngraph::Val adapter.set(ngraph_function); } + std::shared_ptr V10Parser::XmlDeserializer::parse_function(const pugi::xml_node& root, const Blob::CPtr& weights) { OV_ITT_TASK_CHAIN(taskChain, itt::domains::V10Reader_RT, "V10Parser", "Parse"); - using node_params = struct { + struct edge { + size_t fromLayerId, fromPortId, toPortId; + }; + struct node_params { pugi::xml_node xml; GenericLayerParams params; }; + std::map params; std::vector outputs; @@ -340,7 +358,6 @@ std::shared_ptr V10Parser::XmlDeserializer::parse_function(con } } - using edge = struct { size_t fromLayerId, fromPortId, toPortId; }; std::map> edges; std::map> id_to_node; @@ -408,10 +425,12 @@ std::shared_ptr V10Parser::XmlDeserializer::parse_function(con // } if (const auto& parameter_node = std::dynamic_pointer_cast(node)) { + io_map.inputs.insert({layer_id, parameter_nodes.size()}); parameter_nodes.emplace_back(parameter_node); } if (const auto& result_node = std::dynamic_pointer_cast(node)) { + io_map.outputs.insert({layer_id, result_nodes.size()}); result_nodes.emplace_back(result_node); } diff --git a/inference-engine/src/readers/ir_reader/ie_ir_parser.hpp b/inference-engine/src/readers/ir_reader/ie_ir_parser.hpp index 89a40549975c5f..e00af4cccb228f 100644 --- a/inference-engine/src/readers/ir_reader/ie_ir_parser.hpp +++ b/inference-engine/src/readers/ir_reader/ie_ir_parser.hpp @@ -183,10 +183,14 @@ class V10Parser : public IParser { class XmlDeserializer : public ngraph::AttributeVisitor { public: - explicit XmlDeserializer(const pugi::xml_node& node, const Blob::CPtr& weights, - const std::unordered_map& opsets, - std::unordered_map>& variables) - : node(node), weights(weights), opsets(opsets), variables(variables) {} + /// TODO: move whole class to src file + explicit XmlDeserializer( + const pugi::xml_node& node, + const Blob::CPtr& weights, + const std::unordered_map& opsets, + std::unordered_map>& variables) + : node(node), weights(weights), opsets(opsets), variables(variables) {} + void on_adapter(const std::string& name, ngraph::ValueAccessor& value) override { std::string val; if (!getStrAttribute(node.child("data"), name, val)) return; @@ -288,11 +292,26 @@ class V10Parser : public IParser { adapter.set(value); } + private: + struct IoMap { + using NodeIdToIoIndex = std::unordered_map; + NodeIdToIoIndex inputs; + NodeIdToIoIndex outputs; + }; + + //TODO move data to the bottom (or top) const pugi::xml_node node; const Blob::CPtr& weights; const std::unordered_map& opsets; std::unordered_map>& variables; + + /// + /// store information about parameters/results order during function creation + /// it will be used during Inputs/Outputs Description creation in SubGraph processing + /// + IoMap io_map; + /// \brief Traverses port_map in order to create vector of InputDescription shared_ptrs. /// Shall be used only for ops which have port_map attribute. /// \param node xml op representation @@ -303,12 +322,10 @@ class V10Parser : public IParser { /// \param node xml op representation std::vector> parseOutputDescription( const pugi::xml_node& node); - /// \brief Traverses nGraph body function for specified op type and creates a map of all - /// op iterations. Map constains type id and assigned to it consecutive number starting from 0. - /// \param node xml op representation - /// \param type op type name to find - /// \return map container - std::map map_type_in_function(const pugi::xml_node& node, std::string type); + + //TODO consider to call only once per layer/TI-Loop node + IoMap updated_io_map(const pugi::xml_node& node); + /// \brief Traverses xml node representation in order to create nGraph function for it. /// \param node xml node representation /// \param weights weights attached to current node diff --git a/inference-engine/tests/functional/inference_engine/ir_serialization/models/ti_resnet.xml b/inference-engine/tests/functional/inference_engine/ir_serialization/models/ti_resnet.xml index f35e6346e3936b..c79a1ebc5abfd4 100644 --- a/inference-engine/tests/functional/inference_engine/ir_serialization/models/ti_resnet.xml +++ b/inference-engine/tests/functional/inference_engine/ir_serialization/models/ti_resnet.xml @@ -74,16 +74,11 @@ - - - - - 1 - 1 - 512 - - - + @@ -193,6 +188,15 @@ + + + + 1 + 1 + 512 + + + @@ -236,14 +240,15 @@ - - - + + + + 1 1 512 - + @@ -297,4 +302,4 @@ - \ No newline at end of file +