Attempting Example Failing in Tensor Flow Kernel

Hello,

I am attempting the As a generic C++ library tutorial using this project. For the tutorial I am using the Simplicity Studio Component deployment option. I am developing in Simplicity Studio v5 using the Gecko SDK v4.1.0

When calling the run_classifier function from main I fail. By debugging I found that it ends up failing inside the tensor flow kernel, in the file edge-impulse-sdk/tesnorflow/lite/micro/kernels/reduce.cc in the function EvalMean (line 139). It fails on line 202:


I cant really figure out why its failing, the code at that point is pretty dense with multiple macros.

With me not really changing the code from the tutorial I am left wondering how I could have broke something. Are these settings I have outlined realistic? Is there something I should check or a different tutorial I should follow?

Thanks for any help!

Hi @SethW,

Is there a way for you to share your code?
The generic C++ library tutorial is good to follow for unsupported targets. Could you also share which board you’re using?

We also have a good tutorial with Simplicity Studio and the xg24 board that you can follow here. Let me if this helps.

Aurelien

Hi @aurel,

I am using the EFR32xG24 Dev Kit Board (BRD2601B Rev A01)

app.cpp:

#include <cstdio>
#include "app.h"
#include "edge-impulse-sdk/porting/ei_classifier_porting.h"
#include "edge-impulse-sdk/classifier/ei_classifier_types.h"
#include "edge-impulse-sdk/classifier/ei_run_classifier.h"
#include "edge-impulse-sdk/dsp/numpy_types.h"

#define DEBUG true

// Callback function declaration
static int get_signal_data(size_t offset, size_t length, float *out_ptr);

// Raw features copied from test sample (Edge Impulse > Model testing)
static float input_buf[] = {
   61, 82, 83, 94, 84 //there are more raw features but it makes it too long for this code snippet 
    /* Paste your raw features here! */
};

int edge_impulse_main() {
    printf("In edge_impulse_main\n");
    signal_t signal;            // Wrapper for raw input buffer
    ei_impulse_result_t result; // Used to store inference output
    EI_IMPULSE_ERROR res;       // Return code from inference

    // Calculate the length of the buffer
    size_t buf_len = sizeof(input_buf) / sizeof(input_buf[0]);

    // Make sure that the length of the buffer matches expected input length
    if (buf_len != EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE) {
        printf("ERROR: The size of the input buffer is not correct.\r\n");
        printf("Expected %d items, but got %d\r\n",
                EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE,
                (int)buf_len);
        return 1;
    }

    // Assign callback function to fill buffer used for preprocessing/inference
    signal.total_length = EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE;
    signal.get_data = &get_signal_data;

    // Perform DSP pre-processing and inference
    res = run_classifier(&signal, &result, DEBUG);
    printf("After Run classifier\n");

    // Print return code and how long it took to perform inference
    printf("run_classifier returned: %d\r\n", res);
    printf("Timing: DSP %d ms, inference %d ms, anomaly %d ms\r\n",
            result.timing.dsp,
            result.timing.classification,
            result.timing.anomaly);

    // Print the prediction results (object detection)
#if EI_CLASSIFIER_OBJECT_DETECTION == 1
    printf("Object detection bounding boxes:\r\n");
    for (uint32_t i = 0; i < EI_CLASSIFIER_OBJECT_DETECTION_COUNT; i++) {
        ei_impulse_result_bounding_box_t bb = result.bounding_boxes[i];
        if (bb.value == 0) {
            continue;
        }
        printf("  %s (%f) [ x: %u, y: %u, width: %u, height: %u ]\r\n",
                bb.label,
                bb.value,
                bb.x,
                bb.y,
                bb.width,
                bb.height);
    }

    // Print the prediction results (classification)
#else
    printf("Predictions:\r\n");
    for (uint16_t i = 0; i < EI_CLASSIFIER_LABEL_COUNT; i++) {
        printf("  %s: ", ei_classifier_inferencing_categories[i]);
        printf("%.5f\r\n", result.classification[i].value);
    }
#endif

    // Print anomaly result (if it exists)
#if EI_CLASSIFIER_HAS_ANOMALY == 1
    printf("Anomaly prediction: %.3f\r\n", result.anomaly);
#endif

    return 0;
}

// Callback: fill a section of the out_ptr buffer when requested
static int get_signal_data(size_t offset, size_t length, float *out_ptr) {
    for (size_t i = 0; i < length; i++) {
        out_ptr[i] = (input_buf + offset)[i];
    }

    return EIDSP_OK;
}

