Publishing 2019 R1 content
[platform/upstream/dldt.git] / inference-engine / src / inference_engine / ie_layer_validators.cpp
1 // Copyright (C) 2018-2019 Intel Corporation
2 // SPDX-License-Identifier: Apache-2.0
3 //
4
5 #include "ie_layers.h"
6 #include "ie_layer_validators.hpp"
7 #include "debug.h"
8 #include "xml_parse_utils.h"
9 #include <memory>
10 #include <string>
11 #include <map>
12 #include <vector>
13 #include <cmath>
14 #include <limits>
15 #include <ie_iextension.h>
16 #include <ie_format_parser.h>
17
18 #include <details/ie_exception.hpp>
19
20 namespace InferenceEngine {
21
22 using namespace details;
23 using std::vector;
24 using std::string;
25 using std::map;
26
27 template <typename T, typename P>
28 inline bool one_of(T val, P item) { return val == item; }
29 template <typename T, typename P, typename... Args>
30 inline bool one_of(T val, P item, Args... item_others) {
31     return val == item || one_of(val, item_others...);
32 }
33
34 void CNNLayer::validateLayer() {
35     try {
36         LayerValidator::Ptr validator = LayerValidators::getInstance()->getValidator(type);
37         validator->parseParams(this);
38         validator->checkParams(this);
39         InOutDims shapes;
40         getInOutShapes(this, shapes);
41         validator->checkShapes(this, shapes.inDims);
42     } catch(InferenceEngineException ie_e) {
43         THROW_IE_EXCEPTION << "Error of validate layer: " << this->name
44                            << " with type: " << this->type << ". "
45                            << ie_e.what();
46     }
47 }
48
49 struct WeightableParams {
50     std::vector<size_t>  _kernel;
51     size_t _outputs = 0lu;
52     size_t _groups = 1lu;
53     bool _isKernelFromInput = false;
54
55     WeightableParams(size_t outputs, bool isKernelFromInput, size_t groups = 0, const std::vector<size_t>& kernel = {}) :
56                 _kernel(kernel),
57                 _outputs(outputs),
58                 _groups(groups),
59                 _isKernelFromInput(isKernelFromInput) {}
60 };
61
62 void checkWeightable(const std::map<std::string, Blob::Ptr>& blobs,
63                      const vector<SizeVector>& inShapes,
64                      WeightableParams params,
65                      const SizeVector& numDims) {
66     if (inShapes.size() != 1)
67         THROW_IE_EXCEPTION << "Number of inputs (" << inShapes.size() << ") is not equal to expected ones (1)";
68     SizeVector firstInputShape = inShapes[0];
69     size_t inputSize = firstInputShape.size();
70
71     bool isOK = false;
72     for (auto dim : numDims) {
73         if (inputSize == dim) {
74             isOK = true;
75             break;
76         }
77     }
78     if (!isOK) {
79         THROW_IE_EXCEPTION << "Input shape " << details::dumpVec(firstInputShape)
80                            << " has unexpected size, supported sizes: " << details::dumpVec(numDims);
81     }
82
83     if (firstInputShape.empty()) THROW_IE_EXCEPTION << "Input shape can't be empty";
84
85     size_t IC, OC;
86     std::vector<size_t> kernel;
87     IC = firstInputShape[1];
88     if (params._isKernelFromInput) {
89         for (int i = 1; i <= inputSize - 2; i++)
90             kernel.push_back(firstInputShape[inputSize - i]);
91     } else {
92         for (auto k : params._kernel) {
93             kernel.push_back(k);
94         }
95     }
96     OC = params._outputs;
97
98     auto it = blobs.find("weights");
99     if (it != blobs.end()) {  // TODO: return with fixing shape infer tests: THROW_IE_EXCEPTION << "Invalid blobs: no weights";
100         auto weights = it->second;
101         if (weights == nullptr || weights->dims().empty()) THROW_IE_EXCEPTION << "Weights can't be empty";
102
103         auto weightsSize = details::product(weights->dims());
104         size_t expectedWeightsSize = OC * IC;
105         for (auto k : kernel) {
106             expectedWeightsSize *= k;
107         }
108         if (params._groups) expectedWeightsSize /= params._groups;
109         if (expectedWeightsSize != weightsSize) {
110             std::string ker_str;
111             for (int i = 0; i < params._kernel.size(); i++) {
112                 if (!ker_str.empty())
113                     ker_str += "x";
114                 ker_str += std::to_string(kernel[i]);
115             }
116             THROW_IE_EXCEPTION << "New shapes " << details::dumpVec(firstInputShape) << " make Kernels(" << ker_str <<
117                                "), Channels(" << IC << "), Output depth(" << OC << "), Groups("
118                                << params._groups << ") not matching weights size: "
119                                << expectedWeightsSize << " vs " << weightsSize;
120         }
121     }
122
123     it = blobs.find("biases");
124     if (it != blobs.end()) {
125         auto biases = it->second;
126         if (biases == nullptr || biases->dims().empty()) THROW_IE_EXCEPTION << "Biases can't be empty";
127         auto biasesSize = details::product(biases->dims());
128         if (OC != biasesSize) {
129             THROW_IE_EXCEPTION << "Number of outputs (" << OC << ") don't match biases size: " << biasesSize;
130         }
131     }
132 }
133
134 void checkDims(const std::vector<SizeVector>& shapes, const vector<int>& expected_shape_size) {
135     for (auto i : shapes) {
136         if (i.empty()) {
137             THROW_IE_EXCEPTION << " Failed with invalid shapes: dimension is empty";
138         }
139         auto iter = std::find(expected_shape_size.begin(), expected_shape_size.end(), i.size());
140         if (iter == expected_shape_size.end()) {
141             THROW_IE_EXCEPTION << " Failed with invalid shapes: dimension is invalid";
142         }
143     }
144 }
145
146 void checkNumOfInput(const std::vector<SizeVector>& inShapes, const vector<int>& expected_num_of_shapes) {
147     bool shape_was_found = false;
148     for (const auto& i : expected_num_of_shapes) {
149         if (inShapes.size() == i) {
150             shape_was_found = true;
151         }
152     }
153     if (!shape_was_found) {
154         THROW_IE_EXCEPTION << "Number of inputs (" << inShapes.size() << ") is not equal to expected ones";
155     }
156 }
157
158 LayerValidators* LayerValidators::getInstance() {
159     if (!_instance) {
160         _instance = new LayerValidators();
161     }
162     return _instance;
163 }
164
165 LayerValidator::Ptr LayerValidators::getValidator(const std::string& type) {
166     if (_validators.find(type) == _validators.end()) {
167         return std::make_shared<GeneralValidator>(type);
168     }
169     return _validators[type];
170 }
171
172 void LayerValidators::addImpl(const std::string& type, const LayerValidator::Ptr& validator) {
173     _validators[type] = validator;
174 }
175
176 LayerValidators* LayerValidators::_instance = nullptr;
177
178 GeneralValidator::GeneralValidator(const std::string& _type) : LayerValidator(_type) {}
179
180 void FullyConnectedValidator::parseParams(CNNLayer* layer) {
181     auto casted = dynamic_cast<FullyConnectedLayer*>(layer);
182     if (!casted) {
183         THROW_IE_EXCEPTION << "Layer is not instance of FullyConnectedLayer class";
184     }
185     casted->_out_num = casted->GetParamAsUInt("out-size");
186 }
187
188 void FullyConnectedValidator::checkParams(const CNNLayer* layer) {
189     auto casted = dynamic_cast<const FullyConnectedLayer*>(layer);
190     if (!casted) {
191         THROW_IE_EXCEPTION << "Layer is not instance of FullyConnectedLayer class";
192     }
193     unsigned int _out_num = casted->GetParamAsUInt("out-size");
194 }
195
196 void FullyConnectedValidator::checkCorrespondence(const CNNLayer* layer,
197                                                   const std::map<std::string, Blob::Ptr>& blobs,
198                                                   const vector<SizeVector>& inShapes) const {
199     const auto casted = dynamic_cast<const FullyConnectedLayer*>(layer);
200     if (!casted) THROW_IE_EXCEPTION << "Layer is not instance of FullyConnected layer class";
201     checkWeightable(blobs, inShapes, {casted->_out_num, true, 1}, {2, 4, 5});
202 }
203
204 FullyConnectedValidator::FullyConnectedValidator(const std::string& _type) : LayerValidator(_type) {}
205
206 void FullyConnectedValidator::checkShapes(const CNNLayer* layer, const std::vector<SizeVector>& inShapes) const {
207     checkNumOfInput(inShapes, {1});
208 }
209
210 void CropValidator::parseParams(CNNLayer* layer) {
211     auto casted = dynamic_cast<CropLayer*>(layer);
212     if (!casted) {
213         THROW_IE_EXCEPTION << "Layer is not instance of CropLayer class";
214     }
215     if (casted->axis.empty()) {
216         auto getArray = [](std::string param, vector<int>& array) {
217             std::istringstream stream(param);
218             std::string str;
219             while (getline(stream, str, ',')) {
220                 int val = std::stoi(str);
221                 array.push_back(val);
222             }
223         };
224         getArray(layer->GetParamAsString("axis"), casted->axis);
225         if (casted->params.find("offset") != casted->params.end()) {
226             getArray(layer->GetParamAsString("offset"), casted->offset);
227         }
228         if (casted->params.find("dim") != casted->params.end()) {
229             getArray(layer->GetParamAsString("dim"), casted->dim);
230         }
231         if (casted->params.find("crop_begin") != casted->params.end()) {
232             getArray(layer->GetParamAsString("crop_begin"), casted->offset);
233         }
234     }
235 }
236
237 void CropValidator::checkParams(const CNNLayer* layer) {
238     auto casted = dynamic_cast<const CropLayer*>(layer);
239     if (!casted) {
240         THROW_IE_EXCEPTION << "Layer is not instance of CropLayer class";
241     }
242     if (casted->axis.size() != casted->offset.size()) {
243         THROW_IE_EXCEPTION << "Incorrect format of the Crop layer: number of axis doesn't match number of offset - ("
244                            << casted->axis.size() << " vs. " << casted->offset.size() << ")";
245     }
246 }
247
248 CropValidator::CropValidator(const std::string& _type) : LayerValidator(_type) {}
249
250 void CropValidator::checkShapes(const CNNLayer* layer, const vector<SizeVector>& inShapes) const {
251     auto casted = dynamic_cast<const CropLayer*>(layer);
252     if (!casted) {
253         THROW_IE_EXCEPTION << "Layer is not instance of CropLayer class";
254     }
255     size_t numInputs = inShapes.size();
256     checkNumOfInput(inShapes, {1, 2});
257
258     auto firstShape = inShapes[0];
259     size_t shapeSize = firstShape.size();
260     for (size_t i = 0; i < casted->axis.size(); i++) {
261         int axis = casted->axis[i];
262         int offset = casted->offset[i];
263         if (shapeSize <= axis)
264             THROW_IE_EXCEPTION << "Crop axis(" << casted->axis[i]
265                                << ") should be less the number of dimensions of first input ("
266                                << firstShape.size() << ")";
267         if (numInputs == 2) {
268             if (casted->params.find("crop_begin") != casted->params.end()) {
269                 THROW_IE_EXCEPTION
270                         << "Incorrect format of the Crop layer: `crop_begin` and `crop_end` attributes are valid for single input only";
271             }
272             auto secondShape = inShapes[1];
273             if (secondShape.size() <= axis)
274                 THROW_IE_EXCEPTION << "Crop axis(" << axis
275                                    << ") should be less the number of dimensions of second input ("
276                                    << secondShape.size() << ")";
277             size_t newSize = secondShape[axis];
278             if (firstShape[axis] < static_cast<size_t>(offset + newSize)) {
279                 THROW_IE_EXCEPTION << "Incorrect crop data! Offset(" << offset << ") + result size of output("
280                                    << newSize << ") should be less then input size(" << firstShape[axis]
281                                    << ") for axis(" << axis << ")";
282             }
283         } else if (!casted->dim.empty()) {
284             int dim = casted->dim[i];
285             if (firstShape[axis] < static_cast<size_t>(offset + dim)) {
286                 THROW_IE_EXCEPTION << "Incorrect crop data! Offset(" << offset << ") + result size of output("
287                                    << dim << ") should be less then input size(" << firstShape[axis]
288                                    << ") for axis(" << axis << ")";
289             }
290         }
291     }
292 }
293
294 ConvolutionValidator::ConvolutionValidator(const std::string& _type) : LayerValidator(_type) {}
295
296 void ConvolutionValidator::parseParams(CNNLayer* layer) {
297     auto convLayer = dynamic_cast<ConvolutionLayer*>(layer);
298     if (!convLayer) {
299         THROW_IE_EXCEPTION << "Layer is not instance of ConvolutionLayer class";
300     }
301     convLayer->_out_depth = convLayer->GetParamAsUInt("output");
302
303     convLayer->_kernel.clear();
304     convLayer->_stride.clear();
305     convLayer->_padding.clear();
306     convLayer->_pads_end.clear();
307     convLayer->_dilation.clear();
308
309     vector<unsigned int> kernels = convLayer->GetParamAsUInts("kernel", {});
310     if (kernels.empty()) {
311         // IR_v == 2
312         convLayer->_kernel.insert(X_AXIS, convLayer->GetParamAsUInt("kernel-x"));
313         convLayer->_kernel.insert(Y_AXIS, convLayer->GetParamAsUInt("kernel-y"));
314
315         convLayer->_stride.insert(X_AXIS, convLayer->GetParamAsUInt("stride-x", 1u));
316         convLayer->_stride.insert(Y_AXIS, convLayer->GetParamAsUInt("stride-y", 1u));
317         // TODO: maybe just throw exception, why do we change IR?
318         if (0 == convLayer->_stride[X_AXIS]) {
319             convLayer->_stride[X_AXIS] = 1u;
320             LogError("Warning! in layer %s: Stride x is 0, setting to 1 ", convLayer->name.c_str());
321         }
322         if (0 == convLayer->_stride[Y_AXIS]) {
323             convLayer->_stride[Y_AXIS] = 1u;
324             LogError("Warning! in layer %s: Stride y is 0, setting to 1", convLayer->name.c_str());
325         }
326
327         convLayer->_padding.insert(X_AXIS, convLayer->GetParamAsUInt("pad-x", 0u));
328         convLayer->_padding.insert(Y_AXIS, convLayer->GetParamAsUInt("pad-y", 0u));
329
330         convLayer->_pads_end.insert(X_AXIS, convLayer->GetParamAsUInt("pad-r", convLayer->_padding[X_AXIS]));
331         convLayer->_pads_end.insert(Y_AXIS, convLayer->GetParamAsUInt("pad-b", convLayer->_padding[Y_AXIS]));
332
333         convLayer->_dilation.insert(X_AXIS, convLayer->GetParamAsUInt("dilation-x", 1u));
334         convLayer->_dilation.insert(Y_AXIS, convLayer->GetParamAsUInt("dilation-y", 1u));
335     } else {
336         // IR_v > 2
337         for (int i = 1; i <= kernels.size(); i++) {
338             convLayer->_kernel.insert(i - 1, kernels[kernels.size() - i]);
339         }
340
341         vector<unsigned int> default_0 = vector<unsigned int> (convLayer->_kernel.size(), 0u);
342         vector<unsigned int> default_1 = vector<unsigned int> (convLayer->_kernel.size(), 1u);
343
344         vector<unsigned int> strides = convLayer->GetParamAsUInts("strides", default_1);
345         for (int i = 1; i <= strides.size(); i++) {
346             if (strides[strides.size() - i] == 0) {
347                 THROW_IE_EXCEPTION << "Stride could not be 0.\nIn layer " << convLayer->name;
348             }
349             convLayer->_stride.insert(i - 1, strides[strides.size() - i]);
350         }
351
352         vector<unsigned int> pads_begin = convLayer->GetParamAsUInts("pads_begin", default_0);
353         for (int i = 1; i <= pads_begin.size(); i++) {
354             convLayer->_padding.insert(i - 1, pads_begin[pads_begin.size() - i]);
355         }
356
357         vector<unsigned int> pads_end = convLayer->GetParamAsUInts("pads_end", pads_begin);
358         for (int i = 1; i <= pads_end.size(); i++) {
359             convLayer->_pads_end.insert(i - 1, pads_end[pads_end.size() - i]);
360         }
361
362         vector<unsigned int> dilations = convLayer->GetParamAsUInts("dilations", default_1);
363         for (int i = 1; i <= dilations.size(); i++) {
364             convLayer->_dilation.insert(i - 1, dilations[dilations.size() - i]);
365         }
366     }
367
368     convLayer->_auto_pad = convLayer->GetParamAsString("auto_pad", "");
369     convLayer->_group = convLayer->GetParamAsUInt("group", 1u);
370 }
371
372 void ConvolutionValidator::checkParams(const CNNLayer* layer) {
373     auto casted = dynamic_cast<const ConvolutionLayer*>(layer);
374     if (!casted) {
375         THROW_IE_EXCEPTION << "Layer is not instance of ConvolutionLayer class";
376     }
377     casted->GetParamAsUInt("output");
378
379     vector<unsigned int> kernels = casted->GetParamAsUInts("kernel", {});
380     if (kernels.empty()) {
381         // IR_v == 2
382         casted->GetParamAsUInt("kernel-x");
383         casted->GetParamAsUInt("kernel-y");
384         casted->GetParamAsUInt("stride-x", 1u);
385         casted->GetParamAsUInt("stride-y", 1u);
386         casted->GetParamAsUInt("pad-x", 0u);
387         casted->GetParamAsUInt("pad-y", 0u);
388         casted->GetParamAsUInt("pad-r", casted->_padding[X_AXIS]);
389         casted->GetParamAsUInt("pad-b", casted->_padding[Y_AXIS]);
390         casted->GetParamAsUInt("dilation-x", 1u);
391         casted->GetParamAsUInt("dilation-y", 1u);
392     } else {
393         // IR_v > 2
394         vector<unsigned int> default_0 = vector<unsigned int> (casted->_kernel.size(), 0u);
395         vector<unsigned int> default_1 = vector<unsigned int> (casted->_kernel.size(), 1u);
396         casted->GetParamAsUInts("strides", default_1);
397         casted->GetParamAsUInts("pads_begin", default_0);
398         casted->GetParamAsUInts("pads_end", default_0);
399         casted->GetParamAsUInts("dilations", default_1);
400     }
401     casted->GetParamAsString("auto_pad", "");
402     casted->GetParamAsUInt("group", 1);
403 }
404
405 void ConvolutionValidator::checkCorrespondence(const CNNLayer* layer,
406                                                const std::map<std::string, Blob::Ptr>& blobs,
407                                                const vector<SizeVector>& inShapes) const {
408     auto convLayer = dynamic_cast<const ConvolutionLayer*>(layer);
409     if (!convLayer)
410         THROW_IE_EXCEPTION << "Layer is not instance of Convolution layer class";
411
412     std::vector<size_t> krn;
413     for (int i = 0; i < convLayer->_kernel.size(); i++)
414         krn.push_back(convLayer->_kernel[i]);
415     checkWeightable(blobs, inShapes, {convLayer->_out_depth, false, convLayer->_group, krn},
416                     {4, 5});
417 }
418
419 void ConvolutionValidator::checkShapes(const CNNLayer* layer, const std::vector<SizeVector>& inShapes) const {
420     checkNumOfInput(inShapes, {1});
421 }
422
423 void DeconvolutionValidator::parseParams(CNNLayer* layer) {
424     auto deconvLayer = dynamic_cast<DeconvolutionLayer*>(layer);
425     if (!deconvLayer) {
426         THROW_IE_EXCEPTION << "Layer is not instance of DeconvolutionLayer class";
427     }
428     ConvolutionValidator::parseParams(layer);
429 }
430
431 void DeconvolutionValidator::checkParams(const CNNLayer* layer) {
432     auto casted = dynamic_cast<const ConvolutionLayer*>(layer);
433     if (!casted) {
434         THROW_IE_EXCEPTION << "Layer is not instance of ConvolutionLayer class";
435     }
436     casted->GetParamAsUInt("output");
437
438     vector<unsigned int> kernels = casted->GetParamAsUInts("kernel", {});
439     if (kernels.empty()) {
440         // IR_v == 2
441         casted->GetParamAsUInt("kernel-x");
442         casted->GetParamAsUInt("kernel-y");
443         casted->GetParamAsUInt("stride-x", 1u);
444         casted->GetParamAsUInt("stride-y", 1u);
445         casted->GetParamAsUInt("pad-x", 0u);
446         casted->GetParamAsUInt("pad-y", 0u);
447         casted->GetParamAsUInt("pad-r", casted->_padding[X_AXIS]);
448         casted->GetParamAsUInt("pad-b", casted->_padding[Y_AXIS]);
449         casted->GetParamAsUInt("dilation-x", 1u);
450         casted->GetParamAsUInt("dilation-y", 1u);
451     } else {
452         // IR_v > 2
453         vector<unsigned int> default_0 = vector<unsigned int> (casted->_kernel.size(), 0u);
454         vector<unsigned int> default_1 = vector<unsigned int> (casted->_kernel.size(), 1u);
455         casted->GetParamAsUInts("strides", default_1);
456         casted->GetParamAsUInts("pads_begin", default_0);
457         casted->GetParamAsUInts("pads_end", default_0);
458         casted->GetParamAsUInts("dilations", default_1);
459     }
460     casted->GetParamAsString("auto_pad", "");
461     casted->GetParamAsUInt("group", 1);
462 }
463
464 DeconvolutionValidator::DeconvolutionValidator(const std::string& _type) : ConvolutionValidator(_type) {}
465
466 void DeconvolutionValidator::checkCorrespondence(const CNNLayer* layer,
467                                                  const std::map<std::string, Blob::Ptr>& blobs,
468                                                  const vector<SizeVector>& inShapes) const {
469     auto deconv_layer = dynamic_cast<const DeconvolutionLayer*>(layer);
470     if (!deconv_layer)
471         THROW_IE_EXCEPTION << "Layer is not instance of Deconvolution layer class";
472
473     std::vector<size_t> krn;
474     for (int i = 0; i < deconv_layer->_kernel.size(); i++)
475         krn.push_back(deconv_layer->_kernel[i]);
476     checkWeightable(blobs, inShapes, {deconv_layer->_out_depth, false, deconv_layer->_group, krn},
477                     {4, 5});
478 }
479
480 void DeconvolutionValidator::checkShapes(const CNNLayer* layer, const std::vector<SizeVector>& inShapes) const {
481     checkNumOfInput(inShapes, {1});
482 }
483
484 PoolingValidator::PoolingValidator(const std::string& _type) : LayerValidator(_type) {}
485
486 void PoolingValidator::parseParams(CNNLayer* layer) {
487     auto poolLayer = dynamic_cast<PoolingLayer*>(layer);
488     if (!poolLayer) {
489         THROW_IE_EXCEPTION << "Layer is not instance of PoolingLayer class";
490     }
491
492     poolLayer->_kernel.clear();
493     poolLayer->_stride.clear();
494     poolLayer->_padding.clear();
495     poolLayer->_pads_end.clear();
496
497     poolLayer->_auto_pad = poolLayer->GetParamAsString("auto_pad", "");
498
499     vector<unsigned int> kernels = poolLayer->GetParamAsUInts("kernel", {});
500     if (kernels.empty()) {
501         int kernel_x = poolLayer->GetParamAsInt("kernel-x", -1);
502         /** Pooling as custom layer */
503         if (kernel_x == -1) {
504             try {
505                 unsigned int kernel_size = poolLayer->GetParamAsUInt("kernel_size");
506                 unsigned int kernel_w = poolLayer->GetParamAsUInt("kernel_w", 0u);
507                 unsigned int kernel_h = poolLayer->GetParamAsUInt("kernel_h", 0u);
508                 poolLayer->_kernel.insert(X_AXIS, kernel_w == 0u ? kernel_size : kernel_w);
509                 poolLayer->_kernel.insert(Y_AXIS, kernel_h == 0u ? kernel_size : kernel_h);
510
511                 unsigned int stride = poolLayer->GetParamAsUInt("stride", 1u);
512                 unsigned int stride_w = poolLayer->GetParamAsUInt("stride_w", 0u);
513                 unsigned int stride_h = poolLayer->GetParamAsUInt("stride_h", 0u);
514                 poolLayer->_stride.insert(X_AXIS, stride_w == 0u ? stride : stride_w);
515                 poolLayer->_stride.insert(Y_AXIS, stride_h == 0u ? stride : stride_h);
516
517                 unsigned int pad = poolLayer->GetParamAsUInt("pad", 0u);
518                 unsigned int pad_w = poolLayer->GetParamAsUInt("pad_w", 0u);
519                 unsigned int pad_h = poolLayer->GetParamAsUInt("pad_h", 0u);
520
521                 poolLayer->_padding.insert(X_AXIS, pad_w == 0u ? pad : pad_w);
522                 poolLayer->_padding.insert(Y_AXIS, pad_h == 0u ? pad : pad_h);
523
524                 poolLayer->_pads_end.insert(X_AXIS, 0u);
525                 poolLayer->_pads_end.insert(Y_AXIS, 0u);
526             } catch (...) {
527             }
528
529             std::string alg = poolLayer->GetParamAsString("pool", "caffe.PoolingParameter.MAX");
530             poolLayer->_type = alg == "caffe.PoolingParameter.MAX" ? PoolingLayer::MAX : PoolingLayer::AVG;
531         } else  /** Default behavior */ {
532             poolLayer->_kernel.insert(X_AXIS, poolLayer->GetParamAsUInt("kernel-x"));
533             poolLayer->_kernel.insert(Y_AXIS, poolLayer->GetParamAsUInt("kernel-y"));
534
535             poolLayer->_stride.insert(X_AXIS, poolLayer->GetParamAsUInt("stride-x", 1u));
536             poolLayer->_stride.insert(Y_AXIS, poolLayer->GetParamAsUInt("stride-y", 1u));
537             // TODO: maybe just throw exception, why do we change IR?
538             if (0 == poolLayer->_stride[X_AXIS]) {
539                 poolLayer->_stride[X_AXIS] = 1u;
540                 LogError("Warning! in layer %s: Stride x is 0, setting to 1 ", poolLayer->name.c_str());
541             }
542             if (0 == poolLayer->_stride[Y_AXIS]) {
543                 poolLayer->_stride[Y_AXIS] = 1u;
544                 LogError("Warning! in layer %s: Stride y is 0, setting to 1", poolLayer->name.c_str());
545             }
546
547             poolLayer->_padding.insert(X_AXIS, poolLayer->GetParamAsUInt("pad-x", 0u));
548             poolLayer->_padding.insert(Y_AXIS, poolLayer->GetParamAsUInt("pad-y", 0u));
549
550             poolLayer->_pads_end.insert(X_AXIS, poolLayer->GetParamAsUInt("pad-r", poolLayer->_padding[X_AXIS]));
551             poolLayer->_pads_end.insert(Y_AXIS, poolLayer->GetParamAsUInt("pad-b", poolLayer->_padding[Y_AXIS]));
552
553             // TODO: All kind of pool methods
554             poolLayer->_exclude_pad = poolLayer->GetParamsAsBool("exclude-pad", false);
555             std::string alg = poolLayer->GetParamAsString("pool-method", "max");
556             poolLayer->_type = alg == "avg" ? PoolingLayer::AVG : PoolingLayer::MAX;
557             if (alg != "max" && alg != "avg") {
558                 THROW_IE_EXCEPTION << "Layer with type `" << _type << "` has incorrect pool-type!";
559             }
560         }
561     } else {
562         for (int i = 1; i <= kernels.size(); i++) {
563             poolLayer->_kernel.insert(i - 1, kernels[kernels.size() - i]);
564         }
565
566         vector<unsigned int> default_0 = vector<unsigned int> (poolLayer->_kernel.size(), 0u);
567         vector<unsigned int> default_1 = vector<unsigned int> (poolLayer->_kernel.size(), 1u);
568
569         vector<unsigned int> strides = poolLayer->GetParamAsUInts("strides", default_1);
570         for (int i = 1; i <= strides.size(); i++) {
571             if (strides[strides.size() - i] == 0) {
572                 THROW_IE_EXCEPTION << "Stride could not be 0.\nIn layer " << poolLayer->name;
573             }
574             poolLayer->_stride.insert(i - 1, strides[strides.size() - i]);
575         }
576
577         vector<unsigned int> pads_begin = poolLayer->GetParamAsUInts("pads_begin", default_0);
578         for (int i = 1; i <= pads_begin.size(); i++) {
579             poolLayer->_padding.insert(i - 1, pads_begin[pads_begin.size() - i]);
580         }
581
582         vector<unsigned int> pads_end = poolLayer->GetParamAsUInts("pads_end", pads_begin);
583         for (int i = 1; i <= pads_end.size(); i++) {
584             poolLayer->_pads_end.insert(i - 1, pads_end[pads_end.size() - i]);
585         }
586
587         poolLayer->_exclude_pad = poolLayer->GetParamsAsBool("exclude-pad", false);
588         std::string alg = poolLayer->GetParamAsString("pool-method", "max");
589         poolLayer->_type = alg == "avg" ? PoolingLayer::AVG : PoolingLayer::MAX;
590         if (alg != "max" && alg != "avg") {
591             THROW_IE_EXCEPTION << "Layer with type `" << _type << "` has incorrect pad-type!";
592         }
593     }
594     // TODO: checks for presence of all required attributes, and that there's no extraneous parameters only.
595 }
596
597 void PoolingValidator::checkParams(const CNNLayer* layer) {
598     // TODO: check that values belong to the scope of the definition according to spec
599 }
600
601 void PoolingValidator::checkShapes(const CNNLayer* layer, const std::vector<SizeVector>& inShapes) const {
602     checkNumOfInput(inShapes, {1, 2});
603 }
604
605 void BatchNormalizationValidator::parseParams(CNNLayer* layer) {
606     auto casted = dynamic_cast<BatchNormalizationLayer*>(layer);
607     if (!casted) {
608         THROW_IE_EXCEPTION << "Layer is not instance of BatchNormalizationLayer class";
609     }
610     casted->epsilon = casted->GetParamAsFloat("epsilon");
611 }
612
613 void BatchNormalizationValidator::checkParams(const CNNLayer* layer) {
614     auto casted = dynamic_cast<const BatchNormalizationLayer*>(layer);
615     if (!casted) {
616         THROW_IE_EXCEPTION << "Layer is not instance of BatchNormalizationLayer class";
617     }
618     float epsilon = casted->GetParamAsFloat("epsilon");
619     if (epsilon < 0) {
620         THROW_IE_EXCEPTION << "The value of BatchNormalization layer epsilon parameter is invalid";
621     }
622 }
623
624 BatchNormalizationValidator::BatchNormalizationValidator(const std::string& _type) : LayerValidator(_type) {}
625
626 void BatchNormalizationValidator::checkShapes(const CNNLayer* layer, const std::vector<SizeVector>& inShapes) const {
627     checkNumOfInput(inShapes, {1});
628 }
629
630 void PowerValidator::parseParams(CNNLayer* layer) {
631     auto casted = dynamic_cast<PowerLayer*>(layer);
632     if (!casted) {
633         THROW_IE_EXCEPTION << "Layer is not instance of PowerLayer class";
634     }
635     casted->offset = casted->GetParamAsFloat("shift");
636     casted->power = casted->GetParamAsFloat("power");
637     casted->scale = casted->GetParamAsFloat("scale");
638 }
639
640 void PowerValidator::checkParams(const CNNLayer* layer) {
641     LayerValidator::checkParams(layer);
642 }
643
644 PowerValidator::PowerValidator(const std::string& _type) : LayerValidator(_type) {}
645
646 void PowerValidator::checkShapes(const CNNLayer* layer, const std::vector<SizeVector>& inShapes) const {
647     checkNumOfInput(inShapes, {1});
648 }
649
650 void PReLUValidator::parseParams(CNNLayer* layer) {
651     auto casted = dynamic_cast<PReLULayer*>(layer);
652     if (!casted) {
653         THROW_IE_EXCEPTION << "Layer is not instance of PReLULayer class";
654     }
655     casted->_channel_shared = casted->GetParamsAsBool("channel_shared", false);
656 }
657
658 void PReLUValidator::checkParams(const CNNLayer* layer) {
659     LayerValidator::checkParams(layer);
660 }
661
662 PReLUValidator::PReLUValidator(const std::string& _type) : LayerValidator(_type) {}
663
664 void PReLUValidator::checkShapes(const CNNLayer* layer, const std::vector<SizeVector>& inShapes) const {
665     checkNumOfInput(inShapes, {1});
666 }
667
668 void ScaleShiftValidator::parseParams(CNNLayer* layer) {
669     auto casted = dynamic_cast<ScaleShiftLayer*>(layer);
670     if (!casted) {
671         THROW_IE_EXCEPTION << "Layer is not instance of ScaleShiftLayer class";
672     }
673     if (!casted->params.empty()) {
674         casted->_broadcast = casted->GetParamAsUInt("broadcast", 2);
675     }
676 }
677
678 void ScaleShiftValidator::checkParams(const CNNLayer* layer) {
679     LayerValidator::checkParams(layer);
680 }
681
682 ScaleShiftValidator::ScaleShiftValidator(const std::string& _type) : LayerValidator(_type) {}
683
684 void ScaleShiftValidator::checkShapes(const CNNLayer* layer, const std::vector<SizeVector>& inShapes) const {
685     checkNumOfInput(inShapes, {1});
686 }
687
688 void TileValidator::parseParams(CNNLayer* layer) {
689     auto casted = dynamic_cast<TileLayer*>(layer);
690     if (!casted) {
691         THROW_IE_EXCEPTION << "Layer is not instance of TileLayer class";
692     }
693     casted->axis = casted->GetParamAsInt("axis", -1);
694     casted->tiles = casted->GetParamAsInt("tiles", -1);
695 }
696
697 void TileValidator::checkParams(const CNNLayer* layer) {
698     auto casted = dynamic_cast<const TileLayer*>(layer);
699     if (!casted) {
700         THROW_IE_EXCEPTION << "Layer is not instance of TileLayer class";
701     }
702     int axis = casted->GetParamAsInt("axis", -1);
703     int tiles = casted->GetParamAsInt("tiles", -1);
704     if (axis < 0 && tiles < 0) {
705         THROW_IE_EXCEPTION << "The value of Tile layer parameters is invalid";
706     }
707 }
708
709 TileValidator::TileValidator(const std::string& _type) : LayerValidator(_type) {}
710
711 void TileValidator::checkShapes(const CNNLayer* layer, const std::vector<SizeVector>& inShapes) const {
712     checkNumOfInput(inShapes, {1});
713 }
714
715 ReshapeValidator::ReshapeValidator(const std::string& _type) : LayerValidator(_type) {}
716
717 void ReshapeValidator::parseParams(CNNLayer *layer) {
718     auto casted = dynamic_cast<ReshapeLayer *>(layer);
719     if (!casted) {
720         THROW_IE_EXCEPTION << "Layer is not instance of ReshapeLayer class";
721     }
722     casted->shape.clear();
723     if (!casted->params.empty()) {
724         if (casted->type == "Flatten") {
725             casted->num_axes = casted->GetParamAsInt("end_axis", -1);
726             casted->axis = casted->axis = casted->GetParamAsInt("axis", 0);
727         } else {
728             casted->shape = casted->GetParamAsInts("dim", {});
729         }
730     }
731 }
732
733 void ReshapeValidator::checkParams(const CNNLayer *layer) {
734     auto casted = dynamic_cast<const ReshapeLayer *>(layer);
735     if (!casted)
736         THROW_IE_EXCEPTION << "Layer is not instance of ReshapeLayer class";
737     size_t num = 0;
738     for (int dim : casted->shape) {
739         if (dim < -1)
740             THROW_IE_EXCEPTION << "Invalid value of Reshape mask (dim attribute):" << dim
741                                << ". Supported values: 0, -1, >0";
742         if (dim == -1) num++;
743     }
744     if (num > 1) THROW_IE_EXCEPTION << "Invalid Reshape mask (dim attribute): at most one dimension can be `-1`";
745 }
746
747 void EltwiseValidator::parseParams(CNNLayer* layer) {
748     auto casted = dynamic_cast<EltwiseLayer*>(layer);
749     if (!casted) {
750         THROW_IE_EXCEPTION << "Layer is not instance of EltwiseLayer class";
751     }
752     // TODO: fix this onece we switched to IR v2.x also enable dedicated unit tests
753     // @details: need to remove sum
754     std::string op = casted->GetParamAsString("operation", "sum");
755     // TODO: remove empty value case in IRv2.x
756     if (op == "sum" || op == "") {
757         casted->_operation = EltwiseLayer::Sum;
758     } else if (op == "mul" || op == "prod") {
759         casted->_operation = EltwiseLayer::Prod;
760     } else if (op == "max") {
761         casted->_operation = EltwiseLayer::Max;
762     } else if (op == "sub") {
763         casted->_operation = EltwiseLayer::Sub;
764     } else if (op == "div") {
765         casted->_operation = EltwiseLayer::Div;
766     } else if (op == "min") {
767         casted->_operation = EltwiseLayer::Min;
768     } else if (op == "squared_diff") {
769         casted->_operation = EltwiseLayer::Squared_diff;
770     } else if (op == "equal") {
771         casted->_operation = EltwiseLayer::Equal;
772     } else if (op == "not_equal") {
773         casted->_operation = EltwiseLayer::Not_equal;
774     } else if (op == "less") {
775         casted->_operation = EltwiseLayer::Less;
776     } else if (op == "less_equal") {
777         casted->_operation = EltwiseLayer::Less_equal;
778     } else if (op == "greater") {
779         casted->_operation = EltwiseLayer::Greater;
780     } else if (op == "greater_equal") {
781         casted->_operation = EltwiseLayer::Greater_equal;
782     } else if (op == "logical_and") {
783         casted->_operation = EltwiseLayer::Logical_AND;
784     } else if (op == "logical_or") {
785         casted->_operation = EltwiseLayer::Logical_OR;
786     } else if (op == "logical_xor") {
787         casted->_operation = EltwiseLayer::Logical_XOR;
788     } else if (op == "floor_mod") {
789         casted->_operation = EltwiseLayer::Floor_mod;
790     } else if (op == "pow") {
791         casted->_operation = EltwiseLayer::Pow;
792     } else {
793         THROW_IE_EXCEPTION << "Unsupported element wise operation: " << op;
794     }
795
796     auto getArray = [](std::string param, vector<float>& array) {
797         std::istringstream stream(param);
798         std::string str;
799         while (getline(stream, str, ',')) {
800             float val = std::stof(str);
801             array.push_back(val);
802         }
803     };
804     getArray(casted->GetParamAsString("coeff", ""), casted->coeff);
805 }
806
807 void EltwiseValidator::checkParams(const CNNLayer* layer) {
808     auto casted = dynamic_cast<const EltwiseLayer*>(layer);
809     if (!casted) {
810         THROW_IE_EXCEPTION << "Layer is not instance of EltwiseLayer class";
811     }
812 }
813
814 void EltwiseValidator::checkShapes(const CNNLayer* layer, const std::vector<SizeVector>& inShapes) const {
815     if (inShapes.empty()) {
816         THROW_IE_EXCEPTION << "Number of inputs (" << inShapes.size() <<
817                            ") of Eltwise layer is zero";
818     }
819 }
820
821 EltwiseValidator::EltwiseValidator(const std::string& _type) : LayerValidator(_type) {}
822
823 void ClampValidator::parseParams(CNNLayer* layer) {
824     auto casted = dynamic_cast<ClampLayer*>(layer);
825     if (!casted) {
826         THROW_IE_EXCEPTION << "Layer is not instance of ClampLayer class";
827     }
828     casted->min_value = casted->GetParamAsFloat("min");
829     casted->max_value = casted->GetParamAsFloat("max");
830 }
831
832
833 ClampValidator::ClampValidator(const std::string& _type) : LayerValidator(_type) {}
834
835 void ClampValidator::checkShapes(const CNNLayer* layer, const std::vector<SizeVector>& inShapes) const {
836     checkNumOfInput(inShapes, {1});
837 }
838
839 void ReLUValidator::parseParams(CNNLayer* layer) {
840     auto casted = dynamic_cast<ReLULayer*>(layer);
841     if (!casted) {
842         THROW_IE_EXCEPTION << "Layer is not instance of ReLULayer class";
843     }
844     if (!casted->params.empty()) {
845         casted->negative_slope = casted->GetParamAsFloat("negative_slope");
846     }
847 }
848
849 void ReLUValidator::checkParams(const CNNLayer* layer) {
850     auto casted = dynamic_cast<const ReLULayer*>(layer);
851     if (!casted) {
852         THROW_IE_EXCEPTION << "Layer is not instance of ReLULayer class";
853     }
854     if (!casted->params.empty()) {
855         float negative_slope = casted->GetParamAsFloat("negative_slope");
856         if (negative_slope < 0) {
857             THROW_IE_EXCEPTION << "The value of ReLU layer negative_slope parameter is invalid";
858         }
859     }
860 }
861
862 ReLUValidator::ReLUValidator(const std::string& _type) : LayerValidator(_type) {}
863
864 void ReLUValidator::checkShapes(const CNNLayer* layer, const std::vector<SizeVector>& inShapes) const {
865     checkNumOfInput(inShapes, {1, 2});
866 }
867
868 void MVNValidator::parseParams(CNNLayer* layer) {
869     auto casted = dynamic_cast<MVNLayer*>(layer);
870     if (!casted) {
871         THROW_IE_EXCEPTION << "Layer is not instance of MVNLayer class";
872     }
873     casted->across_channels = casted->GetParamAsInt("across_channels", 0);
874     casted->normalize = casted->GetParamAsInt("normalize_variance", 1);
875 }
876
877 void MVNValidator::checkParams(const CNNLayer* layer) {
878 }
879
880 MVNValidator::MVNValidator(const std::string& _type) : LayerValidator(_type) {}
881
882 void MVNValidator::checkShapes(const CNNLayer* layer, const std::vector<SizeVector>& inShapes) const {
883     checkNumOfInput(inShapes, {1});
884 }
885
886 void GRNValidator::parseParams(CNNLayer* layer) {
887     auto casted = dynamic_cast<GRNLayer*>(layer);
888     if (!casted) {
889         THROW_IE_EXCEPTION << "Layer is not instance of GRNLayer class";
890     }
891     casted->bias = casted->GetParamAsFloat("bias", 0.f);
892 }
893
894 void GRNValidator::checkParams(const CNNLayer* layer) {
895     LayerValidator::checkParams(layer);
896 }
897
898 GRNValidator::GRNValidator(const std::string& _type) : LayerValidator(_type) {}
899
900 void GRNValidator::checkShapes(const CNNLayer* layer, const std::vector<SizeVector>& inShapes) const {
901     checkNumOfInput(inShapes, {1});
902 }
903
904 void SoftMaxValidator::parseParams(CNNLayer* layer) {
905     auto casted = dynamic_cast<SoftMaxLayer*>(layer);
906     if (!casted) {
907         THROW_IE_EXCEPTION << "Layer is not instance of SoftMaxLayer class";
908     }
909     casted->axis = casted->GetParamAsInt("axis", 1);
910 }
911
912 void SoftMaxValidator::checkParams(const CNNLayer* layer) {
913     auto casted = dynamic_cast<const SoftMaxLayer*>(layer);
914     if (!casted) {
915         THROW_IE_EXCEPTION << "Layer is not instance of SoftMaxLayer class";
916     }
917     int axis = casted->GetParamAsInt("axis", 1);
918     if (axis < 0) {
919         THROW_IE_EXCEPTION << "The value of SoftMax layer axis parameter is invalid";
920     }
921 }
922
923 SoftMaxValidator::SoftMaxValidator(const std::string& _type) : LayerValidator(_type) {}
924
925 void SoftMaxValidator::checkShapes(const CNNLayer* layer, const std::vector<SizeVector>& inShapes) const {
926     checkNumOfInput(inShapes, {1});
927 }
928
929 void NormValidator::parseParams(CNNLayer* layer) {
930     auto casted = dynamic_cast<NormLayer*>(layer);
931     if (!casted) {
932         THROW_IE_EXCEPTION << "Layer is not instance of NormLayer class";
933     }
934     casted->_size = casted->GetParamAsUInt("local_size", 0);
935     casted->_size += casted->GetParamAsUInt("local-size", 0);
936     casted->_k = casted->GetParamAsUInt("k", 1);
937     casted->_alpha = casted->GetParamAsFloat("alpha");
938     casted->_beta = casted->GetParamAsFloat("beta");
939     casted->_isAcrossMaps = CaselessEq<std::string>()(casted->GetParamAsString("region"), "across");
940 }
941
942 void NormValidator::checkParams(const CNNLayer* layer) {
943     auto casted = dynamic_cast<const NormLayer*>(layer);
944     if (!casted) {
945         THROW_IE_EXCEPTION << "Layer is not instance of NormLayer class";
946     }
947     float _alpha = casted->GetParamAsFloat("alpha");
948     float _beta = casted->GetParamAsFloat("beta");
949     if (_alpha < 0 && _beta < 0) {
950         THROW_IE_EXCEPTION << "The value of Norm layer alpha or beta parameters is invalid";
951     }
952 }
953
954 NormValidator::NormValidator(const std::string& _type) : LayerValidator(_type) {}
955
956 void NormValidator::checkShapes(const CNNLayer* layer, const std::vector<SizeVector>& inShapes) const {
957     checkNumOfInput(inShapes, {1});
958 }
959
960 SplitValidator::SplitValidator(const std::string& _type) : LayerValidator(_type) {}
961
962 void SplitValidator::parseParams(CNNLayer* layer) {
963     auto casted = dynamic_cast<SplitLayer*>(layer);
964     if (!casted) {
965         THROW_IE_EXCEPTION << "Layer is not instance of SplitLayer class";
966     }
967     casted->_axis = casted->GetParamAsUInt("axis", 1);
968
969     std::string out_sizes;
970     for (auto& i : layer->outData) {
971         if (!out_sizes.empty())
972             out_sizes += ",";
973         if (static_cast<int>(i->getTensorDesc().getDims().size()) <= casted->_axis) {
974             THROW_IE_EXCEPTION << "Internal error - dimensions are empty";
975         }
976         out_sizes += std::to_string(i->getTensorDesc().getDims()[casted->_axis]);
977     }
978     if (!out_sizes.empty())
979         casted->params["out_sizes"] = out_sizes;
980 }
981
982 void SplitValidator::checkParams(const CNNLayer* layer) {
983     LayerValidator::checkParams(layer);
984     std::vector<int> out_sizes = layer->GetParamAsInts("out_sizes", {});
985     if (out_sizes.empty()) {
986         THROW_IE_EXCEPTION << "Value of out_sizes attribute is empty";
987     }
988 }
989
990 void SplitValidator::checkShapes(const CNNLayer* layer, const std::vector<SizeVector>& inShapes) const {
991     auto casted = dynamic_cast<const SplitLayer*>(layer);
992     if (!casted) {
993         THROW_IE_EXCEPTION << "Layer is not instance of SplitLayer class";
994     }
995     checkNumOfInput(inShapes, {1});
996     auto version = BaseCreator::version_;
997     if (version > 3) {
998         std::vector<int> out_sizes = layer->GetParamAsInts("out_sizes", {});
999         size_t sum(0);
1000         for (const auto& size : out_sizes)
1001             sum += size;
1002         if (inShapes.empty() || inShapes[0].size() <= casted->_axis)
1003             THROW_IE_EXCEPTION << "Layer has incorrect input shapes!";
1004         if (sum != inShapes[0][casted->_axis]) {
1005             THROW_IE_EXCEPTION << "The sum of the dimensions on the axis(" << casted->_axis
1006                                << ") is not equal out_sizes: " << details::dumpVec(out_sizes);
1007         }
1008     }
1009 }
1010
1011 ConcatValidator::ConcatValidator(const std::string& _type) : LayerValidator(_type) {}
1012
1013 void ConcatValidator::parseParams(CNNLayer* layer) {
1014     auto casted = dynamic_cast<ConcatLayer*>(layer);
1015     if (!casted) {
1016         THROW_IE_EXCEPTION << "Layer is not instance of ConcatLayer class";
1017     }
1018     casted->_axis = casted->GetParamAsUInt("axis", 1);
1019 }
1020
1021 void ConcatValidator::checkParams(const CNNLayer* layer) {
1022 }
1023
1024 void ConcatValidator::checkShapes(const CNNLayer* layer, const std::vector<SizeVector>& inShapes) const {
1025     if (inShapes.empty())
1026         THROW_IE_EXCEPTION << "Inputs are empty";
1027
1028     auto casted = dynamic_cast<const ConcatLayer*>(layer);
1029     if (!casted) {
1030         THROW_IE_EXCEPTION << "Invalid Concat layer.";
1031     }
1032
1033     auto firstShape = inShapes[0];
1034     size_t firstShapeSize = firstShape.size();
1035     size_t axis = casted->_axis;
1036     if (axis >= firstShapeSize)
1037         THROW_IE_EXCEPTION << "Concat axis(" << axis
1038                            << ") should be less the number of current input dimensions ("
1039                            << firstShapeSize << ")";
1040
1041     for (size_t i = 1; i < inShapes.size(); i++) {
1042         auto shape = inShapes[i];
1043         if (shape.size() != firstShapeSize)
1044             THROW_IE_EXCEPTION << "Invalid inputs for Concat layer: number of dimensions must match: "
1045                                << firstShapeSize << " vs " << shape.size();
1046         bool eq_part1 = std::equal(firstShape.begin(), firstShape.begin() + axis,
1047                                    shape.begin());
1048         bool eq_part2 = std::equal(firstShape.begin() + axis + 1, firstShape.end(),
1049                                    shape.begin() + axis + 1);
1050         if (!(eq_part1 && eq_part2))
1051             THROW_IE_EXCEPTION << "Invalid inputs for Concat layer: dimensions should match in all "
1052                                << "positions except axis (" << axis << ") : [" << dumpVec(firstShape) << "] vs ["
1053                                << dumpVec(shape) <<"]";
1054     }
1055 }
1056
1057 GemmValidator::GemmValidator(const std::string& _type) : LayerValidator(_type) {}
1058
1059 void GemmValidator::parseParams(CNNLayer* layer) {
1060     auto casted = dynamic_cast<GemmLayer*>(layer);
1061     if (!casted) {
1062         THROW_IE_EXCEPTION << "Layer is not instance of GemmLayer class";
1063     }
1064     casted->alpha = casted->GetParamAsFloat("alpha", 1);
1065     casted->beta = casted->GetParamAsFloat("beta", 1);
1066     casted->transpose_a = casted->GetParamsAsBool("transpose_a", false);
1067     casted->transpose_b = casted->GetParamsAsBool("transpose_b", false);
1068 }
1069
1070 void GemmValidator::checkParams(const CNNLayer* layer) {
1071     LayerValidator::checkParams(layer);
1072 }
1073
1074 void GemmValidator::checkShapes(const CNNLayer* layer, const vector<SizeVector>& inShapes) const {
1075     auto casted = dynamic_cast<const GemmLayer*>(layer);
1076     if (!casted) {
1077         THROW_IE_EXCEPTION << "Layer is not instance of GemmLayer class";
1078     }
1079
1080     size_t numInputs = inShapes.size();
1081     checkNumOfInput(inShapes, {2, 3});
1082
1083     auto dims0 = inShapes[0];
1084     auto dims1 = inShapes[1];
1085     if (dims0.size() < 2 || dims1.size() < 2) {
1086         THROW_IE_EXCEPTION << "Gemm input shapes must have at least 2 dimensions";
1087     }
1088
1089     unsigned long xAxis = dims0.size() - 1;
1090     unsigned long yAxis = dims0.size() - 2;
1091     if (dims0[xAxis] != dims1[yAxis])
1092         THROW_IE_EXCEPTION << "Gemm input0 x dimension must be equal to input1 y dimension ("
1093                            << dims0[xAxis] << " vs " << dims1[yAxis] << ")";
1094
1095     if (inShapes.size() == 3) {
1096         auto dims2 = inShapes[2];
1097         if (dims2.size() < 2) {
1098             THROW_IE_EXCEPTION << "Gemm input shapes must have at least 2 dimensions";
1099         }
1100
1101         if (dims2[xAxis] != dims1[xAxis])
1102             THROW_IE_EXCEPTION << "Gemm input2 x dimension must be equal to input1 x dimension ("
1103                                << dims2[xAxis] << " vs " << dims1[xAxis] << ")";
1104
1105         if (dims2[yAxis] != dims0[yAxis])
1106             THROW_IE_EXCEPTION << "Gemm input2 y dimension must be equal to input0 y dimension ("
1107                                << dims2[yAxis] << " vs " << dims0[yAxis] << ")";
1108     }
1109 }
1110
1111 PadValidator::PadValidator(const std::string& _type) : LayerValidator(_type) {}
1112
1113 void PadValidator::parseParams(CNNLayer* layer) {
1114     auto casted = dynamic_cast<PadLayer*>(layer);
1115     if (!casted) {
1116         THROW_IE_EXCEPTION << layer->name << " Layer is not instance of PadLayer class";
1117     }
1118     std::vector<uint32_t> pads_begin = casted->GetParamAsUInts("pads_begin");
1119     std::vector<uint32_t> pads_end = casted->GetParamAsUInts("pads_end");
1120
1121     casted->pads_begin.clear();
1122     for (size_t i = 0; i < pads_begin.size(); i++) {
1123         casted->pads_begin.insert(i, pads_begin[i]);
1124     }
1125
1126     casted->pads_end.clear();
1127     for (size_t i = 0; i < pads_end.size(); i++) {
1128         casted->pads_end.insert(i, pads_end[i]);
1129     }
1130
1131     casted->pad_value = casted->GetParamAsFloat("pad_value", 0.0f);
1132
1133     std::string mode = casted->GetParamAsString("pad_mode", "constant");
1134     if (mode == "constant") {
1135         casted->pad_mode = PadLayer::Constant;
1136     } else if (mode == "edge") {
1137         casted->pad_mode = PadLayer::Edge;
1138     } else if (mode == "reflect") {
1139         casted->pad_mode = PadLayer::Reflect;
1140     } else if (mode == "symmetric") {
1141         casted->pad_mode = PadLayer::Symmetric;
1142     } else {
1143         THROW_IE_EXCEPTION << layer->name << " Unsupported pad mode operation: " << mode;
1144     }
1145 }
1146
1147 void PadValidator::checkParams(const CNNLayer* layer) {
1148     LayerValidator::checkParams(layer);
1149 }
1150
1151 void PadValidator::checkShapes(const CNNLayer* layer, const vector<SizeVector>& inShapes) const {
1152     auto casted = dynamic_cast<const PadLayer*>(layer);
1153     if (!casted) {
1154         THROW_IE_EXCEPTION << layer->name << " Layer is not instance of PadLayer class";
1155     }
1156
1157     size_t numInputs = inShapes.size();
1158     checkNumOfInput(inShapes, {1});
1159
1160     if (inShapes[0].size() != casted->pads_begin.size())
1161         THROW_IE_EXCEPTION << layer->name << " Dimensions count mismatch in layer " << layer->name
1162                            << ". Expected: " << casted->pads_begin.size() << " Got: " << inShapes[0].size();
1163
1164     if (inShapes[0].size() != casted->pads_end.size())
1165         THROW_IE_EXCEPTION << layer->name << " Dimensions count mismatch in layer " << layer->name
1166                            << ". Expected: " << casted->pads_end.size() << " Got: " << inShapes[0].size();
1167
1168     if (casted->pad_mode == PadLayer::Symmetric || casted->pad_mode == PadLayer::Reflect) {
1169         for (size_t i = 0; i < inShapes[0].size(); i++) {
1170             if (inShapes[0][i] < casted->pads_begin[i]) {
1171                 THROW_IE_EXCEPTION << layer->name << " Pad can't be grater than input shape in symmetric and reflect modes."
1172                                    << " For dimension " << i << " pad_begin=" << casted->pads_begin[i]
1173                                    << " in_shape="<< inShapes[0][i];
1174             }
1175             if (inShapes[0][i] < casted->pads_end[i]) {
1176                 THROW_IE_EXCEPTION << layer->name << " Pad can't be grater than input shape in symmetric and reflect modes."
1177                                    << " For dimension " << i << " pad_end=" << casted->pads_end[i]
1178                                    << " in_shape="<< inShapes[0][i];
1179             }
1180         }
1181     }
1182 }
1183
1184 GatherValidator::GatherValidator(const std::string& _type) : LayerValidator(_type) {}
1185
1186 void GatherValidator::parseParams(CNNLayer* layer) {
1187     auto casted = dynamic_cast<GatherLayer*>(layer);
1188     if (!casted) {
1189         THROW_IE_EXCEPTION << layer->name << " Layer is not instance of GatherLayer class";
1190     }
1191
1192     casted->axis = casted->GetParamAsInt("axis", 0);
1193 }
1194
1195 void GatherValidator::checkParams(const CNNLayer* layer) {
1196     LayerValidator::checkParams(layer);
1197 }
1198
1199 void GatherValidator::checkShapes(const CNNLayer* layer, const vector<SizeVector>& inShapes) const {
1200     auto casted = dynamic_cast<const GatherLayer*>(layer);
1201     if (!casted) {
1202         THROW_IE_EXCEPTION << layer->name << " Layer is not instance of GatherLayer class";
1203     }
1204
1205     size_t numInputs = inShapes.size();
1206     if (numInputs != 2)
1207         THROW_IE_EXCEPTION << layer->name << " Gather can take only 2 inputs, but actually it has: " << numInputs;
1208
1209     if (casted->axis > 0 && inShapes[0].size() < (1 + casted->axis))
1210         THROW_IE_EXCEPTION << layer->name << " Incorrect input dictionary dimensions " << inShapes[0].size()
1211                            << " and axis number " << casted->axis;
1212     else if (casted->axis < 0 && (static_cast<int>(inShapes[0].size()) + casted->axis) < 0)
1213         THROW_IE_EXCEPTION << layer->name << " Incorrect input dictionary dimensions " << inShapes[0].size()
1214                            << " and axis number " << casted->axis;
1215 }
1216
1217 StridedSliceValidator::StridedSliceValidator(const std::string& _type) : LayerValidator(_type) {}
1218
1219 void StridedSliceValidator::parseParams(CNNLayer* layer) {
1220     auto casted = dynamic_cast<StridedSliceLayer*>(layer);
1221     if (!casted) {
1222         THROW_IE_EXCEPTION << layer->name << " Layer is not instance of StridedSlice class";
1223     }
1224
1225     casted->begin_mask = layer->GetParamAsString("begin_mask", "");
1226     casted->end_mask = layer->GetParamAsString("end_mask", "");
1227     casted->ellipsis_mask = layer->GetParamAsString("ellipsis_mask", "");
1228     casted->new_axis_mask = layer->GetParamAsString("new_axis_mask", "");
1229     casted->shrink_axis_mask = layer->GetParamAsString("shrink_axis_mask", "");
1230 }
1231
1232 void StridedSliceValidator::checkParams(const CNNLayer* layer) {
1233     LayerValidator::checkParams(layer);
1234 }
1235
1236 void StridedSliceValidator::checkShapes(const CNNLayer* layer, const vector<SizeVector>& inShapes) const {
1237     auto casted = dynamic_cast<const StridedSliceLayer*>(layer);
1238     if (!casted) {
1239         THROW_IE_EXCEPTION << layer->name << " Layer is not instance of StridedSliceLayer class";
1240     }
1241
1242     size_t numInputs = inShapes.size();
1243     if (numInputs > 4)
1244         THROW_IE_EXCEPTION << layer->name << " StridedSlice can take up to 4 inputs, but actually it has: " << numInputs;
1245
1246     size_t ellipsis_mask_counter = 0;
1247     for (size_t i = 0; i < casted->ellipsis_mask.size(); ++i) {
1248         if (casted->ellipsis_mask[i] == '1')
1249             ellipsis_mask_counter++;
1250     }
1251     if (ellipsis_mask_counter > 1)
1252         THROW_IE_EXCEPTION << layer->name << " 'Ellipsis_mask' must be a power of two (only one ellipsis)!";
1253 }
1254
1255
1256 ShuffleChannelsValidator::ShuffleChannelsValidator(const std::string& _type) : LayerValidator(_type) {}
1257
1258 void ShuffleChannelsValidator::parseParams(CNNLayer* layer) {
1259     auto casted = dynamic_cast<ShuffleChannelsLayer*>(layer);
1260     if (!casted) {
1261         THROW_IE_EXCEPTION << layer->name << " Layer is not instance of ShuffleChannels class";
1262     }
1263
1264     casted->axis = casted->GetParamAsInt("axis", 1);
1265     casted->group = casted->GetParamAsUInt("group", 1);
1266 }
1267
1268 void ShuffleChannelsValidator::checkParams(const CNNLayer* layer) {
1269     LayerValidator::checkParams(layer);
1270 }
1271
1272 void ShuffleChannelsValidator::checkShapes(const CNNLayer* layer, const vector<SizeVector>& inShapes) const {
1273     auto casted = dynamic_cast<const ShuffleChannelsLayer*>(layer);
1274     if (!casted) {
1275         THROW_IE_EXCEPTION << layer->name << " Layer is not instance of ShuffleChannels class";
1276     }
1277
1278     size_t numInputs = inShapes.size();
1279     if (numInputs != 1)
1280         THROW_IE_EXCEPTION << layer->name << " ShuffleChannels can take only 1 input, but actually it has: " << numInputs;
1281
1282     if (casted->axis > 0 && inShapes[0].size() < (1 + casted->axis))
1283         THROW_IE_EXCEPTION << layer->name << "I ncorrect input tensor dimensions " << inShapes[0].size()
1284         << " and axis number " << casted->axis;
1285     else if (casted->axis < 0 && (static_cast<int>(inShapes[0].size()) + casted->axis) < 0)
1286         THROW_IE_EXCEPTION << layer->name << " Incorrect input dictionary dimensions " << inShapes[0].size()
1287         << " and axis number " << casted->axis;
1288
1289     int axis = casted->axis;
1290     if (axis < 0)
1291         axis += inShapes[0].size();
1292
1293     if (inShapes[0][axis] % casted->group)
1294         THROW_IE_EXCEPTION << layer->name << " Group parameter must evenly divide the channel dimension!";
1295
1296     size_t dataLength = 1;
1297     for (size_t i = axis + 1; i < inShapes[0].size(); i++)
1298         dataLength *= inShapes[0][i];
1299
1300     if (dataLength == 0)
1301         THROW_IE_EXCEPTION << layer->name << " Incorrect input parameters dimension!";
1302 }
1303
1304
1305 DepthToSpaceValidator::DepthToSpaceValidator(const std::string& _type) : LayerValidator(_type) {}
1306
1307 void DepthToSpaceValidator::parseParams(CNNLayer* layer) {
1308     auto casted = dynamic_cast<DepthToSpaceLayer*>(layer);
1309     if (!casted) {
1310         THROW_IE_EXCEPTION << layer->name << " Layer is not instance of DepthToSpace class";
1311     }
1312
1313     casted->block_size = casted->GetParamAsUInt("block_size", 1);
1314 }
1315
1316 void DepthToSpaceValidator::checkParams(const CNNLayer* layer) {
1317     LayerValidator::checkParams(layer);
1318 }
1319
1320 void DepthToSpaceValidator::checkShapes(const CNNLayer* layer, const vector<SizeVector>& inShapes) const {
1321     auto casted = dynamic_cast<const DepthToSpaceLayer*>(layer);
1322     if (!casted) {
1323         THROW_IE_EXCEPTION << layer->name << " Layer is not instance of DepthToSpace class";
1324     }
1325
1326     size_t numInputs = inShapes.size();
1327     if (numInputs != 1)
1328         THROW_IE_EXCEPTION << layer->name << " DepthToSpace can take only 1 input, but actually it has: " << numInputs;
1329
1330     if (inShapes[0].size() < 3)
1331         THROW_IE_EXCEPTION << layer->name << " Incorrect number of input dimensions!";
1332
1333     if (casted->block_size == 0)
1334         THROW_IE_EXCEPTION << layer->name << " Incorrect block_size parameter is zero!";
1335
1336     if (inShapes[0][inShapes[0].size() - 3] % (casted->block_size * casted->block_size))
1337         THROW_IE_EXCEPTION << layer->name << " block_size parameter is incompatible with input tensor Color dimension size!";
1338 }
1339
1340
1341 SpaceToDepthValidator::SpaceToDepthValidator(const std::string& _type) : LayerValidator(_type) {}
1342
1343 void SpaceToDepthValidator::parseParams(CNNLayer* layer) {
1344     auto casted = dynamic_cast<SpaceToDepthLayer*>(layer);
1345     if (!casted) {
1346         THROW_IE_EXCEPTION << layer->name << " Layer is not instance of SpaceToDepth class";
1347     }
1348
1349     casted->block_size = casted->GetParamAsUInt("block_size", 1);
1350 }
1351
1352 void SpaceToDepthValidator::checkParams(const CNNLayer* layer) {
1353     LayerValidator::checkParams(layer);
1354 }
1355
1356 void SpaceToDepthValidator::checkShapes(const CNNLayer* layer, const vector<SizeVector>& inShapes) const {
1357     auto casted = dynamic_cast<const SpaceToDepthLayer*>(layer);
1358     if (!casted) {
1359         THROW_IE_EXCEPTION << layer->name << " Layer is not instance of SpaceToDepth class";
1360     }
1361
1362     size_t numInputs = inShapes.size();
1363     if (numInputs != 1)
1364         THROW_IE_EXCEPTION << layer->name << " SpaceToDepth can take only 1 input, but actually it has: " << numInputs;
1365
1366     if (inShapes[0].size() < 2)
1367         THROW_IE_EXCEPTION << layer->name << " Incorrect number of input dimensions!";
1368
1369     if (casted->block_size == 0)
1370         THROW_IE_EXCEPTION << layer->name << " Incorrect block_size parameter is zero!";
1371
1372     if (inShapes[0][inShapes[0].size() - 1] % casted->block_size)
1373         THROW_IE_EXCEPTION << layer->name << " block_size parameter is incompatible with input tensor With dimension size!";
1374
1375     if (inShapes[0][inShapes[0].size() - 2] % casted->block_size)
1376         THROW_IE_EXCEPTION << layer->name << " block_size parameter is incompatible with input tensor Height dimension size!";
1377 }
1378
1379
1380 ReverseSequenceValidator::ReverseSequenceValidator(const std::string& _type) : LayerValidator(_type) {}
1381
1382 void ReverseSequenceValidator::parseParams(CNNLayer* layer) {
1383     auto casted = dynamic_cast<ReverseSequenceLayer*>(layer);
1384     if (!casted) {
1385         THROW_IE_EXCEPTION << layer->name << " Layer is not instance of ReverseSequence class";
1386     }
1387
1388     casted->seq_axis = casted->GetParamAsInt("seq_axis", 1);
1389     casted->batch_axis = casted->GetParamAsInt("batch_axis", 0);
1390 }
1391
1392 void ReverseSequenceValidator::checkParams(const CNNLayer* layer) {
1393     LayerValidator::checkParams(layer);
1394 }
1395
1396 void ReverseSequenceValidator::checkShapes(const CNNLayer* layer, const vector<SizeVector>& inShapes) const {
1397     auto casted = dynamic_cast<const ReverseSequenceLayer*>(layer);
1398     if (!casted) {
1399         THROW_IE_EXCEPTION << layer->name << " Layer is not instance of ReverseSequence class";
1400     }
1401
1402     size_t numInputs = inShapes.size();
1403     if (numInputs != 2)
1404         THROW_IE_EXCEPTION << layer->name << " ReverseSequence can take 2 inputs, but actually it has: " << numInputs;
1405
1406     if (inShapes[1].size() != 1)
1407         THROW_IE_EXCEPTION << layer->name << " Incorrect number of 'seq_lengths' input dimensions!";
1408
1409     if (casted->seq_axis > 0 && inShapes[0].size() < (1 + casted->seq_axis))
1410         THROW_IE_EXCEPTION << layer->name << "Incorrect input tensor dimensions " << inShapes[0].size()
1411                            << " and seq_axis number " << casted->seq_axis;
1412     else if (casted->seq_axis < 0 && (static_cast<int>(inShapes[0].size()) + casted->seq_axis) < 0)
1413         THROW_IE_EXCEPTION << layer->name << " Incorrect input dictionary dimensions " << inShapes[0].size()
1414                            << " and seq_axis number " << casted->seq_axis;
1415
1416     if (casted->batch_axis > 0 && inShapes[0].size() < (1 + casted->batch_axis))
1417         THROW_IE_EXCEPTION << layer->name << "Incorrect input tensor dimensions " << inShapes[0].size()
1418                            << " and batch_axis number " << casted->batch_axis;
1419     else if (casted->batch_axis < 0 && (static_cast<int>(inShapes[0].size()) + casted->batch_axis) < 0)
1420         THROW_IE_EXCEPTION << layer->name << " Incorrect input dictionary dimensions " << inShapes[0].size()
1421                            << " and batch_axis number " << casted->batch_axis;
1422
1423     int batch_axis = casted->batch_axis;
1424     if (batch_axis < 0)
1425         batch_axis += inShapes[0].size();
1426     if (inShapes[1][0] != inShapes[0][batch_axis])
1427         THROW_IE_EXCEPTION << layer->name << " Incorrect 'seq_lengths_dims' parameter dimensions!";
1428 }
1429
1430
1431 SqueezeValidator::SqueezeValidator(const std::string& _type) : LayerValidator(_type) {}
1432
1433 void SqueezeValidator::parseParams(CNNLayer* layer) {
1434     auto casted = dynamic_cast<SqueezeLayer*>(layer);
1435     if (!casted) {
1436         THROW_IE_EXCEPTION << layer->name << " Layer is not instance of Squeeze class";
1437     }
1438 }
1439
1440 void SqueezeValidator::checkParams(const CNNLayer* layer) {
1441     LayerValidator::checkParams(layer);
1442 }
1443
1444 void SqueezeValidator::checkShapes(const CNNLayer* layer, const vector<SizeVector>& inShapes) const {
1445     auto casted = dynamic_cast<const SqueezeLayer*>(layer);
1446     if (!casted) {
1447         THROW_IE_EXCEPTION << layer->name << " Layer is not instance of Squeeze class";
1448     }
1449
1450     size_t numInputs = inShapes.size();
1451     if (numInputs != 2)
1452         THROW_IE_EXCEPTION << layer->name << " Squeeze can take 2 inputs, but actually it has: " << numInputs;
1453
1454     if (inShapes[1].size() != 1)
1455         THROW_IE_EXCEPTION << layer->name << " Incorrect number of 'indices_to_squeeze' input dimensions!";
1456 }
1457
1458
1459 UnsqueezeValidator::UnsqueezeValidator(const std::string& _type) : LayerValidator(_type) {}
1460
1461 void UnsqueezeValidator::parseParams(CNNLayer* layer) {
1462     auto casted = dynamic_cast<UnsqueezeLayer*>(layer);
1463     if (!casted) {
1464         THROW_IE_EXCEPTION << layer->name << " Layer is not instance of Unsqueeze class";
1465     }
1466 }
1467
1468 void UnsqueezeValidator::checkParams(const CNNLayer* layer) {
1469     LayerValidator::checkParams(layer);
1470 }
1471
1472 void UnsqueezeValidator::checkShapes(const CNNLayer* layer, const vector<SizeVector>& inShapes) const {
1473     auto casted = dynamic_cast<const UnsqueezeLayer*>(layer);
1474     if (!casted) {
1475         THROW_IE_EXCEPTION << layer->name << " Layer is not instance of Unsqueeze class";
1476     }
1477
1478     size_t numInputs = inShapes.size();
1479     if (numInputs != 2)
1480         THROW_IE_EXCEPTION << layer->name << " Unsqueeze can take 2 inputs, but actually it has: " << numInputs;
1481
1482     if (inShapes[1].size() != 1)
1483         THROW_IE_EXCEPTION << layer->name << " Incorrect number of 'indices_to_set' input dimensions!";
1484 }
1485
1486
1487 RangeValidator::RangeValidator(const std::string& _type) : LayerValidator(_type) {}
1488
1489 void RangeValidator::parseParams(CNNLayer* layer) {
1490     auto casted = dynamic_cast<RangeLayer*>(layer);
1491     if (!casted) {
1492         THROW_IE_EXCEPTION << layer->name << " Layer is not instance of Range class";
1493     }
1494 }
1495
1496 void RangeValidator::checkParams(const CNNLayer* layer) {}
1497
1498 void RangeValidator::checkShapes(const CNNLayer* layer, const vector<SizeVector>& inShapes) const {
1499     auto casted = dynamic_cast<const RangeLayer*>(layer);
1500     if (!casted) {
1501         THROW_IE_EXCEPTION << layer->name << " Layer is not instance of Range class";
1502     }
1503
1504     size_t numInputs = inShapes.size();
1505     if (numInputs != 3)
1506         THROW_IE_EXCEPTION << layer->name << " Range can take 3 inputs, but actually it has: " << numInputs;
1507
1508     if (inShapes[0].size() != 1)
1509         THROW_IE_EXCEPTION << layer->name << " Incorrect number of 'start' input dimensions!";
1510
1511     if (inShapes[1].size() != 1)
1512         THROW_IE_EXCEPTION << layer->name << " Incorrect number of 'limit' input dimensions!";
1513
1514     if (inShapes[2].size() != 1)
1515         THROW_IE_EXCEPTION << layer->name << " Incorrect number of 'delta' input dimensions!";
1516 }
1517
1518
1519 FillValidator::FillValidator(const std::string& _type) : LayerValidator(_type) {}
1520
1521 void FillValidator::parseParams(CNNLayer* layer) {}
1522
1523 void FillValidator::checkParams(const CNNLayer* layer) {}
1524
1525 void FillValidator::checkShapes(const CNNLayer* layer, const vector<SizeVector>& inShapes) const {
1526     size_t numInputs = inShapes.size();
1527     if (numInputs != 2)
1528         THROW_IE_EXCEPTION << layer->name << " Fill can take 2 inputs, but actually it has: " << numInputs;
1529
1530     if (inShapes[0].size() != 1)
1531         THROW_IE_EXCEPTION << layer->name << " Incorrect number of 'fill_dims' input dimensions!";
1532
1533     if (inShapes[1].size() != 1)
1534         THROW_IE_EXCEPTION << layer->name << " Incorrect number of 'fill_value' input dimensions!";
1535 }
1536
1537
1538 ExpandValidator::ExpandValidator(const std::string& _type) : LayerValidator(_type) {}
1539
1540 void ExpandValidator::parseParams(CNNLayer* layer) {
1541     auto casted = dynamic_cast<ExpandLayer*>(layer);
1542     if (!casted) {
1543         THROW_IE_EXCEPTION << layer->name << " Layer is not instance of Expand class";
1544     }
1545 }
1546
1547 void ExpandValidator::checkParams(const CNNLayer* layer) {
1548     LayerValidator::checkParams(layer);
1549 }
1550
1551 void ExpandValidator::checkShapes(const CNNLayer* layer, const vector<SizeVector>& inShapes) const {
1552     auto casted = dynamic_cast<const ExpandLayer*>(layer);
1553     if (!casted) {
1554         THROW_IE_EXCEPTION << layer->name << " Layer is not instance of Expand class";
1555     }
1556
1557     size_t numInputs = inShapes.size();
1558     if (numInputs != 2)
1559         THROW_IE_EXCEPTION << layer->name << " Expand can take 2 inputs, but actually it has: " << numInputs;
1560
1561     if (inShapes[1].size() != 1)
1562         THROW_IE_EXCEPTION << layer->name << " Incorrect number of 'shape' input dimensions!";
1563 }
1564
1565 /****************************************/
1566 /*** RNN specific validators ************/
1567 /****************************************/
1568
1569 static RNNCellBase::CellType cell_type_from(string type_name) {
1570     const vector<string> to_remove {"Cell", "Sequence"};
1571     for (auto &sub : to_remove) {
1572         auto idx = type_name.find(sub);
1573         if (idx != string::npos)
1574             type_name.erase(idx);
1575     }
1576
1577     if (!one_of(type_name, "LSTM", "RNN", "GRU"))
1578         THROW_IE_EXCEPTION << "Unknown RNN cell type " << type_name << ". "
1579                            << "Expected one of [ LSTM | RNN | GRU ].";
1580
1581     return type_name == "LSTM" ? RNNSequenceLayer::LSTM :
1582            type_name == "GRU"  ? RNNSequenceLayer::GRU :
1583            type_name == "RNN"  ? RNNSequenceLayer::RNN :
1584            RNNSequenceLayer::LSTM;
1585 }
1586
1587 static RNNSequenceLayer::Direction direction_from(string direction_name) {
1588     if (!one_of(direction_name, "Forward", "Backward", "Bidirectional"))
1589         THROW_IE_EXCEPTION << "Unknown RNN direction type " << direction_name << ". "
1590                            << "Expected one of [ Forward | Backward | Bidirectional ].";
1591
1592     return direction_name == "Forward" ? RNNSequenceLayer::FWD :
1593            direction_name == "Backward" ? RNNSequenceLayer::BWD :
1594            direction_name == "Bidirecttional" ? RNNSequenceLayer::BDR :
1595            RNNSequenceLayer::FWD;
1596 }
1597
1598 template<>
1599 std::vector<std::string>
1600 RNNBaseValidator<RNNSequenceLayer::LSTM>::def_acts {"sigmoid", "tanh", "tanh"};
1601 template<>
1602 std::vector<float>
1603 RNNBaseValidator<RNNSequenceLayer::LSTM>::def_alpha {0, 0, 0};
1604 template<>
1605 std::vector<float>
1606 RNNBaseValidator<RNNSequenceLayer::LSTM>::def_beta {0, 0, 0};
1607 template<>
1608 size_t
1609 RNNBaseValidator<RNNSequenceLayer::LSTM>::G = 4;
1610 template<>
1611 size_t
1612 RNNBaseValidator<RNNSequenceLayer::LSTM>::NS = 2;
1613
1614 template<>
1615 std::vector<std::string>
1616 RNNBaseValidator<RNNSequenceLayer::GRU>::def_acts {"sigmoid", "tanh"};
1617 template<>
1618 std::vector<float>
1619 RNNBaseValidator<RNNSequenceLayer::GRU>::def_alpha {0, 0};
1620 template<>
1621 std::vector<float>
1622 RNNBaseValidator<RNNSequenceLayer::GRU>::def_beta {0, 0};
1623 template<>
1624 size_t
1625 RNNBaseValidator<RNNSequenceLayer::GRU>::G = 3;
1626 template<>
1627 size_t
1628 RNNBaseValidator<RNNSequenceLayer::GRU>::NS = 1;
1629
1630 template<>
1631 std::vector<std::string>
1632 RNNBaseValidator<RNNSequenceLayer::RNN>::def_acts {"tanh"};
1633 template<>
1634 std::vector<float>
1635 RNNBaseValidator<RNNSequenceLayer::RNN>::def_alpha {0};
1636 template<>
1637 std::vector<float>
1638 RNNBaseValidator<RNNSequenceLayer::RNN>::def_beta {0};
1639 template<>
1640 size_t
1641 RNNBaseValidator<RNNSequenceLayer::RNN>::G = 1;
1642 template<>
1643 size_t
1644 RNNBaseValidator<RNNSequenceLayer::RNN>::NS = 1;
1645
1646 template<RNNSequenceLayer::CellType CELL>
1647 RNNBaseValidator<CELL>::RNNBaseValidator(const std::string& _type) : LayerValidator(_type) {}
1648
1649 template<RNNSequenceLayer::CellType CELL>
1650 void RNNBaseValidator<CELL>::parseParams(CNNLayer* layer) {
1651     auto rnn = dynamic_cast<RNNCellBase*>(layer);
1652     if (!rnn)
1653         THROW_IE_EXCEPTION << "Layer is not instance of RNNLayer class";
1654
1655     rnn->cellType = cell_type_from(layer->type);
1656     rnn->hidden_size = rnn->GetParamAsInt("hidden_size");
1657     rnn->clip = rnn->GetParamAsFloat("clip", 0.0f);
1658     rnn->activations = rnn->GetParamAsStrings("activations", def_acts);
1659     rnn->activation_alpha = rnn->GetParamAsFloats("activation_alpha", def_alpha);
1660     rnn->activation_beta = rnn->GetParamAsFloats("activation_beta", def_beta);
1661
1662     if (rnn->cellType == RNNCellBase::GRU) {
1663         auto lbr = rnn->GetParamAsBool("linear_before_reset", false);
1664         if (lbr) rnn->cellType = RNNCellBase::GRU_LBR;
1665     }
1666 }
1667
1668 template<RNNSequenceLayer::CellType CELL>
1669 void RNNBaseValidator<CELL>::checkParams(const InferenceEngine::CNNLayer *layer) {
1670     auto rnn = dynamic_cast<const RNNCellBase*>(layer);
1671     if (!rnn)
1672         THROW_IE_EXCEPTION << "Layer is not instance of RNNLayer class";
1673
1674     if (rnn->clip < 0.0f)
1675         THROW_IE_EXCEPTION << "Clip parameter should be positive";
1676
1677     for (auto &act : rnn->activations)
1678         if (!one_of(act, "sigmoid", "tanh", "relu"))
1679             THROW_IE_EXCEPTION << "Unsupported activation function (" << act << ") for RNN layer.";
1680
1681     int act_num_required = def_acts.size();
1682     if (rnn->activations.size() != act_num_required)
1683         THROW_IE_EXCEPTION << "Expected " << act_num_required << " activations, but provided "
1684                            << rnn->activations.size();
1685
1686     if (rnn->activation_alpha.size() != act_num_required)
1687         THROW_IE_EXCEPTION << "Expected " << act_num_required << " activation alpha parameters, "
1688                            << "but provided " << rnn->activation_alpha.size();
1689     if (rnn->activation_beta.size() != act_num_required)
1690         THROW_IE_EXCEPTION << "Expected " << act_num_required << " activation beta parameters, "
1691                            << "but provided " << rnn->activation_beta.size();
1692 }
1693
1694 template<RNNSequenceLayer::CellType CELL>
1695 void RNNBaseValidator<CELL>::checkCorrespondence(const CNNLayer* layer,
1696          const map<string, Blob::Ptr>& blobs,
1697          const vector<SizeVector>& inShapes) const {
1698     auto rnn = dynamic_cast<const RNNCellBase*>(layer);
1699     if (!rnn)
1700         THROW_IE_EXCEPTION << "Layer is not instance of RNNLayer class";
1701
1702     if (blobs.size() != 2)
1703         THROW_IE_EXCEPTION << "Expected only 2 blobs with trained parameters (weights and biases), "
1704                            << "but provided only " << blobs.size();
1705     if (inShapes.empty())
1706         THROW_IE_EXCEPTION << "No input tensors.";
1707
1708     size_t D = inShapes[0].back();
1709     size_t S = rnn->hidden_size;
1710     size_t expectetd_w_size = G*S*(D+S);
1711     size_t expectetd_b_size = G*S;
1712
1713     if (rnn->cellType == RNNCellBase::GRU_LBR)
1714         expectetd_b_size = (G + 1)*S;
1715
1716     auto w = blobs.find("weights");
1717     if (w == blobs.end())
1718         THROW_IE_EXCEPTION << "Weights blob is not provided";
1719
1720     if (w->second->size() != expectetd_w_size)
1721         THROW_IE_EXCEPTION << "Weights blob has wrang size. Expected " << expectetd_w_size;
1722
1723     auto b = blobs.find("biases");
1724     if (b == blobs.end())
1725         THROW_IE_EXCEPTION << "Biases blob is not provided";
1726
1727     if (b->second->size() != expectetd_b_size)
1728         THROW_IE_EXCEPTION << "Biases blob has wrang size. Expected " << expectetd_b_size;
1729 }
1730
1731 template<RNNSequenceLayer::CellType CELL>
1732 RNNSequenceValidator<CELL>::RNNSequenceValidator(const std::string& _type) : RNNBaseValidator<CELL>(_type) {}
1733
1734 template<RNNSequenceLayer::CellType CELL>
1735 void RNNSequenceValidator<CELL>::parseParams(CNNLayer* layer) {
1736     RNNBaseValidator<CELL>::parseParams(layer);
1737
1738     auto casted = dynamic_cast<RNNSequenceLayer*>(layer);
1739     if (!casted)
1740         THROW_IE_EXCEPTION << "Layer is not instance of RNNLayer class";
1741
1742     std::string direction = layer->GetParamAsString("direction");
1743
1744     casted->axis = layer->GetParamAsUInt("axis", 1);
1745     casted->direction = direction_from(direction);
1746 }
1747
1748 template<RNNSequenceLayer::CellType CELL>
1749 void RNNSequenceValidator<CELL>::checkParams(const InferenceEngine::CNNLayer *layer) {
1750     RNNBaseValidator<CELL>::checkParams(layer);
1751
1752     auto casted = dynamic_cast<const RNNSequenceLayer*>(layer);
1753     if (!casted)
1754         THROW_IE_EXCEPTION << "Layer is not instance of RNNLayer class";
1755
1756     if (!one_of(casted->axis, 1, 0))
1757         THROW_IE_EXCEPTION << "Unsupported iteration axis for RNNSequense layer. Only 0 or 1 axis are supported.";
1758 }
1759
1760 template<RNNSequenceLayer::CellType CELL>
1761 void RNNSequenceValidator<CELL>::checkShapes(const CNNLayer* layer, const vector<SizeVector>& inShapes) const {
1762     auto rnn = dynamic_cast<const RNNSequenceLayer*>(layer);
1763     if (!rnn)
1764         THROW_IE_EXCEPTION << "Layer is not instance of RNNSequenceLayer class";
1765
1766     if (inShapes.empty())
1767         THROW_IE_EXCEPTION << "No input tensors.";
1768
1769     if (inShapes[0].size() != 3)
1770         THROW_IE_EXCEPTION << "First input data tensor should be 3D";
1771
1772     size_t T_axis = rnn->axis;
1773     size_t N_axis = (T_axis + 1)%2;
1774     size_t N = inShapes[0][N_axis];
1775     size_t T = inShapes[0][T_axis];
1776     size_t D = inShapes[0].back();
1777     size_t S = rnn->hidden_size;
1778     size_t NS = RNNSequenceValidator<CELL>::NS;
1779
1780     SizeVector expected_state_shape {N, S};
1781
1782     if (inShapes.size() > 1) {  // has an initial state blobs
1783         if (inShapes.size() != 1 + NS)
1784             THROW_IE_EXCEPTION << "Wrong number of input tensors. Expected 1 (data) or "
1785                                << 1 + NS << " (data and states)";
1786         if (inShapes[1] != expected_state_shape)
1787             THROW_IE_EXCEPTION << "Wrong shape of first initial state tensors.";
1788 //                             << " Expected " << expected_state_shape << " but provided " << inShapes[1];
1789
1790         if (NS == 2 && inShapes[2] != expected_state_shape)
1791             THROW_IE_EXCEPTION << "Wrong shape of second initial state tensors.";
1792 //                             << " Expected " << expected_state_shape << " but provided " << inShapes[2];
1793     }
1794 }
1795
1796 template class details::RNNSequenceValidator<RNNSequenceLayer::RNN>;
1797 template class details::RNNSequenceValidator<RNNSequenceLayer::GRU>;
1798 template class details::RNNSequenceValidator<RNNSequenceLayer::LSTM>;
1799
1800 template<RNNSequenceLayer::CellType CELL>
1801 RNNCellValidator<CELL>::RNNCellValidator(const std::string& _type) : RNNBaseValidator<CELL>(_type) {}
1802
1803 template<RNNSequenceLayer::CellType CELL>
1804 void RNNCellValidator<CELL>::checkShapes(const CNNLayer* layer, const vector<SizeVector>& inShapes) const {
1805     auto rnn = dynamic_cast<const RNNCellBase*>(layer);
1806     if (!rnn)
1807         THROW_IE_EXCEPTION << "Layer is not instance of RNNSequenceLayer class";
1808
1809     const size_t &NS = RNNCellValidator<CELL>::NS;
1810
1811     if (inShapes.size() != NS + 1)
1812         THROW_IE_EXCEPTION << "Wrong number of input tensors. Expected " << NS + 1;
1813
1814     if (inShapes[0].size() != 2)
1815         THROW_IE_EXCEPTION << "First input data tensor should be 2D";
1816
1817     size_t N = inShapes[0][0];
1818     size_t D = inShapes[0][1];
1819     size_t S = rnn->hidden_size;
1820
1821     SizeVector expected_state_shape {N, S};
1822
1823     if (inShapes[1] != expected_state_shape)
1824         THROW_IE_EXCEPTION << "Wrong shape of first initial state tensors.";
1825 //                         << " Expected " << expected_state_shape << " but provided " << inShapes[1];
1826
1827     if (NS == 2 && inShapes[2] != expected_state_shape)
1828         THROW_IE_EXCEPTION << "Wrong shape of second initial state tensors.";
1829 //                         << " Expected " << expected_state_shape << " but provided " << inShapes[2];
1830 }
1831
1832 template class details::RNNCellValidator<RNNSequenceLayer::RNN>;
1833 template class details::RNNCellValidator<RNNSequenceLayer::GRU>;
1834 template class details::RNNCellValidator<RNNSequenceLayer::LSTM>;
1835
1836 void ArgMaxValidator::checkParams(const CNNLayer* layer) {
1837     unsigned int top_k_ = layer->GetParamAsUInt("top_k");
1838 }
1839
1840 void ArgMaxValidator::checkShapes(const CNNLayer* layer, const std::vector<SizeVector>& inShapes) const {
1841     checkNumOfInput(inShapes, {1});
1842 }
1843
1844 ArgMaxValidator::ArgMaxValidator(const std::string& _type) : LayerValidator(_type) {
1845 }
1846
1847 void CTCGreedyDecoderValidator::checkParams(const CNNLayer* layer) {
1848     int flag = layer->GetParamAsInt("ctc_merge_repeated", 0);
1849     if (flag != 0 && flag != 1) {
1850         THROW_IE_EXCEPTION << "CTCGreedyDecoder layer parameter ctc_merge_repeated is invalid";
1851     }
1852 }
1853
1854 void CTCGreedyDecoderValidator::checkShapes(const CNNLayer* layer, const std::vector<SizeVector>& inShapes) const {
1855     checkNumOfInput(inShapes, {1, 2});
1856 }
1857
1858 CTCGreedyDecoderValidator::CTCGreedyDecoderValidator(const std::string& _type) : LayerValidator(_type) {
1859 }
1860
1861 void DetectionOutputValidator::parseParams(CNNLayer* layer) {
1862     unsigned int num_classes = layer->GetParamAsUInt("num_classes");
1863     if (num_classes == 0) {
1864         THROW_IE_EXCEPTION << "num_classes parameter of DetectionOutput layer can't be equal to zero";
1865     }
1866     float _nms_threshold = layer->GetParamAsFloat("nms_threshold");
1867     if (_nms_threshold < 0) {
1868         THROW_IE_EXCEPTION << "nms_threshold parameter of DetectionOutput layer can't be less then zero";
1869     }
1870     int _keep_top_k = layer->GetParamAsUInt("keep_top_k", -1);
1871
1872     if (layer->CheckParamPresence("background_label_id"))
1873         int _background_label_id = layer->GetParamAsUInt("background_label_id", -1);
1874     if (layer->CheckParamPresence("top_k"))
1875         int _top_k = layer->GetParamAsUInt("top_k", -1);
1876     if (layer->CheckParamPresence("variance_encoded_in_target"))
1877         bool _variance_encoded_in_target = static_cast<bool>(layer->GetParamAsUInt("variance_encoded_in_target"));
1878     if (layer->CheckParamPresence("num_orient_classes"))
1879         int _num_orient_classes = layer->GetParamAsUInt("num_orient_classes");
1880     if (layer->CheckParamPresence("share_location"))
1881         bool _share_location = static_cast<bool>(layer->GetParamAsUInt("share_location"));
1882     if (layer->CheckParamPresence("interpolate_orientation"))
1883         int _interpolate_orientation = layer->GetParamAsInt("interpolate_orientation");
1884     if (layer->CheckParamPresence("confidence_threshold")) {
1885         float _confidence_threshold = layer->GetParamAsFloat("confidence_threshold");
1886         if (_confidence_threshold < 0) {
1887             THROW_IE_EXCEPTION << "_nms_threshold parameter of DetectionOutput layer can't be less then zero";
1888         }
1889     }
1890
1891     if (layer->CheckParamPresence("code_type")) {
1892         std::string _code_type = layer->GetParamAsString("code_type");
1893         std::vector<std::string> code_types = {"caffe.PriorBoxParameter.CENTER_SIZE",
1894                                                "caffe.PriorBoxParameter.CORNER"};
1895         auto it = std::find(code_types.begin(), code_types.end(), _code_type);
1896         if (it == code_types.end()) {
1897             THROW_IE_EXCEPTION << "Parameter code_type of DetectionOutput layer ";
1898         }
1899     }
1900 }
1901
1902 void DetectionOutputValidator::checkParams(const CNNLayer* layer) {
1903     unsigned int num_classes = layer->GetParamAsUInt("num_classes");
1904     if (num_classes == 0) {
1905         THROW_IE_EXCEPTION << "num_classes parameter of DetectionOutput layer can't be equal to zero";
1906     }
1907     float _nms_threshold = layer->GetParamAsFloat("nms_threshold");
1908     if (_nms_threshold < 0) {
1909         THROW_IE_EXCEPTION << "nms_threshold parameter of DetectionOutput layer can't be less then zero";
1910     }
1911     int _keep_top_k = layer->GetParamAsUInt("keep_top_k", -1);
1912
1913     if (layer->CheckParamPresence("background_label_id"))
1914         int _background_label_id = layer->GetParamAsUInt("background_label_id", -1);
1915     if (layer->CheckParamPresence("top_k"))
1916         int _top_k = layer->GetParamAsUInt("top_k", -1);
1917     if (layer->CheckParamPresence("variance_encoded_in_target"))
1918         bool _variance_encoded_in_target = static_cast<bool>(layer->GetParamAsUInt("variance_encoded_in_target"));
1919     if (layer->CheckParamPresence("num_orient_classes"))
1920         int _num_orient_classes = layer->GetParamAsUInt("num_orient_classes");
1921     if (layer->CheckParamPresence("share_location"))
1922         bool _share_location = static_cast<bool>(layer->GetParamAsUInt("share_location"));
1923     if (layer->CheckParamPresence("interpolate_orientation"))
1924         int _interpolate_orientation = layer->GetParamAsInt("interpolate_orientation");
1925     if (layer->CheckParamPresence("confidence_threshold")) {
1926         float _confidence_threshold = layer->GetParamAsFloat("confidence_threshold");
1927         if (_confidence_threshold < 0) {
1928             THROW_IE_EXCEPTION << "_nms_threshold parameter of DetectionOutput layer can't be less then zero";
1929         }
1930     }
1931     if (layer->CheckParamPresence("code_type")) {
1932         std::string _code_type = layer->GetParamAsString("code_type");
1933         std::vector<std::string> code_types = {"caffe.PriorBoxParameter.CENTER_SIZE",
1934                                                "caffe.PriorBoxParameter.CORNER"};
1935         auto it = std::find(code_types.begin(), code_types.end(), _code_type);
1936         if (it == code_types.end()) {
1937             THROW_IE_EXCEPTION << "Parameter code_type of DetectionOutput layer ";
1938         }
1939     }
1940 }
1941
1942 void DetectionOutputValidator::checkShapes(const CNNLayer* layer, const std::vector<SizeVector>& inShapes) const {
1943     checkNumOfInput(inShapes, {3, 5});
1944 }
1945
1946 DetectionOutputValidator::DetectionOutputValidator(const std::string& _type) : LayerValidator(_type) {
1947 }
1948
1949 void InterpValidator::checkParams(const CNNLayer* layer) {
1950 }
1951
1952 void InterpValidator::checkShapes(const CNNLayer* layer, const std::vector<SizeVector>& inShapes) const {
1953     checkNumOfInput(inShapes, {1, 2});
1954     auto IS_ZERO = [](float value) {
1955         return std::fabs(value) < std::numeric_limits<float>::epsilon();
1956     };
1957     if (inShapes.size() != 2) {
1958         float factor = layer->GetParamAsFloat("factor", 0);
1959         if (factor < 0)
1960             THROW_IE_EXCEPTION << "factor parameter of Interp layer can't be less then zero";
1961         float shrink_factor = layer->GetParamAsFloat("shrink_factor", 0);
1962         if (shrink_factor < 0)
1963             THROW_IE_EXCEPTION << "shrink_factor parameter of Interp layer can't be less then zero";
1964         float zoom_factor = (layer->GetParamAsFloat("zoom_factor", 0));
1965         if (zoom_factor < 0)
1966             THROW_IE_EXCEPTION << "zoom_factor parameter of Interp layer can't be less then zero";
1967         bool noFactor = IS_ZERO(factor) && IS_ZERO(shrink_factor) && IS_ZERO(zoom_factor);
1968
1969         auto height = layer->GetParamAsUInt("height", 0);
1970         auto width = layer->GetParamAsUInt("width", 0);
1971
1972         if (noFactor && (height == 0 || width == 0)) {
1973             THROW_IE_EXCEPTION
1974                     << "Can't reshape without factor, or target resolution. "
1975                     << "Supported attributes: factor, shrink_factor, zoom_factor, height, width";
1976         }
1977     }
1978 }
1979
1980 InterpValidator::InterpValidator(const std::string& _type) : LayerValidator(_type) {
1981 }
1982
1983 void InterpValidator::parseParams(CNNLayer* layer) {
1984     float factor = layer->GetParamAsFloat("factor", 0);
1985     float shrink_factor = layer->GetParamAsFloat("shrink_factor", 0);
1986     float zoom_factor = layer->GetParamAsFloat("zoom_factor", 0);
1987
1988     auto height = layer->GetParamAsUInt("height", 0);
1989     auto width = layer->GetParamAsUInt("width", 0);
1990 }
1991
1992     void PermuteValidator::checkParams(const CNNLayer* layer) {
1993     std::vector<unsigned int> layerOrder = layer->GetParamAsUInts("order");
1994 }
1995
1996 void PermuteValidator::checkShapes(const CNNLayer* layer, const std::vector<SizeVector>& inShapes) const {
1997     checkNumOfInput(inShapes, {1});
1998 }
1999
2000 PermuteValidator::PermuteValidator(const std::string& _type) : LayerValidator(_type) {
2001 }
2002
2003 void PriorBoxValidator::checkParams(const CNNLayer* layer) {
2004     std::vector<unsigned int> min_sizes = layer->GetParamAsUInts("min_size", {});
2005     std::vector<unsigned int> max_sizes = layer->GetParamAsUInts("max_size", {});
2006     bool flip = static_cast<bool>(layer->GetParamAsInt("flip"));
2007     if (layer->CheckParamPresence("aspect_ratio"))
2008         const std::vector<unsigned int> aspect_ratios = layer->GetParamAsUInts("aspect_ratio", {});
2009     bool clip_ = static_cast<bool>(layer->GetParamAsInt("clip"));
2010     if (layer->CheckParamPresence("variance")) {
2011         float variance_ = layer->GetParamAsFloat("variance", 1.0);
2012         if (variance_ < 0) {
2013             THROW_IE_EXCEPTION << "The value of PriorBox layer variance_ parameter is invalid";
2014         }
2015     }
2016     float step_ = layer->GetParamAsFloat("step", 0);
2017     if (step_ < 0) {
2018         THROW_IE_EXCEPTION << "The value of PriorBox layer step_ parameter is invalid";
2019     }
2020     float offset_ = layer->GetParamAsFloat("offset");
2021     if (offset_ < 0) {
2022         THROW_IE_EXCEPTION << "The value of PriorBox layer offset_ parameter is invalid";
2023     }
2024 }
2025
2026 void PriorBoxValidator::checkShapes(const CNNLayer* layer, const std::vector<SizeVector>& inShapes) const {
2027     checkNumOfInput(inShapes, {2});
2028 }
2029
2030 PriorBoxValidator::PriorBoxValidator(const std::string& _type) : LayerValidator(_type) {
2031 }
2032
2033 void PriorBoxClusteredValidator::checkParams(const CNNLayer* layer) {
2034     std::vector<float> widths = layer->GetParamAsFloats("width", {});
2035     for (auto i : widths) {
2036         if (i < 0) {
2037             THROW_IE_EXCEPTION << "The value of PriorBoxClustered layer width parameter is invalid";
2038         }
2039     }
2040     std::vector<float> heights = layer->GetParamAsFloats("height", {});
2041     for (auto i : heights) {
2042         if (i < 0) {
2043             THROW_IE_EXCEPTION << "The value of PriorBoxClustered layer heights parameter is invalid";
2044         }
2045     }
2046     bool flip = static_cast<bool>(layer->GetParamAsInt("flip"));
2047     bool clip_ = static_cast<bool>(layer->GetParamAsInt("clip"));
2048     float offset_ = layer->GetParamAsFloat("offset");
2049     if (offset_ < 0) {
2050         THROW_IE_EXCEPTION << "The value of PriorBox layer offset_ parameter is invalid";
2051     }
2052     if (layer->CheckParamPresence("variance")) {
2053         float variance_ = layer->GetParamAsFloat("variance");
2054         if (variance_ < 0) {
2055             THROW_IE_EXCEPTION << "The value of PriorBox layer variance_ parameter is invalid";
2056         }
2057     }
2058     float step_h_ = layer->GetParamAsFloat("step_h", 0);
2059     if (step_h_ < 0) {
2060         THROW_IE_EXCEPTION << "The value of PriorBox layer step_h_ parameter is invalid";
2061     }
2062     float step_w_ = layer->GetParamAsFloat("step_w", 0);
2063     if (step_w_ < 0) {
2064         THROW_IE_EXCEPTION << "The value of PriorBox layer step_w_ parameter is invalid";
2065     }
2066     float img_h_ = layer->GetParamAsFloat("img_h", 0);
2067     if (img_h_ < 0) {
2068         THROW_IE_EXCEPTION << "The value of PriorBox layer img_h_ parameter is invalid";
2069     }
2070     float  img_w_ = layer->GetParamAsFloat("img_w", 0);
2071     if (img_w_ < 0) {
2072         THROW_IE_EXCEPTION << "The value of PriorBox layer img_w_ parameter is invalid";
2073     }
2074 }
2075
2076 void PriorBoxClusteredValidator::checkShapes(const CNNLayer* layer, const std::vector<SizeVector>& inShapes) const {
2077     checkNumOfInput(inShapes, {2});
2078 }
2079
2080 PriorBoxClusteredValidator::PriorBoxClusteredValidator(const std::string& _type) : LayerValidator(_type) {
2081 }
2082
2083 void ProposalValidator::checkParams(const CNNLayer* layer) {
2084     unsigned int post_nms_topn_ = layer->GetParamAsUInt("post_nms_topn");
2085
2086     if (layer->CheckParamPresence("feat_stride"))
2087         unsigned int feat_stride_ = layer->GetParamAsUInt("feat_stride");
2088     if (layer->CheckParamPresence("base_size"))
2089         unsigned int base_size_ = layer->GetParamAsUInt("base_size");
2090     if (layer->CheckParamPresence("min_size"))
2091         unsigned int min_size_ = layer->GetParamAsUInt("min_size");
2092     if (layer->CheckParamPresence("pre_nms_topn"))
2093         unsigned int pre_nms_topn_ = layer->GetParamAsUInt("pre_nms_topn");
2094     if (layer->CheckParamPresence("nms_thresh")) {
2095         float nms_thresh_ = layer->GetParamAsFloat("nms_thresh");
2096         if (nms_thresh_ < 0) {
2097             THROW_IE_EXCEPTION << "The value of Proposal layer nms_thresh_ parameter is invalid";
2098         }
2099     }
2100 }
2101
2102 void ProposalValidator::checkShapes(const CNNLayer* layer, const std::vector<SizeVector>& inShapes) const {
2103     checkNumOfInput(inShapes, {3});
2104 }
2105
2106 ProposalValidator::ProposalValidator(const std::string& _type) : LayerValidator(_type) {
2107 }
2108
2109 void PSROIPoolingValidator::checkParams(const CNNLayer* layer) {
2110     unsigned int output_dim = layer->GetParamAsUInt("output_dim");
2111     unsigned int group_size = layer->GetParamAsUInt("group_size");
2112     if (layer->CheckParamPresence("spatial_scale")) {
2113         float spatial_scale_ = layer->GetParamAsFloat("spatial_scale");
2114         if (spatial_scale_ < 0) {
2115             THROW_IE_EXCEPTION << "The value of PSROIPooling layer spatial_scale_ parameter is invalid";
2116         }
2117     }
2118 }
2119
2120 void PSROIPoolingValidator::checkShapes(const CNNLayer* layer, const std::vector<SizeVector>& inShapes) const {
2121     checkNumOfInput(inShapes, {1, 2});
2122 }
2123
2124 PSROIPoolingValidator::PSROIPoolingValidator(const std::string& _type) : LayerValidator(_type) {
2125 }
2126
2127 void RegionYoloValidator::checkParams(const CNNLayer* layer) {
2128     LayerValidator::checkParams(layer);
2129 }
2130
2131 void RegionYoloValidator::checkShapes(const CNNLayer* layer, const std::vector<SizeVector>& inShapes) const {
2132     checkNumOfInput(inShapes, {1});
2133 }
2134
2135 RegionYoloValidator::RegionYoloValidator(const std::string& _type) : LayerValidator(_type) {
2136 }
2137
2138 void ReorgYoloValidator::checkParams(const CNNLayer* layer) {
2139     LayerValidator::checkParams(layer);
2140 }
2141
2142 void ReorgYoloValidator::checkShapes(const CNNLayer* layer, const std::vector<SizeVector>& inShapes) const {
2143     checkNumOfInput(inShapes, {1});
2144 }
2145
2146 ReorgYoloValidator::ReorgYoloValidator(const std::string& _type) : LayerValidator(_type) {
2147 }
2148
2149 void ResampleValidator::checkParams(const CNNLayer* layer) {
2150     if (layer->CheckParamPresence("antialias")) {
2151         auto antialias = static_cast<size_t>(layer->GetParamAsInt("antialias"));
2152
2153         if (antialias != 0 && antialias != 1) {
2154             THROW_IE_EXCEPTION << "The value of resample layer antialias parameter is invalid";
2155         }
2156     }
2157     if (layer->CheckParamPresence("type")) {
2158         std::string type = layer->GetParamAsString("type");
2159         if (type != "caffe.ResampleParameter.NEAREST" && type != "caffe.ResampleParameter.CUBIC" &&
2160             type != "caffe.ResampleParameter.LINEAR") {
2161             THROW_IE_EXCEPTION << "The value of resample layer type parameter is invalid";
2162         }
2163     }
2164 }
2165
2166 void ResampleValidator::checkShapes(const CNNLayer* layer, const std::vector<SizeVector>& inShapes) const {
2167     checkNumOfInput(inShapes, {1, 2});
2168 }
2169
2170 ResampleValidator::ResampleValidator(const std::string& _type) : LayerValidator(_type) {
2171 }
2172
2173 void ROIPoolingValidator::checkParams(const CNNLayer* layer) {
2174     unsigned int pooled_h = layer->GetParamAsUInt("pooled_h");
2175     unsigned int pooled_w = layer->GetParamAsUInt("pooled_w");
2176     float spatial_scale = layer->GetParamAsFloat("spatial_scale");
2177     if (spatial_scale < 0) {
2178         THROW_IE_EXCEPTION << "The value of ROIPooling layer spatial_scale parameter is invalid";
2179     }
2180 }
2181
2182 void ROIPoolingValidator::checkShapes(const CNNLayer* layer, const std::vector<SizeVector>& inShapes) const {
2183     checkNumOfInput(inShapes, {1, 2});
2184 }
2185
2186 ROIPoolingValidator::ROIPoolingValidator(const std::string& _type) : LayerValidator(_type) {
2187 }
2188
2189 void SimplerNMSValidator::checkParams(const CNNLayer* layer) {
2190     unsigned int post_nms_topn_ = layer->GetParamAsUInt("post_nms_topn");
2191
2192     if (layer->CheckParamPresence("min_bbox_size"))
2193         unsigned int min_box_size_ = layer->GetParamAsUInt("min_bbox_size");
2194     if (layer->CheckParamPresence("feat_stride"))
2195         unsigned int feat_stride_ = layer->GetParamAsUInt("feat_stride");
2196     if (layer->CheckParamPresence("pre_nms_topn"))
2197         unsigned int pre_nms_topn_ = layer->GetParamAsUInt("pre_nms_topn");
2198     if (layer->CheckParamPresence("iou_threshold")) {
2199         float iou_threshold_ = layer->GetParamAsFloat("iou_threshold");
2200         if (iou_threshold_ < 0) {
2201             THROW_IE_EXCEPTION << "The value of SimplerNMS layer iou_threshold_ parameter is invalid";
2202         }
2203     }
2204     if (layer->CheckParamPresence("scale"))
2205         std::vector<unsigned int> scale = layer->GetParamAsUInts("scale", {});
2206     if (layer->CheckParamPresence("cls_threshold")) {
2207         float cls_threshold = layer->GetParamAsFloat("cls_threshold");
2208         if (cls_threshold < 0) {
2209             THROW_IE_EXCEPTION << "The value of SimplerNMS layer cls_threshold parameter is invalid";
2210         }
2211     }
2212 }
2213
2214 void SimplerNMSValidator::checkShapes(const CNNLayer* layer, const std::vector<SizeVector>& inShapes) const {
2215     checkNumOfInput(inShapes, {3});
2216 }
2217
2218 SimplerNMSValidator::SimplerNMSValidator(const std::string& _type) : LayerValidator(_type) {
2219 }
2220
2221 void SpatialTransformerValidator::checkParams(const CNNLayer* layer) {
2222     LayerValidator::checkParams(layer);
2223 }
2224
2225 void SpatialTransformerValidator::checkShapes(const CNNLayer* layer, const std::vector<SizeVector>& inShapes) const {
2226     checkNumOfInput(inShapes, {2});
2227 }
2228
2229 SpatialTransformerValidator::SpatialTransformerValidator(const std::string& _type) : LayerValidator(_type) {
2230 }
2231
2232 void UpsamplingValidator::checkParams(const CNNLayer* layer) {
2233     LayerValidator::checkParams(layer);
2234 }
2235
2236 void UpsamplingValidator::checkShapes(const CNNLayer* layer, const std::vector<SizeVector>& inShapes) const {
2237     checkNumOfInput(inShapes, {1});
2238 }
2239
2240 UpsamplingValidator::UpsamplingValidator(const std::string& _type) : LayerValidator(_type) {
2241 }
2242
2243 void UnpoolingValidator::checkParams(const CNNLayer* layer) {
2244     LayerValidator::checkParams(layer);
2245 }
2246
2247 void UnpoolingValidator::checkShapes(const CNNLayer* layer, const std::vector<SizeVector>& inShapes) const {
2248     checkNumOfInput(inShapes, {1});
2249 }
2250
2251 UnpoolingValidator::UnpoolingValidator(const std::string& _type) : LayerValidator(_type) {
2252 }
2253
2254 ActivationValidator::ActivationValidator(const std::string& _type) : LayerValidator(_type) {
2255 }
2256
2257 void ActivationValidator::checkParams(const CNNLayer* layer) {
2258     LayerValidator::checkParams(layer);
2259 }
2260
2261 void ActivationValidator::checkShapes(const CNNLayer* layer, const std::vector<SizeVector>& inShapes) const {
2262     checkNumOfInput(inShapes, {1});
2263 }
2264
2265 ConstValidator::ConstValidator(const std::string& _type) : LayerValidator(_type) {
2266 }
2267
2268 void ConstValidator::checkParams(const CNNLayer* layer) {
2269     LayerValidator::checkParams(layer);
2270 }
2271
2272 void ConstValidator::checkShapes(const CNNLayer* layer, const std::vector<SizeVector>& inShapes) const {
2273     checkNumOfInput(inShapes, {0, 1});
2274 }
2275
2276 CopyValidator::CopyValidator(const std::string& _type) : LayerValidator(_type) {
2277 }
2278
2279 void CopyValidator::checkParams(const CNNLayer* layer) {
2280     LayerValidator::checkParams(layer);
2281 }
2282
2283 void CopyValidator::checkShapes(const CNNLayer* layer, const std::vector<SizeVector>& inShapes) const {
2284     checkNumOfInput(inShapes, {1});
2285 }
2286
2287 ELUValidator::ELUValidator(const std::string& _type) : LayerValidator(_type) {
2288 }
2289
2290 void ELUValidator::checkParams(const CNNLayer* layer) {
2291     LayerValidator::checkParams(layer);
2292 }
2293
2294 void ELUValidator::checkShapes(const CNNLayer* layer, const std::vector<SizeVector>& inShapes) const {
2295     checkNumOfInput(inShapes, {1});
2296 }
2297
2298 InputValidator::InputValidator(const std::string& _type) : LayerValidator(_type) {
2299 }
2300
2301 void InputValidator::checkParams(const CNNLayer* layer) {
2302     LayerValidator::checkParams(layer);
2303 }
2304
2305 void InputValidator::checkShapes(const CNNLayer* layer, const std::vector<SizeVector>& inShapes) const {
2306     checkNumOfInput(inShapes, {0});
2307 }
2308
2309 MemoryValidator::MemoryValidator(const std::string& _type) : LayerValidator(_type) {
2310 }
2311
2312 void MemoryValidator::checkParams(const CNNLayer* layer) {
2313     int size = layer->GetParamAsInt("size");
2314     if (size != 2) {
2315         THROW_IE_EXCEPTION << "The value of Memory layer size parameter is invalid";
2316     }
2317 }
2318
2319 void MemoryValidator::checkShapes(const CNNLayer* layer, const std::vector<SizeVector>& inShapes) const {
2320     checkNumOfInput(inShapes, {1, 0});
2321 }
2322
2323 NormalizeValidator::NormalizeValidator(const std::string& _type) : LayerValidator(_type) {
2324 }
2325
2326 void NormalizeValidator::checkParams(const CNNLayer* layer) {
2327     if (layer->CheckParamPresence("eps")) {
2328         float eps = layer->GetParamAsFloat("eps");
2329         if (eps < 0) {
2330             THROW_IE_EXCEPTION << "The value of Normalize layer eps parameter is invalid";
2331         }
2332     }
2333 }
2334
2335 void NormalizeValidator::checkShapes(const CNNLayer* layer, const std::vector<SizeVector>& inShapes) const {
2336     checkNumOfInput(inShapes, {1});
2337 }
2338
2339 PowerFileValidator::PowerFileValidator(const std::string& _type) : LayerValidator(_type) {
2340 }
2341
2342 void PowerFileValidator::checkParams(const CNNLayer* layer) {
2343     LayerValidator::checkParams(layer);
2344 }
2345
2346 void PowerFileValidator::checkShapes(const CNNLayer* layer, const std::vector<SizeVector>& inShapes) const {
2347     checkNumOfInput(inShapes, {1});
2348 }
2349
2350 ReLU6Validator::ReLU6Validator(const std::string& _type) : LayerValidator(_type) {
2351 }
2352
2353 void ReLU6Validator::checkParams(const CNNLayer* layer) {
2354     LayerValidator::checkParams(layer);
2355 }
2356
2357 void ReLU6Validator::checkShapes(const CNNLayer* layer, const std::vector<SizeVector>& inShapes) const {
2358     checkNumOfInput(inShapes, {1});
2359 }
2360
2361 SigmoidValidator::SigmoidValidator(const std::string& _type) : LayerValidator(_type) {
2362 }
2363
2364 void SigmoidValidator::checkParams(const CNNLayer* layer) {
2365     LayerValidator::checkParams(layer);
2366 }
2367
2368 void SigmoidValidator::checkShapes(const CNNLayer* layer, const std::vector<SizeVector>& inShapes) const {
2369     checkNumOfInput(inShapes, {1});
2370 }
2371
2372 TanHValidator::TanHValidator(const std::string& _type) : LayerValidator(_type) {
2373 }
2374
2375 void TanHValidator::checkShapes(const CNNLayer* layer, const std::vector<SizeVector>& inShapes) const {
2376     checkNumOfInput(inShapes, {1});
2377 }
2378
2379 QuantizeValidator::QuantizeValidator(const std::string& _type) : LayerValidator(_type) {}
2380
2381 void QuantizeValidator::parseParams(CNNLayer* layer) {
2382     auto casted = dynamic_cast<QuantizeLayer*>(layer);
2383     if (!casted) {
2384         THROW_IE_EXCEPTION << "Layer is not instance of QuantizeLayer class";
2385     }
2386
2387     casted->levels = casted->GetParamAsInt("levels", 1);
2388
2389     if (casted->levels <= 1) {
2390         THROW_IE_EXCEPTION << layer->name << ": Incorrect value for parameter levels = " << casted->levels
2391                            << ". Expected to be > 1.";
2392     }
2393 }
2394
2395 void QuantizeValidator::checkParams(const CNNLayer* layer) {
2396     LayerValidator::checkParams(layer);
2397 }
2398
2399 void QuantizeValidator::checkShapes(const CNNLayer* layer, const vector<SizeVector>& inShapes) const {
2400     auto casted = dynamic_cast<const QuantizeLayer*>(layer);
2401     if (!casted) {
2402         THROW_IE_EXCEPTION << "Layer is not instance of QuantizeLayer class";
2403     }
2404
2405     size_t numInputs = inShapes.size();
2406     if (numInputs != 5)
2407         THROW_IE_EXCEPTION << "Quantize can take only 5 inputs, but actually it has: " << numInputs;
2408
2409     auto dims0 = inShapes[0];
2410     if (dims0.size() < 1) {
2411         THROW_IE_EXCEPTION << "Quantize input0 shape must have at least 1 dimension";
2412     }
2413 }
2414
2415 BinaryConvolutionValidator::BinaryConvolutionValidator(const std::string& _type) : LayerValidator(_type) {}
2416
2417 void BinaryConvolutionValidator::parseParams(CNNLayer* layer) {
2418     auto binConvLayer = dynamic_cast<BinaryConvolutionLayer*>(layer);
2419     if (!binConvLayer) {
2420         THROW_IE_EXCEPTION << "Layer is not instance of BinaryConvolutionLayer class";
2421     }
2422
2423     binConvLayer->_pad_value = binConvLayer->GetParamAsFloat("pad_value", -1.f);
2424     binConvLayer->_in_depth = binConvLayer->GetParamAsUInt("input");
2425     binConvLayer->_mode = BinaryConvolutionLayer::xnor_popcount;
2426     std::string mode = binConvLayer->GetParamAsString("mode", "xnor-popcount");
2427     if (mode != "xnor-popcount")
2428         THROW_IE_EXCEPTION << "Layer with type `" << _type << "` has incorrect mode!";
2429
2430     binConvLayer->_out_depth = binConvLayer->GetParamAsUInt("output");
2431
2432     binConvLayer->_kernel.clear();
2433     binConvLayer->_stride.clear();
2434     binConvLayer->_padding.clear();
2435     binConvLayer->_pads_end.clear();
2436     binConvLayer->_dilation.clear();
2437
2438     vector<unsigned int> kernels = binConvLayer->GetParamAsUInts("kernel", {});
2439     if (kernels.empty()) {
2440         // IR_v == 2
2441         binConvLayer->_kernel.insert(X_AXIS, binConvLayer->GetParamAsUInt("kernel-x"));
2442         binConvLayer->_kernel.insert(Y_AXIS, binConvLayer->GetParamAsUInt("kernel-y"));
2443
2444         binConvLayer->_stride.insert(X_AXIS, binConvLayer->GetParamAsUInt("stride-x", 1u));
2445         binConvLayer->_stride.insert(Y_AXIS, binConvLayer->GetParamAsUInt("stride-y", 1u));
2446         // TODO: maybe just throw exception, why do we change IR?
2447         if (0 == binConvLayer->_stride[X_AXIS]) {
2448             binConvLayer->_stride[X_AXIS] = 1u;
2449             LogError("Warning! in layer %s: Stride x is 0, setting to 1 ", binConvLayer->name.c_str());
2450         }
2451         if (0 == binConvLayer->_stride[Y_AXIS]) {
2452             binConvLayer->_stride[Y_AXIS] = 1u;
2453             LogError("Warning! in layer %s: Stride y is 0, setting to 1", binConvLayer->name.c_str());
2454         }
2455
2456         binConvLayer->_padding.insert(X_AXIS, binConvLayer->GetParamAsUInt("pad-x", 0u));
2457         binConvLayer->_padding.insert(Y_AXIS, binConvLayer->GetParamAsUInt("pad-y", 0u));
2458
2459         binConvLayer->_pads_end.insert(X_AXIS, binConvLayer->GetParamAsUInt("pad-r", binConvLayer->_padding[X_AXIS]));
2460         binConvLayer->_pads_end.insert(Y_AXIS, binConvLayer->GetParamAsUInt("pad-b", binConvLayer->_padding[Y_AXIS]));
2461
2462         binConvLayer->_dilation.insert(X_AXIS, binConvLayer->GetParamAsUInt("dilation-x", 1u));
2463         binConvLayer->_dilation.insert(Y_AXIS, binConvLayer->GetParamAsUInt("dilation-y", 1u));
2464     } else {
2465         // IR_v > 2
2466         for (int i = 1; i <= kernels.size(); i++) {
2467             binConvLayer->_kernel.insert(i - 1, kernels[kernels.size() - i]);
2468         }
2469
2470         vector<unsigned int> default_0 = vector<unsigned int> (binConvLayer->_kernel.size(), 0u);
2471         vector<unsigned int> default_1 = vector<unsigned int> (binConvLayer->_kernel.size(), 1u);
2472
2473         vector<unsigned int> strides = binConvLayer->GetParamAsUInts("strides", default_1);
2474         for (int i = 1; i <= strides.size(); i++) {
2475             if (strides[strides.size() - i] == 0) {
2476                 THROW_IE_EXCEPTION << "Stride could not be 0.\nIn layer " << binConvLayer->name;
2477             }
2478             binConvLayer->_stride.insert(i - 1, strides[strides.size() - i]);
2479         }
2480
2481         vector<unsigned int> pads_begin = binConvLayer->GetParamAsUInts("pads_begin", default_0);
2482         for (int i = 1; i <= pads_begin.size(); i++) {
2483             binConvLayer->_padding.insert(i - 1, pads_begin[pads_begin.size() - i]);
2484         }
2485
2486         vector<unsigned int> pads_end = binConvLayer->GetParamAsUInts("pads_end", pads_begin);
2487         for (int i = 1; i <= pads_end.size(); i++) {
2488             binConvLayer->_pads_end.insert(i - 1, pads_end[pads_end.size() - i]);
2489         }
2490
2491         vector<unsigned int> dilations = binConvLayer->GetParamAsUInts("dilations", default_1);
2492         for (int i = 1; i <= dilations.size(); i++) {
2493             binConvLayer->_dilation.insert(i - 1, dilations[dilations.size() - i]);
2494         }
2495     }
2496
2497     binConvLayer->_auto_pad = binConvLayer->GetParamAsString("auto_pad", "");
2498     binConvLayer->_group = binConvLayer->GetParamAsUInt("group", 1u);
2499 }
2500
2501 void BinaryConvolutionValidator::checkParams(const CNNLayer* layer) {
2502     auto casted = dynamic_cast<const BinaryConvolutionLayer*>(layer);
2503     if (!casted) {
2504         THROW_IE_EXCEPTION << "Layer is not instance of BinaryConvolutionLayer class";
2505     }
2506 }
2507
2508 void BinaryConvolutionValidator::checkCorrespondence(const CNNLayer* layer,
2509                                                const std::map<std::string, Blob::Ptr>& blobs,
2510                                                const vector<SizeVector>& inShapes) const {
2511     auto binConvLayer = dynamic_cast<const BinaryConvolutionLayer*>(layer);
2512     if (!binConvLayer)
2513         THROW_IE_EXCEPTION << "Layer is not instance of BinaryConvolutionLayer class";
2514 }
2515
2516 void BinaryConvolutionValidator::checkShapes(const CNNLayer* layer, const std::vector<SizeVector>& inShapes) const {
2517     checkNumOfInput(inShapes, {1});
2518 }
2519
2520 }  // namespace InferenceEngine