/** ****************************************************************************** * @file aiTestUtility.c * @author MCD/AIS Team * @brief STM32 Helper functions for STM32 AI test application ****************************************************************************** * @attention * *

© Copyright (c) 2019,2021 STMicroelectronics. * All rights reserved.

* * This software is licensed under terms that can be found in the LICENSE file in * the root directory of this software component. * If no LICENSE file comes with this software, it is provided AS-IS. * ****************************************************************************** */ /* * Description: * * * History: * - v1.0 - Initial version (from initial aiSystemPerformance file v5.0) * - v2.0 - Update aiPrintNetworkInfo() to use new report with support of * fragmented activations/weights buffer * Update buffer description for binary 32b-packet tensor */ #include #include //#include "logging_levels.h" ///* define LOG_LEVEL here if you want to modify the logging level from the default */ //#define LOG_LEVEL LOG_INFO //#include "logging.h" #if !defined(TFLM_RUNTIME) #include //#include //#define LC_PRINT(...) vLoggingPrintf( "INF", 0 , 0, __VA_ARGS__ ) #define LC_PRINT(...) fprintf(stdout,__VA_ARGS__) #include void aiPlatformVersion(void) { const ai_platform_version rt_ver = ai_platform_runtime_get_version(); LC_PRINT("\r\nAI platform (API %d.%d.%d - RUNTIME %d.%d.%d)\r\n", AI_PLATFORM_API_MAJOR, AI_PLATFORM_API_MINOR, AI_PLATFORM_API_MICRO, rt_ver.major, rt_ver.minor, rt_ver.micro); } void aiLogErr(const ai_error err, const char *fct) { if (fct) LC_PRINT("E: AI error (%s) - type=0x%02x code=0x%02x\r\n", fct, err.type, err.code); else LC_PRINT("E: AI error - type=0x%02x code=0x%02x\r\n", err.type, err.code); } static inline void aiPrintDataType(const ai_buffer_format fmt) { if (AI_BUFFER_FMT_GET_TYPE(fmt) == AI_BUFFER_FMT_TYPE_FLOAT) LC_PRINT("float%d", (int)AI_BUFFER_FMT_GET_BITS(fmt)); else if (AI_BUFFER_FMT_GET_TYPE(fmt) == AI_BUFFER_FMT_TYPE_BOOL) { LC_PRINT("bool%d", (int)AI_BUFFER_FMT_GET_BITS(fmt)); } else { /* integer type */ LC_PRINT("%s%d", AI_BUFFER_FMT_GET_SIGN(fmt)?"i":"u", (int)AI_BUFFER_FMT_GET_BITS(fmt)); } } void aiPrintBufferInfo(const ai_buffer *buffer) { const ai_buffer_format fmt = buffer->format; /* shape + nb elem */ LC_PRINT("(%ld,%ld,%ld,", AI_BUFFER_SHAPE_ELEM(buffer, AI_SHAPE_BATCH), AI_BUFFER_SHAPE_ELEM(buffer, AI_SHAPE_HEIGHT), AI_BUFFER_SHAPE_ELEM(buffer, AI_SHAPE_WIDTH)); if (AI_BUFFER_SHAPE_SIZE(buffer) == 5) { LC_PRINT("%d,%d)", (int)AI_BUFFER_SHAPE_ELEM(buffer, AI_SHAPE_DEPTH), (int)AI_BUFFER_SHAPE_ELEM(buffer, AI_SHAPE_CHANNEL)); } else if (AI_BUFFER_SHAPE_SIZE(buffer) == 6) { LC_PRINT("%d,%d,%d)", (int)AI_BUFFER_SHAPE_ELEM(buffer, AI_SHAPE_DEPTH), (int)AI_BUFFER_SHAPE_ELEM(buffer, AI_SHAPE_EXTENSION), (int)AI_BUFFER_SHAPE_ELEM(buffer, AI_SHAPE_CHANNEL)); } else { LC_PRINT("%d)", (int)AI_BUFFER_SHAPE_ELEM(buffer, AI_SHAPE_CHANNEL)); } LC_PRINT("%d/", (int)AI_BUFFER_SIZE(buffer)); /* type (+meta_data) */ aiPrintDataType(fmt); /* quantized info if available */ if (AI_BUFFER_FMT_GET_TYPE(fmt) == AI_BUFFER_FMT_TYPE_Q) { if (AI_BUFFER_META_INFO_INTQ(buffer->meta_info)) { ai_u16 s_ = AI_BUFFER_META_INFO_INTQ_GET_SIZE(buffer->meta_info); const int max_ = s_> 4?4:s_; LC_PRINT(" %d:", s_); for (int idx=0; idxmeta_info, idx); int zero_point = AI_BUFFER_META_INFO_INTQ_GET_ZEROPOINT(buffer->meta_info, idx); LC_PRINT("(%f,%d),", scale, zero_point); } if (s_ > max_) { LC_PRINT(".."); } } else if (AI_BUFFER_FMT_GET_BITS(fmt) < 8) { /* lower of 8b format */ LC_PRINT(" int32-%db", (int)AI_BUFFER_FMT_GET_BITS(fmt)); } else { LC_PRINT(" Q%d.%d", (int)AI_BUFFER_FMT_GET_BITS(fmt) - ((int)AI_BUFFER_FMT_GET_FBITS(fmt) + (int)AI_BUFFER_FMT_GET_SIGN(fmt)), AI_BUFFER_FMT_GET_FBITS(fmt) ); } } /* @ + size in bytes */ if (buffer->data) LC_PRINT(" @0x%X/%d", (int)buffer->data, (int)AI_BUFFER_BYTE_SIZE(AI_BUFFER_SIZE(buffer), fmt) ); else LC_PRINT(" (User Domain)/%d", (int)AI_BUFFER_BYTE_SIZE(AI_BUFFER_SIZE(buffer), fmt) ); } void aiPrintNetworkInfo(const ai_network_report* report) { LC_PRINT("Network informations...\r\n"); LC_PRINT(" model name : %s\r\n", report->model_name); LC_PRINT(" model signature : %s\r\n", report->model_signature); LC_PRINT(" model datetime : %s\r\n", report->model_datetime); LC_PRINT(" compile datetime : %s\r\n", report->compile_datetime); LC_PRINT(" runtime version : %d.%d.%d\r\n", report->runtime_version.major, report->runtime_version.minor, report->runtime_version.micro); if (report->tool_revision[0]) LC_PRINT(" Tool revision : %s\r\n", (report->tool_revision[0])?report->tool_revision:""); LC_PRINT(" tools version : %d.%d.%d\r\n", report->tool_version.major, report->tool_version.minor, report->tool_version.micro); LC_PRINT(" complexity : %lu MACC\r\n", (unsigned long)report->n_macc); LC_PRINT(" c-nodes : %d\r\n", (int)report->n_nodes); LC_PRINT(" map_activations : %d\r\n", report->map_activations.size); for (int idx=0; idxmap_activations.size;idx++) { const ai_buffer *buffer = &report->map_activations.buffer[idx]; LC_PRINT(" [%d] ", idx); aiPrintBufferInfo(buffer); LC_PRINT("\r\n"); } LC_PRINT(" map_weights : %d\r\n", report->map_weights.size); for (int idx=0; idxmap_weights.size;idx++) { const ai_buffer *buffer = &report->map_weights.buffer[idx]; LC_PRINT(" [%d] ", idx); aiPrintBufferInfo(buffer); LC_PRINT("\r\n"); } LC_PRINT(" n_inputs/n_outputs : %u/%u\r\n", report->n_inputs, report->n_outputs); for (int i=0; in_inputs; i++) { // LC_PRINT(" I[%d] %s\r\n", i, aiGetBufferDesc(&report->inputs[i])); LC_PRINT(" I[%d] ", i); aiPrintBufferInfo(&report->inputs[i]); LC_PRINT("\r\n"); } for (int i=0; in_outputs; i++) { //LC_PRINT(" O[%d] %s\r\n", i, aiGetBufferDesc(&report->outputs[i])); LC_PRINT(" O[%d] ", i); aiPrintBufferInfo(&report->outputs[i]); LC_PRINT("\r\n"); } } #endif /* !TFLM_RUNTIME) */