Publishing R3
[platform/upstream/dldt.git] / inference-engine / src / inference_engine / ie_layer_validators.hpp
1 // Copyright (C) 2018 Intel Corporation
2 //
3 // SPDX-License-Identifier: Apache-2.0
4 //
5
6 #pragma once
7
8 #include "ie_layers.h"
9 #include "caseless.hpp"
10 #include <memory>
11 #include <string>
12 #include <map>
13 #include <vector>
14
15 namespace InferenceEngine {
16 namespace details {
17
18 struct InOutDims {
19     std::vector<std::vector<size_t>> inDims;
20     std::vector<std::vector<size_t>> outDims;
21 };
22
23 /**
24  * @brief Contains methods to validate layer of specific type
25  */
26 class INFERENCE_ENGINE_API_CLASS(LayerValidator) {
27 public:
28     using Ptr = std::shared_ptr<LayerValidator>;
29
30     explicit LayerValidator(const std::string& _type) : _type(_type) {}
31
32     /**
33      * @brief It parses map of params <string,string> and applies to the layer's fields.
34      * This checks for presence of all required attributes, and that there's no extraneous parameters only.
35      * Throws exception in case of parsing error
36      */
37     virtual void parseParams(CNNLayer* layer) {}
38
39     /**
40      * @brief Validates layer parameters separately from blobs and shapes
41      * This is semantic check, like height and width more than kernel sizes, stride > 0, beta > 0, axis is correct and etc
42      * Throws exception if the check fails
43      */
44     virtual void checkParams(const CNNLayer* layer) {}
45
46     /**
47      * @brief Checks correspondence of input shapes and layer parameters.
48      * @note: This function doesn't touch ins and out Data of the layer.
49      * Throws exception if the check fails
50      */
51     virtual void checkShapes(const CNNLayer* layer,
52                              const std::vector<SizeVector>& inShapes) const {}
53
54     /**
55      * @brief Checks correspondence of all parameters in the aggregate, except output shapes.
56      * @note: This function doesn't touch ins and out Data of the layer.
57      * Throws exception if the check fails
58      */
59     virtual void checkCorrespondence(const CNNLayer* layer,
60                                      const std::map<std::string, Blob::Ptr>& blobs,
61                                      const std::vector<SizeVector>& inShapes) const {}
62
63 protected:
64     std::string _type;
65 };
66
67 /**
68  * @brief Contains all validators, registered for specific layer type
69  */
70 class INFERENCE_ENGINE_API_CLASS(LayerValidators) {
71 public:
72     static LayerValidators* getInstance();
73
74     LayerValidators(LayerValidators const&) = delete;
75
76     void operator=(LayerValidators const&)  = delete;
77
78     LayerValidator::Ptr getValidator(const std::string& type);
79
80     void addImpl(const std::string& type, const LayerValidator::Ptr& validator);
81
82 private:
83     LayerValidators() = default;
84
85 private:
86     static LayerValidators* _instance;
87     caseless_unordered_map<std::string, LayerValidator::Ptr> _validators;
88 };
89
90 static void checkWeakData(const DataWeakPtr& data) {
91 }
92
93 static void checkData(const DataPtr& data) {
94 }
95
96
97 /**
98  * @brief Checks that input Data is not empty and pointers are not null, number of inputs correspond number of input shapes, dimensions in Data are not empty
99  */
100 static void checkInputs(const CNNLayer* layer, const std::vector<SizeVector>& inShapes) {
101     // TODO: not finished implementation
102     if (layer->insData.size() != inShapes.size())
103         return THROW_IE_EXCEPTION << "Number of layer's inputs don't correspond number of new input shapes";
104
105     auto inData = layer->insData[0].lock();
106     bool isCorrect = false;
107     SizeVector inDims, inShape;
108     if (inData) {
109         inDims = inData->getDims();
110         inShape = inShapes[0];
111         isCorrect = inShape.size() == inDims.size() && !inShape.empty() && !inDims.empty();
112     }
113
114     if (!isCorrect)
115         return THROW_IE_EXCEPTION << " Failed with invalid shapes: shapes are empty"
116                                   << "new input shape size=" << inShape.size() << ", input shape size in IR="
117                                   << inDims.size();
118 }
119
120 /**
121  * @brief Checks that output Data is not empty and pointers are not null, number of outputs correspond number of output shapes, dimensions in Data are not empty
122  */
123 static void checkOutputs(const CNNLayer* layer, const std::vector<SizeVector>& outShapes) {}
124
125 static void getInOutShapes(const CNNLayer* layer, InOutDims& inOutShapes) {
126     inOutShapes.inDims.clear();
127     inOutShapes.outDims.clear();
128     if (layer) {
129         for (const auto& inData : layer->insData) {
130             auto locked = inData.lock();
131             if (locked) {
132                 inOutShapes.inDims.push_back(locked->getDims());
133             }
134         }
135         for (const auto& outData : layer->outData) {
136             if (outData) {
137                 inOutShapes.outDims.push_back(outData->getDims());
138             }
139         }
140     }
141 }
142
143 class GeneralValidator : public LayerValidator {
144 public:
145     explicit GeneralValidator(const std::string& _type);
146 };
147
148 class INFERENCE_ENGINE_API_CLASS(ConvolutionValidator) : public LayerValidator {
149 public:
150     void parseParams(CNNLayer* layer) override;
151
152     void checkParams(const CNNLayer* layer) override;
153
154     explicit ConvolutionValidator(const std::string& _type);
155
156     void checkCorrespondence(const CNNLayer* layer,
157                              const std::map<std::string, Blob::Ptr>& blobs,
158                              const std::vector<SizeVector>& inShapes) const override;
159 };
160
161 class INFERENCE_ENGINE_API_CLASS(DeconvolutionValidator) : public LayerValidator {
162 public:
163     void parseParams(CNNLayer* layer) override;
164
165     void checkParams(const CNNLayer* layer) override;
166
167     explicit DeconvolutionValidator(const std::string& _type);
168
169     void checkCorrespondence(const CNNLayer* layer,
170                              const std::map<std::string, Blob::Ptr>& blobs,
171                              const std::vector<SizeVector>& inShapes) const override;
172 };
173
174
175 class INFERENCE_ENGINE_API_CLASS(PoolingValidator) : public LayerValidator {
176 public:
177     void parseParams(CNNLayer* layer) override;
178
179     void checkParams(const CNNLayer* layer) override;
180
181     explicit PoolingValidator(const std::string& _type);
182 };
183
184 class INFERENCE_ENGINE_API_CLASS(FullyConnectedValidator) : public LayerValidator {
185 public:
186     explicit FullyConnectedValidator(const std::string& _type);
187
188     void parseParams(CNNLayer* layer) override;
189
190     void checkParams(const CNNLayer* layer) override;
191
192     void checkCorrespondence(const CNNLayer* layer,
193                              const std::map<std::string, Blob::Ptr>& blobs,
194                              const std::vector<SizeVector>& inShapes) const override;
195 };
196
197 class INFERENCE_ENGINE_API_CLASS(CropValidator) : public LayerValidator {
198 public:
199     explicit CropValidator(const std::string& _type);
200
201     void parseParams(CNNLayer* layer) override;
202
203     void checkParams(const CNNLayer* layer) override;
204
205     void checkShapes(const CNNLayer* layer, const std::vector<SizeVector>& inShapes) const override;
206 };
207
208 class INFERENCE_ENGINE_API_CLASS(TileValidator) : public LayerValidator {
209 public:
210     explicit TileValidator(const std::string& _type);
211
212     void parseParams(CNNLayer* layer) override;
213
214     void checkParams(const CNNLayer* layer) override;
215 };
216
217 class INFERENCE_ENGINE_API_CLASS(BatchNormalizationValidator) : public LayerValidator {
218 public:
219     explicit BatchNormalizationValidator(const std::string& _type);
220
221     void parseParams(CNNLayer* layer) override;
222
223     void checkParams(const CNNLayer* layer) override;
224 };
225
226 class INFERENCE_ENGINE_API_CLASS(PowerValidator) : public LayerValidator {
227 public:
228     explicit PowerValidator(const std::string& _type);
229
230     void parseParams(CNNLayer* layer) override;
231
232     void checkParams(const CNNLayer* layer) override;
233 };
234
235 class INFERENCE_ENGINE_API_CLASS(PReLUValidator) : public LayerValidator {
236 public:
237     explicit PReLUValidator(const std::string& _type);
238
239     void parseParams(CNNLayer* layer) override;
240
241     void checkParams(const CNNLayer* layer) override;
242 };
243
244 class INFERENCE_ENGINE_API_CLASS(ScaleShiftValidator) : public LayerValidator {
245 public:
246     explicit ScaleShiftValidator(const std::string& _type);
247
248     void parseParams(CNNLayer* layer) override;
249
250     void checkParams(const CNNLayer* layer) override;
251 };
252
253 class INFERENCE_ENGINE_API_CLASS(ReshapeValidator) : public LayerValidator {
254 public:
255     explicit ReshapeValidator(const std::string& _type);
256
257     void parseParams(CNNLayer* layer) override;
258
259     void checkParams(const CNNLayer* layer) override;
260
261 protected:
262     void calculateIn2Out(ReshapeLayer* layer);
263 };
264
265 class INFERENCE_ENGINE_API_CLASS(EltwiseValidator) : public LayerValidator {
266 public:
267     explicit EltwiseValidator(const std::string& _type);
268
269     void parseParams(CNNLayer* layer) override;
270
271     void checkParams(const CNNLayer* layer) override;
272 };
273
274 class INFERENCE_ENGINE_API_CLASS(ClampValidator) : public LayerValidator {
275 public:
276     explicit ClampValidator(const std::string& _type);
277
278     void parseParams(CNNLayer* layer) override;
279
280     void checkParams(const CNNLayer* layer) override;
281 };
282
283 class INFERENCE_ENGINE_API_CLASS(ReLUValidator) : public LayerValidator {
284 public:
285     explicit ReLUValidator(const std::string& _type);
286
287     void parseParams(CNNLayer* layer) override;
288
289     void checkParams(const CNNLayer* layer) override;
290 };
291
292 class INFERENCE_ENGINE_API_CLASS(MVNValidator) : public LayerValidator {
293 public:
294     explicit MVNValidator(const std::string& _type);
295
296     void parseParams(CNNLayer* layer) override;
297
298     void checkParams(const CNNLayer* layer) override;
299 };
300
301 class INFERENCE_ENGINE_API_CLASS(GRNValidator) : public LayerValidator {
302 public:
303     explicit GRNValidator(const std::string& _type);
304
305     void parseParams(CNNLayer* layer) override;
306
307     void checkParams(const CNNLayer* layer) override;
308 };
309
310 class INFERENCE_ENGINE_API_CLASS(SoftMaxValidator) : public LayerValidator {
311 public:
312     explicit SoftMaxValidator(const std::string& _type);
313
314     void parseParams(CNNLayer* layer) override;
315
316     void checkParams(const CNNLayer* layer) override;
317 };
318
319 class INFERENCE_ENGINE_API_CLASS(NormValidator) : public LayerValidator {
320 public:
321     explicit NormValidator(const std::string& _type);
322
323     void parseParams(CNNLayer* layer) override;
324
325     void checkParams(const CNNLayer* layer) override;
326 };
327
328 class INFERENCE_ENGINE_API_CLASS(SplitValidator) : public LayerValidator {
329 public:
330     explicit SplitValidator(const std::string& _type);
331
332     void parseParams(CNNLayer* layer) override;
333
334     void checkParams(const CNNLayer* layer) override;
335 };
336
337 class INFERENCE_ENGINE_API_CLASS(ConcatValidator) : public LayerValidator {
338 public:
339     explicit ConcatValidator(const std::string& _type);
340
341     void parseParams(CNNLayer* layer) override;
342
343     void checkParams(const CNNLayer* layer) override;
344 };
345
346 template<typename Validator>
347 class ValidatorRegisterBase {
348 public:
349     explicit ValidatorRegisterBase(const std::string& type) {
350         LayerValidators::getInstance()->addImpl(type, std::make_shared<Validator>(type));
351     }
352 };
353
354 #define REG_LAYER_VALIDATOR_FOR_TYPE(__validator, __type) \
355 static ValidatorRegisterBase<__validator> __reg__##__type(#__type)
356
357 REG_LAYER_VALIDATOR_FOR_TYPE(ConvolutionValidator, Convolution);
358 REG_LAYER_VALIDATOR_FOR_TYPE(DeconvolutionValidator, Deconvolution);
359 REG_LAYER_VALIDATOR_FOR_TYPE(PoolingValidator, Pooling);
360 REG_LAYER_VALIDATOR_FOR_TYPE(FullyConnectedValidator, InnerProduct);
361 REG_LAYER_VALIDATOR_FOR_TYPE(FullyConnectedValidator, FullyConnected);
362 REG_LAYER_VALIDATOR_FOR_TYPE(CropValidator, Crop);
363 REG_LAYER_VALIDATOR_FOR_TYPE(BatchNormalizationValidator, BatchNormalization);
364 REG_LAYER_VALIDATOR_FOR_TYPE(PowerValidator, Power);
365 REG_LAYER_VALIDATOR_FOR_TYPE(PReLUValidator, PReLU);
366 REG_LAYER_VALIDATOR_FOR_TYPE(ScaleShiftValidator, ScaleShift);
367 REG_LAYER_VALIDATOR_FOR_TYPE(TileValidator, Tile);
368 REG_LAYER_VALIDATOR_FOR_TYPE(ReshapeValidator, Reshape);
369 REG_LAYER_VALIDATOR_FOR_TYPE(ReshapeValidator, Flatten);
370 REG_LAYER_VALIDATOR_FOR_TYPE(EltwiseValidator, Eltwise);
371 REG_LAYER_VALIDATOR_FOR_TYPE(ClampValidator, Clamp);
372 REG_LAYER_VALIDATOR_FOR_TYPE(ReLUValidator, ReLU);
373 REG_LAYER_VALIDATOR_FOR_TYPE(MVNValidator, MVN);
374 REG_LAYER_VALIDATOR_FOR_TYPE(GRNValidator, GRN);
375 REG_LAYER_VALIDATOR_FOR_TYPE(SoftMaxValidator, SoftMax);
376 REG_LAYER_VALIDATOR_FOR_TYPE(NormValidator, Norm);
377 REG_LAYER_VALIDATOR_FOR_TYPE(NormValidator, LRN);
378 REG_LAYER_VALIDATOR_FOR_TYPE(SplitValidator, Split);
379 REG_LAYER_VALIDATOR_FOR_TYPE(SplitValidator, Slice);
380 REG_LAYER_VALIDATOR_FOR_TYPE(ConcatValidator, Concat);
381
382 }  // namespace details
383 }  // namespace InferenceEngine