9ba01e3368384c965c259a48465e04e02ab64d91
[platform/upstream/dldt.git] / inference-engine / src / vpu / graph_transformer / src / stages / norm.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 <unordered_set>
9 #include <memory>
10 #include <set>
11
12 #include <precision_utils.h>
13
14 namespace vpu {
15
16 namespace {
17
18 class LRNStage final : public StageNode {
19 private:
20     StagePtr cloneImpl() const override {
21         return std::make_shared<LRNStage>(*this);
22     }
23
24     void propagateDataOrderImpl() const override {
25         IE_ASSERT(_inputEdges.size() == 1);
26         IE_ASSERT(_outputEdges.size() == 1);
27
28         auto input = _inputEdges[0]->input();
29
30         _orderInfo.setOutput(_outputEdges[0], input->desc().dimsOrder());
31     }
32
33     void getDataStridesRequirementsImpl() const override {
34         IE_ASSERT(_inputEdges.size() == 1);
35         IE_ASSERT(_outputEdges.size() == 1);
36
37         auto input = _inputEdges[0]->input();
38
39         // LRN supports both HWC and CHW orders, but requires that input and output have the same stride
40
41         auto reqs = StridesRequirement::compact();
42         if (_type == StageType::LRN &&
43             input->desc().dimsOrder().dimInd(Dim::C) != 0) {
44             reqs.add(1, DimStride::Aligned);
45         }
46
47         _stridesInfo.setInput(_inputEdges[0], reqs);
48         _stridesInfo.setOutput(_outputEdges[0], reqs);
49     }
50
51     void finalizeDataLayoutImpl() override {
52     }
53
54     void getBatchSupportInfoImpl() const override {
55         IE_ASSERT(_inputEdges.size() == 1);
56         IE_ASSERT(_outputEdges.size() == 1);
57
58         _batchInfo.setInput(_inputEdges[0], BatchSupport::Split);
59         _batchInfo.setOutput(_outputEdges[0], BatchSupport::Split);
60     }
61
62     void finalCheckImpl() const override {
63     }
64
65     void serializeParamsImpl(BlobSerializer& serializer) const override {
66         auto size = attrs().get<int>("size");
67         auto k = attrs().get<int>("k");
68         auto alpha = attrs().get<float>("alpha");
69         auto beta = attrs().get<float>("beta");
70
71         serializer.append(static_cast<uint32_t>(size));
72         serializer.append(ie::PrecisionUtils::f32tof16(k));
73         serializer.append(ie::PrecisionUtils::f32tof16(alpha));
74         serializer.append(ie::PrecisionUtils::f32tof16(beta));
75         serializer.append(ie::PrecisionUtils::f32tof16(0));  // for alignment
76     }
77
78     void serializeDataImpl(BlobSerializer& serializer) const override {
79         IE_ASSERT(_inputEdges.size() == 1);
80         IE_ASSERT(_outputEdges.size() == 1);
81         IE_ASSERT(_tempBufferEdges.empty());
82
83         auto input = _inputEdges[0]->input();
84         auto output = _outputEdges[0]->output();
85
86         input->serializeOldBuffer(handle_from_this(), serializer);
87         output->serializeOldBuffer(handle_from_this(), serializer);
88     }
89 };
90
91 }  // namespace
92
93 void FrontEnd::parseNorm(
94         const Model::Ptr& model,
95         const ie::CNNLayerPtr& _layer,
96         const DataVector& inputs,
97         const DataVector& outputs) {
98     IE_ASSERT(inputs.size() == 1);
99     IE_ASSERT(outputs.size() == 1);
100
101     auto layer = std::dynamic_pointer_cast<ie::NormLayer>(_layer);
102     IE_ASSERT(layer != nullptr);
103
104     auto stage = model->addNewStage<LRNStage>(
105         layer->name,
106         layer->_isAcrossMaps ? StageType::LRN : StageType::InnerLRN,
107         layer,
108         inputs,
109         outputs);
110
111     stage->attrs().set<int>("size", layer->_size);
112     stage->attrs().set<int>("k", layer->_k);
113     stage->attrs().set<float>("alpha", layer->_alpha);
114     stage->attrs().set<float>("beta", layer->_beta);
115 }
116
117 }  // namespace vpu