Skip to content
Open
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
82 commits
Select commit Hold shift + click to select a range
f932b9c
Update
shoumikhin Jul 31, 2026
a231092
Update
shoumikhin Jul 31, 2026
4b44a20
Update
shoumikhin Aug 1, 2026
0fcd4f5
Update
shoumikhin Aug 1, 2026
42b1290
Update
shoumikhin Aug 1, 2026
576b09e
Update
shoumikhin Aug 1, 2026
b350ed6
Update
shoumikhin Aug 1, 2026
20af43e
Update
shoumikhin Aug 1, 2026
de44074
Update
shoumikhin Aug 1, 2026
64027b7
Update
shoumikhin Aug 1, 2026
9adcc7d
Update
shoumikhin Aug 1, 2026
c67a562
Update
shoumikhin Aug 1, 2026
3d0877f
Update
shoumikhin Aug 1, 2026
a038dbc
Update
shoumikhin Aug 1, 2026
9758ccc
Update
shoumikhin Aug 1, 2026
5869a91
Update
shoumikhin Aug 1, 2026
e063167
Update
shoumikhin Aug 1, 2026
e7001ac
Update
shoumikhin Aug 2, 2026
a2096e2
Update
shoumikhin Aug 2, 2026
9ed601f
Update
shoumikhin Aug 2, 2026
60b801f
Update
shoumikhin Aug 2, 2026
bebbbd9
Update
shoumikhin Aug 2, 2026
dd3af02
Update
shoumikhin Aug 2, 2026
050327c
Update
shoumikhin Aug 2, 2026
5cb77bc
Update
shoumikhin Aug 2, 2026
af284f6
Update
shoumikhin Aug 2, 2026
96334c6
Update
shoumikhin Aug 2, 2026
9addd69
Update
shoumikhin Aug 2, 2026
fbcf931
Update
shoumikhin Aug 2, 2026
1de5047
Update
shoumikhin Aug 2, 2026
85be3cf
Update
shoumikhin Aug 2, 2026
12da9b3
Update
shoumikhin Aug 2, 2026
f972cce
Update
shoumikhin Aug 2, 2026
3832931
Update
shoumikhin Aug 2, 2026
515e34f
Update
shoumikhin Aug 2, 2026
836af39
Update
shoumikhin Aug 3, 2026
e1ee4af
Update
shoumikhin Aug 3, 2026
ba0c8f1
Update
shoumikhin Aug 3, 2026
a7457b5
Update
shoumikhin Aug 3, 2026
efb9bc1
Update
shoumikhin Aug 3, 2026
9d3f6c4
Update
shoumikhin Aug 3, 2026
9e781b3
Update
shoumikhin Aug 3, 2026
25b7c74
Update
shoumikhin Aug 3, 2026
06762fe
Update
shoumikhin Aug 3, 2026
f080144
Update
shoumikhin Aug 3, 2026
85c41d1
Update
shoumikhin Aug 3, 2026
4fc97dd
Update
shoumikhin Aug 3, 2026
d6114ed
Update
shoumikhin Aug 3, 2026
344b53f
Update
shoumikhin Aug 3, 2026
9c41cf2
Update
shoumikhin Aug 3, 2026
c0302fa
Update
shoumikhin Aug 3, 2026
6818a88
Update
shoumikhin Aug 3, 2026
66cf96c
Update
shoumikhin Aug 3, 2026
cac8c9b
Update
shoumikhin Aug 3, 2026
f5819c2
Update
shoumikhin Aug 3, 2026
16ef221
Update
shoumikhin Aug 3, 2026
1347b9d
Update
shoumikhin Aug 3, 2026
6fc6c9c
Update
shoumikhin Aug 3, 2026
7d3b20f
Update
shoumikhin Aug 4, 2026
190a917
Update
shoumikhin Aug 4, 2026
f0d98f4
Update
shoumikhin Aug 4, 2026
8d5f30f
Update
shoumikhin Aug 4, 2026
e1600c8
Update
shoumikhin Aug 4, 2026
9b80da1
Update
shoumikhin Aug 4, 2026
78518c9
Update
shoumikhin Aug 4, 2026
de92937
Update
shoumikhin Aug 4, 2026
b54b04b
Update
shoumikhin Aug 4, 2026
289cf00
Update
shoumikhin Aug 4, 2026
d7ecfa9
Update
shoumikhin Aug 4, 2026
6eb7c6d
Update
shoumikhin Aug 4, 2026
662bef7
Update
shoumikhin Aug 4, 2026
18f9448
Update
shoumikhin Aug 5, 2026
bba6d85
Update
shoumikhin Aug 5, 2026
c489bc4
Update
shoumikhin Aug 5, 2026
8c892d8
Update
shoumikhin Aug 5, 2026
cd98316
Update
shoumikhin Aug 5, 2026
74bcef4
Update
shoumikhin Aug 5, 2026
9fb9a46
Update
shoumikhin Aug 5, 2026
f1e842a
Update
shoumikhin Aug 5, 2026
e9198fe
Update
shoumikhin Aug 5, 2026
00509a8
Update
shoumikhin Aug 5, 2026
4e029cd
Update
shoumikhin Aug 5, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions .ci/scripts/wheel/test_cpp_sdk.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,12 @@
# the operators are registered twice, which aborts at startup.
_KERNEL_SYMBOLS = ("torch::executor::native::abs_out",)

