Skip to content

Commit 893d815

Browse files
authored
Espressif: Add ESP-IDF component template for ExecuTorch (pytorch#24292)
### Summary Add the "hand-written" template for a generated ExecuTorch ESP-IDF component. This contains only the component glue that is copied into generated output: the component `CMakeLists.txt`, manifest template, README, the small C inference API in `et_model.h`/`et_model.cpp`, and the ESP-IDF `MmapDataLoader` stub (ESP-IDF has no `mmap`). It deliberately does not carry a PAL copy; the generator in the next PR copies the shared PAL from pytorch#24291. Splitting the template out keeps the hand-written runtime glue reviewable separately from the generator and its vendored output. On its own this PR is inert: `et_generated.cmake` and `Kconfig` are ### Test plan - With the generator PR applied, generated a component from this template and built a minimal ESP-IDF consumer that calls `et_model_create` for `esp32s3` and `esp32c5` with ESP-IDF v6.0.1; both builds complete. - Verified the template contains no PAL copy; the generated component's `src/platform/esp_pal.cpp` is byte-identical to the shared PAL from pytorch#24291. - Tested fully end to end w/ Muse Gadget SDK on Box 3
1 parent 9975a72 commit 893d815

5 files changed

Lines changed: 968 additions & 0 deletions

File tree

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
# Copyright (c) Meta Platforms, Inc. and affiliates.
2+
# All rights reserved.
3+
#
4+
# This source code is licensed under the BSD-style license found in the
5+
# LICENSE file in the root directory of this source tree.
6+
7+
# ExecuTorch runtime as an ESP-IDF component.
8+
#
9+
# GENERATED by examples/espressif/build_idf_component.sh in the ExecuTorch repo
10+
# -- do not edit this tree by hand. Source lists live in et_generated.cmake next
11+
# to this file; the op profile is selected with CONFIG_ET_OP_PROFILE_* in
12+
# Kconfig (no regeneration needed to switch).
13+
14+
include(${CMAKE_CURRENT_LIST_DIR}/et_generated.cmake)
15+
16+
set(_et_requires esp_hw_support esp_system esp_timer log heap)
17+
18+
if(NOT CONFIG_ET_ENABLE)
19+
# ESP-IDF links every component under components/ into the image, and this
20+
# component's WHOLE_ARCHIVE registration (below) is deliberately GC-proof. The
21+
# gate is off by default, so vendoring the component leaves a project's
22+
# firmware unchanged until CONFIG_ET_ENABLE is set or selected. ESP-IDF's
23+
# component-requirements scan runs this file before Kconfig is loaded, so it
24+
# only ever sees this branch; registering the same requirements here keeps
25+
# those components in the build when the component is enabled. No
26+
# INCLUDE_DIRS: including <et_model.h> while disabled fails at compile time
27+
# rather than at link time.
28+
idf_component_register(PRIV_REQUIRES ${_et_requires})
29+
return()
30+
endif()
31+
32+
# Pick the Kconfig-selected profile (default: ET_DEFAULT_PROFILE).
33+
set(_et_profile "${ET_DEFAULT_PROFILE}")
34+
foreach(_p IN LISTS ET_PROFILES)
35+
string(TOUPPER "${_p}" _p_up)
36+
if(CONFIG_ET_OP_PROFILE_${_p_up})
37+
set(_et_profile "${_p}")
38+
endif()
39+
endforeach()
40+
string(TOUPPER "${_et_profile}" _ET_UP)
41+
42+
set(_et_vendored_srcs ${ET_CORE_SRCS} ${ET_PROFILE_SRCS_${_ET_UP}}
43+
${ET_KERNEL_SRCS_${_ET_UP}}
44+
)
45+
46+
# WHOLE_ARCHIVE: kernel registration happens in static initializers in the
47+
# profile's register_kernels.cpp; normal archive extraction would drop that
48+
# translation unit (nothing references its symbols) and every operator would be
49+
# missing at load time. --gc-sections still strips unused runtime and kernel
50+
# code. src/platform/esp_pal.cpp is copied in by the generator from the shared
51+
# examples/espressif/platform/esp_pal.cpp.
52+
idf_component_register(
53+
SRCS
54+
${_et_vendored_srcs}
55+
"src/et_model.cpp"
56+
"src/platform/esp_pal.cpp"
57+
INCLUDE_DIRS
58+
"include"
59+
PRIV_REQUIRES
60+
${_et_requires}
61+
WHOLE_ARCHIVE
62+
)
63+
64+
target_compile_features(${COMPONENT_LIB} PUBLIC cxx_std_17)
65+
66+
set(_et_max_kernel_num ${ET_MAX_KERNEL_NUM_${_ET_UP}})
67+
if(CONFIG_ET_MAX_KERNEL_NUM)
68+
if(CONFIG_ET_MAX_KERNEL_NUM LESS _et_max_kernel_num)
69+
message(
70+
FATAL_ERROR
71+
"CONFIG_ET_MAX_KERNEL_NUM=${CONFIG_ET_MAX_KERNEL_NUM} is below the "
72+
"${_et_profile} profile's ${_et_max_kernel_num} kernels"
73+
)
74+
endif()
75+
set(_et_max_kernel_num ${CONFIG_ET_MAX_KERNEL_NUM})
76+
endif()
77+
78+
if(CONFIG_ET_PROGRAM_VERIFICATION)
79+
set(_et_program_verification 1)
80+
else()
81+
set(_et_program_verification 0)
82+
endif()
83+
84+
# Consumers including <executorch/...> headers need the same c10 macro mode and
85+
# flatbuffers alignment the runtime was built with. __FUNCTION__ instead of
86+
# __builtin_FUNCTION() keeps log function names without full signatures.
87+
target_compile_definitions(
88+
${COMPONENT_LIB}
89+
PUBLIC C10_USING_CUSTOM_GENERATED_MACROS FLATBUFFERS_MAX_ALIGNMENT=1024
90+
ET_USE_BUILTIN_FUNCTION_NAME=0
91+
PRIVATE MAX_KERNEL_NUM=${_et_max_kernel_num}
92+
ET_ENABLE_PROGRAM_VERIFICATION=${_et_program_verification}
93+
)
94+
95+
if(NOT CONFIG_ET_DEBUG_ASSERTS)
96+
target_compile_definitions(${COMPONENT_LIB} PRIVATE NDEBUG)
97+
endif()
98+
99+
if(CONFIG_ET_OPTIMIZE_SIZE)
100+
target_compile_options(${COMPONENT_LIB} PRIVATE -Os)
101+
endif()
102+
103+
if(NOT CONFIG_ET_ENABLE_LOGGING)
104+
target_compile_definitions(${COMPONENT_LIB} PUBLIC ET_LOG_ENABLED=0)
105+
endif()
106+
107+
# ET_MIN_LOG_LEVEL compiles out ET_LOG calls below the floor; ET_ESP_LOG_LEVEL
108+
# applies the same floor in esp_pal.cpp. ExecuTorch has no warning level, so
109+
# WARN keeps only errors.
110+
if(CONFIG_ET_LOG_LEVEL_ERROR)
111+
set(_et_min_log_level Error)
112+
set(_et_esp_log_level ESP_LOG_ERROR)
113+
elseif(CONFIG_ET_LOG_LEVEL_WARN)
114+
set(_et_min_log_level Error)
115+
set(_et_esp_log_level ESP_LOG_WARN)
116+
elseif(CONFIG_ET_LOG_LEVEL_DEBUG)
117+
set(_et_min_log_level Debug)
118+
set(_et_esp_log_level ESP_LOG_DEBUG)
119+
else() # CONFIG_ET_LOG_LEVEL_INFO (default)
120+
set(_et_min_log_level Info)
121+
set(_et_esp_log_level ESP_LOG_INFO)
122+
endif()
123+
target_compile_definitions(
124+
${COMPONENT_LIB}
125+
PUBLIC ET_MIN_LOG_LEVEL=${_et_min_log_level}
126+
PRIVATE ET_ESP_LOG_LEVEL=${_et_esp_log_level}
127+
)
128+
129+
# ESP-IDF builds with warnings-as-errors; upstream ExecuTorch sources are not
130+
# warning-clean under the IDF flag set, so demote for vendored sources only.
131+
set_source_files_properties(
132+
${_et_vendored_srcs}
133+
PROPERTIES
134+
COMPILE_OPTIONS
135+
"-Wno-error;-Wno-deprecated-declarations;-Wno-unused-parameter;-Wno-sign-compare;-Wno-unused-variable"
136+
)
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
<!--
2+
Copyright (c) Meta Platforms, Inc. and affiliates.
3+
All rights reserved.
4+
5+
This source code is licensed under the BSD-style license found in the
6+
LICENSE file in the root directory of this source tree.
7+
-->
8+
9+
# ExecuTorch for ESP-IDF (`executorch` component)
10+
11+
**This tree is generated. Do not edit it by hand.** It is produced by
12+
`examples/espressif/build_idf_component.sh` in the
13+
[ExecuTorch](https://github.com/pytorch/executorch) repository:
14+
15+
```sh
16+
executorch/examples/espressif/build_idf_component.sh \
17+
--profiles @PROFILES@ --out <this directory>
18+
```
19+
20+
`VERSION` in this directory records the ExecuTorch commit, the op
21+
profiles baked in, and each profile's op-set hash. A `.pte` is only
22+
valid against the profile whose hash its export was checked against;
23+
mismatches surface as `OperatorMissing` at load time.
24+
25+
## Using it
26+
27+
Add the component to your project's component requirements (`REQUIRES
28+
executorch`), enable it (`CONFIG_ET_ENABLE=y`, or `select ET_ENABLE`
29+
from your own Kconfig), pick an op profile in `menuconfig` (ExecuTorch -> Op
30+
profile, or `CONFIG_ET_OP_PROFILE_<NAME>=y` in your sdkconfig), then:
31+
32+
- `#include <et_model.h>` for the small C inference API (flash XIP
33+
model bytes; method, planned and optional scratch arenas either
34+
passed in or allocated with heap_caps internal/PSRAM placement). This
35+
is what most applications should use. The `.pte` bytes must be
36+
16-byte aligned; `et_model_create` rejects misaligned data. Application pipelines built on it (audio
37+
front ends, detectors, wake word logic) live with the application,
38+
not in this runtime component.
39+
- `#include <executorch/...>` for the core C++ runtime
40+
(`Program`/`Method`) and `BufferDataLoader`. `extension::Module`, the
41+
file and mmap data loaders, and external `.ptd` data maps are not
42+
included. Runtime logging goes through ESP_LOG under the
43+
`executorch` tag.
44+
45+
`CONFIG_ET_ENABLE` (default `n`) gates the whole component, so vendoring
46+
it leaves a project's firmware unchanged until it is enabled. While
47+
disabled the component registers empty and `et_model.h` is not on the
48+
include path.
49+
50+
## Op profiles
51+
52+
@PROFILE_TABLE@
53+
54+
Only the selected profile's kernels are compiled in. Switching
55+
profiles is a Kconfig change and a rebuild; no regeneration.
56+
57+
## Size and debug options
58+
59+
`CONFIG_ET_OPTIMIZE_SIZE` builds the runtime with `-Os` regardless of
60+
the project's optimization level. `CONFIG_ET_PROGRAM_VERIFICATION`
61+
compiles in full `.pte` verification, which `et_model_config_t.verify`
62+
requires. `CONFIG_ET_DEBUG_ASSERTS` keeps ExecuTorch's debug
63+
assertions (otherwise the runtime builds with `NDEBUG`).
64+
`CONFIG_ET_MAX_KERNEL_NUM` raises the kernel registry size above the
65+
profile's op count, for applications that register their own kernels.
66+
67+
## Logging
68+
69+
`CONFIG_ET_ENABLE_LOGGING=n` compiles ExecuTorch logging out entirely.
70+
Otherwise runtime messages go to ESP_LOG (tag `executorch`), and
71+
`CONFIG_ET_LOG_LEVEL_*` is a compile-time floor (`ET_MIN_LOG_LEVEL`)
72+
on top of the usual IDF runtime levels. `et_model` logs its own
73+
errors under the `et_model` tag.
74+
75+
## Updating
76+
77+
Re-run the generator against a newer ExecuTorch checkout and replace
78+
this whole directory. Review the `VERSION` diff (commit, op-set
79+
hashes, file counts, size); do not line-review vendored sources.
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
## ExecuTorch runtime for ESP-IDF.
2+
##
3+
## GENERATED by examples/espressif/build_idf_component.sh -- do not edit.
4+
## Version is "<ExecuTorch release>~<packaging revision>"; see VERSION
5+
## in this directory for the exact commit and op-set hashes. Vendored
6+
## third-party code (FlatBuffers, flatcc: Apache-2.0) is listed in
7+
## THIRD_PARTY_LICENSES. No targets list: the runtime is portable
8+
## across ESP targets.
9+
version: "@ET_COMPONENT_VERSION@"
10+
description: ExecuTorch runtime for ESP-IDF
11+
url: https://github.com/pytorch/executorch
12+
license: BSD-3-Clause
13+
dependencies:
14+
idf: ">=6.0"

0 commit comments

Comments
 (0)