Skip to content

Commit 3545844

Browse files
billmguofacebook-github-bot
authored andcommitted
Enable buck-native x86 simulator test for QNN op tests (#20494)
Summary: The QNN operator tests in `backends/qualcomm/tests/test_qnn_delegate.py` already support host x86_64 simulator execution via `--enable_x86_64`, but were only runnable as a standalone argparse script after a CMake build. There was no `buck test` path: `test_qnn_delegate` is a `python_library` (not a test target), and the host `qnn_executor_runner` binary was Android-only. This change wires up a buck-native, internal-only test target `//executorch/backends/qualcomm/tests:test_qnn_delegate_x86` that runs the FP16 and quantized operator suites (`TestQNNFloatingPointOperator`, `TestQNNQuantizedOperator`) on the x86 QNN simulator with no device and no CMake build tree. Changes: - `backends/qualcomm/runtime/targets.bzl`: add `CXX` to the `pal` library platforms (gated `if is_fbcode()`). It already ships `pal/src/linux/*.cpp`, but was gated to `[ANDROID]`, which blocked any host build of `:runtime` (an exported dep). - `examples/qualcomm/executor_runner/targets.bzl`: add `CXX` to `qnn_executor_runner` (gated `if is_fbcode()`) so the host runner binary builds, and add `//executorch/kernels/portable:generated_lib` to its deps. The CMake runner links `full_portable_ops_lib` + `quantized_ops_lib`; the Buck runner had only the quantized lib, so ops that leave a CPU-fallback node (e.g. `acos` -> `aten::asin.out`, `cast`, `index_copy`, `index_put`, `logical_and`, `avg_pool1d`) aborted the runner with a "Missing operator" error. The `CXX` (host) surface is gated to `is_fbcode()` because it is only used by the internal x86 simulator test; in OSS, `CXX` includes macOS (no QNN host libs), so the host runner/pal stay Android-only there, restoring the original OSS build surface. - `backends/qualcomm/tests/test_qnn_delegate_x86.py` (new): under `buck test` the file's argparse `__main__`/`setup_environment()` never runs, so this wrapper sets the equivalent `TestQNN` class attributes (`enable_x86_64`, `backend`, `soc_model`) at import and subclasses the operator TestCases so the runner discovers them. - `backends/qualcomm/tests/BUCK`: add the `test_qnn_delegate_x86` `python_test`, gated behind `runtime.is_oss` via a top-level conditional expression (the BUCK dialect forbids top-level `if`/`def`). It stays out of the OSS graph to preserve the `test-qnn-buck-build-linux` CI signal. The QNN x86 SDK libs and host runner are supplied via `env` (`QNN_SDK_ROOT`, `LD_LIBRARY_PATH`, `QNN_EXECUTOR_RUNNER`). `CUDA_VISIBLE_DEVICES` is forced empty because these tests are CPU-only (calibration, AOT compile, x86 sim); without it, parallel test shards each grabbed CUDA and exhausted GPU memory. The fbcode and xplat copies of all four files are kept byte-identical per the existing twin convention. Differential Revision: D109606746
1 parent 45a14b9 commit 3545844

4 files changed

Lines changed: 84 additions & 2 deletions

File tree

backends/qualcomm/runtime/targets.bzl

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ load(
33
"ANDROID",
44
"CXX",
55
)
6+
load("@fbsource//tools/build_defs:fbsource_utils.bzl", "is_fbcode")
67
load("@fbsource//xplat/executorch/build:runtime_wrapper.bzl", "runtime")
78
load("@fbsource//xplat/executorch/backends/qualcomm/third-party:third_party_libs.bzl", "qnn_third_party_dep")
89

@@ -55,7 +56,9 @@ def define_common_targets():
5556
},
5657
header_namespace = "",
5758
define_static_target = True,
58-
platforms = [ANDROID],
59+
# CXX (host) is only needed for the internal fbcode x86 QNN simulator
60+
# test runner; OSS host builds (incl. macOS) never build this.
61+
platforms = [ANDROID, CXX] if is_fbcode() else [ANDROID],
5962
visibility = ["PUBLIC"],
6063
)
6164

