1*523fa7a6SAndroid Build Coastguard Worker# Copyright (c) Meta Platforms, Inc. and affiliates. 2*523fa7a6SAndroid Build Coastguard Worker# All rights reserved. 3*523fa7a6SAndroid Build Coastguard Worker# 4*523fa7a6SAndroid Build Coastguard Worker# This source code is licensed under the BSD-style license found in the 5*523fa7a6SAndroid Build Coastguard Worker# LICENSE file in the root directory of this source tree. 6*523fa7a6SAndroid Build Coastguard Worker 7*523fa7a6SAndroid Build Coastguard Worker# This file contains util functions to generate code for kernel registration for 8*523fa7a6SAndroid Build Coastguard Worker# both AOT and runtime. 9*523fa7a6SAndroid Build Coastguard Worker 10*523fa7a6SAndroid Build Coastguard Worker# Selective build. See codegen/tools/gen_oplist.py for how to use these 11*523fa7a6SAndroid Build Coastguard Worker# arguments. 12*523fa7a6SAndroid Build Coastguard Workerfunction(gen_selected_ops) 13*523fa7a6SAndroid Build Coastguard Worker set(arg_names LIB_NAME OPS_SCHEMA_YAML ROOT_OPS INCLUDE_ALL_OPS) 14*523fa7a6SAndroid Build Coastguard Worker cmake_parse_arguments(GEN "" "" "${arg_names}" ${ARGN}) 15*523fa7a6SAndroid Build Coastguard Worker 16*523fa7a6SAndroid Build Coastguard Worker message(STATUS "Generating operator lib:") 17*523fa7a6SAndroid Build Coastguard Worker message(STATUS " LIB_NAME: ${GEN_LIB_NAME}") 18*523fa7a6SAndroid Build Coastguard Worker message(STATUS " OPS_SCHEMA_YAML: ${GEN_OPS_SCHEMA_YAML}") 19*523fa7a6SAndroid Build Coastguard Worker message(STATUS " ROOT_OPS: ${GEN_ROOT_OPS}") 20*523fa7a6SAndroid Build Coastguard Worker message(STATUS " INCLUDE_ALL_OPS: ${GEN_INCLUDE_ALL_OPS}") 21*523fa7a6SAndroid Build Coastguard Worker 22*523fa7a6SAndroid Build Coastguard Worker set(_oplist_yaml 23*523fa7a6SAndroid Build Coastguard Worker ${CMAKE_CURRENT_BINARY_DIR}/${GEN_LIB_NAME}/selected_operators.yaml 24*523fa7a6SAndroid Build Coastguard Worker ) 25*523fa7a6SAndroid Build Coastguard Worker file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${GEN_LIB_NAME}) 26*523fa7a6SAndroid Build Coastguard Worker 27*523fa7a6SAndroid Build Coastguard Worker file(GLOB_RECURSE _codegen_tools_srcs "${EXECUTORCH_ROOT}/codegen/tools/*.py") 28*523fa7a6SAndroid Build Coastguard Worker 29*523fa7a6SAndroid Build Coastguard Worker set(_gen_oplist_command "${PYTHON_EXECUTABLE}" -m codegen.tools.gen_oplist 30*523fa7a6SAndroid Build Coastguard Worker --output_path=${_oplist_yaml} 31*523fa7a6SAndroid Build Coastguard Worker ) 32*523fa7a6SAndroid Build Coastguard Worker 33*523fa7a6SAndroid Build Coastguard Worker if(GEN_OPS_SCHEMA_YAML) 34*523fa7a6SAndroid Build Coastguard Worker list(APPEND _gen_oplist_command 35*523fa7a6SAndroid Build Coastguard Worker --ops_schema_yaml_path="${GEN_OPS_SCHEMA_YAML}" 36*523fa7a6SAndroid Build Coastguard Worker ) 37*523fa7a6SAndroid Build Coastguard Worker endif() 38*523fa7a6SAndroid Build Coastguard Worker if(GEN_ROOT_OPS) 39*523fa7a6SAndroid Build Coastguard Worker list(APPEND _gen_oplist_command --root_ops="${GEN_ROOT_OPS}") 40*523fa7a6SAndroid Build Coastguard Worker endif() 41*523fa7a6SAndroid Build Coastguard Worker if(GEN_INCLUDE_ALL_OPS) 42*523fa7a6SAndroid Build Coastguard Worker list(APPEND _gen_oplist_command --include_all_operators) 43*523fa7a6SAndroid Build Coastguard Worker endif() 44*523fa7a6SAndroid Build Coastguard Worker 45*523fa7a6SAndroid Build Coastguard Worker message("Command - ${_gen_oplist_command}") 46*523fa7a6SAndroid Build Coastguard Worker add_custom_command( 47*523fa7a6SAndroid Build Coastguard Worker COMMENT "Generating selected_operators.yaml for ${GEN_LIB_NAME}" 48*523fa7a6SAndroid Build Coastguard Worker OUTPUT ${_oplist_yaml} 49*523fa7a6SAndroid Build Coastguard Worker COMMAND ${_gen_oplist_command} 50*523fa7a6SAndroid Build Coastguard Worker DEPENDS ${GEN_OPS_SCHEMA_YAML} ${_codegen_tools_srcs} 51*523fa7a6SAndroid Build Coastguard Worker WORKING_DIRECTORY ${EXECUTORCH_ROOT} 52*523fa7a6SAndroid Build Coastguard Worker ) 53*523fa7a6SAndroid Build Coastguard Worker 54*523fa7a6SAndroid Build Coastguard Workerendfunction() 55*523fa7a6SAndroid Build Coastguard Worker 56*523fa7a6SAndroid Build Coastguard Worker# Codegen for registering kernels. Kernels are defined in functions_yaml and 57*523fa7a6SAndroid Build Coastguard Worker# custom_ops_yaml. 58*523fa7a6SAndroid Build Coastguard Worker# 59*523fa7a6SAndroid Build Coastguard Worker# Invoked as generate_bindings_for_kernels( LIB_NAME lib_name FUNCTIONS_YAML 60*523fa7a6SAndroid Build Coastguard Worker# functions_yaml CUSTOM_OPS_YAML custom_ops_yaml ) 61*523fa7a6SAndroid Build Coastguard Workerfunction(generate_bindings_for_kernels) 62*523fa7a6SAndroid Build Coastguard Worker set(arg_names LIB_NAME FUNCTIONS_YAML CUSTOM_OPS_YAML) 63*523fa7a6SAndroid Build Coastguard Worker cmake_parse_arguments(GEN "" "${arg_names}" "" ${ARGN}) 64*523fa7a6SAndroid Build Coastguard Worker 65*523fa7a6SAndroid Build Coastguard Worker message(STATUS "Generating kernel bindings:") 66*523fa7a6SAndroid Build Coastguard Worker message(STATUS " LIB_NAME: ${GEN_LIB_NAME}") 67*523fa7a6SAndroid Build Coastguard Worker message(STATUS " FUNCTIONS_YAML: ${GEN_FUNCTIONS_YAML}") 68*523fa7a6SAndroid Build Coastguard Worker message(STATUS " CUSTOM_OPS_YAML: ${GEN_CUSTOM_OPS_YAML}") 69*523fa7a6SAndroid Build Coastguard Worker 70*523fa7a6SAndroid Build Coastguard Worker # Command to generate selected_operators.yaml from custom_ops.yaml. 71*523fa7a6SAndroid Build Coastguard Worker file(GLOB_RECURSE _codegen_templates "${EXECUTORCH_ROOT}/codegen/templates/*") 72*523fa7a6SAndroid Build Coastguard Worker 73*523fa7a6SAndroid Build Coastguard Worker set(_out_dir ${CMAKE_CURRENT_BINARY_DIR}/${GEN_LIB_NAME}) 74*523fa7a6SAndroid Build Coastguard Worker # By default selective build output is selected_operators.yaml 75*523fa7a6SAndroid Build Coastguard Worker set(_oplist_yaml ${_out_dir}/selected_operators.yaml) 76*523fa7a6SAndroid Build Coastguard Worker 77*523fa7a6SAndroid Build Coastguard Worker # Command to codegen C++ wrappers to register custom ops to both PyTorch and 78*523fa7a6SAndroid Build Coastguard Worker # Executorch runtime. 79*523fa7a6SAndroid Build Coastguard Worker execute_process( 80*523fa7a6SAndroid Build Coastguard Worker COMMAND 81*523fa7a6SAndroid Build Coastguard Worker "${PYTHON_EXECUTABLE}" -c 82*523fa7a6SAndroid Build Coastguard Worker "from distutils.sysconfig import get_python_lib;print(get_python_lib())" 83*523fa7a6SAndroid Build Coastguard Worker OUTPUT_VARIABLE site-packages-out 84*523fa7a6SAndroid Build Coastguard Worker ERROR_VARIABLE site-packages-out-error 85*523fa7a6SAndroid Build Coastguard Worker RESULT_VARIABLE site-packages-result 86*523fa7a6SAndroid Build Coastguard Worker WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} 87*523fa7a6SAndroid Build Coastguard Worker OUTPUT_STRIP_TRAILING_WHITESPACE 88*523fa7a6SAndroid Build Coastguard Worker ) 89*523fa7a6SAndroid Build Coastguard Worker file(GLOB_RECURSE _torchgen_srcs "${site-packages-out}/torchgen/*.py") 90*523fa7a6SAndroid Build Coastguard Worker set(_gen_command 91*523fa7a6SAndroid Build Coastguard Worker "${PYTHON_EXECUTABLE}" -m torchgen.gen_executorch 92*523fa7a6SAndroid Build Coastguard Worker --source-path=${EXECUTORCH_ROOT}/codegen --install-dir=${_out_dir} 93*523fa7a6SAndroid Build Coastguard Worker --tags-path=${site-packages-out}/torchgen/packaged/ATen/native/tags.yaml 94*523fa7a6SAndroid Build Coastguard Worker --aten-yaml-path=${site-packages-out}/torchgen/packaged/ATen/native/native_functions.yaml 95*523fa7a6SAndroid Build Coastguard Worker --op-selection-yaml-path=${_oplist_yaml} 96*523fa7a6SAndroid Build Coastguard Worker ) 97*523fa7a6SAndroid Build Coastguard Worker 98*523fa7a6SAndroid Build Coastguard Worker set(_gen_command_sources 99*523fa7a6SAndroid Build Coastguard Worker ${_out_dir}/RegisterCodegenUnboxedKernelsEverything.cpp 100*523fa7a6SAndroid Build Coastguard Worker ${_out_dir}/Functions.h ${_out_dir}/NativeFunctions.h 101*523fa7a6SAndroid Build Coastguard Worker ) 102*523fa7a6SAndroid Build Coastguard Worker 103*523fa7a6SAndroid Build Coastguard Worker if(GEN_FUNCTIONS_YAML) 104*523fa7a6SAndroid Build Coastguard Worker list(APPEND _gen_command --functions-yaml-path=${GEN_FUNCTIONS_YAML}) 105*523fa7a6SAndroid Build Coastguard Worker endif() 106*523fa7a6SAndroid Build Coastguard Worker if(GEN_CUSTOM_OPS_YAML) 107*523fa7a6SAndroid Build Coastguard Worker list(APPEND _gen_command --custom-ops-yaml-path=${GEN_CUSTOM_OPS_YAML}) 108*523fa7a6SAndroid Build Coastguard Worker list(APPEND _gen_command_sources ${_out_dir}/RegisterCPUCustomOps.cpp 109*523fa7a6SAndroid Build Coastguard Worker ${_out_dir}/RegisterSchema.cpp ${_out_dir}/CustomOpsNativeFunctions.h 110*523fa7a6SAndroid Build Coastguard Worker ) 111*523fa7a6SAndroid Build Coastguard Worker endif() 112*523fa7a6SAndroid Build Coastguard Worker 113*523fa7a6SAndroid Build Coastguard Worker add_custom_command( 114*523fa7a6SAndroid Build Coastguard Worker COMMENT "Generating code for kernel registration" 115*523fa7a6SAndroid Build Coastguard Worker OUTPUT ${_gen_command_sources} 116*523fa7a6SAndroid Build Coastguard Worker COMMAND ${_gen_command} 117*523fa7a6SAndroid Build Coastguard Worker DEPENDS ${_oplist_yaml} ${GEN_CUSTOM_OPS_YAML} ${GEN_FUNCTIONS_YAML} 118*523fa7a6SAndroid Build Coastguard Worker ${_codegen_templates} ${_torchgen_srcs} 119*523fa7a6SAndroid Build Coastguard Worker WORKING_DIRECTORY ${EXECUTORCH_ROOT} 120*523fa7a6SAndroid Build Coastguard Worker ) 121*523fa7a6SAndroid Build Coastguard Worker # Make generated file list available in parent scope 122*523fa7a6SAndroid Build Coastguard Worker set(gen_command_sources 123*523fa7a6SAndroid Build Coastguard Worker ${_gen_command_sources} 124*523fa7a6SAndroid Build Coastguard Worker PARENT_SCOPE 125*523fa7a6SAndroid Build Coastguard Worker ) 126*523fa7a6SAndroid Build Coastguard Workerendfunction() 127*523fa7a6SAndroid Build Coastguard Worker 128*523fa7a6SAndroid Build Coastguard Worker# Generate an AOT lib for registering custom ops into PyTorch 129*523fa7a6SAndroid Build Coastguard Workerfunction(gen_custom_ops_aot_lib) 130*523fa7a6SAndroid Build Coastguard Worker cmake_parse_arguments(GEN "" "LIB_NAME" "KERNEL_SOURCES" ${ARGN}) 131*523fa7a6SAndroid Build Coastguard Worker message(STATUS "Generating custom ops aot lib:") 132*523fa7a6SAndroid Build Coastguard Worker message(STATUS " LIB_NAME: ${GEN_LIB_NAME}") 133*523fa7a6SAndroid Build Coastguard Worker foreach(SOURCE IN LISTS GEN_KERNEL_SOURCES) 134*523fa7a6SAndroid Build Coastguard Worker message(STATUS " KERNEL_SOURCE: ${SOURCE}") 135*523fa7a6SAndroid Build Coastguard Worker endforeach() 136*523fa7a6SAndroid Build Coastguard Worker 137*523fa7a6SAndroid Build Coastguard Worker set(_out_dir ${CMAKE_CURRENT_BINARY_DIR}/${GEN_LIB_NAME}) 138*523fa7a6SAndroid Build Coastguard Worker add_library( 139*523fa7a6SAndroid Build Coastguard Worker ${GEN_LIB_NAME} SHARED 140*523fa7a6SAndroid Build Coastguard Worker ${_out_dir}/RegisterCPUCustomOps.cpp ${_out_dir}/RegisterSchema.cpp 141*523fa7a6SAndroid Build Coastguard Worker ${_out_dir}/CustomOpsNativeFunctions.h "${GEN_KERNEL_SOURCES}" 142*523fa7a6SAndroid Build Coastguard Worker ) 143*523fa7a6SAndroid Build Coastguard Worker # Find `Torch`. 144*523fa7a6SAndroid Build Coastguard Worker find_package(Torch REQUIRED) 145*523fa7a6SAndroid Build Coastguard Worker # This lib uses ATen lib, so we explicitly enable rtti and exceptions. 146*523fa7a6SAndroid Build Coastguard Worker target_compile_options(${GEN_LIB_NAME} PRIVATE -frtti -fexceptions) 147*523fa7a6SAndroid Build Coastguard Worker target_compile_definitions(${GEN_LIB_NAME} PRIVATE USE_ATEN_LIB=1) 148*523fa7a6SAndroid Build Coastguard Worker include_directories(${TORCH_INCLUDE_DIRS}) 149*523fa7a6SAndroid Build Coastguard Worker target_link_libraries(${GEN_LIB_NAME} PRIVATE torch) 150*523fa7a6SAndroid Build Coastguard Worker 151*523fa7a6SAndroid Build Coastguard Worker include(${EXECUTORCH_ROOT}/build/Utils.cmake) 152*523fa7a6SAndroid Build Coastguard Worker 153*523fa7a6SAndroid Build Coastguard Worker target_link_options_shared_lib(${GEN_LIB_NAME}) 154*523fa7a6SAndroid Build Coastguard Worker if(TARGET portable_lib) 155*523fa7a6SAndroid Build Coastguard Worker target_link_libraries(${GEN_LIB_NAME} PRIVATE portable_lib) 156*523fa7a6SAndroid Build Coastguard Worker else() 157*523fa7a6SAndroid Build Coastguard Worker target_link_libraries(${GEN_LIB_NAME} PRIVATE executorch_core) 158*523fa7a6SAndroid Build Coastguard Worker endif() 159*523fa7a6SAndroid Build Coastguard Workerendfunction() 160*523fa7a6SAndroid Build Coastguard Worker 161*523fa7a6SAndroid Build Coastguard Worker# Generate a runtime lib for registering operators in Executorch 162*523fa7a6SAndroid Build Coastguard Workerfunction(gen_operators_lib) 163*523fa7a6SAndroid Build Coastguard Worker set(multi_arg_names LIB_NAME KERNEL_LIBS DEPS) 164*523fa7a6SAndroid Build Coastguard Worker cmake_parse_arguments(GEN "" "" "${multi_arg_names}" ${ARGN}) 165*523fa7a6SAndroid Build Coastguard Worker 166*523fa7a6SAndroid Build Coastguard Worker message(STATUS "Generating operator lib:") 167*523fa7a6SAndroid Build Coastguard Worker message(STATUS " LIB_NAME: ${GEN_LIB_NAME}") 168*523fa7a6SAndroid Build Coastguard Worker message(STATUS " KERNEL_LIBS: ${GEN_KERNEL_LIBS}") 169*523fa7a6SAndroid Build Coastguard Worker message(STATUS " DEPS: ${GEN_DEPS}") 170*523fa7a6SAndroid Build Coastguard Worker 171*523fa7a6SAndroid Build Coastguard Worker set(_out_dir ${CMAKE_CURRENT_BINARY_DIR}/${GEN_LIB_NAME}) 172*523fa7a6SAndroid Build Coastguard Worker 173*523fa7a6SAndroid Build Coastguard Worker add_library(${GEN_LIB_NAME}) 174*523fa7a6SAndroid Build Coastguard Worker target_sources( 175*523fa7a6SAndroid Build Coastguard Worker ${GEN_LIB_NAME} 176*523fa7a6SAndroid Build Coastguard Worker PRIVATE ${_out_dir}/RegisterCodegenUnboxedKernelsEverything.cpp 177*523fa7a6SAndroid Build Coastguard Worker ${_out_dir}/Functions.h ${_out_dir}/NativeFunctions.h 178*523fa7a6SAndroid Build Coastguard Worker ) 179*523fa7a6SAndroid Build Coastguard Worker target_link_libraries(${GEN_LIB_NAME} PRIVATE ${GEN_DEPS}) 180*523fa7a6SAndroid Build Coastguard Worker if(GEN_KERNEL_LIBS) 181*523fa7a6SAndroid Build Coastguard Worker target_link_libraries(${GEN_LIB_NAME} PUBLIC ${GEN_KERNEL_LIBS}) 182*523fa7a6SAndroid Build Coastguard Worker endif() 183*523fa7a6SAndroid Build Coastguard Worker 184*523fa7a6SAndroid Build Coastguard Worker target_link_options_shared_lib(${GEN_LIB_NAME}) 185*523fa7a6SAndroid Build Coastguard Worker set(_generated_headers ${_out_dir}/Functions.h ${_out_dir}/NativeFunctions.h) 186*523fa7a6SAndroid Build Coastguard Worker set_target_properties( 187*523fa7a6SAndroid Build Coastguard Worker ${GEN_LIB_NAME} PROPERTIES PUBLIC_HEADER "${_generated_headers}" 188*523fa7a6SAndroid Build Coastguard Worker ) 189*523fa7a6SAndroid Build Coastguard Workerendfunction() 190*523fa7a6SAndroid Build Coastguard Worker 191*523fa7a6SAndroid Build Coastguard Worker# Merge two kernel yaml files, prioritizing functions from FUNCTIONS_YAML and 192*523fa7a6SAndroid Build Coastguard Worker# taking functions from FALLBACK_YAML when no implementation is found. This 193*523fa7a6SAndroid Build Coastguard Worker# corresponds to the merge_yaml buck implementation in codegen/tools. 194*523fa7a6SAndroid Build Coastguard Workerfunction(merge_yaml) 195*523fa7a6SAndroid Build Coastguard Worker set(arg_names FUNCTIONS_YAML FALLBACK_YAML OUTPUT_DIR) 196*523fa7a6SAndroid Build Coastguard Worker cmake_parse_arguments(GEN "" "${arg_names}" "" ${ARGN}) 197*523fa7a6SAndroid Build Coastguard Worker message(STATUS "Merging kernel yaml files:") 198*523fa7a6SAndroid Build Coastguard Worker message(STATUS " FUNCTIONS_YAML: ${GEN_FUNCTIONS_YAML}") 199*523fa7a6SAndroid Build Coastguard Worker message(STATUS " FALLBACK_YAML: ${GEN_FALLBACK_YAML}") 200*523fa7a6SAndroid Build Coastguard Worker message(STATUS " OUTPUT_DIR: ${GEN_OUTPUT_DIR}") 201*523fa7a6SAndroid Build Coastguard Worker 202*523fa7a6SAndroid Build Coastguard Worker set(_gen_command 203*523fa7a6SAndroid Build Coastguard Worker "${PYTHON_EXECUTABLE}" -m codegen.tools.merge_yaml 204*523fa7a6SAndroid Build Coastguard Worker --functions_yaml_path=${GEN_FUNCTIONS_YAML} 205*523fa7a6SAndroid Build Coastguard Worker --fallback_yaml_path=${GEN_FALLBACK_YAML} --output_dir=${GEN_OUTPUT_DIR} 206*523fa7a6SAndroid Build Coastguard Worker ) 207*523fa7a6SAndroid Build Coastguard Worker 208*523fa7a6SAndroid Build Coastguard Worker add_custom_command( 209*523fa7a6SAndroid Build Coastguard Worker COMMENT "Merging kernel yaml files" 210*523fa7a6SAndroid Build Coastguard Worker OUTPUT ${GEN_OUTPUT_DIR}/merged.yaml 211*523fa7a6SAndroid Build Coastguard Worker COMMAND ${_gen_command} 212*523fa7a6SAndroid Build Coastguard Worker DEPENDS ${GEN_FUNCTIONS_YAML} ${GEN_FALLBACK_YAML} 213*523fa7a6SAndroid Build Coastguard Worker WORKING_DIRECTORY ${EXECUTORCH_ROOT} 214*523fa7a6SAndroid Build Coastguard Worker ) 215*523fa7a6SAndroid Build Coastguard Workerendfunction() 216