Publishing 2019 R1 content
[platform/upstream/dldt.git] / inference-engine / src / inference_engine / shape_infer / ie_reshape_launcher.hpp
1 // Copyright (C) 2018-2019 Intel Corporation
2 // SPDX-License-Identifier: Apache-2.0
3 //
4
5 #pragma once
6
7 #include <string>
8 #include <vector>
9 #include <list>
10 #include <map>
11 #include <set>
12 #include <memory>
13
14 #include <ie_layers.h>
15 #include "shape_infer/const_infer/ie_const_infer_impl.hpp"
16 #include "shape_infer/built-in/ie_built_in_holder.hpp"
17
18 namespace InferenceEngine {
19 namespace ShapeInfer {
20
21 class InputController;
22
23 class OutputController;
24
25 class DefaultInitializer {
26 public:
27     using Ptr = std::shared_ptr<DefaultInitializer>;
28
29     virtual void check(const CNNLayer* layer, const IShapeInferImpl::Ptr& impl);
30
31     virtual InputController* createInputController(const CNNLayer* layer);
32
33     virtual OutputController* createOutputController(const CNNLayer* layer);
34
35     virtual ~DefaultInitializer() = default;
36 };
37
38 /**
39  * @class ReshapeLauncher
40  * @brief Helper class to infer shapes for the given CNNLayer by using specified implementation.
41  * Encapsulate input and output shapes, before applying it to the real CNNLayer and Data.
42  */
43 class ReshapeLauncher {
44 public:
45     using Ptr = std::shared_ptr<ReshapeLauncher>;
46
47     /**
48      * @brief constructor
49      * @param layer - const pointer to the layer for performing shape inference.
50      * It is used to obtain parameters, input/output shapes.
51      * @param impl - implementation of shape inference for the given layer
52      */
53     ReshapeLauncher(const CNNLayer* layer, const IShapeInferImpl::Ptr& impl,
54                     const DefaultInitializer::Ptr& initializer = std::make_shared<DefaultInitializer>());
55
56     virtual ~ReshapeLauncher();
57
58     /**
59      * @brief Set input shape for current reshape launcher.
60      * @param shape - input shape to be set
61      */
62     virtual void setShapeByName(const SizeVector& shape, const std::string& dataName);
63
64     virtual void setBlobByName(const Blob::CPtr& blob, const std::string& dataName);
65
66     /**
67      * @brief Return calculated shape for data with requested name.
68      * @return Result shape
69      */
70     virtual SizeVector getShapeByName(const std::string& dataName);
71
72     /**
73      * @brief Set input shape from IR by Data name. If there's no Data with given name it throws exception
74      * @param dataName - name of the corresponding Data.
75      */
76     virtual void setIRShapeByName(const std::string& dataName);
77
78     /**
79      * @brief Calculates output shapes and changed layer params using input shapes that was set
80      * @param resp Pointer to the response message that holds a description of an error if any occurred
81      * @param launchers - Map of pairs: layer name and its reshape launcher.
82      * @return Status code of the operation. OK if succeeded
83      */
84     virtual void reshape(const std::set<ReshapeLauncher::Ptr>& launchers);
85
86     virtual void constInfer(const std::set<ReshapeLauncher::Ptr>& launchers);
87
88     /**
89      * @brief Apply new input shapes, calculated output shapes and changed layer's params to CNNLayer and Data.
90      * @param layer - pointer to the layer for setting changes in layer's params
91      */
92     virtual void applyChanges(CNNLayer* layer);
93
94     /**
95      * @brief Reset all stored to the initial state: input/output shapes and layer's params.
96      * @param layer - pointer to the layer for setting changes in layer's params
97      */
98     virtual void reset();
99
100     virtual std::string getLayerName() const;
101
102     virtual std::string getLayerType() const;
103
104     virtual const CNNLayer* getLayer() const;
105
106     virtual void setShapeInferImpl(const IShapeInferImpl::Ptr& impl);
107
108 protected:
109     InputController* _iController = nullptr;
110     OutputController* _oController = nullptr;
111     const CNNLayer* _layer;
112     IShapeInferImpl::Ptr _reshapeImpl;
113     IConstInferImpl::Ptr _inferImpl;
114
115 protected:
116     /**
117      * @brief Check that all shape infer operations were done with specified layer.
118      * @param layer - pointer to the layer to compare with
119      */
120     void checkLayer(CNNLayer* layer);
121 };
122
123 class FakeInitializer : public DefaultInitializer {
124 public:
125     void check(const CNNLayer* layer, const IShapeInferImpl::Ptr& impl) override;
126
127     InputController* createInputController(const CNNLayer* layer) override;
128
129     OutputController* createOutputController(const CNNLayer* layer) override;
130 };
131
132 /**
133  * @class FakeReshapeLauncher
134  * @brief Helper class to infer shapes for layers without registered shape infer functions.
135  * Encapsulates input and output shapes, before applying it to the real CNNLayer and Data.
136  * If input shape is the same as in IR, it takes output shape from IR as is.
137  * It sets batch size to the first output dimension of all outputs if:
138  *      1) first dimension of all input layers should be the same (assume this is batch size)
139  *      2) calculated input shape of the unsupported layer is different only in a first dimension from original input shape in IR.
140  */
141 class FakeReshapeLauncher : public ReshapeLauncher {
142 public:
143     using Ptr = std::shared_ptr<FakeReshapeLauncher>;
144
145     FakeReshapeLauncher(const CNNLayer* layer, const IShapeInferImpl::Ptr& impl);
146
147     void reshape(const std::set<ReshapeLauncher::Ptr>& launchers) override;
148
149     void constInfer(const std::set<ReshapeLauncher::Ptr>& launchers) override {}
150 };
151
152 class OutputOnlyInitializer : public DefaultInitializer {
153 public:
154     void check(const CNNLayer* layer, const IShapeInferImpl::Ptr& impl) override;
155
156     InputController* createInputController(const CNNLayer* layer) override;
157
158     OutputController* createOutputController(const CNNLayer* layer) override;
159 };
160
161 /**
162  * @class OutputOnlyReshapeLauncher
163  * @brief Helper class to infer shapes for layers without inputs. It creates output controller only, input one is null.
164  */
165 class OutputOnlyReshapeLauncher : public ReshapeLauncher {
166 public:
167     using Ptr = std::shared_ptr<OutputOnlyReshapeLauncher>;
168
169     OutputOnlyReshapeLauncher(const CNNLayer* layer, const IShapeInferImpl::Ptr& impl,
170                               const OutputOnlyInitializer::Ptr& initializer = std::make_shared<OutputOnlyInitializer>());
171
172     void setShapeByName(const SizeVector& shape, const std::string& dataName) override;
173
174     void setIRShapeByName(const std::string& dataName) override;
175
176     void applyChanges(CNNLayer* layer) override;
177
178     void reset() override;
179
180     void setBlobByName(const Blob::CPtr& blob, const std::string& dataName) override;
181
182     void constInfer(const std::set<ReshapeLauncher::Ptr>& launchers) override;
183 };
184
185 class InputInitializer : public OutputOnlyInitializer {
186 public:
187     void check(const CNNLayer* layer, const IShapeInferImpl::Ptr& impl) override;
188 };
189
190 /**
191  * @class InputReshapeLauncher
192  * @brief Helper class to infer shapes for input layers. Supported layer types: `Input` or `Memory`(as inputs only, if index=1)
193  * It takes new given input shape and propagate for connected layers. If shape is not set, it takes shapes from IR.
194  */
195 class InputReshapeLauncher : public OutputOnlyReshapeLauncher {
196 public:
197     using Ptr = std::shared_ptr<InputReshapeLauncher>;
198
199     InputReshapeLauncher(const CNNLayer* layer, const IShapeInferImpl::Ptr& impl,
200                          const DefaultInitializer::Ptr& initializer = std::make_shared<InputInitializer>());
201
202     void reshape(const std::set<ReshapeLauncher::Ptr>& launchers) override;
203 };
204
205 class ConstInitializer : public OutputOnlyInitializer {
206 public:
207     void check(const CNNLayer* layer, const IShapeInferImpl::Ptr& impl) override;
208 };
209
210 /**
211  * @class ConstReshapeLauncher
212  * @brief Helper class to infer shapes for layers with Const type.
213  * It checks if new given shape is the same as in IR. The launcher fails if not and propagate for connected layers otherwise.
214  * If shape is not set, it propagates shapes from IR.
215  */
216 class ConstReshapeLauncher : public OutputOnlyReshapeLauncher {
217 public:
218     using Ptr = std::shared_ptr<InputReshapeLauncher>;
219
220     ConstReshapeLauncher(const CNNLayer* layer, const IShapeInferImpl::Ptr& impl);
221
222     void reshape(const std::set<ReshapeLauncher::Ptr>& launchers) override;
223 };
224
225 class OutMemoryInitializer : public DefaultInitializer {
226     void check(const CNNLayer* layer, const IShapeInferImpl::Ptr& impl) override;
227
228     OutputController* createOutputController(const CNNLayer* layer) override;
229 };
230
231 /**
232  * @class OutMemoryReshapeLauncher
233  * @brief Helper class to infer shapes for layers with Memory type (as outputs only, if index=0).
234  * It sets new input shapes and doesn't call propagation as this layer doesn't have childs.
235  */
236 class OutMemoryReshapeLauncher : public ReshapeLauncher {
237 public:
238     using Ptr = std::shared_ptr<InputReshapeLauncher>;
239
240     OutMemoryReshapeLauncher(const CNNLayer* layer1, const IShapeInferImpl::Ptr& impl1);
241
242     void reshape(const std::set<ReshapeLauncher::Ptr>& launchers) override {}
243
244     void applyChanges(CNNLayer* layer) override;
245
246     void reset() override;
247
248     void constInfer(const std::set<ReshapeLauncher::Ptr>& launchers) override {}
249 };
250
251 }  // namespace ShapeInfer
252 }  // namespace InferenceEngine