diff options
Diffstat (limited to 'src/profiling/test')
-rw-r--r-- | src/profiling/test/FileOnlyProfilingDecoratorTests.cpp | 58 | ||||
-rw-r--r-- | src/profiling/test/ProfilingMocks.hpp | 10 | ||||
-rw-r--r-- | src/profiling/test/ProfilingTestUtils.cpp | 467 | ||||
-rw-r--r-- | src/profiling/test/ProfilingTestUtils.hpp | 32 | ||||
-rw-r--r-- | src/profiling/test/ProfilingTests.cpp | 36 | ||||
-rw-r--r-- | src/profiling/test/ProfilingTests.hpp | 2 | ||||
-rw-r--r-- | src/profiling/test/SendTimelinePacketTests.cpp | 18 | ||||
-rw-r--r-- | src/profiling/test/TestTimelinePacketHandler.cpp | 27 | ||||
-rw-r--r-- | src/profiling/test/TestTimelinePacketHandler.hpp | 2 | ||||
-rw-r--r-- | src/profiling/test/TimelineModel.cpp | 347 | ||||
-rw-r--r-- | src/profiling/test/TimelineModel.hpp | 130 | ||||
-rw-r--r-- | src/profiling/test/TimelinePacketTests.cpp | 6 | ||||
-rw-r--r-- | src/profiling/test/TimelineUtilityMethodsTests.cpp | 18 |
13 files changed, 919 insertions, 234 deletions
diff --git a/src/profiling/test/FileOnlyProfilingDecoratorTests.cpp b/src/profiling/test/FileOnlyProfilingDecoratorTests.cpp index aa877a10e9..31c1c7a0c5 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 @@ BOOST_AUTO_TEST_CASE(TestFileOnlyProfiling) { // 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 @@ BOOST_AUTO_TEST_CASE(TestFileOnlyProfiling) 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 @@ BOOST_AUTO_TEST_CASE(TestFileOnlyProfiling) 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 28e410fb9a..fe8fbd7db9 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 @@ private: 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 20e1a9b446..758d959b02 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 @@ void VerifyTimelineHeaderBinary(const unsigned char* readableData, 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 @@ void VerifyTimelineLabelBinaryPacketData(Optional<ProfilingGuid> guid, // 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 VerifyTimelineEventClassBinaryPacketData(ProfilingGuid guid, } 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 @@ void VerifyTimelineRelationshipBinaryPacketData(ProfilingRelationshipType relati 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 @@ void VerifyTimelineRelationshipBinaryPacketData(ProfilingRelationshipType relati 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 @@ void VerifyTimelineRelationshipBinaryPacketData(ProfilingRelationshipType relati 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 @@ void VerifyTimelineRelationshipBinaryPacketData(ProfilingRelationshipType relati 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 @@ void VerifyTimelineEntityBinaryPacketData(Optional<ProfilingGuid> guid, } 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 @@ void VerifyTimelineEventBinaryPacket(Optional<uint64_t> timestamp, } offset += uint64_t_size; + + ProfilingGuid eventid(readEventGuid); + return eventid; } void VerifyPostOptimisationStructureTestImpl(armnn::BackendId backendId) @@ -414,7 +423,7 @@ void VerifyPostOptimisationStructureTestImpl(armnn::BackendId backendId) 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 @@ void VerifyPostOptimisationStructureTestImpl(armnn::BackendId backendId) 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 @@ void VerifyPostOptimisationStructureTestImpl(armnn::BackendId backendId) // 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 @@ void VerifyPostOptimisationStructureTestImpl(armnn::BackendId backendId) // 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 @@ void VerifyPostOptimisationStructureTestImpl(armnn::BackendId backendId) // 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 @@ void VerifyPostOptimisationStructureTestImpl(armnn::BackendId backendId) // 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 2e7daabda7..a9a69218c7 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 @@ void VerifyTimelineHeaderBinary(const unsigned char* readableData, 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 @@ void VerifyTimelineRelationshipBinaryPacketData(ProfilingRelationshipType relati 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 e3a49e48c3..bc16bb952b 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 @@ BOOST_AUTO_TEST_CASE(CheckCommandHandler) 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 @@ BOOST_AUTO_TEST_CASE(CheckConnectionAcknowledged) 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 @@ BOOST_AUTO_TEST_CASE(CheckConnectionAcknowledged) 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 @@ BOOST_AUTO_TEST_CASE(RequestCounterDirectoryCommandHandlerTest1) // 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 @@ BOOST_AUTO_TEST_CASE(RequestCounterDirectoryCommandHandlerTest2) // 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 @@ BOOST_AUTO_TEST_CASE(CheckProfilingServiceGoodRequestCounterDirectoryPacket) 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 b41f2dd58d..c350fd2860 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 05a6db8d1d..4b45cfef76 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 @@ BOOST_AUTO_TEST_CASE(SendTimelineMessageDirectoryPackageTest) 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_AUTO_TEST_CASE(SendTimelineMessageDirectoryPackageTest) 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 @@ BOOST_AUTO_TEST_CASE(SendTimelinePacketTests3) 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 93fb4b433c..ccb806b238 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::CreateEntity(const Enti 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 @@ ITimelineDecoder::TimelineStatus TimelineMessageDecoder::CreateRelationship( 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 6cc6a0c086..08239fc38f 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 73aa0c5580..d16a300d91 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 @@ void TimelineModel::AddLabel(const ITimelineDecoder::Label& label) 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 @@ Entity* TimelineModel::findEntity(uint64_t id) 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 @@ ModelRelationship* TimelineModel::findRelationship(uint64_t id) } } +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 7b88d5fa2c..a6d62ce3e8 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 @@ namespace profiling 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 @@ public: 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 @@ struct ModelRelationship 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 555ec670bd..96e9bf2400 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 @@ BOOST_AUTO_TEST_CASE(TimelineMessageDirectoryPacketTestFullConstruction) 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 @@ BOOST_AUTO_TEST_CASE(TimelineMessageDirectoryPacketTestFullConstruction) 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 815a3a0f95..720b8b4f02 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 @@ BOOST_AUTO_TEST_CASE(SendWellKnownLabelsAndEventClassesTest) 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 @@ BOOST_AUTO_TEST_CASE(SendWellKnownLabelsAndEventClassesTest) 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 @@ BOOST_AUTO_TEST_CASE(SendWellKnownLabelsAndEventClassesTest) 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, |