@@ -31,6 +31,77 @@ function(arm_runner_require_baremetal_targets)
3131
3232endfunction ()
3333
34+ function (verify_targets_exist )
35+ cmake_parse_arguments (ARG "" "CONTEXT" "TARGETS" ${ARGN} )
36+
37+ set (_targets ${ARG_TARGETS} ${ARG_UNPARSED_ARGUMENTS} )
38+ if (NOT ARG_CONTEXT)
39+ set (ARG_CONTEXT "verify_targets_exist" )
40+ endif ()
41+
42+ foreach (_target IN LISTS _targets)
43+ if (NOT TARGET ${_target} )
44+ message (FATAL_ERROR "${ARG_CONTEXT} requires missing target ${_target} ." )
45+ endif ()
46+ endforeach ()
47+ endfunction ()
48+
49+ # Private function to isolate logic for building prim ops library.
50+ function (_arm_runner_create_prim_ops_lib )
51+ # Parse arguments.
52+ set (options INCLUDE_ALL_OPS)
53+ set (one_value_args LIB_NAME SELECTED_OPS_YAML)
54+ set (multi_value_args DEPS)
55+ cmake_parse_arguments (
56+ ARG "${options} " "${one_value_args} " "${multi_value_args} " ${ARGN}
57+ )
58+
59+ set (_out_dir "${CMAKE_CURRENT_BINARY_DIR } /${ARG_LIB_NAME} " )
60+ set (_sources ${EXECUTORCH_ROOT} /kernels/prim_ops/register_prim_ops.cpp)
61+
62+ # Generate selected operator list if needed.
63+ if (NOT ARG_INCLUDE_ALL_OPS)
64+ set (_selected_prim_ops_header "${_out_dir} /selected_prim_ops.h" )
65+ set (_gen_selected_prim_ops_script
66+ "${EXECUTORCH_ROOT} /codegen/tools/gen_selected_prim_ops.py"
67+ )
68+ set (_gen_selected_prim_ops_command
69+ "${PYTHON_EXECUTABLE} " -m codegen.tools.gen_selected_prim_ops
70+ --op-selection-yaml-path =${ARG_SELECTED_OPS_YAML}
71+ --output-dir=${_out_dir}
72+ )
73+ add_custom_command (
74+ COMMENT "Generating selected_prim_ops.h for ${ARG_LIB_NAME} "
75+ OUTPUT ${_selected_prim_ops_header}
76+ COMMAND ${_gen_selected_prim_ops_command}
77+ DEPENDS ${ARG_SELECTED_OPS_YAML} ${_gen_selected_prim_ops_script}
78+ WORKING_DIRECTORY ${EXECUTORCH_ROOT}
79+ )
80+ list (APPEND _sources ${_selected_prim_ops_header} )
81+ endif ()
82+
83+ # Add prim ops registration library.
84+ add_library (${ARG_LIB_NAME} ${_sources} )
85+ target_include_directories (
86+ ${ARG_LIB_NAME} PRIVATE ${EXECUTORCH_ROOT} /kernels/prim_ops ${_out_dir}
87+ )
88+ if (NOT ARG_INCLUDE_ALL_OPS)
89+ target_compile_definitions (
90+ ${ARG_LIB_NAME} PRIVATE ET_PRIM_OPS_SELECTIVE_BUILD
91+ EXECUTORCH_ENABLE_PRIM_OPS_SELECTIVE_BUILD
92+ )
93+ endif ()
94+ target_link_libraries (${ARG_LIB_NAME} PRIVATE ${ARG_DEPS} )
95+ executorch_target_link_options_shared_lib (${ARG_LIB_NAME} )
96+
97+ # Add prim ops kernel library.
98+ add_library (
99+ ${ARG_LIB_NAME} _impl ${EXECUTORCH_ROOT} /kernels/prim_ops/et_copy_index.cpp
100+ ${EXECUTORCH_ROOT} /kernels/prim_ops/et_view.cpp
101+ )
102+ target_link_libraries (${ARG_LIB_NAME} _impl PRIVATE ${ARG_DEPS} )
103+ endfunction ()
104+
34105#[[
35106Create a selected operator registration library for one operator family.
36107
@@ -62,12 +133,16 @@ Arguments:
62133 INCLUDE_ALL_OPS: Generate a non-selective registration library for the
63134 selected operator family.
64135
136+ PRIM_OPS: Build a selective prim ops library instead of a codegen operators lib.
137+
65138The lib will always be created, even when no operators are selected.
66139OP_LIST and OPS_FROM_MODEL can be used additively.
140+ If neither OP_LIST nor OPS_FROM_MODEL is set, the generated registration
141+ library is empty. INCLUDE_ALL_OPS explicitly builds a full registration library.
67142]]
68143function (arm_runner_create_selected_ops_lib )
69144 # Parse arguments
70- set (options INCLUDE_ALL_OPS)
145+ set (options INCLUDE_ALL_OPS PRIM_OPS )
71146 set (one_value_args LIB_NAME FUNCTIONS_YAML CUSTOM_OPS_YAML OP_LIST
72147 OPS_FROM_MODEL DTYPE_SELECTIVE_BUILD
73148 )
@@ -101,10 +176,13 @@ function(arm_runner_create_selected_ops_lib)
101176 )
102177 endif ()
103178
104- if (NOT ARG_FUNCTIONS_YAML AND NOT ARG_CUSTOM_OPS_YAML)
179+ if (NOT ARG_PRIM_OPS
180+ AND NOT ARG_FUNCTIONS_YAML
181+ AND NOT ARG_CUSTOM_OPS_YAML
182+ )
105183 message (
106184 FATAL_ERROR
107- "${_arm_runner_create_selected_ops_lib_context} requires FUNCTIONS_YAML or CUSTOM_OPS_YAML."
185+ "${_arm_runner_create_selected_ops_lib_context} requires FUNCTIONS_YAML or CUSTOM_OPS_YAML unless PRIM_OPS is set ."
108186 )
109187 endif ()
110188
@@ -128,11 +206,25 @@ function(arm_runner_create_selected_ops_lib)
128206 DTYPE_SELECTIVE_BUILD
129207 "${ARG_DTYPE_SELECTIVE_BUILD} "
130208 )
209+ set (_arm_runner_include_all_ops OFF )
131210 if (ARG_INCLUDE_ALL_OPS)
211+ set (_arm_runner_include_all_ops ON )
132212 list (APPEND _arm_runner_selected_ops_args INCLUDE_ALL_OPS "ON" )
133213 endif ()
134214 gen_selected_ops (${_arm_runner_selected_ops_args} )
135215
216+ if (ARG_PRIM_OPS)
217+ set (_arm_runner_prim_ops_args
218+ LIB_NAME "${ARG_LIB_NAME} " SELECTED_OPS_YAML
219+ "${gen_selected_ops_output_yaml} " DEPS ${ARG_DEPS}
220+ )
221+ if (_arm_runner_include_all_ops)
222+ list (APPEND _arm_runner_prim_ops_args INCLUDE_ALL_OPS)
223+ endif ()
224+ _arm_runner_create_prim_ops_lib (${_arm_runner_prim_ops_args} )
225+ return ()
226+ endif ()
227+
136228 # Codegen for operator library.
137229 set (_arm_ops_binding_args LIB_NAME "${ARG_LIB_NAME} " )
138230 if (ARG_FUNCTIONS_YAML)
@@ -198,21 +290,6 @@ function(arm_runner_configure_runtime_output TARGET_NAME FALLBACK_DIR)
198290 endif ()
199291endfunction ()
200292
201- function (verify_targets_exist )
202- cmake_parse_arguments (ARG "" "CONTEXT" "TARGETS" ${ARGN} )
203-
204- set (_targets ${ARG_TARGETS} ${ARG_UNPARSED_ARGUMENTS} )
205- if (NOT ARG_CONTEXT)
206- set (ARG_CONTEXT "verify_targets_exist" )
207- endif ()
208-
209- foreach (_target IN LISTS _targets)
210- if (NOT TARGET ${_target} )
211- message (FATAL_ERROR "${ARG_CONTEXT} requires missing target ${_target} ." )
212- endif ()
213- endforeach ()
214- endfunction ()
215-
216293# Link the provided target with minimal specs. This minimizes code size, but
217294# comes with limited support. Notably, printing with %zu is not supported.
218295function (arm_runner_link_minimal_specs TARGET_NAME )
0 commit comments