@@ -135,6 +135,44 @@ void et_pal_emit_log_message(
135
135
136
136
namespace {
137
137
138
+ // Setup our own allocator that can show some extra stuff like used and free
139
+ // memory info
140
+ class ArmMemoryAllocator : public executorch ::runtime::MemoryAllocator {
141
+ public:
142
+ ArmMemoryAllocator (uint32_t size, uint8_t * base_address)
143
+ : MemoryAllocator(size, base_address), used_(0 ) {}
144
+
145
+ void * allocate (size_t size, size_t alignment = kDefaultAlignment ) override {
146
+ void * ret = executorch::runtime::MemoryAllocator::allocate (size, alignment);
147
+ if (ret != nullptr ) {
148
+ // Align with the same code as in MemoryAllocator::allocate() to keep
149
+ // used_ "in sync" As alignment is expected to be power of 2 (checked by
150
+ // MemoryAllocator::allocate()) we can check it the lower bits
151
+ // (same as alignment - 1) is zero or not.
152
+ if ((size & (alignment - 1 )) == 0 ) {
153
+ // Already aligned.
154
+ used_ += size;
155
+ } else {
156
+ used_ = (used_ | (alignment - 1 )) + 1 + size;
157
+ }
158
+ }
159
+ return ret;
160
+ }
161
+
162
+ // Returns the used size of the allocator's memory buffer.
163
+ size_t used_size () const {
164
+ return used_;
165
+ }
166
+
167
+ // Returns the free size of the allocator's memory buffer.
168
+ size_t free_size () const {
169
+ return executorch::runtime::MemoryAllocator::size () - used_;
170
+ }
171
+
172
+ private:
173
+ size_t used_;
174
+ };
175
+
138
176
Result<BufferCleanup> prepare_input_tensors (
139
177
Method& method,
140
178
MemoryAllocator& allocator,
@@ -291,7 +329,7 @@ int main(int argc, const char* argv[]) {
291
329
292
330
#ifdef SEMIHOSTING
293
331
const char * output_basename = nullptr ;
294
- MemoryAllocator input_file_allocator (
332
+ ArmMemoryAllocator input_file_allocator (
295
333
input_file_allocation_pool_size, input_file_allocation_pool);
296
334
297
335
/* parse input parameters */
@@ -354,13 +392,15 @@ int main(int argc, const char* argv[]) {
354
392
(unsigned int )method_meta.error ());
355
393
}
356
394
357
- MemoryAllocator method_allocator (
395
+ ArmMemoryAllocator method_allocator (
358
396
method_allocation_pool_size, method_allocation_pool);
359
397
360
398
std::vector<uint8_t *> planned_buffers; // Owns the memory
361
399
std::vector<Span<uint8_t >> planned_spans; // Passed to the allocator
362
400
size_t num_memory_planned_buffers = method_meta->num_memory_planned_buffers ();
363
401
402
+ size_t planned_buffer_membase = method_allocator.used_size ();
403
+
364
404
for (size_t id = 0 ; id < num_memory_planned_buffers; ++id) {
365
405
size_t buffer_size =
366
406
static_cast <size_t >(method_meta->memory_planned_buffer_size (id).get ());
@@ -373,15 +413,20 @@ int main(int argc, const char* argv[]) {
373
413
planned_spans.push_back ({planned_buffers.back (), buffer_size});
374
414
}
375
415
416
+ size_t planned_buffer_memsize =
417
+ method_allocator.used_size () - planned_buffer_membase;
418
+
376
419
HierarchicalAllocator planned_memory (
377
420
{planned_spans.data (), planned_spans.size ()});
378
421
379
- MemoryAllocator temp_allocator (
422
+ ArmMemoryAllocator temp_allocator (
380
423
temp_allocation_pool_size, temp_allocation_pool);
381
424
382
425
MemoryManager memory_manager (
383
426
&method_allocator, &planned_memory, &temp_allocator);
384
427
428
+ size_t method_loaded_membase = method_allocator.used_size ();
429
+
385
430
Result<Method> method = program->load_method (method_name, &memory_manager);
386
431
if (!method.ok ()) {
387
432
ET_LOG (
@@ -390,9 +435,12 @@ int main(int argc, const char* argv[]) {
390
435
method_name,
391
436
method.error ());
392
437
}
438
+ size_t method_loaded_memsize =
439
+ method_allocator.used_size () - method_loaded_membase;
393
440
ET_LOG (Info, " Method loaded." );
394
441
395
442
ET_LOG (Info, " Preparing inputs..." );
443
+ size_t input_membase = method_allocator.used_size ();
396
444
397
445
auto inputs =
398
446
::prepare_input_tensors (*method, method_allocator, input_buffers);
@@ -404,12 +452,52 @@ int main(int argc, const char* argv[]) {
404
452
method_name,
405
453
inputs.error ());
406
454
}
455
+ size_t input_memsize = method_allocator.used_size () - input_membase;
407
456
ET_LOG (Info, " Input prepared." );
408
457
409
458
ET_LOG (Info, " Starting the model execution..." );
459
+ size_t executor_membase = method_allocator.used_size ();
410
460
StartMeasurements ();
411
461
Error status = method->execute ();
412
462
StopMeasurements ();
463
+ size_t executor_memsize = method_allocator.used_size () - executor_membase;
464
+
465
+ ET_LOG (Info, " model_pte_loaded_size: %lu bytes." , pte_size);
466
+ #ifdef SEMIHOSTING
467
+ if (input_file_allocator.size () > 0 ) {
468
+ ET_LOG (
469
+ Info,
470
+ " input_file_allocator_used: %zu / %zu free: %zu ( used: %zu %% ) " ,
471
+ input_file_allocator.used_size (),
472
+ input_file_allocator.size (),
473
+ input_file_allocator.free_size (),
474
+ 100 * input_file_allocator.used_size () / input_file_allocator.size ());
475
+ }
476
+ #endif
477
+ if (method_allocator.size () != 0 ) {
478
+ size_t method_allocator_used = method_allocator.used_size ();
479
+ ET_LOG (
480
+ Info,
481
+ " method_allocator_used: %zu / %zu free: %zu ( used: %zu %% ) " ,
482
+ method_allocator_used,
483
+ method_allocator.size (),
484
+ method_allocator.free_size (),
485
+ 100 * method_allocator_used / method_allocator.size ());
486
+ ET_LOG (
487
+ Info, " method_allocator_planned: %zu bytes" , planned_buffer_memsize);
488
+ ET_LOG (Info, " method_allocator_loaded: %zu bytes" , method_loaded_memsize);
489
+ ET_LOG (Info, " method_allocator_input: %zu bytes" , input_memsize);
490
+ ET_LOG (Info, " method_allocator_executor: %zu bytes" , executor_memsize);
491
+ }
492
+ if (temp_allocator.size () > 0 ) {
493
+ ET_LOG (
494
+ Info,
495
+ " temp_allocator_used: %zu / %zu free: %zu ( used: %zu %% ) " ,
496
+ temp_allocator.used_size (),
497
+ temp_allocator.size (),
498
+ temp_allocator.free_size (),
499
+ 100 * temp_allocator.used_size () / temp_allocator.size ());
500
+ }
413
501
414
502
if (status != Error::Ok) {
415
503
ET_LOG (
0 commit comments