Skip to content

Build XNNPACK as an ExternalProject #12425

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 14 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 11 commits
Commits
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
2 changes: 2 additions & 0 deletions .github/workflows/build-wheels-linux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ on:
- examples/**/*
- pyproject.toml
- setup.py
tags:
- ciflow/binaries/*
push:
branches:
- nightly
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/build-wheels-macos.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ on:
- examples/**/*
- pyproject.toml
- setup.py
tags:
- ciflow/binaries/*
push:
branches:
- nightly
Expand Down
5 changes: 4 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -737,7 +737,10 @@ if(EXECUTORCH_BUILD_EXECUTOR_RUNNER)
endif()

set(CMAKE_EXECUTABLE_SUFFIX ".html")
target_link_options(executor_runner PUBLIC -sALLOW_MEMORY_GROWTH --embed-file "${WASM_MODEL_DIR}@/")
target_link_options(
executor_runner PUBLIC -sALLOW_MEMORY_GROWTH --embed-file
"${WASM_MODEL_DIR}@/"
)
endif()
endif()

Expand Down
3 changes: 1 addition & 2 deletions backends/xnnpack/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -92,9 +92,8 @@ target_include_directories(
${EXECUTORCH_ROOT}/third-party/flatbuffers/include
)

set(xnnpack_third_party pthreadpool extension_threadpool cpuinfo)

include(cmake/Dependencies.cmake)
set(xnnpack_third_party XNNPACK pthreadpool extension_threadpool cpuinfo)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

curious what does this rearrangment do?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just found it weird that we were mutating xnnpack_third_party in cmake/Dependencies.cmake rather than setting it all at once


list(TRANSFORM _xnnpack_backend__srcs PREPEND "${EXECUTORCH_ROOT}/")
add_library(xnnpack_backend ${_xnnpack_backend__srcs})
Expand Down
122 changes: 67 additions & 55 deletions backends/xnnpack/cmake/Dependencies.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -10,71 +10,83 @@ set(THIRD_PARTY_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/third-party")

# --- XNNPACK

# Setting this global PIC flag for all XNNPACK targets. This is needed for
# Object libraries within XNNPACK which must be PIC to successfully link this
# static libXNNPACK
set(ORIGINAL_CMAKE_POSITION_INDEPENDENT_CODE_FLAG
${CMAKE_POSITION_INDEPENDENT_CODE}
)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)

set(XNNPACK_SOURCE_DIR "${THIRD_PARTY_ROOT}/XNNPACK")
set(XNNPACK_INCLUDE_DIR "${XNNPACK_SOURCE_DIR}/include")
set(XNNPACK_LIBRARY_TYPE
"static"
CACHE STRING ""

include(ExternalProject)
include(GNUInstallDirs) # For CMAKE_INSTALL_LIBDIR
set(XNNPACK_INSTALL_DIR "${CMAKE_CURRENT_BINARY_DIR}/XNNPACK/install")
set(XNNPACK_STATIC_LIB
"${XNNPACK_INSTALL_DIR}/${CMAKE_INSTALL_LIBDIR}/libXNNPACK.a"
)
set(XNNPACK_BUILD_BENCHMARKS
OFF
CACHE BOOL ""
set(XNNPACK_MICROKERNELS_STATIC_LIB
"${XNNPACK_INSTALL_DIR}/${CMAKE_INSTALL_LIBDIR}/libxnnpack-microkernels-prod.a"
)
set(XNNPACK_BUILD_TESTS
OFF
CACHE BOOL ""
get_extra_cmake_args_for_external_project(XNNPACK_EXTRA_CMAKE_ARGS)
ExternalProject_Add(
XNNPACKExternalProject
SOURCE_DIR ${XNNPACK_SOURCE_DIR}
# Not 100% clear on these locations
BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/XNNPACK
INSTALL_DIR ${XNNPACK_INSTALL_DIR}
INSTALL_BYPRODUCTS ${XNNPACK_STATIC_LIB} ${XNNPACK_MICROKERNELS_STATIC_LIB}
CMAKE_ARGS
${XNNPACK_EXTRA_CMAKE_ARGS}
-D
XNNPACK_LIBRARY_TYPE=static
-D
XNNPACK_BUILD_BENCHMARKS=OFF
-D
XNNPACK_BUILD_TESTS=OFF
-D
XNNPACK_ENABLE_AVXVNNI=OFF
# Work around observed failure:
# https://github.com/pytorch/executorch/pull/10362#issuecomment-2906391232
-D
XNNPACK_ENABLE_AVX512VNNIGFNI=OFF
-D
ENABLE_XNNPACK_WEIGHTS_CACHE=${EXECUTORCH_XNNPACK_ENABLE_WEIGHT_CACHE}
-D
ENABLE_XNNPACK_SHARED_WORKSPACE=${EXECUTORCH_XNNPACK_SHARED_WORKSPACE}
-D
XNNPACK_ENABLE_KLEIDIAI=${EXECUTORCH_XNNPACK_ENABLE_KLEIDIAI}
-D
CMAKE_INSTALL_PREFIX=<INSTALL_DIR>
-D
XNNPACK_BUILD_ALL_MICROKERNELS=OFF
-D
CMAKE_POSITION_INDEPENDENT_CODE=ON
)
set(XNNPACK_ENABLE_AVXVNNI
OFF
CACHE BOOL ""
)
# Work around observed failure: https://github.com/pytorch/executorch/pull/10362#issuecomment-2906391232
set(XNNPACK_ENABLE_AVX512VNNIGFNI
OFF
CACHE BOOL "")

if(EXECUTORCH_XNNPACK_ENABLE_KLEIDI)
set(XNNPACK_ENABLE_KLEIDIAI
ON
CACHE BOOL ""
)
else()
set(XNNPACK_ENABLE_KLEIDIAI
OFF
CACHE BOOL ""
)
endif()
add_library(XNNPACK STATIC IMPORTED GLOBAL)
# TODO: this probably doesn't work on Windows.
set_property(TARGET XNNPACK PROPERTY IMPORTED_LOCATION ${XNNPACK_STATIC_LIB})

add_dependencies(XNNPACK XNNPACKExternalProject)

set(XNNPACK_BUILD_ALL_MICROKERNELS
OFF
CACHE BOOL ""
add_library(xnnpack-microkernels-prod STATIC IMPORTED GLOBAL)
set_property(
TARGET xnnpack-microkernels-prod PROPERTY IMPORTED_LOCATION
${XNNPACK_MICROKERNELS_STATIC_LIB}
)
add_subdirectory("${XNNPACK_SOURCE_DIR}")
include_directories(SYSTEM ${XNNPACK_INCLUDE_DIR})
list(APPEND xnnpack_third_party XNNPACK)
install(TARGETS xnnpack-microkernels-prod
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
add_dependencies(xnnpack-microkernels-prod XNNPACKExternalProject)

set_target_properties(
XNNPACK PROPERTIES INTERFACE_LINK_LIBRARIES xnnpack-microkernels-prod
Comment on lines +78 to +79
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh shoot does this mean that any targets that link XNNPACK will also automatically link xnnpack-microkernels-prod as well? So we don't have to explicitly list both XNNPACK and xnnpack-microkernels-prod? I was trying to figure out how to do this for a while, but never figured it out.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

target_link_libraries with visibility PUBLIC or INTERFACE does this for normal libraries, but you need to do it this way for IMPORTED libraries.

)

install(DIRECTORY ${XNNPACK_INSTALL_DIR}/ DESTINATION ${CMAKE_INSTALL_PREFIX})

if(EXECUTORCH_XNNPACK_ENABLE_KLEIDI)
install(TARGETS kleidiai
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
add_library(kleidiai SHARED IMPORTED)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think i merged something that might have conflict here. I just added a check

if (TARGET kleidiai)

before adding the library

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should be fine I think

find_library(
KLEIDIAI_LIBRARY kleidiai
PATHS "${CMAKE_CURRENT_BINARY_DIR}/XNNPACK/kleidiai-source"
)
if(not KLEIDIAI_LIBRARY)
message(FATAL_ERROR "Can't find KleidiAI")
endif()
install(FILES ${KLEIDIAI_LIBRARY} PUBLIC_HEADER
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
)
endif()

# Revert PIC Flag to what it originally was
set(CMAKE_POSITION_INDEPENDENT_CODE
${ORIGINAL_CMAKE_POSITION_INDEPENDENT_CODE_FLAG}
)
29 changes: 29 additions & 0 deletions tools/cmake/Utils.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -278,3 +278,32 @@ macro(find_package_torch)
find_package(Torch CONFIG REQUIRED)
endif()
endmacro()

# In order to support cross compiling, we need to propagate a bunch of CMake
# variables to ExternalProject. Call this to get the current values of all
# relevant variables, which should then be passed to CMAKE_ARGS.
function(get_extra_cmake_args_for_external_project outVar)
set(VARIABLES_TO_PROPAGATE
ANDROID_ABI
ANDROID_PLATFORM
CMAKE_ARCHIVE_OUTPUT_DIRECTORY
CMAKE_BUILD_TYPE
CMAKE_C_COMPILER_LAUNCHER
CMAKE_CXX_COMPILER_LAUNCHER
CMAKE_FIND_ROOT_PATH
CMAKE_OSX_DEPLOYMENT_TARGET
CMAKE_TOOLCHAIN_FILE
DEPLOYMENT_TARGET
PLATFORM
)
set(${outVar} "")
foreach(var ${VARIABLES_TO_PROPAGATE})
if(DEFINED ${var})
list(APPEND ${outVar} -D "${var}=${${var}}")
endif()
endforeach()
set(${outVar}
${${outVar}}
PARENT_SCOPE
)
endfunction()
16 changes: 8 additions & 8 deletions tools/cmake/executorch-config.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,9 @@ if(TARGET coremldelegate)
endif()

if(TARGET etdump)
set_target_properties(etdump PROPERTIES INTERFACE_LINK_LIBRARIES "flatccrt;executorch")
set_target_properties(
etdump PROPERTIES INTERFACE_LINK_LIBRARIES "flatccrt;executorch"
)
endif()

if(TARGET optimized_native_cpu_ops_lib)
Expand All @@ -174,13 +176,11 @@ if(TARGET extension_threadpool)
endif()

set(shared_lib_list
# executorch -- size tests fail due to regression if we include this and I'm not sure it's needed.
optimized_native_cpu_ops_lib
portable_ops_lib
quantized_ops_lib
xnnpack_backend
vulkan_backend
quantized_ops_aot_lib)
# executorch -- size tests fail due to regression if we include this and I'm
# not sure it's needed.
optimized_native_cpu_ops_lib portable_ops_lib quantized_ops_lib
xnnpack_backend vulkan_backend quantized_ops_aot_lib
)
foreach(lib ${shared_lib_list})
if(TARGET ${lib})
target_link_options_shared_lib(${lib})
Expand Down
Loading