tensorflow icon indicating copy to clipboard operation
tensorflow copied to clipboard

Build Tensorflow Lite for WASM using Emscripten and CMake

Open Andonvr opened this issue 7 months ago • 3 comments

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.

Andonvr avatar Apr 03 '25 21:04 Andonvr

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=1 only if you really use threading (and the browser supports it with cross-origin isolation).

tapomoyadhikari avatar Apr 04 '25 07:04 tapomoyadhikari

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?

Andonvr avatar Apr 04 '25 07:04 Andonvr

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

Andonvr avatar Apr 04 '25 07:04 Andonvr

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.

Andonvr avatar Apr 05 '25 11:04 Andonvr

Are you satisfied with the resolution of your issue? Yes No

google-ml-butler[bot] avatar Apr 05 '25 11:04 google-ml-butler[bot]