Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[QNN EP] Make QNN EP a shared library #23120

Open
wants to merge 91 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 89 commits
Commits
Show all changes
91 commits
Select commit Hold shift + click to select a range
d035fb4
Copy shared utils into qnn ep
adrianlizarraga Dec 7, 2024
7e46a7d
Update QNN EP's initializer transpose logic to use only functions exp…
adrianlizarraga Dec 10, 2024
a155b33
Update comment
adrianlizarraga Dec 10, 2024
e9c5f14
Added TransposeBase::DoTranspose() to provider bridge. May elect to r…
adrianlizarraga Dec 10, 2024
d0f64dc
Add TypeProto_Tensor_has_elem_type() to provider bridge
adrianlizarraga Dec 10, 2024
f8bd2f6
Add to provider bridge: TensorTypeBase class, TensorTypeBase::GetElem…
adrianlizarraga Dec 10, 2024
1f533a9
Transpose initializers within QNN EP without using CPU EP utils
adrianlizarraga Dec 11, 2024
ccaefb3
Rename transpose func
adrianlizarraga Dec 11, 2024
fb765c7
Remove TransposeBase forward declaration from provider bridge
adrianlizarraga Dec 11, 2024
0237bca
Rewrite SliceOpBuilder util GetInitializerInputData() to not use func…
adrianlizarraga Dec 11, 2024
e3705b2
Revert addition of TensorTypeBase to provider bridge
adrianlizarraga Dec 11, 2024
6f0b3c6
Remove last use of GetTensorShapeFromTensorProto
adrianlizarraga Dec 11, 2024
5939bf6
Add DataTypeUtils::ToType(std::string&) to provider bridge
adrianlizarraga Dec 11, 2024
58dbf49
Add Logger::GetSeverity() to provider bridge
adrianlizarraga Dec 11, 2024
f76b09a
Add TensorShapeProto_Dimensions__size to provider bridge
adrianlizarraga Dec 11, 2024
d189fe6
Add utils::CreateSupportedPartitions() to provider bridege
adrianlizarraga Dec 12, 2024
a0b3c75
Merge main and fix conflicts
adrianlizarraga Dec 13, 2024
48191ea
Use new namespace for NodeAttrHelper
adrianlizarraga Dec 13, 2024
e6afd72
Add to provider bridge: GraphViewer::Nodes(), ConstGraphNodes struct …
adrianlizarraga Dec 13, 2024
0b1e538
Replace usage of cbegin() and cend() in NodeAttrHelper with version t…
adrianlizarraga Dec 13, 2024
fb3618d
Add convenience function to get the default Env to provider bridge
adrianlizarraga Dec 13, 2024
6b581fd
Moving ORT includes to a separate header
adrianlizarraga Dec 14, 2024
a1129e5
Add Node::EdgeEnd wrapper class to provider bridge. Add NodeUnit cons…
adrianlizarraga Dec 15, 2024
ba86c41
Move more header includes to ort_api.h
adrianlizarraga Dec 15, 2024
2b1ea09
Add GraphViewer::NodeProducesGraphOutput() to provider bridge
adrianlizarraga Dec 15, 2024
421cd78
Replace use of InlinedVector with std::vector and fix newly discovere…
adrianlizarraga Dec 15, 2024
d94e6f7
Eliminate use of qmath.h by introducing new quantization utils for QNN
adrianlizarraga Dec 15, 2024
4eb1e80
Move includes into qnn/ort_api.h
adrianlizarraga Dec 15, 2024
d86fb6c
Add TensorProto::has_data_type() to provider bridge
adrianlizarraga Dec 15, 2024
187e3b9
Checkpoint: updating usage of provider bridge in ep
adrianlizarraga Dec 15, 2024
693dd33
Compiles but does not link (until update cmake to build as shared lib)
adrianlizarraga Dec 16, 2024
ae2dbd2
Use provider bridge function to get default Env
adrianlizarraga Dec 16, 2024
db5f0ec
It works! QNN EP is a shared library and all QNN unit tests pass on W…
adrianlizarraga Dec 16, 2024
ea2a141
Add onnxruntime_providers_qnn.dll to nuget
adrianlizarraga Dec 16, 2024
d820c9b
Pass --build_shared_lib to some QNN pipelines. Include Boost::mp11.
adrianlizarraga Dec 16, 2024
9861ec8
Copy qnn dll for java build
adrianlizarraga Dec 16, 2024
b92043d
Add linker -rpath="
adrianlizarraga Dec 17, 2024
f29ce59
two backslashes in rpath
adrianlizarraga Dec 17, 2024
5d954d6
Copy qnn ep dlls when running java unit tests
adrianlizarraga Dec 17, 2024
03614bc
Modify Java bindings to use QNN shared lib
adrianlizarraga Dec 17, 2024
421f39f
Try to build onnxruntime_providers_shared on Android
adrianlizarraga Dec 17, 2024
7aae2b3
Merge branch 'main' into adrianl/qnn-ep-dynamic-lib
adrianlizarraga Dec 17, 2024
9354f18
Pass linker flag to Android build of qnn dll
adrianlizarraga Dec 19, 2024
e8df64f
Try different linker flag for android
adrianlizarraga Dec 19, 2024
863ff04
Use -z undefs on android
adrianlizarraga Dec 19, 2024
ef1b91d
Expose ETW logger functionality via provider bridge. Fix multithreadi…
adrianlizarraga Dec 19, 2024
57e0072
Cmake java android: copy libonnxruntime_providers_shared.so and libon…
adrianlizarraga Dec 19, 2024
bd32daa
QNN Nuget Pipeline: print contents of binaries directory to see if sh…
adrianlizarraga Dec 19, 2024
8a65a1d
Fix print in yaml
adrianlizarraga Dec 19, 2024
7ff94a0
Fix cmake copy command for Java build with qnn
adrianlizarraga Dec 19, 2024
0fbff4a
Try to fix nuget shared lib files for qnn
adrianlizarraga Dec 19, 2024
9cbd0fa
Pass --build_shared_lib when bulding python wheels with qnn [pipelines]
adrianlizarraga Dec 19, 2024
f8747db
Print correct binary directory in QNN Nuget pipeline
adrianlizarraga Dec 19, 2024
058e7bb
Add onnxruntime_providers_qnn.dll/.so to setup.py so that it gets cop…
adrianlizarraga Dec 19, 2024
4172575
Edit Java bindins to allow loading/extracting shared provider libs on…
adrianlizarraga Dec 19, 2024
3e39b88
Create temp directory for java android
adrianlizarraga Dec 19, 2024
5ed035f
consistent library loading logic for java android
adrianlizarraga Dec 20, 2024
6347c5f
Merge branch 'main' into adrianl/qnn-ep-dynamic-lib
adrianlizarraga Dec 20, 2024
6562433
Add temporary logging
adrianlizarraga Dec 22, 2024
0bbf3af
fix typo
adrianlizarraga Dec 22, 2024
c04176a
fix another type in temporary logging code for debugging android qnn …
adrianlizarraga Dec 22, 2024
cc14971
Android: Go back to not extracting shared libs from classpath resources.
adrianlizarraga Dec 22, 2024
4c6a985
Try linking shared.so with qnn.so for android
adrianlizarraga Dec 22, 2024
fc00346
Use --undefined=Provider_GetHost
adrianlizarraga Dec 23, 2024
b707c46
prepend _ to linker arg
adrianlizarraga Dec 23, 2024
7f50558
Add linker option -z global to libonnxruntime_providers_shared.so on …
adrianlizarraga Dec 23, 2024
17c3bde
Try to use libc++_shared.so for android qnn build
adrianlizarraga Dec 23, 2024
7e7fe68
Merge main and fix conflicts
adrianlizarraga Dec 23, 2024
e907fe2
Add shims over functions that create ORT objects. These shims will al…
adrianlizarraga Dec 31, 2024
d83ff7b
Enable build QNN EP as both static and dynamic lib
adrianlizarraga Jan 2, 2025
354203c
Merge branch 'main' into adrianl/qnn-ep-dynamic-lib
adrianlizarraga Jan 2, 2025
d500cf8
Fix java cmake conditions when building qnn as shared lib
adrianlizarraga Jan 2, 2025
183ca05
Handle possibility of shared or static qnn lib in Java bindings
adrianlizarraga Jan 2, 2025
5e44199
properly dectect qnn build when building android+qnn AAR package
adrianlizarraga Jan 2, 2025
29c6872
Don't publish artifacts for QNN Win arm64 if QNN is built as a static…
adrianlizarraga Jan 2, 2025
02b71ed
python linter
adrianlizarraga Jan 2, 2025
52199d7
don't include ntverp.h if not needed. set cmake source_group for QNN …
adrianlizarraga Jan 2, 2025
af16458
Add function to provider bridge to check if ETW for logging is suppor…
adrianlizarraga Jan 2, 2025
1d61cae
python linting
adrianlizarraga Jan 2, 2025
dfc9baf
Move NodeAttrHelper to ort_api.h/cc
adrianlizarraga Jan 2, 2025
325d62f
Make some ort_api.h functions inline
adrianlizarraga Jan 2, 2025
a72efb5
cmake clean up
adrianlizarraga Jan 2, 2025
67abb6a
Clean up include paths
adrianlizarraga Jan 2, 2025
6335a88
Edit pipeline job names
adrianlizarraga Jan 2, 2025
f9e5c0c
Add QnnTelemetry for logging profiling events to etw (works for both …
adrianlizarraga Jan 2, 2025
a4f6923
Add comments to quantization utils
adrianlizarraga Jan 2, 2025
e3f6f5e
Merge branch 'main' into adrianl/qnn-ep-dynamic-lib
adrianlizarraga Jan 2, 2025
4a0c7a1
Fix QnnTelemetry for static lib case
adrianlizarraga Jan 3, 2025
0495a99
Dont use QnnTelemetry on non-windows
adrianlizarraga Jan 3, 2025
98f40ad
Merge branch 'main' into adrianl/qnn-ep-dynamic-lib
adrianlizarraga Jan 6, 2025
4f5c037
review comments: remove no-op cmake statement; change to --use_qnn sh…
adrianlizarraga Jan 6, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions cmake/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ option(onnxruntime_USE_OPENVINO "Build with OpenVINO support" OFF)
option(onnxruntime_USE_COREML "Build with CoreML support" OFF)
option(onnxruntime_USE_NNAPI_BUILTIN "Build with builtin NNAPI lib for Android NNAPI support" OFF)
option(onnxruntime_USE_QNN "Build with QNN support" OFF)
option(onnxruntime_BUILD_QNN_EP_STATIC_LIB "Build with QNN EP as a static library" OFF)
option(onnxruntime_USE_SNPE "Build with SNPE support" OFF)
option(onnxruntime_USE_RKNPU "Build with RKNPU support" OFF)
option(onnxruntime_USE_DNNL "Build with DNNL support" OFF)
Expand Down
19 changes: 13 additions & 6 deletions cmake/onnxruntime.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -199,17 +199,12 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Android" AND onnxruntime_BUILD_JAVA)
endforeach()
endif()

# This list is a reversed topological ordering of library dependencies.
# Earlier entries may depend on later ones. Later ones should not depend on earlier ones.
set(onnxruntime_INTERNAL_LIBRARIES
onnxruntime_session
${onnxruntime_libs}
set(onnxruntime_INTERNAL_PROVIDER_LIBRARIES
${PROVIDERS_ACL}
${PROVIDERS_ARMNN}
${PROVIDERS_COREML}
${PROVIDERS_DML}
${PROVIDERS_NNAPI}
${PROVIDERS_QNN}
${PROVIDERS_SNPE}
${PROVIDERS_RKNPU}
${PROVIDERS_VSINPU}
Expand All @@ -218,6 +213,18 @@ set(onnxruntime_INTERNAL_LIBRARIES
${PROVIDERS_WEBNN}
${PROVIDERS_AZURE}
${PROVIDERS_INTERNAL_TESTING}
)

if (onnxruntime_BUILD_QNN_EP_STATIC_LIB)
list(APPEND onnxruntime_INTERNAL_PROVIDER_LIBRARIES onnxruntime_providers_qnn)
endif()

# This list is a reversed topological ordering of library dependencies.
# Earlier entries may depend on later ones. Later ones should not depend on earlier ones.
set(onnxruntime_INTERNAL_LIBRARIES
onnxruntime_session
${onnxruntime_libs}
${onnxruntime_INTERNAL_PROVIDER_LIBRARIES}
${onnxruntime_winml}
onnxruntime_optimizer
onnxruntime_providers
Expand Down
10 changes: 8 additions & 2 deletions cmake/onnxruntime_java.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ if (WIN32)
if(NOT onnxruntime_ENABLE_STATIC_ANALYSIS)
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>)
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>)
if (onnxruntime_USE_CUDA OR onnxruntime_USE_DNNL OR onnxruntime_USE_OPENVINO OR onnxruntime_USE_TENSORRT)
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))
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>)
endif()
if (onnxruntime_USE_CUDA)
Expand All @@ -163,11 +163,14 @@ if (WIN32)
if (onnxruntime_USE_TENSORRT)
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>)
endif()
if (onnxruntime_USE_QNN AND NOT onnxruntime_BUILD_QNN_EP_STATIC_LIB)
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>)
endif()
endif()
else()
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>)
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>)
if (onnxruntime_USE_CUDA OR onnxruntime_USE_DNNL OR onnxruntime_USE_OPENVINO OR onnxruntime_USE_TENSORRT)
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))
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>)
endif()
if (onnxruntime_USE_CUDA)
Expand All @@ -182,6 +185,9 @@ else()
if (onnxruntime_USE_TENSORRT)
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>)
endif()
if (onnxruntime_USE_QNN AND NOT onnxruntime_BUILD_QNN_EP_STATIC_LIB)
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>)
endif()
endif()

