diff --git a/README.md b/README.md index a32dbc2..8b11c41 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,22 @@ # ESP_TF 1. run create.sf to update source this library just restructures the espressif tensorflow repo (https://github.com/espressif/tflite-micro-esp-examples) to be arduino compatible -2. Move private destructors as needed see commit 47ea0fec385a7701ede45d45b3c4a7ccfcf7a120 ## examples https://github.com/Nickjgniklu/esp_mnist - +## notes +ESP_NN support +Building with #define ESP_NN will enable espressif ansci layer implementations +### example for PIO + -DCONFIG_IDF_TARGET_ESP32S3 -DCONFIG_NN_OPTIMIZED -DCONFIG_IDF_TARGET_ARCH_XTENSA are currently not working but will be required for esp32s3 optimizations +``` +build_flags = + -std=gnu++17 + -DCORE_DEBUG_LEVEL=5 + -DESP_NN + -DCONFIG_IDF_TARGET_ESP32S3 + -DCONFIG_NN_OPTIMIZED + -DCONFIG_IDF_TARGET_ARCH_XTENSA +``` ## TODO # Revalidate arduino versions # mark versions 1.0.2 1.0.3 as bad releases diff --git a/create.sh b/create.sh index 5915e7d..5b84634 100644 --- a/create.sh +++ b/create.sh @@ -26,8 +26,6 @@ find ./src/tensorflow/ ./src/signal/ -type f -exec sed -i -e 's/#include "tools\ echo "Use esp-nn kernals" #replace standard kernals with esp nn cp -a ./src/tensorflow/lite/micro/kernels/esp_nn/. ./src/tensorflow/lite/micro/kernels/ -#add ESP_NN define -sed -i 's/#define TENSORFLOW_LITE_C_COMMON_H_/#define TENSORFLOW_LITE_C_COMMON_H_\n#define ESP_NN 1/g' ./src/tensorflow/lite/c/common.h echo "Making esp-nn files structured for PIO/Arduino" git clone --recurse-submodules https://github.com/espressif/esp-nn.git @@ -48,8 +46,28 @@ find ./src/esp-nn/ -type f -exec sed -i -e 's/#include /#include find ./src/tensorflow/ -type f -exec sed -i -e 's/#include /#include "esp-nn\/esp_nn.h"/g' {} \; find ./src/esp-nn/ -type f -iname "*esp32s3.S" -exec sed -i '1s/^/#ifdef ARCH_ESP32_S3\n/;$a\\n#endif' {} \; -echo "Clean up" +# ESP32 requires TF_LITE_REMOVE_VIRTUAL_DELETE descrutors to be made public +sed -i '/TF_LITE_REMOVE_VIRTUAL_DELETE/d' ./src/tensorflow/lite/micro/memory_planner/linear_memory_planner.h +sed -i '/TF_LITE_REMOVE_VIRTUAL_DELETE/d' ./src/tensorflow/lite/micro/tflite_bridge/micro_error_reporter.h +sed -i '/TF_LITE_REMOVE_VIRTUAL_DELETE/d' ./src/tensorflow/lite/micro/memory_planner/greedy_memory_planner.h + +sed -i 's/private:/TF_LITE_REMOVE_VIRTUAL_DELETE\n&/' ./src/tensorflow/lite/micro/memory_planner/linear_memory_planner.h +sed -i 's/private:/TF_LITE_REMOVE_VIRTUAL_DELETE\n&/' ./src/tensorflow/lite/micro/tflite_bridge/micro_error_reporter.h +sed -i 's/private:/TF_LITE_REMOVE_VIRTUAL_DELETE\n&/' ./src/tensorflow/lite/micro/memory_planner/greedy_memory_planner.h +# change all occurance of #ifndef TF_LITE_STATIC_MEMORY to #ifdef TF_LITE_NOT_STATIC_MEMORY +find ./src/ -type f -exec sed -i -e 's/#ifndef TF_LITE_STATIC_MEMORY/#ifdef TF_LITE_NOT_STATIC_MEMORY/g' {} \; +find ./src/ -type f -exec sed -i -e 's/#if !defined(TF_LITE_STATIC_MEMORY)/#if defined(TF_LITE_NOT_STATIC_MEMORY)/g' {} \; +find ./src/ -type f -exec sed -i -e 's/#ifdef TF_LITE_STATIC_MEMORY/#define TF_LITE_STATIC_MEMORY\n#ifdef TF_LITE_STATIC_MEMORY/g' {} \; + + + + +# Create header file for library +echo "// do not delete" > ./src/ESP_TF.h +echo "// placeholder for arduino library rules" >> ./src/ESP_TF.h + #clean up +echo "Clean up" rm -fr esp-tflite-micro rm -fr esp-nn diff --git a/library.json b/library.json new file mode 100644 index 0000000..beb3914 --- /dev/null +++ b/library.json @@ -0,0 +1,8 @@ +{ + "name": "ESP_TF", + "version": "2.0.0", + "build": { + "srcDir": "src", + "includeDir": "src" + } + } \ No newline at end of file diff --git a/src/ESP_TF.h b/src/ESP_TF.h index b4a5834..cd7bd57 100644 --- a/src/ESP_TF.h +++ b/src/ESP_TF.h @@ -1,2 +1,2 @@ // do not delete -// placeholder for arduino library rules \ No newline at end of file +// placeholder for arduino library rules diff --git a/src/tensorflow/lite/c/common.h b/src/tensorflow/lite/c/common.h index b0b7426..8a8b513 100644 --- a/src/tensorflow/lite/c/common.h +++ b/src/tensorflow/lite/c/common.h @@ -27,7 +27,6 @@ limitations under the License. #ifndef TENSORFLOW_LITE_C_COMMON_H_ #define TENSORFLOW_LITE_C_COMMON_H_ -#define ESP_NN 1 #include "tensorflow/lite/core/c/common.h" diff --git a/src/tensorflow/lite/core/api/flatbuffer_conversions.cc b/src/tensorflow/lite/core/api/flatbuffer_conversions.cc index d36c2b6..e830336 100644 --- a/src/tensorflow/lite/core/api/flatbuffer_conversions.cc +++ b/src/tensorflow/lite/core/api/flatbuffer_conversions.cc @@ -157,7 +157,7 @@ TfLiteRngAlgorithm ConvertRngAlgorithm(RngAlgorithm algorithm) { return kTfLiteRngAlgorithmUnknown; } -#ifndef TF_LITE_STATIC_MEMORY +#ifdef TF_LITE_NOT_STATIC_MEMORY TfLiteStatus ParseOpDataTfLite(const Operator* op, BuiltinOperator op_type, ErrorReporter* error_reporter, BuiltinDataAllocator* allocator, @@ -2890,6 +2890,7 @@ TfLiteStatus ParseOpData(const Operator* op, BuiltinOperator op_type, // * If all the builtin operators were to have their own parse functions, or we // were ok with some amount of code duplication, then this split of the .cc // files would be a lot more feasible. +#define TF_LITE_STATIC_MEMORY #ifdef TF_LITE_STATIC_MEMORY TF_LITE_REPORT_ERROR( error_reporter, diff --git a/src/tensorflow/lite/core/c/common.cc b/src/tensorflow/lite/core/c/common.cc index 7afecdb..7c2c449 100644 --- a/src/tensorflow/lite/core/c/common.cc +++ b/src/tensorflow/lite/core/c/common.cc @@ -15,7 +15,7 @@ limitations under the License. #include "tensorflow/lite/core/c/common.h" -#ifndef TF_LITE_STATIC_MEMORY +#ifdef TF_LITE_NOT_STATIC_MEMORY #include #endif // TF_LITE_STATIC_MEMORY @@ -67,7 +67,7 @@ int TfLiteVarArrayEqual(const T* const a, const T* const b) { return TfLiteVarArrayEqualsArray(a, b->size, b->data); } -#ifndef TF_LITE_STATIC_MEMORY +#ifdef TF_LITE_NOT_STATIC_MEMORY template T* TfLiteVarArrayCreate(const int size) { @@ -119,7 +119,7 @@ int TfLiteIntArrayEqualsArray(const TfLiteIntArray* a, int b_size, return TfLiteVarArrayEqualsArray(a, b_size, b_data); } -#ifndef TF_LITE_STATIC_MEMORY +#ifdef TF_LITE_NOT_STATIC_MEMORY TfLiteIntArray* TfLiteIntArrayCreate(int size) { return TfLiteVarArrayCreate(size); @@ -137,7 +137,7 @@ int TfLiteFloatArrayGetSizeInBytes(int size) { return TfLiteVarArrayGetSizeInBytes(size); } -#ifndef TF_LITE_STATIC_MEMORY +#ifdef TF_LITE_NOT_STATIC_MEMORY TfLiteFloatArray* TfLiteFloatArrayCreate(int size) { return TfLiteVarArrayCreate(size); diff --git a/src/tensorflow/lite/core/c/common.h b/src/tensorflow/lite/core/c/common.h index ea54be9..cc22504 100644 --- a/src/tensorflow/lite/core/c/common.h +++ b/src/tensorflow/lite/core/c/common.h @@ -126,7 +126,7 @@ typedef struct TfLiteIntArray { /// in bytes. size_t TfLiteIntArrayGetSizeInBytes(int size); -#ifndef TF_LITE_STATIC_MEMORY +#ifdef TF_LITE_NOT_STATIC_MEMORY /// Create a array of a given `size` (uninitialized entries). /// This returns a pointer, that you must free using TfLiteIntArrayFree(). TfLiteIntArray* TfLiteIntArrayCreate(int size); @@ -139,7 +139,7 @@ int TfLiteIntArrayEqual(const TfLiteIntArray* a, const TfLiteIntArray* b); int TfLiteIntArrayEqualsArray(const TfLiteIntArray* a, int b_size, const int b_data[]); -#ifndef TF_LITE_STATIC_MEMORY +#ifdef TF_LITE_NOT_STATIC_MEMORY /// Create a copy of an array passed as `src`. /// You are expected to free memory with TfLiteIntArrayFree TfLiteIntArray* TfLiteIntArrayCopy(const TfLiteIntArray* src); @@ -170,7 +170,7 @@ typedef struct TfLiteFloatArray { /// size in bytes. int TfLiteFloatArrayGetSizeInBytes(int size); -#ifndef TF_LITE_STATIC_MEMORY +#ifdef TF_LITE_NOT_STATIC_MEMORY /// Create a array of a given `size` (uninitialized entries). /// This returns a pointer, that you must free using TfLiteFloatArrayFree(). TfLiteFloatArray* TfLiteFloatArrayCreate(int size); @@ -474,7 +474,7 @@ typedef enum TfLiteCustomAllocationFlags { /// A tensor in the interpreter system which is a wrapper around a buffer of /// data including a dimensionality (or NULL if not currently defined). -#ifndef TF_LITE_STATIC_MEMORY +#ifdef TF_LITE_NOT_STATIC_MEMORY typedef struct TfLiteTensor { /// The data type specification for data stored in `data`. This affects /// what member of `data` union should be used. @@ -692,7 +692,7 @@ typedef struct TfLiteEvalTensor { TfLiteType type; } TfLiteEvalTensor; -#ifndef TF_LITE_STATIC_MEMORY +#ifdef TF_LITE_NOT_STATIC_MEMORY /// Free data memory of tensor `t`. void TfLiteTensorDataFree(TfLiteTensor* t); @@ -1410,7 +1410,7 @@ typedef struct TfLiteOpaqueDelegateBuilder { int64_t flags; } TfLiteOpaqueDelegateBuilder; -#ifndef TF_LITE_STATIC_MEMORY +#ifdef TF_LITE_NOT_STATIC_MEMORY // See c_api_opaque.h. // This declaration in common.h is only for backwards compatibility. // NOTE: This function is part of the TensorFlow Lite Extension APIs, see above. diff --git a/src/tensorflow/lite/core/macros.h b/src/tensorflow/lite/core/macros.h index 1bab15b..8c1d31b 100644 --- a/src/tensorflow/lite/core/macros.h +++ b/src/tensorflow/lite/core/macros.h @@ -65,7 +65,7 @@ limitations under the License. #define TFLITE_HAS_ATTRIBUTE_WEAK 0 #endif -#ifndef TF_LITE_STATIC_MEMORY +#ifdef TF_LITE_NOT_STATIC_MEMORY // maximum size of a valid flatbuffer inline constexpr unsigned int flatbuffer_size_max = 2147483648; // If none zero then the buffer is stored outside of the flatbuffers, string diff --git a/src/tensorflow/lite/kernels/internal/compatibility.h b/src/tensorflow/lite/kernels/internal/compatibility.h index 7ba66ed..75b9ebe 100644 --- a/src/tensorflow/lite/kernels/internal/compatibility.h +++ b/src/tensorflow/lite/kernels/internal/compatibility.h @@ -76,7 +76,7 @@ limitations under the License. #define TFLITE_CHECK_LT(x, y) ((x) < (y)) ? (void)0 : TFLITE_ABORT #endif -#ifndef TF_LITE_STATIC_MEMORY +#ifdef TF_LITE_NOT_STATIC_MEMORY // TODO(b/162019032): Consider removing these type-aliases. using int8 = std::int8_t; using uint8 = std::uint8_t; diff --git a/src/tensorflow/lite/kernels/kernel_util.cc b/src/tensorflow/lite/kernels/kernel_util.cc index 6833f6a..b02c4f0 100644 --- a/src/tensorflow/lite/kernels/kernel_util.cc +++ b/src/tensorflow/lite/kernels/kernel_util.cc @@ -21,7 +21,8 @@ limitations under the License. #include #include #include -#ifndef TF_LITE_STATIC_MEMORY + +#ifdef TF_LITE_NOT_STATIC_MEMORY #include #include "tensorflow/lite/array.h" @@ -151,7 +152,7 @@ const TfLiteTensor* GetOptionalInputTensor(const TfLiteContext* context, return GetInput(context, node, index); } -#ifndef TF_LITE_STATIC_MEMORY +#ifdef TF_LITE_NOT_STATIC_MEMORY TfLiteTensor* GetTemporary(TfLiteContext* context, const TfLiteNode* node, int index) { const int tensor_index = ValidateTensorIndexing( @@ -413,7 +414,7 @@ bool HaveSameShapes(const TfLiteTensor* input1, const TfLiteTensor* input2) { return TfLiteIntArrayEqual(input1->dims, input2->dims); } -#ifndef TF_LITE_STATIC_MEMORY +#ifdef TF_LITE_NOT_STATIC_MEMORY TfLiteStatus GetOutputShapeFromInput(TfLiteContext* context, const TfLiteTensor* input, TfLiteIntArray** output_shape) { @@ -580,7 +581,7 @@ bool IsMobilePlatform() { } bool HasUnspecifiedDimension(const TfLiteTensor* tensor) { -#ifndef TF_LITE_STATIC_MEMORY +#ifdef TF_LITE_NOT_STATIC_MEMORY if (tensor->dims_signature) { for (int i : TfLiteIntArrayView(tensor->dims_signature)) { if (i == -1) return true; diff --git a/src/tensorflow/lite/kernels/kernel_util.h b/src/tensorflow/lite/kernels/kernel_util.h index e318118..4f2e4a7 100644 --- a/src/tensorflow/lite/kernels/kernel_util.h +++ b/src/tensorflow/lite/kernels/kernel_util.h @@ -18,7 +18,7 @@ limitations under the License. #include #include -#ifndef TF_LITE_STATIC_MEMORY +#ifdef TF_LITE_NOT_STATIC_MEMORY #include #endif // TF_LITE_STATIC_MEMORY @@ -100,7 +100,7 @@ TfLiteStatus GetOutputSafe(const TfLiteContext* context, const TfLiteNode* node, const TfLiteTensor* GetOptionalInputTensor(const TfLiteContext* context, const TfLiteNode* node, int index); -#ifndef TF_LITE_STATIC_MEMORY +#ifdef TF_LITE_NOT_STATIC_MEMORY // Note: You must check if result is not null: // // TfLiteTensor* my_tensor = GetTemporary(context, node, kMyTensorIdx); @@ -162,7 +162,7 @@ inline int NumOutputs(const TfLiteNode* node) { return node->outputs == nullptr ? 0 : node->outputs->size; } -#ifndef TF_LITE_STATIC_MEMORY +#ifdef TF_LITE_NOT_STATIC_MEMORY inline int NumIntermediates(const TfLiteNode* node) { return node->intermediates->size; } @@ -214,7 +214,7 @@ inline bool IsConstantOrPersistentTensor(const TfLiteTensor* tensor) { inline bool IsDynamicTensor(const TfLiteTensor* tensor) { return tensor->allocation_type == kTfLiteDynamic; } -#ifndef TF_LITE_STATIC_MEMORY +#ifdef TF_LITE_NOT_STATIC_MEMORY // Sets tensor to dynamic. inline void SetTensorToDynamic(TfLiteTensor* tensor) { if (tensor->allocation_type != kTfLiteDynamic) { @@ -302,7 +302,7 @@ void CalculateActivationRange(TfLiteFusedActivation activation, // Return true if the given tensors have the same shape. bool HaveSameShapes(const TfLiteTensor* input1, const TfLiteTensor* input2); -#if !defined(TF_LITE_STATIC_MEMORY) +#if defined(TF_LITE_NOT_STATIC_MEMORY) // Gets the output shape from the input tensor. TfLiteStatus GetOutputShapeFromInput(TfLiteContext* context, const TfLiteTensor* input, diff --git a/src/tensorflow/lite/micro/compatibility.h b/src/tensorflow/lite/micro/compatibility.h index 49acb28..343a346 100644 --- a/src/tensorflow/lite/micro/compatibility.h +++ b/src/tensorflow/lite/micro/compatibility.h @@ -22,6 +22,7 @@ limitations under the License. // nothing to avoid linking in ::delete(). // This macro needs to be included in all subclasses of a virtual base class in // the private section. +#define TF_LITE_STATIC_MEMORY #ifdef TF_LITE_STATIC_MEMORY #define TF_LITE_REMOVE_VIRTUAL_DELETE \ void operator delete(void* p) {} diff --git a/src/tensorflow/lite/micro/memory_planner/greedy_memory_planner.h b/src/tensorflow/lite/micro/memory_planner/greedy_memory_planner.h index 487f901..e67982c 100644 --- a/src/tensorflow/lite/micro/memory_planner/greedy_memory_planner.h +++ b/src/tensorflow/lite/micro/memory_planner/greedy_memory_planner.h @@ -111,10 +111,9 @@ class GreedyMemoryPlanner : public MicroMemoryPlanner { // after invocation. Do to the fact that tensors that tensor data for tensors // that aren't being used during a phase of invocation are overwritten. bool preserves_all_tensors() const override { return false; } - TF_LITE_REMOVE_VIRTUAL_DELETE - - private: + TF_LITE_REMOVE_VIRTUAL_DELETE +private: // Whether a buffer is active in a given time range. bool DoesEntryOverlapInTime(const ListEntry* entry, const int first_time_used, const int last_time_used) const; diff --git a/src/tensorflow/lite/micro/memory_planner/linear_memory_planner.h b/src/tensorflow/lite/micro/memory_planner/linear_memory_planner.h index 12ebb6b..a32658d 100644 --- a/src/tensorflow/lite/micro/memory_planner/linear_memory_planner.h +++ b/src/tensorflow/lite/micro/memory_planner/linear_memory_planner.h @@ -38,9 +38,9 @@ class LinearMemoryPlanner : public MicroMemoryPlanner { // Returns True because the LinearMemoryPlanner preserves all tensors after // invocation. bool preserves_all_tensors() const override { return true; } - TF_LITE_REMOVE_VIRTUAL_DELETE - private: + TF_LITE_REMOVE_VIRTUAL_DELETE +private: static constexpr int kMaxBufferCount = 1024; size_t buffer_offsets_[kMaxBufferCount]; int current_buffer_count_; diff --git a/src/tensorflow/lite/micro/tflite_bridge/micro_error_reporter.h b/src/tensorflow/lite/micro/tflite_bridge/micro_error_reporter.h index 110a81d..bbcb08a 100644 --- a/src/tensorflow/lite/micro/tflite_bridge/micro_error_reporter.h +++ b/src/tensorflow/lite/micro/tflite_bridge/micro_error_reporter.h @@ -27,9 +27,9 @@ class MicroErrorReporter : public ErrorReporter { public: ~MicroErrorReporter() override {} int Report(const char* format, va_list args) override; - TF_LITE_REMOVE_VIRTUAL_DELETE - private: + TF_LITE_REMOVE_VIRTUAL_DELETE +private: }; } // namespace tflite