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
8 changes: 5 additions & 3 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -183,9 +183,11 @@ endif()
add_definitions(-DET_MIN_LOG_LEVEL=${ET_MIN_LOG_LEVEL})

if(NOT EXECUTORCH_ENABLE_PROGRAM_VERIFICATION)
# Avoid pulling in the flatbuffer data verification logic, which can add about
# 20kB. Note that this will set the compiler flag for all targets in this
# directory, and for all subdirectories included after this point.
# Disabling program verification saves ~4kB (stripped) by removing the
# flatbuffer data verification logic. Note that this will set the compiler
# flag for all targets in this directory, and for all subdirectories included
# after this point. When disabled, requesting
# Verification::InternalConsistency at runtime will return an error.
add_definitions(-DET_ENABLE_PROGRAM_VERIFICATION=0)
endif()

Expand Down
4 changes: 2 additions & 2 deletions extension/module/module.h
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ class Module {
*/
ET_NODISCARD virtual runtime::Error load(
const Program::Verification verification =
Program::Verification::Minimal);
Program::Verification::InternalConsistency);

/**
* Loads the program with per-delegate runtime options.
Expand All @@ -196,7 +196,7 @@ class Module {
ET_NODISCARD virtual runtime::Error load(
const LoadBackendOptionsMap& backend_options,
const Program::Verification verification =
Program::Verification::Minimal);
Program::Verification::InternalConsistency);

/**
* Checks if the program is loaded.
Expand Down
12 changes: 7 additions & 5 deletions extension/pybindings/pybindings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1324,7 +1324,7 @@ struct PyProgram final {
std::unique_ptr<ETDumpGen> tracer = nullptr,
size_t debug_buffer_size = 0,
Program::Verification program_verification =
Program::Verification::Minimal)
Program::Verification::InternalConsistency)
: state_(load_program(std::move(loader), program_verification)),
event_tracer_(std::move(tracer)),
debug_buffer_size_(debug_buffer_size) {
Expand Down Expand Up @@ -1371,7 +1371,7 @@ struct PyProgram final {
bool enable_etdump,
size_t debug_buffer_size,
Program::Verification program_verification =
Program::Verification::Minimal) {
Program::Verification::InternalConsistency) {
std::unique_ptr<DataLoader> loader = loader_from_buffer(
buffer.cast<std::string_view>().data(), py::len(buffer));
return std::make_unique<PyProgram>(
Expand All @@ -1387,7 +1387,7 @@ struct PyProgram final {
bool enable_etdump,
size_t debug_buffer_size,
Program::Verification program_verification =
Program::Verification::Minimal) {
Program::Verification::InternalConsistency) {
std::unique_ptr<DataLoader> loader = loader_from_file(path);
return std::make_unique<PyProgram>(
std::move(loader),
Expand Down Expand Up @@ -1718,15 +1718,17 @@ PYBIND11_MODULE(EXECUTORCH_PYTHON_MODULE_NAME, m) {
py::arg("path"),
py::arg("enable_etdump") = false,
py::arg("debug_buffer_size") = 0,
py::arg("program_verification") = Program::Verification::Minimal,
py::arg("program_verification") =
Program::Verification::InternalConsistency,
call_guard);
m.def(
"_load_program_from_buffer",
&PyProgram::load_from_buffer,
py::arg("buffer"),
py::arg("enable_etdump") = false,
py::arg("debug_buffer_size") = 0,
py::arg("program_verification") = Program::Verification::Minimal,
py::arg("program_verification") =
Program::Verification::InternalConsistency,
call_guard);
py::class_<PyProgram>(m, "ExecuTorchProgram")
.def("num_methods", &PyProgram::num_methods, call_guard)
Expand Down
22 changes: 10 additions & 12 deletions runtime/executor/program.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,10 @@
#include <executorch/schema/program_generated.h>

/*
* Program verification can increase code size by ~30k. Targets that need to
* save this space can avoid building it by passing
* -DET_ENABLE_PROGRAM_VERIFICATION=0 on the compile line.
* Program verification adds ~8kB to .text (~4kB stripped). Targets that need
* to save this space can avoid building it by passing
* -DET_ENABLE_PROGRAM_VERIFICATION=0 on the compile line. When disabled,
* requesting Verification::InternalConsistency will return Error::NotSupported.
*/
#ifndef ET_ENABLE_PROGRAM_VERIFICATION
#define ET_ENABLE_PROGRAM_VERIFICATION 1
Expand Down Expand Up @@ -185,18 +186,15 @@ Result<executorch_flatbuffer::ExecutionPlan*> get_execution_plan(
"Program validation failed: likely a corrupt file");
#else
ET_LOG(
Info,
"InternalConsistency verification requested but not available; "
"falling back to Minimal verification. "
"Build with ET_ENABLE_PROGRAM_VERIFICATION=1 for full verification.");
Error,
"InternalConsistency verification requested but not available. "
"Build with ET_ENABLE_PROGRAM_VERIFICATION=1 or "
"use Verification::Minimal to skip verification.");
Copy link

