IVGCVSW-6811 replace ProfilingService includes with IProfilingService

Change-Id: I00521756c8a19d10bfdc98c6ef4204c7f84901c6
Signed-off-by: Jim Flynn <jim.flynn@arm.com>
diff --git a/Android.mk b/Android.mk
index 688a188..fde489f 100644
--- a/Android.mk
+++ b/Android.mk
@@ -243,6 +243,7 @@
         src/profiling/DirectoryCaptureCommandHandler.cpp \
         src/profiling/FileOnlyProfilingConnection.cpp \
         src/profiling/Holder.cpp \
+        src/profiling/IProfilingService.cpp \
         src/profiling/PacketBuffer.cpp \
         src/profiling/PeriodicCounterCapture.cpp \
         src/profiling/PeriodicCounterSelectionCommandHandler.cpp \
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 7cb957e..16f0188 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -448,6 +448,8 @@
     src/profiling/IPacketBuffer.hpp
     src/profiling/IPeriodicCounterCapture.hpp
     src/profiling/IProfilingConnection.hpp
+    src/profiling/IProfilingService.cpp
+    src/profiling/IProfilingService.hpp
     src/profiling/IProfilingConnectionFactory.hpp
     src/profiling/NullProfilingConnection.hpp
     src/profiling/PacketBuffer.cpp
@@ -464,6 +466,7 @@
     src/profiling/ProfilingConnectionFactory.hpp
     src/profiling/ProfilingService.cpp
     src/profiling/ProfilingService.hpp
+    src/profiling/ProfilingState.hpp
     src/profiling/ProfilingStateMachine.cpp
     src/profiling/ProfilingStateMachine.hpp
     src/profiling/ProfilingUtils.cpp
diff --git a/include/armnn/BackendRegistry.hpp b/include/armnn/BackendRegistry.hpp
index 08e164c..40a117e 100644
--- a/include/armnn/BackendRegistry.hpp
+++ b/include/armnn/BackendRegistry.hpp
@@ -20,7 +20,7 @@
 namespace pipe
 {
 
-class ProfilingService;
+class IProfilingService;
 
 } // namespace arm
 } // namespace pipe
@@ -44,7 +44,7 @@
     size_t Size() const;
     BackendIdSet GetBackendIds() const;
     std::string GetBackendIdsAsString() const;
-    void SetProfilingService(armnn::Optional<arm::pipe::ProfilingService&> profilingService);
+    void SetProfilingService(armnn::Optional<arm::pipe::IProfilingService&> profilingService);
     void RegisterAllocator(const BackendId& id, std::shared_ptr<ICustomAllocator> alloc);
     std::unordered_map<BackendId, std::shared_ptr<ICustomAllocator>> GetAllocators();
     void RegisterMemoryOptimizerStrategy(const BackendId& id, std::shared_ptr<IMemoryOptimizerStrategy> strategy);
@@ -78,7 +78,7 @@
     BackendRegistry& operator=(const BackendRegistry&) = delete;
 
     FactoryStorage m_Factories;
-    armnn::Optional<arm::pipe::ProfilingService&> m_ProfilingService;
+    armnn::Optional<arm::pipe::IProfilingService&> m_ProfilingService;
     std::unordered_map<BackendId, std::shared_ptr<ICustomAllocator>> m_CustomMemoryAllocatorMap;
     std::unordered_map<BackendId, std::shared_ptr<IMemoryOptimizerStrategy>> m_MemoryOptimizerStrategyMap;
 };
diff --git a/include/armnn/backends/Workload.hpp b/include/armnn/backends/Workload.hpp
index ddcc5a8..7ffd5c5 100644
--- a/include/armnn/backends/Workload.hpp
+++ b/include/armnn/backends/Workload.hpp
@@ -10,7 +10,7 @@
 #include "WorkingMemDescriptor.hpp"
 
 #include <Profiling.hpp>
-#include <ProfilingService.hpp>
+#include <IProfilingService.hpp>
 
 #include <algorithm>
 
@@ -32,7 +32,7 @@
 
     BaseWorkload(const QueueDescriptor& descriptor, const WorkloadInfo& info)
         : m_Data(descriptor),
-          m_Guid(arm::pipe::ProfilingService::GetNextGuid())
+          m_Guid(arm::pipe::IProfilingService::GetNextGuid())
     {
         m_Data.Validate(info);
     }
diff --git a/include/armnn/profiling/ArmNNProfiling.hpp b/include/armnn/profiling/ArmNNProfiling.hpp
new file mode 100644
index 0000000..39d4a6b
--- /dev/null
+++ b/include/armnn/profiling/ArmNNProfiling.hpp
@@ -0,0 +1,22 @@
+//
+// Copyright © 2022 Arm Ltd and Contributors. All rights reserved.
+// SPDX-License-Identifier: MIT
+//
+
+#pragma once
+
+namespace arm
+{
+
+namespace pipe
+{
+// Static constants describing ArmNN's counter UID's
+static const uint16_t NETWORK_LOADS         = 0;
+static const uint16_t NETWORK_UNLOADS       = 1;
+static const uint16_t REGISTERED_BACKENDS   = 2;
+static const uint16_t UNREGISTERED_BACKENDS = 3;
+static const uint16_t INFERENCES_RUN        = 4;
+static const uint16_t MAX_ARMNN_COUNTER     = INFERENCES_RUN;
+} // namespace pipe
+
+} // namespace arm
diff --git a/profiling/server/src/basePipeServer/tests/BasePipeServerTests.cpp b/profiling/server/src/basePipeServer/tests/BasePipeServerTests.cpp
index 03de769..a0af25f 100644
--- a/profiling/server/src/basePipeServer/tests/BasePipeServerTests.cpp
+++ b/profiling/server/src/basePipeServer/tests/BasePipeServerTests.cpp
@@ -5,6 +5,8 @@
 
 #include <server/include/basePipeServer/ConnectionHandler.hpp>
 
+#include <BufferManager.hpp>
+#include <SendCounterPacket.hpp>
 #include <SocketProfilingConnection.hpp>
 #include <Processes.hpp>
 
@@ -94,4 +96,4 @@
     socketProfilingConnection.Close();
 }
 
