2 // Copyright (c) 2016-2019 Intel Corporation
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
8 // http://www.apache.org/licenses/LICENSE-2.0
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.
17 ///////////////////////////////////////////////////////////////////////////////////////////////////
19 #include "../C/eltwise.h"
20 #include "primitive.hpp"
24 /// @addtogroup cpp_api C++ API
26 /// @addtogroup cpp_topology Network Topology
28 /// @addtogroup cpp_primitives Primitives
31 /// @brief Select mode for the @ref eltwise layer.
32 enum class eltwise_mode : int32_t
34 /// @brief Eltwise sum.
35 sum = cldnn_eltwise_sum,
36 /// @brief Eltwise subtract.
37 sub = cldnn_eltwise_sub,
38 /// @brief Eltwise max.
39 max = cldnn_eltwise_max,
40 /// @brief Eltwise product (Hadamard).
41 prod = cldnn_eltwise_prod,
42 /// @brief Eltwise div.
43 div = cldnn_eltwise_div,
44 /// @brief Eltwise min.
45 min = cldnn_eltwise_min,
46 /// @brief Eltwise pow.
47 pow = cldnn_eltwise_pow,
48 /// @brief Eltwise squared diff.
49 squared_diff = cldnn_eltwise_squared_diff,
50 /// @brief Eltwise mod.
51 mod = cldnn_eltwise_mod,
52 /// @brief Eltwise equal.
53 eq = cldnn_eltwise_eq,
54 /// @brief Eltwise not equal.
55 ne = cldnn_eltwise_ne,
56 /// @brief Eltwise less.
57 lt = cldnn_eltwise_lt,
58 /// @brief Eltwise less of equal.
59 le = cldnn_eltwise_le,
60 /// @brief Eltwise greater.
61 gt = cldnn_eltwise_gt,
62 /// @brief Eltwise greater or equal.
63 ge = cldnn_eltwise_ge,
64 /// @brief Eltwise and.
65 logic_and = cldnn_eltwise_and,
66 /// @brief Eltwise or.
67 logic_or = cldnn_eltwise_or,
68 /// @brief Eltwise XOR.
69 logic_xor = cldnn_eltwise_xor
72 /// @brief Performs elementwise operations (sum, subtract, max or product) on two input primitives
73 /// Also supports built-in Relu @ref activation available by setting it in arguments.
75 /// - both inputs have to have equal sizes in all dimensions or the input tensors are broadcastable
76 /// to the same shape in which the size of each dimention is a max. of input sizes on this dimension)
77 /// - format of both inputs has to be the same
78 /// - when using integer types, only following eltwise modes are supported: sum, sub, prod, div
79 struct eltwise : public primitive_base<eltwise, CLDNN_PRIMITIVE_DESC(eltwise)>
81 CLDNN_DECLARE_PRIMITIVE(eltwise)
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.
91 const primitive_id& id,
92 const primitive_id& input,
93 const primitive_id& input2,
95 bool with_activation = false,
96 float activation_slp = 0.0f,
97 const padding& output_padding = padding()
99 :primitive_base(id, { input, input2 }, output_padding)
100 , output_calibration_factors("")
101 , output_quantization_factor(1.0f)
103 , coefficients(std::vector<float>(0))
104 , with_activation(with_activation)
105 , activation_negative_slope(activation_slp)
106 , stride(std::vector<tensor>(0))
107 , _stride(tensor_vector_to_cldnn_vector(stride))
111 /// @brief Constructs eltwise primitive.
112 /// @param id This primitive id.
113 /// @param input Input primitive id.
114 /// @param input2 Second input primitive id with values needed for eltwise computation.
115 /// @param stride Defines shift in input buffers between adjacent calculations of output values.
116 /// @param mode Eltwise mode.
117 /// @param with_activation Enables Relu activation.
118 /// @param activation_slp Relu activation slope.
120 const primitive_id& id,
121 const primitive_id& input,
122 const primitive_id& input2,
123 std::vector<tensor> stride,
125 bool with_activation = false,
126 float activation_slp = 0.0f,
127 const padding& output_padding = padding()
129 :primitive_base(id, { input, input2 }, output_padding)
130 , output_calibration_factors("")
131 , output_quantization_factor(1.0f)
133 , coefficients(std::vector<float>(0))
134 , with_activation(with_activation)
135 , activation_negative_slope(activation_slp)
137 , _stride(tensor_vector_to_cldnn_vector(stride))
141 /// @brief Constructs eltwise primitive.
142 /// @param id This primitive id.
143 /// @param inputs Input primitives ids.
144 /// @param mode Eltwise mode.
145 /// @param with_activation Enables Relu activation.
146 /// @param activation_slp Relu activation slope.
148 const primitive_id& id,
149 const std::vector<primitive_id>& inputs,
151 bool with_activation = false,
152 float activation_slp = 0.0f,
153 const padding& output_padding = padding()
155 :primitive_base(id, inputs, output_padding)
156 , output_calibration_factors("")
157 , output_quantization_factor(1.0f)
159 , coefficients(std::vector<float>(0))
160 , with_activation(with_activation)
161 , activation_negative_slope(activation_slp)
162 , stride(std::vector<tensor>(0))
163 , _stride(tensor_vector_to_cldnn_vector(stride))
167 /// @brief Constructs eltwise primitive.
168 /// @param id This primitive id.
169 /// @param input Input primitive id.
170 /// @param input2 Second input primitive id with values needed for eltwise computation.
171 /// @param output_calibration_factors Primitive id containing output calibration factors per output feature map.
172 /// @param mode Eltwise mode.
173 /// @param with_activation Enables Relu activation.
174 /// @param activation_slp Relu activation slope.
176 const primitive_id& id,
177 const primitive_id& input,
178 const primitive_id& input2,
179 const primitive_id& output_calibration_factors,
181 bool with_activation = false,
182 float activation_slp = 0.0f,
183 const padding& output_padding = padding()
185 :primitive_base(id, { input, input2 }, output_padding)
186 , output_calibration_factors(output_calibration_factors)
187 , output_quantization_factor(1.0f)
189 , coefficients(std::vector<float>(0))
190 , with_activation(with_activation)
191 , activation_negative_slope(activation_slp)
192 , stride(std::vector<tensor>(0))
193 , _stride(tensor_vector_to_cldnn_vector(stride))
197 /// @brief Constructs eltwise primitive.
198 /// @param id This primitive id.
199 /// @param inputs Input primitives ids.
200 /// @param output_calibration_factors Primitive id containing output calibration factors per output feature map.
201 /// @param mode Eltwise mode.
202 /// @param with_activation Enables Relu activation.
203 /// @param activation_slp Relu activation slope.
205 const primitive_id& id,
206 const std::vector<primitive_id>& inputs,
207 const primitive_id& output_calibration_factors,
209 bool with_activation = false,
210 float activation_slp = 0.0f,
211 const padding& output_padding = padding()
213 :primitive_base(id, inputs, output_padding)
214 , output_calibration_factors(output_calibration_factors)
215 , output_quantization_factor(1.0f)
217 , coefficients(std::vector<float>(0))
218 , with_activation(with_activation)
219 , activation_negative_slope(activation_slp)
220 , stride(std::vector<tensor>(0))
221 , _stride(tensor_vector_to_cldnn_vector(stride))
225 /// @brief Constructs eltwise primitive.
226 /// @param id This primitive id.
227 /// @param input Input primitive id.
228 /// @param input2 Second input primitive id with values needed for eltwise computation.
229 /// @param o_quantization_factor Output quantization factor
230 /// @param mode Eltwise mode.
231 /// @param with_activation Enables Relu activation.
232 /// @param activation_slp Relu activation slope.
234 const primitive_id& id,
235 const primitive_id& input,
236 const primitive_id& input2,
237 const float o_quantization_factor,
239 bool with_activation = false,
240 float activation_slp = 0.0f,
241 const padding& output_padding = padding()
243 :primitive_base(id, { input, input2 }, output_padding)
244 , output_calibration_factors("")
245 , output_quantization_factor(o_quantization_factor)
247 , coefficients(std::vector<float>(0))
248 , with_activation(with_activation)
249 , activation_negative_slope(activation_slp)
250 , stride(std::vector<tensor>(0))
251 , _stride(tensor_vector_to_cldnn_vector(stride))
255 /// @brief Constructs eltwise primitive.
256 /// @param id This primitive id.
257 /// @param inputs Input primitives ids.
258 /// @param o_quantization_factor Output quantization factor
259 /// @param mode Eltwise mode.
260 /// @param with_activation Enables Relu activation.
261 /// @param activation_slp Relu activation slope.
263 const primitive_id& id,
264 const std::vector<primitive_id>& inputs,
265 const float o_quantization_factor,
267 bool with_activation = false,
268 float activation_slp = 0.0f,
269 const padding& output_padding = padding()
271 :primitive_base(id, inputs, output_padding)
272 , output_calibration_factors("")
273 , output_quantization_factor(o_quantization_factor)
275 , coefficients(std::vector<float>(0))
276 , with_activation(with_activation)
277 , activation_negative_slope(activation_slp)
278 , stride(std::vector<tensor>(0))
279 , _stride(tensor_vector_to_cldnn_vector(stride))
283 /// @brief Constructs eltwise primitive.
284 /// @param id This primitive id.
285 /// @param inputs Input primitives ids.
286 /// @param coefficients Blob-wise coefficient for SUM operation
287 /// @param mode Eltwise mode.
288 /// @param with_activation Enables Relu activation.
289 /// @param activation_slp Relu activation slope.
291 const primitive_id& id,
292 const std::vector<primitive_id>& inputs,
294 const std::vector<float>& coefficients,
295 bool with_activation = false,
296 float activation_slp = 0.0f,
297 const padding& output_padding = padding()
299 :primitive_base(id, inputs, output_padding)
300 , output_calibration_factors("")
301 , output_quantization_factor(1.0f)
303 , coefficients(coefficients)
304 , with_activation(with_activation)
305 , activation_negative_slope(activation_slp)
306 , stride(std::vector<tensor>(0))
307 , _stride(tensor_vector_to_cldnn_vector(stride))
309 if (mode == eltwise_mode::sum && !coefficients.empty() && coefficients.size() != inputs.size())
311 throw std::invalid_argument("Invalid eltwise sum coefficients count (should be equal to 0 or input.size)");
313 if (mode != eltwise_mode::sum && !coefficients.empty())
315 throw std::invalid_argument("Only eltwise sum operation supports blob-wise coefficients");
319 /// @brief Constructs a copy from C API @CLDNN_PRIMITIVE_DESC{eltwise}
320 eltwise(const dto* dto)
322 , output_calibration_factors(dto->output_calibration_factors)
323 , output_quantization_factor(dto->output_quantization_factor)
324 , mode(static_cast<eltwise_mode>(dto->mode))
325 , coefficients(float_arr_to_vector(dto->coefficients))
326 , with_activation(dto->with_activation != 0)
327 , activation_negative_slope(dto->activation_negative_slope)
328 , stride(tensor_arr_to_vector(dto->stride))
329 , _stride(tensor_vector_to_cldnn_vector(stride))
331 if (dto->input.size < 2)
332 throw std::invalid_argument("eltiwise dto should containt at least two inputs");
333 if (dto->coefficients.size != 0 && dto->coefficients.size != dto->input.size)
334 throw std::invalid_argument("Invalid eltwise coefficients count in dto (should be equal to 0 or input.size)");
337 /// @brief Primitive id containing output quanitization factors per output feature map.
338 primitive_id output_calibration_factors;
339 /// @brief Output quantization factor
340 float output_quantization_factor;
341 /// @param mode Eltwise mode.
343 /// @param coefficients Blob-wise coefficient for SUM operation.
344 std::vector<float> coefficients;
345 /// @brief Enables Relu activation.
346 bool with_activation;
347 /// @brief Relu activation slope.
348 float activation_negative_slope;
349 /// @brief Defines shift in input buffers between adjacent calculations of output values.
350 std::vector<tensor> stride;
353 std::vector<cldnn_tensor> _stride;
354 std::vector<std::reference_wrapper<const primitive_id>> get_dependencies() const override
356 std::vector<std::reference_wrapper<const primitive_id>> ret;
357 if(!output_calibration_factors.empty())
358 ret.push_back(output_calibration_factors);
363 void update_dto(dto& dto) const override
365 dto.output_calibration_factors = output_calibration_factors.c_str();
366 dto.output_quantization_factor = output_quantization_factor;
367 dto.mode = static_cast<cldnn_eltwise_mode>(mode);
368 dto.coefficients = float_vector_to_arr(coefficients);
369 dto.with_activation = with_activation;
370 dto.activation_negative_slope = activation_negative_slope;
371 dto.stride = tensor_vector_to_arr(_stride);