Skip to content

Commit a593a94

Browse files
adrianlizarragaguschmue
authored andcommitted
[QNN EP] Make QNN EP a shared library (#23120)
### Description - Makes QNN EP a shared library **by default** when building with `--use_qnn` or `--use_qnn shared_lib`. Generates the following build artifacts: - **Windows**: `onnxruntime_providers_qnn.dll` and `onnxruntime_providers_shared.dll` - **Linux**: `libonnxruntime_providers_qnn.so` and `libonnxruntime_providers_shared.so` - **Android**: Not supported. Must build QNN EP as a static library. - Allows QNN EP to still be built as a static library with `--use_qnn static_lib`. This is primarily for the Android QNN AAR package. - Unit tests run for both the static and shared QNN EP builds. ### Detailed changes - Updates Java bindings to support both shared and static QNN EP builds. - Provider bridge API: - Adds logging sink ETW to the provider bridge. Allows EPs to register ETW callbacks for ORT logging. - Adds a variety of methods for onnxruntime objects that are needed by QNN EP. - QNN EP: - Adds `ort_api.h` and `ort_api.cc` that encapsulates the API provided by ORT in a manner that allows the EP to be built as either a shared or static library. - Adds custom function to transpose weights for Conv and Gemm (instead of adding util to provider bridge API). - Adds custom function to quantize data for LeakyRelu (instead of adding util to provider bridge API). - Adds custom ETW tracing for QNN profiling events: - shared library: defines its own TraceLogging provider handle - static library: uses ORT's TraceLogging provider handle and existing telemetry provider. - ORT-QNN Packages: - **Python**: Pipelines build QNN EP as a shared library by default. User can build a local python wheel with QNN EP as a static library by passing `--use_qnn static_lib`. - **NuGet**: Pipelines build QNN EP as a shared library by default. `build.py` currently enforces QNN EP to be built as a shared library. Can add support for building a QNN NuGet package with static later if deemed necessary. - **Android**: Pipelines build QNN EP as a **static library**. `build.py` enforces QNN EP to be built as a static library. Packaging multiple shared libraries into an Android AAR package is not currently supported due to the added need to also distribute a shared libcpp.so library. ### Motivation and Context <!-- - Why is this change required? What problem does it solve? - If it fixes an open issue, please link to the issue here. -->
1 parent c11ebdc commit a593a94

File tree

100 files changed

+2297
-692
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

100 files changed

+2297
-692
lines changed

cmake/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ option(onnxruntime_USE_OPENVINO "Build with OpenVINO support" OFF)
9393
option(onnxruntime_USE_COREML "Build with CoreML support" OFF)
9494
option(onnxruntime_USE_NNAPI_BUILTIN "Build with builtin NNAPI lib for Android NNAPI support" OFF)
9595
option(onnxruntime_USE_QNN "Build with QNN support" OFF)
96+
option(onnxruntime_BUILD_QNN_EP_STATIC_LIB "Build with QNN EP as a static library" OFF)
9697
option(onnxruntime_USE_SNPE "Build with SNPE support" OFF)
9798
option(onnxruntime_USE_RKNPU "Build with RKNPU support" OFF)
9899
option(onnxruntime_USE_DNNL "Build with DNNL support" OFF)

cmake/onnxruntime.cmake

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -199,17 +199,12 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Android" AND onnxruntime_BUILD_JAVA)
199199
endforeach()
200200
endif()
201201

202-
# This list is a reversed topological ordering of library dependencies.
203-
# Earlier entries may depend on later ones. Later ones should not depend on earlier ones.
204-
set(onnxruntime_INTERNAL_LIBRARIES
205-
onnxruntime_session
206-
${onnxruntime_libs}
202+
set(onnxruntime_INTERNAL_PROVIDER_LIBRARIES
207203
${PROVIDERS_ACL}
208204
${PROVIDERS_ARMNN}
209205
${PROVIDERS_COREML}
210206
${PROVIDERS_DML}
211207
${PROVIDERS_NNAPI}
212-
${PROVIDERS_QNN}
213208
${PROVIDERS_SNPE}
214209
${PROVIDERS_RKNPU}
215210
${PROVIDERS_VSINPU}
@@ -218,6 +213,18 @@ set(onnxruntime_INTERNAL_LIBRARIES
218213
${PROVIDERS_WEBNN}
219214
${PROVIDERS_AZURE}
220215
${PROVIDERS_INTERNAL_TESTING}
216+
)
217+
218+
if (onnxruntime_BUILD_QNN_EP_STATIC_LIB)
219+
list(APPEND onnxruntime_INTERNAL_PROVIDER_LIBRARIES onnxruntime_providers_qnn)
220+
endif()
221+
222+
# This list is a reversed topological ordering of library dependencies.
223+
# Earlier entries may depend on later ones. Later ones should not depend on earlier ones.
224+
set(onnxruntime_INTERNAL_LIBRARIES
225+
onnxruntime_session
226+
${onnxruntime_libs}
227+
${onnxruntime_INTERNAL_PROVIDER_LIBRARIES}
221228
${onnxruntime_winml}
222229
onnxruntime_optimizer
223230
onnxruntime_providers

cmake/onnxruntime_java.cmake

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ if (WIN32)
148148
if(NOT onnxruntime_ENABLE_STATIC_ANALYSIS)
149149
add_custom_command(TARGET onnxruntime4j_jni POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:onnxruntime> ${JAVA_PACKAGE_LIB_DIR}/$<TARGET_FILE_NAME:onnxruntime>)
150150
add_custom_command(TARGET onnxruntime4j_jni POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:onnxruntime4j_jni> ${JAVA_PACKAGE_JNI_DIR}/$<TARGET_FILE_NAME:onnxruntime4j_jni>)
151-
if (onnxruntime_USE_CUDA OR onnxruntime_USE_DNNL OR onnxruntime_USE_OPENVINO OR onnxruntime_USE_TENSORRT)
151+
if (onnxruntime_USE_CUDA OR onnxruntime_USE_DNNL OR onnxruntime_USE_OPENVINO OR onnxruntime_USE_TENSORRT OR (onnxruntime_USE_QNN AND NOT onnxruntime_BUILD_QNN_EP_STATIC_LIB))
152152
add_custom_command(TARGET onnxruntime4j_jni POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:onnxruntime_providers_shared> ${JAVA_PACKAGE_LIB_DIR}/$<TARGET_FILE_NAME:onnxruntime_providers_shared>)
153153
endif()
154154
if (onnxruntime_USE_CUDA)
@@ -163,11 +163,14 @@ if (WIN32)
163163
if (onnxruntime_USE_TENSORRT)
164164
add_custom_command(TARGET onnxruntime4j_jni POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:onnxruntime_providers_tensorrt> ${JAVA_PACKAGE_LIB_DIR}/$<TARGET_FILE_NAME:onnxruntime_providers_tensorrt>)
165165
endif()
166+
if (onnxruntime_USE_QNN AND NOT onnxruntime_BUILD_QNN_EP_STATIC_LIB)
167+
add_custom_command(TARGET onnxruntime4j_jni POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:onnxruntime_providers_qnn> ${JAVA_PACKAGE_LIB_DIR}/$<TARGET_FILE_NAME:onnxruntime_providers_qnn>)
168+
endif()
166169
endif()
167170
else()
168171
add_custom_command(TARGET onnxruntime4j_jni POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:onnxruntime> ${JAVA_PACKAGE_LIB_DIR}/$<TARGET_LINKER_FILE_NAME:onnxruntime>)
169172
add_custom_command(TARGET onnxruntime4j_jni POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:onnxruntime4j_jni> ${JAVA_PACKAGE_JNI_DIR}/$<TARGET_LINKER_FILE_NAME:onnxruntime4j_jni>)
170-
if (onnxruntime_USE_CUDA OR onnxruntime_USE_DNNL OR onnxruntime_USE_OPENVINO OR onnxruntime_USE_TENSORRT)
173+
if (onnxruntime_USE_CUDA OR onnxruntime_USE_DNNL OR onnxruntime_USE_OPENVINO OR onnxruntime_USE_TENSORRT OR (onnxruntime_USE_QNN AND NOT onnxruntime_BUILD_QNN_EP_STATIC_LIB))
171174
add_custom_command(TARGET onnxruntime4j_jni POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:onnxruntime_providers_shared> ${JAVA_PACKAGE_LIB_DIR}/$<TARGET_LINKER_FILE_NAME:onnxruntime_providers_shared>)
172175
endif()
173176
if (onnxruntime_USE_CUDA)
@@ -182,6 +185,9 @@ else()
182185
if (onnxruntime_USE_TENSORRT)
183186
add_custom_command(TARGET onnxruntime4j_jni POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:onnxruntime_providers_tensorrt> ${JAVA_PACKAGE_LIB_DIR}/$<TARGET_LINKER_FILE_NAME:onnxruntime_providers_tensorrt>)
184187
endif()
188+
if (onnxruntime_USE_QNN AND NOT onnxruntime_BUILD_QNN_EP_STATIC_LIB)
189+
add_custom_command(TARGET onnxruntime4j_jni POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:onnxruntime_providers_qnn> ${JAVA_PACKAGE_LIB_DIR}/$<TARGET_LINKER_FILE_NAME:onnxruntime_providers_qnn>)
190+
endif()
185191
endif()
186192

187193
# run the build process (this copies the results back into CMAKE_CURRENT_BINARY_DIR)

cmake/onnxruntime_providers.cmake

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,9 +74,6 @@ endif()
7474
if(onnxruntime_USE_JSEP)
7575
set(PROVIDERS_JS onnxruntime_providers_js)
7676
endif()
77-
if(onnxruntime_USE_QNN)
78-
set(PROVIDERS_QNN onnxruntime_providers_qnn)
79-
endif()
8077
if(onnxruntime_USE_RKNPU)
8178
set(PROVIDERS_RKNPU onnxruntime_providers_rknpu)
8279
endif()

cmake/onnxruntime_providers_cpu.cmake

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,9 @@ if (NOT onnxruntime_MINIMAL_BUILD AND NOT onnxruntime_EXTENDED_MINIMAL_BUILD
239239
set_property(TARGET onnxruntime_providers_shared APPEND_STRING PROPERTY LINK_FLAGS "-Xlinker -exported_symbols_list ${ONNXRUNTIME_ROOT}/core/providers/shared/exported_symbols.lst")
240240
elseif(UNIX)
241241
if(NOT ${CMAKE_SYSTEM_NAME} MATCHES "AIX")
242-
set_property(TARGET onnxruntime_providers_shared APPEND_STRING PROPERTY LINK_FLAGS "-Xlinker --version-script=${ONNXRUNTIME_ROOT}/core/providers/shared/version_script.lds -Xlinker --gc-sections")
242+
target_link_options(onnxruntime_providers_shared PRIVATE
243+
"LINKER:--version-script=${ONNXRUNTIME_ROOT}/core/providers/shared/version_script.lds"
244+
"LINKER:--gc-sections")
243245
endif()
244246
elseif(WIN32)
245247
set_property(TARGET onnxruntime_providers_shared APPEND_STRING PROPERTY LINK_FLAGS "-DEF:${ONNXRUNTIME_ROOT}/core/providers/shared/symbols.def")

cmake/onnxruntime_providers_qnn.cmake

Lines changed: 79 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -3,41 +3,89 @@
33

44
add_compile_definitions(USE_QNN=1)
55

6-
# These are shared utils,
7-
# TODO, move to a separate lib when used by EPs other than QNN, NNAPI and CoreML
8-
file(GLOB onnxruntime_providers_shared_utils_cc_srcs CONFIGURE_DEPENDS
9-
"${ONNXRUNTIME_ROOT}/core/providers/shared/utils/utils.h"
10-
"${ONNXRUNTIME_ROOT}/core/providers/shared/utils/utils.cc"
11-
)
6+
if(onnxruntime_BUILD_QNN_EP_STATIC_LIB)
7+
add_compile_definitions(BUILD_QNN_EP_STATIC_LIB=1)
8+
endif()
129

1310
file(GLOB_RECURSE
14-
onnxruntime_providers_qnn_ep_cc_srcs CONFIGURE_DEPENDS
15-
"${ONNXRUNTIME_ROOT}/core/providers/qnn/*.h"
16-
"${ONNXRUNTIME_ROOT}/core/providers/qnn/*.cc"
11+
onnxruntime_providers_qnn_ep_srcs CONFIGURE_DEPENDS
12+
"${ONNXRUNTIME_ROOT}/core/providers/qnn/*.h"
13+
"${ONNXRUNTIME_ROOT}/core/providers/qnn/*.cc"
1714
)
1815

19-
file(GLOB_RECURSE
20-
onnxruntime_providers_qnn_builder_cc_srcs CONFIGURE_DEPENDS
21-
"${ONNXRUNTIME_ROOT}/core/providers/qnn/builder/*.h"
22-
"${ONNXRUNTIME_ROOT}/core/providers/qnn/builder/*.cc"
23-
)
16+
if(onnxruntime_BUILD_QNN_EP_STATIC_LIB)
17+
#
18+
# Build QNN EP as a static library
19+
#
20+
set(onnxruntime_providers_qnn_srcs ${onnxruntime_providers_qnn_ep_srcs})
21+
source_group(TREE ${ONNXRUNTIME_ROOT}/core FILES ${onnxruntime_providers_qnn_srcs})
22+
onnxruntime_add_static_library(onnxruntime_providers_qnn ${onnxruntime_providers_qnn_srcs})
23+
onnxruntime_add_include_to_target(onnxruntime_providers_qnn onnxruntime_common onnxruntime_framework onnx
24+
onnx_proto protobuf::libprotobuf-lite
25+
flatbuffers::flatbuffers Boost::mp11)
26+
add_dependencies(onnxruntime_providers_qnn onnx ${onnxruntime_EXTERNAL_DEPENDENCIES})
27+
set_target_properties(onnxruntime_providers_qnn PROPERTIES CXX_STANDARD_REQUIRED ON)
28+
set_target_properties(onnxruntime_providers_qnn PROPERTIES FOLDER "ONNXRuntime")
29+
target_include_directories(onnxruntime_providers_qnn PRIVATE ${ONNXRUNTIME_ROOT}
30+
${onnxruntime_QNN_HOME}/include/QNN
31+
${onnxruntime_QNN_HOME}/include)
32+
set_target_properties(onnxruntime_providers_qnn PROPERTIES LINKER_LANGUAGE CXX)
2433

25-
set(onnxruntime_providers_qnn_cc_srcs
26-
${onnxruntime_providers_shared_utils_cc_srcs}
27-
${onnxruntime_providers_qnn_ep_cc_srcs}
28-
${onnxruntime_providers_qnn_builder_cc_srcs}
29-
)
34+
# ignore the warning unknown-pragmas on "pragma region"
35+
if(NOT MSVC)
36+
target_compile_options(onnxruntime_providers_qnn PRIVATE "-Wno-unknown-pragmas")
37+
endif()
38+
else()
39+
#
40+
# Build QNN EP as a shared library
41+
#
42+
file(GLOB_RECURSE
43+
onnxruntime_providers_qnn_shared_lib_srcs CONFIGURE_DEPENDS
44+
"${ONNXRUNTIME_ROOT}/core/providers/shared_library/*.h"
45+
"${ONNXRUNTIME_ROOT}/core/providers/shared_library/*.cc"
46+
)
47+
set(onnxruntime_providers_qnn_srcs ${onnxruntime_providers_qnn_ep_srcs}
48+
${onnxruntime_providers_qnn_shared_lib_srcs})
49+
50+
source_group(TREE ${ONNXRUNTIME_ROOT}/core FILES ${onnxruntime_providers_qnn_srcs})
51+
onnxruntime_add_shared_library_module(onnxruntime_providers_qnn ${onnxruntime_providers_qnn_srcs})
52+
onnxruntime_add_include_to_target(onnxruntime_providers_qnn ${ONNXRUNTIME_PROVIDERS_SHARED} ${GSL_TARGET} onnx
53+
onnxruntime_common Boost::mp11 safeint_interface)
54+
target_link_libraries(onnxruntime_providers_qnn PRIVATE ${ONNXRUNTIME_PROVIDERS_SHARED} ${ABSEIL_LIBS} ${CMAKE_DL_LIBS})
55+
add_dependencies(onnxruntime_providers_qnn onnxruntime_providers_shared ${onnxruntime_EXTERNAL_DEPENDENCIES})
56+
target_include_directories(onnxruntime_providers_qnn PRIVATE ${ONNXRUNTIME_ROOT}
57+
${CMAKE_CURRENT_BINARY_DIR}
58+
${onnxruntime_QNN_HOME}/include/QNN
59+
${onnxruntime_QNN_HOME}/include)
60+
61+
# Set linker flags for function(s) exported by EP DLL
62+
if(UNIX)
63+
target_link_options(onnxruntime_providers_qnn PRIVATE
64+
"LINKER:--version-script=${ONNXRUNTIME_ROOT}/core/providers/qnn/version_script.lds"
65+
"LINKER:--gc-sections"
66+
"LINKER:-rpath=\$ORIGIN"
67+
)
68+
elseif(WIN32)
69+
set_property(TARGET onnxruntime_providers_qnn APPEND_STRING PROPERTY LINK_FLAGS
70+
"-DEF:${ONNXRUNTIME_ROOT}/core/providers/qnn/symbols.def")
71+
else()
72+
message(FATAL_ERROR "onnxruntime_providers_qnn unknown platform, need to specify shared library exports for it")
73+
endif()
74+
75+
# Set compile options
76+
if(MSVC)
77+
target_compile_options(onnxruntime_providers_qnn PUBLIC /wd4099 /wd4005)
78+
else()
79+
# ignore the warning unknown-pragmas on "pragma region"
80+
target_compile_options(onnxruntime_providers_qnn PRIVATE "-Wno-unknown-pragmas")
81+
endif()
82+
83+
set_target_properties(onnxruntime_providers_qnn PROPERTIES LINKER_LANGUAGE CXX)
84+
set_target_properties(onnxruntime_providers_qnn PROPERTIES CXX_STANDARD_REQUIRED ON)
85+
set_target_properties(onnxruntime_providers_qnn PROPERTIES FOLDER "ONNXRuntime")
3086

31-
source_group(TREE ${ONNXRUNTIME_ROOT}/core FILES ${onnxruntime_providers_qnn_cc_srcs})
32-
onnxruntime_add_static_library(onnxruntime_providers_qnn ${onnxruntime_providers_qnn_cc_srcs})
33-
onnxruntime_add_include_to_target(onnxruntime_providers_qnn onnxruntime_common onnxruntime_framework onnx onnx_proto protobuf::libprotobuf-lite flatbuffers::flatbuffers Boost::mp11)
34-
target_link_libraries(onnxruntime_providers_qnn)
35-
add_dependencies(onnxruntime_providers_qnn onnx ${onnxruntime_EXTERNAL_DEPENDENCIES})
36-
set_target_properties(onnxruntime_providers_qnn PROPERTIES CXX_STANDARD_REQUIRED ON)
37-
set_target_properties(onnxruntime_providers_qnn PROPERTIES FOLDER "ONNXRuntime")
38-
target_include_directories(onnxruntime_providers_qnn PRIVATE ${ONNXRUNTIME_ROOT} ${onnxruntime_QNN_HOME}/include/QNN ${onnxruntime_QNN_HOME}/include)
39-
set_target_properties(onnxruntime_providers_qnn PROPERTIES LINKER_LANGUAGE CXX)
40-
# ignore the warning unknown-pragmas on "pragma region"
41-
if(NOT MSVC)
42-
target_compile_options(onnxruntime_providers_qnn PRIVATE "-Wno-unknown-pragmas")
87+
install(TARGETS onnxruntime_providers_qnn
88+
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
89+
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
90+
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
4391
endif()

cmake/onnxruntime_python.cmake

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -169,9 +169,7 @@ if (onnxruntime_ENABLE_LAZY_TENSOR)
169169
endif()
170170
endif()
171171

172-
target_link_libraries(onnxruntime_pybind11_state PRIVATE
173-
onnxruntime_session
174-
${onnxruntime_libs}
172+
set(onnxruntime_pybind11_state_static_providers
175173
${PROVIDERS_NNAPI}
176174
${PROVIDERS_VSINPU}
177175
${PROVIDERS_XNNPACK}
@@ -183,7 +181,16 @@ target_link_libraries(onnxruntime_pybind11_state PRIVATE
183181
${PROVIDERS_XNNPACK}
184182
${PROVIDERS_WEBGPU}
185183
${PROVIDERS_AZURE}
186-
${PROVIDERS_QNN}
184+
)
185+
186+
if(onnxruntime_BUILD_QNN_EP_STATIC_LIB)
187+
list(APPEND onnxruntime_pybind11_state_static_providers PRIVATE onnxruntime_providers_qnn)
188+
endif()
189+
190+
target_link_libraries(onnxruntime_pybind11_state PRIVATE
191+
onnxruntime_session
192+
${onnxruntime_libs}
193+
${onnxruntime_pybind11_state_static_providers}
187194
onnxruntime_optimizer
188195
onnxruntime_providers
189196
onnxruntime_util
@@ -1000,6 +1007,16 @@ if (onnxruntime_USE_COREML)
10001007
endif()
10011008

10021009
if (onnxruntime_USE_QNN)
1010+
if(NOT onnxruntime_BUILD_QNN_EP_STATIC_LIB)
1011+
add_custom_command(
1012+
TARGET onnxruntime_pybind11_state POST_BUILD
1013+
COMMAND ${CMAKE_COMMAND} -E copy
1014+
$<TARGET_FILE:onnxruntime_providers_qnn>
1015+
$<TARGET_FILE:onnxruntime_providers_shared>
1016+
$<TARGET_FILE_DIR:${build_output_target}>/onnxruntime/capi/
1017+
)
1018+
endif()
1019+
10031020
add_custom_command(
10041021
TARGET onnxruntime_pybind11_state POST_BUILD
10051022
COMMAND ${CMAKE_COMMAND} -E copy

cmake/onnxruntime_unittests.cmake

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -619,16 +619,13 @@ if(onnxruntime_USE_ARMNN)
619619
list(APPEND onnxruntime_test_providers_dependencies onnxruntime_providers_armnn)
620620
endif()
621621

622-
set(ONNXRUNTIME_TEST_LIBS
623-
onnxruntime_session
624-
${ONNXRUNTIME_INTEROP_TEST_LIBS}
625-
${onnxruntime_libs}
626-
# CUDA, ROCM, TENSORRT, MIGRAPHX, DNNL, and OpenVINO are dynamically loaded at runtime
622+
set(ONNXRUNTIME_TEST_STATIC_PROVIDER_LIBS
623+
# CUDA, ROCM, TENSORRT, MIGRAPHX, DNNL, and OpenVINO are dynamically loaded at runtime.
624+
# QNN EP can be built as either a dynamic and static libs.
627625
${PROVIDERS_NNAPI}
628626
${PROVIDERS_VSINPU}
629627
${PROVIDERS_JS}
630628
${PROVIDERS_WEBGPU}
631-
${PROVIDERS_QNN}
632629
${PROVIDERS_SNPE}
633630
${PROVIDERS_RKNPU}
634631
${PROVIDERS_DML}
@@ -637,6 +634,17 @@ set(ONNXRUNTIME_TEST_LIBS
637634
${PROVIDERS_COREML}
638635
${PROVIDERS_XNNPACK}
639636
${PROVIDERS_AZURE}
637+
)
638+
639+
if (onnxruntime_BUILD_QNN_EP_STATIC_LIB)
640+
list(APPEND ONNXRUNTIME_TEST_STATIC_PROVIDER_LIBS onnxruntime_providers_qnn)
641+
endif()
642+
643+
set(ONNXRUNTIME_TEST_LIBS
644+
onnxruntime_session
645+
${ONNXRUNTIME_INTEROP_TEST_LIBS}
646+
${onnxruntime_libs}
647+
${ONNXRUNTIME_TEST_STATIC_PROVIDER_LIBS}
640648
onnxruntime_optimizer
641649
onnxruntime_providers
642650
onnxruntime_util
@@ -700,7 +708,9 @@ if(onnxruntime_USE_QNN AND NOT onnxruntime_MINIMAL_BUILD AND NOT onnxruntime_RED
700708
list(APPEND onnxruntime_test_framework_src_patterns ${TEST_SRC_DIR}/providers/qnn/*)
701709
list(APPEND onnxruntime_test_framework_libs onnxruntime_providers_qnn)
702710
list(APPEND onnxruntime_test_providers_dependencies onnxruntime_providers_qnn)
703-
list(APPEND onnxruntime_test_providers_libs onnxruntime_providers_qnn)
711+
if(NOT onnxruntime_BUILD_QNN_EP_STATIC_LIB)
712+
list(APPEND onnxruntime_test_providers_dependencies onnxruntime_providers_shared)
713+
endif()
704714
endif()
705715

706716
if(onnxruntime_USE_SNPE)

java/src/main/java/ai/onnxruntime/OnnxRuntime.java

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,9 @@ final class OnnxRuntime {
7676
/** The short name of the ONNX runtime TensorRT provider library */
7777
static final String ONNXRUNTIME_LIBRARY_TENSORRT_NAME = "onnxruntime_providers_tensorrt";
7878

79+
/** The short name of the ONNX runtime QNN provider library */
80+
static final String ONNXRUNTIME_LIBRARY_QNN_NAME = "onnxruntime_providers_qnn";
81+
7982
/** The OS & CPU architecture string */
8083
private static final String OS_ARCH_STR = initOsArch();
8184

@@ -159,8 +162,11 @@ static synchronized void init() throws IOException {
159162
// the ONNX Runtime native library will load it
160163
extractProviderLibrary(ONNXRUNTIME_LIBRARY_SHARED_NAME);
161164

162-
load(ONNXRUNTIME_LIBRARY_NAME);
165+
if (!isAndroid()) {
166+
load(ONNXRUNTIME_LIBRARY_NAME);
167+
}
163168
load(ONNXRUNTIME_JNI_LIBRARY_NAME);
169+
164170
ortApiHandle = initialiseAPIBase(ORT_API_VERSION_14);
165171
if (ortApiHandle == 0L) {
166172
throw new IllegalStateException(
@@ -252,6 +258,16 @@ static boolean extractTensorRT() {
252258
return extractProviderLibrary(ONNXRUNTIME_LIBRARY_TENSORRT_NAME);
253259
}
254260

261+
/**
262+
* Extracts the QNN provider library from the classpath resources if present, or checks to see if
263+
* the QNN provider library is in the directory specified by {@link #ONNXRUNTIME_NATIVE_PATH}.
264+
*
265+
* @return True if the QNN provider library is ready for loading, false otherwise.
266+
*/
267+
static boolean extractQNN() {
268+
return extractProviderLibrary(ONNXRUNTIME_LIBRARY_QNN_NAME);
269+
}
270+
255271
/**
256272
* Extracts a shared provider library from the classpath resources if present, or checks to see if
257273
* that library is in the directory specified by {@link #ONNXRUNTIME_NATIVE_PATH}.
@@ -260,7 +276,7 @@ static boolean extractTensorRT() {
260276
* @return True if the library is ready for loading by ORT's native code, false otherwise.
261277
*/
262278
static synchronized boolean extractProviderLibrary(String libraryName) {
263-
// Android does not need to extract library and it has no shared provider library
279+
// Android does not need to extract provider libraries.
264280
if (isAndroid()) {
265281
return false;
266282
}
@@ -312,7 +328,7 @@ static boolean isAndroid() {
312328
private static void load(String library) throws IOException {
313329
// On Android, we simply use System.loadLibrary
314330
if (isAndroid()) {
315-
System.loadLibrary("onnxruntime4j_jni");
331+
System.loadLibrary(library);
316332
return;
317333
}
318334

java/src/main/java/ai/onnxruntime/OrtSession.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1320,6 +1320,10 @@ public void addXnnpack(Map<String, String> providerOptions) throws OrtException
13201320
*/
13211321
public void addQnn(Map<String, String> providerOptions) throws OrtException {
13221322
String qnnProviderName = "QNN";
1323+
1324+
// QNN can either be built as a shared or static library. extractQNN() will extract the
1325+
// (lib)onnxruntime_providers_qnn(.so/.dll) from classpath resources if present.
1326+
OnnxRuntime.extractQNN();
13231327
addExecutionProvider(qnnProviderName, providerOptions);
13241328
}
13251329

0 commit comments

Comments
 (0)