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
2 changes: 1 addition & 1 deletion .wiki/export/model-specific.md
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ When building C++ applications with ExecuTorch, you can selectively include only
```cmake
gen_selected_ops(
LIB_NAME "select_build_lib"
ROOT_OPS "aten::add.out"
SELECT_OPS_LIST "aten::add.out"
INCLUDE_ALL_OPS "OFF"
)
generate_bindings_for_kernels(
Expand Down
2 changes: 1 addition & 1 deletion .wiki/troubleshooting/performance.md
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ Always use `to_edge_transform_and_lower()` instead of the older `to_edge()` + `t

Only include the operators your model actually needs:
```cmake
gen_selected_ops(LIB_NAME "my_ops" ROOT_OPS "..." INCLUDE_ALL_OPS "OFF")
gen_selected_ops(LIB_NAME "my_ops" SELECT_OPS_LIST "..." INCLUDE_ALL_OPS "OFF")
```

This reduces binary size and can improve load time. [Source: #10297]
Expand Down
2 changes: 1 addition & 1 deletion .wiki/troubleshooting/runtime-errors.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ If an operator is not included in the build, you'll get a runtime error. Use sel
```cmake
gen_selected_ops(
LIB_NAME "my_ops"
ROOT_OPS "aten::add.out;aten::mul.out"
SELECT_OPS_LIST "aten::add.out;aten::mul.out"
INCLUDE_ALL_OPS "OFF"
)
```
Expand Down
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1614,7 +1614,7 @@ if(NOT EXECUTORCH_SELECT_OPS_YAML STREQUAL ""
"executorch_selected_kernels"
OPS_SCHEMA_YAML
"${EXECUTORCH_SELECT_OPS_YAML}"
ROOT_OPS
SELECT_OPS_LIST
"${EXECUTORCH_SELECT_OPS_LIST}"
INCLUDE_ALL_OPS
FALSE
Expand Down
2 changes: 1 addition & 1 deletion backends/arm/cmake/ArmRunnerUtilsInternal.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -481,7 +481,7 @@ function(arm_runner_create_selected_ops_lib)
set(_arm_runner_selected_ops_args
LIB_NAME
"${ARG_LIB_NAME}"
ROOT_OPS
SELECT_OPS_LIST
"${ARG_OP_LIST}"
OPS_FROM_MODEL
"${ARG_OPS_FROM_MODEL}"
Expand Down
27 changes: 16 additions & 11 deletions codegen/tools/gen_oplist.py
Original file line number Diff line number Diff line change
Expand Up @@ -217,14 +217,14 @@ def gen_oplist(
output_path: Path,
model_file_path: Optional[str] = None,
ops_schema_yaml_path: Optional[str] = None,
root_ops: Optional[str] = None,
select_ops_list: Optional[str] = None,
ops_dict: Optional[str] = None,
include_all_operators: bool = False,
):
if not (
model_file_path
or ops_schema_yaml_path
or root_ops
or select_ops_list
or ops_dict
or include_all_operators
):
Expand All @@ -236,12 +236,17 @@ def gen_oplist(
op_set = set()
source_name = None
et_kernel_metadata = {} # type: ignore[var-annotated]
if root_ops:
if select_ops_list:
# decide delimiter
delimiter = "," if "," in root_ops else " "
print(root_ops)
delimiter = "," if "," in select_ops_list else " "
print(select_ops_list)
op_set.update(
set(filter(lambda x: len(x) > 0, map(str.strip, root_ops.split(delimiter))))
set(
filter(
lambda x: len(x) > 0,
map(str.strip, select_ops_list.split(delimiter)),
)
)
)
et_kernel_metadata = merge_et_kernel_metadata(
et_kernel_metadata, {op: ["default"] for op in op_set}
Expand Down Expand Up @@ -310,8 +315,8 @@ def main(args: List[Any]) -> None:
required=False,
)
parser.add_argument(
"--root_ops",
help=("A comma separated list of root operators used by the model"),
"--select_ops_list",
help=("A comma separated list of operators to select for selective build"),
required=False,
)
parser.add_argument(
Expand Down Expand Up @@ -342,7 +347,7 @@ def main(args: List[Any]) -> None:
output_path=output_path,
model_file_path=options.model_file_path,
ops_schema_yaml_path=options.ops_schema_yaml_path,
root_ops=options.root_ops,
select_ops_list=options.select_ops_list,
ops_dict=options.ops_dict,
include_all_operators=options.include_all_operators,
)
Expand All @@ -352,8 +357,8 @@ def main(args: List[Any]) -> None:
command.append(f"--model_file_path {options.model_file_path}")
if options.ops_schema_yaml_path:
command.append(f"--ops_schema_yaml_path {options.ops_schema_yaml_path}")
if options.root_ops:
command.append(f"--root_ops {options.root_ops}")
if options.select_ops_list:
command.append(f"--select_ops_list {options.select_ops_list}")
if options.ops_dict:
command.append(f"--ops_dict {options.ops_dict}")
if options.include_all_operators:
Expand Down
14 changes: 7 additions & 7 deletions codegen/tools/test/test_gen_oplist.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,14 +66,14 @@ def test_gen_op_list_with_valid_model_path(
temp_file.close()

@patch("executorch.codegen.tools.gen_oplist._dump_yaml")
def test_gen_op_list_with_valid_root_ops(
def test_gen_op_list_with_valid_select_ops_list(
self,
mock_dump_yaml: NonCallableMock,
) -> None:
output_path = os.path.join(self.temp_dir.name, "output.yaml")
args = [
f"--output_path={output_path}",
"--root_ops=aten::add,aten::mul",
"--select_ops_list=aten::add,aten::mul",
]
gen_oplist.main(args)
mock_dump_yaml.assert_called_once_with(
Expand All @@ -85,7 +85,7 @@ def test_gen_op_list_with_valid_root_ops(
)

@patch("executorch.codegen.tools.gen_oplist._dump_yaml")
def test_gen_op_list_with_root_ops_and_dtypes(
def test_gen_op_list_with_ops_dict_and_dtypes(
self,
mock_dump_yaml: NonCallableMock,
) -> None:
Expand Down Expand Up @@ -124,7 +124,7 @@ def test_gen_op_list_with_both_op_list_and_ops_schema_yaml_merges(
test_path = os.path.join(self.temp_dir.name, "test.yaml")
args = [
f"--output_path={output_path}",
"--root_ops=aten::relu.out",
"--select_ops_list=aten::relu.out",
f"--ops_schema_yaml_path={self.ops_schema_yaml}",
]
gen_oplist.main(args)
Expand All @@ -148,7 +148,7 @@ def test_gen_op_list_with_include_all_operators(
output_path = os.path.join(self.temp_dir.name, "output.yaml")
args = [
f"--output_path={output_path}",
"--root_ops=aten::add,aten::mul",
"--select_ops_list=aten::add,aten::mul",
"--include_all_operators",
]
gen_oplist.main(args)
Expand All @@ -173,15 +173,15 @@ def test_get_custom_build_selector_with_both_allowlist_and_yaml(
self.assertEqual(len(ops), 2)
self.assertSetEqual(set(ops.keys()), set(op_list))

def test_gen_oplist_generates_from_root_ops(
def test_gen_oplist_generates_from_select_ops_list(
self,
) -> None:
filename = os.path.join(self.temp_dir.name, "selected_operators.yaml")
op_list = ["aten::add.out", "aten::mul.out", "aten::relu.out"]
comma = ","
args = [
f"--output_path={filename}",
f"--root_ops={comma.join(op_list)}",
f"--select_ops_list={comma.join(op_list)}",
]
gen_oplist.main(args)
self.assertTrue(os.path.isfile(filename))
Expand Down
6 changes: 3 additions & 3 deletions docs/source/kernel-library-selective-build.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,14 +58,14 @@ For fine-grained control, we expose a CMake macro [gen_selected_ops](https://git
gen_selected_ops(
LIB_NAME # the name of the selective build operator library to be generated
OPS_SCHEMA_YAML # path to a yaml file containing operators to be selected
ROOT_OPS # comma separated operator names to be selected
SELECT_OPS_LIST # comma separated operator names to be selected
INCLUDE_ALL_OPS # boolean flag to include all operators
OPS_FROM_MODEL # path to a pte file of model to select operators from
DTYPE_SELECTIVE_BUILD # boolean flag to enable dtype selection
)
```

The macro makes a call to gen_oplist.py, which requires a [distinct selection](https://github.com/pytorch/executorch/blob/main/codegen/tools/gen_oplist.py#L222-L228) of API choice. `OPS_SCHEMA_YAML`, `ROOT_OPS`, `INCLUDE_ALL_OPS`, and `OPS_FROM_MODEL` are mutually exclusive options, and should not be used in conjunction.
The macro makes a call to gen_oplist.py, which requires a [distinct selection](https://github.com/pytorch/executorch/blob/main/codegen/tools/gen_oplist.py#L222-L228) of API choice. `OPS_SCHEMA_YAML`, `SELECT_OPS_LIST`, `INCLUDE_ALL_OPS`, and `OPS_FROM_MODEL` are mutually exclusive options, and should not be used in conjunction.

### Select all ops

Expand All @@ -77,7 +77,7 @@ If this input is set to true, it means we are registering all the kernels from a
Context: each kernel library is designed to have a yaml file associated with it. For more information on this yaml file, see [Kernel Library Overview](kernel-library-overview.md). This API allows users to pass in the schema yaml for a kernel library directly, effectively allowlisting all kernels in the library to be registered.


### Select root ops from operator list
### Select ops from operator list

This API lets users pass in a list of operator names. Note that this API can be combined with the API above and we will create a allowlist from the union of both API inputs.

Expand Down
2 changes: 1 addition & 1 deletion examples/arduino/build_arduino_library.sh
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ if [ "${ALL_OPS:-0}" = "1" ]; then
OPLIST_SELECTION=(--include_all_operators)
echo " Op set: every portable op (large - verify it fits your target)"
else
OPLIST_SELECTION=(--root_ops="$ROOT_OPS")
OPLIST_SELECTION=(--select_ops_list="$ROOT_OPS")
echo " Op set: default ($(echo "$ROOT_OPS" | tr ',' '\n' | wc -l | tr -d ' ') root ops)"
fi

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ gen_selected_ops(
"silero_vad_portable_ops_lib"
OPS_SCHEMA_YAML
""
ROOT_OPS
SELECT_OPS_LIST
""
INCLUDE_ALL_OPS
""
Expand Down
8 changes: 5 additions & 3 deletions examples/portable/custom_ops/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,9 @@ executorch_load_build_variables()
# Generate C++ bindings to register kernels into both PyTorch (for AOT) and
# Executorch (for runtime).
if(REGISTER_EXAMPLE_CUSTOM_OP EQUAL 1)
gen_selected_ops(LIB_NAME "custom_ops_lib" ROOT_OPS "my_ops::mul3.out")
gen_selected_ops(LIB_NAME "custom_ops_lib" SELECT_OPS_LIST "my_ops::mul3.out")
elseif(REGISTER_EXAMPLE_CUSTOM_OP EQUAL 2)
gen_selected_ops(LIB_NAME "custom_ops_lib" ROOT_OPS "my_ops::mul4.out")
gen_selected_ops(LIB_NAME "custom_ops_lib" SELECT_OPS_LIST "my_ops::mul4.out")
endif()
# Expect gen_selected_ops output file to be selected_operators.yaml
generate_bindings_for_kernels(
Expand All @@ -81,7 +81,9 @@ message("Generated files ${gen_command_sources}")

# C++ library to register custom ops into PyTorch.
if(REGISTER_EXAMPLE_CUSTOM_OP EQUAL 2)
gen_selected_ops(LIB_NAME "custom_ops_aot_lib" ROOT_OPS "my_ops::mul4.out")
gen_selected_ops(
LIB_NAME "custom_ops_aot_lib" SELECT_OPS_LIST "my_ops::mul4.out"
)
generate_bindings_for_kernels(
LIB_NAME "custom_ops_aot_lib" CUSTOM_OPS_YAML
${CMAKE_CURRENT_LIST_DIR}/custom_ops.yaml
Expand Down
2 changes: 1 addition & 1 deletion examples/portable/custom_ops/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ Currently we use Cmake as the build system to link the `my_ops::mul3.out` kernel

## Selective build

Note that we have defined a custom op for both `my_ops::mul3.out` and `my_ops::mul4.out` in `custom_ops.yaml`. To reduce binary size, we can choose to only register the operators used in the model. This is done by passing in a list of operators to the `gen_oplist` custom rule, for example: `--root_ops="my_ops::mul4.out"`.
Note that we have defined a custom op for both `my_ops::mul3.out` and `my_ops::mul4.out` in `custom_ops.yaml`. To reduce binary size, we can choose to only register the operators used in the model. This is done by passing in a list of operators to the `gen_oplist` custom rule, for example: `--select_ops_list="my_ops::mul4.out"`.

We then let the custom ops library depend on this target, to only register the ops we want.

Expand Down
2 changes: 1 addition & 1 deletion examples/selective_build/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ gen_selected_ops(
"select_build_lib"
OPS_SCHEMA_YAML
"${_custom_ops_yaml}"
ROOT_OPS
SELECT_OPS_LIST
"${EXECUTORCH_SELECT_OPS_LIST}"
INCLUDE_ALL_OPS
"${EXECUTORCH_SELECT_ALL_OPS}"
Expand Down
2 changes: 1 addition & 1 deletion examples/selective_build/advanced/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ gen_selected_ops(
"select_build_lib"
OPS_SCHEMA_YAML
"${_custom_ops_yaml}"
ROOT_OPS
SELECT_OPS_LIST
"${EXECUTORCH_SELECT_OPS_LIST}"
INCLUDE_ALL_OPS
"${EXECUTORCH_SELECT_ALL_OPS}"
Expand Down
3 changes: 2 additions & 1 deletion kernels/portable/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,8 @@ if(EXECUTORCH_BUILD_KERNELS_CUSTOM_AOT AND NOT EXECUTORCH_BUILD_ARM_BAREMETAL)
set(_custom_ops_yaml "${CMAKE_CURRENT_SOURCE_DIR}/custom_ops.yaml")
set(_portable_custom_ops "aten::allclose.out" "aten::allclose.Tensor")
gen_selected_ops(
LIB_NAME "portable_custom_ops_aot_lib" ROOT_OPS ${_portable_custom_ops}
LIB_NAME "portable_custom_ops_aot_lib" SELECT_OPS_LIST
${_portable_custom_ops}
)
generate_bindings_for_kernels(
LIB_NAME "portable_custom_ops_aot_lib" CUSTOM_OPS_YAML
Expand Down
2 changes: 1 addition & 1 deletion kernels/quantized/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ if(NOT CMAKE_GENERATOR STREQUAL "Xcode"
"quantized_decomposed::quantize_per_token.out"
)
gen_selected_ops(
LIB_NAME "quantized_ops_aot_lib" ROOT_OPS ${_quantized_aot_ops}
LIB_NAME "quantized_ops_aot_lib" SELECT_OPS_LIST ${_quantized_aot_ops}
)
# Expect gen_selected_ops output file to be
# quantized_ops_aot_lib/selected_operators.yaml
Expand Down
2 changes: 1 addition & 1 deletion shim_et/xplat/executorch/codegen/codegen.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ def et_operator_library(
)
if final_ops:
genrule_cmd.append(
"--root_ops=" + ",".join(final_ops),
"--select_ops_list=" + ",".join(final_ops),
)
if final_ops_dict:
ops_dict_json = struct_to_json(final_ops_dict)
Expand Down
8 changes: 4 additions & 4 deletions tools/cmake/Codegen.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,15 @@
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 SELECT_OPS_LIST INCLUDE_ALL_OPS
OPS_FROM_MODEL DTYPE_SELECTIVE_BUILD
)
cmake_parse_arguments(GEN "" "" "${arg_names}" ${ARGN})

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}")
message(STATUS " SELECT_OPS_LIST: ${GEN_SELECT_OPS_LIST}")
message(STATUS " INCLUDE_ALL_OPS: ${GEN_INCLUDE_ALL_OPS}")
message(STATUS " OPS_FROM_MODEL: ${GEN_OPS_FROM_MODEL}")
message(STATUS " DTYPE_SELECTIVE_BUILD: ${GEN_DTYPE_SELECTIVE_BUILD}")
Expand Down Expand Up @@ -52,8 +52,8 @@ function(gen_selected_ops)
--ops_schema_yaml_path="${GEN_OPS_SCHEMA_YAML}"
)
endif()
if(GEN_ROOT_OPS)
list(APPEND _gen_oplist_command --root_ops="${GEN_ROOT_OPS}")
if(GEN_SELECT_OPS_LIST)
list(APPEND _gen_oplist_command --select_ops_list="${GEN_SELECT_OPS_LIST}")
endif()
if(GEN_INCLUDE_ALL_OPS)
list(APPEND _gen_oplist_command --include_all_operators)
Expand Down
2 changes: 1 addition & 1 deletion zephyr/samples/mv2-ethosu/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ if(_EXECUTORCH_GEN_ZEPHYR_PORTABLE_OPS)
"cpu_portable_ops_lib"
OPS_SCHEMA_YAML
""
ROOT_OPS
SELECT_OPS_LIST
"${EXECUTORCH_SELECT_OPS_LIST}"
INCLUDE_ALL_OPS
""
Expand Down
Loading