IVGCVSW-4900 Update Timeline Directory Message with new fields

Change-Id: I68097e176f7471a18498492b50339e68004dddd5
Signed-off-by: Jim Flynn <jim.flynn@arm.com>
diff --git a/src/armnn/LoadedNetwork.cpp b/src/armnn/LoadedNetwork.cpp
index 98ad7b8..fbf8cfb 100644
--- a/src/armnn/LoadedNetwork.cpp
+++ b/src/armnn/LoadedNetwork.cpp
@@ -1,5 +1,5 @@
 //
-// Copyright © 2017 Arm Ltd. All rights reserved.
+// Copyright © 2017 Arm Ltd and Contributors. All rights reserved.
 // SPDX-License-Identifier: MIT
 //
 
@@ -74,8 +74,8 @@
     // Link the workload to the layer
     timelineUtils->CreateRelationship(ProfilingRelationshipType::RetentionLink,
                                       layer.GetGuid(),
-                                      workload->GetGuid());
-
+                                      workload->GetGuid(),
+                                      LabelsAndEventClasses::CHILD_GUID);
 }
 
 } // anonymous
@@ -496,7 +496,10 @@
         // Add inference timeline trace if profiling is enabled.
         ProfilingGuid networkGuid = m_OptimizedNetwork->GetGuid();
         timelineUtils->CreateTypedEntity(inferenceGuid, LabelsAndEventClasses::INFERENCE_GUID);
-        timelineUtils->CreateRelationship(ProfilingRelationshipType::RetentionLink, networkGuid, inferenceGuid);
+        timelineUtils->CreateRelationship(ProfilingRelationshipType::RetentionLink,
+                                          networkGuid,
+                                          inferenceGuid,
+                                          LabelsAndEventClasses::EXECUTION_OF_GUID);
         timelineUtils->RecordEvent(inferenceGuid, LabelsAndEventClasses::ARMNN_PROFILING_SOL_EVENT_CLASS);
     }
 
diff --git a/src/armnn/LoadedNetwork.hpp b/src/armnn/LoadedNetwork.hpp
index 17c777d..918375a 100644
--- a/src/armnn/LoadedNetwork.hpp
+++ b/src/armnn/LoadedNetwork.hpp
@@ -1,5 +1,5 @@
 //
-// Copyright © 2017 Arm Ltd. All rights reserved.
+// Copyright © 2017 Arm Ltd and Contributors. All rights reserved.
 // SPDX-License-Identifier: MIT
 //
 #pragma once
diff --git a/src/armnn/Runtime.cpp b/src/armnn/Runtime.cpp
index 76b13d1..5692494 100644
--- a/src/armnn/Runtime.cpp
+++ b/src/armnn/Runtime.cpp
@@ -1,5 +1,5 @@
 //
-// Copyright © 2017 Arm Ltd. All rights reserved.
+// Copyright © 2017 Arm Ltd and Contributors. All rights reserved.
 // SPDX-License-Identifier: MIT
 //
 #include "Runtime.hpp"
@@ -225,6 +225,11 @@
     BackendRegistryInstance().SetProfilingService(m_ProfilingService);
     // pass configuration info to the profiling service
     m_ProfilingService.ConfigureProfilingService(options.m_ProfilingOptions);
+    if (options.m_ProfilingOptions.m_EnableProfiling)
+    {
+        // try to wait for the profiling service to initialise
+        m_ProfilingService.WaitForProfilingServiceActivation(3000);
+    }
 
     m_DeviceSpec.AddSupportedBackends(supportedBackends);
 
diff --git a/src/armnn/Runtime.hpp b/src/armnn/Runtime.hpp
index e7ad3f3..3c90c51 100644
--- a/src/armnn/Runtime.hpp
+++ b/src/armnn/Runtime.hpp
@@ -1,5 +1,5 @@
 //
-// Copyright © 2017 Arm Ltd. All rights reserved.
+// Copyright © 2017 Arm Ltd and Contributors. All rights reserved.
 // SPDX-License-Identifier: MIT
 //
 #pragma once
diff --git a/src/armnn/test/RuntimeTests.cpp b/src/armnn/test/RuntimeTests.cpp
index 5c4b625..7e9acb7 100644
--- a/src/armnn/test/RuntimeTests.cpp
+++ b/src/armnn/test/RuntimeTests.cpp
@@ -1,5 +1,5 @@
 //
-// Copyright © 2017 Arm Ltd. All rights reserved.
+// Copyright © 2017 Arm Ltd and Contributors. All rights reserved.
 // SPDX-License-Identifier: MIT
 //
 
@@ -414,7 +414,7 @@
     BOOST_CHECK(readableBuffer != nullptr);
 
     unsigned int size = readableBuffer->GetSize();
-    BOOST_CHECK(size == 852);
+    BOOST_CHECK(size == 772);
 
     const unsigned char* readableData = readableBuffer->GetReadableData();
     BOOST_CHECK(readableData != nullptr);
@@ -422,12 +422,13 @@
     unsigned int offset = 0;
 
     // Verify Header
-    VerifyTimelineHeaderBinary(readableData, offset, 844);
+    VerifyTimelineHeaderBinary(readableData, offset, 764);
+    BOOST_TEST_MESSAGE("HEADER OK");
 
     // Post-optimisation network
     // Network entity
-    VerifyTimelineEntityBinaryPacketData(optNetGuid, readableData, offset
-                                        );
+    VerifyTimelineEntityBinaryPacketData(optNetGuid, readableData, offset);
+    BOOST_TEST_MESSAGE("NETWORK ENTITY OK");
 
     // Entity - Type relationship
     VerifyTimelineRelationshipBinaryPacketData(ProfilingRelationshipType::LabelLink,
@@ -437,178 +438,187 @@
                                                LabelsAndEventClasses::TYPE_GUID,
                                                readableData,
                                                offset);
+    BOOST_TEST_MESSAGE("NETWORK TYPE RELATIONSHIP OK");
 
     // Input layer
     // Input layer entity
     VerifyTimelineEntityBinaryPacketData(input->GetGuid(), readableData, offset);
+    BOOST_TEST_MESSAGE("INPUT ENTITY OK");
 
     // Name Entity
-    VerifyTimelineLabelBinaryPacketData(EmptyOptional(), "input", readableData, offset);
+    ProfilingGuid inputLabelGuid = VerifyTimelineLabelBinaryPacketData(EmptyOptional(), "input", readableData, offset);
+    BOOST_TEST_MESSAGE("INPUT NAME LABEL OK");
 
     // Entity - Name relationship
     VerifyTimelineRelationshipBinaryPacketData(ProfilingRelationshipType::LabelLink,
                                                EmptyOptional(),
                                                input->GetGuid(),
-                                               EmptyOptional(),
+                                               inputLabelGuid,
                                                LabelsAndEventClasses::NAME_GUID,
                                                readableData,
                                                offset);
+    BOOST_TEST_MESSAGE("INPUT NAME RELATIONSHIP OK");
 
     // Entity - Type relationship
     VerifyTimelineRelationshipBinaryPacketData(ProfilingRelationshipType::LabelLink,
                                                EmptyOptional(),
                                                input->GetGuid(),
-                                               EmptyOptional(),
+                                               LabelsAndEventClasses::LAYER_GUID,
                                                LabelsAndEventClasses::TYPE_GUID,
                                                readableData,
                                                offset);
+    BOOST_TEST_MESSAGE("INPUT TYPE RELATIONSHIP OK");
 
     // Network - Input layer relationship
     VerifyTimelineRelationshipBinaryPacketData(ProfilingRelationshipType::RetentionLink,
                                                EmptyOptional(),
                                                optNetGuid,
                                                input->GetGuid(),
-                                               EmptyOptional(),
+                                               LabelsAndEventClasses::CHILD_GUID,
                                                readableData,
                                                offset);
+    BOOST_TEST_MESSAGE("NETWORK - INPUT CHILD RELATIONSHIP OK");
 
     // Normalization layer
     // Normalization layer entity
     VerifyTimelineEntityBinaryPacketData(normalize->GetGuid(), readableData, offset);
+    BOOST_TEST_MESSAGE("NORMALIZATION LAYER ENTITY OK");
 
     // Name entity
-    VerifyTimelineLabelBinaryPacketData(EmptyOptional(), "normalization", readableData, offset);
+    ProfilingGuid normalizationLayerNameGuid = VerifyTimelineLabelBinaryPacketData(
+        EmptyOptional(), "normalization", readableData, offset);
+    BOOST_TEST_MESSAGE("NORMALIZATION LAYER NAME LABEL OK");
 
     // Entity - Name relationship
     VerifyTimelineRelationshipBinaryPacketData(ProfilingRelationshipType::LabelLink,
                                                EmptyOptional(),
                                                normalize->GetGuid(),
-                                               EmptyOptional(),
+                                               normalizationLayerNameGuid,
                                                LabelsAndEventClasses::NAME_GUID,
                                                readableData,
                                                offset);
+    BOOST_TEST_MESSAGE("NORMALIZATION LAYER NAME RELATIONSHIP OK");
 
     // Entity - Type relationship
     VerifyTimelineRelationshipBinaryPacketData(ProfilingRelationshipType::LabelLink,
                                                EmptyOptional(),
                                                normalize->GetGuid(),
-                                               EmptyOptional(),
+                                               LabelsAndEventClasses::LAYER_GUID,
                                                LabelsAndEventClasses::TYPE_GUID,
                                                readableData,
                                                offset);
+    BOOST_TEST_MESSAGE("NORMALIZATION LAYER TYPE RELATIONSHIP OK");
 
     // Network - Normalize layer relationship
     VerifyTimelineRelationshipBinaryPacketData(ProfilingRelationshipType::RetentionLink,
                                                EmptyOptional(),
                                                optNetGuid,
                                                normalize->GetGuid(),
-                                               EmptyOptional(),
+                                               LabelsAndEventClasses::CHILD_GUID,
                                                readableData,
                                                offset);
+    BOOST_TEST_MESSAGE("NETWORK - NORMALIZATION LAYER CHILD RELATIONSHIP OK");
 
     // Input layer - Normalize layer relationship
     VerifyTimelineRelationshipBinaryPacketData(ProfilingRelationshipType::RetentionLink,
                                                EmptyOptional(),
                                                input->GetGuid(),
                                                normalize->GetGuid(),
-                                               EmptyOptional(),
-                                               readableData,
-                                               offset);
-
-    // Entity - Type relationship
-    VerifyTimelineRelationshipBinaryPacketData(ProfilingRelationshipType::LabelLink,
-                                               EmptyOptional(),
-                                               EmptyOptional(),
                                                LabelsAndEventClasses::CONNECTION_GUID,
-                                               LabelsAndEventClasses::TYPE_GUID,
                                                readableData,
                                                offset);
+    BOOST_TEST_MESSAGE("INPUT - NORMALIZATION LAYER CONNECTION OK");
 
     // Normalization workload
     // Normalization workload entity
-    VerifyTimelineEntityBinaryPacketData(EmptyOptional(), readableData, offset);
+    ProfilingGuid normalizationWorkloadGuid = VerifyTimelineEntityBinaryPacketData(
+        EmptyOptional(), readableData, offset);
+    BOOST_TEST_MESSAGE("NORMALIZATION WORKLOAD ENTITY OK");
 
     // Entity - Type relationship
     VerifyTimelineRelationshipBinaryPacketData(ProfilingRelationshipType::LabelLink,
                                                EmptyOptional(),
-                                               EmptyOptional(),
-                                               EmptyOptional(),
+                                               normalizationWorkloadGuid,
+                                               LabelsAndEventClasses::WORKLOAD_GUID,
                                                LabelsAndEventClasses::TYPE_GUID,
                                                readableData,
                                                offset);
+    BOOST_TEST_MESSAGE("NORMALIZATION WORKLOAD TYPE RELATIONSHIP OK");
 
     // BackendId entity
-    VerifyTimelineLabelBinaryPacketData(EmptyOptional(), "CpuRef", readableData, offset);
+    ProfilingGuid cpuRefLabelGuid = VerifyTimelineLabelBinaryPacketData(
+        EmptyOptional(), "CpuRef", readableData, offset);
+    BOOST_TEST_MESSAGE("CPUREF LABEL OK");
 
     // Entity - BackendId relationship
     VerifyTimelineRelationshipBinaryPacketData(ProfilingRelationshipType::LabelLink,
                                                EmptyOptional(),
-                                               EmptyOptional(),
-                                               EmptyOptional(),
+                                               normalizationWorkloadGuid,
+                                               cpuRefLabelGuid,
                                                LabelsAndEventClasses::BACKENDID_GUID,
                                                readableData,
                                                offset);
+    BOOST_TEST_MESSAGE("NORMALIZATION WORKLOAD BACKEND ID RELATIONSHIP OK");
 
     // Normalize layer - Normalize workload relationship
     VerifyTimelineRelationshipBinaryPacketData(ProfilingRelationshipType::RetentionLink,
                                                EmptyOptional(),
                                                normalize->GetGuid(),
-                                               EmptyOptional(),
-                                               EmptyOptional(),
+                                               normalizationWorkloadGuid,
+                                               LabelsAndEventClasses::CHILD_GUID,
                                                readableData,
                                                offset);
+    BOOST_TEST_MESSAGE("NORMALIZATION LAYER - WORKLOAD CHILD RELATIONSHIP OK");
 
     // Output layer
     // Output layer entity
     VerifyTimelineEntityBinaryPacketData(output->GetGuid(), readableData, offset);
+    BOOST_TEST_MESSAGE("OUTPUT LAYER ENTITY OK");
 
     // Name entity
-    VerifyTimelineLabelBinaryPacketData(EmptyOptional(), "output", readableData, offset);
+    ProfilingGuid outputLabelGuid = VerifyTimelineLabelBinaryPacketData(
+        EmptyOptional(), "output", readableData, offset);
+    BOOST_TEST_MESSAGE("OUTPUT LAYER NAME LABEL OK");
 
     // Entity - Name relationship
     VerifyTimelineRelationshipBinaryPacketData(ProfilingRelationshipType::LabelLink,
                                                EmptyOptional(),
                                                output->GetGuid(),
-                                               EmptyOptional(),
+                                               outputLabelGuid,
                                                LabelsAndEventClasses::NAME_GUID,
                                                readableData,
                                                offset);
+    BOOST_TEST_MESSAGE("OUTPUT LAYER NAME RELATIONSHIP OK");
 
     // Entity - Type relationship
     VerifyTimelineRelationshipBinaryPacketData(ProfilingRelationshipType::LabelLink,
                                                EmptyOptional(),
                                                output->GetGuid(),
-                                               EmptyOptional(),
+                                               LabelsAndEventClasses::LAYER_GUID,
                                                LabelsAndEventClasses::TYPE_GUID,
                                                readableData,
                                                offset);
+    BOOST_TEST_MESSAGE("OUTPUT LAYER TYPE RELATIONSHIP OK");
 
     // Network - Output layer relationship
     VerifyTimelineRelationshipBinaryPacketData(ProfilingRelationshipType::RetentionLink,
                                                EmptyOptional(),
                                                optNetGuid,
                                                output->GetGuid(),
-                                               EmptyOptional(),
+                                               LabelsAndEventClasses::CHILD_GUID,
                                                readableData,
                                                offset);
+    BOOST_TEST_MESSAGE("NETWORK - OUTPUT LAYER CHILD RELATIONSHIP OK");
 
     // Normalize layer - Output layer relationship
     VerifyTimelineRelationshipBinaryPacketData(ProfilingRelationshipType::RetentionLink,
                                                EmptyOptional(),
                                                normalize->GetGuid(),
                                                output->GetGuid(),
-                                               EmptyOptional(),
-                                               readableData,
-                                               offset);
-
-    // Entity - Type relationship
-    VerifyTimelineRelationshipBinaryPacketData(ProfilingRelationshipType::LabelLink,
-                                               EmptyOptional(),
-                                               EmptyOptional(),
                                                LabelsAndEventClasses::CONNECTION_GUID,
-                                               LabelsAndEventClasses::TYPE_GUID,
                                                readableData,
                                                offset);
+    BOOST_TEST_MESSAGE("NORMALIZE LAYER - OUTPUT LAYER CONNECTION OK");
 
     bufferManager.MarkRead(readableBuffer);
 
@@ -651,40 +661,47 @@
 
     // Verify Header
     VerifyTimelineHeaderBinary(readableData, offset, 156);
+    BOOST_TEST_MESSAGE("INPUT WORKLOAD HEADER OK");
 
     // Input workload
     // Input workload entity
-    VerifyTimelineEntityBinaryPacketData(EmptyOptional(), readableData, offset);
+    ProfilingGuid inputWorkloadGuid = VerifyTimelineEntityBinaryPacketData(EmptyOptional(), readableData, offset);
+    BOOST_TEST_MESSAGE("INPUT WORKLOAD ENTITY OK");
 
     // Entity - Type relationship
     VerifyTimelineRelationshipBinaryPacketData(ProfilingRelationshipType::LabelLink,
                                                EmptyOptional(),
-                                               EmptyOptional(),
-                                               EmptyOptional(),
+                                               inputWorkloadGuid,
+                                               LabelsAndEventClasses::WORKLOAD_GUID,
                                                LabelsAndEventClasses::TYPE_GUID,
                                                readableData,
                                                offset);
+    BOOST_TEST_MESSAGE("INPUT WORKLOAD TYPE RELATIONSHIP OK");
 
     // BackendId entity
-    VerifyTimelineLabelBinaryPacketData(EmptyOptional(), "CpuRef", readableData, offset);
+    ProfilingGuid CpuRefLabelGuid = VerifyTimelineLabelBinaryPacketData(
+        EmptyOptional(), "CpuRef", readableData, offset);
+    BOOST_TEST_MESSAGE("CPUREF LABEL OK (INPUT WORKLOAD)");
 
     // Entity - BackendId relationship
     VerifyTimelineRelationshipBinaryPacketData(ProfilingRelationshipType::LabelLink,
                                                EmptyOptional(),
-                                               EmptyOptional(),
-                                               EmptyOptional(),
+                                               inputWorkloadGuid,
+                                               CpuRefLabelGuid,
                                                LabelsAndEventClasses::BACKENDID_GUID,
                                                readableData,
                                                offset);
+    BOOST_TEST_MESSAGE("INPUT WORKLOAD BACKEND ID RELATIONSHIP OK");
 
     // Input layer - Input workload relationship
     VerifyTimelineRelationshipBinaryPacketData(ProfilingRelationshipType::RetentionLink,
                                                EmptyOptional(),
                                                input->GetGuid(),
-                                               EmptyOptional(),
-                                               EmptyOptional(),
+                                               inputWorkloadGuid,
+                                               LabelsAndEventClasses::CHILD_GUID,
                                                readableData,
                                                offset);
+    BOOST_TEST_MESSAGE("INPUT LAYER - INPUT WORKLOAD CHILD RELATIONSHIP OK");
 
     bufferManager.MarkRead(inputReadableBuffer);
 
@@ -699,40 +716,46 @@
 
     // Verify Header
     VerifyTimelineHeaderBinary(readableData, offset, 156);
+    BOOST_TEST_MESSAGE("OUTPUT WORKLOAD HEADER OK");
 
     // Output workload
     // Output workload entity
-    VerifyTimelineEntityBinaryPacketData(EmptyOptional(), readableData, offset);
+    ProfilingGuid outputWorkloadGuid = VerifyTimelineEntityBinaryPacketData(EmptyOptional(), readableData, offset);
+    BOOST_TEST_MESSAGE("OUTPUT WORKLOAD ENTITY OK");
 
     // Entity - Type relationship
     VerifyTimelineRelationshipBinaryPacketData(ProfilingRelationshipType::LabelLink,
                                                EmptyOptional(),
-                                               EmptyOptional(),
-                                               EmptyOptional(),
+                                               outputWorkloadGuid,
+                                               LabelsAndEventClasses::WORKLOAD_GUID,
                                                LabelsAndEventClasses::TYPE_GUID,
                                                readableData,
                                                offset);
+    BOOST_TEST_MESSAGE("OUTPUT WORKLOAD TYPE RELATIONSHIP OK");
 
     // BackendId entity
     VerifyTimelineLabelBinaryPacketData(EmptyOptional(), "CpuRef", readableData, offset);
