From 6c928343b0fa2bf60ffdfe21aea28b598d742ed4 Mon Sep 17 00:00:00 2001 From: Michele Di Giorgio Date: Thu, 22 Jun 2017 16:55:57 +0100 Subject: COMPMID-413: Add support for QS8 and QS16 CLNormalizationLayer. Change-Id: I1aaa9fb8d05796bbca9cfae584e084646552bb71 Reviewed-on: http://mpd-gerrit.cambridge.arm.com/80155 Reviewed-by: Anthony Barbier Tested-by: Kaizen --- src/core/CL/kernels/CLNormalizationLayerKernel.cpp | 37 +++++++++++++++------- 1 file changed, 25 insertions(+), 12 deletions(-) (limited to 'src/core/CL/kernels/CLNormalizationLayerKernel.cpp') diff --git a/src/core/CL/kernels/CLNormalizationLayerKernel.cpp b/src/core/CL/kernels/CLNormalizationLayerKernel.cpp index 1afd76a375..a0607c2ba0 100644 --- a/src/core/CL/kernels/CLNormalizationLayerKernel.cpp +++ b/src/core/CL/kernels/CLNormalizationLayerKernel.cpp @@ -26,6 +26,7 @@ #include "arm_compute/core/CL/CLHelpers.h" #include "arm_compute/core/CL/CLKernelLibrary.h" #include "arm_compute/core/CL/ICLTensor.h" +#include "arm_compute/core/FixedPoint.h" #include "arm_compute/core/Helpers.h" #include "arm_compute/core/TensorInfo.h" #include "arm_compute/core/Utils.h" @@ -46,7 +47,7 @@ BorderSize CLNormalizationLayerKernel::border_size() const void CLNormalizationLayerKernel::configure(const ICLTensor *input, const ICLTensor *squared_input, ICLTensor *output, NormalizationLayerInfo norm_info) { - ARM_COMPUTE_ERROR_ON_DATA_TYPE_CHANNEL_NOT_IN(input, 1, DataType::F16, DataType::F32); + ARM_COMPUTE_ERROR_ON_DATA_TYPE_CHANNEL_NOT_IN(input, 1, DataType::QS8, DataType::QS16, DataType::F16, DataType::F32); ARM_COMPUTE_ERROR_ON_NULLPTR(output); // Output tensor auto initialization if not yet initialized @@ -56,34 +57,46 @@ void CLNormalizationLayerKernel::configure(const ICLTensor *input, const ICLTens ARM_COMPUTE_ERROR_ON_MISMATCHING_SHAPES(input, squared_input, output); ARM_COMPUTE_ERROR_ON_MSG(!(norm_info.norm_size() % 2), "Normalization size should be odd"); ARM_COMPUTE_ERROR_ON_MSG(norm_info.type() == NormType::IN_MAP_2D, "2D In-Map Normalization not implemented"); - - // Set build options - std::set build_opts; - build_opts.emplace(("-DDATA_TYPE=" + get_cl_type_from_data_type(input->info()->data_type()))); + if(is_data_type_fixed_point(input->info()->data_type())) + { + ARM_COMPUTE_ERROR_ON_MISMATCHING_FIXED_POINT(input, squared_input, output); + ARM_COMPUTE_ERROR_ON_VALUE_NOT_REPRESENTABLE_IN_FIXED_POINT(norm_info.beta(), input); + ARM_COMPUTE_ERROR_ON_VALUE_NOT_REPRESENTABLE_IN_FIXED_POINT(norm_info.kappa(), input); + ARM_COMPUTE_ERROR_ON_VALUE_NOT_REPRESENTABLE_IN_FIXED_POINT(norm_info.scale_coeff(), input); + } _input = input; _squared_input = squared_input; _output = output; - _is_in_map = (norm_info.type() == NormType::IN_MAP_1D); + _is_in_map = (norm_info.type() != NormType::CROSS_MAP); const unsigned int border_width = _is_in_map ? std::min(norm_info.norm_size() / 2, 3U) : 0; _border_size = BorderSize(0, border_width); + const unsigned int num_elems_processed_per_iteration = (is_data_type_fixed_point(input->info()->data_type())) ? 16 : 4; + const unsigned int num_elems_read_per_iteration = num_elems_processed_per_iteration + 2 * (norm_info.norm_size() / 2); + + // Set build options + std::set build_opts; + build_opts.emplace(("-DDATA_TYPE=" + get_cl_type_from_data_type(input->info()->data_type()))); + if(is_data_type_fixed_point(input->info()->data_type())) + { + build_opts.emplace(("-DFIXED_POINT_POSITION=" + support::cpp11::to_string(input->info()->fixed_point_position()))); + } + build_opts.emplace(("-DCOEFF=" + support::cpp11::to_string(norm_info.scale_coeff()))); + build_opts.emplace(("-DBETA=" + support::cpp11::to_string(norm_info.beta()))); + build_opts.emplace(("-DKAPPA=" + support::cpp11::to_string(norm_info.kappa()))); + build_opts.emplace(("-DVEC_SIZE=" + support::cpp11::to_string(num_elems_processed_per_iteration))); + // Create kernel std::string kernel_name = (norm_info.type() == NormType::IN_MAP_1D) ? "normalization_layer_in_map_1D" : "normalization_layer_cross_map"; _kernel = static_cast(CLKernelLibrary::get().create_kernel(kernel_name, build_opts)); // Set kernel static arguments unsigned int idx = 3 * num_arguments_per_3D_tensor(); // Skip the input and output parameters - _kernel.setArg(idx++, norm_info.scale_coeff()); - _kernel.setArg(idx++, norm_info.beta()); - _kernel.setArg(idx++, norm_info.kappa()); _kernel.setArg(idx++, norm_info.norm_size() / 2); // Configure kernel window - const unsigned int num_elems_processed_per_iteration = (_is_in_map) ? 4 : 1; - const unsigned int num_elems_read_per_iteration = num_elems_processed_per_iteration + 2 * (norm_info.norm_size() / 2); - Window win = calculate_max_window(*input->info(), Steps(num_elems_processed_per_iteration)); AccessWindowHorizontal input_access(input->info(), -_border_size.left, num_elems_read_per_iteration); -- cgit v1.2.1