Kotlin / multik

Multidimensional array library for Kotlin
https://kotlin.github.io/multik/
Apache License 2.0
646 stars 39 forks source link

JNI Exceptions when using overloaded dot method (perhaps Android specific) #140

Open 9SMTM6 opened 2 years ago

9SMTM6 commented 2 years ago

I am getting JNI excepions without much to go on when I use the general purpose dot method on Android. Interestingly even if I only depend on the kotlin Implementation, which I presumed from documentation was entirely in Kotlin.

The only way I've found to fix the issue is directly using the specific Methods, from the Kotlin implementation that is org.jetbrains.kotlinx.multik.kotlin.linalg.KELinAlgEx.dotVV etc).

Perhaps I'll get around to testing more when that happens, but I'm rather busy already so I'm not hopeful.

devcrocod commented 2 years ago

Please show stacktrace And what dependencies do you use?

devcrocod commented 2 years ago

if you depend on multik-default, then there is multik-openblas there (link1, link2).

and what processor do you have in your phone? if you run in an emulator, it will not work for the reason that the native part is not suitable for emulation. Emulator usually requires android-x64, but we don't have it.

For pure kotlin use implementation("org.jetbrains.kotlinx:multik-kotlin:$multik_version")

9SMTM6 commented 2 years ago

with this code:

    val whatever = mk.ndarray(floatArrayOf(1f, 2f, 3f)) dot  mk.ndarray(floatArrayOf(1f, 2f, 3f))

and these dependencies that may be relevant:


    implementation "org.jetbrains.kotlinx:multik-core:$multik_version"
//    TODO replace with default as soon as that wont cause the app to crash because of
//   org.jetbrains.kotlinx.multik.default.linalg.DefaultLinAlgEx.dotVV
    implementation "org.jetbrains.kotlinx:multik-kotlin:$multik_version"

    implementation "androidx.core:core-ktx:$core_ktx_version"

I'm getting on a Samsung Galaxy S10e

2022-08-12 12:42:49.192 26359-16738/com.example.mcgprototype A/le.mcgprototyp: java_vm_ext.cc:578] JNI DETECTED ERROR IN APPLICATION: JNI CallVoidMethodV called with pending exception java.lang.ExceptionInInitializerError: 
    java_vm_ext.cc:578]   at org.jetbrains.kotlinx.multik.api.linalg.LinAlg org.jetbrains.kotlinx.multik.api.Multik.getLinalg() (Multik.kt:49)
    java_vm_ext.cc:578]   at java.lang.Number org.jetbrains.kotlinx.multik.api.linalg._linalgKt.dotDefVVNumber(org.jetbrains.kotlinx.multik.ndarray.data.MultiArray, org.jetbrains.kotlinx.multik.ndarray.data.MultiArray) (_linalg.kt:53)
    java_vm_ext.cc:578]   at float[] <USERCODE>(java.util.List, java.lang.String) (<USERCODE>)
9SMTM6 commented 2 years ago

oops, sorry, the ACTUAL versions:

        core_ktx_version = "1.8.0"
        multik_version = "0.2.0"

GS10e uses a regular old arm64 SOC.

9SMTM6 commented 2 years ago

It looks exactly the same if I use the default impl. As the comment in the dependency somewhat cryptically noted, in that case it crashes even if I use dotVV method directly.

9SMTM6 commented 2 years ago

And, to complete the picture, this works:

import org.jetbrains.kotlinx.multik.kotlin.linalg.KELinAlgEx

[...]

    val whatever = KELinAlgEx.dotVV(mk.ndarray(floatArrayOf(1f, 2f, 3f)), mk.ndarray(floatArrayOf(1f, 2f, 3f)))
devcrocod commented 2 years ago

Another clarification: is this a multiplatform project?

9SMTM6 commented 2 years ago

Not as far as I'm aware.

It is based on the generated Android Kotlin template from Android Studio. Unless they do something weird under the hood it should just be JVM.

9SMTM6 commented 2 years ago

it also uses amongst others tensorflow, but that shouldnt be relevant, its JNI calls are constantly happening, and as I said, if I "directly" use dotVV and dotMM from the Kotlin-Impl it works fine.

devcrocod commented 2 years ago

I was unable to reproduce this error. But I found out a few things:

  1. This error is not related to native code in multik. So if you have multik-kotlin in your dependencies, you should see something like this in project-structure -> dependencies.

    image
  2. This error seems to be related to the Service Provider Interface. This explains why when you call the method directly with dotVV you don't get the exception - you don't use the SPI logic.

Unfortunately, I can't find the cause of the problem without a reproducible case.

Have you tried deleting the app from your phone and rebuilding the project?

9SMTM6 commented 2 years ago

Sorry, for the inactivity, I was quite busy with other stuff.

Yes, I see these, and only these multik dependencies.

And after uninstalling the applikation and installing it anew the problem persists.

I'm uncertain what I'm supposed to do to make it reproducible. Do you think it depends on the device or something else? I could try and build a new Applikation from the kotlin template and just import multik and try to get the issue, but you would be able to do that too, so unless its something device specific or you want that for some sanity check or similar I dont see how that helps.

devcrocod commented 2 years ago

Do you think it depends on the device or something else?

Not sure.

I'm for reproduction and tried to create a new project from a template, but it worked for me. I have java 11, kotlin 1.7.10

Have you tried running it in an emulator?