blob: 8d0b8a0f0817b544aa26e16e238d5bb82c5ab6a0 [file] [log] [blame]
Finn Williamse63a0262019-10-22 10:30:49 +01001//
2// Copyright © 2019 Arm Ltd. All rights reserved.
3// SPDX-License-Identifier: MIT
4//
5
Finn Williams8a2b4682020-02-26 10:25:26 +00006#include <TimelineCaptureCommandHandler.hpp>
7#include <TimelineDirectoryCaptureCommandHandler.hpp>
8#include <TimelineDecoder.hpp>
Finn Williamse63a0262019-10-22 10:30:49 +01009
10#include <CommandHandlerFunctor.hpp>
11#include <ProfilingService.hpp>
12#include <PacketBuffer.hpp>
13#include <TimelinePacketWriterFactory.hpp>
14
15#include <boost/test/test_tools.hpp>
16#include <boost/test/unit_test_suite.hpp>
17
18BOOST_AUTO_TEST_SUITE(TimelineDecoderTests)
19
20using namespace armnn;
Finn Williams8a2b4682020-02-26 10:25:26 +000021using namespace timelinedecoder;
Finn Williamse63a0262019-10-22 10:30:49 +010022
23void SendTimelinePacketToCommandHandler(const unsigned char* packetBuffer,
24 profiling::CommandHandlerFunctor &CommandHandler)
25{
26 uint32_t uint32_t_size = sizeof(uint32_t);
27 unsigned int offset = 0;
28
29 uint32_t header[2];
30 header[0] = profiling::ReadUint32(packetBuffer, offset);
31 offset += uint32_t_size;
32 header[1] = profiling::ReadUint32(packetBuffer, offset);
33 offset += uint32_t_size;
Finn Williamse63a0262019-10-22 10:30:49 +010034 uint32_t PacketDataLength = header[1] & 0x00FFFFFF;
35
Matteo Martincigh34a407d2019-11-06 15:30:54 +000036 auto uniquePacketData = std::make_unique<unsigned char[]>(PacketDataLength);
Finn Williamse63a0262019-10-22 10:30:49 +010037 std::memcpy(uniquePacketData.get(), packetBuffer + offset, PacketDataLength);
38
Matteo Martincigh34a407d2019-11-06 15:30:54 +000039 armnn::profiling::Packet packet(header[0], PacketDataLength, uniquePacketData);
40
41 BOOST_CHECK(std::memcmp(packetBuffer + offset, packet.GetData(), packet.GetLength()) == 0);
Finn Williamse63a0262019-10-22 10:30:49 +010042
43 CommandHandler(packet);
44}
45
Finn Williams510f6182020-02-21 11:14:08 +000046void PushEntity(TimelineDecoder::Model& model, const ITimelineDecoder::Entity entity)
47{
48 model.m_Entities.emplace_back(entity);
49}
50
51void PushEventClass(TimelineDecoder::Model& model, const ITimelineDecoder::EventClass eventClass)
52{
53 model.m_EventClasses.emplace_back(eventClass);
54}
55
56void PushEvent(TimelineDecoder::Model& model, const ITimelineDecoder::Event event)
57{
58 model.m_Events.emplace_back(event);
59}
60
61void PushLabel(TimelineDecoder::Model& model, const ITimelineDecoder::Label label)
62{
63 model.m_Labels.emplace_back(label);
64}
65
66void PushRelationship(TimelineDecoder::Model& model, const ITimelineDecoder::Relationship relationship)
67{
68 model.m_Relationships.emplace_back(relationship);
69}
70
Matteo Martincigh34a407d2019-11-06 15:30:54 +000071BOOST_AUTO_TEST_CASE(TimelineDirectoryTest)
Finn Williamse63a0262019-10-22 10:30:49 +010072{
Matteo Martincigh34a407d2019-11-06 15:30:54 +000073 uint32_t uint8_t_size = sizeof(uint8_t);
Finn Williamse63a0262019-10-22 10:30:49 +010074 uint32_t uint32_t_size = sizeof(uint32_t);
Matteo Martincigh34a407d2019-11-06 15:30:54 +000075 uint32_t uint64_t_size = sizeof(uint64_t);
Finn Williamse63a0262019-10-22 10:30:49 +010076
77 profiling::BufferManager bufferManager(5);
78 profiling::TimelinePacketWriterFactory timelinePacketWriterFactory(bufferManager);
79
80 std::unique_ptr<profiling::ISendTimelinePacket> sendTimelinePacket =
81 timelinePacketWriterFactory.GetSendTimelinePacket();
82
83 profiling::PacketVersionResolver packetVersionResolver;
84
Finn Williamse6a2ccd2020-02-27 16:21:41 +000085 TimelineDecoder timelineDecoder;
86 TimelineCaptureCommandHandler timelineCaptureCommandHandler(
87 1, 1, packetVersionResolver.ResolvePacketVersion(1, 1).GetEncodedValue(), timelineDecoder);
88
Finn Williams8a2b4682020-02-26 10:25:26 +000089 TimelineDirectoryCaptureCommandHandler timelineDirectoryCaptureCommandHandler(
Finn Williamse6a2ccd2020-02-27 16:21:41 +000090 1, 0, packetVersionResolver.ResolvePacketVersion(1, 0).GetEncodedValue(),
91 timelineCaptureCommandHandler, true);
Finn Williamse63a0262019-10-22 10:30:49 +010092
93 sendTimelinePacket->SendTimelineMessageDirectoryPackage();
94 sendTimelinePacket->Commit();
95
96 std::vector<profiling::SwTraceMessage> swTraceBufferMessages;
97
98 unsigned int offset = uint32_t_size * 2;
99
100 std::unique_ptr<profiling::IPacketBuffer> packetBuffer = bufferManager.GetReadableBuffer();
101
Matteo Martincigh34a407d2019-11-06 15:30:54 +0000102 uint8_t readStreamVersion = ReadUint8(packetBuffer, offset);
103 BOOST_CHECK(readStreamVersion == 4);
104 offset += uint8_t_size;
105 uint8_t readPointerBytes = ReadUint8(packetBuffer, offset);
106 BOOST_CHECK(readPointerBytes == uint64_t_size);
107 offset += uint8_t_size;
108 uint8_t readThreadIdBytes = ReadUint8(packetBuffer, offset);
Colm Donelan5bb3d8a2020-05-12 16:36:46 +0100109 BOOST_CHECK(readThreadIdBytes == armnn::profiling::ThreadIdSize);
Matteo Martincigh34a407d2019-11-06 15:30:54 +0000110 offset += uint8_t_size;
111
Finn Williamse63a0262019-10-22 10:30:49 +0100112 uint32_t declarationSize = profiling::ReadUint32(packetBuffer, offset);
113 offset += uint32_t_size;
114 for(uint32_t i = 0; i < declarationSize; ++i)
115 {
116 swTraceBufferMessages.push_back(profiling::ReadSwTraceMessage(packetBuffer->GetReadableData(), offset));
117 }
118
119 SendTimelinePacketToCommandHandler(packetBuffer->GetReadableData(), timelineDirectoryCaptureCommandHandler);
120
121 for(uint32_t index = 0; index < declarationSize; ++index)
122 {
123 profiling::SwTraceMessage& bufferMessage = swTraceBufferMessages[index];
124 profiling::SwTraceMessage& handlerMessage = timelineDirectoryCaptureCommandHandler.m_SwTraceMessages[index];
125
Matteo Martincigh34a407d2019-11-06 15:30:54 +0000126 BOOST_CHECK(bufferMessage.m_Name == handlerMessage.m_Name);
127 BOOST_CHECK(bufferMessage.m_UiName == handlerMessage.m_UiName);
128 BOOST_CHECK(bufferMessage.m_Id == handlerMessage.m_Id);
Finn Williamse63a0262019-10-22 10:30:49 +0100129
Matteo Martincigh34a407d2019-11-06 15:30:54 +0000130 BOOST_CHECK(bufferMessage.m_ArgTypes.size() == handlerMessage.m_ArgTypes.size());
131 for(uint32_t i = 0; i < bufferMessage.m_ArgTypes.size(); ++i)
Finn Williamse63a0262019-10-22 10:30:49 +0100132 {
Matteo Martincigh34a407d2019-11-06 15:30:54 +0000133 BOOST_CHECK(bufferMessage.m_ArgTypes[i] == handlerMessage.m_ArgTypes[i]);
Finn Williamse63a0262019-10-22 10:30:49 +0100134 }
135
Matteo Martincigh34a407d2019-11-06 15:30:54 +0000136 BOOST_CHECK(bufferMessage.m_ArgNames.size() == handlerMessage.m_ArgNames.size());
137 for(uint32_t i = 0; i < bufferMessage.m_ArgNames.size(); ++i)
Finn Williamse63a0262019-10-22 10:30:49 +0100138 {
Matteo Martincigh34a407d2019-11-06 15:30:54 +0000139 BOOST_CHECK(bufferMessage.m_ArgNames[i] == handlerMessage.m_ArgNames[i]);
Finn Williamse63a0262019-10-22 10:30:49 +0100140 }
141 }
142}
143
144BOOST_AUTO_TEST_CASE(TimelineCaptureTest)
145{
Finn Williamse63a0262019-10-22 10:30:49 +0100146 profiling::BufferManager bufferManager(50);
147 profiling::TimelinePacketWriterFactory timelinePacketWriterFactory(bufferManager);
148
149 std::unique_ptr<profiling::ISendTimelinePacket> sendTimelinePacket =
150 timelinePacketWriterFactory.GetSendTimelinePacket();
151
152 profiling::PacketVersionResolver packetVersionResolver;
153
Finn Williams510f6182020-02-21 11:14:08 +0000154 TimelineDecoder timelineDecoder;
155 const TimelineDecoder::Model& model = timelineDecoder.GetModel();
Finn Williamse63a0262019-10-22 10:30:49 +0100156
Finn Williamse6a2ccd2020-02-27 16:21:41 +0000157
Finn Williams8a2b4682020-02-26 10:25:26 +0000158 TimelineCaptureCommandHandler timelineCaptureCommandHandler(
Colm Donelan5bb3d8a2020-05-12 16:36:46 +0100159 1, 1, packetVersionResolver.ResolvePacketVersion(1, 1).GetEncodedValue(), timelineDecoder,
160 armnn::profiling::ThreadIdSize);
Finn Williamse63a0262019-10-22 10:30:49 +0100161
Keith Davis97da5e22020-03-05 16:25:28 +0000162 using Status = ITimelineDecoder::TimelineStatus;
163 BOOST_CHECK(timelineDecoder.SetEntityCallback(PushEntity) == Status::TimelineStatus_Success);
164 BOOST_CHECK(timelineDecoder.SetEventClassCallback(PushEventClass) == Status::TimelineStatus_Success);
165 BOOST_CHECK(timelineDecoder.SetEventCallback(PushEvent) == Status::TimelineStatus_Success);
166 BOOST_CHECK(timelineDecoder.SetLabelCallback(PushLabel) == Status::TimelineStatus_Success);
167 BOOST_CHECK(timelineDecoder.SetRelationshipCallback(PushRelationship) == Status::TimelineStatus_Success);
Finn Williamse63a0262019-10-22 10:30:49 +0100168
Keith Davis97da5e22020-03-05 16:25:28 +0000169 const uint64_t entityGuid = 111111u;
Finn Williams510f6182020-02-21 11:14:08 +0000170 const uint64_t eventClassGuid = 22222u;
Jim Flynn1892d212020-05-26 21:10:49 +0100171 const uint64_t eventClassNameGuid = 22322u;
Finn Williams510f6182020-02-21 11:14:08 +0000172 const uint64_t timestamp = 33333u;
173 const uint64_t eventGuid = 44444u;
Finn Williamse63a0262019-10-22 10:30:49 +0100174
Finn Williams510f6182020-02-21 11:14:08 +0000175 const std::thread::id threadId = std::this_thread::get_id();
Finn Williamse63a0262019-10-22 10:30:49 +0100176
Finn Williams510f6182020-02-21 11:14:08 +0000177 // need to do a bit of work here to extract the value from threadId
Colm Donelan5bb3d8a2020-05-12 16:36:46 +0100178 unsigned char* uCharThreadId = new unsigned char[armnn::profiling::ThreadIdSize]();;
Finn Williams510f6182020-02-21 11:14:08 +0000179 uint64_t uint64ThreadId;
Finn Williamse63a0262019-10-22 10:30:49 +0100180
Colm Donelan5bb3d8a2020-05-12 16:36:46 +0100181 profiling::WriteBytes(uCharThreadId, 0, &threadId, armnn::profiling::ThreadIdSize);
Finn Williamse63a0262019-10-22 10:30:49 +0100182
Colm Donelan5bb3d8a2020-05-12 16:36:46 +0100183 if (armnn::profiling::ThreadIdSize == 4)
Finn Williams510f6182020-02-21 11:14:08 +0000184 {
185 uint64ThreadId = profiling::ReadUint32(uCharThreadId, 0);
186 }
Colm Donelan5bb3d8a2020-05-12 16:36:46 +0100187 else if (armnn::profiling::ThreadIdSize == 8)
Finn Williams510f6182020-02-21 11:14:08 +0000188 {
189 uint64ThreadId = profiling::ReadUint64(uCharThreadId, 0);
190 }
191 delete[] uCharThreadId;
192
193 const uint64_t labelGuid = 66666u;
Finn Williamse63a0262019-10-22 10:30:49 +0100194 std::string labelName = "test_label";
195
Finn Williams510f6182020-02-21 11:14:08 +0000196 const uint64_t relationshipGuid = 77777u;
197 const uint64_t headGuid = 888888u;
198 const uint64_t tailGuid = 999999u;
Finn Williamse63a0262019-10-22 10:30:49 +0100199
200 for (int i = 0; i < 10; ++i)
201 {
202 // Send entity
203 sendTimelinePacket->SendTimelineEntityBinaryPacket(entityGuid);
204 sendTimelinePacket->Commit();
205 SendTimelinePacketToCommandHandler(bufferManager.GetReadableBuffer()->GetReadableData(),
206 timelineCaptureCommandHandler);
207
208 // Send event class
Jim Flynn1892d212020-05-26 21:10:49 +0100209 sendTimelinePacket->SendTimelineEventClassBinaryPacket(eventClassGuid, eventClassNameGuid);
Finn Williamse63a0262019-10-22 10:30:49 +0100210 sendTimelinePacket->Commit();
211 SendTimelinePacketToCommandHandler(bufferManager.GetReadableBuffer()->GetReadableData(),
212 timelineCaptureCommandHandler);
213
214 // Send event
215 sendTimelinePacket->SendTimelineEventBinaryPacket(timestamp, threadId, eventGuid);
216 sendTimelinePacket->Commit();
217 SendTimelinePacketToCommandHandler(bufferManager.GetReadableBuffer()->GetReadableData(),
218 timelineCaptureCommandHandler);
219
220 // Send label
221 sendTimelinePacket->SendTimelineLabelBinaryPacket(labelGuid, labelName);
222 sendTimelinePacket->Commit();
223 SendTimelinePacketToCommandHandler(bufferManager.GetReadableBuffer()->GetReadableData(),
224 timelineCaptureCommandHandler);
225
226 // Send relationship
227 profiling::ProfilingRelationshipType relationshipType = profiling::ProfilingRelationshipType::DataLink;
228 sendTimelinePacket->SendTimelineRelationshipBinaryPacket(relationshipType,
229 relationshipGuid,
230 headGuid,
Finn Williams0a336dc2020-05-11 15:39:58 +0100231 tailGuid,
232 0);
Finn Williamse63a0262019-10-22 10:30:49 +0100233 sendTimelinePacket->Commit();
234 SendTimelinePacketToCommandHandler(bufferManager.GetReadableBuffer()->GetReadableData(),
235 timelineCaptureCommandHandler);
236 }
237
Finn Williams510f6182020-02-21 11:14:08 +0000238 for (unsigned long i = 0; i < 10; ++i)
Finn Williamse63a0262019-10-22 10:30:49 +0100239 {
Finn Williams510f6182020-02-21 11:14:08 +0000240 BOOST_CHECK(model.m_Entities[i].m_Guid == entityGuid);
Finn Williamse63a0262019-10-22 10:30:49 +0100241
Finn Williams510f6182020-02-21 11:14:08 +0000242 BOOST_CHECK(model.m_EventClasses[i].m_Guid == eventClassGuid);
Finn Williamse63a0262019-10-22 10:30:49 +0100243
Finn Williams510f6182020-02-21 11:14:08 +0000244 BOOST_CHECK(model.m_Events[i].m_TimeStamp == timestamp);
245 BOOST_CHECK(model.m_Events[i].m_ThreadId == uint64ThreadId);
246 BOOST_CHECK(model.m_Events[i].m_Guid == eventGuid);
Finn Williamse63a0262019-10-22 10:30:49 +0100247
Finn Williams510f6182020-02-21 11:14:08 +0000248 BOOST_CHECK(model.m_Labels[i].m_Guid == labelGuid);
249 BOOST_CHECK(model.m_Labels[i].m_Name == labelName);
Finn Williamse63a0262019-10-22 10:30:49 +0100250
Finn Williams510f6182020-02-21 11:14:08 +0000251 BOOST_CHECK(model.m_Relationships[i].m_RelationshipType == ITimelineDecoder::RelationshipType::DataLink);
252 BOOST_CHECK(model.m_Relationships[i].m_Guid == relationshipGuid);
253 BOOST_CHECK(model.m_Relationships[i].m_HeadGuid == headGuid);
254 BOOST_CHECK(model.m_Relationships[i].m_TailGuid == tailGuid);
Finn Williamse63a0262019-10-22 10:30:49 +0100255 }
Finn Williamse63a0262019-10-22 10:30:49 +0100256}
257
Keith Davis5238aff2020-03-11 12:17:05 +0000258BOOST_AUTO_TEST_CASE(TimelineCaptureTestMultipleStringsInBuffer)
259{
Keith Davis5238aff2020-03-11 12:17:05 +0000260 profiling::BufferManager bufferManager(50);
261 profiling::TimelinePacketWriterFactory timelinePacketWriterFactory(bufferManager);
262
263 std::unique_ptr<profiling::ISendTimelinePacket> sendTimelinePacket =
264 timelinePacketWriterFactory.GetSendTimelinePacket();
265
266 profiling::PacketVersionResolver packetVersionResolver;
267
268 TimelineDecoder timelineDecoder;
269 const TimelineDecoder::Model& model = timelineDecoder.GetModel();
270
271 TimelineCaptureCommandHandler timelineCaptureCommandHandler(
Colm Donelan5bb3d8a2020-05-12 16:36:46 +0100272 1, 1, packetVersionResolver.ResolvePacketVersion(1, 1).GetEncodedValue(), timelineDecoder,
273 armnn::profiling::ThreadIdSize);
Keith Davis5238aff2020-03-11 12:17:05 +0000274
275 using Status = ITimelineDecoder::TimelineStatus;
276 BOOST_CHECK(timelineDecoder.SetEntityCallback(PushEntity) == Status::TimelineStatus_Success);
277 BOOST_CHECK(timelineDecoder.SetEventClassCallback(PushEventClass) == Status::TimelineStatus_Success);
278 BOOST_CHECK(timelineDecoder.SetEventCallback(PushEvent) == Status::TimelineStatus_Success);
279 BOOST_CHECK(timelineDecoder.SetLabelCallback(PushLabel) == Status::TimelineStatus_Success);
280 BOOST_CHECK(timelineDecoder.SetRelationshipCallback(PushRelationship) == Status::TimelineStatus_Success);
281
Jim Flynn1892d212020-05-26 21:10:49 +0100282 const uint64_t entityGuid = 111111u;
283 const uint64_t eventClassGuid = 22222u;
284 const uint64_t eventClassNameGuid = 22322u;
285 const uint64_t timestamp = 33333u;
286 const uint64_t eventGuid = 44444u;
Keith Davis5238aff2020-03-11 12:17:05 +0000287
288 const std::thread::id threadId = std::this_thread::get_id();
289
290 // need to do a bit of work here to extract the value from threadId
Colm Donelan5bb3d8a2020-05-12 16:36:46 +0100291 unsigned char* uCharThreadId = new unsigned char[armnn::profiling::ThreadIdSize]();
Keith Davis5238aff2020-03-11 12:17:05 +0000292 uint64_t uint64ThreadId;
293
Colm Donelan5bb3d8a2020-05-12 16:36:46 +0100294 profiling::WriteBytes(uCharThreadId, 0, &threadId, armnn::profiling::ThreadIdSize);
Keith Davis5238aff2020-03-11 12:17:05 +0000295
Colm Donelan5bb3d8a2020-05-12 16:36:46 +0100296 if ( armnn::profiling::ThreadIdSize == 4 )
Keith Davis5238aff2020-03-11 12:17:05 +0000297 {
298 uint64ThreadId = profiling::ReadUint32(uCharThreadId, 0);
Colm Donelan5bb3d8a2020-05-12 16:36:46 +0100299 }
300 else if ( armnn::profiling::ThreadIdSize == 8 )
Keith Davis5238aff2020-03-11 12:17:05 +0000301 {
302 uint64ThreadId = profiling::ReadUint64(uCharThreadId, 0);
303 }
304 delete[] uCharThreadId;
305
306 const uint64_t labelGuid = 66666u;
307 std::string labelName = "test_label";
308 std::string labelName2 = "test_label2";
309 std::string labelName3 = "test_label32";
310
311 const uint64_t relationshipGuid = 77777u;
312 const uint64_t headGuid = 888888u;
313 const uint64_t tailGuid = 999999u;
314
315 // Check with multiple messages in the same buffer
316 for ( int i = 0; i < 9; ++i )
317 {
318 // Send entity
319 sendTimelinePacket->SendTimelineEntityBinaryPacket(entityGuid);
320 // Send event class
Jim Flynn1892d212020-05-26 21:10:49 +0100321 sendTimelinePacket->SendTimelineEventClassBinaryPacket(eventClassGuid, eventClassNameGuid);
Keith Davis5238aff2020-03-11 12:17:05 +0000322 // Send event
323 sendTimelinePacket->SendTimelineEventBinaryPacket(timestamp, threadId, eventGuid);
324 // Send label
325 sendTimelinePacket->SendTimelineLabelBinaryPacket(labelGuid, labelName);
326 sendTimelinePacket->SendTimelineLabelBinaryPacket(labelGuid, labelName2);
327 sendTimelinePacket->SendTimelineLabelBinaryPacket(labelGuid, labelName3);
328 // Send relationship
329 profiling::ProfilingRelationshipType relationshipType = profiling::ProfilingRelationshipType::DataLink;
330 sendTimelinePacket->SendTimelineRelationshipBinaryPacket(relationshipType,
331 relationshipGuid,
332 headGuid,
Finn Williams0a336dc2020-05-11 15:39:58 +0100333 tailGuid,
334 0);
Keith Davis5238aff2020-03-11 12:17:05 +0000335 }
336
337 sendTimelinePacket->Commit();
338 SendTimelinePacketToCommandHandler(bufferManager.GetReadableBuffer()->GetReadableData(),
339 timelineCaptureCommandHandler);
340
341 for ( unsigned long i = 0; i < 9; ++i )
342 {
343 BOOST_CHECK(model.m_Entities[i].m_Guid == entityGuid);
344
345 BOOST_CHECK(model.m_EventClasses[i].m_Guid == eventClassGuid);
346
347 BOOST_CHECK(model.m_Labels[i].m_Guid == labelGuid);
348
349 BOOST_CHECK(model.m_Events[i].m_TimeStamp == timestamp);
350 BOOST_CHECK(model.m_Events[i].m_ThreadId == uint64ThreadId);
351 BOOST_CHECK(model.m_Events[i].m_Guid == eventGuid);
352
353 BOOST_CHECK(model.m_Relationships[i].m_RelationshipType == ITimelineDecoder::RelationshipType::DataLink);
354 BOOST_CHECK(model.m_Relationships[i].m_Guid == relationshipGuid);
355 BOOST_CHECK(model.m_Relationships[i].m_HeadGuid == headGuid);
356 BOOST_CHECK(model.m_Relationships[i].m_TailGuid == tailGuid);
357 }
358 for ( unsigned long i = 0; i < 9; i += 3 )
359 {
360 BOOST_CHECK(model.m_Labels[i].m_Name == labelName);
361 BOOST_CHECK(model.m_Labels[i+1].m_Name == labelName2);
362 BOOST_CHECK(model.m_Labels[i+2].m_Name == labelName3);
363 }
364}
365
Finn Williamse63a0262019-10-22 10:30:49 +0100366BOOST_AUTO_TEST_SUITE_END()