Publishing 2019 R1.1 content and Myriad plugin sources (#162)
[platform/upstream/dldt.git] / inference-engine / src / vpu / graph_transformer / src / stages / deconvolution.cpp
1 // Copyright (C) 2018-2019 Intel Corporation
2 // SPDX-License-Identifier: Apache-2.0
3 //
4
5 #include <vpu/frontend/frontend.hpp>
6
7 #include <vector>
8 #include <memory>
9 #include <tuple>
10 #include <set>
11
12 #include <ie_layers_internal.hpp>
13
14 #include <vpu/stub_stage.hpp>
15
16 namespace vpu {
17
18 void FrontEnd::parseDeconvolution(
19         const Model::Ptr& model,
20         const ie::CNNLayerPtr& layer,
21         const DataVector& inputs,
22         const DataVector& outputs) {
23     IE_ASSERT(inputs.size() == 1);
24     IE_ASSERT(outputs.size() == 1);
25
26     //
27     // Extract parameters
28     //
29
30     auto deconvLayer = std::dynamic_pointer_cast<ie::DeconvolutionLayer>(layer);
31     IE_ASSERT(deconvLayer != nullptr);
32
33     int kernelSizeX = deconvLayer->_kernel_x;
34     int kernelSizeY = deconvLayer->_kernel_y;
35
36     int kernelStrideX = deconvLayer->_stride_x;
37     int kernelStrideY = deconvLayer->_stride_y;
38
39     auto paddings = getPaddings(*deconvLayer);
40     int padLeft = paddings.begin.exist(ie::X_AXIS) ? paddings.begin[ie::X_AXIS] : 0;
41     int padRight = paddings.end.exist(ie::X_AXIS) ? paddings.end[ie::X_AXIS] : padLeft;
42     int padTop = paddings.begin.exist(ie::Y_AXIS) ? paddings.begin[ie::Y_AXIS] : 0;
43     int padBottom = paddings.end.exist(ie::Y_AXIS) ? paddings.end[ie::Y_AXIS] : 0;
44
45     int dilationX = deconvLayer->_dilation_x;
46     int dilationY = deconvLayer->_dilation_y;
47
48     int groupSize = deconvLayer->_group;
49
50     //
51     // Create const datas
52     //
53
54     auto input = inputs[0];
55     auto output = outputs[0];
56
57     if ((groupSize == 0) ||
58         (groupSize > input->desc().dim(Dim::C)) ||
59         (input->desc().dim(Dim::C) % groupSize != 0) ||
60         (groupSize > output->desc().dim(Dim::C)) ||
61         (output->desc().dim(Dim::C) % groupSize != 0)) {
62         VPU_THROW_EXCEPTION << "DeconvolutionLayer has invalid group value";
63     }
64
65     Data weights, biases;
66     std::tie(weights, biases) = getWeightsAndBiases(model, layer);
67
68     IE_ASSERT(weights->desc().totalDimSize() >=
69               kernelSizeX * kernelSizeY * (input->desc().dim(Dim::C) / groupSize) * output->desc().dim(Dim::C));
70     weights = model->duplicateData(
71         weights,
72         "@deconv",
73         DataDesc({
74             kernelSizeX,
75             kernelSizeY,
76             input->desc().dim(Dim::C) / groupSize,
77             output->desc().dim(Dim::C)}));
78
79     if (biases->usage() != DataUsage::Fake) {
80         IE_ASSERT(biases->desc().totalDimSize() >= output->desc().dim(Dim::C));
81         biases = model->duplicateData(
82             biases,
83             "@deconv",
84             DataDesc({output->desc().dim(Dim::C)}));
85     }
86
87     //
88     // Create stub stage
89     //
90
91     auto stage = model->addNewStage<StubStage>(
92         layer->name,
93         StageType::StubDeconv,
94         layer,
95         {input, weights, biases},
96         {output});
97
98     stage->attrs().set<int>("kernelSizeX", kernelSizeX);
99     stage->attrs().set<int>("kernelSizeY", kernelSizeY);
100
101     stage->attrs().set<int>("kernelStrideX", kernelStrideX);
102     stage->attrs().set<int>("kernelStrideY", kernelStrideY);
103
104     stage->attrs().set<int>("padLeft", padLeft);
105     stage->attrs().set<int>("padRight", padRight);
106     stage->attrs().set<int>("padTop", padTop);
107     stage->attrs().set<int>("padBottom", padBottom);
108
109     stage->attrs().set<int>("dilationX", dilationX);
110     stage->attrs().set<int>("dilationY", dilationY);
111
112     stage->attrs().set<int>("groupSize", groupSize);
113     stage->attrs().set<bool>("tryHW", true);
114 }
115
116 }  // namespace vpu