updated readme file due to moving CMake scripts to the root folder
[platform/upstream/dldt.git] / inference-engine / thirdparty / clDNN / src / include / kernel_selector_helper.h
1 // Copyright (c) 2016-2018 Intel Corporation
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //      http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #pragma once
16
17 #include "api/cldnn.hpp"
18 #include "api/tensor.hpp"
19 #include "api/eltwise.hpp"
20 #include "api/scale.hpp"
21 #include "api/quantize.hpp"
22 #include "api/activation.hpp"
23
24 #include "kernel_selector_params.h"
25 #include "kernel_selector_common.h"
26 #include "tensor_type.h"
27
28 #include <cstdint>
29 #include <string>
30 #include <vector>
31 #include <memory>
32
33 using namespace cldnn;
34
35 namespace cldnn {
36 enum class data_types : size_t;
37 enum class tuning_mode;
38 struct format;
39 struct layout;
40 struct program_impl;
41 struct program_node;
42 }  // namespace cldnn
43
44 namespace kernel_selector {
45 using n_dims = kernel_selector::Tensor::NDims;
46 using kernel_data = kernel_selector::KernelData;
47 using kernel_string = kernel_selector::KernelString;
48 using cl_kernel_data = kernel_selector::clKernelData;
49 using kernel_arguments = kernel_selector::Arguments;
50 using kernel_argument_element = kernel_selector::ArgumentDescriptor;
51 using kernel_argument_types = kernel_selector::ArgumentDescriptor::Types;
52 using kernel_scalar_arguments = kernel_selector::Scalars;
53 using kernel_scalar_argument_types = kernel_selector::ScalarDescriptor::Types;
54
55 using data_type = kernel_selector::Datatype;
56 using kernel_type = kernel_selector::KernelType;
57 using weights_type = kernel_selector::WeightsType;
58 using activation_function = kernel_selector::ActivationFunction;
59 using pool_type = kernel_selector::PoolType;
60 using pool_remainder = kernel_selector::PoolRemainder;
61 using argm_axis = kernel_selector::ArgMaxMinAxis;
62 using argm_output = kernel_selector::ArgMaxMinOut;
63 using argm_sort = kernel_selector::ArgMaxMinSortType;
64 using lookt_axis = kernel_selector::LookUpTableAxis;
65 using lrn_mode = kernel_selector::LRNMode;
66 using normalize_mode = kernel_selector::NormalizeMode;
67 using mvn_mode = kernel_selector::MVNMode;
68 using kernel_divider_mode = kernel_selector::KernelDividerMode;
69 using eltwise_mode = kernel_selector::EltwiseMode;
70 using eltwise_input_mode = kernel_selector::EltwiseInputMode;
71 using softmax_dim = kernel_selector::SoftmaxDim;
72 using mean_subtruct_mode = kernel_selector::MeanSubtractMode;
73 using mean_op = kernel_selector::MeanOp;
74 using concat_axis = kernel_selector::ConcatAxis;
75 using tile_axis = kernel_selector::TileAxis;
76 using tuning_mode = kernel_selector::TuningMode;
77 using sample_type = kernel_selector::SampleType;
78 using border_type = kernel_selector::BorderType;
79 using gather_axis = kernel_selector::GatherAxis;
80 using reduce_mode = kernel_selector::ReduceMode;
81
82 using data_tensor = kernel_selector::DataTensor;
83 using weights_tensor = kernel_selector::WeightsTensor;
84 template <typename T>
85 using dim_tensor = kernel_selector::DimTensor<T>;
86 using data_layout = kernel_selector::DataLayout;
87 using weights_layout = kernel_selector::WeightsLayout;
88 using multi_data_tensor = kernel_selector::MultiDataTensor;
89
90 using params = kernel_selector::Params;
91 using weights_reorder_params = kernel_selector::WeightsReorderParams;
92 using generic_kernel_params = kernel_selector::GenericKernelParams;
93
94 struct training_params;
95 }  // namespace kernel_selector
96
97 kernel_selector::data_type to_data_type(data_types dt);
98 data_types from_data_type(kernel_selector::data_type dt);
99 kernel_selector::weights_type to_weights_type(data_types dt);
100 data_types from_weights_type(kernel_selector::weights_type dt);
101 kernel_selector::data_layout to_data_layout(format f);
102 cldnn::format from_data_layout(kernel_selector::data_layout l);
103 kernel_selector::weights_layout to_weights_layout(format f);
104 cldnn::format::type from_weights_layout(kernel_selector::weights_layout l);
105 kernel_selector::tuning_mode to_tuning_mode(cldnn::tuning_mode mode);
106 std::string to_host_version(const cldnn::version_t& version);
107 kernel_selector::data_tensor convert_data_tensor(const layout& l, uint32_t split = 1, const tensor view_offset = tensor {});
108 kernel_selector::weights_tensor convert_weights_tensor(const layout& l);
109 layout from_weights_tensor(const kernel_selector::weights_tensor& t);
110 kernel_selector::activation_function get_kernel_selector_activation_param(activation_func activation_func);
111 kernel_selector::activation_function get_kernel_selector_activation_grad_param(
112     activation_grad_func activation_grad_func);
113
114 template <typename T = std::uint32_t>
115 kernel_selector::dim_tensor<T> convert_dim_vector(const tensor& t) {
116     const auto& sizes = t.sizes(format::bfwzyx);
117     return {static_cast<T>(sizes[0]),
118             static_cast<T>(sizes[1]),
119             static_cast<T>(sizes[2]),
120             static_cast<T>(sizes[3]),
121             static_cast<T>(sizes[4]),
122             static_cast<T>(sizes[5])};
123 }
124
125 template <typename p_type>
126 inline void convert_activation_func_params(const p_type primitive, std::vector<kernel_selector::base_activation_params>& params) {
127     const float negative_slope = primitive->activation_negative_slope;
128     if (negative_slope != 0.0f) {
129         params.emplace_back(kernel_selector::activation_function::RELU_NEGATIVE_SLOPE, negative_slope, 0.0f);
130     } else {
131         params.emplace_back(kernel_selector::activation_function::RELU, 0.0f, 0.0f);
132     }
133 }
134
135 template <typename arg_t>
136 inline void convert_fused_activation_func_params(const arg_t& arg, std::vector<kernel_selector::base_activation_params>& params) {
137     for (size_t i = 0; i < arg.get_fused_activations_funcs().size(); i++) {
138         params.emplace_back(get_kernel_selector_activation_param(arg.get_fused_activations_funcs()[i]),
139                             arg.get_fused_activations_params()[i].a,
140                             arg.get_fused_activations_params()[i].b);
141     }
142 }
143
144 template <typename p_type>
145 inline void convert_new_activation_func(const p_type primitive, std::vector<kernel_selector::base_activation_params>& params) {
146     params.insert(params.begin(), {get_kernel_selector_activation_param(primitive->activation_function),
147                                    primitive->additional_params.a,
148                                    primitive->additional_params.b});
149 }
150
151 template <typename p_type>
152 inline void convert_new_activation_grad_func(const p_type primitive, std::vector<kernel_selector::base_activation_params>& params) {
153     params.insert(params.begin(), {get_kernel_selector_activation_grad_param(primitive->activation_grad_function),
154                                    primitive->additional_params.a,
155                                    primitive->additional_params.b,
156                                    true});
157 }
158
159 void set_params(const program_node& node, kernel_selector::params& params);
160
161 template <typename params_t, typename arg_t>
162 inline params_t get_default_params(const arg_t& arg, uint32_t split = 1) {
163     params_t params;
164
165     set_params(arg, params);
166
167     const auto& input_layout = arg.input().get_output_layout();
168     const auto& output_layout = arg.get_output_layout();
169
170     params.inputs[0] = convert_data_tensor(input_layout, split);
171     params.output = convert_data_tensor(output_layout, split);
172
173     params.layerID = arg.id();
174
175     convert_fused_activation_func_params(arg, params.activations);
176     size_t op_id = 0;
177     for (auto& fused_prim : arg.get_fused_primitives()) {
178         using op_type = kernel_selector::base_params::fused_operation_desc::Type;
179         kernel_selector::base_params::fused_operation_desc desc;
180         if (fused_prim.prim->type == eltwise::type_id()) {
181             desc.type = op_type::ELTWISE;
182         } else if (fused_prim.prim->type == scale::type_id()) {
183             desc.type = op_type::SCALE;
184         } else if (fused_prim.prim->type == quantize::type_id()) {
185             desc.type = op_type::QUANTIZE;
186         } else if (fused_prim.prim->type == activation::type_id()) {
187             desc.type = op_type::ACTIVATION;
188             std::shared_ptr<const primitive> p = fused_prim.prim;
189             auto activation_prim = std::static_pointer_cast<const activation>(p);
190             desc.activation.m = activation_prim->additional_params.a;
191             desc.activation.n = activation_prim->additional_params.b;
192             desc.activation.function = get_kernel_selector_activation_param(activation_prim->activation_function);
193         } else {
194             throw std::runtime_error("Invalid fused primitive type in " + arg.id() + " node");
195         }
196
197         desc.dep_idx_start = fused_prim.dep_start_idx;
198         desc.dep_size = fused_prim.deps.size();
199         desc.op_id = op_id++;
200         desc.output_tensor = convert_data_tensor(fused_prim.output_layout);
201
202         for (size_t i = desc.dep_idx_start; i < desc.dep_idx_start + desc.dep_size; i++) {
203             desc.tensors.push_back(convert_data_tensor(arg.get_dependency(i).get_output_layout()));
204         }
205
206         if (fused_prim.activation != activation_func::none) {
207             desc.activation.m = fused_prim.activation_params.a;
208             desc.activation.n = fused_prim.activation_params.b;
209             desc.activation.function = get_kernel_selector_activation_param(fused_prim.activation);
210         }
211         params.fused_ops.push_back(desc);
212     }
213
214     return params;
215 }
216
217 template <typename params_t, typename arg_t>
218 inline params_t get_weights_bias_default_params(const arg_t& arg, uint32_t split = 1, uint32_t groups = 1) {
219     params_t params = get_default_params<params_t>(arg, split);
220     const auto& weights_layout = arg.weights().get_output_layout();
221     if (groups == 1) {
222         params.weights = convert_weights_tensor(weights_layout);
223     } else {
224         params.weights = convert_weights_tensor(layout(weights_layout.data_type,
225                                                        weights_layout.format,
226                                                        {weights_layout.size.batch[0] / static_cast<int>(groups),
227                                                         weights_layout.size.feature[0],
228                                                         weights_layout.size.spatial[0],
229                                                         weights_layout.size.spatial[1]}));
230     }
231
232     if (arg.bias_term()) {
233         const auto& bias_layout = arg.bias().get_output_layout();
234         // bias per output is not supported on cldnn
235         if (groups == 1) {
236             params.bias.push_back(convert_data_tensor(bias_layout).FlattenFeatureAndSpatials());
237         } else {
238             params.bias.push_back(convert_data_tensor(layout(bias_layout.data_type,
239                                                              bias_layout.format,
240                                                              {bias_layout.size.batch[0],
241                                                               bias_layout.size.feature[0] / static_cast<int>(groups),
242                                                               bias_layout.size.spatial[0],
243                                                               bias_layout.size.spatial[1]}))
244                                       .FlattenFeatureAndSpatials());
245         }
246     }
247
248     return params;
249 }
250
251 void set_learning_params(const program_node& node, kernel_selector::training_params& params, bool use_momentum);
252
253 template <typename params_t, typename arg_t>
254 inline params_t get_default_learning_params(const arg_t& arg, uint32_t split = 1) {
255     params_t params = get_weights_bias_default_params<params_t>(arg, split);
256     set_learning_params(arg, params, arg.use_momentum());
257     return params;
258 }
259
260 void set_optional_params(const program_impl& program, kernel_selector::optional_params& params);
261
262 template <typename optional_params_t>
263 inline optional_params_t get_default_optional_params(const program_impl& program) {
264     optional_params_t params;
265     set_optional_params(program, params);
266     return params;
267 }
268
269 template <typename optional_params_t>
270 inline optional_params_t get_default_weights_bias_optional_params(const program_impl& program) {
271     return get_default_optional_params<optional_params_t>(program);
272 }
273
274 template <typename optional_params_t>
275 inline optional_params_t get_default_learning_optional_params(const program_impl& program) {
276     return get_default_weights_bias_optional_params<optional_params_t>(program);
277 }