-}
\ No newline at end of file
+}
diff --git a/src/armnn/BackendRegistry.cpp b/src/armnn/BackendRegistry.cpp
index 7b1f6bc..01f632f 100644
--- a/src/armnn/BackendRegistry.cpp
+++ b/src/armnn/BackendRegistry.cpp
@@ -5,7 +5,8 @@
 
 #include <armnn/BackendRegistry.hpp>
 #include <armnn/Exceptions.hpp>
-#include <ProfilingService.hpp>
+#include <armnn/profiling/ArmNNProfiling.hpp>
+#include <IProfilingService.hpp>
 
 namespace armnn
 {
@@ -102,7 +103,7 @@
     std::swap(instance.m_Factories, other);
 }
 
-void BackendRegistry::SetProfilingService(armnn::Optional<arm::pipe::ProfilingService&> profilingService)
+void BackendRegistry::SetProfilingService(armnn::Optional<arm::pipe::IProfilingService&> profilingService)
 {
     m_ProfilingService = profilingService;
 }
diff --git a/src/armnn/Layer.cpp b/src/armnn/Layer.cpp
index c827b4b..5818eef 100644
--- a/src/armnn/Layer.cpp
+++ b/src/armnn/Layer.cpp
@@ -5,7 +5,7 @@
 #include "Layer.hpp"
 
 #include "Graph.hpp"
-#include <ProfilingService.hpp>
+#include <IProfilingService.hpp>
 #include <armnn/utility/NumericCast.hpp>
 #include <armnn/backends/TensorHandle.hpp>
 #include <armnn/backends/WorkloadData.hpp>
@@ -202,7 +202,7 @@
 , m_Type(type)
 , m_BackendId()
 , m_BackendHint(EmptyOptional())
-, m_Guid(arm::pipe::ProfilingService::GetNextGuid())
+, m_Guid(arm::pipe::IProfilingService::GetNextGuid())
 {
     IgnoreUnused(layout);
     m_InputSlots.reserve(numInputSlots);
diff --git a/src/armnn/LoadedNetwork.cpp b/src/armnn/LoadedNetwork.cpp
index 1367552..1dbd1e3 100644
--- a/src/armnn/LoadedNetwork.cpp
+++ b/src/armnn/LoadedNetwork.cpp
@@ -20,6 +20,7 @@
 #include <armnn/backends/MemCopyWorkload.hpp>
 #include <backendsCommon/MemSyncWorkload.hpp>
 #include <armnn/BackendHelper.hpp>
+#include <armnn/profiling/ArmNNProfiling.hpp>
 
 #include <fmt/format.h>
 
@@ -82,7 +83,7 @@
 std::unique_ptr<LoadedNetwork> LoadedNetwork::MakeLoadedNetwork(std::unique_ptr<IOptimizedNetwork> net,
                                                                 std::string& errorMessage,
                                                                 const INetworkProperties& networkProperties,
-                                                                ProfilingService&  profilingService)
+                                                                arm::pipe::IProfilingService* profilingService)
 {
     std::unique_ptr<LoadedNetwork> loadedNetwork;
 
@@ -116,7 +117,7 @@
 
 LoadedNetwork::LoadedNetwork(std::unique_ptr<IOptimizedNetwork> net,
                              const INetworkProperties& networkProperties,
-                             ProfilingService&  profilingService) :
+                             arm::pipe::IProfilingService* profilingService) :
                              m_OptimizedNetwork(std::move(net)),
                              m_NetworkProperties(networkProperties),
                              m_TensorHandleFactoryRegistry(),
@@ -254,7 +255,7 @@
 
     ProfilingGuid networkGuid = m_OptimizedNetwork->GetGuid();
     std::unique_ptr<TimelineUtilityMethods> timelineUtils =
-                        TimelineUtilityMethods::GetTimelineUtils(m_ProfilingService);
+        TimelineUtilityMethods::GetTimelineUtils(*m_ProfilingService);
     if (timelineUtils)
     {
         timelineUtils->CreateTypedEntity(networkGuid, LabelsAndEventClasses::NETWORK_GUID);
@@ -549,7 +550,7 @@
     ProfilingGuid networkGuid = m_OptimizedNetwork->GetGuid();
 
     std::unique_ptr<TimelineUtilityMethods> timelineUtils =
-                        TimelineUtilityMethods::GetTimelineUtils(m_ProfilingService);
+        TimelineUtilityMethods::GetTimelineUtils(*m_ProfilingService);
 
     timelineUtils->CreateTypedEntity(networkGuid, LabelsAndEventClasses::NETWORK_GUID);
 
@@ -893,8 +894,8 @@
     }
 
     std::unique_ptr<TimelineUtilityMethods> timelineUtils =
