Skip to content

Commit ed41d21

Browse files
committed
[executorch][runtime] Add NamedDataMap to method load
Add NamedDataMap as an arg to: - Method - load_method - parseTensor Use NamedDataMap to resolve external tensors in parseTensor. Test that the PTE + PTD file run well inside method_test. Differential Revision: [D67127327](https://our.internmc.facebook.com/intern/diff/D67127327/) [ghstack-poisoned]
1 parent 6783e4e commit ed41d21

File tree

13 files changed

+152
-20
lines changed

13 files changed

+152
-20
lines changed

extension/flat_tensor/test/targets.bzl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,8 @@ def define_common_targets(is_fbcode=False):
3535
# The tests use this var to find the program file to load. This uses
3636
# an fbcode target path because the authoring/export tools
3737
# intentionally don't work in xplat (since they're host-only tools).
38-
"ET_MODULE_LINEAR_PROGRAM": "$(location fbcode//executorch/test/models:exported_programs_with_data_separated[ModuleLinear.pte])",
39-
"ET_MODULE_LINEAR_DATA": "$(location fbcode//executorch/test/models:exported_programs_with_data_separated[ModuleLinear.ptd])",
38+
"ET_MODULE_LINEAR_PROGRAM": "$(location fbcode//executorch/test/models:exported_program_and_data[ModuleLinear.pte])",
39+
"ET_MODULE_LINEAR_DATA": "$(location fbcode//executorch/test/models:exported_program_and_data[ModuleLinear.ptd])",
4040
}
4141

