Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Initial support of CMake for TensorFlow Lite
README.md is also added. These commands show a way to use it. $ git clone https://github.com/tensorflow/tensorflow.git tensorflow_src $ mkdir tflite_build && cd tflite_build $ cmake ../tensorflow_src/tensorflow/lite $ cmake --build . -j PiperOrigin-RevId: 327736060 Change-Id: I35acf01b0b33156db5537c146c35de7dc534bb7e
- Loading branch information
1 parent
d523827
commit ec59a62
Showing
23 changed files
with
1,957 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,341 @@ | ||
# | ||
# Copyright 2020 The TensorFlow Authors. All Rights Reserved. | ||
# | ||
# 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 | ||
# | ||
# https://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. | ||
|
||
|
||
# Builds the Tensorflow Lite runtime. | ||
# | ||
# WARNING: This is an experimental that is subject to change. | ||
# This has only been tested on Windows, Linux and macOS. | ||
# | ||
# The following are not currently supported: | ||
# - GPU acceleration | ||
# - Android | ||
# - iOS | ||
# - Micro backend | ||
# - Tests | ||
# - Many features in experimental | ||
# - Host Tools (i.e conversion / analysis tools etc.) | ||
|
||
cmake_minimum_required(VERSION 3.16) | ||
# Double colon in target name means ALIAS or IMPORTED target. | ||
cmake_policy(SET CMP0028 NEW) | ||
# Enable MACOSX_RPATH (@rpath) for built dynamic libraries. | ||
cmake_policy(SET CMP0042 NEW) | ||
project(tensorflow-lite C CXX) | ||
set(TENSORFLOW_SOURCE_DIR "" CACHE PATH | ||
"Directory that contains the TensorFlow project" | ||
) | ||
if(NOT TENSORFLOW_SOURCE_DIR) | ||
set(TENSORFLOW_SOURCE_DIR "${CMAKE_SOURCE_DIR}/../../") | ||
endif() | ||
set(TF_SOURCE_DIR "${TENSORFLOW_SOURCE_DIR}/tensorflow") | ||
set(TFLITE_SOURCE_DIR "${CMAKE_SOURCE_DIR}") | ||
set(CMAKE_MODULE_PATH "${TFLITE_SOURCE_DIR}/tools/cmake/modules" ${CMAKE_MODULE_PATH}) | ||
set(CMAKE_PREFIX_PATH "${TFLITE_SOURCE_DIR}/tools/cmake/modules" ${CMAKE_PREFIX_PATH}) | ||
|
||
option(TFLITE_ENABLE_RUY "Enable experimental RUY integration" OFF) | ||
option(TFLITE_ENABLE_RESOURCE "Enable experimental support for resources" ON) | ||
option(TFLITE_ENABLE_NNAPI "Enable NNAPI (Android only)." ON) | ||
option(TFLITE_ENABLE_MMAP "Enable MMAP (unsupported on Windows)" ON) | ||
option(TFLITE_ENABLE_GPU "Enable GPU (not supported)" OFF) | ||
# This must be enabled when converting from TF models with SELECT_TF_OPS | ||
# enabled. | ||
# https://www.tensorflow.org/lite/guide/ops_select#converting_the_model | ||
# This is currently not supported. | ||
option(TFLITE_ENABLE_FLEX "Enable SELECT_TF_OPS" OFF) # TODO: Add support | ||
option(TFLITE_ENABLE_XNNPACK "Enable XNNPACK backend" OFF) # TODO: Add XNNPACK | ||
option(TFLITE_ENABLE_PROFILING "Enable profiling" OFF) | ||
set(CMAKE_CXX_STANDARD 14) # Some components require C++14. | ||
set(CMAKE_CXX_STANDARD_REQUIRED ON) | ||
set(_TFLITE_ENABLE_NNAPI "${TFLITE_ENABLE_NNAPI}") | ||
if(NOT "${CMAKE_SYSTEM_NAME}" STREQUAL "Android") | ||
set(_TFLITE_ENABLE_NNAPI OFF) | ||
endif() | ||
set(_TFLITE_ENABLE_MMAP "${TFLITE_ENABLE_MMAP}") | ||
if(${CMAKE_SYSTEM_NAME} MATCHES "Windows") | ||
# See https://github.com/tensorflow/tensorflow/blob/\ | ||
# 2b96f3662bd776e277f86997659e61046b56c315/tensorflow/lite/tools/make/\ | ||
# Makefile#L157 | ||
set(_TFLITE_ENABLE_MMAP OFF) | ||
endif() | ||
# Simplifies inclusion of non-test sources and headers from a directory. | ||
# SOURCE_DIR: Directory to search for files. | ||
# SOURCES_VAR: Variable to append with all matching *.cc and *.h files. | ||
# [FILTER expression0 .. expressionN]: | ||
# Additional regular expressions to filter the set of matching | ||
# files. By default, all files ending in "(_test|test_util)\\.(cc|h)" are | ||
# removed. | ||
# [RECURSE]: Whether to recursively search SOURCE_DIR. | ||
macro(populate_source_vars SOURCE_DIR SOURCES_VAR) | ||
cmake_parse_arguments(ARGS "RECURSE" "" "FILTER" ${ARGN}) | ||
if(ARGS_RECURSE) | ||
set(GLOB_OP GLOB_RECURSE) | ||
else() | ||
set(GLOB_OP GLOB) | ||
endif() | ||
set(DEFAULT_FILE_FILTER ".*(_test|test_util)\\.(c|cc|h)$") | ||
file(${GLOB_OP} FOUND_SOURCES "${SOURCE_DIR}/*.*") | ||
list(FILTER FOUND_SOURCES INCLUDE REGEX ".*\\.(c|cc|h)$") | ||
list(FILTER FOUND_SOURCES EXCLUDE REGEX "${DEFAULT_FILE_FILTER}") | ||
foreach(FILE_FILTER ${ARGS_FILTER}) | ||
list(FILTER FOUND_SOURCES EXCLUDE REGEX "${FILE_FILTER}") | ||
endforeach() | ||
list(APPEND ${SOURCES_VAR} ${FOUND_SOURCES}) | ||
endmacro() | ||
# Simplifies inclusion of non-test sources and headers from a directory | ||
# relative to TFLITE_SOURCE_DIR. See populate_source_vars() for the | ||
# description of arguments including and following SOURCES_VAR. | ||
macro(populate_tflite_source_vars RELATIVE_DIR SOURCES_VAR) | ||
populate_source_vars( | ||
"${TFLITE_SOURCE_DIR}/${RELATIVE_DIR}" ${SOURCES_VAR} ${ARGN} | ||
) | ||
endmacro() | ||
# Simplifies inclusion of non-test sources and headers from a directory | ||
# relative to TF_SOURCE_DIR. See populate_source_vars() for the description of | ||
# arguments including and following SOURCES_VAR. | ||
macro(populate_tf_source_vars RELATIVE_DIR SOURCES_VAR) | ||
populate_source_vars( | ||
"${TF_SOURCE_DIR}/${RELATIVE_DIR}" ${SOURCES_VAR} ${ARGN} | ||
) | ||
endmacro() | ||
# Find TensorFlow Lite dependencies. | ||
find_package(absl REQUIRED CONFIG) | ||
find_package(eigen REQUIRED) | ||
find_package(farmhash REQUIRED) | ||
find_package(fft2d REQUIRED) | ||
find_package(flatbuffers REQUIRED) | ||
find_package(gemmlowp REQUIRED) | ||
find_package(neon2sse REQUIRED) | ||
find_package(ruy REQUIRED) | ||
# Generate TensorFlow Lite FlatBuffer code. | ||
# This is not currently neccessary since the generated code is checked into | ||
# the repository but it would likely be preferable to do this in future. | ||
# NOTE: This will not work for cross compilation (e.g for iOS, Android etc.) | ||
# as flatc needs to be compiled with the host toolchain and this currently | ||
# builds with the target toolchain. Instead this should recursively call | ||
# cmake with the default host toolchain to build flatc. | ||
set(TFLITE_FLATBUFFERS_SCHEMAS "${TFLITE_SOURCE_DIR}/schema/schema.fbs") | ||
set(TFLITE_FLATBUFFERS_GEN_DIR | ||
"${CMAKE_BINARY_DIR}/flatbuffers_generated/" | ||
) | ||
set(TFLITE_FLATBUFFERS_HDRS "") | ||
foreach(INPUT_SCHEMA ${TFLITE_FLATBUFFERS_SCHEMAS}) | ||
file(RELATIVE_PATH FILENAME "${TENSORFLOW_SOURCE_DIR}" "${INPUT_SCHEMA}") | ||
get_filename_component(OUTPUT_DIR | ||
"${TFLITE_FLATBUFFERS_GEN_DIR}/${FILENAME}" DIRECTORY | ||
) | ||
get_filename_component(OUTPUT_BASENAME | ||
"${FILENAME}" NAME_WE | ||
) | ||
set(OUTPUT_FILENAME "${OUTPUT_DIR}/${OUTPUT_BASENAME}_generated.h") | ||
list(APPEND TFLITE_FLATBUFFERS_HDRS "${OUTPUT_FILENAME}") | ||
add_custom_command( | ||
OUTPUT "${OUTPUT_FILENAME}" | ||
COMMAND flatc | ||
--cpp | ||
--gen-mutable | ||
--gen-object-api | ||
--reflect-names | ||
-I "${TENSORFLOW_SOURCE_DIR}" | ||
-o "${OUTPUT_DIR}" | ||
"${INPUT_SCHEMA}" | ||
DEPENDS | ||
"${INPUT_SCHEMA}") | ||
endforeach() | ||
set(TF_TARGET_PRIVATE_OPTIONS "") | ||
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang$") | ||
# TensorFlow uses a heap of deprecated proto fields so surpress these | ||
# warnings until they're fixed. | ||
list(APPEND TF_TARGET_PRIVATE_OPTIONS "-Wno-deprecated-declarations") | ||
endif() | ||
# Additional compiler flags used when compiling TF Lite. | ||
set(TFLITE_TARGET_PUBLIC_OPTIONS "") | ||
set(TFLITE_TARGET_PRIVATE_OPTIONS "") | ||
# Additional library dependencies based upon enabled features. | ||
set(TFLITE_TARGET_DEPENDENCIES "") | ||
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang$") | ||
# TFLite uses deprecated methods in neon2sse which generates a huge number of | ||
# warnings so surpress these until they're fixed. | ||
list(APPEND TFLITE_TARGET_PRIVATE_OPTIONS "-Wno-deprecated-declarations") | ||
endif() | ||
if(CMAKE_SYSTEM_NAME MATCHES "Windows") | ||
# Use NOMINMAX to disable the min / max macros in windows.h as they break | ||
# use of std::min std::max. | ||
# Use NOGDI to ERROR macro which breaks TensorFlow logging. | ||
list(APPEND TFLITE_TARGET_PRIVATE_OPTIONS "-DNOMINMAX" "-DNOGDI") | ||
endif() | ||
# Build a list of source files to compile into the TF Lite library. | ||
populate_tflite_source_vars("." TFLITE_SRCS) | ||
if(_TFLITE_ENABLE_MMAP) | ||
list(FILTER TFLITE_SRCS EXCLUDE REGEX ".*mmap_allocation_disabled\\.cc$") | ||
else() | ||
list(FILTER TFLITE_SRCS EXCLUDE REGEX ".*mmap_allocation\\.cc$") | ||
endif() | ||
if(NOT "${CMAKE_SYSTEM_NAME}" STREQUAL "Android") | ||
list(FILTER TFLITE_SRCS EXCLUDE REGEX ".*minimal_logging_android\\.cc$") | ||
endif() | ||
if(NOT "${CMAKE_SYSTEM_NAME}" STREQUAL "iOS") | ||
list(FILTER TFLITE_SRCS EXCLUDE REGEX ".*minimal_logging_ios\\.cc$") | ||
endif() | ||
populate_tflite_source_vars("core" TFLITE_CORE_SRCS) | ||
populate_tflite_source_vars("core/api" TFLITE_CORE_API_SRCS) | ||
populate_tflite_source_vars("c" TFLITE_C_SRCS) | ||
populate_tflite_source_vars("delegates" TFLITE_DELEGATES_SRCS) | ||
if(TFLITE_ENABLE_FLEX) | ||
message(FATAL_ERROR "TF Lite Flex delegate is currently not supported.") | ||
populate_tflite_source_vars("delegates/flex" TFLITE_DELEGATES_FLEX_SRCS) | ||
list(APPEND TFLITE_TARGET_DEPENDENCIES | ||
absl::inlined_vector | ||
absl::optional | ||
absl::type_traits | ||
) | ||
endif() | ||
if(TFLITE_ENABLE_GPU) | ||
# Implementation is under delegates/gpu. | ||
message(FATAL_ERROR | ||
"GPU acceleration is not currently supported in CMake builds" | ||
) | ||
endif() | ||
if(_TFLITE_ENABLE_NNAPI) | ||
populate_tflite_source_vars("delegates/nnapi" | ||
TFLITE_DELEGATES_NNAPI_SRCS | ||
FILTER "(_test_list|_disabled)\\.(cc|h)$" | ||
) | ||
populate_tflite_source_vars( | ||
"nnapi" TFLITE_NNAPI_SRCS FILTER "(_disabled)\\.(cc|h)$" | ||
) | ||
else() | ||
set(TFLITE_DELEGATES_NNAPI_SRCS | ||
"${TFLITE_SOURCE_DIR}/delegates/nnapi/nnapi_delegate_disabled.cc" | ||
) | ||
set(TFLITE_NNAPI_SRCS | ||
"${TFLITE_SOURCE_DIR}/nnapi/nnapi_implementation_disabled.cc" | ||
) | ||
endif() | ||
if(TFLITE_ENABLE_XNNPACK) | ||
populate_tflite_source_vars("delegates/xnnpack" | ||
TFLITE_DELEGATES_XNNPACK_SRCS | ||
) | ||
endif() | ||
if (TFLITE_ENABLE_RESOURCE) | ||
populate_tflite_source_vars("experimental/resource" | ||
TFLITE_EXPERIMENTAL_RESOURCE_SRCS | ||
) | ||
endif() | ||
populate_tflite_source_vars("experimental/ruy" | ||
TFLITE_EXPERIMENTAL_RUY_SRCS | ||
FILTER | ||
".*(test(_fast|_slow|_special_specs))\\.(cc|h)$" | ||
".*(benchmark|tune_tool|example)\\.(cc|h)$" | ||
) | ||
populate_tflite_source_vars("experimental/ruy/profiler" | ||
TFLITE_EXPERIMENTAL_RUY_PROFILER_SRCS | ||
FILTER ".*(test|test_instrumented_library)\\.(cc|h)$" | ||
) | ||
if(TFLITE_ENABLE_RUY) | ||
list(APPEND TFLITE_TARGET_PUBLIC_OPTIONS "-DTFLITE_WITH_RUY") | ||
endif() | ||
populate_tflite_source_vars("kernels" | ||
TFLITE_KERNEL_SRCS | ||
FILTER ".*(_test_util_internal|test_main)\\.(cc|h)" | ||
) | ||
populate_tflite_source_vars("kernels/internal" TFLITE_KERNEL_INTERNAL_SRCS) | ||
populate_tflite_source_vars("kernels/internal/optimized" | ||
TFLITE_KERNEL_INTERNAL_OPT_SRCS | ||
) | ||
populate_tflite_source_vars("kernels/internal/optimized/integer_ops" | ||
TFLITE_KERNEL_INTERNAL_OPT_INTEGER_OPS_SRCS | ||
) | ||
populate_tflite_source_vars("kernels/internal/optimized/sparse_ops" | ||
TFLITE_KERNEL_INTERNAL_OPT_SPARSE_OPS_SRCS | ||
) | ||
populate_tflite_source_vars("kernels/internal/reference" | ||
TFLITE_KERNEL_INTERNAL_REF_SRCS | ||
) | ||
populate_tflite_source_vars("kernels/internal/reference/integer_ops" | ||
TFLITE_KERNEL_INTERNAL_REF_INTEGER_OPS_SRCS | ||
) | ||
populate_tflite_source_vars("kernels/internal/reference/sparse_ops" | ||
TFLITE_KERNEL_INTERNAL_REF_SPARSE_OPS_SRCS | ||
) | ||
if(TFLITE_ENABLE_PROFILING) | ||
populate_tflite_source_vars("profiling" TFLITE_KERNEL_PROFILING_SRCS) | ||
endif() | ||
populate_tflite_source_vars("tools/optimize" TFLITE_TOOLS_OPTIMIZE_SRCS) | ||
populate_tflite_source_vars("tools/optimize/calibration" | ||
TFLITE_TOOLS_OPTIMIZE_CALIBRATION_SRCS | ||
) | ||
populate_tflite_source_vars("tools/optimize/calibration/builtin_logging_ops" | ||
TFLITE_TOOLS_OPTIMIZE_CALIBRATION_OPS_SRCS | ||
) | ||
populate_tflite_source_vars("tools/optimize/sparsity" | ||
TFLITE_TOOLS_OPTIMIZE_SPARSITY_SRCS | ||
) | ||
add_library(tensorflowlite | ||
${TFLITE_CORE_API_SRCS} | ||
${TFLITE_CORE_SRCS} | ||
${TFLITE_C_SRCS} | ||
${TFLITE_DELEGATES_FLEX_SRCS} | ||
${TFLITE_DELEGATES_NNAPI_SRCS} | ||
${TFLITE_DELEGATES_SRCS} | ||
${TFLITE_DELEGATES_XNNPACK_SRCS} | ||
${TFLITE_EXPERIMENTAL_RESOURCE_SRCS} | ||
${TFLITE_EXPERIMENTAL_RUY_PROFILER_SRCS} | ||
${TFLITE_EXPERIMENTAL_RUY_SRCS} | ||
${TFLITE_FLATBUFFERS_HDRS} | ||
${TFLITE_KERNEL_INTERNAL_OPT_INTEGER_OPS_SRCS} | ||
${TFLITE_KERNEL_INTERNAL_OPT_SPARSE_OPS_SRCS} | ||
${TFLITE_KERNEL_INTERNAL_OPT_SRCS} | ||
${TFLITE_KERNEL_INTERNAL_REF_INTEGER_OPS_SRCS} | ||
${TFLITE_KERNEL_INTERNAL_REF_SPARSE_OPS_SRCS} | ||
${TFLITE_KERNEL_INTERNAL_REF_SRCS} | ||
${TFLITE_KERNEL_INTERNAL_SRCS} | ||
${TFLITE_KERNEL_PROFILING_SRCS} | ||
${TFLITE_KERNEL_SRCS} | ||
${TFLITE_NNAPI_SRCS} | ||
${TFLITE_SRCS} | ||
${TFLITE_TOOLS_OPTIMIZE_CALIBRATION_OPS_SRCS} | ||
${TFLITE_TOOLS_OPTIMIZE_CALIBRATION_SRCS} | ||
${TFLITE_TOOLS_OPTIMIZE_SPARSITY_SRCS} | ||
${TFLITE_TOOLS_OPTIMIZE_SRCS} | ||
) | ||
target_link_libraries(tensorflowlite | ||
This comment has been minimized.
Sorry, something went wrong. |
||
PUBLIC | ||
Eigen3::Eigen | ||
NEON_2_SSE | ||
absl::flags | ||
absl::hash | ||
absl::status | ||
absl::strings | ||
absl::synchronization | ||
absl::variant | ||
farmhash | ||
fft2d_fftsg2d | ||
This comment has been minimized.
Sorry, something went wrong. |
||
flatbuffers | ||
gemmlowp | ||
ruy | ||
${TFLITE_TARGET_DEPENDENCIES} | ||
) | ||
target_include_directories(tensorflowlite | ||
PUBLIC | ||
"${TENSORFLOW_SOURCE_DIR}" | ||
PRIVATE | ||
"${TFLITE_FLATBUFFERS_GEN_DIR}" | ||
) | ||
target_compile_options(tensorflowlite | ||
PUBLIC ${TFLITE_TARGET_PUBLIC_OPTIONS} | ||
PRIVATE ${TFLITE_TARGET_PRIVATE_OPTIONS} | ||
) | ||
add_library(tensorflow::tensorflowlite ALIAS tensorflowlite) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
# Build TensorFlow Lite with CMake | ||
|
||
This page describes how to build the TensorFlow Lite static library with CMake | ||
tool. | ||
|
||
The following instructions have been tested on Ubuntu 16.04.3 64-bit PC (AMD64) | ||
and TensorFlow devel docker image | ||
[tensorflow/tensorflow:devel](https://hub.docker.com/r/tensorflow/tensorflow/tags/). | ||
|
||
**Note:** This is an experimental that is subject to change. | ||
|
||
**Note:** The following are not currently supported: Android, iOS, Tests and | ||
Host Tools (i.e benchmark / analysis tools etc.) | ||
|
||
#### Step 1. Install CMake tool | ||
|
||
It requires CMake 3.16 or higher. On Ubunutu, you can simply run the following | ||
command. | ||
|
||
```sh | ||
sudo apt-get install cmake | ||
``` | ||
|
||
Or you can follow [the offcial cmake installation guide](https://cmake.org/install/) | ||
|
||
#### Step 2. Clone TensorFlow repository | ||
|
||
```sh | ||
git clone https://github.com/tensorflow/tensorflow.git tensorflow_src | ||
``` | ||
|
||
**Note:** If you're using the TensorFlow Docker image, the repo is already | ||
provided in `/tensorflow_src/`. | ||
|
||
#### Step 3. Create CMake build directory and run CMake tool | ||
|
||
```sh | ||
mkdir tflite_build | ||
cd tflite_build | ||
cmake ../tensorflow_src/tensorflow/lite | ||
``` | ||
|
||
#### Step 4. Build TensorFlow Lite | ||
|
||
```sh | ||
cmake --build . -j | ||
``` | ||
|
||
**Note:** This should compile a static library `libtensorflow-lite.a` in the | ||
current directory. |
Oops, something went wrong.
In general, i'm finding that when building, not all of these static libraries are being included when linking the archive, such as -
fft2d_fftsg
farmhash
flatbuffers
I've attempted to resolve, but it has me stumped as it looks (by a non cmake expert) like you're doing the right thing.