18#include "kernels/Utils.h"
35 return kTfLiteActRelu;
37 return kTfLiteActRelu6;
39 return kTfLiteActReluN1To1;
41 return kTfLiteActTanh;
43 return kTfLiteActSignBit;
45 return kTfLiteActNone;
47 throw std::runtime_error(
"Unsupported activation type");
56 case Activation::NONE:
57 *activation_min = std::numeric_limits<T>::lowest();
58 *activation_max = std::numeric_limits<T>::max();
60 case Activation::RELU:
62 *activation_max = std::numeric_limits<T>::max();
64 case Activation::RELU_N1_TO_1:
68 case Activation::RELU6:
73 throw std::runtime_error(
"Unsupported activation.");
78 float *activation_max);
80 int32_t *activation_max);
82 int64_t *activation_max);
84static void calculateActivationRangeQuantizedImpl(
Activation activation, int32_t qmin, int32_t qmax,
85 const Tensor *output, int32_t *activation_min,
86 int32_t *activation_max)
88 const float scale = output->scale();
89 const int32_t zero_point = output->zero_point();
91 auto quantize = [scale, zero_point](
float x) {
92 return zero_point +
static_cast<int32_t
>(std::round(x / scale));
97 case Activation::NONE:
98 case Activation::TANH:
99 *activation_min = qmin;
100 *activation_max = qmax;
102 case Activation::RELU:
103 *activation_min = std::max(qmin, quantize(0.0f));
104 *activation_max = qmax;
106 case Activation::RELU_N1_TO_1:
107 *activation_min = std::max(qmin, quantize(-1.0f));
108 *activation_max = std::min(qmax, quantize(1.0f));
110 case Activation::RELU6:
111 *activation_min = std::max(qmin, quantize(0.0f));
112 *activation_max = std::min(qmax, quantize(6.0f));
115 throw std::runtime_error(
"Unsupported activation.");
120 int32_t *activation_min, int32_t *activation_max)
122 assert(output->zero_points().size() == 1);
125 switch (output->element_type())
133 qmax = std::numeric_limits<uint8_t>::max();
140 qmin = -std::numeric_limits<int8_t>::max();
141 qmax = std::numeric_limits<int8_t>::max();
145 assert(output->zero_point() == 0);
146 qmin = -std::numeric_limits<int16_t>::max();
147 qmax = std::numeric_limits<int16_t>::max();
150 throw std::runtime_error(
"luci-intp (calculateActivationRangeQuantized) Unsupported type.");
153 calculateActivationRangeQuantizedImpl(activation, qmin, qmax, output, activation_min,
159 if (double_multiplier == 0.0)
161 *quantized_multiplier = 0;
166 const double q = std::frexp(double_multiplier, shift);
167 auto q_fixed =
static_cast<int64_t
>(std::round(q * (INT64_C(1) << 31)));
169 if (q_fixed == (INT64_C(1) << 31))
174 assert(q_fixed <= std::numeric_limits<int32_t>::max());
190 *quantized_multiplier =
static_cast<int32_t
>(q_fixed);
196 assert(double_multiplier < 1.0);
197 assert(double_multiplier > 0.0);
206 const int num_input1_dims = input1_shape.
num_dims();
207 const int num_input2_dims = input2_shape.
num_dims();
208 const int num_out_dims = std::max(num_input1_dims, num_input2_dims);
211 for (
int i = 0; i < num_out_dims; ++i)
213 const int32_t input1_dim = i < num_input1_dims ? input1_shape.
dim(num_input1_dims - i - 1) : 1;
214 const int32_t input2_dim = i < num_input2_dims ? input2_shape.
dim(num_input2_dims - i - 1) : 1;
216 bool need_broadcast = input1_dim != input2_dim;
217 bool can_broadcast = input1_dim == 1 || input2_dim == 1;
220 output_shape.dim(num_out_dims - i - 1) = std::max(input1_dim, input2_dim);
#define LUCI_INTERPRETER_CHECK(cond)
const luci_interpreter::RuntimeShape output_shape
Shape calculateShapeForBroadcast(const Shape &input1_shape, const Shape &input2_shape)
TfLiteFusedActivation getTfLiteActivation(Activation activation)
void calculateActivationRange(Activation activation, T *activation_min, T *activation_max)
void quantizeMultiplierSmallerThanOneExp(double double_multiplier, int32_t *quantized_multiplier, int *left_shift)
void calculateActivationRangeQuantized(Activation activation, const Tensor *output, int32_t *activation_min, int32_t *activation_max)
void quantizeMultiplier(double double_multiplier, int32_t *quantized_multiplier, int *shift)