ie_inetwork_iterator.hpp
Go to the documentation of this file.
1 // Copyright (C) 2018-2020 Intel Corporation
2 // SPDX-License-Identifier: Apache-2.0
3 //
4 
5 /**
6  * @brief A header file for the INetworkIterator class
7  * @file ie_inetwork_iterator.hpp
8  */
9 #pragma once
10 #include <ie_network.hpp>
11 #include <iterator>
12 #include <list>
13 #include <memory>
14 #include <unordered_map>
15 #include <unordered_set>
16 #include <utility>
17 #include <vector>
18 
19 namespace InferenceEngine {
20 namespace details {
21 
22 template <class NT, class LT>
23 class INFERENCE_ENGINE_NN_BUILDER_DEPRECATED INetworkIterator
24  : public std::iterator<std::input_iterator_tag, std::shared_ptr<LT>> {
25 public:
26  explicit INetworkIterator(NT* network, bool toEnd): network(network), currentIdx(0) {}
27  explicit INetworkIterator(NT* network): network(network), currentIdx(0) {
28  if (!network) return;
29  const auto& inputs = network->getInputs();
30 
31  std::vector<std::shared_ptr<LT>> allInputs;
32  for (const auto& input : inputs) {
33  allInputs.push_back(std::dynamic_pointer_cast<LT>(input));
34  }
35 
36  forestDFS(
37  allInputs,
38  [&](std::shared_ptr<LT> current) {
39  sortedLayers.push_back(current);
40  },
41  false);
42 
43  std::reverse(std::begin(sortedLayers), std::end(sortedLayers));
44  currentLayer = getNextLayer();
45  }
46 
47  IE_SUPPRESS_DEPRECATED_START
48 
49  bool operator!=(const INetworkIterator& that) const {
50  return !operator==(that);
51  }
52 
53  bool operator==(const INetworkIterator& that) const {
54  return network == that.network && currentLayer == that.currentLayer;
55  }
56 
57  typename INetworkIterator::reference operator*() {
58  if (nullptr == currentLayer) {
59  THROW_IE_EXCEPTION << "iterator out of bound";
60  }
61  return currentLayer;
62  }
63 
64  INetworkIterator& operator++() {
65  currentLayer = getNextLayer();
66  return *this;
67  }
68 
69  const INetworkIterator<NT, LT> operator++(int) {
70  INetworkIterator<NT, LT> retval = *this;
71  ++(*this);
72  return retval;
73  }
74 
75  IE_SUPPRESS_DEPRECATED_END
76 
77 private:
78  std::vector<std::shared_ptr<LT>> sortedLayers;
79  std::shared_ptr<LT> currentLayer;
80  NT* network = nullptr;
81  size_t currentIdx;
82 
83  std::shared_ptr<LT> getNextLayer() {
84  return (sortedLayers.size() > currentIdx) ? sortedLayers[currentIdx++] : nullptr;
85  }
86 
87  template <class T>
88  inline void forestDFS(const std::vector<std::shared_ptr<LT>>& heads, const T& visit, bool bVisitBefore) {
89  if (heads.empty()) {
90  return;
91  }
92 
93  std::unordered_map<idx_t, bool> visited;
94  for (auto& layer : heads) {
95  DFS(visited, layer, visit, bVisitBefore);
96  }
97  }
98 
99  template <class T>
100  inline void DFS(std::unordered_map<idx_t, bool>& visited, const std::shared_ptr<LT>& layer, const T& visit,
101  bool visitBefore) {
102  if (layer == nullptr) {
103  return;
104  }
105 
106  if (visitBefore) visit(layer);
107 
108  visited[layer->getId()] = false;
109  for (const auto& connection : network->getLayerConnections(layer->getId())) {
110  if (connection.to().layerId() == layer->getId()) {
111  continue;
112  }
113  const auto outLayer = network->getLayer(connection.to().layerId());
114  if (!outLayer) THROW_IE_EXCEPTION << "Couldn't get layer with id: " << connection.to().layerId();
115  auto i = visited.find(outLayer->getId());
116  if (i != visited.end()) {
117  /**
118  * cycle detected we entered still not completed node
119  */
120  if (!i->second) {
121  THROW_IE_EXCEPTION << "Sorting not possible, due to existed loop.";
122  }
123  continue;
124  }
125 
126  DFS(visited, outLayer, visit, visitBefore);
127  }
128  if (!visitBefore) visit(layer);
129  visited[layer->getId()] = true;
130  }
131 };
132 
133 } // namespace details
134 } // namespace InferenceEngine
#define THROW_IE_EXCEPTION
A macro used to throw the exception with a notable description.
Definition: ie_exception.hpp:25
Inference Engine API.
Definition: ie_argmax_layer.hpp:15
A header file for the Inference Engine Network interface.