Skip to content

Commit d6cf8ec

Browse files
authored
tflite-runtime recipe (#2554)
* add pybind11 * add tflite-runtime * remove apt pybind11 redundant dependency * remove redundant bdist_wheel reference a* move 'v' in version
1 parent 116c538 commit d6cf8ec

File tree

4 files changed

+190
-0
lines changed

4 files changed

+190
-0
lines changed
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
from pythonforandroid.recipe import Recipe
2+
from os.path import join
3+
4+
5+
class Pybind11Recipe(Recipe):
6+
7+
version = '2.9.0'
8+
url = 'https://github.com/pybind/pybind11/archive/refs/tags/v{version}.zip'
9+
10+
def get_include_dir(self, arch):
11+
return join(self.get_build_dir(arch.arch), 'include')
12+
13+
14+
recipe = Pybind11Recipe()
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
--- tflite-runtime/tensorflow/lite/CMakeLists.txt 2022-01-27 17:29:49.460000000 -1000
2+
+++ CMakeLists.txt 2022-02-21 15:03:09.568367300 -1000
3+
@@ -220,6 +220,9 @@
4+
if(NOT "${CMAKE_SYSTEM_NAME}" STREQUAL "iOS")
5+
list(FILTER TFLITE_SRCS EXCLUDE REGEX ".*minimal_logging_ios\\.cc$")
6+
endif()
7+
+if("${CMAKE_SYSTEM_NAME}" STREQUAL "Android")
8+
+ list(FILTER TFLITE_SRCS EXCLUDE REGEX ".*minimal_logging_default\\.cc$")
9+
+endif()
10+
populate_tflite_source_vars("core" TFLITE_CORE_SRCS)
11+
populate_tflite_source_vars("core/api" TFLITE_CORE_API_SRCS)
12+
populate_tflite_source_vars("c" TFLITE_C_SRCS)
13+
@@ -505,6 +508,7 @@
14+
ruy
15+
${CMAKE_DL_LIBS}
16+
${TFLITE_TARGET_DEPENDENCIES}
17+
+ ${ANDROID_LOG_LIB}
18+
)
19+
20+
if (NOT BUILD_SHARED_LIBS)
21+
@@ -550,6 +554,7 @@
22+
tensorflow-lite
23+
${CMAKE_DL_LIBS}
24+
)
25+
+
26+
target_compile_options(_pywrap_tensorflow_interpreter_wrapper
27+
PUBLIC ${TFLITE_TARGET_PUBLIC_OPTIONS}
28+
PRIVATE ${TFLITE_TARGET_PRIVATE_OPTIONS}
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
from pythonforandroid.recipe import PythonRecipe, current_directory,\
2+
shprint, info_main, warning
3+
from pythonforandroid.logger import error
4+
from os.path import join
5+
import sh
6+
7+
8+
class TFLiteRuntimeRecipe(PythonRecipe):
9+
10+
###############################################################
11+
#
12+
# tflite-runtime README:
13+
# https://github.com/Android-for-Python/c4k_tflite_example/blob/main/README.md
14+
#
15+
# Recipe build references:
16+
# https://developer.android.com/ndk/guides/cmake
17+
# https://developer.android.com/ndk/guides/cpu-arm-neon#cmake
18+
# https://www.tensorflow.org/lite/guide/build_cmake
19+
# https://www.tensorflow.org/lite/guide/build_cmake_arm
20+
#
21+
# Tested using cmake 3.16.3 probably requires cmake >= 3.13
22+
#
23+
# THIS RECIPE DOES NOT BUILD x86_64, USE X86 FOR AN EMULATOR
24+
#
25+
###############################################################
26+
27+
version = '2.8.0'
28+
url = 'https://github.com/tensorflow/tensorflow/archive/refs/tags/v{version}.zip'
29+
depends = ['pybind11', 'numpy']
30+
patches = ['CMakeLists.patch', 'build_with_cmake.patch']
31+
site_packages_name = 'tflite-runtime'
32+
call_hostpython_via_targetpython = False
33+
34+
def build_arch(self, arch):
35+
if arch.arch == 'x86_64':
36+
warning("******** tflite-runtime x86_64 will not be built *******")
37+
warning("Expect one of these app run time error messages:")
38+
warning("ModuleNotFoundError: No module named 'tensorflow'")
39+
warning("ModuleNotFoundError: No module named 'tflite_runtime'")
40+
warning("Use x86 not x86_64")
41+
return
42+
43+
env = self.get_recipe_env(arch)
44+
45+
# Directories
46+
root_dir = self.get_build_dir(arch.arch)
47+
script_dir = join(root_dir,
48+
'tensorflow', 'lite', 'tools', 'pip_package')
49+
build_dir = join(script_dir, 'gen', 'tflite_pip', 'python3')
50+
51+
# Includes
52+
python_include_dir = self.ctx.python_recipe.include_root(arch.arch)
53+
pybind11_recipe = self.get_recipe('pybind11', self.ctx)
54+
pybind11_include_dir = pybind11_recipe.get_include_dir(arch)
55+
numpy_include_dir = join(self.ctx.get_site_packages_dir(arch),
56+
'numpy', 'core', 'include')
57+
includes = ' -I' + python_include_dir +\
58+
' -I' + numpy_include_dir +\
59+
' -I' + pybind11_include_dir
60+
61+
# Scripts
62+
build_script = join(script_dir, 'build_pip_package_with_cmake.sh')
63+
toolchain = join(self.ctx.ndk_dir,
64+
'build', 'cmake', 'android.toolchain.cmake')
65+
66+
# Build
67+
########
68+
with current_directory(root_dir):
69+
env.update({
70+
'TENSORFLOW_TARGET': 'android',
71+
'CMAKE_TOOLCHAIN_FILE': toolchain,
72+
'ANDROID_PLATFORM': str(self.ctx.ndk_api),
73+
'ANDROID_ABI': arch.arch,
74+
'WRAPPER_INCLUDES': includes,
75+
'CMAKE_SHARED_LINKER_FLAGS': env['LDFLAGS'],
76+
})
77+
78+
try:
79+
info_main('tflite-runtime is building...')
80+
info_main('Expect this to take at least 5 minutes...')
81+
cmd = sh.Command(build_script)
82+
cmd(_env=env)
83+
except sh.ErrorReturnCode as e:
84+
error(str(e.stderr))
85+
exit(1)
86+
87+
# Install
88+
##########
89+
info_main('Installing tflite-runtime into site-packages')
90+
with current_directory(build_dir):
91+
hostpython = sh.Command(self.hostpython_location)
92+
install_dir = self.ctx.get_python_install_dir(arch.arch)
93+
env['PACKAGE_VERSION'] = self.version
94+
shprint(hostpython, 'setup.py', 'install', '-O2',
95+
'--root={}'.format(install_dir),
96+
'--install-lib=.',
97+
_env=env)
98+
99+
100+
recipe = TFLiteRuntimeRecipe()
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
--- tflite-runtime/tensorflow/lite/tools/pip_package/build_pip_package_with_cmake.sh 2022-01-22 08:57:16.000000000 -1000
2+
+++ build_pip_package_with_cmake.sh 2022-03-02 18:19:05.185550500 -1000
3+
@@ -28,7 +28,7 @@
4+
export TENSORFLOW_TARGET="armhf"
5+
fi
6+
PYTHON_INCLUDE=$(${PYTHON} -c "from sysconfig import get_paths as gp; print(gp()['include'])")
7+
-PYBIND11_INCLUDE=$(${PYTHON} -c "import pybind11; print (pybind11.get_include())")
8+
+# PYBIND11_INCLUDE=$(${PYTHON} -c "import pybind11; print (pybind11.get_include())")
9+
export CROSSTOOL_PYTHON_INCLUDE_PATH=${PYTHON_INCLUDE}
10+
11+
# Fix container image for cross build.
12+
@@ -58,7 +58,7 @@
13+
"${TENSORFLOW_LITE_DIR}/python/metrics/metrics_portable.py" \
14+
"${BUILD_DIR}/tflite_runtime"
15+
echo "__version__ = '${PACKAGE_VERSION}'" >> "${BUILD_DIR}/tflite_runtime/__init__.py"
16+
-echo "__git_version__ = '$(git -C "${TENSORFLOW_DIR}" describe)'" >> "${BUILD_DIR}/tflite_runtime/__init__.py"
17+
+echo "__git_version__ = '${PACKAGE_VERSION}'" >> "${BUILD_DIR}/tflite_runtime/__init__.py"
18+
19+
# Build python interpreter_wrapper.
20+
mkdir -p "${BUILD_DIR}/cmake_build"
21+
@@ -111,6 +111,18 @@
22+
-DCMAKE_CXX_FLAGS="${BUILD_FLAGS}" \
23+
"${TENSORFLOW_LITE_DIR}"
24+
;;
25+
+ android)
26+
+ BUILD_FLAGS=${BUILD_FLAGS:-"${WRAPPER_INCLUDES}"}
27+
+ cmake \
28+
+ -DCMAKE_SYSTEM_NAME=Android \
29+
+ -DANDROID_ARM_NEON=ON \
30+
+ -DCMAKE_CXX_FLAGS="${BUILD_FLAGS}" \
31+
+ -DCMAKE_SHARED_LINKER_FLAGS="${CMAKE_SHARED_LINKER_FLAGS}" \
32+
+ -DCMAKE_TOOLCHAIN_FILE="${CMAKE_TOOLCHAIN_FILE}" \
33+
+ -DANDROID_PLATFORM="${ANDROID_PLATFORM}" \
34+
+ -DANDROID_ABI="${ANDROID_ABI}" \
35+
+ "${TENSORFLOW_LITE_DIR}"
36+
+ ;;
37+
*)
38+
BUILD_FLAGS=${BUILD_FLAGS:-"-I${PYTHON_INCLUDE} -I${PYBIND11_INCLUDE}"}
39+
cmake \
40+
@@ -162,7 +174,7 @@
41+
${PYTHON} setup.py bdist --plat-name=${WHEEL_PLATFORM_NAME} \
42+
bdist_wheel --plat-name=${WHEEL_PLATFORM_NAME}
43+
else
44+
- ${PYTHON} setup.py bdist bdist_wheel
45+
+ ${PYTHON} setup.py bdist
46+
fi
47+
;;
48+
esac

0 commit comments

Comments
 (0)