-                        TimelineUtilityMethods::GetTimelineUtils(m_ProfilingService);
-    ProfilingGuid inferenceGuid = m_ProfilingService.GetNextGuid();
+                        TimelineUtilityMethods::GetTimelineUtils(*m_ProfilingService);
+    ProfilingGuid inferenceGuid = m_ProfilingService->GetNextGuid();
     if (timelineUtils)
     {
         // Add inference timeline trace if profiling is enabled.
@@ -910,9 +911,9 @@
     bool executionSucceeded = true;
 
     {
-        if (m_ProfilingService.IsProfilingEnabled())
+        if (m_ProfilingService->IsProfilingEnabled())
         {
-            m_ProfilingService.IncrementCounterValue(INFERENCES_RUN);
+            m_ProfilingService->IncrementCounterValue(INFERENCES_RUN);
         }
         ARMNN_SCOPED_PROFILING_EVENT(Compute::Undefined, "Execute");
         ARMNN_SCOPED_HEAP_PROFILING("Executing");
@@ -982,7 +983,7 @@
         ARMNN_ASSERT_MSG(inputWorkload, "No input workload created");
 
         std::unique_ptr<TimelineUtilityMethods> timelineUtils =
-                            TimelineUtilityMethods::GetTimelineUtils(m_ProfilingService);
+                            TimelineUtilityMethods::GetTimelineUtils(*m_ProfilingService);
         if (timelineUtils)
         {
             // Add Input Workload to the post-optimisation network structure
@@ -1070,7 +1071,7 @@
         ARMNN_ASSERT_MSG(outputWorkload, "No output workload created");
 
         std::unique_ptr<TimelineUtilityMethods> timelineUtils =
-            TimelineUtilityMethods::GetTimelineUtils(m_ProfilingService);
+            TimelineUtilityMethods::GetTimelineUtils(*m_ProfilingService);
         if (timelineUtils)
         {
             // Add Output Workload to the post-optimisation network structure
@@ -1683,8 +1684,8 @@
     };
 
     std::unique_ptr<TimelineUtilityMethods> timelineUtils =
-           TimelineUtilityMethods::GetTimelineUtils(m_ProfilingService);
-   ProfilingGuid inferenceGuid = m_ProfilingService.GetNextGuid();
+           TimelineUtilityMethods::GetTimelineUtils(*m_ProfilingService);
+    ProfilingGuid inferenceGuid = m_ProfilingService->GetNextGuid();
     if (timelineUtils)
     {
         // Add inference timeline trace if profiling is enabled.
diff --git a/src/armnn/LoadedNetwork.hpp b/src/armnn/LoadedNetwork.hpp
index 09d7604..19f2bcf 100644
--- a/src/armnn/LoadedNetwork.hpp
+++ b/src/armnn/LoadedNetwork.hpp
@@ -19,7 +19,7 @@
 #include <backendsCommon/memoryOptimizerStrategyLibrary/strategies/SingleAxisPriorityList.hpp>
 
 
-#include <ProfilingService.hpp>
+#include <IProfilingService.hpp>
 #include <TimelineUtilityMethods.hpp>
 
 #include <common/include/LabelsAndEventClasses.hpp>
@@ -78,7 +78,7 @@
     static std::unique_ptr<LoadedNetwork> MakeLoadedNetwork(std::unique_ptr<IOptimizedNetwork> net,
                                                             std::string& errorMessage,
                                                             const INetworkProperties& networkProperties,
-                                                            arm::pipe::ProfilingService& profilingService);
+                                                            arm::pipe::IProfilingService* profilingService);
 
     // NOTE we return by reference as the purpose of this method is only to provide
     // access to the private m_Profiler and in theory we should not need to increment
@@ -112,7 +112,7 @@
 
     LoadedNetwork(std::unique_ptr<IOptimizedNetwork> net,
                   const INetworkProperties& networkProperties,
-                  arm::pipe::ProfilingService& profilingService);
+                  arm::pipe::IProfilingService* profilingService);
 
     void EnqueueInput(const BindableLayer& layer, ITensorHandle* tensorHandle, const TensorInfo& tensorInfo);
 
@@ -158,7 +158,8 @@
 
     TensorHandleFactoryRegistry m_TensorHandleFactoryRegistry;
 
-    arm::pipe::ProfilingService& m_ProfilingService;
+    // NOTE: raw pointer because the profiling service is controlled by the Runtime
+    arm::pipe::IProfilingService* m_ProfilingService;
 
     struct ImportedTensorHandlePin
     {
diff --git a/src/armnn/Network.cpp b/src/armnn/Network.cpp
index 498c4a7..58e8b50 100644
--- a/src/armnn/Network.cpp
+++ b/src/armnn/Network.cpp
@@ -26,7 +26,7 @@
 #include <armnn/utility/IgnoreUnused.hpp>
 #include <armnn/utility/PolymorphicDowncast.hpp>
 
-#include <ProfilingService.hpp>
+#include <IProfilingService.hpp>
 
 #include <common/include/ProfilingGuid.hpp>
 
@@ -2866,18 +2866,18 @@
 
 OptimizedNetworkImpl::OptimizedNetworkImpl(const OptimizedNetworkImpl& other, const ModelOptions& modelOptions)
     : m_Graph(new Graph(*other.m_Graph.get()))
-    , m_Guid(arm::pipe::ProfilingService::GetNextGuid())
+    , m_Guid(arm::pipe::IProfilingService::GetNextGuid())
     , m_ModelOptions(modelOptions)
 {
 }
 
 OptimizedNetworkImpl::OptimizedNetworkImpl(std::unique_ptr<Graph> graph)
-    : m_Graph(std::move(graph)), m_Guid(arm::pipe::ProfilingService::GetNextGuid())
+    : m_Graph(std::move(graph)), m_Guid(arm::pipe::IProfilingService::GetNextGuid())
 {
 }
 
 OptimizedNetworkImpl::OptimizedNetworkImpl(std::unique_ptr<Graph> graph, const ModelOptions& modelOptions)
-    : m_Graph(std::move(graph)), m_Guid(arm::pipe::ProfilingService::GetNextGuid()), m_ModelOptions(modelOptions)
+    : m_Graph(std::move(graph)), m_Guid(arm::pipe::IProfilingService::GetNextGuid()), m_ModelOptions(modelOptions)
 {
 }
 
diff --git a/src/armnn/Runtime.cpp b/src/armnn/Runtime.cpp
index 640e594..4cc34ff 100644
--- a/src/armnn/Runtime.cpp
+++ b/src/armnn/Runtime.cpp
@@ -185,7 +185,7 @@
         std::unique_ptr<IOptimizedNetwork>(rawNetwork),
         errorMessage,
         networkProperties,
-        m_ProfilingService);
+        m_ProfilingService.get());
 
     if (!loadedNetwork)
     {
@@ -204,9 +204,9 @@
         context.second->AfterLoadNetwork(networkIdOut);
     }
 
-    if (m_ProfilingService.IsProfilingEnabled())
+    if (m_ProfilingService->IsProfilingEnabled())
     {
-        m_ProfilingService.IncrementCounterValue(arm::pipe::NETWORK_LOADS);
+        m_ProfilingService->IncrementCounterValue(arm::pipe::NETWORK_LOADS);
     }
 
     return Status::Success;
@@ -228,7 +228,7 @@
     }
 
     std::unique_ptr<arm::pipe::TimelineUtilityMethods> timelineUtils =
-        arm::pipe::TimelineUtilityMethods::GetTimelineUtils(m_ProfilingService);
+        arm::pipe::TimelineUtilityMethods::GetTimelineUtils(*m_ProfilingService.get());
     {
         std::lock_guard<std::mutex> lockGuard(m_Mutex);
 
@@ -250,9 +250,9 @@
             return Status::Failure;
         }
 
