Update message_handler_openamp to use NPU profiler

The message_handler_openamp application now uses the NPU profiler to use
a common way to collect profiling data and report it.

Change-Id: Ia2a860c790facc5193aca065636c58e1b5bbef22
Signed-off-by: Mikael Olsson <mikael.olsson@arm.com>
diff --git a/applications/message_handler_openamp/CMakeLists.txt b/applications/message_handler_openamp/CMakeLists.txt
index bc1f4a4..00e7995 100644
--- a/applications/message_handler_openamp/CMakeLists.txt
+++ b/applications/message_handler_openamp/CMakeLists.txt
@@ -1,6 +1,5 @@
 #
 # SPDX-FileCopyrightText: Copyright 2022-2023 Arm Limited and/or its affiliates <open-source-office@arm.com>
-#
 # SPDX-License-Identifier: Apache-2.0
 #
 # Licensed under the Apache License, Version 2.0 (the License); you may
@@ -61,6 +60,7 @@
         $<$<TARGET_EXISTS:ethosu_core_driver>:ethosu_core_driver>
         ethosu_log
         ethosu_mailbox
+        ethosu_profiler
         freertos_kernel
         inference_process
         openamp-freertos)
diff --git a/applications/message_handler_openamp/inference_runner.cpp b/applications/message_handler_openamp/inference_runner.cpp
index 00e95a9..c290773 100644
--- a/applications/message_handler_openamp/inference_runner.cpp
+++ b/applications/message_handler_openamp/inference_runner.cpp
@@ -1,6 +1,5 @@
 /*
  * SPDX-FileCopyrightText: Copyright 2022-2023 Arm Limited and/or its affiliates <open-source-office@arm.com>
- *
  * SPDX-License-Identifier: Apache-2.0
  *
  * Licensed under the Apache License, Version 2.0 (the License); you may
@@ -25,6 +24,7 @@
 #include <cstdlib>
 
 #include <ethosu_log.h>
+#include <ethosu_profiler.hpp>
 
 #if defined(ETHOSU)
 #include <ethosu_driver.h>
@@ -32,6 +32,17 @@
 #endif
 
 /*****************************************************************************
+ * JobContext
+ *****************************************************************************/
+
+struct JobContext {
+    JobContext(Message *msg) : rsp(msg), profiler_context({}) {}
+
+    Message *rsp;
+    struct ethosu_profiler_context profiler_context;
+};
+
+/*****************************************************************************
  * InferenceRunner
  *****************************************************************************/
 
@@ -83,9 +94,9 @@
 void InferenceRunner::handleInferenceRequest(const uint32_t src,
                                              const uint64_t msgId,
                                              const EthosU::ethosu_core_msg_inference_req &request) {
-    auto message =
-        new Message(src, EthosU::ETHOSU_CORE_MSG_INFERENCE_RSP, msgId, sizeof(EthosU::ethosu_core_msg_inference_rsp));
-    auto &response = message->rpmsg.inf_rsp;
+    auto jobContext = new JobContext(
+        new Message(src, EthosU::ETHOSU_CORE_MSG_INFERENCE_RSP, msgId, sizeof(EthosU::ethosu_core_msg_inference_rsp)));
+    auto &response = jobContext->rsp->rpmsg.inf_rsp;
 
     // Setup PMU configuration
     response.pmu_cycle_counter_enable = request.pmu_cycle_counter_enable;
@@ -95,9 +106,11 @@
     }
 
     // Run inference
-    auto job    = makeInferenceJob(request, response);
+    auto job    = makeInferenceJob(request, *jobContext);
     auto failed = inference.runJob(job);
 
+    ethosu_profiler_report(&jobContext->profiler_context);
+
     // Send response rpmsg
     response.ofm_count = job.output.size();
     response.status    = failed ? EthosU::ETHOSU_CORE_STATUS_ERROR : EthosU::ETHOSU_CORE_STATUS_OK;
@@ -106,11 +119,12 @@
         response.ofm_size[i] = job.output[i].size;
     }
 
-    responseQueue.send(message);
+    responseQueue.send(jobContext->rsp);
+    delete jobContext;
 }
 
 InferenceProcess::InferenceJob InferenceRunner::makeInferenceJob(const EthosU::ethosu_core_msg_inference_req &request,
-                                                                 EthosU::ethosu_core_msg_inference_rsp &response) {
+                                                                 JobContext &jobContext) {
     InferenceProcess::InferenceJob job;
 
     job.networkModel =
@@ -126,7 +140,7 @@
             InferenceProcess::DataPtr(reinterpret_cast<void *>(request.ofm[i].ptr), request.ofm[i].size));
     }
 
-    job.externalContext = &response;
+    job.externalContext = &jobContext;
 
     return job;
 }
