xref: /aosp_15_r20/external/armnn/profiling/server/src/timelineDecoder/tests/TimelineTests.cpp (revision 89c4ff92f2867872bb9e2354d150bf0c8c502810)
1 //
2 // Copyright © 2019 Arm Ltd and Contributors. All rights reserved.
3 // SPDX-License-Identifier: MIT
4 //
5 
6 #include <common/include/CommandHandlerFunctor.hpp>
7 #include <common/include/CommonProfilingUtils.hpp>
8 #include <common/include/Threads.hpp>
9 #include <server/include/timelineDecoder/TimelineCaptureCommandHandler.hpp>
10 #include <server/include/timelineDecoder/TimelineDirectoryCaptureCommandHandler.hpp>
11 #include <server/include/timelineDecoder/TimelineDecoder.hpp>
12 
13 #include <client/src/BufferManager.hpp>
14 #include <client/src/ProfilingService.hpp>
15 #include <client/src/PacketBuffer.hpp>
16 #include <client/src/TimelinePacketWriterFactory.hpp>
17 
18 #include <doctest/doctest.h>
19 
20 TEST_SUITE("TimelineDecoderTests")
21 {
SendTimelinePacketToCommandHandler(const unsigned char * packetBuffer,arm::pipe::CommandHandlerFunctor & CommandHandler)22 void SendTimelinePacketToCommandHandler(const unsigned char* packetBuffer,
23                                         arm::pipe::CommandHandlerFunctor& CommandHandler)
24 {
25     uint32_t uint32_t_size = sizeof(uint32_t);
26     unsigned int offset = 0;
27 
28     uint32_t header[2];
29     header[0] = arm::pipe::ReadUint32(packetBuffer, offset);
30     offset += uint32_t_size;
31     header[1] = arm::pipe::ReadUint32(packetBuffer, offset);
32     offset += uint32_t_size;
33     uint32_t PacketDataLength  = header[1] & 0x00FFFFFF;
34 
35     auto uniquePacketData = std::make_unique<unsigned char[]>(PacketDataLength);
36     std::memcpy(uniquePacketData.get(), packetBuffer + offset, PacketDataLength);
37 
38     arm::pipe::Packet packet(header[0], PacketDataLength, uniquePacketData);
39 
40     CHECK(std::memcmp(packetBuffer + offset, packet.GetData(), packet.GetLength()) == 0);
41 
42     CommandHandler(packet);
43 }
44 
PushEntity(arm::pipe::TimelineDecoder::Model & model,const arm::pipe::ITimelineDecoder::Entity entity)45 void PushEntity(arm::pipe::TimelineDecoder::Model& model, const arm::pipe::ITimelineDecoder::Entity entity)
46 {
47     model.m_Entities.emplace_back(entity);
48 }
49 
PushEventClass(arm::pipe::TimelineDecoder::Model & model,const arm::pipe::ITimelineDecoder::EventClass eventClass)50 void PushEventClass(arm::pipe::TimelineDecoder::Model& model, const arm::pipe::ITimelineDecoder::EventClass eventClass)
51 {
52     model.m_EventClasses.emplace_back(eventClass);
53 }
54 
PushEvent(arm::pipe::TimelineDecoder::Model & model,const arm::pipe::ITimelineDecoder::Event event)55 void PushEvent(arm::pipe::TimelineDecoder::Model& model, const arm::pipe::ITimelineDecoder::Event event)
56 {
57     model.m_Events.emplace_back(event);
58 }
59 
PushLabel(arm::pipe::TimelineDecoder::Model & model,const arm::pipe::ITimelineDecoder::Label label)60 void PushLabel(arm::pipe::TimelineDecoder::Model& model, const arm::pipe::ITimelineDecoder::Label label)
61 {
62     model.m_Labels.emplace_back(label);
63 }
64 
PushRelationship(arm::pipe::TimelineDecoder::Model & model,const arm::pipe::ITimelineDecoder::Relationship relationship)65 void PushRelationship(arm::pipe::TimelineDecoder::Model& model,
66                       const arm::pipe::ITimelineDecoder::Relationship relationship)
67 {
68     model.m_Relationships.emplace_back(relationship);
69 }
70 
71 TEST_CASE("TimelineDirectoryTest")
72 {
73     uint32_t uint8_t_size  = sizeof(uint8_t);
74     uint32_t uint32_t_size = sizeof(uint32_t);
75     uint32_t uint64_t_size = sizeof(uint64_t);
76 
77     arm::pipe::BufferManager bufferManager(5);
78     arm::pipe::TimelinePacketWriterFactory timelinePacketWriterFactory(bufferManager);
79 
80     std::unique_ptr<arm::pipe::ISendTimelinePacket> sendTimelinePacket =
81             timelinePacketWriterFactory.GetSendTimelinePacket();
82 
83     arm::pipe::PacketVersionResolver packetVersionResolver;
84 
85     arm::pipe::TimelineDecoder timelineDecoder;
86     arm::pipe::TimelineCaptureCommandHandler timelineCaptureCommandHandler(
87             1, 1, packetVersionResolver.ResolvePacketVersion(1, 1).GetEncodedValue(), timelineDecoder);
88 
89     arm::pipe::TimelineDirectoryCaptureCommandHandler timelineDirectoryCaptureCommandHandler(
90             1, 0, packetVersionResolver.ResolvePacketVersion(1, 0).GetEncodedValue(),
91             timelineCaptureCommandHandler, true);
92 
93     sendTimelinePacket->SendTimelineMessageDirectoryPackage();
94     sendTimelinePacket->Commit();
95 
96     std::vector<arm::pipe::SwTraceMessage> swTraceBufferMessages;
97 
98     unsigned int offset = uint32_t_size * 2;
99 
100     std::unique_ptr<arm::pipe::IPacketBuffer> packetBuffer = bufferManager.GetReadableBuffer();
101 
102     uint8_t readStreamVersion = ReadUint8(packetBuffer, offset);
103     CHECK(readStreamVersion == 4);
104     offset += uint8_t_size;
105     uint8_t readPointerBytes = ReadUint8(packetBuffer, offset);
106     CHECK(readPointerBytes == uint64_t_size);
107     offset += uint8_t_size;
108     uint8_t readThreadIdBytes = ReadUint8(packetBuffer, offset);
109     CHECK(readThreadIdBytes == arm::pipe::ThreadIdSize);
110     offset += uint8_t_size;
111 
112     uint32_t declarationSize = arm::pipe::ReadUint32(packetBuffer->GetReadableData(), offset);
113     offset += uint32_t_size;
114     for(uint32_t i = 0; i < declarationSize; ++i)
115     {
116         swTraceBufferMessages.push_back(arm::pipe::ReadSwTraceMessage(packetBuffer->GetReadableData(),
117                                                                       offset,
118                                                                       packetBuffer->GetSize()));
119     }
120 
121     SendTimelinePacketToCommandHandler(packetBuffer->GetReadableData(), timelineDirectoryCaptureCommandHandler);
122 
123     for(uint32_t index = 0; index < declarationSize; ++index)
124     {
125         arm::pipe::SwTraceMessage& bufferMessage = swTraceBufferMessages[index];
126         arm::pipe::SwTraceMessage& handlerMessage = timelineDirectoryCaptureCommandHandler.m_SwTraceMessages[index];
127 
128         CHECK(bufferMessage.m_Name == handlerMessage.m_Name);
129         CHECK(bufferMessage.m_UiName == handlerMessage.m_UiName);
130         CHECK(bufferMessage.m_Id == handlerMessage.m_Id);
131 
132         CHECK(bufferMessage.m_ArgTypes.size() == handlerMessage.m_ArgTypes.size());
133         for(uint32_t i = 0; i < bufferMessage.m_ArgTypes.size(); ++i)
134         {
135             CHECK(bufferMessage.m_ArgTypes[i] == handlerMessage.m_ArgTypes[i]);
136         }
137 
138         CHECK(bufferMessage.m_ArgNames.size() == handlerMessage.m_ArgNames.size());
139         for(uint32_t i = 0; i < bufferMessage.m_ArgNames.size(); ++i)
140         {
141             CHECK(bufferMessage.m_ArgNames[i] == handlerMessage.m_ArgNames[i]);
142         }
143     }
144 }
145 
146 TEST_CASE("TimelineCaptureTest")
147 {
148     arm::pipe::BufferManager bufferManager(50);
149     arm::pipe::TimelinePacketWriterFactory timelinePacketWriterFactory(bufferManager);
150 
151     std::unique_ptr<arm::pipe::ISendTimelinePacket> sendTimelinePacket =
152         timelinePacketWriterFactory.GetSendTimelinePacket();
153 
154     arm::pipe::PacketVersionResolver packetVersionResolver;
155 
156     arm::pipe::TimelineDecoder timelineDecoder;
157 
158     arm::pipe::TimelineCaptureCommandHandler timelineCaptureCommandHandler(
159         1, 1, packetVersionResolver.ResolvePacketVersion(1, 1).GetEncodedValue(), timelineDecoder,
160         arm::pipe::ThreadIdSize);
161 
162     using Status = arm::pipe::ITimelineDecoder::TimelineStatus;
163     CHECK(timelineDecoder.SetEntityCallback(PushEntity)             == Status::TimelineStatus_Success);
164     CHECK(timelineDecoder.SetEventClassCallback(PushEventClass)     == Status::TimelineStatus_Success);
165     CHECK(timelineDecoder.SetEventCallback(PushEvent)               == Status::TimelineStatus_Success);
166     CHECK(timelineDecoder.SetLabelCallback(PushLabel)               == Status::TimelineStatus_Success);
167     CHECK(timelineDecoder.SetRelationshipCallback(PushRelationship) == Status::TimelineStatus_Success);
168 
169     const uint64_t entityGuid = 111111u;
170     const uint64_t eventClassGuid = 22222u;
171     const uint64_t eventClassNameGuid = 22322u;
172     const uint64_t timestamp = 33333u;
173     const uint64_t eventGuid = 44444u;
174 
175     const int threadId = arm::pipe::GetCurrentThreadId();
176 
177     // need to do a bit of work here to extract the value from threadId
178     unsigned char* uCharThreadId = new unsigned char[arm::pipe::ThreadIdSize]();;
179     uint64_t uint64ThreadId;
180 
181     arm::pipe::WriteBytes(uCharThreadId, 0, &threadId, arm::pipe::ThreadIdSize);
182 
183     if (arm::pipe::ThreadIdSize == 4)
184     {
185         uint64ThreadId =  arm::pipe::ReadUint32(uCharThreadId, 0);
186     }
187     else if (arm::pipe::ThreadIdSize == 8)
188     {
189         uint64ThreadId =  arm::pipe::ReadUint64(uCharThreadId, 0);
190     }
191     delete[] uCharThreadId;
192 
193     const uint64_t labelGuid = 66666u;
194     std::string labelName = "test_label";
195 
196     const uint64_t relationshipGuid = 77777u;
197     const uint64_t headGuid = 888888u;
198     const uint64_t tailGuid = 999999u;
199 
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
209         sendTimelinePacket->SendTimelineEventClassBinaryPacket(eventClassGuid, eventClassNameGuid);
210         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         arm::pipe::ProfilingRelationshipType relationshipType =
228             arm::pipe::ProfilingRelationshipType::DataLink;
229         sendTimelinePacket->SendTimelineRelationshipBinaryPacket(relationshipType,
230                                                                  relationshipGuid,
231                                                                  headGuid,
232                                                                  tailGuid,
233                                                                  0);
234         sendTimelinePacket->Commit();
235         SendTimelinePacketToCommandHandler(bufferManager.GetReadableBuffer()->GetReadableData(),
236                                            timelineCaptureCommandHandler);
237     }
238 
__anonf0e442810102(const arm::pipe::TimelineDecoder::Model& model)239     timelineDecoder.ApplyToModel([&](const arm::pipe::TimelineDecoder::Model& model){
240         for (unsigned long i = 0; i < 10; ++i)
241         {
242             CHECK(model.m_Entities[i].m_Guid == entityGuid);
243 
244             CHECK(model.m_EventClasses[i].m_Guid == eventClassGuid);
245 
246             CHECK(model.m_Events[i].m_TimeStamp == timestamp);
247             CHECK(model.m_Events[i].m_ThreadId == uint64ThreadId);
248             CHECK(model.m_Events[i].m_Guid == eventGuid);
249 
250             CHECK(model.m_Labels[i].m_Guid == labelGuid);
251             CHECK(model.m_Labels[i].m_Name == labelName);
252 
253             CHECK(model.m_Relationships[i].m_RelationshipType ==
254                 arm::pipe::ITimelineDecoder::RelationshipType::DataLink);
255             CHECK(model.m_Relationships[i].m_Guid == relationshipGuid);
256             CHECK(model.m_Relationships[i].m_HeadGuid == headGuid);
257             CHECK(model.m_Relationships[i].m_TailGuid == tailGuid);
258         }
259     });
260 }
261 
262 TEST_CASE("TimelineCaptureTestMultipleStringsInBuffer")
263 {
264     arm::pipe::BufferManager               bufferManager(50);
265     arm::pipe::TimelinePacketWriterFactory timelinePacketWriterFactory(bufferManager);
266 
267     std::unique_ptr<arm::pipe::ISendTimelinePacket> sendTimelinePacket =
268                                                         timelinePacketWriterFactory.GetSendTimelinePacket();
269 
270     arm::pipe::PacketVersionResolver packetVersionResolver;
271 
272     arm::pipe::TimelineDecoder timelineDecoder;
273 
274     arm::pipe::TimelineCaptureCommandHandler timelineCaptureCommandHandler(
275         1, 1, packetVersionResolver.ResolvePacketVersion(1, 1).GetEncodedValue(), timelineDecoder,
276         arm::pipe::ThreadIdSize);
277 
278     using Status = arm::pipe::TimelineDecoder::TimelineStatus;
279     CHECK(timelineDecoder.SetEntityCallback(PushEntity) == Status::TimelineStatus_Success);
280     CHECK(timelineDecoder.SetEventClassCallback(PushEventClass) == Status::TimelineStatus_Success);
281     CHECK(timelineDecoder.SetEventCallback(PushEvent) == Status::TimelineStatus_Success);
282     CHECK(timelineDecoder.SetLabelCallback(PushLabel) == Status::TimelineStatus_Success);
283     CHECK(timelineDecoder.SetRelationshipCallback(PushRelationship) == Status::TimelineStatus_Success);
284 
285     const uint64_t entityGuid         = 111111u;
286     const uint64_t eventClassGuid     = 22222u;
287     const uint64_t eventClassNameGuid = 22322u;
288     const uint64_t timestamp          = 33333u;
289     const uint64_t eventGuid          = 44444u;
290 
291     const int threadId = arm::pipe::GetCurrentThreadId();
292 
293     // need to do a bit of work here to extract the value from threadId
294     unsigned char* uCharThreadId = new unsigned char[arm::pipe::ThreadIdSize]();
295     uint64_t uint64ThreadId;
296 
297     arm::pipe::WriteBytes(uCharThreadId, 0, &threadId, arm::pipe::ThreadIdSize);
298 
299     if ( arm::pipe::ThreadIdSize == 4 )
300     {
301         uint64ThreadId = arm::pipe::ReadUint32(uCharThreadId, 0);
302     }
303     else if ( arm::pipe::ThreadIdSize == 8 )
304     {
305         uint64ThreadId = arm::pipe::ReadUint64(uCharThreadId, 0);
306     }
307     delete[] uCharThreadId;
308 
309     const uint64_t labelGuid  = 66666u;
310     std::string    labelName  = "test_label";
311     std::string    labelName2 = "test_label2";
312     std::string    labelName3 = "test_label32";
313 
314     const uint64_t relationshipGuid = 77777u;
315     const uint64_t headGuid         = 888888u;
316     const uint64_t tailGuid         = 999999u;
317 
318     // Check with multiple messages in the same buffer
319     for ( int i = 0; i < 9; ++i )
320     {
321         // Send entity
322         sendTimelinePacket->SendTimelineEntityBinaryPacket(entityGuid);
323         // Send event class
324         sendTimelinePacket->SendTimelineEventClassBinaryPacket(eventClassGuid, eventClassNameGuid);
325         // Send event
326         sendTimelinePacket->SendTimelineEventBinaryPacket(timestamp, threadId, eventGuid);
327         // Send label
328         sendTimelinePacket->SendTimelineLabelBinaryPacket(labelGuid, labelName);
329         sendTimelinePacket->SendTimelineLabelBinaryPacket(labelGuid, labelName2);
330         sendTimelinePacket->SendTimelineLabelBinaryPacket(labelGuid, labelName3);
331         // Send relationship
332         arm::pipe::ProfilingRelationshipType relationshipType =
333             arm::pipe::ProfilingRelationshipType::DataLink;
334         sendTimelinePacket->SendTimelineRelationshipBinaryPacket(relationshipType,
335                                                                  relationshipGuid,
336                                                                  headGuid,
337                                                                  tailGuid,
338                                                                  0);
339     }
340 
341     sendTimelinePacket->Commit();
342     SendTimelinePacketToCommandHandler(bufferManager.GetReadableBuffer()->GetReadableData(),
343                                        timelineCaptureCommandHandler);
344 
__anonf0e442810202(const arm::pipe::TimelineDecoder::Model& model)345     timelineDecoder.ApplyToModel([&](const arm::pipe::TimelineDecoder::Model& model){
346         for ( unsigned long i = 0; i < 9; ++i )
347         {
348             CHECK(model.m_Entities[i].m_Guid == entityGuid);
349 
350             CHECK(model.m_EventClasses[i].m_Guid == eventClassGuid);
351 
352             CHECK(model.m_Labels[i].m_Guid == labelGuid);
353 
354             CHECK(model.m_Events[i].m_TimeStamp == timestamp);
355             CHECK(model.m_Events[i].m_ThreadId == uint64ThreadId);
356             CHECK(model.m_Events[i].m_Guid == eventGuid);
357 
358             CHECK(model.m_Relationships[i].m_RelationshipType ==
359                 arm::pipe::ITimelineDecoder::RelationshipType::DataLink);
360             CHECK(model.m_Relationships[i].m_Guid == relationshipGuid);
361             CHECK(model.m_Relationships[i].m_HeadGuid == headGuid);
362             CHECK(model.m_Relationships[i].m_TailGuid == tailGuid);
363         }
364         for ( unsigned long i = 0; i < 9; i += 3 )
365         {
366             CHECK(model.m_Labels[i].m_Name == labelName);
367             CHECK(model.m_Labels[i+1].m_Name == labelName2);
368             CHECK(model.m_Labels[i+2].m_Name == labelName3);
369         }
370     });
371 }
372 
373 }
374