Add Event Recorder Profiling

* Add event recorded profiling to ethosu_profiler.
* Rename ethosu_profiler to layer_by_layer_profiler.

Change-Id: Ie39c29845b2d1eb6d9d72e3fce68bf373e9dc888
diff --git a/applications/inference_process/CMakeLists.txt b/applications/inference_process/CMakeLists.txt
index 4bd75c4..1378181 100644
--- a/applications/inference_process/CMakeLists.txt
+++ b/applications/inference_process/CMakeLists.txt
@@ -24,8 +24,8 @@
                            PRIVATE ${TENSORFLOW_PATH} ${TENSORFLOW_PATH}/tensorflow/lite/micro/tools/make/downloads/flatbuffers/include)
 
 target_link_libraries(inference_process PRIVATE tflu cmsis_core cmsis_device)
-if (TARGET ethosu_profiler)
-    target_link_libraries(inference_process PRIVATE ethosu_profiler)
+if (TARGET layer_by_layer_profiler)
+    target_link_libraries(inference_process PRIVATE layer_by_layer_profiler)
 endif()
 if (TARGET arm_profiler)
     target_link_libraries(inference_process PRIVATE arm_profiler)
diff --git a/applications/inference_process/src/inference_process.cpp b/applications/inference_process/src/inference_process.cpp
index 009706e..511a139 100644
--- a/applications/inference_process/src/inference_process.cpp
+++ b/applications/inference_process/src/inference_process.cpp
@@ -26,7 +26,7 @@
 
 #include "arm_profiler.hpp"
 #ifdef ETHOSU
-#include "ethosu_profiler.hpp"
+#include "layer_by_layer_profiler.hpp"
 #endif
 
 #include "inference_process.hpp"
@@ -202,7 +202,7 @@
     // Create the TFL micro interpreter
     tflite::AllOpsResolver resolver;
 #ifdef ETHOSU
-    tflite::EthosUProfiler profiler;
+    tflite::LayerByLayerProfiler profiler;
 #else
     tflite::ArmProfiler profiler;
 #endif
diff --git a/event_recorder.cmake b/event_recorder.cmake
index 3823896..bb9efd9 100644
--- a/event_recorder.cmake
+++ b/event_recorder.cmake
@@ -16,17 +16,18 @@
 # limitations under the License.
 #
 
