Publishing 2019 R1.1 content and Myriad plugin sources (#162)
[platform/upstream/dldt.git] / inference-engine / src / vpu / graph_transformer / src / stages / bias.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 <string>
10
11 #include <vpu/sw/post_op_stage.hpp>
12
13 namespace vpu {
14
15 void FrontEnd::parseBias(
16         const Model::Ptr& model,
17         const ie::CNNLayerPtr& layer,
18         const DataVector& inputs,
19         const DataVector& outputs) {
20     IE_ASSERT(inputs.size() == 2);
21     IE_ASSERT(outputs.size() == 1);
22
23     auto input = inputs[0];
24     auto biases = inputs[1];
25
26     auto biasesDims = biases->desc().dims();
27     if (biasesDims.size() < 4 && input->desc().numDims() == 4) {
28         biasesDims.set(Dim::N, 1);
29     }
30
31     if (input->desc().dims() != biasesDims) {
32         VPU_THROW_EXCEPTION
33             << "Current Bias layer implementation supports only equal inputs (axis 0, 1 for 4D tensor, axis 0 for other dimensions),"
34             << " layer name is " << layer->name;
35     }
36
37     if (biases->desc().numDims() < 4 && input->desc().numDims() == 4) {
38         DataDesc newBiasesDesc({
39             biases->desc().dim(Dim::W),
40             biases->desc().dim(Dim::H),
41             biases->desc().dim(Dim::C),
42             1});
43
44         auto newBiases = model->duplicateData(
45             biases,
46             "@reshaped",
47             newBiasesDesc);
48
49         _stageBuilder->addReshapeStage(
50             model,
51             newBiases->name(),
52             layer,
53             biases,
54             newBiases);
55
56         biases = newBiases;
57     }
58
59     _stageBuilder->addSumStage(
60         model,
61         layer->name,
62         layer,
63         input, biases,
64         outputs[0]);
65 }
66
67 namespace {
68
69 class BiasStage final : public PostOpStage {
70 protected:
71     StagePtr cloneImpl() const override {
72         return std::make_shared<BiasStage>(*this);
73     }
74
75     DataMap<float> propagateScaleFactorsImpl(
76             const DataMap<float>& inputScales,
77             ScalePropagationStep step) override {
78         IE_ASSERT(_inputEdges.size() == 2);
79         IE_ASSERT(_outputEdges.size() == 1);
80
81         auto input = _inputEdges[0]->input();
82         auto biases = _inputEdges[1]->input();
83         auto output = _outputEdges[0]->output();
84
85         DataMap<float> out;
86
87         if (step == ScalePropagationStep::Propagate) {
88             auto inputScale = inputScales.at(input);
89
90             out[biases] = inputScale;
91             out[output] = inputScale;
92         } else {
93             // Bias can only propagate scaling, not generate.
94             out[input] = 1.0f;
95             out[biases] = 1.0f;
96             out[output] = 1.0f;
97         }
98
99         return out;
100     }
101
102     void serializeParamsImpl(BlobSerializer&) const override {
103     }
104 };
105
106 }  // namespace
107
108 Stage StageBuilder::addBiasStage(
109         const Model::Ptr& model,
110         const std::string& name,
111         const ie::CNNLayerPtr& layer,
112         const Data& input,
113         const Data& biases,
114         const Data& output) {
115     return model->addNewStage<BiasStage>(
116         name,
117         StageType::Bias,
118         layer,
119         {input, biases},
120         {output});
121 }
122
123 }  // namespace vpu