-        if (m_ProfilingService.IsProfilingEnabled())
+        if (m_ProfilingService->IsProfilingEnabled())
         {
-            m_ProfilingService.IncrementCounterValue(arm::pipe::NETWORK_UNLOADS);
+            m_ProfilingService->IncrementCounterValue(arm::pipe::NETWORK_UNLOADS);
         }
     }
 
@@ -296,9 +296,9 @@
 }
 
 RuntimeImpl::RuntimeImpl(const IRuntime::CreationOptions& options)
-    : m_NetworkIdCounter(0),
-      m_ProfilingService(*this)
+    : m_NetworkIdCounter(0)
 {
+    m_ProfilingService = arm::pipe::IProfilingService::CreateProfilingService(*this);
     const auto start_time = armnn::GetTimeNow();
     ARMNN_LOG(info) << "ArmNN v" << ARMNN_VERSION;
     if ( options.m_ProfilingOptions.m_TimelineEnabled && !options.m_ProfilingOptions.m_EnableProfiling )
@@ -475,7 +475,9 @@
 
             unique_ptr<arm::pipe::IBackendProfiling> profilingIface =
                 std::make_unique<arm::pipe::BackendProfiling>(arm::pipe::BackendProfiling(
-                    arm::pipe::ConvertExternalProfilingOptions(options.m_ProfilingOptions), m_ProfilingService, id));
+                    arm::pipe::ConvertExternalProfilingOptions(options.m_ProfilingOptions),
+                                                               *m_ProfilingService.get(),
+                                                               id));
 
             // Backends may also provide a profiling context. Ask for it now.
             auto profilingContext = backend->CreateBackendProfilingContext(options, profilingIface);
@@ -483,7 +485,7 @@
             if (profilingContext)
             {
                 // Pass the context onto the profiling service.
-                m_ProfilingService.AddBackendProfilingContext(id, profilingContext);
+                m_ProfilingService->AddBackendProfilingContext(id, profilingContext);
             }
         }
         catch (const BackendUnavailableException&)
@@ -492,14 +494,14 @@
         }
     }
 
-    BackendRegistryInstance().SetProfilingService(m_ProfilingService);
+    BackendRegistryInstance().SetProfilingService(*m_ProfilingService.get());
     // pass configuration info to the profiling service
-    m_ProfilingService.ConfigureProfilingService(
+    m_ProfilingService->ConfigureProfilingService(
         arm::pipe::ConvertExternalProfilingOptions(options.m_ProfilingOptions));
     if (options.m_ProfilingOptions.m_EnableProfiling)
     {
         // try to wait for the profiling service to initialise
-        m_ProfilingService.WaitForProfilingServiceActivation(3000);
+        m_ProfilingService->WaitForProfilingServiceActivation(3000);
     }
 
     m_DeviceSpec.AddSupportedBackends(supportedBackends);
diff --git a/src/armnn/Runtime.hpp b/src/armnn/Runtime.hpp
index 1ac0d21..a8fa5fd 100644
--- a/src/armnn/Runtime.hpp
+++ b/src/armnn/Runtime.hpp
@@ -14,8 +14,6 @@
 
 #include <armnn/backends/DynamicBackend.hpp>
 
-#include <ProfilingService.hpp>
-
 #include <IProfilingService.hpp>
 #include <IReportStructure.hpp>
 
@@ -115,7 +113,7 @@
 private:
     friend void RuntimeLoadedNetworksReserve(RuntimeImpl* runtime); // See RuntimeTests.cpp
 
-    friend arm::pipe::ProfilingService& GetProfilingService(RuntimeImpl* runtime); // See RuntimeTests.cpp
+    friend arm::pipe::IProfilingService& GetProfilingService(RuntimeImpl* runtime); // See RuntimeTests.cpp
 
     int GenerateNetworkId();
 
@@ -150,7 +148,7 @@
     std::vector<DynamicBackendPtr> m_DynamicBackends;
 
     /// Profiling Service Instance
-    arm::pipe::ProfilingService m_ProfilingService;
+    std::unique_ptr<arm::pipe::IProfilingService> m_ProfilingService;
 };
 
 } // namespace armnn
diff --git a/src/armnnTestUtils/TestUtils.cpp b/src/armnnTestUtils/TestUtils.cpp
index 7c9fc90..a67eecf 100644
--- a/src/armnnTestUtils/TestUtils.cpp
+++ b/src/armnnTestUtils/TestUtils.cpp
@@ -56,9 +56,9 @@
     return optNet->pOptimizedNetworkImpl->GetModelOptions();
 }
 
-arm::pipe::ProfilingService& GetProfilingService(armnn::RuntimeImpl* runtime)
+arm::pipe::IProfilingService& GetProfilingService(armnn::RuntimeImpl* runtime)
 {
-    return runtime->m_ProfilingService;
+    return *(runtime->m_ProfilingService.get());
 }
 
