tensorflow: Can not find strtod_l function on Android device

1. System information

  • OS Platform and Distribution: Android 5.1, OPPO device
  • TensorFlow library : Tensorflow lite 2.13.0

When I try to load model and get error:

E/art: dlopen("/data/app/com.app.demo-1/lib/arm64/libtensorflowlite_jni.so", RTLD_LAZY) failed: dlopen failed: cannot locate symbol "strtod_l" referenced by "/data/app/com.app.demo-1/lib/arm64/libtensorflowlite_jni.so"...

About this issue

  • Original URL
  • State: open
  • Created 9 months ago
  • Reactions: 3
  • Comments: 43 (12 by maintainers)

Most upvoted comments

We are considering patching 2.15, since that could be shipped a lot sooner than 2.16.

There doesn’t seem to be much benefit from patching 2.12-2.14, since users who are affected by this issue could just use 2.15 instead. (But please correct me if I am wrong about that.)

@fergushenderson I have just tried tensorflow-lite version 2.15.0. Now I am getting the following compilation error:

> Failed to transform guice-5.1.0.jar (com.google.inject:guice:5.1.0) to match attributes {artifactType=android-dex, asm-transformed-variant=NONE, dexing-enable-desugaring=true, dexing-enable-jacoco-instrumentation=false, dexing-is-debuggable=true, dexing-min-sdk=21, org.gradle.category=library, org.gradle.libraryelements=jar, org.gradle.status=release, org.gradle.usage=java-runtime}.
      > Execution failed for DexingWithClasspathTransform: /Users/nijatahmadli/.gradle/caches/modules-2/files-2.1/com.google.inject/guice/5.1.0/da25056c694c54ba16e78e4fc35f17fc60f0d1b4/guice-5.1.0.jar.
         > Error while dexing.
           Increase the minSdkVersion to 26 or above.

Looks like guice was introduced in 2.15.0 and requires minSdkVersion 26 which I guess stems from the use of Java 8 language features. Unfortunately, upgrading to 26 is not an option for our project.

The fix has been cherry picked onto the r2.16 release branch, and TF Lite 2.16.1 has been released on Maven Central now. I have verified that the libtensorflowlite_jni.so files from TF Lite 2.16.1 do not contain any references to strtod_l. So this issue is fixed now.

It looks like the dependency on guice is probably not needed. So a possible work-around is to simply exclude that in your Gradle config file (e.g. build.gradle):

implementation ("org.tensorflow:tensorflow-lite:2.15.0") {
  exclude group: 'com.google.inject', module: 'guice'
}

[Credit to Khan LeViet for this suggestion.]

We have not tested this work-around yet, but I wanted to share it as soon as possible. Please let us know if this work-around works for you.

I tried this, but I get the following exception when initializing the Interpreter on SDK 23:

val assetManager = context.assets
val model = loadModelFile(assetManager, "mnist.tflite")
val options = Interpreter.Options()
val interpreter = Interpreter(model, options)
java.lang.UnsatisfiedLinkError: Failed to load native TensorFlow Lite methods. Check that the correct native libraries are present, and, if using a custom native library, have been properly loaded via System.loadLibrary():
	java.lang.UnsatisfiedLinkError: dlopen failed: cannot locate symbol "strtod_l" referenced by "/data/app/com.abhi.minibrainage-2/base.apk"...
	at org.tensorflow.lite.TensorFlowLite.init(TensorFlowLite.java:137)
	at org.tensorflow.lite.NativeInterpreterWrapper.<init>(NativeInterpreterWrapper.java:62)
	at org.tensorflow.lite.NativeInterpreterWrapperExperimental.<init>(NativeInterpreterWrapperExperimental.java:36)
	at org.tensorflow.lite.Interpreter.<init>(Interpreter.java:232)
	at com.abhi.minibrainage.DigitClassifier.initializeInterpreter(DigitClassifier.kt:59)
	at com.abhi.minibrainage.DigitClassifier.initialize$lambda$0(DigitClassifier.kt:36)
	at com.abhi.minibrainage.DigitClassifier.$r8$lambda$YB-smHSmZMC0H3c5D98bqcY-rb8(DigitClassifier.kt)
	at com.abhi.minibrainage.DigitClassifier$$ExternalSyntheticLambda0.run(D8$$SyntheticClass:0)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
	at java.lang.Thread.run(Thread.java:818)
