ArmNN  NotReleased
GatordMockTests.cpp File Reference
#include <CommandHandlerRegistry.hpp>
#include <DirectoryCaptureCommandHandler.hpp>
#include <ProfilingService.hpp>
#include <GatordMockService.hpp>
#include <PeriodicCounterCaptureCommandHandler.hpp>
#include <StreamMetadataCommandHandler.hpp>
#include <TimelineDirectoryCaptureCommandHandler.hpp>
#include <test/ProfilingMocks.hpp>
#include <boost/cast.hpp>
#include <boost/test/test_tools.hpp>
#include <boost/test/unit_test_suite.hpp>

Go to the source code of this file.

Functions

 BOOST_AUTO_TEST_CASE (CounterCaptureHandlingTest)
 
 BOOST_AUTO_TEST_CASE (GatorDMockEndToEnd)
 

Function Documentation

◆ BOOST_AUTO_TEST_CASE() [1/2]

BOOST_AUTO_TEST_CASE ( CounterCaptureHandlingTest  )

Definition at line 26 of file GatordMockTests.cpp.

References Version::GetEncodedValue(), PeriodicCounterCaptureCommandHandler::m_CounterCaptureValues, PeriodicCounterCaptureCommandHandler::m_CurrentPeriodValue, CounterCaptureValues::m_Uids, PacketVersionResolver::ResolvePacketVersion(), armnn::profiling::WriteUint16(), armnn::profiling::WriteUint32(), and armnn::profiling::WriteUint64().

27 {
28  using boost::numeric_cast;
29 
30  profiling::PacketVersionResolver packetVersionResolver;
31 
32  // Data with timestamp, counter idx & counter values
33  std::vector<std::pair<uint16_t, uint32_t>> indexValuePairs;
34  indexValuePairs.reserve(5);
35  indexValuePairs.emplace_back(std::make_pair<uint16_t, uint32_t>(0, 100));
36  indexValuePairs.emplace_back(std::make_pair<uint16_t, uint32_t>(1, 200));
37  indexValuePairs.emplace_back(std::make_pair<uint16_t, uint32_t>(2, 300));
38  indexValuePairs.emplace_back(std::make_pair<uint16_t, uint32_t>(3, 400));
39  indexValuePairs.emplace_back(std::make_pair<uint16_t, uint32_t>(4, 500));
40 
41  // ((uint16_t (2 bytes) + uint32_t (4 bytes)) * 5) + word1 + word2
42  uint32_t dataLength = 38;
43 
44  // Simulate two different packets incoming 500 ms apart
45  uint64_t time = static_cast<uint64_t>(
46  std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::steady_clock::now().time_since_epoch())
47  .count());
48 
49  uint64_t time2 = time + 5000;
50 
51  // UniqueData required for Packet class
52  std::unique_ptr<unsigned char[]> uniqueData1 = std::make_unique<unsigned char[]>(dataLength);
53  unsigned char* data1 = reinterpret_cast<unsigned char*>(uniqueData1.get());
54 
55  std::unique_ptr<unsigned char[]> uniqueData2 = std::make_unique<unsigned char[]>(dataLength);
56  unsigned char* data2 = reinterpret_cast<unsigned char*>(uniqueData2.get());
57 
58  uint32_t sizeOfUint64 = numeric_cast<uint32_t>(sizeof(uint64_t));
59  uint32_t sizeOfUint32 = numeric_cast<uint32_t>(sizeof(uint32_t));
60  uint32_t sizeOfUint16 = numeric_cast<uint32_t>(sizeof(uint16_t));
61  // Offset index to point to mem address
62  uint32_t offset = 0;
63 
64  profiling::WriteUint64(data1, offset, time);
65  offset += sizeOfUint64;
66  for (const auto& pair : indexValuePairs)
67  {
68  profiling::WriteUint16(data1, offset, pair.first);
69  offset += sizeOfUint16;
70  profiling::WriteUint32(data1, offset, pair.second);
71  offset += sizeOfUint32;
72  }
73 
74  offset = 0;
75 
76  profiling::WriteUint64(data2, offset, time2);
77  offset += sizeOfUint64;
78  for (const auto& pair : indexValuePairs)
79  {
80  profiling::WriteUint16(data2, offset, pair.first);
81  offset += sizeOfUint16;
82  profiling::WriteUint32(data2, offset, pair.second);
83  offset += sizeOfUint32;
84  }
85 
86  uint32_t headerWord1 = packetVersionResolver.ResolvePacketVersion(0, 4).GetEncodedValue();
87  // Create packet to send through to the command functor
88  profiling::Packet packet1(headerWord1, dataLength, uniqueData1);
89  profiling::Packet packet2(headerWord1, dataLength, uniqueData2);
90 
91  gatordmock::PeriodicCounterCaptureCommandHandler commandHandler(0, 4, headerWord1, true);
92 
93  // Simulate two separate packets coming in to calculate period
94  commandHandler(packet1);
95  commandHandler(packet2);
96 
97  BOOST_ASSERT(commandHandler.m_CurrentPeriodValue == 5000);
98 
99  for (size_t i = 0; i < commandHandler.m_CounterCaptureValues.m_Uids.size(); ++i)
100  {
101  BOOST_ASSERT(commandHandler.m_CounterCaptureValues.m_Uids[i] == i);
102  }
103 }
Version ResolvePacketVersion(uint32_t familyId, uint32_t packetId) const
void WriteUint64(const std::unique_ptr< IPacketBuffer > &packetBuffer, unsigned int offset, uint64_t value)
void WriteUint16(const IPacketBufferPtr &packetBuffer, unsigned int offset, uint16_t value)
void WriteUint32(const IPacketBufferPtr &packetBuffer, unsigned int offset, uint32_t value)