-}
\ No newline at end of file
+}
diff --git a/src/armnnTestUtils/TestUtils.hpp b/src/armnnTestUtils/TestUtils.hpp
index 5433d93..9fea61b 100644
--- a/src/armnnTestUtils/TestUtils.hpp
+++ b/src/armnnTestUtils/TestUtils.hpp
@@ -53,6 +53,6 @@
 {
 Graph& GetGraphForTesting(IOptimizedNetwork* optNetPtr);
 ModelOptions& GetModelOptionsForTesting(IOptimizedNetwork* optNetPtr);
-arm::pipe::ProfilingService& GetProfilingService(RuntimeImpl* runtime);
+arm::pipe::IProfilingService& GetProfilingService(RuntimeImpl* runtime);
 
-} // namespace armnn
\ No newline at end of file
+} // namespace armnn
diff --git a/src/profiling/IProfilingService.cpp b/src/profiling/IProfilingService.cpp
new file mode 100644
index 0000000..9b1aac5
--- /dev/null
+++ b/src/profiling/IProfilingService.cpp
@@ -0,0 +1,49 @@
+//
+// Copyright © 2022 Arm Ltd and Contributors. All rights reserved.
+// SPDX-License-Identifier: MIT
+//
+
+#include "IProfilingService.hpp"
+#include "ProfilingService.hpp"
+
+namespace arm
+{
+
+namespace pipe
+{
+
+std::unique_ptr<IProfilingService> IProfilingService::CreateProfilingService(
+    armnn::Optional<IReportStructure&> reportStructure)
+{
+    return std::make_unique<ProfilingService>(reportStructure);
+}
+
+ProfilingGuidGenerator IProfilingService::m_GuidGenerator;
+
+ProfilingDynamicGuid IProfilingService::GetNextGuid()
+{
+    return m_GuidGenerator.NextGuid();
+}
+
+ProfilingStaticGuid IProfilingService::GetStaticId(const std::string& str)
+{
+    return m_GuidGenerator.GenerateStaticId(str);
+}
+
+void IProfilingService::ResetGuidGenerator()
+{
+    m_GuidGenerator.Reset();
+}
+
+ProfilingDynamicGuid IProfilingService::NextGuid()
+{
+    return IProfilingService::GetNextGuid();
+}
+
+ProfilingStaticGuid IProfilingService::GenerateStaticId(const std::string& str)
+{
+    return IProfilingService::GetStaticId(str);
+}
+
+} // namespace pipe
+} // namespace arm
diff --git a/src/profiling/IProfilingService.hpp b/src/profiling/IProfilingService.hpp
index c2e824e..31d9b8d 100644
--- a/src/profiling/IProfilingService.hpp
+++ b/src/profiling/IProfilingService.hpp
@@ -7,9 +7,16 @@
 
 #include "CounterIdMap.hpp"
 #include "Holder.hpp"
+#include "ICounterValues.hpp"
+#include "ICounterRegistry.hpp"
 #include "IProfilingServiceStatus.hpp"
 #include "ISendCounterPacket.hpp"
+#include "IReportStructure.hpp"
+#include "ProfilingState.hpp"
 
+#include <armnn/backends/profiling/IBackendProfilingContext.hpp>
+#include <armnn/profiling/ProfilingOptions.hpp>
+#include <armnn/Optional.hpp>
 #include <common/include/ProfilingGuidGenerator.hpp>
 
 namespace arm
@@ -18,18 +25,44 @@
 namespace pipe
 {
 
-class IProfilingService : public IProfilingGuidGenerator, public IProfilingServiceStatus
+class IProfilingService : public IProfilingGuidGenerator,
+                          public IProfilingServiceStatus,
+                          public IReadWriteCounterValues
 {
 public:
+    static std::unique_ptr<IProfilingService> CreateProfilingService(
+        armnn::Optional<IReportStructure&> reportStructure = armnn::EmptyOptional());
     virtual ~IProfilingService() {};
     virtual std::unique_ptr<ISendTimelinePacket> GetSendTimelinePacket() const = 0;
     virtual const ICounterMappings& GetCounterMappings() const = 0;
     virtual ISendCounterPacket& GetSendCounterPacket() = 0;
     virtual bool IsProfilingEnabled() const = 0;
+    virtual bool IsTimelineReportingEnabled() const = 0;
     virtual CaptureData GetCaptureData() = 0;
+    virtual ProfilingState GetCurrentState() const = 0;
+    // Resets the profiling options, optionally clears the profiling service entirely
+    virtual void ResetExternalProfilingOptions(const ProfilingOptions& options,
+                                               bool resetProfilingService = false) = 0;
+    virtual ProfilingState ConfigureProfilingService(const ProfilingOptions& options,
+                                                     bool resetProfilingService = false) = 0;
+    // Store a profiling context returned from a backend that support profiling.
+    virtual void AddBackendProfilingContext(const armnn::BackendId backendId,
+        std::shared_ptr<IBackendProfilingContext> profilingContext) = 0;
+    virtual ICounterRegistry& GetCounterRegistry() = 0;
+    virtual IRegisterCounterMapping& GetCounterMappingRegistry() = 0;
+    // IProfilingGuidGenerator functions
+    /// Return the next random Guid in the sequence
+    ProfilingDynamicGuid NextGuid() override;
+    /// Create a ProfilingStaticGuid based on a hash of the string
+    ProfilingStaticGuid GenerateStaticId(const std::string& str) override;
+    static ProfilingDynamicGuid GetNextGuid();
+    static ProfilingStaticGuid GetStaticId(const std::string& str);
+    void ResetGuidGenerator();
+
+private:
+    static ProfilingGuidGenerator m_GuidGenerator;
 };
 
 } // namespace pipe
 
 } // namespace arm
