Skip to content
Draft
Show file tree
Hide file tree
Changes from all 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
175 changes: 88 additions & 87 deletions examples/selective_build/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -37,111 +37,112 @@ set(_common_compile_options -Wno-deprecated-declarations -fPIC
-ffunction-sections -fdata-sections
)

# Let files say "include <executorch/path/to/header.h>".
set(_common_include_directories ${EXECUTORCH_ROOT}/..)

find_package(executorch CONFIG REQUIRED)
find_package(
gflags REQUIRED PATHS ${CMAKE_CURRENT_BINARY_DIR}/../../third-party
)

target_include_directories(
executorch_core INTERFACE ${_common_include_directories}
)
add_subdirectory(${EXECUTORCH_ROOT} ${CMAKE_CURRENT_BINARY_DIR}/executorch)

# ------------------------------ OPTIONS BEGIN -------------------------------

# Option to register ops from yaml file
option(EXECUTORCH_SELECT_OPS_YAML "Register all the ops from a given yaml file"
OFF
# Selective build options.
option(EXECUTORCH_EXAMPLE_SELECT_ALL_OPS
"Whether to register all ops defined in portable kernel library." OFF
)

# Option to register op list
option(EXECUTORCH_SELECT_OPS_LIST "Register a list of ops, separated by comma"
OFF
option(
EXECUTORCH_EXAMPLE_DEFINE_CUSTOM_TARGET
"Whether to define a custom operator target for advanced use cases. If false, the top-level executorch_kernels target is linked."
OFF
)

# Selective build options.
option(EXECUTORCH_SELECT_ALL_OPS
"Whether to register all ops defined in portable kernel library." OFF
option(
EXECUTORCH_EXAMPLE_USE_CUSTOM_OPS
"Whether to include custom ops in the example."
OFF
)

# Option to enable parsing ops and dtypes directly from model pte file
option(EXECUTORCH_SELECT_OPS_FROM_MODEL
"Enable op selection from pte during build." OFF
)
# Note that the following options are defined by the core framework and are also
# used by this example when defining a custom operator target:
#
# EXECUTORCH_SELECT_OPS_YAML EXECUTORCH_SELECT_OPS_LIST
# EXECUTORCH_SELECT_OPS_MODEL EXECUTORCH_DTYPE_SELECTIVE_BUILD

# Option to enable dtype selective build. Note: must be using selective build
# model API.
option(EXECUTORCH_DTYPE_SELECTIVE_BUILD "Enable dtype selective build." OFF)
# ------------------------------- OPTIONS END --------------------------------

#
# The `_<target>_srcs` lists are defined by executorch_load_build_variables.
#
executorch_load_build_variables()

#
# select_build_lib: C++ library to register selected ops in custom kernel
# library
#
set(_kernel_lib)
if(EXECUTORCH_SELECT_OPS_YAML)
set(_custom_ops_yaml
${EXECUTORCH_ROOT}/examples/portable/custom_ops/custom_ops.yaml
)
set(kernel_sources
${EXECUTORCH_ROOT}/examples/portable/custom_ops/custom_ops_1_out.cpp
${EXECUTORCH_ROOT}/examples/portable/custom_ops/custom_ops_2_out.cpp
if(NOT EXECUTORCH_EXAMPLE_DEFINE_CUSTOM_TARGET)
# For standard use cases, we can configure the ExecuTorch kernel library build
# using the EXECUTORCH_SELECT_OPS_* variables. This will reflect in the
# executorch_kernels target, which includes the configured kernel libraries,
# including selective build, where supported.

set(selected_kernel_target executorch_kernels)
else() # EXECUTORCH_EXAMPLE_DEFINE_CUSTOM_TARGET
# For advanced use cases, we can define a custom operator target. This is
# useful when using custom operators.
set(_kernel_lib)

if(EXECUTORCH_EXAMPLE_USE_CUSTOM_OPS)
set(_custom_ops_yaml
${EXECUTORCH_ROOT}/examples/portable/custom_ops/custom_ops.yaml
)
set(kernel_sources
${EXECUTORCH_ROOT}/examples/portable/custom_ops/custom_ops_1_out.cpp
${EXECUTORCH_ROOT}/examples/portable/custom_ops/custom_ops_2_out.cpp
)
#
# custom_kernels: C++ kernel implementations of custom ops
#
add_library(custom_kernels ${kernel_sources})
target_link_libraries(custom_kernels PRIVATE executorch_core)
target_compile_options(custom_kernels PUBLIC ${_common_compile_options})

list(APPEND _kernel_lib custom_kernels)
else()
list(APPEND _kernel_lib portable_kernels)
endif()

gen_selected_ops(
LIB_NAME
"select_build_lib"
OPS_SCHEMA_YAML
"${_custom_ops_yaml}"
ROOT_OPS
"${EXECUTORCH_SELECT_OPS_LIST}"
INCLUDE_ALL_OPS
"${EXECUTORCH_SELECT_ALL_OPS}"
OPS_FROM_MODEL
"${EXECUTORCH_SELECT_OPS_MODEL}"
DTYPE_SELECTIVE_BUILD
"${EXECUTORCH_DTYPE_SELECTIVE_BUILD}"
)
#
# custom_kernels: C++ kernel implementations of custom ops
#
add_library(custom_kernels ${kernel_sources})
target_link_libraries(custom_kernels PRIVATE executorch_core)
target_compile_options(custom_kernels PUBLIC ${_common_compile_options})

list(APPEND _kernel_lib custom_kernels)
else()
list(APPEND _kernel_lib portable_kernels)
endif()

gen_selected_ops(
LIB_NAME
"select_build_lib"
OPS_SCHEMA_YAML
"${_custom_ops_yaml}"
ROOT_OPS
"${EXECUTORCH_SELECT_OPS_LIST}"
INCLUDE_ALL_OPS
"${EXECUTORCH_SELECT_ALL_OPS}"
OPS_FROM_MODEL
"${EXECUTORCH_SELECT_OPS_FROM_MODEL}"
DTYPE_SELECTIVE_BUILD
"${EXECUTORCH_DTYPE_SELECTIVE_BUILD}"
)
generate_bindings_for_kernels(
LIB_NAME
"select_build_lib"
FUNCTIONS_YAML
${EXECUTORCH_ROOT}/kernels/portable/functions.yaml
CUSTOM_OPS_YAML
"${_custom_ops_yaml}"
DTYPE_SELECTIVE_BUILD
"${EXECUTORCH_DTYPE_SELECTIVE_BUILD}"
)

generate_bindings_for_kernels(
LIB_NAME
"select_build_lib"
FUNCTIONS_YAML
${EXECUTORCH_ROOT}/kernels/portable/functions.yaml
CUSTOM_OPS_YAML
"${_custom_ops_yaml}"
DTYPE_SELECTIVE_BUILD
"${EXECUTORCH_DTYPE_SELECTIVE_BUILD}"
)
gen_operators_lib(
LIB_NAME
"select_build_lib"
KERNEL_LIBS
${_kernel_lib}
DEPS
executorch_core
DTYPE_SELECTIVE_BUILD
"${EXECUTORCH_DTYPE_SELECTIVE_BUILD}"
)

gen_operators_lib(
LIB_NAME
"select_build_lib"
KERNEL_LIBS
${_kernel_lib}
DEPS
executorch_core
DTYPE_SELECTIVE_BUILD
"${EXECUTORCH_DTYPE_SELECTIVE_BUILD}"
)
executorch_target_link_options_shared_lib(select_build_lib)
set(selected_kernel_target select_build_lib)
endif()

list(TRANSFORM _executor_runner__srcs PREPEND "${EXECUTORCH_ROOT}/")

Expand All @@ -154,8 +155,8 @@ if(NOT CMAKE_BUILD_TYPE STREQUAL "Debug")
target_link_options_gc_sections(selective_build_test)
endif()
target_link_libraries(
selective_build_test PRIVATE executorch_core extension_evalue_util
extension_runner_util gflags select_build_lib
selective_build_test
PRIVATE executorch_core extension_evalue_util extension_runner_util
gflags::gflags ${selected_kernel_target}
)
executorch_target_link_options_shared_lib(select_build_lib)
target_compile_options(selective_build_test PUBLIC ${_common_compile_options})
8 changes: 5 additions & 3 deletions examples/selective_build/README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Selective Build Examples
To optimize binary size of ExecuTorch runtime, selective build can be used. This folder contains examples to select only the operators needed for ExecuTorch build. This example will demonstrate the CMake build.
To optimize binary size of ExecuTorch runtime, selective build can be used. This folder contains examples to select only the operators needed for ExecuTorch build.

These examples showcase two flows - the simple way, using CMake options to configure the framework build, and an advanced flow - showcasing user-defined kernel targets including custom operators.

## How to run

Expand All @@ -16,8 +18,8 @@ Check out `CMakeLists.txt` for demo of selective build APIs:
1. `SELECT_ALL_OPS`: Select all ops from the dependency kernel libraries, register all of them into ExecuTorch runtime.
2. `SELECT_OPS_LIST`: Only select operators from a list.
3. `SELECT_OPS_YAML`: Only select operators from a yaml file.
4. `SELECT_OPS_FROM_MODEL`: Only select operators from a from an exported model pte.
5. `DTYPE_SELECTIVE_BUILD`: Enable rebuild of `portable_kernels` to use dtype selection. Currently only supported for `SELECTED_OPS_FROM_MODEL` API and `portable_kernels` lib.
4. `SELECT_OPS_MODEL`: Only select operators from a from an exported model pte.
5. `DTYPE_SELECTIVE_BUILD`: Enable rebuild of `portable_kernels` to use dtype selection. Currently only supported for `SELECTED_OPS_MODEL` API and `portable_kernels` lib.

Other configs:
- `MAX_KERNEL_NUM=N`: Only allocate memory for N operators.
30 changes: 3 additions & 27 deletions examples/selective_build/test_selective_build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -85,30 +85,6 @@ test_buck2_select_ops_from_yaml() {
}

# CMake examples; test in OSS. Check the README for more information.
test_cmake_select_all_ops() {
echo "Exporting MobilenetV3"
${PYTHON_EXECUTABLE} -m examples.portable.scripts.export --model_name="mv3"

local example_dir=examples/selective_build
local build_dir=cmake-out/${example_dir}
rm -rf ${build_dir}
retry cmake -DCMAKE_BUILD_TYPE=Release \
-DEXECUTORCH_SELECT_ALL_OPS=ON \
-DCMAKE_INSTALL_PREFIX=cmake-out \
-DPYTHON_EXECUTABLE="$PYTHON_EXECUTABLE" \
-B${build_dir} \
${example_dir}

echo "Building ${example_dir}"
cmake --build ${build_dir} -j9 --config Release

echo 'Running selective build test'
${build_dir}/selective_build_test --model_path="./mv3.pte"

echo "Removing mv3.pte"
rm "./mv3.pte"
}

test_cmake_select_ops_in_list() {
echo "Exporting MobilenetV2"
${PYTHON_EXECUTABLE} -m examples.portable.scripts.export --model_name="mv2"
Expand Down Expand Up @@ -145,7 +121,8 @@ test_cmake_select_ops_in_yaml() {
local build_dir=cmake-out/${example_dir}
rm -rf ${build_dir}
retry cmake -DCMAKE_BUILD_TYPE=Release \
-DEXECUTORCH_SELECT_OPS_YAML=ON \
-DEXECUTORCH_EXAMPLE_USE_CUSTOM_OPS=ON \
-DEXECUTORCH_EXAMPLE_DEFINE_CUSTOM_TARGET=ON \
-DCMAKE_INSTALL_PREFIX=cmake-out \
-DPYTHON_EXECUTABLE="$PYTHON_EXECUTABLE" \
-B${build_dir} \
Expand All @@ -170,7 +147,7 @@ test_cmake_select_ops_in_model() {
local build_dir=cmake-out/${example_dir}
rm -rf ${build_dir}
retry cmake -DCMAKE_BUILD_TYPE="$CMAKE_BUILD_TYPE" \
-DEXECUTORCH_SELECT_OPS_FROM_MODEL="./${model_export_name}" \
-DEXECUTORCH_SELECT_OPS_MODEL="./${model_export_name}" \
-DEXECUTORCH_DTYPE_SELECTIVE_BUILD=ON \
-DEXECUTORCH_OPTIMIZE_SIZE=ON \
-DCMAKE_INSTALL_PREFIX=cmake-out \
Expand Down Expand Up @@ -206,7 +183,6 @@ fi
if [[ $1 == "cmake" ]];
then
cmake_install_executorch_lib $CMAKE_BUILD_TYPE
test_cmake_select_all_ops
test_cmake_select_ops_in_list
test_cmake_select_ops_in_yaml
test_cmake_select_ops_in_model
Expand Down
Loading