Skip to content

Commit af1f7d4

Browse files
committed
Arm backend: Fix CPPCHECK findings in runner and VGF setup
Change-Id: Ib114ad67278edd5aea85288cc907a9d64456b534 Signed-off-by: Per Held <per.held@arm.com>
1 parent 0e36ffa commit af1f7d4

2 files changed

Lines changed: 94 additions & 34 deletions

File tree

backends/arm/runtime/VGFSetup.cpp

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ namespace {
3131
constexpr int64_t kScalarSentinelDimension = 1;
3232
}
3333

34+
#if defined(ET_ARM_VGF_DEBUG)
3435
// Debug function to inspect memory properties
3536
static string memory_flags_to_string(VkMemoryPropertyFlags flags) {
3637
if (flags == 0)
@@ -54,7 +55,7 @@ static string memory_flags_to_string(VkMemoryPropertyFlags flags) {
5455
#undef TRY_FLAG
5556

5657
if (flags) {
57-
// any leftover bits we didn’t name
58+
// Preserve any unrecognized bits in hex so debug logs stay complete.
5859
ostringstream hex;
5960
hex << "0x" << std::hex << flags;
6061
parts.emplace_back(hex.str());
@@ -68,6 +69,7 @@ static string memory_flags_to_string(VkMemoryPropertyFlags flags) {
6869
}
6970
return joined.str();
7071
}
72+
#endif
7173

7274
/**
7375
* Tensor free helper function
@@ -247,6 +249,7 @@ static void debug_print_sequence(
247249
}
248250
}
249251

252+
#if defined(ET_ARM_VGF_DEBUG)
250253
static void debug_print_resources(
251254
unique_ptr<vgflib::ModelResourceTableDecoder>& resource_decoder) {
252255
ET_LOG(Info, "Resources:");
@@ -271,7 +274,7 @@ static void debug_print_resources(
271274
case vgflib::ResourceCategory::INPUT:
272275
case vgflib::ResourceCategory::OUTPUT: {
273276
ET_LOG(Info, " Category INPUT/OUTPUT");
274-
// Get tensor shape and strides
277+
// Log the tensor layout metadata carried in the resource table.
275278
auto shape = resource_decoder->getTensorShape(i);
276279
const vector<int64_t> the_shape(shape.begin(), shape.end());
277280
auto stride = resource_decoder->getTensorStride(i);
@@ -288,7 +291,15 @@ static void debug_print_resources(
288291
j,
289292
static_cast<long long>(the_shape[j]));
290293
}
291-
// Allocate a tensor with bound memory
294+
// Show the memory property combination the runtime currently targets.
295+
ET_LOG(
296+
Info,
297+
" memory flags %s",
298+
memory_flags_to_string(
299+
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT |
300+
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
301+
VK_MEMORY_PROPERTY_HOST_COHERENT_BIT)
302+
.c_str());
292303
break;
293304
}
294305
case vgflib::ResourceCategory::INTERMEDIATE:
@@ -303,6 +314,7 @@ static void debug_print_resources(
303314
}
304315
}
305316
}
317+
#endif
306318

307319
static void debug_print_modules(
308320
unique_ptr<vgflib::ModuleTableDecoder>& module_decoder) {
@@ -370,6 +382,9 @@ bool VgfRepr::process_vgf(
370382
const int segment_id = 0;
371383

372384
debug_print_sequence(sequence_decoder);
385+
#if defined(ET_ARM_VGF_DEBUG)
386+
debug_print_resources(resource_decoder);
387+
#endif
373388
if (sequence_decoder->modelSequenceTableSize() != 1) {
374389
ET_LOG(Error, "Expected sequence length 1");
375390
return false;

examples/arm/executor_runner/arm_executor_runner.cpp

Lines changed: 76 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -271,7 +271,7 @@ unsigned char* ethosu_fast_scratch = dedicated_sram;
271271
}
272272
#endif
273273

274-
void et_pal_init(void) {
274+
[[maybe_unused]] void et_pal_init(void) {
275275
// Enable ARM PMU Clock
276276
ARM_PMU_Enable();
277277
DCB->DEMCR |= DCB_DEMCR_TRCENA_Msk; // Trace enable
@@ -287,19 +287,19 @@ void et_pal_init(void) {
287287
* be implemnted in some way.
288288
*/
289289

290-
ET_NORETURN void et_pal_abort(void) {
290+
[[maybe_unused]] ET_NORETURN void et_pal_abort(void) {
291291
#if !defined(SEMIHOSTING)
292292
__builtin_trap();
293293
#else
294294
_exit(-1);
295295
#endif
296296
}
297297

298-
et_timestamp_t et_pal_current_ticks(void) {
298+
[[maybe_unused]] et_timestamp_t et_pal_current_ticks(void) {
299299
return ARM_PMU_Get_CCNTR();
300300
}
301301

302-
et_tick_ratio_t et_pal_ticks_to_ns_multiplier(void) {
302+
[[maybe_unused]] et_tick_ratio_t et_pal_ticks_to_ns_multiplier(void) {
303303
// Since we don't know the CPU freq for your target and justs cycles in the
304304
// FVP for et_pal_current_ticks() we return a conversion ratio of 1
305305
return {1, 1};
@@ -308,7 +308,7 @@ et_tick_ratio_t et_pal_ticks_to_ns_multiplier(void) {
308308
/**
309309
* Emit a log message via platform output (serial port, console, etc).
310310
*/
311-
void et_pal_emit_log_message(
311+
[[maybe_unused]] void et_pal_emit_log_message(
312312
ET_UNUSED et_timestamp_t timestamp,
313313
et_pal_log_level_t level,
314314
const char* filename,
@@ -332,11 +332,12 @@ void et_pal_emit_log_message(
332332
* Currenyly not used.
333333
*/
334334

335-
void* et_pal_allocate(ET_UNUSED size_t size) {
335+
[[maybe_unused]] void* et_pal_allocate(ET_UNUSED size_t size) {
336336
return nullptr;
337337
}
338338

339-
void et_pal_free(ET_UNUSED void* ptr) {}
339+
// cppcheck-suppress constParameterPointer
340+
[[maybe_unused]] void et_pal_free(ET_UNUSED void* ptr) {}
340341

341342
namespace {
342343

@@ -389,7 +390,7 @@ class Box {
389390
}
390391

391392
private:
392-
alignas(T) uint8_t mem[sizeof(T)];
393+
alignas(T) uint8_t mem[sizeof(T)] = {};
393394
bool has_value = false;
394395

395396
T* ptr() {
@@ -402,7 +403,7 @@ class Box {
402403
};
403404

404405
template <typename ValueType>
405-
void fill_tensor_with_default_value(Tensor& tensor) {
406+
[[maybe_unused]] void fill_tensor_with_default_value(Tensor& tensor) {
406407
ValueType fill_value{};
407408
if constexpr (std::is_same_v<ValueType, bool>) {
408409
fill_value = true;
@@ -420,7 +421,6 @@ Error prepare_input_tensors(
420421
const std::vector<std::pair<char*, size_t>>& input_buffers) {
421422
MethodMeta method_meta = method.method_meta();
422423
size_t num_inputs = method_meta.num_inputs();
423-
size_t num_allocated = 0;
424424

425425
#if defined(SEMIHOSTING)
426426
ET_CHECK_OR_RETURN_ERROR(
@@ -469,8 +469,8 @@ Error prepare_input_tensors(
469469
}
470470
}
471471

472-
// If input_buffers.size <= 0, we don't have any input, fill it with 1's.
473-
if (input_buffers.size() <= 0) {
472+
// If there are no input buffers, fill inputs with 1s.
473+
if (input_buffers.empty()) {
474474
if (input_evalues[i].isTensor()) {
475475
Tensor& tensor = input_evalues[i].toTensor();
476476
switch (tensor.scalar_type()) {
@@ -489,7 +489,7 @@ Error prepare_input_tensors(
489489
break;
490490
}
491491
} else {
492-
printf("Input[%d]: Not Tensor\n", i);
492+
printf("Input[%zu]: Not Tensor\n", i);
493493
}
494494
}
495495
}
@@ -522,6 +522,7 @@ std::pair<char*, size_t> read_binary_file(
522522
Fatal,
523523
"Failed to allocate input file size:%lu",
524524
static_cast<unsigned long>(file_size));
525+
fclose(fp);
525526
return std::make_pair(nullptr, 0);
526527
}
527528
auto read_size = fread(buffer, 1, file_size, fp);
@@ -562,7 +563,7 @@ struct RunnerContext {
562563
#if defined(ET_EVENT_TRACER_ENABLED)
563564
Box<ETDumpGen> etdump_gen;
564565
#if defined(ET_DUMP_INTERMEDIATE_OUTPUTS) || defined(ET_DUMP_OUTPUTS)
565-
void* debug_buffer;
566+
void* debug_buffer = nullptr;
566567
#endif
567568
#endif
568569
#if defined(SEMIHOSTING)
@@ -701,7 +702,7 @@ void runner_init(
701702
ctx.debug_buffer = ctx.method_allocator->allocate(ET_DEBUG_BUFFER_SIZE, 16);
702703
if (ctx.debug_buffer != nullptr) {
703704
Span<uint8_t> debug_buffer_span(
704-
(uint8_t*)ctx.debug_buffer, ET_DEBUG_BUFFER_SIZE);
705+
reinterpret_cast<uint8_t*>(ctx.debug_buffer), ET_DEBUG_BUFFER_SIZE);
705706

706707
Result<bool> result =
707708
ctx.etdump_gen.value().set_debug_buffer(debug_buffer_span);
@@ -973,8 +974,24 @@ void print_outputs(RunnerContext& ctx) {
973974
snprintf(out_filename, 255, "%s-%d.bin", ctx.output_basename, i);
974975
ET_LOG(Info, "Writing output to file: %s", out_filename);
975976
FILE* out_file = fopen(out_filename, "wb");
976-
auto written_size =
977+
if (out_file == nullptr) {
978+
ET_LOG(
979+
Error,
980+
"Could not open output file %s (errno: %d)",
981+
out_filename,
982+
errno);
983+
continue;
984+
}
985+
const size_t written_size =
977986
fwrite(tensor.const_data_ptr<char>(), 1, tensor.nbytes(), out_file);
987+
if (written_size != tensor.nbytes()) {
988+
ET_LOG(
989+
Error,
990+
"Failed to write whole output file %s, wrote %lu of %lu bytes",
991+
out_filename,
992+
static_cast<unsigned long>(written_size),
993+
static_cast<unsigned long>(tensor.nbytes()));
994+
}
978995
fclose(out_file);
979996
#endif //! defined(SEMIHOSTING)
980997
} else {
@@ -983,6 +1000,7 @@ void print_outputs(RunnerContext& ctx) {
9831000
}
9841001
}
9851002

1003+
// cppcheck-suppress constParameterReference
9861004
void write_etdump(RunnerContext& ctx) {
9871005
#if defined(ET_EVENT_TRACER_ENABLED)
9881006
#if !defined(SEMIHOSTING)
@@ -992,14 +1010,15 @@ void write_etdump(RunnerContext& ctx) {
9921010
if (result.buf != nullptr && result.size > 0) {
9931011
// On a device with no file system we can't just write it out
9941012
// to the file-system so we base64 encode it and dump it on the log.
995-
bool dump_outputs = false;
9961013
int mode = base64_enc_modifier_padding | base64_dec_modifier_skipspace;
9971014
size_t etdump_len = result.size;
9981015
size_t encoded_etdump_len = base64_encoded_size(etdump_len, mode);
9991016
size_t base64buffer_len = encoded_etdump_len;
1017+
const char* debug_buffer_flag = "";
10001018
#if defined(ET_DUMP_INTERMEDIATE_OUTPUTS) || defined(ET_DUMP_OUTPUTS)
10011019
// Make base64 buffer fit both so it can be reused istead of allocating two
10021020
// buffers.
1021+
bool dump_outputs = false;
10031022
size_t outputdump_len = 0;
10041023
size_t encoded_outputdump_len = 0;
10051024
if (ctx.debug_buffer != nullptr) {
@@ -1025,29 +1044,35 @@ void write_etdump(RunnerContext& ctx) {
10251044
uint8_t* encoded_buf = reinterpret_cast<uint8_t*>(
10261045
ctx.method_allocator->allocate(base64buffer_len + 1));
10271046
if (encoded_buf != nullptr) {
1028-
int ret;
1029-
const char* debug_buffer_flag = "";
10301047
printf("#[RUN THIS]\n");
10311048
#if defined(ET_DUMP_INTERMEDIATE_OUTPUTS) || defined(ET_DUMP_OUTPUTS)
10321049
if (dump_outputs) {
1033-
ret = base64_encode(
1050+
const int encode_debug_status = base64_encode(
10341051
encoded_buf,
1035-
(uint8_t*)ctx.debug_buffer,
1052+
reinterpret_cast<uint8_t*>(ctx.debug_buffer),
10361053
&encoded_outputdump_len,
10371054
&outputdump_len,
10381055
mode);
1056+
ET_CHECK_MSG(
1057+
encode_debug_status == BASE64_EOK,
1058+
"base64 encoding debug_buffer failed: %s",
1059+
base64_strerror(encode_debug_status));
10391060
encoded_buf[encoded_outputdump_len] = 0x00; // Ensure null termination
10401061
printf("# Writing debug_buffer.bin [base64]\n");
10411062
printf("echo \"%s\" | base64 -d >debug_buffer.bin\n", encoded_buf);
10421063
debug_buffer_flag = "--debug_buffer_path debug_buffer.bin";
10431064
}
10441065
#endif
1045-
ret = base64_encode(
1066+
const int encode_etdump_status = base64_encode(
10461067
encoded_buf,
1047-
(uint8_t*)result.buf,
1068+
reinterpret_cast<const uint8_t*>(result.buf),
10481069
&encoded_etdump_len,
10491070
&etdump_len,
10501071
mode);
1072+
ET_CHECK_MSG(
1073+
encode_etdump_status == BASE64_EOK,
1074+
"base64 encoding etdump failed: %s",
1075+
base64_strerror(encode_etdump_status));
10511076
encoded_buf[encoded_etdump_len] = 0x00; // Ensure null termination
10521077
printf("# Writing etdump.bin [base64]\n");
10531078
printf("echo \"%s\" | base64 -d >etdump.bin\n", encoded_buf);
@@ -1076,8 +1101,17 @@ void write_etdump(RunnerContext& ctx) {
10761101
"Writing etdump debug_buffer to file: %s",
10771102
etdump_output_filename);
10781103
FILE* f = fopen(etdump_output_filename, "w+");
1079-
fwrite((uint8_t*)ctx.debug_buffer, 1, outputdump_len, f);
1080-
fclose(f);
1104+
if (f == nullptr) {
1105+
ET_LOG(
1106+
Error,
1107+
"Could not open etdump debug buffer file %s (errno: %d)",
1108+
etdump_output_filename,
1109+
errno);
1110+
} else {
1111+
fwrite(
1112+
reinterpret_cast<uint8_t*>(ctx.debug_buffer), 1, outputdump_len, f);
1113+
fclose(f);
1114+
}
10811115
}
10821116
#endif
10831117

@@ -1089,14 +1123,25 @@ void write_etdump(RunnerContext& ctx) {
10891123
const char* etdump_filename = "etdump.bin";
10901124
ET_LOG(Info, "Writing etdump to file: %s", etdump_filename);
10911125
FILE* f = fopen(etdump_filename, "w+");
1092-
fwrite((uint8_t*)result.buf, 1, result.size, f);
1093-
fclose(f);
1126+
if (f == nullptr) {
1127+
ET_LOG(
1128+
Error,
1129+
"Could not open etdump file %s (errno: %d)",
1130+
etdump_filename,
1131+
errno);
1132+
} else {
1133+
fwrite(reinterpret_cast<uint8_t*>(result.buf), 1, result.size, f);
1134+
fclose(f);
1135+
}
10941136
free(result.buf);
10951137
}
10961138
#endif // !defined(SEMIHOSTING)
10971139
#endif // defined(ET_EVENT_TRACER_ENABLED)
10981140
}
10991141

1142+
// cppcheck-suppress constParameterReference
1143+
// ET_BUNDLE_IO verification passes ctx.method into devtools/bundled_program
1144+
// helpers, which currently require a non-const Method&.
11001145
bool verify_result(RunnerContext& ctx, const void* model_pte) {
11011146
bool model_ok = false;
11021147
#if defined(ET_BUNDLE_IO)
@@ -1225,21 +1270,21 @@ int main(int argc, const char* argv[]) {
12251270

12261271
/* parse input parameters */
12271272
for (int i = 0; i < argc; i++) {
1228-
size_t nbr_inputs = 0;
12291273
if (std::strcmp(argv[i], "-i") == 0) {
12301274
// input file, read the data into memory
12311275
const char* input_tensor_filename = argv[++i];
1276+
const size_t nbr_inputs = input_buffers.size() + 1;
12321277
ET_LOG(
12331278
Info,
1234-
"Reading input tensor %d from file %s",
1235-
++nbr_inputs,
1279+
"Reading input tensor %zu from file %s",
1280+
nbr_inputs,
12361281
input_tensor_filename);
12371282
auto [buffer, buffer_size] = read_binary_file(
12381283
input_tensor_filename, ctx.input_file_allocator.value());
12391284
if (buffer == nullptr) {
12401285
ET_LOG(
12411286
Error,
1242-
"Reading input tensor %d from file %s ERROR Out of memory",
1287+
"Reading input tensor %zu from file %s ERROR Out of memory",
12431288
nbr_inputs,
12441289
input_tensor_filename);
12451290
_exit(1);

0 commit comments

Comments
 (0)