|  | 
| 1 | 1 | /* | 
| 2 | 2 |  * Copyright (c) Meta Platforms, Inc. and affiliates. | 
| 3 | 3 |  * All rights reserved. | 
|  | 4 | + * Copyright 2025 Arm Limited and/or its affiliates. | 
| 4 | 5 |  * | 
| 5 | 6 |  * This source code is licensed under the BSD-style license found in the | 
| 6 | 7 |  * LICENSE file in the root directory of this source tree. | 
| 7 | 8 |  */ | 
| 8 | 9 | 
 | 
|  | 10 | +#include <executorch/runtime/platform/assert.h> | 
|  | 11 | +#include <executorch/schema/program_generated.h> | 
| 9 | 12 | #include <pybind11/pybind11.h> | 
| 10 | 13 | #include <pybind11/stl.h> | 
| 11 | 14 | 
 | 
| 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 | 
| 14 | 19 | 
 | 
| 15 | 20 | namespace py = pybind11; | 
| 16 | 21 | 
 | 
| @@ -186,8 +191,39 @@ get_kernel_tensor_metadatas_from_execution_plan( | 
| 186 | 191 | 
 | 
| 187 | 192 | const executorch_flatbuffer::Program* _get_program_from_buffer( | 
| 188 | 193 |     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). | 
| 189 | 225 |   return executorch_flatbuffer::GetProgram( | 
| 190 |  | -      buffer.cast<std::string_view>().data()); | 
|  | 226 | +      reinterpret_cast<const uint8_t*>(sv.data())); | 
| 191 | 227 | } | 
| 192 | 228 | 
 | 
| 193 | 229 | py::list _get_program_operators(const executorch_flatbuffer::Program* program) { | 
|  | 
0 commit comments