+    BOOST_TEST_MESSAGE("OUTPUT WORKLOAD CPU REF LABEL OK");
 
     // Entity - BackendId relationship
     VerifyTimelineRelationshipBinaryPacketData(ProfilingRelationshipType::LabelLink,
                                                EmptyOptional(),
-                                               EmptyOptional(),
-                                               EmptyOptional(),
+                                               outputWorkloadGuid,
+                                               CpuRefLabelGuid,
                                                LabelsAndEventClasses::BACKENDID_GUID,
                                                readableData,
                                                offset);
+    BOOST_TEST_MESSAGE("OUTPUT WORKLOAD BACKEND ID RELATIONSHIP OK");
 
     // Output layer - Output workload relationship
     VerifyTimelineRelationshipBinaryPacketData(ProfilingRelationshipType::RetentionLink,
                                                EmptyOptional(),
                                                output->GetGuid(),
-                                               EmptyOptional(),
-                                               EmptyOptional(),
+                                               outputWorkloadGuid,
+                                               LabelsAndEventClasses::CHILD_GUID,
                                                readableData,
                                                offset);
+    BOOST_TEST_MESSAGE("OUTPUT LAYER - OUTPUT WORKLOAD CHILD RELATIONSHIP OK");
 
     bufferManager.MarkRead(outputReadableBuffer);
 
@@ -747,227 +770,267 @@
 
     // Verify Header
     VerifyTimelineHeaderBinary(readableData, offset, 968 + 8 * ThreadIdSize);
+    BOOST_TEST_MESSAGE("INFERENCE HEADER OK");
 
     // Inference timeline trace
     // Inference entity
-    VerifyTimelineEntityBinaryPacketData(EmptyOptional(), readableData, offset);
+    ProfilingGuid inferenceGuid = VerifyTimelineEntityBinaryPacketData(EmptyOptional(), readableData, offset);
+    BOOST_TEST_MESSAGE("INFERENCE ENTITY OK");
 
     // Entity - Type relationship
     VerifyTimelineRelationshipBinaryPacketData(ProfilingRelationshipType::LabelLink,
                                                EmptyOptional(),
-                                               EmptyOptional(),
+                                               inferenceGuid,
                                                LabelsAndEventClasses::INFERENCE_GUID,
                                                LabelsAndEventClasses::TYPE_GUID,
                                                readableData,
                                                offset);
+    BOOST_TEST_MESSAGE("INFERENCE TYPE RELATIONSHIP OK");
 
     // Network - Inference relationship
     VerifyTimelineRelationshipBinaryPacketData(ProfilingRelationshipType::RetentionLink,
                                                EmptyOptional(),
                                                optNetGuid,
-                                               EmptyOptional(),
-                                               EmptyOptional(),
+                                               inferenceGuid,
+                                               LabelsAndEventClasses::EXECUTION_OF_GUID,
                                                readableData,
                                                offset);
+    BOOST_TEST_MESSAGE("NETWORK - INFERENCE EXECUTION_OF RELATIONSHIP OK");
 
     // Start Inference life
     // Event packet - timeline, threadId, eventGuid
-    VerifyTimelineEventBinaryPacket(EmptyOptional(), EmptyOptional(), EmptyOptional(), readableData, offset);
+    ProfilingGuid inferenceEventGuid = VerifyTimelineEventBinaryPacket(
+        EmptyOptional(), EmptyOptional(), EmptyOptional(), readableData, offset);
+    BOOST_TEST_MESSAGE("INFERENCE START OF LIFE EVENT OK");
 
     // Inference - event relationship
     VerifyTimelineRelationshipBinaryPacketData(ProfilingRelationshipType::ExecutionLink,
                                                EmptyOptional(),
-                                               EmptyOptional(),
-                                               EmptyOptional(),
+                                               inferenceGuid,
+                                               inferenceEventGuid,
                                                LabelsAndEventClasses::ARMNN_PROFILING_SOL_EVENT_CLASS,
                                                readableData,
                                                offset);
+    BOOST_TEST_MESSAGE("INFERENCE START OF LIFE RELATIONSHIP OK");
 
     // Execution
     // Input workload execution
     // Input workload execution entity
-    VerifyTimelineEntityBinaryPacketData(EmptyOptional(), readableData, offset);
+    ProfilingGuid inputWorkloadExecutionGuid = VerifyTimelineEntityBinaryPacketData(
+        EmptyOptional(), readableData, offset);
+    BOOST_TEST_MESSAGE("INPUT WORKLOAD EXECUTION ENTITY OK");
 
     // Entity - Type relationship
     VerifyTimelineRelationshipBinaryPacketData(ProfilingRelationshipType::LabelLink,
                                                EmptyOptional(),
-                                               EmptyOptional(),
+                                               inputWorkloadExecutionGuid,
                                                LabelsAndEventClasses::WORKLOAD_EXECUTION_GUID,
                                                LabelsAndEventClasses::TYPE_GUID,
                                                readableData,
                                                offset);
+    BOOST_TEST_MESSAGE("INPUT WORKLOAD EXECUTION TYPE RELATIONSHIP OK");
 
     // Inference - Workload execution relationship
     VerifyTimelineRelationshipBinaryPacketData(ProfilingRelationshipType::RetentionLink,
                                                EmptyOptional(),
-                                               EmptyOptional(),
-                                               EmptyOptional(),
-                                               EmptyOptional(),
+                                               inferenceGuid,
+                                               inputWorkloadExecutionGuid,
+                                               LabelsAndEventClasses::CHILD_GUID,
                                                readableData,
                                                offset);
+    BOOST_TEST_MESSAGE("INFERENCE - INPUT WORKLOAD EXECUTION CHILD RELATIONSHIP OK");
 
     // Workload - Workload execution relationship
     VerifyTimelineRelationshipBinaryPacketData(ProfilingRelationshipType::RetentionLink,
                                                EmptyOptional(),
-                                               EmptyOptional(),
-                                               EmptyOptional(),
-                                               EmptyOptional(),
+                                               inputWorkloadGuid,
+                                               inputWorkloadExecutionGuid,
+                                               LabelsAndEventClasses::EXECUTION_OF_GUID,
                                                readableData,
                                                offset);
+    BOOST_TEST_MESSAGE("INPUT WORKLOAD - INPUT WORKLOAD EXECUTION RELATIONSHIP OK");
 
     // Start Input workload execution life
     // Event packet - timeline, threadId, eventGuid
-    VerifyTimelineEventBinaryPacket(EmptyOptional(), EmptyOptional(), EmptyOptional(), readableData, offset);
+    ProfilingGuid inputWorkloadExecutionSOLEventId = VerifyTimelineEventBinaryPacket(
+        EmptyOptional(), EmptyOptional(), EmptyOptional(), readableData, offset);
 
     // Input workload execution - event relationship
     VerifyTimelineRelationshipBinaryPacketData(ProfilingRelationshipType::ExecutionLink,
                                                EmptyOptional(),
-                                               EmptyOptional(),
-                                               EmptyOptional(),
+                                               inputWorkloadExecutionGuid,
+                                               inputWorkloadExecutionSOLEventId,
                                                LabelsAndEventClasses::ARMNN_PROFILING_SOL_EVENT_CLASS,
                                                readableData,
                                                offset);
+    BOOST_TEST_MESSAGE("INPUT WORKLOAD EXECUTION - START OF LIFE EVENT RELATIONSHIP OK");
 
     // End of Input workload execution life
     // Event packet - timeline, threadId, eventGuid
-    VerifyTimelineEventBinaryPacket(EmptyOptional(), EmptyOptional(), EmptyOptional(), readableData, offset);
+    ProfilingGuid inputWorkloadExecutionEOLEventId = VerifyTimelineEventBinaryPacket(
+        EmptyOptional(), EmptyOptional(), EmptyOptional(), readableData, offset);
 
     // Input workload execution - event relationship
     VerifyTimelineRelationshipBinaryPacketData(ProfilingRelationshipType::ExecutionLink,
                                                EmptyOptional(),
-                                               EmptyOptional(),
-                                               EmptyOptional(),
+                                               inputWorkloadExecutionGuid,
+                                               inputWorkloadExecutionEOLEventId,
                                                LabelsAndEventClasses::ARMNN_PROFILING_EOL_EVENT_CLASS,
                                                readableData,
                                                offset);
+    BOOST_TEST_MESSAGE("INPUT WORKLOAD EXECUTION - END OF LIFE EVENT RELATIONSHIP OK");
 
     // Normalize workload execution
     // Normalize workload execution entity
-    VerifyTimelineEntityBinaryPacketData(EmptyOptional(), readableData, offset);
+    ProfilingGuid normalizeWorkloadExecutionGuid = VerifyTimelineEntityBinaryPacketData(
+        EmptyOptional(), readableData, offset);
+    BOOST_TEST_MESSAGE("NORMALIZE WORKLOAD EXECUTION ENTITY OK");
 
     // Entity - Type relationship
     VerifyTimelineRelationshipBinaryPacketData(ProfilingRelationshipType::LabelLink,
                                                EmptyOptional(),
-                                               EmptyOptional(),
+                                               normalizeWorkloadExecutionGuid,
                                                LabelsAndEventClasses::WORKLOAD_EXECUTION_GUID,
                                                LabelsAndEventClasses::TYPE_GUID,
                                                readableData,
                                                offset);
+    BOOST_TEST_MESSAGE("NORMALIZE WORKLOAD EXECUTION TYPE RELATIONSHIP OK");
 
     // Inference - Workload execution relationship
     VerifyTimelineRelationshipBinaryPacketData(ProfilingRelationshipType::RetentionLink,
                                                EmptyOptional(),
-                                               EmptyOptional(),
-                                               EmptyOptional(),
-                                               EmptyOptional(),
+                                               inferenceGuid,
+                                               normalizeWorkloadExecutionGuid,
+                                               LabelsAndEventClasses::CHILD_GUID,
                                                readableData,
                                                offset);
+    BOOST_TEST_MESSAGE("INFERENCE - NORMALIZE WORKLOAD EXECUTION CHILD RELATIONSHIP OK");
 
     // Workload - Workload execution relationship
     VerifyTimelineRelationshipBinaryPacketData(ProfilingRelationshipType::RetentionLink,
                                                EmptyOptional(),
-                                               EmptyOptional(),
-                                               EmptyOptional(),
-                                               EmptyOptional(),
+                                               normalizationWorkloadGuid,
+                                               normalizeWorkloadExecutionGuid,
+                                               LabelsAndEventClasses::EXECUTION_OF_GUID,
                                                readableData,
                                                offset);
+    BOOST_TEST_MESSAGE("NORMALIZATION WORKLOAD - NORMALIZATION WORKLOAD EXECUTION RELATIONSHIP OK");
 
     // Start Normalize workload execution life
     // Event packet - timeline, threadId, eventGuid
-    VerifyTimelineEventBinaryPacket(EmptyOptional(), EmptyOptional(), EmptyOptional(), readableData, offset);
+    ProfilingGuid normalizationWorkloadExecutionSOLEventGuid = VerifyTimelineEventBinaryPacket(
+        EmptyOptional(), EmptyOptional(), EmptyOptional(), readableData, offset);
+    BOOST_TEST_MESSAGE("NORMALIZATION WORKLOAD EXECUTION START OF LIFE EVENT OK");
 
     // Normalize workload execution - event relationship
     VerifyTimelineRelationshipBinaryPacketData(ProfilingRelationshipType::ExecutionLink,
                                                EmptyOptional(),
-                                               EmptyOptional(),
-                                               EmptyOptional(),
+                                               normalizeWorkloadExecutionGuid,
+                                               normalizationWorkloadExecutionSOLEventGuid,
                                                LabelsAndEventClasses::ARMNN_PROFILING_SOL_EVENT_CLASS,
                                                readableData,
                                                offset);
+    BOOST_TEST_MESSAGE("NORMALIZATION WORKLOAD EXECUTION START OF LIFE RELATIONSHIP OK");
 
     // End of Normalize workload execution life
     // Event packet - timeline, threadId, eventGuid
-    VerifyTimelineEventBinaryPacket(EmptyOptional(), EmptyOptional(), EmptyOptional(), readableData, offset);
+    ProfilingGuid normalizationWorkloadExecutionEOLEventGuid = VerifyTimelineEventBinaryPacket(
+        EmptyOptional(), EmptyOptional(), EmptyOptional(), readableData, offset);
+    BOOST_TEST_MESSAGE("NORMALIZATION WORKLOAD EXECUTION END OF LIFE EVENT OK");
 
     // Normalize workload execution - event relationship
     VerifyTimelineRelationshipBinaryPacketData(ProfilingRelationshipType::ExecutionLink,
                                                EmptyOptional(),
-                                               EmptyOptional(),
-                                               EmptyOptional(),
+                                               normalizeWorkloadExecutionGuid,
+                                               normalizationWorkloadExecutionEOLEventGuid,
                                                LabelsAndEventClasses::ARMNN_PROFILING_EOL_EVENT_CLASS,
                                                readableData,
                                                offset);
+    BOOST_TEST_MESSAGE("NORMALIZATION WORKLOAD EXECUTION END OF LIFE RELATIONSHIP OK");
 
     // Output workload execution
     // Output workload execution entity
-    VerifyTimelineEntityBinaryPacketData(EmptyOptional(), readableData, offset);
+    ProfilingGuid outputWorkloadExecutionGuid = VerifyTimelineEntityBinaryPacketData(
+        EmptyOptional(), readableData, offset);
+    BOOST_TEST_MESSAGE("OUTPUT WORKLOAD EXECUTION ENTITY OK");
 
     // Entity - Type relationship
     VerifyTimelineRelationshipBinaryPacketData(ProfilingRelationshipType::LabelLink,
                                                EmptyOptional(),
-                                               EmptyOptional(),
+                                               outputWorkloadExecutionGuid,
                                                LabelsAndEventClasses::WORKLOAD_EXECUTION_GUID,
                                                LabelsAndEventClasses::TYPE_GUID,
                                                readableData,
                                                offset);
+    BOOST_TEST_MESSAGE("OUTPUT WORKLOAD EXECUTION TYPE RELATIONSHIP OK");
 
     // Inference - Workload execution relationship
     VerifyTimelineRelationshipBinaryPacketData(ProfilingRelationshipType::RetentionLink,
                                                EmptyOptional(),
-                                               EmptyOptional(),
-                                               EmptyOptional(),
-                                               EmptyOptional(),
+                                               inferenceGuid,
+                                               outputWorkloadExecutionGuid,
+                                               LabelsAndEventClasses::CHILD_GUID,
                                                readableData,
                                                offset);
+    BOOST_TEST_MESSAGE("INFERENCE - OUTPUT WORKLOAD EXECUTION CHILD RELATIONSHIP OK");
 
     // Workload - Workload execution relationship
     VerifyTimelineRelationshipBinaryPacketData(ProfilingRelationshipType::RetentionLink,
                                                EmptyOptional(),
-                                               EmptyOptional(),
-                                               EmptyOptional(),
-                                               EmptyOptional(),
+                                               outputWorkloadGuid,
+                                               outputWorkloadExecutionGuid,
+                                               LabelsAndEventClasses::EXECUTION_OF_GUID,
                                                readableData,
                                                offset);
+     BOOST_TEST_MESSAGE("OUTPUT WORKLOAD - OUTPUT WORKLOAD EXECUTION EXECUTION_OF RELATIONSHIP OK");
 
     // Start Output workload execution life
     // Event packet - timeline, threadId, eventGuid
-    VerifyTimelineEventBinaryPacket(EmptyOptional(), EmptyOptional(), EmptyOptional(), readableData, offset);
+    ProfilingGuid outputWorkloadExecutionSOLEventGuid = VerifyTimelineEventBinaryPacket(
+        EmptyOptional(), EmptyOptional(), EmptyOptional(), readableData, offset);
+    BOOST_TEST_MESSAGE("OUTPUT WORKLOAD EXECUTION START OF LIFE EVENT OK");
 
     // Output workload execution - event relationship
     VerifyTimelineRelationshipBinaryPacketData(ProfilingRelationshipType::ExecutionLink,
                                                EmptyOptional(),
-                                               EmptyOptional(),
-                                               EmptyOptional(),
+                                               outputWorkloadExecutionGuid,
+                                               outputWorkloadExecutionSOLEventGuid,
                                                LabelsAndEventClasses::ARMNN_PROFILING_SOL_EVENT_CLASS,
                                                readableData,
                                                offset);
-
+    BOOST_TEST_MESSAGE("OUTPUT WORKLOAD EXECUTION - START OF LIFE EVENT RELATIONSHIP OK");
 
     // End of Normalize workload execution life
     // Event packet - timeline, threadId, eventGuid
-    VerifyTimelineEventBinaryPacket(EmptyOptional(), EmptyOptional(), EmptyOptional(), readableData, offset);
+    ProfilingGuid outputWorkloadExecutionEOLEventGuid = VerifyTimelineEventBinaryPacket(
+        EmptyOptional(), EmptyOptional(), EmptyOptional(), readableData, offset);
+    BOOST_TEST_MESSAGE("OUTPUT WORKLOAD EXECUTION END OF LIFE EVENT OK");
 
     // Output workload execution - event relationship
     VerifyTimelineRelationshipBinaryPacketData(ProfilingRelationshipType::ExecutionLink,
                                                EmptyOptional(),
-                                               EmptyOptional(),
-                                               EmptyOptional(),
+                                               outputWorkloadExecutionGuid,
+                                               outputWorkloadExecutionEOLEventGuid,
                                                LabelsAndEventClasses::ARMNN_PROFILING_EOL_EVENT_CLASS,
                                                readableData,
                                                offset);
+    BOOST_TEST_MESSAGE("OUTPUT WORKLOAD EXECUTION - END OF LIFE EVENT RELATIONSHIP OK");
 
     // End of Inference life
     // Event packet - timeline, threadId, eventGuid
-    VerifyTimelineEventBinaryPacket(EmptyOptional(), EmptyOptional(), EmptyOptional(), readableData, offset);
+    ProfilingGuid inferenceEOLEventGuid = VerifyTimelineEventBinaryPacket(
+        EmptyOptional(), EmptyOptional(), EmptyOptional(), readableData, offset);
+    BOOST_TEST_MESSAGE("INFERENCE END OF LIFE EVENT OK");
 
     // Inference - event relationship
     VerifyTimelineRelationshipBinaryPacketData(ProfilingRelationshipType::ExecutionLink,
                                                EmptyOptional(),
-                                               EmptyOptional(),
-                                               EmptyOptional(),
+                                               inferenceGuid,
+                                               inferenceEOLEventGuid,
                                                LabelsAndEventClasses::ARMNN_PROFILING_EOL_EVENT_CLASS,
                                                readableData,
                                                offset);
+    BOOST_TEST_MESSAGE("INFERENCE - END OF LIFE EVENT RELATIONSHIP OK");
 
     bufferManager.MarkRead(inferenceReadableBuffer);
 }
diff --git a/src/armnn/test/RuntimeTests.hpp b/src/armnn/test/RuntimeTests.hpp
index 588a760..90aed5d 100644
--- a/src/armnn/test/RuntimeTests.hpp
+++ b/src/armnn/test/RuntimeTests.hpp
@@ -1,5 +1,5 @@
 //
-// Copyright © 2017 Arm Ltd. All rights reserved.
+// Copyright © 2017 Arm Ltd and Contributors. All rights reserved.
 // SPDX-License-Identifier: MIT
 //
 #pragma once
diff --git a/src/profiling/ConnectionAcknowledgedCommandHandler.cpp b/src/profiling/ConnectionAcknowledgedCommandHandler.cpp
index 7690573..ce2a36f 100644
--- a/src/profiling/ConnectionAcknowledgedCommandHandler.cpp
+++ b/src/profiling/ConnectionAcknowledgedCommandHandler.cpp
@@ -1,5 +1,5 @@
 //
-// Copyright © 2019 Arm Ltd. All rights reserved.
+// Copyright © 2019 Arm Ltd and Contributors. All rights reserved.
 // SPDX-License-Identifier: MIT
 //
 
@@ -47,7 +47,7 @@
             TimelineUtilityMethods::SendWellKnownLabelsAndEventClasses(m_SendTimelinePacket);
         }
 
