Android: allow building Vulkan/XNNPACK backends as separate shared libraries - #21849
Android: allow building Vulkan/XNNPACK backends as separate shared libraries#21849msluszniak wants to merge 3 commits into
Conversation
…braries
The Android AAR links every enabled backend into libexecutorch_jni.so, so an
app pays for all of them even when it uses one. Vulkan and XNNPACK are the
largest contributors, and an app that ships only the CPU path still carries the
GPU backend.
Add EXECUTORCH_BUILD_VULKAN_BACKEND_SHARED and
EXECUTORCH_BUILD_XNNPACK_BACKEND_SHARED, both defaulting to OFF so existing
builds are unchanged. When set, the backend is emitted as its own .so that
whole-archives the corresponding static archive, and the JNI library no longer
links it. Consumers then load only the backends they need.
Notes:
* jni_noop.cpp is an empty translation unit. A SHARED target whose only
content is a whole-archived static library still needs one source file for
CMake to invoke the linker.
* custom_ops links xnnpack_backend directly, which would pull the backend
back into the JNI library and defeat the split, so that link is dropped
when the shared XNNPACK build is selected.
* build_android_library.sh forwards both variables so they can be driven
from the environment.
🔗 Helpful Links🧪 See artifacts and rendered test results at hud.pytorch.org/pr/pytorch/executorch/21849
Note: Links to docs will display an error until the docs builds have been completed.
|
This PR needs a
|
|
Thanks for the PR, @msluszniak. Once the rest of CI tests are done running, do address the lintrunner logs and other CI tests. |
My bad, sorry 😅 lint fixed |
|
@claude review |
|
Claude finished @kirklandsign's task in 11m 56s —— View job Code reviewNice, focused change — opt-in flags default OFF, so the default AAR is untouched. The mechanics (whole-archiving the backend static lib into a 1. (Important) How does the backend registered in the standalone
|
A split backend links executorch_core statically, so it holds a second copy of the registry and only reaches the runtime's copy by binding its register_backend PLT slot to the first definition in the global lookup scope. version_script.txt makes that definition local in libexecutorch_jni.so, so on the AAR path the backend would register into its own table and the runtime would report DelegateNotFound. Use a version script that exports the registry entry points (and pthreadpool, so a split XNNPACK shares the configured pool) whenever a backend is split out, and write the load-order contract down next to the option. Also drop the dead -fopenmp/-static-openmp flags and the $ORIGIN rpath (the .so has no non-system DT_NEEDED), register both options in the preset system, give jni_noop.cpp the license header, and trim the duplicated rationale comments.
|
Summary
The Android AAR links every enabled backend into
libexecutorch_jni.so, so anapp pays for all of them even when it uses one. Vulkan and XNNPACK are the
largest contributors, and an app shipping only the CPU path still carries the
GPU backend.
This PR adds
EXECUTORCH_BUILD_VULKAN_BACKEND_SHAREDandEXECUTORCH_BUILD_XNNPACK_BACKEND_SHARED, both defaulting to OFF, soexisting builds are byte-for-byte unchanged. When set, the backend is emitted as
its own
.sothat whole-archives the corresponding static archive, and the JNIlibrary no longer links it — consumers load only what they need.
Two details worth calling out for review:
extension/android/jni/jni_noop.cppis an empty translation unit. ASHAREDtarget whose only content is a whole-archived static library still needs one
source file for CMake to invoke the linker on.
custom_opslinksxnnpack_backenddirectly, which would pull the backendback into the JNI library and defeat the split, so that link is dropped when
the shared XNNPACK build is selected.
build_android_library.shforwards both variables so they can be driven fromthe environment.
Test plan
libexecutorch.soasbefore.
EXECUTORCH_BUILD_VULKAN=ON EXECUTORCH_BUILD_VULKAN_BACKEND_SHARED=ON,the Vulkan backend builds as a separate
.soand an app loading it runsVulkan-delegated models on device (Galaxy S26 Ultra, Adreno).
had real-world exercise across both backends.
cc @kirklandsign @cbilgin @SS-JIA @manuelcandales @digantdesai
Fixes #10457