# A representative symbol from the XNNPACK delegate. A second definer means the
# process carries two copies of the delegate.
_XNNPACK_SYMBOLS = (
"executorch::backends::xnnpack::XnnpackBackendOptions::workspace_manager",
)

# `nm -DC` prints "<hexaddr> <kind> <name>" for a definition and
# " U <name>" for an undefined reference.
_DEFINED = re.compile(r"^[0-9a-fA-F]+\s+(?P<kind>[A-Za-z])\s+(?P<name>.+)$")
Expand Down Expand Up @@ -148,6 +154,11 @@ def test_single_kernel_registration() -> None:
_assert_single_definer(_KERNEL_SYMBOLS, "set of CPU kernels")


def test_single_xnnpack_delegate() -> None:
"""Exactly one shipped library may define the XNNPACK delegate."""
_assert_single_definer(_XNNPACK_SYMBOLS, "XNNPACK delegate")


def test_cpp_consumer(work_dir: Path) -> None:
"""A standalone C++ app builds and runs against the installed wheel."""
assert shutil.which("cmake") is not None, "cmake is required to build a consumer"
Expand Down Expand Up @@ -249,4 +260,5 @@ def run_tests(work_dir: Path) -> None:
test_single_backend_registry()
test_single_threadpool()
test_single_kernel_registration()
test_single_xnnpack_delegate()
test_cpp_consumer(work_dir)
33 changes: 22 additions & 11 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1200,9 +1200,15 @@ if(EXECUTORCH_BUILD_PYBIND)
endif()

if(EXECUTORCH_BUILD_XNNPACK)
# need to explicitly specify XNNPACK and xnnpack-microkernels-prod here
# otherwise uses XNNPACK and microkernel-prod symbols from libtorch_cpu
list(APPEND _dep_libs xnnpack_backend XNNPACK xnnpack-microkernels-prod)
if(EXECUTORCH_BUILD_SHARED)
# The delegate bundles XNNPACK and its microkernels, so naming them again
# here would ship a second copy.
list(APPEND _dep_libs xnnpack_backend)
Comment thread
shoumikhin marked this conversation as resolved.
else()
# need to explicitly specify XNNPACK and xnnpack-microkernels-prod here
# otherwise uses XNNPACK and microkernel-prod symbols from libtorch_cpu
list(APPEND _dep_libs xnnpack_backend XNNPACK xnnpack-microkernels-prod)
endif()
endif()

