diff --git a/runtime/executor/method_meta.cpp b/runtime/executor/method_meta.cpp index 0af97b3fdf3..8302301220b 100644 --- a/runtime/executor/method_meta.cpp +++ b/runtime/executor/method_meta.cpp @@ -403,8 +403,14 @@ Result MethodMeta::memory_planned_buffer_device( bool MethodMeta::uses_backend(const char* backend_name) const { ET_CHECK_MSG(backend_name, "backend name is null"); const auto delegates = s_plan_->delegates(); + if (delegates == nullptr) { + return false; + } for (size_t i = 0; i < delegates->size(); i++) { auto delegate = delegates->Get(i); + if (delegate == nullptr || delegate->id() == nullptr) { + continue; + } auto backend_name_len = std::strlen(backend_name); auto delegate_id_len = delegate->id()->size(); if (backend_name_len == delegate_id_len && diff --git a/runtime/executor/test/CMakeLists.txt b/runtime/executor/test/CMakeLists.txt index 26b3f1b393f..00bfd720fd9 100644 --- a/runtime/executor/test/CMakeLists.txt +++ b/runtime/executor/test/CMakeLists.txt @@ -53,6 +53,7 @@ add_custom_command( "${CMAKE_CURRENT_BINARY_DIR}/ModuleMultipleEntry.pte" "${CMAKE_CURRENT_BINARY_DIR}/ModuleSimpleTrain.pte" "${CMAKE_CURRENT_BINARY_DIR}/ModuleStateful.pte" + "${CMAKE_CURRENT_BINARY_DIR}/ModuleAddWithDevice.pte" "${CMAKE_CURRENT_BINARY_DIR}/delegated/ModuleAddMul.pte" COMMAND ${_export_program_cmd} COMMAND @@ -62,6 +63,9 @@ add_custom_command( ${PYTHON_EXECUTABLE} -m test.models.export_delegated_program --modules "ModuleAddMul" --backend_id "StubBackend" --outdir "${CMAKE_CURRENT_BINARY_DIR}/delegated/" + COMMAND + ${PYTHON_EXECUTABLE} -m test.models.export_program_with_device_info + --outdir "${CMAKE_CURRENT_BINARY_DIR}" WORKING_DIRECTORY ${EXECUTORCH_ROOT} ) @@ -77,6 +81,7 @@ add_custom_target( "${CMAKE_CURRENT_BINARY_DIR}/ModuleMultipleEntry.pte" "${CMAKE_CURRENT_BINARY_DIR}/ModuleSimpleTrain.pte" "${CMAKE_CURRENT_BINARY_DIR}/ModuleStateful.pte" + "${CMAKE_CURRENT_BINARY_DIR}/ModuleAddWithDevice.pte" ) set(test_env @@ -92,6 +97,7 @@ set(test_env "ET_MODULE_SIMPLE_TRAIN_PATH=${CMAKE_CURRENT_BINARY_DIR}/ModuleSimpleTrain.pte" "ET_MODULE_STATEFUL_PATH=${CMAKE_CURRENT_BINARY_DIR}/ModuleStateful.pte" "ET_MODULE_ADD_MUL_DELEGATED_PATH=${CMAKE_CURRENT_BINARY_DIR}/delegated/ModuleAddMul.pte" + "ET_MODULE_ADD_WITH_DEVICE_PATH=${CMAKE_CURRENT_BINARY_DIR}/ModuleAddWithDevice.pte" ) et_cxx_test( @@ -130,8 +136,16 @@ et_cxx_test( add_dependencies(method_test generated_pte_files) set_property(TEST method_test PROPERTY ENVIRONMENT ${test_env}) -# TODO(T191569140): Enable this test. et_cxx_test(method_meta_test SOURCES -# method_meta_test.cpp EXTRA_LIBS extension_data_loader) +et_cxx_test( + method_meta_test + SOURCES + method_meta_test.cpp + EXTRA_LIBS + extension_data_loader + program_schema +) +add_dependencies(method_meta_test generated_pte_files) +set_property(TEST method_meta_test PROPERTY ENVIRONMENT ${test_env}) et_cxx_test( program_test SOURCES program_test.cpp EXTRA_LIBS extension_data_loader diff --git a/runtime/executor/test/method_meta_test.cpp b/runtime/executor/test/method_meta_test.cpp index 1324a40cf52..971522bdfcf 100644 --- a/runtime/executor/test/method_meta_test.cpp +++ b/runtime/executor/test/method_meta_test.cpp @@ -12,9 +12,12 @@ #include #include +#include #include #include #include +#include +#include #include #include @@ -25,6 +28,7 @@ using executorch::runtime::Program; using executorch::runtime::Result; using executorch::runtime::Span; using executorch::runtime::TensorInfo; +using torch::executor::util::BufferDataLoader; using torch::executor::util::FileDataLoader; namespace executorch { @@ -72,6 +76,9 @@ class MethodMetaTest : public ::testing::Test { } void SetUp() override { + // Required to initialize the PAL timer before tests trigger ET_LOG calls in + // et_pal_current_ticks(). + executorch::runtime::runtime_init(); load_program(std::getenv("ET_MODULE_ADD_PATH"), "add"); load_program(std::getenv("ET_MODULE_STATEFUL_PATH"), "stateful"); const char* device_path = std::getenv("ET_MODULE_ADD_WITH_DEVICE_PATH"); @@ -275,3 +282,58 @@ TEST_F(MethodMetaTest, MethodMetaBufferDeviceReturnsCudaForDeviceBuffer) { method_meta->memory_planned_buffer_device(2).error(), Error::InvalidArgument); } + +TEST_F(MethodMetaTest, UsesBackendOnUnsetDelegatesReturnsFalse) { + // Construct a minimal schema-valid FlatBuffer program where delegates is + // unset (nullptr). + flatbuffers::FlatBufferBuilder fbb; + std::vector empty_inputs = {}; + std::vector empty_outputs = {}; + std::vector non_const_buffer_sizes = {0}; + auto plan = executorch_flatbuffer::CreateExecutionPlanDirect( + fbb, + /*name=*/"forward", + /*container_meta_type=*/0, + /*values=*/nullptr, + /*inputs=*/&empty_inputs, + /*outputs=*/&empty_outputs, + /*chains=*/nullptr, + /*operators=*/nullptr, + /*delegates=*/nullptr, + /*non_const_buffer_sizes=*/&non_const_buffer_sizes, + /*non_const_buffer_device=*/nullptr); + std::vector> plans = + {plan}; + + auto const_offsets = fbb.CreateVector(std::vector{0}); + auto constant_segment = executorch_flatbuffer::CreateSubsegmentOffsets( + fbb, /*segment_index=*/0, const_offsets); + std::vector> + segments = {executorch_flatbuffer::CreateDataSegment( + fbb, /*offset=*/0, /*size=*/0)}; + + auto program = executorch_flatbuffer::CreateProgramDirect( + fbb, + /*version=*/Program::kMaxSupportedSchemaVersion, + /*execution_plan=*/&plans, + /*constant_buffer=*/nullptr, + /*backend_delegate_data=*/nullptr, + /*segments=*/&segments, + /*constant_segment=*/constant_segment); + executorch_flatbuffer::FinishProgramBuffer(fbb, program); + + std::vector buffer( + fbb.GetBufferPointer(), fbb.GetBufferPointer() + fbb.GetSize()); + if (buffer.size() < Program::kMinHeadBytes) { + buffer.resize(Program::kMinHeadBytes, 0); + } + + BufferDataLoader loader(buffer.data(), buffer.size()); + Result prog = Program::load(&loader, Program::Verification::Minimal); + ASSERT_EQ(prog.error(), Error::Ok); + + Result method_meta = prog->method_meta("forward"); + ASSERT_EQ(method_meta.error(), Error::Ok); + + EXPECT_FALSE(method_meta->uses_backend("xnnpack")); +} diff --git a/runtime/executor/test/targets.bzl b/runtime/executor/test/targets.bzl index 8d397847ec1..822928de341 100644 --- a/runtime/executor/test/targets.bzl +++ b/runtime/executor/test/targets.bzl @@ -177,7 +177,9 @@ def define_common_targets(is_fbcode = False): ], deps = [ "//executorch/runtime/executor:program", + "//executorch/extension/data_loader:buffer_data_loader", "//executorch/extension/data_loader:file_data_loader", + "//executorch/schema:program", ], env = dict( modules_env,