From ae96ce93d9b9398f71d50e74198132e8d8870f53 Mon Sep 17 00:00:00 2001 From: Jake Stevens Date: Thu, 29 Oct 2026 13:51:30 -0700 Subject: [PATCH 1/2] Add CMake build for CpuBackend (#24251) Summary: `CpuBackend` (`backends/cpu`) builds only with Buck today, so the backend test suite's `cpu_fp32` flow cannot run in OSS CI. This adds an opt-in CMake build. Reviewed By: shoumikhin Differential Revision: D127905370 --- CMakeLists.txt | 18 +- backends/cpu/CMakeLists.txt | 163 ++++++++++++++---- backends/cpu/README.md | 7 + backends/cpu/targets.bzl | 7 +- backends/native/CMakeLists.txt | 13 +- backends/native/runtime/CMakeLists.txt | 76 ++++---- backends/native/runtime/cpu/CMakeLists.txt | 2 +- setup.py | 18 ++ .../executorch/build/build_variables.bzl | 13 ++ tools/cmake/Codegen.cmake | 2 + tools/cmake/executorch-config.cmake | 1 + tools/cmake/executorch-wheel-config.cmake | 3 + tools/cmake/preset/default.cmake | 19 ++ 13 files changed, 263 insertions(+), 79 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3768d04a083..d5f1c02ad82 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -787,7 +787,7 @@ endif() if(EXECUTORCH_BUILD_NATIVE) string(APPEND _executorch_backend_dependencies "find_dependency(libzip CONFIG)\n" - "find_dependency(nlohmann_json CONFIG)\n" "find_dependency(Threads)\n" + "find_dependency(nlohmann_json CONFIG)\n" ) endif() if(EXECUTORCH_BUILD_NATIVE_GGML) @@ -797,7 +797,10 @@ if(EXECUTORCH_BUILD_NATIVE_GGML) " add_library(executorch_ggml ALIAS ggml::ggml)\n" "endif()\n" ) endif() -if(EXECUTORCH_BUILD_VULKAN) +if(EXECUTORCH_BUILD_NATIVE + OR EXECUTORCH_BUILD_CPU + OR EXECUTORCH_BUILD_VULKAN +) string(APPEND _executorch_backend_dependencies "find_dependency(Threads)\n") endif() configure_file( @@ -1417,6 +1420,10 @@ if(EXECUTORCH_BUILD_PYBIND) endif() endif() + if(EXECUTORCH_BUILD_CPU) + list(APPEND _dep_libs cpu_backend) + endif() + if(EXECUTORCH_BUILD_VULKAN) list(APPEND _dep_libs vulkan_backend) endif() @@ -1624,10 +1631,15 @@ if(EXECUTORCH_BUILD_VULKAN) list(APPEND _executorch_backends vulkan_backend vulkan_schema) endif() -if(EXECUTORCH_BUILD_NATIVE) +if(EXECUTORCH_BUILD_NATIVE OR EXECUTORCH_BUILD_CPU) add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/backends/native) endif() +if(EXECUTORCH_BUILD_CPU) + add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/backends/cpu) + list(APPEND _executorch_backends cpu_backend) +endif() + if(EXECUTORCH_BUILD_WEBGPU) add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/backends/webgpu) list(APPEND _executorch_backends webgpu_backend) diff --git a/backends/cpu/CMakeLists.txt b/backends/cpu/CMakeLists.txt index 7a1eccc88f0..eb41dcbd040 100644 --- a/backends/cpu/CMakeLists.txt +++ b/backends/cpu/CMakeLists.txt @@ -4,56 +4,147 @@ # This source code is licensed under the BSD-style license found in the # LICENSE file in the root directory of this source tree. -add_library( - cpu_runtime runtime/KernelProvider.cpp runtime/CPUPlan.cpp - runtime/op_helpers/Convolution.cpp -) -target_link_libraries( - cpu_runtime - PUBLIC native_runtime - PRIVATE extension_threadpool +cmake_minimum_required(VERSION 3.24) + +if(NOT EXECUTORCH_ROOT) + set(EXECUTORCH_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/../..) +endif() + +include(${EXECUTORCH_ROOT}/tools/cmake/Utils.cmake) + +if(EXECUTORCH_BUILD_NATIVE_CPU) + add_library( + cpu_runtime runtime/KernelProvider.cpp runtime/CPUPlan.cpp + runtime/op_helpers/Convolution.cpp + ) + target_link_libraries( + cpu_runtime + PUBLIC native_runtime + PRIVATE extension_threadpool + ) + if(EXECUTORCH_BUILD_SHARED) + target_link_libraries(cpu_runtime PUBLIC executorch_shared) + else() + target_link_libraries(cpu_runtime PUBLIC executorch_core) + endif() + + add_library(cpu_reference runtime/providers/reference/ReferenceProvider.cpp) + target_link_libraries(cpu_reference PUBLIC cpu_runtime) + + add_library(cpu_xnnpack runtime/providers/xnnpack/XNNPACKProvider.cpp) + target_link_libraries( + cpu_xnnpack + PUBLIC cpu_runtime + PRIVATE extension_threadpool + ) + if(EXECUTORCH_BUILD_SHARED) + target_link_libraries(cpu_xnnpack PRIVATE xnnpack_shared) + else() + target_link_libraries(cpu_xnnpack PRIVATE XNNPACK) + endif() + + foreach(target cpu_runtime cpu_reference cpu_xnnpack) + add_library(executorch::${target} ALIAS ${target}) + target_compile_features(${target} PUBLIC cxx_std_20) + target_compile_options( + ${target} PRIVATE $<$:/EHsc> + $<$>:-fexceptions> + ) + endforeach() + + install( + TARGETS cpu_runtime cpu_reference cpu_xnnpack + EXPORT ExecuTorchTargets + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + ) + install( + DIRECTORY runtime/ + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/executorch/backends/cpu/runtime + FILES_MATCHING + PATTERN "*.h" + PATTERN "test" EXCLUDE + ) +endif() + +if(NOT EXECUTORCH_BUILD_CPU) + return() +endif() + +# The provider composition that cpu_backend() in targets.bzl generates for the +# default :cpu_backend target. +set(_cpu_provider_registry ${CMAKE_CURRENT_BINARY_DIR}/provider_registry.cpp) +file( + GENERATE + OUTPUT ${_cpu_provider_registry} + CONTENT + "#include +#include +#include +namespace executorch::backends::cpu { +namespace { +RuntimeConfiguration runtime_configuration() { +static const ProviderFactory factories[] = {create_xnnpack_provider,create_reference_provider}; +return {{factories, sizeof(factories) / sizeof(factories[0])}, {}, false}; +} +const bool registered = (register_runtime_configuration(runtime_configuration), true); +} +} +" ) + +list(TRANSFORM _cpu_backend__srcs PREPEND "${EXECUTORCH_ROOT}/") if(EXECUTORCH_BUILD_SHARED) - target_link_libraries(cpu_runtime PUBLIC executorch_shared) + set(_cpu_backend_library_type SHARED) else() - target_link_libraries(cpu_runtime PUBLIC executorch_core) + set(_cpu_backend_library_type STATIC) endif() - -add_library(cpu_reference runtime/providers/reference/ReferenceProvider.cpp) -target_link_libraries(cpu_reference PUBLIC cpu_runtime) - -add_library(cpu_xnnpack runtime/providers/xnnpack/XNNPACKProvider.cpp) +add_library( + cpu_backend ${_cpu_backend_library_type} ${_cpu_backend__srcs} + ${_cpu_provider_registry} +) target_link_libraries( - cpu_xnnpack - PUBLIC cpu_runtime - PRIVATE extension_threadpool + cpu_backend PRIVATE native_program extension_threadpool + optimized_native_cpu_ops_lib ) if(EXECUTORCH_BUILD_SHARED) - target_link_libraries(cpu_xnnpack PRIVATE xnnpack_shared) + set_target_properties( + cpu_backend PROPERTIES OUTPUT_NAME executorch_backend_cpu + ) + executorch_target_soname_policy(cpu_backend) + executorch_target_link_shared_runtime(cpu_backend) + # The XNNPACK delegate library already bundles XNNPACK, so resolve against it + # rather than shipping a second copy. + target_link_libraries( + cpu_backend + PUBLIC executorch_shared + PRIVATE xnnpack_backend + ) + target_include_directories( + cpu_backend + PRIVATE $ + ) + executorch_target_shipped_runtime_path(cpu_backend) else() - target_link_libraries(cpu_xnnpack PRIVATE XNNPACK) + target_link_libraries( + cpu_backend + PUBLIC executorch_core + PRIVATE XNNPACK xnnpack-microkernels-prod + ) endif() - -foreach(target cpu_runtime cpu_reference cpu_xnnpack) - add_library(executorch::${target} ALIAS ${target}) - target_compile_features(${target} PUBLIC cxx_std_20) - target_compile_options( - ${target} PRIVATE $<$:/EHsc> +target_compile_features(cpu_backend PRIVATE cxx_std_20) +target_compile_options( + cpu_backend PRIVATE $<$:/EHsc> $<$>:-fexceptions> - ) -endforeach() +) +set_target_properties(cpu_backend PROPERTIES POSITION_INDEPENDENT_CODE ON) +executorch_target_link_options_shared_lib(cpu_backend) install( - TARGETS cpu_runtime cpu_reference cpu_xnnpack + TARGETS cpu_backend EXPORT ExecuTorchTargets ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} ) -install( - DIRECTORY runtime/ - DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/executorch/backends/cpu/runtime - FILES_MATCHING - PATTERN "*.h" - PATTERN "test" EXCLUDE -) diff --git a/backends/cpu/README.md b/backends/cpu/README.md index 51c58edebeb..7adb9b0cb70 100644 --- a/backends/cpu/README.md +++ b/backends/cpu/README.md @@ -37,6 +37,13 @@ The shared `KernelProvider` contract, `CPUPlan`, and `CpuBackend` remain in [`targets.bzl`](targets.bzl). The Buck `cpu_backend` target links the baseline XNNPACK and Reference providers. +The CMake `cpu_backend` target (`-DEXECUTORCH_BUILD_CPU=ON`, which requires +`-DEXECUTORCH_BUILD_XNNPACK=ON` and `-DEXECUTORCH_BUILD_KERNELS_OPTIMIZED=ON`) +links the same composition, including the full optimized and portable kernel +library for the Reference provider. Selective kernel builds are not supported. +The CPU backend is disabled by default, including in Python wheels. Enable it +for an editable install with +`CMAKE_ARGS="-DEXECUTORCH_BUILD_CPU=ON" ./install_executorch.sh --editable`. Applications compose providers with [`cpu_backend()`](cpu_backend.bzl). `CPUPlan` retains selection, regions, storage requirements and prepared executables diff --git a/backends/cpu/targets.bzl b/backends/cpu/targets.bzl index 80f0e6a9198..6832e6f1201 100644 --- a/backends/cpu/targets.bzl +++ b/backends/cpu/targets.bzl @@ -1,15 +1,12 @@ load("@fbsource//xplat/executorch/backends/xnnpack/third-party:third_party_libs.bzl", "third_party_dep") +load("@fbsource//xplat/executorch/build:build_variables.bzl", "CPU_RUNTIME_BUCK_SRCS") load("@fbsource//xplat/executorch/build:runtime_wrapper.bzl", "runtime") load(":cpu_backend.bzl", "cpu_backend", "cpu_provider") def define_common_targets(): runtime.cxx_library( name = "cpu_runtime", - srcs = [ - "runtime/KernelProvider.cpp", - "runtime/CPUPlan.cpp", - "runtime/op_helpers/Convolution.cpp", - ], + srcs = CPU_RUNTIME_BUCK_SRCS, exported_headers = [ "runtime/KernelProvider.h", "runtime/CPUPlan.h", diff --git a/backends/native/CMakeLists.txt b/backends/native/CMakeLists.txt index f5ed501d68e..1a2911aab89 100644 --- a/backends/native/CMakeLists.txt +++ b/backends/native/CMakeLists.txt @@ -11,9 +11,14 @@ if(NOT DEFINED CMAKE_POSITION_INDEPENDENT_CODE) endif() find_package(Threads REQUIRED) -find_package(libzip CONFIG REQUIRED) -if(NOT TARGET nlohmann_json::nlohmann_json) - find_package(nlohmann_json CONFIG REQUIRED) + +# A CPU backend build without EXECUTORCH_BUILD_NATIVE only needs the graph and +# the program reader, which have no third-party dependencies. +if(EXECUTORCH_BUILD_NATIVE) + find_package(libzip CONFIG REQUIRED) + if(NOT TARGET nlohmann_json::nlohmann_json) + find_package(nlohmann_json CONFIG REQUIRED) + endif() endif() add_subdirectory(runtime) @@ -45,6 +50,6 @@ if(EXECUTORCH_BUILD_NATIVE_VISION_RUNNER OR EXECUTORCH_BUILD_NATIVE_LLM_RUNNER) add_subdirectory(examples) endif() -if(EXECUTORCH_BUILD_TESTS) +if(EXECUTORCH_BUILD_NATIVE AND EXECUTORCH_BUILD_TESTS) add_subdirectory(test) endif() diff --git a/backends/native/runtime/CMakeLists.txt b/backends/native/runtime/CMakeLists.txt index 3a416526bdb..5867567f294 100644 --- a/backends/native/runtime/CMakeLists.txt +++ b/backends/native/runtime/CMakeLists.txt @@ -42,41 +42,58 @@ add_library( graph/utils/GraphUtils.cpp ) -add_library(native_reference_gguf_kquant utils/ReferenceGgufKQuant.cpp) -target_link_libraries(native_reference_gguf_kquant PRIVATE Threads::Threads) - -add_library( - native_package - deserialize/OwnedBytes.cpp deserialize/Package.cpp - deserialize/SafeTensorsReader.cpp deserialize/Samples.cpp - deserialize/ZipReader.cpp -) +add_library(native_program Deserialize.cpp Program.cpp) target_link_libraries( - native_package + native_program PUBLIC native_graph - PRIVATE libzip::zip nlohmann_json::nlohmann_json Threads::Threads -) - -add_library( - native_runtime Deserialize.cpp Program.cpp MethodMeta.cpp TensorInfo.cpp - Validation.cpp -) -target_link_libraries( - native_runtime - PUBLIC native_graph native_package PRIVATE $ Threads::Threads ) -add_dependencies(native_runtime native_graph_schema_gen) +add_dependencies(native_program native_graph_schema_gen) -add_library(native_engine engine/Engine.cpp) -target_link_libraries(native_engine PUBLIC native_runtime) +set(_native_runtime_targets native_graph native_program) -add_library(native_api api/Model.cpp) -target_link_libraries(native_api PUBLIC native_engine) +if(EXECUTORCH_BUILD_NATIVE) + add_library(native_reference_gguf_kquant utils/ReferenceGgufKQuant.cpp) + target_link_libraries(native_reference_gguf_kquant PRIVATE Threads::Threads) -foreach(target native_graph native_reference_gguf_kquant native_package - native_runtime native_engine native_api -) + add_library( + native_package + deserialize/OwnedBytes.cpp deserialize/Package.cpp + deserialize/SafeTensorsReader.cpp deserialize/Samples.cpp + deserialize/ZipReader.cpp + ) + target_link_libraries( + native_package + PUBLIC native_graph + PRIVATE libzip::zip nlohmann_json::nlohmann_json Threads::Threads + ) + + add_library(native_runtime MethodMeta.cpp TensorInfo.cpp Validation.cpp) + target_link_libraries( + native_runtime + PUBLIC native_program native_package + PRIVATE $ Threads::Threads + ) + add_dependencies(native_runtime native_graph_schema_gen) + + add_library(native_engine engine/Engine.cpp) + target_link_libraries(native_engine PUBLIC native_runtime) + + add_library(native_api api/Model.cpp) + target_link_libraries(native_api PUBLIC native_engine) + + list( + APPEND + _native_runtime_targets + native_reference_gguf_kquant + native_package + native_runtime + native_engine + native_api + ) +endif() + +foreach(target ${_native_runtime_targets}) add_library(executorch::${target} ALIAS ${target}) target_compile_features(${target} PUBLIC cxx_std_20) target_compile_options( @@ -90,8 +107,7 @@ foreach(target native_graph native_reference_gguf_kquant native_package endforeach() install( - TARGETS native_graph native_reference_gguf_kquant native_package - native_runtime native_engine native_api + TARGETS ${_native_runtime_targets} EXPORT ExecuTorchTargets ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} diff --git a/backends/native/runtime/cpu/CMakeLists.txt b/backends/native/runtime/cpu/CMakeLists.txt index 7838ca21406..058d3c9f2bb 100644 --- a/backends/native/runtime/cpu/CMakeLists.txt +++ b/backends/native/runtime/cpu/CMakeLists.txt @@ -4,7 +4,7 @@ # This source code is licensed under the BSD-style license found in the # LICENSE file in the root directory of this source tree. -if(NOT TARGET cpu_runtime) +if(NOT EXECUTORCH_BUILD_CPU AND NOT TARGET cpu_runtime) add_subdirectory( ${EXECUTORCH_ROOT}/backends/cpu ${CMAKE_CURRENT_BINARY_DIR}/cpu_runtime ) diff --git a/setup.py b/setup.py index b3448485054..e9c541e9dab 100644 --- a/setup.py +++ b/setup.py @@ -1401,6 +1401,12 @@ def _windows_import_libraries() -> List["BuiltFile"]: None, ["EXECUTORCH_BUILD_XNNPACK", "EXECUTORCH_BUILD_NATIVE_CPU"], ), + ( + "backends/cpu/", + "executorch_backend_cpu", + None, + ["EXECUTORCH_BUILD_CPU"], + ), ( "backends/cuda/", "executorch_backend_cuda", @@ -2956,6 +2962,8 @@ def run(self): # noqa C901 cmake_build_args += ["--target", "executorch_kernels_torchao"] if cmake_cache.is_enabled("EXECUTORCH_BUILD_XNNPACK"): cmake_build_args += ["--target", "xnnpack_backend"] + if cmake_cache.is_enabled("EXECUTORCH_BUILD_CPU"): + cmake_build_args += ["--target", "cpu_backend"] if cmake_cache.is_enabled("EXECUTORCH_BUILD_KERNELS_LLM_AOT"): cmake_build_args += ["--target", "custom_ops_aot_lib"] @@ -3208,6 +3216,16 @@ def iter_distribution_names(self): "EXECUTORCH_BUILD_NATIVE_CPU", ], ), + BuiltFile( + src_dir="%CMAKE_CACHE_DIR%/backends/cpu/" + _CFG, + src_name=get_dynamic_lib_name("executorch_backend_cpu"), + dst="executorch/lib/" + + get_dynamic_lib_name("executorch_backend_cpu"), + dependent_cmake_flags=[ + "EXECUTORCH_BUILD_SHARED", + "EXECUTORCH_BUILD_CPU", + ], + ), # Install the MLX delegate beside them, so a C++ consumer can link # it out of the wheel rather than only reaching it from Python. BuiltFile( diff --git a/shim_et/xplat/executorch/build/build_variables.bzl b/shim_et/xplat/executorch/build/build_variables.bzl index b0e7f7e7065..edad3455157 100644 --- a/shim_et/xplat/executorch/build/build_variables.bzl +++ b/shim_et/xplat/executorch/build/build_variables.bzl @@ -432,6 +432,19 @@ XNNPACK_SCHEMA_SRCS = [ "backends/xnnpack/serialization/runtime_schema.fbs", ] +CPU_RUNTIME_BUCK_SRCS = [ + "runtime/KernelProvider.cpp", + "runtime/CPUPlan.cpp", + "runtime/op_helpers/Convolution.cpp", +] + +# CpuBackend with the default provider composition: XNNPACK and Reference. +CPU_BACKEND_SRCS = ["backends/cpu/" + x for x in CPU_RUNTIME_BUCK_SRCS + [ + "runtime/CPUBackend.cpp", + "runtime/providers/reference/ReferenceProvider.cpp", + "runtime/providers/xnnpack/XNNPACKProvider.cpp", +]] + VULKAN_SCHEMA_SRCS = [ "backends/vulkan/serialization/schema.fbs", ] diff --git a/tools/cmake/Codegen.cmake b/tools/cmake/Codegen.cmake index 3f1ef2bf2ad..ade33d205f3 100644 --- a/tools/cmake/Codegen.cmake +++ b/tools/cmake/Codegen.cmake @@ -591,6 +591,7 @@ function(executorch_load_build_variables) XNN_EXECUTOR_RUNNER_SRCS XNNPACK_BACKEND_SRCS XNNPACK_SCHEMA_SRCS + CPU_BACKEND_SRCS VULKAN_SCHEMA_SRCS CUSTOM_OPS_SRCS LLAMA_RUNNER_SRCS @@ -622,6 +623,7 @@ function(executorch_load_build_variables) _xnn_executor_runner__srcs _xnnpack_backend__srcs _xnnpack_schema__srcs + _cpu_backend__srcs _vulkan_schema__srcs _custom_ops__srcs _llama_runner__srcs diff --git a/tools/cmake/executorch-config.cmake b/tools/cmake/executorch-config.cmake index 3d3b650f33e..0e9645efd14 100644 --- a/tools/cmake/executorch-config.cmake +++ b/tools/cmake/executorch-config.cmake @@ -123,6 +123,7 @@ set(optional_lib_list extension_threadpool extension_training xnnpack_backend + cpu_backend vulkan_backend optimized_kernels optimized_portable_kernels diff --git a/tools/cmake/executorch-wheel-config.cmake b/tools/cmake/executorch-wheel-config.cmake index 130dfac3c7b..3aa29d3963d 100644 --- a/tools/cmake/executorch-wheel-config.cmake +++ b/tools/cmake/executorch-wheel-config.cmake @@ -75,6 +75,7 @@ # model. Not part of EXECUTORCH_LIBRARIES, see # below. # executorch::backend_xnnpack The XNNPACK delegate. +# executorch::backend_cpu The CPU delegate, when explicitly enabled. # executorch::backend_coreml The Core ML delegate. macOS only. # executorch::backend_mlx The MLX delegate. macOS on Apple Silicon only. # Its Metal kernel archive is published as @@ -383,6 +384,7 @@ if(_executorch_runtime_library AND NOT _executorch_targets_supported) ITEMS libexecutorch_kernels_optimized libexecutorch_kernels_torchao libexecutorch_backend_xnnpack + libexecutorch_backend_cpu libexecutorch_backend_coreml libexecutorch_backend_mlx libexecutorch_backend_cuda @@ -765,6 +767,7 @@ if(TARGET executorch::runtime AND TARGET executorch::threadpool) endif() _executorch_define_component(backend_xnnpack executorch_backend_xnnpack) +_executorch_define_component(backend_cpu executorch_backend_cpu) # The Core ML delegate, present only in a wheel built on macOS. _executorch_define_component(backend_coreml executorch_backend_coreml) # The MLX delegate, present only in a wheel built on Apple Silicon with the diff --git a/tools/cmake/preset/default.cmake b/tools/cmake/preset/default.cmake index bd367629453..069fde0fd13 100644 --- a/tools/cmake/preset/default.cmake +++ b/tools/cmake/preset/default.cmake @@ -175,6 +175,7 @@ define_overridable_option( define_overridable_option( EXECUTORCH_BUILD_XNNPACK "Build the XNNPACK backend" BOOL OFF ) +define_overridable_option(EXECUTORCH_BUILD_CPU "Build the CPU backend" BOOL OFF) define_overridable_option( EXECUTORCH_BUILD_VULKAN "Build the Vulkan backend" BOOL OFF ) @@ -502,6 +503,24 @@ check_required_options_on( EXECUTORCH_BUILD_PTHREADPOOL ) +# The default composition uses XNNPACK and the full Reference kernel library. +check_required_options_on( + IF_ON EXECUTORCH_BUILD_CPU REQUIRES EXECUTORCH_BUILD_XNNPACK + EXECUTORCH_BUILD_KERNELS_OPTIMIZED +) + +if(EXECUTORCH_BUILD_CPU) + if(NOT EXECUTORCH_SELECT_OPS_YAML STREQUAL "" + OR NOT EXECUTORCH_SELECT_OPS_LIST STREQUAL "" + OR NOT EXECUTORCH_SELECT_OPS_MODEL STREQUAL "" + ) + message( + FATAL_ERROR + "EXECUTORCH_BUILD_CPU does not support selective kernel builds" + ) + endif() +endif() + check_conflicting_options_on( IF_ON EXECUTORCH_BUILD_ARM_BAREMETAL CONFLICTS_WITH EXECUTORCH_BUILD_PTHREADPOOL EXECUTORCH_BUILD_CPUINFO From e85e133236eacaef314d63a0b9d32e8373e308a4 Mon Sep 17 00:00:00 2001 From: Jake Stevens Date: Thu, 29 Oct 2026 13:51:30 -0700 Subject: [PATCH 2/2] Add OSS CI for the CPU backend test suite flow (#24252) Summary: Run the backend test suite's `cpu_fp32` flow in OSS CI the way XNNPACK, Vulkan and WebGPU run theirs, now that `EXECUTORCH_BUILD_CPU` builds `CpuBackend` into the pybindings. Reviewed By: shoumikhin Differential Revision: D127905371 --- .ci/scripts/test_backend.sh | 4 ++++ .github/workflows/_test_backend.yml | 2 +- .github/workflows/test-backend-cpu.yml | 31 ++++++++++++++++++++++++++ 3 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/test-backend-cpu.yml diff --git a/.ci/scripts/test_backend.sh b/.ci/scripts/test_backend.sh index 51a49c7f6d2..a6dbeef9b12 100755 --- a/.ci/scripts/test_backend.sh +++ b/.ci/scripts/test_backend.sh @@ -53,6 +53,10 @@ if [[ "$FLOW" == *qnn* ]]; then EXTRA_BUILD_ARGS+=" -DEXECUTORCH_BUILD_QNN=ON -DQNN_SDK_ROOT=$QNN_SDK_ROOT -DEXECUTORCH_BUILD_EXTENSION_TENSOR=ON" fi +if [[ "$FLOW" == *cpu* ]]; then + EXTRA_BUILD_ARGS+=" -DEXECUTORCH_BUILD_CPU=ON -DEXECUTORCH_BUILD_XNNPACK=ON -DEXECUTORCH_BUILD_KERNELS_OPTIMIZED=ON" +fi + if [[ "$FLOW" == *vulkan* ]]; then # CPU runners can have Mesa ICDs installed without a usable hardware GPU. source .ci/scripts/setup-vulkan-linux-deps.sh "swiftshader" diff --git a/.github/workflows/_test_backend.yml b/.github/workflows/_test_backend.yml index 0bd1f3d24fd..e50e25ad156 100644 --- a/.github/workflows/_test_backend.yml +++ b/.github/workflows/_test_backend.yml @@ -4,7 +4,7 @@ on: workflow_call: inputs: backend: - description: 'Backend to test (xnnpack, coreml, vulkan, qnn, openvino)' + description: 'Backend to test (xnnpack, coreml, vulkan, qnn, openvino, cpu)' required: true type: string flows: diff --git a/.github/workflows/test-backend-cpu.yml b/.github/workflows/test-backend-cpu.yml new file mode 100644 index 00000000000..477dd9bc489 --- /dev/null +++ b/.github/workflows/test-backend-cpu.yml @@ -0,0 +1,31 @@ +name: Test CPU Backend + +on: + schedule: + - cron: 0 2 * * * + push: + branches: + - main + - release/* + tags: + - ciflow/nightly/* + pull_request: + workflow_dispatch: + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref_name }}-${{ github.ref_type == 'branch' && github.sha }}-${{ github.event_name == 'workflow_dispatch' }}-${{ github.event_name == 'schedule' }} + cancel-in-progress: true + +jobs: + test-cpu: + uses: ./.github/workflows/_test_backend.yml + permissions: + id-token: write + contents: read + with: + backend: cpu + flows: '["cpu_fp32"]' + ref: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }} + timeout: 120 + run-linux: true + docker-image: ci-image:executorch-ubuntu-22.04-gcc11