aboutsummaryrefslogtreecommitdiff
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
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
-rw-r--r--src/armnn/LoadedNetwork.cpp52
-rw-r--r--src/armnn/LoadedNetwork.hpp5
-rw-r--r--src/armnn/test/RuntimeTests.cpp312
-rw-r--r--src/profiling/LabelsAndEventClasses.cpp6
-rw-r--r--src/profiling/LabelsAndEventClasses.hpp4
-rw-r--r--src/profiling/TimelineUtilityMethods.cpp24
-rw-r--r--src/profiling/TimelineUtilityMethods.hpp5
-rw-r--r--src/profiling/test/ProfilingTestUtils.cpp388
-rw-r--r--src/profiling/test/TimelineUtilityMethodsTests.cpp12
9 files changed, 802 insertions, 6 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)
diff --git a/src/profiling/LabelsAndEventClasses.cpp b/src/profiling/LabelsAndEventClasses.cpp
index 2424104042..fa89f1c0fa 100644
--- a/src/profiling/LabelsAndEventClasses.cpp
+++ b/src/profiling/LabelsAndEventClasses.cpp
@@ -33,6 +33,8 @@ std::string LabelsAndEventClasses::LAYER("layer");
std::string LabelsAndEventClasses::WORKLOAD("workload");
std::string LabelsAndEventClasses::NETWORK("network");
std::string LabelsAndEventClasses::CONNECTION("connection");
+std::string LabelsAndEventClasses::INFERENCE("inference");
+std::string LabelsAndEventClasses::WORKLOAD_EXECUTION("workload_execution");
ProfilingStaticGuid LabelsAndEventClasses::LAYER_GUID(
m_GuidGenerator.GenerateStaticId(LabelsAndEventClasses::LAYER));
@@ -42,6 +44,10 @@ ProfilingStaticGuid LabelsAndEventClasses::NETWORK_GUID(
m_GuidGenerator.GenerateStaticId(LabelsAndEventClasses::NETWORK));
ProfilingStaticGuid LabelsAndEventClasses::CONNECTION_GUID(
m_GuidGenerator.GenerateStaticId(LabelsAndEventClasses::CONNECTION));
+ProfilingStaticGuid LabelsAndEventClasses::INFERENCE_GUID(
+ m_GuidGenerator.GenerateStaticId(LabelsAndEventClasses::INFERENCE));
+ProfilingStaticGuid LabelsAndEventClasses::WORKLOAD_EXECUTION_GUID(
+ m_GuidGenerator.GenerateStaticId(LabelsAndEventClasses::WORKLOAD_EXECUTION));
// Event Class GUIDs
ProfilingStaticGuid LabelsAndEventClasses::ARMNN_PROFILING_SOL_EVENT_CLASS(
diff --git a/src/profiling/LabelsAndEventClasses.hpp b/src/profiling/LabelsAndEventClasses.hpp
index c2082dd9e5..69cee9aaea 100644
--- a/src/profiling/LabelsAndEventClasses.hpp
+++ b/src/profiling/LabelsAndEventClasses.hpp
@@ -33,10 +33,14 @@ public:
static std::string WORKLOAD;
static std::string NETWORK;
static std::string CONNECTION;
+ static std::string INFERENCE;
+ static std::string WORKLOAD_EXECUTION;
static ProfilingStaticGuid LAYER_GUID;
static ProfilingStaticGuid WORKLOAD_GUID;
static ProfilingStaticGuid NETWORK_GUID;
static ProfilingStaticGuid CONNECTION_GUID;
+ static ProfilingStaticGuid INFERENCE_GUID;
+ static ProfilingStaticGuid WORKLOAD_EXECUTION_GUID;
// Event Class GUIDs
static ProfilingStaticGuid ARMNN_PROFILING_SOL_EVENT_CLASS;
diff --git a/src/profiling/TimelineUtilityMethods.cpp b/src/profiling/TimelineUtilityMethods.cpp
index d540c5970b..972916104e 100644
--- a/src/profiling/TimelineUtilityMethods.cpp
+++ b/src/profiling/TimelineUtilityMethods.cpp
@@ -62,6 +62,14 @@ void TimelineUtilityMethods::SendWellKnownLabelsAndEventClasses()
m_SendTimelinePacket->SendTimelineLabelBinaryPacket(LabelsAndEventClasses::CONNECTION_GUID,
LabelsAndEventClasses::CONNECTION);
+ // Send the "inference" label, this call throws in case of error
+ m_SendTimelinePacket->SendTimelineLabelBinaryPacket(LabelsAndEventClasses::INFERENCE_GUID,
+ LabelsAndEventClasses::INFERENCE);
+
+ // Send the "workload_execution" label, this call throws in case of error
+ m_SendTimelinePacket->SendTimelineLabelBinaryPacket(LabelsAndEventClasses::WORKLOAD_EXECUTION_GUID,
+ LabelsAndEventClasses::WORKLOAD_EXECUTION);
+
// Send the "start of life" event class, this call throws in case of error
m_SendTimelinePacket->SendTimelineEventClassBinaryPacket(LabelsAndEventClasses::ARMNN_PROFILING_SOL_EVENT_CLASS);
@@ -386,6 +394,22 @@ ProfilingDynamicGuid TimelineUtilityMethods::RecordEvent(ProfilingGuid entityGui
return eventGuid;
}
+ProfilingDynamicGuid TimelineUtilityMethods::RecordWorkloadInferenceAndStartOfLifeEvent(ProfilingGuid workloadGuid,
+ ProfilingGuid inferenceGuid)
+{
+ ProfilingDynamicGuid workloadInferenceGuid = ProfilingService::Instance().NextGuid();
+ CreateTypedEntity(workloadInferenceGuid, LabelsAndEventClasses::WORKLOAD_EXECUTION_GUID);
+ CreateRelationship(ProfilingRelationshipType::RetentionLink, inferenceGuid, workloadInferenceGuid);
+ CreateRelationship(ProfilingRelationshipType::RetentionLink, workloadGuid, workloadInferenceGuid);
+ RecordEvent(workloadInferenceGuid, LabelsAndEventClasses::ARMNN_PROFILING_SOL_EVENT_CLASS);
+ return workloadInferenceGuid;
+}
+
+void TimelineUtilityMethods::RecordEndOfLifeEvent(ProfilingGuid entityGuid)
+{
+ RecordEvent(entityGuid, LabelsAndEventClasses::ARMNN_PROFILING_EOL_EVENT_CLASS);
+}
+
} // namespace profiling
} // namespace armnn
diff --git a/src/profiling/TimelineUtilityMethods.hpp b/src/profiling/TimelineUtilityMethods.hpp
index 8e071611a2..5b00ec8738 100644
--- a/src/profiling/TimelineUtilityMethods.hpp
+++ b/src/profiling/TimelineUtilityMethods.hpp
@@ -80,6 +80,11 @@ public:
ProfilingDynamicGuid RecordEvent(ProfilingGuid entityGuid, ProfilingStaticGuid eventClassGuid);
+ ProfilingDynamicGuid RecordWorkloadInferenceAndStartOfLifeEvent(ProfilingGuid workloadGuid,
+ ProfilingGuid inferenceGuid);
+
+ void RecordEndOfLifeEvent(ProfilingGuid entityGuid);
+
void Commit() { m_SendTimelinePacket->Commit(); }
private:
diff --git a/src/profiling/test/ProfilingTestUtils.cpp b/src/profiling/test/ProfilingTestUtils.cpp
index 862dcf0bf3..bc8b7a7b4d 100644
--- a/src/profiling/test/ProfilingTestUtils.cpp
+++ b/src/profiling/test/ProfilingTestUtils.cpp
@@ -832,6 +832,10 @@ void VerifyPostOptimisationStructureTestImpl(armnn::BackendId backendId)
// 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);
@@ -955,4 +959,388 @@ void VerifyPostOptimisationStructureTestImpl(armnn::BackendId backendId)
offset);
bufferManager.MarkRead(outputReadableBuffer);
+
+ // Validate inference data
+ size = inferenceReadableBuffer->GetSize();
+ BOOST_CHECK(size == 2020);
+
+ 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);
+
+ // Conv2d workload execution
+ // Conv2d 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 Conv2d workload execution life
+ // Event packet - timeline, threadId, eventGuid
+ VerifyTimelineEventBinaryPacket(EmptyOptional(), EmptyOptional(), EmptyOptional(), readableData, offset);
+
+ // Conv2d 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 Conv2d workload execution life
+ // Event packet - timeline, threadId, eventGuid
+ VerifyTimelineEventBinaryPacket(EmptyOptional(), EmptyOptional(), EmptyOptional(), readableData, offset);
+
+ // Conv2d 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);
+
+ // Activation workload execution
+ // Activation 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 Activation workload execution life
+ // Event packet - timeline, threadId, eventGuid
+ VerifyTimelineEventBinaryPacket(EmptyOptional(), EmptyOptional(), EmptyOptional(), readableData, offset);
+
+ // Activation 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 Activation workload execution life
+ // Event packet - timeline, threadId, eventGuid
+ VerifyTimelineEventBinaryPacket(EmptyOptional(), EmptyOptional(), EmptyOptional(), readableData, offset);
+
+ // Activation 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);
}
diff --git a/src/profiling/test/TimelineUtilityMethodsTests.cpp b/src/profiling/test/TimelineUtilityMethodsTests.cpp
index ae1ee558bf..abacdb5288 100644
--- a/src/profiling/test/TimelineUtilityMethodsTests.cpp
+++ b/src/profiling/test/TimelineUtilityMethodsTests.cpp
@@ -87,7 +87,7 @@ BOOST_AUTO_TEST_CASE(SendWellKnownLabelsAndEventClassesTest)
auto readableBuffer = mockBufferManager.GetReadableBuffer();
BOOST_CHECK(readableBuffer != nullptr);
unsigned int size = readableBuffer->GetSize();
- BOOST_TEST(size == 308);
+ BOOST_TEST(size == 388);
const unsigned char* readableData = readableBuffer->GetReadableData();
BOOST_CHECK(readableData != nullptr);
@@ -142,6 +142,16 @@ BOOST_AUTO_TEST_CASE(SendWellKnownLabelsAndEventClassesTest)
LabelsAndEventClasses::CONNECTION,
readableData,
offset);
+ // Inference
+ VerifyTimelineLabelBinaryPacket(LabelsAndEventClasses::INFERENCE_GUID,
+ LabelsAndEventClasses::INFERENCE,
+ readableData,
+ offset);
+ // Workload Execution
+ VerifyTimelineLabelBinaryPacket(LabelsAndEventClasses::WORKLOAD_EXECUTION_GUID,
+ LabelsAndEventClasses::WORKLOAD_EXECUTION,
+ readableData,
+ offset);
// First "well-known" event class: START OF LIFE
VerifyTimelineEventClassBinaryPacket(LabelsAndEventClasses::ARMNN_PROFILING_SOL_EVENT_CLASS,