Skip to content

Commit f6af4ae

Browse files
JakeStevensfacebook-github-bot
authored andcommitted
Update EVal Payload to use pointers for larger objects
Summary: As noted in the comment, switching to ptrs in the union can save memory. Specifically, the size of this object goes from 24 bytes -> 8 bytes. In this diff, we move to pointers for some of the larger objects. When parsing the flatbuffer, we allocate memory from the method allocator and store this in the EVal. The get* functions then de-reference that pointer. Differential Revision: D79286076
1 parent 0b40181 commit f6af4ae

File tree

2 files changed

+66
-38
lines changed

2 files changed

+66
-38
lines changed

runtime/core/evalue.h

Lines changed: 28 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -94,15 +94,14 @@ struct EValue {
9494
int64_t as_int;
9595
double as_double;
9696
bool as_bool;
97-
// TODO(jakeszwe): convert back to pointers to optimize size of this
98-
// struct
99-
executorch::aten::ArrayRef<char> as_string;
100-
executorch::aten::ArrayRef<double> as_double_list;
101-
executorch::aten::ArrayRef<bool> as_bool_list;
102-
BoxedEvalueList<int64_t> as_int_list;
103-
BoxedEvalueList<executorch::aten::Tensor> as_tensor_list;
104-
BoxedEvalueList<std::optional<executorch::aten::Tensor>>
105-
as_list_optional_tensor;
97+
98+
executorch::aten::ArrayRef<char>* as_string_ptr;
99+
executorch::aten::ArrayRef<double>* as_double_list_ptr;
100+
executorch::aten::ArrayRef<bool>* as_bool_list_ptr;
101+
BoxedEvalueList<int64_t>* as_int_list_ptr;
102+
BoxedEvalueList<executorch::aten::Tensor>* as_tensor_list_ptr;
103+
BoxedEvalueList<std::optional<executorch::aten::Tensor>>*
104+
as_list_optional_tensor_ptr;
106105
} copyable_union;
107106

108107
// Since a Tensor just holds a TensorImpl*, there's no value to use Tensor*
@@ -280,9 +279,8 @@ struct EValue {
280279
}
281280