-
diff --git a/src/profiling/ProfilingService.cpp b/src/profiling/ProfilingService.cpp
index cef8a6d..2e67dc8 100644
--- a/src/profiling/ProfilingService.cpp
+++ b/src/profiling/ProfilingService.cpp
@@ -21,23 +21,6 @@
 namespace pipe
 {
 
-ProfilingGuidGenerator ProfilingService::m_GuidGenerator;
-
-ProfilingDynamicGuid ProfilingService::GetNextGuid()
-{
-    return m_GuidGenerator.NextGuid();
-}
-
-ProfilingStaticGuid ProfilingService::GetStaticId(const std::string& str)
-{
-    return m_GuidGenerator.GenerateStaticId(str);
-}
-
-void ProfilingService::ResetGuidGenerator()
-{
-    m_GuidGenerator.Reset();
-}
-
 void ProfilingService::ResetExternalProfilingOptions(const arm::pipe::ProfilingOptions& options,
                                                      bool resetProfilingService)
 {
@@ -316,16 +299,6 @@
     return counterValuePtr->operator++(std::memory_order::memory_order_relaxed);
 }
 
-ProfilingDynamicGuid ProfilingService::NextGuid()
-{
-    return ProfilingService::GetNextGuid();
-}
-
-ProfilingStaticGuid ProfilingService::GenerateStaticId(const std::string& str)
-{
-    return ProfilingService::GetStaticId(str);
-}
-
 std::unique_ptr<ISendTimelinePacket> ProfilingService::GetSendTimelinePacket() const
 {
     return m_TimelinePacketWriterFactory.GetSendTimelinePacket();
diff --git a/src/profiling/ProfilingService.hpp b/src/profiling/ProfilingService.hpp
index ab71b0c..a4b02c1 100644
--- a/src/profiling/ProfilingService.hpp
+++ b/src/profiling/ProfilingService.hpp
@@ -15,7 +15,6 @@
 #include "ICounterRegistry.hpp"
 #include "ICounterValues.hpp"
 #include <armnn/profiling/ILocalPacketHandler.hpp>
-#include <armnn/profiling/ProfilingOptions.hpp>
 #include "IProfilingService.hpp"
 #include "IReportStructure.hpp"
 #include "PeriodicCounterCapture.hpp"
@@ -29,9 +28,9 @@
 #include "SendTimelinePacket.hpp"
 #include "TimelinePacketWriterFactory.hpp"
 #include "INotifyBackends.hpp"
+#include <armnn/profiling/ArmNNProfiling.hpp>
 #include <armnn/backends/profiling/IBackendProfilingContext.hpp>
 
-#include <common/include/ProfilingGuidGenerator.hpp>
 
 #include <list>
 
@@ -40,15 +39,8 @@
 
 namespace pipe
 {
-// Static constants describing ArmNN's counter UID's
-static const uint16_t NETWORK_LOADS         = 0;
-static const uint16_t NETWORK_UNLOADS       = 1;
-static const uint16_t REGISTERED_BACKENDS   = 2;
-static const uint16_t UNREGISTERED_BACKENDS = 3;
-static const uint16_t INFERENCES_RUN        = 4;
-static const uint16_t MAX_ARMNN_COUNTER     = INFERENCES_RUN;
 
-class ProfilingService : public IReadWriteCounterValues, public IProfilingService, public INotifyBackends
+class ProfilingService : public IProfilingService, public INotifyBackends
 {
 public:
     using IProfilingConnectionFactoryPtr = std::unique_ptr<IProfilingConnectionFactory>;
@@ -150,9 +142,9 @@
 
     // Resets the profiling options, optionally clears the profiling service entirely
     void ResetExternalProfilingOptions(const ProfilingOptions& options,
-                                       bool resetProfilingService = false);
+                                       bool resetProfilingService = false) override;
     ProfilingState ConfigureProfilingService(const ProfilingOptions& options,
-                                             bool resetProfilingService = false);
+                                             bool resetProfilingService = false) override;
 
 
     // Updates the profiling service, making it transition to a new state if necessary
@@ -163,21 +155,21 @@
 
     // Store a profiling context returned from a backend that support profiling.
     void AddBackendProfilingContext(const armnn::BackendId backendId,
-        std::shared_ptr<IBackendProfilingContext> profilingContext);
+        std::shared_ptr<IBackendProfilingContext> profilingContext) override;
 
     // Enable the recording of timeline events and entities
     void NotifyBackendsForTimelineReporting() override;
 
     const ICounterDirectory& GetCounterDirectory() const;
-    ICounterRegistry& GetCounterRegistry();
-    ProfilingState GetCurrentState() const;
+    ICounterRegistry& GetCounterRegistry() override;
+    ProfilingState GetCurrentState() const override;
     bool IsCounterRegistered(uint16_t counterUid) const override;
     uint32_t GetAbsoluteCounterValue(uint16_t counterUid) const override;
     uint32_t GetDeltaCounterValue(uint16_t counterUid) override;
     uint16_t GetCounterCount() const override;
     // counter global/backend mapping functions
     const ICounterMappings& GetCounterMappings() const override;
-    IRegisterCounterMapping& GetCounterMappingRegistry();
+    IRegisterCounterMapping& GetCounterMappingRegistry() override;
 
     // Getters for the profiling service state
     bool IsProfilingEnabled() const override;
@@ -193,13 +185,6 @@
     uint32_t SubtractCounterValue(uint16_t counterUid, uint32_t value) override;
     uint32_t IncrementCounterValue(uint16_t counterUid) override;
 
-    // IProfilingGuidGenerator functions
-    /// Return the next random Guid in the sequence
-    ProfilingDynamicGuid NextGuid() override;
-    /// Create a ProfilingStaticGuid based on a hash of the string
-    ProfilingStaticGuid GenerateStaticId(const std::string& str) override;
-
-
     std::unique_ptr<ISendTimelinePacket> GetSendTimelinePacket() const override;
 
     ISendCounterPacket& GetSendCounterPacket() override
@@ -207,13 +192,7 @@
         return m_SendCounterPacket;
     }
 
-    static ProfilingDynamicGuid GetNextGuid();
-
-    static ProfilingStaticGuid GetStaticId(const std::string& str);
-
-    void ResetGuidGenerator();
-
-    bool IsTimelineReportingEnabled()
+    bool IsTimelineReportingEnabled() const override
     {
         return m_TimelineReporting;
     }
@@ -272,8 +251,6 @@
     BackendProfilingContext     m_BackendProfilingContexts;
     uint16_t                    m_MaxGlobalCounterId;
 
-    static ProfilingGuidGenerator m_GuidGenerator;
-
     // Signalling to let external actors know when service is active or not
     std::mutex m_ServiceActiveMutex;
     std::condition_variable m_ServiceActiveConditionVariable;
diff --git a/src/profiling/ProfilingState.hpp b/src/profiling/ProfilingState.hpp
new file mode 100644
index 0000000..0fc1903
--- /dev/null
+++ b/src/profiling/ProfilingState.hpp
@@ -0,0 +1,24 @@
+//
+// Copyright © 2022 Arm Ltd. All rights reserved.
+// SPDX-License-Identifier: MIT
+//
+
+#pragma once
+
+namespace arm
+{
+
+namespace pipe
+{
+
+enum class ProfilingState
+{
+    Uninitialised,
+    NotConnected,
+    WaitingForAck,
+    Active
+};
+
+} // namespace pipe
+
+} // namespace arm
diff --git a/src/profiling/ProfilingStateMachine.hpp b/src/profiling/ProfilingStateMachine.hpp
index 2980556..2648bca 100644
--- a/src/profiling/ProfilingStateMachine.hpp
+++ b/src/profiling/ProfilingStateMachine.hpp
@@ -5,6 +5,8 @@
 
 #pragma once
 
