18#ifndef LUCI_INTERPRETER_KERNELS_UTILS_H
19#define LUCI_INTERPRETER_KERNELS_UTILS_H
22#include "luci_interpreter/core/Tensor.h"
24#include <tensorflow/lite/kernels/internal/tensor_utils.h>
25#include <tensorflow/lite/kernels/internal/types.h>
36#define LUCI_INTERPRETER_CHECK(cond) \
38 throw std::runtime_error(std::string(__FILE__) + ":" + std::to_string(__LINE__) + +"(" + \
39 std::string(#cond) + ") was not true.");
41inline int32_t
computePadding(int32_t stride, int32_t dilation_rate, int32_t in_size,
42 int32_t filter_size, int32_t out_size)
44 const int32_t effective_filter_size = (filter_size - 1) * dilation_rate + 1;
45 const int32_t padding = ((out_size - 1) * stride + effective_filter_size - in_size) / 2;
46 return padding > 0 ? padding : 0;
50 int32_t filter_size, int32_t out_size, int32_t *
offset)
52 int32_t effective_filter_size = (filter_size - 1) * dilation_rate + 1;
53 int32_t total_padding = ((out_size - 1) * stride + effective_filter_size - in_size);
54 total_padding = total_padding > 0 ? total_padding : 0;
55 *
offset = total_padding % 2;
56 return total_padding / 2;
60 int32_t stride, int32_t dilation_rate = 1)
62 const int32_t effective_filter_size = (filter_size - 1) * dilation_rate + 1;
66 return (image_size + stride - 1) / stride;
68 return (image_size + stride - effective_filter_size) / stride;
75inline int32_t
calcOffset(
const Shape &shape, int32_t d0, int32_t d1, int32_t d2, int32_t d3)
77 return ((d0 * shape.
dim(1) + d1) * shape.
dim(2) + d2) * shape.
dim(3) + d3;
86 int32_t *activation_min, int32_t *activation_max);
88template <
typename T>
constexpr bool one_of_types() {
return false; }
91template <
typename T,
typename U,
typename... Other>
constexpr bool one_of_types()
93 return std::is_same<T, U>::value ||
one_of_types<T, Other...>();
108 static_assert(one_of_types<T, float, int32_t, int64_t>(),
"Unsupported dtype");
110 if (std::is_same<T, float>::value)
112 if (std::is_same<T, int32_t>::value)
125void quantizeMultiplier(
double double_multiplier, int32_t *quantized_multiplier,
int *shift);
140 const double input_product_scale =
static_cast<double>(input_scale * filter_scale);
142 return input_product_scale /
static_cast<double>(output_scale);
148 const std::vector<float> &filter_scale,
151 std::vector<double> effective_output_scales;
152 size_t n = filter_scale.size();
153 effective_output_scales.reserve(n);
154 for (
size_t i = 0; i < n; ++i)
156 effective_output_scales.push_back(
159 return effective_output_scales;
169inline std::vector<ChannelQuantMultipliers>
172 size_t n = effective_scale.size();
173 std::vector<ChannelQuantMultipliers> params(n);
174 for (
size_t i = 0; i < n; ++i)
190 const std::vector<T> &_v;
196 if (tensor ==
nullptr)
197 return tflite::RuntimeShape();
199 const Shape &shape = tensor->shape();
200 tflite::RuntimeShape runtime_shape(shape.
num_dims());
201 for (
int i = 0; i < shape.
num_dims(); ++i)
203 runtime_shape.SetDim(i, shape.
dim(i));
205 return runtime_shape;
210 return tensor !=
nullptr ? tensor->data<T>() :
nullptr;
215 return tensor !=
nullptr ? tensor->data<T>() :
nullptr;
223 using ElementT =
typename std::conditional<is_const, const T, T>::type;
224 using TensorT =
typename std::conditional<is_const, const Tensor, Tensor>::type;
229 const int num_tensors = tensor_list.size();
231 all_data_.reserve(num_tensors);
232 all_shape_.reserve(num_tensors);
233 all_shape_ptr_.reserve(num_tensors);
235 for (
TensorT *tensor : tensor_list)
237 all_data_.push_back(getTensorData<T>(tensor));
244 for (tflite::RuntimeShape &shape : all_shape_)
246 all_shape_ptr_.push_back(&shape);
259 const tflite::RuntimeShape *
const *
shapes()
const {
return all_shape_ptr_.data(); }
262 std::vector<ElementT *> all_data_;
263 std::vector<tflite::RuntimeShape> all_shape_;
264 std::vector<tflite::RuntimeShape *> all_shape_ptr_;
278 for (
TensorT *tensor : tensor_list)
280 zero_point_.push_back(tensor->zero_point());
281 scale_.push_back(tensor->scale());
285 const float *
scale()
const {
return scale_.data(); }
286 const int32_t *
zero_point()
const {
return zero_point_.data(); }
289 std::vector<int32_t> zero_point_;
290 std::vector<float> scale_;
BroadcastableWrapper(const std::vector< T > &v)
const float * scale() const
const int32_t * zero_point() const
VectorOfQuantizedTensors(const std::vector< TensorT * > &tensor_list)
VectorOfTensors(const std::vector< TensorT * > &tensor_list)
const tflite::RuntimeShape *const * shapes() const
ElementT *const * data() const
typename std::conditional< is_const, const Tensor, Tensor >::type TensorT
typename std::conditional< is_const, const T, T >::type ElementT
#define LUCI_INTERPRETER_CHECK(cond)
__global uchar * offset(const Image *img, int x, int y)
int32_t computePadding(int32_t stride, int32_t dilation_rate, int32_t in_size, int32_t filter_size, int32_t out_size)
int32_t calcOffset(const Shape &shape, int32_t d0, int32_t d1, int32_t d2, int32_t d3)
Shape calculateShapeForBroadcast(const Shape &input1_shape, const Shape &input2_shape)
TfLiteFusedActivation getTfLiteActivation(Activation activation)
const T * getTensorData(const Tensor *tensor)
std::vector< ChannelQuantMultipliers > quantizeMultipliers(const std::vector< double > &effective_scale)
tflite::RuntimeShape getTensorShape(const Tensor *tensor)
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)
constexpr bool one_of_types()
double getQuantizedConvolutionMultipler(float input_scale, float filter_scale, float output_scale)
int32_t computePaddingWithOffset(int32_t stride, int32_t dilation_rate, int32_t in_size, int32_t filter_size, int32_t out_size, int32_t *offset)
void quantizeMultiplier(double double_multiplier, int32_t *quantized_multiplier, int *shift)
int32_t computeOutputSize(Padding padding, int32_t image_size, int32_t filter_size, int32_t stride, int32_t dilation_rate=1)
std::vector< double > getQuantizedConvolutionMultiplers(float input_scale, const std::vector< float > &filter_scale, float output_scale)
void fillArithmeticActivationRange(tflite::ArithmeticParams &p, Activation act)
ChannelQuantMultipliers()=default