// Copyright (C) 2018-2019 Intel Corporation // SPDX-License-Identifier: Apache-2.0 // #include <ie_layers.h> #include <gtest/gtest.h> #include <ie_data.h> #include "ie_precision.hpp" #include <inference_engine/ie_layers_internal.hpp> using namespace std; using InferenceEngine::X_AXIS; using InferenceEngine::Y_AXIS; using namespace InferenceEngine; const std::string defaultLayerName = "layer"; const std::string defaultLayerType = "unknown"; InferenceEngine::Precision defaultPrecision{InferenceEngine::Precision::FP32}; class LayersTests : public ::testing::Test { public: virtual void TearDown() { } virtual void SetUp() { } static InferenceEngine::LayerParams getParamsForLayer(std::string name, std::string type, InferenceEngine::Precision precision) { InferenceEngine::LayerParams params = {}; params.name = name; params.type = type; params.precision = precision; return params; } static InferenceEngine::LayerParams getDefaultParamsForLayer() { return getParamsForLayer(defaultLayerName, defaultLayerType, defaultPrecision); } template<class T> bool checkCreateLayer() { T layer(getDefaultParamsForLayer()); return layer.name == defaultLayerName; } }; TEST_F(LayersTests, canCreateLayersWithDefaultParams) { ASSERT_TRUE(checkCreateLayer<InferenceEngine::CNNLayer>()); ASSERT_TRUE(checkCreateLayer<InferenceEngine::ConvolutionLayer>()); ASSERT_TRUE(checkCreateLayer<InferenceEngine::DeconvolutionLayer>()); ASSERT_TRUE(checkCreateLayer<InferenceEngine::PoolingLayer>()); ASSERT_TRUE(checkCreateLayer<InferenceEngine::PowerLayer>()); ASSERT_TRUE(checkCreateLayer<InferenceEngine::FullyConnectedLayer>()); ASSERT_TRUE(checkCreateLayer<InferenceEngine::ConcatLayer>()); ASSERT_TRUE(checkCreateLayer<InferenceEngine::SplitLayer>()); ASSERT_TRUE(checkCreateLayer<InferenceEngine::NormLayer>()); ASSERT_TRUE(checkCreateLayer<InferenceEngine::SoftMaxLayer>()); ASSERT_TRUE(checkCreateLayer<InferenceEngine::GRNLayer>()); ASSERT_TRUE(checkCreateLayer<InferenceEngine::ReLULayer>()); ASSERT_TRUE(checkCreateLayer<InferenceEngine::EltwiseLayer>()); ASSERT_TRUE(checkCreateLayer<InferenceEngine::CropLayer>()); ASSERT_TRUE(checkCreateLayer<InferenceEngine::ScaleShiftLayer>()); } TEST_F(LayersTests, throwsOnExpiredDataPtr) { InferenceEngine::CNNLayer layer(getDefaultParamsForLayer()); InferenceEngine::DataPtr dataPtr( new InferenceEngine::Data("data", InferenceEngine::Precision::FP32, InferenceEngine::NCHW)); layer.insData.resize(1); layer.insData[0] = dataPtr; dataPtr.reset(); ASSERT_THROW(layer.input(), InferenceEngine::details::InferenceEngineException); } template<class T> void ASSERT_CNN_LAYER_DEFAULT(T& l) { ASSERT_STREQ(l.params["some"].c_str(), "some"); } template<> void ASSERT_CNN_LAYER_DEFAULT(ConvolutionLayer& l) { ASSERT_EQ(l._kernel[X_AXIS], 1); ASSERT_EQ(l._kernel_x, 1); ASSERT_EQ(l._out_depth, 3); ASSERT_EQ(l._group, 4); ASSERT_EQ(l._pads_end[X_AXIS], 5); ASSERT_EQ(l._stride[X_AXIS], 6); ASSERT_EQ(l._stride_x, 6); ASSERT_EQ(l._dilation[X_AXIS], 7); ASSERT_EQ(l._dilation_x, 7); ASSERT_NO_FATAL_FAILURE(ASSERT_CNN_LAYER_DEFAULT(static_cast<CNNLayer&>(l))); } template<> void ASSERT_CNN_LAYER_DEFAULT(DeconvolutionLayer& l) { ASSERT_NO_FATAL_FAILURE(ASSERT_CNN_LAYER_DEFAULT(static_cast<ConvolutionLayer&>(l))); } template<> void ASSERT_CNN_LAYER_DEFAULT(PoolingLayer& l) { ASSERT_NO_FATAL_FAILURE(ASSERT_CNN_LAYER_DEFAULT(static_cast<CNNLayer&>(l))); } template<class T> void checkCopyLayerWithKernel(T& layer_1) { T layer_2(LayersTests::getDefaultParamsForLayer()); layer_2 = layer_1; ASSERT_NO_FATAL_FAILURE(ASSERT_CNN_LAYER_DEFAULT(layer_2)); T layer_3(layer_1); ASSERT_NO_FATAL_FAILURE(ASSERT_CNN_LAYER_DEFAULT(layer_3)); T layer_4(LayersTests::getDefaultParamsForLayer()); //use copy to temporary object then move it using asignment operator { T layerx(layer_1); layer_4 = std::move(layerx); } ASSERT_NO_FATAL_FAILURE(ASSERT_CNN_LAYER_DEFAULT(layer_4)); //use copy to temporary object then move it using move ctor T layerx(layer_1); T layer_5 = std::move(layerx); ASSERT_NO_FATAL_FAILURE(ASSERT_CNN_LAYER_DEFAULT(layer_5)); layer_1._kernel[X_AXIS] = 4; ASSERT_EQ(layer_1._kernel_x, 4); layer_1._kernel_x = 40; ASSERT_EQ(layer_1._kernel[X_AXIS], 40); ASSERT_NO_FATAL_FAILURE(ASSERT_CNN_LAYER_DEFAULT(layer_2)); ASSERT_NO_FATAL_FAILURE(ASSERT_CNN_LAYER_DEFAULT(layer_3)); ASSERT_NO_FATAL_FAILURE(ASSERT_CNN_LAYER_DEFAULT(layer_4)); ASSERT_NO_FATAL_FAILURE(ASSERT_CNN_LAYER_DEFAULT(layer_5)); } TEST_F(LayersTests, copyConvolution) { ConvolutionLayer layer_1(getDefaultParamsForLayer()); layer_1._kernel.insert(X_AXIS, 1); layer_1._padding.insert(X_AXIS, 2); layer_1._out_depth = 3; layer_1._group = 4; layer_1._pads_end.insert(X_AXIS, 5); layer_1._stride.insert(X_AXIS, 6); layer_1._dilation.insert(X_AXIS, 7); layer_1.params["some"] = "some"; checkCopyLayerWithKernel(layer_1); } TEST_F(LayersTests, copyDeconvolution) { ConvolutionLayer layer_1(getDefaultParamsForLayer()); layer_1._kernel.insert(X_AXIS, 1); layer_1._padding.insert(X_AXIS, 2); layer_1._out_depth = 3; layer_1._group = 4; layer_1._pads_end.insert(X_AXIS, 5); layer_1._stride.insert(X_AXIS, 6); layer_1._dilation.insert(X_AXIS, 7); layer_1.params["some"] = "some"; checkCopyLayerWithKernel(layer_1); } TEST_F(LayersTests, copyPooling) { PoolingLayer layer_1(getDefaultParamsForLayer()); layer_1._kernel.insert(X_AXIS, 1); layer_1._padding.insert(X_AXIS, 2); layer_1._type = PoolingLayer::MAX; layer_1._exclude_pad = true; layer_1._pads_end.insert(X_AXIS, 5); layer_1._stride.insert(X_AXIS, 6); layer_1.params["some"] = "some"; checkCopyLayerWithKernel(layer_1); } TEST_F(LayersTests, canNotInserOutOfBounds) { PoolingLayer layer_1(getDefaultParamsForLayer()); ASSERT_ANY_THROW(layer_1._kernel.insert(MAX_DIMS_NUMBER, 5)); ASSERT_ANY_THROW(layer_1._kernel.insert(-1, 5)); } TEST_F(LayersTests, canInsertIntoExistedAxis) { PoolingLayer layer_1(getDefaultParamsForLayer()); layer_1._kernel.insert(Z_AXIS, 5); ASSERT_EQ(layer_1._kernel[Z_AXIS], 5); // for backward compatibility with IRv2 initial size is 2 ASSERT_EQ(layer_1._kernel.size(), 3); layer_1._kernel.insert(Z_AXIS, 6); ASSERT_EQ(layer_1._kernel[Z_AXIS], 6); ASSERT_EQ(layer_1._kernel.size(), 3); layer_1._kernel.insert(Z_AXIS, 0); ASSERT_EQ(layer_1._kernel[Z_AXIS], 0); ASSERT_EQ(layer_1._kernel.size(), 3); layer_1._kernel.insert(Z_AXIS, 6); ASSERT_EQ(layer_1._kernel[Z_AXIS], 6); ASSERT_EQ(layer_1._kernel.size(), 3); } TEST_F(LayersTests, canRemoveProperty) { PoolingLayer layer_1(getDefaultParamsForLayer()); layer_1._kernel.insert(Z_AXIS, 5); layer_1._kernel.remove(X_AXIS); layer_1._kernel.remove(Y_AXIS); ASSERT_EQ(layer_1._kernel.size(), 1); layer_1._kernel.remove(Z_AXIS); ASSERT_EQ(layer_1._kernel.size(), 0); } TEST_F(LayersTests, cannotRemovePropertyOutOfRange) { PoolingLayer layer_1(getDefaultParamsForLayer()); layer_1._kernel.insert(Z_AXIS, 5); ASSERT_NO_THROW(layer_1._kernel.remove(MAX_DIMS_NUMBER + 1000000)); ASSERT_NO_THROW(layer_1._kernel.remove(-1)); ASSERT_EQ(layer_1._kernel.size(), 3); } TEST_F(LayersTests, convIRv2BackwardCompatibility) { ConvolutionLayer conv(getDefaultParamsForLayer()); ASSERT_NO_THROW(conv._kernel[X_AXIS]); ASSERT_NO_THROW(conv._kernel[Y_AXIS]); ASSERT_NO_THROW(conv._padding[X_AXIS]); ASSERT_NO_THROW(conv._padding[Y_AXIS]); ASSERT_NO_THROW(conv._stride[X_AXIS]); ASSERT_NO_THROW(conv._stride[Y_AXIS]); ASSERT_NO_THROW(conv._dilation[X_AXIS]); ASSERT_NO_THROW(conv._dilation[Y_AXIS]); conv._kernel_x = 9u; ASSERT_EQ(conv._kernel[X_AXIS], 9u); conv._kernel_y = 2u; ASSERT_EQ(conv._kernel[Y_AXIS], 2u); conv._padding_x = 3u; ASSERT_EQ(conv._padding[X_AXIS], 3u); conv._padding_y = 4u; ASSERT_EQ(conv._padding[Y_AXIS], 4u); conv._stride_x = 5u; ASSERT_EQ(conv._stride[X_AXIS], 5u); conv._stride_y = 6u; ASSERT_EQ(conv._stride[Y_AXIS], 6u); conv._dilation_x = 7u; ASSERT_EQ(conv._dilation[X_AXIS], 7u); conv._dilation_y = 8u; ASSERT_EQ(conv._dilation[Y_AXIS], 8u); conv._kernel[X_AXIS] = 8u; ASSERT_EQ(conv._kernel_x, 8u); conv._kernel[Y_AXIS] = 7u; ASSERT_EQ(conv._kernel_y, 7u); conv._padding[X_AXIS] = 6u; ASSERT_EQ(conv._padding_x, 6u); conv._padding[Y_AXIS] = 5u; ASSERT_EQ(conv._padding_y, 5u); conv._stride[X_AXIS] = 4u; ASSERT_EQ(conv._stride_x, 4u); conv._stride[Y_AXIS] = 3u; ASSERT_EQ(conv._stride_y, 3u); conv._dilation[X_AXIS] = 2u; ASSERT_EQ(conv._dilation_x, 2u); conv._dilation[Y_AXIS] = 9u; ASSERT_EQ(conv._dilation_y, 9u); } TEST_F(LayersTests, deconvIRv2BackwardCompatibility) { DeconvolutionLayer deconv(getDefaultParamsForLayer()); ASSERT_NO_THROW(deconv._kernel[X_AXIS]); ASSERT_NO_THROW(deconv._kernel[Y_AXIS]); ASSERT_NO_THROW(deconv._padding[X_AXIS]); ASSERT_NO_THROW(deconv._padding[Y_AXIS]); ASSERT_NO_THROW(deconv._stride[X_AXIS]); ASSERT_NO_THROW(deconv._stride[Y_AXIS]); ASSERT_NO_THROW(deconv._dilation[X_AXIS]); ASSERT_NO_THROW(deconv._dilation[Y_AXIS]); deconv._kernel_x = 9u; ASSERT_EQ(deconv._kernel[X_AXIS], 9u); deconv._kernel_y = 2u; ASSERT_EQ(deconv._kernel[Y_AXIS], 2u); deconv._padding_x = 3u; ASSERT_EQ(deconv._padding[X_AXIS], 3u); deconv._padding_y = 4u; ASSERT_EQ(deconv._padding[Y_AXIS], 4u); deconv._stride_x = 5u; ASSERT_EQ(deconv._stride[X_AXIS], 5u); deconv._stride_y = 6u; ASSERT_EQ(deconv._stride[Y_AXIS], 6u); deconv._dilation_x = 7u; ASSERT_EQ(deconv._dilation[X_AXIS], 7u); deconv._dilation_y = 8u; ASSERT_EQ(deconv._dilation[Y_AXIS], 8u); deconv._kernel[X_AXIS] = 8u; ASSERT_EQ(deconv._kernel_x, 8u); deconv._kernel[Y_AXIS] = 7u; ASSERT_EQ(deconv._kernel_y, 7u); deconv._padding[X_AXIS] = 6u; ASSERT_EQ(deconv._padding_x, 6u); deconv._padding[Y_AXIS] = 5u; ASSERT_EQ(deconv._padding_y, 5u); deconv._stride[X_AXIS] = 4u; ASSERT_EQ(deconv._stride_x, 4u); deconv._stride[Y_AXIS] = 3u; ASSERT_EQ(deconv._stride_y, 3u); deconv._dilation[X_AXIS] = 2u; ASSERT_EQ(deconv._dilation_x, 2u); deconv._dilation[Y_AXIS] = 9u; ASSERT_EQ(deconv._dilation_y, 9u); } TEST_F(LayersTests, poolIRv2BackwardCompatibility) { PoolingLayer pool(getDefaultParamsForLayer()); ASSERT_NO_THROW(pool._kernel[X_AXIS]); ASSERT_NO_THROW(pool._kernel[Y_AXIS]); ASSERT_NO_THROW(pool._padding[X_AXIS]); ASSERT_NO_THROW(pool._padding[Y_AXIS]); ASSERT_NO_THROW(pool._stride[X_AXIS]); ASSERT_NO_THROW(pool._stride[Y_AXIS]); pool._kernel_x = 9u; ASSERT_EQ(pool._kernel[X_AXIS], 9u); pool._kernel_y = 2u; ASSERT_EQ(pool._kernel[Y_AXIS], 2u); pool._padding_x = 3u; ASSERT_EQ(pool._padding[X_AXIS], 3u); pool._padding_y = 4u; ASSERT_EQ(pool._padding[Y_AXIS], 4u); pool._stride_x = 5u; ASSERT_EQ(pool._stride[X_AXIS], 5u); pool._stride_y = 6u; ASSERT_EQ(pool._stride[Y_AXIS], 6u); pool._kernel[X_AXIS] = 8u; ASSERT_EQ(pool._kernel_x, 8u); pool._kernel[Y_AXIS] = 7u; ASSERT_EQ(pool._kernel_y, 7u); pool._padding[X_AXIS] = 6u; ASSERT_EQ(pool._padding_x, 6u); pool._padding[Y_AXIS] = 5u; ASSERT_EQ(pool._padding_y, 5u); pool._stride[X_AXIS] = 4u; ASSERT_EQ(pool._stride_x, 4u); pool._stride[Y_AXIS] = 3u; ASSERT_EQ(pool._stride_y, 3u); } TEST_F(LayersTests, canGetPadBeginForConvolution) { ConvolutionLayer layer(getDefaultParamsForLayer()); PropertyVector<unsigned> ref{{1, 2}}; layer._padding = ref; auto allPads = getPaddings(layer); ASSERT_EQ(allPads.begin, ref); } TEST_F(LayersTests, canGetPadEndForConvolution) { ConvolutionLayer layer(getDefaultParamsForLayer()); PropertyVector<unsigned> ref{{1, 2}}; layer._pads_end = ref; auto allPads = getPaddings(layer); ASSERT_EQ(allPads.end, ref); } TEST_F(LayersTests, canGetPad3DBeginForConvolution) { ConvolutionLayer layer(getDefaultParamsForLayer()); PropertyVector<unsigned> ref; ref.insert(X_AXIS, 1); ref.insert(Y_AXIS, 2); ref.insert(Z_AXIS, 3); layer._padding = ref; auto allPads = getPaddings(layer); ASSERT_EQ(allPads.begin, ref); } TEST_F(LayersTests, canGetPad3DEndForConvolution) { ConvolutionLayer layer(getDefaultParamsForLayer()); PropertyVector<unsigned> ref; ref.insert(X_AXIS, 1); ref.insert(Y_AXIS, 2); ref.insert(Z_AXIS, 3); layer._pads_end = ref; auto allPads = getPaddings(layer); ASSERT_EQ(allPads.end, ref); } TEST_F(LayersTests, returnDefaultPadForEmptyConvolution) { ConvolutionLayer layer(getDefaultParamsForLayer()); auto allPads = getPaddings(layer); PropertyVector<unsigned> ref_begin(2, 0u); PropertyVector<unsigned> ref_end; ASSERT_EQ(allPads.begin, ref_begin); ASSERT_EQ(allPads.end, ref_end); } TEST_F(LayersTests, returnEmptyPadForValidPadConvolution) { ConvolutionLayer layer(getDefaultParamsForLayer()); layer.params["auto_pad"] = "valid"; auto allPads = getPaddings(layer); PropertyVector<unsigned> ref(2,0u); ASSERT_EQ(allPads.begin, ref); ASSERT_EQ(allPads.end, ref); PropertyVector<unsigned> ref3D(2,0u); layer._kernel.insert(Z_AXIS, 0u); ASSERT_EQ(allPads.begin, ref3D); ASSERT_EQ(allPads.end, ref3D); } TEST_F(LayersTests, throwOnSamePadForEmptyConvolution) { ConvolutionLayer layer(getDefaultParamsForLayer()); layer.params["auto_pad"] = "same_upper"; ASSERT_THROW(getPaddings(layer), details::InferenceEngineException); } TEST_F(LayersTests, throwOnInvalidDimsSamePadForConvolution) { ConvolutionLayer layer(getDefaultParamsForLayer()); layer.params["auto_pad"] = "same_upper"; auto emptyData = std::make_shared<InferenceEngine::Data>("", Precision::UNSPECIFIED); layer.insData.push_back(emptyData); ASSERT_THROW(getPaddings(layer), details::InferenceEngineException); } TEST_F(LayersTests, throwOn2DSamePadForConvolution) { ConvolutionLayer layer(getDefaultParamsForLayer()); layer.params["auto_pad"] = "same_upper"; auto notEmptyData = std::make_shared<InferenceEngine::Data>("", SizeVector{1, 1}, Precision::UNSPECIFIED, Layout::NC); layer.insData.push_back(notEmptyData); ASSERT_THROW(getPaddings(layer), details::InferenceEngineException); } TEST_F(LayersTests, throwWithNotEnoughParamsSamePadForConvolution) { ConvolutionLayer layer(getDefaultParamsForLayer()); layer.params["auto_pad"] = "same_upper"; auto notEmptyData = std::make_shared<InferenceEngine::Data>("", SizeVector{1, 2, 3, 4}, Precision::UNSPECIFIED); layer.insData.push_back(notEmptyData); ASSERT_NO_THROW(getPaddings(layer)); auto notEmptyData3D = std::make_shared<InferenceEngine::Data>("", SizeVector{1, 2, 3, 4, 5}, Precision::UNSPECIFIED, Layout::NCDHW); layer._kernel.insert(Z_AXIS, 0u); layer.insData[0] = notEmptyData3D; ASSERT_NO_THROW(getPaddings(layer)); } // parameters are from real model, like Mobilenet-SSD TEST_F(LayersTests, canGetSamePadForConvolutionEvenInput) { ConvolutionLayer layer(getDefaultParamsForLayer()); layer.params["auto_pad"] = "same_upper"; TensorDesc tensorDesc(Precision::UNSPECIFIED, SizeVector{1, 144, 160, 160}, Layout::NCHW); auto notEmptyData = std::make_shared<InferenceEngine::Data>("", tensorDesc); layer.insData.push_back(notEmptyData); layer._dilation = PropertyVector<unsigned>{{1, 1}}; layer._kernel = PropertyVector<unsigned>{{3, 3}}; layer._stride = PropertyVector<unsigned>{{2, 2}}; auto pad = getPaddings(layer); ASSERT_EQ(pad.begin, PropertyVector<unsigned>(2, 0)); ASSERT_EQ(pad.end, PropertyVector<unsigned>(2, 1)); } // parameters are from real model, like V-Net TEST_F(LayersTests, canGetSamePadForConvolutionEvenInput3D) { ConvolutionLayer layer(getDefaultParamsForLayer()); layer.params["auto_pad"] = "same_upper"; TensorDesc tensorDesc(Precision::UNSPECIFIED, SizeVector{1, 6, 190, 190, 20}, Layout::NCDHW); auto notEmptyData = std::make_shared<InferenceEngine::Data>("", tensorDesc); layer.insData.push_back(notEmptyData); layer._dilation.insert(X_AXIS, 1u); layer._dilation.insert(Y_AXIS, 1u); layer._dilation.insert(Z_AXIS, 1u); layer._kernel.insert(X_AXIS, 5u); layer._kernel.insert(Y_AXIS, 5u); layer._kernel.insert(Z_AXIS, 5u); layer._stride.insert(X_AXIS, 1u); layer._stride.insert(Y_AXIS, 1u); layer._stride.insert(Z_AXIS, 1u); auto pad = getPaddings(layer); ASSERT_EQ(pad.begin, PropertyVector<unsigned>(3, 2u)); ASSERT_EQ(pad.end, PropertyVector<unsigned>(3, 2u)); } // parameters are from real model, like Mobilenet-SSD TEST_F(LayersTests, canGetSamePadForConvolutionOddInput) { ConvolutionLayer layer(getDefaultParamsForLayer()); layer.params["auto_pad"] = "same_upper"; TensorDesc tensorDesc(Precision::UNSPECIFIED, SizeVector{1, 144, 75, 75}, Layout::NCHW); auto notEmptyData = std::make_shared<InferenceEngine::Data>("", tensorDesc); layer.insData.push_back(notEmptyData); layer._dilation = PropertyVector<unsigned>{{1, 1}}; layer._kernel = PropertyVector<unsigned>{{3, 3}}; layer._stride = PropertyVector<unsigned>{{2, 2}}; PropertyVector<unsigned> ref(2, 1); auto pad = getPaddings(layer); ASSERT_EQ(pad.begin, ref); ASSERT_EQ(pad.end, ref); } TEST_F(LayersTests, canGetSamePadForDeConvolutionEvenInput) { DeconvolutionLayer layer(getDefaultParamsForLayer()); layer.params["auto_pad"] = "same_upper"; TensorDesc tensorDesc(Precision::UNSPECIFIED, SizeVector{1, 144, 160, 160}, Layout::NCHW); auto notEmptyData = std::make_shared<InferenceEngine::Data>("", tensorDesc); layer.insData.push_back(notEmptyData); layer._dilation = PropertyVector<unsigned>{{1, 1}}; layer._kernel = PropertyVector<unsigned>{{3, 3}}; layer._stride = PropertyVector<unsigned>{{2, 2}}; auto pad = getPaddings(layer); ASSERT_EQ(pad.begin, PropertyVector<unsigned>(2, 0)); ASSERT_EQ(pad.end, PropertyVector<unsigned>(2, 1)); } TEST_F(LayersTests, canGetSamePadForDeConvolutionOddInput) { DeconvolutionLayer layer(getDefaultParamsForLayer()); layer.params["auto_pad"] = "same_upper"; TensorDesc tensorDesc(Precision::UNSPECIFIED, SizeVector{1, 144, 75, 75}, Layout::NCHW); auto notEmptyData = std::make_shared<InferenceEngine::Data>("", tensorDesc); layer.insData.push_back(notEmptyData); layer._dilation = PropertyVector<unsigned>{{1, 1}}; layer._kernel = PropertyVector<unsigned>{{3, 3}}; layer._stride = PropertyVector<unsigned>{{2, 2}}; PropertyVector<unsigned> ref(2, 1); auto pad = getPaddings(layer); ASSERT_EQ(pad.begin, ref); ASSERT_EQ(pad.end, ref); } TEST_F(LayersTests, canGetSamePadForPoolingEvenInput) { PoolingLayer layer(getDefaultParamsForLayer()); layer.params["auto_pad"] = "same_upper"; TensorDesc tensorDesc(Precision::UNSPECIFIED, SizeVector{1, 144, 160, 160}, Layout::NCHW); auto notEmptyData = std::make_shared<InferenceEngine::Data>("", tensorDesc); layer.insData.push_back(notEmptyData); layer._kernel = PropertyVector<unsigned>{{3, 3}}; layer._stride = PropertyVector<unsigned>{{2, 2}}; auto pad = getPaddings(layer); ASSERT_EQ(pad.begin, PropertyVector<unsigned>(2, 0)); ASSERT_EQ(pad.end, PropertyVector<unsigned>(2, 1)); } TEST_F(LayersTests, canGetSamePadForPoolingOddInput) { PoolingLayer layer(getDefaultParamsForLayer()); layer.params["auto_pad"] = "same_upper"; TensorDesc tensorDesc(Precision::UNSPECIFIED, SizeVector{1, 144, 75, 75}, Layout::NCHW); auto notEmptyData = std::make_shared<InferenceEngine::Data>("", tensorDesc); layer.insData.push_back(notEmptyData); layer._kernel = PropertyVector<unsigned>{{3, 3}}; layer._stride = PropertyVector<unsigned>{{2, 2}}; PropertyVector<unsigned> ref(2, 1); auto pad = getPaddings(layer); ASSERT_EQ(pad.begin, ref); ASSERT_EQ(pad.end, ref); } TEST_F(LayersTests, cannotGetPadForUnsupportedLayer) { FullyConnectedLayer layer(getDefaultParamsForLayer()); ASSERT_ANY_THROW(getPaddingsImpl(layer)); }