+#include "ProfilingState.hpp"
+
 #include <atomic>
 
 #include <armnn/utility/IgnoreUnused.hpp>
@@ -15,14 +17,6 @@
 namespace pipe
 {
 
-enum class ProfilingState
-{
-    Uninitialised,
-    NotConnected,
-    WaitingForAck,
-    Active
-};
-
 class ProfilingStateMachine
 {
 public:
@@ -71,4 +65,3 @@
 } // namespace pipe
 
 } // namespace arm
-
diff --git a/src/profiling/RegisterBackendCounters.hpp b/src/profiling/RegisterBackendCounters.hpp
index f25feb5..34f9f3a 100644
--- a/src/profiling/RegisterBackendCounters.hpp
+++ b/src/profiling/RegisterBackendCounters.hpp
@@ -8,7 +8,7 @@
 #include "armnn/backends/profiling/IBackendProfiling.hpp"
 #include "CounterIdMap.hpp"
 #include "CounterDirectory.hpp"
-#include "ProfilingService.hpp"
+#include "IProfilingService.hpp"
 
 namespace arm
 {
@@ -21,7 +21,7 @@
 public:
 
     RegisterBackendCounters(
-        uint16_t currentMaxGlobalCounterID, const armnn::BackendId& backendId, ProfilingService& profilingService)
+        uint16_t currentMaxGlobalCounterID, const armnn::BackendId& backendId, IProfilingService& profilingService)
         : m_CurrentMaxGlobalCounterID(currentMaxGlobalCounterID),
           m_BackendId(backendId),
           m_ProfilingService(profilingService),
@@ -55,10 +55,10 @@
 private:
     uint16_t m_CurrentMaxGlobalCounterID;
     const armnn::BackendId& m_BackendId;
-    ProfilingService& m_ProfilingService;
+    IProfilingService& m_ProfilingService;
     ICounterRegistry& m_CounterDirectory;
 };
 
 } // namespace pipe
 