282281
/****** String Type ******/
283-
/*implicit*/ EValue(const char* s, size_t size) : tag(Tag::String) {
284-
payload.copyable_union.as_string =
285-
executorch::aten::ArrayRef<char>(s, size);
282+
/*implicit*/ EValue(executorch::aten::ArrayRef<char>* s) : tag(Tag::String) {
283+
payload.copyable_union.as_string_ptr = s;
286284
}
287285

288286
bool isString() const {
@@ -292,13 +290,13 @@ struct EValue {
292290
std::string_view toString() const {
293291
ET_CHECK_MSG(isString(), "EValue is not a String.");
294292
return std::string_view(
295-
payload.copyable_union.as_string.data(),
296-
payload.copyable_union.as_string.size());
293+
payload.copyable_union.as_string_ptr->data(),
294+
payload.copyable_union.as_string_ptr->size());
297295
}
298296

299297
/****** Int List Type ******/
300-
/*implicit*/ EValue(BoxedEvalueList<int64_t> i) : tag(Tag::ListInt) {
301-
payload.copyable_union.as_int_list = i;
298+
/*implicit*/ EValue(BoxedEvalueList<int64_t>* i) : tag(Tag::ListInt) {
299+
payload.copyable_union.as_int_list_ptr = i;
302300
}
303301

304302
bool isIntList() const {
@@ -307,12 +305,13 @@ struct EValue {
307305

308306
executorch::aten::ArrayRef<int64_t> toIntList() const {
309307
ET_CHECK_MSG(isIntList(), "EValue is not an Int List.");
310-
return payload.copyable_union.as_int_list.get();
308+
return (payload.copyable_union.as_int_list_ptr)->get();
311309
}
312310

313311
/****** Bool List Type ******/
314-
/*implicit*/ EValue(executorch::aten::ArrayRef<bool> b) : tag(Tag::ListBool) {
315-
payload.copyable_union.as_bool_list = b;
312+
/*implicit*/ EValue(executorch::aten::ArrayRef<bool>* b)
313+
: tag(Tag::ListBool) {
314+
payload.copyable_union.as_bool_list_ptr = b;
316315
}
317316

318317
bool isBoolList() const {
@@ -321,13 +320,13 @@ struct EValue {
321320

322321
executorch::aten::ArrayRef<bool> toBoolList() const {
323322
ET_CHECK_MSG(isBoolList(), "EValue is not a Bool List.");
324-
return payload.copyable_union.as_bool_list;
323+
return *(payload.copyable_union.as_bool_list_ptr);
325324
}
326325

327326
/****** Double List Type ******/
328-
/*implicit*/ EValue(executorch::aten::ArrayRef<double> d)
327+
/*implicit*/ EValue(executorch::aten::ArrayRef<double>* d)
329328
: tag(Tag::ListDouble) {
330-
payload.copyable_union.as_double_list = d;
329+
payload.copyable_union.as_double_list_ptr = d;
331330
}
332331

333332
bool isDoubleList() const {
@@ -336,13 +335,13 @@ struct EValue {
336335

337336
executorch::aten::ArrayRef<double> toDoubleList() const {
338337
ET_CHECK_MSG(isDoubleList(), "EValue is not a Double List.");
339-
return payload.copyable_union.as_double_list;
338+
return *(payload.copyable_union.as_double_list_ptr);
340339
}
341340

342341
/****** Tensor List Type ******/
343-
/*implicit*/ EValue(BoxedEvalueList<executorch::aten::Tensor> t)
342+
/*implicit*/ EValue(BoxedEvalueList<executorch::aten::Tensor>* t)
344343
: tag(Tag::ListTensor) {
345-
payload.copyable_union.as_tensor_list = t;
344+
payload.copyable_union.as_tensor_list_ptr = t;
346345
}
347346

348347
bool isTensorList() const {
@@ -351,14 +350,14 @@ struct EValue {
351350

352351
executorch::aten::ArrayRef<executorch::aten::Tensor> toTensorList() const {
353352
ET_CHECK_MSG(isTensorList(), "EValue is not a Tensor List.");
354-
return payload.copyable_union.as_tensor_list.get();
353+
return payload.copyable_union.as_tensor_list_ptr->get();
355354
}
356355

357356
/****** List Optional Tensor Type ******/
358357
/*implicit*/ EValue(
359-
BoxedEvalueList<std::optional<executorch::aten::Tensor>> t)
358+
BoxedEvalueList<std::optional<executorch::aten::Tensor>>* t)
360359
: tag(Tag::ListOptionalTensor) {
361-
payload.copyable_union.as_list_optional_tensor = t;
360+
payload.copyable_union.as_list_optional_tensor_ptr = t;
362361
}
363362

364363
bool isListOptionalTensor() const {
@@ -367,7 +366,7 @@ struct EValue {
367366

368367
executorch::aten::ArrayRef<std::optional<executorch::aten::Tensor>>
369368
toListOptionalTensor() const {
370-
return payload.copyable_union.as_list_optional_tensor.get();
369+
return payload.copyable_union.as_list_optional_tensor_ptr->get();
371370
}
372371

373372
/****** ScalarType Type ******/

runtime/executor/method.cpp

Lines changed: 38 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -496,8 +496,12 @@ Error Method::parse_values(const NamedDataMap* external_data_map) {
496496
j);
497497
evalp_list[j] = &values_[static_cast<size_t>(value_index)];
498498
}
499-
new (&values_[i]) EValue(
500-
BoxedEvalueList<int64_t>(evalp_list, int_list, items->size()));
499+
auto* boxed_list_mem =
500+
memory_manager_->method_allocator()
501+
->allocateInstance<BoxedEvalueList<int64_t>>();
502+
auto boxed_list = new (boxed_list_mem)
503+
BoxedEvalueList<int64_t>(evalp_list, int_list, items->size());
504+
new (&values_[i]) EValue(boxed_list);
501505
} break;
502506
case executorch_flatbuffer::KernelTypes::BoolList: {
503507
const auto items =
@@ -514,8 +518,12 @@ Error Method::parse_values(const NamedDataMap* external_data_map) {
514518
// portable here we need to allocate a new array of bool and copy cast
515519
// the flatbuffer data into it, but because of how exceptionally rare
516520
// this case is its low prio TODO: jakeszwe
517-
new (&values_[i]) EValue(executorch::aten::ArrayRef<bool>(
518-
(const bool*)items->data(), items->size()));
521+
auto* bool_list_mem =
522+
memory_manager_->method_allocator()
523+
->allocateInstance<executorch::aten::ArrayRef<bool>>();
524+
auto bool_list = new (bool_list_mem) executorch::aten::ArrayRef<bool>(
525+
(const bool*)items->data(), items->size());
526+
new (&values_[i]) EValue(bool_list);
519527
} break;
520528
case executorch_flatbuffer::KernelTypes::DoubleList: {
521529
const auto items =
@@ -525,8 +533,12 @@ Error Method::parse_values(const NamedDataMap* external_data_map) {
525533
InvalidProgram,
526534
"Missing list at index %" ET_PRIsize_t,
527535
i);
528-
new (&values_[i]) EValue(
529-
executorch::aten::ArrayRef<double>(items->data(), items->size()));
536+
auto* double_list_mem =
537+
memory_manager_->method_allocator()
538+
->allocateInstance<executorch::aten::ArrayRef<double>>();
539+
auto double_list = new (double_list_mem)
540+
executorch::aten::ArrayRef<double>(items->data(), items->size());
541+
new (&values_[i]) EValue(double_list);
530542
} break;
531543
case executorch_flatbuffer::KernelTypes::String: {
532544
const auto fb_str =
@@ -537,7 +549,12 @@ Error Method::parse_values(const NamedDataMap* external_data_map) {
537549
InvalidProgram,
538550
"Missing string at index %" ET_PRIsize_t,
539551
i);
540-
new (&values_[i]) EValue(fb_str->c_str(), fb_str->size());
552+
auto* char_list_mem =
553+
memory_manager_->method_allocator()
554+
->allocateInstance<executorch::aten::ArrayRef<char>>();
555+
auto char_list = new (char_list_mem)
556+
executorch::aten::ArrayRef<char>(fb_str->c_str(), fb_str->size());
557+
new (&values_[i]) EValue(char_list);
541558
} break;
542559
case executorch_flatbuffer::KernelTypes::Tensor: {
543560
auto t = deserialization::parseTensor(
@@ -577,7 +594,12 @@ Error Method::parse_values(const NamedDataMap* external_data_map) {
577594
static_cast<uint32_t>(tensors.error()));
578595
return tensors.error();
579596
}
580-
new (&values_[i]) EValue(tensors.get());
597+
auto* boxed_tensor_list_mem =
598+
memory_manager_->method_allocator()
599+
->allocateInstance<BoxedEvalueList<executorch::aten::Tensor>>();
600+
auto boxed_tensor_list = new (boxed_tensor_list_mem)
601+
BoxedEvalueList<executorch::aten::Tensor>(std::move(tensors.get()));
602+
new (&values_[i]) EValue(boxed_tensor_list);
581603
} break;
582604
case executorch_flatbuffer::KernelTypes::OptionalTensorList: {
583605
const auto items =
@@ -601,7 +623,14 @@ Error Method::parse_values(const NamedDataMap* external_data_map) {
601623
static_cast<uint32_t>(tensors.error()));
602624
return tensors.error();
603625
}
604-
new (&values_[i]) EValue(tensors.get());
626+
auto* boxed_optional_tensor_list_mem =
627+
memory_manager_->method_allocator()
628+
->allocateInstance<
629+
BoxedEvalueList<std::optional<executorch::aten::Tensor>>>();
630+
auto boxed_optional_tensor_list = new (boxed_optional_tensor_list_mem)
631+
BoxedEvalueList<std::optional<executorch::aten::Tensor>>(
632+
std::move(tensors.get()));
633+
new (&values_[i]) EValue(boxed_optional_tensor_list);
605634
} break;
606635
default:
607636
// flatbuffer enums start at 0, but they generate a hidden NONE enum

0 commit comments

Comments
 (0)