Publishing 2019 R1 content
[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/C/cldnn.h"
18 #include "api/CPP/tensor.hpp"
19
20 #include "kernel_selector_params.h"
21 #include "kernel_selector_common.h"
22 #include "tensor_type.h"
23
24 #include <cstdint>
25
26 using namespace cldnn;
27
28 namespace cldnn
29 {
30     enum class data_types : size_t;
31     enum class tuning_mode;
32     struct format;
33     struct layout;
34     struct program_impl;
35     struct program_node;
36 }
37
38 namespace kernel_selector
39 {
40     using n_dims                            = kernel_selector::Tensor::NDims;
41     using kernel_data                       = kernel_selector::KernelData;
42     using kernel_string                     = kernel_selector::KernelString;
43     using cl_kernel_data                    = kernel_selector::clKernelData;
44     using kernel_arguments                  = kernel_selector::Arguments;
45     using kernel_argument_element           = kernel_selector::ArgumentDescriptor;
46     using kernel_argument_types             = kernel_selector::ArgumentDescriptor::Types;
47     using kernel_scalar_arguments           = kernel_selector::Scalars;
48     using kernel_scalar_argument_types      = kernel_selector::ScalarDescriptor::Types;
49
50     using data_type                         = kernel_selector::Datatype;
51     using kernel_type                       = kernel_selector::KernelType;
52     using weights_type                      = kernel_selector::WeightsType;
53     using activation_function               = kernel_selector::ActivationFunction;
54     using pool_type                         = kernel_selector::PoolType;
55     using pool_remainder                    = kernel_selector::PoolRemainder;
56         using argm_axis                         = kernel_selector::ArgMaxMinAxis;
57         using argm_output                       = kernel_selector::ArgMaxMinOut;
58     using lookt_axis                        = kernel_selector::LookUpTableAxis;
59     using lrn_mode                          = kernel_selector::LRNMode;
60     using normalize_mode                    = kernel_selector::NormalizeMode;
61     using mvn_mode                          = kernel_selector::MVNMode;
62     using kernel_divider_mode               = kernel_selector::KernelDividerMode;
63     using eltwise_mode                      = kernel_selector::EltwiseMode;
64     using eltwise_input_mode                = kernel_selector::EltwiseInputMode;
65     using softmax_dim                       = kernel_selector::SoftmaxDim;
66     using mean_subtruct_mode                = kernel_selector::MeanSubtractMode;
67     using mean_op                           = kernel_selector::MeanOp;
68     using concat_axis                       = kernel_selector::ConcatAxis;
69     using tile_axis                         = kernel_selector::TileAxis;
70     using tuning_mode                       = kernel_selector::TuningMode;
71     using sample_type                       = kernel_selector::SampleType;
72     using border_type                       = kernel_selector::BorderType;
73     using gather_axis                       = kernel_selector::GatherAxis;
74
75     using data_tensor                       = kernel_selector::DataTensor;
76     using weights_tensor                    = kernel_selector::WeightsTensor;
77     template <typename T> using dim_tensor  = kernel_selector::DimTensor<T>;
78     using data_layout                       = kernel_selector::DataLayout;
79     using weights_layout                    = kernel_selector::WeightsLayout;
80     using multi_data_tensor                 = kernel_selector::MultiDataTensor;
81
82     using params                            = kernel_selector::Params;
83     using weights_reorder_params            = kernel_selector::WeightsReorderParams;
84     using generic_kernel_params             = kernel_selector::GenericKernelParams;
85
86     struct training_params;
87 }
88
89 kernel_selector::data_type to_data_type(data_types dt);
90 data_types from_data_type(kernel_selector::data_type dt);
91 kernel_selector::weights_type to_weights_type(data_types dt);
92 data_types from_weights_type(kernel_selector::weights_type dt);
93 kernel_selector::data_layout to_data_layout(format f);
94 cldnn::format from_data_layout(kernel_selector::data_layout l);
95 kernel_selector::weights_layout to_weights_layout(format f);
96 cldnn::format::type from_weights_layout(kernel_selector::weights_layout l);
97 kernel_selector::tuning_mode to_tuning_mode(cldnn::tuning_mode mode);
98 std::string to_host_version(const cldnn::version_t& version);
99 kernel_selector::data_tensor convert_data_tensor(const layout& l, uint32_t split = 1, const tensor view_offset = {});
100 kernel_selector::weights_tensor convert_weights_tensor(const layout& l);
101 kernel_selector::activation_function get_kernel_selector_activation_param(cldnn_activation_func activation_func);
102 kernel_selector::activation_function get_kernel_selector_activation_grad_param(cldnn_activation_grad_func activation_grad_func);
103
104 template <typename T = std::uint32_t>
105 kernel_selector::dim_tensor<T> convert_dim_vector(const tensor& t)
106 {
107     const auto& sizes = t.sizes(format::bfyx);
108     return {
109         static_cast<T>(sizes[0]),
110         static_cast<T>(sizes[1]),
111         static_cast<T>(sizes[2]),
112         static_cast<T>(sizes[3]),
113     };
114 }
115
116 template <typename p_type>
117 inline void convert_activation_func_params(const p_type primitive, kernel_selector::base_activation_params& params)
118 {
119     const float negative_slope = primitive->activation_negative_slope;
120     if (negative_slope != 0.0f)
121     {
122         params.m = negative_slope;
123         params.function = kernel_selector::activation_function::RELU_NEGATIVE_SLOPE;
124     }
125     else
126     {
127         params.function = kernel_selector::activation_function::RELU;
128     }
129 }
130
131 template <typename arg_t>
132 inline void convert_fused_activation_func_params(const arg_t& arg, kernel_selector::base_activation_params& params)
133 {
134     params.m = arg.get_fused_activation_params().a;
135     params.n = arg.get_fused_activation_params().b;
136     params.function = get_kernel_selector_activation_param(arg.get_fused_activation_func());
137 }
138
139 template <typename p_type>
140 inline void convert_new_activation_func(const p_type primitive, kernel_selector::base_activation_params& params)
141 {
142     params.function = get_kernel_selector_activation_param(primitive->activation_func);
143     params.m = primitive->additional_params.a;
144     params.n = primitive->additional_params.b;
145 }
146
147 void set_params(const program_node& node, kernel_selector::params& params);
148
149 template <typename params_t, typename arg_t>
150 inline params_t get_default_params(const arg_t& arg, uint32_t split = 1)
151 {
152     params_t params;
153
154     set_params(arg, params);
155
156     const auto& input_layout    = arg.input().get_output_layout();
157     const auto& output_layout   = arg.get_output_layout();
158
159     params.inputs[0] = convert_data_tensor(input_layout, split);
160     params.output = convert_data_tensor(output_layout, split);
161
162     params.layerID = arg.id();
163
164     convert_fused_activation_func_params(arg, params.activation);
165
166     return params;
167 }
168
169 template <typename params_t, typename arg_t>
170 inline params_t get_weights_bias_default_params(const arg_t& arg, uint32_t split = 1, uint32_t groups = 1)
171 {
172     params_t params = get_default_params<params_t>(arg, split);
173     const auto& weights_layout = arg.weights().get_output_layout();
174     if (groups == 1) {
175         params.weights = convert_weights_tensor(weights_layout);
176     }
177     else {
178         params.weights = convert_weights_tensor(layout(weights_layout.data_type, weights_layout.format,
179             { weights_layout.size.batch[0]/(int)groups, weights_layout.size.feature[0], weights_layout.size.spatial[0], weights_layout.size.spatial[1] }
180         ));
181     }
182
183     if (arg.bias_term())
184     {
185         const auto& bias_layout = arg.bias().get_output_layout();
186         // bias per output is not supported on cldnn
187         if (groups == 1) {
188             params.bias.push_back(convert_data_tensor(bias_layout).FlattenFeatureAndSpatials());        }
189         else {
190             params.bias.push_back(convert_data_tensor(
191                 layout(
192                     bias_layout.data_type, bias_layout.format,
193                     { bias_layout.size.batch[0], bias_layout.size.feature[0], bias_layout.size.spatial[0]/(int)groups, bias_layout.size.spatial[1] }
194                 )).FlattenFeatureAndSpatials()
195             );
196         }
197     }
198
199     return params;
200 }
201
202 void set_learning_params(const program_node& node, kernel_selector::training_params& params, bool use_momentum);
203
204 template <typename params_t, typename arg_t>
205 inline params_t get_default_learning_params(const arg_t& arg, uint32_t split = 1)
206 {
207         params_t params = get_weights_bias_default_params<params_t>(arg, split);
208     set_learning_params(arg, params, arg.use_momentum());
209         return params;
210 }
211
212 void set_optional_params(const program_impl& program, kernel_selector::optional_params& params);
213
214 template <typename optional_params_t>
215 inline optional_params_t get_default_optional_params(const program_impl& program)
216 {
217     optional_params_t params;
218     set_optional_params(program, params);
219     return params;
220 }
221
222 template <typename optional_params_t>
223 inline optional_params_t get_default_weights_bias_optional_params(const program_impl& program)
224 {
225     return get_default_optional_params<optional_params_t>(program);
226 }
227
228 template <typename optional_params_t>
229 inline optional_params_t get_default_learning_optional_params(const program_impl& program)
230 {
231         return get_default_weights_bias_optional_params<optional_params_t>(program);
232 }