-        if(m_BackendProfilingContext.has_value())
+        if (m_BackendProfilingContext.has_value())
         {
             for (auto backendContext : m_BackendProfilingContext.value())
             {
@@ -60,6 +60,9 @@
             }
         }
 
+        // At this point signal any external processes waiting on the profiling system
+        // to come up that profiling is fully active
+        m_ProfilingServiceStatus.NotifyProfilingServiceActive();
         break;
     case ProfilingState::Active:
         return; // NOP
diff --git a/src/profiling/ConnectionAcknowledgedCommandHandler.hpp b/src/profiling/ConnectionAcknowledgedCommandHandler.hpp
index 8aba921..f65b23f 100644
--- a/src/profiling/ConnectionAcknowledgedCommandHandler.hpp
+++ b/src/profiling/ConnectionAcknowledgedCommandHandler.hpp
@@ -1,5 +1,5 @@
 //
-// Copyright © 2019 Arm Ltd. All rights reserved.
+// Copyright © 2019 Arm Ltd and Contributors. All rights reserved.
 // SPDX-License-Identifier: MIT
 //
 
@@ -7,6 +7,7 @@
 
 #include <armnn/backends/profiling/IBackendProfilingContext.hpp>
 #include "CommandHandlerFunctor.hpp"
+#include "IProfilingServiceStatus.hpp"
 #include "ISendCounterPacket.hpp"
 #include "armnn/profiling/ISendTimelinePacket.hpp"
 #include <Packet.hpp>
@@ -32,12 +33,14 @@
                                          ISendCounterPacket& sendCounterPacket,
                                          ISendTimelinePacket& sendTimelinePacket,
                                          ProfilingStateMachine& profilingStateMachine,
+                                         IProfilingServiceStatus& profilingServiceStatus,
                                          Optional<BackendProfilingContexts> backendProfilingContexts = EmptyOptional())
         : CommandHandlerFunctor(familyId, packetId, version)
         , m_CounterDirectory(counterDirectory)
         , m_SendCounterPacket(sendCounterPacket)
         , m_SendTimelinePacket(sendTimelinePacket)
         , m_StateMachine(profilingStateMachine)
+        , m_ProfilingServiceStatus(profilingServiceStatus)
         , m_BackendProfilingContext(backendProfilingContexts)
     {}
 
@@ -53,6 +56,7 @@
     ISendCounterPacket&      m_SendCounterPacket;
     ISendTimelinePacket&     m_SendTimelinePacket;
     ProfilingStateMachine&   m_StateMachine;
+    IProfilingServiceStatus& m_ProfilingServiceStatus;
     Optional<BackendProfilingContexts> m_BackendProfilingContext;
     bool m_TimelineEnabled = false;
 };
diff --git a/src/profiling/IProfilingService.hpp b/src/profiling/IProfilingService.hpp
index 7f3ff70..760f243 100644
--- a/src/profiling/IProfilingService.hpp
+++ b/src/profiling/IProfilingService.hpp
@@ -1,5 +1,5 @@
 //
-// Copyright © 2020 Arm Ltd. All rights reserved.
+// Copyright © 2020 Arm Ltd and Contributors. All rights reserved.
 // SPDX-License-Identifier: MIT
 //
 
@@ -7,6 +7,7 @@
 
 #include "CounterIdMap.hpp"
 #include "Holder.hpp"
+#include "IProfilingServiceStatus.hpp"
 #include "ISendCounterPacket.hpp"
 #include "ProfilingGuidGenerator.hpp"
 
@@ -16,7 +17,7 @@
 namespace profiling
 {
 
-class IProfilingService : public IProfilingGuidGenerator
+class IProfilingService : public IProfilingGuidGenerator, public IProfilingServiceStatus
 {
 public:
     virtual ~IProfilingService() {};
diff --git a/src/profiling/IProfilingServiceStatus.hpp b/src/profiling/IProfilingServiceStatus.hpp
new file mode 100644
index 0000000..45d4aac
--- /dev/null
+++ b/src/profiling/IProfilingServiceStatus.hpp
@@ -0,0 +1,29 @@
+//
+// Copyright © 2020 Arm Ltd and Contributors. All rights reserved.
+// SPDX-License-Identifier: MIT
+//
+
+#pragma once
+
+#include <Packet.hpp>
+#include <armnn/profiling/ILocalPacketHandler.hpp>
+
+#include <cstdint>
+
+namespace armnn
+{
+
+namespace profiling
+{
+
+class IProfilingServiceStatus
+{
+public:
+    virtual void NotifyProfilingServiceActive() = 0;
+    virtual void WaitForProfilingServiceActivation(unsigned int timeout) = 0;
+    virtual ~IProfilingServiceStatus() {};
+};
+
+} // namespace profiling
+
+} // namespace armnn
diff --git a/src/profiling/LabelsAndEventClasses.cpp b/src/profiling/LabelsAndEventClasses.cpp
index daf1992..6b6a190 100644
--- a/src/profiling/LabelsAndEventClasses.cpp
+++ b/src/profiling/LabelsAndEventClasses.cpp
@@ -1,5 +1,5 @@
 //
-// Copyright © 2019 Arm Ltd. All rights reserved.
+// Copyright © 2019 Arm Ltd and Contributors. All rights reserved.
 // SPDX-License-Identifier: MIT
 //
 
@@ -19,6 +19,8 @@
 std::string LabelsAndEventClasses::TYPE_LABEL("type");
 std::string LabelsAndEventClasses::INDEX_LABEL("index");
 std::string LabelsAndEventClasses::BACKENDID_LABEL("backendId");
+std::string LabelsAndEventClasses::CHILD_LABEL("child");
+std::string LabelsAndEventClasses::EXECUTION_OF_LABEL("execution_of");
 
 ProfilingStaticGuid LabelsAndEventClasses::EMPTY_GUID(0);
 ProfilingStaticGuid LabelsAndEventClasses::NAME_GUID(
@@ -29,6 +31,10 @@
     m_GuidGenerator.GenerateStaticId(LabelsAndEventClasses::INDEX_LABEL));
 ProfilingStaticGuid LabelsAndEventClasses::BACKENDID_GUID(
     m_GuidGenerator.GenerateStaticId(LabelsAndEventClasses::BACKENDID_LABEL));
+ProfilingStaticGuid LabelsAndEventClasses::CHILD_GUID(
+    m_GuidGenerator.GenerateStaticId(LabelsAndEventClasses::CHILD_LABEL));
+ProfilingStaticGuid LabelsAndEventClasses::EXECUTION_OF_GUID(
+    m_GuidGenerator.GenerateStaticId(LabelsAndEventClasses::EXECUTION_OF_LABEL));
 
 // Common types
 std::string LabelsAndEventClasses::LAYER("layer");
diff --git a/src/profiling/LabelsAndEventClasses.hpp b/src/profiling/LabelsAndEventClasses.hpp
index 13332ff..835fc79 100644
--- a/src/profiling/LabelsAndEventClasses.hpp
+++ b/src/profiling/LabelsAndEventClasses.hpp
@@ -1,5 +1,5 @@
 //
-// Copyright © 2019 Arm Ltd. All rights reserved.
+// Copyright © 2019 Arm Ltd and Contributors. All rights reserved.
 // SPDX-License-Identifier: MIT
 //
 
@@ -25,11 +25,15 @@
     ARMNN_DLLEXPORT static std::string TYPE_LABEL;
     ARMNN_DLLEXPORT static std::string INDEX_LABEL;
     ARMNN_DLLEXPORT static std::string BACKENDID_LABEL;
+    ARMNN_DLLEXPORT static std::string CHILD_LABEL;
+    ARMNN_DLLEXPORT static std::string EXECUTION_OF_LABEL;
     ARMNN_DLLEXPORT static ProfilingStaticGuid EMPTY_GUID;
     ARMNN_DLLEXPORT static ProfilingStaticGuid NAME_GUID;
     ARMNN_DLLEXPORT static ProfilingStaticGuid TYPE_GUID;
     ARMNN_DLLEXPORT static ProfilingStaticGuid INDEX_GUID;
     ARMNN_DLLEXPORT static ProfilingStaticGuid BACKENDID_GUID;
+    ARMNN_DLLEXPORT static ProfilingStaticGuid CHILD_GUID;
+    ARMNN_DLLEXPORT static ProfilingStaticGuid EXECUTION_OF_GUID;
 
     // Common types
     ARMNN_DLLEXPORT static std::string LAYER;
diff --git a/src/profiling/ProfilingGuidGenerator.hpp b/src/profiling/ProfilingGuidGenerator.hpp
index dc6e22b..86f9ce0 100644
--- a/src/profiling/ProfilingGuidGenerator.hpp
+++ b/src/profiling/ProfilingGuidGenerator.hpp
@@ -1,5 +1,5 @@
 //
-// Copyright © 2019 Arm Ltd. All rights reserved.
+// Copyright © 2019 Arm Ltd and Contributors. All rights reserved.
 // SPDX-License-Identifier: MIT
 //
 
@@ -43,6 +43,13 @@
         return ProfilingStaticGuid(staticHash);
     }
 
+    /// Reset the generator back to zero. Used mainly for test.
+    inline void Reset()
+    {
+        std::lock_guard<std::mutex> sequencelock(m_SequenceMutex);
+        m_Sequence = 0;
+    }
+
 private:
     std::hash<std::string> m_Hash;
     uint64_t m_Sequence;
diff --git a/src/profiling/ProfilingService.cpp b/src/profiling/ProfilingService.cpp
index 21972b4..8532c3e 100644
--- a/src/profiling/ProfilingService.cpp
+++ b/src/profiling/ProfilingService.cpp
@@ -1,5 +1,5 @@
 //
-// Copyright © 2017 Arm Ltd. All rights reserved.
+// Copyright © 2019 Arm Ltd and Contributors. All rights reserved.
 // SPDX-License-Identifier: MIT
 //
 
@@ -29,6 +29,11 @@
     return m_GuidGenerator.GenerateStaticId(str);
 }
 
+void ProfilingService::ResetGuidGenerator()
+{
+    m_GuidGenerator.Reset();
+}
+
 void ProfilingService::ResetExternalProfilingOptions(const ExternalProfilingOptions& options,
                                                      bool resetProfilingService)
 {
@@ -452,6 +457,10 @@
 
 void ProfilingService::Stop()
 {
+    {   // only lock when we are updating the inference completed variable
+        std::unique_lock<std::mutex> lck(m_ServiceActiveMutex);
+        m_ServiceActive = false;
+    }
     // The order in which we reset/stop the components is not trivial!
     // First stop the producing threads
     // Command Handler first as it is responsible for launching then Periodic Counter capture thread
@@ -491,6 +500,39 @@
     }
 }
 
+void ProfilingService::NotifyProfilingServiceActive()
+{
+    {   // only lock when we are updating the inference completed variable
+        std::unique_lock<std::mutex> lck(m_ServiceActiveMutex);
+        m_ServiceActive = true;
+    }
+    m_ServiceActiveConditionVariable.notify_one();
+}
+
+void ProfilingService::WaitForProfilingServiceActivation(unsigned int timeout)
+{
+    std::unique_lock<std::mutex> lck(m_ServiceActiveMutex);
+
+    auto start = std::chrono::high_resolution_clock::now();
+    // Here we we will go back to sleep after a spurious wake up if
+    // m_InferenceCompleted is not yet true.
+    if (!m_ServiceActiveConditionVariable.wait_for(lck,
+                                                   std::chrono::milliseconds(timeout),
+                                                   [&]{return m_ServiceActive == true;}))
+    {
+        if (m_ServiceActive == true)
+        {
+            return;
+        }
+        auto finish = std::chrono::high_resolution_clock::now();
+        std::chrono::duration<double, std::milli> elapsed = finish - start;
+        std::stringstream ss;
+        ss << "Timed out waiting on profiling service activation for " << elapsed.count() << " ms";
+        ARMNN_LOG(warning) << ss.str();
+    }
+    return;
+}
+
 ProfilingService::~ProfilingService()
 {
     Stop();
diff --git a/src/profiling/ProfilingService.hpp b/src/profiling/ProfilingService.hpp
index d7e4628..247b945 100644
--- a/src/profiling/ProfilingService.hpp
+++ b/src/profiling/ProfilingService.hpp
@@ -1,5 +1,5 @@
 //
-// Copyright © 2017 Arm Ltd. All rights reserved.
+// Copyright © 2019 Arm Ltd and Contributors. All rights reserved.
 // SPDX-License-Identifier: MIT
 //
 
@@ -82,6 +82,7 @@
                                                  m_SendCounterPacket,
                                                  m_SendTimelinePacket,
                                                  m_StateMachine,
+                                                 *this,
                                                  m_BackendProfilingContexts)
         , m_RequestCounterDirectoryCommandHandler(0,
                                                   3,
@@ -123,6 +124,7 @@
                                                       *this)
         , m_TimelinePacketWriterFactory(m_BufferManager)
         , m_MaxGlobalCounterId(armnn::profiling::INFERENCES_RUN)
+        , m_ServiceActive(false)
     {
         // Register the "Connection Acknowledged" command handler
         m_CommandHandlerRegistry.RegisterFunctor(&m_ConnectionAcknowledgedCommandHandler);
@@ -193,6 +195,7 @@
     /// 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
@@ -204,12 +207,18 @@
 
     static ProfilingStaticGuid GetStaticId(const std::string& str);
 
+    void ResetGuidGenerator();
+
     bool IsTimelineReportingEnabled()
     {
         return m_TimelineReporting;
     }
 
     void AddLocalPacketHandler(ILocalPacketHandlerSharedPtr localPacketHandler);
+
+    void NotifyProfilingServiceActive() override; // IProfilingServiceStatus
+    void WaitForProfilingServiceActivation(unsigned int timeout) override; // IProfilingServiceStatus
+
 private:
     //Copy/move constructors/destructors and copy/move assignment operators are deleted
     ProfilingService(const ProfilingService&) = delete;
@@ -261,6 +270,11 @@
 
     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;
+    bool m_ServiceActive;
+
 protected:
 
     // Protected methods for testing
diff --git a/src/profiling/ProfilingUtils.cpp b/src/profiling/ProfilingUtils.cpp
index 2482e2c..d67694f 100644
--- a/src/profiling/ProfilingUtils.cpp
+++ b/src/profiling/ProfilingUtils.cpp
@@ -1,5 +1,5 @@
 //
-// Copyright © 2017 Arm Ltd. All rights reserved.
+// Copyright © 2019 Arm Ltd and Contributors. All rights reserved.
 // SPDX-License-Identifier: MIT
 //
 
@@ -652,17 +652,17 @@
     // |-----------|---------------------|-----------------------|-------------|-------------------------------------|
     // |    0      |   declareLabel      |   declare label       |    ps       |  guid,value                         |
     // |    1      |   declareEntity     |   declare entity      |    p        |  guid                               |
-    // |    2      | declareEventClass   |  declare event class  |    p        |  guid                               |
-    // |    3      | declareRelationship | declare relationship  |    Ippp     |  relationshipType,relationshipGuid, |
-    // |           |                     |                       |             |  headGuid,tailGuid                  |
+    // |    2      | declareEventClass   |  declare event class  |    pp       |  guid,nameGuid                      |
+    // |    3      | declareRelationship | declare relationship  |    Ipppp    |  relationshipType,relationshipGuid, |
+    // |           |                     |                       |             |  headGuid,tailGuid,attributeGuid    |
     // |    4      |   declareEvent      |   declare event       |    @tp      |  timestamp,threadId,eventGuid       |
     std::vector<std::vector<std::string>> timelineDirectoryMessages
     {
         { "0", "declareLabel", "declare label", "ps", "guid,value" },
         { "1", "declareEntity", "declare entity", "p", "guid" },
-        { "2", "declareEventClass", "declare event class", "p", "guid" },
-        { "3", "declareRelationship", "declare relationship", "Ippp",
-          "relationshipType,relationshipGuid,headGuid,tailGuid" },
+        { "2", "declareEventClass", "declare event class", "pp", "guid,nameGuid" },
+        { "3", "declareRelationship", "declare relationship", "Ipppp",
+          "relationshipType,relationshipGuid,headGuid,tailGuid,attributeGuid" },
         { "4", "declareEvent", "declare event", "@tp", "timestamp,threadId,eventGuid" }
     };
 
diff --git a/src/profiling/ProfilingUtils.hpp b/src/profiling/ProfilingUtils.hpp
index 9c7ad03..95fa780 100644
--- a/src/profiling/ProfilingUtils.hpp
+++ b/src/profiling/ProfilingUtils.hpp
@@ -1,5 +1,5 @@
 //
-// Copyright © 2017 Arm Ltd. All rights reserved.
+// Copyright © 2019 Arm Ltd and Contributors. All rights reserved.
 // SPDX-License-Identifier: MIT
 //
 
diff --git a/src/profiling/SendTimelinePacket.hpp b/src/profiling/SendTimelinePacket.hpp
index b1bae04..2b710c7 100644
--- a/src/profiling/SendTimelinePacket.hpp
+++ b/src/profiling/SendTimelinePacket.hpp
@@ -96,8 +96,7 @@
                     continue;
 
                 case TimelinePacketStatus::Error:
-                    throw RuntimeException("Error processing while sending TimelineBinaryPacket",
-                                           CHECK_LOCATION());
+                    throw RuntimeException("Error processing while sending TimelineBinaryPacket", CHECK_LOCATION());
 
                 default:
                     m_Offset += numberOfBytesWritten;
@@ -106,9 +105,23 @@
             }
         }
     }
+    catch (const RuntimeException& ex)
+    {
+        // don't swallow in the catch all block
+        throw ex;
+    }
+    catch (const BufferExhaustion& ex)
+    {
+        // ditto
+        throw ex;
+    }
+    catch (const Exception& ex)
+    {
+        throw ex;
+    }
     catch ( ... )
     {
-        throw RuntimeException("Error processing while sending TimelineBinaryPacket", CHECK_LOCATION());
+        throw RuntimeException("Unknown Exception thrown while sending TimelineBinaryPacket", CHECK_LOCATION());
     }
 }
 
diff --git a/src/profiling/TimelineUtilityMethods.cpp b/src/profiling/TimelineUtilityMethods.cpp
index 306551b..2727bd6 100644
--- a/src/profiling/TimelineUtilityMethods.cpp
+++ b/src/profiling/TimelineUtilityMethods.cpp
@@ -1,5 +1,5 @@
 //
-// Copyright © 2019 Arm Ltd. All rights reserved.
+// Copyright © 2019 Arm Ltd and Contributors. All rights reserved.
 // SPDX-License-Identifier: MIT
 //
 
@@ -45,6 +45,14 @@
     timelinePacket.SendTimelineLabelBinaryPacket(LabelsAndEventClasses::BACKENDID_GUID,
                                                  LabelsAndEventClasses::BACKENDID_LABEL);
 
+    // Send the "child" label, this call throws in case of error
+    timelinePacket.SendTimelineLabelBinaryPacket(LabelsAndEventClasses::CHILD_GUID,
+                                                 LabelsAndEventClasses::CHILD_LABEL);
+
+    // Send the "execution_of" label, this call throws in case of error
+    timelinePacket.SendTimelineLabelBinaryPacket(LabelsAndEventClasses::EXECUTION_OF_GUID,
+                                                 LabelsAndEventClasses::EXECUTION_OF_LABEL);
+
     // Send the "layer" label, this call throws in case of error
     timelinePacket.SendTimelineLabelBinaryPacket(LabelsAndEventClasses::LAYER_GUID,
                                                  LabelsAndEventClasses::LAYER);
@@ -283,7 +291,7 @@
                                                                retentionLinkGuid,
                                                                parentEntityGuid,
                                                                childEntityGuid,
-                                                               LabelsAndEventClasses::EMPTY_GUID);
+                                                               LabelsAndEventClasses::CHILD_GUID);
 }
 
 void TimelineUtilityMethods::CreateNamedTypedChildEntity(ProfilingGuid childEntityGuid,
@@ -309,12 +317,13 @@
                                                                retentionLinkGuid,
                                                                parentEntityGuid,
                                                                childEntityGuid,
-                                                               LabelsAndEventClasses::EMPTY_GUID);
+                                                               LabelsAndEventClasses::CHILD_GUID);
 }
 
 ProfilingDynamicGuid TimelineUtilityMethods::CreateRelationship(ProfilingRelationshipType relationshipType,
                                                                 ProfilingGuid headGuid,
-                                                                ProfilingGuid tailGuid)
+                                                                ProfilingGuid tailGuid,
+                                                                ProfilingGuid relationshipCategory)
 {
     // Generate a GUID for the relationship
     ProfilingDynamicGuid relationshipGuid = profiling::ProfilingService::GetNextGuid();
@@ -324,7 +333,7 @@
                                                                relationshipGuid,
                                                                headGuid,
                                                                tailGuid,
-                                                               LabelsAndEventClasses::EMPTY_GUID);
+                                                               relationshipCategory);
     return relationshipGuid;
 }
 
