6
6
#include " hetero_executable_network.hpp"
7
7
#include " hetero_async_infer_request.hpp"
8
8
#include " hetero_itt.hpp"
9
+ #include " ie_precision.hpp"
10
+ #include " openvino/core/dimension.hpp"
11
+ #include " openvino/core/except.hpp"
12
+ #include " openvino/core/type.hpp"
13
+ #include " openvino/core/type/element_type.hpp"
14
+ #include " openvino/op/result.hpp"
15
+ #include " transformations/utils/utils.hpp"
16
+ #include " openvino/op/parameter.hpp"
9
17
#include " xml_parse_utils.h"
10
18
#include < caseless.hpp>
11
19
@@ -63,6 +71,7 @@ HeteroExecutableNetwork::HeteroExecutableNetwork(const InferenceEngine::CNNNetwo
63
71
#ifndef NDEBUG
64
72
dumpDotFile = true ;
65
73
#endif
74
+
66
75
QueryNetworkResult queryNetworkResult;
67
76
auto orderedOps = clonedFunction->get_ordered_ops ();
68
77
bool allEmpty = true ;
@@ -548,6 +557,44 @@ HeteroExecutableNetwork::HeteroExecutableNetwork(std::istream&
548
557
});
549
558
}
550
559
560
+ const auto parseNode = [] (const pugi::xml_node & xml_node, bool is_param) ->
561
+ std::shared_ptr<const ov::Node> {
562
+ const std::string operation_name = GetStrAttr (xml_node, " operation_name" );
563
+ const auto elementType =
564
+ ov::EnumNames<ov::element::Type_t>::as_enum (GetStrAttr (xml_node, " element_type" ));
565
+
566
+ std::vector<ov::Dimension> partialShape;
567
+ pugi::xml_node partialShapeNode = xml_node.child (" partial_shape" );
568
+ FOREACH_CHILD (dimNode, partialShapeNode, " dim" ) {
569
+ partialShape.emplace_back (ov::Dimension (GetInt64Attr (dimNode, " value" )));
570
+ }
571
+
572
+ pugi::xml_node tensorNamesNode = xml_node.child (" tensor_names" );
573
+ std::unordered_set<std::string> tensorNames;
574
+ FOREACH_CHILD (tensorNameNode, tensorNamesNode, " tensor_name" ) {
575
+ tensorNames.insert (GetStrAttr (tensorNameNode, " value" ));
576
+ }
577
+
578
+ std::shared_ptr<ov::Node> node = std::make_shared<ov::op::v0::Parameter>(elementType, partialShape);
579
+ if (!is_param)
580
+ node = std::make_shared<ov::op::v0::Result>(node);
581
+ node->set_friendly_name (operation_name);
582
+ node->output (0 ).get_tensor ().add_names (tensorNames);
583
+
584
+ return node;
585
+ };
586
+ (void )parseNode;
587
+
588
+ pugi::xml_node parametersNode = heteroNode.child (" parameters" );
589
+ FOREACH_CHILD (parameterNode, parametersNode, " parameter" ) {
590
+ _parameters.emplace_back (parseNode (parameterNode, true ));
591
+ }
592
+
593
+ pugi::xml_node resultsNode = heteroNode.child (" results" );
594
+ FOREACH_CHILD (resultNode, resultsNode, " result" ) {
595
+ _results.emplace_back (parseNode (resultNode, false ));
596
+ }
597
+
551
598
// save state
552
599
this ->_config = importedConfigs;
553
600
this ->_networks = std::move (descs);
@@ -559,6 +606,8 @@ void HeteroExecutableNetwork::Export(std::ostream& heteroModel) {
559
606
auto heteroNode = doc.append_child (" hetero" );
560
607
heteroNode.append_attribute (" name" ).set_value (_name.c_str ());
561
608
609
+ // CNNNetwork inputs and outputs information
610
+
562
611
auto inputsNode = heteroNode.append_child (" inputs" );
563
612
for (auto && networkInput : _networkInputs) {
564
613
inputsNode.append_child (" input" ).append_attribute (" name" ).set_value (networkInput.first .c_str ());
@@ -569,6 +618,46 @@ void HeteroExecutableNetwork::Export(std::ostream& heteroModel) {
569
618
outputsNode.append_child (" output" ).append_attribute (" name" ).set_value (networkInput.first .c_str ());
570
619
}
571
620
621
+ const auto serializeNode = [&] (const std::shared_ptr<const ov::Node>& node,
622
+ pugi::xml_node & xml_node) {
623
+ const bool is_result = ov::is_type<ov::op::v0::Result>(node);
624
+ const std::string name = is_result ?
625
+ ngraph::op::util::create_ie_output_name (node->input_value (0 )) :
626
+ node->get_friendly_name ();
627
+ xml_node.append_attribute (" operation_name" ).set_value (name.c_str ());
628
+ xml_node.append_attribute (" element_type" ).set_value (
629
+ node->get_output_element_type (0 ).get_type_name ().c_str ());
630
+
631
+ const auto & pShape = node->get_output_partial_shape (0 );
632
+ OPENVINO_ASSERT (pShape.rank ().is_static (), " Serialization of shapes with dynamic rank is not supported" );
633
+ auto partialShapeNode = xml_node.append_child (" partial_shape" );
634
+ for (auto && dim : node->get_output_partial_shape (0 )) {
635
+ if (dim.is_dynamic ())
636
+ partialShapeNode.append_child (" dim" ).append_attribute (" value" ).set_value (" -1" );
637
+ else
638
+ partialShapeNode.append_child (" dim" ).append_attribute (" value" ).set_value (std::to_string (dim.get_length ()).c_str ());
639
+ }
640
+
641
+ auto tensorNamesNode = xml_node.append_child (" tensor_names" );
642
+ for (auto & tensorName : node->get_output_tensor (0 ).get_names ()) {
643
+ tensorNamesNode.append_child (" tensor_name" ).append_attribute (" value" ).set_value (tensorName.c_str ());
644
+ }
645
+ };
646
+
647
+ // ngraph parameters info
648
+ auto subnetworkParamsNode = heteroNode.append_child (" parameters" );
649
+ for (auto && parameter : getInputs ()) {
650
+ auto parameterNode = subnetworkParamsNode.append_child (" parameter" );
651
+ serializeNode (parameter, parameterNode);
652
+ }
653
+
654
+ // ngraph results info
655
+ auto subnetworkResultsNode = heteroNode.append_child (" results" );
656
+ for (auto && result : getOutputs ()) {
657
+ auto parameterNode = subnetworkResultsNode.append_child (" result" );
658
+ serializeNode (result, parameterNode);
659
+ }
660
+
572
661
auto subnetworksNode = heteroNode.append_child (" subnetworks" );
573
662
for (auto && subnetwork : _networks) {
574
663
auto subnet = subnetwork._clonedNetwork ;
0 commit comments