aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNarumol Prangnawarat <narumol.prangnawarat@arm.com>2019-11-22 11:26:06 +0000
committerJim Flynn Arm <jim.flynn@arm.com>2019-11-29 17:01:45 +0000
commitdf31cfe29f9dccc4c2055a1d2a97de644b07d522 (patch)
tree15e848d398c35e669ecb0cff574907c4bd1662b9
parenta68d8530d3dcfc7c54b9c2bfa00b407f45145253 (diff)
downloadarmnn-df31cfe29f9dccc4c2055a1d2a97de644b07d522.tar.gz
IVGCVSW-4070 Implement "send post-optimized network structure"
* Send post-optimisation network structure if profiling service is enabled * Refactor TimelineUtilityMethods * Fix RecordEvent to link eventGuid with eventClassGuid * Add common types and guid to LabelsAndEventClasses * Add CreateRelationship to TimelineUtilityMethods * Add CreateTypedEntity to TimelineUtilityMethods * Add MarkEntityWithType to TimelineUtilityMethods * Move VerifyTimeline functions to ProfilingTestUtils * Post-optimisation network structure unit tests to Ref, Cl, Neon Signed-off-by: Narumol Prangnawarat <narumol.prangnawarat@arm.com> Change-Id: I0194f2037c236450c912f4c3cb11e46b80c0f512
-rw-r--r--Android.mk4
-rw-r--r--CMakeLists.txt2
-rw-r--r--src/armnn/LoadedNetwork.cpp69
-rw-r--r--src/armnn/test/RuntimeTests.cpp360
-rw-r--r--src/backends/cl/test/ClRuntimeTests.cpp6
-rw-r--r--src/backends/neon/test/NeonRuntimeTests.cpp6
-rw-r--r--src/profiling/LabelsAndEventClasses.cpp18
-rw-r--r--src/profiling/LabelsAndEventClasses.hpp12
-rw-r--r--src/profiling/ProfilingService.hpp8
-rw-r--r--src/profiling/TimelineUtilityMethods.cpp237
-rw-r--r--src/profiling/TimelineUtilityMethods.hpp49
-rw-r--r--src/profiling/test/ProfilingTestUtils.cpp818
-rw-r--r--src/profiling/test/ProfilingTestUtils.hpp70
-rw-r--r--src/profiling/test/TimelineUtilityMethodsTests.cpp410
14 files changed, 1652 insertions, 417 deletions
diff --git a/Android.mk b/Android.mk
index d755d20201..4dc023ecaf 100644
--- a/Android.mk
+++ b/Android.mk
@@ -199,6 +199,7 @@ LOCAL_SRC_FILES := \
src/profiling/SendCounterPacket.cpp \
src/profiling/SendTimelinePacket.cpp \
src/profiling/SocketProfilingConnection.cpp \
+ src/profiling/TimelinePacketWriterFactory.cpp \
src/profiling/TimelineUtilityMethods.cpp
LOCAL_STATIC_LIBRARIES := \
@@ -330,7 +331,8 @@ LOCAL_SRC_FILES := \
src/armnn/test/TensorTest.cpp \
src/armnn/test/TestUtils.cpp \
src/armnn/test/UnitTests.cpp \
- src/armnn/test/UtilsTests.cpp
+ src/armnn/test/UtilsTests.cpp \
+ src/profiling/test/ProfilingTestUtils.cpp
ifeq ($(ARMNN_REF_ENABLED),1)
LOCAL_SRC_FILES += \
diff --git a/CMakeLists.txt b/CMakeLists.txt
index ad9e9ee91d..7b6e1ab980 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -632,6 +632,8 @@ if(BUILD_UNIT_TESTS)
src/profiling/test/ProfilingGuidTest.cpp
src/profiling/test/ProfilingTests.cpp
src/profiling/test/ProfilingTests.hpp
+ src/profiling/test/ProfilingTestUtils.cpp
+ src/profiling/test/ProfilingTestUtils.hpp
src/profiling/test/SendCounterPacketTests.cpp
src/profiling/test/SendCounterPacketTests.hpp
src/profiling/test/SendTimelinePacketTests.cpp
diff --git a/src/armnn/LoadedNetwork.cpp b/src/armnn/LoadedNetwork.cpp
index e9a3545e35..36a56b044e 100644
--- a/src/armnn/LoadedNetwork.cpp
+++ b/src/armnn/LoadedNetwork.cpp
@@ -17,6 +17,9 @@
#include <backendsCommon/IMemoryManager.hpp>
#include <backendsCommon/MemCopyWorkload.hpp>
#include <backendsCommon/MemSyncWorkload.hpp>
+#include <LabelsAndEventClasses.hpp>
+#include <ProfilingService.hpp>
+#include <TimelineUtilityMethods.hpp>
#include <boost/polymorphic_cast.hpp>
#include <boost/assert.hpp>
@@ -27,6 +30,7 @@ namespace armnn
{
using namespace std;
+using namespace armnn::profiling;
namespace
{
@@ -39,6 +43,43 @@ std::string ToErrorMessage(const char * prefix, const ExceptionType & error)
return ss.str();
}
+void AddLayerStructure(std::unique_ptr<TimelineUtilityMethods>& timelineUtils,
+ const Layer& layer,
+ ProfilingGuid networkGuid)
+{
+ // Add layer to the post-optimisation network structure
+ std::string layerName = layer.GetNameStr().empty() ? "<Unnamed>" : layer.GetNameStr();
+ timelineUtils->CreateNamedTypedChildEntity(layer.GetGuid(),
+ networkGuid,
+ layerName,
+ LabelsAndEventClasses::LAYER_GUID);
+ for (auto&& input : layer.GetInputSlots())
+ {
+ const IOutputSlot* source = input.GetConnectedOutputSlot();
+ BOOST_ASSERT(source != NULL);
+ timelineUtils->CreateConnectionRelationship(ProfilingRelationshipType::RetentionLink,
+ source->GetOwningLayerGuid(),
+ layer.GetGuid());
+ }
+}
+
+void AddWorkloadStructure(std::unique_ptr<TimelineUtilityMethods>& timelineUtils,
+ std::unique_ptr<IWorkload>& workload,
+ const Layer& layer)
+{
+ // Add workload to the post-optimisation network structure
+ timelineUtils->CreateTypedEntity(workload->GetGuid(), LabelsAndEventClasses::WORKLOAD_GUID);
+ timelineUtils->MarkEntityWithLabel(workload->GetGuid(),
+ layer.GetBackendId().Get(),
+ LabelsAndEventClasses::BACKENDID_GUID);
+
+ // Link the workload to the layer
+ timelineUtils->CreateRelationship(ProfilingRelationshipType::RetentionLink,
+ layer.GetGuid(),
+ workload->GetGuid());
+
+}
+
} // anonymous
std::unique_ptr<LoadedNetwork> LoadedNetwork::MakeLoadedNetwork(std::unique_ptr<OptimizedNetwork> net,
@@ -149,9 +190,22 @@ LoadedNetwork::LoadedNetwork(std::unique_ptr<OptimizedNetwork> net,
}
}
+ ProfilingGuid networkGuid = m_OptimizedNetwork->GetGuid();
+ std::unique_ptr<TimelineUtilityMethods> timelineUtils = TimelineUtilityMethods::GetTimelineUtils();
+ if (timelineUtils)
+ {
+ timelineUtils->CreateTypedEntity(networkGuid, LabelsAndEventClasses::NETWORK_GUID);
+ }
+
//Then create workloads.
for (auto&& layer : order)
{
+ if (timelineUtils)
+ {
+ // Add layer to the post-optimisation network structure
+ AddLayerStructure(timelineUtils, *layer, networkGuid);
+ }
+
const IWorkloadFactory& workloadFactory = GetWorkloadFactory(*layer);
switch (layer->GetType())
@@ -168,13 +222,20 @@ LoadedNetwork::LoadedNetwork(std::unique_ptr<OptimizedNetwork> net,
if (!workload)
{
- const char* const layerName = layer->GetNameStr().length() != 0 ? layer->GetName() : "<Unnamed>";
+ const char* const layerName =
+ layer->GetNameStr().length() != 0 ? layer->GetName() : "<Unnamed>";
throw InvalidArgumentException(boost::str(
boost::format("No workload created for layer (name: '%1%' type: '%2%') (compute '%3%')")
% layerName % static_cast<int>(layer->GetType()) % layer->GetBackendId().Get()
));
}
+ if (timelineUtils)
+ {
+ // Add workload to the post-optimisation network structure
+ AddWorkloadStructure(timelineUtils, workload, *layer);
+ }
+
m_WorkloadQueue.push_back(move(workload));
// release the constant data in the layer..
layer->ReleaseConstantData();
@@ -183,6 +244,12 @@ LoadedNetwork::LoadedNetwork(std::unique_ptr<OptimizedNetwork> net,
}
}
+ if (timelineUtils)
+ {
+ // Commit to send the post-optimisation network structure
+ timelineUtils->Commit();
+ }
+
// Set up memory.
m_OptimizedNetwork->GetGraph().AllocateDynamicBuffers();
diff --git a/src/armnn/test/RuntimeTests.cpp b/src/armnn/test/RuntimeTests.cpp
index 998808c508..f84f73d810 100644
--- a/src/armnn/test/RuntimeTests.cpp
+++ b/src/armnn/test/RuntimeTests.cpp
@@ -9,6 +9,9 @@
#include <Runtime.hpp>
#include <armnn/TypesUtils.hpp>
+#include <LabelsAndEventClasses.hpp>
+#include <test/ProfilingTestUtils.hpp>
+
#include <HeapProfiling.hpp>
#include <LeakChecking.hpp>
@@ -17,6 +20,7 @@
#endif
#include <boost/test/unit_test.hpp>
+#include "RuntimeTests.hpp"
namespace armnn
{
@@ -284,4 +288,360 @@ BOOST_AUTO_TEST_CASE(IVGCVSW_1929_QuantizedSoftmaxIssue)
BOOST_TEST(!optNet);
}
+BOOST_AUTO_TEST_CASE(ProfilingDisable)
+{
+ using namespace armnn;
+
+ // Create runtime in which the test will run
+ armnn::IRuntime::CreationOptions options;
+ armnn::IRuntimePtr runtime(armnn::IRuntime::Create(options));
+
+ // build up the structure of the network
+ INetworkPtr net(INetwork::Create());
+
+ IConnectableLayer* input = net->AddInputLayer(0);
+
+ // This layer configuration isn't supported by CpuAcc, should fall back to CpuRef.
+ NormalizationDescriptor descriptor;
+ IConnectableLayer* normalize = net->AddNormalizationLayer(descriptor);
+
+ IConnectableLayer* output = net->AddOutputLayer(0);
+
+ input->GetOutputSlot(0).Connect(normalize->GetInputSlot(0));
+ normalize->GetOutputSlot(0).Connect(output->GetInputSlot(0));
+
+ input->GetOutputSlot(0).SetTensorInfo(TensorInfo({ 1, 1, 4, 4 }, DataType::Float32));
+ normalize->GetOutputSlot(0).SetTensorInfo(TensorInfo({ 1, 1, 4, 4 }, DataType::Float32));
+
+ // optimize the network
+ std::vector<armnn::BackendId> backends = { armnn::Compute::CpuRef };
+ IOptimizedNetworkPtr optNet = Optimize(*net, backends, runtime->GetDeviceSpec());
+
+ // Load it into the runtime. It should succeed.
+ armnn::NetworkId netId;
+ BOOST_TEST(runtime->LoadNetwork(netId, std::move(optNet)) == Status::Success);
+
+ profiling::ProfilingServiceRuntimeHelper profilingServiceHelper;
+ profiling::BufferManager& bufferManager = profilingServiceHelper.GetProfilingBufferManager();
+ auto readableBuffer = bufferManager.GetReadableBuffer();
+
+ // Profiling is not enabled, the post-optimisation structure should not be created
+ BOOST_TEST(!readableBuffer);
+}
+
+BOOST_AUTO_TEST_CASE(ProfilingEnableCpuRef)
+{
+ using namespace armnn;
+ using namespace armnn::profiling;
+
+ // Create runtime in which the test will run
+ armnn::IRuntime::CreationOptions options;
+ options.m_ProfilingOptions.m_EnableProfiling = true;
+ armnn::IRuntimePtr runtime(armnn::IRuntime::Create(options));
+
+ // build up the structure of the network
+ INetworkPtr net(INetwork::Create());
+
+ IConnectableLayer* input = net->AddInputLayer(0, "input");
+
+ NormalizationDescriptor descriptor;
+ IConnectableLayer* normalize = net->AddNormalizationLayer(descriptor, "normalization");
+
+ IConnectableLayer* output = net->AddOutputLayer(0, "output");
+
+ input->GetOutputSlot(0).Connect(normalize->GetInputSlot(0));
+ normalize->GetOutputSlot(0).Connect(output->GetInputSlot(0));
+
+ input->GetOutputSlot(0).SetTensorInfo(TensorInfo({ 1, 1, 4, 4 }, DataType::Float32));
+ normalize->GetOutputSlot(0).SetTensorInfo(TensorInfo({ 1, 1, 4, 4 }, DataType::Float32));
+
+ // optimize the network
+ std::vector<armnn::BackendId> backends = { armnn::Compute::CpuRef };
+ IOptimizedNetworkPtr optNet = Optimize(*net, backends, runtime->GetDeviceSpec());
+
+ ProfilingGuid optNetGuid = optNet->GetGuid();
+
+ // Load it into the runtime. It should succeed.
+ armnn::NetworkId netId;
+ BOOST_TEST(runtime->LoadNetwork(netId, std::move(optNet)) == Status::Success);
+
+ profiling::ProfilingServiceRuntimeHelper profilingServiceHelper;
+ profiling::BufferManager& bufferManager = profilingServiceHelper.GetProfilingBufferManager();
+ auto readableBuffer = bufferManager.GetReadableBuffer();
+
+ // Profiling is enabled, the post-optimisation structure should be created
+ BOOST_CHECK(readableBuffer != nullptr);
+
+ unsigned int size = readableBuffer->GetSize();
+ BOOST_CHECK(size == 1356);
+
+ const unsigned char* readableData = readableBuffer->GetReadableData();
+ BOOST_CHECK(readableData != nullptr);
+
+ unsigned int offset = 0;
+
+ // Post-optimisation network
+ // Network entity
+ VerifyTimelineEntityBinaryPacket(optNetGuid, readableData, offset);
+
+ // Entity - Type relationship
+ VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::LabelLink,
+ EmptyOptional(),
+ optNetGuid,
+ LabelsAndEventClasses::NETWORK_GUID,
+ readableData,
+ offset);
+
+ // Type label relationship
+ VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::LabelLink,
+ EmptyOptional(),
+ EmptyOptional(),
+ LabelsAndEventClasses::TYPE_GUID,
+ readableData,
+ offset);
+
+ // Input layer
+ // Input layer entity
+ VerifyTimelineEntityBinaryPacket(input->GetGuid(), readableData, offset);
+
+ // Name Entity
+ VerifyTimelineLabelBinaryPacket(EmptyOptional(), "input", readableData, offset);
+
+ // Entity - Name relationship
+ VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::LabelLink,
+ EmptyOptional(),
+ input->GetGuid(),
+ EmptyOptional(),
+ readableData,
+ offset);
+
+ // Name label relationship
+ VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::LabelLink,
+ EmptyOptional(),
+ EmptyOptional(),
+ LabelsAndEventClasses::NAME_GUID,
+ readableData,
+ offset);
+
+ // Entity - Type relationship
+ VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::LabelLink,
+ EmptyOptional(),
+ input->GetGuid(),
+ EmptyOptional(),
+ readableData,
+ offset);
+
+ // Type label relationship
+ VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::LabelLink,
+ EmptyOptional(),
+ EmptyOptional(),
+ LabelsAndEventClasses::TYPE_GUID,
+ readableData,
+ offset);
+
+ // Network - Input layer relationship
+ VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::RetentionLink,
+ EmptyOptional(),
+ optNetGuid,
+ input->GetGuid(),
+ readableData,
+ offset);
+
+ // Normalization layer
+ // Normalization layer entity
+ VerifyTimelineEntityBinaryPacket(normalize->GetGuid(), readableData, offset);
+
+ // Name entity
+ VerifyTimelineLabelBinaryPacket(EmptyOptional(), "normalization", readableData, offset);
+
+ // Entity - Name relationship
+ VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::LabelLink,
+ EmptyOptional(),
+ normalize->GetGuid(),
+ EmptyOptional(),
+ readableData,
+ offset);
+
+ // Name label relationship
+ VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::LabelLink,
+ EmptyOptional(),
+ EmptyOptional(),
+ LabelsAndEventClasses::NAME_GUID,
+ readableData,
+ offset);
+
+ // Entity - Type relationship
+ VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::LabelLink,
+ EmptyOptional(),
+ normalize->GetGuid(),
+ EmptyOptional(),
+ readableData,
+ offset);
+
+ // Type label relationship
+ VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::LabelLink,
+ EmptyOptional(),
+ EmptyOptional(),
+ LabelsAndEventClasses::TYPE_GUID,
+ readableData,
+ offset);
+
+ // Network - Normalize layer relationship
+ VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::RetentionLink,
+ EmptyOptional(),
+ optNetGuid,
+ normalize->GetGuid(),
+ readableData,
+ offset);
+
+ // Input layer - Normalize layer relationship
+ VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::RetentionLink,
+ EmptyOptional(),
+ input->GetGuid(),
+ normalize->GetGuid(),
+ readableData,
+ offset);
+
+ // Entity - Type relationship
+ VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::LabelLink,
+ EmptyOptional(),
+ EmptyOptional(),
+ LabelsAndEventClasses::CONNECTION_GUID,
+ readableData,
+ offset);
+
+ // Type label relationship
+ VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::LabelLink,
+ EmptyOptional(),
+ EmptyOptional(),
+ LabelsAndEventClasses::TYPE_GUID,
+ readableData,
+ offset);
+
+ // Normalization workload
+ // Normalization workload entity
+ VerifyTimelineEntityBinaryPacket(EmptyOptional(), readableData, offset);
+
+ // Entity - Type relationship
+ VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::LabelLink,
+ EmptyOptional(),
+ EmptyOptional(),
+ EmptyOptional(),
+ readableData,
+ offset);
+
+ // Type label relationship
+ VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::LabelLink,
+ EmptyOptional(),
+ EmptyOptional(),
+ LabelsAndEventClasses::TYPE_GUID,
+ readableData,
+ offset);
+
+ // BackendId entity
+ VerifyTimelineLabelBinaryPacket(EmptyOptional(), "CpuRef", readableData, offset);
+
+ // Entity - BackendId relationship
+ VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::LabelLink,
+ EmptyOptional(),
+ EmptyOptional(),
+ EmptyOptional(),
+ readableData,
+ offset);
+
+ // BackendId label relationship
+ VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::LabelLink,
+ EmptyOptional(),
+ EmptyOptional(),
+ LabelsAndEventClasses::BACKENDID_GUID,
+ readableData,
+ offset);
+
+ // Normalize layer - Normalize workload relationship
+ VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::RetentionLink,
+ EmptyOptional(),
+ normalize->GetGuid(),
+ EmptyOptional(),
+ readableData,
+ offset);
+
+ // Output layer
+ // Output layer entity
+ VerifyTimelineEntityBinaryPacket(output->GetGuid(), readableData, offset);
+
+ // Name entity
+ VerifyTimelineLabelBinaryPacket(EmptyOptional(), "output", readableData, offset);
+
+ // Entity - Name relationship
+ VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::LabelLink,
+ EmptyOptional(),
+ output->GetGuid(),
+ EmptyOptional(),
+ readableData,
+ offset);
+
+ // Name label relationship
+ VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::LabelLink,
+ EmptyOptional(),
+ EmptyOptional(),
+ LabelsAndEventClasses::NAME_GUID,
+ readableData,
+ offset);
+
+ // Entity - Type relationship
+ VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::LabelLink,
+ EmptyOptional(),
+ output->GetGuid(),
+ EmptyOptional(),
+ readableData,
+ offset);
+
+ // Type label relationship
+ VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::LabelLink,
+ EmptyOptional(),
+ EmptyOptional(),
+ LabelsAndEventClasses::TYPE_GUID,
+ readableData,
+ offset);
+
+ // Network - Output layer relationship
+ VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::RetentionLink,
+ EmptyOptional(),
+ optNetGuid,
+ output->GetGuid(),
+ readableData,
+ offset);
+
+ // Normalize layer - Output layer relationship
+ VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::RetentionLink,
+ EmptyOptional(),
+ normalize->GetGuid(),
+ output->GetGuid(),
+ readableData,
+ offset);
+
+ // Entity - Type relationship
+ VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::LabelLink,
+ EmptyOptional(),
+ EmptyOptional(),
+ LabelsAndEventClasses::CONNECTION_GUID,
+ readableData,
+ offset);
+
+ // Type label relationship
+ VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::LabelLink,
+ EmptyOptional(),
+ EmptyOptional(),
+ LabelsAndEventClasses::TYPE_GUID,
+ readableData,
+ offset);
+
+ bufferManager.MarkRead(readableBuffer);
+}
+
+BOOST_AUTO_TEST_CASE(ProfilingPostOptimisationStructureCpuRef)
+{
+ VerifyPostOptimisationStructureTestImpl(armnn::Compute::CpuRef);
+}
+
BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/backends/cl/test/ClRuntimeTests.cpp b/src/backends/cl/test/ClRuntimeTests.cpp
index c6da261c15..9aa36173d0 100644
--- a/src/backends/cl/test/ClRuntimeTests.cpp
+++ b/src/backends/cl/test/ClRuntimeTests.cpp
@@ -8,6 +8,7 @@
#include <LeakChecking.hpp>
#include <backendsCommon/test/RuntimeTestImpl.hpp>
+#include <test/ProfilingTestUtils.hpp>
#include <boost/core/ignore_unused.hpp>
#include <boost/test/unit_test.hpp>
@@ -148,4 +149,9 @@ BOOST_AUTO_TEST_CASE(RuntimeMemoryUsage)
}
#endif
+BOOST_AUTO_TEST_CASE(ProfilingPostOptimisationStructureGpuAcc)
+{
+ VerifyPostOptimisationStructureTestImpl(armnn::Compute::GpuAcc);
+}
+
BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/backends/neon/test/NeonRuntimeTests.cpp b/src/backends/neon/test/NeonRuntimeTests.cpp
index 129cd1afe3..2aaf422a68 100644
--- a/src/backends/neon/test/NeonRuntimeTests.cpp
+++ b/src/backends/neon/test/NeonRuntimeTests.cpp
@@ -8,6 +8,7 @@
#include <LeakChecking.hpp>
#include <backendsCommon/test/RuntimeTestImpl.hpp>
+#include <test/ProfilingTestUtils.hpp>
#include <boost/test/unit_test.hpp>
@@ -65,4 +66,9 @@ BOOST_AUTO_TEST_CASE(RuntimeMemoryLeaksCpuAcc)
}
#endif
+BOOST_AUTO_TEST_CASE(ProfilingPostOptimisationStructureCpuAcc)
+{
+ VerifyPostOptimisationStructureTestImpl(armnn::Compute::CpuAcc);
+}
+
BOOST_AUTO_TEST_SUITE_END() \ No newline at end of file
diff --git a/src/profiling/LabelsAndEventClasses.cpp b/src/profiling/LabelsAndEventClasses.cpp
index a00562db9c..2424104042 100644
--- a/src/profiling/LabelsAndEventClasses.cpp
+++ b/src/profiling/LabelsAndEventClasses.cpp
@@ -17,6 +17,7 @@ ProfilingGuidGenerator LabelsAndEventClasses::m_GuidGenerator;
std::string LabelsAndEventClasses::NAME_LABEL("name");
std::string LabelsAndEventClasses::TYPE_LABEL("type");
std::string LabelsAndEventClasses::INDEX_LABEL("index");
+std::string LabelsAndEventClasses::BACKENDID_LABEL("backendId");
ProfilingStaticGuid LabelsAndEventClasses::NAME_GUID(
m_GuidGenerator.GenerateStaticId(LabelsAndEventClasses::NAME_LABEL));
@@ -24,6 +25,23 @@ ProfilingStaticGuid LabelsAndEventClasses::TYPE_GUID(
m_GuidGenerator.GenerateStaticId(LabelsAndEventClasses::TYPE_LABEL));
ProfilingStaticGuid LabelsAndEventClasses::INDEX_GUID(
m_GuidGenerator.GenerateStaticId(LabelsAndEventClasses::INDEX_LABEL));
+ProfilingStaticGuid LabelsAndEventClasses::BACKENDID_GUID(
+ m_GuidGenerator.GenerateStaticId(LabelsAndEventClasses::BACKENDID_LABEL));
+
+// Common types
+std::string LabelsAndEventClasses::LAYER("layer");
+std::string LabelsAndEventClasses::WORKLOAD("workload");
+std::string LabelsAndEventClasses::NETWORK("network");
+std::string LabelsAndEventClasses::CONNECTION("connection");
+
+ProfilingStaticGuid LabelsAndEventClasses::LAYER_GUID(
+ m_GuidGenerator.GenerateStaticId(LabelsAndEventClasses::LAYER));
+ProfilingStaticGuid LabelsAndEventClasses::WORKLOAD_GUID(
+ m_GuidGenerator.GenerateStaticId(LabelsAndEventClasses::WORKLOAD));
+ProfilingStaticGuid LabelsAndEventClasses::NETWORK_GUID(
+ m_GuidGenerator.GenerateStaticId(LabelsAndEventClasses::NETWORK));
+ProfilingStaticGuid LabelsAndEventClasses::CONNECTION_GUID(
+ m_GuidGenerator.GenerateStaticId(LabelsAndEventClasses::CONNECTION));
// Event Class GUIDs
ProfilingStaticGuid LabelsAndEventClasses::ARMNN_PROFILING_SOL_EVENT_CLASS(
diff --git a/src/profiling/LabelsAndEventClasses.hpp b/src/profiling/LabelsAndEventClasses.hpp
index daa33addab..c2082dd9e5 100644
--- a/src/profiling/LabelsAndEventClasses.hpp
+++ b/src/profiling/LabelsAndEventClasses.hpp
@@ -22,9 +22,21 @@ public:
static std::string NAME_LABEL;
static std::string TYPE_LABEL;
static std::string INDEX_LABEL;
+ static std::string BACKENDID_LABEL;
static ProfilingStaticGuid NAME_GUID;
static ProfilingStaticGuid TYPE_GUID;
static ProfilingStaticGuid INDEX_GUID;
+ static ProfilingStaticGuid BACKENDID_GUID;
+
+ // Common types
+ static std::string LAYER;
+ static std::string WORKLOAD;
+ static std::string NETWORK;
+ static std::string CONNECTION;
+ static ProfilingStaticGuid LAYER_GUID;
+ static ProfilingStaticGuid WORKLOAD_GUID;
+ static ProfilingStaticGuid NETWORK_GUID;
+ static ProfilingStaticGuid CONNECTION_GUID;
// Event Class GUIDs
static ProfilingStaticGuid ARMNN_PROFILING_SOL_EVENT_CLASS;
diff --git a/src/profiling/ProfilingService.hpp b/src/profiling/ProfilingService.hpp
index 9fc642fe9d..f9b057c68b 100644
--- a/src/profiling/ProfilingService.hpp
+++ b/src/profiling/ProfilingService.hpp
@@ -77,6 +77,9 @@ public:
std::unique_ptr<ISendTimelinePacket> GetSendTimelinePacket() const;
+ /// Check if the profiling is enabled
+ bool IsEnabled() { return m_Options.m_EnableProfiling; }
+
private:
// Copy/move constructors/destructors and copy/move assignment operators are deleted
ProfilingService(const ProfilingService&) = delete;
@@ -201,6 +204,11 @@ protected:
{
return instance.m_SendCounterPacket.WaitForPacketSent(timeout);
}
+
+ BufferManager& GetBufferManager(ProfilingService& instance)
+ {
+ return instance.m_BufferManager;
+ }
};
} // namespace profiling
diff --git a/src/profiling/TimelineUtilityMethods.cpp b/src/profiling/TimelineUtilityMethods.cpp
index c1ae610e49..d540c5970b 100644
--- a/src/profiling/TimelineUtilityMethods.cpp
+++ b/src/profiling/TimelineUtilityMethods.cpp
@@ -13,25 +13,60 @@ namespace armnn
namespace profiling
{
+std::unique_ptr<TimelineUtilityMethods> TimelineUtilityMethods::GetTimelineUtils()
+{
+ if (ProfilingService::Instance().IsEnabled())
+ {
+ std::unique_ptr<ISendTimelinePacket> sendTimelinepacket = ProfilingService::Instance().GetSendTimelinePacket();
+ return std::make_unique<TimelineUtilityMethods>(sendTimelinepacket);
+ }
+ else
+ {
+ std::unique_ptr<TimelineUtilityMethods> empty;
+ return empty;
+ }
+}
+
+
void TimelineUtilityMethods::SendWellKnownLabelsAndEventClasses()
{
// Send the "name" label, this call throws in case of error
- m_SendTimelinePacket.SendTimelineLabelBinaryPacket(LabelsAndEventClasses::NAME_GUID,
- LabelsAndEventClasses::NAME_LABEL);
+ m_SendTimelinePacket->SendTimelineLabelBinaryPacket(LabelsAndEventClasses::NAME_GUID,
+ LabelsAndEventClasses::NAME_LABEL);
// Send the "type" label, this call throws in case of error
- m_SendTimelinePacket.SendTimelineLabelBinaryPacket(LabelsAndEventClasses::TYPE_GUID,
- LabelsAndEventClasses::TYPE_LABEL);
+ m_SendTimelinePacket->SendTimelineLabelBinaryPacket(LabelsAndEventClasses::TYPE_GUID,
+ LabelsAndEventClasses::TYPE_LABEL);
// Send the "index" label, this call throws in case of error
- m_SendTimelinePacket.SendTimelineLabelBinaryPacket(LabelsAndEventClasses::INDEX_GUID,
- LabelsAndEventClasses::INDEX_LABEL);
+ m_SendTimelinePacket->SendTimelineLabelBinaryPacket(LabelsAndEventClasses::INDEX_GUID,
+ LabelsAndEventClasses::INDEX_LABEL);
+
+ // Send the "backendId" label, this call throws in case of error
+ m_SendTimelinePacket->SendTimelineLabelBinaryPacket(LabelsAndEventClasses::BACKENDID_GUID,
+ LabelsAndEventClasses::BACKENDID_LABEL);
+
+ // Send the "layer" label, this call throws in case of error
+ m_SendTimelinePacket->SendTimelineLabelBinaryPacket(LabelsAndEventClasses::LAYER_GUID,
+ LabelsAndEventClasses::LAYER);
+
+ // Send the "workload" label, this call throws in case of error
+ m_SendTimelinePacket->SendTimelineLabelBinaryPacket(LabelsAndEventClasses::WORKLOAD_GUID,
+ LabelsAndEventClasses::WORKLOAD);
+
+ // Send the "network" label, this call throws in case of error
+ m_SendTimelinePacket->SendTimelineLabelBinaryPacket(LabelsAndEventClasses::NETWORK_GUID,
+ LabelsAndEventClasses::NETWORK);
+
+ // Send the "connection" label, this call throws in case of error
+ m_SendTimelinePacket->SendTimelineLabelBinaryPacket(LabelsAndEventClasses::CONNECTION_GUID,
+ LabelsAndEventClasses::CONNECTION);
// Send the "start of life" event class, this call throws in case of error
- m_SendTimelinePacket.SendTimelineEventClassBinaryPacket(LabelsAndEventClasses::ARMNN_PROFILING_SOL_EVENT_CLASS);
+ m_SendTimelinePacket->SendTimelineEventClassBinaryPacket(LabelsAndEventClasses::ARMNN_PROFILING_SOL_EVENT_CLASS);
// Send the "end of life" event class, this call throws in case of error
- m_SendTimelinePacket.SendTimelineEventClassBinaryPacket(LabelsAndEventClasses::ARMNN_PROFILING_EOL_EVENT_CLASS);
+ m_SendTimelinePacket->SendTimelineEventClassBinaryPacket(LabelsAndEventClasses::ARMNN_PROFILING_EOL_EVENT_CLASS);
}
ProfilingDynamicGuid TimelineUtilityMethods::CreateNamedTypedEntity(const std::string& name, const std::string& type)
@@ -56,7 +91,7 @@ ProfilingDynamicGuid TimelineUtilityMethods::CreateNamedTypedEntity(const std::s
return entityGuid;
}
-void TimelineUtilityMethods::CreateNamedTypedEntity(ProfilingDynamicGuid entityGuid,
+void TimelineUtilityMethods::CreateNamedTypedEntity(ProfilingGuid entityGuid,
const std::string& name,
const std::string& type)
{
@@ -73,7 +108,7 @@ void TimelineUtilityMethods::CreateNamedTypedEntity(ProfilingDynamicGuid entityG
}
// Send Entity Binary Packet of the entity to the external profiling service
- m_SendTimelinePacket.SendTimelineEntityBinaryPacket(entityGuid);
+ m_SendTimelinePacket->SendTimelineEntityBinaryPacket(entityGuid);
// Create name entity and send the relationship of the entity with the given name
NameEntity(entityGuid, name);
@@ -82,6 +117,26 @@ void TimelineUtilityMethods::CreateNamedTypedEntity(ProfilingDynamicGuid entityG
TypeEntity(entityGuid, type);
}
+void TimelineUtilityMethods::CreateNamedTypedEntity(ProfilingGuid entityGuid,
+ const std::string& name,
+ ProfilingStaticGuid typeGuid)
+{
+ // Check that the entity name is valid
+ if (name.empty())
+ {
+ throw InvalidArgumentException("Invalid entity name, the entity name cannot be empty");
+ }
+
+ // Send Entity Binary Packet of the entity to the external profiling service
+ m_SendTimelinePacket->SendTimelineEntityBinaryPacket(entityGuid);
+
+ // Create name entity and send the relationship of the entity with the given name
+ NameEntity(entityGuid, name);
+
+ // Create type entity and send the relationship of the entity with the given type
+ MarkEntityWithType(entityGuid, typeGuid);
+}
+
ProfilingStaticGuid TimelineUtilityMethods::DeclareLabel(const std::string& labelName)
{
// Check that the label name is valid
@@ -95,52 +150,74 @@ ProfilingStaticGuid TimelineUtilityMethods::DeclareLabel(const std::string& labe
ProfilingStaticGuid labelGuid = ProfilingService::Instance().GenerateStaticId(labelName);
// Send the new label to the external profiling service, this call throws in case of error
- m_SendTimelinePacket.SendTimelineLabelBinaryPacket(labelGuid, labelName);
+ m_SendTimelinePacket->SendTimelineLabelBinaryPacket(labelGuid, labelName);
return labelGuid;
}
-void TimelineUtilityMethods::CreateTypedLabel(ProfilingGuid entityGuid,
- const std::string& entityName,
- ProfilingStaticGuid labelTypeGuid)
+void TimelineUtilityMethods::MarkEntityWithLabel(ProfilingGuid entityGuid,
+ const std::string& labelName,
+ ProfilingStaticGuid labelTypeGuid)
{
- // Check that the entity name is valid
- if (entityName.empty())
+ // Check that the label name is valid
+ if (labelName.empty())
{
- // The entity name is invalid
+ // The label name is invalid
throw InvalidArgumentException("Invalid entity name, the entity name cannot be empty");
}
- // Declare a label with the entity's name, this call throws in case of error
- ProfilingStaticGuid labelGuid = DeclareLabel(entityName);
+ // Declare a label with the label's name, this call throws in case of error
+ ProfilingStaticGuid labelGuid = DeclareLabel(labelName);
+
+ // Generate a GUID for the label relationship
+ ProfilingDynamicGuid relationshipGuid = ProfilingService::Instance().NextGuid();
+
+ // Send the new label link to the external profiling service, this call throws in case of error
+ m_SendTimelinePacket->SendTimelineRelationshipBinaryPacket(ProfilingRelationshipType::LabelLink,
+ relationshipGuid,
+ entityGuid,
+ labelGuid);
+
+ // Generate a GUID for the label relationship
+ ProfilingDynamicGuid relationshipLabelGuid = ProfilingService::Instance().NextGuid();
+
+ // Send the new label link to the external profiling service, this call throws in case of error
+ m_SendTimelinePacket->SendTimelineRelationshipBinaryPacket(ProfilingRelationshipType::LabelLink,
+ relationshipLabelGuid,
+ relationshipGuid,
+ labelTypeGuid);
+}
+void TimelineUtilityMethods::MarkEntityWithType(ProfilingGuid entityGuid,
+ ProfilingStaticGuid typeNameGuid)
+{
// Generate a GUID for the label relationship
ProfilingDynamicGuid relationshipGuid = ProfilingService::Instance().NextGuid();
// Send the new label link to the external profiling service, this call throws in case of error
- m_SendTimelinePacket.SendTimelineRelationshipBinaryPacket(ProfilingRelationshipType::LabelLink,
- relationshipGuid,
- entityGuid,
- labelGuid);
+ m_SendTimelinePacket->SendTimelineRelationshipBinaryPacket(ProfilingRelationshipType::LabelLink,
+ relationshipGuid,
+ entityGuid,
+ typeNameGuid);
// Generate a GUID for the label relationship
ProfilingDynamicGuid relationshipLabelGuid = ProfilingService::Instance().NextGuid();
// Send the new label link to the external profiling service, this call throws in case of error
- m_SendTimelinePacket.SendTimelineRelationshipBinaryPacket(ProfilingRelationshipType::LabelLink,
- relationshipLabelGuid,
- relationshipGuid,
- labelTypeGuid);
+ m_SendTimelinePacket->SendTimelineRelationshipBinaryPacket(ProfilingRelationshipType::LabelLink,
+ relationshipLabelGuid,
+ relationshipGuid,
+ LabelsAndEventClasses::TYPE_GUID);
}
void TimelineUtilityMethods::NameEntity(ProfilingGuid entityGuid, const std::string& name)
{
- CreateTypedLabel(entityGuid, name, LabelsAndEventClasses::NAME_GUID);
+ MarkEntityWithLabel(entityGuid, name, LabelsAndEventClasses::NAME_GUID);
}
void TimelineUtilityMethods::TypeEntity(ProfilingGuid entityGuid, const std::string& type)
{
- CreateTypedLabel(entityGuid, type, LabelsAndEventClasses::TYPE_GUID);
+ MarkEntityWithLabel(entityGuid, type, LabelsAndEventClasses::TYPE_GUID);
}
ProfilingDynamicGuid TimelineUtilityMethods::CreateNamedTypedChildEntity(ProfilingGuid parentEntityGuid,
@@ -168,15 +245,15 @@ ProfilingDynamicGuid TimelineUtilityMethods::CreateNamedTypedChildEntity(Profili
ProfilingDynamicGuid retentionLinkGuid = ProfilingService::Instance().NextGuid();
// Send the new retention link to the external profiling service, this call throws in case of error
- m_SendTimelinePacket.SendTimelineRelationshipBinaryPacket(ProfilingRelationshipType::RetentionLink,
- retentionLinkGuid,
- parentEntityGuid,
- childEntityGuid);
+ m_SendTimelinePacket->SendTimelineRelationshipBinaryPacket(ProfilingRelationshipType::RetentionLink,
+ retentionLinkGuid,
+ parentEntityGuid,
+ childEntityGuid);
return childEntityGuid;
}
-void TimelineUtilityMethods::CreateNamedTypedChildEntity(ProfilingDynamicGuid childEntityGuid,
+void TimelineUtilityMethods::CreateNamedTypedChildEntity(ProfilingGuid childEntityGuid,
ProfilingGuid parentEntityGuid,
const std::string& entityName,
const std::string& entityType)
@@ -202,10 +279,76 @@ void TimelineUtilityMethods::CreateNamedTypedChildEntity(ProfilingDynamicGuid ch
ProfilingDynamicGuid retentionLinkGuid = ProfilingService::Instance().NextGuid();
// Send the new retention link to the external profiling service, this call throws in case of error
- m_SendTimelinePacket.SendTimelineRelationshipBinaryPacket(ProfilingRelationshipType::RetentionLink,
- retentionLinkGuid,
- parentEntityGuid,
- childEntityGuid);
+ m_SendTimelinePacket->SendTimelineRelationshipBinaryPacket(ProfilingRelationshipType::RetentionLink,
+ retentionLinkGuid,
+ parentEntityGuid,
+ childEntityGuid);
+}
+
+void TimelineUtilityMethods::CreateNamedTypedChildEntity(ProfilingGuid childEntityGuid,
+ ProfilingGuid parentEntityGuid,
+ const std::string& entityName,
+ ProfilingStaticGuid typeGuid)
+{
+ // Check that the entity name is valid
+ if (entityName.empty())
+ {
+ // The entity name is invalid
+ throw InvalidArgumentException("Invalid entity name, the entity name cannot be empty");
+ }
+
+ // Create a named type entity from the given guid, name and type, this call throws in case of error
+ CreateNamedTypedEntity(childEntityGuid, entityName, typeGuid);
+
+ // Generate a GUID for the retention link relationship
+ ProfilingDynamicGuid retentionLinkGuid = ProfilingService::Instance().NextGuid();
+
+ // Send the new retention link to the external profiling service, this call throws in case of error
+ m_SendTimelinePacket->SendTimelineRelationshipBinaryPacket(ProfilingRelationshipType::RetentionLink,
+ retentionLinkGuid,
+ parentEntityGuid,
+ childEntityGuid);
+}
+
+ProfilingDynamicGuid TimelineUtilityMethods::CreateRelationship(ProfilingRelationshipType relationshipType,
+ ProfilingGuid headGuid,
+ ProfilingGuid tailGuid)
+{
+ // Generate a GUID for the relationship
+ ProfilingDynamicGuid relationshipGuid = ProfilingService::Instance().NextGuid();
+
+ // Send the new retention link to the external profiling service, this call throws in case of error
+ m_SendTimelinePacket->SendTimelineRelationshipBinaryPacket(relationshipType,
+ relationshipGuid,
+ headGuid,
+ tailGuid);
+ return relationshipGuid;
+}
+
+ProfilingDynamicGuid TimelineUtilityMethods::CreateConnectionRelationship(ProfilingRelationshipType relationshipType,
+ ProfilingGuid headGuid,
+ ProfilingGuid tailGuid)
+{
+ // Generate a GUID for the relationship
+ ProfilingDynamicGuid relationshipGuid = ProfilingService::Instance().NextGuid();
+
+ // Send the new retention link to the external profiling service, this call throws in case of error
+ m_SendTimelinePacket->SendTimelineRelationshipBinaryPacket(relationshipType,
+ relationshipGuid,
+ headGuid,
+ tailGuid);
+
+ MarkEntityWithType(relationshipGuid, LabelsAndEventClasses::CONNECTION_GUID);
+ return relationshipGuid;
+}
+
+void TimelineUtilityMethods::CreateTypedEntity(ProfilingGuid entityGuid, ProfilingStaticGuid entityTypeGuid)
+{
+ // Send Entity Binary Packet of the entity to the external profiling service
+ m_SendTimelinePacket->SendTimelineEntityBinaryPacket(entityGuid);
+
+ // Create type entity and send the relationship of the entity with the given type
+ MarkEntityWithType(entityGuid, entityTypeGuid);
}
ProfilingDynamicGuid TimelineUtilityMethods::RecordEvent(ProfilingGuid entityGuid, ProfilingStaticGuid eventClassGuid)
@@ -220,25 +363,25 @@ ProfilingDynamicGuid TimelineUtilityMethods::RecordEvent(ProfilingGuid entityGui
ProfilingDynamicGuid eventGuid = ProfilingService::Instance().NextGuid();
// Send the new timeline event to the external profiling service, this call throws in case of error
- m_SendTimelinePacket.SendTimelineEventBinaryPacket(timestamp, threadId, eventGuid);
+ m_SendTimelinePacket->SendTimelineEventBinaryPacket(timestamp, threadId, eventGuid);
// Generate a GUID for the execution link
ProfilingDynamicGuid executionLinkId = ProfilingService::Instance().NextGuid();
// Send the new execution link to the external profiling service, this call throws in case of error
- m_SendTimelinePacket.SendTimelineRelationshipBinaryPacket(ProfilingRelationshipType::ExecutionLink,
- executionLinkId,
- entityGuid,
- eventGuid);
+ m_SendTimelinePacket->SendTimelineRelationshipBinaryPacket(ProfilingRelationshipType::ExecutionLink,
+ executionLinkId,
+ entityGuid,
+ eventGuid);
// Generate a GUID for the data relationship link
ProfilingDynamicGuid eventClassLinkId = ProfilingService::Instance().NextGuid();
// Send the new data relationship link to the external profiling service, this call throws in case of error
- m_SendTimelinePacket.SendTimelineRelationshipBinaryPacket(ProfilingRelationshipType::DataLink,
- eventClassLinkId,
- entityGuid,
- eventClassGuid);
+ m_SendTimelinePacket->SendTimelineRelationshipBinaryPacket(ProfilingRelationshipType::DataLink,
+ eventClassLinkId,
+ eventGuid,
+ eventClassGuid);
return eventGuid;
}
diff --git a/src/profiling/TimelineUtilityMethods.hpp b/src/profiling/TimelineUtilityMethods.hpp
index 3683ed3383..8e071611a2 100644
--- a/src/profiling/TimelineUtilityMethods.hpp
+++ b/src/profiling/TimelineUtilityMethods.hpp
@@ -17,18 +17,34 @@ namespace profiling
class TimelineUtilityMethods
{
public:
- TimelineUtilityMethods(ISendTimelinePacket& sendTimelinePacket)
- : m_SendTimelinePacket(sendTimelinePacket)
- {}
+
+ // static factory method which will return a pointer to a timelie utility methods
+ // object if profiling is enabled. Otherwise will return a null unique_ptr
+ static std::unique_ptr<TimelineUtilityMethods> GetTimelineUtils();
+
+ TimelineUtilityMethods(std::unique_ptr<ISendTimelinePacket>& sendTimelinePacket)
+ : m_SendTimelinePacket(std::move(sendTimelinePacket)) {}
+
+ TimelineUtilityMethods(TimelineUtilityMethods&& other)
+ : m_SendTimelinePacket(std::move(other.m_SendTimelinePacket)) {}
+
+ TimelineUtilityMethods(const TimelineUtilityMethods& other) = delete;
+
+ TimelineUtilityMethods& operator=(const TimelineUtilityMethods& other) = delete;
+
+ TimelineUtilityMethods& operator=(TimelineUtilityMethods&& other) = default;
+
~TimelineUtilityMethods() = default;
void SendWellKnownLabelsAndEventClasses();
ProfilingDynamicGuid CreateNamedTypedEntity(const std::string& name, const std::string& type);
- void CreateNamedTypedEntity(ProfilingDynamicGuid entityGuid, const std::string& name, const std::string& type);
+ void CreateNamedTypedEntity(ProfilingGuid entityGuid, const std::string& name, const std::string& type);
+
+ void CreateNamedTypedEntity(ProfilingGuid entityGuid, const std::string& name, ProfilingStaticGuid typeGuid);
- void CreateTypedLabel(ProfilingGuid entityGuid, const std::string& entityName, ProfilingStaticGuid labelTypeGuid);
+ void MarkEntityWithLabel(ProfilingGuid entityGuid, const std::string &labelName, ProfilingStaticGuid labelLinkGuid);
ProfilingStaticGuid DeclareLabel(const std::string& labelName);
@@ -40,15 +56,34 @@ public:
const std::string& entityName,
const std::string& entityType);
- void CreateNamedTypedChildEntity(ProfilingDynamicGuid entityGuid,
+ void CreateNamedTypedChildEntity(ProfilingGuid entityGuid,
ProfilingGuid parentEntityGuid,
const std::string& entityName,
const std::string& entityType);
+ void CreateNamedTypedChildEntity(ProfilingGuid entityGuid,
+ ProfilingGuid parentEntityGuid,
+ const std::string& entityName,
+ ProfilingStaticGuid typeGuid);
+
+ ProfilingDynamicGuid CreateRelationship(ProfilingRelationshipType relationshipType,
+ ProfilingGuid headGuid,
+ ProfilingGuid tailGuid);
+
+ ProfilingDynamicGuid CreateConnectionRelationship(ProfilingRelationshipType relationshipType,
+ ProfilingGuid headGuid,
+ ProfilingGuid tailGuid);
+
+ void CreateTypedEntity(ProfilingGuid entityGuid, ProfilingStaticGuid typeGuid);
+
+ void MarkEntityWithType(ProfilingGuid entityGuid, ProfilingStaticGuid typeNameGuid);
+
ProfilingDynamicGuid RecordEvent(ProfilingGuid entityGuid, ProfilingStaticGuid eventClassGuid);
+ void Commit() { m_SendTimelinePacket->Commit(); }
+
private:
- ISendTimelinePacket& m_SendTimelinePacket;
+ std::unique_ptr<ISendTimelinePacket> m_SendTimelinePacket;
};
} // namespace profiling
diff --git a/src/profiling/test/ProfilingTestUtils.cpp b/src/profiling/test/ProfilingTestUtils.cpp
new file mode 100644
index 0000000000..7f18ef33d6
--- /dev/null
+++ b/src/profiling/test/ProfilingTestUtils.cpp
@@ -0,0 +1,818 @@
+//
+// Copyright © 2019 Arm Ltd. All rights reserved.
+// SPDX-License-Identifier: MIT
+//
+
+#include "ProfilingTestUtils.hpp"
+#include "ProfilingUtils.hpp"
+
+#include <armnn/Descriptors.hpp>
+#include <LabelsAndEventClasses.hpp>
+#include <ProfilingService.hpp>
+
+#include <boost/test/unit_test.hpp>
+
+inline unsigned int OffsetToNextWord(unsigned int numberOfBytes)
+{
+ unsigned int uint32_t_size = sizeof(uint32_t);
+
+ unsigned int remainder = numberOfBytes % uint32_t_size;
+ if (remainder == 0)
+ {
+ return numberOfBytes;
+ }
+
+ return numberOfBytes + uint32_t_size - remainder;
+}
+
+void VerifyTimelineLabelBinaryPacket(Optional<ProfilingGuid> guid,
+ const std::string& label,
+ const unsigned char* readableData,
+ unsigned int& offset)
+{
+ BOOST_ASSERT(readableData);
+
+ // Utils
+ unsigned int uint32_t_size = sizeof(uint32_t);
+ unsigned int uint64_t_size = sizeof(uint64_t);
+ unsigned int label_size = boost::numeric_cast<unsigned int>(label.size());
+
+ // Check the TimelineLabelBinaryPacket header
+ uint32_t entityBinaryPacketHeaderWord0 = ReadUint32(readableData, offset);
+ uint32_t entityBinaryPacketFamily = (entityBinaryPacketHeaderWord0 >> 26) & 0x0000003F;
+ uint32_t entityBinaryPacketClass = (entityBinaryPacketHeaderWord0 >> 19) & 0x0000007F;
+ uint32_t entityBinaryPacketType = (entityBinaryPacketHeaderWord0 >> 16) & 0x00000007;
+ uint32_t entityBinaryPacketStreamId = (entityBinaryPacketHeaderWord0 >> 0) & 0x00000007;
+ BOOST_CHECK(entityBinaryPacketFamily == 1);
+ BOOST_CHECK(entityBinaryPacketClass == 0);
+ BOOST_CHECK(entityBinaryPacketType == 1);
+ BOOST_CHECK(entityBinaryPacketStreamId == 0);
+ offset += uint32_t_size;
+ uint32_t entityBinaryPacketHeaderWord1 = ReadUint32(readableData, offset);
+ uint32_t eventBinaryPacketSequenceNumber = (entityBinaryPacketHeaderWord1 >> 24) & 0x00000001;
+ uint32_t eventBinaryPacketDataLength = (entityBinaryPacketHeaderWord1 >> 0) & 0x00FFFFFF;
+ BOOST_CHECK(eventBinaryPacketSequenceNumber == 0);
+ BOOST_CHECK(eventBinaryPacketDataLength == 16 + OffsetToNextWord(label_size + 1));
+
+ // Check the decl id
+ offset += uint32_t_size;
+ uint32_t eventClassDeclId = ReadUint32(readableData, offset);
+ BOOST_CHECK(eventClassDeclId == 0);
+
+ // Check the profiling GUID
+ offset += uint32_t_size;
+ uint64_t readProfilingGuid = ReadUint64(readableData, offset);
+ if (guid.has_value())
+ {
+ BOOST_CHECK(readProfilingGuid == guid.value());
+ }
+ else
+ {
+ BOOST_CHECK(readProfilingGuid == ProfilingService::Instance().GenerateStaticId(label));
+ }
+
+ // Check the SWTrace label
+ offset += uint64_t_size;
+ uint32_t swTraceLabelLength = ReadUint32(readableData, offset);
+ BOOST_CHECK(swTraceLabelLength == label_size + 1); // Label length including the null-terminator
+ offset += uint32_t_size;
+ BOOST_CHECK(std::memcmp(readableData + offset, // Offset to the label in the buffer
+ label.data(), // The original label
+ swTraceLabelLength - 1) == 0); // The length of the label
+ BOOST_CHECK(readableData[offset + swTraceLabelLength] == '\0'); // The null-terminator
+
+ // SWTrace strings are written in blocks of words, so the offset has to be updated to the next whole word
+ offset += OffsetToNextWord(swTraceLabelLength);
+}
+
+void VerifyTimelineEventClassBinaryPacket(ProfilingGuid guid,
+ const unsigned char* readableData,
+ unsigned int& offset)
+{
+ BOOST_ASSERT(readableData);
+
+ // Utils
+ unsigned int uint32_t_size = sizeof(uint32_t);
+ unsigned int uint64_t_size = sizeof(uint64_t);
+
+ // Check the TimelineEventClassBinaryPacket header
+ uint32_t entityBinaryPacketHeaderWord0 = ReadUint32(readableData, offset);
+ uint32_t entityBinaryPacketFamily = (entityBinaryPacketHeaderWord0 >> 26) & 0x0000003F;
+ uint32_t entityBinaryPacketClass = (entityBinaryPacketHeaderWord0 >> 19) & 0x0000007F;
+ uint32_t entityBinaryPacketType = (entityBinaryPacketHeaderWord0 >> 16) & 0x00000007;
+ uint32_t entityBinaryPacketStreamId = (entityBinaryPacketHeaderWord0 >> 0) & 0x00000007;
+ BOOST_CHECK(entityBinaryPacketFamily == 1);
+ BOOST_CHECK(entityBinaryPacketClass == 0);
+ BOOST_CHECK(entityBinaryPacketType == 1);
+ BOOST_CHECK(entityBinaryPacketStreamId == 0);
+ offset += uint32_t_size;
+ uint32_t entityBinaryPacketHeaderWord1 = ReadUint32(readableData, offset);
+ uint32_t eventBinaryPacketSequenceNumber = (entityBinaryPacketHeaderWord1 >> 24) & 0x00000001;
+ uint32_t eventBinaryPacketDataLength = (entityBinaryPacketHeaderWord1 >> 0) & 0x00FFFFFF;
+ BOOST_CHECK(eventBinaryPacketSequenceNumber == 0);
+ BOOST_CHECK(eventBinaryPacketDataLength == 12);
+
+ // Check the decl id
+ offset += uint32_t_size;
+ uint32_t eventClassDeclId = ReadUint32(readableData, offset);
+ BOOST_CHECK(eventClassDeclId == 2);
+
+ // Check the profiling GUID
+ offset += uint32_t_size;
+ uint64_t readProfilingGuid = ReadUint64(readableData, offset);
+ BOOST_CHECK(readProfilingGuid == guid);
+
+ // Update the offset to allow parsing to be continued after this function returns
+ offset += uint64_t_size;
+}
+
+void VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType relationshipType,
+ Optional<ProfilingGuid> relationshipGuid,
+ Optional<ProfilingGuid> headGuid,
+ Optional<ProfilingGuid> tailGuid,
+ const unsigned char* readableData,
+ unsigned int& offset)
+{
+ BOOST_ASSERT(readableData);
+
+ uint32_t relationshipTypeUint = 0;
+ switch (relationshipType)
+ {
+ case ProfilingRelationshipType::RetentionLink:
+ relationshipTypeUint = 0;
+ break;
+ case ProfilingRelationshipType::ExecutionLink:
+ relationshipTypeUint = 1;
+ break;
+ case ProfilingRelationshipType::DataLink:
+ relationshipTypeUint = 2;
+ break;
+ case ProfilingRelationshipType::LabelLink:
+ relationshipTypeUint = 3;
+ break;
+ default:
+ BOOST_ERROR("Unknown relationship type");
+ }
+
+ // Utils
+ unsigned int uint32_t_size = sizeof(uint32_t);
+ unsigned int uint64_t_size = sizeof(uint64_t);
+
+ // Check the TimelineLabelBinaryPacket header
+ uint32_t entityBinaryPacketHeaderWord0 = ReadUint32(readableData, offset);
+ uint32_t entityBinaryPacketFamily = (entityBinaryPacketHeaderWord0 >> 26) & 0x0000003F;
+ uint32_t entityBinaryPacketClass = (entityBinaryPacketHeaderWord0 >> 19) & 0x0000007F;
+ uint32_t entityBinaryPacketType = (entityBinaryPacketHeaderWord0 >> 16) & 0x00000007;
+ uint32_t entityBinaryPacketStreamId = (entityBinaryPacketHeaderWord0 >> 0) & 0x00000007;
+ BOOST_CHECK(entityBinaryPacketFamily == 1);
+ BOOST_CHECK(entityBinaryPacketClass == 0);
+ BOOST_CHECK(entityBinaryPacketType == 1);
+ BOOST_CHECK(entityBinaryPacketStreamId == 0);
+ offset += uint32_t_size;
+ uint32_t entityBinaryPacketHeaderWord1 = ReadUint32(readableData, offset);
+ uint32_t eventBinaryPacketSequenceNumber = (entityBinaryPacketHeaderWord1 >> 24) & 0x00000001;
+ uint32_t eventBinaryPacketDataLength = (entityBinaryPacketHeaderWord1 >> 0) & 0x00FFFFFF;
+ BOOST_CHECK(eventBinaryPacketSequenceNumber == 0);
+ BOOST_CHECK(eventBinaryPacketDataLength == 32);
+
+ // Check the decl id
+ offset += uint32_t_size;
+ uint32_t eventClassDeclId = ReadUint32(readableData, offset);
+ BOOST_CHECK(eventClassDeclId == 3);
+
+ // Check the relationship type
+ offset += uint32_t_size;
+ uint32_t readRelationshipTypeUint = ReadUint32(readableData, offset);
+ BOOST_CHECK(readRelationshipTypeUint == relationshipTypeUint);
+
+ // Check the relationship GUID
+ offset += uint32_t_size;
+ uint64_t readRelationshipGuid = ReadUint64(readableData, offset);
+ if (relationshipGuid.has_value())
+ {
+ BOOST_CHECK(readRelationshipGuid == relationshipGuid.value());
+ }
+ else
+ {
+ BOOST_CHECK(readRelationshipGuid != ProfilingGuid(0));
+ }
+
+ // Check the head of relationship GUID
+ offset += uint64_t_size;
+ uint64_t readHeadRelationshipGuid = ReadUint64(readableData, offset);
+ if (headGuid.has_value())
+ {
+ BOOST_CHECK(readHeadRelationshipGuid == headGuid.value());
+ }
+ else
+ {
+ BOOST_CHECK(readHeadRelationshipGuid != ProfilingGuid(0));
+ }
+
+ // Check the tail of relationship GUID
+ offset += uint64_t_size;
+ uint64_t readTailRelationshipGuid = ReadUint64(readableData, offset);
+ if (tailGuid.has_value())
+ {
+ BOOST_CHECK(readTailRelationshipGuid == tailGuid.value());
+ }
+ else
+ {
+ BOOST_CHECK(readTailRelationshipGuid != ProfilingGuid(0));
+ }
+
+ // Update the offset to allow parsing to be continued after this function returns
+ offset += uint64_t_size;
+}
+
+void VerifyTimelineEntityBinaryPacket(Optional<ProfilingGuid> guid,
+ const unsigned char* readableData,
+ unsigned int& offset)
+{
+ BOOST_ASSERT(readableData);
+
+ // Utils
+ unsigned int uint32_t_size = sizeof(uint32_t);
+ unsigned int uint64_t_size = sizeof(uint64_t);
+
+ // Reading TimelineEntityClassBinaryPacket
+ uint32_t entityBinaryPacketHeaderWord0 = ReadUint32(readableData, offset);
+ uint32_t entityBinaryPacketFamily = (entityBinaryPacketHeaderWord0 >> 26) & 0x0000003F;
+ uint32_t entityBinaryPacketClass = (entityBinaryPacketHeaderWord0 >> 19) & 0x0000007F;
+ uint32_t entityBinaryPacketType = (entityBinaryPacketHeaderWord0 >> 16) & 0x00000007;
+ uint32_t entityBinaryPacketStreamId = (entityBinaryPacketHeaderWord0 >> 0) & 0x00000007;
+
+ BOOST_CHECK(entityBinaryPacketFamily == 1);
+ BOOST_CHECK(entityBinaryPacketClass == 0);
+ BOOST_CHECK(entityBinaryPacketType == 1);
+ BOOST_CHECK(entityBinaryPacketStreamId == 0);
+
+ offset += uint32_t_size;
+ uint32_t entityBinaryPacketHeaderWord1 = ReadUint32(readableData, offset);
+ uint32_t entityBinaryPacketSequenceNumbered = (entityBinaryPacketHeaderWord1 >> 24) & 0x00000001;
+ uint32_t entityBinaryPacketDataLength = (entityBinaryPacketHeaderWord1 >> 0) & 0x00FFFFFF;
+ BOOST_CHECK(entityBinaryPacketSequenceNumbered == 0);
+ BOOST_CHECK(entityBinaryPacketDataLength == 12);
+
+ // Check the decl_id
+ offset += uint32_t_size;
+ uint32_t entityDeclId = ReadUint32(readableData, offset);
+ BOOST_CHECK(entityDeclId == 1);
+
+ // Check the profiling GUID
+ offset += uint32_t_size;
+ uint64_t readProfilingGuid = ReadUint64(readableData, offset);
+
+ if (guid.has_value())
+ {
+ BOOST_CHECK(readProfilingGuid == guid.value());
+ }
+ else
+ {
+ BOOST_CHECK(readProfilingGuid != ProfilingGuid(0));
+ }
+
+ offset += uint64_t_size;
+}
+
+void VerifyTimelineEventBinaryPacket(Optional<uint64_t> timestamp,
+ Optional<std::thread::id> threadId,
+ Optional<ProfilingGuid> eventGuid,
+ const unsigned char* readableData,
+ unsigned int& offset)
+{
+ BOOST_ASSERT(readableData);
+
+ // Utils
+ unsigned int uint32_t_size = sizeof(uint32_t);
+ unsigned int uint64_t_size = sizeof(uint64_t);
+ unsigned int threadId_size = sizeof(std::thread::id);
+
+ // Reading TimelineEventBinaryPacket
+ uint32_t entityBinaryPacketHeaderWord0 = ReadUint32(readableData, offset);
+ uint32_t entityBinaryPacketFamily = (entityBinaryPacketHeaderWord0 >> 26) & 0x0000003F;
+ uint32_t entityBinaryPacketClass = (entityBinaryPacketHeaderWord0 >> 19) & 0x0000007F;
+ uint32_t entityBinaryPacketType = (entityBinaryPacketHeaderWord0 >> 16) & 0x00000007;
+ uint32_t entityBinaryPacketStreamId = (entityBinaryPacketHeaderWord0 >> 0) & 0x00000007;
+
+ BOOST_CHECK(entityBinaryPacketFamily == 1);
+ BOOST_CHECK(entityBinaryPacketClass == 0);
+ BOOST_CHECK(entityBinaryPacketType == 1);
+ BOOST_CHECK(entityBinaryPacketStreamId == 0);
+
+ offset += uint32_t_size;
+ uint32_t entityBinaryPacketHeaderWord1 = ReadUint32(readableData, offset);
+ uint32_t entityBinaryPacketSequenceNumbered = (entityBinaryPacketHeaderWord1 >> 24) & 0x00000001;
+ uint32_t entityBinaryPacketDataLength = (entityBinaryPacketHeaderWord1 >> 0) & 0x00FFFFFF;
+ BOOST_CHECK(entityBinaryPacketSequenceNumbered == 0);
+ BOOST_CHECK(entityBinaryPacketDataLength == 20 + threadId_size);
+
+ // Check the decl_id
+ offset += uint32_t_size;
+ uint32_t entityDeclId = ReadUint32(readableData, offset);
+ BOOST_CHECK(entityDeclId == 4);
+
+ // Check the timestamp
+ offset += uint32_t_size;
+ uint64_t readTimestamp = ReadUint64(readableData, offset);
+ if (timestamp.has_value())
+ {
+ BOOST_CHECK(readTimestamp == timestamp.value());
+ }
+ else
+ {
+ BOOST_CHECK(readTimestamp != 0);
+ }
+
+ // Check the thread id
+ offset += uint64_t_size;
+ std::vector<uint8_t> readThreadId(threadId_size, 0);
+ ReadBytes(readableData, offset, threadId_size, readThreadId.data());
+ if (threadId.has_value())
+ {
+ BOOST_CHECK(readThreadId == threadId.value());
+ }
+ else
+ {
+ BOOST_CHECK(readThreadId == std::this_thread::get_id());
+ }
+
+ // Check the event GUID
+ offset += threadId_size;
+ uint64_t readEventGuid = ReadUint64(readableData, offset);
+ if (eventGuid.has_value())
+ {
+ BOOST_CHECK(readEventGuid == eventGuid.value());
+ }
+ else
+ {
+ BOOST_CHECK(readEventGuid != ProfilingGuid(0));
+ }
+
+ offset += uint64_t_size;
+}
+
+void VerifyPostOptimisationStructureTestImpl(armnn::BackendId backendId)
+{
+ using namespace armnn;
+
+ // Create runtime in which test will run
+ armnn::IRuntime::CreationOptions options;
+ options.m_ProfilingOptions.m_EnableProfiling = true;
+ armnn::IRuntimePtr runtime(armnn::IRuntime::Create(options));
+
+ // build up the structure of the network
+ INetworkPtr net(INetwork::Create());
+
+ // Convolution details
+ TensorInfo inputInfo({ 1, 2, 5, 1 }, DataType::Float32);
+ TensorInfo weightInfo({ 3, 2, 3, 1}, DataType::Float32);
+ TensorInfo biasInfo({ 3 }, DataType::Float32);
+ TensorInfo outputInfo({ 1, 3, 7, 1}, DataType::Float32);
+ std::vector<float> weightsData{
+ 1.0f, 0.0f, 0.0f,
+ 0.0f, 2.0f, -1.5f,
+
+ 0.0f, 0.0f, 0.0f,
+ 0.2f, 0.2f, 0.2f,
+
+ 0.5f, 0.0f, 0.5f,
+ 0.0f, -1.0f, 0.0f
+ };
+ ConstTensor weights(weightInfo, weightsData);
+
+ Optional<ConstTensor> optionalBiases;
+ std::vector<float> biasesData{ 1.0f, 0.0f, 0.0f };
+ ConstTensor biases(biasInfo, biasesData);
+ optionalBiases = Optional<ConstTensor>(biases);
+
+ // Input layer
+ IConnectableLayer* input = net->AddInputLayer(0, "input");
+
+ // Convolution2d layer
+ Convolution2dDescriptor conv2dDesc;
+ conv2dDesc.m_StrideX = 1;
+ conv2dDesc.m_StrideY = 1;
+ conv2dDesc.m_PadLeft = 0;
+ conv2dDesc.m_PadRight = 0;
+ conv2dDesc.m_PadTop = 2;
+ conv2dDesc.m_PadBottom = 2;
+ conv2dDesc.m_BiasEnabled = true;
+ IConnectableLayer* conv2d = net->AddConvolution2dLayer(conv2dDesc, weights, optionalBiases);
+
+ // Activation layer
+ armnn::ActivationDescriptor activationDesc;
+ armnn::IConnectableLayer* const activation = net->AddActivationLayer(activationDesc, "activation");
+
+ // Output layer
+ IConnectableLayer* output = net->AddOutputLayer(0, "output");
+
+ input->GetOutputSlot(0).Connect(conv2d->GetInputSlot(0));
+ conv2d->GetOutputSlot(0).Connect(activation->GetInputSlot(0));
+ activation->GetOutputSlot(0).Connect(output->GetInputSlot(0));
+
+ input->GetOutputSlot(0).SetTensorInfo(inputInfo);
+ conv2d->GetOutputSlot(0).SetTensorInfo(outputInfo);
+ activation->GetOutputSlot(0).SetTensorInfo(outputInfo);
+
+ // optimize the network
+ std::vector<armnn::BackendId> backends = { backendId };
+ IOptimizedNetworkPtr optNet = Optimize(*net, backends, runtime->GetDeviceSpec());
+
+ ProfilingGuid optNetGuid = optNet->GetGuid();
+
+ // Load it into the runtime. It should success.
+ armnn::NetworkId netId;
+ BOOST_TEST(runtime->LoadNetwork(netId, std::move(optNet)) == Status::Success);
+
+ profiling::ProfilingServiceRuntimeHelper profilingServiceHelper;
+ profiling::BufferManager& bufferManager = profilingServiceHelper.GetProfilingBufferManager();
+ auto readableBuffer = bufferManager.GetReadableBuffer();
+
+ // Profiling is enable, the post-optimisation structure should be created
+ BOOST_CHECK(readableBuffer != nullptr);
+
+ unsigned int size = readableBuffer->GetSize();
+ BOOST_CHECK(size == 1980);
+
+ const unsigned char* readableData = readableBuffer->GetReadableData();
+ BOOST_CHECK(readableData != nullptr);
+
+ unsigned int offset = 0;
+
+ // Post-optimisation network
+ // Network entity
+ VerifyTimelineEntityBinaryPacket(optNetGuid, readableData, offset);
+
+ // Entity - Type relationship
+ VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::LabelLink,
+ EmptyOptional(),
+ optNetGuid,
+ EmptyOptional(),
+ readableData,
+ offset);
+
+ // Type label relationship
+ VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::LabelLink,
+ EmptyOptional(),
+ EmptyOptional(),
+ LabelsAndEventClasses::TYPE_GUID,
+ readableData,
+ offset);
+
+ // Input layer
+ // Input layer entity
+ VerifyTimelineEntityBinaryPacket(input->GetGuid(), readableData, offset);
+
+ // Name Entity
+ VerifyTimelineLabelBinaryPacket(EmptyOptional(), "input", readableData, offset);
+
+ // Entity - Name relationship
+ VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::LabelLink,
+ EmptyOptional(),
+ input->GetGuid(),
+ EmptyOptional(),
+ readableData,
+ offset);
+
+ // Name label relationship
+ VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::LabelLink,
+ EmptyOptional(),
+ EmptyOptional(),
+ LabelsAndEventClasses::NAME_GUID,
+ readableData,
+ offset);
+
+ // Entity - Type relationship
+ VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::LabelLink,
+ EmptyOptional(),
+ input->GetGuid(),
+ EmptyOptional(),
+ readableData,
+ offset);
+
+ // Type label relationship
+ VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::LabelLink,
+ EmptyOptional(),
+ EmptyOptional(),
+ LabelsAndEventClasses::TYPE_GUID,
+ readableData,
+ offset);
+
+ // Network - Input layer relationship
+ VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::RetentionLink,
+ EmptyOptional(),
+ optNetGuid,
+ input->GetGuid(),
+ readableData,
+ offset);
+
+ // Conv2d layer
+ // Conv2d layer entity
+ VerifyTimelineEntityBinaryPacket(conv2d->GetGuid(), readableData, offset);
+
+ // Name entity
+ VerifyTimelineLabelBinaryPacket(EmptyOptional(), "<Unnamed>", readableData, offset);
+
+ // Entity - Name relationship
+ VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::LabelLink,
+ EmptyOptional(),
+ conv2d->GetGuid(),
+ EmptyOptional(),
+ readableData,
+ offset);
+
+ // Name label relationship
+ VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::LabelLink,
+ EmptyOptional(),
+ EmptyOptional(),
+ LabelsAndEventClasses::NAME_GUID,
+ readableData,
+ offset);
+
+ // Entity - Type relationship
+ VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::LabelLink,
+ EmptyOptional(),
+ conv2d->GetGuid(),
+ EmptyOptional(),
+ readableData,
+ offset);
+
+ // Type label relationship
+ VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::LabelLink,
+ EmptyOptional(),
+ EmptyOptional(),
+ LabelsAndEventClasses::TYPE_GUID,
+ readableData,
+ offset);
+
+ // Network - Conv2d layer relationship
+ VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::RetentionLink,
+ EmptyOptional(),
+ optNetGuid,
+ conv2d->GetGuid(),
+ readableData,
+ offset);
+
+ // Input layer - Conv2d layer relationship
+ VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::RetentionLink,
+ EmptyOptional(),
+ input->GetGuid(),
+ conv2d->GetGuid(),
+ readableData,
+ offset);
+
+ // Entity - Type relationship
+ VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::LabelLink,
+ EmptyOptional(),
+ EmptyOptional(),
+ LabelsAndEventClasses::CONNECTION_GUID,
+ readableData,
+ offset);
+
+ // Type label relationship
+ VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::LabelLink,
+ EmptyOptional(),
+ EmptyOptional(),
+ LabelsAndEventClasses::TYPE_GUID,
+ readableData,
+ offset);
+
+ // Conv2d workload
+ // Conv2d workload entity
+ VerifyTimelineEntityBinaryPacket(EmptyOptional(), readableData, offset);
+
+ // Entity - Type relationship
+ VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::LabelLink,
+ EmptyOptional(),
+ EmptyOptional(),
+ EmptyOptional(),
+ readableData,
+ offset);
+
+ // Type label relationship
+ VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::LabelLink,
+ EmptyOptional(),
+ EmptyOptional(),
+ LabelsAndEventClasses::TYPE_GUID,
+ readableData,
+ offset);
+
+ // BackendId entity
+ VerifyTimelineLabelBinaryPacket(EmptyOptional(), backendId.Get(), readableData, offset);
+
+ // Entity - BackendId relationship
+ VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::LabelLink,
+ EmptyOptional(),
+ EmptyOptional(),
+ EmptyOptional(),
+ readableData,
+ offset);
+
+ // BackendId label relationship
+ VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::LabelLink,
+ EmptyOptional(),
+ EmptyOptional(),
+ LabelsAndEventClasses::BACKENDID_GUID,
+ readableData,
+ offset);
+
+ // Conv2d layer - Conv2d workload relationship
+ VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::RetentionLink,
+ EmptyOptional(),
+ conv2d->GetGuid(),
+ EmptyOptional(),
+ readableData,
+ offset);
+
+ // Activation layer
+ // Activation layer entity
+ VerifyTimelineEntityBinaryPacket(activation->GetGuid(), readableData, offset);
+
+ // Name entity
+ VerifyTimelineLabelBinaryPacket(EmptyOptional(), "activation", readableData, offset);
+
+ // Entity - Name relationship
+ VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::LabelLink,
+ EmptyOptional(),
+ activation->GetGuid(),
+ EmptyOptional(),
+ readableData,
+ offset);
+
+ // Name label relationship
+ VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::LabelLink,
+ EmptyOptional(),
+ EmptyOptional(),
+ LabelsAndEventClasses::NAME_GUID,
+ readableData,
+ offset);
+
+ // Entity - Type relationship
+ VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::LabelLink,
+ EmptyOptional(),
+ activation->GetGuid(),
+ EmptyOptional(),
+ readableData,
+ offset);
+
+ // Type label relationship
+ VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::LabelLink,
+ EmptyOptional(),
+ EmptyOptional(),
+ LabelsAndEventClasses::TYPE_GUID,
+ readableData,
+ offset);
+
+ // Network - Activation layer relationship
+ VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::RetentionLink,
+ EmptyOptional(),
+ optNetGuid,
+ activation->GetGuid(),
+ readableData,
+ offset);
+
+ // Conv2d layer - Activation layer relationship
+ VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::RetentionLink,
+ EmptyOptional(),
+ conv2d->GetGuid(),
+ activation->GetGuid(),
+ readableData,
+ offset);
+
+ // Entity - Type relationship
+ VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::LabelLink,
+ EmptyOptional(),
+ EmptyOptional(),
+ LabelsAndEventClasses::CONNECTION_GUID,
+ readableData,
+ offset);
+
+ // Type label relationship
+ VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::LabelLink,
+ EmptyOptional(),
+ EmptyOptional(),
+ LabelsAndEventClasses::TYPE_GUID,
+ readableData,
+ offset);
+
+ // Activation workload
+ // Activation workload entity
+ VerifyTimelineEntityBinaryPacket(EmptyOptional(), readableData, offset);
+
+ // Entity - Type relationship
+ VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::LabelLink,
+ EmptyOptional(),
+ EmptyOptional(),
+ EmptyOptional(),
+ readableData,
+ offset);
+
+ // Type label relationship
+ VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::LabelLink,
+ EmptyOptional(),
+ EmptyOptional(),
+ LabelsAndEventClasses::TYPE_GUID,
+ readableData,
+ offset);
+
+ // BackendId entity
+ VerifyTimelineLabelBinaryPacket(EmptyOptional(), backendId.Get(), readableData, offset);
+
+ // Entity - BackendId relationship
+ VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::LabelLink,
+ EmptyOptional(),
+ EmptyOptional(),
+ EmptyOptional(),
+ readableData,
+ offset);
+
+ // BackendId label relationship
+ VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::LabelLink,
+ EmptyOptional(),
+ EmptyOptional(),
+ LabelsAndEventClasses::BACKENDID_GUID,
+ readableData,
+ offset);
+
+ // Activation layer - Activation workload relationship
+ VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::RetentionLink,
+ EmptyOptional(),
+ activation->GetGuid(),
+ EmptyOptional(),
+ readableData,
+ offset);
+
+ // Output layer
+ // Output layer entity
+ VerifyTimelineEntityBinaryPacket(output->GetGuid(), readableData, offset);
+
+ // Name entity
+ VerifyTimelineLabelBinaryPacket(EmptyOptional(), "output", readableData, offset);
+
+ // Entity - Name relationship
+ VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::LabelLink,
+ EmptyOptional(),
+ output->GetGuid(),
+ EmptyOptional(),
+ readableData,
+ offset);
+
+ // Name label relationship
+ VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::LabelLink,
+ EmptyOptional(),
+ EmptyOptional(),
+ LabelsAndEventClasses::NAME_GUID,
+ readableData,
+ offset);
+
+ // Entity - Type relationship
+ VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::LabelLink,
+ EmptyOptional(),
+ output->GetGuid(),
+ EmptyOptional(),
+ readableData,
+ offset);
+
+ // Type label relationship
+ VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::LabelLink,
+ EmptyOptional(),
+ EmptyOptional(),
+ LabelsAndEventClasses::TYPE_GUID,
+ readableData,
+ offset);
+
+ // Network - Output layer relationship
+ VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::RetentionLink,
+ EmptyOptional(),
+ optNetGuid,
+ output->GetGuid(),
+ readableData,
+ offset);
+
+ // Activation layer - Output layer relationship
+ VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::RetentionLink,
+ EmptyOptional(),
+ activation->GetGuid(),
+ output->GetGuid(),
+ readableData,
+ offset);
+
+ // Entity - Type relationship
+ VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::LabelLink,
+ EmptyOptional(),
+ EmptyOptional(),
+ LabelsAndEventClasses::CONNECTION_GUID,
+ readableData,
+ offset);
+
+ // Type label relationship
+ VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::LabelLink,
+ EmptyOptional(),
+ EmptyOptional(),
+ LabelsAndEventClasses::TYPE_GUID,
+ readableData,
+ offset);
+
+ bufferManager.MarkRead(readableBuffer);
+}
diff --git a/src/profiling/test/ProfilingTestUtils.hpp b/src/profiling/test/ProfilingTestUtils.hpp
new file mode 100644
index 0000000000..7fb5d62591
--- /dev/null
+++ b/src/profiling/test/ProfilingTestUtils.hpp
@@ -0,0 +1,70 @@
+//
+// Copyright © 2019 Arm Ltd. All rights reserved.
+// SPDX-License-Identifier: MIT
+//
+
+#pragma once
+
+#include "ProfilingUtils.hpp"
+
+#include <armnn/BackendId.hpp>
+#include <armnn/Optional.hpp>
+#include <armnn/Types.hpp>
+#include <BufferManager.hpp>
+#include <ProfilingService.hpp>
+
+using namespace armnn;
+using namespace armnn::profiling;
+
+inline unsigned int OffsetToNextWord(unsigned int numberOfBytes);
+
+void VerifyTimelineLabelBinaryPacket(Optional<ProfilingGuid> guid,
+ const std::string& label,
+ const unsigned char* readableData,
+ unsigned int& offset);
+
+void VerifyTimelineEventClassBinaryPacket(ProfilingGuid guid,
+ const unsigned char* readableData,
+ unsigned int& offset);
+
+void VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType relationshipType,
+ Optional<ProfilingGuid> relationshipGuid,
+ Optional<ProfilingGuid> headGuid,
+ Optional<ProfilingGuid> tailGuid,
+ const unsigned char* readableData,
+ unsigned int& offset);
+
+void VerifyTimelineEntityBinaryPacket(Optional<ProfilingGuid> guid,
+ const unsigned char* readableData,
+ unsigned int& offset);
+
+void VerifyTimelineEventBinaryPacket(Optional<uint64_t> timestamp,
+ Optional<std::thread::id> threadId,
+ Optional<ProfilingGuid> eventGuid,
+ const unsigned char* readableData,
+ unsigned int& offset);
+
+void VerifyPostOptimisationStructureTestImpl(armnn::BackendId backendId);
+
+namespace armnn
+{
+
+namespace profiling
+{
+
+class ProfilingServiceRuntimeHelper : public ProfilingService
+{
+public:
+ ProfilingServiceRuntimeHelper() = default;
+ ~ProfilingServiceRuntimeHelper() = default;
+
+ BufferManager& GetProfilingBufferManager()
+ {
+ return GetBufferManager(ProfilingService::Instance());
+ }
+};
+
+} // namespace profiling
+
+} // namespace armnn
+
diff --git a/src/profiling/test/TimelineUtilityMethodsTests.cpp b/src/profiling/test/TimelineUtilityMethodsTests.cpp
index 7d1a7c1a87..ae1ee558bf 100644
--- a/src/profiling/test/TimelineUtilityMethodsTests.cpp
+++ b/src/profiling/test/TimelineUtilityMethodsTests.cpp
@@ -4,368 +4,26 @@
//
#include "SendCounterPacketTests.hpp"
+#include "ProfilingTestUtils.hpp"
#include <SendTimelinePacket.hpp>
#include <TimelineUtilityMethods.hpp>
#include <LabelsAndEventClasses.hpp>
#include <ProfilingService.hpp>
+#include <memory>
+
#include <boost/test/unit_test.hpp>
using namespace armnn;
using namespace armnn::profiling;
-namespace
-{
-
-inline unsigned int OffsetToNextWord(unsigned int numberOfBytes)
-{
- unsigned int uint32_t_size = sizeof(uint32_t);
-
- unsigned int remainder = numberOfBytes % uint32_t_size;
- if (remainder == 0)
- {
- return numberOfBytes;
- }
-
- return numberOfBytes + uint32_t_size - remainder;
-}
-
-void VerifyTimelineLabelBinaryPacket(Optional<ProfilingGuid> guid,
- const std::string& label,
- const unsigned char* readableData,
- unsigned int& offset)
-{
- BOOST_ASSERT(readableData);
-
- // Utils
- unsigned int uint32_t_size = sizeof(uint32_t);
- unsigned int uint64_t_size = sizeof(uint64_t);
- unsigned int label_size = boost::numeric_cast<unsigned int>(label.size());
-
- // Check the TimelineLabelBinaryPacket header
- uint32_t entityBinaryPacketHeaderWord0 = ReadUint32(readableData, offset);
- uint32_t entityBinaryPacketFamily = (entityBinaryPacketHeaderWord0 >> 26) & 0x0000003F;
- uint32_t entityBinaryPacketClass = (entityBinaryPacketHeaderWord0 >> 19) & 0x0000007F;
- uint32_t entityBinaryPacketType = (entityBinaryPacketHeaderWord0 >> 16) & 0x00000007;
- uint32_t entityBinaryPacketStreamId = (entityBinaryPacketHeaderWord0 >> 0) & 0x00000007;
- BOOST_CHECK(entityBinaryPacketFamily == 1);
- BOOST_CHECK(entityBinaryPacketClass == 0);
- BOOST_CHECK(entityBinaryPacketType == 1);
- BOOST_CHECK(entityBinaryPacketStreamId == 0);
- offset += uint32_t_size;
- uint32_t entityBinaryPacketHeaderWord1 = ReadUint32(readableData, offset);
- uint32_t eventBinaryPacketSequenceNumber = (entityBinaryPacketHeaderWord1 >> 24) & 0x00000001;
- uint32_t eventBinaryPacketDataLength = (entityBinaryPacketHeaderWord1 >> 0) & 0x00FFFFFF;
- BOOST_CHECK(eventBinaryPacketSequenceNumber == 0);
- BOOST_CHECK(eventBinaryPacketDataLength == 16 + OffsetToNextWord(label_size + 1));
-
- // Check the decl id
- offset += uint32_t_size;
- uint32_t eventClassDeclId = ReadUint32(readableData, offset);
- BOOST_CHECK(eventClassDeclId == 0);
-
- // Check the profiling GUID
- offset += uint32_t_size;
- uint64_t readProfilingGuid = ReadUint64(readableData, offset);
- if (guid.has_value())
- {
- BOOST_CHECK(readProfilingGuid == guid.value());
- }
- else
- {
- BOOST_CHECK(readProfilingGuid == ProfilingService::Instance().GenerateStaticId(label));
- }
-
- // Check the SWTrace label
- offset += uint64_t_size;
- uint32_t swTraceLabelLength = ReadUint32(readableData, offset);
- BOOST_CHECK(swTraceLabelLength == label_size + 1); // Label length including the null-terminator
- offset += uint32_t_size;
- BOOST_CHECK(std::memcmp(readableData + offset, // Offset to the label in the buffer
- label.data(), // The original label
- swTraceLabelLength - 1) == 0); // The length of the label
- BOOST_CHECK(readableData[offset + swTraceLabelLength] == '\0'); // The null-terminator
-
- // SWTrace strings are written in blocks of words, so the offset has to be updated to the next whole word
- offset += OffsetToNextWord(swTraceLabelLength);
-}
-
-void VerifyTimelineEventClassBinaryPacket(ProfilingGuid guid,
- const unsigned char* readableData,
- unsigned int& offset)
-{
- BOOST_ASSERT(readableData);
-
- // Utils
- unsigned int uint32_t_size = sizeof(uint32_t);
- unsigned int uint64_t_size = sizeof(uint64_t);
-
- // Check the TimelineEventClassBinaryPacket header
- uint32_t entityBinaryPacketHeaderWord0 = ReadUint32(readableData, offset);
- uint32_t entityBinaryPacketFamily = (entityBinaryPacketHeaderWord0 >> 26) & 0x0000003F;
- uint32_t entityBinaryPacketClass = (entityBinaryPacketHeaderWord0 >> 19) & 0x0000007F;
- uint32_t entityBinaryPacketType = (entityBinaryPacketHeaderWord0 >> 16) & 0x00000007;
- uint32_t entityBinaryPacketStreamId = (entityBinaryPacketHeaderWord0 >> 0) & 0x00000007;
- BOOST_CHECK(entityBinaryPacketFamily == 1);
- BOOST_CHECK(entityBinaryPacketClass == 0);
- BOOST_CHECK(entityBinaryPacketType == 1);
- BOOST_CHECK(entityBinaryPacketStreamId == 0);
- offset += uint32_t_size;
- uint32_t entityBinaryPacketHeaderWord1 = ReadUint32(readableData, offset);
- uint32_t eventBinaryPacketSequenceNumber = (entityBinaryPacketHeaderWord1 >> 24) & 0x00000001;
- uint32_t eventBinaryPacketDataLength = (entityBinaryPacketHeaderWord1 >> 0) & 0x00FFFFFF;
- BOOST_CHECK(eventBinaryPacketSequenceNumber == 0);
- BOOST_CHECK(eventBinaryPacketDataLength == 12);
-
- // Check the decl id
- offset += uint32_t_size;
- uint32_t eventClassDeclId = ReadUint32(readableData, offset);
- BOOST_CHECK(eventClassDeclId == 2);
-
- // Check the profiling GUID
- offset += uint32_t_size;
- uint64_t readProfilingGuid = ReadUint64(readableData, offset);
- BOOST_CHECK(readProfilingGuid == guid);
-
- // Update the offset to allow parsing to be continued after this function returns
- offset += uint64_t_size;
-}
-
-void VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType relationshipType,
- Optional<ProfilingGuid> relationshipGuid,
- Optional<ProfilingGuid> headGuid,
- Optional<ProfilingGuid> tailGuid,
- const unsigned char* readableData,
- unsigned int& offset)
-{
- BOOST_ASSERT(readableData);
-
- uint32_t relationshipTypeUint = 0;
- switch (relationshipType)
- {
- case ProfilingRelationshipType::RetentionLink:
- relationshipTypeUint = 0;
- break;
- case ProfilingRelationshipType::ExecutionLink:
- relationshipTypeUint = 1;
- break;
- case ProfilingRelationshipType::DataLink:
- relationshipTypeUint = 2;
- break;
- case ProfilingRelationshipType::LabelLink:
- relationshipTypeUint = 3;
- break;
- default:
- BOOST_ERROR("Unknown relationship type");
- }
-
- // Utils
- unsigned int uint32_t_size = sizeof(uint32_t);
- unsigned int uint64_t_size = sizeof(uint64_t);
-
- // Check the TimelineLabelBinaryPacket header
- uint32_t entityBinaryPacketHeaderWord0 = ReadUint32(readableData, offset);
- uint32_t entityBinaryPacketFamily = (entityBinaryPacketHeaderWord0 >> 26) & 0x0000003F;
- uint32_t entityBinaryPacketClass = (entityBinaryPacketHeaderWord0 >> 19) & 0x0000007F;
- uint32_t entityBinaryPacketType = (entityBinaryPacketHeaderWord0 >> 16) & 0x00000007;
- uint32_t entityBinaryPacketStreamId = (entityBinaryPacketHeaderWord0 >> 0) & 0x00000007;
- BOOST_CHECK(entityBinaryPacketFamily == 1);
- BOOST_CHECK(entityBinaryPacketClass == 0);
- BOOST_CHECK(entityBinaryPacketType == 1);
- BOOST_CHECK(entityBinaryPacketStreamId == 0);
- offset += uint32_t_size;
- uint32_t entityBinaryPacketHeaderWord1 = ReadUint32(readableData, offset);
- uint32_t eventBinaryPacketSequenceNumber = (entityBinaryPacketHeaderWord1 >> 24) & 0x00000001;
- uint32_t eventBinaryPacketDataLength = (entityBinaryPacketHeaderWord1 >> 0) & 0x00FFFFFF;
- BOOST_CHECK(eventBinaryPacketSequenceNumber == 0);
- BOOST_CHECK(eventBinaryPacketDataLength == 32);
-
- // Check the decl id
- offset += uint32_t_size;
- uint32_t eventClassDeclId = ReadUint32(readableData, offset);
- BOOST_CHECK(eventClassDeclId == 3);
-
- // Check the relationship type
- offset += uint32_t_size;
- uint32_t readRelationshipTypeUint = ReadUint32(readableData, offset);
- BOOST_CHECK(readRelationshipTypeUint == relationshipTypeUint);
-
- // Check the relationship GUID
- offset += uint32_t_size;
- uint64_t readRelationshipGuid = ReadUint64(readableData, offset);
- if (relationshipGuid.has_value())
- {
- BOOST_CHECK(readRelationshipGuid == relationshipGuid.value());
- }
- else
- {
- BOOST_CHECK(readRelationshipGuid != ProfilingGuid(0));
- }
-
- // Check the head of relationship GUID
- offset += uint64_t_size;
- uint64_t readHeadRelationshipGuid = ReadUint64(readableData, offset);
- if (headGuid.has_value())
- {
- BOOST_CHECK(readHeadRelationshipGuid == headGuid.value());
- }
- else
- {
- BOOST_CHECK(readHeadRelationshipGuid != ProfilingGuid(0));
- }
-
- // Check the tail of relationship GUID
- offset += uint64_t_size;
- uint64_t readTailRelationshipGuid = ReadUint64(readableData, offset);
- if (tailGuid.has_value())
- {
- BOOST_CHECK(readTailRelationshipGuid == tailGuid.value());
- }
- else
- {
- BOOST_CHECK(readTailRelationshipGuid != ProfilingGuid(0));
- }
-
- // Update the offset to allow parsing to be continued after this function returns
- offset += uint64_t_size;
-}
-
-void VerifyTimelineEntityBinaryPacket(Optional<ProfilingGuid> guid,
- const unsigned char* readableData,
- unsigned int& offset)
-{
- BOOST_ASSERT(readableData);
-
- // Utils
- unsigned int uint32_t_size = sizeof(uint32_t);
- unsigned int uint64_t_size = sizeof(uint64_t);
-
- // Reading TimelineEntityClassBinaryPacket
- uint32_t entityBinaryPacketHeaderWord0 = ReadUint32(readableData, offset);
- uint32_t entityBinaryPacketFamily = (entityBinaryPacketHeaderWord0 >> 26) & 0x0000003F;
- uint32_t entityBinaryPacketClass = (entityBinaryPacketHeaderWord0 >> 19) & 0x0000007F;
- uint32_t entityBinaryPacketType = (entityBinaryPacketHeaderWord0 >> 16) & 0x00000007;
- uint32_t entityBinaryPacketStreamId = (entityBinaryPacketHeaderWord0 >> 0) & 0x00000007;
-
- BOOST_CHECK(entityBinaryPacketFamily == 1);
- BOOST_CHECK(entityBinaryPacketClass == 0);
- BOOST_CHECK(entityBinaryPacketType == 1);
- BOOST_CHECK(entityBinaryPacketStreamId == 0);
-
- offset += uint32_t_size;
- uint32_t entityBinaryPacketHeaderWord1 = ReadUint32(readableData, offset);
- uint32_t entityBinaryPacketSequenceNumbered = (entityBinaryPacketHeaderWord1 >> 24) & 0x00000001;
- uint32_t entityBinaryPacketDataLength = (entityBinaryPacketHeaderWord1 >> 0) & 0x00FFFFFF;
- BOOST_CHECK(entityBinaryPacketSequenceNumbered == 0);
- BOOST_CHECK(entityBinaryPacketDataLength == 12);
-
- // Check the decl_id
- offset += uint32_t_size;
- uint32_t entityDeclId = ReadUint32(readableData, offset);
- BOOST_CHECK(entityDeclId == 1);
-
- // Check the profiling GUID
- offset += uint32_t_size;
- uint64_t readProfilingGuid = ReadUint64(readableData, offset);
-
- if (guid.has_value())
- {
- BOOST_CHECK(readProfilingGuid == guid.value());
- }
- else
- {
- BOOST_CHECK(readProfilingGuid != ProfilingGuid(0));
- }
-
- offset += uint64_t_size;
-}
-
-void VerifyTimelineEventBinaryPacket(Optional<uint64_t> timestamp,
- Optional<std::thread::id> threadId,
- Optional<ProfilingGuid> eventGuid,
- const unsigned char* readableData,
- unsigned int& offset)
-{
- BOOST_ASSERT(readableData);
-
- // Utils
- unsigned int uint32_t_size = sizeof(uint32_t);
- unsigned int uint64_t_size = sizeof(uint64_t);
- unsigned int threadId_size = sizeof(std::thread::id);
-
- // Reading TimelineEventBinaryPacket
- uint32_t entityBinaryPacketHeaderWord0 = ReadUint32(readableData, offset);
- uint32_t entityBinaryPacketFamily = (entityBinaryPacketHeaderWord0 >> 26) & 0x0000003F;
- uint32_t entityBinaryPacketClass = (entityBinaryPacketHeaderWord0 >> 19) & 0x0000007F;
- uint32_t entityBinaryPacketType = (entityBinaryPacketHeaderWord0 >> 16) & 0x00000007;
- uint32_t entityBinaryPacketStreamId = (entityBinaryPacketHeaderWord0 >> 0) & 0x00000007;
-
- BOOST_CHECK(entityBinaryPacketFamily == 1);
- BOOST_CHECK(entityBinaryPacketClass == 0);
- BOOST_CHECK(entityBinaryPacketType == 1);
- BOOST_CHECK(entityBinaryPacketStreamId == 0);
-
- offset += uint32_t_size;
- uint32_t entityBinaryPacketHeaderWord1 = ReadUint32(readableData, offset);
- uint32_t entityBinaryPacketSequenceNumbered = (entityBinaryPacketHeaderWord1 >> 24) & 0x00000001;
- uint32_t entityBinaryPacketDataLength = (entityBinaryPacketHeaderWord1 >> 0) & 0x00FFFFFF;
- BOOST_CHECK(entityBinaryPacketSequenceNumbered == 0);
- BOOST_CHECK(entityBinaryPacketDataLength == 20 + threadId_size);
-
- // Check the decl_id
- offset += uint32_t_size;
- uint32_t entityDeclId = ReadUint32(readableData, offset);
- BOOST_CHECK(entityDeclId == 4);
-
- // Check the timestamp
- offset += uint32_t_size;
- uint64_t readTimestamp = ReadUint64(readableData, offset);
- if (timestamp.has_value())
- {
- BOOST_CHECK(readTimestamp == timestamp.value());
- }
- else
- {
- BOOST_CHECK(readTimestamp != 0);
- }
-
- // Check the thread id
- offset += uint64_t_size;
- std::vector<uint8_t> readThreadId(threadId_size, 0);
- ReadBytes(readableData, offset, threadId_size, readThreadId.data());
- if (threadId.has_value())
- {
- BOOST_CHECK(readThreadId == threadId.value());
- }
- else
- {
- BOOST_CHECK(readThreadId == std::this_thread::get_id());
- }
-
- // Check the event GUID
- offset += threadId_size;
- uint64_t readEventGuid = ReadUint64(readableData, offset);
- if (eventGuid.has_value())
- {
- BOOST_CHECK(readEventGuid == eventGuid.value());
- }
- else
- {
- BOOST_CHECK(readEventGuid != ProfilingGuid(0));
- }
-
- offset += uint64_t_size;
-}
-
-} // Anonymous namespace
-
BOOST_AUTO_TEST_SUITE(TimelineUtilityMethodsTests)
BOOST_AUTO_TEST_CASE(CreateTypedLabelTest)
{
MockBufferManager mockBufferManager(1024);
- SendTimelinePacket sendTimelinePacket(mockBufferManager);
+ std::unique_ptr<ISendTimelinePacket> sendTimelinePacket = std::make_unique<SendTimelinePacket>(mockBufferManager);
TimelineUtilityMethods timelineUtilityMethods(sendTimelinePacket);
// Generate first guid to ensure that the named typed entity guid is not 0 on local single test.
@@ -375,10 +33,10 @@ BOOST_AUTO_TEST_CASE(CreateTypedLabelTest)
const std::string entityName = "some entity";
ProfilingStaticGuid labelTypeGuid(456);
- BOOST_CHECK_NO_THROW(timelineUtilityMethods.CreateTypedLabel(entityGuid, entityName, labelTypeGuid));
+ BOOST_CHECK_NO_THROW(timelineUtilityMethods.MarkEntityWithLabel(entityGuid, entityName, labelTypeGuid));
// Commit all packets at once
- sendTimelinePacket.Commit();
+ timelineUtilityMethods.Commit();
// Get the readable buffer
auto readableBuffer = mockBufferManager.GetReadableBuffer();
@@ -417,19 +75,19 @@ BOOST_AUTO_TEST_CASE(CreateTypedLabelTest)
BOOST_AUTO_TEST_CASE(SendWellKnownLabelsAndEventClassesTest)
{
MockBufferManager mockBufferManager(1024);
- SendTimelinePacket sendTimelinePacket(mockBufferManager);
+ std::unique_ptr<ISendTimelinePacket> sendTimelinePacket = std::make_unique<SendTimelinePacket>(mockBufferManager);
TimelineUtilityMethods timelineUtilityMethods(sendTimelinePacket);
BOOST_CHECK_NO_THROW(timelineUtilityMethods.SendWellKnownLabelsAndEventClasses());
// Commit all packets at once
- sendTimelinePacket.Commit();
+ timelineUtilityMethods.Commit();
// Get the readable buffer
auto readableBuffer = mockBufferManager.GetReadableBuffer();
BOOST_CHECK(readableBuffer != nullptr);
unsigned int size = readableBuffer->GetSize();
- BOOST_CHECK(size == 136);
+ BOOST_TEST(size == 308);
const unsigned char* readableData = readableBuffer->GetReadableData();
BOOST_CHECK(readableData != nullptr);
@@ -454,6 +112,37 @@ BOOST_AUTO_TEST_CASE(SendWellKnownLabelsAndEventClassesTest)
readableData,
offset);
+ // Forth "well-known" label: BACKENDID
+ VerifyTimelineLabelBinaryPacket(LabelsAndEventClasses::BACKENDID_GUID,
+ LabelsAndEventClasses::BACKENDID_LABEL,
+ readableData,
+ offset);
+
+ // Well-known types
+ // Layer
+ VerifyTimelineLabelBinaryPacket(LabelsAndEventClasses::LAYER_GUID,
+ LabelsAndEventClasses::LAYER,
+ readableData,
+ offset);
+
+ // Workload
+ VerifyTimelineLabelBinaryPacket(LabelsAndEventClasses::WORKLOAD_GUID,
+ LabelsAndEventClasses::WORKLOAD,
+ readableData,
+ offset);
+
+ // Network
+ VerifyTimelineLabelBinaryPacket(LabelsAndEventClasses::NETWORK_GUID,
+ LabelsAndEventClasses::NETWORK,
+ readableData,
+ offset);
+
+ // Connection
+ VerifyTimelineLabelBinaryPacket(LabelsAndEventClasses::CONNECTION_GUID,
+ LabelsAndEventClasses::CONNECTION,
+ readableData,
+ offset);
+
// First "well-known" event class: START OF LIFE
VerifyTimelineEventClassBinaryPacket(LabelsAndEventClasses::ARMNN_PROFILING_SOL_EVENT_CLASS,
readableData,
@@ -471,7 +160,7 @@ BOOST_AUTO_TEST_CASE(SendWellKnownLabelsAndEventClassesTest)
BOOST_AUTO_TEST_CASE(CreateNamedTypedChildEntityTest)
{
MockBufferManager mockBufferManager(1024);
- SendTimelinePacket sendTimelinePacket(mockBufferManager);
+ std::unique_ptr<ISendTimelinePacket> sendTimelinePacket = std::make_unique<SendTimelinePacket>(mockBufferManager);
TimelineUtilityMethods timelineUtilityMethods(sendTimelinePacket);
ProfilingDynamicGuid childEntityGuid(0);
@@ -497,7 +186,7 @@ BOOST_AUTO_TEST_CASE(CreateNamedTypedChildEntityTest)
BOOST_CHECK(childEntityGuid != ProfilingGuid(0));
// Commit all packets at once
- sendTimelinePacket.Commit();
+ timelineUtilityMethods.Commit();
// Get the readable buffer
auto readableBuffer = mockBufferManager.GetReadableBuffer();
@@ -566,7 +255,7 @@ BOOST_AUTO_TEST_CASE(CreateNamedTypedChildEntityTest)
BOOST_AUTO_TEST_CASE(DeclareLabelTest)
{
MockBufferManager mockBufferManager(1024);
- SendTimelinePacket sendTimelinePacket(mockBufferManager);
+ std::unique_ptr<ISendTimelinePacket> sendTimelinePacket = std::make_unique<SendTimelinePacket>(mockBufferManager);
TimelineUtilityMethods timelineUtilityMethods(sendTimelinePacket);
// Generate first guid to ensure that the named typed entity guid is not 0 on local single test.
@@ -594,7 +283,7 @@ BOOST_AUTO_TEST_CASE(DeclareLabelTest)
BOOST_AUTO_TEST_CASE(CreateNameTypeEntityInvalidTest)
{
MockBufferManager mockBufferManager(1024);
- SendTimelinePacket sendTimelinePacket(mockBufferManager);
+ std::unique_ptr<ISendTimelinePacket> sendTimelinePacket = std::make_unique<SendTimelinePacket>(mockBufferManager);
TimelineUtilityMethods timelineUtilityMethods(sendTimelinePacket);
// Invalid name
@@ -618,7 +307,7 @@ BOOST_AUTO_TEST_CASE(CreateNameTypeEntityInvalidTest)
BOOST_AUTO_TEST_CASE(CreateNameTypeEntityTest)
{
MockBufferManager mockBufferManager(1024);
- SendTimelinePacket sendTimelinePacket(mockBufferManager);
+ std::unique_ptr<ISendTimelinePacket> sendTimelinePacket = std::make_unique<SendTimelinePacket>(mockBufferManager);
TimelineUtilityMethods timelineUtilityMethods(sendTimelinePacket);
const std::string entityName = "Entity0";
@@ -631,7 +320,7 @@ BOOST_AUTO_TEST_CASE(CreateNameTypeEntityTest)
BOOST_CHECK(guid != ProfilingGuid(0));
// Commit all packets at once
- sendTimelinePacket.Commit();
+ timelineUtilityMethods.Commit();
// Get the readable buffer
auto readableBuffer = mockBufferManager.GetReadableBuffer();
@@ -694,9 +383,8 @@ BOOST_AUTO_TEST_CASE(CreateNameTypeEntityTest)
BOOST_AUTO_TEST_CASE(RecordEventTest)
{
MockBufferManager mockBufferManager(1024);
- SendTimelinePacket sendTimelinePacket(mockBufferManager);
+ std::unique_ptr<ISendTimelinePacket> sendTimelinePacket = std::make_unique<SendTimelinePacket>(mockBufferManager);
TimelineUtilityMethods timelineUtilityMethods(sendTimelinePacket);
-
// Generate first guid to ensure that the named typed entity guid is not 0 on local single test.
ProfilingService::Instance().NextGuid();
@@ -707,7 +395,7 @@ BOOST_AUTO_TEST_CASE(RecordEventTest)
BOOST_CHECK(eventGuid != ProfilingGuid(0));
// Commit all packets at once
- sendTimelinePacket.Commit();
+ timelineUtilityMethods.Commit();
// Get the readable buffer
auto readableBuffer = mockBufferManager.GetReadableBuffer();
@@ -734,7 +422,7 @@ BOOST_AUTO_TEST_CASE(RecordEventTest)
// Third packet sent: TimelineRelationshipBinaryPacket
VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::DataLink,
EmptyOptional(),
- entityGuid,
+ eventGuid,
eventClassGuid,
readableData,
offset);