| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| #ifndef TENSORFLOW_LITE_KERNELS_KERNEL_UTIL_H_ |
| #define TENSORFLOW_LITE_KERNELS_KERNEL_UTIL_H_ |
|
|
| #include <stdint.h> |
|
|
| #include <limits> |
| #ifndef TF_LITE_STATIC_MEMORY |
| #include <string> |
| #endif |
|
|
| #include "edge-impulse-sdk/tensorflow/lite/core/c/builtin_op_data.h" |
| #include "edge-impulse-sdk/tensorflow/lite/core/c/common.h" |
|
|
| namespace tflite { |
|
|
| |
| |
| |
| |
| |
|
|
| |
| |
| |
| |
| |
| |
| |
| const TfLiteTensor* GetInput(const TfLiteContext* context, |
| const TfLiteNode* node, int index); |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| TfLiteStatus GetInputSafe(const TfLiteContext* context, const TfLiteNode* node, |
| int index, const TfLiteTensor** tensor); |
|
|
| |
| |
| |
| |
| |
| |
| |
| TfLiteTensor* GetVariableInput(TfLiteContext* context, const TfLiteNode* node, |
| int index); |
|
|
| |
| |
| |
| |
| |
| |
| |
| TfLiteTensor* GetOutput(TfLiteContext* context, const TfLiteNode* node, |
| int index); |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| TfLiteStatus GetOutputSafe(const TfLiteContext* context, const TfLiteNode* node, |
| int index, TfLiteTensor** tensor); |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| const TfLiteTensor* GetOptionalInputTensor(const TfLiteContext* context, |
| const TfLiteNode* node, int index); |
|
|
| #ifndef TF_LITE_STATIC_MEMORY |
| |
| |
| |
| |
| |
| |
| |
| TfLiteTensor* GetTemporary(TfLiteContext* context, const TfLiteNode* node, |
| int index); |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| TfLiteStatus GetTemporarySafe(const TfLiteContext* context, |
| const TfLiteNode* node, int index, |
| TfLiteTensor** tensor); |
|
|
| |
| |
| |
| |
| |
| |
| |
| const TfLiteTensor* GetIntermediates(TfLiteContext* context, |
| const TfLiteNode* node, int index); |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| TfLiteStatus GetIntermediatesSafe(const TfLiteContext* context, |
| const TfLiteNode* node, int index, |
| TfLiteTensor** tensor); |
| #endif |
|
|
| inline int NumDimensions(const TfLiteTensor* t) { return t->dims->size; } |
| inline int SizeOfDimension(const TfLiteTensor* t, int dim) { |
| return t->dims->data[dim]; |
| } |
|
|
| inline int NumDimensions(const TfLiteEvalTensor* t) { return t->dims->size; } |
| inline int SizeOfDimension(const TfLiteEvalTensor* t, int dim) { |
| return t->dims->data[dim]; |
| } |
|
|
| inline int NumInputs(const TfLiteNode* node) { |
| return node->inputs == nullptr ? 0 : node->inputs->size; |
| } |
| inline int NumOutputs(const TfLiteNode* node) { |
| return node->outputs == nullptr ? 0 : node->outputs->size; |
| } |
|
|
| #ifndef TF_LITE_STATIC_MEMORY |
| inline int NumIntermediates(const TfLiteNode* node) { |
| return node->intermediates->size; |
| } |
| #endif |
|
|
| inline int64_t NumElements(const TfLiteIntArray* dims) { |
| int64_t count = 1; |
| for (int i = 0; i < dims->size; ++i) { |
| count *= dims->data[i]; |
| } |
| return count; |
| } |
|
|
| inline int64_t NumElements(const TfLiteTensor* t) { |
| return NumElements(t->dims); |
| } |
|
|
| inline int64_t NumElements(const int* dims, int num_dims) { |
| int64_t count = 1; |
| for (int i = 0; i < num_dims; ++i) { |
| count *= dims[i]; |
| } |
| return count; |
| } |
|
|
| |
| |
| |
| |
| |
| inline bool IsConstantTensor(const TfLiteTensor* tensor) { |
| return tensor->allocation_type == kTfLiteMmapRo; |
| } |
|
|
| inline bool IsConstantOrPersistentTensor(const TfLiteTensor* tensor) { |
| return IsConstantTensor(tensor) || |
| (tensor->allocation_type == kTfLitePersistentRo); |
| } |
|
|
| |
| |
| inline bool IsDynamicTensor(const TfLiteTensor* tensor) { |
| return tensor->allocation_type == kTfLiteDynamic; |
| } |
|
|
| |
| inline void SetTensorToDynamic(TfLiteTensor* tensor) { |
| if (tensor->allocation_type != kTfLiteDynamic) { |
| tensor->allocation_type = kTfLiteDynamic; |
| tensor->data.raw = nullptr; |
| } |
| } |
|
|
| |
| inline void SetTensorToPersistentRo(TfLiteTensor* tensor) { |
| if (tensor->allocation_type != kTfLitePersistentRo) { |
| tensor->allocation_type = kTfLitePersistentRo; |
| tensor->data.raw = nullptr; |
| } |
| } |
|
|
| |
| |
| inline bool IsHybridOp(const TfLiteTensor* input, const TfLiteTensor* weight) { |
| return ((weight->type == kTfLiteUInt8 || weight->type == kTfLiteInt8) && |
| input->type == kTfLiteFloat32); |
| } |
|
|
| |
| TfLiteStatus PopulateConvolutionQuantizationParams( |
| TfLiteContext* context, const TfLiteTensor* input, |
| const TfLiteTensor* filter, const TfLiteTensor* bias, TfLiteTensor* output, |
| const TfLiteFusedActivation& activation, int32_t* multiplier, int* shift, |
| int32_t* output_activation_min, int32_t* output_activation_max, |
| int32_t* per_channel_multiplier, int32_t* per_channel_shift); |
|
|
| TfLiteStatus PopulateConvolutionQuantizationParams( |
| TfLiteContext* context, const TfLiteTensor* input, |
| const TfLiteTensor* filter, const TfLiteTensor* bias, TfLiteTensor* output, |
| const TfLiteFusedActivation& activation, int32_t* multiplier, int* shift, |
| int32_t* output_activation_min, int32_t* output_activation_max, |
| int32_t* per_channel_multiplier, int32_t* per_channel_shift, |
| int num_channels); |
|
|
| |
| |
| |
| TfLiteStatus GetQuantizedConvolutionMultipler(TfLiteContext* context, |
| const TfLiteTensor* input, |
| const TfLiteTensor* filter, |
| const TfLiteTensor* bias, |
| TfLiteTensor* output, |
| double* multiplier); |
|
|
| TfLiteStatus GetQuantizedConvolutionMultipler(TfLiteContext* context, |
| const TfLiteTensor* input, |
| const TfLiteTensor* filter, |
| TfLiteTensor* output, |
| double* multiplier); |
|
|
| |
| |
| TfLiteStatus CalculateActivationRangeQuantized(TfLiteContext* context, |
| TfLiteFusedActivation activation, |
| TfLiteTensor* output, |
| int32_t* act_min, |
| int32_t* act_max); |
|
|
| |
| |
| template <typename T> |
| void CalculateActivationRange(TfLiteFusedActivation activation, |
| T* activation_min, T* activation_max) { |
| if (activation == kTfLiteActRelu) { |
| *activation_min = 0; |
| *activation_max = std::numeric_limits<T>::max(); |
| } else if (activation == kTfLiteActRelu6) { |
| *activation_min = 0; |
| *activation_max = 6; |
| } else if (activation == kTfLiteActReluN1To1) { |
| *activation_min = -1; |
| *activation_max = 1; |
| } else { |
| *activation_min = std::numeric_limits<T>::lowest(); |
| *activation_max = std::numeric_limits<T>::max(); |
| } |
| } |
|
|
| |
| bool HaveSameShapes(const TfLiteTensor* input1, const TfLiteTensor* input2); |
|
|
| #if !defined(TF_LITE_STATIC_MEMORY) |
| |
| TfLiteStatus GetOutputShapeFromInput(TfLiteContext* context, |
| const TfLiteTensor* input, |
| TfLiteIntArray** output_shape); |
|
|
| const std::string GetShapeDebugString(const TfLiteIntArray* shape); |
|
|
| #endif |
|
|
| |
| |
| TfLiteStatus CalculateShapeForBroadcast(TfLiteContext* context, |
| const TfLiteTensor* input1, |
| const TfLiteTensor* input2, |
| TfLiteIntArray** output_shape); |
|
|
| |
| |
| TfLiteStatus CalculateShapeForBroadcast(TfLiteContext* context, |
| const TfLiteTensor* input1, |
| const TfLiteTensor* input2, |
| const TfLiteTensor* input3, |
| TfLiteIntArray** output_shape); |
|
|
| |
| int TfLiteTypeGetSize(TfLiteType type); |
|
|
| |
| bool IsMobilePlatform(); |
|
|
| |
| bool HasUnspecifiedDimension(const TfLiteTensor* tensor); |
|
|
| } |
|
|
| #endif |
|
|