Caused by: java.lang.UnsatisfiedLinkError: No implementation found for void org.tensorflow.lite.TensorFlowLite.nativeDoNothing() (tried Java_org_tensorflow_lite_TensorFlowLite_nativeDoNothing and Java_org_tensorflow_lite_TensorFlowLite_nativeDoNothing__)
	at org.tensorflow.lite.TensorFlowLite.nativeDoNothing(Native Method)
	at org.tensorflow.lite.TensorFlowLite.init(TensorFlowLite.java:132)
	at org.tensorflow.lite.NativeInterpreterWrapper.<init>(NativeInterpreterWrapper.java:62) 
	at org.tensorflow.lite.NativeInterpreterWrapperExperimental.<init>(NativeInterpreterWrapperExperimental.java:36) 
	at org.tensorflow.lite.Interpreter.<init>(Interpreter.java:232) 
	at com.abhi.minibrainage.DigitClassifier.initializeInterpreter(DigitClassifier.kt:59) 
	at com.abhi.minibrainage.DigitClassifier.initialize$lambda$0(DigitClassifier.kt:36) 
	at com.abhi.minibrainage.DigitClassifier.$r8$lambda$YB-smHSmZMC0H3c5D98bqcY-rb8(DigitClassifier.kt) 
	at com.abhi.minibrainage.DigitClassifier$$ExternalSyntheticLambda0.run(D8$$SyntheticClass:0) 
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113) 
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588) 
	at java.lang.Thread.run(Thread.java:818) 

According to the error messages, guice-5.1.0.jar is not compatible with Android 21. The Java support 8 of Android by desugaring seems not working with guice-5.1.0.jar, could you please consider removing it from the dependency list of tensorflow-lite?

@fergushenderson I have just tried tensorflow-lite version 2.15.0. Now I am getting the following compilation error:

> Failed to transform guice-5.1.0.jar (com.google.inject:guice:5.1.0) to match attributes {artifactType=android-dex, asm-transformed-variant=NONE, dexing-enable-desugaring=true, dexing-enable-jacoco-instrumentation=false, dexing-is-debuggable=true, dexing-min-sdk=21, org.gradle.category=library, org.gradle.libraryelements=jar, org.gradle.status=release, org.gradle.usage=java-runtime}.
      > Execution failed for DexingWithClasspathTransform: /Users/nijatahmadli/.gradle/caches/modules-2/files-2.1/com.google.inject/guice/5.1.0/da25056c694c54ba16e78e4fc35f17fc60f0d1b4/guice-5.1.0.jar.
         > Error while dexing.
           Increase the minSdkVersion to 26 or above.

Looks like guice was introduced in 2.15.0 and requires minSdkVersion 26 which I guess stems from the use of Java 8 language features. Unfortunately, upgrading to 26 is not an option for our project.

We are going to fix this.

I have been discussing this with the TF Lite team, and we have consensus that this is a problem that should be fixed. I have analyzed the cause and possible solutions, and produced a prototype solution that allows use of AHardwareBuffer on versions of Android that support it while still remaining compatible with earlier versions of Android back to Android API level 21. A TF Lite team member (@turbotoribio) has taken on the remaining tasks to get this fix landed.

The main part of the fix has landed: https://github.com/tensorflow/tensorflow/commit/c7c3135b2802f3b8886f2ecefc39de49799b1e9b

The remaining parts are to change ANDROID_NDK_API_LEVEL from 26 back to 21.

The fix will be included in TF Lite 2.16.

It looks like the dependency on guice is probably not needed. So a possible work-around is to simply exclude that in your Gradle config file (e.g. build.gradle):

implementation ("org.tensorflow:tensorflow-lite:2.15.0") {
  exclude group: 'com.google.inject', module: 'guice'
}

[Credit to Khan LeViet for this suggestion.]

We have not tested this work-around yet, but I wanted to share it as soon as possible. Please let us know if this work-around works for you.

@fergushenderson Our project needs version 2.15 please help me to answer the release date