+add_library(rte_component INTERFACE)
+target_include_directories(rte_component INTERFACE lib/rte_component/include)
+target_link_libraries(rte_component INTERFACE cmsis_device)
+target_compile_definitions(rte_component INTERFACE RTE_Components_CMSIS_device_header=\"${ARM_CPU}${ARM_FEATURES}.h\")
+
 add_library(event_recorder INTERFACE)
 
 target_include_directories(event_recorder INTERFACE
     ${CMSIS_VIEW_PATH}/EventRecorder/Include
     ${CMSIS_VIEW_PATH}/EventRecorder/Config)
 
-target_include_directories(event_recorder INTERFACE
-      ${CMSIS_VIEW_PATH}/EventRecorder/Config)
+target_link_libraries(event_recorder INTERFACE rte_component)
+target_sources(event_recorder INTERFACE ${CMSIS_VIEW_PATH}/EventRecorder/Source/EventRecorder.c)
 
-target_link_libraries(event_recorder INTERFACE cmsis_device)
-target_sources(event_recorder INTERFACE
-      ${CMSIS_VIEW_PATH}/EventRecorder/Source/EventRecorder.c)
 
-target_compile_definitions(event_recorder INTERFACE RTE_Components_CMSIS_device_header=\"${ARM_CPU}${ARM_FEATURES}.h\")
diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt
index ae18806..5536949 100644
--- a/lib/CMakeLists.txt
+++ b/lib/CMakeLists.txt
@@ -16,12 +16,11 @@
 # limitations under the License.
 #
 
-# Build ethosu_profiler
-add_subdirectory(ethosu_profiler)
+# Build layer_by_layer_profiler
+add_subdirectory(layer_by_layer_profiler)
 
 # Build arm_profiler
 add_subdirectory(arm_profiler)
 
 # Build ethosu_monitor
 add_subdirectory(ethosu_monitor)
-
diff --git a/lib/ethosu_profiler/CMakeLists.txt b/lib/layer_by_layer_profiler/CMakeLists.txt
similarity index 69%
rename from lib/ethosu_profiler/CMakeLists.txt
rename to lib/layer_by_layer_profiler/CMakeLists.txt
index 336a696..9774685 100644
--- a/lib/ethosu_profiler/CMakeLists.txt
+++ b/lib/layer_by_layer_profiler/CMakeLists.txt
@@ -19,8 +19,8 @@
 if (NOT TARGET ethosu_core_driver)
     return()
 endif()
-add_library(ethosu_profiler INTERFACE)
 
-target_link_libraries(ethosu_profiler INTERFACE ethosu_core_driver tflu)
-target_include_directories(ethosu_profiler INTERFACE include)
-target_sources(ethosu_profiler INTERFACE src/ethosu_profiler.cpp)
+add_library(layer_by_layer_profiler INTERFACE)
+target_link_libraries(layer_by_layer_profiler INTERFACE ethosu_core_driver tflu event_recorder)
+target_include_directories(layer_by_layer_profiler INTERFACE include)
+target_sources(layer_by_layer_profiler INTERFACE src/layer_by_layer_profiler.cpp)
diff --git a/lib/ethosu_profiler/include/ethosu_profiler.hpp b/lib/layer_by_layer_profiler/include/layer_by_layer_profiler.hpp
similarity index 73%
rename from lib/ethosu_profiler/include/ethosu_profiler.hpp
rename to lib/layer_by_layer_profiler/include/layer_by_layer_profiler.hpp
index 12c337c..8e8dc0f 100644
--- a/lib/ethosu_profiler/include/ethosu_profiler.hpp
+++ b/lib/layer_by_layer_profiler/include/layer_by_layer_profiler.hpp
@@ -16,9 +16,10 @@
  * limitations under the License.
  */
 
-#ifndef ETHOSU_PROFILER_H
-#define ETHOSU_PROFILER_H
+#ifndef LAYER_BY_LAYER_PROFILER_H
+#define LAYER_BY_LAYER_PROFILER_H
 
+#include "EventRecorder.h"
 #include "tensorflow/lite/kernels/internal/compatibility.h"
 #include <memory>
 #include <pmu_ethosu.h>
@@ -26,9 +27,12 @@
 // NOTE: This profiler only works on systems with 1 NPU due to the use of
 // ethosu_reserve_driver().
 namespace tflite {
-class EthosUProfiler : public MicroProfiler {
+class LayerByLayerProfiler : public MicroProfiler {
 public:
-    EthosUProfiler(size_t max_events = 200);
+    enum Backend { PRINTF, EVENT_RECORDER };
+    LayerByLayerProfiler(size_t max_events = 200,
+                         Backend backend   = PRINTF,
+                         int32_t event_id  = EventID(EventLevelError, EvtStatistics_No, EventRecordNone));
     uint32_t BeginEvent(const char *tag);
     void EndEvent(uint32_t event_handle);
     uint64_t GetTotalTicks() const;
@@ -39,6 +43,9 @@
     std::unique_ptr<const char *[]> tags_;
     std::unique_ptr<uint64_t[]> start_ticks_;
     std::unique_ptr<uint64_t[]> end_ticks_;
+
+    Backend backend_;
+    int32_t event_id_;
     size_t num_events_;
 
     TF_LITE_REMOVE_VIRTUAL_DELETE;
diff --git a/lib/ethosu_profiler/src/ethosu_profiler.cpp b/lib/layer_by_layer_profiler/src/layer_by_layer_profiler.cpp
similarity index 74%
rename from lib/ethosu_profiler/src/ethosu_profiler.cpp
rename to lib/layer_by_layer_profiler/src/layer_by_layer_profiler.cpp
index 50b65f0..f7922cb 100644
--- a/lib/ethosu_profiler/src/ethosu_profiler.cpp
+++ b/lib/layer_by_layer_profiler/src/layer_by_layer_profiler.cpp
@@ -23,7 +23,7 @@
 
 #include <string.h>
 
-#include "ethosu_profiler.hpp"
+#include "layer_by_layer_profiler.hpp"
 #include <ethosu_driver.h>
 #include <inttypes.h>
 #include <stdio.h>
@@ -38,7 +38,9 @@
 
 namespace tflite {
 
-EthosUProfiler::EthosUProfiler(size_t max_events) : max_events_(max_events), num_events_(0) {
+LayerByLayerProfiler::LayerByLayerProfiler(size_t max_events, Backend backend, int32_t event_id) :
+    max_events_(max_events), backend_(backend), event_id_(event_id), num_events_(0) {
+
     tags_        = std::make_unique<const char *[]>(max_events_);
     start_ticks_ = std::make_unique<uint64_t[]>(max_events_);
     end_ticks_   = std::make_unique<uint64_t[]>(max_events_);
@@ -50,7 +52,7 @@
 }
 
 // NOTE: THIS PROFILER ONLY WORKS ON SYSTEMS WITH 1 NPU
-uint32_t EthosUProfiler::BeginEvent(const char *tag) {
+uint32_t LayerByLayerProfiler::BeginEvent(const char *tag) {
     if (num_events_ == max_events_) {
         tflite::GetMicroErrorReporter()->Report("Profiling event overflow, max: %u events", max_events_);
         num_events_ = 0;
@@ -74,7 +76,7 @@
 }
 
 // NOTE: THIS PROFILER ONLY WORKS ON SYSTEMS WITH 1 NPU
-void EthosUProfiler::EndEvent(uint32_t event_handle) {
+void LayerByLayerProfiler::EndEvent(uint32_t event_handle) {
     TFLITE_DCHECK(event_handle < max_events_);
 
     if (strcmp("ethos-u", tags_[event_handle]) == 0) {
@@ -85,12 +87,16 @@
         end_ticks_[event_handle] = GetCurrentTimeTicks();
     }
 
-    printf("%s : cycle_cnt : %" PRIu64 " cycles\n",
-           tags_[event_handle],
-           end_ticks_[event_handle] - start_ticks_[event_handle]);
+    if (backend_ == PRINTF) {
+        printf("%s : cycle_cnt : %" PRIu64 " cycles\n",
+               tags_[event_handle],
+               end_ticks_[event_handle] - start_ticks_[event_handle]);
+    } else {
+        EventRecord2(event_id_, (int32_t)event_handle, end_ticks_[event_handle] - start_ticks_[event_handle]);
+    }
 }
 
-uint64_t EthosUProfiler::GetTotalTicks() const {
+uint64_t LayerByLayerProfiler::GetTotalTicks() const {
     uint64_t ticks = 0;
 
     for (size_t i = 0; i < num_events_; ++i) {
@@ -100,11 +106,14 @@
     return ticks;
 }
 
-void EthosUProfiler::Log() const {
+void LayerByLayerProfiler::Log() const {
+
 #if !defined(TF_LITE_STRIP_ERROR_STRINGS)
-    for (int i = 0; i < num_events_; ++i) {
-        uint64_t ticks = end_ticks_[i] - start_ticks_[i];
-        printf("%s took %" PRIu64 " cycles\n", tags_[i], ticks);
+    if (backend_ == PRINTF) {
+        for (size_t i = 0; i < num_events_; ++i) {
+            uint64_t ticks = end_ticks_[i] - start_ticks_[i];
+            printf("%s took %" PRIu64 " cycles\n", tags_[i], ticks);
+        }
     }
 #endif
 }
diff --git a/lib/ethosu_monitor/include/RTE_Components.h b/lib/rte_component/include/RTE_Components.h
similarity index 91%
rename from lib/ethosu_monitor/include/RTE_Components.h
rename to lib/rte_component/include/RTE_Components.h
index 97b6624..024f52b 100644
--- a/lib/ethosu_monitor/include/RTE_Components.h
+++ b/lib/rte_component/include/RTE_Components.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021 Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2021 Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: Apache-2.0
  *
@@ -15,6 +15,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 #ifndef RTE_COMPONENTS_H
 #define RTE_COMPONENTS_H