Publishing 2019 R1 content
[platform/upstream/dldt.git] / inference-engine / src / inference_engine / builders / ie_eltwise_layer.cpp
1 // Copyright (C) 2018-2019 Intel Corporation
2 // SPDX-License-Identifier: Apache-2.0
3 //
4
5 #include <builders/ie_eltwise_layer.hpp>
6 #include <ie_cnn_layer_builder.h>
7
8 #include <vector>
9 #include <string>
10
11 using namespace InferenceEngine;
12
13 Builder::EltwiseLayer::EltwiseLayer(const std::string& name): LayerDecorator("Eltwise", name) {
14     getLayer()->getOutputPorts().resize(1);
15     getLayer()->getInputPorts().resize(2);
16     setEltwiseType(EltwiseType::SUM);
17 }
18
19 Builder::EltwiseLayer::EltwiseLayer(const Layer::Ptr& layer): LayerDecorator(layer) {
20     checkType("Eltwise");
21
22     std::string operatorStr = getLayer()->getParameters()["operation"];
23     if (operatorStr == "max") {
24         type = MAX;
25     } else if (operatorStr == "sum") {
26         type = SUM;
27     } else if (operatorStr == "mul") {
28         type = MUL;
29     } else if (operatorStr == "sub") {
30         type = SUB;
31     } else if (operatorStr == "div") {
32         type = DIV;
33     } else if (operatorStr == "min") {
34         type = MIN;
35     } else if (operatorStr == "squared_diff") {
36         type = SQUARED_DIFF;
37     }
38 }
39
40 Builder::EltwiseLayer::EltwiseLayer(const Layer::CPtr& layer): LayerDecorator(layer) {
41     checkType("Eltwise");
42
43     const auto cLayer = static_cast<const EltwiseLayer*>(this)->getLayer();
44
45     std::string operatorStr = cLayer->getParameters().at("operation");
46     if (operatorStr == "max") {
47         type = MAX;
48     } else if (operatorStr == "sum") {
49         type = SUM;
50     } else if (operatorStr == "mul") {
51         type = MUL;
52     } else if (operatorStr == "sub") {
53         type = SUB;
54     } else if (operatorStr == "div") {
55         type = DIV;
56     } else if (operatorStr == "min") {
57         type = MIN;
58     } else if (operatorStr == "squared_diff") {
59         type = SQUARED_DIFF;
60     }
61 }
62
63 Builder::EltwiseLayer& Builder::EltwiseLayer::setName(const std::string& name) {
64     getLayer()->setName(name);
65     return *this;
66 }
67
68 const std::vector<Port>& Builder::EltwiseLayer::getInputPorts() const {
69     return getLayer()->getInputPorts();
70 }
71
72 Builder::EltwiseLayer& Builder::EltwiseLayer::setInputPorts(const std::vector<Port>& ports) {
73     getLayer()->getInputPorts() = ports;
74     return *this;
75 }
76
77 const Port& Builder::EltwiseLayer::getOutputPort() const {
78     return getLayer()->getOutputPorts()[0];
79 }
80
81 Builder::EltwiseLayer& Builder::EltwiseLayer::setOutputPort(const Port &port) {
82     getLayer()->getOutputPorts()[0] = port;
83     return *this;
84 }
85
86 const std::vector<float> Builder::EltwiseLayer::getScales() const {
87     return getLayer()->getParameters().at("scales");
88 }
89
90 // TODO: IR doesn't contain Scales!!!
91 Builder::EltwiseLayer& Builder::EltwiseLayer::setScales(const std::vector<float>& scales) {
92     getLayer()->getParameters()["scales"] = scales;
93     return *this;
94 }
95
96 Builder::EltwiseLayer::EltwiseType Builder::EltwiseLayer::getEltwiseType() const {
97     return type;
98 }
99
100 Builder::EltwiseLayer& Builder::EltwiseLayer::setEltwiseType(Builder::EltwiseLayer::EltwiseType type) {
101     this->type = type;
102     std::string operatorStr;
103     switch (type) {
104         case MAX:
105             operatorStr = "max";
106             break;
107         case SUM:
108             operatorStr = "sum";
109             break;
110         case MUL:
111             operatorStr = "mul";
112             break;
113         case SUB:
114             operatorStr = "sub";
115             break;
116         case DIV:
117             operatorStr = "div";
118             break;
119         case MIN:
120             operatorStr = "min";
121             break;
122         case SQUARED_DIFF:
123             operatorStr = "squared_diff";
124             break;
125     }
126     getLayer()->getParameters()["operation"] = operatorStr;
127     return *this;
128 }
129
130 REG_VALIDATOR_FOR(Eltwise, [](const InferenceEngine::Builder::Layer::CPtr& input_layer, bool partial) {
131     Builder::EltwiseLayer layer(input_layer);
132
133     if (layer.getInputPorts().size() != 2) {
134         THROW_IE_EXCEPTION << "Input ports are incorrect in the layer " << layer.getName()
135                            << ". Number of input ports should be equal to 2.";
136     }
137     if (partial && (layer.getInputPorts()[0].shape().empty() || layer.getInputPorts()[1].shape().empty() ||
138             layer.getOutputPort().shape().empty()))
139         return;
140
141     if (layer.getInputPorts()[0].shape() != layer.getInputPorts()[1].shape()) {
142         THROW_IE_EXCEPTION << "Input ports are incorrect in the layer " << layer.getName()
143                            << ". They should have equal dimensions";
144     }
145
146     if (layer.getInputPorts()[0].shape() != layer.getOutputPort().shape()) {
147         THROW_IE_EXCEPTION << "Layer " << layer.getName() << " have different input and output ports. "
148                            << "They should have equal dimensions.";
149     }
150 });
151
152 REG_CONVERTER_FOR(Eltwise, [](const CNNLayerPtr& cnnLayer, Builder::Layer& layer) {
153     layer.getParameters()["scales"] = cnnLayer->GetParamAsFloats("scales", {});
154     layer.getParameters()["operation"] = cnnLayer->GetParamAsString("operation");
155 });
156
157