Skip to content

Commit

Permalink
[QNN EP] set up py packaging pipeline for Linux x64 (#22132)
Browse files Browse the repository at this point in the history
set up a pipeline to produce nightly Linux x64 whls for onnxruntime-qnn
this can be used for offline context binary generation.
  • Loading branch information
jywu-msft committed Sep 19, 2024
1 parent d5f6343 commit 944d873
Show file tree
Hide file tree
Showing 9 changed files with 152 additions and 7 deletions.
5 changes: 4 additions & 1 deletion cmake/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -838,7 +838,10 @@ if (onnxruntime_USE_QNN)
endif()

if (MSVC OR ${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
file(GLOB QNN_LIB_FILES LIST_DIRECTORIES false "${onnxruntime_QNN_HOME}/lib/${QNN_ARCH_ABI}/libQnn*.so" "${onnxruntime_QNN_HOME}/lib/${QNN_ARCH_ABI}/Qnn*.dll")
file(GLOB QNN_LIB_FILES LIST_DIRECTORIES false "${onnxruntime_QNN_HOME}/lib/${QNN_ARCH_ABI}/libQnn*.so"
"${onnxruntime_QNN_HOME}/lib/${QNN_ARCH_ABI}/Qnn*.dll"
"${onnxruntime_QNN_HOME}/lib/${QNN_ARCH_ABI}/libHtpPrepare.so"
"${onnxruntime_QNN_HOME}/lib/${QNN_ARCH_ABI}/HtpPrepare.dll")
if (${QNN_ARCH_ABI} STREQUAL "aarch64-windows-msvc" OR ${QNN_ARCH_ABI} STREQUAL "arm64x-windows-msvc")
file(GLOB EXTRA_HTP_LIB LIST_DIRECTORIES false "${onnxruntime_QNN_HOME}/lib/hexagon-v68/unsigned/libQnnHtpV68Skel.so"
"${onnxruntime_QNN_HOME}/lib/hexagon-v73/unsigned/libQnnHtpV73Skel.so"
Expand Down
6 changes: 6 additions & 0 deletions cmake/onnxruntime_python.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -1034,6 +1034,12 @@ if (onnxruntime_USE_QNN)
${QNN_LIB_FILES}
$<TARGET_FILE_DIR:${build_output_target}>/onnxruntime/capi/
)
add_custom_command(
TARGET onnxruntime_pybind11_state POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy
$<TARGET_FILE:onnxruntime_qnn_ctx_gen>
$<TARGET_FILE_DIR:${build_output_target}>/onnxruntime/capi/
)
if (EXISTS "${onnxruntime_QNN_HOME}/Qualcomm AI Hub Proprietary License.pdf")
add_custom_command(
TARGET onnxruntime_pybind11_state POST_BUILD
Expand Down
16 changes: 14 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ def parse_arg_remove_string(argv, arg_name_equal):
is_migraphx = False
is_rocm = False
is_openvino = False
is_qnn = False
# The following arguments are mutually exclusive
if wheel_name_suffix == "gpu":
# TODO: how to support multiple CUDA versions?
Expand Down Expand Up @@ -87,7 +88,8 @@ def parse_arg_remove_string(argv, arg_name_equal):
# keep the same name since AzureEP will release with CpuEP by default.
pass
elif parse_arg_remove_boolean(sys.argv, "--use_qnn"):
package_name = "onnxruntime-qnn"
is_qnn = True
package_name = "onnxruntime-qnn" if not nightly_build else "ort-qnn-nightly"

if is_rocm or is_migraphx:
package_name = "onnxruntime-rocm" if not nightly_build else "ort-rocm-nightly"
Expand Down Expand Up @@ -278,7 +280,7 @@ def run(self):
pass

_bdist_wheel.run(self)
if is_manylinux and not disable_auditwheel_repair and not is_openvino:
if is_manylinux and not disable_auditwheel_repair and not is_openvino and not is_qnn:
assert self.dist_dir is not None
file = glob(path.join(self.dist_dir, "*linux*.whl"))[0]
logger.info("repairing %s for manylinux1", file)
Expand Down Expand Up @@ -348,6 +350,16 @@ def finalize_options(self):
libs.append(providers_cuda_or_rocm)
libs.append(providers_tensorrt_or_migraphx)
libs.append(providers_cann)
# QNN
qnn_deps = [
"libQnnCpu.so",
"libQnnHtp.so",
"libQnnSaver.so",
"libQnnSystem.so",
"libHtpPrepare.so",
"onnxruntime_qnn_ctx_gen",
]
dl_libs.extend(qnn_deps)
if nightly_build:
libs.extend(["libonnxruntime_pywrapper.so"])
elif platform.system() == "Darwin":
Expand Down
4 changes: 2 additions & 2 deletions tools/ci_build/build.py
Original file line number Diff line number Diff line change
Expand Up @@ -2277,10 +2277,10 @@ def build_python_wheel(
args.append("--wheel_name_suffix=directml")
elif use_cann:
args.append("--use_cann")
elif use_azure:
args.append("--use_azure")
elif use_qnn:
args.append("--use_qnn")
elif use_azure:
args.append("--use_azure")

run_subprocess(args, cwd=cwd)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,4 @@ stages:
enable_windows_arm64_qnn: false
enable_windows_arm64ec_qnn: false
enable_windows_x64_qnn: false
enable_linux_x64_qnn: false
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,11 @@ parameters:
type: boolean
default: true

- name: enable_linux_x64_qnn
displayName: 'Whether Linux x86_64 package with QNN EP is built.'
type: boolean
default: true

- name: build_py_parameters
displayName: 'Specify extra build parameters'
type: string
Expand Down Expand Up @@ -80,6 +85,7 @@ stages:
enable_windows_arm64_qnn: ${{ parameters.enable_windows_arm64_qnn }}
enable_windows_arm64ec_qnn: ${{ parameters.enable_windows_arm64ec_qnn }}
enable_windows_x64_qnn: ${{ parameters.enable_windows_x64_qnn }}
enable_linux_x64_qnn: ${{ parameters.enable_linux_x64_qnn }}
build_py_parameters: ${{ parameters.build_py_parameters }}
cmake_build_type: ${{ parameters.cmake_build_type }}
qnn_sdk_version: ${{ parameters.qnn_sdk_version }}
Expand Down
97 changes: 97 additions & 0 deletions tools/ci_build/github/azure-pipelines/templates/py-linux-qnn.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
parameters:
- name: machine_pool
type: string

- name: cmake_build_type
type: string
default: 'Release'
values:
- Debug
- Release
- RelWithDebInfo
- MinSizeRel

- name: device
type: string
default: 'NPU'

- name: with_cache
type: boolean
default: false

- name: extra_build_arg
type: string
default: ''

- name: QnnSdk
displayName: QNN SDK version
type: string
default: 2.26.0.240828

jobs:
- job: Linux_py_qnn_Wheels_x64
timeoutInMinutes: 240
workspace:
clean: all
pool: ${{ parameters.machine_pool }}
variables:
# The build machine pool doesn't have dotnet, so it can't run CG.
- name: skipComponentGovernanceDetection
value: true
- name: ORT_CACHE_DIR
value: $(Agent.TempDirectory)/ort_ccache
- name: TODAY
value: $[format('{0:dd}{0:MM}{0:yyyy}', pipeline.startTime)]
- name: extra_build_args
${{ if ne(parameters.extra_build_arg, '') }}:
value: -x ${{ parameters.extra_build_arg }}
${{ if eq(parameters.extra_build_arg, '') }}:
value: ''
steps:
- task: mspremier.PostBuildCleanup.PostBuildCleanup-task.PostBuildCleanup@3
displayName: 'Clean Agent Directories'
condition: always()

- checkout: self
clean: true
submodules: none

- template: jobs/download_linux_qnn_sdk.yml
parameters:
QnnSDKVersion: ${{ parameters.QnnSdk }}

- template: set-nightly-build-option-variable-step.yml

- template: get-docker-image-steps.yml
parameters:
Dockerfile: tools/ci_build/github/linux/docker/inference/x86_64/python/cpu/Dockerfile
Context: tools/ci_build/github/linux/docker/inference/x86_64/python/cpu
DockerBuildArgs: "--build-arg BUILD_UID=$( id -u )"
Repository: onnxruntimecpubuildpythonx86_64_qnn

- template: linux-build-step-with-cache.yml
parameters:
WithCache: ${{parameters.with_cache}}
Today: $(TODAY)
AdditionalKey: Linux_py_qnn_Wheels_x64
CacheDir: $(ORT_CACHE_DIR)
ChangeEveryCommit: true
BuildStep:
- task: Bash@3
displayName: 'Build Python Wheel'
inputs:
targetType: filePath
filePath: tools/ci_build/github/linux/run_python_dockerbuild.sh
arguments: -i onnxruntimecpubuildpythonx86_64_qnn -d "${{ parameters.device }}" -c ${{ parameters.cmake_build_type }} $(extra_build_args)
env:
ADDITIONAL_DOCKER_PARAMETER: "--volume $(QnnSDKRootDir):/qnn_sdk"

- task: PublishBuildArtifacts@1
displayName: 'Publish Artifact: Linux ONNXRuntime QNN python wheel'
inputs:
PathtoPublish: '$(Build.BinariesDirectory)/dist'
ArtifactName: onnxruntime-linux-qnn-x64

- template: component-governance-component-detection-steps.yml
parameters :
condition : 'succeeded'
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,11 @@ parameters:
type: boolean
default: true

- name: enable_linux_x64_qnn
displayName: 'Whether Linux x86_64 package with QNN EP is built.'
type: boolean
default: true

- name: cmake_build_type
type: string
displayName: 'Linux packages cmake build type. Linux Only.'
Expand Down Expand Up @@ -533,3 +538,13 @@ stages:
MACHINE_POOL: 'Onnxruntime-QNNEP-Windows-2022-CPU'
QNN_SDK: ${{ parameters.qnn_sdk_version }}
BUILD_PY_PARAMETERS: ${{ parameters.build_py_parameters }}

- ${{ if eq(parameters.enable_linux_x64_qnn, true) }}:
- stage: Python_Packaging_Linux_x64_QNN
dependsOn: []
jobs:
- template: py-linux-qnn.yml
parameters:
machine_pool: 'onnxruntime-Ubuntu2204-AMD-CPU'
extra_build_arg: ${{ parameters.build_py_parameters }}
cmake_build_type: ${{ parameters.cmake_build_type }}
9 changes: 7 additions & 2 deletions tools/ci_build/github/linux/build_linux_python_package.sh
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@ PYTHON_EXES=("/opt/python/cp38-cp38/bin/python3.8" "/opt/python/cp39-cp39/bin/py
while getopts "d:p:x:c:" parameter_Option
do case "${parameter_Option}"
in
#GPU or CPU.
#GPU|CPU|NPU.
d) BUILD_DEVICE=${OPTARG};;
p) PYTHON_EXES=${OPTARG};;
x) EXTRA_ARG=${OPTARG};;
c) BUILD_CONFIG=${OPTARG};;
*) echo "Usage: $0 -d <GPU|CPU> [-p <python_exe_path>] [-x <extra_build_arg>] [-c <build_config>]"
*) echo "Usage: $0 -d <GPU|CPU|NPU> [-p <python_exe_path>] [-x <extra_build_arg>] [-c <build_config>]"
exit 1;;
esac
done
Expand Down Expand Up @@ -55,6 +55,11 @@ if [ "$BUILD_DEVICE" == "GPU" ]; then
BUILD_ARGS+=("--nvcc_threads=1" "--use_cuda" "--use_tensorrt" "--cuda_version=$SHORT_CUDA_VERSION" "--tensorrt_home=/usr" "--cuda_home=/usr/local/cuda-$SHORT_CUDA_VERSION" "--cudnn_home=/usr/local/cuda-$SHORT_CUDA_VERSION" "--cmake_extra_defines" "CMAKE_CUDA_ARCHITECTURES=52;60;61;70;75;80")
fi

if [ "$BUILD_DEVICE" == "NPU" ]; then
#Enable QNN EP
BUILD_ARGS+=("--use_qnn" "--qnn_home=/qnn_sdk")
fi

for PYTHON_EXE in "${PYTHON_EXES[@]}"
do
rm -rf /build/"$BUILD_CONFIG"
Expand Down

0 comments on commit 944d873

Please sign in to comment.