Skip to main content
Visitor II
December 5, 2024
Solved

X-CUBE-AI: ai_network_create_and_init() weights info required

  • December 5, 2024
  • 1 reply
  • 764 views

Hi,

I'm working with X-CUBE AI.
The code seems working but I have a doubt:
status_init = ai_network_create_and_init(&network_handle, act_addr, NULL);
Is NULL parameter correct ?
Why souldn't I need to pass a pointer also for weigths like 'act_addr' ?

If it is required how am I supposed to achieve this point without occcupy other RAM space ?

 

(Note that inference output is actually weird, but it could be correct cause I used mockup input data to feed the network)
Please, take a look to code and log below:

 

 

....network_data_params.h....

#ifndef NETWORK_DATA_PARAMS_H
#define NETWORK_DATA_PARAMS_H

#include "ai_platform.h"

/*
#define AI_NETWORK_DATA_WEIGHTS_PARAMS \
 (AI_HANDLE_PTR(&ai_network_data_weights_params[1]))
*/

#define AI_NETWORK_DATA_CONFIG (NULL)


#define AI_NETWORK_DATA_ACTIVATIONS_SIZES \
 { 306432, }
#define AI_NETWORK_DATA_ACTIVATIONS_SIZE (306432)
#define AI_NETWORK_DATA_ACTIVATIONS_COUNT (1)
#define AI_NETWORK_DATA_ACTIVATION_1_SIZE (306432)



#define AI_NETWORK_DATA_WEIGHTS_SIZES \
 { 390920, }
#define AI_NETWORK_DATA_WEIGHTS_SIZE (390920)
#define AI_NETWORK_DATA_WEIGHTS_COUNT (1)
#define AI_NETWORK_DATA_WEIGHT_1_SIZE (390920)



#define AI_NETWORK_DATA_ACTIVATIONS_TABLE_GET() \
 (&g_network_activations_table[1])

extern ai_handle g_network_activations_table[1 + 2];



#define AI_NETWORK_DATA_WEIGHTS_TABLE_GET() \
 (&g_network_weights_table[1])

extern ai_handle g_network_weights_table[1 + 2];


#endif /* NETWORK_DATA_PARAMS_H */


//.........
//Global Variables
ai_handle network_handle;
ai_buffer * ai_input;
ai_buffer * ai_output;
AI_ALIGNED(4) ai_u8 activations[AI_NETWORK_DATA_ACTIVATIONS_SIZE];
ai_float patches[AI_NETWORK_IN_1_SIZE]; // Singola patch da passare alla rete
ai_float inference_result[AI_NETWORK_OUT_1_CHANNEL];
//..........
void run_neural_network(void) {
 ai_error status_init;
 ai_i32 status_run;

 // Local activations array
 const ai_handle act_addr[] = { activations };

 // Init network after creation
 status_init = ai_network_create_and_init(&network_handle, act_addr, NULL);
 if (status_init.type != AI_ERROR_NONE) {
 send_uart_message("Network creation and initialization failed.\r\n");
 return;
 }

 ai_input = ai_network_inputs_get(network_handle, NULL);
 ai_output = ai_network_outputs_get(network_handle, NULL);

 ai_input[0].data = AI_HANDLE_PTR(patches); // Dati di input sono le patch (già in forma 128x32x1)
 ai_output[0].data = AI_HANDLE_PTR(inference_result);

 // Process Inference
 status_run = ai_network_run(network_handle, ai_input, ai_output);
 if (status_run <= 0 ) {
 sprintf(uart_buffer, "Inference failed. Input size: %lu, Status: %ld\r\n", ai_input[0].size, status_run);
 send_uart_message(uart_buffer);

 ai_error error = ai_network_get_error(network_handle);
 sprintf(uart_buffer, "Error type: %d, Code: %d\r\n", error.type, error.code);
 send_uart_message(uart_buffer);
 return;
 }

 send_uart_message("Inference SUCCESS!!!\r\n");

 // Extract result
 float32_t* result = (float32_t*)ai_output[0].data;

 // Send results by uart
 sprintf(uart_buffer, "Inference result: %f\r\n", result[0]);
 send_uart_message(uart_buffer);

 // Debug
 for (uint32_t i = 0; i < AI_NETWORK_OUT_1_CHANNEL; i++) {
 sprintf(uart_buffer, "Output[%lu]: %f\r\n", i, result[i]);
 send_uart_message(uart_buffer);
 }

 // Destroy Network
 ai_network_destroy(network_handle);
}
//....Log...
Ricevuto: Inference SUCCESS!!!.
Ricevuto: Inference result: 0.000000
Ricevuto: Output[0]: 0.000000
Ricevuto: Output[1]: 1.000000
Ricevuto: Process completed.

 

 

 

Best answer by fauvarque.daniel

As stated in the documentation (now online)

https://stedgeai-dc.st.com/assets/embedded-docs/embedded_client_api_legacy.html

his helper function aggregates the call of the create and init functions (see code in the generated 'network.c' file). It allows to pass the addresses of the activations buffers and optionally the addresses of the weights buffers.

2 cases:

  1. You have generated the .c files the regular way, the weights are embedded in the code and you pass NULL to the weights parameters
  2. You have generated the .c files asking to generate a separated binary for the weights (--binary in the command line). In that case you need to put the address of the weights. The address corresponds to the Flash address of the weights or the RAM address if you've copied the weights from flash to ram

Regards

1 reply

fauvarque.daniel
fauvarque.danielBest answer
ST Employee
December 6, 2024

As stated in the documentation (now online)

https://stedgeai-dc.st.com/assets/embedded-docs/embedded_client_api_legacy.html

his helper function aggregates the call of the create and init functions (see code in the generated 'network.c' file). It allows to pass the addresses of the activations buffers and optionally the addresses of the weights buffers.

2 cases:

  1. You have generated the .c files the regular way, the weights are embedded in the code and you pass NULL to the weights parameters
  2. You have generated the .c files asking to generate a separated binary for the weights (--binary in the command line). In that case you need to put the address of the weights. The address corresponds to the Flash address of the weights or the RAM address if you've copied the weights from flash to ram

Regards