@@ -340,9 +349,7 @@
                                                                relationshipGuid,
                                                                headGuid,
                                                                tailGuid,
-                                                               LabelsAndEventClasses::EMPTY_GUID);
-
-    MarkEntityWithType(relationshipGuid, LabelsAndEventClasses::CONNECTION_GUID);
+                                                               LabelsAndEventClasses::CONNECTION_GUID);
     return relationshipGuid;
 }
 
@@ -387,8 +394,14 @@
 {
     ProfilingDynamicGuid workloadInferenceGuid = profiling::ProfilingService::GetNextGuid();
     CreateTypedEntity(workloadInferenceGuid, LabelsAndEventClasses::WORKLOAD_EXECUTION_GUID);
-    CreateRelationship(ProfilingRelationshipType::RetentionLink, inferenceGuid, workloadInferenceGuid);
-    CreateRelationship(ProfilingRelationshipType::RetentionLink, workloadGuid, workloadInferenceGuid);
+    CreateRelationship(ProfilingRelationshipType::RetentionLink,
+                       inferenceGuid,
+                       workloadInferenceGuid,
+                       LabelsAndEventClasses::CHILD_GUID);
+    CreateRelationship(ProfilingRelationshipType::RetentionLink,
+                       workloadGuid,
+                       workloadInferenceGuid,
+                       LabelsAndEventClasses::EXECUTION_OF_GUID);
     RecordEvent(workloadInferenceGuid, LabelsAndEventClasses::ARMNN_PROFILING_SOL_EVENT_CLASS);
     return workloadInferenceGuid;
 }
diff --git a/src/profiling/TimelineUtilityMethods.hpp b/src/profiling/TimelineUtilityMethods.hpp
index 4f24726..857d82f 100644
--- a/src/profiling/TimelineUtilityMethods.hpp
+++ b/src/profiling/TimelineUtilityMethods.hpp
@@ -1,5 +1,5 @@
 //
-// Copyright © 2019 Arm Ltd. All rights reserved.
+// Copyright © 2019 Arm Ltd and Contributors. All rights reserved.
 // SPDX-License-Identifier: MIT
 //
 
@@ -71,7 +71,8 @@
 
     ProfilingDynamicGuid CreateRelationship(ProfilingRelationshipType relationshipType,
                                             ProfilingGuid headGuid,
-                                            ProfilingGuid tailGuid);
+                                            ProfilingGuid tailGuid,
+                                            ProfilingGuid relationshipCategory);
 
     ProfilingDynamicGuid CreateConnectionRelationship(ProfilingRelationshipType relationshipType,
                                                       ProfilingGuid headGuid,
diff --git a/src/profiling/test/FileOnlyProfilingDecoratorTests.cpp b/src/profiling/test/FileOnlyProfilingDecoratorTests.cpp
index aa877a1..31c1c7a 100644
--- a/src/profiling/test/FileOnlyProfilingDecoratorTests.cpp
+++ b/src/profiling/test/FileOnlyProfilingDecoratorTests.cpp
@@ -1,12 +1,14 @@
 //
-// Copyright © 2019 Arm Ltd. All rights reserved.
+// Copyright © 2019 Arm Ltd and Contributors. All rights reserved.
 // SPDX-License-Identifier: MIT
 //
 
 #include <Filesystem.hpp>
+#include <LabelsAndEventClasses.hpp>
 #include <ProfilingService.hpp>
-#include <Runtime.hpp>
+#include "ProfilingTestUtils.hpp"
 #include "PrintPacketHeaderHandler.hpp"
+#include <Runtime.hpp>
 #include "TestTimelinePacketHandler.hpp"
 
 #include <boost/filesystem.hpp>
@@ -51,9 +53,7 @@
 {
     // This test requires at least one backend registry to be enabled
     // which can execute a NormalizationLayer
-    if (BackendRegistryInstance().IsBackendRegistered(GetComputeDeviceAsCString(armnn::Compute::CpuRef)) ||
-        BackendRegistryInstance().IsBackendRegistered(GetComputeDeviceAsCString(armnn::Compute::CpuAcc)) ||
-        BackendRegistryInstance().IsBackendRegistered(GetComputeDeviceAsCString(armnn::Compute::GpuAcc)))
+    if (!HasSuitableBackendRegistered())
     {
         return;
     }
@@ -71,6 +71,8 @@
     creationOptions.m_ProfilingOptions.m_LocalPacketHandlers.push_back(localPacketHandlerPtr);
 
     armnn::Runtime runtime(creationOptions);
+    // ensure the GUID generator is reset to zero
+    GetProfilingService(&runtime).ResetGuidGenerator();
 
     // Load a simple network
     // build up the structure of the network
@@ -115,6 +117,52 @@
     runtime.EnqueueWorkload(netId, inputTensors, outputTensors);
 
     static_cast<TestTimelinePacketHandler*>(localPacketHandlerPtr.get())->WaitOnInferenceCompletion(3000);
+
+    const TimelineModel& model =
+        static_cast<TestTimelinePacketHandler*>(localPacketHandlerPtr.get())->GetTimelineModel();
+
+    for (auto& error : model.GetErrors())
+    {
+        std::cout << error.what() << std::endl;
+    }
+    BOOST_TEST(model.GetErrors().empty());
+    std::vector<std::string> desc = GetModelDescription(model);
+    std::vector<std::string> expectedOutput;
+    expectedOutput.push_back("Entity [0] name = input type = layer");
+    expectedOutput.push_back("   connection [14] from entity [0] to entity [1]");
+    expectedOutput.push_back("   child: Entity [23] backendId = CpuRef type = workload");
+    expectedOutput.push_back("Entity [1] name = normalization type = layer");
+    expectedOutput.push_back("   connection [22] from entity [1] to entity [2]");
+    expectedOutput.push_back("   child: Entity [15] backendId = CpuRef type = workload");
+    expectedOutput.push_back("Entity [2] name = output type = layer");
+    expectedOutput.push_back("   child: Entity [27] backendId = CpuRef type = workload");
+    expectedOutput.push_back("Entity [6] type = network");
+    expectedOutput.push_back("   child: Entity [0] name = input type = layer");
+    expectedOutput.push_back("   child: Entity [1] name = normalization type = layer");
+    expectedOutput.push_back("   child: Entity [2] name = output type = layer");
+    expectedOutput.push_back("   execution: Entity [31] type = inference");
+    expectedOutput.push_back("Entity [15] backendId = CpuRef type = workload");
+    expectedOutput.push_back("   execution: Entity [44] type = workload_execution");
+    expectedOutput.push_back("Entity [23] backendId = CpuRef type = workload");
+    expectedOutput.push_back("   execution: Entity [36] type = workload_execution");
+    expectedOutput.push_back("Entity [27] backendId = CpuRef type = workload");
+    expectedOutput.push_back("   execution: Entity [52] type = workload_execution");
+    expectedOutput.push_back("Entity [31] type = inference");
+    expectedOutput.push_back("   child: Entity [36] type = workload_execution");
+    expectedOutput.push_back("   child: Entity [44] type = workload_execution");
+    expectedOutput.push_back("   child: Entity [52] type = workload_execution");
+    expectedOutput.push_back("   event: [34] class [start_of_life]");
+    expectedOutput.push_back("   event: [60] class [end_of_life]");
+    expectedOutput.push_back("Entity [36] type = workload_execution");
+    expectedOutput.push_back("   event: [40] class [start_of_life]");
+    expectedOutput.push_back("   event: [42] class [end_of_life]");
+    expectedOutput.push_back("Entity [44] type = workload_execution");
+    expectedOutput.push_back("   event: [48] class [start_of_life]");
+    expectedOutput.push_back("   event: [50] class [end_of_life]");
+    expectedOutput.push_back("Entity [52] type = workload_execution");
+    expectedOutput.push_back("   event: [56] class [start_of_life]");
+    expectedOutput.push_back("   event: [58] class [end_of_life]");
+    BOOST_TEST(CompareOutput(desc, expectedOutput));
 }
 
 BOOST_AUTO_TEST_CASE(DumpOutgoingValidFileEndToEnd, * boost::unit_test::disabled())
diff --git a/src/profiling/test/ProfilingMocks.hpp b/src/profiling/test/ProfilingMocks.hpp
index 28e410f..fe8fbd7 100644
--- a/src/profiling/test/ProfilingMocks.hpp
+++ b/src/profiling/test/ProfilingMocks.hpp
@@ -1,5 +1,5 @@
 //
-// Copyright © 2020 Arm Ltd. All rights reserved.
+// Copyright © 2020 Arm Ltd and Contributors. All rights reserved.
 // SPDX-License-Identifier: MIT
 //
 
@@ -7,6 +7,7 @@
 
 #include <Holder.hpp>
 #include <IProfilingConnectionFactory.hpp>
+#include <IProfilingServiceStatus.hpp>
 #include <ProfilingService.hpp>
 #include <ProfilingGuidGenerator.hpp>
 #include <ProfilingUtils.hpp>
@@ -691,6 +692,13 @@
     CaptureData            m_CaptureData;
 };
 
+class MockProfilingServiceStatus : public IProfilingServiceStatus
+{
+public:
+    void NotifyProfilingServiceActive() override {}
+    void WaitForProfilingServiceActivation(unsigned int timeout) override { IgnoreUnused(timeout); }
+};
+
 } // namespace profiling
 
 } // namespace armnn
diff --git a/src/profiling/test/ProfilingTestUtils.cpp b/src/profiling/test/ProfilingTestUtils.cpp
index 20e1a9b..758d959 100644
--- a/src/profiling/test/ProfilingTestUtils.cpp
+++ b/src/profiling/test/ProfilingTestUtils.cpp
@@ -1,5 +1,5 @@
 //
-// Copyright © 2019 Arm Ltd. All rights reserved.
+// Copyright © 2019 Arm Ltd and Contributors. All rights reserved.
 // SPDX-License-Identifier: MIT
 //
 
@@ -75,10 +75,10 @@
     offset += uint32_t_size;
 }
 
-void VerifyTimelineLabelBinaryPacketData(Optional<ProfilingGuid> guid,
-                                         const std::string& label,
-                                         const unsigned char* readableData,
-                                         unsigned int& offset)
+ProfilingGuid VerifyTimelineLabelBinaryPacketData(Optional<ProfilingGuid> guid,
+                                                  const std::string& label,
+                                                  const unsigned char* readableData,
+                                                  unsigned int& offset)
 {
     ARMNN_ASSERT(readableData);
 
@@ -115,6 +115,9 @@
 
     // SWTrace strings are written in blocks of words, so the offset has to be updated to the next whole word
     offset += OffsetToNextWord(swTraceLabelLength);
+
+    ProfilingGuid labelGuid(readProfilingGuid);
+    return labelGuid;
 }
 
 void VerifyTimelineEventClassBinaryPacketData(ProfilingGuid guid,
@@ -146,12 +149,12 @@
 }
 
 void VerifyTimelineRelationshipBinaryPacketData(ProfilingRelationshipType relationshipType,
-                                            Optional<ProfilingGuid> relationshipGuid,
-                                            Optional<ProfilingGuid> headGuid,
-                                            Optional<ProfilingGuid> tailGuid,
-                                            Optional<ProfilingGuid> attributeGuid,
-                                            const unsigned char* readableData,
-                                            unsigned int& offset)
+                                                Optional<ProfilingGuid> relationshipGuid,
+                                                Optional<ProfilingGuid> headGuid,
+                                                Optional<ProfilingGuid> tailGuid,
+                                                Optional<ProfilingGuid> attributeGuid,
+                                                const unsigned char* readableData,
+                                                unsigned int& offset)
 {
     ARMNN_ASSERT(readableData);
 
@@ -199,7 +202,7 @@
         BOOST_CHECK(readRelationshipGuid != ProfilingGuid(0));
     }
 
-    // Check the head of relationship GUID
+    // Check the head GUID of the relationship
     offset += uint64_t_size;
     uint64_t readHeadRelationshipGuid = ReadUint64(readableData, offset);
     if (headGuid.has_value())
@@ -211,7 +214,7 @@
         BOOST_CHECK(readHeadRelationshipGuid != ProfilingGuid(0));
     }
 
-    // Check the tail of relationship GUID
+    // Check the tail GUID of the relationship
     offset += uint64_t_size;
     uint64_t readTailRelationshipGuid = ReadUint64(readableData, offset);
     if (tailGuid.has_value())
@@ -223,7 +226,7 @@
         BOOST_CHECK(readTailRelationshipGuid != ProfilingGuid(0));
     }
 
-    // Check the tail of relationship GUID
+    // Check the attribute GUID of the relationship
     offset += uint64_t_size;
     uint64_t readAttributeRelationshipGuid = ReadUint64(readableData, offset);
     if (attributeGuid.has_value())
@@ -239,9 +242,9 @@
     offset += uint64_t_size;
 }
 
-void VerifyTimelineEntityBinaryPacketData(Optional<ProfilingGuid> guid,
-                                          const unsigned char* readableData,
-                                          unsigned int& offset)
+ProfilingGuid VerifyTimelineEntityBinaryPacketData(Optional<ProfilingGuid> guid,
+                                                   const unsigned char* readableData,
+                                                   unsigned int& offset)
 {
     ARMNN_ASSERT(readableData);
 
@@ -268,13 +271,16 @@
     }
 
     offset += uint64_t_size;
+
+    ProfilingGuid entityGuid(readProfilingGuid);
+    return entityGuid;
 }
 
-void VerifyTimelineEventBinaryPacket(Optional<uint64_t> timestamp,
-                                     Optional<std::thread::id> threadId,
-                                     Optional<ProfilingGuid> eventGuid,
-                                     const unsigned char* readableData,
-                                     unsigned int& offset)
+ProfilingGuid VerifyTimelineEventBinaryPacket(Optional<uint64_t> timestamp,
+                                              Optional<std::thread::id> threadId,
+                                              Optional<ProfilingGuid> eventGuid,
+                                              const unsigned char* readableData,
+                                              unsigned int& offset)
 {
     ARMNN_ASSERT(readableData);
 
@@ -325,6 +331,9 @@
     }
 
     offset += uint64_t_size;
+
+    ProfilingGuid eventid(readEventGuid);
+    return eventid;
 }
 
 void VerifyPostOptimisationStructureTestImpl(armnn::BackendId backendId)
@@ -414,7 +423,7 @@
     BOOST_CHECK(readableBuffer != nullptr);
 
     unsigned int size = readableBuffer->GetSize();
-    BOOST_CHECK(size == 1244);
+    BOOST_CHECK(size == 1124);
 
     const unsigned char* readableData = readableBuffer->GetReadableData();
     BOOST_CHECK(readableData != nullptr);
@@ -422,289 +431,289 @@
     unsigned int offset = 0;
 
     // Verify Header
-    VerifyTimelineHeaderBinary(readableData, offset, 1236);
+    VerifyTimelineHeaderBinary(readableData, offset, 1116);
+    BOOST_TEST_MESSAGE("HEADER OK");
 
     // Post-optimisation network
     // Network entity
     VerifyTimelineEntityBinaryPacketData(optNetGuid, readableData, offset);
+    BOOST_TEST_MESSAGE("NETWORK ENTITY OK");
 
     // Entity - Type relationship
     VerifyTimelineRelationshipBinaryPacketData(ProfilingRelationshipType::LabelLink,
                                                EmptyOptional(),
                                                optNetGuid,
-                                               EmptyOptional(),
+                                               LabelsAndEventClasses::NETWORK_GUID,
                                                LabelsAndEventClasses::TYPE_GUID,
                                                readableData,
                                                offset);
+    BOOST_TEST_MESSAGE("NETWORK TYPE RELATIONSHIP OK");
 
     // Input layer
     // Input layer entity
     VerifyTimelineEntityBinaryPacketData(input->GetGuid(), readableData, offset);
+    BOOST_TEST_MESSAGE("INPUT ENTITY OK");
 
     // Name Entity
-    VerifyTimelineLabelBinaryPacketData(EmptyOptional(), "input", readableData, offset);
+    ProfilingGuid inputLabelGuid = VerifyTimelineLabelBinaryPacketData(EmptyOptional(), "input", readableData, offset);
+    BOOST_TEST_MESSAGE("INPUT NAME LABEL OK");
 
     // Entity - Name relationship
     VerifyTimelineRelationshipBinaryPacketData(ProfilingRelationshipType::LabelLink,
                                                EmptyOptional(),
                                                input->GetGuid(),
-                                               EmptyOptional(),
+                                               inputLabelGuid,
                                                LabelsAndEventClasses::NAME_GUID,
                                                readableData,
                                                offset);
-
-    // Name label relationship
-
+    BOOST_TEST_MESSAGE("INPUT NAME RELATIONSHIP OK");
 
     // Entity - Type relationship
     VerifyTimelineRelationshipBinaryPacketData(ProfilingRelationshipType::LabelLink,
                                                EmptyOptional(),
                                                input->GetGuid(),
-                                               EmptyOptional(),
+                                               LabelsAndEventClasses::LAYER_GUID,
                                                LabelsAndEventClasses::TYPE_GUID,
                                                readableData,
                                                offset);
-
-    // Type label relationship
-
+    BOOST_TEST_MESSAGE("INPUT TYPE RELATIONSHIP OK");
 
     // Network - Input layer relationship
     VerifyTimelineRelationshipBinaryPacketData(ProfilingRelationshipType::RetentionLink,
                                                EmptyOptional(),
                                                optNetGuid,
                                                input->GetGuid(),
-                                               EmptyOptional(),
+                                               LabelsAndEventClasses::CHILD_GUID,
                                                readableData,
                                                offset);
+    BOOST_TEST_MESSAGE("NETWORK - INPUT CHILD RELATIONSHIP OK");
 
     // Conv2d layer
     // Conv2d layer entity
     VerifyTimelineEntityBinaryPacketData(conv2d->GetGuid(), readableData, offset);
 
     // Name entity
-    VerifyTimelineLabelBinaryPacketData(EmptyOptional(), "<Unnamed>", readableData, offset);
+    ProfilingGuid conv2dNameLabelGuid = VerifyTimelineLabelBinaryPacketData(
+        EmptyOptional(), "<Unnamed>", readableData, offset);
+    BOOST_TEST_MESSAGE("CONV2D NAME LABEL OK");
 
     // Entity - Name relationship
     VerifyTimelineRelationshipBinaryPacketData(ProfilingRelationshipType::LabelLink,
                                                EmptyOptional(),
                                                conv2d->GetGuid(),
-                                               EmptyOptional(),
+                                               conv2dNameLabelGuid,
                                                LabelsAndEventClasses::NAME_GUID,
                                                readableData,
                                                offset);
+    BOOST_TEST_MESSAGE("CONV2D NAME RELATIONSHIP OK");
 
     // Entity - Type relationship
     VerifyTimelineRelationshipBinaryPacketData(ProfilingRelationshipType::LabelLink,
                                                EmptyOptional(),
                                                conv2d->GetGuid(),
-                                               EmptyOptional(),
+                                               LabelsAndEventClasses::LAYER_GUID,
                                                LabelsAndEventClasses::TYPE_GUID,
                                                readableData,
                                                offset);
-
+    BOOST_TEST_MESSAGE("CONV2D TYPE RELATIONSHIP OK");
 
     // Network - Conv2d layer relationship
     VerifyTimelineRelationshipBinaryPacketData(ProfilingRelationshipType::RetentionLink,
                                                EmptyOptional(),
                                                optNetGuid,
                                                conv2d->GetGuid(),
-                                               EmptyOptional(),
+                                               LabelsAndEventClasses::CHILD_GUID,
                                                readableData,
                                                offset);
