Validate the target execution path
The Corstone-320 FVP is a software model of a Cortex-M85 and Ethos-U85 system. Use it to validate the program, runtime, driver, and NPU integration before moving to a board. FVP counters are not final hardware benchmark results.
The Arm executor runner is a generic bare-metal application. It loads the
.pte artifact embedded during the build, reads raw input tensors through
semihosting, invokes the ExecuTorch method, and writes output files back to the
Linux host.
The build converts the selected .pte artifact into model_pte.h. The runner
uses that byte array to load the ExecuTorch program and its first method:
#include "model_pte.h"
model_data = model_pte;
model_size = sizeof(model_pte);
ctx.loader.reset(model_data, model_size);
auto& loader = ctx.loader.value();
Result<Program> program_result = Program::load(&loader);
ctx.program.reset(std::move(program_result.get()));
Program& program = ctx.program.value();
ctx.method.reset(program.load_method(
ctx.method_name, &ctx.memory_manager.value()));
With semihosting enabled, the -i i0.bin argument reads the raw input from the
Linux host. The runner checks its byte count against the method input and
copies it into the ExecuTorch tensor:
auto [buffer, buffer_size] = read_binary_file(
input_tensor_filename, ctx.input_file_allocator.value());
input_buffers.push_back(std::make_pair(buffer, buffer_size));
if (buffer_size == tensor_meta->nbytes()) {
Tensor& tensor = input_evalues[i].toTensor();
std::memcpy(tensor.mutable_data_ptr<int8_t>(), buffer, buffer_size);
}
The model runs through the standard ExecuTorch Method API. After execution,
the runner obtains each output tensor and writes its raw bytes to out-0.bin:
status = ctx.method.value()->execute();
ctx.method.value()->get_outputs(outputs.data(), outputs.size());
fwrite(
tensor.const_data_ptr<char>(), 1, tensor.nbytes(), out_file);
Course complete
Nice work
You completed Optimize and deploy AI inference with ExecuTorch on Arm.