From 6398a98ac273931cc0b3ab33222d255d1edf48b0 Mon Sep 17 00:00:00 2001 From: Jim Flynn Date: Wed, 27 May 2020 17:05:21 +0100 Subject: IVGCVSW-4900 Update Timeline Directory Message with new fields Change-Id: I68097e176f7471a18498492b50339e68004dddd5 Signed-off-by: Jim Flynn --- src/armnn/LoadedNetwork.cpp | 11 +- src/armnn/LoadedNetwork.hpp | 2 +- src/armnn/Runtime.cpp | 7 +- src/armnn/Runtime.hpp | 2 +- src/armnn/test/RuntimeTests.cpp | 285 ++++++++----- src/armnn/test/RuntimeTests.hpp | 2 +- .../ConnectionAcknowledgedCommandHandler.cpp | 7 +- .../ConnectionAcknowledgedCommandHandler.hpp | 6 +- src/profiling/IProfilingService.hpp | 5 +- src/profiling/IProfilingServiceStatus.hpp | 29 ++ src/profiling/LabelsAndEventClasses.cpp | 8 +- src/profiling/LabelsAndEventClasses.hpp | 6 +- src/profiling/ProfilingGuidGenerator.hpp | 9 +- src/profiling/ProfilingService.cpp | 44 +- src/profiling/ProfilingService.hpp | 16 +- src/profiling/ProfilingUtils.cpp | 14 +- src/profiling/ProfilingUtils.hpp | 2 +- src/profiling/SendTimelinePacket.hpp | 19 +- src/profiling/TimelineUtilityMethods.cpp | 33 +- src/profiling/TimelineUtilityMethods.hpp | 5 +- .../test/FileOnlyProfilingDecoratorTests.cpp | 58 ++- src/profiling/test/ProfilingMocks.hpp | 10 +- src/profiling/test/ProfilingTestUtils.cpp | 467 +++++++++++++-------- src/profiling/test/ProfilingTestUtils.hpp | 32 +- src/profiling/test/ProfilingTests.cpp | 36 +- src/profiling/test/ProfilingTests.hpp | 2 +- src/profiling/test/SendTimelinePacketTests.cpp | 18 +- src/profiling/test/TestTimelinePacketHandler.cpp | 27 +- src/profiling/test/TestTimelinePacketHandler.hpp | 2 +- src/profiling/test/TimelineModel.cpp | 347 ++++++++++++++- src/profiling/test/TimelineModel.hpp | 130 +++++- src/profiling/test/TimelinePacketTests.cpp | 6 +- src/profiling/test/TimelineUtilityMethodsTests.cpp | 18 +- 33 files changed, 1279 insertions(+), 386 deletions(-) create mode 100644 src/profiling/IProfilingServiceStatus.hpp diff --git a/src/armnn/LoadedNetwork.cpp b/src/armnn/LoadedNetwork.cpp index 98ad7b80e7..fbf8cfbb4c 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 @@ void AddWorkloadStructure(std::unique_ptr& timelineUtils // Link the workload to the layer timelineUtils->CreateRelationship(ProfilingRelationshipType::RetentionLink, layer.GetGuid(), - workload->GetGuid()); - + workload->GetGuid(), + LabelsAndEventClasses::CHILD_GUID); } } // anonymous @@ -496,7 +496,10 @@ Status LoadedNetwork::EnqueueWorkload(const InputTensors& inputTensors, // 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 17c777d94d..918375ac38 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 76b13d16ce..5692494836 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 @@ Runtime::Runtime(const CreationOptions& options) 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 e7ad3f3f4f..3c90c51bb2 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 5c4b6252dd..7e9acb7d79 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_AUTO_TEST_CASE(ProfilingEnableCpuRef) 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 @@ BOOST_AUTO_TEST_CASE(ProfilingEnableCpuRef) 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 @@ BOOST_AUTO_TEST_CASE(ProfilingEnableCpuRef) 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 @@ BOOST_AUTO_TEST_CASE(ProfilingEnableCpuRef) // 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 @@ BOOST_AUTO_TEST_CASE(ProfilingEnableCpuRef) // 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 @@ BOOST_AUTO_TEST_CASE(ProfilingEnableCpuRef) // 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 588a760472..90aed5de1e 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 7690573ccf..ce2a36f9fb 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 @@ void ConnectionAcknowledgedCommandHandler::operator()(const Packet& packet) TimelineUtilityMethods::SendWellKnownLabelsAndEventClasses(m_SendTimelinePacket); } - if(m_BackendProfilingContext.has_value()) + if (m_BackendProfilingContext.has_value()) { for (auto backendContext : m_BackendProfilingContext.value()) { @@ -60,6 +60,9 @@ void ConnectionAcknowledgedCommandHandler::operator()(const Packet& packet) } } + // 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 8aba9216b8..f65b23f457 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 #include "CommandHandlerFunctor.hpp" +#include "IProfilingServiceStatus.hpp" #include "ISendCounterPacket.hpp" #include "armnn/profiling/ISendTimelinePacket.hpp" #include @@ -32,12 +33,14 @@ public: ISendCounterPacket& sendCounterPacket, ISendTimelinePacket& sendTimelinePacket, ProfilingStateMachine& profilingStateMachine, + IProfilingServiceStatus& profilingServiceStatus, Optional 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 @@ private: ISendCounterPacket& m_SendCounterPacket; ISendTimelinePacket& m_SendTimelinePacket; ProfilingStateMachine& m_StateMachine; + IProfilingServiceStatus& m_ProfilingServiceStatus; Optional m_BackendProfilingContext; bool m_TimelineEnabled = false; }; diff --git a/src/profiling/IProfilingService.hpp b/src/profiling/IProfilingService.hpp index 7f3ff70062..760f2433bd 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 armnn 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 0000000000..45d4aac088 --- /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 +#include + +#include + +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 daf199258a..6b6a190507 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::NAME_LABEL("name"); 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 @@ ProfilingStaticGuid LabelsAndEventClasses::INDEX_GUID( 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 13332ff0ff..835fc7923e 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 @@ public: 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 dc6e22b10a..86f9ce09de 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 @@ public: return ProfilingStaticGuid(staticHash); } + /// Reset the generator back to zero. Used mainly for test. + inline void Reset() + { + std::lock_guard sequencelock(m_SequenceMutex); + m_Sequence = 0; + } + private: std::hash m_Hash; uint64_t m_Sequence; diff --git a/src/profiling/ProfilingService.cpp b/src/profiling/ProfilingService.cpp index 21972b4c7f..8532c3efad 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 @@ ProfilingStaticGuid ProfilingService::GetStaticId(const std::string& str) 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::Reset() void ProfilingService::Stop() { + { // only lock when we are updating the inference completed variable + std::unique_lock 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::NotifyBackendsForTimelineReporting() } } +void ProfilingService::NotifyProfilingServiceActive() +{ + { // only lock when we are updating the inference completed variable + std::unique_lock lck(m_ServiceActiveMutex); + m_ServiceActive = true; + } + m_ServiceActiveConditionVariable.notify_one(); +} + +void ProfilingService::WaitForProfilingServiceActivation(unsigned int timeout) +{ + std::unique_lock 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 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 d7e4628f68..247b945813 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 @@ public: m_SendCounterPacket, m_SendTimelinePacket, m_StateMachine, + *this, m_BackendProfilingContexts) , m_RequestCounterDirectoryCommandHandler(0, 3, @@ -123,6 +124,7 @@ public: *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 @@ public: /// Create a ProfilingStaticGuid based on a hash of the string ProfilingStaticGuid GenerateStaticId(const std::string& str) override; + std::unique_ptr GetSendTimelinePacket() const override; ISendCounterPacket& GetSendCounterPacket() override @@ -204,12 +207,18 @@ public: 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 @@ private: 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 2482e2c205..d67694fc33 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 @@ TimelinePacketStatus WriteTimelineMessageDirectoryPackage(unsigned char* buffer, // |-----------|---------------------|-----------------------|-------------|-------------------------------------| // | 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> 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 9c7ad037e5..95fa780934 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 b1bae04947..2b710c7a25 100644 --- a/src/profiling/SendTimelinePacket.hpp +++ b/src/profiling/SendTimelinePacket.hpp @@ -96,8 +96,7 @@ void SendTimelinePacket::ForwardWriteBinaryFunction(Func& func, Params&& ... par 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 @@ void SendTimelinePacket::ForwardWriteBinaryFunction(Func& func, Params&& ... par } } } + 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 306551bdc4..2727bd6e9b 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 @@ void TimelineUtilityMethods::SendWellKnownLabelsAndEventClasses(ISendTimelinePac 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 @@ void TimelineUtilityMethods::CreateNamedTypedChildEntity(ProfilingGuid childEnti retentionLinkGuid, parentEntityGuid, childEntityGuid, - LabelsAndEventClasses::EMPTY_GUID); + LabelsAndEventClasses::CHILD_GUID); } void TimelineUtilityMethods::CreateNamedTypedChildEntity(ProfilingGuid childEntityGuid, @@ -309,12 +317,13 @@ void TimelineUtilityMethods::CreateNamedTypedChildEntity(ProfilingGuid childEnti 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 @@ ProfilingDynamicGuid TimelineUtilityMethods::CreateRelationship(ProfilingRelatio relationshipGuid, headGuid, tailGuid, - LabelsAndEventClasses::EMPTY_GUID); + relationshipCategory); return relationshipGuid; } @@ -340,9 +349,7 @@ ProfilingDynamicGuid TimelineUtilityMethods::CreateConnectionRelationship(Profil relationshipGuid, headGuid, tailGuid, - LabelsAndEventClasses::EMPTY_GUID); - - MarkEntityWithType(relationshipGuid, LabelsAndEventClasses::CONNECTION_GUID); + LabelsAndEventClasses::CONNECTION_GUID); return relationshipGuid; } @@ -387,8 +394,14 @@ ProfilingDynamicGuid TimelineUtilityMethods::RecordWorkloadInferenceAndStartOfLi { 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 4f24726307..857d82f267 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 @@ public: 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 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 +#include #include -#include +#include "ProfilingTestUtils.hpp" #include "PrintPacketHeaderHandler.hpp" +#include #include "TestTimelinePacketHandler.hpp" #include @@ -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(localPacketHandlerPtr.get())->WaitOnInferenceCompletion(3000); + + const TimelineModel& model = + static_cast(localPacketHandlerPtr.get())->GetTimelineModel(); + + for (auto& error : model.GetErrors()) + { + std::cout << error.what() << std::endl; + } + BOOST_TEST(model.GetErrors().empty()); + std::vector desc = GetModelDescription(model); + std::vector 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 #include +#include #include #include #include @@ -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 guid, - const std::string& label, - const unsigned char* readableData, - unsigned int& offset) +ProfilingGuid VerifyTimelineLabelBinaryPacketData(Optional guid, + const std::string& label, + const unsigned char* readableData, + unsigned int& offset) { ARMNN_ASSERT(readableData); @@ -115,6 +115,9 @@ void VerifyTimelineLabelBinaryPacketData(Optional 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 relationshipGuid, - Optional headGuid, - Optional tailGuid, - Optional attributeGuid, - const unsigned char* readableData, - unsigned int& offset) + Optional relationshipGuid, + Optional headGuid, + Optional tailGuid, + Optional 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 guid, - const unsigned char* readableData, - unsigned int& offset) +ProfilingGuid VerifyTimelineEntityBinaryPacketData(Optional guid, + const unsigned char* readableData, + unsigned int& offset) { ARMNN_ASSERT(readableData); @@ -268,13 +271,16 @@ void VerifyTimelineEntityBinaryPacketData(Optional guid, } offset += uint64_t_size; + + ProfilingGuid entityGuid(readProfilingGuid); + return entityGuid; } -void VerifyTimelineEventBinaryPacket(Optional timestamp, - Optional threadId, - Optional eventGuid, - const unsigned char* readableData, - unsigned int& offset) +ProfilingGuid VerifyTimelineEventBinaryPacket(Optional timestamp, + Optional threadId, + Optional eventGuid, + const unsigned char* readableData, + unsigned int& offset) { ARMNN_ASSERT(readableData); @@ -325,6 +331,9 @@ void VerifyTimelineEventBinaryPacket(Optional 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(), "", readableData, offset); + ProfilingGuid conv2dNameLabelGuid = VerifyTimelineLabelBinaryPacketData( + EmptyOptional(), "", 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 output, std::vector 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 guid, - const std::string& label, - const unsigned char* readableData, - unsigned int& offset); +ProfilingGuid VerifyTimelineLabelBinaryPacketData(Optional 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 guid, - const unsigned char* readableData, - unsigned int& offset); +ProfilingGuid VerifyTimelineEntityBinaryPacketData(Optional guid, + const unsigned char* readableData, + unsigned int& offset); -void VerifyTimelineEventBinaryPacket(Optional timestamp, - Optional threadId, - Optional eventGuid, - const unsigned char* readableData, - unsigned int& offset); +ProfilingGuid VerifyTimelineEventBinaryPacket(Optional timestamp, + Optional threadId, + Optional 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 output, std::vector 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 #include @@ -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 + +#include 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 GetModelDescription(const TimelineModel& model) +{ + std::vector 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 +#include #include +#include #include namespace armnn @@ -18,11 +20,76 @@ namespace profiling using LabelMap = std::map; using Attribute = std::pair; using Attributes = std::map; +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& GetChildren() const {return m_Children;} + const std::vector& GetConnections() const {return m_Connections;} + const std::vector& GetExecutions() const {return m_Executions;} + const std::vector& GetEvents() const {return m_Events;} private: uint64_t m_Guid; Attributes m_Attributes; std::vector m_Children; + std::vector m_Connections; + std::vector m_Executions; + std::vector m_Events; }; using Entities = std::map; struct ModelRelationship @@ -48,20 +141,49 @@ struct ModelRelationship std::vector m_RelatedEntities; }; using Relationships = std::map; +using EventClasses = std::map; +using Events = std::map; 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& 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 m_Errors; + std::vector 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 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, -- cgit v1.2.1