+    BOOST_TEST_MESSAGE("NETWORK - CONV2D CHILD RELATIONSHIP OK");
 
     // Input layer - Conv2d layer relationship
     VerifyTimelineRelationshipBinaryPacketData(ProfilingRelationshipType::RetentionLink,
                                                EmptyOptional(),
                                                input->GetGuid(),
                                                conv2d->GetGuid(),
-                                               EmptyOptional(),
-                                               readableData,
-                                               offset);
-
-    // Entity - Type relationship
-    VerifyTimelineRelationshipBinaryPacketData(ProfilingRelationshipType::LabelLink,
-                                               EmptyOptional(),
-                                               EmptyOptional(),
                                                LabelsAndEventClasses::CONNECTION_GUID,
-                                               LabelsAndEventClasses::TYPE_GUID,
                                                readableData,
                                                offset);
-
-
+    BOOST_TEST_MESSAGE("INPUT - CONV2D LAYER CONNECTION OK");
 
     // Conv2d workload
     // Conv2d workload entity
-    VerifyTimelineEntityBinaryPacketData(EmptyOptional(), readableData, offset);
+    ProfilingGuid conv2DWorkloadGuid = VerifyTimelineEntityBinaryPacketData(EmptyOptional(), readableData, offset);
+    BOOST_TEST_MESSAGE("CONV2D WORKLOAD ENTITY OK");
 
     // Entity - Type relationship
     VerifyTimelineRelationshipBinaryPacketData(ProfilingRelationshipType::LabelLink,
                                                EmptyOptional(),
-                                               EmptyOptional(),
-                                               EmptyOptional(),
+                                               conv2DWorkloadGuid,
+                                               LabelsAndEventClasses::WORKLOAD_GUID,
                                                LabelsAndEventClasses::TYPE_GUID,
                                                readableData,
                                                offset);
-
+    BOOST_TEST_MESSAGE("CONV2D WORKLOAD TYPE RELATIONSHIP OK");
 
     // BackendId entity
-    VerifyTimelineLabelBinaryPacketData(EmptyOptional(), backendId.Get(), readableData, offset);
+    ProfilingGuid backendIdLabelGuid = VerifyTimelineLabelBinaryPacketData(
+        EmptyOptional(), backendId.Get(), readableData, offset);
 
     // Entity - BackendId relationship
     VerifyTimelineRelationshipBinaryPacketData(ProfilingRelationshipType::LabelLink,
                                                EmptyOptional(),
-                                               EmptyOptional(),
-                                               EmptyOptional(),
+                                               conv2DWorkloadGuid,
+                                               backendIdLabelGuid,
                                                LabelsAndEventClasses::BACKENDID_GUID,
                                                readableData,
                                                offset);
+    BOOST_TEST_MESSAGE("CONV2D WORKLOAD BACKEND ID RELATIONSHIP OK");
 
 
     // Conv2d layer - Conv2d workload relationship
     VerifyTimelineRelationshipBinaryPacketData(ProfilingRelationshipType::RetentionLink,
                                                EmptyOptional(),
                                                conv2d->GetGuid(),
-                                               EmptyOptional(),
-                                               EmptyOptional(),
+                                               conv2DWorkloadGuid,
+                                               LabelsAndEventClasses::CHILD_GUID,
                                                readableData,
                                                offset);
+    BOOST_TEST_MESSAGE("CONV2D LAYER - WORKLOAD CHILD RELATIONSHIP OK");
 
     // Activation layer
     // Activation layer entity
     VerifyTimelineEntityBinaryPacketData(activation->GetGuid(), readableData, offset);
+    BOOST_TEST_MESSAGE("ACTIVATION ENTITY OK");
 
     // Name entity
-    VerifyTimelineLabelBinaryPacketData(EmptyOptional(), "activation", readableData, offset);
+    ProfilingGuid activationLabelGuid = VerifyTimelineLabelBinaryPacketData(
+        EmptyOptional(), "activation", readableData, offset);
+    BOOST_TEST_MESSAGE("ACTIVATION NAME LABEL OK");
 
     // Entity - Name relationship
     VerifyTimelineRelationshipBinaryPacketData(ProfilingRelationshipType::LabelLink,
                                                EmptyOptional(),
                                                activation->GetGuid(),
-                                               EmptyOptional(),
+                                               activationLabelGuid,
                                                LabelsAndEventClasses::NAME_GUID,
                                                readableData,
                                                offset);
+    BOOST_TEST_MESSAGE("ACTIVATION LAYER - NAME RELATIONSHIP OK");
 
     // Entity - Type relationship
     VerifyTimelineRelationshipBinaryPacketData(ProfilingRelationshipType::LabelLink,
                                                EmptyOptional(),
                                                activation->GetGuid(),
-                                               EmptyOptional(),
+                                               LabelsAndEventClasses::LAYER_GUID,
                                                LabelsAndEventClasses::TYPE_GUID,
                                                readableData,
                                                offset);
+    BOOST_TEST_MESSAGE("ACTIVATION LAYER TYPE RELATIONSHIP OK");
 
     // Network - Activation layer relationship
     VerifyTimelineRelationshipBinaryPacketData(ProfilingRelationshipType::RetentionLink,
                                                EmptyOptional(),
                                                optNetGuid,
                                                activation->GetGuid(),
-                                               EmptyOptional(),
+                                               LabelsAndEventClasses::CHILD_GUID,
                                                readableData,
                                                offset);
+    BOOST_TEST_MESSAGE("NETWORK - ACTIVATION LAYER CHILD RELATIONSHIP OK");
 
     // Conv2d layer - Activation layer relationship
     VerifyTimelineRelationshipBinaryPacketData(ProfilingRelationshipType::RetentionLink,
                                                EmptyOptional(),
                                                conv2d->GetGuid(),
                                                activation->GetGuid(),
-                                               EmptyOptional(),
-                                               readableData,
-                                               offset);
-
-    // Entity - Type relationship
-    VerifyTimelineRelationshipBinaryPacketData(ProfilingRelationshipType::LabelLink,
-                                               EmptyOptional(),
-                                               EmptyOptional(),
                                                LabelsAndEventClasses::CONNECTION_GUID,
-                                               LabelsAndEventClasses::TYPE_GUID,
                                                readableData,
                                                offset);
+    BOOST_TEST_MESSAGE("CONV2D LAYER - ACTIVATION LAYER CONNECTION OK");
 
     // Activation workload
     // Activation workload entity
-    VerifyTimelineEntityBinaryPacketData(EmptyOptional(), readableData, offset);
+    ProfilingGuid activationWorkloadGuid = VerifyTimelineEntityBinaryPacketData(EmptyOptional(), readableData, offset);
+    BOOST_TEST_MESSAGE("ACTIVATION WORKLOAD ENTITY OK");
 
     // Entity - Type relationship
     VerifyTimelineRelationshipBinaryPacketData(ProfilingRelationshipType::LabelLink,
                                                EmptyOptional(),
-                                               EmptyOptional(),
-                                               EmptyOptional(),
+                                               activationWorkloadGuid,
+                                               LabelsAndEventClasses::WORKLOAD_GUID,
                                                LabelsAndEventClasses::TYPE_GUID,
                                                readableData,
                                                offset);
+    BOOST_TEST_MESSAGE("ACTIVATION WORKLAD TYPE RELATIONSHIP OK");
 
     // BackendId entity
     VerifyTimelineLabelBinaryPacketData(EmptyOptional(), backendId.Get(), readableData, offset);
+    BOOST_TEST_MESSAGE("BACKEND ID LABEL OK");
 
     // Entity - BackendId relationship
     VerifyTimelineRelationshipBinaryPacketData(ProfilingRelationshipType::LabelLink,
                                                EmptyOptional(),
-                                               EmptyOptional(),
-                                               EmptyOptional(),
+                                               activationWorkloadGuid,
+                                               backendIdLabelGuid,
                                                LabelsAndEventClasses::BACKENDID_GUID,
                                                readableData,
                                                offset);
+    BOOST_TEST_MESSAGE("ACTIVATION WORKLOAD BACKEND ID RELATIONSHIP OK");
 
     // Activation layer - Activation workload relationship
     VerifyTimelineRelationshipBinaryPacketData(ProfilingRelationshipType::RetentionLink,
                                                EmptyOptional(),
                                                activation->GetGuid(),
-                                               EmptyOptional(),
-                                               EmptyOptional(),
+                                               activationWorkloadGuid,
+                                               LabelsAndEventClasses::CHILD_GUID,
                                                readableData,
                                                offset);
+    BOOST_TEST_MESSAGE("ACTIVATION LAYER - WORKLOAD CHILD RELATIONSHIP OK");
 
     // Output layer
     // Output layer entity
     VerifyTimelineEntityBinaryPacketData(output->GetGuid(), readableData, offset);
+    BOOST_TEST_MESSAGE("OUTPUT LAYER ENTITY OK");
 
     // Name entity
-    VerifyTimelineLabelBinaryPacketData(EmptyOptional(), "output", readableData, offset);
+    ProfilingGuid outputLabelGuid = VerifyTimelineLabelBinaryPacketData(
+        EmptyOptional(), "output", readableData, offset);
 
     // Entity - Name relationship
     VerifyTimelineRelationshipBinaryPacketData(ProfilingRelationshipType::LabelLink,
                                                EmptyOptional(),
                                                output->GetGuid(),
-                                               EmptyOptional(),
+                                               outputLabelGuid,
                                                LabelsAndEventClasses::NAME_GUID,
                                                readableData,
                                                offset);
+    BOOST_TEST_MESSAGE("OUTPUT LAYER NAME RELATIONSHIP OK");
 
     // Entity - Type relationship
     VerifyTimelineRelationshipBinaryPacketData(ProfilingRelationshipType::LabelLink,
                                                EmptyOptional(),
                                                output->GetGuid(),
-                                               EmptyOptional(),
+                                               LabelsAndEventClasses::LAYER_GUID,
                                                LabelsAndEventClasses::TYPE_GUID,
                                                readableData,
                                                offset);
+    BOOST_TEST_MESSAGE("OUTPUT LAYER TYPE RELATIONSHIP OK");
 
     // Network - Output layer relationship
     VerifyTimelineRelationshipBinaryPacketData(ProfilingRelationshipType::RetentionLink,
                                                EmptyOptional(),
                                                optNetGuid,
                                                output->GetGuid(),
-                                               EmptyOptional(),
+                                               LabelsAndEventClasses::CHILD_GUID,
                                                readableData,
                                                offset);
+    BOOST_TEST_MESSAGE("NETWORK - OUTPUT LAYER CHILD RELATIONSHIP OK");
 
     // Activation layer - Output layer relationship
     VerifyTimelineRelationshipBinaryPacketData(ProfilingRelationshipType::RetentionLink,
                                                EmptyOptional(),
                                                activation->GetGuid(),
                                                output->GetGuid(),
-                                               EmptyOptional(),
-                                               readableData,
-                                               offset);
-
-    // Entity - Type relationship
-    VerifyTimelineRelationshipBinaryPacketData(ProfilingRelationshipType::LabelLink,
-                                               EmptyOptional(),
-                                               EmptyOptional(),
                                                LabelsAndEventClasses::CONNECTION_GUID,
-                                               LabelsAndEventClasses::TYPE_GUID,
                                                readableData,
                                                offset);
+    BOOST_TEST_MESSAGE("ACTIVATION LAYER - OUTPUT LAYER CONNECTION OK");
 
     bufferManager.MarkRead(readableBuffer);
 
@@ -747,19 +756,22 @@
 
     // Verify Header
     VerifyTimelineHeaderBinary(readableData, offset, 156);
+    BOOST_TEST_MESSAGE("INPUT WORKLOAD HEADER OK");
 
     // Input workload
     // Input workload entity
-    VerifyTimelineEntityBinaryPacketData(EmptyOptional(), readableData, offset);
+    ProfilingGuid inputWorkloadGuid = VerifyTimelineEntityBinaryPacketData(EmptyOptional(), readableData, offset);
+    BOOST_TEST_MESSAGE("INPUT WORKLOAD TYPE RELATIONSHIP OK");
 
     // Entity - Type relationship
     VerifyTimelineRelationshipBinaryPacketData(ProfilingRelationshipType::LabelLink,
                                                EmptyOptional(),
-                                               EmptyOptional(),
-                                               EmptyOptional(),
+                                               inputWorkloadGuid,
+                                               LabelsAndEventClasses::WORKLOAD_GUID,
                                                LabelsAndEventClasses::TYPE_GUID,
                                                readableData,
                                                offset);
+    BOOST_TEST_MESSAGE("INPUT WORKLOAD TYPE RELATIONSHIP OK");
 
     // BackendId entity
     VerifyTimelineLabelBinaryPacketData(EmptyOptional(), backendId.Get(), readableData, offset);
@@ -767,20 +779,22 @@
     // Entity - BackendId relationship
     VerifyTimelineRelationshipBinaryPacketData(ProfilingRelationshipType::LabelLink,
                                                EmptyOptional(),
-                                               EmptyOptional(),
-                                               EmptyOptional(),
+                                               inputWorkloadGuid,
+                                               backendIdLabelGuid,
                                                LabelsAndEventClasses::BACKENDID_GUID,
                                                readableData,
                                                offset);
+    BOOST_TEST_MESSAGE("INPUT WORKLOAD BACKEND ID RELATIONSHIP OK");
 
     // Input layer - Input workload relationship
     VerifyTimelineRelationshipBinaryPacketData(ProfilingRelationshipType::RetentionLink,
                                                EmptyOptional(),
                                                input->GetGuid(),
-                                               EmptyOptional(),
-                                               EmptyOptional(),
+                                               inputWorkloadGuid,
+                                               LabelsAndEventClasses::CHILD_GUID,
                                                readableData,
                                                offset);
+    BOOST_TEST_MESSAGE("INPUT LAYER - INPUT WORKLOAD CHILD RELATIONSHIP OK");
 
     bufferManager.MarkRead(inputReadableBuffer);
 
@@ -795,40 +809,46 @@
 
     // Verify Header
     VerifyTimelineHeaderBinary(readableData, offset, 156);
+    BOOST_TEST_MESSAGE("OUTPUT WORKLOAD HEADER OK");
 
     // Output workload
     // Output workload entity
-    VerifyTimelineEntityBinaryPacketData(EmptyOptional(), readableData, offset);
+    ProfilingGuid outputWorkloadGuid = VerifyTimelineEntityBinaryPacketData(EmptyOptional(), readableData, offset);
+    BOOST_TEST_MESSAGE("OUTPUT WORKLOAD ENTITY OK");
 
     // Entity - Type relationship
     VerifyTimelineRelationshipBinaryPacketData(ProfilingRelationshipType::LabelLink,
                                                EmptyOptional(),
-                                               EmptyOptional(),
-                                               EmptyOptional(),
+                                               outputWorkloadGuid,
+                                               LabelsAndEventClasses::WORKLOAD_GUID,
                                                LabelsAndEventClasses::TYPE_GUID,
                                                readableData,
                                                offset);
+    BOOST_TEST_MESSAGE("OUTPUT WORKLOAD TYPE RELATIONSHIP OK");
 
     // BackendId entity
     VerifyTimelineLabelBinaryPacketData(EmptyOptional(), backendId.Get(), readableData, offset);
+    BOOST_TEST_MESSAGE("OUTPUT WORKLOAD LABEL OK");
 
     // Entity - BackendId relationship
     VerifyTimelineRelationshipBinaryPacketData(ProfilingRelationshipType::LabelLink,
                                                EmptyOptional(),
-                                               EmptyOptional(),
-                                               EmptyOptional(),
+                                               outputWorkloadGuid,
+                                               backendIdLabelGuid,
                                                LabelsAndEventClasses::BACKENDID_GUID,
                                                readableData,
                                                offset);
+    BOOST_TEST_MESSAGE("OUTPUT WORKLOAD BACKEND ID RELATIONSHIP OK");
 
     // Output layer - Output workload relationship
     VerifyTimelineRelationshipBinaryPacketData(ProfilingRelationshipType::RetentionLink,
                                                EmptyOptional(),
                                                output->GetGuid(),
-                                               EmptyOptional(),
-                                               EmptyOptional(),
+                                               outputWorkloadGuid,
+                                               LabelsAndEventClasses::CHILD_GUID,
                                                readableData,
                                                offset);
+    BOOST_TEST_MESSAGE("OUTPUT LAYER - OUTPUT WORKLOAD CHILD RELATIONSHIP OK");
 
     bufferManager.MarkRead(outputReadableBuffer);
 
@@ -844,283 +864,384 @@
 
     // Verify Header
     VerifyTimelineHeaderBinary(readableData, offset, 1220 + 10 * ThreadIdSize);
+    BOOST_TEST_MESSAGE("INFERENCE HEADER OK");
 
     // Inference timeline trace
     // Inference entity
-    VerifyTimelineEntityBinaryPacketData(EmptyOptional(), readableData, offset);
+    ProfilingGuid inferenceGuid = VerifyTimelineEntityBinaryPacketData(EmptyOptional(), readableData, offset);
+    BOOST_TEST_MESSAGE("INFERENCE ENTITY OK");
 
     // Entity - Type relationship
     VerifyTimelineRelationshipBinaryPacketData(ProfilingRelationshipType::LabelLink,
                                                EmptyOptional(),
-                                               EmptyOptional(),
+                                               inferenceGuid,
                                                LabelsAndEventClasses::INFERENCE_GUID,
                                                LabelsAndEventClasses::TYPE_GUID,
                                                readableData,
                                                offset);
+    BOOST_TEST_MESSAGE("INFERENCE TYPE RELATIONSHIP OK");
 
     // Network - Inference relationship
     VerifyTimelineRelationshipBinaryPacketData(ProfilingRelationshipType::RetentionLink,
                                                EmptyOptional(),
                                                optNetGuid,
-                                               EmptyOptional(),
-                                               EmptyOptional(),
+                                               inferenceGuid,
+                                               LabelsAndEventClasses::EXECUTION_OF_GUID,
                                                readableData,
                                                offset);
+    BOOST_TEST_MESSAGE("NETWORK - INFERENCE EXECUTION_OF RELATIONSHIP OK");
 
     // Start Inference life
     // Event packet - timeline, threadId, eventGuid
-    VerifyTimelineEventBinaryPacket(EmptyOptional(), EmptyOptional(), EmptyOptional(), readableData, offset);
+    ProfilingGuid inferenceEventGuid = VerifyTimelineEventBinaryPacket(
+        EmptyOptional(), EmptyOptional(), EmptyOptional(), readableData, offset);
+    BOOST_TEST_MESSAGE("INFERENCE START OF LIFE EVENT OK");
 
     // Inference - event relationship
     VerifyTimelineRelationshipBinaryPacketData(ProfilingRelationshipType::ExecutionLink,
                                                EmptyOptional(),
-                                               EmptyOptional(),
-                                               EmptyOptional(),
+                                               inferenceGuid,
+                                               inferenceEventGuid,
                                                LabelsAndEventClasses::ARMNN_PROFILING_SOL_EVENT_CLASS,
                                                readableData,
                                                offset);
+    BOOST_TEST_MESSAGE("INFERENCE START OF LIFE RELATIONSHIP OK");
 
     // Execution
     // Input workload execution
     // Input workload execution entity
-    VerifyTimelineEntityBinaryPacketData(EmptyOptional(), readableData, offset);
+    ProfilingGuid inputWorkloadExecutionGuid = VerifyTimelineEntityBinaryPacketData(
+        EmptyOptional(), readableData, offset);
+    BOOST_TEST_MESSAGE("INPUT WORKLOAD EXECUTION ENTITY OK");
 
     // Entity - Type relationship
     VerifyTimelineRelationshipBinaryPacketData(ProfilingRelationshipType::LabelLink,
                                                EmptyOptional(),
-                                               EmptyOptional(),
+                                               inputWorkloadExecutionGuid,
                                                LabelsAndEventClasses::WORKLOAD_EXECUTION_GUID,
                                                LabelsAndEventClasses::TYPE_GUID,
                                                readableData,
                                                offset);
+    BOOST_TEST_MESSAGE("INPUT WORKLOAD EXECUTION TYPE RELATIONSHIP OK");
 
     // Inference - Workload execution relationship
     VerifyTimelineRelationshipBinaryPacketData(ProfilingRelationshipType::RetentionLink,
                                                EmptyOptional(),
-                                               EmptyOptional(),
-                                               EmptyOptional(),
-                                               EmptyOptional(),
+                                               inferenceGuid,
+                                               inputWorkloadExecutionGuid,
+                                               LabelsAndEventClasses::CHILD_GUID,
                                                readableData,
                                                offset);
