Embedded Inference Client ST Edge AI Client APIs (Application Example)
ST Edge AI Core Technology 2.2.0
Introduction
This article includes a complete reference snippet related to the usage of the ST Edge AI Embedded Client APIs
/**
******************************************************************************
* @file stai_main_app.c
* @author AST Embedded Analytics Research Platform
* @date 2024-05-23T10:34:45+0200
******************************************************************************
* Copyright (c) 2024 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.
******************************************************************************
*/
#include <inttypes.h>
#include <stdio.h>
#include <string.h>
#include "stai.h" /* include ST Edge AI macros, types and data structures */
#include "network_inputs.h" /* where input1 buffer is defined */
#include "network.h" /* include ST Edge AI generated network model */
#define LOG_PRINT(fmt, ...) \
{ printf(fmt, ##__VA_ARGS__); fflush(stdout); }
int main(int argc, char* argv[])
{
= STAI_SUCCESS;
stai_return_code return_code
("name:%s\n", STAI_NETWORK_MODEL_NAME)
LOG_PRINT
("n_inputs:%d\n", STAI_NETWORK_IN_NUM)
LOG_PRINT("n_outputs:%d\n", STAI_NETWORK_OUT_NUM)
LOG_PRINT
("activations:%d\n", STAI_NETWORK_ACTIVATIONS_SIZE_BYTES)
LOG_PRINT("weights:%d\n", STAI_NETWORK_WEIGHTS_SIZE_BYTES)
LOG_PRINT("runtime_name:STM.AI\n")
LOG_PRINT
/* !New!: Declare and allocate memory for private network context instance */
(network, STAI_NETWORK_CONTEXT_SIZE)
STAI_NETWORK_CONTEXT_DECLARE
/* !New!: Runtime initialization */
= stai_runtime_init();
return_code
/* Initialize network context */
= stai_network_init(network);
return_code if (return_code != STAI_SUCCESS) {
(" ## Test Failed executing stai init: 0x%x.\n\n", return_code)
LOG_PRINTreturn -1;
}
/* Declare activations buffer pointers array */
[STAI_NETWORK_ACTIVATIONS_NUM] = {0};
stai_ptr activation_buffers
/* Allocate and set activation buffer #1 */
(STAI_NETWORK_ACTIVATION_1_ALIGNMENT)
STAI_ALIGNEDuint8_t activation1[STAI_NETWORK_ACTIVATION_1_SIZE] = {0};
[0] = (stai_ptr)(activation1);
activation_buffers
/* Allocate and set activation buffer #2 */
(STAI_NETWORK_ACTIVATION_2_ALIGNMENT)
STAI_ALIGNEDuint8_t activation2[STAI_NETWORK_ACTIVATION_2_SIZE] = {0};
[1] = (stai_ptr)(activation2);
activation_buffers
/* !New!: Set network activations buffers */
= stai_network_set_activations(network, activation_buffers, STAI_NETWORK_ACTIVATIONS_NUM);
return_code if (return_code != STAI_SUCCESS) {
(" ## Test Failed executing stai set activations: 0x%x.\n\n", return_code)
LOG_PRINTreturn -1;
}
#if 0
/* NOTE: This step is no more required now in ST Edge AI Client APIs since weights buffers are generated and bind
directly to the C model */
/* !New!: Declare activations buffer pointers array */
stai_ptr weight_buffers[STAI_NETWORK_WEIGHTS_NUM] = {0};
stai_size n_weights = 0;
return_code = stai_network_get_weights(network, weight_buffers, &n_weights);
if ((return_code == STAI_SUCCESS) && (n_weights==STAI_NETWORK_WEIGHTS_NUM)) {
return_code = stai_network_set_weights(network, weight_buffers, n_weights);
} else {
LOG_PRINT(" ## Test Failed executing stai set weights: 0x%x.\n\n", return_code)
return -1;
}
#endif
/* Inputs Buffer Setup */
/* C-Table declaring inputs buffer pointers array and set inputs addresses */
[STAI_NETWORK_IN_NUM] = {
stai_ptr input_buffers(stai_ptr)input1 /* defined in network_inputs.h */
};
/* !New!: Set network inputs buffers */
= stai_network_set_inputs(network, input_buffers, STAI_NETWORK_IN_NUM);
return_code if (return_code != STAI_SUCCESS) {
(" ## Test Failed executing stai set inputs: 0x%x.\n\n", return_code)
LOG_PRINTreturn -1;
}
/* Outputs Buffers Setup */
/* Allocate and declare output buffer #1 */
(STAI_NETWORK_OUT_1_ALIGNMENT)
STAI_ALIGNEDfloat output1[STAI_NETWORK_OUT_1_SIZE];
/* Declare outputs buffer pointers array and set outputs addresses */
[STAI_NETWORK_OUT_NUM] = {
stai_ptr output_buffers(stai_ptr)output1
};
/* Set network outputs buffers */
= stai_network_set_outputs(network, output_buffers, STAI_NETWORK_OUT_NUM);
return_code if (return_code != STAI_SUCCESS) {
(" ## Test Failed executing stai set outputs: 0x%x.\n\n", return_code)
LOG_PRINTreturn -1;
}
;
stai_network_info info= stai_network_get_info(network, &info);
return_code if (return_code != STAI_SUCCESS) {
(" ## Test Failed executing stai get network info: 0x%x.\n\n", return_code)
LOG_PRINTreturn -1;
}
("* Runtime version : %d.%d.%d\n",
LOG_PRINT.runtime_version.major, info.runtime_version.minor, info.runtime_version.micro)
info("* Tool version : %d.%d.%d\n",
LOG_PRINT.tool_version.major, info.tool_version.minor, info.tool_version.micro)
info("* APIs version : %d.%d.%d\n",
LOG_PRINT.api_version.major, info.api_version.minor, info.api_version.micro)
info("* Network nodes : %d\n", info.n_nodes)
LOG_PRINT("* Network macc : %d\n", info.n_macc)
LOG_PRINT("* Network inputs : %d\n", info.n_inputs)
LOG_PRINT("* Network outputs : %d\n", info.n_outputs)
LOG_PRINT
/* Execute network model inference on sample test (synchronous mode) */
("Starting inference\n")
LOG_PRINT
/* The run API now supports both sync and async modes */
= stai_network_run(network, STAI_MODE_SYNC);
return_code
("Completed inference\n")
LOG_PRINTif (return_code != STAI_SUCCESS) {
(" ## Test Failed executing stai network run: 0x%x.\n\n", return_code)
LOG_PRINTreturn -1;
}
("__START_OUTPUT1 __\n")
LOG_PRINTfor(int32_t o = 0; o < STAI_NETWORK_OUT_1_SIZE; o++) {
const float value = ((float*)output1)[o];
if (o != 0 && o % 10 == 0) {
("\n")
LOG_PRINT}
("%f " ", value);
LOG_PRINT}
("\n__END_OUTPUT1 __\n")
LOG_PRINT
/* Network de-initialization */
= stai_network_deinit(network);
return_code
/* Runtime de-initialization */
= stai_runtime_deinit();
return_code
return (return_code == STAI_SUCCESS) ? 0 : -1;
}