@@ -137,7 +151,8 @@
 void ethosu_inference_begin(ethosu_driver *drv, void *userArg) {
     LOG_DEBUG("");
 
-    auto response = static_cast<EthosU::ethosu_core_msg_inference_rsp *>(userArg);
+    auto context   = static_cast<JobContext *>(userArg);
+    auto &response = context->rsp->rpmsg.inf_rsp;
 
     // Calculate maximum number of events
     const int numEvents = std::min(static_cast<int>(ETHOSU_PMU_Get_NumEventCounters()), ETHOSU_CORE_PMU_MAX);
@@ -147,12 +162,12 @@
 
     // Configure and enable events
     for (int i = 0; i < numEvents; i++) {
-        ETHOSU_PMU_Set_EVTYPER(drv, i, static_cast<ethosu_pmu_event_type>(response->pmu_event_config[i]));
+        ETHOSU_PMU_Set_EVTYPER(drv, i, static_cast<ethosu_pmu_event_type>(response.pmu_event_config[i]));
         ETHOSU_PMU_CNTR_Enable(drv, 1u << i);
     }
 
     // Enable cycle counter
-    if (response->pmu_cycle_counter_enable) {
+    if (response.pmu_cycle_counter_enable) {
         ETHOSU_PMU_PMCCNTR_CFG_Set_Stop_Event(drv, ETHOSU_PMU_NPU_IDLE);
         ETHOSU_PMU_PMCCNTR_CFG_Set_Start_Event(drv, ETHOSU_PMU_NPU_ACTIVE);
 
@@ -162,14 +177,23 @@
 
     // Reset all counters
     ETHOSU_PMU_EVCNTR_ALL_Reset(drv);
+
+    ethosu_profiler_start(&context->profiler_context);
 }
 
 void ethosu_inference_end(ethosu_driver *drv, void *userArg) {
-    auto response = static_cast<EthosU::ethosu_core_msg_inference_rsp *>(userArg);
+    LOG_DEBUG("");
+
+    auto context   = static_cast<JobContext *>(userArg);
+    auto &response = context->rsp->rpmsg.inf_rsp;
+
+    ethosu_profiler_end(&context->profiler_context);
 
     // Get cycle counter
-    if (response->pmu_cycle_counter_enable) {
-        response->pmu_cycle_counter_count = ETHOSU_PMU_Get_CCNTR(drv);
+    if (response.pmu_cycle_counter_enable) {
+        uint64_t cycleCount              = ETHOSU_PMU_Get_CCNTR(drv);
+        response.pmu_cycle_counter_count = cycleCount;
+        ethosu_profiler_add_to_pmu_cycles(&context->profiler_context, cycleCount);
     }
 
     // Calculate maximum number of events
@@ -178,12 +202,14 @@
     // Get event counters
     int i;
     for (i = 0; i < numEvents; i++) {
-        response->pmu_event_count[i] = ETHOSU_PMU_Get_EVCNTR(drv, i);
+        uint32_t eventValue         = ETHOSU_PMU_Get_EVCNTR(drv, i);
+        response.pmu_event_count[i] = eventValue;
+        ethosu_profiler_add_to_pmu_event(&context->profiler_context, i, eventValue);
     }
 
     for (; i < ETHOSU_CORE_PMU_MAX; i++) {
-        response->pmu_event_config[i] = 0;
-        response->pmu_event_count[i]  = 0;
+        response.pmu_event_config[i] = 0;
+        response.pmu_event_count[i]  = 0;
     }
 
     // Disable PMU
diff --git a/applications/message_handler_openamp/inference_runner.hpp b/applications/message_handler_openamp/inference_runner.hpp
index c9461a0..f87aa7a 100644
--- a/applications/message_handler_openamp/inference_runner.hpp
+++ b/applications/message_handler_openamp/inference_runner.hpp
@@ -1,6 +1,5 @@
 /*
  * SPDX-FileCopyrightText: Copyright 2022-2023 Arm Limited and/or its affiliates <open-source-office@arm.com>
- *
  * SPDX-License-Identifier: Apache-2.0
  *
  * Licensed under the Apache License, Version 2.0 (the License); you may
@@ -27,6 +26,12 @@
 #include <inference_process.hpp>
 
 /*****************************************************************************
+ * JobContext
+ *****************************************************************************/
+
+struct JobContext;
+
+/*****************************************************************************
  * InferenceRunner
  *****************************************************************************/
 
@@ -45,7 +50,7 @@
                                 const uint64_t msgId,
                                 const EthosU::ethosu_core_msg_inference_req &request);
     InferenceProcess::InferenceJob makeInferenceJob(const EthosU::ethosu_core_msg_inference_req &request,
-                                                    EthosU::ethosu_core_msg_inference_rsp &response);
+                                                    JobContext &context);
 
     MessageHandler::InferenceQueue &inferenceQueue;
     MessageHandler::ResponseQueue &responseQueue;