1 // Copyright (C) 2018-2019 Intel Corporation
2 // SPDX-License-Identifier: Apache-2.0
10 #include "ie_layers_internal.hpp"
11 #include "layer_transform.hpp"
13 namespace InferenceEngine {
16 int getKernel(const Layer &layer, size_t i) {
17 if (layer._dilation.size() > i && layer._dilation[i])
18 return (layer._kernel[i] - 1) * layer._dilation[i] + 1;
19 return layer._kernel[i];
23 int getKernel(const PoolingLayer &layer, size_t i) {
24 return layer._kernel[i];
28 Paddings getPaddingsInternal(const Layer &layer) {
29 std::string errorPrefix = "Failed to calculate padding for " + layer.type + ": ";
31 const std::map<std::string, std::string> ¶ms = layer.params;
32 const std::vector<DataWeakPtr> &insData = layer.insData;
33 auto it = params.find("auto_pad");
34 if (it != params.end()) {
35 if (it->second == "valid") {
36 return {PropertyVector<unsigned>(layer._kernel.size(), 0u),
37 PropertyVector<unsigned>(layer._kernel.size(), 0u)};
39 if (insData.size() != 1)
40 THROW_IE_EXCEPTION << "number of inputs should be equal 1";
41 auto firstInput = insData[0].lock();
43 THROW_IE_EXCEPTION << "input is empty";
44 auto shape = firstInput->getTensorDesc().getDims();
45 auto shape_size = shape.size();
46 if (shape_size < 4 || shape_size > 5)
47 THROW_IE_EXCEPTION << "input shape must be 4D or 5D";
49 std::vector<int> shapes;
50 shapes.push_back(shape[shape_size - 1]);
51 shapes.push_back(shape[shape_size - 2]);
53 shapes.push_back(shape[shape_size - 3]);
55 PropertyVector<unsigned int> pad_begin, pad_end;
57 for (size_t i = 0; i < layer._kernel.size(); i++) {
59 int kernel = getKernel(layer, i);
61 int stride = layer._stride.size() > i ? layer._stride[i] : 1;
63 if (sh % stride == 0) {
64 PA = std::max(kernel - stride, 0);
66 PA = std::max(kernel - (sh % stride), 0);
68 unsigned p_begin = PA / 2;
69 unsigned p_end = PA - p_begin;
71 pad_begin.insert(i, p_begin);
72 pad_end.insert(i, p_end);
75 return {pad_begin, pad_end};
78 return {layer._padding, layer._pads_end};
79 } catch (const InferenceEngine::details::InferenceEngineException &iee) {
80 THROW_IE_EXCEPTION << errorPrefix << iee.what();
84 class PaddingsUpdater {
85 std::reference_wrapper<Paddings> pad;
87 explicit PaddingsUpdater(Paddings & pad) : pad(pad) {}
89 typename std::enable_if<!std::is_same<T, CNNLayer*>::value, bool>::type
90 operator () (T & layer) const {
91 pad.get() = getPaddingsInternal(*layer);
94 bool operator () (CNNLayer * layer) const {
95 THROW_IE_EXCEPTION << "padding calculation for layer: " << layer->name << "(" << layer->type << ") unsupported";
99 Paddings getPaddingsImpl(const CNNLayer &layer) {
101 details::visitActualLayer(std::tuple <DeconvolutionLayer*, ConvolutionLayer*, BinaryConvolutionLayer*, PoolingLayer*,
102 CNNLayer*>(), layer, PaddingsUpdater(actual));
106 } // namespace InferenceEngine