Skip to content

Commit 5041fa1

Browse files
committed
Make _get_program_from_buffer work for bundled programs
Add some cmake to only do this if executorch is built with bundleio. codegen/tools subdirectory needs to be moved in top-level CmakeLists.txt to have access to the bundled_program target. Signed-off-by: Erik Lundell <[email protected]> Change-Id: Ic953bdfd5223eb835e46150bde19b08b082e8444
1 parent 7e228ee commit 5041fa1

File tree

3 files changed

+47
-6
lines changed

3 files changed

+47
-6
lines changed

CMakeLists.txt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -738,9 +738,6 @@ endif()
738738

739739
if(EXECUTORCH_BUILD_PYBIND)
740740

741-
# Add codegen tools subdirectory for selective_build pybind module
742-
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/codegen/tools)
743-
744741
if(NOT EXECUTORCH_BUILD_EXTENSION_DATA_LOADER)
745742
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/extension/data_loader)
746743
endif()
@@ -749,6 +746,9 @@ if(EXECUTORCH_BUILD_PYBIND)
749746
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/devtools)
750747
endif()
751748

749+
# Add codegen tools subdirectory for selective_build pybind module
750+
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/codegen/tools)
751+
752752
# Create bundled_module target only for pybindings when bundled_program exists
753753
# This target has hard dependencies on devtools generated headers
754754
if(TARGET bundled_program)

codegen/tools/CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# Copyright (c) Meta Platforms, Inc. and affiliates.
22
# All rights reserved.
3+
# Copyright 2025 Arm Limited and/or its affiliates.
34
#
45
# This source code is licensed under the BSD-style license found in the
56
# LICENSE file in the root directory of this source tree.
@@ -28,6 +29,10 @@ target_compile_options(
2829
)
2930

3031
# Link against required libraries
32+
if(TARGET bundled_program)
33+
target_compile_definitions(selective_build PRIVATE -DET_BUNDLE_IO)
34+
target_link_libraries(selective_build PRIVATE bundled_program)
35+
endif()
3136
target_link_libraries(selective_build PRIVATE executorch_core program_schema)
3237

3338
# Install the module

codegen/tools/selective_build.cpp

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,21 @@
11
/*
22
* Copyright (c) Meta Platforms, Inc. and affiliates.
33
* All rights reserved.
4+
* Copyright 2025 Arm Limited and/or its affiliates.
45
*
56
* This source code is licensed under the BSD-style license found in the
67
* LICENSE file in the root directory of this source tree.
78
*/
89

10+
#include <executorch/runtime/platform/assert.h>
11+
#include <executorch/schema/program_generated.h>
912
#include <pybind11/pybind11.h>
1013
#include <pybind11/stl.h>
1114

12-
#include <executorch/runtime/platform/assert.h>
13-
#include <executorch/schema/program_generated.h>
15+
#ifdef ET_BUNDLE_IO
16+
#include <executorch/devtools/bundled_program/bundled_program.h>
17+
#include <stdexcept>
18+
#endif
1419

1520
namespace py = pybind11;
1621

@@ -186,8 +191,39 @@ get_kernel_tensor_metadatas_from_execution_plan(
186191

187192
const executorch_flatbuffer::Program* _get_program_from_buffer(
188193
const py::bytes& buffer) {
194+
// Access the Python bytes without copying and get raw pointer/size.
195+
const std::string_view sv = buffer.cast<std::string_view>();
196+
void* buf_ptr = const_cast<void*>(static_cast<const void*>(sv.data()));
197+
const size_t buf_len = sv.size();
198+
#ifdef ET_BUNDLE_IO
199+
200+
// If this is a bundled program, extract the inner ExecuTorch program bytes.
201+
if (executorch::bundled_program::is_bundled_program(buf_ptr, buf_len)) {
202+
const void* program_data = nullptr;
203+
size_t program_size = 0;
204+
205+
const auto status = executorch::bundled_program::get_program_data(
206+
buf_ptr, // serialized BundledProgram start
207+
buf_len, // total size of the BundledProgram blob
208+
&program_data, // [out] pointer to inner .pte bytes
209+
&program_size // [out] size of inner .pte bytes
210+
);
211+
212+
if (status != ::executorch::runtime::Error::Ok || program_data == nullptr ||
213+
program_size == 0) {
214+
throw std::runtime_error(
215+
"bundled_program::get_program_data() failed or returned empty data");
216+
}
217+
218+
// program_data points directly at the flatbuffer-encoded Program region.
219+
return executorch_flatbuffer::GetProgram(
220+
reinterpret_cast<const uint8_t*>(program_data));
221+
}
222+
#endif
223+
// Otherwise treat the buffer as a raw .pte (flatbuffer Program with optional
224+
// extended header).
189225
return executorch_flatbuffer::GetProgram(
190-
buffer.cast<std::string_view>().data());
226+
reinterpret_cast<const uint8_t*>(sv.data()));
191227
}
192228

193229
py::list _get_program_operators(const executorch_flatbuffer::Program* program) {

0 commit comments

Comments
 (0)