2 // Copyright © 2019 Arm Ltd. All rights reserved.
3 // SPDX-License-Identifier: MIT
6 #include "SendCounterPacketTests.hpp"
8 #include <CounterDirectory.hpp>
9 #include <BufferManager.hpp>
10 #include <EncodeVersion.hpp>
11 #include <ProfilingUtils.hpp>
12 #include <SendCounterPacket.hpp>
14 #include <armnn/Exceptions.hpp>
15 #include <armnn/Conversion.hpp>
17 #include <boost/test/unit_test.hpp>
18 #include <boost/numeric/conversion/cast.hpp>
22 using namespace armnn::profiling;
27 void SetNotConnectedProfilingState(ProfilingStateMachine& profilingStateMachine)
29 ProfilingState currentState = profilingStateMachine.GetCurrentState();
32 case ProfilingState::WaitingForAck:
33 profilingStateMachine.TransitionToState(ProfilingState::Active);
34 case ProfilingState::Uninitialised:
35 case ProfilingState::Active:
36 profilingStateMachine.TransitionToState(ProfilingState::NotConnected);
37 case ProfilingState::NotConnected:
40 BOOST_CHECK_MESSAGE(false, "Invalid profiling state");
44 void SetWaitingForAckProfilingState(ProfilingStateMachine& profilingStateMachine)
46 ProfilingState currentState = profilingStateMachine.GetCurrentState();
49 case ProfilingState::Uninitialised:
50 case ProfilingState::Active:
51 profilingStateMachine.TransitionToState(ProfilingState::NotConnected);
52 case ProfilingState::NotConnected:
53 profilingStateMachine.TransitionToState(ProfilingState::WaitingForAck);
54 case ProfilingState::WaitingForAck:
57 BOOST_CHECK_MESSAGE(false, "Invalid profiling state");
61 void SetActiveProfilingState(ProfilingStateMachine& profilingStateMachine)
63 ProfilingState currentState = profilingStateMachine.GetCurrentState();
66 case ProfilingState::Uninitialised:
67 profilingStateMachine.TransitionToState(ProfilingState::NotConnected);
68 case ProfilingState::NotConnected:
69 profilingStateMachine.TransitionToState(ProfilingState::WaitingForAck);
70 case ProfilingState::WaitingForAck:
71 profilingStateMachine.TransitionToState(ProfilingState::Active);
72 case ProfilingState::Active:
75 BOOST_CHECK_MESSAGE(false, "Invalid profiling state");
79 } // Anonymous namespace
81 BOOST_AUTO_TEST_SUITE(SendCounterPacketTests)
83 BOOST_AUTO_TEST_CASE(MockSendCounterPacketTest)
85 MockBufferManager mockBuffer(512);
86 MockSendCounterPacket mockSendCounterPacket(mockBuffer);
88 mockSendCounterPacket.SendStreamMetaDataPacket();
90 auto packetBuffer = mockBuffer.GetReadableBuffer();
91 const char* buffer = reinterpret_cast<const char*>(packetBuffer->GetReadableData());
93 BOOST_TEST(strcmp(buffer, "SendStreamMetaDataPacket") == 0);
95 mockBuffer.MarkRead(packetBuffer);
97 CounterDirectory counterDirectory;
98 mockSendCounterPacket.SendCounterDirectoryPacket(counterDirectory);
100 packetBuffer = mockBuffer.GetReadableBuffer();
101 buffer = reinterpret_cast<const char*>(packetBuffer->GetReadableData());
103 BOOST_TEST(strcmp(buffer, "SendCounterDirectoryPacket") == 0);
105 mockBuffer.MarkRead(packetBuffer);
107 uint64_t timestamp = 0;
108 std::vector<std::pair<uint16_t, uint32_t>> indexValuePairs;
110 mockSendCounterPacket.SendPeriodicCounterCapturePacket(timestamp, indexValuePairs);
112 packetBuffer = mockBuffer.GetReadableBuffer();
113 buffer = reinterpret_cast<const char*>(packetBuffer->GetReadableData());
115 BOOST_TEST(strcmp(buffer, "SendPeriodicCounterCapturePacket") == 0);
117 mockBuffer.MarkRead(packetBuffer);
119 uint32_t capturePeriod = 0;
120 std::vector<uint16_t> selectedCounterIds;
121 mockSendCounterPacket.SendPeriodicCounterSelectionPacket(capturePeriod, selectedCounterIds);
123 packetBuffer = mockBuffer.GetReadableBuffer();
124 buffer = reinterpret_cast<const char*>(packetBuffer->GetReadableData());
126 BOOST_TEST(strcmp(buffer, "SendPeriodicCounterSelectionPacket") == 0);
128 mockBuffer.MarkRead(packetBuffer);
131 BOOST_AUTO_TEST_CASE(SendPeriodicCounterSelectionPacketTest)
133 ProfilingStateMachine profilingStateMachine;
135 // Error no space left in buffer
136 MockBufferManager mockBuffer1(10);
137 SendCounterPacket sendPacket1(profilingStateMachine, mockBuffer1);
139 uint32_t capturePeriod = 1000;
140 std::vector<uint16_t> selectedCounterIds;
141 BOOST_CHECK_THROW(sendPacket1.SendPeriodicCounterSelectionPacket(capturePeriod, selectedCounterIds),
144 // Packet without any counters
145 MockBufferManager mockBuffer2(512);
146 SendCounterPacket sendPacket2(profilingStateMachine, mockBuffer2);
148 sendPacket2.SendPeriodicCounterSelectionPacket(capturePeriod, selectedCounterIds);
149 auto readBuffer2 = mockBuffer2.GetReadableBuffer();
151 uint32_t headerWord0 = ReadUint32(readBuffer2, 0);
152 uint32_t headerWord1 = ReadUint32(readBuffer2, 4);
153 uint32_t period = ReadUint32(readBuffer2, 8);
155 BOOST_TEST(((headerWord0 >> 26) & 0x3F) == 0); // packet family
156 BOOST_TEST(((headerWord0 >> 16) & 0x3FF) == 4); // packet id
157 BOOST_TEST(headerWord1 == 4); // data lenght
158 BOOST_TEST(period == 1000); // capture period
160 // Full packet message
161 MockBufferManager mockBuffer3(512);
162 SendCounterPacket sendPacket3(profilingStateMachine, mockBuffer3);
164 selectedCounterIds.reserve(5);
165 selectedCounterIds.emplace_back(100);
166 selectedCounterIds.emplace_back(200);
167 selectedCounterIds.emplace_back(300);
168 selectedCounterIds.emplace_back(400);
169 selectedCounterIds.emplace_back(500);
170 sendPacket3.SendPeriodicCounterSelectionPacket(capturePeriod, selectedCounterIds);
171 auto readBuffer3 = mockBuffer3.GetReadableBuffer();
173 headerWord0 = ReadUint32(readBuffer3, 0);
174 headerWord1 = ReadUint32(readBuffer3, 4);
175 period = ReadUint32(readBuffer3, 8);
177 BOOST_TEST(((headerWord0 >> 26) & 0x3F) == 0); // packet family
178 BOOST_TEST(((headerWord0 >> 16) & 0x3FF) == 4); // packet id
179 BOOST_TEST(headerWord1 == 14); // data lenght
180 BOOST_TEST(period == 1000); // capture period
182 uint16_t counterId = 0;
183 uint32_t offset = 12;
186 for(const uint16_t& id : selectedCounterIds)
188 counterId = ReadUint16(readBuffer3, offset);
189 BOOST_TEST(counterId == id);
194 BOOST_AUTO_TEST_CASE(SendPeriodicCounterCapturePacketTest)
196 ProfilingStateMachine profilingStateMachine;
198 // Error no space left in buffer
199 MockBufferManager mockBuffer1(10);
200 SendCounterPacket sendPacket1(profilingStateMachine, mockBuffer1);
202 auto captureTimestamp = std::chrono::steady_clock::now();
203 uint64_t time = static_cast<uint64_t >(captureTimestamp.time_since_epoch().count());
204 std::vector<std::pair<uint16_t, uint32_t>> indexValuePairs;
206 BOOST_CHECK_THROW(sendPacket1.SendPeriodicCounterCapturePacket(time, indexValuePairs),
209 // Packet without any counters
210 MockBufferManager mockBuffer2(512);
211 SendCounterPacket sendPacket2(profilingStateMachine, mockBuffer2);
213 sendPacket2.SendPeriodicCounterCapturePacket(time, indexValuePairs);
214 auto readBuffer2 = mockBuffer2.GetReadableBuffer();
216 uint32_t headerWord0 = ReadUint32(readBuffer2, 0);
217 uint32_t headerWord1 = ReadUint32(readBuffer2, 4);
218 uint64_t readTimestamp = ReadUint64(readBuffer2, 8);
220 BOOST_TEST(((headerWord0 >> 26) & 0x3F) == 1); // packet family
221 BOOST_TEST(((headerWord0 >> 19) & 0x3F) == 0); // packet class
222 BOOST_TEST(((headerWord0 >> 16) & 0x3) == 0); // packet type
223 BOOST_TEST(headerWord1 == 8); // data length
224 BOOST_TEST(time == readTimestamp); // capture period
226 // Full packet message
227 MockBufferManager mockBuffer3(512);
228 SendCounterPacket sendPacket3(profilingStateMachine, mockBuffer3);
230 indexValuePairs.reserve(5);
231 indexValuePairs.emplace_back(std::make_pair<uint16_t, uint32_t >(0, 100));
232 indexValuePairs.emplace_back(std::make_pair<uint16_t, uint32_t >(1, 200));
233 indexValuePairs.emplace_back(std::make_pair<uint16_t, uint32_t >(2, 300));
234 indexValuePairs.emplace_back(std::make_pair<uint16_t, uint32_t >(3, 400));
235 indexValuePairs.emplace_back(std::make_pair<uint16_t, uint32_t >(4, 500));
236 sendPacket3.SendPeriodicCounterCapturePacket(time, indexValuePairs);
237 auto readBuffer3 = mockBuffer3.GetReadableBuffer();
239 headerWord0 = ReadUint32(readBuffer3, 0);
240 headerWord1 = ReadUint32(readBuffer3, 4);
241 uint64_t readTimestamp2 = ReadUint64(readBuffer3, 8);
243 BOOST_TEST(((headerWord0 >> 26) & 0x3F) == 1); // packet family
244 BOOST_TEST(((headerWord0 >> 19) & 0x3F) == 0); // packet class
245 BOOST_TEST(((headerWord0 >> 16) & 0x3) == 0); // packet type
246 BOOST_TEST(headerWord1 == 38); // data length
247 BOOST_TEST(time == readTimestamp2); // capture period
249 uint16_t counterIndex = 0;
250 uint32_t counterValue = 100;
251 uint32_t offset = 16;
254 for (auto it = indexValuePairs.begin(), end = indexValuePairs.end(); it != end; ++it)
256 // Check Counter Index
257 uint16_t readIndex = ReadUint16(readBuffer3, offset);
258 BOOST_TEST(counterIndex == readIndex);
262 // Check Counter Value
263 uint32_t readValue = ReadUint32(readBuffer3, offset);
264 BOOST_TEST(counterValue == readValue);
271 BOOST_AUTO_TEST_CASE(SendStreamMetaDataPacketTest)
273 using boost::numeric_cast;
275 uint32_t sizeUint32 = numeric_cast<uint32_t>(sizeof(uint32_t));
277 ProfilingStateMachine profilingStateMachine;
279 // Error no space left in buffer
280 MockBufferManager mockBuffer1(10);
281 SendCounterPacket sendPacket1(profilingStateMachine, mockBuffer1);
282 BOOST_CHECK_THROW(sendPacket1.SendStreamMetaDataPacket(), armnn::profiling::BufferExhaustion);
284 // Full metadata packet
286 std::string processName = GetProcessName().substr(0, 60);
288 uint32_t infoSize = numeric_cast<uint32_t>(GetSoftwareInfo().size()) > 0 ?
289 numeric_cast<uint32_t>(GetSoftwareInfo().size()) + 1 : 0;
290 uint32_t hardwareVersionSize = numeric_cast<uint32_t>(GetHardwareVersion().size()) > 0 ?
291 numeric_cast<uint32_t>(GetHardwareVersion().size()) + 1 : 0;
292 uint32_t softwareVersionSize = numeric_cast<uint32_t>(GetSoftwareVersion().size()) > 0 ?
293 numeric_cast<uint32_t>(GetSoftwareVersion().size()) + 1 : 0;
294 uint32_t processNameSize = numeric_cast<uint32_t>(processName.size()) > 0 ?
295 numeric_cast<uint32_t>(processName.size()) + 1 : 0;
297 uint32_t packetEntries = 6;
299 MockBufferManager mockBuffer2(512);
300 SendCounterPacket sendPacket2(profilingStateMachine, mockBuffer2);
301 sendPacket2.SendStreamMetaDataPacket();
302 auto readBuffer2 = mockBuffer2.GetReadableBuffer();
304 uint32_t headerWord0 = ReadUint32(readBuffer2, 0);
305 uint32_t headerWord1 = ReadUint32(readBuffer2, sizeUint32);
307 BOOST_TEST(((headerWord0 >> 26) & 0x3F) == 0); // packet family
308 BOOST_TEST(((headerWord0 >> 16) & 0x3FF) == 0); // packet id
310 uint32_t totalLength = numeric_cast<uint32_t>(2 * sizeUint32 + 10 * sizeUint32 + infoSize + hardwareVersionSize +
311 softwareVersionSize + processNameSize + sizeUint32 +
312 2 * packetEntries * sizeUint32);
314 BOOST_TEST(headerWord1 == totalLength - (2 * sizeUint32)); // data length
316 uint32_t offset = sizeUint32 * 2;
317 BOOST_TEST(ReadUint32(readBuffer2, offset) == SendCounterPacket::PIPE_MAGIC); // pipe_magic
318 offset += sizeUint32;
319 BOOST_TEST(ReadUint32(readBuffer2, offset) == EncodeVersion(1, 0, 0)); // stream_metadata_version
320 offset += sizeUint32;
321 BOOST_TEST(ReadUint32(readBuffer2, offset) == SendCounterPacket::MAX_METADATA_PACKET_LENGTH); // max_data_len
322 offset += sizeUint32;
323 BOOST_TEST(ReadUint32(readBuffer2, offset) == numeric_cast<uint32_t>(getpid())); // pid
324 offset += sizeUint32;
325 uint32_t poolOffset = 10 * sizeUint32;
326 BOOST_TEST(ReadUint32(readBuffer2, offset) == (infoSize ? poolOffset : 0)); // offset_info
327 offset += sizeUint32;
328 poolOffset += infoSize;
329 BOOST_TEST(ReadUint32(readBuffer2, offset) == (hardwareVersionSize ? poolOffset : 0)); // offset_hw_version
330 offset += sizeUint32;
331 poolOffset += hardwareVersionSize;
332 BOOST_TEST(ReadUint32(readBuffer2, offset) == (softwareVersionSize ? poolOffset : 0)); // offset_sw_version
333 offset += sizeUint32;
334 poolOffset += softwareVersionSize;
335 BOOST_TEST(ReadUint32(readBuffer2, offset) == (processNameSize ? poolOffset : 0)); // offset_process_name
336 offset += sizeUint32;
337 poolOffset += processNameSize;
338 BOOST_TEST(ReadUint32(readBuffer2, offset) == (packetEntries ? poolOffset : 0)); // offset_packet_version_table
339 offset += sizeUint32;
340 BOOST_TEST(ReadUint32(readBuffer2, offset) == 0); // reserved
342 const unsigned char* readData2 = readBuffer2->GetReadableData();
344 offset += sizeUint32;
347 BOOST_TEST(strcmp(reinterpret_cast<const char *>(&readData2[offset]), GetSoftwareInfo().c_str()) == 0);
351 if (hardwareVersionSize)
353 BOOST_TEST(strcmp(reinterpret_cast<const char *>(&readData2[offset]), GetHardwareVersion().c_str()) == 0);
354 offset += hardwareVersionSize;
357 if (softwareVersionSize)
359 BOOST_TEST(strcmp(reinterpret_cast<const char *>(&readData2[offset]), GetSoftwareVersion().c_str()) == 0);
360 offset += softwareVersionSize;
365 BOOST_TEST(strcmp(reinterpret_cast<const char *>(&readData2[offset]), GetProcessName().c_str()) == 0);
366 offset += processNameSize;
371 BOOST_TEST((ReadUint32(readBuffer2, offset) >> 16) == packetEntries);
372 offset += sizeUint32;
373 for (uint32_t i = 0; i < packetEntries - 1; ++i)
375 BOOST_TEST(((ReadUint32(readBuffer2, offset) >> 26) & 0x3F) == 0);
376 BOOST_TEST(((ReadUint32(readBuffer2, offset) >> 16) & 0x3FF) == i);
377 offset += sizeUint32;
378 BOOST_TEST(ReadUint32(readBuffer2, offset) == EncodeVersion(1, 0, 0));
379 offset += sizeUint32;
382 BOOST_TEST(((ReadUint32(readBuffer2, offset) >> 26) & 0x3F) == 1);
383 BOOST_TEST(((ReadUint32(readBuffer2, offset) >> 16) & 0x3FF) == 0);
384 offset += sizeUint32;
385 BOOST_TEST(ReadUint32(readBuffer2, offset) == EncodeVersion(1, 0, 0));
386 offset += sizeUint32;
389 BOOST_TEST(offset == totalLength);
392 BOOST_AUTO_TEST_CASE(CreateDeviceRecordTest)
394 ProfilingStateMachine profilingStateMachine;
396 MockBufferManager mockBuffer(0);
397 SendCounterPacketTest sendCounterPacketTest(profilingStateMachine, mockBuffer);
399 // Create a device for testing
400 uint16_t deviceUid = 27;
401 const std::string deviceName = "some_device";
402 uint16_t deviceCores = 3;
403 const DevicePtr device = std::make_unique<Device>(deviceUid, deviceName, deviceCores);
405 // Create a device record
406 SendCounterPacket::DeviceRecord deviceRecord;
407 std::string errorMessage;
408 bool result = sendCounterPacketTest.CreateDeviceRecordTest(device, deviceRecord, errorMessage);
411 BOOST_CHECK(errorMessage.empty());
412 BOOST_CHECK(deviceRecord.size() == 6); // Size in words: header [2] + device name [4]
414 uint16_t deviceRecordWord0[]
416 static_cast<uint16_t>(deviceRecord[0] >> 16),
417 static_cast<uint16_t>(deviceRecord[0])
419 BOOST_CHECK(deviceRecordWord0[0] == deviceUid); // uid
420 BOOST_CHECK(deviceRecordWord0[1] == deviceCores); // cores
421 BOOST_CHECK(deviceRecord[1] == 0); // name_offset
422 BOOST_CHECK(deviceRecord[2] == deviceName.size() + 1); // The length of the SWTrace string (name)
423 BOOST_CHECK(std::memcmp(deviceRecord.data() + 3, deviceName.data(), deviceName.size()) == 0); // name
426 BOOST_AUTO_TEST_CASE(CreateInvalidDeviceRecordTest)
428 ProfilingStateMachine profilingStateMachine;
430 MockBufferManager mockBuffer(0);
431 SendCounterPacketTest sendCounterPacketTest(profilingStateMachine, mockBuffer);
433 // Create a device for testing
434 uint16_t deviceUid = 27;
435 const std::string deviceName = "some€£invalid‡device";
436 uint16_t deviceCores = 3;
437 const DevicePtr device = std::make_unique<Device>(deviceUid, deviceName, deviceCores);
439 // Create a device record
440 SendCounterPacket::DeviceRecord deviceRecord;
441 std::string errorMessage;
442 bool result = sendCounterPacketTest.CreateDeviceRecordTest(device, deviceRecord, errorMessage);
444 BOOST_CHECK(!result);
445 BOOST_CHECK(!errorMessage.empty());
446 BOOST_CHECK(deviceRecord.empty());
449 BOOST_AUTO_TEST_CASE(CreateCounterSetRecordTest)
451 ProfilingStateMachine profilingStateMachine;
453 MockBufferManager mockBuffer(0);
454 SendCounterPacketTest sendCounterPacketTest(profilingStateMachine, mockBuffer);
456 // Create a counter set for testing
457 uint16_t counterSetUid = 27;
458 const std::string counterSetName = "some_counter_set";
459 uint16_t counterSetCount = 3421;
460 const CounterSetPtr counterSet = std::make_unique<CounterSet>(counterSetUid, counterSetName, counterSetCount);
462 // Create a counter set record
463 SendCounterPacket::CounterSetRecord counterSetRecord;
464 std::string errorMessage;
465 bool result = sendCounterPacketTest.CreateCounterSetRecordTest(counterSet, counterSetRecord, errorMessage);
468 BOOST_CHECK(errorMessage.empty());
469 BOOST_CHECK(counterSetRecord.size() == 8); // Size in words: header [2] + counter set name [6]
471 uint16_t counterSetRecordWord0[]
473 static_cast<uint16_t>(counterSetRecord[0] >> 16),
474 static_cast<uint16_t>(counterSetRecord[0])
476 BOOST_CHECK(counterSetRecordWord0[0] == counterSetUid); // uid
477 BOOST_CHECK(counterSetRecordWord0[1] == counterSetCount); // cores
478 BOOST_CHECK(counterSetRecord[1] == 0); // name_offset
479 BOOST_CHECK(counterSetRecord[2] == counterSetName.size() + 1); // The length of the SWTrace string (name)
480 BOOST_CHECK(std::memcmp(counterSetRecord.data() + 3, counterSetName.data(), counterSetName.size()) == 0); // name
483 BOOST_AUTO_TEST_CASE(CreateInvalidCounterSetRecordTest)
485 ProfilingStateMachine profilingStateMachine;
487 MockBufferManager mockBuffer(0);
488 SendCounterPacketTest sendCounterPacketTest(profilingStateMachine, mockBuffer);
490 // Create a counter set for testing
491 uint16_t counterSetUid = 27;
492 const std::string counterSetName = "some invalid_counter€£set";
493 uint16_t counterSetCount = 3421;
494 const CounterSetPtr counterSet = std::make_unique<CounterSet>(counterSetUid, counterSetName, counterSetCount);
496 // Create a counter set record
497 SendCounterPacket::CounterSetRecord counterSetRecord;
498 std::string errorMessage;
499 bool result = sendCounterPacketTest.CreateCounterSetRecordTest(counterSet, counterSetRecord, errorMessage);
501 BOOST_CHECK(!result);
502 BOOST_CHECK(!errorMessage.empty());
503 BOOST_CHECK(counterSetRecord.empty());
506 BOOST_AUTO_TEST_CASE(CreateEventRecordTest)
508 ProfilingStateMachine profilingStateMachine;
510 MockBufferManager mockBuffer(0);
511 SendCounterPacketTest sendCounterPacketTest(profilingStateMachine, mockBuffer);
513 // Create a counter for testing
514 uint16_t counterUid = 7256;
515 uint16_t maxCounterUid = 132;
516 uint16_t deviceUid = 132;
517 uint16_t counterSetUid = 4497;
518 uint16_t counterClass = 1;
519 uint16_t counterInterpolation = 1;
520 double counterMultiplier = 1234.567f;
521 const std::string counterName = "some_valid_counter";
522 const std::string counterDescription = "a_counter_for_testing";
523 const std::string counterUnits = "Mrads2";
524 const CounterPtr counter = std::make_unique<Counter>(counterUid,
527 counterInterpolation,
534 BOOST_ASSERT(counter);
536 // Create an event record
537 SendCounterPacket::EventRecord eventRecord;
538 std::string errorMessage;
539 bool result = sendCounterPacketTest.CreateEventRecordTest(counter, eventRecord, errorMessage);
542 BOOST_CHECK(errorMessage.empty());
543 BOOST_CHECK(eventRecord.size() == 24); // Size in words: header [8] + counter name [6] + description [7] + units [3]
545 uint16_t eventRecordWord0[]
547 static_cast<uint16_t>(eventRecord[0] >> 16),
548 static_cast<uint16_t>(eventRecord[0])
550 uint16_t eventRecordWord1[]
552 static_cast<uint16_t>(eventRecord[1] >> 16),
553 static_cast<uint16_t>(eventRecord[1])
555 uint16_t eventRecordWord2[]
557 static_cast<uint16_t>(eventRecord[2] >> 16),
558 static_cast<uint16_t>(eventRecord[2])
560 uint32_t eventRecordWord34[]
565 BOOST_CHECK(eventRecordWord0[0] == maxCounterUid); // max_counter_uid
566 BOOST_CHECK(eventRecordWord0[1] == counterUid); // counter_uid
567 BOOST_CHECK(eventRecordWord1[0] == deviceUid); // device
568 BOOST_CHECK(eventRecordWord1[1] == counterSetUid); // counter_set
569 BOOST_CHECK(eventRecordWord2[0] == counterClass); // class
570 BOOST_CHECK(eventRecordWord2[1] == counterInterpolation); // interpolation
571 BOOST_CHECK(std::memcmp(eventRecordWord34, &counterMultiplier, sizeof(counterMultiplier)) == 0); // multiplier
573 ARMNN_NO_CONVERSION_WARN_BEGIN
574 uint32_t counterNameOffset = 0; // The name is the first item in pool
575 uint32_t counterDescriptionOffset = counterNameOffset + // Counter name offset
576 4u + // Counter name length (uint32_t)
577 counterName.size() + // 18u
578 1u + // Null-terminator
579 1u; // Rounding to the next word
580 size_t counterUnitsOffset = counterDescriptionOffset + // Counter description offset
581 4u + // Counter description length (uint32_t)
582 counterDescription.size() + // 21u
583 1u + // Null-terminator
584 2u; // Rounding to the next word
585 ARMNN_NO_CONVERSION_WARN_END
587 BOOST_CHECK(eventRecord[5] == counterNameOffset); // name_offset
588 BOOST_CHECK(eventRecord[6] == counterDescriptionOffset); // description_offset
589 BOOST_CHECK(eventRecord[7] == counterUnitsOffset); // units_offset
591 auto eventRecordPool = reinterpret_cast<unsigned char*>(eventRecord.data() + 8u); // The start of the pool
592 size_t uint32_t_size = sizeof(uint32_t);
594 // The length of the SWTrace string (name)
595 BOOST_CHECK(eventRecordPool[counterNameOffset] == counterName.size() + 1);
597 BOOST_CHECK(std::memcmp(eventRecordPool +
598 counterNameOffset + // Offset
599 uint32_t_size /* The length of the name */,
601 counterName.size()) == 0); // name
602 // The null-terminator at the end of the name
603 BOOST_CHECK(eventRecordPool[counterNameOffset + uint32_t_size + counterName.size()] == '\0');
605 // The length of the SWTrace string (description)
606 BOOST_CHECK(eventRecordPool[counterDescriptionOffset] == counterDescription.size() + 1);
607 // The counter description
608 BOOST_CHECK(std::memcmp(eventRecordPool +
609 counterDescriptionOffset + // Offset
610 uint32_t_size /* The length of the description */,
611 counterDescription.data(),
612 counterDescription.size()) == 0); // description
613 // The null-terminator at the end of the description
614 BOOST_CHECK(eventRecordPool[counterDescriptionOffset + uint32_t_size + counterDescription.size()] == '\0');
616 // The length of the SWTrace namestring (units)
617 BOOST_CHECK(eventRecordPool[counterUnitsOffset] == counterUnits.size() + 1);
619 BOOST_CHECK(std::memcmp(eventRecordPool +
620 counterUnitsOffset + // Offset
621 uint32_t_size /* The length of the units */,
623 counterUnits.size()) == 0); // units
624 // The null-terminator at the end of the units
625 BOOST_CHECK(eventRecordPool[counterUnitsOffset + uint32_t_size + counterUnits.size()] == '\0');
628 BOOST_AUTO_TEST_CASE(CreateEventRecordNoUnitsTest)
630 ProfilingStateMachine profilingStateMachine;
632 MockBufferManager mockBuffer(0);
633 SendCounterPacketTest sendCounterPacketTest(profilingStateMachine, mockBuffer);
635 // Create a counter for testing
636 uint16_t counterUid = 44312;
637 uint16_t maxCounterUid = 345;
638 uint16_t deviceUid = 101;
639 uint16_t counterSetUid = 34035;
640 uint16_t counterClass = 0;
641 uint16_t counterInterpolation = 1;
642 double counterMultiplier = 4435.0023f;
643 const std::string counterName = "some_valid_counter";
644 const std::string counterDescription = "a_counter_for_testing";
645 const CounterPtr counter = std::make_unique<Counter>(counterUid,
648 counterInterpolation,
655 BOOST_ASSERT(counter);
657 // Create an event record
658 SendCounterPacket::EventRecord eventRecord;
659 std::string errorMessage;
660 bool result = sendCounterPacketTest.CreateEventRecordTest(counter, eventRecord, errorMessage);
663 BOOST_CHECK(errorMessage.empty());
664 BOOST_CHECK(eventRecord.size() == 21); // Size in words: header [8] + counter name [6] + description [7]
666 uint16_t eventRecordWord0[]
668 static_cast<uint16_t>(eventRecord[0] >> 16),
669 static_cast<uint16_t>(eventRecord[0])
671 uint16_t eventRecordWord1[]
673 static_cast<uint16_t>(eventRecord[1] >> 16),
674 static_cast<uint16_t>(eventRecord[1])
676 uint16_t eventRecordWord2[]
678 static_cast<uint16_t>(eventRecord[2] >> 16),
679 static_cast<uint16_t>(eventRecord[2])
681 uint32_t eventRecordWord34[]
686 BOOST_CHECK(eventRecordWord0[0] == maxCounterUid); // max_counter_uid
687 BOOST_CHECK(eventRecordWord0[1] == counterUid); // counter_uid
688 BOOST_CHECK(eventRecordWord1[0] == deviceUid); // device
689 BOOST_CHECK(eventRecordWord1[1] == counterSetUid); // counter_set
690 BOOST_CHECK(eventRecordWord2[0] == counterClass); // class
691 BOOST_CHECK(eventRecordWord2[1] == counterInterpolation); // interpolation
692 BOOST_CHECK(std::memcmp(eventRecordWord34, &counterMultiplier, sizeof(counterMultiplier)) == 0); // multiplier
694 ARMNN_NO_CONVERSION_WARN_BEGIN
695 uint32_t counterNameOffset = 0; // The name is the first item in pool
696 uint32_t counterDescriptionOffset = counterNameOffset + // Counter name offset
697 4u + // Counter name length (uint32_t)
698 counterName.size() + // 18u
699 1u + // Null-terminator
700 1u; // Rounding to the next word
701 ARMNN_NO_CONVERSION_WARN_END
703 BOOST_CHECK(eventRecord[5] == counterNameOffset); // name_offset
704 BOOST_CHECK(eventRecord[6] == counterDescriptionOffset); // description_offset
705 BOOST_CHECK(eventRecord[7] == 0); // units_offset
707 auto eventRecordPool = reinterpret_cast<unsigned char*>(eventRecord.data() + 8u); // The start of the pool
708 size_t uint32_t_size = sizeof(uint32_t);
710 // The length of the SWTrace string (name)
711 BOOST_CHECK(eventRecordPool[counterNameOffset] == counterName.size() + 1);
713 BOOST_CHECK(std::memcmp(eventRecordPool +
714 counterNameOffset + // Offset
715 uint32_t_size, // The length of the name
717 counterName.size()) == 0); // name
718 // The null-terminator at the end of the name
719 BOOST_CHECK(eventRecordPool[counterNameOffset + uint32_t_size + counterName.size()] == '\0');
721 // The length of the SWTrace string (description)
722 BOOST_CHECK(eventRecordPool[counterDescriptionOffset] == counterDescription.size() + 1);
723 // The counter description
724 BOOST_CHECK(std::memcmp(eventRecordPool +
725 counterDescriptionOffset + // Offset
726 uint32_t_size, // The length of the description
727 counterDescription.data(),
728 counterDescription.size()) == 0); // description
729 // The null-terminator at the end of the description
730 BOOST_CHECK(eventRecordPool[counterDescriptionOffset + uint32_t_size + counterDescription.size()] == '\0');
733 BOOST_AUTO_TEST_CASE(CreateInvalidEventRecordTest1)
735 ProfilingStateMachine profilingStateMachine;
737 MockBufferManager mockBuffer(0);
738 SendCounterPacketTest sendCounterPacketTest(profilingStateMachine, mockBuffer);
740 // Create a counter for testing
741 uint16_t counterUid = 7256;
742 uint16_t maxCounterUid = 132;
743 uint16_t deviceUid = 132;
744 uint16_t counterSetUid = 4497;
745 uint16_t counterClass = 1;
746 uint16_t counterInterpolation = 1;
747 double counterMultiplier = 1234.567f;
748 const std::string counterName = "some_invalid_counter £££"; // Invalid name
749 const std::string counterDescription = "a_counter_for_testing";
750 const std::string counterUnits = "Mrads2";
751 const CounterPtr counter = std::make_unique<Counter>(counterUid,
754 counterInterpolation,
761 BOOST_ASSERT(counter);
763 // Create an event record
764 SendCounterPacket::EventRecord eventRecord;
765 std::string errorMessage;
766 bool result = sendCounterPacketTest.CreateEventRecordTest(counter, eventRecord, errorMessage);
768 BOOST_CHECK(!result);
769 BOOST_CHECK(!errorMessage.empty());
770 BOOST_CHECK(eventRecord.empty());
773 BOOST_AUTO_TEST_CASE(CreateInvalidEventRecordTest2)
775 ProfilingStateMachine profilingStateMachine;
777 MockBufferManager mockBuffer(0);
778 SendCounterPacketTest sendCounterPacketTest(profilingStateMachine, mockBuffer);
780 // Create a counter for testing
781 uint16_t counterUid = 7256;
782 uint16_t maxCounterUid = 132;
783 uint16_t deviceUid = 132;
784 uint16_t counterSetUid = 4497;
785 uint16_t counterClass = 1;
786 uint16_t counterInterpolation = 1;
787 double counterMultiplier = 1234.567f;
788 const std::string counterName = "some_invalid_counter";
789 const std::string counterDescription = "an invalid d€scription"; // Invalid description
790 const std::string counterUnits = "Mrads2";
791 const CounterPtr counter = std::make_unique<Counter>(counterUid,
794 counterInterpolation,
801 BOOST_ASSERT(counter);
803 // Create an event record
804 SendCounterPacket::EventRecord eventRecord;
805 std::string errorMessage;
806 bool result = sendCounterPacketTest.CreateEventRecordTest(counter, eventRecord, errorMessage);
808 BOOST_CHECK(!result);
809 BOOST_CHECK(!errorMessage.empty());
810 BOOST_CHECK(eventRecord.empty());
813 BOOST_AUTO_TEST_CASE(CreateInvalidEventRecordTest3)
815 ProfilingStateMachine profilingStateMachine;
817 MockBufferManager mockBuffer(0);
818 SendCounterPacketTest sendCounterPacketTest(profilingStateMachine, mockBuffer);
820 // Create a counter for testing
821 uint16_t counterUid = 7256;
822 uint16_t maxCounterUid = 132;
823 uint16_t deviceUid = 132;
824 uint16_t counterSetUid = 4497;
825 uint16_t counterClass = 1;
826 uint16_t counterInterpolation = 1;
827 double counterMultiplier = 1234.567f;
828 const std::string counterName = "some_invalid_counter";
829 const std::string counterDescription = "a valid description";
830 const std::string counterUnits = "Mrad s2"; // Invalid units
831 const CounterPtr counter = std::make_unique<Counter>(counterUid,
834 counterInterpolation,
841 BOOST_ASSERT(counter);
843 // Create an event record
844 SendCounterPacket::EventRecord eventRecord;
845 std::string errorMessage;
846 bool result = sendCounterPacketTest.CreateEventRecordTest(counter, eventRecord, errorMessage);
848 BOOST_CHECK(!result);
849 BOOST_CHECK(!errorMessage.empty());
850 BOOST_CHECK(eventRecord.empty());
853 BOOST_AUTO_TEST_CASE(CreateCategoryRecordTest)
855 ProfilingStateMachine profilingStateMachine;
857 MockBufferManager mockBuffer(0);
858 SendCounterPacketTest sendCounterPacketTest(profilingStateMachine, mockBuffer);
860 // Create a category for testing
861 const std::string categoryName = "some_category";
862 uint16_t deviceUid = 1302;
863 uint16_t counterSetUid = 20734;
864 const CategoryPtr category = std::make_unique<Category>(categoryName, deviceUid, counterSetUid);
865 BOOST_ASSERT(category);
866 category->m_Counters = { 11u, 23u, 5670u };
868 // Create a collection of counters
870 counters.insert(std::make_pair<uint16_t, CounterPtr>(11,
871 CounterPtr(new Counter(11,
881 counters.insert(std::make_pair<uint16_t, CounterPtr>(23,
882 CounterPtr(new Counter(23,
888 "the second counter",
892 counters.insert(std::make_pair<uint16_t, CounterPtr>(5670,
893 CounterPtr(new Counter(5670,
898 "and this is number 3",
903 Counter* counter1 = counters.find(11)->second.get();
904 Counter* counter2 = counters.find(23)->second.get();
905 Counter* counter3 = counters.find(5670)->second.get();
906 BOOST_ASSERT(counter1);
907 BOOST_ASSERT(counter2);
908 BOOST_ASSERT(counter3);
909 uint16_t categoryEventCount = boost::numeric_cast<uint16_t>(counters.size());
911 // Create a category record
912 SendCounterPacket::CategoryRecord categoryRecord;
913 std::string errorMessage;
914 bool result = sendCounterPacketTest.CreateCategoryRecordTest(category, counters, categoryRecord, errorMessage);
917 BOOST_CHECK(errorMessage.empty());
918 BOOST_CHECK(categoryRecord.size() == 80); // Size in words: header [4] + event pointer table [3] +
919 // category name [5] + event records [68 = 22 + 20 + 26]
921 uint16_t categoryRecordWord0[]
923 static_cast<uint16_t>(categoryRecord[0] >> 16),
924 static_cast<uint16_t>(categoryRecord[0])
926 uint16_t categoryRecordWord1[]
928 static_cast<uint16_t>(categoryRecord[1] >> 16),
929 static_cast<uint16_t>(categoryRecord[1])
931 BOOST_CHECK(categoryRecordWord0[0] == deviceUid); // device
932 BOOST_CHECK(categoryRecordWord0[1] == counterSetUid); // counter_set
933 BOOST_CHECK(categoryRecordWord1[0] == categoryEventCount); // event_count
934 BOOST_CHECK(categoryRecordWord1[1] == 0); // reserved
936 size_t uint32_t_size = sizeof(uint32_t);
938 ARMNN_NO_CONVERSION_WARN_BEGIN
939 uint32_t eventPointerTableOffset = 0; // The event pointer table is the first item in pool
940 uint32_t categoryNameOffset = eventPointerTableOffset + // Event pointer table offset
941 categoryEventCount * uint32_t_size; // The size of the event pointer table
942 ARMNN_NO_CONVERSION_WARN_END
944 BOOST_CHECK(categoryRecord[2] == eventPointerTableOffset); // event_pointer_table_offset
945 BOOST_CHECK(categoryRecord[3] == categoryNameOffset); // name_offset
947 auto categoryRecordPool = reinterpret_cast<unsigned char*>(categoryRecord.data() + 4u); // The start of the pool
949 // The event pointer table
950 uint32_t eventRecord0Offset = categoryRecordPool[eventPointerTableOffset + 0 * uint32_t_size];
951 uint32_t eventRecord1Offset = categoryRecordPool[eventPointerTableOffset + 1 * uint32_t_size];
952 uint32_t eventRecord2Offset = categoryRecordPool[eventPointerTableOffset + 2 * uint32_t_size];
953 BOOST_CHECK(eventRecord0Offset == 32);
954 BOOST_CHECK(eventRecord1Offset == 120);
955 BOOST_CHECK(eventRecord2Offset == 200);
957 // The length of the SWTrace namestring (name)
958 BOOST_CHECK(categoryRecordPool[categoryNameOffset] == categoryName.size() + 1);
960 BOOST_CHECK(std::memcmp(categoryRecordPool +
961 categoryNameOffset + // Offset
962 uint32_t_size, // The length of the name
964 categoryName.size()) == 0); // name
965 // The null-terminator at the end of the name
966 BOOST_CHECK(categoryRecordPool[categoryNameOffset + uint32_t_size + categoryName.size()] == '\0');
968 // For brevity, checking only the UIDs, max counter UIDs and names of the counters in the event records,
969 // as the event records already have a number of unit tests dedicated to them
971 // Counter1 UID and max counter UID
972 uint16_t eventRecord0Word0[2] = { 0u, 0u };
973 std::memcpy(eventRecord0Word0, categoryRecordPool + eventRecord0Offset, sizeof(eventRecord0Word0));
974 BOOST_CHECK(eventRecord0Word0[0] == counter1->m_Uid);
975 BOOST_CHECK(eventRecord0Word0[1] == counter1->m_MaxCounterUid);
978 uint32_t counter1NameOffset = 0;
979 std::memcpy(&counter1NameOffset, categoryRecordPool + eventRecord0Offset + 5u * uint32_t_size, uint32_t_size);
980 BOOST_CHECK(counter1NameOffset == 0);
981 // The length of the SWTrace string (name)
982 BOOST_CHECK(categoryRecordPool[eventRecord0Offset + // Offset to the event record
983 8u * uint32_t_size + // Offset to the event record pool
984 counter1NameOffset // Offset to the name of the counter
985 ] == counter1->m_Name.size() + 1); // The length of the name including the
988 BOOST_CHECK(std::memcmp(categoryRecordPool + // The beginning of the category pool
989 eventRecord0Offset + // Offset to the event record
990 8u * uint32_t_size + // Offset to the event record pool
991 counter1NameOffset + // Offset to the name of the counter
992 uint32_t_size, // The length of the name
993 counter1->m_Name.data(),
994 counter1->m_Name.size()) == 0); // name
995 // The null-terminator at the end of the counter1 name
996 BOOST_CHECK(categoryRecordPool[eventRecord0Offset + // Offset to the event record
997 8u * uint32_t_size + // Offset to the event record pool
998 counter1NameOffset + // Offset to the name of the counter
999 uint32_t_size + // The length of the name
1000 counter1->m_Name.size() // The name of the counter
1004 uint32_t counter2NameOffset = 0;
1005 std::memcpy(&counter2NameOffset, categoryRecordPool + eventRecord1Offset + 5u * uint32_t_size, uint32_t_size);
1006 BOOST_CHECK(counter2NameOffset == 0);
1007 // The length of the SWTrace string (name)
1008 BOOST_CHECK(categoryRecordPool[eventRecord1Offset + // Offset to the event record
1009 8u * uint32_t_size + // Offset to the event record pool
1010 counter2NameOffset // Offset to the name of the counter
1011 ] == counter2->m_Name.size() + 1); // The length of the name including the
1013 // The counter2 name
1014 BOOST_CHECK(std::memcmp(categoryRecordPool + // The beginning of the category pool
1015 eventRecord1Offset + // Offset to the event record
1016 8u * uint32_t_size + // Offset to the event record pool
1017 counter2NameOffset + // Offset to the name of the counter
1018 uint32_t_size, // The length of the name
1019 counter2->m_Name.data(),
1020 counter2->m_Name.size()) == 0); // name
1021 // The null-terminator at the end of the counter2 name
1022 BOOST_CHECK(categoryRecordPool[eventRecord1Offset + // Offset to the event record
1023 8u * uint32_t_size + // Offset to the event record pool
1024 counter2NameOffset + // Offset to the name of the counter
1025 uint32_t_size + // The length of the name
1026 counter2->m_Name.size() // The name of the counter
1030 uint32_t counter3NameOffset = 0;
1031 std::memcpy(&counter3NameOffset, categoryRecordPool + eventRecord2Offset + 5u * uint32_t_size, uint32_t_size);
1032 BOOST_CHECK(counter3NameOffset == 0);
1033 // The length of the SWTrace string (name)
1034 BOOST_CHECK(categoryRecordPool[eventRecord2Offset + // Offset to the event record
1035 8u * uint32_t_size + // Offset to the event record pool
1036 counter3NameOffset // Offset to the name of the counter
1037 ] == counter3->m_Name.size() + 1); // The length of the name including the
1039 // The counter3 name
1040 BOOST_CHECK(std::memcmp(categoryRecordPool + // The beginning of the category pool
1041 eventRecord2Offset + // Offset to the event record
1042 8u * uint32_t_size + // Offset to the event record pool
1043 counter3NameOffset + // Offset to the name of the counter
1044 uint32_t_size, // The length of the name
1045 counter3->m_Name.data(),
1046 counter3->m_Name.size()) == 0); // name
1047 // The null-terminator at the end of the counter3 name
1048 BOOST_CHECK(categoryRecordPool[eventRecord2Offset + // Offset to the event record
1049 8u * uint32_t_size + // Offset to the event record pool
1050 counter3NameOffset + // Offset to the name of the counter
1051 uint32_t_size + // The length of the name
1052 counter3->m_Name.size() // The name of the counter
1056 BOOST_AUTO_TEST_CASE(CreateInvalidCategoryRecordTest1)
1058 ProfilingStateMachine profilingStateMachine;
1060 MockBufferManager mockBuffer(0);
1061 SendCounterPacketTest sendCounterPacketTest(profilingStateMachine, mockBuffer);
1063 // Create a category for testing
1064 const std::string categoryName = "some invalid category";
1065 uint16_t deviceUid = 1302;
1066 uint16_t counterSetUid = 20734;
1067 const CategoryPtr category = std::make_unique<Category>(categoryName, deviceUid, counterSetUid);
1068 BOOST_CHECK(category);
1070 // Create a category record
1072 SendCounterPacket::CategoryRecord categoryRecord;
1073 std::string errorMessage;
1074 bool result = sendCounterPacketTest.CreateCategoryRecordTest(category, counters, categoryRecord, errorMessage);
1076 BOOST_CHECK(!result);
1077 BOOST_CHECK(!errorMessage.empty());
1078 BOOST_CHECK(categoryRecord.empty());
1081 BOOST_AUTO_TEST_CASE(CreateInvalidCategoryRecordTest2)
1083 ProfilingStateMachine profilingStateMachine;
1085 MockBufferManager mockBuffer(0);
1086 SendCounterPacketTest sendCounterPacketTest(profilingStateMachine, mockBuffer);
1088 // Create a category for testing
1089 const std::string categoryName = "some_category";
1090 uint16_t deviceUid = 1302;
1091 uint16_t counterSetUid = 20734;
1092 const CategoryPtr category = std::make_unique<Category>(categoryName, deviceUid, counterSetUid);
1093 BOOST_CHECK(category);
1094 category->m_Counters = { 11u, 23u, 5670u };
1096 // Create a collection of counters
1098 counters.insert(std::make_pair<uint16_t, CounterPtr>(11,
1099 CounterPtr(new Counter(11,
1104 "count€r1", // Invalid name
1105 "the first counter",
1110 Counter* counter1 = counters.find(11)->second.get();
1111 BOOST_CHECK(counter1);
1113 // Create a category record
1114 SendCounterPacket::CategoryRecord categoryRecord;
1115 std::string errorMessage;
1116 bool result = sendCounterPacketTest.CreateCategoryRecordTest(category, counters, categoryRecord, errorMessage);
1118 BOOST_CHECK(!result);
1119 BOOST_CHECK(!errorMessage.empty());
1120 BOOST_CHECK(categoryRecord.empty());
1123 BOOST_AUTO_TEST_CASE(SendCounterDirectoryPacketTest1)
1125 ProfilingStateMachine profilingStateMachine;
1127 // The counter directory used for testing
1128 CounterDirectory counterDirectory;
1130 // Register a device
1131 const std::string device1Name = "device1";
1132 const Device* device1 = nullptr;
1133 BOOST_CHECK_NO_THROW(device1 = counterDirectory.RegisterDevice(device1Name, 3));
1134 BOOST_CHECK(counterDirectory.GetDeviceCount() == 1);
1135 BOOST_CHECK(device1);
1137 // Register a device
1138 const std::string device2Name = "device2";
1139 const Device* device2 = nullptr;
1140 BOOST_CHECK_NO_THROW(device2 = counterDirectory.RegisterDevice(device2Name));
1141 BOOST_CHECK(counterDirectory.GetDeviceCount() == 2);
1142 BOOST_CHECK(device2);
1144 // Buffer with not enough space
1145 MockBufferManager mockBuffer(10);
1146 SendCounterPacket sendCounterPacket(profilingStateMachine, mockBuffer);
1147 BOOST_CHECK_THROW(sendCounterPacket.SendCounterDirectoryPacket(counterDirectory),
1148 armnn::profiling::BufferExhaustion);
1151 BOOST_AUTO_TEST_CASE(SendCounterDirectoryPacketTest2)
1153 ProfilingStateMachine profilingStateMachine;
1155 // The counter directory used for testing
1156 CounterDirectory counterDirectory;
1158 // Register a device
1159 const std::string device1Name = "device1";
1160 const Device* device1 = nullptr;
1161 BOOST_CHECK_NO_THROW(device1 = counterDirectory.RegisterDevice(device1Name, 3));
1162 BOOST_CHECK(counterDirectory.GetDeviceCount() == 1);
1163 BOOST_CHECK(device1);
1165 // Register a device
1166 const std::string device2Name = "device2";
1167 const Device* device2 = nullptr;
1168 BOOST_CHECK_NO_THROW(device2 = counterDirectory.RegisterDevice(device2Name));
1169 BOOST_CHECK(counterDirectory.GetDeviceCount() == 2);
1170 BOOST_CHECK(device2);
1172 // Register a counter set
1173 const std::string counterSet1Name = "counterset1";
1174 const CounterSet* counterSet1 = nullptr;
1175 BOOST_CHECK_NO_THROW(counterSet1 = counterDirectory.RegisterCounterSet(counterSet1Name));
1176 BOOST_CHECK(counterDirectory.GetCounterSetCount() == 1);
1177 BOOST_CHECK(counterSet1);
1179 // Register a category associated to "device1" and "counterset1"
1180 const std::string category1Name = "category1";
1181 const Category* category1 = nullptr;
1182 BOOST_CHECK_NO_THROW(category1 = counterDirectory.RegisterCategory(category1Name,
1184 counterSet1->m_Uid));
1185 BOOST_CHECK(counterDirectory.GetCategoryCount() == 1);
1186 BOOST_CHECK(category1);
1188 // Register a category not associated to "device2" but no counter set
1189 const std::string category2Name = "category2";
1190 const Category* category2 = nullptr;
1191 BOOST_CHECK_NO_THROW(category2 = counterDirectory.RegisterCategory(category2Name,
1193 BOOST_CHECK(counterDirectory.GetCategoryCount() == 2);
1194 BOOST_CHECK(category2);
1196 // Register a counter associated to "category1"
1197 const Counter* counter1 = nullptr;
1198 BOOST_CHECK_NO_THROW(counter1 = counterDirectory.RegisterCounter(category1Name,
1203 "counter1description",
1204 std::string("counter1units")));
1205 BOOST_CHECK(counterDirectory.GetCounterCount() == 3);
1206 BOOST_CHECK(counter1);
1208 // Register a counter associated to "category1"
1209 const Counter* counter2 = nullptr;
1210 BOOST_CHECK_NO_THROW(counter2 = counterDirectory.RegisterCounter(category1Name,
1215 "counter2description",
1216 std::string("counter2units"),
1217 armnn::EmptyOptional(),
1220 BOOST_CHECK(counterDirectory.GetCounterCount() == 4);
1221 BOOST_CHECK(counter2);
1223 // Register a counter associated to "category2"
1224 const Counter* counter3 = nullptr;
1225 BOOST_CHECK_NO_THROW(counter3 = counterDirectory.RegisterCounter(category2Name,
1230 "counter3description",
1231 armnn::EmptyOptional(),
1234 counterSet1->m_Uid));
1235 BOOST_CHECK(counterDirectory.GetCounterCount() == 9);
1236 BOOST_CHECK(counter3);
1238 // Buffer with enough space
1239 MockBufferManager mockBuffer(1024);
1240 SendCounterPacket sendCounterPacket(profilingStateMachine, mockBuffer);
1241 BOOST_CHECK_NO_THROW(sendCounterPacket.SendCounterDirectoryPacket(counterDirectory));
1243 // Get the readable buffer
1244 auto readBuffer = mockBuffer.GetReadableBuffer();
1246 // Check the packet header
1247 uint32_t packetHeaderWord0 = ReadUint32(readBuffer, 0);
1248 uint32_t packetHeaderWord1 = ReadUint32(readBuffer, 4);
1249 BOOST_TEST(((packetHeaderWord0 >> 26) & 0x3F) == 0); // packet_family
1250 BOOST_TEST(((packetHeaderWord0 >> 16) & 0x3FF) == 2); // packet_id
1251 BOOST_TEST(packetHeaderWord1 == 936); // data_length
1253 // Check the body header
1254 uint32_t bodyHeaderWord0 = ReadUint32(readBuffer, 8);
1255 uint32_t bodyHeaderWord1 = ReadUint32(readBuffer, 12);
1256 uint32_t bodyHeaderWord2 = ReadUint32(readBuffer, 16);
1257 uint32_t bodyHeaderWord3 = ReadUint32(readBuffer, 20);
1258 uint32_t bodyHeaderWord4 = ReadUint32(readBuffer, 24);
1259 uint32_t bodyHeaderWord5 = ReadUint32(readBuffer, 28);
1260 uint16_t deviceRecordCount = static_cast<uint16_t>(bodyHeaderWord0 >> 16);
1261 uint16_t counterSetRecordCount = static_cast<uint16_t>(bodyHeaderWord2 >> 16);
1262 uint16_t categoryRecordCount = static_cast<uint16_t>(bodyHeaderWord4 >> 16);
1263 BOOST_TEST(deviceRecordCount == 2); // device_records_count
1264 BOOST_TEST(bodyHeaderWord1 == 0); // device_records_pointer_table_offset
1265 BOOST_TEST(counterSetRecordCount == 1); // counter_set_count
1266 BOOST_TEST(bodyHeaderWord3 == 8); // counter_set_pointer_table_offset
1267 BOOST_TEST(categoryRecordCount == 2); // categories_count
1268 BOOST_TEST(bodyHeaderWord5 == 12); // categories_pointer_table_offset
1270 // Check the device records pointer table
1271 uint32_t deviceRecordOffset0 = ReadUint32(readBuffer, 32);
1272 uint32_t deviceRecordOffset1 = ReadUint32(readBuffer, 36);
1273 BOOST_TEST(deviceRecordOffset0 == 0); // Device record offset for "device1"
1274 BOOST_TEST(deviceRecordOffset1 == 20); // Device record offset for "device2"
1276 // Check the counter set pointer table
1277 uint32_t counterSetRecordOffset0 = ReadUint32(readBuffer, 40);
1278 BOOST_TEST(counterSetRecordOffset0 == 40); // Counter set record offset for "counterset1"
1280 // Check the category pointer table
1281 uint32_t categoryRecordOffset0 = ReadUint32(readBuffer, 44);
1282 uint32_t categoryRecordOffset1 = ReadUint32(readBuffer, 48);
1283 BOOST_TEST(categoryRecordOffset0 == 64); // Category record offset for "category1"
1284 BOOST_TEST(categoryRecordOffset1 == 476); // Category record offset for "category2"
1286 // Get the device record pool offset
1287 uint32_t uint32_t_size = sizeof(uint32_t);
1288 uint32_t packetBodyPoolOffset = 2u * uint32_t_size + // packet_header
1289 6u * uint32_t_size + // body_header
1290 deviceRecordCount * uint32_t_size + // Size of device_records_pointer_table
1291 counterSetRecordCount * uint32_t_size + // Size of counter_set_pointer_table
1292 categoryRecordCount * uint32_t_size; // Size of categories_pointer_table
1294 // Device record structure/collection used for testing
1299 uint32_t name_offset;
1300 uint32_t name_length;
1303 std::vector<DeviceRecord> deviceRecords;
1304 uint32_t deviceRecordsPointerTableOffset = 2u * uint32_t_size + // packet_header
1305 6u * uint32_t_size + // body_header
1306 bodyHeaderWord1; // device_records_pointer_table_offset
1308 const unsigned char* readData = readBuffer->GetReadableData();
1310 for (uint32_t i = 0; i < deviceRecordCount; i++)
1312 // Get the device record offset
1313 uint32_t deviceRecordOffset = ReadUint32(readBuffer, deviceRecordsPointerTableOffset + i * uint32_t_size);
1315 // Collect the data for the device record
1316 uint32_t deviceRecordWord0 = ReadUint32(readBuffer,
1317 packetBodyPoolOffset + deviceRecordOffset + 0 * uint32_t_size);
1318 uint32_t deviceRecordWord1 = ReadUint32(readBuffer,
1319 packetBodyPoolOffset + deviceRecordOffset + 1 * uint32_t_size);
1320 DeviceRecord deviceRecord;
1321 deviceRecord.uid = static_cast<uint16_t>(deviceRecordWord0 >> 16); // uid
1322 deviceRecord.cores = static_cast<uint16_t>(deviceRecordWord0); // cores
1323 deviceRecord.name_offset = deviceRecordWord1; // name_offset
1325 uint32_t deviceRecordPoolOffset = packetBodyPoolOffset + // Packet body offset
1326 deviceRecordOffset + // Device record offset
1327 2 * uint32_t_size + // Device record header
1328 deviceRecord.name_offset; // Device name offset
1329 uint32_t deviceRecordNameLength = ReadUint32(readBuffer, deviceRecordPoolOffset);
1330 deviceRecord.name_length = deviceRecordNameLength; // name_length
1331 unsigned char deviceRecordNameNullTerminator = // name null-terminator
1332 ReadUint8(readBuffer, deviceRecordPoolOffset + uint32_t_size + deviceRecordNameLength - 1);
1333 BOOST_CHECK(deviceRecordNameNullTerminator == '\0');
1334 std::vector<unsigned char> deviceRecordNameBuffer(deviceRecord.name_length - 1);
1335 std::memcpy(deviceRecordNameBuffer.data(),
1336 readData + deviceRecordPoolOffset + uint32_t_size, deviceRecordNameBuffer.size());
1337 deviceRecord.name.assign(deviceRecordNameBuffer.begin(), deviceRecordNameBuffer.end()); // name
1339 deviceRecords.push_back(deviceRecord);
1342 // Check that the device records are correct
1343 BOOST_CHECK(deviceRecords.size() == 2);
1344 for (const DeviceRecord& deviceRecord : deviceRecords)
1346 const Device* device = counterDirectory.GetDevice(deviceRecord.uid);
1347 BOOST_CHECK(device);
1348 BOOST_CHECK(device->m_Uid == deviceRecord.uid);
1349 BOOST_CHECK(device->m_Cores == deviceRecord.cores);
1350 BOOST_CHECK(device->m_Name == deviceRecord.name);
1353 // Counter set record structure/collection used for testing
1354 struct CounterSetRecord
1358 uint32_t name_offset;
1359 uint32_t name_length;
1362 std::vector<CounterSetRecord> counterSetRecords;
1363 uint32_t counterSetRecordsPointerTableOffset = 2u * uint32_t_size + // packet_header
1364 6u * uint32_t_size + // body_header
1365 bodyHeaderWord3; // counter_set_pointer_table_offset
1366 for (uint32_t i = 0; i < counterSetRecordCount; i++)
1368 // Get the counter set record offset
1369 uint32_t counterSetRecordOffset = ReadUint32(readBuffer,
1370 counterSetRecordsPointerTableOffset + i * uint32_t_size);
1372 // Collect the data for the counter set record
1373 uint32_t counterSetRecordWord0 = ReadUint32(readBuffer,
1374 packetBodyPoolOffset + counterSetRecordOffset + 0 * uint32_t_size);
1375 uint32_t counterSetRecordWord1 = ReadUint32(readBuffer,
1376 packetBodyPoolOffset + counterSetRecordOffset + 1 * uint32_t_size);
1377 CounterSetRecord counterSetRecord;
1378 counterSetRecord.uid = static_cast<uint16_t>(counterSetRecordWord0 >> 16); // uid
1379 counterSetRecord.count = static_cast<uint16_t>(counterSetRecordWord0); // count
1380 counterSetRecord.name_offset = counterSetRecordWord1; // name_offset
1382 uint32_t counterSetRecordPoolOffset = packetBodyPoolOffset + // Packet body offset
1383 counterSetRecordOffset + // Counter set record offset
1384 2 * uint32_t_size + // Counter set record header
1385 counterSetRecord.name_offset; // Counter set name offset
1386 uint32_t counterSetRecordNameLength = ReadUint32(readBuffer, counterSetRecordPoolOffset);
1387 counterSetRecord.name_length = counterSetRecordNameLength; // name_length
1388 unsigned char counterSetRecordNameNullTerminator = // name null-terminator
1389 ReadUint8(readBuffer, counterSetRecordPoolOffset + uint32_t_size + counterSetRecordNameLength - 1);
1390 BOOST_CHECK(counterSetRecordNameNullTerminator == '\0');
1391 std::vector<unsigned char> counterSetRecordNameBuffer(counterSetRecord.name_length - 1);
1392 std::memcpy(counterSetRecordNameBuffer.data(),
1393 readData + counterSetRecordPoolOffset + uint32_t_size, counterSetRecordNameBuffer.size());
1394 counterSetRecord.name.assign(counterSetRecordNameBuffer.begin(), counterSetRecordNameBuffer.end()); // name
1396 counterSetRecords.push_back(counterSetRecord);
1399 // Check that the counter set records are correct
1400 BOOST_CHECK(counterSetRecords.size() == 1);
1401 for (const CounterSetRecord& counterSetRecord : counterSetRecords)
1403 const CounterSet* counterSet = counterDirectory.GetCounterSet(counterSetRecord.uid);
1404 BOOST_CHECK(counterSet);
1405 BOOST_CHECK(counterSet->m_Uid == counterSetRecord.uid);
1406 BOOST_CHECK(counterSet->m_Count == counterSetRecord.count);
1407 BOOST_CHECK(counterSet->m_Name == counterSetRecord.name);
1410 // Event record structure/collection used for testing
1413 uint16_t counter_uid;
1414 uint16_t max_counter_uid;
1416 uint16_t counter_set;
1417 uint16_t counter_class;
1418 uint16_t interpolation;
1420 uint32_t name_offset;
1421 uint32_t name_length;
1423 uint32_t description_offset;
1424 uint32_t description_length;
1425 std::string description;
1426 uint32_t units_offset;
1427 uint32_t units_length;
1430 // Category record structure/collection used for testing
1431 struct CategoryRecord
1434 uint16_t counter_set;
1435 uint16_t event_count;
1436 uint32_t event_pointer_table_offset;
1437 uint32_t name_offset;
1438 uint32_t name_length;
1440 std::vector<uint32_t> event_pointer_table;
1441 std::vector<EventRecord> event_records;
1443 std::vector<CategoryRecord> categoryRecords;
1444 uint32_t categoryRecordsPointerTableOffset = 2u * uint32_t_size + // packet_header
1445 6u * uint32_t_size + // body_header
1446 bodyHeaderWord5; // categories_pointer_table_offset
1447 for (uint32_t i = 0; i < categoryRecordCount; i++)
1449 // Get the category record offset
1450 uint32_t categoryRecordOffset = ReadUint32(readBuffer, categoryRecordsPointerTableOffset + i * uint32_t_size);
1452 // Collect the data for the category record
1453 uint32_t categoryRecordWord0 = ReadUint32(readBuffer,
1454 packetBodyPoolOffset + categoryRecordOffset + 0 * uint32_t_size);
1455 uint32_t categoryRecordWord1 = ReadUint32(readBuffer,
1456 packetBodyPoolOffset + categoryRecordOffset + 1 * uint32_t_size);
1457 uint32_t categoryRecordWord2 = ReadUint32(readBuffer,
1458 packetBodyPoolOffset + categoryRecordOffset + 2 * uint32_t_size);
1459 uint32_t categoryRecordWord3 = ReadUint32(readBuffer,
1460 packetBodyPoolOffset + categoryRecordOffset + 3 * uint32_t_size);
1461 CategoryRecord categoryRecord;
1462 categoryRecord.device = static_cast<uint16_t>(categoryRecordWord0 >> 16); // device
1463 categoryRecord.counter_set = static_cast<uint16_t>(categoryRecordWord0); // counter_set
1464 categoryRecord.event_count = static_cast<uint16_t>(categoryRecordWord1 >> 16); // event_count
1465 categoryRecord.event_pointer_table_offset = categoryRecordWord2; // event_pointer_table_offset
1466 categoryRecord.name_offset = categoryRecordWord3; // name_offset
1468 uint32_t categoryRecordPoolOffset = packetBodyPoolOffset + // Packet body offset
1469 categoryRecordOffset + // Category record offset
1470 4 * uint32_t_size; // Category record header
1472 uint32_t categoryRecordNameLength = ReadUint32(readBuffer,
1473 categoryRecordPoolOffset + categoryRecord.name_offset);
1474 categoryRecord.name_length = categoryRecordNameLength; // name_length
1475 unsigned char categoryRecordNameNullTerminator =
1476 ReadUint8(readBuffer,
1477 categoryRecordPoolOffset +
1478 categoryRecord.name_offset +
1480 categoryRecordNameLength - 1); // name null-terminator
1481 BOOST_CHECK(categoryRecordNameNullTerminator == '\0');
1482 std::vector<unsigned char> categoryRecordNameBuffer(categoryRecord.name_length - 1);
1483 std::memcpy(categoryRecordNameBuffer.data(),
1485 categoryRecordPoolOffset +
1486 categoryRecord.name_offset +
1488 categoryRecordNameBuffer.size());
1489 categoryRecord.name.assign(categoryRecordNameBuffer.begin(), categoryRecordNameBuffer.end()); // name
1491 categoryRecord.event_pointer_table.resize(categoryRecord.event_count);
1492 for (uint32_t eventIndex = 0; eventIndex < categoryRecord.event_count; eventIndex++)
1494 uint32_t eventRecordOffset = ReadUint32(readBuffer,
1495 categoryRecordPoolOffset +
1496 categoryRecord.event_pointer_table_offset +
1497 eventIndex * uint32_t_size);
1498 categoryRecord.event_pointer_table[eventIndex] = eventRecordOffset;
1500 // Collect the data for the event record
1501 uint32_t eventRecordWord0 = ReadUint32(readBuffer,
1502 categoryRecordPoolOffset + eventRecordOffset + 0 * uint32_t_size);
1503 uint32_t eventRecordWord1 = ReadUint32(readBuffer,
1504 categoryRecordPoolOffset + eventRecordOffset + 1 * uint32_t_size);
1505 uint32_t eventRecordWord2 = ReadUint32(readBuffer,
1506 categoryRecordPoolOffset + eventRecordOffset + 2 * uint32_t_size);
1507 uint64_t eventRecordWord34 = ReadUint64(readBuffer,
1508 categoryRecordPoolOffset + eventRecordOffset + 3 * uint32_t_size);
1509 uint32_t eventRecordWord5 = ReadUint32(readBuffer,
1510 categoryRecordPoolOffset + eventRecordOffset + 5 * uint32_t_size);
1511 uint32_t eventRecordWord6 = ReadUint32(readBuffer,
1512 categoryRecordPoolOffset + eventRecordOffset + 6 * uint32_t_size);
1513 uint32_t eventRecordWord7 = ReadUint32(readBuffer,
1514 categoryRecordPoolOffset + eventRecordOffset + 7 * uint32_t_size);
1515 EventRecord eventRecord;
1516 eventRecord.counter_uid = static_cast<uint16_t>(eventRecordWord0); // counter_uid
1517 eventRecord.max_counter_uid = static_cast<uint16_t>(eventRecordWord0 >> 16); // max_counter_uid
1518 eventRecord.device = static_cast<uint16_t>(eventRecordWord1 >> 16); // device
1519 eventRecord.counter_set = static_cast<uint16_t>(eventRecordWord1); // counter_set
1520 eventRecord.counter_class = static_cast<uint16_t>(eventRecordWord2 >> 16); // class
1521 eventRecord.interpolation = static_cast<uint16_t>(eventRecordWord2); // interpolation
1522 std::memcpy(&eventRecord.multiplier, &eventRecordWord34, sizeof(eventRecord.multiplier)); // multiplier
1523 eventRecord.name_offset = static_cast<uint32_t>(eventRecordWord5); // name_offset
1524 eventRecord.description_offset = static_cast<uint32_t>(eventRecordWord6); // description_offset
1525 eventRecord.units_offset = static_cast<uint32_t>(eventRecordWord7); // units_offset
1527 uint32_t eventRecordPoolOffset = categoryRecordPoolOffset + // Category record pool offset
1528 eventRecordOffset + // Event record offset
1529 8 * uint32_t_size; // Event record header
1531 uint32_t eventRecordNameLength = ReadUint32(readBuffer,
1532 eventRecordPoolOffset + eventRecord.name_offset);
1533 eventRecord.name_length = eventRecordNameLength; // name_length
1534 unsigned char eventRecordNameNullTerminator =
1535 ReadUint8(readBuffer,
1536 eventRecordPoolOffset +
1537 eventRecord.name_offset +
1539 eventRecordNameLength - 1); // name null-terminator
1540 BOOST_CHECK(eventRecordNameNullTerminator == '\0');
1541 std::vector<unsigned char> eventRecordNameBuffer(eventRecord.name_length - 1);
1542 std::memcpy(eventRecordNameBuffer.data(),
1544 eventRecordPoolOffset +
1545 eventRecord.name_offset +
1547 eventRecordNameBuffer.size());
1548 eventRecord.name.assign(eventRecordNameBuffer.begin(), eventRecordNameBuffer.end()); // name
1550 uint32_t eventRecordDescriptionLength = ReadUint32(readBuffer,
1551 eventRecordPoolOffset + eventRecord.description_offset);
1552 eventRecord.description_length = eventRecordDescriptionLength; // description_length
1553 unsigned char eventRecordDescriptionNullTerminator =
1554 ReadUint8(readBuffer,
1555 eventRecordPoolOffset +
1556 eventRecord.description_offset +
1558 eventRecordDescriptionLength - 1); // description null-terminator
1559 BOOST_CHECK(eventRecordDescriptionNullTerminator == '\0');
1560 std::vector<unsigned char> eventRecordDescriptionBuffer(eventRecord.description_length - 1);
1561 std::memcpy(eventRecordDescriptionBuffer.data(),
1563 eventRecordPoolOffset +
1564 eventRecord.description_offset +
1566 eventRecordDescriptionBuffer.size());
1567 eventRecord.description.assign(eventRecordDescriptionBuffer.begin(),
1568 eventRecordDescriptionBuffer.end()); // description
1570 if (eventRecord.units_offset > 0)
1572 uint32_t eventRecordUnitsLength = ReadUint32(readBuffer,
1573 eventRecordPoolOffset + eventRecord.units_offset);
1574 eventRecord.units_length = eventRecordUnitsLength; // units_length
1575 unsigned char eventRecordUnitsNullTerminator =
1576 ReadUint8(readBuffer,
1577 eventRecordPoolOffset +
1578 eventRecord.units_offset +
1580 eventRecordUnitsLength - 1); // units null-terminator
1581 BOOST_CHECK(eventRecordUnitsNullTerminator == '\0');
1582 std::vector<unsigned char> eventRecordUnitsBuffer(eventRecord.units_length - 1);
1583 std::memcpy(eventRecordUnitsBuffer.data(),
1585 eventRecordPoolOffset +
1586 eventRecord.units_offset +
1588 eventRecordUnitsBuffer.size());
1589 eventRecord.units.assign(eventRecordUnitsBuffer.begin(), eventRecordUnitsBuffer.end()); // units
1592 categoryRecord.event_records.push_back(eventRecord);
1595 categoryRecords.push_back(categoryRecord);
1598 // Check that the category records are correct
1599 BOOST_CHECK(categoryRecords.size() == 2);
1600 for (const CategoryRecord& categoryRecord : categoryRecords)
1602 const Category* category = counterDirectory.GetCategory(categoryRecord.name);
1603 BOOST_CHECK(category);
1604 BOOST_CHECK(category->m_Name == categoryRecord.name);
1605 BOOST_CHECK(category->m_DeviceUid == categoryRecord.device);
1606 BOOST_CHECK(category->m_CounterSetUid == categoryRecord.counter_set);
1607 BOOST_CHECK(category->m_Counters.size() == categoryRecord.event_count);
1609 // Check that the event records are correct
1610 for (const EventRecord& eventRecord : categoryRecord.event_records)
1612 const Counter* counter = counterDirectory.GetCounter(eventRecord.counter_uid);
1613 BOOST_CHECK(counter);
1614 BOOST_CHECK(counter->m_MaxCounterUid == eventRecord.max_counter_uid);
1615 BOOST_CHECK(counter->m_DeviceUid == eventRecord.device);
1616 BOOST_CHECK(counter->m_CounterSetUid == eventRecord.counter_set);
1617 BOOST_CHECK(counter->m_Class == eventRecord.counter_class);
1618 BOOST_CHECK(counter->m_Interpolation == eventRecord.interpolation);
1619 BOOST_CHECK(counter->m_Multiplier == eventRecord.multiplier);
1620 BOOST_CHECK(counter->m_Name == eventRecord.name);
1621 BOOST_CHECK(counter->m_Description == eventRecord.description);
1622 BOOST_CHECK(counter->m_Units == eventRecord.units);
1627 BOOST_AUTO_TEST_CASE(SendCounterDirectoryPacketTest3)
1629 ProfilingStateMachine profilingStateMachine;
1631 // Using a mock counter directory that allows to register invalid objects
1632 MockCounterDirectory counterDirectory;
1634 // Register an invalid device
1635 const std::string deviceName = "inv@lid dev!c€";
1636 const Device* device = nullptr;
1637 BOOST_CHECK_NO_THROW(device = counterDirectory.RegisterDevice(deviceName, 3));
1638 BOOST_CHECK(counterDirectory.GetDeviceCount() == 1);
1639 BOOST_CHECK(device);
1641 // Buffer with enough space
1642 MockBufferManager mockBuffer(1024);
1643 SendCounterPacket sendCounterPacket(profilingStateMachine, mockBuffer);
1644 BOOST_CHECK_THROW(sendCounterPacket.SendCounterDirectoryPacket(counterDirectory), armnn::RuntimeException);
1647 BOOST_AUTO_TEST_CASE(SendCounterDirectoryPacketTest4)
1649 ProfilingStateMachine profilingStateMachine;
1651 // Using a mock counter directory that allows to register invalid objects
1652 MockCounterDirectory counterDirectory;
1654 // Register an invalid counter set
1655 const std::string counterSetName = "inv@lid count€rs€t";
1656 const CounterSet* counterSet = nullptr;
1657 BOOST_CHECK_NO_THROW(counterSet = counterDirectory.RegisterCounterSet(counterSetName));
1658 BOOST_CHECK(counterDirectory.GetCounterSetCount() == 1);
1659 BOOST_CHECK(counterSet);
1661 // Buffer with enough space
1662 MockBufferManager mockBuffer(1024);
1663 SendCounterPacket sendCounterPacket(profilingStateMachine, mockBuffer);
1664 BOOST_CHECK_THROW(sendCounterPacket.SendCounterDirectoryPacket(counterDirectory), armnn::RuntimeException);
1667 BOOST_AUTO_TEST_CASE(SendCounterDirectoryPacketTest5)
1669 ProfilingStateMachine profilingStateMachine;
1671 // Using a mock counter directory that allows to register invalid objects
1672 MockCounterDirectory counterDirectory;
1674 // Register an invalid category
1675 const std::string categoryName = "c@t€gory";
1676 const Category* category = nullptr;
1677 BOOST_CHECK_NO_THROW(category = counterDirectory.RegisterCategory(categoryName));
1678 BOOST_CHECK(counterDirectory.GetCategoryCount() == 1);
1679 BOOST_CHECK(category);
1681 // Buffer with enough space
1682 MockBufferManager mockBuffer(1024);
1683 SendCounterPacket sendCounterPacket(profilingStateMachine, mockBuffer);
1684 BOOST_CHECK_THROW(sendCounterPacket.SendCounterDirectoryPacket(counterDirectory), armnn::RuntimeException);
1687 BOOST_AUTO_TEST_CASE(SendCounterDirectoryPacketTest6)
1689 ProfilingStateMachine profilingStateMachine;
1691 // Using a mock counter directory that allows to register invalid objects
1692 MockCounterDirectory counterDirectory;
1694 // Register an invalid device
1695 const std::string deviceName = "inv@lid dev!c€";
1696 const Device* device = nullptr;
1697 BOOST_CHECK_NO_THROW(device = counterDirectory.RegisterDevice(deviceName, 3));
1698 BOOST_CHECK(counterDirectory.GetDeviceCount() == 1);
1699 BOOST_CHECK(device);
1701 // Register an invalid counter set
1702 const std::string counterSetName = "inv@lid count€rs€t";
1703 const CounterSet* counterSet = nullptr;
1704 BOOST_CHECK_NO_THROW(counterSet = counterDirectory.RegisterCounterSet(counterSetName));
1705 BOOST_CHECK(counterDirectory.GetCounterSetCount() == 1);
1706 BOOST_CHECK(counterSet);
1708 // Register an invalid category associated to an invalid device and an invalid counter set
1709 const std::string categoryName = "c@t€gory";
1710 const Category* category = nullptr;
1711 BOOST_CHECK_NO_THROW(category = counterDirectory.RegisterCategory(categoryName,
1713 counterSet->m_Uid));
1714 BOOST_CHECK(counterDirectory.GetCategoryCount() == 1);
1715 BOOST_CHECK(category);
1717 // Buffer with enough space
1718 MockBufferManager mockBuffer(1024);
1719 SendCounterPacket sendCounterPacket(profilingStateMachine, mockBuffer);
1720 BOOST_CHECK_THROW(sendCounterPacket.SendCounterDirectoryPacket(counterDirectory), armnn::RuntimeException);
1723 BOOST_AUTO_TEST_CASE(SendCounterDirectoryPacketTest7)
1725 ProfilingStateMachine profilingStateMachine;
1727 // Using a mock counter directory that allows to register invalid objects
1728 MockCounterDirectory counterDirectory;
1730 // Register an valid device
1731 const std::string deviceName = "valid device";
1732 const Device* device = nullptr;
1733 BOOST_CHECK_NO_THROW(device = counterDirectory.RegisterDevice(deviceName, 3));
1734 BOOST_CHECK(counterDirectory.GetDeviceCount() == 1);
1735 BOOST_CHECK(device);
1737 // Register an valid counter set
1738 const std::string counterSetName = "valid counterset";
1739 const CounterSet* counterSet = nullptr;
1740 BOOST_CHECK_NO_THROW(counterSet = counterDirectory.RegisterCounterSet(counterSetName));
1741 BOOST_CHECK(counterDirectory.GetCounterSetCount() == 1);
1742 BOOST_CHECK(counterSet);
1744 // Register an valid category associated to a valid device and a valid counter set
1745 const std::string categoryName = "category";
1746 const Category* category = nullptr;
1747 BOOST_CHECK_NO_THROW(category = counterDirectory.RegisterCategory(categoryName,
1749 counterSet->m_Uid));
1750 BOOST_CHECK(counterDirectory.GetCategoryCount() == 1);
1751 BOOST_CHECK(category);
1753 // Register an invalid counter associated to a valid category
1754 const Counter* counter = nullptr;
1755 BOOST_CHECK_NO_THROW(counter = counterDirectory.RegisterCounter(categoryName,
1760 "counter description",
1761 std::string("invalid counter units"),
1764 counterSet->m_Uid));
1765 BOOST_CHECK(counterDirectory.GetCounterCount() == 5);
1766 BOOST_CHECK(counter);
1768 // Buffer with enough space
1769 MockBufferManager mockBuffer(1024);
1770 SendCounterPacket sendCounterPacket(profilingStateMachine, mockBuffer);
1771 BOOST_CHECK_THROW(sendCounterPacket.SendCounterDirectoryPacket(counterDirectory), armnn::RuntimeException);
1774 BOOST_AUTO_TEST_CASE(SendThreadTest0)
1776 ProfilingStateMachine profilingStateMachine;
1777 SetActiveProfilingState(profilingStateMachine);
1779 MockProfilingConnection mockProfilingConnection;
1780 MockStreamCounterBuffer mockStreamCounterBuffer(0);
1781 SendCounterPacket sendCounterPacket(profilingStateMachine, mockStreamCounterBuffer);
1783 // Try to start the send thread many times, it must only start once
1785 sendCounterPacket.Start(mockProfilingConnection);
1786 BOOST_CHECK(sendCounterPacket.IsRunning());
1787 sendCounterPacket.Start(mockProfilingConnection);
1788 sendCounterPacket.Start(mockProfilingConnection);
1789 sendCounterPacket.Start(mockProfilingConnection);
1790 sendCounterPacket.Start(mockProfilingConnection);
1791 BOOST_CHECK(sendCounterPacket.IsRunning());
1793 std::this_thread::sleep_for(std::chrono::seconds(1));
1795 sendCounterPacket.Stop();
1796 BOOST_CHECK(!sendCounterPacket.IsRunning());
1799 BOOST_AUTO_TEST_CASE(SendThreadTest1)
1801 ProfilingStateMachine profilingStateMachine;
1802 SetActiveProfilingState(profilingStateMachine);
1804 unsigned int totalWrittenSize = 0;
1806 MockProfilingConnection mockProfilingConnection;
1807 MockStreamCounterBuffer mockStreamCounterBuffer(1024);
1808 SendCounterPacket sendCounterPacket(profilingStateMachine, mockStreamCounterBuffer);
1809 sendCounterPacket.Start(mockProfilingConnection);
1811 // Interleaving writes and reads to/from the buffer with pauses to test that the send thread actually waits for
1812 // something to become available for reading
1814 std::this_thread::sleep_for(std::chrono::seconds(1));
1816 CounterDirectory counterDirectory;
1817 sendCounterPacket.SendStreamMetaDataPacket();
1819 // Get the size of the Stream Metadata Packet
1820 std::string processName = GetProcessName().substr(0, 60);
1821 unsigned int processNameSize = processName.empty() ? 0 : boost::numeric_cast<unsigned int>(processName.size()) + 1;
1822 unsigned int streamMetadataPacketsize = 118 + processNameSize;
1823 totalWrittenSize += streamMetadataPacketsize;
1825 sendCounterPacket.SetReadyToRead();
1827 std::this_thread::sleep_for(std::chrono::milliseconds(100));
1829 sendCounterPacket.SendCounterDirectoryPacket(counterDirectory);
1831 // Get the size of the Counter Directory Packet
1832 unsigned int counterDirectoryPacketSize = 32;
1833 totalWrittenSize += counterDirectoryPacketSize;
1835 sendCounterPacket.SetReadyToRead();
1837 std::this_thread::sleep_for(std::chrono::milliseconds(100));
1839 sendCounterPacket.SendPeriodicCounterCapturePacket(123u,
1845 // Get the size of the Periodic Counter Capture Packet
1846 unsigned int periodicCounterCapturePacketSize = 28;
1847 totalWrittenSize += periodicCounterCapturePacketSize;
1849 sendCounterPacket.SetReadyToRead();
1851 std::this_thread::sleep_for(std::chrono::milliseconds(100));
1853 sendCounterPacket.SendPeriodicCounterCapturePacket(44u,
1858 // Get the size of the Periodic Counter Capture Packet
1859 periodicCounterCapturePacketSize = 22;
1860 totalWrittenSize += periodicCounterCapturePacketSize;
1862 sendCounterPacket.SendPeriodicCounterCapturePacket(1234u,
1871 // Get the size of the Periodic Counter Capture Packet
1872 periodicCounterCapturePacketSize = 46;
1873 totalWrittenSize += periodicCounterCapturePacketSize;
1875 sendCounterPacket.SendPeriodicCounterCapturePacket(997u,
1883 // Get the size of the Periodic Counter Capture Packet
1884 periodicCounterCapturePacketSize = 40;
1885 totalWrittenSize += periodicCounterCapturePacketSize;
1887 sendCounterPacket.SetReadyToRead();
1889 std::this_thread::sleep_for(std::chrono::milliseconds(100));
1891 sendCounterPacket.SendPeriodicCounterSelectionPacket(1000u, { 1345u, 254u, 4536u, 408u, 54u, 6323u, 428u, 1u, 6u });
1893 // Get the size of the Periodic Counter Capture Packet
1894 periodicCounterCapturePacketSize = 30;
1895 totalWrittenSize += periodicCounterCapturePacketSize;
1897 sendCounterPacket.SetReadyToRead();
1899 // To test an exact value of the "read size" in the mock buffer, wait two seconds to allow the send thread to
1900 // read all what's remaining in the buffer
1901 std::this_thread::sleep_for(std::chrono::seconds(2));
1903 sendCounterPacket.Stop();
1905 BOOST_CHECK(mockStreamCounterBuffer.GetCommittedSize() == totalWrittenSize);
1906 BOOST_CHECK(mockStreamCounterBuffer.GetReadableSize() == totalWrittenSize);
1907 BOOST_CHECK(mockStreamCounterBuffer.GetReadSize() == totalWrittenSize);
1910 BOOST_AUTO_TEST_CASE(SendThreadTest2)
1912 ProfilingStateMachine profilingStateMachine;
1913 SetActiveProfilingState(profilingStateMachine);
1915 unsigned int totalWrittenSize = 0;
1917 MockProfilingConnection mockProfilingConnection;
1918 MockStreamCounterBuffer mockStreamCounterBuffer(1024);
1919 SendCounterPacket sendCounterPacket(profilingStateMachine, mockStreamCounterBuffer);
1920 sendCounterPacket.Start(mockProfilingConnection);
1922 // Adding many spurious "ready to read" signals throughout the test to check that the send thread is
1923 // capable of handling unnecessary read requests
1925 std::this_thread::sleep_for(std::chrono::seconds(1));
1927 sendCounterPacket.SetReadyToRead();
1929 CounterDirectory counterDirectory;
1930 sendCounterPacket.SendStreamMetaDataPacket();
1932 // Get the size of the Stream Metadata Packet
1933 std::string processName = GetProcessName().substr(0, 60);
1934 unsigned int processNameSize = processName.empty() ? 0 : boost::numeric_cast<unsigned int>(processName.size()) + 1;
1935 unsigned int streamMetadataPacketsize = 118 + processNameSize;
1936 totalWrittenSize += streamMetadataPacketsize;
1938 sendCounterPacket.SetReadyToRead();
1940 std::this_thread::sleep_for(std::chrono::milliseconds(100));
1942 sendCounterPacket.SendCounterDirectoryPacket(counterDirectory);
1944 // Get the size of the Counter Directory Packet
1945 unsigned int counterDirectoryPacketSize = 32;
1946 totalWrittenSize += counterDirectoryPacketSize;
1948 sendCounterPacket.SetReadyToRead();
1949 sendCounterPacket.SetReadyToRead();
1951 std::this_thread::sleep_for(std::chrono::milliseconds(100));
1953 sendCounterPacket.SendPeriodicCounterCapturePacket(123u,
1959 // Get the size of the Periodic Counter Capture Packet
1960 unsigned int periodicCounterCapturePacketSize = 28;
1961 totalWrittenSize += periodicCounterCapturePacketSize;
1963 sendCounterPacket.SetReadyToRead();
1965 std::this_thread::sleep_for(std::chrono::milliseconds(100));
1967 sendCounterPacket.SetReadyToRead();
1968 sendCounterPacket.SetReadyToRead();
1969 sendCounterPacket.SetReadyToRead();
1971 std::this_thread::sleep_for(std::chrono::milliseconds(100));
1973 sendCounterPacket.SetReadyToRead();
1974 sendCounterPacket.SendPeriodicCounterCapturePacket(44u,
1979 // Get the size of the Periodic Counter Capture Packet
1980 periodicCounterCapturePacketSize = 22;
1981 totalWrittenSize += periodicCounterCapturePacketSize;
1983 sendCounterPacket.SendPeriodicCounterCapturePacket(1234u,
1992 // Get the size of the Periodic Counter Capture Packet
1993 periodicCounterCapturePacketSize = 46;
1994 totalWrittenSize += periodicCounterCapturePacketSize;
1996 sendCounterPacket.SetReadyToRead();
1997 sendCounterPacket.SendPeriodicCounterCapturePacket(997u,
2005 // Get the size of the Periodic Counter Capture Packet
2006 periodicCounterCapturePacketSize = 40;
2007 totalWrittenSize += periodicCounterCapturePacketSize;
2009 sendCounterPacket.SetReadyToRead();
2010 sendCounterPacket.SetReadyToRead();
2012 std::this_thread::sleep_for(std::chrono::milliseconds(100));
2014 sendCounterPacket.SendPeriodicCounterSelectionPacket(1000u, { 1345u, 254u, 4536u, 408u, 54u, 6323u, 428u, 1u, 6u });
2016 // Get the size of the Periodic Counter Capture Packet
2017 periodicCounterCapturePacketSize = 30;
2018 totalWrittenSize += periodicCounterCapturePacketSize;
2020 sendCounterPacket.SetReadyToRead();
2022 // To test an exact value of the "read size" in the mock buffer, wait two seconds to allow the send thread to
2023 // read all what's remaining in the buffer
2024 std::this_thread::sleep_for(std::chrono::seconds(2));
2026 sendCounterPacket.Stop();
2028 BOOST_CHECK(mockStreamCounterBuffer.GetCommittedSize() == totalWrittenSize);
2029 BOOST_CHECK(mockStreamCounterBuffer.GetReadableSize() == totalWrittenSize);
2030 BOOST_CHECK(mockStreamCounterBuffer.GetReadSize() == totalWrittenSize);
2033 BOOST_AUTO_TEST_CASE(SendThreadTest3)
2035 ProfilingStateMachine profilingStateMachine;
2036 SetActiveProfilingState(profilingStateMachine);
2038 unsigned int totalWrittenSize = 0;
2040 MockProfilingConnection mockProfilingConnection;
2041 MockStreamCounterBuffer mockStreamCounterBuffer(1024);
2042 SendCounterPacket sendCounterPacket(profilingStateMachine, mockStreamCounterBuffer);
2043 sendCounterPacket.Start(mockProfilingConnection);
2045 // Not using pauses or "grace periods" to stress test the send thread
2047 sendCounterPacket.SetReadyToRead();
2049 CounterDirectory counterDirectory;
2050 sendCounterPacket.SendStreamMetaDataPacket();
2052 // Get the size of the Stream Metadata Packet
2053 std::string processName = GetProcessName().substr(0, 60);
2054 unsigned int processNameSize = processName.empty() ? 0 : boost::numeric_cast<unsigned int>(processName.size()) + 1;
2055 unsigned int streamMetadataPacketsize = 118 + processNameSize;
2056 totalWrittenSize += streamMetadataPacketsize;
2058 sendCounterPacket.SetReadyToRead();
2059 sendCounterPacket.SendCounterDirectoryPacket(counterDirectory);
2061 // Get the size of the Counter Directory Packet
2062 unsigned int counterDirectoryPacketSize =32;
2063 totalWrittenSize += counterDirectoryPacketSize;
2065 sendCounterPacket.SetReadyToRead();
2066 sendCounterPacket.SetReadyToRead();
2067 sendCounterPacket.SendPeriodicCounterCapturePacket(123u,
2073 // Get the size of the Periodic Counter Capture Packet
2074 unsigned int periodicCounterCapturePacketSize = 28;
2075 totalWrittenSize += periodicCounterCapturePacketSize;
2077 sendCounterPacket.SetReadyToRead();
2078 sendCounterPacket.SetReadyToRead();
2079 sendCounterPacket.SetReadyToRead();
2080 sendCounterPacket.SetReadyToRead();
2081 sendCounterPacket.SetReadyToRead();
2082 sendCounterPacket.SendPeriodicCounterCapturePacket(44u,
2087 // Get the size of the Periodic Counter Capture Packet
2088 periodicCounterCapturePacketSize = 22;
2089 totalWrittenSize += periodicCounterCapturePacketSize;
2091 sendCounterPacket.SendPeriodicCounterCapturePacket(1234u,
2100 // Get the size of the Periodic Counter Capture Packet
2101 periodicCounterCapturePacketSize = 46;
2102 totalWrittenSize += periodicCounterCapturePacketSize;
2104 sendCounterPacket.SetReadyToRead();
2105 sendCounterPacket.SetReadyToRead();
2106 sendCounterPacket.SendPeriodicCounterCapturePacket(997u,
2114 // Get the size of the Periodic Counter Capture Packet
2115 periodicCounterCapturePacketSize = 40;
2116 totalWrittenSize += periodicCounterCapturePacketSize;
2118 sendCounterPacket.SetReadyToRead();
2119 sendCounterPacket.SetReadyToRead();
2120 sendCounterPacket.SendPeriodicCounterSelectionPacket(1000u, { 1345u, 254u, 4536u, 408u, 54u, 6323u, 428u, 1u, 6u });
2122 // Get the size of the Periodic Counter Capture Packet
2123 periodicCounterCapturePacketSize = 30;
2124 totalWrittenSize += periodicCounterCapturePacketSize;
2126 sendCounterPacket.SetReadyToRead();
2128 // Abruptly terminating the send thread, the amount of data sent may be less that the amount written (the send
2129 // thread is not guaranteed to flush the buffer)
2130 sendCounterPacket.Stop();
2132 BOOST_CHECK(mockStreamCounterBuffer.GetCommittedSize() == totalWrittenSize);
2133 BOOST_CHECK(mockStreamCounterBuffer.GetReadableSize() <= totalWrittenSize);
2134 BOOST_CHECK(mockStreamCounterBuffer.GetReadSize() <= totalWrittenSize);
2135 BOOST_CHECK(mockStreamCounterBuffer.GetReadSize() <= mockStreamCounterBuffer.GetReadableSize());
2136 BOOST_CHECK(mockStreamCounterBuffer.GetReadSize() <= mockStreamCounterBuffer.GetCommittedSize());
2139 BOOST_AUTO_TEST_CASE(SendThreadBufferTest)
2141 ProfilingStateMachine profilingStateMachine;
2142 SetActiveProfilingState(profilingStateMachine);
2144 MockProfilingConnection mockProfilingConnection;
2145 BufferManager bufferManager(1, 1024);
2146 SendCounterPacket sendCounterPacket(profilingStateMachine, bufferManager, -1);
2147 sendCounterPacket.Start(mockProfilingConnection);
2149 // Interleaving writes and reads to/from the buffer with pauses to test that the send thread actually waits for
2150 // something to become available for reading
2151 std::this_thread::sleep_for(std::chrono::seconds(1));
2153 // SendStreamMetaDataPacket
2154 sendCounterPacket.SendStreamMetaDataPacket();
2156 // Read data from the buffer
2157 // Buffer should become readable after commit by SendStreamMetaDataPacket
2158 auto packetBuffer = bufferManager.GetReadableBuffer();
2159 BOOST_TEST(packetBuffer.get());
2161 std::string processName = GetProcessName().substr(0, 60);
2162 unsigned int processNameSize = processName.empty() ? 0 : boost::numeric_cast<unsigned int>(processName.size()) + 1;
2163 unsigned int streamMetadataPacketsize = 118 + processNameSize;
2164 BOOST_TEST(packetBuffer->GetSize() == streamMetadataPacketsize);
2166 // Buffer is not available when SendStreamMetaDataPacket already occupied the buffer.
2167 unsigned int reservedSize = 0;
2168 auto reservedBuffer = bufferManager.Reserve(512, reservedSize);
2169 BOOST_TEST(!reservedBuffer.get());
2171 // Recommit to be read by sendCounterPacket
2172 bufferManager.Commit(packetBuffer, streamMetadataPacketsize);
2174 sendCounterPacket.SetReadyToRead();
2176 std::this_thread::sleep_for(std::chrono::seconds(1));
2178 // The buffer is read by the send thread so it should not be in the readable buffer.
2179 auto readBuffer = bufferManager.GetReadableBuffer();
2180 BOOST_TEST(!readBuffer);
2182 // Successfully reserved the buffer with requested size
2183 reservedBuffer = bufferManager.Reserve(512, reservedSize);
2184 BOOST_TEST(reservedSize == 512);
2185 BOOST_TEST(reservedBuffer.get());
2187 // Release the buffer to be used by sendCounterPacket
2188 bufferManager.Release(reservedBuffer);
2190 // SendCounterDirectoryPacket
2191 CounterDirectory counterDirectory;
2192 sendCounterPacket.SendCounterDirectoryPacket(counterDirectory);
2194 // Read data from the buffer
2195 // Buffer should become readable after commit by SendCounterDirectoryPacket
2196 auto counterDirectoryPacketBuffer = bufferManager.GetReadableBuffer();
2197 BOOST_TEST(counterDirectoryPacketBuffer.get());
2199 // Get the size of the Counter Directory Packet
2200 unsigned int counterDirectoryPacketSize = 32;
2201 BOOST_TEST(counterDirectoryPacketBuffer->GetSize() == counterDirectoryPacketSize);
2203 // Buffer is not available when SendCounterDirectoryPacket already occupied the buffer.
2205 reservedBuffer = bufferManager.Reserve(512, reservedSize);
2206 BOOST_TEST(reservedSize == 0);
2207 BOOST_TEST(!reservedBuffer.get());
2209 // Recommit to be read by sendCounterPacket
2210 bufferManager.Commit(counterDirectoryPacketBuffer, counterDirectoryPacketSize);
2212 sendCounterPacket.SetReadyToRead();
2214 std::this_thread::sleep_for(std::chrono::seconds(1));
2216 // The buffer is read by the send thread so it should not be in the readable buffer.
2217 readBuffer = bufferManager.GetReadableBuffer();
2218 BOOST_TEST(!readBuffer);
2220 // Successfully reserved the buffer with requested size
2221 reservedBuffer = bufferManager.Reserve(512, reservedSize);
2222 BOOST_TEST(reservedSize == 512);
2223 BOOST_TEST(reservedBuffer.get());
2225 // Release the buffer to be used by sendCounterPacket
2226 bufferManager.Release(reservedBuffer);
2228 // SendPeriodicCounterCapturePacket
2229 sendCounterPacket.SendPeriodicCounterCapturePacket(123u,
2235 // Read data from the buffer
2236 // Buffer should become readable after commit by SendPeriodicCounterCapturePacket
2237 auto periodicCounterCapturePacketBuffer = bufferManager.GetReadableBuffer();
2238 BOOST_TEST(periodicCounterCapturePacketBuffer.get());
2240 // Get the size of the Periodic Counter Capture Packet
2241 unsigned int periodicCounterCapturePacketSize = 28;
2242 BOOST_TEST(periodicCounterCapturePacketBuffer->GetSize() == periodicCounterCapturePacketSize);
2244 // Buffer is not available when SendPeriodicCounterCapturePacket already occupied the buffer.
2246 reservedBuffer = bufferManager.Reserve(512, reservedSize);
2247 BOOST_TEST(reservedSize == 0);
2248 BOOST_TEST(!reservedBuffer.get());
2250 // Recommit to be read by sendCounterPacket
2251 bufferManager.Commit(periodicCounterCapturePacketBuffer, periodicCounterCapturePacketSize);
2253 sendCounterPacket.SetReadyToRead();
2255 std::this_thread::sleep_for(std::chrono::seconds(1));
2257 // The buffer is read by the send thread so it should not be in the readable buffer.
2258 readBuffer = bufferManager.GetReadableBuffer();
2259 BOOST_TEST(!readBuffer);
2261 // Successfully reserved the buffer with requested size
2262 reservedBuffer = bufferManager.Reserve(512, reservedSize);
2263 BOOST_TEST(reservedSize == 512);
2264 BOOST_TEST(reservedBuffer.get());
2266 sendCounterPacket.Stop();
2269 BOOST_AUTO_TEST_CASE(SendThreadBufferTest1)
2271 ProfilingStateMachine profilingStateMachine;
2272 SetActiveProfilingState(profilingStateMachine);
2274 MockProfilingConnection mockProfilingConnection;
2275 BufferManager bufferManager(3, 1024);
2276 SendCounterPacket sendCounterPacket(profilingStateMachine, bufferManager, -1);
2277 sendCounterPacket.Start(mockProfilingConnection);
2279 // SendStreamMetaDataPacket
2280 sendCounterPacket.SendStreamMetaDataPacket();
2282 // Read data from the buffer
2283 // Buffer should become readable after commit by SendStreamMetaDataPacket
2284 auto packetBuffer = bufferManager.GetReadableBuffer();
2285 BOOST_TEST(packetBuffer.get());
2287 std::string processName = GetProcessName().substr(0, 60);
2288 unsigned int processNameSize = processName.empty() ? 0 : boost::numeric_cast<unsigned int>(processName.size()) + 1;
2289 unsigned int streamMetadataPacketsize = 118 + processNameSize;
2290 BOOST_TEST(packetBuffer->GetSize() == streamMetadataPacketsize);
2292 // Recommit to be read by sendCounterPacket
2293 bufferManager.Commit(packetBuffer, streamMetadataPacketsize);
2295 sendCounterPacket.SetReadyToRead();
2297 // SendCounterDirectoryPacket
2298 CounterDirectory counterDirectory;
2299 sendCounterPacket.SendCounterDirectoryPacket(counterDirectory);
2301 sendCounterPacket.SetReadyToRead();
2303 // SendPeriodicCounterCapturePacket
2304 sendCounterPacket.SendPeriodicCounterCapturePacket(123u,
2310 sendCounterPacket.SetReadyToRead();
2312 sendCounterPacket.Stop();
2314 // The buffer is read by the send thread so it should not be in the readable buffer.
2315 auto readBuffer = bufferManager.GetReadableBuffer();
2316 BOOST_TEST(!readBuffer);
2318 // Successfully reserved the buffer with requested size
2319 unsigned int reservedSize = 0;
2320 auto reservedBuffer = bufferManager.Reserve(512, reservedSize);
2321 BOOST_TEST(reservedSize == 512);
2322 BOOST_TEST(reservedBuffer.get());
2324 // Check that data was actually written to the profiling connection in any order
2325 const std::vector<uint32_t>& writtenData = mockProfilingConnection.GetWrittenData();
2326 BOOST_TEST(writtenData.size() == 3);
2327 bool foundStreamMetaDataPacket =
2328 std::find(writtenData.begin(), writtenData.end(), streamMetadataPacketsize) != writtenData.end();
2329 bool foundCounterDirectoryPacket = std::find(writtenData.begin(), writtenData.end(), 32) != writtenData.end();
2330 bool foundPeriodicCounterCapturePacket = std::find(writtenData.begin(), writtenData.end(), 28) != writtenData.end();
2331 BOOST_TEST(foundStreamMetaDataPacket);
2332 BOOST_TEST(foundCounterDirectoryPacket);
2333 BOOST_TEST(foundPeriodicCounterCapturePacket);
2336 BOOST_AUTO_TEST_CASE(SendThreadSendStreamMetadataPacket1)
2338 ProfilingStateMachine profilingStateMachine;
2340 MockProfilingConnection mockProfilingConnection;
2341 BufferManager bufferManager(3, 1024);
2342 SendCounterPacket sendCounterPacket(profilingStateMachine, bufferManager);
2343 sendCounterPacket.Start(mockProfilingConnection);
2345 // The profiling state is set to "Uninitialized", so the send thread should throw an exception
2347 // Wait a bit to make sure that the send thread is properly started
2348 std::this_thread::sleep_for(std::chrono::milliseconds(100));
2350 BOOST_CHECK_THROW(sendCounterPacket.Stop(), armnn::RuntimeException);
2353 BOOST_AUTO_TEST_CASE(SendThreadSendStreamMetadataPacket2)
2355 ProfilingStateMachine profilingStateMachine;
2356 SetNotConnectedProfilingState(profilingStateMachine);
2358 MockProfilingConnection mockProfilingConnection;
2359 BufferManager bufferManager(3, 1024);
2360 SendCounterPacket sendCounterPacket(profilingStateMachine, bufferManager);
2361 sendCounterPacket.Start(mockProfilingConnection);
2363 // The profiling state is set to "NotConnected", so the send thread should throw an exception
2365 // Wait a bit to make sure that the send thread is properly started
2366 std::this_thread::sleep_for(std::chrono::milliseconds(100));
2368 BOOST_CHECK_THROW(sendCounterPacket.Stop(), armnn::RuntimeException);
2371 BOOST_AUTO_TEST_CASE(SendThreadSendStreamMetadataPacket3)
2373 ProfilingStateMachine profilingStateMachine;
2374 SetWaitingForAckProfilingState(profilingStateMachine);
2376 // Calculate the size of a Stream Metadata packet
2377 std::string processName = GetProcessName().substr(0, 60);
2378 unsigned int processNameSize = processName.empty() ? 0 : boost::numeric_cast<unsigned int>(processName.size()) + 1;
2379 unsigned int streamMetadataPacketsize = 118 + processNameSize;
2381 MockProfilingConnection mockProfilingConnection;
2382 BufferManager bufferManager(3, 1024);
2383 SendCounterPacket sendCounterPacket(profilingStateMachine, bufferManager);
2384 sendCounterPacket.Start(mockProfilingConnection);
2386 // The profiling state is set to "WaitingForAck", so the send thread should send a Stream Metadata packet
2388 // Wait for a bit to make sure that we get the packet
2389 std::this_thread::sleep_for(std::chrono::milliseconds(100));
2391 BOOST_CHECK_NO_THROW(sendCounterPacket.Stop());
2393 // Check that the buffer contains one Stream Metadata packet
2394 const std::vector<uint32_t>& writtenData = mockProfilingConnection.GetWrittenData();
2395 BOOST_TEST(writtenData.size() == 1);
2396 BOOST_TEST(writtenData[0] == streamMetadataPacketsize);
2399 BOOST_AUTO_TEST_CASE(SendThreadSendStreamMetadataPacket4)
2401 ProfilingStateMachine profilingStateMachine;
2402 SetWaitingForAckProfilingState(profilingStateMachine);
2404 // Calculate the size of a Stream Metadata packet
2405 std::string processName = GetProcessName().substr(0, 60);
2406 unsigned int processNameSize = processName.empty() ? 0 : boost::numeric_cast<unsigned int>(processName.size()) + 1;
2407 unsigned int streamMetadataPacketsize = 118 + processNameSize;
2409 MockProfilingConnection mockProfilingConnection;
2410 BufferManager bufferManager(3, 1024);
2411 SendCounterPacket sendCounterPacket(profilingStateMachine, bufferManager);
2412 sendCounterPacket.Start(mockProfilingConnection);
2414 // The profiling state is set to "WaitingForAck", so the send thread should send a Stream Metadata packet
2416 // Wait for a bit to make sure that we get the packet
2417 std::this_thread::sleep_for(std::chrono::milliseconds(100));
2419 // Check that the profiling state is still "WaitingForAck"
2420 BOOST_TEST((profilingStateMachine.GetCurrentState() == ProfilingState::WaitingForAck));
2422 // Check that the buffer contains one Stream Metadata packet
2423 const std::vector<uint32_t>& writtenData = mockProfilingConnection.GetWrittenData();
2424 BOOST_TEST(writtenData.size() == 1);
2425 BOOST_TEST(writtenData[0] == streamMetadataPacketsize);
2427 mockProfilingConnection.Clear();
2429 // Try triggering a new buffer read
2430 sendCounterPacket.SetReadyToRead();
2432 // Wait for a bit to make sure that we get the packet
2433 std::this_thread::sleep_for(std::chrono::milliseconds(100));
2435 // Check that the profiling state is still "WaitingForAck"
2436 BOOST_TEST((profilingStateMachine.GetCurrentState() == ProfilingState::WaitingForAck));
2438 // Check that the buffer contains one Stream Metadata packet
2439 BOOST_TEST(writtenData.size() == 1);
2440 BOOST_TEST(writtenData[0] == streamMetadataPacketsize);
2442 BOOST_CHECK_NO_THROW(sendCounterPacket.Stop());
2445 BOOST_AUTO_TEST_SUITE_END()