11 #include <client/src/ProfilingService.hpp> 12 #include <client/src/TimelinePacketWriterFactory.hpp> 16 #include <common/include/LabelsAndEventClasses.hpp> 17 #include <common/include/CommandHandlerRegistry.hpp> 22 #include <server/include/timelineDecoder/TimelineDirectoryCaptureCommandHandler.hpp> 23 #include <server/include/timelineDecoder/TimelineDecoder.hpp> 24 #include <server/include/basePipeServer/ConnectionHandler.hpp> 26 #include <doctest/doctest.h> 30 using namespace armnn;
31 using namespace std::this_thread;
34 TEST_CASE(
"CounterCaptureHandlingTest")
36 arm::pipe::PacketVersionResolver packetVersionResolver;
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));
48 uint32_t dataLength = 38;
51 uint64_t time =
static_cast<uint64_t
>(
52 std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::steady_clock::now().time_since_epoch())
55 uint64_t time2 = time + 5000;
58 std::unique_ptr<unsigned char[]> uniqueData1 = std::make_unique<unsigned char[]>(dataLength);
59 unsigned char* data1 =
reinterpret_cast<unsigned char*
>(uniqueData1.get());
61 std::unique_ptr<unsigned char[]> uniqueData2 = std::make_unique<unsigned char[]>(dataLength);
62 unsigned char* data2 =
reinterpret_cast<unsigned char*
>(uniqueData2.get());
70 arm::pipe::WriteUint64(data1, offset, time);
71 offset += sizeOfUint64;
72 for (
const auto& pair : indexValuePairs)
74 arm::pipe::WriteUint16(data1, offset, pair.first);
75 offset += sizeOfUint16;
76 arm::pipe::WriteUint32(data1, offset, pair.second);
77 offset += sizeOfUint32;
82 arm::pipe::WriteUint64(data2, offset, time2);
83 offset += sizeOfUint64;
84 for (
const auto& pair : indexValuePairs)
86 arm::pipe::WriteUint16(data2, offset, pair.first);
87 offset += sizeOfUint16;
88 arm::pipe::WriteUint32(data2, offset, pair.second);
89 offset += sizeOfUint32;
92 uint32_t headerWord1 = packetVersionResolver.ResolvePacketVersion(0, 4).GetEncodedValue();
94 arm::pipe::Packet packet1(headerWord1, dataLength, uniqueData1);
95 arm::pipe::Packet packet2(headerWord1, dataLength, uniqueData2);
100 commandHandler(packet1);
101 commandHandler(packet2);
111 void WaitFor(std::function<
bool()> predicate, std::string errorMsg, uint32_t timeout = 2000, uint32_t sleepTime = 50)
113 uint32_t timeSlept = 0;
116 if (timeSlept >= timeout)
118 FAIL(
"Timeout: " << errorMsg);
120 std::this_thread::sleep_for(std::chrono::milliseconds(sleepTime));
121 timeSlept += sleepTime;
125 void CheckTimelineDirectory(arm::pipe::TimelineDirectoryCaptureCommandHandler& commandHandler)
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);
130 uint32_t threadId_size =
sizeof(int);
132 arm::pipe::BufferManager bufferManager(5);
133 arm::pipe::TimelinePacketWriterFactory timelinePacketWriterFactory(bufferManager);
135 std::unique_ptr<arm::pipe::ISendTimelinePacket> sendTimelinePacket =
136 timelinePacketWriterFactory.GetSendTimelinePacket();
138 sendTimelinePacket->SendTimelineMessageDirectoryPackage();
139 sendTimelinePacket->Commit();
141 std::vector<arm::pipe::SwTraceMessage> swTraceBufferMessages;
143 unsigned int offset = uint32_t_size * 2;
145 std::unique_ptr<arm::pipe::IPacketBuffer> packetBuffer = bufferManager.GetReadableBuffer();
147 uint8_t readStreamVersion = ReadUint8(packetBuffer, offset);
148 CHECK(readStreamVersion == 4);
149 offset += uint8_t_size;
150 uint8_t readPointerBytes = ReadUint8(packetBuffer, offset);
151 CHECK(readPointerBytes == uint64_t_size);
152 offset += uint8_t_size;
153 uint8_t readThreadIdBytes = ReadUint8(packetBuffer, offset);
154 CHECK(readThreadIdBytes == threadId_size);
155 offset += uint8_t_size;
157 uint32_t declarationSize = arm::pipe::ReadUint32(packetBuffer, offset);
158 offset += uint32_t_size;
159 for(uint32_t i = 0; i < declarationSize; ++i)
161 swTraceBufferMessages.push_back(arm::pipe::ReadSwTraceMessage(packetBuffer->GetReadableData(),
163 packetBuffer->GetSize()));
166 for(uint32_t index = 0; index < declarationSize; ++index)
168 arm::pipe::SwTraceMessage& bufferMessage = swTraceBufferMessages[index];
169 arm::pipe::SwTraceMessage& handlerMessage = commandHandler.m_SwTraceMessages[index];
171 CHECK(bufferMessage.m_Name == handlerMessage.m_Name);
172 CHECK(bufferMessage.m_UiName == handlerMessage.m_UiName);
173 CHECK(bufferMessage.m_Id == handlerMessage.m_Id);
175 CHECK(bufferMessage.m_ArgTypes.size() == handlerMessage.m_ArgTypes.size());
176 for(uint32_t i = 0; i < bufferMessage.m_ArgTypes.size(); ++i)
178 CHECK(bufferMessage.m_ArgTypes[i] == handlerMessage.m_ArgTypes[i]);
181 CHECK(bufferMessage.m_ArgNames.size() == handlerMessage.m_ArgNames.size());
182 for(uint32_t i = 0; i < bufferMessage.m_ArgNames.size(); ++i)
184 CHECK(bufferMessage.m_ArgNames[i] == handlerMessage.m_ArgNames[i]);
189 void CheckTimelinePackets(arm::pipe::TimelineDecoder& timelineDecoder)
192 timelineDecoder.ApplyToModel([&](arm::pipe::TimelineDecoder::Model& m) {
193 CHECK(m.m_Labels[i].m_Guid == arm::pipe::LabelsAndEventClasses::NAME_GUID);
194 CHECK(m.m_Labels[i++].m_Name == arm::pipe::LabelsAndEventClasses::NAME_LABEL);
196 CHECK(m.m_Labels[i].m_Guid == arm::pipe::LabelsAndEventClasses::TYPE_GUID);
197 CHECK(m.m_Labels[i++].m_Name == arm::pipe::LabelsAndEventClasses::TYPE_LABEL);
199 CHECK(m.m_Labels[i].m_Guid == arm::pipe::LabelsAndEventClasses::INDEX_GUID);
200 CHECK(m.m_Labels[i++].m_Name == arm::pipe::LabelsAndEventClasses::INDEX_LABEL);
202 CHECK(m.m_Labels[i].m_Guid == arm::pipe::LabelsAndEventClasses::BACKENDID_GUID);
203 CHECK(m.m_Labels[i++].m_Name == arm::pipe::LabelsAndEventClasses::BACKENDID_LABEL);
205 CHECK(m.m_Labels[i].m_Guid == arm::pipe::LabelsAndEventClasses::CHILD_GUID);
206 CHECK(m.m_Labels[i++].m_Name == arm::pipe::LabelsAndEventClasses::CHILD_LABEL);
208 CHECK(m.m_Labels[i].m_Guid == arm::pipe::LabelsAndEventClasses::EXECUTION_OF_GUID);
209 CHECK(m.m_Labels[i++].m_Name ==
210 arm::pipe::LabelsAndEventClasses::EXECUTION_OF_LABEL);
212 CHECK(m.m_Labels[i].m_Guid == arm::pipe::LabelsAndEventClasses::PROCESS_ID_GUID);
213 CHECK(m.m_Labels[i++].m_Name ==
214 arm::pipe::LabelsAndEventClasses::PROCESS_ID_LABEL);
216 CHECK(m.m_Labels[i].m_Guid == arm::pipe::LabelsAndEventClasses::LAYER_GUID);
217 CHECK(m.m_Labels[i++].m_Name == arm::pipe::LabelsAndEventClasses::LAYER);
219 CHECK(m.m_Labels[i].m_Guid == arm::pipe::LabelsAndEventClasses::WORKLOAD_GUID);
220 CHECK(m.m_Labels[i++].m_Name == arm::pipe::LabelsAndEventClasses::WORKLOAD);
222 CHECK(m.m_Labels[i].m_Guid == arm::pipe::LabelsAndEventClasses::NETWORK_GUID);
223 CHECK(m.m_Labels[i++].m_Name == arm::pipe::LabelsAndEventClasses::NETWORK);
225 CHECK(m.m_Labels[i].m_Guid == arm::pipe::LabelsAndEventClasses::CONNECTION_GUID);
226 CHECK(m.m_Labels[i++].m_Name == arm::pipe::LabelsAndEventClasses::CONNECTION);
228 CHECK(m.m_Labels[i].m_Guid == arm::pipe::LabelsAndEventClasses::INFERENCE_GUID);
229 CHECK(m.m_Labels[i++].m_Name == arm::pipe::LabelsAndEventClasses::INFERENCE);
231 CHECK(m.m_Labels[i].m_Guid ==
232 arm::pipe::LabelsAndEventClasses::WORKLOAD_EXECUTION_GUID);
233 CHECK(m.m_Labels[i++].m_Name ==
234 arm::pipe::LabelsAndEventClasses::WORKLOAD_EXECUTION);
236 CHECK(m.m_EventClasses[0].m_Guid ==
237 arm::pipe::LabelsAndEventClasses::ARMNN_PROFILING_SOL_EVENT_CLASS);
238 CHECK(m.m_EventClasses[1].m_Guid ==
239 arm::pipe::LabelsAndEventClasses::ARMNN_PROFILING_EOL_EVENT_CLASS);
243 TEST_CASE(
"GatorDMockEndToEnd")
249 std::string udsNamespace =
"gatord_namespace";
251 CHECK_NOTHROW(arm::pipe::ConnectionHandler connectionHandler(udsNamespace,
false));
253 arm::pipe::ConnectionHandler connectionHandler(udsNamespace,
false);
256 arm::pipe::ProfilingOptions options;
257 options.m_EnableProfiling =
true;
258 options.m_TimelineEnabled =
true;
261 arm::pipe::ProfilingService profilingService(arm::pipe::MAX_ARMNN_COUNTER,
263 arm::pipe::ARMNN_SOFTWARE_INFO,
264 arm::pipe::ARMNN_SOFTWARE_VERSION,
265 arm::pipe::ARMNN_HARDWARE_VERSION);
266 profilingService.ResetExternalProfilingOptions(options,
true);
269 CHECK(profilingService.GetCurrentState() == arm::pipe::ProfilingState::Uninitialised);
270 profilingService.Update();
271 CHECK(profilingService.GetCurrentState() == arm::pipe::ProfilingState::NotConnected);
272 profilingService.Update();
275 auto basePipeServer = connectionHandler.GetNewBasePipeServer(
false);
281 arm::pipe::DirectoryCaptureCommandHandler& directoryCaptureCommandHandler =
285 WaitFor([&](){
return profilingService.GetCurrentState() == arm::pipe::ProfilingState::WaitingForAck;},
286 "Profiling service did not switch to WaitingForAck state");
288 profilingService.Update();
292 FAIL(
"Failed to receive StreamMetaData");
299 WaitFor([&](){
return profilingService.GetCurrentState() == arm::pipe::ProfilingState::Active;},
300 "Profiling service did not switch to Active state");
303 WaitFor([&](){
return directoryCaptureCommandHandler.ParsedCounterDirectory();},
304 "MockGatord did not receive counter directory packet");
307 WaitFor([&](){
return timelineDecoder.ApplyToModel([&](arm::pipe::TimelineDecoder::Model& m){
308 return m.m_EventClasses.size() >= 2;});},
309 "MockGatord did not receive well known timeline labels and event classes");
313 CheckTimelinePackets(timelineDecoder);
315 const arm::pipe::ICounterDirectory& serviceCounterDirectory = profilingService.GetCounterDirectory();
316 const arm::pipe::ICounterDirectory& receivedCounterDirectory = directoryCaptureCommandHandler.GetCounterDirectory();
319 CHECK(serviceCounterDirectory.GetDeviceCount() == receivedCounterDirectory.GetDeviceCount());
320 CHECK(serviceCounterDirectory.GetCounterSetCount() == receivedCounterDirectory.GetCounterSetCount());
321 CHECK(serviceCounterDirectory.GetCategoryCount() == receivedCounterDirectory.GetCategoryCount());
322 CHECK(serviceCounterDirectory.GetCounterCount() == receivedCounterDirectory.GetCounterCount());
324 receivedCounterDirectory.GetDeviceCount();
325 serviceCounterDirectory.GetDeviceCount();
327 const arm::pipe::Devices& serviceDevices = serviceCounterDirectory.GetDevices();
328 for (
auto& device : serviceDevices)
331 auto foundDevice = receivedCounterDirectory.GetDevices().find(device.second->m_Uid);
332 CHECK(foundDevice != receivedCounterDirectory.GetDevices().end());
333 CHECK(device.second->m_Name.compare((*foundDevice).second->m_Name) == 0);
334 CHECK(device.second->m_Cores == (*foundDevice).second->m_Cores);
337 const arm::pipe::CounterSets& serviceCounterSets = serviceCounterDirectory.GetCounterSets();
338 for (
auto& counterSet : serviceCounterSets)
341 auto foundCounterSet = receivedCounterDirectory.GetCounterSets().find(counterSet.second->m_Uid);
342 CHECK(foundCounterSet != receivedCounterDirectory.GetCounterSets().end());
343 CHECK(counterSet.second->m_Name.compare((*foundCounterSet).second->m_Name) == 0);
344 CHECK(counterSet.second->m_Count == (*foundCounterSet).second->m_Count);
347 const arm::pipe::Categories& serviceCategories = serviceCounterDirectory.GetCategories();
348 for (
auto& category : serviceCategories)
350 for (
auto& receivedCategory : receivedCounterDirectory.GetCategories())
352 if (receivedCategory->m_Name.compare(category->m_Name) == 0)
356 std::sort(category->m_Counters.begin(), category->m_Counters.end());
357 std::sort(receivedCategory->m_Counters.begin(), receivedCategory->m_Counters.end());
359 std::function<bool(const uint16_t&, const uint16_t&)> comparator =
360 [&directoryCaptureCommandHandler](
const uint16_t& first,
const uint16_t& second) {
361 uint16_t translated = directoryCaptureCommandHandler.TranslateUIDCopyToOriginal(second);
362 if (translated == first)
369 CHECK(std::equal(category->m_Counters.begin(), category->m_Counters.end(),
370 receivedCategory->m_Counters.begin(), comparator));
377 const arm::pipe::Counters& receivedCounters = receivedCounterDirectory.GetCounters();
378 for (
auto& receivedCounter : receivedCounters)
382 uint16_t translated = directoryCaptureCommandHandler.TranslateUIDCopyToOriginal(receivedCounter.first);
383 const arm::pipe::Counter* serviceCounter = serviceCounterDirectory.GetCounter(translated);
384 CHECK(serviceCounter->m_DeviceUid == receivedCounter.second->m_DeviceUid);
385 CHECK(serviceCounter->m_Name.compare(receivedCounter.second->m_Name) == 0);
386 CHECK(serviceCounter->m_CounterSetUid == receivedCounter.second->m_CounterSetUid);
387 CHECK(serviceCounter->m_Multiplier == receivedCounter.second->m_Multiplier);
388 CHECK(serviceCounter->m_Interpolation == receivedCounter.second->m_Interpolation);
389 CHECK(serviceCounter->m_Class == receivedCounter.second->m_Class);
390 CHECK(serviceCounter->m_Units.compare(receivedCounter.second->m_Units) == 0);
391 CHECK(serviceCounter->m_Description.compare(receivedCounter.second->m_Description) == 0);
395 options.m_EnableProfiling =
false;
396 profilingService.ResetExternalProfilingOptions(options,
true);
401 TEST_CASE(
"GatorDMockTimeLineActivation")
410 std::string udsNamespace =
"gatord_namespace";
412 arm::pipe::ConnectionHandler connectionHandler(udsNamespace,
false);
419 auto basePipeServer = connectionHandler.GetNewBasePipeServer(
false);
425 FAIL(
"Failed to receive StreamMetaData");
442 IConnectableLayer* normalize = net->AddNormalizationLayer(descriptor,
"normalization");
456 "MockGatord did not receive counter directory packet");
460 WaitFor([&](){
return timelineDecoder.ApplyToModel([&](arm::pipe::TimelineDecoder::Model& m){
461 return m.m_EventClasses.size() >= 2;});},
462 "MockGatord did not receive well known timeline labels");
464 WaitFor([&](){
return timelineDecoder.ApplyToModel([&](arm::pipe::TimelineDecoder::Model& m){
465 return m.m_Entities.size() >= 1;});},
466 "MockGatord did not receive mock backend test entity");
469 timelineDecoder.ApplyToModel([&](
const arm::pipe::TimelineDecoder::Model& m){
470 CHECK(m.m_Entities.size() == 1);
471 CHECK(m.m_EventClasses.size() == 2);
472 CHECK(m.m_Labels.size() == 15);
473 CHECK(m.m_Relationships.size() == 0);
474 CHECK(m.m_Events.size() == 0);
480 "Timeline packets were not deactivated");
490 "Timeline packets were not activated");
498 WaitFor([&](){
return timelineDecoder.ApplyToModel([&](arm::pipe::TimelineDecoder::Model& m){
499 return m.m_Labels.size() >= 24;});},
500 "MockGatord did not receive well known timeline labels");
503 timelineDecoder.ApplyToModel([&](
const arm::pipe::TimelineDecoder::Model& m){
504 CHECK(m.m_Entities.size() == 6);
505 CHECK(m.m_EventClasses.size() == 4);
506 CHECK(m.m_Labels.size() == 34);
507 CHECK(m.m_Relationships.size() == 15);
508 CHECK(m.m_Events.size() == 0);
Interface for a layer that is connectable to other layers via InputSlots and OutputSlots.
CPU Execution: Reference C++ kernels.
arm::pipe::TimelineDirectoryCaptureCommandHandler & GetTimelineDirectoryCaptureCommandHandler()
BackendRegistry & BackendRegistryInstance()
Status LoadNetwork(NetworkId &networkIdOut, IOptimizedNetworkPtr network)
Loads a complete network into the Runtime.
Copyright (c) 2021 ARM Limited and Contributors.
void SendDeactivateTimelinePacket()
Send a deactivate timeline packet back to the client.
bool m_EnableProfiling
Indicates whether external profiling is enabled or not.
void SendActivateTimelinePacket()
Send a activate timeline packet back to the client.
virtual void SetTensorInfo(const TensorInfo &tensorInfo)=0
bool WaitForStreamMetaData()
Once the connection is open wait to receive the stream meta data packet from the client.
arm::pipe::DirectoryCaptureCommandHandler & GetDirectoryCaptureCommandHandler()
arm::pipe::TimelineDecoder & GetTimelineDecoder()
IOptimizedNetworkPtr Optimize(const INetwork &network, const std::vector< BackendId > &backendPreferences, const IDeviceSpec &deviceSpec, const OptimizerOptions &options=OptimizerOptions(), Optional< std::vector< std::string > &> messages=EmptyOptional())
Create an optimized version of the network.
const IDeviceSpec & GetDeviceSpec() const
TEST_SUITE("GatordMockTests")
uint64_t m_CurrentPeriodValue
std::unique_ptr< IOptimizedNetwork, void(*)(IOptimizedNetwork *network)> IOptimizedNetworkPtr
#define ARMNN_ASSERT(COND)
bool LaunchReceivingThread()
Start the thread that will receive all packets and print them nicely to stdout.
static MockBackendProfilingService & Instance()
CounterCaptureValues m_CounterCaptureValues
std::vector< uint16_t > m_Uids
A class that implements a Mock Gatord server.
MockBackendProfilingContext * GetContext()
bool TimelineReportingEnabled()
virtual const IInputSlot & GetInputSlot(unsigned int index) const =0
Get a const input slot handle by slot index.
std::enable_if_t< std::is_unsigned< Source >::value &&std::is_unsigned< Dest >::value, Dest > numeric_cast(Source source)
bool m_TimelineEnabled
Indicates whether external timeline profiling is enabled or not.
virtual const IOutputSlot & GetOutputSlot(unsigned int index) const =0
Get the const output slot handle by slot index.
void WaitForReceivingThread()
This is a placeholder method to prevent main exiting.
std::unique_ptr< INetwork, void(*)(INetwork *network)> INetworkPtr
virtual int Connect(IInputSlot &destination)=0
A NormalizationDescriptor for the NormalizationLayer.
ExternalProfilingOptions m_ProfilingOptions
arm::pipe::IProfilingService & GetProfilingService(armnn::RuntimeImpl *runtime)
static INetworkPtr Create(NetworkOptions networkOptions={})
void SendConnectionAck()
Send a connection acknowledged packet back to the client.