◆ BOOST_AUTO_TEST_CASE() [2/2]

BOOST_AUTO_TEST_CASE ( GatorDMockEndToEnd  )

Definition at line 105 of file GatordMockTests.cpp.

References armnn::profiling::Active, GatordMockService::BlockForOneClient(), BOOST_AUTO_TEST_SUITE_END(), BOOST_CHECK(), ICounterDirectory::GetCategories(), ICounterDirectory::GetCategoryCount(), ICounterDirectory::GetCounter(), ICounterDirectory::GetCounterCount(), ProfilingService::GetCounterDirectory(), ICounterDirectory::GetCounters(), ICounterDirectory::GetCounterSetCount(), ICounterDirectory::GetCounterSets(), ProfilingService::GetCurrentState(), ICounterDirectory::GetDeviceCount(), ICounterDirectory::GetDevices(), Version::GetEncodedValue(), ProfilingService::Instance(), GatordMockService::LaunchReceivingThread(), Counter::m_Class, Counter::m_CounterSetUid, Counter::m_Description, Counter::m_DeviceUid, IRuntime::CreationOptions::ExternalProfilingOptions::m_EnableProfiling, Counter::m_Interpolation, Counter::m_Multiplier, Counter::m_Name, Counter::m_Units, armnn::profiling::NotConnected, GatordMockService::OpenListeningSocket(), options, profilingService, CommandHandlerRegistry::RegisterFunctor(), ProfilingService::ResetExternalProfilingOptions(), PacketVersionResolver::ResolvePacketVersion(), GatordMockService::SendConnectionAck(), armnn::profiling::Uninitialised, ProfilingService::Update(), GatordMockService::WaitForReceivingThread(), GatordMockService::WaitForStreamMetaData(), and armnn::profiling::WaitingForAck.

