Merge branch 'feat/add_loader_mode' into 'master'

Feat/add loader mode

See merge request speech-recognition-framework/esp-sr!35
This commit is contained in:
Sun Xiang Yu 2023-04-13 14:49:48 +08:00
commit 70ee950788
10 changed files with 98 additions and 1 deletions

View File

@ -4,6 +4,11 @@
- Available storage is less than the remaining flash space on IDF v5.0.
If you can not map model partition successfully, please check the left free storage by `spi_flash_mmap_get_free_pages(ESP_PARTITION_MMAP_DATA)`
## unreleased
- Bugfix: remove all cxx11:string
- Bugfix: remove esp-partition require for esp32s2 & esp32c3 on idf v4.4
- Add more loader option for multinet to blance CPU and memory consumption
## 1.3.0
- Update the partition APIs to keep compatible with both IDF v4.4 and IDF v5.0
- Add a new Chinese MultiNet6 mdoel for air conditioner controller

View File

@ -32,7 +32,8 @@ extern multi_heap_handle_t gst_heap;
#endif
//Flags for matrices
#define DL_MF_FOREIGNDATA (1) /*< Matrix *item data actually points to another matrix and should not be freed */
#define DL_MF_FOREIGNDATA 1 /*< Matrix pointer and item data actually points to another matrix and should not be freed */
#define DL_MF_FOREIGNITEM 2 /*< Only item data actually points to another matrix and should not be freed */
//'Normal' float matrix
typedef struct {

View File

@ -17,6 +17,15 @@ typedef enum {
ESP_MN_STATE_TIMEOUT = 2, // time out
} esp_mn_state_t;
//Set multinet loading mode
//The memory comsumption is decreased with increasing mode,
//As a consequence also the CPU loading rate goes up
typedef enum {
ESP_MN_LOAD_FROM_PSRAM = 0, // Load all weights from PSRAM. Fastest computation with Maximum memory consumption
ESP_MN_LOAD_FROM_PSRAM_FLASH = 1, // Load some weights from PSRAM and laod the rest from FLASH (default)
ESP_MN_LOAD_FROM_FLASH = 2, // Load more weights from FLASH. Minimum memory consumption with slowest computation
} esp_mn_loader_mode_t;
typedef enum {
ESP_MN_GREEDY_SEARCH = 0, // greedy search
ESP_MN_BEAM_SEARCH = 1, // beam search
@ -66,6 +75,18 @@ typedef struct _mn_node_ {
*/
typedef model_iface_data_t* (*esp_mn_iface_op_create_t)(const char *model_name, int duration);
/**
* @brief Switch multinet mode to change memory consumption and CPU loading
*
* @warning Just Support multinet6 or later versions
*
* @param model The model object to query
* @param mode The multinet loader mode
*
* @returns Handle to the model data.
*/
typedef model_iface_data_t* (*esp_mn_iface_op_switch_loader_mode_t)(model_iface_data_t *model, esp_mn_loader_mode_t mode);
/**
* @brief Callback function type to fetch the amount of samples that need to be passed to the detect function
*
@ -173,4 +194,5 @@ typedef struct {
esp_mn_iface_op_open_log_t open_log;
esp_mn_iface_op_clean_t clean;
esp_wn_iface_op_set_speech_commands set_speech_commands;
esp_mn_iface_op_switch_loader_mode_t switch_loader_mode;
} esp_mn_iface_t;

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -114,4 +114,73 @@ TEST_CASE("multinet detect/get_results API & cpu loading", "[mn]")
multinet->destroy(model_data);
esp_srmodel_deinit(models);
TEST_ASSERT_EQUAL(true, (cpu_loading < 75 && tv_ms > 0));
}
TEST_CASE("multinet switch loader mode", "[mn]")
{
vTaskDelay(500 / portTICK_PERIOD_MS);
srmodel_list_t *models = esp_srmodel_init("model");
char *model_name = esp_srmodel_filter(models, "mn6", NULL);
if (model_name != NULL) {
esp_mn_iface_t *multinet = esp_mn_handle_from_name(model_name);
int start_size = heap_caps_get_free_size(MALLOC_CAP_8BIT);
int start_internal_size = heap_caps_get_free_size(MALLOC_CAP_INTERNAL);
struct timeval tv_start, tv_end;
gettimeofday(&tv_start, NULL);
model_iface_data_t *model_data = multinet->create(model_name, 6000);
int create_size = start_size - heap_caps_get_free_size(MALLOC_CAP_8BIT);
int create_internal_size = start_internal_size - heap_caps_get_free_size(MALLOC_CAP_INTERNAL);
int first_create_size = create_size;
printf("Internal RAM: %d, PSRAM:%d\n\n", create_internal_size, create_size-create_internal_size);
model_data = multinet->switch_loader_mode(model_data, ESP_MN_LOAD_FROM_PSRAM_FLASH);
create_size = start_size - heap_caps_get_free_size(MALLOC_CAP_8BIT);
create_internal_size = start_internal_size - heap_caps_get_free_size(MALLOC_CAP_INTERNAL);
printf("Internal RAM: %d, PSRAM:%d\n\n", create_internal_size, create_size-create_internal_size);
model_data = multinet->switch_loader_mode(model_data, ESP_MN_LOAD_FROM_PSRAM);
create_size = start_size - heap_caps_get_free_size(MALLOC_CAP_8BIT);
create_internal_size = start_internal_size - heap_caps_get_free_size(MALLOC_CAP_INTERNAL);
printf("Internal RAM: %d, PSRAM:%d\n\n", create_internal_size, create_size-create_internal_size);
model_data = multinet->switch_loader_mode(model_data, ESP_MN_LOAD_FROM_PSRAM);
model_data = multinet->switch_loader_mode(model_data, ESP_MN_LOAD_FROM_PSRAM_FLASH);
create_size = start_size - heap_caps_get_free_size(MALLOC_CAP_8BIT);
create_internal_size = start_internal_size - heap_caps_get_free_size(MALLOC_CAP_INTERNAL);
printf("Internal RAM: %d, PSRAM:%d\n\n", create_internal_size, create_size-create_internal_size);
model_data = multinet->switch_loader_mode(model_data, ESP_MN_LOAD_FROM_FLASH);
create_size = start_size - heap_caps_get_free_size(MALLOC_CAP_8BIT);
create_internal_size = start_internal_size - heap_caps_get_free_size(MALLOC_CAP_INTERNAL);
printf("Internal RAM: %d, PSRAM:%d\n\n", create_internal_size, create_size-create_internal_size);
model_data = multinet->switch_loader_mode(model_data, ESP_MN_LOAD_FROM_FLASH);
model_data = multinet->switch_loader_mode(model_data, ESP_MN_LOAD_FROM_PSRAM);
model_data = multinet->switch_loader_mode(model_data, ESP_MN_LOAD_FROM_FLASH);
model_data = multinet->switch_loader_mode(model_data, ESP_MN_LOAD_FROM_PSRAM_FLASH);
create_size = start_size - heap_caps_get_free_size(MALLOC_CAP_8BIT);
create_internal_size = start_internal_size - heap_caps_get_free_size(MALLOC_CAP_INTERNAL);
printf("Internal RAM: %d, PSRAM:%d\n\n", create_internal_size, create_size-create_internal_size);
gettimeofday(&tv_end, NULL);
int tv_ms=(tv_end.tv_sec-tv_start.tv_sec)*1000+(tv_end.tv_usec-tv_start.tv_usec)/1000;
printf("create latency:%d ms\n", tv_ms);
multinet->destroy(model_data);
int first_end_size = heap_caps_get_free_size(MALLOC_CAP_8BIT);
int first_end_internal_size = heap_caps_get_free_size(MALLOC_CAP_INTERNAL);
int last_end_size = first_end_size;
int last_end_internal_size = first_end_internal_size;
int mem_leak = start_size - last_end_size;
printf("create&destroy times:%d, memory leak:%d\n", 1, mem_leak);
esp_srmodel_deinit(models);
TEST_ASSERT_EQUAL(true, (mem_leak) < 1000 && first_create_size == create_size);
} else {
printf("Just support multinet6 and the later versions\n");
TEST_ASSERT_EQUAL(true, 1);
}
}