Copilot AI Apr 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The error text says "use Verification::Minimal to skip verification", but Minimal still performs basic checks (e.g., root table offset bounds check below). Consider rewording to avoid implying verification is entirely skipped (e.g., "use Verification::Minimal for basic verification" / "reduced verification").

Suggested change
"use Verification::Minimal to skip verification.");
"use Verification::Minimal for basic verification.");

Copilot uses AI. Check for mistakes.
return Error::NotSupported;
#endif
}

if (verification == Verification::Minimal
#if !ET_ENABLE_PROGRAM_VERIFICATION
|| verification == Verification::InternalConsistency
#endif
) {
if (verification == Verification::Minimal) {
// Verify that the root table offset is within bounds.
// In InternalConsistency mode this is done by VerifyProgramBuffer above.
uint32_t root_offset =
Expand Down
6 changes: 3 additions & 3 deletions runtime/executor/program.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ class Program final {
*/
Minimal,
/**
* When ET_ENABLE_PROGRAM_VERIFICATION is enabled,
* When ET_ENABLE_PROGRAM_VERIFICATION is enabled (the default),
* Do full verification of the data, ensuring that internal pointers are
* self-consistent and that the data has not been truncated or obviously
* corrupted. May not catch all types of corruption, but should guard
Expand Down Expand Up @@ -86,12 +86,12 @@ class Program final {
*/
ET_NODISCARD static Result<Program> load(
DataLoader* loader,
Verification verification = Verification::Minimal);
Verification verification = Verification::InternalConsistency);

Comment on lines 87 to 90
Copy link

Copilot AI Apr 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With the default argument now set to Verification::InternalConsistency, building with ET_ENABLE_PROGRAM_VERIFICATION=0 (or equivalent build option) will make Program::load(loader) fail with Error::NotSupported unless callers explicitly pass Verification::Minimal. If the goal is that space-constrained builds can "opt out" purely via the build flag, consider making the default conditional on ET_ENABLE_PROGRAM_VERIFICATION (or introducing a "Default" mode) or documenting this behavior prominently.

Copilot uses AI. Check for mistakes.
/// DEPRECATED: Use the lowercase `load()` instead.
ET_DEPRECATED ET_NODISCARD static Result<Program> Load(
DataLoader* loader,
Verification verification = Verification::Minimal) {
Verification verification = Verification::InternalConsistency) {
return load(loader, verification);
}

Expand Down
7 changes: 4 additions & 3 deletions runtime/executor/targets.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@ load("@fbsource//xplat/executorch/build:runtime_wrapper.bzl", "get_aten_mode_opt
def _program_preprocessor_flags():
"""Returns the preprocessor_flags to use when building Program.cpp"""

# The code for flatbuffer verification can add ~30k of .text to the binary.
# It's a valuable feature, but make it optional for space-constrained
# systems.
# The code for flatbuffer verification adds ~8kB of .text (~4kB stripped).
# It's enabled by default, but can be disabled for space-constrained
# systems. When disabled, requesting InternalConsistency verification
# will return Error::NotSupported.
enable_verification = native.read_config(
"executorch",
"enable_program_verification",
Expand Down
2 changes: 1 addition & 1 deletion tools/cmake/preset/default.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ define_overridable_option(
)
define_overridable_option(
EXECUTORCH_ENABLE_PROGRAM_VERIFICATION
"Build with ET_ENABLE_PROGRAM_VERIFICATION" BOOL ${_is_build_type_debug}
"Build with ET_ENABLE_PROGRAM_VERIFICATION" BOOL ON
)
define_overridable_option(
EXECUTORCH_ENABLE_EVENT_TRACER "Build with ET_EVENT_TRACER_ENABLED" BOOL OFF
Expand Down
Loading