106 {
107  // The purpose of this test is to setup both sides of the profiling service and get to the point of receiving
108  // performance data.
109 
110  //These variables are used to wait for the profiling service
111  uint32_t timeout = 2000;
112  uint32_t sleepTime = 50;
113  uint32_t timeSlept = 0;
114 
115  profiling::PacketVersionResolver packetVersionResolver;
116 
117  // Create the Command Handler Registry
119 
120  // Update with derived functors
121  gatordmock::StreamMetadataCommandHandler streamMetadataCommandHandler(
122  0, 0, packetVersionResolver.ResolvePacketVersion(0, 0).GetEncodedValue(), true);
123 
124  gatordmock::PeriodicCounterCaptureCommandHandler counterCaptureCommandHandler(
125  0, 4, packetVersionResolver.ResolvePacketVersion(0, 4).GetEncodedValue(), true);
126 
127  profiling::DirectoryCaptureCommandHandler directoryCaptureCommandHandler(
128  0, 2, packetVersionResolver.ResolvePacketVersion(0, 2).GetEncodedValue(), true);
129 
130  gatordmock::TimelineDirectoryCaptureCommandHandler timelineDirectoryCaptureCommandHandler(
131  1, 0, packetVersionResolver.ResolvePacketVersion(1, 0).GetEncodedValue(), true);
132 
133  // Register different derived functors
134  registry.RegisterFunctor(&streamMetadataCommandHandler);
135  registry.RegisterFunctor(&counterCaptureCommandHandler);
136  registry.RegisterFunctor(&directoryCaptureCommandHandler);
137  registry.RegisterFunctor(&timelineDirectoryCaptureCommandHandler);
138  // Setup the mock service to bind to the UDS.
139  std::string udsNamespace = "gatord_namespace";
140  gatordmock::GatordMockService mockService(registry, false);
141  mockService.OpenListeningSocket(udsNamespace);
142 
143  // Enable the profiling service.
145  options.m_EnableProfiling = true;
146  profiling::ProfilingService& profilingService = profiling::ProfilingService::Instance();
147  profilingService.ResetExternalProfilingOptions(options, true);
148 
149  // Bring the profiling service to the "WaitingForAck" state
150  BOOST_CHECK(profilingService.GetCurrentState() == profiling::ProfilingState::Uninitialised);
151  profilingService.Update();
152  BOOST_CHECK(profilingService.GetCurrentState() == profiling::ProfilingState::NotConnected);
153  profilingService.Update();
154 
155  // Connect the profiling service to the mock Gatord.
156  int clientFd = mockService.BlockForOneClient();
157  if (-1 == clientFd)
158  {
159  BOOST_FAIL("Failed to connect client");
160  }
161 
162  // Give the profiling service sending thread time start executing and send the stream metadata.
163  while (profilingService.GetCurrentState() != profiling::ProfilingState::WaitingForAck)
164  {
165  if (timeSlept >= timeout)
166  {
167  BOOST_FAIL("Timeout: Profiling service did not switch to WaitingForAck state");
168  }
169  std::this_thread::sleep_for(std::chrono::milliseconds(sleepTime));
170  timeSlept += sleepTime;
171  }
172 
173  profilingService.Update();
174  // Read the stream metadata on the mock side.
175  if (!mockService.WaitForStreamMetaData())
176  {
177  BOOST_FAIL("Failed to receive StreamMetaData");
178  }
179  // Send Ack from GatorD
180  mockService.SendConnectionAck();
181 
182  timeSlept = 0;
183  while (profilingService.GetCurrentState() != profiling::ProfilingState::Active)
184  {
185  if (timeSlept >= timeout)
186  {
187  BOOST_FAIL("Timeout: Profiling service did not switch to Active state");
188  }
189  std::this_thread::sleep_for(std::chrono::milliseconds(sleepTime));
190  timeSlept += sleepTime;
191  }
192 
193  mockService.LaunchReceivingThread();
194  // As part of the default startup of the profiling service a counter directory packet will be sent.
195  timeSlept = 0;
196  while (!directoryCaptureCommandHandler.ParsedCounterDirectory())
197  {
198  if (timeSlept >= timeout)
199  {
200  BOOST_FAIL("Timeout: MockGatord did not receive counter directory packet");
201  }
202  std::this_thread::sleep_for(std::chrono::milliseconds(sleepTime));
203  timeSlept += sleepTime;
204  }
205 
206  const profiling::ICounterDirectory& serviceCounterDirectory = profilingService.GetCounterDirectory();
207  const profiling::ICounterDirectory& receivedCounterDirectory = directoryCaptureCommandHandler.GetCounterDirectory();
208 
209  // Compare thre basics of the counter directory from the service and the one we received over the wire.
210  BOOST_ASSERT(serviceCounterDirectory.GetDeviceCount() == receivedCounterDirectory.GetDeviceCount());
211  BOOST_ASSERT(serviceCounterDirectory.GetCounterSetCount() == receivedCounterDirectory.GetCounterSetCount());
212  BOOST_ASSERT(serviceCounterDirectory.GetCategoryCount() == receivedCounterDirectory.GetCategoryCount());
213  BOOST_ASSERT(serviceCounterDirectory.GetCounterCount() == receivedCounterDirectory.GetCounterCount());
214 
215  receivedCounterDirectory.GetDeviceCount();
216  serviceCounterDirectory.GetDeviceCount();
217 
218  const profiling::Devices& serviceDevices = serviceCounterDirectory.GetDevices();
219  for (auto& device : serviceDevices)
220  {
221  // Find the same device in the received counter directory.
222  auto foundDevice = receivedCounterDirectory.GetDevices().find(device.second->m_Uid);
223  BOOST_CHECK(foundDevice != receivedCounterDirectory.GetDevices().end());
224  BOOST_CHECK(device.second->m_Name.compare((*foundDevice).second->m_Name) == 0);
225  BOOST_CHECK(device.second->m_Cores == (*foundDevice).second->m_Cores);
226  }
227 
228  const profiling::CounterSets& serviceCounterSets = serviceCounterDirectory.GetCounterSets();
229  for (auto& counterSet : serviceCounterSets)
230  {
231  // Find the same counter set in the received counter directory.
232  auto foundCounterSet = receivedCounterDirectory.GetCounterSets().find(counterSet.second->m_Uid);
233  BOOST_CHECK(foundCounterSet != receivedCounterDirectory.GetCounterSets().end());
234  BOOST_CHECK(counterSet.second->m_Name.compare((*foundCounterSet).second->m_Name) == 0);
235  BOOST_CHECK(counterSet.second->m_Count == (*foundCounterSet).second->m_Count);
236  }
237 
238  const profiling::Categories& serviceCategories = serviceCounterDirectory.GetCategories();
239  for (auto& category : serviceCategories)
240  {
241  for (auto& receivedCategory : receivedCounterDirectory.GetCategories())
242  {
243  if (receivedCategory->m_Name.compare(category->m_Name) == 0)
244  {
245  // We've found the matching category.
246  BOOST_CHECK(category->m_DeviceUid == receivedCategory->m_DeviceUid);
247  BOOST_CHECK(category->m_CounterSetUid == receivedCategory->m_CounterSetUid);
248  // Now look at the interiors of the counters. Start by sorting them.
249  std::sort(category->m_Counters.begin(), category->m_Counters.end());
250  std::sort(receivedCategory->m_Counters.begin(), receivedCategory->m_Counters.end());
251  // When comparing uid's here we need to translate them.
252  std::function<bool(const uint16_t&, const uint16_t&)> comparator =
253  [&directoryCaptureCommandHandler](const uint16_t& first, const uint16_t& second) {
254  uint16_t translated = directoryCaptureCommandHandler.TranslateUIDCopyToOriginal(second);
255  if (translated == first)
256  {
257  return true;
258  }
259  return false;
260  };
261  // Then let vector == do the work.
262  BOOST_CHECK(std::equal(category->m_Counters.begin(), category->m_Counters.end(),
263  receivedCategory->m_Counters.begin(), comparator));
264  break;
265  }
266  }
267  }
268 
269  // Finally check the content of the counters.
270  const profiling::Counters& receivedCounters = receivedCounterDirectory.GetCounters();
271  for (auto& receivedCounter : receivedCounters)
272  {
273  // Translate the Uid and find the corresponding counter in the original counter directory.
274  // Note we can't check m_MaxCounterUid here as it will likely differ between the two counter directories.
275  uint16_t translated = directoryCaptureCommandHandler.TranslateUIDCopyToOriginal(receivedCounter.first);
276  const profiling::Counter* serviceCounter = serviceCounterDirectory.GetCounter(translated);
277  BOOST_CHECK(serviceCounter->m_DeviceUid == receivedCounter.second->m_DeviceUid);
278  BOOST_CHECK(serviceCounter->m_Name.compare(receivedCounter.second->m_Name) == 0);
279  BOOST_CHECK(serviceCounter->m_CounterSetUid == receivedCounter.second->m_CounterSetUid);
280  BOOST_CHECK(serviceCounter->m_Multiplier == receivedCounter.second->m_Multiplier);
281  BOOST_CHECK(serviceCounter->m_Interpolation == receivedCounter.second->m_Interpolation);
282  BOOST_CHECK(serviceCounter->m_Class == receivedCounter.second->m_Class);
283  BOOST_CHECK(serviceCounter->m_Units.compare(receivedCounter.second->m_Units) == 0);
284  BOOST_CHECK(serviceCounter->m_Description.compare(receivedCounter.second->m_Description) == 0);
285  }
286 
287  mockService.WaitForReceivingThread();
288  options.m_EnableProfiling = false;
289  profilingService.ResetExternalProfilingOptions(options, true);
290 
291  // Future tests here will add counters to the ProfilingService, increment values and examine
292  // PeriodicCounterCapture data received. These are yet to be integrated.
293 }
virtual const Devices & GetDevices() const =0
std::unordered_set< CategoryPtr > Categories
Version ResolvePacketVersion(uint32_t familyId, uint32_t packetId) const
std::unordered_map< uint16_t, DevicePtr > Devices
std::unordered_map< uint16_t, CounterSetPtr > CounterSets
virtual uint16_t GetCategoryCount() const =0
virtual const Categories & GetCategories() const =0
virtual uint16_t GetDeviceCount() const =0
virtual const CounterSets & GetCounterSets() const =0
virtual uint16_t GetCounterCount() const =0
const ICounterDirectory & GetCounterDirectory() const
virtual const Counter * GetCounter(uint16_t uid) const =0
void ResetExternalProfilingOptions(const ExternalProfilingOptions &options, bool resetProfilingService=false)
virtual const Counters & GetCounters() const =0
BOOST_CHECK(profilingService.GetCurrentState()==ProfilingState::WaitingForAck)
void RegisterFunctor(CommandHandlerFunctor *functor, uint32_t familyId, uint32_t packetId, uint32_t version)
virtual uint16_t GetCounterSetCount() const =0
std::unordered_map< uint16_t, CounterPtr > Counters
ProfilingState GetCurrentState() const
ProfilingService & profilingService
armnn::Runtime::CreationOptions::ExternalProfilingOptions options