diff options
author | David Monahan <david.monahan@arm.com> | 2019-12-02 08:35:43 +0000 |
---|---|---|
committer | Narumol Prangnawarat <narumol.prangnawarat@arm.com> | 2019-12-04 15:34:07 +0000 |
commit | 6198fe0f653fb60c938a3c269bf28aeefcdad07e (patch) | |
tree | fad59f7c352d9263efd24a8dde7d94e79dd827b3 /src/armnn | |
parent | 109c05bc985d25f513444a7caa1e54557ef0f3c0 (diff) | |
download | armnn-6198fe0f653fb60c938a3c269bf28aeefcdad07e.tar.gz |
IVGCVSW-4016 Add the Inference timeline trace and unit tests
Signed-off-by: David Monahan <david.monahan@arm.com>
Signed-off-by: Narumol Prangnawarat <narumol.prangnawarat@arm.com>
Change-Id: I0cfbc2e1ed8f1eded1841866ebf9f39a066e91af
Diffstat (limited to 'src/armnn')
-rw-r--r-- | src/armnn/LoadedNetwork.cpp | 52 | ||||
-rw-r--r-- | src/armnn/LoadedNetwork.hpp | 5 | ||||
-rw-r--r-- | src/armnn/test/RuntimeTests.cpp | 312 |
3 files changed, 364 insertions, 5 deletions
diff --git a/src/armnn/LoadedNetwork.cpp b/src/armnn/LoadedNetwork.cpp index 778c469043..16ec42308c 100644 --- a/src/armnn/LoadedNetwork.cpp +++ b/src/armnn/LoadedNetwork.cpp @@ -19,7 +19,6 @@ #include <backendsCommon/MemSyncWorkload.hpp> #include <LabelsAndEventClasses.hpp> #include <ProfilingService.hpp> -#include <TimelineUtilityMethods.hpp> #include <boost/polymorphic_cast.hpp> #include <boost/assert.hpp> @@ -449,14 +448,31 @@ Status LoadedNetwork::EnqueueWorkload(const InputTensors& inputTensors, EnqueueOutput(*outputLayer, pin.GetTensorHandle(), pin.GetTensorInfo()); } + std::unique_ptr<TimelineUtilityMethods> timelineUtils = TimelineUtilityMethods::GetTimelineUtils(); + ProfilingGuid inferenceGuid = ProfilingService::Instance().NextGuid(); + if (timelineUtils) + { + // 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->RecordEvent(inferenceGuid, LabelsAndEventClasses::ARMNN_PROFILING_SOL_EVENT_CLASS); + } + bool executionSucceeded = true; { ARMNN_SCOPED_PROFILING_EVENT(Compute::Undefined, "Execute"); ARMNN_SCOPED_HEAP_PROFILING("Executing"); - executionSucceeded = Execute(); + executionSucceeded = Execute(timelineUtils, inferenceGuid); } + if (timelineUtils) + { + // Add end of life of the inference timeline if profiling is enabled. + timelineUtils->RecordEvent(inferenceGuid, LabelsAndEventClasses::ARMNN_PROFILING_EOL_EVENT_CLASS); + timelineUtils->Commit(); + } return executionSucceeded ? Status::Success : Status::Failure; } @@ -656,7 +672,8 @@ void LoadedNetwork::FreeWorkingMemory() m_IsWorkingMemAllocated = false; } -bool LoadedNetwork::Execute() +bool LoadedNetwork::Execute(std::unique_ptr<TimelineUtilityMethods>& timelineUtils, + profiling::ProfilingGuid inferenceGuid) { bool success = true; @@ -671,19 +688,46 @@ bool LoadedNetwork::Execute() std::lock_guard<std::mutex> lockGuard(m_WorkingMemMutex); AllocateWorkingMemory(); + ProfilingDynamicGuid workloadInferenceID(0); for (auto& input : m_InputQueue) { + if(timelineUtils) + { + workloadInferenceID = timelineUtils->RecordWorkloadInferenceAndStartOfLifeEvent(input->GetGuid(), + inferenceGuid); + } input->Execute(); + if(timelineUtils) + { + timelineUtils->RecordEndOfLifeEvent(workloadInferenceID); + } } for (auto& workload : m_WorkloadQueue) { + if(timelineUtils) + { + workloadInferenceID = timelineUtils->RecordWorkloadInferenceAndStartOfLifeEvent(workload->GetGuid(), + inferenceGuid); + } workload->Execute(); + if(timelineUtils) + { + timelineUtils->RecordEndOfLifeEvent(workloadInferenceID); + } } - for (auto& output: m_OutputQueue) { + if(timelineUtils) + { + workloadInferenceID = timelineUtils->RecordWorkloadInferenceAndStartOfLifeEvent(output->GetGuid(), + inferenceGuid); + } output->Execute(); + if(timelineUtils) + { + timelineUtils->RecordEndOfLifeEvent(workloadInferenceID); + } } } catch (const RuntimeException& error) diff --git a/src/armnn/LoadedNetwork.hpp b/src/armnn/LoadedNetwork.hpp index 08c09b8801..1ac53daecb 100644 --- a/src/armnn/LoadedNetwork.hpp +++ b/src/armnn/LoadedNetwork.hpp @@ -15,6 +15,7 @@ #include <backendsCommon/TensorHandleFactoryRegistry.hpp> #include <backendsCommon/Workload.hpp> #include <backendsCommon/WorkloadFactory.hpp> +#include <TimelineUtilityMethods.hpp> #include <mutex> #include <unordered_map> @@ -62,7 +63,9 @@ private: void EnqueueOutput(const BindableLayer& layer, ITensorHandle* tensorHandle, const TensorInfo& tensorInfo); - bool Execute(); + bool Execute(std::unique_ptr<profiling::TimelineUtilityMethods>& timelineUtils, + profiling::ProfilingGuid inferenceGuid); + const IWorkloadFactory& GetWorkloadFactory(const Layer& layer) const; diff --git a/src/armnn/test/RuntimeTests.cpp b/src/armnn/test/RuntimeTests.cpp index 2567e86862..4fd847a577 100644 --- a/src/armnn/test/RuntimeTests.cpp +++ b/src/armnn/test/RuntimeTests.cpp @@ -654,6 +654,10 @@ BOOST_AUTO_TEST_CASE(ProfilingEnableCpuRef) // Does the inference. runtime->EnqueueWorkload(netId, inputTensors, outputTensors); + // Get readable buffer for inference timeline + auto inferenceReadableBuffer = bufferManager.GetReadableBuffer(); + BOOST_CHECK(inferenceReadableBuffer != nullptr); + // Get readable buffer for output workload auto outputReadableBuffer = bufferManager.GetReadableBuffer(); BOOST_CHECK(outputReadableBuffer != nullptr); @@ -777,6 +781,314 @@ BOOST_AUTO_TEST_CASE(ProfilingEnableCpuRef) offset); bufferManager.MarkRead(outputReadableBuffer); + + // Validate inference data + size = inferenceReadableBuffer->GetSize(); + BOOST_CHECK(size == 1608); + + readableData = inferenceReadableBuffer->GetReadableData(); + BOOST_CHECK(readableData != nullptr); + + offset = 0; + + // Inference timeline trace + // Inference entity + VerifyTimelineEntityBinaryPacket(EmptyOptional(), readableData, offset); + + // Entity - Type relationship + VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::LabelLink, + EmptyOptional(), + EmptyOptional(), + LabelsAndEventClasses::INFERENCE_GUID, + readableData, + offset); + + // Type label relationship + VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::LabelLink, + EmptyOptional(), + EmptyOptional(), + LabelsAndEventClasses::TYPE_GUID, + readableData, + offset); + + // Network - Inference relationship + VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::RetentionLink, + EmptyOptional(), + optNetGuid, + EmptyOptional(), + readableData, + offset); + + // Start Inference life + // Event packet - timeline, threadId, eventGuid + VerifyTimelineEventBinaryPacket(EmptyOptional(), EmptyOptional(), EmptyOptional(), readableData, offset); + + // Inference - event relationship + VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::ExecutionLink, + EmptyOptional(), + EmptyOptional(), + EmptyOptional(), + readableData, + offset); + + // Event - event class relationship + VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::DataLink, + EmptyOptional(), + EmptyOptional(), + LabelsAndEventClasses::ARMNN_PROFILING_SOL_EVENT_CLASS, + readableData, + offset); + + // Execution + // Input workload execution + // Input workload execution entity + VerifyTimelineEntityBinaryPacket(EmptyOptional(), readableData, offset); + + // Entity - Type relationship + VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::LabelLink, + EmptyOptional(), + EmptyOptional(), + LabelsAndEventClasses::WORKLOAD_EXECUTION_GUID, + readableData, + offset); + + // Type label relationship + VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::LabelLink, + EmptyOptional(), + EmptyOptional(), + LabelsAndEventClasses::TYPE_GUID, + readableData, + offset); + + // Inference - Workload execution relationship + VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::RetentionLink, + EmptyOptional(), + EmptyOptional(), + EmptyOptional(), + readableData, + offset); + + // Workload - Workload execution relationship + VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::RetentionLink, + EmptyOptional(), + EmptyOptional(), + EmptyOptional(), + readableData, + offset); + + // Start Input workload execution life + // Event packet - timeline, threadId, eventGuid + VerifyTimelineEventBinaryPacket(EmptyOptional(), EmptyOptional(), EmptyOptional(), readableData, offset); + + // Input workload execution - event relationship + VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::ExecutionLink, + EmptyOptional(), + EmptyOptional(), + EmptyOptional(), + readableData, + offset); + + // Event - event class relationship + VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::DataLink, + EmptyOptional(), + EmptyOptional(), + LabelsAndEventClasses::ARMNN_PROFILING_SOL_EVENT_CLASS, + readableData, + offset); + + // End of Input workload execution life + // Event packet - timeline, threadId, eventGuid + VerifyTimelineEventBinaryPacket(EmptyOptional(), EmptyOptional(), EmptyOptional(), readableData, offset); + + // Input workload execution - event relationship + VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::ExecutionLink, + EmptyOptional(), + EmptyOptional(), + EmptyOptional(), + readableData, + offset); + + // Event - event class relationship + VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::DataLink, + EmptyOptional(), + EmptyOptional(), + LabelsAndEventClasses::ARMNN_PROFILING_EOL_EVENT_CLASS, + readableData, + offset); + + // Normalize workload execution + // Normalize workload execution entity + VerifyTimelineEntityBinaryPacket(EmptyOptional(), readableData, offset); + + // Entity - Type relationship + VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::LabelLink, + EmptyOptional(), + EmptyOptional(), + LabelsAndEventClasses::WORKLOAD_EXECUTION_GUID, + readableData, + offset); + + // Type label relationship + VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::LabelLink, + EmptyOptional(), + EmptyOptional(), + LabelsAndEventClasses::TYPE_GUID, + readableData, + offset); + + // Inference - Workload execution relationship + VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::RetentionLink, + EmptyOptional(), + EmptyOptional(), + EmptyOptional(), + readableData, + offset); + + // Workload - Workload execution relationship + VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::RetentionLink, + EmptyOptional(), + EmptyOptional(), + EmptyOptional(), + readableData, + offset); + + // Start Normalize workload execution life + // Event packet - timeline, threadId, eventGuid + VerifyTimelineEventBinaryPacket(EmptyOptional(), EmptyOptional(), EmptyOptional(), readableData, offset); + + // Normalize workload execution - event relationship + VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::ExecutionLink, + EmptyOptional(), + EmptyOptional(), + EmptyOptional(), + readableData, + offset); + + // Event - event class relationship + VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::DataLink, + EmptyOptional(), + EmptyOptional(), + LabelsAndEventClasses::ARMNN_PROFILING_SOL_EVENT_CLASS, + readableData, + offset); + + // End of Normalize workload execution life + // Event packet - timeline, threadId, eventGuid + VerifyTimelineEventBinaryPacket(EmptyOptional(), EmptyOptional(), EmptyOptional(), readableData, offset); + + // Normalize workload execution - event relationship + VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::ExecutionLink, + EmptyOptional(), + EmptyOptional(), + EmptyOptional(), + readableData, + offset); + + // Event - event class relationship + VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::DataLink, + EmptyOptional(), + EmptyOptional(), + LabelsAndEventClasses::ARMNN_PROFILING_EOL_EVENT_CLASS, + readableData, + offset); + + // Output workload execution + // Output workload execution entity + VerifyTimelineEntityBinaryPacket(EmptyOptional(), readableData, offset); + + // Entity - Type relationship + VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::LabelLink, + EmptyOptional(), + EmptyOptional(), + LabelsAndEventClasses::WORKLOAD_EXECUTION_GUID, + readableData, + offset); + + // Type label relationship + VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::LabelLink, + EmptyOptional(), + EmptyOptional(), + LabelsAndEventClasses::TYPE_GUID, + readableData, + offset); + + // Inference - Workload execution relationship + VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::RetentionLink, + EmptyOptional(), + EmptyOptional(), + EmptyOptional(), + readableData, + offset); + + // Workload - Workload execution relationship + VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::RetentionLink, + EmptyOptional(), + EmptyOptional(), + EmptyOptional(), + readableData, + offset); + + // Start Output workload execution life + // Event packet - timeline, threadId, eventGuid + VerifyTimelineEventBinaryPacket(EmptyOptional(), EmptyOptional(), EmptyOptional(), readableData, offset); + + // Output workload execution - event relationship + VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::ExecutionLink, + EmptyOptional(), + EmptyOptional(), + EmptyOptional(), + readableData, + offset); + + // Event - event class relationship + VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::DataLink, + EmptyOptional(), + EmptyOptional(), + LabelsAndEventClasses::ARMNN_PROFILING_SOL_EVENT_CLASS, + readableData, + offset); + + // End of Normalize workload execution life + // Event packet - timeline, threadId, eventGuid + VerifyTimelineEventBinaryPacket(EmptyOptional(), EmptyOptional(), EmptyOptional(), readableData, offset); + + // Output workload execution - event relationship + VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::ExecutionLink, + EmptyOptional(), + EmptyOptional(), + EmptyOptional(), + readableData, + offset); + + // Event - event class relationship + VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::DataLink, + EmptyOptional(), + EmptyOptional(), + LabelsAndEventClasses::ARMNN_PROFILING_EOL_EVENT_CLASS, + readableData, + offset); + + // End of Inference life + // Event packet - timeline, threadId, eventGuid + VerifyTimelineEventBinaryPacket(EmptyOptional(), EmptyOptional(), EmptyOptional(), readableData, offset); + + // Inference - event relationship + VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::ExecutionLink, + EmptyOptional(), + EmptyOptional(), + EmptyOptional(), + readableData, + offset); + + // Event - event class relationship + VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::DataLink, + EmptyOptional(), + EmptyOptional(), + LabelsAndEventClasses::ARMNN_PROFILING_EOL_EVENT_CLASS, + readableData, + offset); + + bufferManager.MarkRead(inferenceReadableBuffer); } BOOST_AUTO_TEST_CASE(ProfilingPostOptimisationStructureCpuRef) |