Skip to content

Android: export curated EXECUTORCH_1_0 ABI from libexecutorch.so (hot-pluggable backends, milestone 1) - #21945

Open
RanjithRagavan wants to merge 2 commits into
pytorch:mainfrom
RanjithRagavan:android-split-backend-abi
Open

Android: export curated EXECUTORCH_1_0 ABI from libexecutorch.so (hot-pluggable backends, milestone 1)#21945
RanjithRagavan wants to merge 2 commits into
pytorch:mainfrom
RanjithRagavan:android-split-backend-abi

Conversation

@RanjithRagavan

@RanjithRagavan RanjithRagavan commented Aug 19, 2026

Copy link
Copy Markdown
Contributor

Summary

First step of the hot-pluggable backends plan (#10457), which lets Android apps opt out of unused backends to shrink binary size (#19329).

Today the Android AAR ships a single libexecutorch.so that links every backend via --whole-archive, and its linker version script exports only JNI_OnLoad and Java_*. A backend built as a standalone .so therefore can't reach the process-wide backend/kernel registries — its self-registration silently writes into a private copy, and delegation fails. This is why external attempts at per-backend .so files hit "duplicate kernel" errors.

The fix: add a versioned EXECUTORCH_1_0 node to extension/android/jni/version_script.txt that exports the curated surface an external .so needs to self-register at load time through normal ELF symbol interposition — the same mechanism the QNN backend already relies on:

  • Registration entry pointsregister_backend, get_backend_class, register_kernels
  • RTTI/vtables for polymorphic public types such as BackendInterface (its key function is emitted in the core .so, so subclasses in external .so files need these symbols)
  • The public executorch::runtime / executorch::aten API namespaces backend implementations are written against (Tensor, EValue, MemoryManager, FreeableBuffer, logging)
  • The et_pal_* C API so backend .so files share the process-wide logging/allocation hooks

The boundary is deliberately namespace-scoped rather than symbol-by-symbol so it stays maintainable as the public headers evolve; everything else stays hidden for LTO/--gc-sections. Additive symbols go into a new version node so external .so files get a stable ABI tag — answering the issue's open question in favor of a curated, versioned list.

What this does NOT change: the monolithic .so topology is untouched — no target, link, or loading-behavior change for existing consumers. Split build mode (milestone 2) and the first carved-out backend (milestone 3) build on top of this.

Test plan

  • Self-verifying build: scripts/build_android_library.sh now asserts — via the NDK's llvm-nm — that the built libexecutorch.so actually exports the required symbols (registration functions, BackendInterface RTTI/vtable, etensor::Tensor, EValue, et_pal_emit_log_message, JNI_OnLoad). If the ABI surface ever regresses, the Android AAR build fails loudly instead of shipping a silently broken artifact.
  • No-regression: existing Android CI exercises the monolithic path end to end (unit tests, instrumentation tests, demo app builds); exporting additional symbols does not alter code generation, only the dynamic symbol table.
  • This unblocks the milestone-1 acceptance criterion: a standalone backend .so can now resolve the core registry symbols at dlopen time; milestone 3's Vulkan pilot will demonstrate the end-to-end flow.

Refs #10457 (milestone 1 of 7), #19329

cc @kirklandsign @cbilgin

…-pluggable backends, milestone 1)

First step of the hot-pluggable backends plan (pytorch#10457) to let Android
apps opt out of unused backends (pytorch#19329).

Today libexecutorch.so exports only JNI_OnLoad and Java_*. A backend
built as a standalone .so cannot reach the process-wide backend/kernel
registries, so its static registration writes into a private copy and
delegation fails with 'backend not found' / duplicate-kernel errors.

This change adds a versioned EXECUTORCH_1_0 node to
extension/android/jni/version_script.txt exporting the curated surface
an external .so needs to self-register at load time via ELF symbol
interposition:

- registration entry points: register_backend, get_backend_class,
  register_kernels
- RTTI/vtables for polymorphic public types such as BackendInterface
  (its key function is emitted in the core .so)
- the public executorch::runtime / executorch::aten API namespaces that
  backend implementations are written against (Tensor, EValue,
  MemoryManager, FreeableBuffer, logging)
- the et_pal_* C API so backend .so files share process-wide
  logging/allocation hooks

The boundary is namespace-scoped instead of symbol-by-symbol so it
stays maintainable as public headers evolve; everything else stays
hidden for LTO/gc-sections. Future additive symbols go into a new
version node so external .so files can depend on a stable ABI tag.

The monolithic .so topology is unchanged: no target, link, or loading
behavior changes for existing consumers.

Verification: build_android_library.sh now asserts the built
libexecutorch.so actually exports the required symbols (via NDK
llvm-nm), failing the build if the ABI surface regresses. Existing
Android CI exercises the monolithic path end to end.
@pytorch-bot

pytorch-bot Bot commented Aug 19, 2026

Copy link
Copy Markdown

🔗 Helpful Links

🧪 See artifacts and rendered test results at hud.pytorch.org/pr/pytorch/executorch/21945

Note: Links to docs will display an error until the docs builds have been completed.

⚠️ 14 Awaiting Approval

As of commit b35dcb0 with merge base 1b2838b (image):

AWAITING APPROVAL - The following workflows need approval before CI can run:

This comment was automatically generated by Dr. CI and updates every 15 minutes.

@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Aug 19, 2026
@RanjithRagavan

Copy link
Copy Markdown
Contributor Author

@pytorchbot label "module: android"

@RanjithRagavan

Copy link
Copy Markdown
Contributor Author

@pytorchbot label "release notes: none"

@pytorch-bot pytorch-bot Bot added module: android Issues related to Android code, build, and execution release notes: none Do not include this in the release notes labels Aug 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. module: android Issues related to Android code, build, and execution release notes: none Do not include this in the release notes

Projects

Status: Todo

Development

Successfully merging this pull request may close these issues.

2 participants