Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 4 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,15 +40,13 @@ The diagram below illustrates the RPS application architecture. During algorithm
1. [Create the input interface](./Documentation/README.md#input-interface-and-signal-conditioning), add signal conditioning, and start capturing data for ML model training.
2. [Select an ML model](./Documentation/README.md#create-ml-model), then use the captured data for training, analysis, and creation of the optimized ML model.
3. [Integrate the ML model](./Documentation/README.md#integrate-ml-model) into the SDS framework and analyze performance.
4. Configure `OUTPUT_PREDICTION_METADATA` based on your workflow:
4. Configure ML output prediction metadata at runtime using SDS user flag 5 (`1UL << 5`).

**Configuration file:**
`RockPaperScissors/AppKit-E8_USB/algorithm/AlgorithmTest.cproject.yml`
- Set `OUTPUT_PREDICTION_METADATA = 0` to view the generated `.sds` files using the Arm SDS VS Code extension.
- Set `OUTPUT_PREDICTION_METADATA = 1` to enable live inference streaming in Fusion Studio, which parses the prediction metadata (predicted class label, confidence score, and class index) to render overlayed frames.
- Set the flag to include prediction metadata (predicted class label, confidence score, and class index) for live inference streaming in Fusion Studio.
- Clear the flag to record `ML_Out.sds` with only class confidence scores.
> [!Note]
>
> By default, `OUTPUT_PREDICTION_METADATA` is set to `0`
> Prediction metadata is disabled by default.

**Test Embedded Application:**

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,11 @@ project:
- C10_USING_CUSTOM_GENERATED_MACROS
- ET_NUM_INFERENCES: 1
- ET_LOG_DUMP_OUTPUT
- ET_DEBUG_BUFFER_SIZE: 0x8000
- USE_PERFORMANCE_MONITOR
- USE_SEGGER_SYSVIEW
- OUTPUT_PREDICTION_METADATA: 0

setups:
- ET_DEBUG_BUFFER_SIZE: 0x8000
- USE_PERFORMANCE_MONITOR
- USE_SEGGER_SYSVIEW

setups:
- setup: Scratch pool for non-simulator
not-for-context: +SSE-320-U85
define:
Expand Down
28 changes: 16 additions & 12 deletions RockPaperScissors/AppKit-E8_USB/algorithm/algorithm.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,10 @@
*/

#ifndef ALGORITHM_H_
#define ALGORITHM_H_

#include <stdint.h>
#define ALGORITHM_H_

#include <stdbool.h>
#include <stdint.h>

#ifdef __cplusplus
extern "C"
Expand All @@ -40,15 +41,18 @@ extern int32_t InitAlgorithm (void);
extern void ResetAlgorithm (void);

/**
\fn int32_t ExecuteAlgorithm (uint8_t *in_buf, uint32_t in_num, uint8_t *out_buf, uint32_t out_num)
\brief Execute algorithm under test.
\param[in] in_buf pointer to memory buffer containing input data for algorithm
\param[in] in_num number of data bytes in input data buffer (in bytes)
\param[out] out_buf pointer to memory buffer for returning algorithm output
\param[in] out_num maximum number of data bytes returned as algorithm output (in bytes)
\return 0 on success; -1 on error
*/
extern int32_t ExecuteAlgorithm (uint8_t *in_buf, uint32_t in_num, uint8_t *out_buf, uint32_t out_num);
\fn int32_t ExecuteAlgorithm (uint8_t *in_buf, uint32_t in_num, uint8_t *out_buf, uint32_t out_num, bool output_prediction_metadata)
\brief Execute algorithm under test.
\param[in] in_buf pointer to memory buffer containing input data for algorithm
\param[in] in_num number of data bytes in input data buffer (in bytes)
\param[out] out_buf pointer to memory buffer for returning algorithm output
\param[in] out_num maximum number of data bytes returned as algorithm output (in bytes)
\param[in] output_prediction_metadata
true to emit predicted class metadata, false to emit class scores
\return 0 on success; -1 on error
*/
extern int32_t ExecuteAlgorithm (uint8_t *in_buf, uint32_t in_num, uint8_t *out_buf, uint32_t out_num,
bool output_prediction_metadata);

#ifdef __cplusplus
}
Expand Down
21 changes: 10 additions & 11 deletions RockPaperScissors/AppKit-E8_USB/algorithm/algorithm_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,13 @@
// Input Data block size, in bytes
#ifndef ALGO_DATA_IN_BLOCK_SIZE
#define ALGO_DATA_IN_BLOCK_SIZE (ML_IMAGE_WIDTH * ML_IMAGE_HEIGHT * 3U)
#endif

#ifndef ALGO_DATA_OUT_BLOCK_SIZE
#if defined(OUTPUT_PREDICTION_METADATA) && OUTPUT_PREDICTION_METADATA
#define ALGO_DATA_OUT_BLOCK_SIZE (120U)
#else
#define ALGO_DATA_OUT_BLOCK_SIZE (MODEL_NUM_CLASSES * sizeof(float))
#endif
#endif

#endif
#endif

#define ALGO_DATA_OUT_CLASS_SCORES_BLOCK_SIZE (MODEL_NUM_CLASSES * sizeof(float))
#define ALGO_DATA_OUT_METADATA_BLOCK_SIZE (120U)

#ifndef ALGO_DATA_OUT_BLOCK_SIZE
#define ALGO_DATA_OUT_BLOCK_SIZE ALGO_DATA_OUT_CLASS_SCORES_BLOCK_SIZE
#endif

#endif
28 changes: 16 additions & 12 deletions RockPaperScissors/AppKit-E8_USB/algorithm/algorithm_user.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -159,16 +159,19 @@ void ResetAlgorithm (void) {
*/

/**
\fn int32_t ExecuteAlgorithm (uint8_t *in_buf, uint32_t in_num, uint8_t *out_buf, uint32_t out_num)
\brief Execute algorithm under test.
\param[in] in_buf pointer to input frame buffer (RGB888, HWC, 224x224x3)
\param[in] in_num number of bytes in input buffer
\param[out] out_buf pointer to output buffer (receives runner_output_label_t)
\param[in] out_num maximum bytes available in output buffer
\return 0 on success; -1 on error
*/
int32_t ExecuteAlgorithm(uint8_t *in_buf, uint32_t in_num,
uint8_t *out_buf, uint32_t out_num) {
\fn int32_t ExecuteAlgorithm (uint8_t *in_buf, uint32_t in_num, uint8_t *out_buf, uint32_t out_num, bool output_prediction_metadata)
\brief Execute algorithm under test.
\param[in] in_buf pointer to input frame buffer (RGB888, HWC, 224x224x3)
\param[in] in_num number of bytes in input buffer
\param[out] out_buf pointer to output buffer (receives runner_output_label_t)
\param[in] out_num maximum bytes available in output buffer
\param[in] output_prediction_metadata
true to emit predicted class metadata, false to emit class scores
\return 0 on success; -1 on error
*/
int32_t ExecuteAlgorithm(uint8_t *in_buf, uint32_t in_num,
uint8_t *out_buf, uint32_t out_num,
bool output_prediction_metadata) {

#ifndef SIMULATOR
vStreamStatus_t v_status;
Expand Down Expand Up @@ -223,7 +226,8 @@ int32_t ExecuteAlgorithm(uint8_t *in_buf, uint32_t in_num,
uint32_t post_process_time = profiler_start();
#endif

postprocess(*ctx, in_buf, IMAGE_WIDTH, IMAGE_HEIGHT, out_buf, out_num);
postprocess(*ctx, in_buf, IMAGE_WIDTH, IMAGE_HEIGHT, out_buf, out_num,
output_prediction_metadata);

#if !defined(SIMULATOR) && defined(USE_SEGGER_SYSVIEW)
SEGGER_SYSVIEW_MarkStop(SYSVIEW_MARKER_POST_PROCESS);
Expand Down Expand Up @@ -303,4 +307,4 @@ int32_t ExecuteAlgorithm(uint8_t *in_buf, uint32_t in_num,
#endif

return 0;
}
}
44 changes: 24 additions & 20 deletions RockPaperScissors/AppKit-E8_USB/algorithm/arm_executor_runner.cc
Original file line number Diff line number Diff line change
Expand Up @@ -939,31 +939,35 @@ void print_outputs(RunnerContext& ctx)
* \param[in] ctx RunnerContext after a successful run_inference().
* \param[in] img_buf RGB888 frame buffer to draw the label onto.
* \param[in] img_width Frame width in pixels.
* \param[in] img_height Frame height in pixels
* \param[out] out_buf Caller buffer to receive detection_result_t result.
* \param[in] out_num Byte size of out_buf.
*/
void postprocess(RunnerContext& ctx, uint8_t* img_buf,
uint32_t img_width, uint32_t img_height,
uint8_t* out_buf, uint32_t out_num) {
* \param[in] img_height Frame height in pixels
* \param[out] out_buf Caller buffer to receive detection_result_t result.
* \param[in] out_num Byte size of out_buf.
* \param[in] output_prediction_metadata
* true to emit predicted class metadata, false to emit class scores.
*/
void postprocess(RunnerContext& ctx, uint8_t* img_buf,
uint32_t img_width, uint32_t img_height,
uint8_t* out_buf, uint32_t out_num,
bool output_prediction_metadata) {

memset(&output_label, 0, sizeof(output_label));

/* Decode output tensor → output_label, conf_int, classify_object */
print_outputs(ctx);

/* Copy shortened label plus confidence into caller's output buffer */
#if OUTPUT_PREDICTION_METADATA
if (out_num >= sizeof(output_label_t)) {
memcpy(out_buf, &output_label, sizeof(output_label));
}
#else
if (out_num >= sizeof(class_probs)) {
memcpy(out_buf, class_probs, sizeof(class_probs));
}
#endif

/* Only draw if label is valid */
if (output_prediction_metadata) {
/* Copy predicted label, confidence, and class index into caller's output buffer */
if (out_num >= sizeof(output_label_t)) {
memcpy(out_buf, &output_label, sizeof(output_label));
}
} else {
/* Copy class confidence scores into caller's output buffer */
if (out_num >= sizeof(class_probs)) {
memcpy(out_buf, class_probs, sizeof(class_probs));
}
}

/* Only draw if label is valid */
if (output_label.label_name[0] != '\0')
{
/* Format label string and draw onto frame */
Expand Down Expand Up @@ -1046,4 +1050,4 @@ bool run_inference(RunnerContext& ctx) {
ctx.method_name, status);

return (status == Error::Ok);
}
}
18 changes: 10 additions & 8 deletions RockPaperScissors/AppKit-E8_USB/algorithm/arm_executor_runner.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,11 +110,13 @@ bool run_inference(RunnerContext &ctx);
* \param[in] ctx RunnerContext after a successful run_inference().
* \param[in] img_buf RGB888 frame buffer to draw the label onto.
* \param[in] img_width Frame width in pixels.
* \param[in] img_height Frame height in pixels
* \param[out] out_buf Caller buffer to receive runner_output_label_t result.
* \param[in] out_num Byte size of out_buf.
*/
void postprocess(RunnerContext &ctx, uint8_t *img_buf, uint32_t img_width, uint32_t img_height,
uint8_t *out_buf, uint32_t out_num);

#endif /* ARM_EXECUTOR_RUNNER_H */
* \param[in] img_height Frame height in pixels
* \param[out] out_buf Caller buffer to receive runner_output_label_t result.
* \param[in] out_num Byte size of out_buf.
* \param[in] output_prediction_metadata
* true to emit predicted class metadata, false to emit class scores.
*/
void postprocess(RunnerContext &ctx, uint8_t *img_buf, uint32_t img_width, uint32_t img_height,
uint8_t *out_buf, uint32_t out_num, bool output_prediction_metadata);

#endif /* ARM_EXECUTOR_RUNNER_H */
22 changes: 22 additions & 0 deletions RockPaperScissors/AppKit-E8_USB/algorithm/sds_control.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ osThreadAttr_t attr_sdsControlThread = {
static volatile uint32_t idle_cnt = 0U;
static volatile uint8_t rst_idle_cnt = 0U;
static uint32_t no_load_cnt = 0U;
static volatile bool output_prediction_metadata_enabled = false;

#ifdef RTE_CMSIS_RTOS2_RTX5
// Measure system idle time if OS is RTX5
Expand Down Expand Up @@ -152,6 +153,26 @@ void sdsStatusLED (void) {
ticks--;
}

// Output metadata control state driven by SDSIO user flag 5.
bool sdsIsPredictionMetadataEnabled (void) {
return output_prediction_metadata_enabled;
}

static void sdsPredictionMetadataControlUpdate (void) {
bool requested;

requested = ((sdsFlags & SDS_USER_FLAG_OUTPUT_PREDICTION_METADATA) != 0U);

if (requested != output_prediction_metadata_enabled) {
output_prediction_metadata_enabled = requested;
if (requested) {
sdsFlagsModify(SDS_USER_FLAG_OUTPUT_PREDICTION_METADATA, 0U);
} else {
sdsFlagsModify(0U, SDS_USER_FLAG_OUTPUT_PREDICTION_METADATA);
}
}
}

// SDS event callback
static void sds_event_callback (sdsId_t id, uint32_t event) {
(void)id;
Expand Down Expand Up @@ -193,6 +214,7 @@ __NO_RETURN void sdsControlThread (void *argument) {

for (;;) {
sdsExchange(); // Exchange control information with host
sdsPredictionMetadataControlUpdate(); // Update runtime ML_Out format control

// Detect if user button was pressed
btn_val = vioGetSignal(vioBUTTON0);
Expand Down
30 changes: 18 additions & 12 deletions RockPaperScissors/AppKit-E8_USB/algorithm/sds_control.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,24 @@
*/

#ifndef SDS_CONTROL_H_
#define SDS_CONTROL_H_

#include <stdint.h>
#include "cmsis_compiler.h"

#ifdef __cplusplus
extern "C"
{
#endif

// SDS control thread function
extern __NO_RETURN void sdsControlThread (void *argument);
#define SDS_CONTROL_H_

#include <stdbool.h>
#include <stdint.h>
#include "cmsis_compiler.h"

#define SDS_USER_FLAG_OUTPUT_PREDICTION_METADATA (1UL << 5)

#ifdef __cplusplus
extern "C"
{
#endif

// Returns true when ML_Out should include predicted class metadata.
extern bool sdsIsPredictionMetadataEnabled (void);

// SDS control thread function
extern __NO_RETURN void sdsControlThread (void *argument);

// Application main function
extern int32_t app_main (void);
Expand Down
Loading