18#ifndef LUCI_INTERPRETER_KERNELS_BINARYOPUTILS_H
19#define LUCI_INTERPRETER_KERNELS_BINARYOPUTILS_H
22#include "PALComparisons.h"
24#include "ProcessBroadcastShapes.h"
47 static_assert(one_of_types<T, float, int32_t, int64_t>(),
"Unsupported dtype");
49 if (std::is_same<T, float>::value)
51 if (std::is_same<T, int32_t>::value)
59template <
typename T,
typename TISOFunc = nullptr_t,
typename TISOBroadcastFunc = nullptr_t,
60 typename Options = nullptr_t>
61void evalTISOKernel(TISOFunc tiso_func, TISOBroadcastFunc tiso_broadcast_func,
67 fillArithmeticActivationRange<T>(params,
luci_actfunc(options->fused_activation_function()));
69 const bool need_broadcast =
74 tiso_broadcast_func(params, input_shape_1, kernels::getTensorData<T>(kernel_data->
input1_data),
75 input_shape_2, kernels::getTensorData<T>(kernel_data->
input2_data),
80 const int flat_size = input_shape_1.flatSize();
81 tiso_func(params, flat_size, kernels::getTensorData<T>(kernel_data->
input1_data),
82 kernels::getTensorData<T>(kernel_data->
input2_data),
83 kernels::getTensorData<T>(kernel_data->
output_data));
87template <
typename T,
typename TISOFunc = nullptr_t,
typename TISOBroadcastFunc = nullptr_t,
88 typename Options = nullptr_t>
94 uint8_t *inplace_data_ptr =
nullptr;
95 circle::Tensor *input_inplace_tensor =
nullptr;
99 evalTISOKernel<T, TISOFunc, TISOBroadcastFunc, Options>(
100 tiso_func, tiso_broadcast_func, kernel, &kernel_data, options, std::move(input_shape_1),
106 if (input_inplace_tensor == kernel->
input1())
119 Tensor::element_type(kernel.
input2()));
121 Tensor::element_type(kernel.
output()));
125template <
typename T,
typename TISOFunc = nullptr_t,
typename TISOBroadcastFunc = nullptr_t,
126 typename Options = nullptr_t>
129 const Options *options)
131 const auto *input1 = kernel->
input1();
132 const auto *input2 = kernel->
input2();
133 const auto *output = kernel->
output();
135 const auto input1_scale =
static_cast<double>(Tensor::scale(input1));
136 const auto input2_scale =
static_cast<double>(Tensor::scale(input2));
137 const auto output_scale =
static_cast<double>(Tensor::scale(output));
139 const int left_shift = 20;
140 const double twice_max_input_scale = 2 * std::max(input1_scale, input2_scale);
141 const double real_input1_multiplier = input1_scale / twice_max_input_scale;
142 const double real_input2_multiplier = input2_scale / twice_max_input_scale;
143 const double real_output_multiplier = twice_max_input_scale / ((1 << left_shift) * output_scale);
145 int32_t input1_multiplier{}, input2_multiplier{}, output_multiplier{};
146 int input1_shift{}, input2_shift{}, output_shift{};
154 int32_t activation_min{};
155 int32_t activation_max{};
157 output, &activation_min, &activation_max);
162 params.input1_offset = -Tensor::zero_point(input1);
163 params.input1_multiplier = input1_multiplier;
164 params.input1_shift = input1_shift;
165 params.input2_offset = -Tensor::zero_point(input2);
166 params.input2_multiplier = input2_multiplier;
167 params.input2_shift = input2_shift;
168 params.output_offset = Tensor::zero_point(output);
169 params.output_multiplier = output_multiplier;
170 params.output_shift = output_shift;
171 params.quantized_activation_min = activation_min;
172 params.quantized_activation_max = activation_max;
187 kernels::getTensorData<uint8_t>(kernel_data->
input1_data),
193template <
typename T,
typename TISOFunc = nullptr_t,
typename TISOBroadcastFunc = nullptr_t,
194 typename Options = nullptr_t>
198 uint8_t *inplace_data_ptr =
nullptr;
199 circle::Tensor *input_inplace_tensor =
nullptr;
203 evalTISOQuantizedKernel<T, TISOFunc, TISOBroadcastFunc, Options>(tiso_func, tiso_broadcast_func,
204 kernel, &kernel_data, options);
207 if (input_inplace_tensor == kernel->
input1())
void makeInplaceOperation(const circle::Tensor *src_tensor, const circle::Tensor *dst_tensor)
BaseRuntimeGraph * runtime_graph() const
TISOData readInplaceData(uint8_t *&inplace_data_ptr, circle::Tensor *&input_inplace_tensor)
const circle::Tensor * output() const
const circle::Tensor * input2() const
const circle::Tensor * input1() const
#define LUCI_INTERPRETER_CHECK(cond)
const luci_interpreter::RuntimeShape output_shape
void evalTISOInplaceKernel(TISOFunc tiso_func, TISOBroadcastFunc tiso_broadcast_func, kernels::TISOKernel *kernel, const Options *options, RuntimeShape &&input_shape_1, RuntimeShape &&input_shape_2, RuntimeShape &&output_shape)
void evalTISOQuantizedKernel(TISOFunc tiso_func, TISOBroadcastFunc tiso_broadcast_func, kernels::TISOKernel *kernel, kernels::TISOData *kernel_data, const Options *options)
void evalTISOKernel(TISOFunc tiso_func, TISOBroadcastFunc tiso_broadcast_func, kernels::TISOKernel *kernel, kernels::TISOData *kernel_data, const Options *options, RuntimeShape &&input_shape_1, RuntimeShape &&input_shape_2, RuntimeShape &&output_shape)
tflite::RuntimeShape getTensorShape(const Tensor *tensor)
luci_interpreter::FusedActFunc 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 CheckBinaryOpDataTypesEqual(const kernels::TISOKernel &kernel)
void evalTISOInplaceQuantizedKernel(TISOFunc tiso_func, TISOBroadcastFunc tiso_broadcast_func, kernels::TISOKernel *kernel, const Options *options)
void fillArithmeticActivationRange(tflite::ArithmeticParams &p, Activation act)
bool ProcessBroadcastShapes(const luci_interpreter::RuntimeShape &shape0, const luci_interpreter::RuntimeShape &shape1, luci_interpreter_pal::ArithmeticParams *params)
FusedActFunc luci_actfunc(const circle::ActivationFunctionType type)
This file contains utility macro.
int32_t quantized_activation_min
float float_activation_max
float float_activation_min
int64_t int64_activation_max
int64_t int64_activation_min
int32_t quantized_activation_max