-} // namespace arm
\ No newline at end of file
+} // namespace arm
diff --git a/src/profiling/TimelineUtilityMethods.cpp b/src/profiling/TimelineUtilityMethods.cpp
index bc8e7b6..fea8ed7 100644
--- a/src/profiling/TimelineUtilityMethods.cpp
+++ b/src/profiling/TimelineUtilityMethods.cpp
@@ -15,7 +15,7 @@
 namespace pipe
 {
 
-std::unique_ptr<TimelineUtilityMethods> TimelineUtilityMethods::GetTimelineUtils(ProfilingService& profilingService)
+std::unique_ptr<TimelineUtilityMethods> TimelineUtilityMethods::GetTimelineUtils(IProfilingService& profilingService)
 {
     if (profilingService.GetCurrentState() == ProfilingState::Active && profilingService.IsTimelineReportingEnabled())
     {
@@ -114,7 +114,7 @@
     }
 
     // Generate dynamic GUID of the entity
-    ProfilingDynamicGuid entityGuid = ProfilingService::GetNextGuid();
+    ProfilingDynamicGuid entityGuid = IProfilingService::GetNextGuid();
 
     CreateNamedTypedEntity(entityGuid, name, type);
 
@@ -177,7 +177,7 @@
     }
 
     // Generate a static GUID for the given label name
-    ProfilingStaticGuid labelGuid = ProfilingService::GetStaticId(labelName);
+    ProfilingStaticGuid labelGuid = IProfilingService::GetStaticId(labelName);
 
     // Send the new label to the external profiling service, this call throws in case of error
     m_SendTimelinePacket->SendTimelineLabelBinaryPacket(labelGuid, labelName);
@@ -200,7 +200,7 @@
     ProfilingStaticGuid labelGuid = DeclareLabel(labelName);
 
     // Generate a GUID for the label relationship
-    ProfilingDynamicGuid relationshipGuid = ProfilingService::GetNextGuid();
+    ProfilingDynamicGuid relationshipGuid = IProfilingService::GetNextGuid();
 
     // Send the new label link to the external profiling service, this call throws in case of error
     m_SendTimelinePacket->SendTimelineRelationshipBinaryPacket(ProfilingRelationshipType::LabelLink,
@@ -214,7 +214,7 @@
                                                 ProfilingStaticGuid typeNameGuid)
 {
     // Generate a GUID for the label relationship
-    ProfilingDynamicGuid relationshipGuid = ProfilingService::GetNextGuid();
+    ProfilingDynamicGuid relationshipGuid = IProfilingService::GetNextGuid();
 
     // Send the new label link to the external profiling service, this call throws in case of error
     m_SendTimelinePacket->SendTimelineRelationshipBinaryPacket(ProfilingRelationshipType::LabelLink,
@@ -256,7 +256,7 @@
     ProfilingDynamicGuid childEntityGuid = CreateNamedTypedEntity(entityName, entityType);
 
     // Generate a GUID for the retention link relationship
-    ProfilingDynamicGuid retentionLinkGuid = ProfilingService::GetNextGuid();
+    ProfilingDynamicGuid retentionLinkGuid = IProfilingService::GetNextGuid();
 
     // Send the new retention link to the external profiling service, this call throws in case of error
     m_SendTimelinePacket->SendTimelineRelationshipBinaryPacket(ProfilingRelationshipType::RetentionLink,
@@ -291,7 +291,7 @@
     CreateNamedTypedEntity(childEntityGuid, entityName, entityType);
 
     // Generate a GUID for the retention link relationship
-    ProfilingDynamicGuid retentionLinkGuid = ProfilingService::GetNextGuid();
+    ProfilingDynamicGuid retentionLinkGuid = IProfilingService::GetNextGuid();
 
     // Send the new retention link to the external profiling service, this call throws in case of error
     m_SendTimelinePacket->SendTimelineRelationshipBinaryPacket(ProfilingRelationshipType::RetentionLink,
@@ -317,7 +317,7 @@
     CreateNamedTypedEntity(childEntityGuid, entityName, typeGuid);
 
     // Generate a GUID for the retention link relationship
-    ProfilingDynamicGuid retentionLinkGuid = ProfilingService::GetNextGuid();
+    ProfilingDynamicGuid retentionLinkGuid = IProfilingService::GetNextGuid();
 
     // Send the new retention link to the external profiling service, this call throws in case of error
     m_SendTimelinePacket->SendTimelineRelationshipBinaryPacket(ProfilingRelationshipType::RetentionLink,
@@ -333,7 +333,7 @@
                                                                 ProfilingGuid relationshipCategory)
 {
     // Generate a GUID for the relationship
-    ProfilingDynamicGuid relationshipGuid = ProfilingService::GetNextGuid();
+    ProfilingDynamicGuid relationshipGuid = IProfilingService::GetNextGuid();
 
     // Send the new retention link to the external profiling service, this call throws in case of error
     m_SendTimelinePacket->SendTimelineRelationshipBinaryPacket(relationshipType,
@@ -349,7 +349,7 @@
                                                                           ProfilingGuid tailGuid)
 {
     // Generate a GUID for the relationship
-    ProfilingDynamicGuid relationshipGuid = ProfilingService::GetNextGuid();
+    ProfilingDynamicGuid relationshipGuid = IProfilingService::GetNextGuid();
 
     // Send the new retention link to the external profiling service, this call throws in case of error
     m_SendTimelinePacket->SendTimelineRelationshipBinaryPacket(relationshipType,
@@ -378,13 +378,13 @@
     int threadId = armnnUtils::Threads::GetCurrentThreadId();
 
     // Generate a GUID for the event
-    ProfilingDynamicGuid eventGuid = ProfilingService::GetNextGuid();
+    ProfilingDynamicGuid eventGuid = IProfilingService::GetNextGuid();
 
     // Send the new timeline event to the external profiling service, this call throws in case of error
     m_SendTimelinePacket->SendTimelineEventBinaryPacket(timestamp, threadId, eventGuid);
 
     // Generate a GUID for the execution link
-    ProfilingDynamicGuid executionLinkId = ProfilingService::GetNextGuid();
+    ProfilingDynamicGuid executionLinkId = IProfilingService::GetNextGuid();
 
     // Send the new execution link to the external profiling service, this call throws in case of error
     m_SendTimelinePacket->SendTimelineRelationshipBinaryPacket(ProfilingRelationshipType::ExecutionLink,
@@ -399,7 +399,7 @@
 ProfilingDynamicGuid TimelineUtilityMethods::RecordWorkloadInferenceAndStartOfLifeEvent(ProfilingGuid workloadGuid,
                                                                                         ProfilingGuid inferenceGuid)
 {
-    ProfilingDynamicGuid workloadInferenceGuid = ProfilingService::GetNextGuid();
+    ProfilingDynamicGuid workloadInferenceGuid = IProfilingService::GetNextGuid();
     CreateTypedEntity(workloadInferenceGuid, LabelsAndEventClasses::WORKLOAD_EXECUTION_GUID);
     CreateRelationship(ProfilingRelationshipType::RetentionLink,
                        inferenceGuid,
diff --git a/src/profiling/TimelineUtilityMethods.hpp b/src/profiling/TimelineUtilityMethods.hpp
index d0c9658..fa25dc4 100644
--- a/src/profiling/TimelineUtilityMethods.hpp
+++ b/src/profiling/TimelineUtilityMethods.hpp
@@ -5,7 +5,7 @@
 
 #pragma once
 
-#include "ProfilingService.hpp"
+#include "IProfilingService.hpp"
 #include "armnn/profiling/ISendTimelinePacket.hpp"
 
 #include <armnn/Types.hpp>
@@ -22,7 +22,7 @@
 
     // static factory method which will return a pointer to a timelie utility methods
     // object if profiling is enabled. Otherwise will return a null unique_ptr
-    static std::unique_ptr<TimelineUtilityMethods> GetTimelineUtils(ProfilingService& profilingService);
+    static std::unique_ptr<TimelineUtilityMethods> GetTimelineUtils(IProfilingService& profilingService);
 
     TimelineUtilityMethods(
         std::unique_ptr<ISendTimelinePacket>& sendTimelinePacket)
diff --git a/src/profiling/backends/BackendProfiling.hpp b/src/profiling/backends/BackendProfiling.hpp
index 82678a1..545234d 100644
--- a/src/profiling/backends/BackendProfiling.hpp
+++ b/src/profiling/backends/BackendProfiling.hpp
@@ -18,7 +18,7 @@
 {
 public:
     BackendProfiling(const ProfilingOptions& options,
-                     ProfilingService& profilingService,
+                     IProfilingService& profilingService,
                      const armnn::BackendId& backendId)
             : m_Options(options),
               m_ProfilingService(profilingService),
@@ -44,7 +44,7 @@
 
 private:
     ProfilingOptions m_Options;
-    ProfilingService& m_ProfilingService;
+    IProfilingService& m_ProfilingService;
     armnn::BackendId m_BackendId;
 };
 
diff --git a/src/profiling/test/ProfilingTestUtils.hpp b/src/profiling/test/ProfilingTestUtils.hpp
index 810a34c..16c6dde 100644
--- a/src/profiling/test/ProfilingTestUtils.hpp
+++ b/src/profiling/test/ProfilingTestUtils.hpp
@@ -72,23 +72,22 @@
 class ProfilingServiceRuntimeHelper : public ProfilingService
 {
 public:
-    ProfilingServiceRuntimeHelper(ProfilingService& profilingService)
+    ProfilingServiceRuntimeHelper(IProfilingService& profilingService)
     : m_ProfilingService(profilingService) {}
     ~ProfilingServiceRuntimeHelper() = default;
 
     BufferManager& GetProfilingBufferManager()
     {
-        return GetBufferManager(m_ProfilingService);
+        return GetBufferManager(static_cast<ProfilingService&>(m_ProfilingService));
     }
-    ProfilingService& m_ProfilingService;
+    IProfilingService& m_ProfilingService;
 
     void ForceTransitionToState(ProfilingState newState)
     {
-        TransitionToState(m_ProfilingService, newState);
+        TransitionToState(static_cast<ProfilingService&>(m_ProfilingService), newState);
     }
 };
 
 } // namespace pipe
 
 } // namespace arm
-