pyHailoRT: Module not found - Android - Chaquopy

HailoRT version

version: 17.1.0 and 17.1.1

Android version

version: 12.0.0
Custom version of NXP with updated firmware, PCIE driver, cross compiled libhailort.so and _pyhailort.cpython*.so

Chaquopy version

version: 15.0.1

https://chaquo.com/chaquopy/doc/current/

Devices or emulators where the issue happens

NXP IMX8 M Plus EVK (eval board)

Relevant parts of your code

import hailo_platform as hailo_platform

Describe your issue

I want to integrate the pyHailoRT module for neural network inference into my chaquopy project.

However when import that module I get an module not found error.

2024-05-07 13:19:51.210  2070-2106  AndroidRuntime          com.chaquo.python.console            E  FATAL EXCEPTION: pool-2-thread-1

                                                                                                    Process: com.chaquo.python.console, PID: 2070

                                                                                                    com.chaquo.python.PyException: ModuleNotFoundError: No module named 'hailo_platform.pyhailort._pyhailort'

                                                                                                      at <python>.java.chaquopy.import_override(import.pxi:20)

                                                                                                      at <python>.java.chaquopy.import_override(import.pxi:60)

                                                                                                      at <python>.hailo_platform.pyhailort.pyhailort.<module>(pyhailort.py:17)

                                                                                                      at <python>.java.chaquopy.import_override(import.pxi:60)

                                                                                                      at <python>.hailo_platform.tools.udp_rate_limiter.<module>(udp_rate_limiter.py:9)

                                                                                                      at <python>.java.chaquopy.import_override(import.pxi:60)

                                                                                                      at <python>.hailo_platform.<module>(__init__.py:17)

                                                                                                      at <python>.java.chaquopy.import_override(import.pxi:60)

                                                                                                      at <python>.object_detector.hailort.hailort_detector.<module>(hailort_detector.py:10)

                                                                                                      at <python>.java.chaquopy.import_override(import.pxi:60)

                                                                                                      at <python>.object_detector.object_detector.from_file(object_detector.py:117)

                                                                                                      at <python>.main.main(main.py:109)

                                                                                                      at <python>.chaquopy_java.call(chaquopy_java.pyx:354)

                                                                                                      at <python>.chaquopy_java.Java_com_chaquo_python_PyObject_callAttrThrowsNative(chaquopy_java.pyx:326)

                                                                                                      at com.chaquo.python.PyObject.callAttrThrowsNative(Native Method)

                                                                                                      at com.chaquo.python.PyObject.callAttrThrows(PyObject.java:232)

                                                                                                      at com.chaquo.python.PyObject.callAttr(PyObject.java:221)

                                                                                                      at com.chaquo.python.console.MainActivity.lambda$onStart$0$com-chaquo-python-console-MainActivity(MainActivity.java:131)

                                                                                                      at com.chaquo.python.console.MainActivity$$ExternalSyntheticLambda0.run(D8$$SyntheticClass:0)

                                                                                                      at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)

                                                                                                      at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)

                                                                                                      at java.lang.Thread.run(Thread.java:920)

2024-05-07 13:19:51.249  2070-2106  Process                 com.chaquo.python.console            I  Sending signal. PID: 2070 SIG: 9

Further I get a warning while building the app that hailort-17.0 is not compatible with numpy 1.19.5 which is installed by default for python 3.8 (which is my target python version). But the build succeeds. However at runtime I get the module import error see above.
Further I noticed that the folder: /data/data/com.chaquo.python.console/files/chaquopy/AssetFinder/requirements
does contains the hailo_platform folder only a folder for the tutorial assets hailo_tutorials. What triggers the copy of the shared libraries and necessary assests in order to import and use a module?
I tried to manfully copy the hailo_platform after build. But the module import error stills persists.

When upgrading to python 3.10 (also updating numpy to 1.23.0 and hailort-17.0 to python 3.10) I get another issue during the build. The build fails then with:Value Error: invalid literal for int() with base 10.

In order that everything works fine

  • firmware
  • pcie-driver
  • hailortcli
  • c++ libhailort
  • python bindings (pyHailoRT wheel)

must be available for the target platform which is android arm64 in the case of the NXP imx8.

Everything on that list is adjusted and cross compiled
As either the libhailort (prebuild c++ examples) and hailortcli are working the problem I experience has nothing to do with that components I guess.

I build the python wheel myself by

  • downloading the original wheel for linux-arm64-python3.8
  • cross-compiling either libhailort and _pyhailo.cpython*.so for android arm64 with the Android NDK llvm clang compiler.
  • unzipping the original python wheel
  • replacing the _pyhailo.cpython*.so with the new cross compiled one
  • re-zipping the folder to a modified python wheel
  • installing the python wheel with pip in build.gradle
plugins {
    id 'com.android.application'
    id 'com.chaquo.python'
}

// get path to python.exe
def findPythonExecutable() {
    def possibleCondaLocations = [
            "${System.properties["user.home"]}\\Miniconda3\\envs\\android_3.8\\python.exe",
    ]
    for (def condaLocation : possibleCondaLocations) {
        if (file(condaLocation).exists()) {
            return condaLocation
        }
    }
    throw new GradleException("Python executable not found in any of the expected locations.")
}

// define Python version and set path to python.exe
chaquopy {
    defaultConfig {
        version = "3.8"
        buildPython(findPythonExecutable())
        pip {
            install("six")
            install("hailort-4.17.0-cp38-cp38-linux_aarch64.whl")
            install("loguru")
        }
        pyc {
            src = false
        }
    }
}

android {
    namespace 'com.chaquo.python.console'
    compileSdk = 34
    defaultConfig {
        applicationId "com.chaquo.python.console"
        minSdk = 21
        targetSdk = 34
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
        ndk {
            abiFilters "arm64-v8a"
        }
    }

    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'androidx.appcompat:appcompat:1.1.0'
    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
    implementation 'androidx.lifecycle:lifecycle-extensions:2.1.0'
    testImplementation 'androidx.arch.core:core-testing:2.0.0'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'androidx.test.ext:junit:1.1.1'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.0'
}

Hi, thanks you for bringing it to our attention.
We are aware of this issue and working to solve it.