IVGCVSW-4320 Implement the bulk reporting of counter values from backends

* Implemented unit test for ReportCounters function in BackendProfiling

Signed-off-by: Jim Flynn <jim.flynn@arm.com>
Signed-off-by: Sadik Armagan <sadik.armagan@arm.com>
Change-Id: Iec342a96060c8ef6090e6cc67bda8a7a3e890c50
diff --git a/include/armnn/backends/profiling/IBackendProfiling.hpp b/include/armnn/backends/profiling/IBackendProfiling.hpp
index a649ece..989c5e8 100644
--- a/include/armnn/backends/profiling/IBackendProfiling.hpp
+++ b/include/armnn/backends/profiling/IBackendProfiling.hpp
@@ -18,6 +18,8 @@
 
 struct CounterValue
 {
+    CounterValue(uint16_t id, uint32_t value) :
+        counterId(id), counterValue(value) {}
     uint16_t counterId;
     uint32_t counterValue;
 };
diff --git a/src/profiling/test/ProfilingMocks.hpp b/src/profiling/test/ProfilingMocks.hpp
index 9d13213..3782a0f 100644
--- a/src/profiling/test/ProfilingMocks.hpp
+++ b/src/profiling/test/ProfilingMocks.hpp
@@ -5,6 +5,7 @@
 
 #pragma once
 
+#include <Holder.hpp>
 #include <IProfilingConnectionFactory.hpp>
 #include <IProfilingService.hpp>
 #include <ProfilingGuidGenerator.hpp>
@@ -647,6 +648,74 @@
     Counters    m_Counters;
 };
 
+class MockProfilingService : public IProfilingService, public IRegisterCounterMapping
+{
+public:
+    MockProfilingService(MockBufferManager& mockBufferManager,
+                         bool isProfilingEnabled,
+                         const CaptureData& captureData) :
+        m_SendCounterPacket(mockBufferManager),
+        m_IsProfilingEnabled(isProfilingEnabled),
+        m_CaptureData(captureData) {}
+
+    /// Return the next random Guid in the sequence
+    ProfilingDynamicGuid NextGuid() override
+    {
+        return m_GuidGenerator.NextGuid();
+    }
+
+    /// Create a ProfilingStaticGuid based on a hash of the string
+    ProfilingStaticGuid GenerateStaticId(const std::string& str) override
+    {
+        return m_GuidGenerator.GenerateStaticId(str);
+    }
+
+    std::unique_ptr<ISendTimelinePacket> GetSendTimelinePacket() const override
+    {
+        return nullptr;
+    }
+
+    const ICounterMappings& GetCounterMappings() const override
+    {
+        return m_CounterMapping;
+    }
+
+    ISendCounterPacket& GetSendCounterPacket() override
+    {
+        return m_SendCounterPacket;
+    }
+
+    bool IsProfilingEnabled() const override
+    {
+        return m_IsProfilingEnabled;
+    }
+
+    CaptureData GetCaptureData() override
+    {
+        CaptureData copy(m_CaptureData);
+        return copy;
+    }
+
+    void RegisterMapping(uint16_t globalCounterId,
+                         uint16_t backendCounterId,
+                         const armnn::BackendId& backendId) override
+    {
+        m_CounterMapping.RegisterMapping(globalCounterId, backendCounterId, backendId);
+    }
+
+    void Reset() override
+    {
+        m_CounterMapping.Reset();
+    }
+
+private:
+    ProfilingGuidGenerator m_GuidGenerator;
+    CounterIdMap m_CounterMapping;
+    SendCounterPacket m_SendCounterPacket;
+    bool m_IsProfilingEnabled;
+    CaptureData m_CaptureData;
+};
+
 } // namespace profiling
 
 } // namespace armnn
diff --git a/src/profiling/test/ProfilingTests.cpp b/src/profiling/test/ProfilingTests.cpp
index af9f1b8..c025aa2 100644
--- a/src/profiling/test/ProfilingTests.cpp
+++ b/src/profiling/test/ProfilingTests.cpp
@@ -3413,4 +3413,63 @@
     profilingService.ResetExternalProfilingOptions(options.m_ProfilingOptions, true);
 }
 
+BOOST_AUTO_TEST_CASE(CheckRegisterCounters)
+{
+    armnn::Runtime::CreationOptions options;
+    options.m_ProfilingOptions.m_EnableProfiling = true;
+    MockBufferManager mockBuffer(1024);
+    CaptureData captureData;
+    MockProfilingService mockProfilingService(
+        mockBuffer, options.m_ProfilingOptions.m_EnableProfiling, captureData);
+    armnn::BackendId cpuRefId(armnn::Compute::CpuRef);
+
+    mockProfilingService.RegisterMapping(6, 0, cpuRefId);
+    mockProfilingService.RegisterMapping(7, 1, cpuRefId);
+    mockProfilingService.RegisterMapping(8, 2, cpuRefId);
+
+    armnn::profiling::BackendProfiling backendProfiling(options,
+                                                        mockProfilingService,
+                                                        cpuRefId);
+
+    armnn::profiling::Timestamp timestamp;
+    timestamp.timestamp = 1000998;
+    timestamp.counterValues.emplace_back(0, 700);
+    timestamp.counterValues.emplace_back(2, 93);
+    std::vector<armnn::profiling::Timestamp> timestamps;
+    timestamps.push_back(timestamp);
+    backendProfiling.ReportCounters(timestamps);
+
+    auto readBuffer = mockBuffer.GetReadableBuffer();
+
+    uint32_t headerWord0 = ReadUint32(readBuffer, 0);
+    uint32_t headerWord1 = ReadUint32(readBuffer, 4);
+    uint64_t readTimestamp = ReadUint64(readBuffer, 8);
+
+    BOOST_TEST(((headerWord0 >> 26) & 0x0000003F) == 3); // packet family
+    BOOST_TEST(((headerWord0 >> 19) & 0x0000007F) == 0); // packet class
+    BOOST_TEST(((headerWord0 >> 16) & 0x00000007) == 0); // packet type
+    BOOST_TEST(headerWord1 == 20);                       // data length
+    BOOST_TEST(1000998 == readTimestamp);                // capture period
+
+    uint32_t offset = 16;
+    // Check Counter Index
+    uint16_t readIndex = ReadUint16(readBuffer, offset);
+    BOOST_TEST(6 == readIndex);
+
+    // Check Counter Value
+    offset += 2;
+    uint32_t readValue = ReadUint32(readBuffer, offset);
+    BOOST_TEST(700 == readValue);
+
+    // Check Counter Index
+    offset += 4;
+    readIndex = ReadUint16(readBuffer, offset);
+    BOOST_TEST(8 == readIndex);
+
+    // Check Counter Value
+    offset += 2;
+    readValue = ReadUint32(readBuffer, offset);
+    BOOST_TEST(93 == readValue);
+}
+
 BOOST_AUTO_TEST_SUITE_END()