Skip to content

Commit efe9333

Browse files
larryliu0820claude
andcommitted
Download QNN SDK outside of CMake for wheel builds (v2)
Unlike the reverted #17717 which set EXECUTORCH_BUILD_QNN=ON in pybind.cmake (causing all pybind-preset CI jobs to attempt the flaky cmake-time SDK download), this keeps QNN OFF in the preset. Only wheel builds enable it: setup.py detects QNN_SDK_ROOT and passes -DEXECUTORCH_BUILD_QNN=ON to cmake. The pre_build_script downloads the SDK before cmake runs, avoiding the flaky in-cmake download. The cmake fallback download is kept as a last resort, gated on QNN_SDK_ROOT not already being set. Co-authored-by: Claude <noreply@anthropic.com>
1 parent 19de115 commit efe9333

File tree

5 files changed

+53
-5
lines changed

5 files changed

+53
-5
lines changed

.ci/scripts/wheel/pre_build_script.sh

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,3 +44,16 @@ fi
4444
# able to see the installed torch package.
4545

4646
"${GITHUB_WORKSPACE}/${REPOSITORY}/install_requirements.sh" --example
47+
48+
# Download Qualcomm QNN SDK on Linux x86_64 so the wheel build can include the
49+
# QNN backend. The SDK is large, so we download it here (outside CMake) rather
50+
# than during cmake configure.
51+
if [[ "$(uname -s)" == "Linux" && "$(uname -m)" == "x86_64" ]]; then
52+
echo "Downloading Qualcomm QNN SDK..."
53+
QNN_SDK_ROOT=$(python3 \
54+
"${GITHUB_WORKSPACE}/${REPOSITORY}/backends/qualcomm/scripts/download_qnn_sdk.py" \
55+
--print-sdk-path)
56+
export QNN_SDK_ROOT
57+
echo "QNN_SDK_ROOT=${QNN_SDK_ROOT}" >> "${GITHUB_ENV}"
58+
echo "QNN SDK downloaded to ${QNN_SDK_ROOT}"
59+
fi

.ci/scripts/wheel/test_linux.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,25 @@
55
# This source code is licensed under the BSD-style license found in the
66
# LICENSE file in the root directory of this source tree.
77

8+
import platform
9+
810
import test_base
911
from examples.models import Backend, Model
1012

1113
if __name__ == "__main__":
14+
# On Linux x86_64 the wheel is built with the Qualcomm backend.
15+
# Verify that it was registered correctly.
16+
if platform.system() == "Linux" and platform.machine() in ("x86_64", "amd64"):
17+
from executorch.extension.pybindings.portable_lib import (
18+
_get_registered_backend_names,
19+
)
20+
21+
registered = _get_registered_backend_names()
22+
assert (
23+
"QnnBackend" in registered
24+
), f"QnnBackend not found in registered backends: {registered}"
25+
print("✓ QnnBackend is registered")
26+
1227
test_base.run_tests(
1328
model_tests=[
1429
test_base.ModelTest(

.github/workflows/pull.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ jobs:
1616
test-qnn-wheel-packages-linux:
1717
name: test-qnn-wheel-packages-linux
1818
uses: pytorch/test-infra/.github/workflows/linux_job_v2.yml@main
19-
if: false
2019
permissions:
2120
id-token: write
2221
contents: read

backends/qualcomm/CMakeLists.txt

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,19 @@ get_filename_component(
2323
_common_include_directories "${EXECUTORCH_SOURCE_DIR}/.." ABSOLUTE
2424
)
2525

26-
# We only download QNN SDK when we build pip wheel for ExecuTorch. Please don't
27-
# change this code unless you know what you are doing.
28-
if(EXECUTORCH_BUILD_WHEEL_DO_NOT_USE)
26+
# If QNN_SDK_ROOT was not passed as a CMake variable, fall back to the
27+
# environment variable. Prefer downloading the SDK *outside* of CMake (e.g. via
28+
# backends/qualcomm/scripts/download_qnn_sdk.py) and passing the path in.
29+
if(NOT DEFINED QNN_SDK_ROOT AND DEFINED ENV{QNN_SDK_ROOT})
30+
set(QNN_SDK_ROOT
31+
$ENV{QNN_SDK_ROOT}
32+
CACHE PATH "Qualcomm SDK root directory" FORCE
33+
)
34+
endif()
35+
36+
# Last-resort fallback: download during cmake configure when building wheels and
37+
# QNN_SDK_ROOT was not provided externally.
38+
if(NOT DEFINED QNN_SDK_ROOT AND EXECUTORCH_BUILD_WHEEL_DO_NOT_USE)
2939
set(_qnn_default_sdk_dir "${CMAKE_CURRENT_BINARY_DIR}/sdk/qnn")
3040

3141
if(EXISTS "${_qnn_default_sdk_dir}" AND EXISTS "${_qnn_default_sdk_dir}/lib")
@@ -35,7 +45,7 @@ if(EXECUTORCH_BUILD_WHEEL_DO_NOT_USE)
3545
CACHE PATH "Qualcomm SDK root directory" FORCE
3646
)
3747
else()
38-
message(STATUS "Downloading Qualcomm SDK")
48+
message(STATUS "Downloading Qualcomm SDK (fallback)")
3949
execute_process(
4050
COMMAND
4151
${PYTHON_EXECUTABLE}

setup.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -706,6 +706,17 @@ def run(self): # noqa C901
706706
):
707707
cmake_configuration_args += ["-DEXECUTORCH_BUILD_CUDA=ON"]
708708

709+
# Check if QNN SDK is available (via QNN_SDK_ROOT env var), and if so,
710+
# enable building the Qualcomm backend by default.
711+
qnn_sdk_root = os.environ.get("QNN_SDK_ROOT", "").strip()
712+
if qnn_sdk_root and install_utils.is_cmake_option_on(
713+
cmake_configuration_args, "EXECUTORCH_BUILD_QNN", default=True
714+
):
715+
cmake_configuration_args += [
716+
"-DEXECUTORCH_BUILD_QNN=ON",
717+
f"-DQNN_SDK_ROOT={qnn_sdk_root}",
718+
]
719+
709720
with Buck2EnvironmentFixer():
710721
# Generate the cmake cache from scratch to ensure that the cache state
711722
# is predictable.

0 commit comments

Comments
 (0)