quic / qidk

Other
76 stars 16 forks source link

Trying to use QNN in an Android project #7

Closed OuterSpaceTraveller closed 7 months ago

OuterSpaceTraveller commented 7 months ago

Hi!

I am trying to use QNN in an Android project. I am able to load the model, backend, etc. but I think there is something wrong with how I am trying to load the skel file.

I get the messages like in the demo exec:

qnn-sample-app build version: v2.10.0.230425122932_54038 Backend build version: v2.10.0.230425122932_54038

I have in LD_LIBRARY_PATH (this is only for testing atm): model, backend, skel and stub. I have tested using all versions provided with the 2.10 package and all return same error message, which indicates to me that probably the skel.so file is not correctly opened in the jni libs path.

in logic

    auto devicePropertySupportStatus = sample_app->isDevicePropertySupported();
    if (qnn::tools::sample_app::StatusCode::FAILURE != devicePropertySupportStatus) {
        auto createDeviceStatus = sample_app->createDevice();
        if (qnn::tools::sample_app::StatusCode::SUCCESS != createDeviceStatus) {
            QNN_ERROR("Device Creation failure");
        } else {
            QNN_INFO("Device Created!");
        }
    }

The device property is supported. I get error 14001 from the QNN engine in app->createDevice();, which translates to device error -> invalid config.

I can get this message if I move the skel file to unwanted location in the cmdline executable:

 0.0ms [ ERROR ]  <E> DspTransport.openSession qnn_open failed, 0x80000406

 0.0ms [ ERROR ]  <E> IDspTransport: Unable to load lib 0x80000406

 0.0ms [ ERROR ]  <E> DspTransport failed,cannot open session, error 0x00000009

 0.0ms [ ERROR ]  <E> Unable to load Skel Library. transportStatus: 9

 0.0ms [ ERROR ]  <E> Failed to retrieve skel build id: err: 10001

 0.0ms [ ERROR ]  <E> Failed to load skel, error: 4000

 0.0ms [VERBOSE]  <V> exits device initialization with  14001

 0.0ms [ ERROR ]  <E> Tranport layer setup failed: 14001

 0.0ms [ ERROR ]  <E> Failed to parse default platform info: 14001

 0.0ms [ ERROR ]  <E> Failed to load default platform info: 14001

 0.0ms [ ERROR ]  <E> Failed to parse platform config: 14001

 0.0ms [  INFO ]  <I> QnnDevice_create done. status 0x36b1

45.7ms [ ERROR ] Failed to create device
45.8ms [ ERROR ] Device Creation failure

Which I predict is about the same error message as what I am getting from the QNN engine in Android project. The backend phases before the CreateDevice are completed successfully; app->initialize(); and app->initializeBackend();

I have tried looking at the QNN manual but there does not seem to be any implementation details for building projects for Android devices outside of sample cmdline executables. Where should the skel.so be located in a project? The project currently is 98% same logic as the c++ cmdline application, same variables are used and the cmdline logic is intact, I just manually add the argc and argv vars in JNI layer.

I have tested setting the adsp variable also, but it does not seem to have any effect.

shuyuan-wang commented 5 months ago

Hi, how did you fix this problem?

OuterSpaceTraveller commented 5 months ago

Hi!

Update and include same libraries that are included in the SNPE demo (cdsp) and add update to ADSP_LIBRARY_PATH and LD_LIBRARY_PATH, to have the same includes. This path can be asked from Java and passed to JNI layer. It seems even though the names are different the shared objects probably are the same, meaning the SNPE probably just uses the QNN libraries.

The path can be asked like this, in the Java activity or fragment: (just example command, might need to do some adjusting)

String nativeLibPath = this.getActivity().getApplication().getApplicationInfo().nativeLibraryDir;

For including the skel etc. I did it in the Java class initialization as as required and created jniLibs directory (libs/arm64-v8a exactly without modifying the build.gradle)

Notice you cannot include the dsp libraries e.g. from Hexagon library directly, they are located already in the device. Instead use this for loading (add to manifests):

<uses-native-library
      android:name="[libcdsprpc.so](https://libcdsprpc.so/)"
      android:required="true" />

Someone also had noted that this is sometimes necessary in the gradle, but my device does not seem to care:

android:extractNativeLibs="true"

If the cdsp option gives error (not found or something like that) then probably the error is in the ADSP and LD paths, here is an example:

bool SetAdspLibraryPath(std::string nativeLibPath) {
    nativeLibPath += ";/data/local/tmp/mv_dlc;/vendor/lib/rfsa/adsp;/vendor/dsp/cdsp;/system/lib/rfsa/adsp;/system/vendor/lib/rfsa/adsp;/dsp";

    __android_log_print(ANDROID_LOG_INFO, "SNPE ", "ADSP Lib Path = %s \n", nativeLibPath.c_str());
    std::cout << "ADSP Lib Path = " << nativeLibPath << std::endl;

    return setenv("ADSP_LIBRARY_PATH", nativeLibPath.c_str(), 1 /*override*/) == 0;
}