24.02.1
|
Go to the documentation of this file.
46 static const std::vector<CpuActivationKernel::ActivationKernel> available_kernels = {
47 #ifdef ARM_COMPUTE_ENABLE_SVE
48 {
"sve2_q8_activation_lut",
49 [](
const ActivationDataTypeISASelectorData &data)
53 data.f != ActivationLayerInfo::ActivationFunction::RELU;
56 #endif // ARM_COMPUTE_ENABLE_SVE
59 "neon_q8_activation_lut",
60 [](
const ActivationDataTypeISASelectorData &data)
63 data.f != ActivationLayerInfo::ActivationFunction::RELU;
67 {
"sve2_qu8_activation",
68 [](
const ActivationDataTypeISASelectorData &data) {
70 data.f != ActivationLayerInfo::ActivationFunction::GELU;
73 {
"sve2_qs8_activation",
74 [](
const ActivationDataTypeISASelectorData &data)
77 data.f != ActivationLayerInfo::ActivationFunction::GELU;
80 {
"sve2_qs16_activation",
81 [](
const ActivationDataTypeISASelectorData &data) {
83 data.f != ActivationLayerInfo::ActivationFunction::GELU;
86 {
"sve_fp16_activation_lut",
87 [](
const ActivationDataTypeISASelectorData &data)
89 return data.dt ==
DataType::F16 && data.isa.fp16 && data.isa.sve &&
90 data.f == ActivationLayerInfo::ActivationFunction::LOGISTIC;
93 {
"sve_fp16_activation",
94 [](
const ActivationDataTypeISASelectorData &data)
96 return data.dt ==
DataType::F16 && data.isa.sve && data.isa.fp16 &&
97 data.f != ActivationLayerInfo::ActivationFunction::GELU;
100 {
"sve_fp32_activation",
101 [](
const ActivationDataTypeISASelectorData &data)
102 {
return data.dt ==
DataType::F32 && data.isa.sve && data.f != ActivationLayerInfo::ActivationFunction::GELU; },
104 {
"neon_fp16_activation",
105 [](
const ActivationDataTypeISASelectorData &data) {
return data.dt ==
DataType::F16 && data.isa.fp16; },
107 {
"neon_fp32_activation", [](
const ActivationDataTypeISASelectorData &data) {
return data.dt ==
DataType::F32; },
109 {
"neon_qu8_activation", [](
const ActivationDataTypeISASelectorData &data) {
return data.dt ==
DataType::QASYMM8; },
111 {
"neon_qs8_activation",
114 {
"neon_qs16_activation", [](
const ActivationDataTypeISASelectorData &data) {
return data.dt ==
DataType::QSYMM16; },
119 static const std::array<ActivationLayerInfo::ActivationFunction, 8> qasymm8_activations = {
120 ActivationLayerInfo::ActivationFunction::RELU, ActivationLayerInfo::ActivationFunction::LU_BOUNDED_RELU,
121 ActivationLayerInfo::ActivationFunction::BOUNDED_RELU, ActivationLayerInfo::ActivationFunction::LOGISTIC,
122 ActivationLayerInfo::ActivationFunction::TANH, ActivationLayerInfo::ActivationFunction::HARD_SWISH,
123 ActivationLayerInfo::ActivationFunction::LEAKY_RELU, ActivationLayerInfo::ActivationFunction::GELU,
126 static const std::array<ActivationLayerInfo::ActivationFunction, 4> qsymm16_activations = {
127 ActivationLayerInfo::ActivationFunction::LOGISTIC, ActivationLayerInfo::ActivationFunction::TANH,
128 ActivationLayerInfo::ActivationFunction::HARD_SWISH, ActivationLayerInfo::ActivationFunction::LU_BOUNDED_RELU};
130 Status
validate_arguments(
const ITensorInfo *
src,
const ITensorInfo *
dst,
const ActivationLayerInfo &activation_info)
141 const QuantizationInfo &oq_info = (
dst !=
nullptr) ?
dst->quantization_info() :
src->quantization_info();
146 (std::find(std::begin(qasymm8_activations),
std::end(qasymm8_activations), f_act) ==
148 "For QASYMM8 only hard swish, leaky relu, tanh, logistic, relu and lower/upper bounded relu are supported");
151 (std::find(std::begin(qsymm16_activations),
std::end(qsymm16_activations),
152 f_act) ==
std::end(qsymm16_activations)),
153 "For QSYMM16 only tanh and logistic are supported");
155 (f_act == ActivationLayerInfo::ActivationFunction::TANH) &&
156 (oq_info != QuantizationInfo(1.f / 128.f, 128)));
158 (f_act == ActivationLayerInfo::ActivationFunction::LOGISTIC) &&
159 (oq_info != QuantizationInfo(1.f / 256.f, 0)));
162 (f_act == ActivationLayerInfo::ActivationFunction::TANH) &&
163 (oq_info != QuantizationInfo(1.f / 128.f, 0)));
165 (f_act == ActivationLayerInfo::ActivationFunction::LOGISTIC) &&
166 (oq_info != QuantizationInfo(1.f / 256.f, -128)));
169 (f_act == ActivationLayerInfo::ActivationFunction::TANH) &&
170 (oq_info != QuantizationInfo(1.f / 32768.f, 0)));
172 (f_act == ActivationLayerInfo::ActivationFunction::LOGISTIC) &&
173 (oq_info != QuantizationInfo(1.f / 32768.f, 0)));
176 if ((
dst !=
nullptr) && (
dst->total_size() != 0))
196 return std::make_pair(Status{}, win);
201 const UniformQuantizationInfo &qi_in,
202 const UniformQuantizationInfo &qi_out,
203 ActivationLayerInfo::LookupTable256 &lut,
207 for (
size_t i = 0; i < lut.size(); ++i)
213 case ActivationLayerInfo::ActivationFunction::HARD_SWISH:
214 tmp_f = tmp_f * ((std::min(std::max((tmp_f + 3), 0.0f), 6.0f)) * 0.166666667f);
216 case ActivationLayerInfo::ActivationFunction::LEAKY_RELU:
217 tmp_f = tmp_f > 0 ? tmp_f : tmp_f * a;
219 case ActivationLayerInfo::ActivationFunction::LOGISTIC:
220 tmp_f = 1.f / (1.f + std::exp(-tmp_f));
222 case ActivationLayerInfo::ActivationFunction::ABS:
223 tmp_f = std::abs(tmp_f);
225 case ActivationLayerInfo::ActivationFunction::LINEAR:
226 tmp_f = a * tmp_f +
b;
228 case ActivationLayerInfo::ActivationFunction::BOUNDED_RELU:
229 tmp_f = std::min<>(a, std::max(0.f, tmp_f));
231 case ActivationLayerInfo::ActivationFunction::LU_BOUNDED_RELU:
232 tmp_f = std::min<>(a, std::max<>(
b, tmp_f));
234 case ActivationLayerInfo::ActivationFunction::SOFT_RELU:
235 tmp_f = (tmp_f > 12.f) ? tmp_f : std::log(1.f + std::exp(tmp_f));
237 case ActivationLayerInfo::ActivationFunction::ELU:
238 tmp_f = (tmp_f >= 0) ? tmp_f : a * (std::exp(tmp_f) - 1);
240 case ActivationLayerInfo::ActivationFunction::SQRT:
241 tmp_f = std::sqrt(tmp_f);
243 case ActivationLayerInfo::ActivationFunction::SQUARE:
244 tmp_f = tmp_f * tmp_f;
246 case ActivationLayerInfo::ActivationFunction::TANH:
247 tmp_f = a * std::tanh(
b * tmp_f);
249 case ActivationLayerInfo::ActivationFunction::IDENTITY:
251 case ActivationLayerInfo::ActivationFunction::SWISH:
252 tmp_f = tmp_f / (1.f + std::exp(-a * tmp_f));
254 case ActivationLayerInfo::ActivationFunction::GELU:
255 tmp_f = tmp_f * (0.5f * (1.0f + erff(tmp_f / 1.41421356237f)));
266 #endif // __aarch64__
285 _run_method = uk->ukernel;
286 _name = std::string(
"CpuActivationKernel").append(
"/").append(uk->name);
295 ActivationLayerInfo::LookupTable256 tmp_lut;
296 init_lut(activation_info.
activation(),
src->data_type(),
src->quantization_info().uniform(),
297 (
dst) ?
dst->quantization_info().uniform() :
src->quantization_info().uniform(), tmp_lut,
298 activation_info.
a(), activation_info.
b());
299 activation_info.setLookupTable256(tmp_lut);
303 activation_info.
activation() == ActivationLayerInfo::ActivationFunction::LOGISTIC)
306 activation_info.setLookupTable65536((lut_manager.get_lut_table(
info)));
308 #endif // __aarch64__
309 _act_info = activation_info;
315 ICPPKernel::configure(win);
366 return _name.c_str();
371 return available_kernels;
void sve2_qsymm16_activation(const ITensor *src, ITensor *dst, const ActivationLayerInfo &act_info, const Window &window)
@ QASYMM16
quantized, asymmetric fixed-point 16-bit number
float dequantize_qasymm8(uint8_t value, const INFO_TYPE &qinfo)
Dequantize a value given an unsigned 8-bit asymmetric quantization scheme.
SimpleTensor< float > src
void run_op(ITensorPack &tensors, const Window &window, const ThreadInfo &info) override
Execute the kernel on the passed window.
void sve2_q8_activation_lut(const ITensor *src, ITensor *dst, const ActivationLayerInfo &act_info, const Window &window)
static LUTManager & get_instance()
#define REGISTER_Q8_NEON(func_name)
Window calculate_max_window(const ValidRegion &valid_region, const Steps &steps, bool skip_border, BorderSize border_size)
void neon_qasymm8_signed_activation(const ITensor *src, ITensor *dst, const ActivationLayerInfo &act_info, const Window &window)
static const std::vector< ActivationKernel > & get_available_kernels()
@ QASYMM8
quantized, asymmetric fixed-point 8-bit number unsigned
arm_compute::ActivationFunction ActivationFunction
Status validate_arguments(const ITensorInfo *src, const ITensorInfo *weights, const ITensorInfo *dst, const PadStrideInfo &conv_info)
#define ARM_COMPUTE_ERROR_ON_UNCONFIGURED_KERNEL(k)
#define ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_SHAPES(...)
static constexpr size_t DimX
Alias for dimension 0 also known as X dimension.
uint8_t quantize_qasymm8(float value, const INFO_TYPE &qinfo, RoundingPolicy rounding_policy=RoundingPolicy::TO_NEAREST_UP)
Quantize a value given an unsigned 8-bit asymmetric quantization scheme.
#define REGISTER_QASYMM8_SIGNED_NEON(func_name)
#define ARM_COMPUTE_ERROR(msg)
Print the given message then throw an std::runtime_error.
static CPUInfo & get()
Access the KernelLibrary singleton.
bool is_data_type_quantized_symmetric(DataType dt)
Check if a given data type is of symmetric quantized type.
Interface for CPU tensor.
void neon_qsymm16_activation(const ITensor *src, ITensor *dst, const ActivationLayerInfo &act_info, const Window &window)
ITensor * get_tensor(int id)
Get tensor of a given id from the pac.
#define REGISTER_FP16_NEON(func_name)
ActivationFunction activation() const
Get the type of activation function.
#define REGISTER_QSYMM16_SVE2(func_name)
size_t get_mws(const CPUInfo &platform, size_t thread_count) const override
Return minimum workload size of the relevant kernel.
const char * name() const override
Name of the kernel.
#define REGISTER_QASYMM8_NEON(func_name)
#define ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_DATA_TYPES(...)
#define ARM_COMPUTE_RETURN_ERROR_ON_DATA_TYPE_CHANNEL_NOT_IN(t, c,...)
@ QSYMM16
quantized, symmetric fixed-point 16-bit number
#define ARM_COMPUTE_RETURN_ON_ERROR(status)
Checks if a status contains an error and returns it.
Activation Layer Information class.
#define REGISTER_FP32_NEON(func_name)
bool empty() const
Checks if pack is empty.
#define REGISTER_QSYMM16_NEON(func_name)
#define ARM_COMPUTE_ERROR_ON_NULLPTR(...)
#define REGISTER_FP32_SVE(func_name)
#define ARM_COMPUTE_ERROR_ON(cond)
If the condition is true then an error message is printed and an exception thrown.
void neon_qasymm8_activation(const ITensor *src, ITensor *dst, const ActivationLayerInfo &act_info, const Window &window)
const ITensor * get_const_tensor(int id) const
Get constant tensor of a given id.
#define ARM_COMPUTE_ERROR_THROW_ON(status)
bool enabled() const
Check if initialised.
int8_t quantize_qasymm8_signed(float value, const INFO_TYPE &qinfo, RoundingPolicy rounding_policy=RoundingPolicy::TO_NEAREST_UP)
Quantize a value given a signed 8-bit asymmetric quantization scheme.
#define ARM_COMPUTE_RETURN_ERROR_ON(cond)
If the condition is true, an error is returned.
static Status validate(const ITensorInfo *src, const ITensorInfo *dst, const ActivationLayerInfo &act_info)
Static function to check if given info will lead to a valid configuration.
#define ARM_COMPUTE_RETURN_ERROR_ON_CPU_F16_UNSUPPORTED(tensor)
bool auto_init_if_empty(ITensorInfo &info, const TensorShape &shape, int num_channels, DataType data_type, QuantizationInfo quantization_info=QuantizationInfo())
Auto initialize the tensor info (shape, number of channels and data type) if the current assignment i...
@ QASYMM8_SIGNED
quantized, asymmetric fixed-point 8-bit number signed
#define ARM_COMPUTE_ERROR_ON_INVALID_SUBWINDOW(f, s)
void neon_fp32_activation(const ITensor *src, ITensor *dst, const ActivationLayerInfo &act_info, const Window &window)
std::pair< Status, Window > validate_and_configure_window(ITensorInfo *src, ITensorInfo *dst)
#define REGISTER_QASYMM8_SIGNED_SVE2(func_name)
#define ARM_COMPUTE_UNUSED(...)
To avoid unused variables warnings.
void sve_fp16_activation_lut(const ITensor *src, ITensor *dst, const ActivationLayerInfo &act_info, const Window &window)
void sve2_qasymm8_signed_activation(const ITensor *src, ITensor *dst, const ActivationLayerInfo &act_info, const Window &window)
void sve_fp16_activation(const ITensor *src, ITensor *dst, const ActivationLayerInfo &act_info, const Window &window)
static const auto * get_implementation(const SelectorType &selector, KernelSelectionType selection_type=KernelSelectionType::Supported)
Micro-kernel selector.
const Window & window() const
The maximum window the kernel can be executed on.
Information about executing thread and CPU.
void configure(const ITensorInfo *src, ITensorInfo *dst, ActivationLayerInfo activation_info)
Configure kernel for a given list of arguments.
float a() const
Get the alpha value.
Describe a multidimensional execution window.
float dequantize_qasymm8_signed(int8_t value, const INFO_TYPE &qinfo)
Dequantize a value given a signed 8-bit asymmetric quantization scheme.
#define ARM_COMPUTE_RETURN_ERROR_ON_MSG(cond, msg)
If the condition is true, an error is returned.
std::pair< Window, size_t > calculate_squashed_or_max_window(const ITensorInfo &src0, const ITensorInfo &src1)
Copyright (c) 2017-2024 Arm Limited.
void sve_fp32_activation(const ITensor *src, ITensor *dst, const ActivationLayerInfo &act_info, const Window &window)
#define REGISTER_FP16_SVE(func_name)
@ F16
16-bit floating-point number
void end(TokenStream &in, bool &valid)
bool is_data_type_quantized_asymmetric(DataType dt)
Check if a given data type is of asymmetric quantized type.
Store the tensor's metadata.
@ F32
32-bit floating-point number
ScaleKernelInfo info(interpolation_policy, default_border_mode, PixelValue(), sampling_policy, false)
void sve2_qasymm8_activation(const ITensor *src, ITensor *dst, const ActivationLayerInfo &act_info, const Window &window)
float b() const
Get the beta value.
DataType
Available data types.
void neon_fp16_activation(const ITensor *src, ITensor *dst, const ActivationLayerInfo &act_info, const Window &window)
#define REGISTER_QASYMM8_SVE2(func_name)
static constexpr size_t default_mws