+    BOOST_TEST_MESSAGE("INPUT WORKLOAD - INPUT WORKLOAD EXECUTION RELATIONSHIP OK");
 
     // Workload - Workload execution relationship
     VerifyTimelineRelationshipBinaryPacketData(ProfilingRelationshipType::RetentionLink,
                                                EmptyOptional(),
-                                               EmptyOptional(),
-                                               EmptyOptional(),
-                                               EmptyOptional(),
+                                               inputWorkloadGuid,
+                                               inputWorkloadExecutionGuid,
+                                               LabelsAndEventClasses::EXECUTION_OF_GUID,
                                                readableData,
                                                offset);
+    BOOST_TEST_MESSAGE("INPUT WORKLOAD - INPUT WORKLOAD EXECUTION RELATIONSHIP OK");
 
     // Start Input workload execution life
     // Event packet - timeline, threadId, eventGuid
-    VerifyTimelineEventBinaryPacket(EmptyOptional(), EmptyOptional(), EmptyOptional(), readableData, offset);
+    ProfilingGuid inputWorkloadExecutionSOLEventId = VerifyTimelineEventBinaryPacket(
+        EmptyOptional(), EmptyOptional(), EmptyOptional(), readableData, offset);
+    BOOST_TEST_MESSAGE("INPUT WORKLOAD EXECUTION - START OF LIFE EVENT OK");
 
     // Input workload execution - event relationship
     VerifyTimelineRelationshipBinaryPacketData(ProfilingRelationshipType::ExecutionLink,
                                                EmptyOptional(),
-                                               EmptyOptional(),
-                                               EmptyOptional(),
+                                               inputWorkloadExecutionGuid,
+                                               inputWorkloadExecutionSOLEventId,
                                                LabelsAndEventClasses::ARMNN_PROFILING_SOL_EVENT_CLASS,
                                                readableData,
                                                offset);
+    BOOST_TEST_MESSAGE("INPUT WORKLOAD EXECUTION - START OF LIFE EVENT RELATIONSHIP OK");
 
     // End of Input workload execution life
     // Event packet - timeline, threadId, eventGuid
-    VerifyTimelineEventBinaryPacket(EmptyOptional(), EmptyOptional(), EmptyOptional(), readableData, offset);
+    ProfilingGuid inputWorkloadExecutionEOLEventId = VerifyTimelineEventBinaryPacket(
+        EmptyOptional(), EmptyOptional(), EmptyOptional(), readableData, offset);
+    BOOST_TEST_MESSAGE("INPUT WORKLOAD EXECUTION - END OF LIFE EVENT OK");
 
     // Input workload execution - event relationship
     VerifyTimelineRelationshipBinaryPacketData(ProfilingRelationshipType::ExecutionLink,
                                                EmptyOptional(),
-                                               EmptyOptional(),
-                                               EmptyOptional(),
+                                               inputWorkloadExecutionGuid,
+                                               inputWorkloadExecutionEOLEventId,
                                                LabelsAndEventClasses::ARMNN_PROFILING_EOL_EVENT_CLASS,
                                                readableData,
                                                offset);
+    BOOST_TEST_MESSAGE("INPUT WORKLOAD EXECUTION - END OF LIFE EVENT RELATIONSHIP OK");
 
     // Conv2d workload execution
     // Conv2d workload execution entity
-    VerifyTimelineEntityBinaryPacketData(EmptyOptional(), readableData, offset);
+    ProfilingGuid conv2DWorkloadExecutionGuid = VerifyTimelineEntityBinaryPacketData(
+        EmptyOptional(), readableData, offset);
+    BOOST_TEST_MESSAGE("CONV2D WORKLOAD EXECUTION ENTITY OK");
 
     // Entity - Type relationship
     VerifyTimelineRelationshipBinaryPacketData(ProfilingRelationshipType::LabelLink,
                                                EmptyOptional(),
-                                               EmptyOptional(),
+                                               conv2DWorkloadExecutionGuid,
                                                LabelsAndEventClasses::WORKLOAD_EXECUTION_GUID,
                                                LabelsAndEventClasses::TYPE_GUID,
                                                readableData,
                                                offset);
+    BOOST_TEST_MESSAGE("CONV2D WORKLOAD EXECUTION TYPE RELATIONSHIP OK");
 
     // Inference - Workload execution relationship
     VerifyTimelineRelationshipBinaryPacketData(ProfilingRelationshipType::RetentionLink,
                                                EmptyOptional(),
-                                               EmptyOptional(),
-                                               EmptyOptional(),
-                                               EmptyOptional(),
+                                               inferenceGuid,
+                                               conv2DWorkloadExecutionGuid,
+                                               LabelsAndEventClasses::CHILD_GUID,
                                                readableData,
                                                offset);
+    BOOST_TEST_MESSAGE("INFERENCE - CONV2D WORKLOAD EXECUTION CHILD RELATIONSHIP OK");
 
     // Workload - Workload execution relationship
     VerifyTimelineRelationshipBinaryPacketData(ProfilingRelationshipType::RetentionLink,
                                                EmptyOptional(),
-                                               EmptyOptional(),
-                                               EmptyOptional(),
-                                               EmptyOptional(),
+                                               conv2DWorkloadGuid,
+                                               conv2DWorkloadExecutionGuid,
+                                               LabelsAndEventClasses::EXECUTION_OF_GUID,
                                                readableData,
                                                offset);
+    BOOST_TEST_MESSAGE("CONV2D WORKLOAD - CONV2D WORKLOAD EXECUTION RELATIONSHIP OK");
 
     // Start Conv2d workload execution life
     // Event packet - timeline, threadId, eventGuid
-    VerifyTimelineEventBinaryPacket(EmptyOptional(), EmptyOptional(), EmptyOptional(), readableData, offset);
+    ProfilingGuid conv2DWorkloadExecutionSOLEventGuid = VerifyTimelineEventBinaryPacket(
+        EmptyOptional(), EmptyOptional(), EmptyOptional(), readableData, offset);
+    BOOST_TEST_MESSAGE("CONV2D WORKLOAD EXECUTION START OF LIFE EVENT OK");
 
     // Conv2d workload execution - event relationship
     VerifyTimelineRelationshipBinaryPacketData(ProfilingRelationshipType::ExecutionLink,
                                                EmptyOptional(),
-                                               EmptyOptional(),
-                                               EmptyOptional(),
+                                               conv2DWorkloadExecutionGuid,
+                                               conv2DWorkloadExecutionSOLEventGuid,
                                                LabelsAndEventClasses::ARMNN_PROFILING_SOL_EVENT_CLASS,
                                                readableData,
                                                offset);
+    BOOST_TEST_MESSAGE("CONV2D WORKLOAD EXECUTION START OF LIFE RELATIONSHIP OK");
 
     // End of Conv2d workload execution life
     // Event packet - timeline, threadId, eventGuid
-    VerifyTimelineEventBinaryPacket(EmptyOptional(), EmptyOptional(), EmptyOptional(), readableData, offset);
+    ProfilingGuid conv2DWorkloadExecutionEOLEventGuid = VerifyTimelineEventBinaryPacket(
+        EmptyOptional(), EmptyOptional(), EmptyOptional(), readableData, offset);
+    BOOST_TEST_MESSAGE("CONV2D WORKLOAD EXECUTION END OF LIFE EVENT OK");
 
     // Conv2d workload execution - event relationship
     VerifyTimelineRelationshipBinaryPacketData(ProfilingRelationshipType::ExecutionLink,
                                                EmptyOptional(),
-                                               EmptyOptional(),
-                                               EmptyOptional(),
+                                               conv2DWorkloadExecutionGuid,
+                                               conv2DWorkloadExecutionEOLEventGuid,
                                                LabelsAndEventClasses::ARMNN_PROFILING_EOL_EVENT_CLASS,
                                                readableData,
                                                offset);
+    BOOST_TEST_MESSAGE("CONV2D WORKLOAD EXECUTION END OF LIFE RELATIONSHIP OK");
 
     // Activation workload execution
     // Activation workload execution entity
-    VerifyTimelineEntityBinaryPacketData(EmptyOptional(), readableData, offset);
+    ProfilingGuid activationWorkloadExecutionGuid = VerifyTimelineEntityBinaryPacketData(
+        EmptyOptional(), readableData, offset);
+    BOOST_TEST_MESSAGE("ACTIVATION WORKLOAD EXECUTION ENTITY OK");
 
     // Entity - Type relationship
     VerifyTimelineRelationshipBinaryPacketData(ProfilingRelationshipType::LabelLink,
                                                EmptyOptional(),
-                                               EmptyOptional(),
+                                               activationWorkloadExecutionGuid,
                                                LabelsAndEventClasses::WORKLOAD_EXECUTION_GUID,
                                                LabelsAndEventClasses::TYPE_GUID,
                                                readableData,
                                                offset);
+    BOOST_TEST_MESSAGE("ACTIVATION WORKLOAD EXECUTION TYPE RELATIONSHIP OK");
 
     // Inference - Workload execution relationship
     VerifyTimelineRelationshipBinaryPacketData(ProfilingRelationshipType::RetentionLink,
                                                EmptyOptional(),
-                                               EmptyOptional(),
-                                               EmptyOptional(),
-                                               EmptyOptional(),
+                                               inferenceGuid,
+                                               activationWorkloadExecutionGuid,
+                                               LabelsAndEventClasses::CHILD_GUID,
                                                readableData,
                                                offset);
+    BOOST_TEST_MESSAGE("INFERENCE - ACTIVATION WORKLOAD EXECUTION CHILD RELATIONSHIP OK");
 
     // Workload - Workload execution relationship
     VerifyTimelineRelationshipBinaryPacketData(ProfilingRelationshipType::RetentionLink,
                                                EmptyOptional(),
-                                               EmptyOptional(),
-                                               EmptyOptional(),
-                                               EmptyOptional(),
+                                               activationWorkloadGuid,
+                                               activationWorkloadExecutionGuid,
+                                               LabelsAndEventClasses::EXECUTION_OF_GUID,
                                                readableData,
                                                offset);
+    BOOST_TEST_MESSAGE("ACTIVATION WORKLOAD - ACTIVATION WORKLOAD EXECUTION RELATIONSHIP OK");
 
     // Start Activation workload execution life
     // Event packet - timeline, threadId, eventGuid
-    VerifyTimelineEventBinaryPacket(EmptyOptional(), EmptyOptional(), EmptyOptional(), readableData, offset);
+    ProfilingGuid activationWorkloadExecutionSOLEventGuid = VerifyTimelineEventBinaryPacket(
+        EmptyOptional(), EmptyOptional(), EmptyOptional(), readableData, offset);
+    BOOST_TEST_MESSAGE("ACTIVATION WORKLOAD EXECUTION START OF LIFE EVENT OK");
 
     // Activation workload execution - event relationship
     VerifyTimelineRelationshipBinaryPacketData(ProfilingRelationshipType::ExecutionLink,
                                                EmptyOptional(),
-                                               EmptyOptional(),
-                                               EmptyOptional(),
+                                               activationWorkloadExecutionGuid,
+                                               activationWorkloadExecutionSOLEventGuid,
                                                LabelsAndEventClasses::ARMNN_PROFILING_SOL_EVENT_CLASS,
                                                readableData,
                                                offset);
+    BOOST_TEST_MESSAGE("ACTIVATION WORKLOAD EXECUTION START OF LIFE RELATIONSHIP OK");
 
     // End of Activation workload execution life
     // Event packet - timeline, threadId, eventGuid
-    VerifyTimelineEventBinaryPacket(EmptyOptional(), EmptyOptional(), EmptyOptional(), readableData, offset);
+    ProfilingGuid activationWorkloadExecutionEOLEventGuid = VerifyTimelineEventBinaryPacket(
+        EmptyOptional(), EmptyOptional(), EmptyOptional(), readableData, offset);
+    BOOST_TEST_MESSAGE("ACTIVATION WORKLOAD EXECUTION END OF LIFE EVENT OK");
 
     // Activation workload execution - event relationship
     VerifyTimelineRelationshipBinaryPacketData(ProfilingRelationshipType::ExecutionLink,
                                                EmptyOptional(),
-                                               EmptyOptional(),
-                                               EmptyOptional(),
+                                               activationWorkloadExecutionGuid,
+                                               activationWorkloadExecutionEOLEventGuid,
                                                LabelsAndEventClasses::ARMNN_PROFILING_EOL_EVENT_CLASS,
                                                readableData,
                                                offset);
+    BOOST_TEST_MESSAGE("ACTIVATION WORKLOAD EXECUTION END OF LIFE RELATIONSHIP OK");
 
     // Output workload execution
     // Output workload execution entity
-    VerifyTimelineEntityBinaryPacketData(EmptyOptional(), readableData, offset);
+    ProfilingGuid outputWorkloadExecutionGuid = VerifyTimelineEntityBinaryPacketData(
+        EmptyOptional(), readableData, offset);
+    BOOST_TEST_MESSAGE("OUTPUT WORKLOAD EXECUTION ENTITY OK");
 
     // Entity - Type relationship
     VerifyTimelineRelationshipBinaryPacketData(ProfilingRelationshipType::LabelLink,
                                                EmptyOptional(),
-                                               EmptyOptional(),
+                                               outputWorkloadExecutionGuid,
                                                LabelsAndEventClasses::WORKLOAD_EXECUTION_GUID,
                                                LabelsAndEventClasses::TYPE_GUID,
                                                readableData,
                                                offset);
+    BOOST_TEST_MESSAGE("OUTPUT WORKLOAD EXECUTION TYPE RELATIONSHIP OK");
 
     // Inference - Workload execution relationship
     VerifyTimelineRelationshipBinaryPacketData(ProfilingRelationshipType::RetentionLink,
                                                EmptyOptional(),
-                                               EmptyOptional(),
-                                               EmptyOptional(),
-                                               EmptyOptional(),
+                                               inferenceGuid,
+                                               outputWorkloadExecutionGuid,
+                                               LabelsAndEventClasses::CHILD_GUID,
                                                readableData,
                                                offset);
+    BOOST_TEST_MESSAGE("INFERENCE - OUTPUT WORKLOAD EXECUTION CHILD RELATIONSHIP OK");
 
     // Workload - Workload execution relationship
     VerifyTimelineRelationshipBinaryPacketData(ProfilingRelationshipType::RetentionLink,
                                                EmptyOptional(),
-                                               EmptyOptional(),
-                                               EmptyOptional(),
-                                               EmptyOptional(),
+                                               outputWorkloadGuid,
+                                               outputWorkloadExecutionGuid,
+                                               LabelsAndEventClasses::EXECUTION_OF_GUID,
                                                readableData,
                                                offset);
+    BOOST_TEST_MESSAGE("OUTPUT WORKLOAD - OUTPUT WORKLOAD EXECUTION EXECUTION_OF RELATIONSHIP OK");
 
     // Start Output workload execution life
     // Event packet - timeline, threadId, eventGuid
-    VerifyTimelineEventBinaryPacket(EmptyOptional(), EmptyOptional(), EmptyOptional(), readableData, offset);
+    ProfilingGuid outputWorkloadExecutionSOLEventGuid = VerifyTimelineEventBinaryPacket(
+        EmptyOptional(), EmptyOptional(), EmptyOptional(), readableData, offset);
+    BOOST_TEST_MESSAGE("OUTPUT WORKLOAD EXECUTION START OF LIFE EVENT OK");
 
     // Output workload execution - event relationship
     VerifyTimelineRelationshipBinaryPacketData(ProfilingRelationshipType::ExecutionLink,
                                                EmptyOptional(),
-                                               EmptyOptional(),
-                                               EmptyOptional(),
+                                               outputWorkloadExecutionGuid,
+                                               outputWorkloadExecutionSOLEventGuid,
                                                LabelsAndEventClasses::ARMNN_PROFILING_SOL_EVENT_CLASS,
                                                readableData,
                                                offset);
+    BOOST_TEST_MESSAGE("OUTPUT WORKLOAD EXECUTION - START OF LIFE EVENT RELATIONSHIP OK");
 
     // End of Normalize workload execution life
     // Event packet - timeline, threadId, eventGuid
-    VerifyTimelineEventBinaryPacket(EmptyOptional(), EmptyOptional(), EmptyOptional(), readableData, offset);
+    ProfilingGuid outputWorkloadExecutionEOLEventGuid = VerifyTimelineEventBinaryPacket(
+        EmptyOptional(), EmptyOptional(), EmptyOptional(), readableData, offset);
+    BOOST_TEST_MESSAGE("OUTPUT WORKLOAD EXECUTION END OF LIFE EVENT OK");
 
     // Output workload execution - event relationship
     VerifyTimelineRelationshipBinaryPacketData(ProfilingRelationshipType::ExecutionLink,
                                                EmptyOptional(),
-                                               EmptyOptional(),
-                                               EmptyOptional(),
+                                               outputWorkloadExecutionGuid,
+                                               outputWorkloadExecutionEOLEventGuid,
                                                LabelsAndEventClasses::ARMNN_PROFILING_EOL_EVENT_CLASS,
                                                readableData,
                                                offset);
+    BOOST_TEST_MESSAGE("OUTPUT WORKLOAD EXECUTION - END OF LIFE EVENT RELATIONSHIP OK");
 
     // End of Inference life
     // Event packet - timeline, threadId, eventGuid
-    VerifyTimelineEventBinaryPacket(EmptyOptional(), EmptyOptional(), EmptyOptional(), readableData, offset);
+    ProfilingGuid inferenceEOLEventGuid = VerifyTimelineEventBinaryPacket(
+        EmptyOptional(), EmptyOptional(), EmptyOptional(), readableData, offset);
+    BOOST_TEST_MESSAGE("INFERENCE END OF LIFE EVENT OK");
 
     // Inference - event relationship
     VerifyTimelineRelationshipBinaryPacketData(ProfilingRelationshipType::ExecutionLink,
                                                EmptyOptional(),
-                                               EmptyOptional(),
-                                               EmptyOptional(),
+                                               inferenceGuid,
+                                               inferenceEOLEventGuid,
                                                LabelsAndEventClasses::ARMNN_PROFILING_EOL_EVENT_CLASS,
                                                readableData,
                                                offset);
+    BOOST_TEST_MESSAGE("INFERENCE - END OF LIFE EVENT RELATIONSHIP OK");
 
     bufferManager.MarkRead(inferenceReadableBuffer);
 }
+
+bool HasSuitableBackendRegistered()
+{
+    if (BackendRegistryInstance().IsBackendRegistered(GetComputeDeviceAsCString(armnn::Compute::CpuRef)))
+    {
+        return true;
+    }
+    if (BackendRegistryInstance().IsBackendRegistered(GetComputeDeviceAsCString(armnn::Compute::CpuAcc)))
+    {
+        return true;
+    }
+    if (BackendRegistryInstance().IsBackendRegistered(GetComputeDeviceAsCString(armnn::Compute::GpuAcc)))
+    {
+        return true;
+    }
+    return false;
+}
+
+bool CompareOutput(std::vector<std::string> output, std::vector<std::string> expectedOutput)
+{
+    if (output.size() != expectedOutput.size())
+    {
+        std::cerr << "output has [" << output.size() << "] lines, expected was ["
+                  << expectedOutput.size() << "] lines" << std::endl;
+        std::cerr << std::endl << "actual" << std::endl << std::endl;
+        for (auto line : output)
+        {
+            std::cerr << line << std::endl;
+        }
+        std::cerr << std::endl << "expected" << std::endl << std::endl;
+        for (auto line : expectedOutput)
+        {
+            std::cerr << line << std::endl;
+        }
+        return false;
+    }
+    bool bRet = true;
+    for (unsigned long i = 0; i < output.size(); ++i)
+    {
+        if (output[i] != expectedOutput[i])
+        {
+            bRet = false;
+            std::cerr << i << ": actual [" << output[i] << "] expected [" << expectedOutput[i] << "]" << std::endl;
+        }
+    }
+    return bRet;
+}
diff --git a/src/profiling/test/ProfilingTestUtils.hpp b/src/profiling/test/ProfilingTestUtils.hpp
index 2e7daab..a9a6921 100644
--- a/src/profiling/test/ProfilingTestUtils.hpp
+++ b/src/profiling/test/ProfilingTestUtils.hpp
@@ -1,5 +1,5 @@
 //
