Skip to content
Open
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
55 changes: 54 additions & 1 deletion examples/selective_build/test_selective_build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ test_cmake_select_ops_in_model() {
# the .pte via gen_selected_max_kernel_num().
retry cmake -DCMAKE_BUILD_TYPE="$CMAKE_BUILD_TYPE" \
-DEXECUTORCH_SELECT_OPS_MODEL="./${model_export_name}" \
-DEXECUTORCH_DTYPE_SELECTIVE_BUILD=ON \
-DEXECUTORCH_ENABLE_DTYPE_SELECTIVE_BUILD=ON \
-DEXECUTORCH_OPTIMIZE_SIZE=ON \
-DCMAKE_INSTALL_PREFIX=cmake-out \
-DPYTHON_EXECUTABLE="$PYTHON_EXECUTABLE" \
Expand All @@ -171,6 +171,58 @@ test_cmake_select_ops_in_model() {
|| { echo "ERROR: header missing expected define"; exit 1; }
echo "Generated: $(cat ${generated_header} | tail -1)"

echo "Verifying dtype-selective variant header was generated"
local generated_variant_header
generated_variant_header=$(find "${build_dir}" -name selected_op_variants.h -print -quit)
if [[ -z "${generated_variant_header}" ]]; then
echo "ERROR: selected_op_variants.h not generated"
exit 1
fi

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

echo "Removing ${model_export_name}"
rm "./${model_export_name}"
}

test_cmake_select_ops_in_model_and_list() {
local model_name="add_mul"
local model_export_name="${model_name}.pte"
echo "Exporting ${model_name}"
${PYTHON_EXECUTABLE} -m examples.portable.scripts.export --model_name="${model_name}"
local example_dir=examples/selective_build/basic
local build_dir=cmake-out/${example_dir}_combined
rm -rf ${build_dir}
retry cmake -DCMAKE_BUILD_TYPE="$CMAKE_BUILD_TYPE" \
-DEXECUTORCH_SELECT_OPS_MODEL="./${model_export_name}" \
-DEXECUTORCH_SELECT_OPS_LIST="aten::relu.out" \
-DCMAKE_INSTALL_PREFIX=cmake-out \
-DPYTHON_EXECUTABLE="$PYTHON_EXECUTABLE" \
-B${build_dir} \
${example_dir}

echo "Building ${example_dir} with model and list selectors"
cmake --build ${build_dir} -j9 --config $CMAKE_BUILD_TYPE

echo "Verifying merged selected_operators.yaml contains both selector inputs"
local selected_operators_yaml=${build_dir}/executorch/executorch_selected_kernels/selected_operators.yaml
if [[ ! -f "${selected_operators_yaml}" ]]; then
echo "ERROR: selected_operators.yaml not generated"
exit 1
fi
${PYTHON_EXECUTABLE} - <<PY
import yaml

with open("${selected_operators_yaml}") as f:
ops = set(yaml.safe_load(f)["operators"].keys())

expected = {"aten::add.out", "aten::mm.out", "aten::relu.out"}
missing = expected - ops
if missing:
raise RuntimeError(f"Missing merged ops: {sorted(missing)}")
PY

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

Expand Down Expand Up @@ -199,6 +251,7 @@ then
test_cmake_select_ops_in_list
test_cmake_select_ops_in_yaml
test_cmake_select_ops_in_model
test_cmake_select_ops_in_model_and_list
elif [[ $1 == "buck2" ]];
then
test_buck2_select_all_ops
Expand Down
6 changes: 6 additions & 0 deletions tools/cmake/Codegen.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,12 @@ function(gen_operators_lib)
selected_portable_kernels PRIVATE EXECUTORCH_SELECTIVE_BUILD_DTYPE=1
)

install(
TARGETS selected_kernels_util_all_deps selected_portable_kernels
EXPORT ExecuTorchTargets
DESTINATION ${CMAKE_INSTALL_LIBDIR}
)

target_link_libraries(${GEN_LIB_NAME} PUBLIC selected_portable_kernels)
else()
message(
Expand Down
73 changes: 69 additions & 4 deletions tools/cmake/common/preset.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -117,12 +117,75 @@ macro(load_build_preset)
endmacro()

# Check if the required options are set.
function(is_option_enabled NAME OUT_VAR)
if(NOT DEFINED ${NAME} AND NOT DEFINED CACHE{${NAME}})
set(${OUT_VAR}
FALSE
PARENT_SCOPE
)
return()
endif()

get_property(
_option_type_set
CACHE ${NAME}
PROPERTY TYPE
SET
)
if(_option_type_set)
get_property(
_option_type
CACHE ${NAME}
PROPERTY TYPE
)
if("${_option_type}" STREQUAL "BOOL")
if(${NAME})
set(${OUT_VAR}
TRUE
PARENT_SCOPE
)
else()
set(${OUT_VAR}
FALSE
PARENT_SCOPE
)
endif()
else()
if(NOT "${${NAME}}" STREQUAL "")
set(${OUT_VAR}
TRUE
PARENT_SCOPE
)
else()
set(${OUT_VAR}
FALSE
PARENT_SCOPE
)
endif()
endif()
else()
if("${${NAME}}")
set(${OUT_VAR}
TRUE
PARENT_SCOPE
)
else()
set(${OUT_VAR}
FALSE
PARENT_SCOPE
)
endif()
endif()
endfunction()

function(check_required_options_on)
cmake_parse_arguments(ARG "" "IF_ON" "REQUIRES" ${ARGN})

if(${${ARG_IF_ON}})
is_option_enabled(${ARG_IF_ON} _if_on)
if(_if_on)
foreach(required ${ARG_REQUIRES})
if(NOT ${${required}})
is_option_enabled(${required} _required_on)
if(NOT _required_on)
message(FATAL_ERROR "Use of '${ARG_IF_ON}' requires '${required}'")
endif()
endforeach()
Expand All @@ -133,9 +196,11 @@ endfunction()
function(check_conflicting_options_on)
cmake_parse_arguments(ARG "" "IF_ON" "CONFLICTS_WITH" ${ARGN})

if(${${ARG_IF_ON}})
is_option_enabled(${ARG_IF_ON} _if_on)
if(_if_on)
foreach(conflict ${ARG_CONFLICTS_WITH})
if(${${conflict}})
is_option_enabled(${conflict} _conflict_on)
if(_conflict_on)
message(FATAL_ERROR "Both '${ARG_IF_ON}' and '${conflict}' can't be ON")
endif()
endforeach()
Expand Down
12 changes: 3 additions & 9 deletions tools/cmake/preset/default.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -423,15 +423,9 @@ check_conflicting_options_on(
EXECUTORCH_BUILD_PTHREADPOOL EXECUTORCH_BUILD_CPUINFO
)

# Selective build specifiers are mutually exclusive.
check_conflicting_options_on(
IF_ON EXECUTORCH_SELECT_OPS_YAML CONFLICTS_WITH EXECUTORCH_SELECT_OPS_LIST
EXECUTORCH_SELECT_OPS_MODEL
)

check_conflicting_options_on(
IF_ON EXECUTORCH_SELECT_OPS_LIST CONFLICTS_WITH EXECUTORCH_SELECT_OPS_MODEL
)
# Legacy selective build selectors are intentionally allowed to compose.
# This matches gen_oplist.py, which merges list, YAML, and model inputs into
# one selected_operators.yaml file.

check_required_options_on(
IF_ON EXECUTORCH_BUILD_WASM REQUIRES EXECUTORCH_BUILD_EXTENSION_MODULE
Expand Down
Loading