# # SPDX-FileCopyrightText: Copyright 2021-2024 Arm Limited and/or its affiliates # # SPDX-License-Identifier: Apache-2.0 # # Licensed under the Apache License, Version 2.0 (the License); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an AS IS BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # add_library(tflu STATIC) # Tensorflow Lite Micro (TFLM) build variables. set(TFLM_PATH "${TENSORFLOW_PATH}/tensorflow/lite/micro") set(TFLM_BUILD_TYPE "release" CACHE STRING "TFLM build type, can be release, release_with_logs or debug") set(TFLM_OPTIMIZATION_LEVEL "-O2" CACHE STRING "TFLM kernel optimization level") set(TFLM_OPTIMIZE_KERNELS_FOR "speed" CACHE STRING "TFLM kernel implementation optimization type, can be speed or size") ############################################################################# # Helpers ############################################################################# include(FetchContent) # Download third party macro(download_third_party target) cmake_policy(PUSH) if(POLICY CMP0135) cmake_policy(SET CMP0135 NEW) endif() cmake_parse_arguments(DOWNLOAD "" "URL;URL_MD5;SOURCE_DIR" "" ${ARGN}) message("Downloading ${DOWNLOAD_URL}") FetchContent_Declare(${target} URL ${DOWNLOAD_URL} URL_MD5 ${DOWNLOAD_MD5} SOURCE_DIR ${DOWNLOAD_SOURCE_DIR} ${PATCH_COMMAND}) FetchContent_GetProperties(${target}) if (NOT ${target}_POPULATED) FetchContent_Populate(${target}) endif() cmake_policy(POP) endmacro() function(tensorflow_source_exists RESULT TARGET SOURCE) get_target_property(SOURCES ${TARGET} SOURCES) # Loop over source files already added to this target foreach(TMP ${SOURCES}) get_filename_component(SOURCE_NAME ${SOURCE} NAME) get_filename_component(TMP_NAME ${TMP} NAME) # Check if file already exists if (${SOURCE_NAME} STREQUAL ${TMP_NAME}) set(${RESULT} TRUE PARENT_SCOPE) return() endif() endforeach() set(${RESULT} FALSE PARENT_SCOPE) endfunction() function(tensorflow_target_sources_glob TARGET GLOB UNIQUE) foreach (EXPR ${ARGN}) # Find files matching globbing expression file(${GLOB} SOURCES ${EXPR}) # Remove tests list(FILTER SOURCES EXCLUDE REGEX ".*_test\.cc") # Add files to target foreach(SOURCE ${SOURCES}) tensorflow_source_exists(SOURCE_EXISTS ${TARGET} ${SOURCE}) if (NOT ${UNIQUE} OR NOT ${SOURCE_EXISTS}) target_sources(${TARGET} PRIVATE ${SOURCE}) endif() endforeach() endforeach() endfunction() ############################################################################# # Download thirdparty ############################################################################# # Flatbuffers # Synch revision with 'tensorflow/lite/micro/tools/make/flatbuffers_download.sh' download_third_party(tensorflow-flatbuffers URL "https://github.com/google/flatbuffers/archive/v23.5.26.zip" URL_MD5 e87e8acd8e2d53653387ad78720316e2) target_include_directories(tflu PUBLIC ${tensorflow-flatbuffers_SOURCE_DIR}/include) target_compile_definitions(tflu PUBLIC FLATBUFFERS_LOCALE_INDEPENDENT=0) # Gemlowp # Synch revision with 'tensorflow/lite/micro/tools/make/third_party_downloads.inc' download_third_party(tensorflow-gemlowp URL "https://github.com/google/gemmlowp/archive/719139ce755a0f31cbf1c37f7f98adcc7fc9f425.zip" URL_MD5 7e8191b24853d75de2af87622ad293ba) target_include_directories(tflu PUBLIC ${tensorflow-gemlowp_SOURCE_DIR}) # Ruy # Synch revision with 'tensorflow/lite/micro/tools/make/third_party_downloads.inc' download_third_party(tensorflow-ruy URL "https://github.com/google/ruy/archive/d37128311b445e758136b8602d1bbd2a755e115d.zip" URL_MD5 abf7a91eb90d195f016ebe0be885bb6e) target_include_directories(tflu PUBLIC ${tensorflow-ruy_SOURCE_DIR}) ############################################################################# # CMSIS-NN ############################################################################# if (NOT ${CORE_SOFTWARE_ACCELERATOR} STREQUAL "CPU") add_subdirectory(${CMSIS_NN_PATH} cmsis_nn) target_compile_options(cmsis-nn PRIVATE ${TFLM_OPTIMIZATION_LEVEL}) tensorflow_target_sources_glob(tflu GLOB TRUE ${TFLM_PATH}/kernels/cmsis_nn/*.cc) target_include_directories(tflu PUBLIC ${CMSIS_NN_PATH}) target_compile_definitions(tflu PUBLIC CMSIS_NN) target_link_libraries(tflu PUBLIC cmsis-nn) endif() ############################################################################# # Ethos-U ############################################################################# if(TARGET ethosu_core_driver) tensorflow_target_sources_glob(tflu GLOB TRUE ${TFLM_PATH}/kernels/ethos_u/*.cc) target_link_libraries(tflu PUBLIC ethosu_core_driver) endif() ############################################################################# # Cortex-M generic ############################################################################# tensorflow_target_sources_glob(tflu GLOB TRUE ${TFLM_PATH}/cortex_m_generic/*.cc) target_include_directories(tflu PRIVATE ${TFLM_PATH}/cortex_m_generic) # For DWT/PMU counters target_link_libraries(tflu PRIVATE cmsis_device) target_compile_definitions(tflu PRIVATE ${ARM_CPU}) if(("${ARM_CPU}" STREQUAL "ARMCM55") OR ("${ARM_CPU}" STREQUAL "ARMCM85")) target_compile_definitions(tflu PRIVATE ARM_MODEL_USE_PMU_COUNTERS) endif() ############################################################################# # Tensorflow micro lite ############################################################################# tensorflow_target_sources_glob(tflu GLOB TRUE ${TFLM_PATH}/*.cc ${TFLM_PATH}/arena_allocator/*.cc ${TFLM_PATH}/memory_planner/*.cc ${TFLM_PATH}/kernels/*.cc ${TFLM_PATH}/tflite_bridge/*.cc) tensorflow_target_sources_glob(tflu GLOB_RECURSE FALSE ${TFLM_PATH}/../c/*.cc ${TFLM_PATH}/../core/*.cc ${TFLM_PATH}/../core/api/*.cc ${TFLM_PATH}/../kernels/*.cc ${TFLM_PATH}/../schema/*.cc) target_include_directories(tflu PUBLIC ${TENSORFLOW_PATH}) target_compile_definitions(tflu PUBLIC TF_LITE_STATIC_MEMORY $<$:NDEBUG;TF_LITE_STRIP_ERROR_STRINGS> $<$:NDEBUG> $<$:KERNELS_OPTIMIZED_FOR_SPEED> $<$:KERNELS_OPTIMIZED_FOR_SIZE>) target_compile_options(tflu PRIVATE ${TFLM_OPTIMIZATION_LEVEL} -fno-unwind-tables -ffunction-sections -fdata-sections -fmessage-length=0 -funsigned-char "$<$:-fno-rtti;-fno-exceptions;-fno-threadsafe-statics>" -Wall -Wextra -Wdouble-promotion -Wmissing-field-initializers -Wshadow -Wstrict-aliasing -Wswitch -Wunused-variable -Wunused-function -Wvla PUBLIC -Wno-cast-align -Wno-null-dereference -Wno-unused-parameter -Wno-switch-default ) # Install libraries and header files install(TARGETS tflu DESTINATION "lib")