# run the build process (this copies the results back into CMAKE_CURRENT_BINARY_DIR)
Expand Down
3 changes: 0 additions & 3 deletions cmake/onnxruntime_providers.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,6 @@ endif()
if(onnxruntime_USE_JSEP)
set(PROVIDERS_JS onnxruntime_providers_js)
endif()
if(onnxruntime_USE_QNN)
set(PROVIDERS_QNN onnxruntime_providers_qnn)
endif()
if(onnxruntime_USE_RKNPU)
set(PROVIDERS_RKNPU onnxruntime_providers_rknpu)
endif()
Expand Down
4 changes: 3 additions & 1 deletion cmake/onnxruntime_providers_cpu.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,9 @@ if (NOT onnxruntime_MINIMAL_BUILD AND NOT onnxruntime_EXTENDED_MINIMAL_BUILD
set_property(TARGET onnxruntime_providers_shared APPEND_STRING PROPERTY LINK_FLAGS "-Xlinker -exported_symbols_list ${ONNXRUNTIME_ROOT}/core/providers/shared/exported_symbols.lst")
elseif(UNIX)
if(NOT ${CMAKE_SYSTEM_NAME} MATCHES "AIX")
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")
target_link_options(onnxruntime_providers_shared PRIVATE
"LINKER:--version-script=${ONNXRUNTIME_ROOT}/core/providers/shared/version_script.lds"
"LINKER:--gc-sections")
endif()
elseif(WIN32)
set_property(TARGET onnxruntime_providers_shared APPEND_STRING PROPERTY LINK_FLAGS "-DEF:${ONNXRUNTIME_ROOT}/core/providers/shared/symbols.def")
Expand Down
111 changes: 80 additions & 31 deletions cmake/onnxruntime_providers_qnn.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -3,41 +3,90 @@

add_compile_definitions(USE_QNN=1)

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

file(GLOB_RECURSE
onnxruntime_providers_qnn_ep_cc_srcs CONFIGURE_DEPENDS
"${ONNXRUNTIME_ROOT}/core/providers/qnn/*.h"
"${ONNXRUNTIME_ROOT}/core/providers/qnn/*.cc"
onnxruntime_providers_qnn_ep_srcs CONFIGURE_DEPENDS
"${ONNXRUNTIME_ROOT}/core/providers/qnn/*.h"
"${ONNXRUNTIME_ROOT}/core/providers/qnn/*.cc"
)

file(GLOB_RECURSE
onnxruntime_providers_qnn_builder_cc_srcs CONFIGURE_DEPENDS
"${ONNXRUNTIME_ROOT}/core/providers/qnn/builder/*.h"
"${ONNXRUNTIME_ROOT}/core/providers/qnn/builder/*.cc"
)
if(onnxruntime_BUILD_QNN_EP_STATIC_LIB)
#
# Build QNN EP as a static library
#
set(onnxruntime_providers_qnn_srcs ${onnxruntime_providers_qnn_ep_srcs})
source_group(TREE ${ONNXRUNTIME_ROOT}/core FILES ${onnxruntime_providers_qnn_srcs})
onnxruntime_add_static_library(onnxruntime_providers_qnn ${onnxruntime_providers_qnn_srcs})
onnxruntime_add_include_to_target(onnxruntime_providers_qnn onnxruntime_common onnxruntime_framework onnx
onnx_proto protobuf::libprotobuf-lite
flatbuffers::flatbuffers Boost::mp11)
target_link_libraries(onnxruntime_providers_qnn)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line is empty

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks. I removed this line (it is currently there in main branch for building qnn ep as static lib).

add_dependencies(onnxruntime_providers_qnn onnx ${onnxruntime_EXTERNAL_DEPENDENCIES})
set_target_properties(onnxruntime_providers_qnn PROPERTIES CXX_STANDARD_REQUIRED ON)
set_target_properties(onnxruntime_providers_qnn PROPERTIES FOLDER "ONNXRuntime")
target_include_directories(onnxruntime_providers_qnn PRIVATE ${ONNXRUNTIME_ROOT}
${onnxruntime_QNN_HOME}/include/QNN
${onnxruntime_QNN_HOME}/include)
set_target_properties(onnxruntime_providers_qnn PROPERTIES LINKER_LANGUAGE CXX)

set(onnxruntime_providers_qnn_cc_srcs
${onnxruntime_providers_shared_utils_cc_srcs}
${onnxruntime_providers_qnn_ep_cc_srcs}
${onnxruntime_providers_qnn_builder_cc_srcs}
)
# ignore the warning unknown-pragmas on "pragma region"
if(NOT MSVC)
target_compile_options(onnxruntime_providers_qnn PRIVATE "-Wno-unknown-pragmas")
endif()
else()
#
# Build QNN EP as a shared library
#
file(GLOB_RECURSE
onnxruntime_providers_qnn_shared_lib_srcs CONFIGURE_DEPENDS
"${ONNXRUNTIME_ROOT}/core/providers/shared_library/*.h"
"${ONNXRUNTIME_ROOT}/core/providers/shared_library/*.cc"
)
set(onnxruntime_providers_qnn_srcs ${onnxruntime_providers_qnn_ep_srcs}
${onnxruntime_providers_qnn_shared_lib_srcs})

source_group(TREE ${ONNXRUNTIME_ROOT}/core FILES ${onnxruntime_providers_qnn_srcs})
onnxruntime_add_shared_library_module(onnxruntime_providers_qnn ${onnxruntime_providers_qnn_srcs})
onnxruntime_add_include_to_target(onnxruntime_providers_qnn ${ONNXRUNTIME_PROVIDERS_SHARED} ${GSL_TARGET} onnx
onnxruntime_common Boost::mp11 safeint_interface)
target_link_libraries(onnxruntime_providers_qnn PRIVATE ${ONNXRUNTIME_PROVIDERS_SHARED} ${ABSEIL_LIBS} ${CMAKE_DL_LIBS})
add_dependencies(onnxruntime_providers_qnn onnxruntime_providers_shared ${onnxruntime_EXTERNAL_DEPENDENCIES})
target_include_directories(onnxruntime_providers_qnn PRIVATE ${ONNXRUNTIME_ROOT}
${CMAKE_CURRENT_BINARY_DIR}
${onnxruntime_QNN_HOME}/include/QNN
${onnxruntime_QNN_HOME}/include)

# Set linker flags for function(s) exported by EP DLL
if(UNIX)
target_link_options(onnxruntime_providers_qnn PRIVATE
"LINKER:--version-script=${ONNXRUNTIME_ROOT}/core/providers/qnn/version_script.lds"
"LINKER:--gc-sections"
"LINKER:-rpath=\$ORIGIN"
)
elseif(WIN32)
set_property(TARGET onnxruntime_providers_qnn APPEND_STRING PROPERTY LINK_FLAGS
"-DEF:${ONNXRUNTIME_ROOT}/core/providers/qnn/symbols.def")
else()
message(FATAL_ERROR "onnxruntime_providers_qnn unknown platform, need to specify shared library exports for it")
endif()

# Set compile options
if(MSVC)
target_compile_options(onnxruntime_providers_qnn PUBLIC /wd4099 /wd4005)
else()
# ignore the warning unknown-pragmas on "pragma region"
target_compile_options(onnxruntime_providers_qnn PRIVATE "-Wno-unknown-pragmas")
endif()

set_target_properties(onnxruntime_providers_qnn PROPERTIES LINKER_LANGUAGE CXX)
set_target_properties(onnxruntime_providers_qnn PROPERTIES CXX_STANDARD_REQUIRED ON)
set_target_properties(onnxruntime_providers_qnn PROPERTIES FOLDER "ONNXRuntime")

source_group(TREE ${ONNXRUNTIME_ROOT}/core FILES ${onnxruntime_providers_qnn_cc_srcs})
onnxruntime_add_static_library(onnxruntime_providers_qnn ${onnxruntime_providers_qnn_cc_srcs})
onnxruntime_add_include_to_target(onnxruntime_providers_qnn onnxruntime_common onnxruntime_framework onnx onnx_proto protobuf::libprotobuf-lite flatbuffers::flatbuffers Boost::mp11)
target_link_libraries(onnxruntime_providers_qnn)
add_dependencies(onnxruntime_providers_qnn onnx ${onnxruntime_EXTERNAL_DEPENDENCIES})
set_target_properties(onnxruntime_providers_qnn PROPERTIES CXX_STANDARD_REQUIRED ON)
set_target_properties(onnxruntime_providers_qnn PROPERTIES FOLDER "ONNXRuntime")
target_include_directories(onnxruntime_providers_qnn PRIVATE ${ONNXRUNTIME_ROOT} ${onnxruntime_QNN_HOME}/include/QNN ${onnxruntime_QNN_HOME}/include)
set_target_properties(onnxruntime_providers_qnn PROPERTIES LINKER_LANGUAGE CXX)
# ignore the warning unknown-pragmas on "pragma region"
if(NOT MSVC)
target_compile_options(onnxruntime_providers_qnn PRIVATE "-Wno-unknown-pragmas")
install(TARGETS onnxruntime_providers_qnn
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
endif()
25 changes: 21 additions & 4 deletions cmake/onnxruntime_python.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -169,9 +169,7 @@ if (onnxruntime_ENABLE_LAZY_TENSOR)
endif()
endif()

target_link_libraries(onnxruntime_pybind11_state PRIVATE
onnxruntime_session
${onnxruntime_libs}
set(onnxruntime_pybind11_state_static_providers
${PROVIDERS_NNAPI}
${PROVIDERS_VSINPU}
${PROVIDERS_XNNPACK}
Expand All @@ -183,7 +181,16 @@ target_link_libraries(onnxruntime_pybind11_state PRIVATE
${PROVIDERS_XNNPACK}
${PROVIDERS_WEBGPU}
${PROVIDERS_AZURE}
${PROVIDERS_QNN}
)

if(onnxruntime_BUILD_QNN_EP_STATIC_LIB)
list(APPEND onnxruntime_pybind11_state_static_providers PRIVATE onnxruntime_providers_qnn)
endif()

target_link_libraries(onnxruntime_pybind11_state PRIVATE
onnxruntime_session
${onnxruntime_libs}
${onnxruntime_pybind11_state_static_providers}
onnxruntime_optimizer
onnxruntime_providers
onnxruntime_util
Expand Down Expand Up @@ -1000,6 +1007,16 @@ if (onnxruntime_USE_COREML)
endif()

if (onnxruntime_USE_QNN)
if(NOT onnxruntime_BUILD_QNN_EP_STATIC_LIB)
add_custom_command(
TARGET onnxruntime_pybind11_state POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy
$<TARGET_FILE:onnxruntime_providers_qnn>
$<TARGET_FILE:onnxruntime_providers_shared>
$<TARGET_FILE_DIR:${build_output_target}>/onnxruntime/capi/
)
endif()

add_custom_command(
TARGET onnxruntime_pybind11_state POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy
Expand Down
24 changes: 17 additions & 7 deletions cmake/onnxruntime_unittests.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -627,16 +627,13 @@ if(onnxruntime_USE_ARMNN)
list(APPEND onnxruntime_test_providers_dependencies onnxruntime_providers_armnn)
endif()

set(ONNXRUNTIME_TEST_LIBS
onnxruntime_session
${ONNXRUNTIME_INTEROP_TEST_LIBS}
${onnxruntime_libs}
# CUDA, ROCM, TENSORRT, MIGRAPHX, DNNL, and OpenVINO are dynamically loaded at runtime
set(ONNXRUNTIME_TEST_STATIC_PROVIDER_LIBS
# CUDA, ROCM, TENSORRT, MIGRAPHX, DNNL, and OpenVINO are dynamically loaded at runtime.
# QNN EP can be built as either a dynamic and static libs.
${PROVIDERS_NNAPI}
${PROVIDERS_VSINPU}
${PROVIDERS_JS}
${PROVIDERS_WEBGPU}
${PROVIDERS_QNN}
${PROVIDERS_SNPE}
${PROVIDERS_RKNPU}
${PROVIDERS_DML}
Expand All @@ -645,6 +642,17 @@ set(ONNXRUNTIME_TEST_LIBS
${PROVIDERS_COREML}
${PROVIDERS_XNNPACK}
${PROVIDERS_AZURE}
)

if (onnxruntime_BUILD_QNN_EP_STATIC_LIB)
list(APPEND ONNXRUNTIME_TEST_STATIC_PROVIDER_LIBS onnxruntime_providers_qnn)
endif()

set(ONNXRUNTIME_TEST_LIBS
onnxruntime_session
${ONNXRUNTIME_INTEROP_TEST_LIBS}
${onnxruntime_libs}
${ONNXRUNTIME_TEST_STATIC_PROVIDER_LIBS}
onnxruntime_optimizer
onnxruntime_providers
onnxruntime_util
Expand Down Expand Up @@ -708,7 +716,9 @@ if(onnxruntime_USE_QNN AND NOT onnxruntime_MINIMAL_BUILD AND NOT onnxruntime_RED
list(APPEND onnxruntime_test_framework_src_patterns ${TEST_SRC_DIR}/providers/qnn/*)
list(APPEND onnxruntime_test_framework_libs onnxruntime_providers_qnn)
list(APPEND onnxruntime_test_providers_dependencies onnxruntime_providers_qnn)
list(APPEND onnxruntime_test_providers_libs onnxruntime_providers_qnn)
if(NOT onnxruntime_BUILD_QNN_EP_STATIC_LIB)
list(APPEND onnxruntime_test_providers_dependencies onnxruntime_providers_shared)
endif()
endif()

if(onnxruntime_USE_SNPE)
Expand Down
22 changes: 19 additions & 3 deletions java/src/main/java/ai/onnxruntime/OnnxRuntime.java
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,9 @@ final class OnnxRuntime {
/** The short name of the ONNX runtime TensorRT provider library */
static final String ONNXRUNTIME_LIBRARY_TENSORRT_NAME = "onnxruntime_providers_tensorrt";

/** The short name of the ONNX runtime QNN provider library */
static final String ONNXRUNTIME_LIBRARY_QNN_NAME = "onnxruntime_providers_qnn";

/** The OS & CPU architecture string */
private static final String OS_ARCH_STR = initOsArch();

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

load(ONNXRUNTIME_LIBRARY_NAME);
if (!isAndroid()) {
load(ONNXRUNTIME_LIBRARY_NAME);
}
load(ONNXRUNTIME_JNI_LIBRARY_NAME);

ortApiHandle = initialiseAPIBase(ORT_API_VERSION_14);
if (ortApiHandle == 0L) {
throw new IllegalStateException(
Expand Down Expand Up @@ -252,6 +258,16 @@ static boolean extractTensorRT() {
return extractProviderLibrary(ONNXRUNTIME_LIBRARY_TENSORRT_NAME);
}

/**
* Extracts the QNN provider library from the classpath resources if present, or checks to see if
* the QNN provider library is in the directory specified by {@link #ONNXRUNTIME_NATIVE_PATH}.
*
* @return True if the QNN provider library is ready for loading, false otherwise.
*/
static boolean extractQNN() {
return extractProviderLibrary(ONNXRUNTIME_LIBRARY_QNN_NAME);
}

/**
* Extracts a shared provider library from the classpath resources if present, or checks to see if
* that library is in the directory specified by {@link #ONNXRUNTIME_NATIVE_PATH}.
Expand All @@ -260,7 +276,7 @@ static boolean extractTensorRT() {
* @return True if the library is ready for loading by ORT's native code, false otherwise.
*/
static synchronized boolean extractProviderLibrary(String libraryName) {
// Android does not need to extract library and it has no shared provider library
// Android does not need to extract provider libraries.
if (isAndroid()) {
return false;
}
Expand Down Expand Up @@ -312,7 +328,7 @@ static boolean isAndroid() {
private static void load(String library) throws IOException {
// On Android, we simply use System.loadLibrary
if (isAndroid()) {
System.loadLibrary("onnxruntime4j_jni");
System.loadLibrary(library);
return;
}

Expand Down
4 changes: 4 additions & 0 deletions java/src/main/java/ai/onnxruntime/OrtSession.java
Original file line number Diff line number Diff line change
Expand Up @@ -1320,6 +1320,10 @@ public void addXnnpack(Map<String, String> providerOptions) throws OrtException
*/
public void addQnn(Map<String, String> providerOptions) throws OrtException {
String qnnProviderName = "QNN";

// QNN can either be built as a shared or static library. extractQNN() will extract the
// (lib)onnxruntime_providers_qnn(.so/.dll) from classpath resources if present.
OnnxRuntime.extractQNN();
addExecutionProvider(qnnProviderName, providerOptions);
}

Expand Down
Loading
Loading