From 20f3347c6b7b7323e5c5be5d0b217301c61a3b9c Mon Sep 17 00:00:00 2001 From: BujSet Date: Thu, 12 Jun 2025 11:46:27 -0700 Subject: [PATCH 1/3] Manual command works, but not in cmake, need to figure out why --- examples/selective_build/CMakeLists.txt | 24 ++++++- .../selective_build/test_selective_build.sh | 31 ++++++++- tools/cmake/Codegen.cmake | 66 ++++++++++++++++--- 3 files changed, 105 insertions(+), 16 deletions(-) diff --git a/examples/selective_build/CMakeLists.txt b/examples/selective_build/CMakeLists.txt index a37b4362d78..1d7670418e1 100644 --- a/examples/selective_build/CMakeLists.txt +++ b/examples/selective_build/CMakeLists.txt @@ -61,6 +61,10 @@ option(EXECUTORCH_SELECT_OPS_LIST "Register a list of ops, separated by comma" option(EXECUTORCH_SELECT_ALL_OPS "Whether to register all ops defined in portable kernel library." OFF ) + +# Option to enable dtype header generation during selective build process +option(EXECUTORCH_DTYPE_GEN_HEADER "Enable dtype header generation during selection during build." OFF +) # ------------------------------- OPTIONS END -------------------------------- # @@ -108,16 +112,30 @@ gen_selected_ops( "${EXECUTORCH_SELECT_OPS_LIST}" INCLUDE_ALL_OPS "${EXECUTORCH_SELECT_ALL_OPS}" + DTYPE_HEADER + "${EXECUTORCH_DTYPE_GEN_HEADER}" ) generate_bindings_for_kernels( - LIB_NAME "select_build_lib" FUNCTIONS_YAML - ${EXECUTORCH_ROOT}/kernels/portable/functions.yaml CUSTOM_OPS_YAML + LIB_NAME + "select_build_lib" + FUNCTIONS_YAML + ${EXECUTORCH_ROOT}/kernels/portable/functions.yaml + CUSTOM_OPS_YAML "${_custom_ops_yaml}" + DTYPE_HEADER + "${EXECUTORCH_DTYPE_GEN_HEADER}" ) gen_operators_lib( - LIB_NAME "select_build_lib" KERNEL_LIBS ${_kernel_lib} DEPS executorch_core + LIB_NAME + "select_build_lib" + KERNEL_LIBS + ${_kernel_lib} + DEPS + executorch_core + DTYPE_HEADER + "${EXECUTORCH_DTYPE_GEN_HEADER}" ) list(TRANSFORM _executor_runner__srcs PREPEND "${EXECUTORCH_ROOT}/") diff --git a/examples/selective_build/test_selective_build.sh b/examples/selective_build/test_selective_build.sh index 324a4fe27a5..5cb2444c53b 100644 --- a/examples/selective_build/test_selective_build.sh +++ b/examples/selective_build/test_selective_build.sh @@ -161,6 +161,30 @@ test_cmake_select_ops_in_yaml() { rm "./custom_ops_1.pte" } +test_cmake_select_ops_in_yaml_gen_dtype_header() { + echo "Exporting custom_op_1" + ${PYTHON_EXECUTABLE} -m examples.portable.custom_ops.custom_ops_1 + 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_OPS_YAML=ON \ + -DEXECUTORCH_DTYPE_GEN_HEADER=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="./custom_ops_1.pte" + + echo "Removing custom_ops_1.pte" + rm "./custom_ops_1.pte" +} + if [[ -z $BUCK ]]; then BUCK=buck2 @@ -174,9 +198,10 @@ fi if [[ $1 == "cmake" ]]; then cmake_install_executorch_lib - test_cmake_select_all_ops - test_cmake_select_ops_in_list - test_cmake_select_ops_in_yaml +# test_cmake_select_all_ops +# test_cmake_select_ops_in_list +# test_cmake_select_ops_in_yaml + test_cmake_select_ops_in_yaml_gen_dtype_header elif [[ $1 == "buck2" ]]; then test_buck2_select_all_ops diff --git a/tools/cmake/Codegen.cmake b/tools/cmake/Codegen.cmake index f1dac84de43..17c8e654f4a 100644 --- a/tools/cmake/Codegen.cmake +++ b/tools/cmake/Codegen.cmake @@ -12,7 +12,7 @@ include(${EXECUTORCH_ROOT}/tools/cmake/Utils.cmake) function(gen_selected_ops) - set(arg_names LIB_NAME OPS_SCHEMA_YAML ROOT_OPS INCLUDE_ALL_OPS) + set(arg_names LIB_NAME OPS_SCHEMA_YAML ROOT_OPS INCLUDE_ALL_OPS DTYPE_HEADER) cmake_parse_arguments(GEN "" "" "${arg_names}" ${ARGN}) message(STATUS "Generating operator lib:") @@ -20,10 +20,12 @@ function(gen_selected_ops) message(STATUS " OPS_SCHEMA_YAML: ${GEN_OPS_SCHEMA_YAML}") message(STATUS " ROOT_OPS: ${GEN_ROOT_OPS}") message(STATUS " INCLUDE_ALL_OPS: ${GEN_INCLUDE_ALL_OPS}") + message(STATUS " DTYPE_HEADER: ${GEN_DTYPE_HEADER}") set(_oplist_yaml ${CMAKE_CURRENT_BINARY_DIR}/${GEN_LIB_NAME}/selected_operators.yaml ) + file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${GEN_LIB_NAME}) file(GLOB_RECURSE _codegen_tools_srcs "${EXECUTORCH_ROOT}/codegen/tools/*.py") @@ -53,6 +55,23 @@ function(gen_selected_ops) WORKING_DIRECTORY ${EXECUTORCH_ROOT} ) + if(GEN_DTYPE_HEADER) + set(_opvariant_h + ${CMAKE_CURRENT_BINARY_DIR}/${GEN_LIB_NAME}/selected_op_variants.h + ) + set(_gen_opvariant_command "${PYTHON_EXECUTABLE}" -m codegen.tools.gen_selected_op_variants + --yaml-file=${_oplist_yaml} + --output-dir=${CMAKE_CURRENT_BINARY_DIR}/${GEN_LIB_NAME}/ + ) + message("Command - ${_gen_opvariant_command}") + add_custom_command( + COMMENT "Generating selected_op_variants.h for ${GEN_LIB_NAME}" + OUTPUT ${_opvariant_h} + COMMAND ${_gen_opvariant_command} + DEPENDS ${_optlist_yaml} ${_codegen_tools_srcs} + WORKING_DIRECTORY ${EXECUTORCH_ROOT} + ) + endif() endfunction() # Codegen for registering kernels. Kernels are defined in functions_yaml and @@ -62,7 +81,7 @@ endfunction() # functions_yaml CUSTOM_OPS_YAML custom_ops_yaml ) function(generate_bindings_for_kernels) set(options ADD_EXCEPTION_BOUNDARY) - set(arg_names LIB_NAME FUNCTIONS_YAML CUSTOM_OPS_YAML) + set(arg_names LIB_NAME FUNCTIONS_YAML CUSTOM_OPS_YAML DTYPE_HEADER) cmake_parse_arguments(GEN "${options}" "${arg_names}" "" ${ARGN}) message(STATUS "Generating kernel bindings:") @@ -70,6 +89,7 @@ function(generate_bindings_for_kernels) message(STATUS " FUNCTIONS_YAML: ${GEN_FUNCTIONS_YAML}") message(STATUS " CUSTOM_OPS_YAML: ${GEN_CUSTOM_OPS_YAML}") message(STATUS " ADD_EXCEPTION_BOUNDARY: ${GEN_ADD_EXCEPTION_BOUNDARY}") + message(STATUS " DTYPE_HEADER: ${GEN_DTYPE_HEADER}") # Command to generate selected_operators.yaml from custom_ops.yaml. file(GLOB_RECURSE _codegen_templates "${EXECUTORCH_ROOT}/codegen/templates/*") @@ -78,6 +98,13 @@ function(generate_bindings_for_kernels) # By default selective build output is selected_operators.yaml set(_oplist_yaml ${_out_dir}/selected_operators.yaml) + # If dtype selective build is enable, force header file to be preserved + if(GEN_DTYPE_HEADER) + set(_opvariant_h ${_out_dir}/selected_op_variants.h) + else() + set(_opvariant_h "") + endif() + # Command to codegen C++ wrappers to register custom ops to both PyTorch and # Executorch runtime. execute_process( @@ -108,6 +135,10 @@ function(generate_bindings_for_kernels) ${_out_dir}/Functions.h ${_out_dir}/NativeFunctions.h ) + if(GEN_DTYPE_HEADER) + list(APPEND _gen_command_sources ${_out_dir}/selected_op_variants.h) + endif() + if(GEN_FUNCTIONS_YAML) list(APPEND _gen_command --functions-yaml-path=${GEN_FUNCTIONS_YAML}) endif() @@ -122,8 +153,9 @@ function(generate_bindings_for_kernels) COMMENT "Generating code for kernel registration" OUTPUT ${_gen_command_sources} COMMAND ${_gen_command} - DEPENDS ${_oplist_yaml} ${GEN_CUSTOM_OPS_YAML} ${GEN_FUNCTIONS_YAML} - ${_codegen_templates} ${_torchgen_srcs} + DEPENDS ${_oplist_yaml} ${_opvariants_h} ${GEN_CUSTOM_OPS_YAML} + ${GEN_FUNCTIONS_YAML} ${_codegen_templates} + ${_torchgen_srcs} WORKING_DIRECTORY ${EXECUTORCH_ROOT} ) # Make generated file list available in parent scope @@ -165,22 +197,33 @@ endfunction() # Generate a runtime lib for registering operators in Executorch function(gen_operators_lib) - set(multi_arg_names LIB_NAME KERNEL_LIBS DEPS) + set(multi_arg_names LIB_NAME KERNEL_LIBS DEPS DTYPE_HEADER) cmake_parse_arguments(GEN "" "" "${multi_arg_names}" ${ARGN}) message(STATUS "Generating operator lib:") message(STATUS " LIB_NAME: ${GEN_LIB_NAME}") message(STATUS " KERNEL_LIBS: ${GEN_KERNEL_LIBS}") message(STATUS " DEPS: ${GEN_DEPS}") + message(STATUS " DTYPE_HEADER: ${GEN_HEADER}") set(_out_dir ${CMAKE_CURRENT_BINARY_DIR}/${GEN_LIB_NAME}) add_library(${GEN_LIB_NAME}) - target_sources( - ${GEN_LIB_NAME} - PRIVATE ${_out_dir}/RegisterCodegenUnboxedKernelsEverything.cpp - ${_out_dir}/Functions.h ${_out_dir}/NativeFunctions.h - ) + if(GEN_DTYPE_SELECT) + target_sources( + ${GEN_LIB_NAME} + PRIVATE ${_out_dir}/RegisterCodegenUnboxedKernelsEverything.cpp + ${_out_dir}/Functions.h ${_out_dir}/NativeFunctions.h + ${_out_dir}/selected_op_variants.h + ) + else() + target_sources( + ${GEN_LIB_NAME} + PRIVATE ${_out_dir}/RegisterCodegenUnboxedKernelsEverything.cpp + ${_out_dir}/Functions.h ${_out_dir}/NativeFunctions.h + ) + endif() + target_link_libraries(${GEN_LIB_NAME} PRIVATE ${GEN_DEPS}) if(GEN_KERNEL_LIBS) target_link_libraries(${GEN_LIB_NAME} PUBLIC ${GEN_KERNEL_LIBS}) @@ -188,6 +231,9 @@ function(gen_operators_lib) target_link_options_shared_lib(${GEN_LIB_NAME}) set(_generated_headers ${_out_dir}/Functions.h ${_out_dir}/NativeFunctions.h) + if(GEN_DTYPE_SELECT) + list(APPEND _generated_headers ${_out_dir}/selected_op_variants.h) + endif() set_target_properties( ${GEN_LIB_NAME} PROPERTIES PUBLIC_HEADER "${_generated_headers}" ) From 9bed555bacf61e88d9068720b6ecf56d1796f16f Mon Sep 17 00:00:00 2001 From: BujSet Date: Thu, 12 Jun 2025 14:12:54 -0700 Subject: [PATCH 2/3] Fix minor typos --- tools/cmake/Codegen.cmake | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tools/cmake/Codegen.cmake b/tools/cmake/Codegen.cmake index 17c8e654f4a..24fd9c52c2e 100644 --- a/tools/cmake/Codegen.cmake +++ b/tools/cmake/Codegen.cmake @@ -15,7 +15,7 @@ function(gen_selected_ops) set(arg_names LIB_NAME OPS_SCHEMA_YAML ROOT_OPS INCLUDE_ALL_OPS DTYPE_HEADER) cmake_parse_arguments(GEN "" "" "${arg_names}" ${ARGN}) - message(STATUS "Generating operator lib:") + message(STATUS "Generating selected operator lib:") message(STATUS " LIB_NAME: ${GEN_LIB_NAME}") message(STATUS " OPS_SCHEMA_YAML: ${GEN_OPS_SCHEMA_YAML}") message(STATUS " ROOT_OPS: ${GEN_ROOT_OPS}") @@ -204,12 +204,12 @@ function(gen_operators_lib) message(STATUS " LIB_NAME: ${GEN_LIB_NAME}") message(STATUS " KERNEL_LIBS: ${GEN_KERNEL_LIBS}") message(STATUS " DEPS: ${GEN_DEPS}") - message(STATUS " DTYPE_HEADER: ${GEN_HEADER}") + message(STATUS " DTYPE_HEADER: ${GEN_DTYPE_HEADER}") set(_out_dir ${CMAKE_CURRENT_BINARY_DIR}/${GEN_LIB_NAME}) add_library(${GEN_LIB_NAME}) - if(GEN_DTYPE_SELECT) + if(GEN_DTYPE_HEADER) target_sources( ${GEN_LIB_NAME} PRIVATE ${_out_dir}/RegisterCodegenUnboxedKernelsEverything.cpp @@ -231,7 +231,7 @@ function(gen_operators_lib) target_link_options_shared_lib(${GEN_LIB_NAME}) set(_generated_headers ${_out_dir}/Functions.h ${_out_dir}/NativeFunctions.h) - if(GEN_DTYPE_SELECT) + if(GEN_DTYPE_HEADER) list(APPEND _generated_headers ${_out_dir}/selected_op_variants.h) endif() set_target_properties( From 70a92b310485029987d5adeda5e4135bfaaa7250 Mon Sep 17 00:00:00 2001 From: BujSet Date: Thu, 12 Jun 2025 14:19:15 -0700 Subject: [PATCH 3/3] Minor comment changes --- examples/selective_build/test_selective_build.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/selective_build/test_selective_build.sh b/examples/selective_build/test_selective_build.sh index 5cb2444c53b..3d206bd5e15 100644 --- a/examples/selective_build/test_selective_build.sh +++ b/examples/selective_build/test_selective_build.sh @@ -198,9 +198,9 @@ fi if [[ $1 == "cmake" ]]; then cmake_install_executorch_lib -# test_cmake_select_all_ops -# test_cmake_select_ops_in_list -# test_cmake_select_ops_in_yaml + test_cmake_select_all_ops + test_cmake_select_ops_in_list + test_cmake_select_ops_in_yaml test_cmake_select_ops_in_yaml_gen_dtype_header elif [[ $1 == "buck2" ]]; then