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 <anchao@lixiang.com>
This commit is contained in:
chao an 2024-12-02 10:27:44 +08:00 committed by Xiang Xiao
parent 0b3428942f
commit 296d5d15af
3 changed files with 107 additions and 2 deletions

View file

@ -0,0 +1,26 @@
From 971d7129e14c012bb10215cbc7370c3176490617 Mon Sep 17 00:00:00 2001
From: chao an <anchao@lixiang.com>
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 <anchao@lixiang.com>
---
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

View file

@ -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 <tflite data file> <cc header file>`
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()

View file

@ -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