1 // Copyright (C) 2018-2019 Intel Corporation
2 // SPDX-License-Identifier: Apache-2.0
6 #include "ie_layer_validators.hpp"
8 #include "xml_parse_utils.h"
15 #include <ie_iextension.h>
16 #include <ie_format_parser.h>
18 #include <details/ie_exception.hpp>
20 namespace InferenceEngine {
22 using namespace details;
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...);
34 void CNNLayer::validateLayer() {
36 LayerValidator::Ptr validator = LayerValidators::getInstance()->getValidator(type);
37 validator->parseParams(this);
38 validator->checkParams(this);
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 << ". "
49 struct WeightableParams {
50 std::vector<size_t> _kernel;
51 size_t _outputs = 0lu;
53 bool _isKernelFromInput = false;
55 WeightableParams(size_t outputs, bool isKernelFromInput, size_t groups = 0, const std::vector<size_t>& kernel = {}) :
59 _isKernelFromInput(isKernelFromInput) {}
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();
72 for (auto dim : numDims) {
73 if (inputSize == dim) {
79 THROW_IE_EXCEPTION << "Input shape " << details::dumpVec(firstInputShape)
80 << " has unexpected size, supported sizes: " << details::dumpVec(numDims);
83 if (firstInputShape.empty()) THROW_IE_EXCEPTION << "Input shape can't be empty";
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]);
92 for (auto k : params._kernel) {
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";
103 auto weightsSize = details::product(weights->dims());
104 size_t expectedWeightsSize = OC * IC;
105 for (auto k : kernel) {
106 expectedWeightsSize *= k;
108 if (params._groups) expectedWeightsSize /= params._groups;
109 if (expectedWeightsSize != weightsSize) {
111 for (int i = 0; i < params._kernel.size(); i++) {
112 if (!ker_str.empty())
114 ker_str += std::to_string(kernel[i]);
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;
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;
134 void checkDims(const std::vector<SizeVector>& shapes, const vector<int>& expected_shape_size) {
135 for (auto i : shapes) {
137 THROW_IE_EXCEPTION << " Failed with invalid shapes: dimension is empty";
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";
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;
153 if (!shape_was_found) {
154 THROW_IE_EXCEPTION << "Number of inputs (" << inShapes.size() << ") is not equal to expected ones";
158 LayerValidators* LayerValidators::getInstance() {
160 _instance = new LayerValidators();
165 LayerValidator::Ptr LayerValidators::getValidator(const std::string& type) {
166 if (_validators.find(type) == _validators.end()) {
167 return std::make_shared<GeneralValidator>(type);
169 return _validators[type];
172 void LayerValidators::addImpl(const std::string& type, const LayerValidator::Ptr& validator) {
173 _validators[type] = validator;
176 LayerValidators* LayerValidators::_instance = nullptr;
178 GeneralValidator::GeneralValidator(const std::string& _type) : LayerValidator(_type) {}
180 void FullyConnectedValidator::parseParams(CNNLayer* layer) {
181 auto casted = dynamic_cast<FullyConnectedLayer*>(layer);
183 THROW_IE_EXCEPTION << "Layer is not instance of FullyConnectedLayer class";
185 casted->_out_num = casted->GetParamAsUInt("out-size");
188 void FullyConnectedValidator::checkParams(const CNNLayer* layer) {
189 auto casted = dynamic_cast<const FullyConnectedLayer*>(layer);
191 THROW_IE_EXCEPTION << "Layer is not instance of FullyConnectedLayer class";
193 unsigned int _out_num = casted->GetParamAsUInt("out-size");
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});
204 FullyConnectedValidator::FullyConnectedValidator(const std::string& _type) : LayerValidator(_type) {}
206 void FullyConnectedValidator::checkShapes(const CNNLayer* layer, const std::vector<SizeVector>& inShapes) const {
207 checkNumOfInput(inShapes, {1});
210 void CropValidator::parseParams(CNNLayer* layer) {
211 auto casted = dynamic_cast<CropLayer*>(layer);
213 THROW_IE_EXCEPTION << "Layer is not instance of CropLayer class";
215 if (casted->axis.empty()) {
216 auto getArray = [](std::string param, vector<int>& array) {
217 std::istringstream stream(param);
219 while (getline(stream, str, ',')) {
220 int val = std::stoi(str);
221 array.push_back(val);
224 getArray(layer->GetParamAsString("axis"), casted->axis);
225 if (casted->params.find("offset") != casted->params.end()) {
226 getArray(layer->GetParamAsString("offset"), casted->offset);
228 if (casted->params.find("dim") != casted->params.end()) {
229 getArray(layer->GetParamAsString("dim"), casted->dim);
231 if (casted->params.find("crop_begin") != casted->params.end()) {
232 getArray(layer->GetParamAsString("crop_begin"), casted->offset);
237 void CropValidator::checkParams(const CNNLayer* layer) {
238 auto casted = dynamic_cast<const CropLayer*>(layer);
240 THROW_IE_EXCEPTION << "Layer is not instance of CropLayer class";
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() << ")";
248 CropValidator::CropValidator(const std::string& _type) : LayerValidator(_type) {}
250 void CropValidator::checkShapes(const CNNLayer* layer, const vector<SizeVector>& inShapes) const {
251 auto casted = dynamic_cast<const CropLayer*>(layer);
253 THROW_IE_EXCEPTION << "Layer is not instance of CropLayer class";
255 size_t numInputs = inShapes.size();
256 checkNumOfInput(inShapes, {1, 2});
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()) {
270 << "Incorrect format of the Crop layer: `crop_begin` and `crop_end` attributes are valid for single input only";
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 << ")";
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 << ")";
294 ConvolutionValidator::ConvolutionValidator(const std::string& _type) : LayerValidator(_type) {}
296 void ConvolutionValidator::parseParams(CNNLayer* layer) {
297 auto convLayer = dynamic_cast<ConvolutionLayer*>(layer);
299 THROW_IE_EXCEPTION << "Layer is not instance of ConvolutionLayer class";
301 convLayer->_out_depth = convLayer->GetParamAsUInt("output");
303 convLayer->_kernel.clear();
304 convLayer->_stride.clear();
305 convLayer->_padding.clear();
306 convLayer->_pads_end.clear();
307 convLayer->_dilation.clear();
309 vector<unsigned int> kernels = convLayer->GetParamAsUInts("kernel", {});
310 if (kernels.empty()) {
312 convLayer->_kernel.insert(X_AXIS, convLayer->GetParamAsUInt("kernel-x"));
313 convLayer->_kernel.insert(Y_AXIS, convLayer->GetParamAsUInt("kernel-y"));
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());
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());
327 convLayer->_padding.insert(X_AXIS, convLayer->GetParamAsUInt("pad-x", 0u));
328 convLayer->_padding.insert(Y_AXIS, convLayer->GetParamAsUInt("pad-y", 0u));
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]));
333 convLayer->_dilation.insert(X_AXIS, convLayer->GetParamAsUInt("dilation-x", 1u));
334 convLayer->_dilation.insert(Y_AXIS, convLayer->GetParamAsUInt("dilation-y", 1u));
337 for (int i = 1; i <= kernels.size(); i++) {
338 convLayer->_kernel.insert(i - 1, kernels[kernels.size() - i]);
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);
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;
349 convLayer->_stride.insert(i - 1, strides[strides.size() - i]);
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]);
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]);
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]);
368 convLayer->_auto_pad = convLayer->GetParamAsString("auto_pad", "");
369 convLayer->_group = convLayer->GetParamAsUInt("group", 1u);
372 void ConvolutionValidator::checkParams(const CNNLayer* layer) {
373 auto casted = dynamic_cast<const ConvolutionLayer*>(layer);
375 THROW_IE_EXCEPTION << "Layer is not instance of ConvolutionLayer class";
377 casted->GetParamAsUInt("output");
379 vector<unsigned int> kernels = casted->GetParamAsUInts("kernel", {});
380 if (kernels.empty()) {
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);
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);
401 casted->GetParamAsString("auto_pad", "");
402 casted->GetParamAsUInt("group", 1);
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);
410 THROW_IE_EXCEPTION << "Layer is not instance of Convolution layer class";
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},
419 void ConvolutionValidator::checkShapes(const CNNLayer* layer, const std::vector<SizeVector>& inShapes) const {
420 checkNumOfInput(inShapes, {1});
423 void DeconvolutionValidator::parseParams(CNNLayer* layer) {
424 auto deconvLayer = dynamic_cast<DeconvolutionLayer*>(layer);
426 THROW_IE_EXCEPTION << "Layer is not instance of DeconvolutionLayer class";
428 ConvolutionValidator::parseParams(layer);
431 void DeconvolutionValidator::checkParams(const CNNLayer* layer) {
432 auto casted = dynamic_cast<const ConvolutionLayer*>(layer);
434 THROW_IE_EXCEPTION << "Layer is not instance of ConvolutionLayer class";
436 casted->GetParamAsUInt("output");
438 vector<unsigned int> kernels = casted->GetParamAsUInts("kernel", {});
439 if (kernels.empty()) {
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);
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);
460 casted->GetParamAsString("auto_pad", "");
461 casted->GetParamAsUInt("group", 1);
464 DeconvolutionValidator::DeconvolutionValidator(const std::string& _type) : ConvolutionValidator(_type) {}
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);
471 THROW_IE_EXCEPTION << "Layer is not instance of Deconvolution layer class";
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},
480 void DeconvolutionValidator::checkShapes(const CNNLayer* layer, const std::vector<SizeVector>& inShapes) const {
481 checkNumOfInput(inShapes, {1});
484 PoolingValidator::PoolingValidator(const std::string& _type) : LayerValidator(_type) {}
486 void PoolingValidator::parseParams(CNNLayer* layer) {
487 auto poolLayer = dynamic_cast<PoolingLayer*>(layer);
489 THROW_IE_EXCEPTION << "Layer is not instance of PoolingLayer class";
492 poolLayer->_kernel.clear();
493 poolLayer->_stride.clear();
494 poolLayer->_padding.clear();
495 poolLayer->_pads_end.clear();
497 poolLayer->_auto_pad = poolLayer->GetParamAsString("auto_pad", "");
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) {
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);
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);
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);
521 poolLayer->_padding.insert(X_AXIS, pad_w == 0u ? pad : pad_w);
522 poolLayer->_padding.insert(Y_AXIS, pad_h == 0u ? pad : pad_h);
524 poolLayer->_pads_end.insert(X_AXIS, 0u);
525 poolLayer->_pads_end.insert(Y_AXIS, 0u);
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"));
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());
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());
547 poolLayer->_padding.insert(X_AXIS, poolLayer->GetParamAsUInt("pad-x", 0u));
548 poolLayer->_padding.insert(Y_AXIS, poolLayer->GetParamAsUInt("pad-y", 0u));
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]));
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!";
562 for (int i = 1; i <= kernels.size(); i++) {
563 poolLayer->_kernel.insert(i - 1, kernels[kernels.size() - i]);
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);
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;
574 poolLayer->_stride.insert(i - 1, strides[strides.size() - i]);
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]);
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]);
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!";
594 // TODO: checks for presence of all required attributes, and that there's no extraneous parameters only.
597 void PoolingValidator::checkParams(const CNNLayer* layer) {
598 // TODO: check that values belong to the scope of the definition according to spec
601 void PoolingValidator::checkShapes(const CNNLayer* layer, const std::vector<SizeVector>& inShapes) const {
602 checkNumOfInput(inShapes, {1, 2});
605 void BatchNormalizationValidator::parseParams(CNNLayer* layer) {
606 auto casted = dynamic_cast<BatchNormalizationLayer*>(layer);
608 THROW_IE_EXCEPTION << "Layer is not instance of BatchNormalizationLayer class";
610 casted->epsilon = casted->GetParamAsFloat("epsilon");
613 void BatchNormalizationValidator::checkParams(const CNNLayer* layer) {
614 auto casted = dynamic_cast<const BatchNormalizationLayer*>(layer);
616 THROW_IE_EXCEPTION << "Layer is not instance of BatchNormalizationLayer class";
618 float epsilon = casted->GetParamAsFloat("epsilon");
620 THROW_IE_EXCEPTION << "The value of BatchNormalization layer epsilon parameter is invalid";
624 BatchNormalizationValidator::BatchNormalizationValidator(const std::string& _type) : LayerValidator(_type) {}
626 void BatchNormalizationValidator::checkShapes(const CNNLayer* layer, const std::vector<SizeVector>& inShapes) const {
627 checkNumOfInput(inShapes, {1});
630 void PowerValidator::parseParams(CNNLayer* layer) {
631 auto casted = dynamic_cast<PowerLayer*>(layer);
633 THROW_IE_EXCEPTION << "Layer is not instance of PowerLayer class";
635 casted->offset = casted->GetParamAsFloat("shift");
636 casted->power = casted->GetParamAsFloat("power");
637 casted->scale = casted->GetParamAsFloat("scale");
640 void PowerValidator::checkParams(const CNNLayer* layer) {
641 LayerValidator::checkParams(layer);
644 PowerValidator::PowerValidator(const std::string& _type) : LayerValidator(_type) {}
646 void PowerValidator::checkShapes(const CNNLayer* layer, const std::vector<SizeVector>& inShapes) const {
647 checkNumOfInput(inShapes, {1});
650 void PReLUValidator::parseParams(CNNLayer* layer) {
651 auto casted = dynamic_cast<PReLULayer*>(layer);
653 THROW_IE_EXCEPTION << "Layer is not instance of PReLULayer class";
655 casted->_channel_shared = casted->GetParamsAsBool("channel_shared", false);
658 void PReLUValidator::checkParams(const CNNLayer* layer) {
659 LayerValidator::checkParams(layer);
662 PReLUValidator::PReLUValidator(const std::string& _type) : LayerValidator(_type) {}
664 void PReLUValidator::checkShapes(const CNNLayer* layer, const std::vector<SizeVector>& inShapes) const {
665 checkNumOfInput(inShapes, {1});
668 void ScaleShiftValidator::parseParams(CNNLayer* layer) {
669 auto casted = dynamic_cast<ScaleShiftLayer*>(layer);
671 THROW_IE_EXCEPTION << "Layer is not instance of ScaleShiftLayer class";
673 if (!casted->params.empty()) {
674 casted->_broadcast = casted->GetParamAsUInt("broadcast", 2);
678 void ScaleShiftValidator::checkParams(const CNNLayer* layer) {
679 LayerValidator::checkParams(layer);
682 ScaleShiftValidator::ScaleShiftValidator(const std::string& _type) : LayerValidator(_type) {}
684 void ScaleShiftValidator::checkShapes(const CNNLayer* layer, const std::vector<SizeVector>& inShapes) const {
685 checkNumOfInput(inShapes, {1});
688 void TileValidator::parseParams(CNNLayer* layer) {
689 auto casted = dynamic_cast<TileLayer*>(layer);
691 THROW_IE_EXCEPTION << "Layer is not instance of TileLayer class";
693 casted->axis = casted->GetParamAsInt("axis", -1);
694 casted->tiles = casted->GetParamAsInt("tiles", -1);
697 void TileValidator::checkParams(const CNNLayer* layer) {
698 auto casted = dynamic_cast<const TileLayer*>(layer);
700 THROW_IE_EXCEPTION << "Layer is not instance of TileLayer class";
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";
709 TileValidator::TileValidator(const std::string& _type) : LayerValidator(_type) {}
711 void TileValidator::checkShapes(const CNNLayer* layer, const std::vector<SizeVector>& inShapes) const {
712 checkNumOfInput(inShapes, {1});
715 ReshapeValidator::ReshapeValidator(const std::string& _type) : LayerValidator(_type) {}
717 void ReshapeValidator::parseParams(CNNLayer *layer) {
718 auto casted = dynamic_cast<ReshapeLayer *>(layer);
720 THROW_IE_EXCEPTION << "Layer is not instance of ReshapeLayer class";
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);
728 casted->shape = casted->GetParamAsInts("dim", {});
733 void ReshapeValidator::checkParams(const CNNLayer *layer) {
734 auto casted = dynamic_cast<const ReshapeLayer *>(layer);
736 THROW_IE_EXCEPTION << "Layer is not instance of ReshapeLayer class";
738 for (int dim : casted->shape) {
740 THROW_IE_EXCEPTION << "Invalid value of Reshape mask (dim attribute):" << dim
741 << ". Supported values: 0, -1, >0";
742 if (dim == -1) num++;
744 if (num > 1) THROW_IE_EXCEPTION << "Invalid Reshape mask (dim attribute): at most one dimension can be `-1`";
747 void EltwiseValidator::parseParams(CNNLayer* layer) {
748 auto casted = dynamic_cast<EltwiseLayer*>(layer);
750 THROW_IE_EXCEPTION << "Layer is not instance of EltwiseLayer class";
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;
793 THROW_IE_EXCEPTION << "Unsupported element wise operation: " << op;
796 auto getArray = [](std::string param, vector<float>& array) {
797 std::istringstream stream(param);
799 while (getline(stream, str, ',')) {
800 float val = std::stof(str);
801 array.push_back(val);
804 getArray(casted->GetParamAsString("coeff", ""), casted->coeff);
807 void EltwiseValidator::checkParams(const CNNLayer* layer) {
808 auto casted = dynamic_cast<const EltwiseLayer*>(layer);
810 THROW_IE_EXCEPTION << "Layer is not instance of EltwiseLayer class";
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";
821 EltwiseValidator::EltwiseValidator(const std::string& _type) : LayerValidator(_type) {}
823 void ClampValidator::parseParams(CNNLayer* layer) {
824 auto casted = dynamic_cast<ClampLayer*>(layer);
826 THROW_IE_EXCEPTION << "Layer is not instance of ClampLayer class";
828 casted->min_value = casted->GetParamAsFloat("min");
829 casted->max_value = casted->GetParamAsFloat("max");
833 ClampValidator::ClampValidator(const std::string& _type) : LayerValidator(_type) {}
835 void ClampValidator::checkShapes(const CNNLayer* layer, const std::vector<SizeVector>& inShapes) const {
836 checkNumOfInput(inShapes, {1});
839 void ReLUValidator::parseParams(CNNLayer* layer) {
840 auto casted = dynamic_cast<ReLULayer*>(layer);
842 THROW_IE_EXCEPTION << "Layer is not instance of ReLULayer class";
844 if (!casted->params.empty()) {
845 casted->negative_slope = casted->GetParamAsFloat("negative_slope");
849 void ReLUValidator::checkParams(const CNNLayer* layer) {
850 auto casted = dynamic_cast<const ReLULayer*>(layer);
852 THROW_IE_EXCEPTION << "Layer is not instance of ReLULayer class";
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";
862 ReLUValidator::ReLUValidator(const std::string& _type) : LayerValidator(_type) {}
864 void ReLUValidator::checkShapes(const CNNLayer* layer, const std::vector<SizeVector>& inShapes) const {
865 checkNumOfInput(inShapes, {1, 2});
868 void MVNValidator::parseParams(CNNLayer* layer) {
869 auto casted = dynamic_cast<MVNLayer*>(layer);
871 THROW_IE_EXCEPTION << "Layer is not instance of MVNLayer class";
873 casted->across_channels = casted->GetParamAsInt("across_channels", 0);
874 casted->normalize = casted->GetParamAsInt("normalize_variance", 1);
877 void MVNValidator::checkParams(const CNNLayer* layer) {
880 MVNValidator::MVNValidator(const std::string& _type) : LayerValidator(_type) {}
882 void MVNValidator::checkShapes(const CNNLayer* layer, const std::vector<SizeVector>& inShapes) const {
883 checkNumOfInput(inShapes, {1});
886 void GRNValidator::parseParams(CNNLayer* layer) {
887 auto casted = dynamic_cast<GRNLayer*>(layer);
889 THROW_IE_EXCEPTION << "Layer is not instance of GRNLayer class";
891 casted->bias = casted->GetParamAsFloat("bias", 0.f);
894 void GRNValidator::checkParams(const CNNLayer* layer) {
895 LayerValidator::checkParams(layer);
898 GRNValidator::GRNValidator(const std::string& _type) : LayerValidator(_type) {}
900 void GRNValidator::checkShapes(const CNNLayer* layer, const std::vector<SizeVector>& inShapes) const {
901 checkNumOfInput(inShapes, {1});
904 void SoftMaxValidator::parseParams(CNNLayer* layer) {
905 auto casted = dynamic_cast<SoftMaxLayer*>(layer);
907 THROW_IE_EXCEPTION << "Layer is not instance of SoftMaxLayer class";
909 casted->axis = casted->GetParamAsInt("axis", 1);
912 void SoftMaxValidator::checkParams(const CNNLayer* layer) {
913 auto casted = dynamic_cast<const SoftMaxLayer*>(layer);
915 THROW_IE_EXCEPTION << "Layer is not instance of SoftMaxLayer class";
917 int axis = casted->GetParamAsInt("axis", 1);
919 THROW_IE_EXCEPTION << "The value of SoftMax layer axis parameter is invalid";
923 SoftMaxValidator::SoftMaxValidator(const std::string& _type) : LayerValidator(_type) {}
925 void SoftMaxValidator::checkShapes(const CNNLayer* layer, const std::vector<SizeVector>& inShapes) const {
926 checkNumOfInput(inShapes, {1});
929 void NormValidator::parseParams(CNNLayer* layer) {
930 auto casted = dynamic_cast<NormLayer*>(layer);
932 THROW_IE_EXCEPTION << "Layer is not instance of NormLayer class";
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");
942 void NormValidator::checkParams(const CNNLayer* layer) {
943 auto casted = dynamic_cast<const NormLayer*>(layer);
945 THROW_IE_EXCEPTION << "Layer is not instance of NormLayer class";
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";
954 NormValidator::NormValidator(const std::string& _type) : LayerValidator(_type) {}
956 void NormValidator::checkShapes(const CNNLayer* layer, const std::vector<SizeVector>& inShapes) const {
957 checkNumOfInput(inShapes, {1});
960 SplitValidator::SplitValidator(const std::string& _type) : LayerValidator(_type) {}
962 void SplitValidator::parseParams(CNNLayer* layer) {
963 auto casted = dynamic_cast<SplitLayer*>(layer);
965 THROW_IE_EXCEPTION << "Layer is not instance of SplitLayer class";
967 casted->_axis = casted->GetParamAsUInt("axis", 1);
969 std::string out_sizes;
970 for (auto& i : layer->outData) {
971 if (!out_sizes.empty())
973 if (static_cast<int>(i->getTensorDesc().getDims().size()) <= casted->_axis) {
974 THROW_IE_EXCEPTION << "Internal error - dimensions are empty";
976 out_sizes += std::to_string(i->getTensorDesc().getDims()[casted->_axis]);
978 if (!out_sizes.empty())
979 casted->params["out_sizes"] = out_sizes;
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";
990 void SplitValidator::checkShapes(const CNNLayer* layer, const std::vector<SizeVector>& inShapes) const {
991 auto casted = dynamic_cast<const SplitLayer*>(layer);
993 THROW_IE_EXCEPTION << "Layer is not instance of SplitLayer class";
995 checkNumOfInput(inShapes, {1});
996 auto version = BaseCreator::version_;
998 std::vector<int> out_sizes = layer->GetParamAsInts("out_sizes", {});
1000 for (const auto& size : out_sizes)
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);
1011 ConcatValidator::ConcatValidator(const std::string& _type) : LayerValidator(_type) {}
1013 void ConcatValidator::parseParams(CNNLayer* layer) {
1014 auto casted = dynamic_cast<ConcatLayer*>(layer);
1016 THROW_IE_EXCEPTION << "Layer is not instance of ConcatLayer class";
1018 casted->_axis = casted->GetParamAsUInt("axis", 1);
1021 void ConcatValidator::checkParams(const CNNLayer* layer) {
1024 void ConcatValidator::checkShapes(const CNNLayer* layer, const std::vector<SizeVector>& inShapes) const {
1025 if (inShapes.empty())
1026 THROW_IE_EXCEPTION << "Inputs are empty";
1028 auto casted = dynamic_cast<const ConcatLayer*>(layer);
1030 THROW_IE_EXCEPTION << "Invalid Concat layer.";
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 << ")";
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,
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) <<"]";
1057 GemmValidator::GemmValidator(const std::string& _type) : LayerValidator(_type) {}
1059 void GemmValidator::parseParams(CNNLayer* layer) {
1060 auto casted = dynamic_cast<GemmLayer*>(layer);
1062 THROW_IE_EXCEPTION << "Layer is not instance of GemmLayer class";
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);
1070 void GemmValidator::checkParams(const CNNLayer* layer) {
1071 LayerValidator::checkParams(layer);
1074 void GemmValidator::checkShapes(const CNNLayer* layer, const vector<SizeVector>& inShapes) const {
1075 auto casted = dynamic_cast<const GemmLayer*>(layer);
1077 THROW_IE_EXCEPTION << "Layer is not instance of GemmLayer class";
1080 size_t numInputs = inShapes.size();
1081 checkNumOfInput(inShapes, {2, 3});
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";
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] << ")";
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";
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] << ")";
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] << ")";
1111 PadValidator::PadValidator(const std::string& _type) : LayerValidator(_type) {}
1113 void PadValidator::parseParams(CNNLayer* layer) {
1114 auto casted = dynamic_cast<PadLayer*>(layer);
1116 THROW_IE_EXCEPTION << layer->name << " Layer is not instance of PadLayer class";
1118 std::vector<uint32_t> pads_begin = casted->GetParamAsUInts("pads_begin");
1119 std::vector<uint32_t> pads_end = casted->GetParamAsUInts("pads_end");
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]);
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]);
1131 casted->pad_value = casted->GetParamAsFloat("pad_value", 0.0f);
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;
1143 THROW_IE_EXCEPTION << layer->name << " Unsupported pad mode operation: " << mode;
1147 void PadValidator::checkParams(const CNNLayer* layer) {
1148 LayerValidator::checkParams(layer);
1151 void PadValidator::checkShapes(const CNNLayer* layer, const vector<SizeVector>& inShapes) const {
1152 auto casted = dynamic_cast<const PadLayer*>(layer);
1154 THROW_IE_EXCEPTION << layer->name << " Layer is not instance of PadLayer class";
1157 size_t numInputs = inShapes.size();
1158 checkNumOfInput(inShapes, {1});
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();
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();
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];
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];
1184 GatherValidator::GatherValidator(const std::string& _type) : LayerValidator(_type) {}
1186 void GatherValidator::parseParams(CNNLayer* layer) {
1187 auto casted = dynamic_cast<GatherLayer*>(layer);
1189 THROW_IE_EXCEPTION << layer->name << " Layer is not instance of GatherLayer class";
1192 casted->axis = casted->GetParamAsInt("axis", 0);
1195 void GatherValidator::checkParams(const CNNLayer* layer) {
1196 LayerValidator::checkParams(layer);
1199 void GatherValidator::checkShapes(const CNNLayer* layer, const vector<SizeVector>& inShapes) const {
1200 auto casted = dynamic_cast<const GatherLayer*>(layer);
1202 THROW_IE_EXCEPTION << layer->name << " Layer is not instance of GatherLayer class";
1205 size_t numInputs = inShapes.size();
1207 THROW_IE_EXCEPTION << layer->name << " Gather can take only 2 inputs, but actually it has: " << numInputs;
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;
1217 StridedSliceValidator::StridedSliceValidator(const std::string& _type) : LayerValidator(_type) {}
1219 void StridedSliceValidator::parseParams(CNNLayer* layer) {
1220 auto casted = dynamic_cast<StridedSliceLayer*>(layer);
1222 THROW_IE_EXCEPTION << layer->name << " Layer is not instance of StridedSlice class";
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", "");
1232 void StridedSliceValidator::checkParams(const CNNLayer* layer) {
1233 LayerValidator::checkParams(layer);
1236 void StridedSliceValidator::checkShapes(const CNNLayer* layer, const vector<SizeVector>& inShapes) const {
1237 auto casted = dynamic_cast<const StridedSliceLayer*>(layer);
1239 THROW_IE_EXCEPTION << layer->name << " Layer is not instance of StridedSliceLayer class";
1242 size_t numInputs = inShapes.size();
1244 THROW_IE_EXCEPTION << layer->name << " StridedSlice can take up to 4 inputs, but actually it has: " << numInputs;
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++;
1251 if (ellipsis_mask_counter > 1)
1252 THROW_IE_EXCEPTION << layer->name << " 'Ellipsis_mask' must be a power of two (only one ellipsis)!";
1256 ShuffleChannelsValidator::ShuffleChannelsValidator(const std::string& _type) : LayerValidator(_type) {}
1258 void ShuffleChannelsValidator::parseParams(CNNLayer* layer) {
1259 auto casted = dynamic_cast<ShuffleChannelsLayer*>(layer);
1261 THROW_IE_EXCEPTION << layer->name << " Layer is not instance of ShuffleChannels class";
1264 casted->axis = casted->GetParamAsInt("axis", 1);
1265 casted->group = casted->GetParamAsUInt("group", 1);
1268 void ShuffleChannelsValidator::checkParams(const CNNLayer* layer) {
1269 LayerValidator::checkParams(layer);
1272 void ShuffleChannelsValidator::checkShapes(const CNNLayer* layer, const vector<SizeVector>& inShapes) const {
1273 auto casted = dynamic_cast<const ShuffleChannelsLayer*>(layer);
1275 THROW_IE_EXCEPTION << layer->name << " Layer is not instance of ShuffleChannels class";
1278 size_t numInputs = inShapes.size();
1280 THROW_IE_EXCEPTION << layer->name << " ShuffleChannels can take only 1 input, but actually it has: " << numInputs;
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;
1289 int axis = casted->axis;
1291 axis += inShapes[0].size();
1293 if (inShapes[0][axis] % casted->group)
1294 THROW_IE_EXCEPTION << layer->name << " Group parameter must evenly divide the channel dimension!";
1296 size_t dataLength = 1;
1297 for (size_t i = axis + 1; i < inShapes[0].size(); i++)
1298 dataLength *= inShapes[0][i];
1300 if (dataLength == 0)
1301 THROW_IE_EXCEPTION << layer->name << " Incorrect input parameters dimension!";
1305 DepthToSpaceValidator::DepthToSpaceValidator(const std::string& _type) : LayerValidator(_type) {}
1307 void DepthToSpaceValidator::parseParams(CNNLayer* layer) {
1308 auto casted = dynamic_cast<DepthToSpaceLayer*>(layer);
1310 THROW_IE_EXCEPTION << layer->name << " Layer is not instance of DepthToSpace class";
1313 casted->block_size = casted->GetParamAsUInt("block_size", 1);
1316 void DepthToSpaceValidator::checkParams(const CNNLayer* layer) {
1317 LayerValidator::checkParams(layer);
1320 void DepthToSpaceValidator::checkShapes(const CNNLayer* layer, const vector<SizeVector>& inShapes) const {
1321 auto casted = dynamic_cast<const DepthToSpaceLayer*>(layer);
1323 THROW_IE_EXCEPTION << layer->name << " Layer is not instance of DepthToSpace class";
1326 size_t numInputs = inShapes.size();
1328 THROW_IE_EXCEPTION << layer->name << " DepthToSpace can take only 1 input, but actually it has: " << numInputs;
1330 if (inShapes[0].size() < 3)
1331 THROW_IE_EXCEPTION << layer->name << " Incorrect number of input dimensions!";
1333 if (casted->block_size == 0)
1334 THROW_IE_EXCEPTION << layer->name << " Incorrect block_size parameter is zero!";
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!";
1341 SpaceToDepthValidator::SpaceToDepthValidator(const std::string& _type) : LayerValidator(_type) {}
1343 void SpaceToDepthValidator::parseParams(CNNLayer* layer) {
1344 auto casted = dynamic_cast<SpaceToDepthLayer*>(layer);
1346 THROW_IE_EXCEPTION << layer->name << " Layer is not instance of SpaceToDepth class";
1349 casted->block_size = casted->GetParamAsUInt("block_size", 1);
1352 void SpaceToDepthValidator::checkParams(const CNNLayer* layer) {
1353 LayerValidator::checkParams(layer);
1356 void SpaceToDepthValidator::checkShapes(const CNNLayer* layer, const vector<SizeVector>& inShapes) const {
1357 auto casted = dynamic_cast<const SpaceToDepthLayer*>(layer);
1359 THROW_IE_EXCEPTION << layer->name << " Layer is not instance of SpaceToDepth class";
1362 size_t numInputs = inShapes.size();
1364 THROW_IE_EXCEPTION << layer->name << " SpaceToDepth can take only 1 input, but actually it has: " << numInputs;
1366 if (inShapes[0].size() < 2)
1367 THROW_IE_EXCEPTION << layer->name << " Incorrect number of input dimensions!";
1369 if (casted->block_size == 0)
1370 THROW_IE_EXCEPTION << layer->name << " Incorrect block_size parameter is zero!";
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!";
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!";
1380 ReverseSequenceValidator::ReverseSequenceValidator(const std::string& _type) : LayerValidator(_type) {}
1382 void ReverseSequenceValidator::parseParams(CNNLayer* layer) {
1383 auto casted = dynamic_cast<ReverseSequenceLayer*>(layer);
1385 THROW_IE_EXCEPTION << layer->name << " Layer is not instance of ReverseSequence class";
1388 casted->seq_axis = casted->GetParamAsInt("seq_axis", 1);
1389 casted->batch_axis = casted->GetParamAsInt("batch_axis", 0);
1392 void ReverseSequenceValidator::checkParams(const CNNLayer* layer) {
1393 LayerValidator::checkParams(layer);
1396 void ReverseSequenceValidator::checkShapes(const CNNLayer* layer, const vector<SizeVector>& inShapes) const {
1397 auto casted = dynamic_cast<const ReverseSequenceLayer*>(layer);
1399 THROW_IE_EXCEPTION << layer->name << " Layer is not instance of ReverseSequence class";
1402 size_t numInputs = inShapes.size();
1404 THROW_IE_EXCEPTION << layer->name << " ReverseSequence can take 2 inputs, but actually it has: " << numInputs;
1406 if (inShapes[1].size() != 1)
1407 THROW_IE_EXCEPTION << layer->name << " Incorrect number of 'seq_lengths' input dimensions!";
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;
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;
1423 int batch_axis = casted->batch_axis;
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!";
1431 SqueezeValidator::SqueezeValidator(const std::string& _type) : LayerValidator(_type) {}
1433 void SqueezeValidator::parseParams(CNNLayer* layer) {
1434 auto casted = dynamic_cast<SqueezeLayer*>(layer);
1436 THROW_IE_EXCEPTION << layer->name << " Layer is not instance of Squeeze class";
1440 void SqueezeValidator::checkParams(const CNNLayer* layer) {
1441 LayerValidator::checkParams(layer);
1444 void SqueezeValidator::checkShapes(const CNNLayer* layer, const vector<SizeVector>& inShapes) const {
1445 auto casted = dynamic_cast<const SqueezeLayer*>(layer);
1447 THROW_IE_EXCEPTION << layer->name << " Layer is not instance of Squeeze class";
1450 size_t numInputs = inShapes.size();
1452 THROW_IE_EXCEPTION << layer->name << " Squeeze can take 2 inputs, but actually it has: " << numInputs;
1454 if (inShapes[1].size() != 1)
1455 THROW_IE_EXCEPTION << layer->name << " Incorrect number of 'indices_to_squeeze' input dimensions!";
1459 UnsqueezeValidator::UnsqueezeValidator(const std::string& _type) : LayerValidator(_type) {}
1461 void UnsqueezeValidator::parseParams(CNNLayer* layer) {
1462 auto casted = dynamic_cast<UnsqueezeLayer*>(layer);
1464 THROW_IE_EXCEPTION << layer->name << " Layer is not instance of Unsqueeze class";
1468 void UnsqueezeValidator::checkParams(const CNNLayer* layer) {
1469 LayerValidator::checkParams(layer);
1472 void UnsqueezeValidator::checkShapes(const CNNLayer* layer, const vector<SizeVector>& inShapes) const {
1473 auto casted = dynamic_cast<const UnsqueezeLayer*>(layer);
1475 THROW_IE_EXCEPTION << layer->name << " Layer is not instance of Unsqueeze class";
1478 size_t numInputs = inShapes.size();
1480 THROW_IE_EXCEPTION << layer->name << " Unsqueeze can take 2 inputs, but actually it has: " << numInputs;
1482 if (inShapes[1].size() != 1)
1483 THROW_IE_EXCEPTION << layer->name << " Incorrect number of 'indices_to_set' input dimensions!";
1487 RangeValidator::RangeValidator(const std::string& _type) : LayerValidator(_type) {}
1489 void RangeValidator::parseParams(CNNLayer* layer) {
1490 auto casted = dynamic_cast<RangeLayer*>(layer);
1492 THROW_IE_EXCEPTION << layer->name << " Layer is not instance of Range class";
1496 void RangeValidator::checkParams(const CNNLayer* layer) {}
1498 void RangeValidator::checkShapes(const CNNLayer* layer, const vector<SizeVector>& inShapes) const {
1499 auto casted = dynamic_cast<const RangeLayer*>(layer);
1501 THROW_IE_EXCEPTION << layer->name << " Layer is not instance of Range class";
1504 size_t numInputs = inShapes.size();
1506 THROW_IE_EXCEPTION << layer->name << " Range can take 3 inputs, but actually it has: " << numInputs;
1508 if (inShapes[0].size() != 1)
1509 THROW_IE_EXCEPTION << layer->name << " Incorrect number of 'start' input dimensions!";
1511 if (inShapes[1].size() != 1)
1512 THROW_IE_EXCEPTION << layer->name << " Incorrect number of 'limit' input dimensions!";
1514 if (inShapes[2].size() != 1)
1515 THROW_IE_EXCEPTION << layer->name << " Incorrect number of 'delta' input dimensions!";
1519 FillValidator::FillValidator(const std::string& _type) : LayerValidator(_type) {}
1521 void FillValidator::parseParams(CNNLayer* layer) {}
1523 void FillValidator::checkParams(const CNNLayer* layer) {}
1525 void FillValidator::checkShapes(const CNNLayer* layer, const vector<SizeVector>& inShapes) const {
1526 size_t numInputs = inShapes.size();
1528 THROW_IE_EXCEPTION << layer->name << " Fill can take 2 inputs, but actually it has: " << numInputs;
1530 if (inShapes[0].size() != 1)
1531 THROW_IE_EXCEPTION << layer->name << " Incorrect number of 'fill_dims' input dimensions!";
1533 if (inShapes[1].size() != 1)
1534 THROW_IE_EXCEPTION << layer->name << " Incorrect number of 'fill_value' input dimensions!";
1538 ExpandValidator::ExpandValidator(const std::string& _type) : LayerValidator(_type) {}
1540 void ExpandValidator::parseParams(CNNLayer* layer) {
1541 auto casted = dynamic_cast<ExpandLayer*>(layer);
1543 THROW_IE_EXCEPTION << layer->name << " Layer is not instance of Expand class";
1547 void ExpandValidator::checkParams(const CNNLayer* layer) {
1548 LayerValidator::checkParams(layer);
1551 void ExpandValidator::checkShapes(const CNNLayer* layer, const vector<SizeVector>& inShapes) const {
1552 auto casted = dynamic_cast<const ExpandLayer*>(layer);
1554 THROW_IE_EXCEPTION << layer->name << " Layer is not instance of Expand class";
1557 size_t numInputs = inShapes.size();
1559 THROW_IE_EXCEPTION << layer->name << " Expand can take 2 inputs, but actually it has: " << numInputs;
1561 if (inShapes[1].size() != 1)
1562 THROW_IE_EXCEPTION << layer->name << " Incorrect number of 'shape' input dimensions!";
1565 /****************************************/
1566 /*** RNN specific validators ************/
1567 /****************************************/
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);
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 ].";
1581 return type_name == "LSTM" ? RNNSequenceLayer::LSTM :
1582 type_name == "GRU" ? RNNSequenceLayer::GRU :
1583 type_name == "RNN" ? RNNSequenceLayer::RNN :
1584 RNNSequenceLayer::LSTM;
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 ].";
1592 return direction_name == "Forward" ? RNNSequenceLayer::FWD :
1593 direction_name == "Backward" ? RNNSequenceLayer::BWD :
1594 direction_name == "Bidirecttional" ? RNNSequenceLayer::BDR :
1595 RNNSequenceLayer::FWD;
1599 std::vector<std::string>
1600 RNNBaseValidator<RNNSequenceLayer::LSTM>::def_acts {"sigmoid", "tanh", "tanh"};
1603 RNNBaseValidator<RNNSequenceLayer::LSTM>::def_alpha {0, 0, 0};
1606 RNNBaseValidator<RNNSequenceLayer::LSTM>::def_beta {0, 0, 0};
1609 RNNBaseValidator<RNNSequenceLayer::LSTM>::G = 4;
1612 RNNBaseValidator<RNNSequenceLayer::LSTM>::NS = 2;
1615 std::vector<std::string>
1616 RNNBaseValidator<RNNSequenceLayer::GRU>::def_acts {"sigmoid", "tanh"};
1619 RNNBaseValidator<RNNSequenceLayer::GRU>::def_alpha {0, 0};
1622 RNNBaseValidator<RNNSequenceLayer::GRU>::def_beta {0, 0};
1625 RNNBaseValidator<RNNSequenceLayer::GRU>::G = 3;
1628 RNNBaseValidator<RNNSequenceLayer::GRU>::NS = 1;
1631 std::vector<std::string>
1632 RNNBaseValidator<RNNSequenceLayer::RNN>::def_acts {"tanh"};
1635 RNNBaseValidator<RNNSequenceLayer::RNN>::def_alpha {0};
1638 RNNBaseValidator<RNNSequenceLayer::RNN>::def_beta {0};
1641 RNNBaseValidator<RNNSequenceLayer::RNN>::G = 1;
1644 RNNBaseValidator<RNNSequenceLayer::RNN>::NS = 1;
1646 template<RNNSequenceLayer::CellType CELL>
1647 RNNBaseValidator<CELL>::RNNBaseValidator(const std::string& _type) : LayerValidator(_type) {}
1649 template<RNNSequenceLayer::CellType CELL>
1650 void RNNBaseValidator<CELL>::parseParams(CNNLayer* layer) {
1651 auto rnn = dynamic_cast<RNNCellBase*>(layer);
1653 THROW_IE_EXCEPTION << "Layer is not instance of RNNLayer class";
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);
1662 if (rnn->cellType == RNNCellBase::GRU) {
1663 auto lbr = rnn->GetParamAsBool("linear_before_reset", false);
1664 if (lbr) rnn->cellType = RNNCellBase::GRU_LBR;
1668 template<RNNSequenceLayer::CellType CELL>
1669 void RNNBaseValidator<CELL>::checkParams(const InferenceEngine::CNNLayer *layer) {
1670 auto rnn = dynamic_cast<const RNNCellBase*>(layer);
1672 THROW_IE_EXCEPTION << "Layer is not instance of RNNLayer class";
1674 if (rnn->clip < 0.0f)
1675 THROW_IE_EXCEPTION << "Clip parameter should be positive";
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.";
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();
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();
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);
1700 THROW_IE_EXCEPTION << "Layer is not instance of RNNLayer class";
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.";
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;
1713 if (rnn->cellType == RNNCellBase::GRU_LBR)
1714 expectetd_b_size = (G + 1)*S;
1716 auto w = blobs.find("weights");
1717 if (w == blobs.end())
1718 THROW_IE_EXCEPTION << "Weights blob is not provided";
1720 if (w->second->size() != expectetd_w_size)
1721 THROW_IE_EXCEPTION << "Weights blob has wrang size. Expected " << expectetd_w_size;
1723 auto b = blobs.find("biases");
1724 if (b == blobs.end())
1725 THROW_IE_EXCEPTION << "Biases blob is not provided";
1727 if (b->second->size() != expectetd_b_size)
1728 THROW_IE_EXCEPTION << "Biases blob has wrang size. Expected " << expectetd_b_size;
1731 template<RNNSequenceLayer::CellType CELL>
1732 RNNSequenceValidator<CELL>::RNNSequenceValidator(const std::string& _type) : RNNBaseValidator<CELL>(_type) {}
1734 template<RNNSequenceLayer::CellType CELL>
1735 void RNNSequenceValidator<CELL>::parseParams(CNNLayer* layer) {
1736 RNNBaseValidator<CELL>::parseParams(layer);
1738 auto casted = dynamic_cast<RNNSequenceLayer*>(layer);
1740 THROW_IE_EXCEPTION << "Layer is not instance of RNNLayer class";
1742 std::string direction = layer->GetParamAsString("direction");
1744 casted->axis = layer->GetParamAsUInt("axis", 1);
1745 casted->direction = direction_from(direction);
1748 template<RNNSequenceLayer::CellType CELL>
1749 void RNNSequenceValidator<CELL>::checkParams(const InferenceEngine::CNNLayer *layer) {
1750 RNNBaseValidator<CELL>::checkParams(layer);
1752 auto casted = dynamic_cast<const RNNSequenceLayer*>(layer);
1754 THROW_IE_EXCEPTION << "Layer is not instance of RNNLayer class";
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.";
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);
1764 THROW_IE_EXCEPTION << "Layer is not instance of RNNSequenceLayer class";
1766 if (inShapes.empty())
1767 THROW_IE_EXCEPTION << "No input tensors.";
1769 if (inShapes[0].size() != 3)
1770 THROW_IE_EXCEPTION << "First input data tensor should be 3D";
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;
1780 SizeVector expected_state_shape {N, S};
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];
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];
1796 template class details::RNNSequenceValidator<RNNSequenceLayer::RNN>;
1797 template class details::RNNSequenceValidator<RNNSequenceLayer::GRU>;
1798 template class details::RNNSequenceValidator<RNNSequenceLayer::LSTM>;
1800 template<RNNSequenceLayer::CellType CELL>
1801 RNNCellValidator<CELL>::RNNCellValidator(const std::string& _type) : RNNBaseValidator<CELL>(_type) {}
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);
1807 THROW_IE_EXCEPTION << "Layer is not instance of RNNSequenceLayer class";
1809 const size_t &NS = RNNCellValidator<CELL>::NS;
1811 if (inShapes.size() != NS + 1)
1812 THROW_IE_EXCEPTION << "Wrong number of input tensors. Expected " << NS + 1;
1814 if (inShapes[0].size() != 2)
1815 THROW_IE_EXCEPTION << "First input data tensor should be 2D";
1817 size_t N = inShapes[0][0];
1818 size_t D = inShapes[0][1];
1819 size_t S = rnn->hidden_size;
1821 SizeVector expected_state_shape {N, S};
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];
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];
1832 template class details::RNNCellValidator<RNNSequenceLayer::RNN>;
1833 template class details::RNNCellValidator<RNNSequenceLayer::GRU>;
1834 template class details::RNNCellValidator<RNNSequenceLayer::LSTM>;
1836 void ArgMaxValidator::checkParams(const CNNLayer* layer) {
1837 unsigned int top_k_ = layer->GetParamAsUInt("top_k");
1840 void ArgMaxValidator::checkShapes(const CNNLayer* layer, const std::vector<SizeVector>& inShapes) const {
1841 checkNumOfInput(inShapes, {1});
1844 ArgMaxValidator::ArgMaxValidator(const std::string& _type) : LayerValidator(_type) {
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";
1854 void CTCGreedyDecoderValidator::checkShapes(const CNNLayer* layer, const std::vector<SizeVector>& inShapes) const {
1855 checkNumOfInput(inShapes, {1, 2});
1858 CTCGreedyDecoderValidator::CTCGreedyDecoderValidator(const std::string& _type) : LayerValidator(_type) {
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";
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";
1870 int _keep_top_k = layer->GetParamAsUInt("keep_top_k", -1);
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";
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 ";
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";
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";
1911 int _keep_top_k = layer->GetParamAsUInt("keep_top_k", -1);
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";
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 ";
1942 void DetectionOutputValidator::checkShapes(const CNNLayer* layer, const std::vector<SizeVector>& inShapes) const {
1943 checkNumOfInput(inShapes, {3, 5});
1946 DetectionOutputValidator::DetectionOutputValidator(const std::string& _type) : LayerValidator(_type) {
1949 void InterpValidator::checkParams(const CNNLayer* layer) {
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();
1957 if (inShapes.size() != 2) {
1958 float factor = layer->GetParamAsFloat("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);
1969 auto height = layer->GetParamAsUInt("height", 0);
1970 auto width = layer->GetParamAsUInt("width", 0);
1972 if (noFactor && (height == 0 || width == 0)) {
1974 << "Can't reshape without factor, or target resolution. "
1975 << "Supported attributes: factor, shrink_factor, zoom_factor, height, width";
1980 InterpValidator::InterpValidator(const std::string& _type) : LayerValidator(_type) {
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);
1988 auto height = layer->GetParamAsUInt("height", 0);
1989 auto width = layer->GetParamAsUInt("width", 0);
1992 void PermuteValidator::checkParams(const CNNLayer* layer) {
1993 std::vector<unsigned int> layerOrder = layer->GetParamAsUInts("order");
1996 void PermuteValidator::checkShapes(const CNNLayer* layer, const std::vector<SizeVector>& inShapes) const {
1997 checkNumOfInput(inShapes, {1});
2000 PermuteValidator::PermuteValidator(const std::string& _type) : LayerValidator(_type) {
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";
2016 float step_ = layer->GetParamAsFloat("step", 0);
2018 THROW_IE_EXCEPTION << "The value of PriorBox layer step_ parameter is invalid";
2020 float offset_ = layer->GetParamAsFloat("offset");
2022 THROW_IE_EXCEPTION << "The value of PriorBox layer offset_ parameter is invalid";
2026 void PriorBoxValidator::checkShapes(const CNNLayer* layer, const std::vector<SizeVector>& inShapes) const {
2027 checkNumOfInput(inShapes, {2});
2030 PriorBoxValidator::PriorBoxValidator(const std::string& _type) : LayerValidator(_type) {
2033 void PriorBoxClusteredValidator::checkParams(const CNNLayer* layer) {
2034 std::vector<float> widths = layer->GetParamAsFloats("width", {});
2035 for (auto i : widths) {
2037 THROW_IE_EXCEPTION << "The value of PriorBoxClustered layer width parameter is invalid";
2040 std::vector<float> heights = layer->GetParamAsFloats("height", {});
2041 for (auto i : heights) {
2043 THROW_IE_EXCEPTION << "The value of PriorBoxClustered layer heights parameter is invalid";
2046 bool flip = static_cast<bool>(layer->GetParamAsInt("flip"));
2047 bool clip_ = static_cast<bool>(layer->GetParamAsInt("clip"));
2048 float offset_ = layer->GetParamAsFloat("offset");
2050 THROW_IE_EXCEPTION << "The value of PriorBox layer offset_ parameter is invalid";
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";
2058 float step_h_ = layer->GetParamAsFloat("step_h", 0);
2060 THROW_IE_EXCEPTION << "The value of PriorBox layer step_h_ parameter is invalid";
2062 float step_w_ = layer->GetParamAsFloat("step_w", 0);
2064 THROW_IE_EXCEPTION << "The value of PriorBox layer step_w_ parameter is invalid";
2066 float img_h_ = layer->GetParamAsFloat("img_h", 0);
2068 THROW_IE_EXCEPTION << "The value of PriorBox layer img_h_ parameter is invalid";
2070 float img_w_ = layer->GetParamAsFloat("img_w", 0);
2072 THROW_IE_EXCEPTION << "The value of PriorBox layer img_w_ parameter is invalid";
2076 void PriorBoxClusteredValidator::checkShapes(const CNNLayer* layer, const std::vector<SizeVector>& inShapes) const {
2077 checkNumOfInput(inShapes, {2});
2080 PriorBoxClusteredValidator::PriorBoxClusteredValidator(const std::string& _type) : LayerValidator(_type) {
2083 void ProposalValidator::checkParams(const CNNLayer* layer) {
2084 unsigned int post_nms_topn_ = layer->GetParamAsUInt("post_nms_topn");
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";
2102 void ProposalValidator::checkShapes(const CNNLayer* layer, const std::vector<SizeVector>& inShapes) const {
2103 checkNumOfInput(inShapes, {3});
2106 ProposalValidator::ProposalValidator(const std::string& _type) : LayerValidator(_type) {
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";
2120 void PSROIPoolingValidator::checkShapes(const CNNLayer* layer, const std::vector<SizeVector>& inShapes) const {
2121 checkNumOfInput(inShapes, {1, 2});
2124 PSROIPoolingValidator::PSROIPoolingValidator(const std::string& _type) : LayerValidator(_type) {
2127 void RegionYoloValidator::checkParams(const CNNLayer* layer) {
2128 LayerValidator::checkParams(layer);
2131 void RegionYoloValidator::checkShapes(const CNNLayer* layer, const std::vector<SizeVector>& inShapes) const {
2132 checkNumOfInput(inShapes, {1});
2135 RegionYoloValidator::RegionYoloValidator(const std::string& _type) : LayerValidator(_type) {
2138 void ReorgYoloValidator::checkParams(const CNNLayer* layer) {
2139 LayerValidator::checkParams(layer);
2142 void ReorgYoloValidator::checkShapes(const CNNLayer* layer, const std::vector<SizeVector>& inShapes) const {
2143 checkNumOfInput(inShapes, {1});
2146 ReorgYoloValidator::ReorgYoloValidator(const std::string& _type) : LayerValidator(_type) {
2149 void ResampleValidator::checkParams(const CNNLayer* layer) {
2150 if (layer->CheckParamPresence("antialias")) {
2151 auto antialias = static_cast<size_t>(layer->GetParamAsInt("antialias"));
2153 if (antialias != 0 && antialias != 1) {
2154 THROW_IE_EXCEPTION << "The value of resample layer antialias parameter is invalid";
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";
2166 void ResampleValidator::checkShapes(const CNNLayer* layer, const std::vector<SizeVector>& inShapes) const {
2167 checkNumOfInput(inShapes, {1, 2});
2170 ResampleValidator::ResampleValidator(const std::string& _type) : LayerValidator(_type) {
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";
2182 void ROIPoolingValidator::checkShapes(const CNNLayer* layer, const std::vector<SizeVector>& inShapes) const {
2183 checkNumOfInput(inShapes, {1, 2});
2186 ROIPoolingValidator::ROIPoolingValidator(const std::string& _type) : LayerValidator(_type) {
2189 void SimplerNMSValidator::checkParams(const CNNLayer* layer) {
2190 unsigned int post_nms_topn_ = layer->GetParamAsUInt("post_nms_topn");
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";
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";
2214 void SimplerNMSValidator::checkShapes(const CNNLayer* layer, const std::vector<SizeVector>& inShapes) const {
2215 checkNumOfInput(inShapes, {3});
2218 SimplerNMSValidator::SimplerNMSValidator(const std::string& _type) : LayerValidator(_type) {
2221 void SpatialTransformerValidator::checkParams(const CNNLayer* layer) {
2222 LayerValidator::checkParams(layer);
2225 void SpatialTransformerValidator::checkShapes(const CNNLayer* layer, const std::vector<SizeVector>& inShapes) const {
2226 checkNumOfInput(inShapes, {2});
2229 SpatialTransformerValidator::SpatialTransformerValidator(const std::string& _type) : LayerValidator(_type) {
2232 void UpsamplingValidator::checkParams(const CNNLayer* layer) {
2233 LayerValidator::checkParams(layer);
2236 void UpsamplingValidator::checkShapes(const CNNLayer* layer, const std::vector<SizeVector>& inShapes) const {
2237 checkNumOfInput(inShapes, {1});
2240 UpsamplingValidator::UpsamplingValidator(const std::string& _type) : LayerValidator(_type) {
2243 void UnpoolingValidator::checkParams(const CNNLayer* layer) {
2244 LayerValidator::checkParams(layer);
2247 void UnpoolingValidator::checkShapes(const CNNLayer* layer, const std::vector<SizeVector>& inShapes) const {
2248 checkNumOfInput(inShapes, {1});
2251 UnpoolingValidator::UnpoolingValidator(const std::string& _type) : LayerValidator(_type) {
2254 ActivationValidator::ActivationValidator(const std::string& _type) : LayerValidator(_type) {
2257 void ActivationValidator::checkParams(const CNNLayer* layer) {
2258 LayerValidator::checkParams(layer);
2261 void ActivationValidator::checkShapes(const CNNLayer* layer, const std::vector<SizeVector>& inShapes) const {
2262 checkNumOfInput(inShapes, {1});
2265 ConstValidator::ConstValidator(const std::string& _type) : LayerValidator(_type) {
2268 void ConstValidator::checkParams(const CNNLayer* layer) {
2269 LayerValidator::checkParams(layer);
2272 void ConstValidator::checkShapes(const CNNLayer* layer, const std::vector<SizeVector>& inShapes) const {
2273 checkNumOfInput(inShapes, {0, 1});
2276 CopyValidator::CopyValidator(const std::string& _type) : LayerValidator(_type) {
2279 void CopyValidator::checkParams(const CNNLayer* layer) {
2280 LayerValidator::checkParams(layer);
2283 void CopyValidator::checkShapes(const CNNLayer* layer, const std::vector<SizeVector>& inShapes) const {
2284 checkNumOfInput(inShapes, {1});
2287 ELUValidator::ELUValidator(const std::string& _type) : LayerValidator(_type) {
2290 void ELUValidator::checkParams(const CNNLayer* layer) {
2291 LayerValidator::checkParams(layer);
2294 void ELUValidator::checkShapes(const CNNLayer* layer, const std::vector<SizeVector>& inShapes) const {
2295 checkNumOfInput(inShapes, {1});
2298 InputValidator::InputValidator(const std::string& _type) : LayerValidator(_type) {
2301 void InputValidator::checkParams(const CNNLayer* layer) {
2302 LayerValidator::checkParams(layer);
2305 void InputValidator::checkShapes(const CNNLayer* layer, const std::vector<SizeVector>& inShapes) const {
2306 checkNumOfInput(inShapes, {0});
2309 MemoryValidator::MemoryValidator(const std::string& _type) : LayerValidator(_type) {
2312 void MemoryValidator::checkParams(const CNNLayer* layer) {
2313 int size = layer->GetParamAsInt("size");
2315 THROW_IE_EXCEPTION << "The value of Memory layer size parameter is invalid";
2319 void MemoryValidator::checkShapes(const CNNLayer* layer, const std::vector<SizeVector>& inShapes) const {
2320 checkNumOfInput(inShapes, {1, 0});
2323 NormalizeValidator::NormalizeValidator(const std::string& _type) : LayerValidator(_type) {
2326 void NormalizeValidator::checkParams(const CNNLayer* layer) {
2327 if (layer->CheckParamPresence("eps")) {
2328 float eps = layer->GetParamAsFloat("eps");
2330 THROW_IE_EXCEPTION << "The value of Normalize layer eps parameter is invalid";
2335 void NormalizeValidator::checkShapes(const CNNLayer* layer, const std::vector<SizeVector>& inShapes) const {
2336 checkNumOfInput(inShapes, {1});
2339 PowerFileValidator::PowerFileValidator(const std::string& _type) : LayerValidator(_type) {
2342 void PowerFileValidator::checkParams(const CNNLayer* layer) {
2343 LayerValidator::checkParams(layer);
2346 void PowerFileValidator::checkShapes(const CNNLayer* layer, const std::vector<SizeVector>& inShapes) const {
2347 checkNumOfInput(inShapes, {1});
2350 ReLU6Validator::ReLU6Validator(const std::string& _type) : LayerValidator(_type) {
2353 void ReLU6Validator::checkParams(const CNNLayer* layer) {
2354 LayerValidator::checkParams(layer);
2357 void ReLU6Validator::checkShapes(const CNNLayer* layer, const std::vector<SizeVector>& inShapes) const {
2358 checkNumOfInput(inShapes, {1});
2361 SigmoidValidator::SigmoidValidator(const std::string& _type) : LayerValidator(_type) {
2364 void SigmoidValidator::checkParams(const CNNLayer* layer) {
2365 LayerValidator::checkParams(layer);
2368 void SigmoidValidator::checkShapes(const CNNLayer* layer, const std::vector<SizeVector>& inShapes) const {
2369 checkNumOfInput(inShapes, {1});
2372 TanHValidator::TanHValidator(const std::string& _type) : LayerValidator(_type) {
2375 void TanHValidator::checkShapes(const CNNLayer* layer, const std::vector<SizeVector>& inShapes) const {
2376 checkNumOfInput(inShapes, {1});
2379 QuantizeValidator::QuantizeValidator(const std::string& _type) : LayerValidator(_type) {}
2381 void QuantizeValidator::parseParams(CNNLayer* layer) {
2382 auto casted = dynamic_cast<QuantizeLayer*>(layer);
2384 THROW_IE_EXCEPTION << "Layer is not instance of QuantizeLayer class";
2387 casted->levels = casted->GetParamAsInt("levels", 1);
2389 if (casted->levels <= 1) {
2390 THROW_IE_EXCEPTION << layer->name << ": Incorrect value for parameter levels = " << casted->levels
2391 << ". Expected to be > 1.";
2395 void QuantizeValidator::checkParams(const CNNLayer* layer) {
2396 LayerValidator::checkParams(layer);
2399 void QuantizeValidator::checkShapes(const CNNLayer* layer, const vector<SizeVector>& inShapes) const {
2400 auto casted = dynamic_cast<const QuantizeLayer*>(layer);
2402 THROW_IE_EXCEPTION << "Layer is not instance of QuantizeLayer class";
2405 size_t numInputs = inShapes.size();
2407 THROW_IE_EXCEPTION << "Quantize can take only 5 inputs, but actually it has: " << numInputs;
2409 auto dims0 = inShapes[0];
2410 if (dims0.size() < 1) {
2411 THROW_IE_EXCEPTION << "Quantize input0 shape must have at least 1 dimension";
2415 BinaryConvolutionValidator::BinaryConvolutionValidator(const std::string& _type) : LayerValidator(_type) {}
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";
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!";
2430 binConvLayer->_out_depth = binConvLayer->GetParamAsUInt("output");
2432 binConvLayer->_kernel.clear();
2433 binConvLayer->_stride.clear();
2434 binConvLayer->_padding.clear();
2435 binConvLayer->_pads_end.clear();
2436 binConvLayer->_dilation.clear();
2438 vector<unsigned int> kernels = binConvLayer->GetParamAsUInts("kernel", {});
2439 if (kernels.empty()) {
2441 binConvLayer->_kernel.insert(X_AXIS, binConvLayer->GetParamAsUInt("kernel-x"));
2442 binConvLayer->_kernel.insert(Y_AXIS, binConvLayer->GetParamAsUInt("kernel-y"));
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());
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());
2456 binConvLayer->_padding.insert(X_AXIS, binConvLayer->GetParamAsUInt("pad-x", 0u));
2457 binConvLayer->_padding.insert(Y_AXIS, binConvLayer->GetParamAsUInt("pad-y", 0u));
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]));
2462 binConvLayer->_dilation.insert(X_AXIS, binConvLayer->GetParamAsUInt("dilation-x", 1u));
2463 binConvLayer->_dilation.insert(Y_AXIS, binConvLayer->GetParamAsUInt("dilation-y", 1u));
2466 for (int i = 1; i <= kernels.size(); i++) {
2467 binConvLayer->_kernel.insert(i - 1, kernels[kernels.size() - i]);
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);
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;
2478 binConvLayer->_stride.insert(i - 1, strides[strides.size() - i]);
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]);
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]);
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]);
2497 binConvLayer->_auto_pad = binConvLayer->GetParamAsString("auto_pad", "");
2498 binConvLayer->_group = binConvLayer->GetParamAsUInt("group", 1u);
2501 void BinaryConvolutionValidator::checkParams(const CNNLayer* layer) {
2502 auto casted = dynamic_cast<const BinaryConvolutionLayer*>(layer);
2504 THROW_IE_EXCEPTION << "Layer is not instance of BinaryConvolutionLayer class";
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);
2513 THROW_IE_EXCEPTION << "Layer is not instance of BinaryConvolutionLayer class";
2516 void BinaryConvolutionValidator::checkShapes(const CNNLayer* layer, const std::vector<SizeVector>& inShapes) const {
2517 checkNumOfInput(inShapes, {1});
2520 } // namespace InferenceEngine