Skip to content
Merged
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
136 changes: 136 additions & 0 deletions examples/espressif/idf_component_template/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
# Copyright (c) Meta Platforms, Inc. and affiliates.
# All rights reserved.
#
# This source code is licensed under the BSD-style license found in the
# LICENSE file in the root directory of this source tree.

# ExecuTorch runtime as an ESP-IDF component.
#
# GENERATED by examples/espressif/build_idf_component.sh in the ExecuTorch repo
# -- do not edit this tree by hand. Source lists live in et_generated.cmake next
# to this file; the op profile is selected with CONFIG_ET_OP_PROFILE_* in
# Kconfig (no regeneration needed to switch).

include(${CMAKE_CURRENT_LIST_DIR}/et_generated.cmake)

set(_et_requires esp_hw_support esp_system esp_timer log heap)

if(NOT CONFIG_ET_ENABLE)
# ESP-IDF links every component under components/ into the image, and this
# component's WHOLE_ARCHIVE registration (below) is deliberately GC-proof. The
# gate is off by default, so vendoring the component leaves a project's
# firmware unchanged until CONFIG_ET_ENABLE is set or selected. ESP-IDF's
# component-requirements scan runs this file before Kconfig is loaded, so it
# only ever sees this branch; registering the same requirements here keeps
# those components in the build when the component is enabled. No
# INCLUDE_DIRS: including <et_model.h> while disabled fails at compile time
# rather than at link time.
idf_component_register(PRIV_REQUIRES ${_et_requires})
return()
endif()

# Pick the Kconfig-selected profile (default: ET_DEFAULT_PROFILE).
set(_et_profile "${ET_DEFAULT_PROFILE}")
foreach(_p IN LISTS ET_PROFILES)
string(TOUPPER "${_p}" _p_up)
if(CONFIG_ET_OP_PROFILE_${_p_up})
set(_et_profile "${_p}")
endif()
endforeach()
string(TOUPPER "${_et_profile}" _ET_UP)

set(_et_vendored_srcs ${ET_CORE_SRCS} ${ET_PROFILE_SRCS_${_ET_UP}}
${ET_KERNEL_SRCS_${_ET_UP}}
)

# WHOLE_ARCHIVE: kernel registration happens in static initializers in the
# profile's register_kernels.cpp; normal archive extraction would drop that
# translation unit (nothing references its symbols) and every operator would be
# missing at load time. --gc-sections still strips unused runtime and kernel
# code. src/platform/esp_pal.cpp is copied in by the generator from the shared
# examples/espressif/platform/esp_pal.cpp.
idf_component_register(
SRCS
${_et_vendored_srcs}
"src/et_model.cpp"
"src/platform/esp_pal.cpp"
INCLUDE_DIRS
"include"
PRIV_REQUIRES
${_et_requires}
WHOLE_ARCHIVE
)

target_compile_features(${COMPONENT_LIB} PUBLIC cxx_std_17)

set(_et_max_kernel_num ${ET_MAX_KERNEL_NUM_${_ET_UP}})
if(CONFIG_ET_MAX_KERNEL_NUM)
if(CONFIG_ET_MAX_KERNEL_NUM LESS _et_max_kernel_num)
message(
FATAL_ERROR
"CONFIG_ET_MAX_KERNEL_NUM=${CONFIG_ET_MAX_KERNEL_NUM} is below the "
"${_et_profile} profile's ${_et_max_kernel_num} kernels"
)
endif()
set(_et_max_kernel_num ${CONFIG_ET_MAX_KERNEL_NUM})
endif()

if(CONFIG_ET_PROGRAM_VERIFICATION)
set(_et_program_verification 1)
else()
set(_et_program_verification 0)
endif()

# Consumers including <executorch/...> headers need the same c10 macro mode and
# flatbuffers alignment the runtime was built with. __FUNCTION__ instead of
# __builtin_FUNCTION() keeps log function names without full signatures.
target_compile_definitions(
${COMPONENT_LIB}
PUBLIC C10_USING_CUSTOM_GENERATED_MACROS FLATBUFFERS_MAX_ALIGNMENT=1024
ET_USE_BUILTIN_FUNCTION_NAME=0
PRIVATE MAX_KERNEL_NUM=${_et_max_kernel_num}
ET_ENABLE_PROGRAM_VERIFICATION=${_et_program_verification}
)

if(NOT CONFIG_ET_DEBUG_ASSERTS)
target_compile_definitions(${COMPONENT_LIB} PRIVATE NDEBUG)
endif()

if(CONFIG_ET_OPTIMIZE_SIZE)
target_compile_options(${COMPONENT_LIB} PRIVATE -Os)
endif()

if(NOT CONFIG_ET_ENABLE_LOGGING)
target_compile_definitions(${COMPONENT_LIB} PUBLIC ET_LOG_ENABLED=0)
endif()

