1414// limitations under the License.
1515// *****************************************************************************
1616
17+ #include < functional>
1718#include < set>
1819
1920#include " graph.hpp"
@@ -25,26 +26,40 @@ namespace ngraph
2526 {
2627 namespace detail
2728 {
28- std::string to_string (const std::set<std::string>& set)
29+ static std::string to_string (
30+ const std::map<std::string, std::reference_wrapper<const onnx::NodeProto>>& map)
2931 {
3032 std::string result;
31- for (auto it = std::begin (set ); it != std::end (set ); ++it)
33+ for (auto it = std::begin (map ); it != std::end (map ); ++it)
3234 {
33- result += (it != std::begin (set ) ? " , " : " " ) + *it ;
35+ result += (it != std::begin (map ) ? " , " : " " ) + it-> first ;
3436 }
3537 return result;
3638 }
3739
38- inline std::string to_string (const onnx::NodeProto& node_proto)
40+ static std::string get_node_domain (const onnx::NodeProto& node_proto)
3941 {
40- return (node_proto.domain ().empty () ? " " : node_proto.domain () + " ." ) +
41- node_proto.op_type ();
42+ return (node_proto.domain ().empty () ? " " : node_proto.domain ());
4243 }
43- }
4444
45- Graph::Graph (const onnx::GraphProto& graph_proto,
46- const Model& model,
47- const Weights& weights)
45+ // / \brief Gets the operator represented by provided node unique identificator.
46+ // /
47+ // / \param[in] node_proto The node protobuf representation object.
48+ // /
49+ // / \note The operator is uniquely identified by the tuple (domain, op_type,
50+ // / since_version). The first two elements are stored in NodeProto object,
51+ // / thus we use only them.
52+ // /
53+ // / \return The unique identificator.
54+ // /
55+ static std::string get_op_domain_and_name (const onnx::NodeProto& node_proto)
56+ {
57+ std::string domain = get_node_domain (node_proto);
58+ return (domain.empty () ? " " : domain + " ." ) + node_proto.op_type ();
59+ }
60+ } // namespace detail
61+
62+ Graph::Graph (const onnx::GraphProto& graph_proto, Model& model, const Weights& weights)
4863 : m_graph_proto{&graph_proto}
4964 , m_model{&model}
5065 {
@@ -70,17 +85,34 @@ namespace ngraph
7085 }
7186
7287 // Verify that ONNX graph contains only nodes of available operator types
73- std::set <std::string> unknown_operator_types ;
88+ std::map <std::string, std::reference_wrapper< const onnx::NodeProto>> unknown_operators ;
7489 for (const auto & node_proto : m_graph_proto->node ())
7590 {
7691 if (!m_model->is_operator_available (node_proto))
7792 {
78- unknown_operator_types.emplace (detail::to_string (node_proto));
93+ unknown_operators.emplace (detail::get_op_domain_and_name (node_proto),
94+ node_proto);
95+ // Try adding missing domain
96+ m_model->enable_opset_domain (detail::get_node_domain (node_proto));
97+ }
98+ }
99+
100+ // Reverify wheter we still have any unavailable operators.
101+ auto it = std::begin (unknown_operators);
102+ while (it != std::end (unknown_operators))
103+ {
104+ if (m_model->is_operator_available (it->second ))
105+ {
106+ it = unknown_operators.erase (it);
107+ }
108+ else
109+ {
110+ it++;
79111 }
80112 }
81113
82- NGRAPH_ASSERT (unknown_operator_types .empty ())
83- << " unknown operations: " << detail::to_string (unknown_operator_types );
114+ NGRAPH_ASSERT (unknown_operators .empty ()) << " unknown operations: "
115+ << detail::to_string (unknown_operators );
84116
85117 // Process ONNX graph nodes, convert to nGraph nodes
86118 for (const auto & node_proto : m_graph_proto->node ())
0 commit comments