Publishing R5 content (#72)
[platform/upstream/dldt.git] / inference-engine / src / inference_engine / ie_util_internal.hpp
1 // Copyright (C) 2018 Intel Corporation
2 // SPDX-License-Identifier: Apache-2.0
3 //
4
5 #ifndef IE_UTIL_HPP
6 #define IE_UTIL_HPP
7
8 #include <vector>
9 #include <functional>
10 #include <deque>
11 #include <unordered_set>
12 #include <utility>
13 #include <string>
14
15 #include <cpp/ie_cnn_network.h>
16 #include <cnn_network_impl.hpp>
17 #include <tuple>
18 #include <type_traits>
19
20
21 namespace InferenceEngine {
22
23 /**
24  * @brief Simple helper function to check element presence in container
25  * container must provede stl-compliant find member function
26  *
27  * @param container - Container to check
28  * @param element - element to check
29  *
30  * @return true if element present in container
31  */
32 template<typename C, typename T>
33 bool contains(const C& container, const T& element) {
34     return container.find(element) != container.end();
35 }
36
37 /**
38  * @brief checks that given type is one of specified in variadic template list
39  * @tparam ...
40  */
41 template <typename...>
42 struct is_one_of {
43     static constexpr bool value = false;
44 };
45
46 /**
47  * @brief checks that given type is one of specified in variadic template list
48  * @tparam ...
49  */
50 template <typename F, typename S, typename... T>
51 struct is_one_of<F, S, T...> {
52     static constexpr bool value =
53         std::is_same<F, S>::value || is_one_of<F, T...>::value;
54 };
55
56
57
58 /**
59  * @brief Split graph into subgraphs using provided splitter object
60  *
61  * @param network - Source network
62  * @param splitter - Splitter object, take two adjacent layers, must return true
63  * if layers must go to different subgraphs
64  *
65  * @return list of subgraphs
66  */
67 INFERENCE_ENGINE_API_CPP(std::vector<std::vector<InferenceEngine::CNNLayerPtr>>)
68 groupSubgraphs(InferenceEngine::ICNNNetwork& network,
69                std::function<bool(const InferenceEngine::CNNLayerPtr&,
70                                   const InferenceEngine::CNNLayerPtr&)> splitter);
71
72 /**
73  * @brief Creates data object copy unconnected to any graph
74  * @param source - source data object
75  * @return Shared pointer to new data object
76  */
77 INFERENCE_ENGINE_API_CPP(DataPtr) cloneData(const Data& source);
78
79 /**
80  * @brief Creates layer object copy, unconnected to any grapoh
81  * @param source - source layer object
82  * @return Shared pointer to new layer object
83  */
84 INFERENCE_ENGINE_API_CPP(CNNLayerPtr) clonelayer(const CNNLayer& source);
85
86 /**
87  * @brief Clones selected set of nodes into separate network
88  * only connections between passed nodes will be duplicated
89  *
90  * @param layers - layers to clone, must all be in same network
91  * @param layerCloner - layer cloning functor
92  *
93  * @return Cloned network
94  */
95 INFERENCE_ENGINE_API_CPP(InferenceEngine::details::CNNNetworkImplPtr)
96 cloneNet(const std::vector<InferenceEngine::CNNLayerPtr>& layers,
97          std::function<CNNLayerPtr(const CNNLayer&)> layerCloner = clonelayer);
98
99 /**
100  * Clones the whole network. All layers and data objects will be cloned
101  *
102  * Blobs inside layers are reused
103  * */
104 INFERENCE_ENGINE_API_CPP(InferenceEngine::details::CNNNetworkImplPtr)
105 cloneNet(const InferenceEngine::ICNNNetwork &network);
106
107 namespace traverse {
108
109 INFERENCE_ENGINE_API_CPP(void)
110 forward(const InferenceEngine::CNNLayerPtr& layer, std::deque<InferenceEngine::CNNLayerPtr>& layers);
111
112 INFERENCE_ENGINE_API_CPP(void)
113 backward(const InferenceEngine::CNNLayerPtr& layer, std::deque<InferenceEngine::CNNLayerPtr>& layers);
114
115 template<class T>
116 void traverse(T& inputs,
117               std::function<void(InferenceEngine::CNNLayerPtr& layer)> apply,
118               std::function<void(const InferenceEngine::CNNLayerPtr& layer, std::deque<InferenceEngine::CNNLayerPtr>& layers)> expand = forward) {
119     std::unordered_set<InferenceEngine::CNNLayerPtr> visitedObjects;
120     std::deque<InferenceEngine::CNNLayerPtr>         layersToCheck;
121
122     layersToCheck.insert(layersToCheck.end(), inputs.begin(), inputs.end());
123
124     while (!layersToCheck.empty()) {
125         auto& layer = layersToCheck.front();
126         if (visitedObjects.insert(layer).second) {
127             apply(layer);
128             expand(layer, layersToCheck);
129         }
130         layersToCheck.pop_front();
131     }
132 }
133
134 INFERENCE_ENGINE_API_CPP(void)
135 traverse(InferenceEngine::ICNNNetwork& network,
136          std::function<void(InferenceEngine::CNNLayerPtr& layer)> apply,
137          std::function<void(const InferenceEngine::CNNLayerPtr& layer,
138          std::deque<InferenceEngine::CNNLayerPtr>& layers)> expand = forward);
139
140 }  // namespace traverse
141
142 using ordered_properties = std::vector<std::pair<std::string, std::string>>;
143 using printer_callback = std::function<void(const InferenceEngine::CNNLayerPtr,
144                                             ordered_properties &,
145                                             ordered_properties &)>;
146
147 /**
148  * @brief Visualize network in GraphViz (.dot) format and write to output stream
149  *
150  * @param network - graph to visualize
151  * @param out - output stream for saving graph
152  * @param layer_cb - callback function, that called on every printed layer node
153  */
154 INFERENCE_ENGINE_API_CPP(void) saveGraphToDot(InferenceEngine::ICNNNetwork &network, std::ostream &out, printer_callback layer_cb = nullptr);
155
156 /**
157   @brief Return root data objects, i.e. objects came from input or const layers
158
159   @param network - network to process
160
161   @return set of root data objects,
162   */
163 INFERENCE_ENGINE_API_CPP(std::unordered_set<DataPtr>)
164 getRootDataObjects(ICNNNetwork &network);
165
166 }  // namespace InferenceEngine
167
168 #endif  // IE_UTIL_HPP