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] set up py packaging pipeline for Linux x64 #22132

Merged
merged 21 commits into from
Sep 19, 2024
Merged
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"
jywu-msft marked this conversation as resolved.
Show resolved Hide resolved
"${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 @@ -1027,6 +1027,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",
jywu-msft marked this conversation as resolved.
Show resolved Hide resolved
]
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
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 @@
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};;

Check warning on line 18 in tools/ci_build/github/linux/build_linux_python_package.sh

View workflow job for this annotation

GitHub Actions / Optional Lint

[shellcheck] reported by reviewdog 🐶 Variable was used as an array but is now assigned a string. Raw Output: ./tools/ci_build/github/linux/build_linux_python_package.sh:18:4: warning: Variable was used as an array but is now assigned a string. (ShellCheck.SC2178)
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 @@ -50,11 +50,16 @@
fi

if [ "$BUILD_DEVICE" == "GPU" ]; then
SHORT_CUDA_VERSION=$(echo $CUDA_VERSION | sed 's/\([[:digit:]]\+\.[[:digit:]]\+\)\.[[:digit:]]\+/\1/')

Check warning on line 53 in tools/ci_build/github/linux/build_linux_python_package.sh

View workflow job for this annotation

GitHub Actions / Optional Lint

[shellcheck] reported by reviewdog 🐶 See if you can use ${variable//search/replace} instead. Raw Output: ./tools/ci_build/github/linux/build_linux_python_package.sh:53:26: info: See if you can use ${variable//search/replace} instead. (ShellCheck.SC2001)

Check warning on line 53 in tools/ci_build/github/linux/build_linux_python_package.sh

View workflow job for this annotation

GitHub Actions / Optional Lint

[shellcheck] reported by reviewdog 🐶 Double quote to prevent globbing and word splitting. Raw Output: ./tools/ci_build/github/linux/build_linux_python_package.sh:53:31: info: Double quote to prevent globbing and word splitting. (ShellCheck.SC2086)
#Enable CUDA and TRT EPs.
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
Loading