aboutsummaryrefslogtreecommitdiff
path: root/src/armnn
diff options
context:
space:
mode:
authorDavid Monahan <david.monahan@arm.com>2019-12-02 08:35:43 +0000
committerNarumol Prangnawarat <narumol.prangnawarat@arm.com>2019-12-04 15:34:07 +0000
commit6198fe0f653fb60c938a3c269bf28aeefcdad07e (patch)
treefad59f7c352d9263efd24a8dde7d94e79dd827b3 /src/armnn
parent109c05bc985d25f513444a7caa1e54557ef0f3c0 (diff)
downloadarmnn-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.cpp52
-rw-r--r--src/armnn/LoadedNetwork.hpp5
-rw-r--r--src/armnn/test/RuntimeTests.cpp312
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)