diff options
Diffstat (limited to 'src/core/CL/kernels')
-rw-r--r-- | src/core/CL/kernels/CLActivationLayerKernel.cpp | 61 |
1 files changed, 40 insertions, 21 deletions
diff --git a/src/core/CL/kernels/CLActivationLayerKernel.cpp b/src/core/CL/kernels/CLActivationLayerKernel.cpp index 65e6561b0a..34d1298d61 100644 --- a/src/core/CL/kernels/CLActivationLayerKernel.cpp +++ b/src/core/CL/kernels/CLActivationLayerKernel.cpp @@ -30,14 +30,14 @@ #include "arm_compute/core/Helpers.h" #include "arm_compute/core/IAccessWindow.h" #include "arm_compute/core/TensorInfo.h" +#include "arm_compute/core/Types.h" #include "arm_compute/core/Utils.h" #include "arm_compute/core/Window.h" - -#include "arm_compute/core/CL/CLHelpers.h" -#include "arm_compute/core/Types.h" +#include "arm_compute/core/utils/helpers/float_ops.h" #include "support/ToolchainSupport.h" #include <cmath> +#include <set> using namespace arm_compute; @@ -47,11 +47,23 @@ Status validate_arguments(const ITensorInfo *input, const ITensorInfo *output, c { ARM_COMPUTE_RETURN_ERROR_ON_F16_UNSUPPORTED(input); ARM_COMPUTE_RETURN_ERROR_ON_DATA_TYPE_CHANNEL_NOT_IN(input, 1, DataType::U8, DataType::QASYMM8, DataType::F16, DataType::F32); - ARM_COMPUTE_RETURN_ERROR_ON_MSG((input->data_type() == DataType::QASYMM8) && (act_info.activation() != ActivationLayerInfo::ActivationFunction::LU_BOUNDED_RELU) - && (act_info.activation() != ActivationLayerInfo::ActivationFunction::BOUNDED_RELU) - && (act_info.activation() != ActivationLayerInfo::ActivationFunction::RELU) - && (act_info.activation() != ActivationLayerInfo::ActivationFunction::LOGISTIC), - "For QASYMM8 only logistic, relu, lower bounded relu and lower-upper bounded relu are supported"); + + static std::set<ActivationLayerInfo::ActivationFunction> qs8_supported_activations = + { + ActivationLayerInfo::ActivationFunction::RELU, + ActivationLayerInfo::ActivationFunction::LU_BOUNDED_RELU, + ActivationLayerInfo::ActivationFunction::BOUNDED_RELU, + ActivationLayerInfo::ActivationFunction::LOGISTIC, + ActivationLayerInfo::ActivationFunction::TANH + }; + const DataType data_type = input->data_type(); + const QuantizationInfo &oq_info = (output != nullptr) ? output->quantization_info() : input->quantization_info(); + const ActivationLayerInfo::ActivationFunction f_act = act_info.activation(); + + ARM_COMPUTE_RETURN_ERROR_ON_MSG(is_data_type_quantized_asymmetric(data_type) && (qs8_supported_activations.count(f_act) == 0), + "For QASYMM8 only tanh, logistic, relu and lower/upper bounded relu are supported"); + ARM_COMPUTE_RETURN_ERROR_ON(is_data_type_quantized_asymmetric(data_type) && (f_act == ActivationLayerInfo::ActivationFunction::TANH) && (oq_info != QuantizationInfo(1.f / 128.f, 128))); + ARM_COMPUTE_RETURN_ERROR_ON(is_data_type_quantized_asymmetric(data_type) && (f_act == ActivationLayerInfo::ActivationFunction::LOGISTIC) && (oq_info != QuantizationInfo(1.f / 256.f, 0))); // Checks performed when output is configured if((output != nullptr) && (output->total_size() != 0)) @@ -122,7 +134,10 @@ void CLActivationLayerKernel::configure(ICLTensor *input, ICLTensor *output, Act int a_const_int = 0; int b_const_int = 0; - const bool is_quantized_asymmetric = is_data_type_quantized_asymmetric(dt); + const ActivationLayerInfo::ActivationFunction f_act = act_info.activation(); + const bool is_quantized_asymmetric = is_data_type_quantized_asymmetric(dt); + const bool perform_activation_in_float = (f_act == ActivationLayerInfo::ActivationFunction::LOGISTIC) || (f_act == ActivationLayerInfo::ActivationFunction::TANH); + // Create quantized version of constants a, b if needed if(is_quantized_asymmetric) { @@ -131,18 +146,29 @@ void CLActivationLayerKernel::configure(ICLTensor *input, ICLTensor *output, Act b_const_int = quantize_qasymm8(b_const, iq_info); } - const bool is_logistic_activation_quantized = is_quantized_asymmetric && act_info.activation() == ActivationLayerInfo::ActivationFunction::LOGISTIC; // Set build options CLBuildOptions build_opts; - build_opts.add_option_if(!is_logistic_activation_quantized, "-DACT=" + lower_string(string_from_activation_func(act_info.activation()))); + build_opts.add_option_if(perform_activation_in_float, "-DFLOAT_DOMAIN"); + build_opts.add_option_if(_run_in_place, "-DIN_PLACE"); + build_opts.add_option(("-DACT=" + lower_string(string_from_activation_func(f_act)))); build_opts.add_option(("-DDATA_TYPE=" + get_cl_type_from_data_type(dt))); build_opts.add_option(("-DVEC_SIZE=" + support::cpp11::to_string(num_elems_processed_per_iteration))); - if(is_quantized_asymmetric) + // Set A, B constants in build options + if(is_quantized_asymmetric && !perform_activation_in_float) { build_opts.add_option(("-DA_VAL=" + support::cpp11::to_string(a_const_int))); build_opts.add_option(("-DB_VAL=" + support::cpp11::to_string(b_const_int))); + } + else + { + build_opts.add_option(("-DA_VAL=" + float_to_string_with_full_precision(a_const))); + build_opts.add_option(("-DB_VAL=" + float_to_string_with_full_precision(b_const))); + } + // Set quantization info build options + if(is_quantized_asymmetric) + { const UniformQuantizationInfo iq_info = input->info()->quantization_info().uniform(); // Quantized value of 0 corresponds to the offset o1 @@ -151,7 +177,7 @@ void CLActivationLayerKernel::configure(ICLTensor *input, ICLTensor *output, Act build_opts.add_option(("-DO1_VAL=" + support::cpp11::to_string(iq_info.offset))); // Set scale and offset of the input and output if they have different quantization info - if(is_quantized_asymmetric && output != nullptr) + if(output != nullptr) { const UniformQuantizationInfo oq_info = output->info()->quantization_info().uniform(); @@ -162,19 +188,12 @@ void CLActivationLayerKernel::configure(ICLTensor *input, ICLTensor *output, Act } } } - else - { - build_opts.add_option(("-DA_VAL=" + float_to_string_with_full_precision(a_const))); - build_opts.add_option(("-DB_VAL=" + float_to_string_with_full_precision(b_const))); - } - - build_opts.add_option_if(_run_in_place, "-DIN_PLACE"); // Create kernel std::string kernel_name = std::string("activation_layer"); if(is_quantized_asymmetric) { - kernel_name += is_logistic_activation_quantized ? std::string("_logistic_qa8") : std::string("_qa8"); + kernel_name += perform_activation_in_float ? std::string("_qa8_f32") : std::string("_qa8"); } _kernel = static_cast<cl::Kernel>(CLKernelLibrary::get().create_kernel(kernel_name, build_opts.options())); |