-// Copyright © 2019 Arm Ltd. All rights reserved.
+// Copyright © 2019 Arm Ltd and Contributors. All rights reserved.
 // SPDX-License-Identifier: MIT
 //
 
@@ -27,10 +27,10 @@
                                 unsigned int& offset,
                                 uint32_t packetDataLength);
 
-void VerifyTimelineLabelBinaryPacketData(Optional<ProfilingGuid> guid,
-                                         const std::string& label,
-                                         const unsigned char* readableData,
-                                         unsigned int& offset);
+ProfilingGuid VerifyTimelineLabelBinaryPacketData(Optional<ProfilingGuid> guid,
+                                                  const std::string& label,
+                                                  const unsigned char* readableData,
+                                                  unsigned int& offset);
 
 void VerifyTimelineEventClassBinaryPacketData(ProfilingGuid guid,
                                               ProfilingGuid nameGuid,
@@ -45,18 +45,24 @@
                                                 const unsigned char* readableData,
                                                 unsigned int& offset);
 
-void VerifyTimelineEntityBinaryPacketData(Optional<ProfilingGuid> guid,
-                                          const unsigned char* readableData,
-                                          unsigned int& offset);
+ProfilingGuid VerifyTimelineEntityBinaryPacketData(Optional<ProfilingGuid> guid,
+                                                   const unsigned char* readableData,
+                                                   unsigned int& offset);
 
-void VerifyTimelineEventBinaryPacket(Optional<uint64_t> timestamp,
-                                     Optional<std::thread::id> threadId,
-                                     Optional<ProfilingGuid> eventGuid,
-                                     const unsigned char* readableData,
-                                     unsigned int& offset);
+ProfilingGuid VerifyTimelineEventBinaryPacket(Optional<uint64_t> timestamp,
+                                              Optional<std::thread::id> threadId,
+                                              Optional<ProfilingGuid> eventGuid,
+                                              const unsigned char* readableData,
+                                              unsigned int& offset);
 
 void VerifyPostOptimisationStructureTestImpl(armnn::BackendId backendId);
 
+// returns true if a CpuRef, CpuAcc or GpuAcc
+// backend is registered
+bool HasSuitableBackendRegistered();
+
+bool CompareOutput(std::vector<std::string> output, std::vector<std::string> expectedOutput);
+
 namespace armnn
 {
 
diff --git a/src/profiling/test/ProfilingTests.cpp b/src/profiling/test/ProfilingTests.cpp
index e3a49e4..bc16bb9 100644
--- a/src/profiling/test/ProfilingTests.cpp
+++ b/src/profiling/test/ProfilingTests.cpp
@@ -1,5 +1,5 @@
 //
-// Copyright © 2017 Arm Ltd. All rights reserved.
+// Copyright © 2019 Arm Ltd and Contributors. All rights reserved.
 // SPDX-License-Identifier: MIT
 //
 
@@ -141,10 +141,12 @@
     SendCounterPacket sendCounterPacket(mockBuffer);
     SendThread sendThread(profilingStateMachine, mockBuffer, sendCounterPacket);
     SendTimelinePacket sendTimelinePacket(mockBuffer);
+    MockProfilingServiceStatus mockProfilingServiceStatus;
 
     ConnectionAcknowledgedCommandHandler connectionAcknowledgedCommandHandler(0, 1, 4194304, counterDirectory,
                                                                               sendCounterPacket, sendTimelinePacket,
-                                                                              profilingStateMachine);
+                                                                              profilingStateMachine,
+                                                                              mockProfilingServiceStatus);
     CommandHandlerRegistry commandHandlerRegistry;
 
     commandHandlerRegistry.RegisterFunctor(&connectionAcknowledgedCommandHandler);
@@ -2043,9 +2045,16 @@
     SendCounterPacket sendCounterPacket(mockBuffer);
     SendThread sendThread(profilingState, mockBuffer, sendCounterPacket);
     SendTimelinePacket sendTimelinePacket(mockBuffer);
+    MockProfilingServiceStatus mockProfilingServiceStatus;
 
-    ConnectionAcknowledgedCommandHandler commandHandler(packetFamilyId, connectionPacketId, version, counterDirectory,
-                                                        sendCounterPacket, sendTimelinePacket, profilingState);
+    ConnectionAcknowledgedCommandHandler commandHandler(packetFamilyId,
+                                                        connectionPacketId,
+                                                        version,
+                                                        counterDirectory,
+                                                        sendCounterPacket,
+                                                        sendTimelinePacket,
+                                                        profilingState,
+                                                        mockProfilingServiceStatus);
 
     // command handler received packet on ProfilingState::Uninitialised
     BOOST_CHECK_THROW(commandHandler(packetA), armnn::Exception);
@@ -2070,9 +2079,14 @@
     Packet packetB(differentPacketId, dataLength1, uniqueData1);
     profilingState.TransitionToState(ProfilingState::NotConnected);
     profilingState.TransitionToState(ProfilingState::WaitingForAck);
-    ConnectionAcknowledgedCommandHandler differentCommandHandler(packetFamilyId, differentPacketId, version,
-                                                                 counterDirectory, sendCounterPacket,
-                                                                 sendTimelinePacket, profilingState);
+    ConnectionAcknowledgedCommandHandler differentCommandHandler(packetFamilyId,
+                                                                 differentPacketId,
+                                                                 version,
+                                                                 counterDirectory,
+                                                                 sendCounterPacket,
+                                                                 sendTimelinePacket,
+                                                                 profilingState,
+                                                                 mockProfilingServiceStatus);
     BOOST_CHECK_THROW(differentCommandHandler(packetB), armnn::Exception);
 }
 
@@ -2439,7 +2453,7 @@
     // Timeline message directory packet
     BOOST_TEST(((header2Word0 >> 26) & 0x0000003F) == 1); // packet family
     BOOST_TEST(((header2Word0 >> 16) & 0x000003FF) == 0); // packet id
-    BOOST_TEST(header2Word1 == 419);                      // data length
+    BOOST_TEST(header2Word1 == 443);                      // data length
 }
 
 BOOST_AUTO_TEST_CASE(RequestCounterDirectoryCommandHandlerTest2)
@@ -2524,7 +2538,7 @@
     // Timeline message directory packet
     BOOST_TEST(((header2Word0 >> 26) & 0x0000003F) == 1); // packet family
     BOOST_TEST(((header2Word0 >> 16) & 0x000003FF) == 0); // packet id
-    BOOST_TEST(header2Word1 == 419);                      // data length
+    BOOST_TEST(header2Word1 == 443);                      // data length
 }
 
 BOOST_AUTO_TEST_CASE(CheckProfilingServiceGoodConnectionAcknowledgedPacket)
@@ -2635,9 +2649,9 @@
     mockProfilingConnection->WritePacket(std::move(requestCounterDirectoryPacket));
 
     // Expecting one CounterDirectory Packet of length 652
-    // and one TimelineMessageDirectory packet of length 427
+    // and one TimelineMessageDirectory packet of length 451
     BOOST_CHECK(helper.WaitForPacketsSent(mockProfilingConnection, PacketType::CounterDirectory, 652) == 1);
-    BOOST_CHECK(helper.WaitForPacketsSent(mockProfilingConnection, PacketType::TimelineMessageDirectory, 427) == 1);
+    BOOST_CHECK(helper.WaitForPacketsSent(mockProfilingConnection, PacketType::TimelineMessageDirectory, 451) == 1);
 
     // The Request Counter Directory Command Handler should not have updated the profiling state
     BOOST_CHECK(profilingService.GetCurrentState() == ProfilingState::Active);
diff --git a/src/profiling/test/ProfilingTests.hpp b/src/profiling/test/ProfilingTests.hpp
index b41f2dd..c350fd2 100644
--- a/src/profiling/test/ProfilingTests.hpp
+++ b/src/profiling/test/ProfilingTests.hpp
@@ -1,5 +1,5 @@
 //
-// Copyright © 2019 Arm Ltd. All rights reserved.
+// Copyright © 2019 Arm Ltd and Contributors. All rights reserved.
 // SPDX-License-Identifier: MIT
 //
 
diff --git a/src/profiling/test/SendTimelinePacketTests.cpp b/src/profiling/test/SendTimelinePacketTests.cpp
index 05a6db8..4b45cfe 100644
--- a/src/profiling/test/SendTimelinePacketTests.cpp
+++ b/src/profiling/test/SendTimelinePacketTests.cpp
@@ -1,5 +1,5 @@
 //
-// Copyright © 2019 Arm Ltd. All rights reserved.
+// Copyright © 2019 Arm Ltd and Contributors. All rights reserved.
 // SPDX-License-Identifier: MIT
 //
 
@@ -54,7 +54,7 @@
     uint32_t sequenceNumbered = (packetHeaderWord1 >> 24) & 0x00000001;
     uint32_t dataLength       = (packetHeaderWord1 >>  0) & 0x00FFFFFF;
     BOOST_CHECK(sequenceNumbered ==  0);
-    BOOST_CHECK(dataLength       == 419);
+    BOOST_CHECK(dataLength       == 443);
 
     offset += uint32_t_size;
     uint8_t readStreamVersion = ReadUint8(packetBuffer, offset);
@@ -98,26 +98,30 @@
     BOOST_CHECK(swTraceMessage.m_Id == 2);
     BOOST_CHECK(swTraceMessage.m_Name == "declareEventClass");
     BOOST_CHECK(swTraceMessage.m_UiName == "declare event class");
-    BOOST_CHECK(swTraceMessage.m_ArgTypes.size() == 1);
+    BOOST_CHECK(swTraceMessage.m_ArgTypes.size() == 2);
     BOOST_CHECK(swTraceMessage.m_ArgTypes[0] == 'p');
-    BOOST_CHECK(swTraceMessage.m_ArgNames.size() == 1);
+    BOOST_CHECK(swTraceMessage.m_ArgTypes[1] == 'p');
+    BOOST_CHECK(swTraceMessage.m_ArgNames.size() == 2);
     BOOST_CHECK(swTraceMessage.m_ArgNames[0] == "guid");
+    BOOST_CHECK(swTraceMessage.m_ArgNames[1] == "nameGuid");
 
     swTraceMessage = ReadSwTraceMessage(packetBuffer->GetReadableData(), offset);
 
     BOOST_CHECK(swTraceMessage.m_Id == 3);
     BOOST_CHECK(swTraceMessage.m_Name == "declareRelationship");
     BOOST_CHECK(swTraceMessage.m_UiName == "declare relationship");
-    BOOST_CHECK(swTraceMessage.m_ArgTypes.size() == 4);
+    BOOST_CHECK(swTraceMessage.m_ArgTypes.size() == 5);
     BOOST_CHECK(swTraceMessage.m_ArgTypes[0] == 'I');
     BOOST_CHECK(swTraceMessage.m_ArgTypes[1] == 'p');
     BOOST_CHECK(swTraceMessage.m_ArgTypes[2] == 'p');
     BOOST_CHECK(swTraceMessage.m_ArgTypes[3] == 'p');
-    BOOST_CHECK(swTraceMessage.m_ArgNames.size() == 4);
+    BOOST_CHECK(swTraceMessage.m_ArgTypes[4] == 'p');
+    BOOST_CHECK(swTraceMessage.m_ArgNames.size() == 5);
     BOOST_CHECK(swTraceMessage.m_ArgNames[0] == "relationshipType");
     BOOST_CHECK(swTraceMessage.m_ArgNames[1] == "relationshipGuid");
     BOOST_CHECK(swTraceMessage.m_ArgNames[2] == "headGuid");
     BOOST_CHECK(swTraceMessage.m_ArgNames[3] == "tailGuid");
+    BOOST_CHECK(swTraceMessage.m_ArgNames[4] == "attributeGuid");
 
     swTraceMessage = ReadSwTraceMessage(packetBuffer->GetReadableData(), offset);
 
@@ -403,7 +407,7 @@
     const uint64_t eventClassBinaryPacketNameGuid = 8845u;
     BOOST_CHECK_THROW(sendTimelinePacket->SendTimelineEventClassBinaryPacket(
                       eventClassBinaryPacketProfilingGuid, eventClassBinaryPacketNameGuid),
-                      armnn::RuntimeException);
+                      armnn::profiling::BufferExhaustion);
 }
 
 BOOST_AUTO_TEST_CASE(GetGuidsFromProfilingService)
diff --git a/src/profiling/test/TestTimelinePacketHandler.cpp b/src/profiling/test/TestTimelinePacketHandler.cpp
index 93fb4b4..ccb806b 100644
--- a/src/profiling/test/TestTimelinePacketHandler.cpp
+++ b/src/profiling/test/TestTimelinePacketHandler.cpp
@@ -1,10 +1,11 @@
 //
-// Copyright © 2020 Arm Ltd. All rights reserved.
+// Copyright © 2020 Arm Ltd and Contributors. All rights reserved.
 // SPDX-License-Identifier: MIT
 //
 
 #include "TestTimelinePacketHandler.hpp"
 #include "IProfilingConnection.hpp"
+#include <LabelsAndEventClasses.hpp>
 
 #include <armnn/utility/IgnoreUnused.hpp>
 
@@ -98,19 +99,13 @@
 ITimelineDecoder::TimelineStatus TimelineMessageDecoder::CreateEventClass(
     const ITimelineDecoder::EventClass& eventClass)
 {
-    // for the moment terminate the run here so we can get this code
-    // onto master prior to a major re-organisation
-    if (m_PacketHandler != nullptr)
-    {
-        m_PacketHandler->SetInferenceComplete();
-    }
-    IgnoreUnused(eventClass);
+    m_TimelineModel.AddEventClass(eventClass);
     return ITimelineDecoder::TimelineStatus::TimelineStatus_Success;
 }
 
 ITimelineDecoder::TimelineStatus TimelineMessageDecoder::CreateEvent(const ITimelineDecoder::Event& event)
 {
-    IgnoreUnused(event);
+    m_TimelineModel.AddEvent(event);
     return ITimelineDecoder::TimelineStatus::TimelineStatus_Success;
 }
 
@@ -124,6 +119,20 @@
     const ITimelineDecoder::Relationship& relationship)
 {
     m_TimelineModel.AddRelationship(relationship);
+    // check to see if this is an execution link to an inference of event class end of life
+    // if so the inference has completed so send out a notification...
+    if (relationship.m_RelationshipType == RelationshipType::ExecutionLink &&
+        m_TimelineModel.IsInferenceGuid(relationship.m_HeadGuid))
+    {
+        ProfilingStaticGuid attributeGuid(relationship.m_AttributeGuid);
+        if (attributeGuid == armnn::profiling::LabelsAndEventClasses::ARMNN_PROFILING_EOL_EVENT_CLASS)
+        {
+            if (m_PacketHandler != nullptr)
+            {
+                m_PacketHandler->SetInferenceComplete();
+            }
+        }
+    }
     return ITimelineDecoder::TimelineStatus::TimelineStatus_Success;
 }
 
diff --git a/src/profiling/test/TestTimelinePacketHandler.hpp b/src/profiling/test/TestTimelinePacketHandler.hpp
index 6cc6a0c..08239fc 100644
--- a/src/profiling/test/TestTimelinePacketHandler.hpp
+++ b/src/profiling/test/TestTimelinePacketHandler.hpp
@@ -1,5 +1,5 @@
 //
-// Copyright © 2020 Arm Ltd. All rights reserved.
+// Copyright © 2020 Arm Ltd and Contributors. All rights reserved.
 // SPDX-License-Identifier: MIT
 //
 
diff --git a/src/profiling/test/TimelineModel.cpp b/src/profiling/test/TimelineModel.cpp
index 73aa0c5..d16a300 100644
--- a/src/profiling/test/TimelineModel.cpp
+++ b/src/profiling/test/TimelineModel.cpp
@@ -1,9 +1,12 @@
 //
-// Copyright © 2020 Arm Ltd. All rights reserved.
+// Copyright © 2020 Arm Ltd and Contributors. All rights reserved.
 // SPDX-License-Identifier: MIT
 //
 
 #include "TimelineModel.hpp"
+#include <LabelsAndEventClasses.hpp>
+
+#include <algorithm>
 
 namespace armnn
 {
@@ -16,12 +19,25 @@
     m_LabelMap.emplace(label.m_Guid, label);
 }
 
+std::string* TimelineModel::FindLabel(uint64_t guid)
+{
+    auto iter = m_LabelMap.find(guid);
+    if (iter != m_LabelMap.end())
+    {
+        return &iter->second.m_Name;
+    }
+    else
+    {
+        return nullptr;
+    }
+}
+
 void TimelineModel::AddEntity(uint64_t guid)
 {
     m_Entities.emplace(guid, guid);
 }
 
