Skip to content

Commit 69cc7fa

Browse files
authored
Arm backend: Check memory allocation on target (#9735)
This fix a problem with the code continue running efter a faild allocation and sync up the example to better match examples/devtools/example_runner/example_runner.cpp Signed-off-by: Zingo Andersen <zingo.andersen@arm.com>
1 parent eef0010 commit 69cc7fa

File tree

1 file changed

+69
-34
lines changed

1 file changed

+69
-34
lines changed

examples/arm/executor_runner/arm_executor_runner.cpp

Lines changed: 69 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,6 @@ Result<BufferCleanup> prepare_input_tensors(
257257

258258
void** inputs =
259259
static_cast<void**>(allocator.allocate(num_inputs * sizeof(void*)));
260-
261260
ET_CHECK_OR_RETURN_ERROR(
262261
inputs != nullptr,
263262
MemoryAllocationFailed,
@@ -349,15 +348,19 @@ std::pair<char*, size_t> read_binary_file(
349348
"Could not open file %s (errno: %d) for reading, exiting!",
350349
filename,
351350
errno);
352-
_exit(1);
351+
return std::make_pair(nullptr, 0);
353352
}
354353

355354
fseek(fp, 0, SEEK_END);
356355
auto file_size = ftell(fp);
357356
fseek(fp, 0, SEEK_SET);
358357

359358
char* buffer = static_cast<char*>(allocator.allocate(file_size));
360-
359+
if (buffer == nullptr) {
360+
ET_LOG(
361+
Fatal, "Failed to allocate input file size:%zu", (uint32_t)file_size);
362+
return std::make_pair(nullptr, 0);
363+
}
361364
auto read_size = fread(buffer, 1, file_size, fp);
362365
if (read_size != file_size) {
363366
ET_LOG(
@@ -415,12 +418,28 @@ int main(int argc, const char* argv[]) {
415418
input_tensor_filename);
416419
auto [buffer, buffer_size] =
417420
read_binary_file(input_tensor_filename, input_file_allocator);
421+
if (buffer == nullptr) {
422+
ET_LOG(
423+
Error,
424+
"Reading input tensor %d from file %s ERROR Out of memory",
425+
nbr_inputs,
426+
input_tensor_filename);
427+
_exit(1);
428+
}
418429
input_buffers.push_back(std::make_pair(buffer, buffer_size));
419430
} else if (std::strcmp(argv[i], "-m") == 0) {
420431
const char* pte_filename = argv[++i];
421432
ET_LOG(Info, "Reading pte model from file %s", pte_filename);
422433
auto [buffer, buffer_size] =
423434
read_binary_file(pte_filename, input_file_allocator);
435+
if (buffer == nullptr) {
436+
ET_LOG(
437+
Error,
438+
"Reading pte model from file %s ERROR Out of memory",
439+
pte_filename);
440+
_exit(1);
441+
}
442+
424443
// Store the model data with the same variable as if it was loaded
425444
// from compiled in location.
426445
model_pte = buffer;
@@ -510,6 +529,10 @@ int main(int argc, const char* argv[]) {
510529
/* Move to it's own allocator when MemoryPlanner is in place. */
511530
uint8_t* buffer =
512531
reinterpret_cast<uint8_t*>(method_allocator.allocate(buffer_size));
532+
ET_CHECK_MSG(
533+
buffer != nullptr,
534+
"Could not allocate memory for memory planned buffer size %zu",
535+
buffer_size);
513536
planned_buffers.push_back(buffer);
514537
planned_spans.push_back({planned_buffers.back(), buffer_size});
515538
}
@@ -623,6 +646,7 @@ int main(int argc, const char* argv[]) {
623646
ET_LOG(Info, "Starting the model execution...");
624647
size_t executor_membase = method_allocator.used_size();
625648
StartMeasurements();
649+
// Run the model.
626650
Error status = method->execute();
627651
StopMeasurements();
628652
size_t executor_memsize = method_allocator.used_size() - executor_membase;
@@ -680,6 +704,7 @@ int main(int argc, const char* argv[]) {
680704
status = method->get_outputs(outputs.data(), outputs.size());
681705
ET_CHECK(status == Error::Ok);
682706

707+
// Print the outputs.
683708
for (int i = 0; i < outputs.size(); ++i) {
684709
Tensor t = outputs[i].toTensor();
685710
#if !defined(SEMIHOSTING)
@@ -722,31 +747,10 @@ int main(int argc, const char* argv[]) {
722747
#endif
723748
}
724749

725-
#if defined(ET_BUNDLE_IO)
726-
if (bundle_io) {
727-
// Verify the result.
728-
status = executorch::bundled_program::verify_method_outputs(
729-
*method, model_pte, testset_idx, et_rtol, et_atol);
730-
if (status == Error::Ok) {
731-
ET_LOG(Info, "Model output match expected BundleIO bpte ref data.");
732-
ET_LOG(Info, "TEST: BundleIO index[%d] Test_result: PASS", testset_idx);
733-
} else {
734-
ET_LOG(
735-
Error,
736-
"Model output don't match expected BundleIO bpte ref data. rtol=%f atol=%f",
737-
et_rtol,
738-
et_atol);
739-
ET_LOG(Error, "TEST: BundleIO index[%d] Test_result: FAIL", testset_idx);
740-
}
741-
ET_CHECK_MSG(
742-
status == Error::Ok,
743-
"Bundle verification failed with status 0x%" PRIx32,
744-
status);
745-
}
746-
#endif
747-
748750
#if defined(ET_EVENT_TRACER_ENABLED)
749751
#if !defined(SEMIHOSTING)
752+
// Dump the etdump data containing profiling/debugging data to the serial line
753+
// base64 encoded
750754
ETDumpResult result = etdump_gen.get_etdump_data();
751755
if (result.buf != nullptr && result.size > 0) {
752756
// On a device with no file system we can't just write it out
@@ -756,15 +760,24 @@ int main(int argc, const char* argv[]) {
756760
size_t encoded_len = base64_encoded_size(result.size, mode);
757761
uint8_t* encoded_buf =
758762
reinterpret_cast<uint8_t*>(method_allocator.allocate(encoded_len + 1));
759-
int ret = base64_encode(
760-
encoded_buf, (uint8_t*)result.buf, &encoded_len, &len, mode);
761-
encoded_buf[encoded_len] = 0x00; // Ensure null termination
762-
ET_LOG(Info, "Writing etdump.bin [base64]");
763-
printf(
764-
"#---\nbase64 -i -d <<<\"\\\n%s\\\n\" >etdump.bin\npython3 -m devtools.inspector.inspector_cli --etdump_path etdump.bin --source_time_scale cycles --target_time_scale cycles\n#---\n",
765-
encoded_buf);
763+
if (encoded_buf != nullptr) {
764+
int ret = base64_encode(
765+
encoded_buf, (uint8_t*)result.buf, &encoded_len, &len, mode);
766+
encoded_buf[encoded_len] = 0x00; // Ensure null termination
767+
ET_LOG(Info, "Writing etdump.bin [base64]");
768+
printf(
769+
"#---\nbase64 -i -d <<<\"\\\n%s\\\n\" >etdump.bin\npython3 -m devtools.inspector.inspector_cli --etdump_path etdump.bin --source_time_scale cycles --target_time_scale cycles\n#---\n",
770+
encoded_buf);
771+
} else {
772+
ET_LOG(
773+
Error,
774+
"Could not allocate memory etdump base64 encoding size %zu",
775+
encoded_len + 1);
776+
}
766777
}
767778
#else
779+
// Dump the etdump data containing profiling/debugging data to the specified
780+
// file.
768781
etdump_result result = etdump_gen.get_etdump_data();
769782
if (result.buf != nullptr && result.size > 0) {
770783
// On a device with a file system we can just write it out
@@ -779,7 +792,29 @@ int main(int argc, const char* argv[]) {
779792
#endif
780793
#endif
781794

782-
out:
795+
#if defined(ET_BUNDLE_IO)
796+
if (bundle_io) {
797+
// Verify the result.
798+
status = executorch::bundled_program::verify_method_outputs(
799+
*method, model_pte, testset_idx, et_rtol, et_atol);
800+
if (status == Error::Ok) {
801+
ET_LOG(Info, "Model output match expected BundleIO bpte ref data.");
802+
ET_LOG(Info, "TEST: BundleIO index[%d] Test_result: PASS", testset_idx);
803+
} else {
804+
ET_LOG(
805+
Error,
806+
"Model output don't match expected BundleIO bpte ref data. rtol=%f atol=%f",
807+
et_rtol,
808+
et_atol);
809+
ET_LOG(Error, "TEST: BundleIO index[%d] Test_result: FAIL", testset_idx);
810+
}
811+
ET_CHECK_MSG(
812+
status == Error::Ok,
813+
"Bundle verification failed with status 0x%" PRIx32,
814+
status);
815+
}
816+
#endif
817+
783818
ET_LOG(Info, "Program complete, exiting.");
784819
#if defined(SEMIHOSTING)
785820
_exit(0);

0 commit comments

Comments
 (0)