backends/qualcomm/tests/BUCK

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,3 +87,29 @@ fbcode_target(_kind = runtime.python_test,
8787
"//executorch/examples/qualcomm/oss_scripts/llama:static_llama",
8888
]),
8989
)
90+
91+
# Runs the QNN operator tests on the x86_64 host simulator under buck. Internal
92+
# only: the underlying :test_qnn_delegate library pulls in caffe2/torchvision/etc
93+
# that are unavailable in OSS Buck (see the comment on that target), and keeping
94+
# it out of the OSS graph preserves the `test-qnn-buck-build-linux` CI signal.
95+
# The host qnn_executor_runner binary and the QNN x86 SDK libs are supplied via
96+
# env; the test reads QNN_EXECUTOR_RUNNER/QNN_SDK_ROOT and runs the simulator.
97+
None if runtime.is_oss else fbcode_target(
98+
_kind = runtime.python_test,
99+
name = "test_qnn_delegate_x86",
100+
srcs = [
101+
"test_qnn_delegate_x86.py",
102+
],
103+
env = {
104+
# Force CPU: quantization calibration, AOT compile, and the x86 HTP sim
105+
# all run on CPU. Without this, parallel test shards each grab CUDA and
106+
# exhaust GPU memory ("CUDA error: out of memory").
107+
"CUDA_VISIBLE_DEVICES": "",
108+
"LD_LIBRARY_PATH": "$(location fbsource//third-party/qualcomm/qnn/qnn-{0}:qnn_offline_compile_libs)".format(get_qnn_library_version()),
109+
"QNN_EXECUTOR_RUNNER": "$(location //executorch/examples/qualcomm/executor_runner:qnn_executor_runner)",
110+
"QNN_SDK_ROOT": "$(location fbsource//third-party/qualcomm/qnn/qnn-{0}:__dir__)".format(get_qnn_library_version()),
111+
},
112+
deps = [
113+
":test_qnn_delegate",
114+
],
115+
)
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# Copyright (c) Qualcomm Innovation Center, Inc.
2+
# All rights reserved
3+
#
4+
# This source code is licensed under the BSD-style license found in the
5+
# LICENSE file in the root directory of this source tree.
6+
7+
"""
8+
Buck-native entry point that runs the QNN operator tests on the x86_64 host
9+
simulator (no connected device, no CMake build tree).
10+
11+
The full ``test_qnn_delegate.py`` suite is normally driven by its argparse
12+
``__main__`` block (``setup_environment``). That block never executes under a
13+
Buck ``python_test`` runner -- Buck imports the module and runs the discovered
14+
``TestCase`` subclasses directly -- so the flags that select host simulation
15+
(``--enable_x86_64``, ``--soc_model``, ``--backend``) are never parsed. This
16+
module re-exports the operator test classes and sets the equivalent ``TestQNN``
17+
class attributes at import time so the same tests run unmodified under
18+
``buck test``.
19+
20+
The QNN x86 SDK libraries and the host ``qnn_executor_runner`` binary are
21+
provided by the Buck target's ``env`` (``QNN_SDK_ROOT``, ``LD_LIBRARY_PATH``,
22+
``QNN_EXECUTOR_RUNNER``); see the ``test_qnn_delegate_x86`` target in BUCK.
23+
"""
24+
25+
import os
26+
27+
from executorch.backends.qualcomm.tests import test_qnn_delegate as _ops
28+
from executorch.backends.qualcomm.tests.utils import TestQNN
29+
30+
# Compile ahead-of-time and execute through the x86 simulator (qnn_executor_runner)
31+
# instead of pushing to a device over adb.
32+
TestQNN.enable_x86_64 = True
33+
TestQNN.backend = os.environ.get("QNN_BACKEND", "htp")
34+
# Only selects the HTP architecture baked into the offline-compiled context
35+
# binary; the x86 simulator runs the same graph regardless of the physical SoC.
36+
TestQNN.soc_model = os.environ.get("QNN_SOC_MODEL", "SM8650")
37+
38+
39+
# Subclass (rather than re-import) so the test runner discovers these classes as
40+
# defined in this module. The base classes stay behind the `_ops` module handle
41+
# so they are not collected (and double-run) from this module's namespace.
42+
class TestQNNFloatingPointOperator(_ops.TestQNNFloatingPointOperator):
43+
pass
44+
45+
46+
class TestQNNQuantizedOperator(_ops.TestQNNQuantizedOperator):
47+
pass

examples/qualcomm/executor_runner/targets.bzl

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
load(
22
"@fbsource//tools/build_defs:default_platform_defs.bzl",
33
"ANDROID",
4+
"CXX",
45
)
56
load("@fbsource//tools/build_defs:fbsource_utils.bzl", "is_fbcode")
67
load("@fbsource//xplat/executorch/build:runtime_wrapper.bzl", "runtime")
@@ -23,14 +24,19 @@ def define_common_targets():
2324
"//executorch/runtime/executor:program",
2425
"//executorch/devtools/etdump:etdump_flatcc",
2526
"//executorch/devtools/bundled_program:runtime",
27+
"//executorch/kernels/portable:generated_lib",
2628
"//executorch/kernels/quantized:generated_lib",
2729
"//executorch/extension/data_loader:buffer_data_loader",
2830
"//executorch/extension/data_loader:file_data_loader",
2931
"//executorch/extension/tensor:tensor",
3032
"//executorch/extension/runner_util:inputs",
3133
"//executorch/backends/qualcomm/runtime:runtime",
3234
],
33-
platforms = [ANDROID],
35+
# The host (CXX) build of this runner is only used by the internal
36+
# fbcode buck-native x86 QNN simulator test. Keep it out of OSS builds
37+
# (CXX there includes macOS, which has no QNN host libs) -- restore the
38+
# original Android-only surface in OSS.
39+
platforms = [ANDROID, CXX] if is_fbcode() else [ANDROID],
3440
external_deps = [
3541
"gflags",
3642
],

0 commit comments

Comments
 (0)