# ET_MIN_LOG_LEVEL compiles out ET_LOG calls below the floor; ET_ESP_LOG_LEVEL
# applies the same floor in esp_pal.cpp. ExecuTorch has no warning level, so
# WARN keeps only errors.
if(CONFIG_ET_LOG_LEVEL_ERROR)
set(_et_min_log_level Error)
set(_et_esp_log_level ESP_LOG_ERROR)
elseif(CONFIG_ET_LOG_LEVEL_WARN)
set(_et_min_log_level Error)
set(_et_esp_log_level ESP_LOG_WARN)
elseif(CONFIG_ET_LOG_LEVEL_DEBUG)
set(_et_min_log_level Debug)
set(_et_esp_log_level ESP_LOG_DEBUG)
else() # CONFIG_ET_LOG_LEVEL_INFO (default)
set(_et_min_log_level Info)
set(_et_esp_log_level ESP_LOG_INFO)
endif()
target_compile_definitions(
${COMPONENT_LIB}
PUBLIC ET_MIN_LOG_LEVEL=${_et_min_log_level}
PRIVATE ET_ESP_LOG_LEVEL=${_et_esp_log_level}
)

Comment thread
JakeStevens marked this conversation as resolved.
Resolved
# ESP-IDF builds with warnings-as-errors; upstream ExecuTorch sources are not
# warning-clean under the IDF flag set, so demote for vendored sources only.
set_source_files_properties(
${_et_vendored_srcs}
PROPERTIES
COMPILE_OPTIONS
"-Wno-error;-Wno-deprecated-declarations;-Wno-unused-parameter;-Wno-sign-compare;-Wno-unused-variable"
)
79 changes: 79 additions & 0 deletions examples/espressif/idf_component_template/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
<!--
Copyright (c) Meta Platforms, Inc. and affiliates.
All rights reserved.

This source code is licensed under the BSD-style license found in the
LICENSE file in the root directory of this source tree.
-->

# ExecuTorch for ESP-IDF (`executorch` component)

**This tree is generated. Do not edit it by hand.** It is produced by
`examples/espressif/build_idf_component.sh` in the
[ExecuTorch](https://github.com/pytorch/executorch) repository:

```sh
executorch/examples/espressif/build_idf_component.sh \
--profiles @PROFILES@ --out <this directory>
```

`VERSION` in this directory records the ExecuTorch commit, the op
profiles baked in, and each profile's op-set hash. A `.pte` is only
valid against the profile whose hash its export was checked against;
mismatches surface as `OperatorMissing` at load time.

## Using it

Add the component to your project's component requirements (`REQUIRES
executorch`), enable it (`CONFIG_ET_ENABLE=y`, or `select ET_ENABLE`
from your own Kconfig), pick an op profile in `menuconfig` (ExecuTorch -> Op
profile, or `CONFIG_ET_OP_PROFILE_<NAME>=y` in your sdkconfig), then:

- `#include <et_model.h>` for the small C inference API (flash XIP
model bytes; method, planned and optional scratch arenas either
passed in or allocated with heap_caps internal/PSRAM placement). This
is what most applications should use. The `.pte` bytes must be
16-byte aligned; `et_model_create` rejects misaligned data. Application pipelines built on it (audio
front ends, detectors, wake word logic) live with the application,
not in this runtime component.
- `#include <executorch/...>` for the core C++ runtime
(`Program`/`Method`) and `BufferDataLoader`. `extension::Module`, the
file and mmap data loaders, and external `.ptd` data maps are not
included. Runtime logging goes through ESP_LOG under the
`executorch` tag.

`CONFIG_ET_ENABLE` (default `n`) gates the whole component, so vendoring
it leaves a project's firmware unchanged until it is enabled. While
disabled the component registers empty and `et_model.h` is not on the
include path.

## Op profiles

@PROFILE_TABLE@

Only the selected profile's kernels are compiled in. Switching
profiles is a Kconfig change and a rebuild; no regeneration.

## Size and debug options

`CONFIG_ET_OPTIMIZE_SIZE` builds the runtime with `-Os` regardless of
the project's optimization level. `CONFIG_ET_PROGRAM_VERIFICATION`
compiles in full `.pte` verification, which `et_model_config_t.verify`
requires. `CONFIG_ET_DEBUG_ASSERTS` keeps ExecuTorch's debug
assertions (otherwise the runtime builds with `NDEBUG`).
`CONFIG_ET_MAX_KERNEL_NUM` raises the kernel registry size above the
profile's op count, for applications that register their own kernels.

## Logging

`CONFIG_ET_ENABLE_LOGGING=n` compiles ExecuTorch logging out entirely.
Otherwise runtime messages go to ESP_LOG (tag `executorch`), and
`CONFIG_ET_LOG_LEVEL_*` is a compile-time floor (`ET_MIN_LOG_LEVEL`)
on top of the usual IDF runtime levels. `et_model` logs its own
errors under the `et_model` tag.

## Updating

Re-run the generator against a newer ExecuTorch checkout and replace
this whole directory. Review the `VERSION` diff (commit, op-set
hashes, file counts, size); do not line-review vendored sources.
14 changes: 14 additions & 0 deletions examples/espressif/idf_component_template/idf_component.yml.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
## ExecuTorch runtime for ESP-IDF.
##
## GENERATED by examples/espressif/build_idf_component.sh -- do not edit.
## Version is "<ExecuTorch release>~<packaging revision>"; see VERSION
## in this directory for the exact commit and op-set hashes. Vendored
## third-party code (FlatBuffers, flatcc: Apache-2.0) is listed in
## THIRD_PARTY_LICENSES. No targets list: the runtime is portable
## across ESP targets.
version: "@ET_COMPONENT_VERSION@"
description: ExecuTorch runtime for ESP-IDF
url: https://github.com/pytorch/executorch
license: BSD-3-Clause
dependencies:
idf: ">=6.0"
Loading
Loading