From c04019985db1ee44c71834892ad17365185a3f8d Mon Sep 17 00:00:00 2001 From: Matteo Martincigh Date: Mon, 28 Oct 2019 15:24:34 +0000 Subject: IVGCVSW-4035 Add a CreateTypedLabel function * Create new utility function in the TimelineUtilityMethods class * Added unit tests Signed-off-by: Matteo Martincigh Change-Id: I63704b94d5cc6861e4e160de2aae4ae497699dd2 --- src/profiling/TimelineUtilityMethods.cpp | 33 +++++ src/profiling/TimelineUtilityMethods.hpp | 1 + src/profiling/test/TimelineUtilityMethodsTests.cpp | 161 ++++++++++++++++++++- 3 files changed, 193 insertions(+), 2 deletions(-) diff --git a/src/profiling/TimelineUtilityMethods.cpp b/src/profiling/TimelineUtilityMethods.cpp index aa9f5a5635..b34b70f984 100644 --- a/src/profiling/TimelineUtilityMethods.cpp +++ b/src/profiling/TimelineUtilityMethods.cpp @@ -52,6 +52,39 @@ ProfilingStaticGuid TimelineUtilityMethods::DeclareLabel(const std::string& labe return labelGuid; } +void TimelineUtilityMethods::CreateTypedLabel(ProfilingGuid entityGuid, + const std::string& entityName, + ProfilingStaticGuid labelTypeGuid) +{ + // 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"); + } + + // Declare a label with the entity's name, this call throws in case of error + ProfilingGuid labelGuid = DeclareLabel(entityName); + + // Generate a GUID for the label relationship + ProfilingGuid 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 + ProfilingGuid 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); +} + } // namespace profiling } // namespace armnn diff --git a/src/profiling/TimelineUtilityMethods.hpp b/src/profiling/TimelineUtilityMethods.hpp index f3e925e3dc..63e5c40ae2 100644 --- a/src/profiling/TimelineUtilityMethods.hpp +++ b/src/profiling/TimelineUtilityMethods.hpp @@ -25,6 +25,7 @@ public: void SendWellKnownLabelsAndEventClasses(); ProfilingStaticGuid DeclareLabel(const std::string& labelName); + void CreateTypedLabel(ProfilingGuid entityGuid, const std::string& entityName, ProfilingStaticGuid labelTypeGuid); private: ISendTimelinePacket& m_SendTimelinePacket; diff --git a/src/profiling/test/TimelineUtilityMethodsTests.cpp b/src/profiling/test/TimelineUtilityMethodsTests.cpp index 6d0fa2e105..c98ed83201 100644 --- a/src/profiling/test/TimelineUtilityMethodsTests.cpp +++ b/src/profiling/test/TimelineUtilityMethodsTests.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include @@ -30,7 +31,7 @@ inline unsigned int OffsetToNextWord(unsigned int numberOfBytes) return numberOfBytes + uint32_t_size - remainder; } -void VerifyTimelineLabelBinaryPacket(ProfilingGuid guid, +void VerifyTimelineLabelBinaryPacket(Optional guid, const std::string& label, const unsigned char* readableData, unsigned int& offset) @@ -67,7 +68,14 @@ void VerifyTimelineLabelBinaryPacket(ProfilingGuid guid, // Check the profiling GUID offset += uint32_t_size; uint64_t readProfilingGuid = ReadUint64(readableData, offset); - BOOST_CHECK(readProfilingGuid == guid); + 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; @@ -120,6 +128,106 @@ void VerifyTimelineEventClassBinaryPacket(ProfilingGuid guid, 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; } @@ -127,6 +235,55 @@ void VerifyTimelineEventClassBinaryPacket(ProfilingGuid guid, BOOST_AUTO_TEST_SUITE(TimelineUtilityMethodsTests) +BOOST_AUTO_TEST_CASE(CreateTypedLabelTest) +{ + MockBufferManager mockBufferManager(1024); + SendTimelinePacket sendTimelinePacket(mockBufferManager); + TimelineUtilityMethods timelineUtilityMethods(sendTimelinePacket); + + ProfilingGuid entityGuid(123); + const std::string entityName = "some entity"; + ProfilingStaticGuid labelTypeGuid(456); + + BOOST_CHECK_NO_THROW(timelineUtilityMethods.CreateTypedLabel(entityGuid, entityName, labelTypeGuid)); + + // Commit all packets at once + sendTimelinePacket.Commit(); + + // Get the readable buffer + auto readableBuffer = mockBufferManager.GetReadableBuffer(); + BOOST_CHECK(readableBuffer != nullptr); + unsigned int size = readableBuffer->GetSize(); + BOOST_CHECK(size == 116); + const unsigned char* readableData = readableBuffer->GetReadableData(); + BOOST_CHECK(readableData != nullptr); + + // Utils + unsigned int offset = 0; + + // First packet sent: TimelineLabelBinaryPacket + VerifyTimelineLabelBinaryPacket(EmptyOptional(), entityName, readableData, offset); + + // Second packet sent: TimelineRelationshipBinaryPacket + VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::LabelLink, + EmptyOptional(), + entityGuid, + EmptyOptional(), + readableData, + offset); + + // Third packet sent: TimelineRelationshipBinaryPacket + VerifyTimelineRelationshipBinaryPacket(ProfilingRelationshipType::LabelLink, + EmptyOptional(), + EmptyOptional(), + labelTypeGuid, + readableData, + offset); + + // Mark the buffer as read + mockBufferManager.MarkRead(readableBuffer); +} + BOOST_AUTO_TEST_CASE(SendWellKnownLabelsAndEventClassesTest) { MockBufferManager mockBufferManager(1024); -- cgit v1.2.1