diff --git a/CMakeLists.txt b/CMakeLists.txt index 1f44b650aa1..bf4bff5a2b8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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() diff --git a/extension/module/module.h b/extension/module/module.h index 08a68b2676b..66d798e7d3a 100644 --- a/extension/module/module.h +++ b/extension/module/module.h @@ -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. @@ -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. diff --git a/extension/pybindings/pybindings.cpp b/extension/pybindings/pybindings.cpp index 684a345e334..0f2ea9e9bfd 100644 --- a/extension/pybindings/pybindings.cpp +++ b/extension/pybindings/pybindings.cpp @@ -1324,7 +1324,7 @@ struct PyProgram final { std::unique_ptr 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) { @@ -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 loader = loader_from_buffer( buffer.cast().data(), py::len(buffer)); return std::make_unique( @@ -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 loader = loader_from_file(path); return std::make_unique( std::move(loader), @@ -1718,7 +1718,8 @@ 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", @@ -1726,7 +1727,8 @@ PYBIND11_MODULE(EXECUTORCH_PYTHON_MODULE_NAME, m) { 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_(m, "ExecuTorchProgram") .def("num_methods", &PyProgram::num_methods, call_guard) diff --git a/runtime/executor/program.cpp b/runtime/executor/program.cpp index 82991011127..4102d5b6eeb 100644 --- a/runtime/executor/program.cpp +++ b/runtime/executor/program.cpp @@ -20,9 +20,10 @@ #include /* - * 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 @@ -185,18 +186,15 @@ Result 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."); + 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 = diff --git a/runtime/executor/program.h b/runtime/executor/program.h index c4b96a241d7..166c15c5757 100644 --- a/runtime/executor/program.h +++ b/runtime/executor/program.h @@ -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 @@ -86,12 +86,12 @@ class Program final { */ ET_NODISCARD static Result load( DataLoader* loader, - Verification verification = Verification::Minimal); + Verification verification = Verification::InternalConsistency); /// DEPRECATED: Use the lowercase `load()` instead. ET_DEPRECATED ET_NODISCARD static Result Load( DataLoader* loader, - Verification verification = Verification::Minimal) { + Verification verification = Verification::InternalConsistency) { return load(loader, verification); } diff --git a/runtime/executor/targets.bzl b/runtime/executor/targets.bzl index 90f8d0221e9..c610f7f0f1c 100644 --- a/runtime/executor/targets.bzl +++ b/runtime/executor/targets.bzl @@ -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", diff --git a/tools/cmake/preset/default.cmake b/tools/cmake/preset/default.cmake index 423194776bc..352fcf46a3b 100644 --- a/tools/cmake/preset/default.cmake +++ b/tools/cmake/preset/default.cmake @@ -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