/***************************************************************************//**
 * Initialize application.
 ******************************************************************************/
void app_init(void)
{
  printf("App Init\n");
}

/***************************************************************************//**
 * App ticking function.
 ******************************************************************************/
void app_process_action(void)
{
  edge_impulse_main();
  //printf("App Action");
}

Which is used by main.cpp:

#include "sl_component_catalog.h"
#include "sl_system_init.h"
#include "app.h"
#if defined(SL_CATALOG_POWER_MANAGER_PRESENT)
#include "sl_power_manager.h"
#endif
#if defined(SL_CATALOG_KERNEL_PRESENT)
#include "sl_system_kernel.h"
#else // SL_CATALOG_KERNEL_PRESENT
#include "sl_system_process_action.h"
#endif // SL_CATALOG_KERNEL_PRESENT

int main(void)
{
  // Initialize Silicon Labs device, system, service(s) and protocol stack(s).
  // Note that if the kernel is present, processing task(s) will be created by
  // this call.
  sl_system_init();

  // Initialize the application. For example, create periodic timer(s) or
  // task(s) if the kernel is present.
  app_init();

#if defined(SL_CATALOG_KERNEL_PRESENT)
  // Start the kernel. Task(s) created in app_init() will start running.
  sl_system_kernel_start();
#else // SL_CATALOG_KERNEL_PRESENT
  while (1) {
    // Do not remove this call: Silicon Labs components process action routine
    // must be called from the super loop.
    sl_system_process_action();

    // Application process.
    app_process_action();

#if defined(SL_CATALOG_POWER_MANAGER_PRESENT)
    // Let the CPU go to sleep if the system allows it.
    sl_power_manager_sleep();
#endif
  }
#endif // SL_CATALOG_KERNEL_PRESENT
}

The rest of the code is the out of the box code coming from the librarys.

I am also attempting the tutorial you linked but I am getting errors associated with gattdb_classifier being undeclared.
C:/Users/seth.worthylake/Downloads/Simplicity_Studio_tutorial/firmware-silabs-xg24-main/src/ble.c:54:53: error: ‘gattdb_classifier’ undeclared (first use in this function)
54 | sc = sl_bt_gatt_server_read_attribute_value(gattdb_classifier,

I followed all steps in Using Simplicity Studio v5 Section, except I am using the Gecko SDK 4.1.0.

Hi @SethW,
Regarding your first problem, is it a runtime error? Is it possible to share your project number in the EI Studio? Then I can take a look at your model and try to run it. Maybe your model is creating some hard fault when MVP is used to make computations.

BTW, if that is possible please try to use Gecko 4.0.2. We hadn’t tested the firmware with the most recent Gecko SDK (4.1.0).

Matt

Hello @mateusz ,

The project number is 114681, its a clone of a workshop project with some of my own data mixed in.

I will try using Gecko 4.0.2 and see what that does.

Thanks!

Hey @mateusz,

Following the new tutorial with Gecko SDK 4.0.2 and am getting these errors when attempting to build, any insights?

Thanks

Hi @SethW
It seems that you have to regenerate the project. Please open *.slcp file of your project in Simplicity Studio and press “Force Generation” button (in the center panel, at the bottom).

Matt

Hey @mateusz

Force Generation then building also not working. Still get same errors. Also attempted clean build then Force Generation then build. Still same errors :confused:
Let me know if there are any other ideas on how to get this to work.


Thanks,
Seth

Hi @SethW
For some reason, I can’t run my Simplicity Studio, but could you check if:

  1. firmware-sdk directory is in your project (in Project Explorer), it’s in the root directory and contains all files sam as in our firmware-xg24 repository?
  2. In the project properties, in C and C++ include sections, you have an option including the projects’ root directory? Otherwise, the compiler won’t be able to see the firmware-sdk directory.

Also, could you check what is your version of the Simplicity Studio?

Matt

Hi @mateusz,

I am using Simplicity Studio Version: SV5.4.0.0

Also my firmware-sdk directory has all the files

and I do have an option pointing to the projects root directory. The errors themselves come from

But I restarted the project from scratch, but when creating the project I set the project directory to the same directory as the cloned git repo (not the default location), then after following the instructions I have gotten a successful build and a successful run. I was also able to use my own model! Now I’m going to try to have it do more than just output the prediction %'s.

Thanks for all the help!
Seth

2 Likes

Hi @SethW
I’m glad everything is working fine!
Thanks for sharing your solution to the issue.

Best regards,
Mateusz