55e72ab60fa518f316756a3d3900ef3e40a00568
[platform/upstream/dldt.git] / inference-engine / thirdparty / clDNN / api / CPP / eltwise.hpp
1 /*
2 // Copyright (c) 2016-2019 Intel Corporation
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //      http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 */
16
17 ///////////////////////////////////////////////////////////////////////////////////////////////////
18 #pragma once
19 #include "../C/eltwise.h"
20 #include "primitive.hpp"
21 #include <vector>
22
23 namespace cldnn {
24 /// @addtogroup cpp_api C++ API
25 /// @{
26 /// @addtogroup cpp_topology Network Topology
27 /// @{
28 /// @addtogroup cpp_primitives Primitives
29 /// @{
30
31 /// @brief Select mode for the @ref eltwise layer.
32 enum class eltwise_mode : int32_t {
33     /// @brief Eltwise sum.
34     sum = cldnn_eltwise_sum,
35     /// @brief Eltwise subtract.
36     sub = cldnn_eltwise_sub,
37     /// @brief Eltwise max.
38     max = cldnn_eltwise_max,
39     /// @brief Eltwise product (Hadamard).
40     prod = cldnn_eltwise_prod,
41     /// @brief Eltwise div.
42     div = cldnn_eltwise_div,
43     /// @brief Eltwise min.
44     min = cldnn_eltwise_min,
45     /// @brief Eltwise pow.
46     pow = cldnn_eltwise_pow,
47     /// @brief Eltwise squared diff.
48     squared_diff = cldnn_eltwise_squared_diff,
49     /// @brief Eltwise mod.
50     mod = cldnn_eltwise_mod,
51     /// @brief Eltwise equal.
52     eq = cldnn_eltwise_eq,
53     /// @brief Eltwise not equal.
54     ne = cldnn_eltwise_ne,
55     /// @brief Eltwise less.
56     lt = cldnn_eltwise_lt,
57     /// @brief Eltwise less of equal.
58     le = cldnn_eltwise_le,
59     /// @brief Eltwise greater.
60     gt = cldnn_eltwise_gt,
61     /// @brief Eltwise greater or equal.
62     ge = cldnn_eltwise_ge,
63     /// @brief Eltwise and.
64     logic_and = cldnn_eltwise_and,
65     /// @brief Eltwise or.
66     logic_or = cldnn_eltwise_or,
67     /// @brief Eltwise XOR.
68     logic_xor = cldnn_eltwise_xor,
69     /// @brief Eltwise floormod.
70     floor_mod = cldnn_eltwise_floor_mod
71 };
72
73 /// @brief Performs elementwise operations (sum, subtract, max or product) on two input primitives
74 /// Also supports built-in Relu @ref activation available by setting it in arguments.
75 /// @notes
76 /// - both inputs have to have equal sizes in all dimensions or the input tensors are broadcastable
77 ///   to the same shape in which the size of each dimention is a max. of input sizes on this dimension)
78 /// - format of both inputs has to be the same
79 /// - when using integer types, only following eltwise modes are supported: sum, sub, prod, div
80 struct eltwise : public primitive_base<eltwise, CLDNN_PRIMITIVE_DESC(eltwise)> {
81     CLDNN_DECLARE_PRIMITIVE(eltwise)
82
83     /// @brief Constructs eltwise primitive.
84     /// @param id This primitive id.
85     /// @param input Input primitive id.
86     /// @param input2 Second input primitive id with values needed for eltwise computation.
87     /// @param mode Eltwise mode.
88     /// @param with_activation Enables Relu activation.
89     /// @param activation_slp Relu activation slope.
90     eltwise(const primitive_id& id,
91             const primitive_id& input,
92             const primitive_id& input2,
93             eltwise_mode mode,
94             bool with_activation = false,
95             float activation_slp = 0.0f,
96             const padding& output_padding = padding())
97         : primitive_base(id, {input, input2}, output_padding),
98           output_calibration_factors(""),
99           output_quantization_factor(1.0f),
100           inputs_calibration_factors(_inputs_calibration_factors.cpp_ids),
101           input_quantization_factors(0),
102           mode(mode),
103           coefficients(std::vector<float>(0)),
104           with_activation(with_activation),
105           activation_negative_slope(activation_slp),
106           stride(std::vector<tensor>(0)),
107           _inputs_calibration_factors(std::vector<primitive_id>(0)),
108           _stride(tensor_vector_to_cldnn_vector(stride)) {}
109
110     /// @brief Constructs eltwise primitive.
111     /// @param id This primitive id.
112     /// @param input Input primitive id.
113     /// @param input2 Second input primitive id with values needed for eltwise computation.
114     /// @param stride Defines shift in input buffers between adjacent calculations of output values.
115     /// @param mode Eltwise mode.
116     /// @param with_activation Enables Relu activation.
117     /// @param activation_slp Relu activation slope.
118     eltwise(const primitive_id& id,
119             const primitive_id& input,
120             const primitive_id& input2,
121             std::vector<tensor> stride,
122             eltwise_mode mode,
123             bool with_activation = false,
124             float activation_slp = 0.0f,
125             const padding& output_padding = padding())
126         : primitive_base(id, {input, input2}, output_padding),
127           output_calibration_factors(""),
128           output_quantization_factor(1.0f),
129           inputs_calibration_factors(_inputs_calibration_factors.cpp_ids),
130           input_quantization_factors(0),
131           mode(mode),
132           coefficients(std::vector<float>(0)),
133           with_activation(with_activation),
134           activation_negative_slope(activation_slp),
135           stride(stride),
136           _inputs_calibration_factors(std::vector<primitive_id>(0)),
137           _stride(tensor_vector_to_cldnn_vector(stride)) {}
138
139     /// @brief Constructs eltwise primitive.
140     /// @param id This primitive id.
141     /// @param inputs Input primitives ids.
142     /// @param mode Eltwise mode.
143     /// @param with_activation Enables Relu activation.
144     /// @param activation_slp Relu activation slope.
145     eltwise(const primitive_id& id,
146             const std::vector<primitive_id>& inputs,
147             eltwise_mode mode,
148             bool with_activation = false,
149             float activation_slp = 0.0f,
150             const padding& output_padding = padding())
151         : primitive_base(id, inputs, output_padding),
152           output_calibration_factors(""),
153           output_quantization_factor(1.0f),
154           inputs_calibration_factors(_inputs_calibration_factors.cpp_ids),
155           input_quantization_factors(0),
156           mode(mode),
157           coefficients(std::vector<float>(0)),
158           with_activation(with_activation),
159           activation_negative_slope(activation_slp),
160           stride(std::vector<tensor>(0)),
161           _inputs_calibration_factors(std::vector<primitive_id>(0)),
162           _stride(tensor_vector_to_cldnn_vector(stride)) {}
163
164     /// @brief Constructs eltwise primitive.
165     /// @param id This primitive id.
166     /// @param input Input primitive id.
167     /// @param input2 Second input primitive id with values needed for eltwise computation.
168     /// @param output_calibration_factors Primitive id containing output calibration factors per output feature map.
169     /// @param mode Eltwise mode.
170     /// @param with_activation Enables Relu activation.
171     /// @param activation_slp Relu activation slope.
172     eltwise(const primitive_id& id,
173             const primitive_id& input,
174             const primitive_id& input2,
175             const primitive_id& output_calibration_factors,
176             eltwise_mode mode,
177             bool with_activation = false,
178             float activation_slp = 0.0f,
179             const padding& output_padding = padding())
180         : primitive_base(id, {input, input2}, output_padding),
181           output_calibration_factors(output_calibration_factors),
182           output_quantization_factor(1.0f),
183           inputs_calibration_factors(_inputs_calibration_factors.cpp_ids),
184           input_quantization_factors(0),
185           mode(mode),
186           coefficients(std::vector<float>(0)),
187           with_activation(with_activation),
188           activation_negative_slope(activation_slp),
189           stride(std::vector<tensor>(0)),
190           _inputs_calibration_factors(std::vector<primitive_id>(0)),
191           _stride(tensor_vector_to_cldnn_vector(stride)) {}
192
193     /// @brief Constructs eltwise primitive.
194     /// @param id This primitive id.
195     /// @param inputs Input primitives ids.
196     /// @param output_calibration_factors Primitive id containing output calibration factors per output feature map.
197     /// @param mode Eltwise mode.
198     /// @param with_activation Enables Relu activation.
199     /// @param activation_slp Relu activation slope.
200     eltwise(const primitive_id& id,
201             const std::vector<primitive_id>& inputs,
202             const primitive_id& output_calibration_factors,
203             eltwise_mode mode,
204             bool with_activation = false,
205             float activation_slp = 0.0f,
206             const padding& output_padding = padding())
207         : primitive_base(id, inputs, output_padding),
208           output_calibration_factors(output_calibration_factors),
209           output_quantization_factor(1.0f),
210           inputs_calibration_factors(_inputs_calibration_factors.cpp_ids),
211           input_quantization_factors(0),
212           mode(mode),
213           coefficients(std::vector<float>(0)),
214           with_activation(with_activation),
215           activation_negative_slope(activation_slp),
216           stride(std::vector<tensor>(0)),
217           _inputs_calibration_factors(std::vector<primitive_id>(0)),
218           _stride(tensor_vector_to_cldnn_vector(stride)) {}
219
220     /// @brief Constructs eltwise primitive.
221     /// @param id This primitive id.
222     /// @param input Input primitive id.
223     /// @param input2 Second input primitive id with values needed for eltwise computation.
224     /// @param o_quantization_factor Output quantization factor
225     /// @param mode Eltwise mode.
226     /// @param with_activation Enables Relu activation.
227     /// @param activation_slp Relu activation slope.
228     eltwise(const primitive_id& id,
229             const primitive_id& input,
230             const primitive_id& input2,
231             const float o_quantization_factor,
232             eltwise_mode mode,
233             bool with_activation = false,
234             float activation_slp = 0.0f,
235             const padding& output_padding = padding())
236         : primitive_base(id, {input, input2}, output_padding),
237           output_calibration_factors(""),
238           output_quantization_factor(o_quantization_factor),
239           inputs_calibration_factors(_inputs_calibration_factors.cpp_ids),
240           input_quantization_factors(0),
241           mode(mode),
242           coefficients(std::vector<float>(0)),
243           with_activation(with_activation),
244           activation_negative_slope(activation_slp),
245           stride(std::vector<tensor>(0)),
246           _inputs_calibration_factors(std::vector<primitive_id>(0)),
247           _stride(tensor_vector_to_cldnn_vector(stride)) {}
248
249     /// @brief Constructs eltwise primitive.
250     /// @param id This primitive id.
251     /// @param inputs Input primitives ids.
252     /// @param o_quantization_factor Output quantization factor
253     /// @param mode Eltwise mode.
254     /// @param with_activation Enables Relu activation.
255     /// @param activation_slp Relu activation slope.
256     eltwise(const primitive_id& id,
257             const std::vector<primitive_id>& inputs,
258             const float o_quantization_factor,
259             eltwise_mode mode,
260             bool with_activation = false,
261             float activation_slp = 0.0f,
262             const padding& output_padding = padding())
263         : primitive_base(id, inputs, output_padding),
264           output_calibration_factors(""),
265           output_quantization_factor(o_quantization_factor),
266           inputs_calibration_factors(_inputs_calibration_factors.cpp_ids),
267           input_quantization_factors(0),
268           mode(mode),
269           coefficients(std::vector<float>(0)),
270           with_activation(with_activation),
271           activation_negative_slope(activation_slp),
272           stride(std::vector<tensor>(0)),
273           _inputs_calibration_factors(std::vector<primitive_id>(0)),
274           _stride(tensor_vector_to_cldnn_vector(stride)) {}
275
276     /// @brief Constructs eltwise primitive.
277     /// @param id This primitive id.
278     /// @param inputs Input primitives ids.
279     /// @param coefficients Blob-wise coefficient for SUM operation
280     /// @param mode Eltwise mode.
281     /// @param with_activation Enables Relu activation.
282     /// @param activation_slp Relu activation slope.
283     eltwise(const primitive_id& id,
284             const std::vector<primitive_id>& inputs,
285             eltwise_mode mode,
286             const std::vector<float>& coefficients,
287             bool with_activation = false,
288             float activation_slp = 0.0f,
289             const padding& output_padding = padding())
290         : primitive_base(id, inputs, output_padding),
291           output_calibration_factors(""),
292           output_quantization_factor(1.0f),
293           inputs_calibration_factors(_inputs_calibration_factors.cpp_ids),
294           input_quantization_factors(0),
295           mode(mode),
296           coefficients(coefficients),
297           with_activation(with_activation),
298           activation_negative_slope(activation_slp),
299           stride(std::vector<tensor>(0)),
300           _inputs_calibration_factors(std::vector<primitive_id>(0)),
301           _stride(tensor_vector_to_cldnn_vector(stride)) {
302         if (mode == eltwise_mode::sum && !coefficients.empty() && coefficients.size() != inputs.size()) {
303             throw std::invalid_argument("Invalid eltwise sum coefficients count (should be equal to 0 or input.size)");
304         }
305         if (mode != eltwise_mode::sum && !coefficients.empty()) {
306             throw std::invalid_argument("Only eltwise sum operation supports blob-wise coefficients");
307         }
308     }
309
310     /// @brief Constructs a copy from C API @CLDNN_PRIMITIVE_DESC{eltwise}
311     eltwise(const dto* dto)
312         : primitive_base(dto),
313           output_calibration_factors(dto->output_calibration_factors),
314           output_quantization_factor(dto->output_quantization_factor),
315           inputs_calibration_factors(_inputs_calibration_factors.cpp_ids),
316           input_quantization_factors(float_arr_to_vector(dto->input_quantization_factors)),
317           mode(static_cast<eltwise_mode>(dto->mode)),
318           coefficients(float_arr_to_vector(dto->coefficients)),
319           with_activation(dto->with_activation != 0),
320           activation_negative_slope(dto->activation_negative_slope),
321           stride(tensor_arr_to_vector(dto->stride)),
322           _inputs_calibration_factors(dto->input_calibration_factors),
323           _stride(tensor_vector_to_cldnn_vector(stride)) {
324         if (dto->input.size < 2)
325             throw std::invalid_argument("eltiwise dto should containt at least two inputs");
326         if (dto->coefficients.size != 0 && dto->coefficients.size != dto->input.size)
327             throw std::invalid_argument(
328                 "Invalid eltwise coefficients count in dto (should be equal to 0 or input.size)");
329     }
330
331     /// @brief Primitive id containing output quanitization factors per output feature map.
332     primitive_id output_calibration_factors;
333     /// @brief Output quantization factor
334     float output_quantization_factor;
335     /// @brief List of primitive ids containing input quantization factors per feature map, one primitive id for each input.
336     fixed_size_vector_ref inputs_calibration_factors;
337     /// @brief List of quantization factors per input.
338     std::vector<float> input_quantization_factors;
339     /// @param mode Eltwise mode.
340     eltwise_mode mode;
341     /// @param coefficients Blob-wise coefficient for SUM operation.
342     std::vector<float> coefficients;
343     /// @brief Enables Relu activation.
344     bool with_activation;
345     /// @brief Relu activation slope.
346     float activation_negative_slope;
347     /// @brief Defines shift in input buffers between adjacent calculations of output values.
348     std::vector<tensor> stride;
349
350 protected:
351     primitive_id_arr _inputs_calibration_factors;
352     std::vector<cldnn_tensor> _stride;
353     std::vector<std::reference_wrapper<const primitive_id>> get_dependencies() const override {
354         std::vector<std::reference_wrapper<const primitive_id>> ret;
355         if (!output_calibration_factors.empty())
356             ret.push_back(output_calibration_factors);
357
358         for (auto& icf : inputs_calibration_factors) ret.push_back(icf);
359
360         return ret;
361     }
362
363     void update_dto(dto& dto) const override {
364         dto.output_calibration_factors = output_calibration_factors.c_str();
365         dto.output_quantization_factor = output_quantization_factor;
366         dto.input_calibration_factors = _inputs_calibration_factors.ref();
367         dto.input_quantization_factors = float_vector_to_arr(input_quantization_factors);
368         dto.mode = static_cast<cldnn_eltwise_mode>(mode);
369         dto.coefficients = float_vector_to_arr(coefficients);
370         dto.with_activation = with_activation;
371         dto.activation_negative_slope = activation_negative_slope;
372         dto.stride = tensor_vector_to_arr(_stride);
373     }
374 };
375 /// @}
376 /// @}
377 /// @}
378 }  // namespace cldnn