From 296d5d15af56d1a39876bf1ea04cf2274a78780b Mon Sep 17 00:00:00 2001 From: chao an Date: Mon, 2 Dec 2024 10:27:44 +0800 Subject: [PATCH] tflm: add tflm hello world example into nuttx build 1. add tflm hello world example into nuttx build 2. add tflm model convert flow Test on sim/tflm $ cmake -B build -DBOARD_CONFIG=sim/tflm -GNinja $ cmake --build build $ ./build/nuttx NuttShell (NSH) NuttX-10.4.0 nsh> tflm_hello 0 (id=0): size=16, offset=0, first_used=0 last_used=1 1 (id=1): size=64, offset=64, first_used=1 last_used=2 2 (id=2): size=64, offset=0, first_used=2 last_used=3 3 (id=3): size=16, offset=64, first_used=3 last_used=3 0: 0000000000...................................................................... (1k) 1: 0000000000..............................1111111111111111111111111111111111111111 (1k) 2: 22222222222222222222222222222222222222221111111111111111111111111111111111111111 (1k) 3: 22222222222222222222222222222222222222223333333333.............................. (1k) "Unique Tag","Total ticks across all events with that tag." FULLY_CONNECTED, 0 "total number of ticks", 0 [RecordingMicroAllocator] Arena allocation total 2344 bytes [RecordingMicroAllocator] Arena allocation head 128 bytes [RecordingMicroAllocator] Arena allocation tail 2216 bytes [RecordingMicroAllocator] 'TfLiteEvalTensor data' used 240 bytes with alignment overhead (requested 240 bytes for 10 allocations) [RecordingMicroAllocator] 'Persistent TfLiteTensor data' used 128 bytes with alignment overhead (requested 128 bytes for 2 tensors) [RecordingMicroAllocator] 'Persistent buffer data' used 1152 bytes with alignment overhead (requested 1100 bytes for 7 allocations) [RecordingMicroAllocator] 'NodeAndRegistration struct' used 192 bytes with alignment overhead (requested 192 bytes for 3 NodeAndRegistration structs) 0 (id=0): size=16, offset=0, first_used=0 last_used=1 1 (id=1): size=64, offset=64, first_used=1 last_used=2 2 (id=2): size=64, offset=0, first_used=2 last_used=3 3 (id=3): size=16, offset=64, first_used=3 last_used=3 0: 0000000000...................................................................... (1k) 1: 0000000000..............................1111111111111111111111111111111111111111 (1k) 2: 22222222222222222222222222222222222222221111111111111111111111111111111111111111 (1k) 3: 22222222222222222222222222222222222222223333333333.............................. (1k) 0 (id=0): size=16, offset=16, first_used=0 last_used=1 1 (id=1): size=16, offset=0, first_used=1 last_used=2 2 (id=2): size=16, offset=16, first_used=2 last_used=3 3 (id=3): size=16, offset=0, first_used=3 last_used=3 0: ................0000000000000000................................................ (1k) 1: 11111111111111110000000000000000................................................ (1k) 2: 11111111111111112222222222222222................................................ (1k) 3: 33333333333333332222222222222222................................................ (1k) ~~~ALL TESTS PASSED~~~ nsh> Signed-off-by: chao an --- ...n-C-to-main-function-to-avoid-c-mang.patch | 26 ++++++++ mlearning/tflite-micro/CMakeLists.txt | 64 +++++++++++++++++++ mlearning/tflite-micro/Kconfig | 19 +++++- 3 files changed, 107 insertions(+), 2 deletions(-) create mode 100644 mlearning/tflite-micro/0004-tflite-add-extern-C-to-main-function-to-avoid-c-mang.patch diff --git a/mlearning/tflite-micro/0004-tflite-add-extern-C-to-main-function-to-avoid-c-mang.patch b/mlearning/tflite-micro/0004-tflite-add-extern-C-to-main-function-to-avoid-c-mang.patch new file mode 100644 index 000000000..84f0bc028 --- /dev/null +++ b/mlearning/tflite-micro/0004-tflite-add-extern-C-to-main-function-to-avoid-c-mang.patch @@ -0,0 +1,26 @@ +From 971d7129e14c012bb10215cbc7370c3176490617 Mon Sep 17 00:00:00 2001 +From: chao an +Date: Mon, 2 Dec 2024 10:23:12 +0800 +Subject: [PATCH] tflite: add extern "C" to main function to avoid c++ mangling + +Signed-off-by: chao an +--- + tensorflow/lite/micro/examples/hello_world/hello_world_test.cc | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tensorflow/lite/micro/examples/hello_world/hello_world_test.cc b/tensorflow/lite/micro/examples/hello_world/hello_world_test.cc +index ec23571a..24982e90 100644 +--- a/tensorflow/lite/micro/examples/hello_world/hello_world_test.cc ++++ b/tensorflow/lite/micro/examples/hello_world/hello_world_test.cc +@@ -149,7 +149,7 @@ TfLiteStatus LoadQuantModelAndPerformInference() { + return kTfLiteOk; + } + +-int main(int argc, char* argv[]) { ++extern "C" int main(int argc, char* argv[]) { + tflite::InitializeTarget(); + TF_LITE_ENSURE_STATUS(ProfileMemoryAndLatency()); + TF_LITE_ENSURE_STATUS(LoadFloatModelAndPerformInference()); +-- +2.34.1 + diff --git a/mlearning/tflite-micro/CMakeLists.txt b/mlearning/tflite-micro/CMakeLists.txt index 788408607..482e920b7 100644 --- a/mlearning/tflite-micro/CMakeLists.txt +++ b/mlearning/tflite-micro/CMakeLists.txt @@ -42,6 +42,8 @@ if(CONFIG_TFLITEMICRO) ${TFLITE_MICRO_DIR} -p1 < ${CMAKE_CURRENT_LIST_DIR}/0002-quantize-int8.patch && patch -d ${TFLITE_MICRO_DIR} -p1 < ${CMAKE_CURRENT_LIST_DIR}/0003-mean-int8.patch + && patch -d ${TFLITE_MICRO_DIR} -p1 < + ${CMAKE_CURRENT_LIST_DIR}/0004-tflite-add-extern-C-to-main-function-to-avoid-c-mang.patch DOWNLOAD_NO_PROGRESS true TIMEOUT 30) @@ -162,6 +164,42 @@ if(CONFIG_TFLITEMICRO) target_sources(tflite_micro PRIVATE ${TFLITE_MICRO_SRCS}) target_include_directories(tflite_micro PUBLIC ${INCDIR}) + # Help function to generate tflite data + # + # TFLM is designed to run on microcontrollers and other platforms without + # dynamic memory allocation and without filesystems. This means that data + # files such as TFLite models and test inputs must be built into the binary. + # + # Historically, data files have been included as cc arrays generated manually + # using `xxd -i ` + + function(tflite_generate_data in out declare) + set(tflm_data_out + ${CMAKE_BINARY_DIR}/apps/mlearning/tflite-micro/tflite-micro/${out}) + if(NOT EXISTS ${tflm_data_out}) + get_filename_component(TFLM_OUT ${tflm_data_out} DIRECTORY) + if(NOT EXISTS ${TFLM_OUT}) + file(MAKE_DIRECTORY ${TFLM_OUT}) + endif() + execute_process(COMMAND xxd -i ${TFLITE_MICRO_DIR}/${in} ${tflm_data_out}) + + # Replace array name + + string(REGEX REPLACE "([/|.])" "_" tflm_data_define + ${TFLITE_MICRO_DIR}/${in}) + string(REPLACE "-" "_" _tflm_data_define ${tflm_data_define}) + file(READ ${tflm_data_out} tflm_contents) + encode_brackets(tflm_contents) + encode_semicolon(tflm_contents) + string(REPLACE ${_tflm_data_define} ${declare} tflm_contents + ${tflm_contents}) + decode_semicolon(tflm_contents) + decode_brackets(tflm_contents) + file(WRITE ${tflm_data_out} "${tflm_contents}") + + endif() + endfunction() + if(CONFIG_TFLITEMICRO_TOOL) nuttx_add_application( NAME @@ -178,4 +216,30 @@ if(CONFIG_TFLITEMICRO) ${COMMON_FLAGS}) endif() + if(CONFIG_TFLITEMICRO_HELLOWORLD) + tflite_generate_data( + tensorflow/lite/micro/examples/hello_world/models/hello_world_float.tflite + tensorflow/lite/micro/examples/hello_world/models/hello_world_float_model_data.h + g_hello_world_float_model_data) + tflite_generate_data( + tensorflow/lite/micro/examples/hello_world/models/hello_world_int8.tflite + tensorflow/lite/micro/examples/hello_world/models/hello_world_int8_model_data.h + g_hello_world_int8_model_data) + + nuttx_add_application( + NAME + tflm_hello + STACKSIZE + ${CONFIG_TFLITEMICRO_HELLOWORLD_STACKSIZE} + PRIORITY + ${CONFIG_TFLITEMICRO_HELLOWORLD_PRIORITY} + SRCS + ${TFLITE_MICRO_DIR}/tensorflow/lite/micro/examples/hello_world/hello_world_test.cc + INCLUDE_DIRECTORIES + ${INCDIR} + ${CMAKE_BINARY_DIR}/apps/mlearning/tflite-micro/tflite-micro + COMPILE_FLAGS + ${COMMON_FLAGS}) + endif() + endif() diff --git a/mlearning/tflite-micro/Kconfig b/mlearning/tflite-micro/Kconfig index b7eaf75cc..06193fff1 100644 --- a/mlearning/tflite-micro/Kconfig +++ b/mlearning/tflite-micro/Kconfig @@ -41,5 +41,20 @@ config TFLITEMICRO_TOOL_STACKSIZE int "tflite-micro tool stacksize" default 4096 -endif -endif +endif # TFLITEMICRO_TOOL + +config TFLITEMICRO_HELLOWORLD + bool "Enable Tflite-micro hello world example" + default n + +if TFLITEMICRO_HELLOWORLD +config TFLITEMICRO_HELLOWORLD_PRIORITY + int "Tflite-micro hello world priority" + default 100 + +config TFLITEMICRO_HELLOWORLD_STACKSIZE + int "Tflite-micro hello world stacksize" + default 4096 + +endif # TFLITEMICRO_HELLOWORLD +endif # TFLITEMICRO