From: Matteo Martincigh Date: Wed, 16 Oct 2019 09:29:17 +0000 (+0100) Subject: IVGCVSW-3931 Create the Timeline Event Binary Packet X-Git-Tag: submit/tizen/20200316.035456~150 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=8844c2f35b06931a799f9a77637e8e291b43d60a;p=platform%2Fupstream%2Farmnn.git IVGCVSW-3931 Create the Timeline Event Binary Packet * Added WriteTimelineEventBinaryPacket function * Added unit tests * Code refactoring Signed-off-by: Matteo Martincigh Change-Id: I36b6a8b26bb46eb5ea97bb711ef7e153ea6d851f --- diff --git a/src/profiling/ProfilingUtils.cpp b/src/profiling/ProfilingUtils.cpp index 798cfa4..b7def29 100644 --- a/src/profiling/ProfilingUtils.cpp +++ b/src/profiling/ProfilingUtils.cpp @@ -247,7 +247,7 @@ std::string GetProcessName() /// packetType Timeline Packet Type /// streamId Stream identifier /// seqeunceNumbered When non-zero the 4 bytes following the header is a u32 sequence number -/// dataLength Unsigned 24-bit integer. Length of data, in bytes. Zero is permitted. +/// dataLength Unsigned 24-bit integer. Length of data, in bytes. Zero is permitted /// /// \returns /// Pair of uint32_t containing word0 and word1 of the header @@ -287,13 +287,18 @@ std::pair CreateTimelinePacketHeader(uint32_t packetFamily, /// * declareEvent /// /// \param -/// Data lenght of the message body in byte +/// dataLength The length of the message body in bytes /// /// \returns /// Pair of uint32_t containing word0 and word1 of the header std::pair CreateTimelineMessagePacketHeader(unsigned int dataLength) { - return CreateTimelinePacketHeader(1,0,1,0,0,dataLength); + return CreateTimelinePacketHeader(1, // Packet family + 0, // Packet class + 1, // Packet type + 0, // Stream id + 0, // Sequence number + dataLength); // Data length } TimelinePacketStatus WriteTimelineLabelBinaryPacket(uint64_t profilingGuid, @@ -302,7 +307,7 @@ TimelinePacketStatus WriteTimelineLabelBinaryPacket(uint64_t profilingGuid, unsigned int bufferSize, unsigned int& numberOfBytesWritten) { - // Initialize the ouput value + // Initialize the output value numberOfBytesWritten = 0; // Check that the given buffer is valid @@ -342,8 +347,7 @@ TimelinePacketStatus WriteTimelineLabelBinaryPacket(uint64_t profilingGuid, } // Create packet header - uint32_t dataLength = boost::numeric_cast(timelineLabelPacketDataLength); // decl_id + GUID + label - std::pair packetHeader = CreateTimelineMessagePacketHeader(dataLength); + std::pair packetHeader = CreateTimelineMessagePacketHeader(timelineLabelPacketDataLength); // Initialize the offset for writing in the buffer unsigned int offset = 0; @@ -378,7 +382,7 @@ TimelinePacketStatus WriteTimelineEntityBinaryPacket(uint64_t profilingGuid, unsigned int bufferSize, unsigned int& numberOfBytesWritten) { - // Initialize the ouput value + // Initialize the output value numberOfBytesWritten = 0; // Check that the given buffer is valid @@ -407,8 +411,7 @@ TimelinePacketStatus WriteTimelineEntityBinaryPacket(uint64_t profilingGuid, } // Create packet header - uint32_t dataLength = boost::numeric_cast(timelineEntityPacketDataLength); - std::pair packetHeader = CreateTimelineMessagePacketHeader(dataLength); + std::pair packetHeader = CreateTimelineMessagePacketHeader(timelineEntityPacketDataLength); // Initialize the offset for writing in the buffer unsigned int offset = 0; @@ -448,24 +451,25 @@ TimelinePacketStatus WriteTimelineMessageDirectoryPackage(unsigned char* buffer, // Utils unsigned int uint32_t_size = sizeof(uint32_t); - // the payload/data of the packet consists of swtrace event definitions encoded according + // The payload/data of the packet consists of swtrace event definitions encoded according // to the swtrace directory specification. The messages being the five defined below: // | decl_id | decl_name | ui_name | arg_types | arg_names | // |-----------|---------------------|-----------------------|-------------|-------------------------------------| // | 0 | declareLabel | declare label | ps | guid,value | // | 1 | declareEntity | declare entity | p | guid | // | 2 | declareEventClass | declare event class | p | guid | - // | 3 | declareRelationship | declare relationship | Ippp | relationshipType,relationshipGuid, - // headGuid,tailGuid | + // | 3 | declareRelationship | declare relationship | Ippp | relationshipType,relationshipGuid, | + // | | | | | headGuid,tailGuid | // | 4 | declareEvent | declare event | @tp | timestamp,threadId,eventGuid | - std::vector> timelineDirectoryMessages = - { {"declareLabel", "declare label", "ps", "guid,value"}, - {"declareEntity", "declare entity", "p", "guid"}, - {"declareEventClass", "declare event class", "p", "guid"}, - {"declareRelationship", "declare relationship", - "Ippp", "relationshipType,relationshipGuid,headGuid,tailGuid"}, - {"declareEvent", "declare event", "@tp", "timestamp,threadId,eventGuid"} }; + std::vector> timelineDirectoryMessages + { + {"declareLabel", "declare label", "ps", "guid,value"}, + {"declareEntity", "declare entity", "p", "guid"}, + {"declareEventClass", "declare event class", "p", "guid"}, + {"declareRelationship", "declare relationship", "Ippp", "relationshipType,relationshipGuid,headGuid,tailGuid"}, + {"declareEvent", "declare event", "@tp", "timestamp,threadId,eventGuid"} + }; unsigned int messagesDataLength = 0u; std::vector>> swTraceTimelineDirectoryMessages; @@ -501,8 +505,8 @@ TimelinePacketStatus WriteTimelineMessageDirectoryPackage(unsigned char* buffer, } // Create packet header - uint32_t dataLength = boost::numeric_cast(messagesDataLength); - std::pair packetHeader = CreateTimelinePacketHeader(1,0,0,0,0,dataLength); + uint32_t dataLength = boost::numeric_cast(messagesDataLength); + std::pair packetHeader = CreateTimelinePacketHeader(1, 0, 0, 0, 0, dataLength); // Initialize the offset for writing in the buffer unsigned int offset = 0; @@ -540,7 +544,7 @@ TimelinePacketStatus WriteTimelineEventClassBinaryPacket(uint64_t profilingGuid, unsigned int bufferSize, unsigned int& numberOfBytesWritten) { - // Initialize the ouput value + // Initialize the output value numberOfBytesWritten = 0; // Check that the given buffer is valid @@ -553,15 +557,15 @@ TimelinePacketStatus WriteTimelineEventClassBinaryPacket(uint64_t profilingGuid, unsigned int uint32_t_size = sizeof(uint32_t); unsigned int uint64_t_size = sizeof(uint64_t); - // dec_id of the timeline message - uint32_t decId = 2; + // decl_id of the timeline message + uint32_t declId = 2; // Calculate the length of the data (in bytes) - unsigned int packetBodySize = uint32_t_size + uint64_t_size; // decl_id + Profiling GUID + unsigned int packetBodySize = uint32_t_size + uint64_t_size; // decl_id + Profiling GUID // Calculate the timeline binary packet size (in bytes) - unsigned int packetSize = 2 * uint32_t_size + // Header (2 words) - packetBodySize; // Body + unsigned int packetSize = 2 * uint32_t_size + // Header (2 words) + packetBodySize; // Body // Check whether the timeline binary packet fits in the given buffer if (packetSize > bufferSize) @@ -570,8 +574,7 @@ TimelinePacketStatus WriteTimelineEventClassBinaryPacket(uint64_t profilingGuid, } // Create packet header - uint32_t dataLength = boost::numeric_cast(packetBodySize); - std::pair packetHeader = CreateTimelineMessagePacketHeader(dataLength); + std::pair packetHeader = CreateTimelineMessagePacketHeader(packetBodySize); // Initialize the offset for writing in the buffer unsigned int offset = 0; @@ -583,7 +586,7 @@ TimelinePacketStatus WriteTimelineEventClassBinaryPacket(uint64_t profilingGuid, offset += uint32_t_size; // Write the timeline binary packet payload to the buffer - WriteUint32(buffer, offset, decId); // dec_id + WriteUint32(buffer, offset, declId); // decl_id offset += uint32_t_size; WriteUint64(buffer, offset, profilingGuid); // Profiling GUID @@ -593,6 +596,73 @@ TimelinePacketStatus WriteTimelineEventClassBinaryPacket(uint64_t profilingGuid, return TimelinePacketStatus::Ok; } +TimelinePacketStatus WriteTimelineEventBinaryPacket(uint64_t timestamp, + uint32_t threadId, + uint64_t profilingGuid, + unsigned char* buffer, + unsigned int bufferSize, + unsigned int& numberOfBytesWritten) +{ + // Initialize the output value + numberOfBytesWritten = 0; + + // Check that the given buffer is valid + if (buffer == nullptr || bufferSize == 0) + { + return TimelinePacketStatus::BufferExhaustion; + } + + // Utils + unsigned int uint32_t_size = sizeof(uint32_t); + unsigned int uint64_t_size = sizeof(uint64_t); + + // decl_id of the timeline message + uint32_t declId = 4; + + // Calculate the length of the data (in bytes) + unsigned int timelineEventPacketDataLength = uint32_t_size + // decl_id + uint64_t_size + // Timestamp + uint32_t_size + // Thread id + uint64_t_size; // Profiling GUID + + // Calculate the timeline binary packet size (in bytes) + unsigned int timelineEventPacketSize = 2 * uint32_t_size + // Header (2 words) + timelineEventPacketDataLength; // Timestamp + thread id + profiling GUID + + // Check whether the timeline binary packet fits in the given buffer + if (timelineEventPacketSize > bufferSize) + { + return TimelinePacketStatus::BufferExhaustion; + } + + // Create packet header + std::pair packetHeader = CreateTimelineMessagePacketHeader(timelineEventPacketDataLength); + + // Initialize the offset for writing in the buffer + unsigned int offset = 0; + + // Write the timeline binary packet header to the buffer + WriteUint32(buffer, offset, packetHeader.first); + offset += uint32_t_size; + WriteUint32(buffer, offset, packetHeader.second); + offset += uint32_t_size; + + // Write the timeline binary packet payload to the buffer + WriteUint32(buffer, offset, declId); // decl_id + offset += uint32_t_size; + WriteUint64(buffer, offset, timestamp); // Timestamp + offset += uint64_t_size; + WriteUint32(buffer, offset, threadId); // Thread id + offset += uint32_t_size; + WriteUint64(buffer, offset, profilingGuid); // Profiling GUID + offset += uint64_t_size; + + // Update the number of bytes written + numberOfBytesWritten = timelineEventPacketSize; + + return TimelinePacketStatus::Ok; +} + } // namespace profiling } // namespace armnn diff --git a/src/profiling/ProfilingUtils.hpp b/src/profiling/ProfilingUtils.hpp index 8c0251d..c8a5c7f 100644 --- a/src/profiling/ProfilingUtils.hpp +++ b/src/profiling/ProfilingUtils.hpp @@ -133,9 +133,9 @@ TimelinePacketStatus WriteTimelineLabelBinaryPacket(uint64_t profilingGuid, unsigned int& numberOfBytesWritten); TimelinePacketStatus WriteTimelineEntityBinaryPacket(uint64_t profilingGuid, - unsigned char* buffer, - unsigned int bufferSize, - unsigned int& numberOfBytesWritten); + unsigned char* buffer, + unsigned int bufferSize, + unsigned int& numberOfBytesWritten); TimelinePacketStatus WriteTimelineMessageDirectoryPackage(unsigned char* buffer, unsigned int bufferSize, @@ -146,6 +146,13 @@ TimelinePacketStatus WriteTimelineEventClassBinaryPacket(uint64_t profilingGuid, unsigned int bufferSize, unsigned int& numberOfBytesWritten); +TimelinePacketStatus WriteTimelineEventBinaryPacket(uint64_t timestamp, + uint32_t threadId, + uint64_t profilingGuid, + unsigned char* buffer, + unsigned int bufferSize, + unsigned int& numberOfBytesWritten); + class BufferExhaustion : public armnn::Exception { using Exception::Exception; diff --git a/src/profiling/test/TimelinePacketTests.cpp b/src/profiling/test/TimelinePacketTests.cpp index 759d825..558af04 100644 --- a/src/profiling/test/TimelinePacketTests.cpp +++ b/src/profiling/test/TimelinePacketTests.cpp @@ -433,4 +433,116 @@ BOOST_AUTO_TEST_CASE(TimelineEventClassTest4) BOOST_CHECK(readProfilingGuid == profilingGuid); } -BOOST_AUTO_TEST_SUITE_END() // TimelinePacketTests \ No newline at end of file +BOOST_AUTO_TEST_CASE(TimelineEventPacketTest1) +{ + const uint64_t timestamp = 456789u; + const uint32_t threadId = 654321u; + const uint64_t profilingGuid = 123456u; + unsigned int numberOfBytesWritten = 789u; + TimelinePacketStatus result = WriteTimelineEventBinaryPacket(timestamp, + threadId, + profilingGuid, + nullptr, + 512u, + numberOfBytesWritten); + BOOST_CHECK(result == TimelinePacketStatus::BufferExhaustion); + BOOST_CHECK(numberOfBytesWritten == 0); +} + +BOOST_AUTO_TEST_CASE(TimelineEventPacketTest2) +{ + std::vector buffer(512, 0); + + const uint64_t timestamp = 456789u; + const uint32_t threadId = 654321u; + const uint64_t profilingGuid = 123456u; + unsigned int numberOfBytesWritten = 789u; + TimelinePacketStatus result = WriteTimelineEventBinaryPacket(timestamp, + threadId, + profilingGuid, + buffer.data(), + 0, + numberOfBytesWritten); + BOOST_CHECK(result == TimelinePacketStatus::BufferExhaustion); + BOOST_CHECK(numberOfBytesWritten == 0); +} + +BOOST_AUTO_TEST_CASE(TimelineEventPacketTest3) +{ + std::vector buffer(10, 0); + + const uint64_t timestamp = 456789u; + const uint32_t threadId = 654321u; + const uint64_t profilingGuid = 123456u; + unsigned int numberOfBytesWritten = 789u; + TimelinePacketStatus result = WriteTimelineEventBinaryPacket(timestamp, + threadId, + profilingGuid, + buffer.data(), + boost::numeric_cast(buffer.size()), + numberOfBytesWritten); + BOOST_CHECK(result == TimelinePacketStatus::BufferExhaustion); + BOOST_CHECK(numberOfBytesWritten == 0); +} + +BOOST_AUTO_TEST_CASE(TimelineEventPacketTest4) +{ + std::vector buffer(512, 0); + + const uint64_t timestamp = 456789u; + const uint32_t threadId = 654321u; + const uint64_t profilingGuid = 123456u; + unsigned int numberOfBytesWritten = 789u; + TimelinePacketStatus result = WriteTimelineEventBinaryPacket(timestamp, + threadId, + profilingGuid, + buffer.data(), + boost::numeric_cast(buffer.size()), + numberOfBytesWritten); + BOOST_CHECK(result == TimelinePacketStatus::Ok); + BOOST_CHECK(numberOfBytesWritten == 32); + + unsigned int uint32_t_size = sizeof(uint32_t); + unsigned int uint64_t_size = sizeof(uint64_t); + + // Check the packet header + unsigned int offset = 0; + uint32_t packetHeaderWord0 = ReadUint32(buffer.data(), offset); + uint32_t packetFamily = (packetHeaderWord0 >> 26) & 0x0000003F; + uint32_t packetClass = (packetHeaderWord0 >> 19) & 0x0000007F; + uint32_t packetType = (packetHeaderWord0 >> 16) & 0x00000007; + uint32_t streamId = (packetHeaderWord0 >> 0) & 0x00000007; + BOOST_CHECK(packetFamily == 1); + BOOST_CHECK(packetClass == 0); + BOOST_CHECK(packetType == 1); + BOOST_CHECK(streamId == 0); + + offset += uint32_t_size; + uint32_t packetHeaderWord1 = ReadUint32(buffer.data(), offset); + uint32_t sequenceNumbered = (packetHeaderWord1 >> 24) & 0x00000001; + uint32_t dataLength = (packetHeaderWord1 >> 0) & 0x00FFFFFF; + BOOST_CHECK(sequenceNumbered == 0); + BOOST_CHECK(dataLength == 24); + + // Check the decl_id + offset += uint32_t_size; + uint32_t readDeclId = ReadUint32(buffer.data(), offset); + BOOST_CHECK(readDeclId == 4); + + // Check the timestamp + offset += uint32_t_size; + uint64_t readTimestamp = ReadUint64(buffer.data(), offset); + BOOST_CHECK(readTimestamp == timestamp); + + // Check the thread id + offset += uint64_t_size; + uint32_t readThreadId = ReadUint32(buffer.data(), offset); + BOOST_CHECK(readThreadId == threadId); + + // Check the profiling GUID + offset += uint32_t_size; + uint64_t readProfilingGuid = ReadUint64(buffer.data(), offset); + BOOST_CHECK(readProfilingGuid == profilingGuid); +} + +BOOST_AUTO_TEST_SUITE_END()