if(EXECUTORCH_BUILD_VULKAN)
Expand Down Expand Up @@ -1257,14 +1263,19 @@ if(EXECUTORCH_BUILD_PYBIND)
target_compile_options(portable_lib PUBLIC ${_pybind_compile_options})
target_link_libraries(portable_lib PRIVATE ${_dep_libs})
executorch_target_link_shared_runtime(portable_lib)
# The operators register themselves from a static initializer, so nothing here
# references a symbol from the kernels library and some linkers drop it, which
# surfaces at runtime as a missing kernel rather than a link error.
if(TARGET optimized_native_cpu_ops_lib)
executorch_target_retain_shared_library(
portable_lib optimized_native_cpu_ops_lib
)
endif()
# These libraries register their operators or their backend from a static
# initializer, so nothing here references a symbol from them and some linkers
# drop them from DT_NEEDED. That surfaces at runtime as a missing kernel or an
# unregistered backend rather than as a link error.
foreach(_retained_component optimized_native_cpu_ops_lib xnnpack_backend
aoti_cuda_backend
)
Comment thread
Copilot marked this conversation as resolved.
Outdated
if(TARGET ${_retained_component})
executorch_target_retain_shared_library(
portable_lib ${_retained_component}
)
endif()
endforeach()

# Set RPATH to find PyTorch and backend libraries relative to the installation
# location. This goes from executorch/extension/pybindings up to
Expand Down
34 changes: 32 additions & 2 deletions backends/xnnpack/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -101,11 +101,41 @@ set(xnnpack_third_party pthreadpool extension_threadpool cpuinfo)
include(cmake/Dependencies.cmake)

list(TRANSFORM _xnnpack_backend__srcs PREPEND "${EXECUTORCH_ROOT}/")
add_library(xnnpack_backend ${_xnnpack_backend__srcs})
# Build the delegate as a shared library for the wheel so a process has one copy
# of it, and keep it static everywhere else so no other build changes.
if(EXECUTORCH_BUILD_SHARED)
set(_xnnpack_backend_library_type SHARED)
else()
set(_xnnpack_backend_library_type STATIC)
endif()
add_library(
xnnpack_backend ${_xnnpack_backend_library_type} ${_xnnpack_backend__srcs}
)
target_link_libraries(
xnnpack_backend PUBLIC ${xnnpack_third_party} executorch_core xnnpack_schema
xnnpack_backend PUBLIC ${xnnpack_third_party} xnnpack_schema
extension_threadpool
)
if(EXECUTORCH_BUILD_SHARED)
Comment thread
shoumikhin marked this conversation as resolved.
set_target_properties(
xnnpack_backend
PROPERTIES OUTPUT_NAME executorch_xnnpack_backend
VERSION "${PROJECT_VERSION}"
SOVERSION "${PROJECT_VERSION_MAJOR}"
)
# XNNPACK and its microkernels are forced static, so bundle them inside this
# library instead of making every consumer supply them.
executorch_target_whole_archive(xnnpack_backend XNNPACK)
executorch_target_whole_archive(xnnpack_backend xnnpack-microkernels-prod)
target_link_libraries(xnnpack_backend PUBLIC executorch_shared)
if(NOT APPLE)
# Ships beside the runtime in the wheel's lib/ directory.
set_target_properties(
xnnpack_backend PROPERTIES BUILD_RPATH "$ORIGIN" INSTALL_RPATH "$ORIGIN"
)
endif()
else()
target_link_libraries(xnnpack_backend PUBLIC executorch_core)
endif()
target_include_directories(
xnnpack_backend PUBLIC ${_common_include_directories}
)
Expand Down
17 changes: 17 additions & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -1143,6 +1143,23 @@ def run(self): # noqa C901
),
dependent_cmake_flags=["EXECUTORCH_BUILD_SHARED"],
),
# Install the XNNPACK delegate beside them, so a process has one
# copy of it instead of one per component that uses it.
BuiltFile(
src_dir="%CMAKE_CACHE_DIR%/backends/xnnpack/",
src_name=(
"libexecutorch_xnnpack_backend.so."
f"{get_runtime_soname_major()}.*"
),
dst=(
"executorch/lib/libexecutorch_xnnpack_backend.so."
f"{get_runtime_soname_major()}"
),
dependent_cmake_flags=[
"EXECUTORCH_BUILD_SHARED",
"EXECUTORCH_BUILD_XNNPACK",
],
),
# Install the prebuilt pybindings extension wrapper for the runtime,
# portable kernels, and a selection of backends. This lets users
# load and execute .pte files from python.
Expand Down
Loading