Skip to content

Commit e425dbb

Browse files
zingofacebook-github-bot
authored andcommitted
Arm backend: Track target memory usage (#5341)
Summary: This adds memory stats API to the Memory Allocator and make it possible for the backends to track and report runtime memory usage. Pull Request resolved: #5341 Reviewed By: manuelcandales Differential Revision: D62874650 Pulled By: digantdesai fbshipit-source-id: 9b737d973466544c2df491236ed5e6a14c57eb40
1 parent d516309 commit e425dbb

File tree

2 files changed

+43
-3
lines changed

2 files changed

+43
-3
lines changed

examples/arm/executor_runner/arm_executor_runner.cpp

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
// needs to be large enough to take an entire model. On the FVP,
2929
// network_model_sec is linked to the DDR, which is large (256MB on
3030
// Corstone-300).
31-
const size_t input_allocation_pool_size = 100 * 1024 * 1024;
31+
const size_t input_allocation_pool_size = 60 * 1024 * 1024;
3232
unsigned char __attribute__((
3333
section("network_model_sec"),
3434
aligned(16))) input_allocation_pool[input_allocation_pool_size];
@@ -63,7 +63,7 @@ using executorch::runtime::Span;
6363
using executorch::runtime::Tag;
6464
using executorch::runtime::TensorInfo;
6565

66-
#define METHOD_ALLOCATOR_POOL_SIZE (70 * 1024 * 1024)
66+
#define METHOD_ALLOCATOR_POOL_SIZE (60 * 1024 * 1024)
6767
unsigned char __attribute__((
6868
section("network_model_sec"),
6969
aligned(16))) method_allocation_pool[METHOD_ALLOCATOR_POOL_SIZE];
@@ -326,6 +326,8 @@ int main(int argc, const char* argv[]) {
326326
std::vector<Span<uint8_t>> planned_spans; // Passed to the allocator
327327
size_t num_memory_planned_buffers = method_meta->num_memory_planned_buffers();
328328

329+
size_t planned_buffer_membase = method_allocator.used_size();
330+
329331
for (size_t id = 0; id < num_memory_planned_buffers; ++id) {
330332
size_t buffer_size =
331333
static_cast<size_t>(method_meta->memory_planned_buffer_size(id).get());
@@ -337,6 +339,8 @@ int main(int argc, const char* argv[]) {
337339
planned_buffers.push_back(buffer);
338340
planned_spans.push_back({planned_buffers.back(), buffer_size});
339341
}
342+
size_t planned_buffer_memsize =
343+
method_allocator.used_size() - planned_buffer_membase;
340344

341345
HierarchicalAllocator planned_memory(
342346
{planned_spans.data(), planned_spans.size()});
@@ -347,6 +351,7 @@ int main(int argc, const char* argv[]) {
347351
MemoryManager memory_manager(
348352
&method_allocator, &planned_memory, &temp_allocator);
349353

354+
size_t method_loaded_membase = method_allocator.used_size();
350355
Result<Method> method = program->load_method(method_name, &memory_manager);
351356
if (!method.ok()) {
352357
ET_LOG(
@@ -355,10 +360,12 @@ int main(int argc, const char* argv[]) {
355360
method_name,
356361
method.error());
357362
}
363+
size_t method_loaded_memsize =
364+
method_allocator.used_size() - method_loaded_membase;
358365
ET_LOG(Info, "Method loaded.");
359366

360367
ET_LOG(Info, "Preparing inputs...");
361-
368+
size_t input_membase = method_allocator.used_size();
362369
auto inputs =
363370
::prepare_input_tensors(*method, method_allocator, input_buffers);
364371

@@ -369,12 +376,15 @@ int main(int argc, const char* argv[]) {
369376
method_name,
370377
inputs.error());
371378
}
379+
size_t input_memsize = method_allocator.used_size() - input_membase;
372380
ET_LOG(Info, "Input prepared.");
373381

374382
ET_LOG(Info, "Starting the model execution...");
383+
size_t executor_membase = method_allocator.used_size();
375384
StartMeasurements();
376385
Error status = method->execute();
377386
StopMeasurements();
387+
size_t executor_memsize = method_allocator.used_size() - executor_membase;
378388

379389
if (status != Error::Ok) {
380390
ET_LOG(
@@ -425,6 +435,25 @@ int main(int argc, const char* argv[]) {
425435
}
426436
out:
427437
ET_LOG(Info, "Program complete, exiting.");
438+
if (method_allocator.size() != 0) {
439+
size_t method_allocator_used = method_allocator.used_size();
440+
ET_LOG(
441+
Info,
442+
"Method allocator area ( method_allocator_planned: %zu method_allocator_loaded: %zu method_allocator_input: %zu method_allocator_executor: %zu ) total: %zu",
443+
planned_buffer_memsize,
444+
method_loaded_memsize,
445+
input_memsize,
446+
executor_memsize,
447+
method_allocator_used);
448+
ET_LOG(
449+
Info,
450+
"Method allocator area method_allocator_used: %d / method_allocator_size: %d method_allocator_free: %d ( used: %d %% ) ",
451+
method_allocator_used,
452+
method_allocator.size(),
453+
method_allocator.free_size(),
454+
100 * method_allocator_used / method_allocator.size());
455+
}
456+
428457
#ifdef SEMIHOSTING
429458
_exit(0);
430459
#endif

runtime/core/memory_allocator.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
/*
22
* Copyright (c) Meta Platforms, Inc. and affiliates.
33
* All rights reserved.
4+
* Copyright 2024 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.
@@ -150,6 +151,16 @@ class MemoryAllocator {
150151
return size_;
151152
}
152153

154+
// Returns the used size of the allocator's memory buffer.
155+
virtual uint32_t used_size() const {
156+
return cur_ - begin_;
157+
}
158+
159+
// Returns the free size of the allocator's memory buffer.
160+
virtual uint32_t free_size() const {
161+
return end_ - cur_;
162+
}
163+
153164
// Resets the current pointer to the base address. It does nothing to
154165
// the contents.
155166
virtual void reset() {

0 commit comments

Comments
 (0)