From df31cfe29f9dccc4c2055a1d2a97de644b07d522 Mon Sep 17 00:00:00 2001 From: Narumol Prangnawarat Date: Fri, 22 Nov 2019 11:26:06 +0000 Subject: 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 Change-Id: I0194f2037c236450c912f4c3cb11e46b80c0f512 --- Android.mk | 4 +- CMakeLists.txt | 2 + src/armnn/LoadedNetwork.cpp | 69 +- src/armnn/test/RuntimeTests.cpp | 360 +++++++++ src/backends/cl/test/ClRuntimeTests.cpp | 6 + src/backends/neon/test/NeonRuntimeTests.cpp | 6 + src/profiling/LabelsAndEventClasses.cpp | 18 + src/profiling/LabelsAndEventClasses.hpp | 12 + src/profiling/ProfilingService.hpp | 8 + src/profiling/TimelineUtilityMethods.cpp | 237 ++++-- src/profiling/TimelineUtilityMethods.hpp | 49 +- src/profiling/test/ProfilingTestUtils.cpp | 818 +++++++++++++++++++++ src/profiling/test/ProfilingTestUtils.hpp | 70 ++ src/profiling/test/TimelineUtilityMethodsTests.cpp | 410 ++--------- 14 files changed, 1652 insertions(+), 417 deletions(-) create mode 100644 src/profiling/test/ProfilingTestUtils.cpp create mode 100644 src/profiling/test/ProfilingTestUtils.hpp 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 #include #include +#include +#include +#include #include #include @@ -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& timelineUtils, + const Layer& layer, + ProfilingGuid networkGuid) +{ + // Add layer to the post-optimisation network structure + std::string layerName = layer.GetNameStr().empty() ? "" : 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& timelineUtils, + std::unique_ptr& 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::MakeLoadedNetwork(std::unique_ptr net, @@ -149,9 +190,22 @@ LoadedNetwork::LoadedNetwork(std::unique_ptr net, } } + ProfilingGuid networkGuid = m_OptimizedNetwork->GetGuid(); + std::unique_ptr 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 net, if (!workload) { - const char* const layerName = layer->GetNameStr().length() != 0 ? layer->GetName() : ""; + const char* const layerName = + layer->GetNameStr().length() != 0 ? layer->GetName() : ""; throw InvalidArgumentException(boost::str( boost::format("No workload created for layer (name: '%1%' type: '%2%') (compute '%3%')") % layerName % static_cast(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 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 #include +#include +#include + #include #include @@ -17,6 +20,7 @@ #endif #include +#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 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 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 #include +#include #include #include @@ -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 #include +#include #include @@ -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 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::GetTimelineUtils() +{ + if (ProfilingService::Instance().IsEnabled()) + { + std::unique_ptr sendTimelinepacket = ProfilingService::Instance().GetSendTimelinePacket(); + return std::make_unique(sendTimelinepacket); + } + else + { + std::unique_ptr 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 GetTimelineUtils(); + + TimelineUtilityMethods(std::unique_ptr& 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 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 +#include +#include + +#include + +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 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(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 relationshipGuid, + Optional headGuid, + Optional 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 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 timestamp, + Optional threadId, + Optional 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 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 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 optionalBiases; + std::vector biasesData{ 1.0f, 0.0f, 0.0f }; + ConstTensor biases(biasInfo, biasesData); + optionalBiases = Optional(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 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(), "", 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 +#include +#include +#include +#include + +using namespace armnn; +using namespace armnn::profiling; + +inline unsigned int OffsetToNextWord(unsigned int numberOfBytes); + +void VerifyTimelineLabelBinaryPacket(Optional 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 relationshipGuid, + Optional headGuid, + Optional tailGuid, + const unsigned char* readableData, + unsigned int& offset); + +void VerifyTimelineEntityBinaryPacket(Optional guid, + const unsigned char* readableData, + unsigned int& offset); + +void VerifyTimelineEventBinaryPacket(Optional timestamp, + Optional threadId, + Optional 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 #include #include #include +#include + #include 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 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(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 relationshipGuid, - Optional headGuid, - Optional 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 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 timestamp, - Optional threadId, - Optional 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 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 sendTimelinePacket = std::make_unique(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 sendTimelinePacket = std::make_unique(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 sendTimelinePacket = std::make_unique(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 sendTimelinePacket = std::make_unique(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 sendTimelinePacket = std::make_unique(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 sendTimelinePacket = std::make_unique(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 sendTimelinePacket = std::make_unique(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); -- cgit v1.2.1