From c2ec3b734bb1816421fbf5dc6d8e162671aa0cd8 Mon Sep 17 00:00:00 2001 From: gwang-msft <62914304+gwang-msft@users.noreply.github.com> Date: Wed, 22 Jul 2020 14:08:12 -0700 Subject: [PATCH] [Android NNAPI EP] Remove dependency on external JD/DNNLibrary (#4576) * remove dependency of external jd-dnnlibrary * remove extra variables not used any more * update /cgmanifest.json --- .gitmodules | 3 - BUILD.md | 48 +-- cgmanifests/cgmanifest.json | 11 +- cgmanifests/submodules/cgmanifest.json | 120 ------- cmake/CMakeLists.txt | 9 +- cmake/external/DNNLibrary | 1 - cmake/onnxruntime_java.cmake | 2 +- cmake/onnxruntime_providers.cmake | 34 +- cmake/onnxruntime_unittests.cmake | 9 +- .../NNAPI-ExecutionProvider.md | 14 +- .../images/nnapi-ep-huaweihonorv10.png | Bin 40347 -> 0 bytes .../images/nnapi-ep-oneplus6t.png | Bin 42524 -> 0 bytes .../images/nnapi-ep-rk3399.png | Bin 40176 -> 0 bytes .../nnapi_execution_provider.cc | 328 ------------------ .../nnapi_execution_provider.h | 25 -- .../providers/nnapi/nnapi_provider_factory.cc | 7 - onnxruntime/test/framework/test_utils.h | 6 +- onnxruntime/test/onnx/main.cc | 2 +- .../test/providers/nnapi/nnapi_basic_test.cc | 11 +- samples/c_cxx/CMakeLists.txt | 3 +- server/CMakeLists.txt | 3 +- tools/ci_build/build.py | 15 +- tools/ci_build/github/linux/run_build.sh | 2 +- 23 files changed, 40 insertions(+), 613 deletions(-) delete mode 160000 cmake/external/DNNLibrary delete mode 100644 docs/execution_providers/images/nnapi-ep-huaweihonorv10.png delete mode 100644 docs/execution_providers/images/nnapi-ep-oneplus6t.png delete mode 100644 docs/execution_providers/images/nnapi-ep-rk3399.png delete mode 100644 onnxruntime/core/providers/nnapi/nnapi_dnnlibrary/nnapi_execution_provider.cc delete mode 100644 onnxruntime/core/providers/nnapi/nnapi_dnnlibrary/nnapi_execution_provider.h diff --git a/.gitmodules b/.gitmodules index 23bdfa36ce..f9be021588 100644 --- a/.gitmodules +++ b/.gitmodules @@ -25,9 +25,6 @@ [submodule "cmake/external/eigen"] path = cmake/external/eigen url = https://gitlab.com/libeigen/eigen.git -[submodule "cmake/external/DNNLibrary"] - path = cmake/external/DNNLibrary - url = https://github.com/JDAI-CV/DNNLibrary [submodule "cmake/external/horovod"] path = cmake/external/horovod url = https://github.com/horovod/horovod.git diff --git a/BUILD.md b/BUILD.md index 219508df21..e43593fbbf 100644 --- a/BUILD.md +++ b/BUILD.md @@ -257,13 +257,13 @@ DNNL: `./build.sh --use_dnnl` #### Deprecation Notice | | | -| --- | --- | +| --- | --- | | Deprecation Begins | June 1, 2020 | | Removal Date | December 1, 2020 | Starting with the OpenVINO™ toolkit 2020.2 release, all of the features previously available through nGraph have been merged into the OpenVINO™ toolkit. As a result, all the features previously available through ONNX RT Execution Provider for nGraph have been merged with ONNX RT Execution Provider for OpenVINO™ toolkit. -Therefore, ONNX RT Execution Provider for **nGraph** will be deprecated starting June 1, 2020 and will be completely removed on December 1, 2020. Users are recommended to migrate to the ONNX RT Execution Provider for OpenVINO™ toolkit as the unified solution for all AI inferencing on Intel® hardware. +Therefore, ONNX RT Execution Provider for **nGraph** will be deprecated starting June 1, 2020 and will be completely removed on December 1, 2020. Users are recommended to migrate to the ONNX RT Execution Provider for OpenVINO™ toolkit as the unified solution for all AI inferencing on Intel® hardware. See more information on the nGraph Execution Provider [here](./docs/execution_providers/nGraph-ExecutionProvider.md). @@ -345,31 +345,6 @@ For more information on OpenVINO Execution Provider's ONNX Layer support, To --- -### Android NNAPI - -See more information on the NNAPI Execution Provider [here](./docs/execution_providers/NNAPI-ExecutionProvider.md). - -#### Prerequisites - -To build ONNX Runtime with the NN API EP, first install Android NDK (see [Android Build instructions](#android)) - -#### Build Instructions - -The basic build commands are below. There are also some other parameters for building the Android version. See [Android Build instructions](#android) for more details. - -##### Cross compiling on Windows - -```bash -./build.bat --android --android_sdk_path --android_ndk_path --use_dnnlibrary -``` - -##### Cross compiling on Linux - -```bash -./build.sh --android --android_sdk_path --android_ndk_path --use_dnnlibrary -``` ---- - ### NUPHAR See more information on the Nuphar Execution Provider [here](./docs/execution_providers/Nuphar-ExecutionProvider.md). @@ -983,7 +958,7 @@ Install an NDK version - NDK path in our example with this install would be `.../Android/ndk/21.1.6352462` - NOTE: If you install the ndk-bundle package the path will be `.../Android/ndk-bundle` as there's no version number -#### Build Instructions +#### Android Build Instructions ##### Cross compiling on Windows @@ -998,14 +973,23 @@ e.g. using the paths from our example ./build.bat --android --android_sdk_path .../Android --android_ndk_path .../Android/ndk/21.1.6352462 --android_abi arm64-v8a --android_api 27 --cmake_generator Ninja ``` -##### Cross compiling on Linux +##### Cross compiling on Linux and macOS ``` ./build.sh --android --android_sdk_path --android_ndk_path --android_abi --android_api ``` -Android Archive (AAR) files, which can be imported directly in Android Studio, will be generated in your_build_dir/java/build/outputs/aar. -If you want to use NNAPI Execution Provider on Android, see [docs/execution_providers/NNAPI-ExecutionProvider.md](/docs/execution_providers/NNAPI-ExecutionProvider.md). +##### Build Android Archive (AAR) + +Android Archive (AAR) files, which can be imported directly in Android Studio, will be generated in your_build_dir/java/build/outputs/aar, by using the above building commands with `--build_java` + +#### Android NNAPI Execution Provider + +If you want to use NNAPI Execution Provider on Android, see [NNAPI Execution Provider](/docs/execution_providers/NNAPI-ExecutionProvider.md). + +##### Build Instructions + +Android NNAPI Execution Provider can be built using building commands in [Android Build instructions](#android-build-instructions) with `--use_nnapi` --- @@ -1014,7 +998,7 @@ If you want to use NNAPI Execution Provider on Android, see [docs/execution_prov See more information on the MIGraphX Execution Provider [here](./docs/execution_providers/MIGraphX-ExecutionProvider.md). #### Prerequisites -* Install [ROCM](https://rocmdocs.amd.com/en/latest/Installation_Guide/Installation-Guide.html) +* Install [ROCM](https://rocmdocs.amd.com/en/latest/Installation_Guide/Installation-Guide.html) * The MIGraphX execution provider for ONNX Runtime is built and tested with ROCM3.3 * Install [MIGraphX](https://github.com/ROCmSoftwarePlatform/AMDMIGraphX) * The path to MIGraphX installation must be provided via the `--migraphx_home parameter`. diff --git a/cgmanifests/cgmanifest.json b/cgmanifests/cgmanifest.json index 944f5b730b..eb4042a1ec 100644 --- a/cgmanifests/cgmanifest.json +++ b/cgmanifests/cgmanifest.json @@ -173,15 +173,6 @@ } } }, - { - "component": { - "type": "git", - "git": { - "commitHash": "647d4c3f4d47d9cf63fb90ec175c414a005adea7", - "repositoryUrl": "https://github.com/JDAI-CV/DNNLibrary.git" - } - } - }, { "component": { "Type": "other", @@ -308,4 +299,4 @@ } ], "Version": 1 -} +} \ No newline at end of file diff --git a/cgmanifests/submodules/cgmanifest.json b/cgmanifests/submodules/cgmanifest.json index 45466db2aa..916ba53cf6 100644 --- a/cgmanifests/submodules/cgmanifest.json +++ b/cgmanifests/submodules/cgmanifest.json @@ -1,126 +1,6 @@ { "Version": 1, "Registrations": [ - { - "component": { - "type": "git", - "git": { - "commitHash": "e17f11e966b2cce7d747799b76bb9843813d4b01", - "repositoryUrl": "https://github.com/JDAI-CV/DNNLibrary" - }, - "comments": "git submodule at cmake/external/DNNLibrary" - } - }, - { - "component": { - "type": "git", - "git": { - "commitHash": "9e7e8cbe9f675123dd41b7c62868acad39188cae", - "repositoryUrl": "https://github.com/google/flatbuffers" - }, - "comments": "git submodule at cmake/external/DNNLibrary/third_party/flatbuffers" - } - }, - { - "component": { - "type": "git", - "git": { - "commitHash": "8d7a107d68c127f3f494bb7807b796c8c5a97a82", - "repositoryUrl": "https://github.com/google/glog" - }, - "comments": "git submodule at cmake/external/DNNLibrary/third_party/glog" - } - }, - { - "component": { - "type": "git", - "git": { - "commitHash": "94d238d96e3fb3a7ba34f03c284b9ad3516163be", - "repositoryUrl": "https://github.com/onnx/onnx" - }, - "comments": "git submodule at cmake/external/DNNLibrary/third_party/onnx" - } - }, - { - "component": { - "type": "git", - "git": { - "commitHash": "e776aa0275e293707b6a0901e0e8d8a8a3679508", - "repositoryUrl": "https://github.com/google/benchmark.git" - }, - "comments": "git submodule at cmake/external/DNNLibrary/third_party/onnx/third_party/benchmark" - } - }, - { - "component": { - "type": "git", - "git": { - "commitHash": "a1041190c8b8ff0cd9e2f0752248ad5e3789ea0c", - "repositoryUrl": "https://github.com/pybind/pybind11.git" - }, - "comments": "git submodule at cmake/external/DNNLibrary/third_party/onnx/third_party/pybind11" - } - }, - { - "component": { - "type": "git", - "git": { - "commitHash": "6a00cbc4a9b8e68b71caf7f774b3f9c753ae84d5", - "repositoryUrl": "https://github.com/wjakob/clang-cindex-python3" - }, - "comments": "git submodule at cmake/external/DNNLibrary/third_party/onnx/third_party/pybind11/tools/clang" - } - }, - { - "component": { - "type": "git", - "git": { - "commitHash": "6973c3a5041636c1d8dc5f7f6c8c1f3c15bc63d6", - "repositoryUrl": "https://github.com/google/protobuf/" - }, - "comments": "git submodule at cmake/external/DNNLibrary/third_party/protobuf" - } - }, - { - "component": { - "type": "git", - "git": { - "commitHash": "5b7683f49e1e9223cf9927b24f6fd3d6bd82e3f8", - "repositoryUrl": "https://github.com/google/benchmark.git" - }, - "comments": "git submodule at cmake/external/DNNLibrary/third_party/protobuf/third_party/benchmark" - } - }, - { - "component": { - "type": "git", - "git": { - "commitHash": "c3bb0ee2a63279a803aaad956b9b26d74bf9e6e2", - "repositoryUrl": "https://github.com/google/googletest.git" - }, - "comments": "git submodule at cmake/external/DNNLibrary/third_party/protobuf/third_party/googletest" - } - }, - { - "component": { - "type": "git", - "git": { - "commitHash": "9bb3313162c0b856125e481ceece9d8faa567716", - "repositoryUrl": "https://github.com/pybind/pybind11" - }, - "comments": "git submodule at cmake/external/DNNLibrary/third_party/pybind11" - } - }, - { - "component": { - "type": "git", - "git": { - "commitHash": "6a00cbc4a9b8e68b71caf7f774b3f9c753ae84d5", - "repositoryUrl": "https://github.com/wjakob/clang-cindex-python3" - }, - "comments": "git submodule at cmake/external/DNNLibrary/third_party/pybind11/tools/clang" - } - }, { "component": { "type": "git", diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index 3a9cd9d383..374d28e3ee 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -50,7 +50,6 @@ option(onnxruntime_ENABLE_MEMLEAK_CHECKER "Experimental: Enable memory leak chec option(onnxruntime_USE_CUDA "Build with CUDA support" OFF) option(onnxruntime_USE_OPENVINO "Build with OpenVINO support" OFF) option(onnxruntime_USE_EIGEN_FOR_BLAS "Use eign for blas" ON) -option(onnxruntime_USE_NNAPI_DNNLIBRARY "Build with DNNLibrary for Android NNAPI support" OFF) option(onnxruntime_USE_NNAPI_BUILTIN "Build with builtin NNAPI lib for Android NNAPI support" OFF) option(onnxruntime_USE_RKNPU "Build with RKNPU support" OFF) option(onnxruntime_USE_DNNL "Build with DNNL support" OFF) @@ -199,10 +198,6 @@ if(onnxruntime_ENABLE_LTO) endif() endif() -if(onnxruntime_USE_NNAPI_BUILTIN AND onnxruntime_USE_NNAPI_DNNLIBRARY) - message(FATAL_ERROR "Please use only one of onnxruntime_USE_NNAPI_BUILTIN, onnxruntime_USE_NNAPI_DNNLIBRARY") -endif() - if(onnxruntime_DISABLE_RTTI) add_compile_definitions(ORT_NO_RTTI GOOGLE_PROTOBUF_NO_RTTI) if(MSVC) @@ -924,7 +919,7 @@ if (onnxruntime_USE_TENSORRT) # needs to link with stdc++fs in Linux if (NOT APPLE) list(APPEND onnxruntime_EXTERNAL_LIBRARIES stdc++fs) - endif() + endif() endif() endif() @@ -998,7 +993,7 @@ if (onnxruntime_ENABLE_TRAINING) if(NOT DEFINED onnxruntime_MPI_HOME) execute_process(COMMAND mpirun --version OUTPUT_VARIABLE MPIRUN_OUTPUT) else() - execute_process(COMMAND ${onnxruntime_MPI_HOME}/bin/mpirun --version OUTPUT_VARIABLE MPIRUN_OUTPUT) + execute_process(COMMAND ${onnxruntime_MPI_HOME}/bin/mpirun --version OUTPUT_VARIABLE MPIRUN_OUTPUT) endif(NOT DEFINED onnxruntime_MPI_HOME) string( REGEX MATCH "[0-9]+.[0-9]+.[0-9]" MPI_VERSION ${MPIRUN_OUTPUT}) message( STATUS "MPI Version: ${MPI_VERSION}") diff --git a/cmake/external/DNNLibrary b/cmake/external/DNNLibrary deleted file mode 160000 index e17f11e966..0000000000 --- a/cmake/external/DNNLibrary +++ /dev/null @@ -1 +0,0 @@ -Subproject commit e17f11e966b2cce7d747799b76bb9843813d4b01 diff --git a/cmake/onnxruntime_java.cmake b/cmake/onnxruntime_java.cmake index dc10831d99..8cf84f32fb 100644 --- a/cmake/onnxruntime_java.cmake +++ b/cmake/onnxruntime_java.cmake @@ -76,7 +76,7 @@ endif() if (onnxruntime_USE_TENSORRT) target_compile_definitions(onnxruntime4j_jni PRIVATE USE_TENSORRT=1) endif() -if (onnxruntime_USE_NNAPI_DNNLIBRARY OR onnxruntime_USE_NNAPI_BUILTIN) +if (onnxruntime_USE_NNAPI_BUILTIN) target_compile_definitions(onnxruntime4j_jni PRIVATE USE_NNAPI=1) endif() if (onnxruntime_USE_NUPHAR) diff --git a/cmake/onnxruntime_providers.cmake b/cmake/onnxruntime_providers.cmake index a9e246dbca..65f74790c9 100644 --- a/cmake/onnxruntime_providers.cmake +++ b/cmake/onnxruntime_providers.cmake @@ -59,7 +59,7 @@ if(onnxruntime_USE_TENSORRT) set(PROVIDERS_TENSORRT onnxruntime_providers_tensorrt) list(APPEND ONNXRUNTIME_PROVIDER_NAMES tensorrt) endif() -if(onnxruntime_USE_NNAPI_DNNLIBRARY OR onnxruntime_USE_NNAPI_BUILTIN) +if(onnxruntime_USE_NNAPI_BUILTIN) set(PROVIDERS_NNAPI onnxruntime_providers_nnapi) list(APPEND ONNXRUNTIME_PROVIDER_NAMES nnapi) endif() @@ -159,7 +159,7 @@ if (onnxruntime_ENABLE_TRAINING) if (onnxruntime_USE_HOROVOD) target_include_directories(onnxruntime_providers PRIVATE ${HOROVOD_INCLUDE_DIRS}) endif() - if (onnxruntime_USE_NCCL OR onnxruntime_USE_HOROVOD) + if (onnxruntime_USE_NCCL OR onnxruntime_USE_HOROVOD) target_include_directories(onnxruntime_providers PUBLIC ${MPI_INCLUDE_DIRS}) endif() endif() @@ -509,36 +509,8 @@ if (onnxruntime_USE_OPENVINO) endif() -if (onnxruntime_USE_NNAPI_DNNLIBRARY) +if (onnxruntime_USE_NNAPI_BUILTIN) add_definitions(-DUSE_NNAPI=1) - add_definitions(-DUSE_NNAPI_DNNLIBRARY=1) - option(DNN_READ_ONNX "" ON) - set(DNN_CUSTOM_PROTOC_EXECUTABLE ${ONNX_CUSTOM_PROTOC_EXECUTABLE}) - option(DNN_CMAKE_INSTALL "" OFF) - option(DNN_BUILD_BIN "" OFF) - add_subdirectory(${REPO_ROOT}/cmake/external/DNNLibrary) - file(GLOB - onnxruntime_providers_nnapi_cc_srcs CONFIGURE_DEPENDS - "${ONNXRUNTIME_ROOT}/core/providers/nnapi/*.cc" - "${ONNXRUNTIME_ROOT}/core/providers/nnapi/nnapi_dnnlibrary/*.h" - "${ONNXRUNTIME_ROOT}/core/providers/nnapi/nnapi_dnnlibrary/*.cc" - ) - source_group(TREE ${ONNXRUNTIME_ROOT}/core FILES ${onnxruntime_providers_nnapi_cc_srcs}) - add_library(onnxruntime_providers_nnapi ${onnxruntime_providers_nnapi_cc_srcs}) - onnxruntime_add_include_to_target(onnxruntime_providers_nnapi onnxruntime_common onnxruntime_framework onnx onnx_proto protobuf::libprotobuf-lite dnnlibrary::dnnlibrary) - target_link_libraries(onnxruntime_providers_nnapi dnnlibrary::dnnlibrary) - add_dependencies(onnxruntime_providers_nnapi - dnnlibrary::dnnlibrary - onnx ${onnxruntime_EXTERNAL_DEPENDENCIES}) - # Header files of DNNLibrary requires C++17, fortunately, all modern Android NDKs support C++17 - set_target_properties(onnxruntime_providers_nnapi PROPERTIES CXX_STANDARD 17) - set_target_properties(onnxruntime_providers_nnapi PROPERTIES CXX_STANDARD_REQUIRED ON) - set_target_properties(onnxruntime_providers_nnapi PROPERTIES FOLDER "ONNXRuntime") - target_include_directories(onnxruntime_providers_nnapi PRIVATE ${ONNXRUNTIME_ROOT} ${nnapi_INCLUDE_DIRS}) - set_target_properties(onnxruntime_providers_nnapi PROPERTIES LINKER_LANGUAGE CXX) -elseif (onnxruntime_USE_NNAPI_BUILTIN) - add_definitions(-DUSE_NNAPI=1) - add_definitions(-DUSE_NNAPI_BUILTIN=1) file(GLOB onnxruntime_providers_nnapi_cc_srcs_top CONFIGURE_DEPENDS "${ONNXRUNTIME_ROOT}/core/providers/nnapi/*.cc" diff --git a/cmake/onnxruntime_unittests.cmake b/cmake/onnxruntime_unittests.cmake index 12dd6e0053..113ec17851 100644 --- a/cmake/onnxruntime_unittests.cmake +++ b/cmake/onnxruntime_unittests.cmake @@ -207,7 +207,7 @@ if (onnxruntime_USE_NGRAPH) list(APPEND onnxruntime_test_providers_src ${onnxruntime_test_providers_ngraph_src}) endif() -if (onnxruntime_USE_NNAPI_DNNLIBRARY OR onnxruntime_USE_NNAPI_BUILTIN) +if (onnxruntime_USE_NNAPI_BUILTIN) file(GLOB_RECURSE onnxruntime_test_providers_nnapi_src CONFIGURE_DEPENDS "${TEST_SRC_DIR}/providers/nnapi/*" ) @@ -303,7 +303,7 @@ if(onnxruntime_USE_OPENVINO) list(APPEND onnxruntime_test_providers_dependencies onnxruntime_providers_openvino) endif() -if(onnxruntime_USE_NNAPI_DNNLIBRARY OR onnxruntime_USE_NNAPI_BUILTIN) +if(onnxruntime_USE_NNAPI_BUILTIN) list(APPEND onnxruntime_test_providers_dependencies onnxruntime_providers_nnapi) endif() @@ -393,7 +393,7 @@ if(onnxruntime_USE_TENSORRT) list(APPEND onnxruntime_test_providers_libs onnxruntime_providers_tensorrt) endif() -if(onnxruntime_USE_NNAPI_DNNLIBRARY OR onnxruntime_USE_NNAPI_BUILTIN) +if(onnxruntime_USE_NNAPI_BUILTIN) list(APPEND onnxruntime_test_framework_src_patterns ${TEST_SRC_DIR}/providers/nnapi/*) list(APPEND onnxruntime_test_framework_libs onnxruntime_providers_nnapi) list(APPEND onnxruntime_test_providers_dependencies onnxruntime_providers_nnapi) @@ -692,9 +692,6 @@ add_test(NAME onnx_test_pytorch_operator if (CMAKE_SYSTEM_NAME STREQUAL "Android") list(APPEND android_shared_libs log android) - if (onnxruntime_USE_NNAPI_DNNLIBRARY) - list(APPEND android_shared_libs neuralnetworks) - endif() endif() #perf test runner diff --git a/docs/execution_providers/NNAPI-ExecutionProvider.md b/docs/execution_providers/NNAPI-ExecutionProvider.md index e6dd8452c8..59b8659a8f 100644 --- a/docs/execution_providers/NNAPI-ExecutionProvider.md +++ b/docs/execution_providers/NNAPI-ExecutionProvider.md @@ -1,14 +1,14 @@ # NNAPI Execution Provider -[Android Neural Networks API (NNAPI)](https://developer.android.com/ndk/guides/neuralnetworks) is a unified interface to CPU, GPU, and NN accelerators on Android. It is supported by onnxruntime via [DNNLibrary](https://github.com/JDAI-CV/DNNLibrary). +[Android Neural Networks API (NNAPI)](https://developer.android.com/ndk/guides/neuralnetworks) is a unified interface to CPU, GPU, and NN accelerators on Android. ## Minimum requirements -The NNAPI EP requires Android devices with Android 8.1 or higher. +The NNAPI EP requires Android devices with Android 8.1 or higher, it is recommended to use Android devices with Android 9 or higher to achieve optimal performance. ## Build NNAPI EP -For build instructions, please see the [BUILD page](../../BUILD.md#Android-NNAPI). +For build instructions, please see the [BUILD page](../../BUILD.md#Android-NNAPI-Execution-Provider). ## Using NNAPI EP in C/C++ @@ -27,11 +27,3 @@ session_object.RegisterExecutionProvider(std::make_unique<::onnxruntime::NnapiEx status = session_object.Load(model_file_name); ``` The C API details are [here](../C_API.md#c-api). - -## Performance - -![NNAPI EP on RK3399](./images/nnapi-ep-rk3399.png) - -![NNAPI EP on OnePlus 6T](./images/nnapi-ep-oneplus6t.png) - -![NNAPI EP on Huawei Honor V10](./images/nnapi-ep-huaweihonorv10.png) diff --git a/docs/execution_providers/images/nnapi-ep-huaweihonorv10.png b/docs/execution_providers/images/nnapi-ep-huaweihonorv10.png deleted file mode 100644 index f3c5cd2a0cb1cc0e7b2c580383f66a8ad99adf46..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 40347 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 diff --git a/docs/execution_providers/images/nnapi-ep-oneplus6t.png b/docs/execution_providers/images/nnapi-ep-oneplus6t.png deleted file mode 100644 index 7d626a357219e2d0487985109aa7e90e059594a8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 42524 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 ^>NC#XZhUT5Wdh#06v%?m7~mF{S+x`% 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 GH~lXWWiUYi diff --git a/docs/execution_providers/images/nnapi-ep-rk3399.png b/docs/execution_providers/images/nnapi-ep-rk3399.png deleted file mode 100644 index d83784fca52e4e86fbd60169e7345120e983209d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 40176 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 S_&Y?mVz~L}A;-*Sto|RXe5kqr diff --git a/onnxruntime/core/providers/nnapi/nnapi_dnnlibrary/nnapi_execution_provider.cc b/onnxruntime/core/providers/nnapi/nnapi_dnnlibrary/nnapi_execution_provider.cc deleted file mode 100644 index d80f51191c..0000000000 --- a/onnxruntime/core/providers/nnapi/nnapi_dnnlibrary/nnapi_execution_provider.cc +++ /dev/null @@ -1,328 +0,0 @@ -// Copyright 2019 JD.com Inc. JD AI - -#include "nnapi_execution_provider.h" -#include "core/framework/allocatormgr.h" -#include "core/framework/compute_capability.h" -#include "core/session/onnxruntime_cxx_api.h" -#include "core/session/inference_session.h" -#include "core/graph/model.h" -#include "dnnlibrary/ModelBuilder.h" -#include "dnnlibrary/OnnxReader.h" -#include "tools/onnx2daq/OnnxConverter.h" - -namespace onnxruntime { - -constexpr const char* NNAPI = "Nnapi"; - -NnapiExecutionProvider::NnapiExecutionProvider() - : IExecutionProvider{onnxruntime::kNnapiExecutionProvider} { - DeviceAllocatorRegistrationInfo device_info( - {OrtMemTypeDefault, - [](int) { - return onnxruntime::make_unique(OrtMemoryInfo(NNAPI, OrtAllocatorType::OrtDeviceAllocator)); - }, - std::numeric_limits::max()}); - - InsertAllocator(CreateAllocator(device_info)); - - DeviceAllocatorRegistrationInfo cpu_memory_info( - {OrtMemTypeCPUOutput, - [](int) { - return onnxruntime::make_unique( - OrtMemoryInfo(NNAPI, OrtAllocatorType::OrtDeviceAllocator, OrtDevice(), 0, OrtMemTypeCPUOutput)); - }, - std::numeric_limits::max()}); - - InsertAllocator(CreateAllocator(cpu_memory_info)); -} - -NnapiExecutionProvider::~NnapiExecutionProvider() {} - -std::vector> NnapiExecutionProvider::GetSupportedNodes(const ONNX_NAMESPACE::ModelProto& model_proto) const { - dnn::OnnxConverter converter; - const auto nodes = converter.GetSupportedNodes(model_proto); - if (!nodes) { - return {{}}; - } - return nodes.value(); -} - -std::vector> -NnapiExecutionProvider::GetCapability(const onnxruntime::GraphViewer& graph, - const std::vector& /*kernel_registries*/) const { - // This method is based on that of TRT EP - // Construct modelproto from graph - onnxruntime::Model model(graph.Name(), true, ModelMetaData(), PathString(), IOnnxRuntimeOpSchemaRegistryList(), - graph.DomainToVersionMap(), std::vector(), *GetLogger()); - onnxruntime::Graph& graph_build = model.MainGraph(); - const std::vector& node_index = graph.GetNodesInTopologicalOrder(); - std::set all_node_inputs; - for (const auto& node : graph.Nodes()) { - std::vector inputs, outputs; - for (auto input : node.InputDefs()) { - auto& n_input = graph_build.GetOrCreateNodeArg(input->Name(), input->TypeAsProto()); - inputs.push_back(&n_input); - all_node_inputs.insert(&n_input); - } - for (auto output : node.OutputDefs()) { - auto& n_output = graph_build.GetOrCreateNodeArg(output->Name(), output->TypeAsProto()); - outputs.push_back(&n_output); - } - graph_build.AddNode(node.Name(), node.OpType(), node.Description(), inputs, outputs, &node.GetAttributes(), node.Domain()); - } - const auto graph_outputs = graph.GetOutputs(); - //Add initializer to graph - const auto& init_tensors = graph.GetAllInitializedTensors(); - for (const auto& tensor : init_tensors) { - graph_build.AddInitializedTensor(*(tensor.second)); - } - - ORT_ENFORCE(graph_build.Resolve().IsOK()); - ONNX_NAMESPACE::ModelProto model_proto = model.ToProto(); - model_proto.set_ir_version(ONNX_NAMESPACE::Version::IR_VERSION); - - const auto supported_nodes_vector = GetSupportedNodes(model_proto); - - std::unique_ptr sub_graph = onnxruntime::make_unique(); - - // Find inputs, initializers and outputs for each supported subgraph - std::vector> result; - - int counter = 0; - - for (const auto& group : supported_nodes_vector) { - if (!group.empty()) { - std::unordered_set node_set; - node_set.reserve(group.size()); - for (const auto& index : group) { - node_set.insert(node_index[index]); - } - std::unique_ptr sub_graph = onnxruntime::make_unique(); - // Find inputs and outputs of the subgraph - std::unordered_map fused_inputs, fused_outputs, fused_outputs_to_add; - std::unordered_set erased; - int input_order = 0; - int output_order = 0; - - for (const auto& index : group) { - sub_graph->nodes.push_back(node_index[index]); - const auto& node = graph.GetNode(node_index[index]); - - for (const auto& input : node->InputDefs()) { - const auto& it = fused_outputs.find(input); - - if (it != fused_outputs.end()) { - fused_outputs.erase(it); - erased.insert(input); - } - //only when input is neither in output list nor erased list, add the input to input list - else if (erased.find(input) == erased.end()) { - fused_inputs[input] = input_order++; - } - } - - // For output searching, there is a special case: - // If node's OutputEdges are more than its outputs, meaning certain output is used more than once, - // if the output is connected to nodes that don't belong to the subgraph, the output need to be added - // to the output list - if (node->GetOutputEdgesCount() > node->OutputDefs().size()) { - for (auto it = node->OutputEdgesBegin(), end = node->OutputEdgesEnd(); it != end; ++it) { - const auto& node_idx = it->GetNode().Index(); - const auto& output = (it->GetNode()).InputDefs()[it->GetDstArgIndex()]; - - if (node_set.find(node_idx) != node_set.end()) { - const auto& iter = fused_inputs.find(output); - - if (iter != fused_inputs.end()) { - fused_inputs.erase(iter); - erased.insert(output); - } else if (erased.find(output) == erased.end()) { - fused_outputs[output] = output_order++; - } - } else { - fused_outputs_to_add[output] = output_order++; - } - } - } else { - for (const auto& output : node->OutputDefs()) { - const auto& it = fused_inputs.find(output); - - if (it != fused_inputs.end()) { - fused_inputs.erase(it); - erased.insert(output); - } - // only when output is neither in input list nor erased list, add the output to output list - else if (erased.find(output) == erased.end()) { - fused_outputs[output] = output_order++; - } - } - } - } - - fused_outputs.insert(fused_outputs_to_add.begin(), fused_outputs_to_add.end()); - - // Sort inputs and outputs by the order they were added - std::multimap inputs, outputs; - - for (auto it = fused_inputs.begin(), end = fused_inputs.end(); it != end; ++it) { - inputs.insert(std::pair(it->second, it->first)); - } - - for (auto it = fused_outputs.begin(), end = fused_outputs.end(); it != end; ++it) { - for (const auto& x : all_node_inputs) { - if (x->Name() == it->first->Name()) { - outputs.insert(std::pair(it->second, it->first)); - break; - } - } - if (std::find(graph_outputs.begin(), graph_outputs.end(), it->first) != graph_outputs.end()) { - outputs.insert(std::pair(it->second, it->first)); - } - } - - // Assign inputs and outputs to subgraph's meta_def - auto meta_def = onnxruntime::make_unique<::onnxruntime::IndexedSubGraph::MetaDef>(); - meta_def->name = "NNAPI_" + std::to_string(counter++); - meta_def->domain = kMSDomain; - - for (const auto& input : inputs) { - meta_def->inputs.push_back(input.second->Name()); - } - - for (const auto& output : outputs) { - meta_def->outputs.push_back(output.second->Name()); - } - - meta_def->since_version = 1; - sub_graph->SetMetaDef(meta_def); - - result.push_back(onnxruntime::make_unique(std::move(sub_graph))); - } - } - - return result; -} - -common::Status NnapiExecutionProvider::Compile(const std::vector& fused_nodes, - std::vector& node_compute_funcs) { - for (const auto* fused_node : fused_nodes) { - // Reconstruct graph proto from fused node's function body - const auto* func_body = fused_node->GetFunctionBody(); - if (!func_body) { - return common::Status(common::ONNXRUNTIME, common::INVALID_ARGUMENT, "Function body is empty"); - } - const Graph& graph_body = func_body->Body(); - onnxruntime::Model model(graph_body.Name(), true, ModelMetaData(), PathString(), - IOnnxRuntimeOpSchemaRegistryList(), graph_body.DomainToVersionMap(), - std::vector(), *GetLogger()); - ONNX_NAMESPACE::ModelProto model_proto = model.ToProto(); - *(model_proto.mutable_graph()) = graph_body.ToGraphProto(); - model_proto.set_ir_version(ONNX_NAMESPACE::Version::IR_VERSION); - - dnn::OnnxReader onnx_reader; - dnn::ModelBuilder model_builder; - onnx_reader.ReadOnnx(model_proto, model_builder); - model_builder.AllowFp16(true); - auto dnn_model = model_builder.Compile(model_builder.PREFERENCE_SUSTAINED_SPEED); - dnn_models_.emplace(fused_node->Name(), std::move(dnn_model)); - - NodeComputeInfo compute_info; - compute_info.create_state_func = [&](ComputeContext* context, FunctionState* state) { - *state = dnn_models_[context->node_name].get(); - return 0; - }; - - compute_info.release_state_func = [](FunctionState state) { - // the `state` is a dnn::model managed by unique_ptr - ORT_UNUSED_PARAMETER(state); - }; - - compute_info.compute_func = [](FunctionState state, const OrtCustomOpApi* api, OrtKernelContext* context) { - Ort::CustomOpApi ort{*api}; - dnn::Model* model = reinterpret_cast(state); - const size_t num_inputs = ort.KernelContext_GetInputCount(context); - const size_t num_outputs = ort.KernelContext_GetOutputCount(context); - ORT_ENFORCE(model->GetInputs().size() <= num_inputs, "Inconsistent input sizes"); - ORT_ENFORCE(model->GetOutputs().size() == num_outputs, "Inconsistent output sizes"); - // Maintain the created nhwc buffers so that they can be deleted after inferencing - std::vector nhwc_inputs; - std::vector>> nhwc_outputs; - for (size_t i = 0; i < num_outputs; i++) { - const auto output_name = model->GetOutputs()[i]; - const auto output_shape = model->GetShape(output_name); - std::vector int64_output_shape(output_shape.begin(), output_shape.end()); - if (int64_output_shape.size() == 4) { - // NHWC to NCHW - std::swap(int64_output_shape[1], int64_output_shape[3]); - std::swap(int64_output_shape[2], int64_output_shape[3]); - float* nhwc_output = new float[model->GetSize(output_name)]; - model->SetOutputBuffer(i, nhwc_output); - nhwc_outputs.push_back(std::make_tuple(i, nhwc_output, int64_output_shape)); - } else { - auto* output_tensor = ort.KernelContext_GetOutput(context, i, int64_output_shape.data(), int64_output_shape.size()); - model->SetOutputBuffer(i, ort.GetTensorMutableData(output_tensor)); - } - } - std::vector inputs; - for (size_t i = 0; i < model->GetInputs().size(); i++) { - const OrtValue* input_tensor = ort.KernelContext_GetInput(context, i); - float* input = const_cast(ort.GetTensorData(input_tensor)); - - const auto tensor_info = ort.GetTensorTypeAndShape(input_tensor); - const auto& tensor_shape = ort.GetTensorShape(tensor_info); - - if (tensor_shape.size() == 4) { - // Transpose nchw -> nhwc manually - const int N = tensor_shape[0], C = tensor_shape[1], H = tensor_shape[2], W = tensor_shape[3]; - float* nhwc_input = new float[N * C * H * W]; - for (int n = 0; n < N; n++) { - for (int c = 0; c < C; c++) { - for (int h = 0; h < H; h++) { - for (int w = 0; w < W; w++) { - nhwc_input[n * H * W * C + h * W * C + w * C + c] = input[n * C * H * W + c * H * W + h * W + w]; - } - } - } - } - inputs.push_back(nhwc_input); - nhwc_inputs.push_back(nhwc_input); - } else { - inputs.push_back(input); - } - ort.ReleaseTensorTypeAndShapeInfo(tensor_info); - } - model->Predict(inputs); - // Transpose nhwc -> nchw manually - for (size_t i = 0; i < nhwc_outputs.size(); i++) { - const auto output = nhwc_outputs[i]; - size_t index; - float* nhwc_data; - std::vector nchw_shape; - std::tie(index, nhwc_data, nchw_shape) = output; - auto* output_tensor = ort.KernelContext_GetOutput(context, index, nchw_shape.data(), nchw_shape.size()); - const int N = nchw_shape[0], C = nchw_shape[1], H = nchw_shape[2], W = nchw_shape[3]; - float* nchw_output = ort.GetTensorMutableData(output_tensor); - for (int n = 0; n < N; n++) { - for (int c = 0; c < C; c++) { - for (int h = 0; h < H; h++) { - for (int w = 0; w < W; w++) { - nchw_output[n * C * H * W + c * H * W + h * W + w] = nhwc_data[n * H * W * C + h * W * C + w * C + c]; - } - } - } - } - } - for (auto nhwc_input : nhwc_inputs) { - delete[] nhwc_input; - } - for (auto nhwc_output : nhwc_outputs) { - delete[] std::get<1>(nhwc_output); - } - return Status::OK(); - }; - - node_compute_funcs.push_back(compute_info); - } - return Status::OK(); -} -} // namespace onnxruntime diff --git a/onnxruntime/core/providers/nnapi/nnapi_dnnlibrary/nnapi_execution_provider.h b/onnxruntime/core/providers/nnapi/nnapi_dnnlibrary/nnapi_execution_provider.h deleted file mode 100644 index a03eb5c7f4..0000000000 --- a/onnxruntime/core/providers/nnapi/nnapi_dnnlibrary/nnapi_execution_provider.h +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright 2019 JD.com Inc. JD AI - -#pragma once - -#include "core/framework/execution_provider.h" -#include "core/graph/onnx_protobuf.h" -#include "dnnlibrary/Model.h" - -namespace onnxruntime { -class NnapiExecutionProvider : public IExecutionProvider { - public: - NnapiExecutionProvider(); - virtual ~NnapiExecutionProvider(); - - std::vector> - GetCapability(const onnxruntime::GraphViewer& graph, - const std::vector& /*kernel_registries*/) const override; - common::Status Compile(const std::vector& fused_nodes, - std::vector& node_compute_funcs) override; - - private: - std::unordered_map> dnn_models_; - std::vector> GetSupportedNodes(const ONNX_NAMESPACE::ModelProto& model_proto) const; -}; -} // namespace onnxruntime diff --git a/onnxruntime/core/providers/nnapi/nnapi_provider_factory.cc b/onnxruntime/core/providers/nnapi/nnapi_provider_factory.cc index 1b50a5bdb4..11f3bf67d8 100644 --- a/onnxruntime/core/providers/nnapi/nnapi_provider_factory.cc +++ b/onnxruntime/core/providers/nnapi/nnapi_provider_factory.cc @@ -2,12 +2,7 @@ #include "core/providers/nnapi/nnapi_provider_factory.h" #include "core/session/abi_session_options_impl.h" - -#ifdef USE_NNAPI_DNNLIBRARY -#include "nnapi_dnnlibrary/nnapi_execution_provider.h" -#elif USE_NNAPI_BUILTIN #include "nnapi_builtin/nnapi_execution_provider.h" -#endif using namespace onnxruntime; @@ -33,5 +28,3 @@ ORT_API_STATUS_IMPL(OrtSessionOptionsAppendExecutionProvider_Nnapi, _In_ OrtSess options->provider_factories.push_back(onnxruntime::CreateExecutionProviderFactory_Nnapi()); return nullptr; } - - diff --git a/onnxruntime/test/framework/test_utils.h b/onnxruntime/test/framework/test_utils.h index 431ea52ef8..56184b2262 100644 --- a/onnxruntime/test/framework/test_utils.h +++ b/onnxruntime/test/framework/test_utils.h @@ -22,11 +22,7 @@ #include "core/providers/openvino/openvino_execution_provider.h" #endif #ifdef USE_NNAPI -# ifdef USE_NNAPI_DNNLIBRARY -# include "core/providers/nnapi/nnapi_dnnlibrary/nnapi_execution_provider.h" -# elif USE_NNAPI_BUILTIN -# include "core/providers/nnapi/nnapi_builtin/nnapi_execution_provider.h" -# endif +#include "core/providers/nnapi/nnapi_builtin/nnapi_execution_provider.h" #endif #ifdef USE_RKNPU #include "core/providers/rknpu/rknpu_execution_provider.h" diff --git a/onnxruntime/test/onnx/main.cc b/onnxruntime/test/onnx/main.cc index db82906abe..3864461149 100644 --- a/onnxruntime/test/onnx/main.cc +++ b/onnxruntime/test/onnx/main.cc @@ -344,7 +344,7 @@ int real_main(int argc, char* argv[], Ort::Env& env) { #ifdef USE_NNAPI Ort::ThrowOnError(OrtSessionOptionsAppendExecutionProvider_Nnapi(sf)); #else - fprintf(stderr, "DNNLibrary/NNAPI is not supported in this build"); + fprintf(stderr, "NNAPI is not supported in this build"); return -1; #endif } diff --git a/onnxruntime/test/providers/nnapi/nnapi_basic_test.cc b/onnxruntime/test/providers/nnapi/nnapi_basic_test.cc index 1354a81cdc..877303f921 100644 --- a/onnxruntime/test/providers/nnapi/nnapi_basic_test.cc +++ b/onnxruntime/test/providers/nnapi/nnapi_basic_test.cc @@ -1,14 +1,9 @@ +#include "core/common/logging/logging.h" +#include "core/providers/nnapi/nnapi_builtin/nnapi_execution_provider.h" #include "core/session/inference_session.h" +#include "gtest/gtest.h" #include "test/providers/provider_test_utils.h" #include "test/framework/test_utils.h" -#include "gtest/gtest.h" -#include "core/common/logging/logging.h" - -#ifdef USE_NNAPI_DNNLIBRARY -#include "core/providers/nnapi/nnapi_dnnlibrary/nnapi_execution_provider.h" -#elif USE_NNAPI_BUILTIN -#include "core/providers/nnapi/nnapi_builtin/nnapi_execution_provider.h" -#endif using namespace std; using namespace ONNX_NAMESPACE; diff --git a/samples/c_cxx/CMakeLists.txt b/samples/c_cxx/CMakeLists.txt index d4b37dcba6..078c53c0f9 100644 --- a/samples/c_cxx/CMakeLists.txt +++ b/samples/c_cxx/CMakeLists.txt @@ -15,7 +15,6 @@ endif() #onnxruntime providers option(onnxruntime_USE_CUDA "Build with CUDA support" OFF) option(onnxruntime_USE_OPENVINO "Build with OpenVINO support" OFF) -option(onnxruntime_USE_NNAPI_DNNLIBRARY "Build with DNNLibrary for Android NNAPI support" OFF) option(onnxruntime_USE_NNAPI_BUILTIN "Build with builtin NNAPI lib for Android NNAPI support" OFF) option(onnxruntime_USE_DNNL "Build with DNNL support" OFF) option(onnxruntime_USE_NGRAPH "Build with nGraph support" OFF) @@ -56,7 +55,7 @@ endif() if(onnxruntime_USE_OPENVINO) add_definitions(-DUSE_OPENVINO) endif() -if(onnxruntime_USE_NNAPI_DNNLIBRARY OR onnxruntime_USE_NNAPI_BUILTIN) +if(onnxruntime_USE_NNAPI_BUILTIN) add_definitions(-DUSE_NNAPI) endif() if(onnxruntime_USE_DNNL) diff --git a/server/CMakeLists.txt b/server/CMakeLists.txt index 1712fdb1ef..cd2ba56871 100755 --- a/server/CMakeLists.txt +++ b/server/CMakeLists.txt @@ -8,7 +8,6 @@ project(onnxruntime C CXX) option(onnxruntime_USE_CUDA "Build with CUDA support" OFF) option(onnxruntime_USE_OPENVINO "Build with OpenVINO support" OFF) -option(onnxruntime_USE_NNAPI_DNNLIBRARY "Build with DNNLibrary for Android NNAPI support" OFF) option(onnxruntime_USE_NNAPI_BUILTIN "Build with builtin NNAPI lib for Android NNAPI support" OFF) option(onnxruntime_USE_DNNL "Build with DNNL support" OFF) option(onnxruntime_USE_NGRAPH "Build with nGraph support" OFF) @@ -24,7 +23,7 @@ endif() if(onnxruntime_USE_OPENVINO) add_definitions(-DUSE_OPENVINO=1) endif() -if(onnxruntime_USE_NNAPI_DNNLIBRARY OR onnxruntime_USE_NNAPI_BUILTIN) +if(onnxruntime_USE_NNAPI_BUILTIN) add_definitions(-DUSE_NNAPI=1) endif() if(onnxruntime_USE_DNNL) diff --git a/tools/ci_build/build.py b/tools/ci_build/build.py index e5ca353a38..f5ab736535 100755 --- a/tools/ci_build/build.py +++ b/tools/ci_build/build.py @@ -257,8 +257,6 @@ def parse_arguments(): choices=["CPU_FP32", "GPU_FP32", "GPU_FP16", "VAD-M_FP16", "MYRIAD_FP16", "VAD-F_FP32"], help="Build with OpenVINO for specific hardware.") - parser.add_argument( - "--use_dnnlibrary", action='store_true', help="Build with DNNLibrary.") parser.add_argument( "--use_nnapi", action='store_true', help="Build with NNAPI support.") parser.add_argument( @@ -601,14 +599,13 @@ def generate_build_tree(cmake_path, source_dir, build_dir, cuda_home, cudnn_home "ON" if args.use_openvino == "VAD-F_FP32" else "OFF"), "-Donnxruntime_USE_OPENVINO_BINARY=" + ( "ON" if args.use_openvino else "OFF"), - "-Donnxruntime_USE_NNAPI_DNNLIBRARY=" + ("ON" if args.use_dnnlibrary else "OFF"), "-Donnxruntime_USE_NNAPI_BUILTIN=" + ("ON" if args.use_nnapi else "OFF"), "-Donnxruntime_USE_RKNPU=" + ("ON" if args.use_rknpu else "OFF"), "-Donnxruntime_USE_OPENMP=" + ( "ON" if args.use_openmp and not ( - args.use_dnnlibrary or args.use_mklml or args.use_ngraph or + args.use_nnapi or args.use_mklml or args.use_ngraph or args.android or (args.ios and is_macOS()) - or args.use_rknpu or args.use_nnapi) + or args.use_rknpu) else "OFF"), "-Donnxruntime_USE_TVM=" + ("ON" if args.use_tvm else "OFF"), "-Donnxruntime_USE_LLVM=" + ("ON" if args.use_llvm else "OFF"), @@ -707,12 +704,6 @@ def generate_build_tree(cmake_path, source_dir, build_dir, cuda_home, cudnn_home "-Deigen_SOURCE_PATH=" + args.eigen_path] if args.android: - if args.use_dnnlibrary and args.use_nnapi: - raise BuildError( - "Only one of --use_dnnlibrary and --use_nnapi " + - "can be enabled" - ) - cmake_args += [ "-DCMAKE_TOOLCHAIN_FILE=" + args.android_ndk_path + "/build/cmake/android.toolchain.cmake", @@ -1176,7 +1167,7 @@ def run_onnxruntime_tests(args, source_dir, ctest_path, build_dir, configs): adb_push('onnx_test_runner', '/data/local/tmp/', cwd=cwd) adb_shell( 'cd /data/local/tmp && /data/local/tmp/onnxruntime_test_all') - if args.use_dnnlibrary or args.use_nnapi: + if args.use_nnapi: adb_shell( 'cd /data/local/tmp && /data/local/tmp/onnx_test_runner -e nnapi /data/local/tmp/test') # noqa else: diff --git a/tools/ci_build/github/linux/run_build.sh b/tools/ci_build/github/linux/run_build.sh index a8800dba2c..2c0ba57c10 100755 --- a/tools/ci_build/github/linux/run_build.sh +++ b/tools/ci_build/github/linux/run_build.sh @@ -23,7 +23,7 @@ if [ $BUILD_OS = "android" ]; then pushd /onnxruntime_src mkdir build-android && cd build-android if [ $BUILD_DEVICE = "nnapi" ]; then - cmake -DCMAKE_TOOLCHAIN_FILE=/android-ndk/build/cmake/android.toolchain.cmake -DANDROID_ABI=arm64-v8a -DONNX_CUSTOM_PROTOC_EXECUTABLE=/usr/bin/protoc -Donnxruntime_USE_NNAPI=ON ../cmake + cmake -DCMAKE_TOOLCHAIN_FILE=/android-ndk/build/cmake/android.toolchain.cmake -DANDROID_ABI=arm64-v8a -DONNX_CUSTOM_PROTOC_EXECUTABLE=/usr/bin/protoc -Donnxruntime_USE_NNAPI_BUILTIN=ON ../cmake else cmake -DCMAKE_TOOLCHAIN_FILE=/android-ndk/build/cmake/android.toolchain.cmake -DANDROID_ABI=arm64-v8a -DONNX_CUSTOM_PROTOC_EXECUTABLE=/usr/bin/protoc ../cmake fi