tensorflow
tensorflow copied to clipboard
Build Tensorflow Lite for WASM using Emscripten and CMake
Issue type
Support
Have you reproduced the bug with TensorFlow Nightly?
No
Source
source
TensorFlow version
2.19.0
Custom code
No
OS platform and distribution
No response
Mobile device
No response
Python version
No response
Bazel version
No response
GCC/compiler version
Emcc: 4.0.5
CUDA/cuDNN version
No response
GPU model and memory
No response
Current behavior?
I'm trying to build Tensorflow Lite to WASM, using Emscripten and CMake. See my example repo here.
I can't use the prebuilt Tensorflow.js, even with the WASM backend, since I need to call the inference from several threads right within C++. Leaving WASM to call a tensorflow.js function that runs WASM again, would defeat the purpose for my usecase.
Anyway, the example I'm using here does not even use threads or anything, so that is not all too relevant, just some background.
I have these lines in my CMakeLists.txt:
include(${CMAKE_SOURCE_DIR}/cmake/SetupTFLite.cmake)
add_dependencies(${MAIN} tensorflow-lite)
target_link_libraries(${MAIN} tensorflow-lite)
The cmake/SetupTFLite.cmake clones tensorflow, checks out a tag, and then adds the tensorflow/lite subdirectory.
It is worth mentioning, I had to add set(CMAKE_SYSTEM_NAME "Linux"), otherwise I would get this error while configuring:
[cmake] CMake Error at build/xnnpack/CMakeLists.txt:359 (MESSAGE):
[cmake] Unrecognized CMAKE_SYSTEM_NAME value "Emscripten"
Anyway, so that variable was set.
Configuring all of this works, using the command shown in the repos README.
But building fails: And it seems to fail at different points. Here are a few from consecutive runs:
[build] [ 6%] Linking CXX executable flatc.js
[build] [ 6%] Built target flatc
[build] make: *** [all] Error 2
[proc] The command: /usr/local/bin/cmake --build /Users/anton/tflite-wasm-example/build --config Debug --target all -j 13 -- exited with code: 2
[build] [ 8%] Linking CXX static library libprotobufd.a
[build] [ 8%] Built target libprotobuf
[build] make: *** [all] Error 2
[proc] The command: /usr/local/bin/cmake --build /Users/anton/tflite-wasm-example/build --config Debug --target all -j 13 -- exited with code: 2
[build] /Users/anton/tflite-wasm-example/build/xnnpack/src/xnnpack/math.h:446:52: note: include the header <math.h> or explicitly provide a declaration for 'rint'
[build] 1 error generated.
[build] make[2]: *** [_deps/xnnpack-build/CMakeFiles/normalization.dir/src/normalization.c.o] Error 1
[build] make[1]: *** [_deps/xnnpack-build/CMakeFiles/normalization.dir/all] Error 2
[build] 1 error generated.
[build] make[2]: *** [_deps/xnnpack-build/CMakeFiles/indirection.dir/src/indirection.c.o] Error 1
[build] make[1]: *** [_deps/xnnpack-build/CMakeFiles/indirection.dir/all] Error 2
[build] make[1]: *** [_deps/cpuinfo-build/CMakeFiles/cpuinfo_internals.dir/all] Error 2
[build] make: *** [all] Error 2
[proc] The command: /usr/local/bin/cmake --build /Users/anton/tflite-wasm-example/build --config Debug --target all -j 13 -- exited with code: 2
(it then keeps failing at this spot!)
My first hunch is that building my main.cpp does not wait for tensorflow to be built? As in, something is wrong with the dependencies? And that's why Tensorflow compiles further and further, with the previous run still being cached? Sort of race-conditiony?
But then it definitely always fails at the "xnnpack/math.h" thing?
Is there some simple example of using Tensorflow Lite directly within C++ and compiling it using CMake? I found this one, and oriented myself at it. Plus, it doesn't use WASM.
Standalone code to reproduce the issue
I set up a minimal repo to reproduce here.
Relevant files:
CMakeLists.txt: The CMake configuration file for the project.cmake/SetupTFLite.cmake: A CMake script that clones TensorFlow Lite and includes it in the build.
My repo does not include emscripten, nor flatbuffer, this you will have to adjust in the build commands. But maybe you will already see what mistake I made.
Relevant log output
Described above.
Fix 3: Modify Build Flags
Sometimes, the issue stems from Emscripten’s standard library setup. You can try:
emcmake cmake .. -DCMAKE_SYSTEM_NAME=Emscripten \
-DCMAKE_C_COMPILER=emcc \
-DCMAKE_CXX_COMPILER=em++ \
-DCMAKE_CXX_FLAGS="-std=c++17 -s USE_PTHREADS=1 -s WASM=1 -s USE_SDL=2 -s ENVIRONMENT=web -s MODULARIZE=1" \
-DCMAKE_C_FLAGS="-std=c11"
Then run:
cmake --build . -j
Ensure that:
- You're using the latest compatible Emscripten (>=3.x).
- You include
-s USE_PTHREADS=1only if you really use threading (and the browser supports it with cross-origin isolation).
When I use -DCMAKE_SYSTEM_NAME=Emscripten, I get this error:
-- The ASM compiler identification is unknown
-- Found assembler: /Users/anton/emsdk/upstream/emscripten/emcc
-- Warning: Did not find file Compiler/-ASM
-- Building for XNNPACK_TARGET_PROCESSOR: x86
CMake Error at build/xnnpack/CMakeLists.txt:359 (MESSAGE):
Unrecognized CMAKE_SYSTEM_NAME value "Emscripten"
But I got this before, and circumvented this by setting the CMAKE_SYSTEM_NAME to Linux?
But after making that adjustment and building, I still get this error:
make[2]: *** [_deps/xnnpack-build/CMakeFiles/microkernels-prod.dir/src/qu8-gemm/gen/qu8-gemm-1x4c8-minmax-fp32-avx-ld128.c.o] Error 1
make[2]: *** [_deps/xnnpack-build/CMakeFiles/microkernels-prod.dir/src/f16-rminmax/gen/f16-rmax-avx512fp16-u128-acc4.c.o] Error 1
In file included from /Users/anton/tflite-wasm-example/build/xnnpack/src/qs8-vadd/gen/qs8-vadd-minmax-scalar-u4.c:12:
/Users/anton/tflite-wasm-example/build/xnnpack/src/xnnpack/math.h:446:52: error: call to undeclared library function 'rint' with type 'double (double)'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
446 | return __builtin_wasm_trunc_saturate_u_i32_f64(rint(x));
| ^
/Users/anton/tflite-wasm-example/build/xnnpack/src/xnnpack/math.h:446:52: note: include the header <math.h> or explicitly provide a declaration for 'rint'
In file included from /Users/anton/tflite-wasm-example/build/xnnpack/src/f32-vhswish/gen/f32-vhswish-scalar-u4.c:13:
/Users/anton/tflite-wasm-example/build/xnnpack/src/xnnpack/math.h:446:52: error: call to undeclared library function 'rint' with type 'double (double)'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
446 | return __builtin_wasm_trunc_saturate_u_i32_f64(rint(x));
| ^
/Users/anton/tflite-wasm-example/build/xnnpack/src/xnnpack/math.h:446:52: note: include the header <math.h> or explicitly provide a declaration for 'rint'
1 error generated.
make[2]: *** [_deps/xnnpack-build/CMakeFiles/microkernels-prod.dir/src/qu8-dwconv/gen/qu8-dwconv-25p1c-minmax-fp32-scalar-fmagic.c.o] Error 1
1 error generated.
make[2]: *** [_deps/xnnpack-build/CMakeFiles/microkernels-prod.dir/src/f32-qc4w-gemm/gen/f32-qc4w-gemm-1x4-minmax-scalar.c.o] Error 1
1 error generated.
make[2]: *** [_deps/xnnpack-build/CMakeFiles/microkernels-prod.dir/src/f32-vhswish/gen/f32-vhswish-scalar-u4.c.o] Error 1
1 error generated.
make[2]: *** [_deps/xnnpack-build/CMakeFiles/microkernels-prod.dir/src/qs8-vadd/gen/qs8-vadd-minmax-scalar-u4.c.o] Error 1
In file included from /Users/anton/tflite-wasm-example/build/xnnpack/src/qs8-dwconv/gen/qs8-dwconv-25p1c-minmax-fp32-scalar-imagic.c:15:
In file included from /Users/anton/tflite-wasm-example/build/xnnpack/src/xnnpack/dwconv.h:15:
In file included from /Users/anton/tflite-wasm-example/build/xnnpack/src/xnnpack/microparams.h:13:
/Users/anton/tflite-wasm-example/build/xnnpack/src/xnnpack/math.h:446:52: error: call to undeclared library function 'rint' with type 'double (double)'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
446 | return __builtin_wasm_trunc_saturate_u_i32_f64(rint(x));
| ^
/Users/anton/tflite-wasm-example/build/xnnpack/src/xnnpack/math.h:446:52: note: include the header <math.h> or explicitly provide a declaration for 'rint'
In file included from /Users/anton/tflite-wasm-example/build/xnnpack/src/f32-ibilinear/gen/f32-ibilinear-scalar-c2.c:12:
In file included from /Users/anton/tflite-wasm-example/build/xnnpack/src/xnnpack/ibilinear.h:12:
/Users/anton/tflite-wasm-example/build/xnnpack/src/xnnpack/math.h:446:52: error: call to undeclared library function 'rint' with type 'double (double)'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
446 | return __builtin_wasm_trunc_saturate_u_i32_f64(rint(x));
| ^
/Users/anton/tflite-wasm-example/build/xnnpack/src/xnnpack/math.h:446:52: note: include the header <math.h> or explicitly provide a declaration for 'rint'
1 error generated.
make[2]: *** [_deps/xnnpack-build/CMakeFiles/microkernels-prod.dir/src/f32-ibilinear/gen/f32-ibilinear-scalar-c2.c.o] Error 1
1 error generated.
make[2]: *** [_deps/xnnpack-build/CMakeFiles/microkernels-prod.dir/src/qs8-dwconv/gen/qs8-dwconv-25p1c-minmax-fp32-scalar-imagic.c.o] Error 1
make[1]: *** [_deps/xnnpack-build/CMakeFiles/microkernels-prod.dir/all] Error 2
[ 26%] Built target flatc
make: *** [all] Error 2
After some thinking, I will close this Issue and open a separate slightly different one. I think my problem does not lie with CMake, but on the overall building of a static WASM library.