Publishing 2019 R1 content
[platform/upstream/dldt.git] / inference-engine / src / inference_engine / ie_util_internal.hpp
1 // Copyright (C) 2018-2019 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          const ICNNNetworkStats* networkStats,
98          std::function<CNNLayerPtr(const CNNLayer&)> layerCloner = clonelayer);
99
100 /**
101  * Clones the whole network. All layers and data objects will be cloned
102  *
103  * Blobs inside layers are reused
104  * */
105 INFERENCE_ENGINE_API_CPP(InferenceEngine::details::CNNNetworkImplPtr)
106 cloneNet(const InferenceEngine::ICNNNetwork &network);
107
108 namespace traverse {
109
110 INFERENCE_ENGINE_API_CPP(void)
111 forward(const InferenceEngine::CNNLayerPtr& layer, std::deque<InferenceEngine::CNNLayerPtr>& layers);
112
113 INFERENCE_ENGINE_API_CPP(void)
114 backward(const InferenceEngine::CNNLayerPtr& layer, std::deque<InferenceEngine::CNNLayerPtr>& layers);
115
116 template<class T>
117 void traverse(T& inputs,
118               std::function<void(InferenceEngine::CNNLayerPtr& layer)> apply,
119               std::function<void(const InferenceEngine::CNNLayerPtr& layer, std::deque<InferenceEngine::CNNLayerPtr>& layers)> expand = forward) {
120     std::unordered_set<InferenceEngine::CNNLayerPtr> visitedObjects;
121     std::deque<InferenceEngine::CNNLayerPtr>         layersToCheck;
122
123     layersToCheck.insert(layersToCheck.end(), inputs.begin(), inputs.end());
124
125     while (!layersToCheck.empty()) {
126         auto& layer = layersToCheck.front();
127         if (visitedObjects.insert(layer).second) {
128             apply(layer);
129             expand(layer, layersToCheck);
130         }
131         layersToCheck.pop_front();
132     }
133 }
134
135 INFERENCE_ENGINE_API_CPP(void)
136 traverse(InferenceEngine::ICNNNetwork& network,
137          std::function<void(InferenceEngine::CNNLayerPtr& layer)> apply,
138          std::function<void(const InferenceEngine::CNNLayerPtr& layer,
139          std::deque<InferenceEngine::CNNLayerPtr>& layers)> expand = forward);
140
141 }  // namespace traverse
142
143 using ordered_properties = std::vector<std::pair<std::string, std::string>>;
144 using printer_callback = std::function<void(const InferenceEngine::CNNLayerPtr,
145                                             ordered_properties &,
146                                             ordered_properties &)>;
147
148 /**
149  * @brief Visualize network in GraphViz (.dot) format and write to output stream
150  *
151  * @param network - graph to visualize
152  * @param out - output stream for saving graph
153  * @param layer_cb - callback function, that called on every printed layer node
154  */
155 INFERENCE_ENGINE_API_CPP(void) saveGraphToDot(InferenceEngine::ICNNNetwork &network, std::ostream &out, printer_callback layer_cb = nullptr);
156
157 /**
158   @brief Return root data objects, i.e. objects came from input or const layers
159
160   @param network - network to process
161
162   @return set of root data objects,
163   */
164 INFERENCE_ENGINE_API_CPP(std::unordered_set<DataPtr>)
165 getRootDataObjects(ICNNNetwork &network);
166
167 }  // namespace InferenceEngine
168
169 #endif  // IE_UTIL_HPP