-Entity* TimelineModel::findEntity(uint64_t id)
+Entity* TimelineModel::FindEntity(uint64_t id)
 {
     auto iter = m_Entities.find(id);
     if (iter != m_Entities.end())
@@ -37,9 +53,212 @@
 void TimelineModel::AddRelationship(const ITimelineDecoder::Relationship& relationship)
 {
     m_Relationships.emplace(relationship.m_Guid, relationship);
+    if (relationship.m_RelationshipType == ITimelineDecoder::RelationshipType::LabelLink)
+    {
+        HandleLabelLink(relationship);
+    }
+    else if (relationship.m_RelationshipType == ITimelineDecoder::RelationshipType::RetentionLink)
+    {
+        // Take care of the special case of a connection between layers in ArmNN
+        // modelled by a retention link between two layer entities with an attribute GUID
+        // of connection
+        if (relationship.m_AttributeGuid == armnn::profiling::LabelsAndEventClasses::CONNECTION_GUID)
+        {
+            HandleConnection(relationship);
+        }
+        else if (relationship.m_AttributeGuid == armnn::profiling::LabelsAndEventClasses::CHILD_GUID)
+        {
+            HandleChild(relationship);
+        }
+        else if (relationship.m_AttributeGuid == armnn::profiling::LabelsAndEventClasses::EXECUTION_OF_GUID)
+        {
+            HandleExecutionOf(relationship);
+        }
+        else
+        {
+            // report unknown relationship type
+            std::stringstream ss;
+            ss << "Encountered a RetentionLink of unknown type [" << relationship.m_AttributeGuid << "]";
+            m_Errors.push_back(armnnProfiling::ProfilingException(ss.str()));
+        }
+    }
+    else if (relationship.m_RelationshipType == ITimelineDecoder::RelationshipType::ExecutionLink)
+    {
+        HandleExecutionLink(relationship);
+    }
 }
 
-ModelRelationship* TimelineModel::findRelationship(uint64_t id)
+void TimelineModel::HandleLabelLink(const ITimelineDecoder::Relationship& relationship)
+{
+    Entity* entity = FindEntity(relationship.m_HeadGuid);
+    // we have a label attribute of an entity
+    std::string* value = nullptr;
+    std::string* attribute = nullptr;
+    value = FindLabel(relationship.m_TailGuid);
+    if (value == nullptr)
+    {
+        //report an error
+        std::stringstream ss;
+        ss << "could not find label link [" << relationship.m_Guid <<
+           "] value [" << relationship.m_TailGuid << "]";
+        m_Errors.push_back(armnnProfiling::ProfilingException(ss.str()));
+    }
+    if (relationship.m_AttributeGuid != 0)
+    {
+        attribute = FindLabel(relationship.m_AttributeGuid);
+        if (attribute == nullptr)
+        {
+            //report an error
+            std::stringstream ss;
+            ss << "could not find label link [" << relationship.m_Guid <<
+               "] attribute [" << relationship.m_AttributeGuid << "]";
+            m_Errors.push_back(armnnProfiling::ProfilingException(ss.str()));
+        }
+    }
+    else
+    {
+        //report an error
+        std::stringstream ss;
+        ss << "label link [" << relationship.m_Guid << "] has a zero attribute guid";
+        m_Errors.push_back(armnnProfiling::ProfilingException(ss.str()));
+    }
+    if (entity != nullptr && attribute != nullptr && value != nullptr)
+    {
+        entity->AddAttribute(*attribute, *value);
+        // if the attribute is 'type' and the value is 'inference'
+        // we need to cache the entity guid as an inference
+        if (armnn::profiling::LabelsAndEventClasses::TYPE_LABEL.compare(*attribute) == 0 &&
+            armnn::profiling::LabelsAndEventClasses::INFERENCE.compare(*value) == 0)
+        {
+            m_InferenceGuids.push_back(relationship.m_HeadGuid);
+        }
+    }
+
+    if (entity == nullptr)
+    {
+        //report an error
+        std::stringstream ss;
+        ss << "could not find label link [" << relationship.m_Guid <<
+           "] entity [" << relationship.m_HeadGuid << "] ";
+        if (value != nullptr)
+        {
+            ss << "value [" << *value << "] ";
+        }
+        if (attribute != nullptr)
+        {
+            ss << "attribute [" << *attribute << "] ";
+        }
+        m_Errors.push_back(armnnProfiling::ProfilingException(ss.str()));
+    }
+}
+
+void TimelineModel::HandleConnection(const ITimelineDecoder::Relationship& relationship)
+{
+    Entity* outputLayer = FindEntity(relationship.m_HeadGuid);
+    if (outputLayer == nullptr)
+    {
+        std::stringstream ss;
+        ss << "could not find output entity [" << relationship.m_HeadGuid << "]";
+        ss << " of connection [" << relationship.m_Guid << "]";
+        m_Errors.push_back(armnnProfiling::ProfilingException(ss.str()));
+        return;
+    }
+    Entity* inputLayer = FindEntity(relationship.m_TailGuid);
+    if (inputLayer == nullptr)
+    {
+        std::stringstream ss;
+        ss << "could not find input entity [" << relationship.m_TailGuid << "]";
+        ss << " of connection [" << relationship.m_Guid << "]";
+        m_Errors.push_back(armnnProfiling::ProfilingException(ss.str()));
+        return;
+    }
+    Connection connection(relationship.m_Guid, outputLayer, inputLayer);
+    outputLayer->AddConnection(connection);
+}
+
+void TimelineModel::HandleChild(const ITimelineDecoder::Relationship& relationship)
+{
+    Entity* parentEntity = FindEntity(relationship.m_HeadGuid);
+    if (parentEntity == nullptr)
+    {
+        std::stringstream ss;
+        ss << "could not find parent entity [" << relationship.m_HeadGuid << "]";
+        ss << " of child relationship [" << relationship.m_Guid << "]";
+        m_Errors.push_back(armnnProfiling::ProfilingException(ss.str()));
+        return;
+    }
+    Entity* childEntity = FindEntity(relationship.m_TailGuid);
+    if (childEntity == nullptr)
+    {
+        std::stringstream ss;
+        ss << "could not find child entity [" << relationship.m_TailGuid << "]";
+        ss << " of child relationship [" << relationship.m_Guid << "]";
+        m_Errors.push_back(armnnProfiling::ProfilingException(ss.str()));
+        return;
+    }
+    parentEntity->AddChild(childEntity);
+}
+
+void TimelineModel::HandleExecutionOf(const ITimelineDecoder::Relationship& relationship)
+{
+    Entity* parentEntity = FindEntity(relationship.m_HeadGuid);
+    if (parentEntity == nullptr)
+    {
+        std::stringstream ss;
+        ss << "could not find parent entity [" << relationship.m_HeadGuid << "]";
+        ss << " of execution relationship [" << relationship.m_Guid << "]";
+        m_Errors.push_back(armnnProfiling::ProfilingException(ss.str()));
+        return;
+    }
+    Entity* executedEntity = FindEntity(relationship.m_TailGuid);
+    if (executedEntity == nullptr)
+    {
+        std::stringstream ss;
+        ss << "could not find executed entity [" << relationship.m_TailGuid << "]";
+        ss << " of execution relationship [" << relationship.m_Guid << "]";
+        m_Errors.push_back(armnnProfiling::ProfilingException(ss.str()));
+        return;
+    }
+    parentEntity->AddExecution(executedEntity);
+}
+
+void TimelineModel::HandleExecutionLink(const ITimelineDecoder::Relationship& relationship)
+{
+    // entityGuid,
+    Entity* parentEntity = FindEntity(relationship.m_HeadGuid);
+    if (parentEntity == nullptr)
+    {
+        std::stringstream ss;
+        ss << "could not find entity [" << relationship.m_HeadGuid << "]";
+        ss << " of ExecutionLink [" << relationship.m_Guid << "]";
+        m_Errors.push_back(armnnProfiling::ProfilingException(ss.str()));
+        return;
+    }
+    // eventGuid,
+    EventObj* eventObj = FindEvent(relationship.m_TailGuid);
+    if (eventObj == nullptr)
+    {
+        std::stringstream ss;
+        ss << "could not find event [" << relationship.m_TailGuid << "]";
+        ss << " of ExecutionLink [" << relationship.m_Guid << "]";
+        m_Errors.push_back(armnnProfiling::ProfilingException(ss.str()));
+        return;
+    }
+    // eventClassGuid
+    EventClassObj* eventClassObj = FindEventClass(relationship.m_AttributeGuid);
+    if (eventClassObj == nullptr)
+    {
+        std::stringstream ss;
+        ss << "could not find event class [" << relationship.m_TailGuid << "]";
+        ss << " of ExecutionLink [" << relationship.m_Guid << "]";
+        m_Errors.push_back(armnnProfiling::ProfilingException(ss.str()));
+        return;
+    }
+    eventObj->SetEventClass(eventClassObj);
+    parentEntity->AddEvent(eventObj);
+}
+
+ModelRelationship* TimelineModel::FindRelationship(uint64_t id)
 {
     auto iter = m_Relationships.find(id);
     if (iter != m_Relationships.end())
@@ -52,6 +271,128 @@
     }
 }
 
+bool TimelineModel::IsInferenceGuid(uint64_t guid) const
+{
+    auto it = std::find(m_InferenceGuids.begin(), m_InferenceGuids.end(), guid);
+    return it != m_InferenceGuids.end();
+}
+
+void TimelineModel::AddEventClass(const ITimelineDecoder::EventClass& eventClass)
+{
+    std::string* eventClassName = FindLabel(eventClass.m_NameGuid);
+    if (eventClassName != nullptr)
+    {
+        EventClassObj eventClassObj(eventClass.m_Guid, *eventClassName);
+        m_EventClasses.emplace(eventClassObj.GetGuid(), eventClassObj);
+    }
+    else
+    {
+        std::stringstream ss;
+        ss << "could not find name [" << eventClass.m_NameGuid << "]";
+        ss << " of of event class  [" << eventClass.m_Guid << "]";
+        m_Errors.push_back(armnnProfiling::ProfilingException(ss.str()));
+    }
+}
+
+EventClassObj* TimelineModel::FindEventClass(uint64_t id)
+{
+    auto iter = m_EventClasses.find(id);
+    if (iter != m_EventClasses.end())
+    {
+        return &(iter->second);
+    }
+    else
+    {
+        return nullptr;
+    }
+}
+
+void TimelineModel::AddEvent(const ITimelineDecoder::Event& event)
+{
+    EventObj evt(event.m_Guid, event.m_TimeStamp, event.m_ThreadId);
+    m_Events.emplace(event.m_Guid, evt);
+}
+
+EventObj* TimelineModel::FindEvent(uint64_t id)
+{
+    auto iter = m_Events.find(id);
+    if (iter != m_Events.end())
+    {
+        return &(iter->second);
+    }
+    else
+    {
+        return nullptr;
+    }
+}
+
+std::vector<std::string> GetModelDescription(const TimelineModel& model)
+{
+    std::vector<std::string> desc;
+    for (auto& entry : model.GetEntities())
+    {
+        auto& entity = entry.second;
+        desc.push_back(GetEntityDescription(entity));
+        for (auto& connection : entity.GetConnections())
+        {
+            desc.push_back(GetConnectionDescription(connection));
+        }
+        for (auto child : entity.GetChildren())
+        {
+            desc.push_back(GetChildDescription(child));
+        }
+        for (auto execution : entity.GetExecutions())
+        {
+            desc.push_back(GetExecutionDescription(execution));
+        }
+        for (auto event : entity.GetEvents())
+        {
+            desc.push_back(GetEventDescription(event));
+        }
+    }
+    return desc;
+}
+
+std::string GetEntityDescription(const Entity& entity)
+{
+    std::stringstream ss;
+    ss << "Entity [" << entity.GetGuid() << "]";
+    for (auto& attributeEntry : entity.GetAttributes())
+    {
+        ss << " " << attributeEntry.second.first << " = " << attributeEntry.second.second;
+    }
+    return ss.str();
+}
+
+std::string GetChildDescription(Entity* entity)
+{
+    std::stringstream ss;
+    ss << "   child: " << GetEntityDescription(*entity);
+    return ss.str();
+}
+
+std::string GetConnectionDescription(const Connection& connection)
+{
+    std::stringstream ss;
+    ss << "   connection [" << connection.GetGuid() << "] from entity [";
+    ss << connection.GetHead()->GetGuid() << "] to entity [" << connection.GetTail()->GetGuid() << "]";
+    return ss.str();
+}
+
+std::string GetExecutionDescription(Entity* execution)
+{
+    std::stringstream ss;
+    ss << "   execution: " << GetEntityDescription(*execution);
+    return ss.str();
+}
+
+std::string GetEventDescription(EventObj* event)
+{
+    std::stringstream ss;
+    ss << "   event: [" << event->GetGuid() << "] class [" << event->GetEventClass() << "]";
+    return ss.str();
+}
+
 } // namespace profiling
 
 } // namespace armnn
\ No newline at end of file
diff --git a/src/profiling/test/TimelineModel.hpp b/src/profiling/test/TimelineModel.hpp
index 7b88d5f..a6d62ce 100644
--- a/src/profiling/test/TimelineModel.hpp
+++ b/src/profiling/test/TimelineModel.hpp
@@ -1,13 +1,15 @@
 //
-// Copyright © 2020 Arm Ltd. All rights reserved.
+// Copyright © 2020 Arm Ltd and Contributors. All rights reserved.
 // SPDX-License-Identifier: MIT
 //
 
 #pragma once
 
 #include <armnn/profiling/ITimelineDecoder.hpp>
+#include <common/include/ProfilingException.hpp>
 
 #include <map>
+#include <sstream>
 #include <vector>
 
 namespace armnn
@@ -18,11 +20,76 @@
 using LabelMap = std::map<uint64_t, ITimelineDecoder::Label>;
 using Attribute = std::pair<std::string, std::string>;
 using Attributes = std::map<std::string, Attribute>;
+class Entity;
+class Connection
+{
+public:
+    Connection(uint64_t guid, Entity* head, Entity* tail) :
+        m_Guid(guid), m_HeadEntity(head), m_TailEntity(tail)
+    {
+        if (head == nullptr)
+        {
+            std::stringstream ss;
+            ss << "connection [" << guid << "] head cannot be null";
+            throw armnnProfiling::ProfilingException(ss.str());
+        }
+        if (tail == nullptr)
+        {
+            std::stringstream ss;
+            ss << "connection [" << guid << "] tail cannot be null";
+            throw armnnProfiling::ProfilingException(ss.str());
+        }
+    }
+
+    uint64_t GetGuid() const {return m_Guid;}
+    const Entity* GetHead() const {return m_HeadEntity;}
+    const Entity* GetTail() const {return m_TailEntity;}
+private:
+    uint64_t m_Guid;
+    Entity* m_HeadEntity;
+    Entity* m_TailEntity;
+};
+class EventClassObj
+{
+public:
+    EventClassObj(uint64_t guid, const std::string& name) : m_Guid(guid), m_Name(name) {}
+    uint64_t GetGuid() const {return m_Guid;}
+    const std::string& GetName() const {return m_Name;}
+private:
+    uint64_t m_Guid;
+    std::string m_Name;
+};
+class EventObj
+{
+public:
+    EventObj(uint64_t guid, uint64_t timestamp, uint64_t threadId) :
+        m_Guid(guid), m_TimeStamp(timestamp), m_ThreadId(threadId) {}
+    uint64_t GetGuid() const {return m_Guid;}
+    uint64_t GetTimeStamp() const {return m_TimeStamp;}
+    uint64_t GetThreadId() const {return m_ThreadId;}
+    void SetEventClass(EventClassObj* evtClass) {m_EventClass = evtClass;}
+    std::string GetEventClass()
+    {
+        if (m_EventClass == nullptr)
+        {
+            return "";
+        }
+        else
+        {
+            return m_EventClass->GetName();
+        }
+    }
+private:
+    uint64_t m_Guid;
+    uint64_t m_TimeStamp;
+    uint64_t m_ThreadId;
+    EventClassObj* m_EventClass;
+};
 class Entity
 {
 public:
     Entity(uint64_t guid) : m_Guid(guid) {}
-    uint64_t GetGuid() {return m_Guid;}
+    uint64_t GetGuid() const {return m_Guid;}
     void AddChild(Entity* child)
     {
         if (child != nullptr)
@@ -35,10 +102,36 @@
         Attribute attr(type, value);
         m_Attributes.emplace(type, attr);
     }
+    void AddConnection(const Connection& connection)
+    {
+        m_Connections.push_back(connection);
+    }
+    void AddExecution(Entity* execution)
+    {
+        if (execution != nullptr)
+        {
+            m_Executions.push_back(execution);
+        }
+    }
+    void AddEvent(EventObj* event)
+    {
+        if (event != nullptr)
+        {
+            m_Events.push_back(event);
+        }
+    }
+    const Attributes& GetAttributes() const {return m_Attributes;}
+    const std::vector<Entity*>& GetChildren() const {return m_Children;}
+    const std::vector<Connection>& GetConnections() const {return m_Connections;}
+    const std::vector<Entity*>& GetExecutions() const {return m_Executions;}
+    const std::vector<EventObj*>& GetEvents() const {return m_Events;}
 private:
     uint64_t m_Guid;
     Attributes m_Attributes;
     std::vector<Entity*> m_Children;
+    std::vector<Connection> m_Connections;
+    std::vector<Entity*> m_Executions;
+    std::vector<EventObj*> m_Events;
 };
 using Entities = std::map<uint64_t, Entity>;
 struct ModelRelationship
@@ -48,20 +141,49 @@
     std::vector<Entity*> m_RelatedEntities;
 };
 using Relationships = std::map<uint64_t, ModelRelationship>;
+using EventClasses = std::map<uint64_t, EventClassObj>;
+using Events = std::map<uint64_t, EventObj>;
 class TimelineModel
 {
 public:
     void AddLabel(const ITimelineDecoder::Label& label);
+    std::string* FindLabel(uint64_t guid);
     void AddEntity(uint64_t guid);
-    Entity* findEntity(uint64_t id);
+    Entity* FindEntity(uint64_t id);
     void AddRelationship(const ITimelineDecoder::Relationship& relationship);
-    ModelRelationship* findRelationship(uint64_t id);
+    ModelRelationship* FindRelationship(uint64_t id);
+    const LabelMap& GetLabelMap() const {return m_LabelMap;}
+    const Entities& GetEntities() const {return m_Entities;}
+    const std::vector<armnnProfiling::ProfilingException>& GetErrors() const {return m_Errors;}
+    bool IsInferenceGuid(uint64_t guid) const;
+    void AddEventClass(const ITimelineDecoder::EventClass& eventClass);
+    const EventClasses& GetEventClasses() const {return m_EventClasses;}
+    EventClassObj* FindEventClass(uint64_t id);
+    void AddEvent(const ITimelineDecoder::Event& event);
+    EventObj* FindEvent(uint64_t id);
 private:
     LabelMap m_LabelMap;
     Entities m_Entities;
     Relationships m_Relationships;
+    std::vector<armnnProfiling::ProfilingException> m_Errors;
+    std::vector<uint64_t> m_InferenceGuids;
+    EventClasses m_EventClasses;
+    Events m_Events;
+
+    void HandleLabelLink(const ITimelineDecoder::Relationship& relationship);
+    void HandleConnection(const ITimelineDecoder::Relationship& relationship);
+    void HandleChild(const ITimelineDecoder::Relationship& relationship);
+    void HandleExecutionOf(const ITimelineDecoder::Relationship& relationship);
+    void HandleExecutionLink(const ITimelineDecoder::Relationship& relationship);
 };
 
+std::vector<std::string> GetModelDescription(const TimelineModel& model);
+std::string GetEntityDescription(const Entity& entity);
+std::string GetChildDescription(Entity* entity);
+std::string GetConnectionDescription(const Connection& connection);
+std::string GetExecutionDescription(Entity* execution);
+std::string GetEventDescription(EventObj* event);
+
 } // namespace profiling
 
 } // namespace armnn
\ No newline at end of file
diff --git a/src/profiling/test/TimelinePacketTests.cpp b/src/profiling/test/TimelinePacketTests.cpp
index 555ec67..96e9bf2 100644
--- a/src/profiling/test/TimelinePacketTests.cpp
+++ b/src/profiling/test/TimelinePacketTests.cpp
@@ -1,5 +1,5 @@
 //
-// Copyright © 2019 Arm Ltd. All rights reserved.
+// Copyright © 2019 Arm Ltd and Contributors. All rights reserved.
 // SPDX-License-Identifier: MIT
 //
 
@@ -461,7 +461,7 @@
                                                                        numberOfBytesWritten);
     BOOST_CHECK(result == TimelinePacketStatus::Ok);
 
-    BOOST_CHECK(numberOfBytesWritten == 427);
+    BOOST_CHECK(numberOfBytesWritten == 451);
 
     unsigned int uint8_t_size  = sizeof(uint8_t);
     unsigned int uint32_t_size = sizeof(uint32_t);
@@ -484,7 +484,7 @@
     uint32_t sequenceNumbered = (packetHeaderWord1 >> 24) & 0x00000001;
     uint32_t dataLength       = (packetHeaderWord1 >>  0) & 0x00FFFFFF;
     BOOST_CHECK(sequenceNumbered ==  0);
-    BOOST_CHECK(dataLength       == 419);
+    BOOST_CHECK(dataLength       == 443);
 
     // Check the stream header
     offset += uint32_t_size;
diff --git a/src/profiling/test/TimelineUtilityMethodsTests.cpp b/src/profiling/test/TimelineUtilityMethodsTests.cpp
index 815a3a0..720b8b4 100644
--- a/src/profiling/test/TimelineUtilityMethodsTests.cpp
+++ b/src/profiling/test/TimelineUtilityMethodsTests.cpp
@@ -1,5 +1,5 @@
 //
-// Copyright © 2019 Arm Ltd. All rights reserved.
+// Copyright © 2019 Arm Ltd and Contributors. All rights reserved.
 // SPDX-License-Identifier: MIT
 //
 
@@ -82,7 +82,7 @@
     auto readableBuffer = mockBufferManager.GetReadableBuffer();
     BOOST_CHECK(readableBuffer != nullptr);
     unsigned int size = readableBuffer->GetSize();
-    BOOST_TEST(size == 376);
+    BOOST_TEST(size == 432);
     const unsigned char* readableData = readableBuffer->GetReadableData();
     BOOST_CHECK(readableData != nullptr);
 
@@ -90,7 +90,7 @@
     unsigned int offset = 0;
 
     // Verify Header
-    VerifyTimelineHeaderBinary(readableData, offset, 368);
+    VerifyTimelineHeaderBinary(readableData, offset, 424);
 
     // First "well-known" label: NAME
     VerifyTimelineLabelBinaryPacketData(LabelsAndEventClasses::NAME_GUID,
@@ -116,6 +116,18 @@
                                         readableData,
                                         offset);
 
+    // Fifth "well-known" label: CHILD
+    VerifyTimelineLabelBinaryPacketData(LabelsAndEventClasses::CHILD_GUID,
+                                        LabelsAndEventClasses::CHILD_LABEL,
+                                        readableData,
+                                        offset);
+
+    // Sixth "well-known" label: EXECUTION_OF
+    VerifyTimelineLabelBinaryPacketData(LabelsAndEventClasses::EXECUTION_OF_GUID,
+                                        LabelsAndEventClasses::EXECUTION_OF_LABEL,
+                                        readableData,
+                                        offset);
+
     // Well-known types
     // Layer
     VerifyTimelineLabelBinaryPacketData(LabelsAndEventClasses::LAYER_GUID,