4242
runtime.cxx_test(

runtime/executor/method.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include <executorch/runtime/backend/interface.h>
1717
#include <executorch/runtime/core/event_tracer_hooks.h>
1818
#include <executorch/runtime/core/exec_aten/util/tensor_util.h>
19+
#include <executorch/runtime/core/named_data_map.h>
1920
#include <executorch/runtime/core/span.h>
2021
#include <executorch/runtime/executor/memory_manager.h>
2122
#include <executorch/runtime/executor/platform_memory_allocator.h>
@@ -414,7 +415,8 @@ Error Method::parse_values() {
414415
auto t = deserialization::parseTensor(
415416
program_,
416417
memory_manager_,
417-
static_cast<const executorch_flatbuffer::Tensor*>(val));
418+
static_cast<const executorch_flatbuffer::Tensor*>(val),
419+
named_data_map_);
418420
if (!t.ok()) {
419421
ET_LOG(
420422
Error,
@@ -607,7 +609,8 @@ Result<Method> Method::load(
607609
executorch_flatbuffer::ExecutionPlan* s_plan,
608610
const Program* program,
609611
MemoryManager* memory_manager,
610-
EventTracer* event_tracer) {
612+
EventTracer* event_tracer,
613+
const NamedDataMap* named_data_map) {
611614
MemoryAllocator* temp_allocator = memory_manager->temp_allocator();
612615
if (temp_allocator == nullptr) {
613616
PlatformMemoryAllocator* platform_allocator =
@@ -619,7 +622,8 @@ Result<Method> Method::load(
619622
new (platform_allocator) PlatformMemoryAllocator();
620623
temp_allocator = platform_allocator;
621624
}
622-
Method method(program, memory_manager, event_tracer, temp_allocator);
625+
Method method(
626+
program, memory_manager, event_tracer, temp_allocator, named_data_map);
623627

624628
Error err = method.init(s_plan);
625629
if (err != Error::Ok) {

runtime/executor/method.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include <executorch/runtime/core/evalue.h>
1212
#include <executorch/runtime/core/event_tracer.h>
1313
#include <executorch/runtime/core/exec_aten/exec_aten.h>
14+
#include <executorch/runtime/core/named_data_map.h>
1415
#include <executorch/runtime/core/span.h>
1516
#include <executorch/runtime/executor/memory_manager.h>
1617
#include <executorch/runtime/executor/method_meta.h>
@@ -54,6 +55,7 @@ class Method final {
5455
program_(rhs.program_),
5556
memory_manager_(rhs.memory_manager_),
5657
temp_allocator_(rhs.temp_allocator_),
58+
named_data_map_(rhs.named_data_map_),
5759
serialization_plan_(rhs.serialization_plan_),
5860
event_tracer_(rhs.event_tracer_),
5961
n_value_(rhs.n_value_),
@@ -271,11 +273,13 @@ class Method final {
271273
const Program* program,
272274
MemoryManager* memory_manager,
273275
EventTracer* event_tracer,
274-
MemoryAllocator* temp_allocator)
276+
MemoryAllocator* temp_allocator,
277+
const NamedDataMap* named_data_map)
275278
: step_state_(),
276279
program_(program),
277280
memory_manager_(memory_manager),
278281
temp_allocator_(temp_allocator),
282+
named_data_map_(named_data_map),
279283
serialization_plan_(nullptr),
280284
event_tracer_(event_tracer),
281285
n_value_(0),
@@ -291,7 +295,8 @@ class Method final {
291295
executorch_flatbuffer::ExecutionPlan* s_plan,
292296
const Program* program,
293297
MemoryManager* memory_manager,
294-
EventTracer* event_tracer);
298+
EventTracer* event_tracer,
299+
const NamedDataMap* named_data_map);
295300

296301
/**
297302
* Initialize the method from its serialized representation.
@@ -317,6 +322,7 @@ class Method final {
317322
const Program* program_;
318323
MemoryManager* memory_manager_;
319324
MemoryAllocator* temp_allocator_;
325+
const NamedDataMap* named_data_map_;
320326
executorch_flatbuffer::ExecutionPlan* serialization_plan_;
321327
EventTracer* event_tracer_;
322328

runtime/executor/program.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,8 @@ Result<const char*> Program::get_method_name(size_t plan_index) const {
240240
Result<Method> Program::load_method(
241241
const char* method_name,
242242
MemoryManager* memory_manager,
243-
EventTracer* event_tracer) const {
243+
EventTracer* event_tracer,
244+
const NamedDataMap* named_data_map) const {
244245
EXECUTORCH_SCOPE_PROF("Program::load_method");
245246
internal::event_tracer_create_event_block(event_tracer, "Default");
246247
internal::EventTracerProfileMethodScope event_tracer_scope =
@@ -257,7 +258,8 @@ Result<Method> Program::load_method(
257258
if (!plan.ok()) {
258259
return plan.error();
259260
}
260-
return Method::load(plan.get(), this, memory_manager, event_tracer);
261+
return Method::load(
262+
plan.get(), this, memory_manager, event_tracer, named_data_map);
261263
}
262264

263265
Result<MethodMeta> Program::method_meta(const char* method_name) const {

runtime/executor/program.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,8 @@ class Program final {
132132
Result<Method> load_method(
133133
const char* method_name,
134134
MemoryManager* memory_manager,
135-
EventTracer* event_tracer = nullptr) const;
135+
EventTracer* event_tracer = nullptr,
136+
const NamedDataMap* named_data_map = nullptr) const;
136137

137138
/**
138139
* Gathers metadata for the named method.

runtime/executor/targets.bzl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ def define_common_targets():
7979
":memory_manager",
8080
"//executorch/runtime/backend:interface",
8181
"//executorch/runtime/core:core",
82+
"//executorch/runtime/core:named_data_map",
8283
"//executorch/runtime/core:evalue" + aten_suffix,
8384
"//executorch/runtime/core:event_tracer" + aten_suffix,
8485
"//executorch/runtime/core/exec_aten:lib" + aten_suffix,

runtime/executor/tensor_parser.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@ namespace deserialization {
2121
ET_NODISCARD Result<executorch::aten::Tensor> parseTensor(
2222
const Program* program,
2323
MemoryManager* memory_manager,
24-
const executorch_flatbuffer::Tensor* s_tensor);
24+
const executorch_flatbuffer::Tensor* s_tensor,
25+
const NamedDataMap* named_data_map = nullptr);
2526

2627
ET_NODISCARD Result<BoxedEvalueList<executorch::aten::Tensor>> parseTensorList(
2728
const flatbuffers::Vector<int32_t>* tensor_indices,
@@ -108,7 +109,8 @@ ET_NODISCARD Result<void*> getTensorDataPtr(
108109
const executorch_flatbuffer::Tensor* s_tensor,
109110
const Program* program,
110111
size_t nbytes,
111-
HierarchicalAllocator* allocator);
112+
HierarchicalAllocator* allocator,
113+
const NamedDataMap* named_data_map = nullptr);
112114

113115
} // namespace deserialization
114116
} // namespace runtime

runtime/executor/tensor_parser_aten.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
#include <executorch/runtime/core/exec_aten/util/dim_order_util.h>
1212
#include <executorch/runtime/core/exec_aten/util/scalar_type_util.h>
13+
#include <executorch/runtime/core/named_data_map.h>
1314
#include <executorch/runtime/executor/memory_manager.h>
1415
#include <executorch/runtime/executor/program.h>
1516
#include <executorch/runtime/platform/profiler.h>
@@ -31,7 +32,8 @@ void deleteNothing(void*) {}
3132
Result<at::Tensor> parseTensor(
3233
const Program* program,
3334
MemoryManager* memory_manager,
34-
const executorch_flatbuffer::Tensor* s_tensor) {
35+
const executorch_flatbuffer::Tensor* s_tensor,
36+
const NamedDataMap* named_data_map) {
3537
EXECUTORCH_SCOPE_PROF("TensorParser::parseTensor");
3638

3739
ET_CHECK_OR_RETURN_ERROR(
@@ -102,7 +104,11 @@ Result<at::Tensor> parseTensor(
102104
} else {
103105
// Now that we know how big the tensor is, find and assign its memory.
104106
Result<void*> data_ptr = getTensorDataPtr(
105-
s_tensor, program, tensor.nbytes(), memory_manager->planned_memory());
107+
s_tensor,
108+
program,
109+
tensor.nbytes(),
110+
memory_manager->planned_memory(),
111+
named_data_map);
106112
if (!data_ptr.ok()) {
107113
ET_LOG(
108114
Error,

runtime/executor/tensor_parser_exec_aten.cpp

Lines changed: 74 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ namespace executorch {
1919
namespace runtime {
2020
namespace deserialization {
2121

22+
using executorch::aten::ScalarType;
23+
using executorch::runtime::TensorLayout;
2224
// Provides access to private Program methods.
2325
class TensorParser final {
2426
public:
@@ -113,7 +115,8 @@ ET_NODISCARD Result<void*> getTensorDataPtr(
113115
const executorch_flatbuffer::Tensor* s_tensor,
114116
const Program* program,
115117
size_t nbytes,
116-
HierarchicalAllocator* allocator) {
118+
HierarchicalAllocator* allocator,
119+
const NamedDataMap* named_data_map) {
117120
auto data_buffer_idx = s_tensor->data_buffer_idx();
118121
const executorch_flatbuffer::AllocationDetails* allocation_info =
119122
s_tensor->allocation_info();
@@ -132,8 +135,76 @@ ET_NODISCARD Result<void*> getTensorDataPtr(
132135
}
133136
return planned_ptr;
134137

135-
// Constant
136-
} else if (data_buffer_idx > 0 && allocation_info == nullptr) {
138+
}
139+
// Constant, stored externally.
140+
else if (
141+
allocation_info == nullptr && s_tensor->extra_tensor_info() != nullptr &&
142+
s_tensor->extra_tensor_info()->location() ==
143+
executorch_flatbuffer::TensorDataLocation::EXTERNAL) {
144+
// Check that fqn is not null.
145+
ET_CHECK_OR_RETURN_ERROR(
146+
s_tensor->extra_tensor_info()->fully_qualified_name() != nullptr,
147+
InvalidExternalData,
148+
"Fully qualified name of external tensor is null");
149+
// Look up tensor in named data map.
150+
Result<const TensorLayout> tensor_layout_res = named_data_map->get_metadata(
151+
s_tensor->extra_tensor_info()->fully_qualified_name()->c_str());
152+
if (!tensor_layout_res.ok()) {
153+
return tensor_layout_res.error();
154+
}
155+
const TensorLayout& tensor_layout = tensor_layout_res.get();
156+
157+
// Compatibility checking.
158+
ET_CHECK_OR_RETURN_ERROR(
159+
static_cast<ScalarType>(s_tensor->scalar_type()) ==
160+
tensor_layout.scalar_type(),
161+
InvalidExternalData,
162+
"Scalar type mismatch. Expected %hhd, got %hhd.",
163+
static_cast<int8_t>(s_tensor->scalar_type()),
164+
static_cast<int8_t>(tensor_layout.scalar_type()));
165+
ET_CHECK_OR_RETURN_ERROR(
166+
nbytes == tensor_layout.nbytes(),
167+
InvalidExternalData,
168+
"Nbytes mismatch. Expected %zu, got %zu.",
169+
nbytes,
170+
tensor_layout.nbytes());
171+
int dim = s_tensor->sizes()->size();
172+
ET_CHECK_OR_RETURN_ERROR(
173+
dim == tensor_layout.sizes().size(),
174+
InvalidExternalData,
175+
"Dim mismatch. Expected %d, got %zu.",
176+
dim,
177+
tensor_layout.sizes().size());
178+
for (int i = 0; i < dim; i++) {
179+
ET_CHECK_OR_RETURN_ERROR(
180+
s_tensor->sizes()->Get(i) == tensor_layout.sizes()[i],
181+
InvalidExternalData,
182+
"Sizes mismatch. Expected %d, got %d for size at index %d.",
183+
s_tensor->sizes()->Get(i),
184+
tensor_layout.sizes()[i],
185+
i);
186+
ET_CHECK_OR_RETURN_ERROR(
187+
s_tensor->dim_order()->Get(i) == tensor_layout.dim_order()[i],
188+
InvalidExternalData,
189+
"Dim order mismatch. Expected %d, got %d for dim at index %d.",
190+
s_tensor->dim_order()->Get(i),
191+
tensor_layout.dim_order()[i],
192+
i);
193+
}
194+
195+
Result<FreeableBuffer> data_res = named_data_map->get_data(
196+
s_tensor->extra_tensor_info()->fully_qualified_name()->c_str());
197+
if (!data_res.ok()) {
198+
return data_res.error();
199+
}
200+
// The const_cast is 'ok' here because program and runtime should guarantee
201+
// that this data is never modified. Temporary until we introduce the
202+
// `get_and_persist_data` API from TODO(T214294528).
203+
return const_cast<void*>(static_cast<const void*>(data_res.get().data()));
204+
}
205+
206+
// Constant, stored in PTE file.
207+
else if (data_buffer_idx > 0 && allocation_info == nullptr) {
137208
auto const_data =
138209
program->get_constant_buffer_data(data_buffer_idx, nbytes);
139210
if (!const_data.ok()) {

runtime/executor/tensor_parser_portable.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include <executorch/runtime/core/exec_aten/exec_aten.h>
1212
#include <executorch/runtime/core/exec_aten/util/dim_order_util.h>
1313
#include <executorch/runtime/core/exec_aten/util/scalar_type_util.h>
14+
#include <executorch/runtime/core/named_data_map.h>
1415
#include <executorch/runtime/executor/memory_manager.h>
1516
#include <executorch/runtime/executor/program.h>
1617
#include <executorch/runtime/platform/profiler.h>
@@ -27,7 +28,8 @@ using torch::executor::TensorImpl;
2728
Result<Tensor> parseTensor(
2829
const Program* program,
2930
MemoryManager* memory_manager,
30-
const executorch_flatbuffer::Tensor* s_tensor) {
31+
const executorch_flatbuffer::Tensor* s_tensor,
32+
const NamedDataMap* named_data_map) {
3133
EXECUTORCH_SCOPE_PROF("TensorParser::parseTensor");
3234
auto method_allocator = memory_manager->method_allocator();
3335

@@ -146,7 +148,8 @@ Result<Tensor> parseTensor(
146148
s_tensor,
147149
program,
148150
tensor_impl->nbytes(),
149-
memory_manager->planned_memory());
151+
memory_manager->planned_memory(),
152+
named_data_map);
150153
if (!data_ptr.ok()) {
151154
ET_LOG(
152155
Error,

0 commit comments

Comments
 (0)