1 // Copyright (c) 2016-2018 Intel Corporation
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
7 // http://www.apache.org/licenses/LICENSE-2.0
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.
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"
24 #include "kernel_selector_params.h"
25 #include "kernel_selector_common.h"
26 #include "tensor_type.h"
33 using namespace cldnn;
36 enum class data_types : size_t;
37 enum class tuning_mode;
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;
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;
82 using data_tensor = kernel_selector::DataTensor;
83 using weights_tensor = kernel_selector::WeightsTensor;
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;
90 using params = kernel_selector::Params;
91 using weights_reorder_params = kernel_selector::WeightsReorderParams;
92 using generic_kernel_params = kernel_selector::GenericKernelParams;
94 struct training_params;
95 } // namespace kernel_selector
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);
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])};
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);
131 params.emplace_back(kernel_selector::activation_function::RELU, 0.0f, 0.0f);
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);
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});
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,
159 void set_params(const program_node& node, kernel_selector::params& params);
161 template <typename params_t, typename arg_t>
162 inline params_t get_default_params(const arg_t& arg, uint32_t split = 1) {
165 set_params(arg, params);
167 const auto& input_layout = arg.input().get_output_layout();
168 const auto& output_layout = arg.get_output_layout();
170 params.inputs[0] = convert_data_tensor(input_layout, split);
171 params.output = convert_data_tensor(output_layout, split);
173 params.layerID = arg.id();
175 convert_fused_activation_func_params(arg, params.activations);
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);
194 throw std::runtime_error("Invalid fused primitive type in " + arg.id() + " node");
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);
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()));
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);
211 params.fused_ops.push_back(desc);
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();
222 params.weights = convert_weights_tensor(weights_layout);
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]}));
232 if (arg.bias_term()) {
233 const auto& bias_layout = arg.bias().get_output_layout();
234 // bias per output is not supported on cldnn
236 params.bias.push_back(convert_data_tensor(bias_layout).FlattenFeatureAndSpatials());
238 params.bias.push_back(convert_data_tensor(layout(bias_layout.data_type,
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());
251 void set_learning_params(const program_node& node, kernel_selector::training_params& params, bool use_momentum);
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());
260 void set_optional_params(const program_impl& program, kernel_selector::optional_params& params);
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);
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);
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);