blob: e99bdb55a7a20e2cac257cbfd1382d2d3c3d3d24 [file] [log] [blame]
Colm Donelana21620d2019-10-11 13:09:49 +01001//
2// Copyright © 2017 Arm Ltd. All rights reserved.
3// SPDX-License-Identifier: MIT
4//
5
Matteo Martincigh65984272019-10-17 13:26:21 +01006#include <CommandHandlerRegistry.hpp>
Finn Williams2ed809c2020-04-20 21:21:07 +01007#include <ConnectionHandler.hpp>
Keith Davis3201eea2019-10-24 17:30:41 +01008#include <DirectoryCaptureCommandHandler.hpp>
Finn Williams0c8cb992020-05-07 10:38:15 +01009#include <GatordMockService.hpp>
Finn Williamsaf1c63b2020-03-23 18:01:49 +000010#include <LabelsAndEventClasses.hpp>
Finn Williamsaf1c63b2020-03-23 18:01:49 +000011#include <ProfilingService.hpp>
Finn Williamsaf1c63b2020-03-23 18:01:49 +000012#include <TimelinePacketWriterFactory.hpp>
Finn Williams8a2b4682020-02-26 10:25:26 +000013
Matteo Martincighcdfb9412019-11-08 11:23:06 +000014#include <TimelineDirectoryCaptureCommandHandler.hpp>
Finn Williamse6a2ccd2020-02-27 16:21:41 +000015#include <TimelineDecoder.hpp>
Colm Donelana21620d2019-10-11 13:09:49 +010016
Keith Davis33ed2212020-03-30 10:43:41 +010017#include <Runtime.hpp>
Finn Williams0c8cb992020-05-07 10:38:15 +010018
19#include <MockBackend.hpp>
Keith Davis33ed2212020-03-30 10:43:41 +010020
Colm Donelana21620d2019-10-11 13:09:49 +010021#include <boost/cast.hpp>
22#include <boost/test/test_tools.hpp>
23#include <boost/test/unit_test_suite.hpp>
24
Finn Williams2ed809c2020-04-20 21:21:07 +010025
Colm Donelana21620d2019-10-11 13:09:49 +010026BOOST_AUTO_TEST_SUITE(GatordMockTests)
27
28using namespace armnn;
Finn Williamse6a2ccd2020-02-27 16:21:41 +000029using namespace std::this_thread;
Colm Donelana21620d2019-10-11 13:09:49 +010030using namespace std::chrono_literals;
31
Colm Donelana21620d2019-10-11 13:09:49 +010032BOOST_AUTO_TEST_CASE(CounterCaptureHandlingTest)
33{
34 using boost::numeric_cast;
35
Finn Williams15db7452019-10-15 14:22:13 +010036 profiling::PacketVersionResolver packetVersionResolver;
Colm Donelana21620d2019-10-11 13:09:49 +010037
38 // Data with timestamp, counter idx & counter values
39 std::vector<std::pair<uint16_t, uint32_t>> indexValuePairs;
40 indexValuePairs.reserve(5);
41 indexValuePairs.emplace_back(std::make_pair<uint16_t, uint32_t>(0, 100));
42 indexValuePairs.emplace_back(std::make_pair<uint16_t, uint32_t>(1, 200));
43 indexValuePairs.emplace_back(std::make_pair<uint16_t, uint32_t>(2, 300));
44 indexValuePairs.emplace_back(std::make_pair<uint16_t, uint32_t>(3, 400));
45 indexValuePairs.emplace_back(std::make_pair<uint16_t, uint32_t>(4, 500));
46
47 // ((uint16_t (2 bytes) + uint32_t (4 bytes)) * 5) + word1 + word2
48 uint32_t dataLength = 38;
49
50 // Simulate two different packets incoming 500 ms apart
51 uint64_t time = static_cast<uint64_t>(
52 std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::steady_clock::now().time_since_epoch())
53 .count());
54
Finn Williamsc6263452019-10-11 18:25:07 +010055 uint64_t time2 = time + 5000;
Colm Donelana21620d2019-10-11 13:09:49 +010056
57 // UniqueData required for Packet class
58 std::unique_ptr<unsigned char[]> uniqueData1 = std::make_unique<unsigned char[]>(dataLength);
Colm Donelanb682d842019-10-16 12:24:20 +010059 unsigned char* data1 = reinterpret_cast<unsigned char*>(uniqueData1.get());
Colm Donelana21620d2019-10-11 13:09:49 +010060
61 std::unique_ptr<unsigned char[]> uniqueData2 = std::make_unique<unsigned char[]>(dataLength);
Colm Donelanb682d842019-10-16 12:24:20 +010062 unsigned char* data2 = reinterpret_cast<unsigned char*>(uniqueData2.get());
Colm Donelana21620d2019-10-11 13:09:49 +010063
64 uint32_t sizeOfUint64 = numeric_cast<uint32_t>(sizeof(uint64_t));
65 uint32_t sizeOfUint32 = numeric_cast<uint32_t>(sizeof(uint32_t));
66 uint32_t sizeOfUint16 = numeric_cast<uint32_t>(sizeof(uint16_t));
67 // Offset index to point to mem address
68 uint32_t offset = 0;
69
70 profiling::WriteUint64(data1, offset, time);
71 offset += sizeOfUint64;
72 for (const auto& pair : indexValuePairs)
73 {
74 profiling::WriteUint16(data1, offset, pair.first);
75 offset += sizeOfUint16;
76 profiling::WriteUint32(data1, offset, pair.second);
77 offset += sizeOfUint32;
78 }
79
80 offset = 0;
81
82 profiling::WriteUint64(data2, offset, time2);
83 offset += sizeOfUint64;
84 for (const auto& pair : indexValuePairs)
85 {
86 profiling::WriteUint16(data2, offset, pair.first);
87 offset += sizeOfUint16;
88 profiling::WriteUint32(data2, offset, pair.second);
89 offset += sizeOfUint32;
90 }
91
Finn Williams15db7452019-10-15 14:22:13 +010092 uint32_t headerWord1 = packetVersionResolver.ResolvePacketVersion(0, 4).GetEncodedValue();
Colm Donelana21620d2019-10-11 13:09:49 +010093 // Create packet to send through to the command functor
94 profiling::Packet packet1(headerWord1, dataLength, uniqueData1);
95 profiling::Packet packet2(headerWord1, dataLength, uniqueData2);
96
Keith Davis3201eea2019-10-24 17:30:41 +010097 gatordmock::PeriodicCounterCaptureCommandHandler commandHandler(0, 4, headerWord1, true);
Colm Donelana21620d2019-10-11 13:09:49 +010098
99 // Simulate two separate packets coming in to calculate period
100 commandHandler(packet1);
101 commandHandler(packet2);
102
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +0100103 ARMNN_ASSERT(commandHandler.m_CurrentPeriodValue == 5000);
Colm Donelana21620d2019-10-11 13:09:49 +0100104
105 for (size_t i = 0; i < commandHandler.m_CounterCaptureValues.m_Uids.size(); ++i)
106 {
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +0100107 ARMNN_ASSERT(commandHandler.m_CounterCaptureValues.m_Uids[i] == i);
Colm Donelana21620d2019-10-11 13:09:49 +0100108 }
109}
110
Keith Davis33ed2212020-03-30 10:43:41 +0100111void WaitFor(std::function<bool()> predicate, std::string errorMsg, uint32_t timeout = 2000, uint32_t sleepTime = 50)
112{
113 uint32_t timeSlept = 0;
114 while (!predicate())
115 {
116 if (timeSlept >= timeout)
117 {
118 BOOST_FAIL("Timeout: " + errorMsg);
119 }
120 std::this_thread::sleep_for(std::chrono::milliseconds(sleepTime));
121 timeSlept += sleepTime;
122 }
123}
Finn Williamsaf1c63b2020-03-23 18:01:49 +0000124
125void CheckTimelineDirectory(timelinedecoder::TimelineDirectoryCaptureCommandHandler& commandHandler)
126{
127 uint32_t uint8_t_size = sizeof(uint8_t);
128 uint32_t uint32_t_size = sizeof(uint32_t);
129 uint32_t uint64_t_size = sizeof(uint64_t);
Jim Flynn1fdeb992020-07-09 07:28:37 +0100130 uint32_t threadId_size = sizeof(int);
Finn Williamsaf1c63b2020-03-23 18:01:49 +0000131
132 profiling::BufferManager bufferManager(5);
133 profiling::TimelinePacketWriterFactory timelinePacketWriterFactory(bufferManager);
134
135 std::unique_ptr<profiling::ISendTimelinePacket> sendTimelinePacket =
136 timelinePacketWriterFactory.GetSendTimelinePacket();
137
138 sendTimelinePacket->SendTimelineMessageDirectoryPackage();
139 sendTimelinePacket->Commit();
140
141 std::vector<profiling::SwTraceMessage> swTraceBufferMessages;
142
143 unsigned int offset = uint32_t_size * 2;
144
145 std::unique_ptr<profiling::IPacketBuffer> packetBuffer = bufferManager.GetReadableBuffer();
146
147 uint8_t readStreamVersion = ReadUint8(packetBuffer, offset);
148 BOOST_CHECK(readStreamVersion == 4);
149 offset += uint8_t_size;
150 uint8_t readPointerBytes = ReadUint8(packetBuffer, offset);
151 BOOST_CHECK(readPointerBytes == uint64_t_size);
152 offset += uint8_t_size;
153 uint8_t readThreadIdBytes = ReadUint8(packetBuffer, offset);
154 BOOST_CHECK(readThreadIdBytes == threadId_size);
155 offset += uint8_t_size;
156
157 uint32_t declarationSize = profiling::ReadUint32(packetBuffer, offset);
158 offset += uint32_t_size;
159 for(uint32_t i = 0; i < declarationSize; ++i)
160 {
161 swTraceBufferMessages.push_back(profiling::ReadSwTraceMessage(packetBuffer->GetReadableData(), offset));
162 }
163
164 for(uint32_t index = 0; index < declarationSize; ++index)
165 {
166 profiling::SwTraceMessage& bufferMessage = swTraceBufferMessages[index];
167 profiling::SwTraceMessage& handlerMessage = commandHandler.m_SwTraceMessages[index];
168
169 BOOST_CHECK(bufferMessage.m_Name == handlerMessage.m_Name);
170 BOOST_CHECK(bufferMessage.m_UiName == handlerMessage.m_UiName);
171 BOOST_CHECK(bufferMessage.m_Id == handlerMessage.m_Id);
172
173 BOOST_CHECK(bufferMessage.m_ArgTypes.size() == handlerMessage.m_ArgTypes.size());
174 for(uint32_t i = 0; i < bufferMessage.m_ArgTypes.size(); ++i)
175 {
176 BOOST_CHECK(bufferMessage.m_ArgTypes[i] == handlerMessage.m_ArgTypes[i]);
177 }
178
179 BOOST_CHECK(bufferMessage.m_ArgNames.size() == handlerMessage.m_ArgNames.size());
180 for(uint32_t i = 0; i < bufferMessage.m_ArgNames.size(); ++i)
181 {
182 BOOST_CHECK(bufferMessage.m_ArgNames[i] == handlerMessage.m_ArgNames[i]);
183 }
184 }
185}
186
187void CheckTimelinePackets(timelinedecoder::TimelineDecoder& timelineDecoder)
188{
189 BOOST_CHECK(timelineDecoder.GetModel().m_Labels[0].m_Guid == profiling::LabelsAndEventClasses::NAME_GUID);
190 BOOST_CHECK(timelineDecoder.GetModel().m_Labels[0].m_Name == profiling::LabelsAndEventClasses::NAME_LABEL);
191
192 BOOST_CHECK(timelineDecoder.GetModel().m_Labels[1].m_Guid == profiling::LabelsAndEventClasses::TYPE_GUID);
193 BOOST_CHECK(timelineDecoder.GetModel().m_Labels[1].m_Name == profiling::LabelsAndEventClasses::TYPE_LABEL);
194
195 BOOST_CHECK(timelineDecoder.GetModel().m_Labels[2].m_Guid == profiling::LabelsAndEventClasses::INDEX_GUID);
196 BOOST_CHECK(timelineDecoder.GetModel().m_Labels[2].m_Name == profiling::LabelsAndEventClasses::INDEX_LABEL);
197
198 BOOST_CHECK(timelineDecoder.GetModel().m_Labels[3].m_Guid == profiling::LabelsAndEventClasses::BACKENDID_GUID);
199 BOOST_CHECK(timelineDecoder.GetModel().m_Labels[3].m_Name == profiling::LabelsAndEventClasses::BACKENDID_LABEL);
200
201 BOOST_CHECK(timelineDecoder.GetModel().m_Labels[4].m_Guid == profiling::LabelsAndEventClasses::LAYER_GUID);
202 BOOST_CHECK(timelineDecoder.GetModel().m_Labels[4].m_Name == profiling::LabelsAndEventClasses::LAYER);
203
204 BOOST_CHECK(timelineDecoder.GetModel().m_Labels[5].m_Guid == profiling::LabelsAndEventClasses::WORKLOAD_GUID);
205 BOOST_CHECK(timelineDecoder.GetModel().m_Labels[5].m_Name == profiling::LabelsAndEventClasses::WORKLOAD);
206
207 BOOST_CHECK(timelineDecoder.GetModel().m_Labels[6].m_Guid == profiling::LabelsAndEventClasses::NETWORK_GUID);
208 BOOST_CHECK(timelineDecoder.GetModel().m_Labels[6].m_Name == profiling::LabelsAndEventClasses::NETWORK);
209
210 BOOST_CHECK(timelineDecoder.GetModel().m_Labels[7].m_Guid == profiling::LabelsAndEventClasses::CONNECTION_GUID);
211 BOOST_CHECK(timelineDecoder.GetModel().m_Labels[7].m_Name == profiling::LabelsAndEventClasses::CONNECTION);
212
213 BOOST_CHECK(timelineDecoder.GetModel().m_Labels[8].m_Guid == profiling::LabelsAndEventClasses::INFERENCE_GUID);
214 BOOST_CHECK(timelineDecoder.GetModel().m_Labels[8].m_Name == profiling::LabelsAndEventClasses::INFERENCE);
215
216 BOOST_CHECK(timelineDecoder.GetModel().m_Labels[9].m_Guid ==
217 profiling::LabelsAndEventClasses::WORKLOAD_EXECUTION_GUID);
218 BOOST_CHECK(timelineDecoder.GetModel().m_Labels[9].m_Name == profiling::LabelsAndEventClasses::WORKLOAD_EXECUTION);
219
220 BOOST_CHECK(timelineDecoder.GetModel().m_EventClasses[0].m_Guid ==
221 profiling::LabelsAndEventClasses::ARMNN_PROFILING_SOL_EVENT_CLASS);
222 BOOST_CHECK(timelineDecoder.GetModel().m_EventClasses[1].m_Guid ==
223 profiling::LabelsAndEventClasses::ARMNN_PROFILING_EOL_EVENT_CLASS);
224}
225
Colm Donelana21620d2019-10-11 13:09:49 +0100226BOOST_AUTO_TEST_CASE(GatorDMockEndToEnd)
227{
228 // The purpose of this test is to setup both sides of the profiling service and get to the point of receiving
229 // performance data.
230
Colm Donelana21620d2019-10-11 13:09:49 +0100231 // Setup the mock service to bind to the UDS.
232 std::string udsNamespace = "gatord_namespace";
Finn Williamse6a2ccd2020-02-27 16:21:41 +0000233
Finn Williams2ed809c2020-04-20 21:21:07 +0100234 BOOST_CHECK_NO_THROW(armnnProfiling::ConnectionHandler connectionHandler(udsNamespace, false));
Finn Williamse6a2ccd2020-02-27 16:21:41 +0000235
Finn Williams2ed809c2020-04-20 21:21:07 +0100236 armnnProfiling::ConnectionHandler connectionHandler(udsNamespace, false);
Colm Donelana21620d2019-10-11 13:09:49 +0100237
238 // Enable the profiling service.
Narumol Prangnawarat85ad78c2019-11-18 15:34:23 +0000239 armnn::IRuntime::CreationOptions::ExternalProfilingOptions options;
Finn Williamsd7fcafa2020-04-23 17:55:18 +0100240 options.m_EnableProfiling = true;
241 options.m_TimelineEnabled = true;
242
Sadik Armagan3184c902020-03-18 10:57:30 +0000243 armnn::profiling::ProfilingService profilingService;
Colm Donelana21620d2019-10-11 13:09:49 +0100244 profilingService.ResetExternalProfilingOptions(options, true);
245
246 // Bring the profiling service to the "WaitingForAck" state
247 BOOST_CHECK(profilingService.GetCurrentState() == profiling::ProfilingState::Uninitialised);
248 profilingService.Update();
249 BOOST_CHECK(profilingService.GetCurrentState() == profiling::ProfilingState::NotConnected);
250 profilingService.Update();
251
Finn Williams2ed809c2020-04-20 21:21:07 +0100252 // Connect the profiling service
253 auto basePipeServer = connectionHandler.GetNewBasePipeServer(false);
Finn Williams15db7452019-10-15 14:22:13 +0100254
Finn Williams2ed809c2020-04-20 21:21:07 +0100255 // Connect the profiling service to the mock Gatord.
256 gatordmock::GatordMockService mockService(std::move(basePipeServer), false);
Keith Davis33ed2212020-03-30 10:43:41 +0100257
258 timelinedecoder::TimelineDecoder& timelineDecoder = mockService.GetTimelineDecoder();
259 profiling::DirectoryCaptureCommandHandler& directoryCaptureCommandHandler =
260 mockService.GetDirectoryCaptureCommandHandler();
Finn Williamse6a2ccd2020-02-27 16:21:41 +0000261
Colm Donelana21620d2019-10-11 13:09:49 +0100262 // Give the profiling service sending thread time start executing and send the stream metadata.
Keith Davis33ed2212020-03-30 10:43:41 +0100263 WaitFor([&](){return profilingService.GetCurrentState() == profiling::ProfilingState::WaitingForAck;},
264 "Profiling service did not switch to WaitingForAck state");
Finn Williams15db7452019-10-15 14:22:13 +0100265
Colm Donelana21620d2019-10-11 13:09:49 +0100266 profilingService.Update();
267 // Read the stream metadata on the mock side.
268 if (!mockService.WaitForStreamMetaData())
269 {
270 BOOST_FAIL("Failed to receive StreamMetaData");
271 }
272 // Send Ack from GatorD
273 mockService.SendConnectionAck();
Keith Davis33ed2212020-03-30 10:43:41 +0100274 // And start to listen for packets
Finn Williams15db7452019-10-15 14:22:13 +0100275 mockService.LaunchReceivingThread();
Keith Davis33ed2212020-03-30 10:43:41 +0100276
277 WaitFor([&](){return profilingService.GetCurrentState() == profiling::ProfilingState::Active;},
278 "Profiling service did not switch to Active state");
Finn Williams15db7452019-10-15 14:22:13 +0100279
Finn Williamsaf1c63b2020-03-23 18:01:49 +0000280 // As part of the default startup of the profiling service a counter directory packet will be sent.
Keith Davis33ed2212020-03-30 10:43:41 +0100281 WaitFor([&](){return directoryCaptureCommandHandler.ParsedCounterDirectory();},
282 "MockGatord did not receive counter directory packet");
Finn Williamsaf1c63b2020-03-23 18:01:49 +0000283
Keith Davis33ed2212020-03-30 10:43:41 +0100284 // Following that we will receive a collection of well known timeline labels and event classes
285 WaitFor([&](){return timelineDecoder.GetModel().m_EventClasses.size() >= 2;},
286 "MockGatord did not receive well known timeline labels and event classes");
Finn Williamsaf1c63b2020-03-23 18:01:49 +0000287
Keith Davis33ed2212020-03-30 10:43:41 +0100288 CheckTimelineDirectory(mockService.GetTimelineDirectoryCaptureCommandHandler());
Finn Williamsaf1c63b2020-03-23 18:01:49 +0000289 // Verify the commonly used timeline packets sent when the profiling service enters the active state
290 CheckTimelinePackets(timelineDecoder);
291
Keith Davis3201eea2019-10-24 17:30:41 +0100292 const profiling::ICounterDirectory& serviceCounterDirectory = profilingService.GetCounterDirectory();
293 const profiling::ICounterDirectory& receivedCounterDirectory = directoryCaptureCommandHandler.GetCounterDirectory();
Finn Williams15db7452019-10-15 14:22:13 +0100294
Finn Williamsaf1c63b2020-03-23 18:01:49 +0000295 // Compare the basics of the counter directory from the service and the one we received over the wire.
296 BOOST_CHECK(serviceCounterDirectory.GetDeviceCount() == receivedCounterDirectory.GetDeviceCount());
297 BOOST_CHECK(serviceCounterDirectory.GetCounterSetCount() == receivedCounterDirectory.GetCounterSetCount());
298 BOOST_CHECK(serviceCounterDirectory.GetCategoryCount() == receivedCounterDirectory.GetCategoryCount());
299 BOOST_CHECK(serviceCounterDirectory.GetCounterCount() == receivedCounterDirectory.GetCounterCount());
Keith Davis3201eea2019-10-24 17:30:41 +0100300
301 receivedCounterDirectory.GetDeviceCount();
302 serviceCounterDirectory.GetDeviceCount();
Finn Williams15db7452019-10-15 14:22:13 +0100303
304 const profiling::Devices& serviceDevices = serviceCounterDirectory.GetDevices();
Finn Williams15db7452019-10-15 14:22:13 +0100305 for (auto& device : serviceDevices)
306 {
Keith Davis3201eea2019-10-24 17:30:41 +0100307 // Find the same device in the received counter directory.
308 auto foundDevice = receivedCounterDirectory.GetDevices().find(device.second->m_Uid);
309 BOOST_CHECK(foundDevice != receivedCounterDirectory.GetDevices().end());
310 BOOST_CHECK(device.second->m_Name.compare((*foundDevice).second->m_Name) == 0);
311 BOOST_CHECK(device.second->m_Cores == (*foundDevice).second->m_Cores);
Finn Williams15db7452019-10-15 14:22:13 +0100312 }
313
Keith Davis3201eea2019-10-24 17:30:41 +0100314 const profiling::CounterSets& serviceCounterSets = serviceCounterDirectory.GetCounterSets();
Finn Williams15db7452019-10-15 14:22:13 +0100315 for (auto& counterSet : serviceCounterSets)
316 {
Keith Davis3201eea2019-10-24 17:30:41 +0100317 // Find the same counter set in the received counter directory.
318 auto foundCounterSet = receivedCounterDirectory.GetCounterSets().find(counterSet.second->m_Uid);
319 BOOST_CHECK(foundCounterSet != receivedCounterDirectory.GetCounterSets().end());
320 BOOST_CHECK(counterSet.second->m_Name.compare((*foundCounterSet).second->m_Name) == 0);
321 BOOST_CHECK(counterSet.second->m_Count == (*foundCounterSet).second->m_Count);
Finn Williams15db7452019-10-15 14:22:13 +0100322 }
323
324 const profiling::Categories& serviceCategories = serviceCounterDirectory.GetCategories();
Finn Williams15db7452019-10-15 14:22:13 +0100325 for (auto& category : serviceCategories)
326 {
Keith Davis3201eea2019-10-24 17:30:41 +0100327 for (auto& receivedCategory : receivedCounterDirectory.GetCategories())
Finn Williams15db7452019-10-15 14:22:13 +0100328 {
Keith Davis3201eea2019-10-24 17:30:41 +0100329 if (receivedCategory->m_Name.compare(category->m_Name) == 0)
330 {
331 // We've found the matching category.
Keith Davis3201eea2019-10-24 17:30:41 +0100332 // Now look at the interiors of the counters. Start by sorting them.
333 std::sort(category->m_Counters.begin(), category->m_Counters.end());
334 std::sort(receivedCategory->m_Counters.begin(), receivedCategory->m_Counters.end());
335 // When comparing uid's here we need to translate them.
336 std::function<bool(const uint16_t&, const uint16_t&)> comparator =
337 [&directoryCaptureCommandHandler](const uint16_t& first, const uint16_t& second) {
338 uint16_t translated = directoryCaptureCommandHandler.TranslateUIDCopyToOriginal(second);
339 if (translated == first)
340 {
341 return true;
342 }
343 return false;
344 };
345 // Then let vector == do the work.
346 BOOST_CHECK(std::equal(category->m_Counters.begin(), category->m_Counters.end(),
347 receivedCategory->m_Counters.begin(), comparator));
348 break;
349 }
Finn Williams15db7452019-10-15 14:22:13 +0100350 }
Keith Davis3201eea2019-10-24 17:30:41 +0100351 }
352
353 // Finally check the content of the counters.
354 const profiling::Counters& receivedCounters = receivedCounterDirectory.GetCounters();
355 for (auto& receivedCounter : receivedCounters)
356 {
357 // Translate the Uid and find the corresponding counter in the original counter directory.
358 // Note we can't check m_MaxCounterUid here as it will likely differ between the two counter directories.
359 uint16_t translated = directoryCaptureCommandHandler.TranslateUIDCopyToOriginal(receivedCounter.first);
360 const profiling::Counter* serviceCounter = serviceCounterDirectory.GetCounter(translated);
361 BOOST_CHECK(serviceCounter->m_DeviceUid == receivedCounter.second->m_DeviceUid);
362 BOOST_CHECK(serviceCounter->m_Name.compare(receivedCounter.second->m_Name) == 0);
363 BOOST_CHECK(serviceCounter->m_CounterSetUid == receivedCounter.second->m_CounterSetUid);
364 BOOST_CHECK(serviceCounter->m_Multiplier == receivedCounter.second->m_Multiplier);
365 BOOST_CHECK(serviceCounter->m_Interpolation == receivedCounter.second->m_Interpolation);
366 BOOST_CHECK(serviceCounter->m_Class == receivedCounter.second->m_Class);
367 BOOST_CHECK(serviceCounter->m_Units.compare(receivedCounter.second->m_Units) == 0);
368 BOOST_CHECK(serviceCounter->m_Description.compare(receivedCounter.second->m_Description) == 0);
Finn Williams15db7452019-10-15 14:22:13 +0100369 }
370
371 mockService.WaitForReceivingThread();
372 options.m_EnableProfiling = false;
373 profilingService.ResetExternalProfilingOptions(options, true);
Colm Donelana21620d2019-10-11 13:09:49 +0100374 // Future tests here will add counters to the ProfilingService, increment values and examine
375 // PeriodicCounterCapture data received. These are yet to be integrated.
Colm Donelana21620d2019-10-11 13:09:49 +0100376}
377
Keith Davis33ed2212020-03-30 10:43:41 +0100378BOOST_AUTO_TEST_CASE(GatorDMockTimeLineActivation)
379{
Finn Williams0c32ccf2020-05-12 13:37:06 +0100380 // This test requires the CpuRef backend to be enabled
381 if(!BackendRegistryInstance().IsBackendRegistered("CpuRef"))
382 {
383 return;
384 }
Keith Davis33ed2212020-03-30 10:43:41 +0100385 armnn::MockBackendInitialiser initialiser;
386 // Setup the mock service to bind to the UDS.
387 std::string udsNamespace = "gatord_namespace";
388
Finn Williams2ed809c2020-04-20 21:21:07 +0100389 armnnProfiling::ConnectionHandler connectionHandler(udsNamespace, false);
Keith Davis33ed2212020-03-30 10:43:41 +0100390
391 armnn::IRuntime::CreationOptions options;
392 options.m_ProfilingOptions.m_EnableProfiling = true;
Finn Williamsd7fcafa2020-04-23 17:55:18 +0100393 options.m_ProfilingOptions.m_TimelineEnabled = true;
Keith Davis33ed2212020-03-30 10:43:41 +0100394 armnn::Runtime runtime(options);
395
Finn Williams2ed809c2020-04-20 21:21:07 +0100396 auto basePipeServer = connectionHandler.GetNewBasePipeServer(false);
397 gatordmock::GatordMockService mockService(std::move(basePipeServer), false);
Keith Davis33ed2212020-03-30 10:43:41 +0100398
399 // Read the stream metadata on the mock side.
400 if (!mockService.WaitForStreamMetaData())
401 {
402 BOOST_FAIL("Failed to receive StreamMetaData");
403 }
404
405 armnn::MockBackendProfilingService mockProfilingService = armnn::MockBackendProfilingService::Instance();
406 armnn::MockBackendProfilingContext *mockBackEndProfilingContext = mockProfilingService.GetContext();
407
408 // Send Ack from GatorD
409 mockService.SendConnectionAck();
410 // And start to listen for packets
411 mockService.LaunchReceivingThread();
412
413 // Build and optimize a simple network while we wait
414 INetworkPtr net(INetwork::Create());
415
416 IConnectableLayer* input = net->AddInputLayer(0, "input");
417
418 NormalizationDescriptor descriptor;
419 IConnectableLayer* normalize = net->AddNormalizationLayer(descriptor, "normalization");
420
421 IConnectableLayer* output = net->AddOutputLayer(0, "output");
422
423 input->GetOutputSlot(0).Connect(normalize->GetInputSlot(0));
424 normalize->GetOutputSlot(0).Connect(output->GetInputSlot(0));
425
426 input->GetOutputSlot(0).SetTensorInfo(TensorInfo({ 1, 1, 4, 4 }, DataType::Float32));
427 normalize->GetOutputSlot(0).SetTensorInfo(TensorInfo({ 1, 1, 4, 4 }, DataType::Float32));
428
429 std::vector<armnn::BackendId> backends = { armnn::Compute::CpuRef };
430 IOptimizedNetworkPtr optNet = Optimize(*net, backends, runtime.GetDeviceSpec());
431
432 WaitFor([&](){return mockService.GetDirectoryCaptureCommandHandler().ParsedCounterDirectory();},
433 "MockGatord did not receive counter directory packet");
434
435 timelinedecoder::TimelineDecoder& timelineDecoder = mockService.GetTimelineDecoder();
436
437 WaitFor([&](){return timelineDecoder.GetModel().m_EventClasses.size() >= 2;},
438 "MockGatord did not receive well known timeline labels");
439
Finn Williamsfe5a24b2020-04-09 16:05:28 +0100440 WaitFor([&](){return timelineDecoder.GetModel().m_Entities.size() >= 1;},
441 "MockGatord did not receive mock backend test entity");
442
Keith Davis33ed2212020-03-30 10:43:41 +0100443 // Packets we expect from SendWellKnownLabelsAndEventClassesTest
Finn Williamsfe5a24b2020-04-09 16:05:28 +0100444 BOOST_CHECK(timelineDecoder.GetModel().m_Entities.size() == 1);
Keith Davis33ed2212020-03-30 10:43:41 +0100445 BOOST_CHECK(timelineDecoder.GetModel().m_EventClasses.size() == 2);
Jan Eilersfd55dc92020-06-25 12:00:38 +0100446 BOOST_CHECK(timelineDecoder.GetModel().m_Labels.size() == 14);
Keith Davis33ed2212020-03-30 10:43:41 +0100447 BOOST_CHECK(timelineDecoder.GetModel().m_Relationships.size() == 0);
448 BOOST_CHECK(timelineDecoder.GetModel().m_Events.size() == 0);
449
450 mockService.SendDeactivateTimelinePacket();
451
452 WaitFor([&](){return !mockBackEndProfilingContext->TimelineReportingEnabled();},
453 "Timeline packets were not deactivated");
454
455 // Load the network into runtime now that timeline reporting is disabled
456 armnn::NetworkId netId;
457 runtime.LoadNetwork(netId, std::move(optNet));
458
459 // Now activate timeline packets
460 mockService.SendActivateTimelinePacket();
461
462 WaitFor([&](){return mockBackEndProfilingContext->TimelineReportingEnabled();},
463 "Timeline packets were not activated");
464
465 // Once timeline packets have been reactivated the ActivateTimelineReportingCommandHandler will resend the
466 // SendWellKnownLabelsAndEventClasses and then send the structure of any loaded networks
467 WaitFor([&](){return timelineDecoder.GetModel().m_Labels.size() >= 24;},
468 "MockGatord did not receive well known timeline labels");
469
Jan Eilersfd55dc92020-06-25 12:00:38 +0100470 // Packets we expect from SendWellKnownLabelsAndEventClassesTest * 2 + network above (input, norm, backend, output)
Finn Williamsfe5a24b2020-04-09 16:05:28 +0100471 BOOST_CHECK(timelineDecoder.GetModel().m_Entities.size() == 6);
Keith Davis33ed2212020-03-30 10:43:41 +0100472 BOOST_CHECK(timelineDecoder.GetModel().m_EventClasses.size() == 4);
Jan Eilersfd55dc92020-06-25 12:00:38 +0100473 BOOST_CHECK(timelineDecoder.GetModel().m_Labels.size() == 32);
Finn Williams0a336dc2020-05-11 15:39:58 +0100474 BOOST_CHECK(timelineDecoder.GetModel().m_Relationships.size() == 17);
Keith Davis33ed2212020-03-30 10:43:41 +0100475 BOOST_CHECK(timelineDecoder.GetModel().m_Events.size() == 0);
476
477 mockService.WaitForReceivingThread();
Keith Davis33ed2212020-03-30 10:43:41 +0100478 GetProfilingService(&runtime).Disconnect();
479}
480
Colm Donelana21620d2019-10-11 13:09:49 +0100481BOOST_AUTO_TEST_SUITE_END()