2 // Copyright © 2019 Arm Ltd. All rights reserved.
3 // SPDX-License-Identifier: MIT
6 #include "SendCounterPacketTests.hpp"
8 #include <EncodeVersion.hpp>
9 #include <ProfilingUtils.hpp>
10 #include <SendCounterPacket.hpp>
11 #include <CounterDirectory.hpp>
13 #include <armnn/Exceptions.hpp>
14 #include <armnn/Conversion.hpp>
16 #include <boost/test/unit_test.hpp>
17 #include <boost/numeric/conversion/cast.hpp>
21 using namespace armnn::profiling;
23 BOOST_AUTO_TEST_SUITE(SendCounterPacketTests)
25 BOOST_AUTO_TEST_CASE(MockSendCounterPacketTest)
27 MockBufferManager mockBuffer(512);
28 MockSendCounterPacket sendCounterPacket(mockBuffer);
30 sendCounterPacket.SendStreamMetaDataPacket();
32 auto packetBuffer = mockBuffer.GetReadableBuffer();
33 const char* buffer = reinterpret_cast<const char*>(packetBuffer->GetReadableData());
35 BOOST_TEST(strcmp(buffer, "SendStreamMetaDataPacket") == 0);
37 mockBuffer.MarkRead(packetBuffer);
39 CounterDirectory counterDirectory;
40 sendCounterPacket.SendCounterDirectoryPacket(counterDirectory);
42 packetBuffer = mockBuffer.GetReadableBuffer();
43 buffer = reinterpret_cast<const char*>(packetBuffer->GetReadableData());
45 BOOST_TEST(strcmp(buffer, "SendCounterDirectoryPacket") == 0);
47 mockBuffer.MarkRead(packetBuffer);
49 uint64_t timestamp = 0;
50 std::vector<std::pair<uint16_t, uint32_t>> indexValuePairs;
52 sendCounterPacket.SendPeriodicCounterCapturePacket(timestamp, indexValuePairs);
54 packetBuffer = mockBuffer.GetReadableBuffer();
55 buffer = reinterpret_cast<const char*>(packetBuffer->GetReadableData());
57 BOOST_TEST(strcmp(buffer, "SendPeriodicCounterCapturePacket") == 0);
59 mockBuffer.MarkRead(packetBuffer);
61 uint32_t capturePeriod = 0;
62 std::vector<uint16_t> selectedCounterIds;
63 sendCounterPacket.SendPeriodicCounterSelectionPacket(capturePeriod, selectedCounterIds);
65 packetBuffer = mockBuffer.GetReadableBuffer();
66 buffer = reinterpret_cast<const char*>(packetBuffer->GetReadableData());
68 BOOST_TEST(strcmp(buffer, "SendPeriodicCounterSelectionPacket") == 0);
70 mockBuffer.MarkRead(packetBuffer);
73 BOOST_AUTO_TEST_CASE(SendPeriodicCounterSelectionPacketTest)
75 // Error no space left in buffer
76 MockProfilingConnection mockProfilingConnection;
77 MockBufferManager mockBuffer1(10);
78 SendCounterPacket sendPacket1(mockProfilingConnection, mockBuffer1);
80 uint32_t capturePeriod = 1000;
81 std::vector<uint16_t> selectedCounterIds;
82 BOOST_CHECK_THROW(sendPacket1.SendPeriodicCounterSelectionPacket(capturePeriod, selectedCounterIds),
85 // Packet without any counters
86 MockBufferManager mockBuffer2(512);
87 SendCounterPacket sendPacket2(mockProfilingConnection, mockBuffer2);
89 sendPacket2.SendPeriodicCounterSelectionPacket(capturePeriod, selectedCounterIds);
90 auto readBuffer2 = mockBuffer2.GetReadableBuffer();
92 uint32_t headerWord0 = ReadUint32(readBuffer2, 0);
93 uint32_t headerWord1 = ReadUint32(readBuffer2, 4);
94 uint32_t period = ReadUint32(readBuffer2, 8);
96 BOOST_TEST(((headerWord0 >> 26) & 0x3F) == 0); // packet family
97 BOOST_TEST(((headerWord0 >> 16) & 0x3FF) == 4); // packet id
98 BOOST_TEST(headerWord1 == 4); // data lenght
99 BOOST_TEST(period == 1000); // capture period
101 // Full packet message
102 MockBufferManager mockBuffer3(512);
103 SendCounterPacket sendPacket3(mockProfilingConnection, mockBuffer3);
105 selectedCounterIds.reserve(5);
106 selectedCounterIds.emplace_back(100);
107 selectedCounterIds.emplace_back(200);
108 selectedCounterIds.emplace_back(300);
109 selectedCounterIds.emplace_back(400);
110 selectedCounterIds.emplace_back(500);
111 sendPacket3.SendPeriodicCounterSelectionPacket(capturePeriod, selectedCounterIds);
112 auto readBuffer3 = mockBuffer3.GetReadableBuffer();
114 headerWord0 = ReadUint32(readBuffer3, 0);
115 headerWord1 = ReadUint32(readBuffer3, 4);
116 period = ReadUint32(readBuffer3, 8);
118 BOOST_TEST(((headerWord0 >> 26) & 0x3F) == 0); // packet family
119 BOOST_TEST(((headerWord0 >> 16) & 0x3FF) == 4); // packet id
120 BOOST_TEST(headerWord1 == 14); // data lenght
121 BOOST_TEST(period == 1000); // capture period
123 uint16_t counterId = 0;
124 uint32_t offset = 12;
127 for(const uint16_t& id : selectedCounterIds)
129 counterId = ReadUint16(readBuffer3, offset);
130 BOOST_TEST(counterId == id);
135 BOOST_AUTO_TEST_CASE(SendPeriodicCounterCapturePacketTest)
137 // Error no space left in buffer
138 MockProfilingConnection mockProfilingConnection;
139 MockBufferManager mockBuffer1(10);
140 SendCounterPacket sendPacket1(mockProfilingConnection, mockBuffer1);
142 auto captureTimestamp = std::chrono::steady_clock::now();
143 uint64_t time = static_cast<uint64_t >(captureTimestamp.time_since_epoch().count());
144 std::vector<std::pair<uint16_t, uint32_t>> indexValuePairs;
146 BOOST_CHECK_THROW(sendPacket1.SendPeriodicCounterCapturePacket(time, indexValuePairs),
149 // Packet without any counters
150 MockBufferManager mockBuffer2(512);
151 SendCounterPacket sendPacket2(mockProfilingConnection, mockBuffer2);
153 sendPacket2.SendPeriodicCounterCapturePacket(time, indexValuePairs);
154 auto readBuffer2 = mockBuffer2.GetReadableBuffer();
156 uint32_t headerWord0 = ReadUint32(readBuffer2, 0);
157 uint32_t headerWord1 = ReadUint32(readBuffer2, 4);
158 uint64_t readTimestamp = ReadUint64(readBuffer2, 8);
160 BOOST_TEST(((headerWord0 >> 26) & 0x3F) == 1); // packet family
161 BOOST_TEST(((headerWord0 >> 19) & 0x3F) == 0); // packet class
162 BOOST_TEST(((headerWord0 >> 16) & 0x3) == 0); // packet type
163 BOOST_TEST(headerWord1 == 8); // data length
164 BOOST_TEST(time == readTimestamp); // capture period
166 // Full packet message
167 MockBufferManager mockBuffer3(512);
168 SendCounterPacket sendPacket3(mockProfilingConnection, mockBuffer3);
170 indexValuePairs.reserve(5);
171 indexValuePairs.emplace_back(std::make_pair<uint16_t, uint32_t >(0, 100));
172 indexValuePairs.emplace_back(std::make_pair<uint16_t, uint32_t >(1, 200));
173 indexValuePairs.emplace_back(std::make_pair<uint16_t, uint32_t >(2, 300));
174 indexValuePairs.emplace_back(std::make_pair<uint16_t, uint32_t >(3, 400));
175 indexValuePairs.emplace_back(std::make_pair<uint16_t, uint32_t >(4, 500));
176 sendPacket3.SendPeriodicCounterCapturePacket(time, indexValuePairs);
177 auto readBuffer3 = mockBuffer3.GetReadableBuffer();
179 headerWord0 = ReadUint32(readBuffer3, 0);
180 headerWord1 = ReadUint32(readBuffer3, 4);
181 uint64_t readTimestamp2 = ReadUint64(readBuffer3, 8);
183 BOOST_TEST(((headerWord0 >> 26) & 0x3F) == 1); // packet family
184 BOOST_TEST(((headerWord0 >> 19) & 0x3F) == 0); // packet class
185 BOOST_TEST(((headerWord0 >> 16) & 0x3) == 0); // packet type
186 BOOST_TEST(headerWord1 == 38); // data length
187 BOOST_TEST(time == readTimestamp2); // capture period
189 uint16_t counterIndex = 0;
190 uint32_t counterValue = 100;
191 uint32_t offset = 16;
194 for (auto it = indexValuePairs.begin(), end = indexValuePairs.end(); it != end; ++it)
196 // Check Counter Index
197 uint16_t readIndex = ReadUint16(readBuffer3, offset);
198 BOOST_TEST(counterIndex == readIndex);
202 // Check Counter Value
203 uint32_t readValue = ReadUint32(readBuffer3, offset);
204 BOOST_TEST(counterValue == readValue);
211 BOOST_AUTO_TEST_CASE(SendStreamMetaDataPacketTest)
213 using boost::numeric_cast;
215 uint32_t sizeUint32 = numeric_cast<uint32_t>(sizeof(uint32_t));
217 // Error no space left in buffer
218 MockProfilingConnection mockProfilingConnection;
219 MockBufferManager mockBuffer1(10);
220 SendCounterPacket sendPacket1(mockProfilingConnection, mockBuffer1);
221 BOOST_CHECK_THROW(sendPacket1.SendStreamMetaDataPacket(), armnn::profiling::BufferExhaustion);
223 // Full metadata packet
225 std::string processName = GetProcessName().substr(0, 60);
227 uint32_t infoSize = numeric_cast<uint32_t>(GetSoftwareInfo().size()) > 0 ?
228 numeric_cast<uint32_t>(GetSoftwareInfo().size()) + 1 : 0;
229 uint32_t hardwareVersionSize = numeric_cast<uint32_t>(GetHardwareVersion().size()) > 0 ?
230 numeric_cast<uint32_t>(GetHardwareVersion().size()) + 1 : 0;
231 uint32_t softwareVersionSize = numeric_cast<uint32_t>(GetSoftwareVersion().size()) > 0 ?
232 numeric_cast<uint32_t>(GetSoftwareVersion().size()) + 1 : 0;
233 uint32_t processNameSize = numeric_cast<uint32_t>(processName.size()) > 0 ?
234 numeric_cast<uint32_t>(processName.size()) + 1 : 0;
236 uint32_t packetEntries = 6;
238 MockBufferManager mockBuffer2(512);
239 SendCounterPacket sendPacket2(mockProfilingConnection, mockBuffer2);
240 sendPacket2.SendStreamMetaDataPacket();
241 auto readBuffer2 = mockBuffer2.GetReadableBuffer();
243 uint32_t headerWord0 = ReadUint32(readBuffer2, 0);
244 uint32_t headerWord1 = ReadUint32(readBuffer2, sizeUint32);
246 BOOST_TEST(((headerWord0 >> 26) & 0x3F) == 0); // packet family
247 BOOST_TEST(((headerWord0 >> 16) & 0x3FF) == 0); // packet id
249 uint32_t totalLength = numeric_cast<uint32_t>(2 * sizeUint32 + 10 * sizeUint32 + infoSize + hardwareVersionSize +
250 softwareVersionSize + processNameSize + sizeUint32 +
251 2 * packetEntries * sizeUint32);
253 BOOST_TEST(headerWord1 == totalLength - (2 * sizeUint32)); // data length
255 uint32_t offset = sizeUint32 * 2;
256 BOOST_TEST(ReadUint32(readBuffer2, offset) == SendCounterPacket::PIPE_MAGIC); // pipe_magic
257 offset += sizeUint32;
258 BOOST_TEST(ReadUint32(readBuffer2, offset) == EncodeVersion(1, 0, 0)); // stream_metadata_version
259 offset += sizeUint32;
260 BOOST_TEST(ReadUint32(readBuffer2, offset) == SendCounterPacket::MAX_METADATA_PACKET_LENGTH); // max_data_len
261 offset += sizeUint32;
262 BOOST_TEST(ReadUint32(readBuffer2, offset) == numeric_cast<uint32_t>(getpid())); // pid
263 offset += sizeUint32;
264 uint32_t poolOffset = 10 * sizeUint32;
265 BOOST_TEST(ReadUint32(readBuffer2, offset) == (infoSize ? poolOffset : 0)); // offset_info
266 offset += sizeUint32;
267 poolOffset += infoSize;
268 BOOST_TEST(ReadUint32(readBuffer2, offset) == (hardwareVersionSize ? poolOffset : 0)); // offset_hw_version
269 offset += sizeUint32;
270 poolOffset += hardwareVersionSize;
271 BOOST_TEST(ReadUint32(readBuffer2, offset) == (softwareVersionSize ? poolOffset : 0)); // offset_sw_version
272 offset += sizeUint32;
273 poolOffset += softwareVersionSize;
274 BOOST_TEST(ReadUint32(readBuffer2, offset) == (processNameSize ? poolOffset : 0)); // offset_process_name
275 offset += sizeUint32;
276 poolOffset += processNameSize;
277 BOOST_TEST(ReadUint32(readBuffer2, offset) == (packetEntries ? poolOffset : 0)); // offset_packet_version_table
278 offset += sizeUint32;
279 BOOST_TEST(ReadUint32(readBuffer2, offset) == 0); // reserved
281 const unsigned char* readData2 = readBuffer2->GetReadableData();
283 offset += sizeUint32;
286 BOOST_TEST(strcmp(reinterpret_cast<const char *>(&readData2[offset]), GetSoftwareInfo().c_str()) == 0);
290 if (hardwareVersionSize)
292 BOOST_TEST(strcmp(reinterpret_cast<const char *>(&readData2[offset]), GetHardwareVersion().c_str()) == 0);
293 offset += hardwareVersionSize;
296 if (softwareVersionSize)
298 BOOST_TEST(strcmp(reinterpret_cast<const char *>(&readData2[offset]), GetSoftwareVersion().c_str()) == 0);
299 offset += softwareVersionSize;
304 BOOST_TEST(strcmp(reinterpret_cast<const char *>(&readData2[offset]), GetProcessName().c_str()) == 0);
305 offset += processNameSize;
310 BOOST_TEST((ReadUint32(readBuffer2, offset) >> 16) == packetEntries);
311 offset += sizeUint32;
312 for (uint32_t i = 0; i < packetEntries - 1; ++i)
314 BOOST_TEST(((ReadUint32(readBuffer2, offset) >> 26) & 0x3F) == 0);
315 BOOST_TEST(((ReadUint32(readBuffer2, offset) >> 16) & 0x3FF) == i);
316 offset += sizeUint32;
317 BOOST_TEST(ReadUint32(readBuffer2, offset) == EncodeVersion(1, 0, 0));
318 offset += sizeUint32;
321 BOOST_TEST(((ReadUint32(readBuffer2, offset) >> 26) & 0x3F) == 1);
322 BOOST_TEST(((ReadUint32(readBuffer2, offset) >> 16) & 0x3FF) == 0);
323 offset += sizeUint32;
324 BOOST_TEST(ReadUint32(readBuffer2, offset) == EncodeVersion(1, 0, 0));
325 offset += sizeUint32;
328 BOOST_TEST(offset == totalLength);
331 BOOST_AUTO_TEST_CASE(CreateDeviceRecordTest)
333 MockProfilingConnection mockProfilingConnection;
334 MockBufferManager mockBuffer(0);
335 SendCounterPacketTest sendCounterPacketTest(mockProfilingConnection, mockBuffer);
337 // Create a device for testing
338 uint16_t deviceUid = 27;
339 const std::string deviceName = "some_device";
340 uint16_t deviceCores = 3;
341 const DevicePtr device = std::make_unique<Device>(deviceUid, deviceName, deviceCores);
343 // Create a device record
344 SendCounterPacket::DeviceRecord deviceRecord;
345 std::string errorMessage;
346 bool result = sendCounterPacketTest.CreateDeviceRecordTest(device, deviceRecord, errorMessage);
349 BOOST_CHECK(errorMessage.empty());
350 BOOST_CHECK(deviceRecord.size() == 6); // Size in words: header [2] + device name [4]
352 uint16_t deviceRecordWord0[]
354 static_cast<uint16_t>(deviceRecord[0] >> 16),
355 static_cast<uint16_t>(deviceRecord[0])
357 BOOST_CHECK(deviceRecordWord0[0] == deviceUid); // uid
358 BOOST_CHECK(deviceRecordWord0[1] == deviceCores); // cores
359 BOOST_CHECK(deviceRecord[1] == 0); // name_offset
360 BOOST_CHECK(deviceRecord[2] == deviceName.size() + 1); // The length of the SWTrace string (name)
361 BOOST_CHECK(std::memcmp(deviceRecord.data() + 3, deviceName.data(), deviceName.size()) == 0); // name
364 BOOST_AUTO_TEST_CASE(CreateInvalidDeviceRecordTest)
366 MockProfilingConnection mockProfilingConnection;
367 MockBufferManager mockBuffer(0);
368 SendCounterPacketTest sendCounterPacketTest(mockProfilingConnection, mockBuffer);
370 // Create a device for testing
371 uint16_t deviceUid = 27;
372 const std::string deviceName = "some€£invalid‡device";
373 uint16_t deviceCores = 3;
374 const DevicePtr device = std::make_unique<Device>(deviceUid, deviceName, deviceCores);
376 // Create a device record
377 SendCounterPacket::DeviceRecord deviceRecord;
378 std::string errorMessage;
379 bool result = sendCounterPacketTest.CreateDeviceRecordTest(device, deviceRecord, errorMessage);
381 BOOST_CHECK(!result);
382 BOOST_CHECK(!errorMessage.empty());
383 BOOST_CHECK(deviceRecord.empty());
386 BOOST_AUTO_TEST_CASE(CreateCounterSetRecordTest)
388 MockProfilingConnection mockProfilingConnection;
389 MockBufferManager mockBuffer(0);
390 SendCounterPacketTest sendCounterPacketTest(mockProfilingConnection, mockBuffer);
392 // Create a counter set for testing
393 uint16_t counterSetUid = 27;
394 const std::string counterSetName = "some_counter_set";
395 uint16_t counterSetCount = 3421;
396 const CounterSetPtr counterSet = std::make_unique<CounterSet>(counterSetUid, counterSetName, counterSetCount);
398 // Create a counter set record
399 SendCounterPacket::CounterSetRecord counterSetRecord;
400 std::string errorMessage;
401 bool result = sendCounterPacketTest.CreateCounterSetRecordTest(counterSet, counterSetRecord, errorMessage);
404 BOOST_CHECK(errorMessage.empty());
405 BOOST_CHECK(counterSetRecord.size() == 8); // Size in words: header [2] + counter set name [6]
407 uint16_t counterSetRecordWord0[]
409 static_cast<uint16_t>(counterSetRecord[0] >> 16),
410 static_cast<uint16_t>(counterSetRecord[0])
412 BOOST_CHECK(counterSetRecordWord0[0] == counterSetUid); // uid
413 BOOST_CHECK(counterSetRecordWord0[1] == counterSetCount); // cores
414 BOOST_CHECK(counterSetRecord[1] == 0); // name_offset
415 BOOST_CHECK(counterSetRecord[2] == counterSetName.size() + 1); // The length of the SWTrace string (name)
416 BOOST_CHECK(std::memcmp(counterSetRecord.data() + 3, counterSetName.data(), counterSetName.size()) == 0); // name
419 BOOST_AUTO_TEST_CASE(CreateInvalidCounterSetRecordTest)
421 MockProfilingConnection mockProfilingConnection;
422 MockBufferManager mockBuffer(0);
423 SendCounterPacketTest sendCounterPacketTest(mockProfilingConnection, mockBuffer);
425 // Create a counter set for testing
426 uint16_t counterSetUid = 27;
427 const std::string counterSetName = "some invalid_counter€£set";
428 uint16_t counterSetCount = 3421;
429 const CounterSetPtr counterSet = std::make_unique<CounterSet>(counterSetUid, counterSetName, counterSetCount);
431 // Create a counter set record
432 SendCounterPacket::CounterSetRecord counterSetRecord;
433 std::string errorMessage;
434 bool result = sendCounterPacketTest.CreateCounterSetRecordTest(counterSet, counterSetRecord, errorMessage);
436 BOOST_CHECK(!result);
437 BOOST_CHECK(!errorMessage.empty());
438 BOOST_CHECK(counterSetRecord.empty());
441 BOOST_AUTO_TEST_CASE(CreateEventRecordTest)
443 MockProfilingConnection mockProfilingConnection;
444 MockBufferManager mockBuffer(0);
445 SendCounterPacketTest sendCounterPacketTest(mockProfilingConnection, mockBuffer);
447 // Create a counter for testing
448 uint16_t counterUid = 7256;
449 uint16_t maxCounterUid = 132;
450 uint16_t deviceUid = 132;
451 uint16_t counterSetUid = 4497;
452 uint16_t counterClass = 1;
453 uint16_t counterInterpolation = 1;
454 double counterMultiplier = 1234.567f;
455 const std::string counterName = "some_valid_counter";
456 const std::string counterDescription = "a_counter_for_testing";
457 const std::string counterUnits = "Mrads2";
458 const CounterPtr counter = std::make_unique<Counter>(counterUid,
461 counterInterpolation,
468 BOOST_ASSERT(counter);
470 // Create an event record
471 SendCounterPacket::EventRecord eventRecord;
472 std::string errorMessage;
473 bool result = sendCounterPacketTest.CreateEventRecordTest(counter, eventRecord, errorMessage);
476 BOOST_CHECK(errorMessage.empty());
477 BOOST_CHECK(eventRecord.size() == 24); // Size in words: header [8] + counter name [6] + description [7] + units [3]
479 uint16_t eventRecordWord0[]
481 static_cast<uint16_t>(eventRecord[0] >> 16),
482 static_cast<uint16_t>(eventRecord[0])
484 uint16_t eventRecordWord1[]
486 static_cast<uint16_t>(eventRecord[1] >> 16),
487 static_cast<uint16_t>(eventRecord[1])
489 uint16_t eventRecordWord2[]
491 static_cast<uint16_t>(eventRecord[2] >> 16),
492 static_cast<uint16_t>(eventRecord[2])
494 uint32_t eventRecordWord34[]
499 BOOST_CHECK(eventRecordWord0[0] == maxCounterUid); // max_counter_uid
500 BOOST_CHECK(eventRecordWord0[1] == counterUid); // counter_uid
501 BOOST_CHECK(eventRecordWord1[0] == deviceUid); // device
502 BOOST_CHECK(eventRecordWord1[1] == counterSetUid); // counter_set
503 BOOST_CHECK(eventRecordWord2[0] == counterClass); // class
504 BOOST_CHECK(eventRecordWord2[1] == counterInterpolation); // interpolation
505 BOOST_CHECK(std::memcmp(eventRecordWord34, &counterMultiplier, sizeof(counterMultiplier)) == 0); // multiplier
507 ARMNN_NO_CONVERSION_WARN_BEGIN
508 uint32_t counterNameOffset = 0; // The name is the first item in pool
509 uint32_t counterDescriptionOffset = counterNameOffset + // Counter name offset
510 4u + // Counter name length (uint32_t)
511 counterName.size() + // 18u
512 1u + // Null-terminator
513 1u; // Rounding to the next word
514 size_t counterUnitsOffset = counterDescriptionOffset + // Counter description offset
515 4u + // Counter description length (uint32_t)
516 counterDescription.size() + // 21u
517 1u + // Null-terminator
518 2u; // Rounding to the next word
519 ARMNN_NO_CONVERSION_WARN_END
521 BOOST_CHECK(eventRecord[5] == counterNameOffset); // name_offset
522 BOOST_CHECK(eventRecord[6] == counterDescriptionOffset); // description_offset
523 BOOST_CHECK(eventRecord[7] == counterUnitsOffset); // units_offset
525 auto eventRecordPool = reinterpret_cast<unsigned char*>(eventRecord.data() + 8u); // The start of the pool
526 size_t uint32_t_size = sizeof(uint32_t);
528 // The length of the SWTrace string (name)
529 BOOST_CHECK(eventRecordPool[counterNameOffset] == counterName.size() + 1);
531 BOOST_CHECK(std::memcmp(eventRecordPool +
532 counterNameOffset + // Offset
533 uint32_t_size /* The length of the name */,
535 counterName.size()) == 0); // name
536 // The null-terminator at the end of the name
537 BOOST_CHECK(eventRecordPool[counterNameOffset + uint32_t_size + counterName.size()] == '\0');
539 // The length of the SWTrace string (description)
540 BOOST_CHECK(eventRecordPool[counterDescriptionOffset] == counterDescription.size() + 1);
541 // The counter description
542 BOOST_CHECK(std::memcmp(eventRecordPool +
543 counterDescriptionOffset + // Offset
544 uint32_t_size /* The length of the description */,
545 counterDescription.data(),
546 counterDescription.size()) == 0); // description
547 // The null-terminator at the end of the description
548 BOOST_CHECK(eventRecordPool[counterDescriptionOffset + uint32_t_size + counterDescription.size()] == '\0');
550 // The length of the SWTrace namestring (units)
551 BOOST_CHECK(eventRecordPool[counterUnitsOffset] == counterUnits.size() + 1);
553 BOOST_CHECK(std::memcmp(eventRecordPool +
554 counterUnitsOffset + // Offset
555 uint32_t_size /* The length of the units */,
557 counterUnits.size()) == 0); // units
558 // The null-terminator at the end of the units
559 BOOST_CHECK(eventRecordPool[counterUnitsOffset + uint32_t_size + counterUnits.size()] == '\0');
562 BOOST_AUTO_TEST_CASE(CreateEventRecordNoUnitsTest)
564 MockProfilingConnection mockProfilingConnection;
565 MockBufferManager mockBuffer(0);
566 SendCounterPacketTest sendCounterPacketTest(mockProfilingConnection, mockBuffer);
568 // Create a counter for testing
569 uint16_t counterUid = 44312;
570 uint16_t maxCounterUid = 345;
571 uint16_t deviceUid = 101;
572 uint16_t counterSetUid = 34035;
573 uint16_t counterClass = 0;
574 uint16_t counterInterpolation = 1;
575 double counterMultiplier = 4435.0023f;
576 const std::string counterName = "some_valid_counter";
577 const std::string counterDescription = "a_counter_for_testing";
578 const CounterPtr counter = std::make_unique<Counter>(counterUid,
581 counterInterpolation,
588 BOOST_ASSERT(counter);
590 // Create an event record
591 SendCounterPacket::EventRecord eventRecord;
592 std::string errorMessage;
593 bool result = sendCounterPacketTest.CreateEventRecordTest(counter, eventRecord, errorMessage);
596 BOOST_CHECK(errorMessage.empty());
597 BOOST_CHECK(eventRecord.size() == 21); // Size in words: header [8] + counter name [6] + description [7]
599 uint16_t eventRecordWord0[]
601 static_cast<uint16_t>(eventRecord[0] >> 16),
602 static_cast<uint16_t>(eventRecord[0])
604 uint16_t eventRecordWord1[]
606 static_cast<uint16_t>(eventRecord[1] >> 16),
607 static_cast<uint16_t>(eventRecord[1])
609 uint16_t eventRecordWord2[]
611 static_cast<uint16_t>(eventRecord[2] >> 16),
612 static_cast<uint16_t>(eventRecord[2])
614 uint32_t eventRecordWord34[]
619 BOOST_CHECK(eventRecordWord0[0] == maxCounterUid); // max_counter_uid
620 BOOST_CHECK(eventRecordWord0[1] == counterUid); // counter_uid
621 BOOST_CHECK(eventRecordWord1[0] == deviceUid); // device
622 BOOST_CHECK(eventRecordWord1[1] == counterSetUid); // counter_set
623 BOOST_CHECK(eventRecordWord2[0] == counterClass); // class
624 BOOST_CHECK(eventRecordWord2[1] == counterInterpolation); // interpolation
625 BOOST_CHECK(std::memcmp(eventRecordWord34, &counterMultiplier, sizeof(counterMultiplier)) == 0); // multiplier
627 ARMNN_NO_CONVERSION_WARN_BEGIN
628 uint32_t counterNameOffset = 0; // The name is the first item in pool
629 uint32_t counterDescriptionOffset = counterNameOffset + // Counter name offset
630 4u + // Counter name length (uint32_t)
631 counterName.size() + // 18u
632 1u + // Null-terminator
633 1u; // Rounding to the next word
634 ARMNN_NO_CONVERSION_WARN_END
636 BOOST_CHECK(eventRecord[5] == counterNameOffset); // name_offset
637 BOOST_CHECK(eventRecord[6] == counterDescriptionOffset); // description_offset
638 BOOST_CHECK(eventRecord[7] == 0); // units_offset
640 auto eventRecordPool = reinterpret_cast<unsigned char*>(eventRecord.data() + 8u); // The start of the pool
641 size_t uint32_t_size = sizeof(uint32_t);
643 // The length of the SWTrace string (name)
644 BOOST_CHECK(eventRecordPool[counterNameOffset] == counterName.size() + 1);
646 BOOST_CHECK(std::memcmp(eventRecordPool +
647 counterNameOffset + // Offset
648 uint32_t_size, // The length of the name
650 counterName.size()) == 0); // name
651 // The null-terminator at the end of the name
652 BOOST_CHECK(eventRecordPool[counterNameOffset + uint32_t_size + counterName.size()] == '\0');
654 // The length of the SWTrace string (description)
655 BOOST_CHECK(eventRecordPool[counterDescriptionOffset] == counterDescription.size() + 1);
656 // The counter description
657 BOOST_CHECK(std::memcmp(eventRecordPool +
658 counterDescriptionOffset + // Offset
659 uint32_t_size, // The length of the description
660 counterDescription.data(),
661 counterDescription.size()) == 0); // description
662 // The null-terminator at the end of the description
663 BOOST_CHECK(eventRecordPool[counterDescriptionOffset + uint32_t_size + counterDescription.size()] == '\0');
666 BOOST_AUTO_TEST_CASE(CreateInvalidEventRecordTest1)
668 MockProfilingConnection mockProfilingConnection;
669 MockBufferManager mockBuffer(0);
670 SendCounterPacketTest sendCounterPacketTest(mockProfilingConnection, mockBuffer);
672 // Create a counter for testing
673 uint16_t counterUid = 7256;
674 uint16_t maxCounterUid = 132;
675 uint16_t deviceUid = 132;
676 uint16_t counterSetUid = 4497;
677 uint16_t counterClass = 1;
678 uint16_t counterInterpolation = 1;
679 double counterMultiplier = 1234.567f;
680 const std::string counterName = "some_invalid_counter £££"; // Invalid name
681 const std::string counterDescription = "a_counter_for_testing";
682 const std::string counterUnits = "Mrads2";
683 const CounterPtr counter = std::make_unique<Counter>(counterUid,
686 counterInterpolation,
693 BOOST_ASSERT(counter);
695 // Create an event record
696 SendCounterPacket::EventRecord eventRecord;
697 std::string errorMessage;
698 bool result = sendCounterPacketTest.CreateEventRecordTest(counter, eventRecord, errorMessage);
700 BOOST_CHECK(!result);
701 BOOST_CHECK(!errorMessage.empty());
702 BOOST_CHECK(eventRecord.empty());
705 BOOST_AUTO_TEST_CASE(CreateInvalidEventRecordTest2)
707 MockProfilingConnection mockProfilingConnection;
708 MockBufferManager mockBuffer(0);
709 SendCounterPacketTest sendCounterPacketTest(mockProfilingConnection, mockBuffer);
711 // Create a counter for testing
712 uint16_t counterUid = 7256;
713 uint16_t maxCounterUid = 132;
714 uint16_t deviceUid = 132;
715 uint16_t counterSetUid = 4497;
716 uint16_t counterClass = 1;
717 uint16_t counterInterpolation = 1;
718 double counterMultiplier = 1234.567f;
719 const std::string counterName = "some_invalid_counter";
720 const std::string counterDescription = "an invalid d€scription"; // Invalid description
721 const std::string counterUnits = "Mrads2";
722 const CounterPtr counter = std::make_unique<Counter>(counterUid,
725 counterInterpolation,
732 BOOST_ASSERT(counter);
734 // Create an event record
735 SendCounterPacket::EventRecord eventRecord;
736 std::string errorMessage;
737 bool result = sendCounterPacketTest.CreateEventRecordTest(counter, eventRecord, errorMessage);
739 BOOST_CHECK(!result);
740 BOOST_CHECK(!errorMessage.empty());
741 BOOST_CHECK(eventRecord.empty());
744 BOOST_AUTO_TEST_CASE(CreateInvalidEventRecordTest3)
746 MockProfilingConnection mockProfilingConnection;
747 MockBufferManager mockBuffer(0);
748 SendCounterPacketTest sendCounterPacketTest(mockProfilingConnection, mockBuffer);
750 // Create a counter for testing
751 uint16_t counterUid = 7256;
752 uint16_t maxCounterUid = 132;
753 uint16_t deviceUid = 132;
754 uint16_t counterSetUid = 4497;
755 uint16_t counterClass = 1;
756 uint16_t counterInterpolation = 1;
757 double counterMultiplier = 1234.567f;
758 const std::string counterName = "some_invalid_counter";
759 const std::string counterDescription = "a valid description";
760 const std::string counterUnits = "Mrad s2"; // Invalid units
761 const CounterPtr counter = std::make_unique<Counter>(counterUid,
764 counterInterpolation,
771 BOOST_ASSERT(counter);
773 // Create an event record
774 SendCounterPacket::EventRecord eventRecord;
775 std::string errorMessage;
776 bool result = sendCounterPacketTest.CreateEventRecordTest(counter, eventRecord, errorMessage);
778 BOOST_CHECK(!result);
779 BOOST_CHECK(!errorMessage.empty());
780 BOOST_CHECK(eventRecord.empty());
783 BOOST_AUTO_TEST_CASE(CreateCategoryRecordTest)
785 MockProfilingConnection mockProfilingConnection;
786 MockBufferManager mockBuffer(0);
787 SendCounterPacketTest sendCounterPacketTest(mockProfilingConnection, mockBuffer);
789 // Create a category for testing
790 const std::string categoryName = "some_category";
791 uint16_t deviceUid = 1302;
792 uint16_t counterSetUid = 20734;
793 const CategoryPtr category = std::make_unique<Category>(categoryName, deviceUid, counterSetUid);
794 BOOST_ASSERT(category);
795 category->m_Counters = { 11u, 23u, 5670u };
797 // Create a collection of counters
799 counters.insert(std::make_pair<uint16_t, CounterPtr>(11,
800 CounterPtr(new Counter(11,
810 counters.insert(std::make_pair<uint16_t, CounterPtr>(23,
811 CounterPtr(new Counter(23,
817 "the second counter",
821 counters.insert(std::make_pair<uint16_t, CounterPtr>(5670,
822 CounterPtr(new Counter(5670,
827 "and this is number 3",
832 Counter* counter1 = counters.find(11)->second.get();
833 Counter* counter2 = counters.find(23)->second.get();
834 Counter* counter3 = counters.find(5670)->second.get();
835 BOOST_ASSERT(counter1);
836 BOOST_ASSERT(counter2);
837 BOOST_ASSERT(counter3);
838 uint16_t categoryEventCount = boost::numeric_cast<uint16_t>(counters.size());
840 // Create a category record
841 SendCounterPacket::CategoryRecord categoryRecord;
842 std::string errorMessage;
843 bool result = sendCounterPacketTest.CreateCategoryRecordTest(category, counters, categoryRecord, errorMessage);
846 BOOST_CHECK(errorMessage.empty());
847 BOOST_CHECK(categoryRecord.size() == 80); // Size in words: header [4] + event pointer table [3] +
848 // category name [5] + event records [68 = 22 + 20 + 26]
850 uint16_t categoryRecordWord0[]
852 static_cast<uint16_t>(categoryRecord[0] >> 16),
853 static_cast<uint16_t>(categoryRecord[0])
855 uint16_t categoryRecordWord1[]
857 static_cast<uint16_t>(categoryRecord[1] >> 16),
858 static_cast<uint16_t>(categoryRecord[1])
860 BOOST_CHECK(categoryRecordWord0[0] == deviceUid); // device
861 BOOST_CHECK(categoryRecordWord0[1] == counterSetUid); // counter_set
862 BOOST_CHECK(categoryRecordWord1[0] == categoryEventCount); // event_count
863 BOOST_CHECK(categoryRecordWord1[1] == 0); // reserved
865 size_t uint32_t_size = sizeof(uint32_t);
867 ARMNN_NO_CONVERSION_WARN_BEGIN
868 uint32_t eventPointerTableOffset = 0; // The event pointer table is the first item in pool
869 uint32_t categoryNameOffset = eventPointerTableOffset + // Event pointer table offset
870 categoryEventCount * uint32_t_size; // The size of the event pointer table
871 ARMNN_NO_CONVERSION_WARN_END
873 BOOST_CHECK(categoryRecord[2] == eventPointerTableOffset); // event_pointer_table_offset
874 BOOST_CHECK(categoryRecord[3] == categoryNameOffset); // name_offset
876 auto categoryRecordPool = reinterpret_cast<unsigned char*>(categoryRecord.data() + 4u); // The start of the pool
878 // The event pointer table
879 uint32_t eventRecord0Offset = categoryRecordPool[eventPointerTableOffset + 0 * uint32_t_size];
880 uint32_t eventRecord1Offset = categoryRecordPool[eventPointerTableOffset + 1 * uint32_t_size];
881 uint32_t eventRecord2Offset = categoryRecordPool[eventPointerTableOffset + 2 * uint32_t_size];
882 BOOST_CHECK(eventRecord0Offset == 32);
883 BOOST_CHECK(eventRecord1Offset == 120);
884 BOOST_CHECK(eventRecord2Offset == 200);
886 // The length of the SWTrace namestring (name)
887 BOOST_CHECK(categoryRecordPool[categoryNameOffset] == categoryName.size() + 1);
889 BOOST_CHECK(std::memcmp(categoryRecordPool +
890 categoryNameOffset + // Offset
891 uint32_t_size, // The length of the name
893 categoryName.size()) == 0); // name
894 // The null-terminator at the end of the name
895 BOOST_CHECK(categoryRecordPool[categoryNameOffset + uint32_t_size + categoryName.size()] == '\0');
897 // For brevity, checking only the UIDs, max counter UIDs and names of the counters in the event records,
898 // as the event records already have a number of unit tests dedicated to them
900 // Counter1 UID and max counter UID
901 uint16_t eventRecord0Word0[2] = { 0u, 0u };
902 std::memcpy(eventRecord0Word0, categoryRecordPool + eventRecord0Offset, sizeof(eventRecord0Word0));
903 BOOST_CHECK(eventRecord0Word0[0] == counter1->m_Uid);
904 BOOST_CHECK(eventRecord0Word0[1] == counter1->m_MaxCounterUid);
907 uint32_t counter1NameOffset = 0;
908 std::memcpy(&counter1NameOffset, categoryRecordPool + eventRecord0Offset + 5u * uint32_t_size, uint32_t_size);
909 BOOST_CHECK(counter1NameOffset == 0);
910 // The length of the SWTrace string (name)
911 BOOST_CHECK(categoryRecordPool[eventRecord0Offset + // Offset to the event record
912 8u * uint32_t_size + // Offset to the event record pool
913 counter1NameOffset // Offset to the name of the counter
914 ] == counter1->m_Name.size() + 1); // The length of the name including the
917 BOOST_CHECK(std::memcmp(categoryRecordPool + // The beginning of the category pool
918 eventRecord0Offset + // Offset to the event record
919 8u * uint32_t_size + // Offset to the event record pool
920 counter1NameOffset + // Offset to the name of the counter
921 uint32_t_size, // The length of the name
922 counter1->m_Name.data(),
923 counter1->m_Name.size()) == 0); // name
924 // The null-terminator at the end of the counter1 name
925 BOOST_CHECK(categoryRecordPool[eventRecord0Offset + // Offset to the event record
926 8u * uint32_t_size + // Offset to the event record pool
927 counter1NameOffset + // Offset to the name of the counter
928 uint32_t_size + // The length of the name
929 counter1->m_Name.size() // The name of the counter
933 uint32_t counter2NameOffset = 0;
934 std::memcpy(&counter2NameOffset, categoryRecordPool + eventRecord1Offset + 5u * uint32_t_size, uint32_t_size);
935 BOOST_CHECK(counter2NameOffset == 0);
936 // The length of the SWTrace string (name)
937 BOOST_CHECK(categoryRecordPool[eventRecord1Offset + // Offset to the event record
938 8u * uint32_t_size + // Offset to the event record pool
939 counter2NameOffset // Offset to the name of the counter
940 ] == counter2->m_Name.size() + 1); // The length of the name including the
943 BOOST_CHECK(std::memcmp(categoryRecordPool + // The beginning of the category pool
944 eventRecord1Offset + // Offset to the event record
945 8u * uint32_t_size + // Offset to the event record pool
946 counter2NameOffset + // Offset to the name of the counter
947 uint32_t_size, // The length of the name
948 counter2->m_Name.data(),
949 counter2->m_Name.size()) == 0); // name
950 // The null-terminator at the end of the counter2 name
951 BOOST_CHECK(categoryRecordPool[eventRecord1Offset + // Offset to the event record
952 8u * uint32_t_size + // Offset to the event record pool
953 counter2NameOffset + // Offset to the name of the counter
954 uint32_t_size + // The length of the name
955 counter2->m_Name.size() // The name of the counter
959 uint32_t counter3NameOffset = 0;
960 std::memcpy(&counter3NameOffset, categoryRecordPool + eventRecord2Offset + 5u * uint32_t_size, uint32_t_size);
961 BOOST_CHECK(counter3NameOffset == 0);
962 // The length of the SWTrace string (name)
963 BOOST_CHECK(categoryRecordPool[eventRecord2Offset + // Offset to the event record
964 8u * uint32_t_size + // Offset to the event record pool
965 counter3NameOffset // Offset to the name of the counter
966 ] == counter3->m_Name.size() + 1); // The length of the name including the
969 BOOST_CHECK(std::memcmp(categoryRecordPool + // The beginning of the category pool
970 eventRecord2Offset + // Offset to the event record
971 8u * uint32_t_size + // Offset to the event record pool
972 counter3NameOffset + // Offset to the name of the counter
973 uint32_t_size, // The length of the name
974 counter3->m_Name.data(),
975 counter3->m_Name.size()) == 0); // name
976 // The null-terminator at the end of the counter3 name
977 BOOST_CHECK(categoryRecordPool[eventRecord2Offset + // Offset to the event record
978 8u * uint32_t_size + // Offset to the event record pool
979 counter3NameOffset + // Offset to the name of the counter
980 uint32_t_size + // The length of the name
981 counter3->m_Name.size() // The name of the counter
985 BOOST_AUTO_TEST_CASE(CreateInvalidCategoryRecordTest1)
987 MockProfilingConnection mockProfilingConnection;
988 MockBufferManager mockBuffer(0);
989 SendCounterPacketTest sendCounterPacketTest(mockProfilingConnection, mockBuffer);
991 // Create a category for testing
992 const std::string categoryName = "some invalid category";
993 uint16_t deviceUid = 1302;
994 uint16_t counterSetUid = 20734;
995 const CategoryPtr category = std::make_unique<Category>(categoryName, deviceUid, counterSetUid);
996 BOOST_CHECK(category);
998 // Create a category record
1000 SendCounterPacket::CategoryRecord categoryRecord;
1001 std::string errorMessage;
1002 bool result = sendCounterPacketTest.CreateCategoryRecordTest(category, counters, categoryRecord, errorMessage);
1004 BOOST_CHECK(!result);
1005 BOOST_CHECK(!errorMessage.empty());
1006 BOOST_CHECK(categoryRecord.empty());
1009 BOOST_AUTO_TEST_CASE(CreateInvalidCategoryRecordTest2)
1011 MockProfilingConnection mockProfilingConnection;
1012 MockBufferManager mockBuffer(0);
1013 SendCounterPacketTest sendCounterPacketTest(mockProfilingConnection, mockBuffer);
1015 // Create a category for testing
1016 const std::string categoryName = "some_category";
1017 uint16_t deviceUid = 1302;
1018 uint16_t counterSetUid = 20734;
1019 const CategoryPtr category = std::make_unique<Category>(categoryName, deviceUid, counterSetUid);
1020 BOOST_CHECK(category);
1021 category->m_Counters = { 11u, 23u, 5670u };
1023 // Create a collection of counters
1025 counters.insert(std::make_pair<uint16_t, CounterPtr>(11,
1026 CounterPtr(new Counter(11,
1031 "count€r1", // Invalid name
1032 "the first counter",
1037 Counter* counter1 = counters.find(11)->second.get();
1038 BOOST_CHECK(counter1);
1040 // Create a category record
1041 SendCounterPacket::CategoryRecord categoryRecord;
1042 std::string errorMessage;
1043 bool result = sendCounterPacketTest.CreateCategoryRecordTest(category, counters, categoryRecord, errorMessage);
1045 BOOST_CHECK(!result);
1046 BOOST_CHECK(!errorMessage.empty());
1047 BOOST_CHECK(categoryRecord.empty());
1050 BOOST_AUTO_TEST_CASE(SendCounterDirectoryPacketTest1)
1052 // The counter directory used for testing
1053 CounterDirectory counterDirectory;
1055 // Register a device
1056 const std::string device1Name = "device1";
1057 const Device* device1 = nullptr;
1058 BOOST_CHECK_NO_THROW(device1 = counterDirectory.RegisterDevice(device1Name, 3));
1059 BOOST_CHECK(counterDirectory.GetDeviceCount() == 1);
1060 BOOST_CHECK(device1);
1062 // Register a device
1063 const std::string device2Name = "device2";
1064 const Device* device2 = nullptr;
1065 BOOST_CHECK_NO_THROW(device2 = counterDirectory.RegisterDevice(device2Name));
1066 BOOST_CHECK(counterDirectory.GetDeviceCount() == 2);
1067 BOOST_CHECK(device2);
1069 // Buffer with not enough space
1070 MockProfilingConnection mockProfilingConnection;
1071 MockBufferManager mockBuffer(10);
1072 SendCounterPacket sendCounterPacket(mockProfilingConnection, mockBuffer);
1073 BOOST_CHECK_THROW(sendCounterPacket.SendCounterDirectoryPacket(counterDirectory),
1074 armnn::profiling::BufferExhaustion);
1077 BOOST_AUTO_TEST_CASE(SendCounterDirectoryPacketTest2)
1079 // The counter directory used for testing
1080 CounterDirectory counterDirectory;
1082 // Register a device
1083 const std::string device1Name = "device1";
1084 const Device* device1 = nullptr;
1085 BOOST_CHECK_NO_THROW(device1 = counterDirectory.RegisterDevice(device1Name, 3));
1086 BOOST_CHECK(counterDirectory.GetDeviceCount() == 1);
1087 BOOST_CHECK(device1);
1089 // Register a device
1090 const std::string device2Name = "device2";
1091 const Device* device2 = nullptr;
1092 BOOST_CHECK_NO_THROW(device2 = counterDirectory.RegisterDevice(device2Name));
1093 BOOST_CHECK(counterDirectory.GetDeviceCount() == 2);
1094 BOOST_CHECK(device2);
1096 // Register a counter set
1097 const std::string counterSet1Name = "counterset1";
1098 const CounterSet* counterSet1 = nullptr;
1099 BOOST_CHECK_NO_THROW(counterSet1 = counterDirectory.RegisterCounterSet(counterSet1Name));
1100 BOOST_CHECK(counterDirectory.GetCounterSetCount() == 1);
1101 BOOST_CHECK(counterSet1);
1103 // Register a category associated to "device1" and "counterset1"
1104 const std::string category1Name = "category1";
1105 const Category* category1 = nullptr;
1106 BOOST_CHECK_NO_THROW(category1 = counterDirectory.RegisterCategory(category1Name,
1108 counterSet1->m_Uid));
1109 BOOST_CHECK(counterDirectory.GetCategoryCount() == 1);
1110 BOOST_CHECK(category1);
1112 // Register a category not associated to "device2" but no counter set
1113 const std::string category2Name = "category2";
1114 const Category* category2 = nullptr;
1115 BOOST_CHECK_NO_THROW(category2 = counterDirectory.RegisterCategory(category2Name,
1117 BOOST_CHECK(counterDirectory.GetCategoryCount() == 2);
1118 BOOST_CHECK(category2);
1120 // Register a counter associated to "category1"
1121 const Counter* counter1 = nullptr;
1122 BOOST_CHECK_NO_THROW(counter1 = counterDirectory.RegisterCounter(category1Name,
1127 "counter1description",
1128 std::string("counter1units")));
1129 BOOST_CHECK(counterDirectory.GetCounterCount() == 3);
1130 BOOST_CHECK(counter1);
1132 // Register a counter associated to "category1"
1133 const Counter* counter2 = nullptr;
1134 BOOST_CHECK_NO_THROW(counter2 = counterDirectory.RegisterCounter(category1Name,
1139 "counter2description",
1140 std::string("counter2units"),
1141 armnn::EmptyOptional(),
1144 BOOST_CHECK(counterDirectory.GetCounterCount() == 4);
1145 BOOST_CHECK(counter2);
1147 // Register a counter associated to "category2"
1148 const Counter* counter3 = nullptr;
1149 BOOST_CHECK_NO_THROW(counter3 = counterDirectory.RegisterCounter(category2Name,
1154 "counter3description",
1155 armnn::EmptyOptional(),
1158 counterSet1->m_Uid));
1159 BOOST_CHECK(counterDirectory.GetCounterCount() == 9);
1160 BOOST_CHECK(counter3);
1162 // Buffer with enough space
1163 MockProfilingConnection mockProfilingConnection;
1164 MockBufferManager mockBuffer(1024);
1165 SendCounterPacket sendCounterPacket(mockProfilingConnection, mockBuffer);
1166 BOOST_CHECK_NO_THROW(sendCounterPacket.SendCounterDirectoryPacket(counterDirectory));
1168 // Get the readable buffer
1169 auto readBuffer = mockBuffer.GetReadableBuffer();
1171 // Check the packet header
1172 uint32_t packetHeaderWord0 = ReadUint32(readBuffer, 0);
1173 uint32_t packetHeaderWord1 = ReadUint32(readBuffer, 4);
1174 BOOST_TEST(((packetHeaderWord0 >> 26) & 0x3F) == 0); // packet_family
1175 BOOST_TEST(((packetHeaderWord0 >> 16) & 0x3FF) == 2); // packet_id
1176 BOOST_TEST(packetHeaderWord1 == 936); // data_length
1178 // Check the body header
1179 uint32_t bodyHeaderWord0 = ReadUint32(readBuffer, 8);
1180 uint32_t bodyHeaderWord1 = ReadUint32(readBuffer, 12);
1181 uint32_t bodyHeaderWord2 = ReadUint32(readBuffer, 16);
1182 uint32_t bodyHeaderWord3 = ReadUint32(readBuffer, 20);
1183 uint32_t bodyHeaderWord4 = ReadUint32(readBuffer, 24);
1184 uint32_t bodyHeaderWord5 = ReadUint32(readBuffer, 28);
1185 uint16_t deviceRecordCount = static_cast<uint16_t>(bodyHeaderWord0 >> 16);
1186 uint16_t counterSetRecordCount = static_cast<uint16_t>(bodyHeaderWord2 >> 16);
1187 uint16_t categoryRecordCount = static_cast<uint16_t>(bodyHeaderWord4 >> 16);
1188 BOOST_TEST(deviceRecordCount == 2); // device_records_count
1189 BOOST_TEST(bodyHeaderWord1 == 0); // device_records_pointer_table_offset
1190 BOOST_TEST(counterSetRecordCount == 1); // counter_set_count
1191 BOOST_TEST(bodyHeaderWord3 == 8); // counter_set_pointer_table_offset
1192 BOOST_TEST(categoryRecordCount == 2); // categories_count
1193 BOOST_TEST(bodyHeaderWord5 == 12); // categories_pointer_table_offset
1195 // Check the device records pointer table
1196 uint32_t deviceRecordOffset0 = ReadUint32(readBuffer, 32);
1197 uint32_t deviceRecordOffset1 = ReadUint32(readBuffer, 36);
1198 BOOST_TEST(deviceRecordOffset0 == 0); // Device record offset for "device1"
1199 BOOST_TEST(deviceRecordOffset1 == 20); // Device record offset for "device2"
1201 // Check the counter set pointer table
1202 uint32_t counterSetRecordOffset0 = ReadUint32(readBuffer, 40);
1203 BOOST_TEST(counterSetRecordOffset0 == 40); // Counter set record offset for "counterset1"
1205 // Check the category pointer table
1206 uint32_t categoryRecordOffset0 = ReadUint32(readBuffer, 44);
1207 uint32_t categoryRecordOffset1 = ReadUint32(readBuffer, 48);
1208 BOOST_TEST(categoryRecordOffset0 == 64); // Category record offset for "category1"
1209 BOOST_TEST(categoryRecordOffset1 == 476); // Category record offset for "category2"
1211 // Get the device record pool offset
1212 uint32_t uint32_t_size = sizeof(uint32_t);
1213 uint32_t packetBodyPoolOffset = 2u * uint32_t_size + // packet_header
1214 6u * uint32_t_size + // body_header
1215 deviceRecordCount * uint32_t_size + // Size of device_records_pointer_table
1216 counterSetRecordCount * uint32_t_size + // Size of counter_set_pointer_table
1217 categoryRecordCount * uint32_t_size; // Size of categories_pointer_table
1219 // Device record structure/collection used for testing
1224 uint32_t name_offset;
1225 uint32_t name_length;
1228 std::vector<DeviceRecord> deviceRecords;
1229 uint32_t deviceRecordsPointerTableOffset = 2u * uint32_t_size + // packet_header
1230 6u * uint32_t_size + // body_header
1231 bodyHeaderWord1; // device_records_pointer_table_offset
1233 const unsigned char* readData = readBuffer->GetReadableData();
1235 for (uint32_t i = 0; i < deviceRecordCount; i++)
1237 // Get the device record offset
1238 uint32_t deviceRecordOffset = ReadUint32(readBuffer, deviceRecordsPointerTableOffset + i * uint32_t_size);
1240 // Collect the data for the device record
1241 uint32_t deviceRecordWord0 = ReadUint32(readBuffer,
1242 packetBodyPoolOffset + deviceRecordOffset + 0 * uint32_t_size);
1243 uint32_t deviceRecordWord1 = ReadUint32(readBuffer,
1244 packetBodyPoolOffset + deviceRecordOffset + 1 * uint32_t_size);
1245 DeviceRecord deviceRecord;
1246 deviceRecord.uid = static_cast<uint16_t>(deviceRecordWord0 >> 16); // uid
1247 deviceRecord.cores = static_cast<uint16_t>(deviceRecordWord0); // cores
1248 deviceRecord.name_offset = deviceRecordWord1; // name_offset
1250 uint32_t deviceRecordPoolOffset = packetBodyPoolOffset + // Packet body offset
1251 deviceRecordOffset + // Device record offset
1252 2 * uint32_t_size + // Device record header
1253 deviceRecord.name_offset; // Device name offset
1254 uint32_t deviceRecordNameLength = ReadUint32(readBuffer, deviceRecordPoolOffset);
1255 deviceRecord.name_length = deviceRecordNameLength; // name_length
1256 unsigned char deviceRecordNameNullTerminator = // name null-terminator
1257 ReadUint8(readBuffer, deviceRecordPoolOffset + uint32_t_size + deviceRecordNameLength - 1);
1258 BOOST_CHECK(deviceRecordNameNullTerminator == '\0');
1259 std::vector<unsigned char> deviceRecordNameBuffer(deviceRecord.name_length - 1);
1260 std::memcpy(deviceRecordNameBuffer.data(),
1261 readData + deviceRecordPoolOffset + uint32_t_size, deviceRecordNameBuffer.size());
1262 deviceRecord.name.assign(deviceRecordNameBuffer.begin(), deviceRecordNameBuffer.end()); // name
1264 deviceRecords.push_back(deviceRecord);
1267 // Check that the device records are correct
1268 BOOST_CHECK(deviceRecords.size() == 2);
1269 for (const DeviceRecord& deviceRecord : deviceRecords)
1271 const Device* device = counterDirectory.GetDevice(deviceRecord.uid);
1272 BOOST_CHECK(device);
1273 BOOST_CHECK(device->m_Uid == deviceRecord.uid);
1274 BOOST_CHECK(device->m_Cores == deviceRecord.cores);
1275 BOOST_CHECK(device->m_Name == deviceRecord.name);
1278 // Counter set record structure/collection used for testing
1279 struct CounterSetRecord
1283 uint32_t name_offset;
1284 uint32_t name_length;
1287 std::vector<CounterSetRecord> counterSetRecords;
1288 uint32_t counterSetRecordsPointerTableOffset = 2u * uint32_t_size + // packet_header
1289 6u * uint32_t_size + // body_header
1290 bodyHeaderWord3; // counter_set_pointer_table_offset
1291 for (uint32_t i = 0; i < counterSetRecordCount; i++)
1293 // Get the counter set record offset
1294 uint32_t counterSetRecordOffset = ReadUint32(readBuffer,
1295 counterSetRecordsPointerTableOffset + i * uint32_t_size);
1297 // Collect the data for the counter set record
1298 uint32_t counterSetRecordWord0 = ReadUint32(readBuffer,
1299 packetBodyPoolOffset + counterSetRecordOffset + 0 * uint32_t_size);
1300 uint32_t counterSetRecordWord1 = ReadUint32(readBuffer,
1301 packetBodyPoolOffset + counterSetRecordOffset + 1 * uint32_t_size);
1302 CounterSetRecord counterSetRecord;
1303 counterSetRecord.uid = static_cast<uint16_t>(counterSetRecordWord0 >> 16); // uid
1304 counterSetRecord.count = static_cast<uint16_t>(counterSetRecordWord0); // count
1305 counterSetRecord.name_offset = counterSetRecordWord1; // name_offset
1307 uint32_t counterSetRecordPoolOffset = packetBodyPoolOffset + // Packet body offset
1308 counterSetRecordOffset + // Counter set record offset
1309 2 * uint32_t_size + // Counter set record header
1310 counterSetRecord.name_offset; // Counter set name offset
1311 uint32_t counterSetRecordNameLength = ReadUint32(readBuffer, counterSetRecordPoolOffset);
1312 counterSetRecord.name_length = counterSetRecordNameLength; // name_length
1313 unsigned char counterSetRecordNameNullTerminator = // name null-terminator
1314 ReadUint8(readBuffer, counterSetRecordPoolOffset + uint32_t_size + counterSetRecordNameLength - 1);
1315 BOOST_CHECK(counterSetRecordNameNullTerminator == '\0');
1316 std::vector<unsigned char> counterSetRecordNameBuffer(counterSetRecord.name_length - 1);
1317 std::memcpy(counterSetRecordNameBuffer.data(),
1318 readData + counterSetRecordPoolOffset + uint32_t_size, counterSetRecordNameBuffer.size());
1319 counterSetRecord.name.assign(counterSetRecordNameBuffer.begin(), counterSetRecordNameBuffer.end()); // name
1321 counterSetRecords.push_back(counterSetRecord);
1324 // Check that the counter set records are correct
1325 BOOST_CHECK(counterSetRecords.size() == 1);
1326 for (const CounterSetRecord& counterSetRecord : counterSetRecords)
1328 const CounterSet* counterSet = counterDirectory.GetCounterSet(counterSetRecord.uid);
1329 BOOST_CHECK(counterSet);
1330 BOOST_CHECK(counterSet->m_Uid == counterSetRecord.uid);
1331 BOOST_CHECK(counterSet->m_Count == counterSetRecord.count);
1332 BOOST_CHECK(counterSet->m_Name == counterSetRecord.name);
1335 // Event record structure/collection used for testing
1338 uint16_t counter_uid;
1339 uint16_t max_counter_uid;
1341 uint16_t counter_set;
1342 uint16_t counter_class;
1343 uint16_t interpolation;
1345 uint32_t name_offset;
1346 uint32_t name_length;
1348 uint32_t description_offset;
1349 uint32_t description_length;
1350 std::string description;
1351 uint32_t units_offset;
1352 uint32_t units_length;
1355 // Category record structure/collection used for testing
1356 struct CategoryRecord
1359 uint16_t counter_set;
1360 uint16_t event_count;
1361 uint32_t event_pointer_table_offset;
1362 uint32_t name_offset;
1363 uint32_t name_length;
1365 std::vector<uint32_t> event_pointer_table;
1366 std::vector<EventRecord> event_records;
1368 std::vector<CategoryRecord> categoryRecords;
1369 uint32_t categoryRecordsPointerTableOffset = 2u * uint32_t_size + // packet_header
1370 6u * uint32_t_size + // body_header
1371 bodyHeaderWord5; // categories_pointer_table_offset
1372 for (uint32_t i = 0; i < categoryRecordCount; i++)
1374 // Get the category record offset
1375 uint32_t categoryRecordOffset = ReadUint32(readBuffer, categoryRecordsPointerTableOffset + i * uint32_t_size);
1377 // Collect the data for the category record
1378 uint32_t categoryRecordWord0 = ReadUint32(readBuffer,
1379 packetBodyPoolOffset + categoryRecordOffset + 0 * uint32_t_size);
1380 uint32_t categoryRecordWord1 = ReadUint32(readBuffer,
1381 packetBodyPoolOffset + categoryRecordOffset + 1 * uint32_t_size);
1382 uint32_t categoryRecordWord2 = ReadUint32(readBuffer,
1383 packetBodyPoolOffset + categoryRecordOffset + 2 * uint32_t_size);
1384 uint32_t categoryRecordWord3 = ReadUint32(readBuffer,
1385 packetBodyPoolOffset + categoryRecordOffset + 3 * uint32_t_size);
1386 CategoryRecord categoryRecord;
1387 categoryRecord.device = static_cast<uint16_t>(categoryRecordWord0 >> 16); // device
1388 categoryRecord.counter_set = static_cast<uint16_t>(categoryRecordWord0); // counter_set
1389 categoryRecord.event_count = static_cast<uint16_t>(categoryRecordWord1 >> 16); // event_count
1390 categoryRecord.event_pointer_table_offset = categoryRecordWord2; // event_pointer_table_offset
1391 categoryRecord.name_offset = categoryRecordWord3; // name_offset
1393 uint32_t categoryRecordPoolOffset = packetBodyPoolOffset + // Packet body offset
1394 categoryRecordOffset + // Category record offset
1395 4 * uint32_t_size; // Category record header
1397 uint32_t categoryRecordNameLength = ReadUint32(readBuffer,
1398 categoryRecordPoolOffset + categoryRecord.name_offset);
1399 categoryRecord.name_length = categoryRecordNameLength; // name_length
1400 unsigned char categoryRecordNameNullTerminator =
1401 ReadUint8(readBuffer,
1402 categoryRecordPoolOffset +
1403 categoryRecord.name_offset +
1405 categoryRecordNameLength - 1); // name null-terminator
1406 BOOST_CHECK(categoryRecordNameNullTerminator == '\0');
1407 std::vector<unsigned char> categoryRecordNameBuffer(categoryRecord.name_length - 1);
1408 std::memcpy(categoryRecordNameBuffer.data(),
1410 categoryRecordPoolOffset +
1411 categoryRecord.name_offset +
1413 categoryRecordNameBuffer.size());
1414 categoryRecord.name.assign(categoryRecordNameBuffer.begin(), categoryRecordNameBuffer.end()); // name
1416 categoryRecord.event_pointer_table.resize(categoryRecord.event_count);
1417 for (uint32_t eventIndex = 0; eventIndex < categoryRecord.event_count; eventIndex++)
1419 uint32_t eventRecordOffset = ReadUint32(readBuffer,
1420 categoryRecordPoolOffset +
1421 categoryRecord.event_pointer_table_offset +
1422 eventIndex * uint32_t_size);
1423 categoryRecord.event_pointer_table[eventIndex] = eventRecordOffset;
1425 // Collect the data for the event record
1426 uint32_t eventRecordWord0 = ReadUint32(readBuffer,
1427 categoryRecordPoolOffset + eventRecordOffset + 0 * uint32_t_size);
1428 uint32_t eventRecordWord1 = ReadUint32(readBuffer,
1429 categoryRecordPoolOffset + eventRecordOffset + 1 * uint32_t_size);
1430 uint32_t eventRecordWord2 = ReadUint32(readBuffer,
1431 categoryRecordPoolOffset + eventRecordOffset + 2 * uint32_t_size);
1432 uint64_t eventRecordWord34 = ReadUint64(readBuffer,
1433 categoryRecordPoolOffset + eventRecordOffset + 3 * uint32_t_size);
1434 uint32_t eventRecordWord5 = ReadUint32(readBuffer,
1435 categoryRecordPoolOffset + eventRecordOffset + 5 * uint32_t_size);
1436 uint32_t eventRecordWord6 = ReadUint32(readBuffer,
1437 categoryRecordPoolOffset + eventRecordOffset + 6 * uint32_t_size);
1438 uint32_t eventRecordWord7 = ReadUint32(readBuffer,
1439 categoryRecordPoolOffset + eventRecordOffset + 7 * uint32_t_size);
1440 EventRecord eventRecord;
1441 eventRecord.counter_uid = static_cast<uint16_t>(eventRecordWord0); // counter_uid
1442 eventRecord.max_counter_uid = static_cast<uint16_t>(eventRecordWord0 >> 16); // max_counter_uid
1443 eventRecord.device = static_cast<uint16_t>(eventRecordWord1 >> 16); // device
1444 eventRecord.counter_set = static_cast<uint16_t>(eventRecordWord1); // counter_set
1445 eventRecord.counter_class = static_cast<uint16_t>(eventRecordWord2 >> 16); // class
1446 eventRecord.interpolation = static_cast<uint16_t>(eventRecordWord2); // interpolation
1447 std::memcpy(&eventRecord.multiplier, &eventRecordWord34, sizeof(eventRecord.multiplier)); // multiplier
1448 eventRecord.name_offset = static_cast<uint32_t>(eventRecordWord5); // name_offset
1449 eventRecord.description_offset = static_cast<uint32_t>(eventRecordWord6); // description_offset
1450 eventRecord.units_offset = static_cast<uint32_t>(eventRecordWord7); // units_offset
1452 uint32_t eventRecordPoolOffset = categoryRecordPoolOffset + // Category record pool offset
1453 eventRecordOffset + // Event record offset
1454 8 * uint32_t_size; // Event record header
1456 uint32_t eventRecordNameLength = ReadUint32(readBuffer,
1457 eventRecordPoolOffset + eventRecord.name_offset);
1458 eventRecord.name_length = eventRecordNameLength; // name_length
1459 unsigned char eventRecordNameNullTerminator =
1460 ReadUint8(readBuffer,
1461 eventRecordPoolOffset +
1462 eventRecord.name_offset +
1464 eventRecordNameLength - 1); // name null-terminator
1465 BOOST_CHECK(eventRecordNameNullTerminator == '\0');
1466 std::vector<unsigned char> eventRecordNameBuffer(eventRecord.name_length - 1);
1467 std::memcpy(eventRecordNameBuffer.data(),
1469 eventRecordPoolOffset +
1470 eventRecord.name_offset +
1472 eventRecordNameBuffer.size());
1473 eventRecord.name.assign(eventRecordNameBuffer.begin(), eventRecordNameBuffer.end()); // name
1475 uint32_t eventRecordDescriptionLength = ReadUint32(readBuffer,
1476 eventRecordPoolOffset + eventRecord.description_offset);
1477 eventRecord.description_length = eventRecordDescriptionLength; // description_length
1478 unsigned char eventRecordDescriptionNullTerminator =
1479 ReadUint8(readBuffer,
1480 eventRecordPoolOffset +
1481 eventRecord.description_offset +
1483 eventRecordDescriptionLength - 1); // description null-terminator
1484 BOOST_CHECK(eventRecordDescriptionNullTerminator == '\0');
1485 std::vector<unsigned char> eventRecordDescriptionBuffer(eventRecord.description_length - 1);
1486 std::memcpy(eventRecordDescriptionBuffer.data(),
1488 eventRecordPoolOffset +
1489 eventRecord.description_offset +
1491 eventRecordDescriptionBuffer.size());
1492 eventRecord.description.assign(eventRecordDescriptionBuffer.begin(),
1493 eventRecordDescriptionBuffer.end()); // description
1495 if (eventRecord.units_offset > 0)
1497 uint32_t eventRecordUnitsLength = ReadUint32(readBuffer,
1498 eventRecordPoolOffset + eventRecord.units_offset);
1499 eventRecord.units_length = eventRecordUnitsLength; // units_length
1500 unsigned char eventRecordUnitsNullTerminator =
1501 ReadUint8(readBuffer,
1502 eventRecordPoolOffset +
1503 eventRecord.units_offset +
1505 eventRecordUnitsLength - 1); // units null-terminator
1506 BOOST_CHECK(eventRecordUnitsNullTerminator == '\0');
1507 std::vector<unsigned char> eventRecordUnitsBuffer(eventRecord.units_length - 1);
1508 std::memcpy(eventRecordUnitsBuffer.data(),
1510 eventRecordPoolOffset +
1511 eventRecord.units_offset +
1513 eventRecordUnitsBuffer.size());
1514 eventRecord.units.assign(eventRecordUnitsBuffer.begin(), eventRecordUnitsBuffer.end()); // units
1517 categoryRecord.event_records.push_back(eventRecord);
1520 categoryRecords.push_back(categoryRecord);
1523 // Check that the category records are correct
1524 BOOST_CHECK(categoryRecords.size() == 2);
1525 for (const CategoryRecord& categoryRecord : categoryRecords)
1527 const Category* category = counterDirectory.GetCategory(categoryRecord.name);
1528 BOOST_CHECK(category);
1529 BOOST_CHECK(category->m_Name == categoryRecord.name);
1530 BOOST_CHECK(category->m_DeviceUid == categoryRecord.device);
1531 BOOST_CHECK(category->m_CounterSetUid == categoryRecord.counter_set);
1532 BOOST_CHECK(category->m_Counters.size() == categoryRecord.event_count);
1534 // Check that the event records are correct
1535 for (const EventRecord& eventRecord : categoryRecord.event_records)
1537 const Counter* counter = counterDirectory.GetCounter(eventRecord.counter_uid);
1538 BOOST_CHECK(counter);
1539 BOOST_CHECK(counter->m_MaxCounterUid == eventRecord.max_counter_uid);
1540 BOOST_CHECK(counter->m_DeviceUid == eventRecord.device);
1541 BOOST_CHECK(counter->m_CounterSetUid == eventRecord.counter_set);
1542 BOOST_CHECK(counter->m_Class == eventRecord.counter_class);
1543 BOOST_CHECK(counter->m_Interpolation == eventRecord.interpolation);
1544 BOOST_CHECK(counter->m_Multiplier == eventRecord.multiplier);
1545 BOOST_CHECK(counter->m_Name == eventRecord.name);
1546 BOOST_CHECK(counter->m_Description == eventRecord.description);
1547 BOOST_CHECK(counter->m_Units == eventRecord.units);
1552 BOOST_AUTO_TEST_CASE(SendCounterDirectoryPacketTest3)
1554 // Using a mock counter directory that allows to register invalid objects
1555 MockCounterDirectory counterDirectory;
1557 // Register an invalid device
1558 const std::string deviceName = "inv@lid dev!c€";
1559 const Device* device = nullptr;
1560 BOOST_CHECK_NO_THROW(device = counterDirectory.RegisterDevice(deviceName, 3));
1561 BOOST_CHECK(counterDirectory.GetDeviceCount() == 1);
1562 BOOST_CHECK(device);
1564 // Buffer with enough space
1565 MockProfilingConnection mockProfilingConnection;
1566 MockBufferManager mockBuffer(1024);
1567 SendCounterPacket sendCounterPacket(mockProfilingConnection, mockBuffer);
1568 BOOST_CHECK_THROW(sendCounterPacket.SendCounterDirectoryPacket(counterDirectory), armnn::RuntimeException);
1571 BOOST_AUTO_TEST_CASE(SendCounterDirectoryPacketTest4)
1573 // Using a mock counter directory that allows to register invalid objects
1574 MockCounterDirectory counterDirectory;
1576 // Register an invalid counter set
1577 const std::string counterSetName = "inv@lid count€rs€t";
1578 const CounterSet* counterSet = nullptr;
1579 BOOST_CHECK_NO_THROW(counterSet = counterDirectory.RegisterCounterSet(counterSetName));
1580 BOOST_CHECK(counterDirectory.GetCounterSetCount() == 1);
1581 BOOST_CHECK(counterSet);
1583 // Buffer with enough space
1584 MockProfilingConnection mockProfilingConnection;
1585 MockBufferManager mockBuffer(1024);
1586 SendCounterPacket sendCounterPacket(mockProfilingConnection, mockBuffer);
1587 BOOST_CHECK_THROW(sendCounterPacket.SendCounterDirectoryPacket(counterDirectory), armnn::RuntimeException);
1590 BOOST_AUTO_TEST_CASE(SendCounterDirectoryPacketTest5)
1592 // Using a mock counter directory that allows to register invalid objects
1593 MockCounterDirectory counterDirectory;
1595 // Register an invalid category
1596 const std::string categoryName = "c@t€gory";
1597 const Category* category = nullptr;
1598 BOOST_CHECK_NO_THROW(category = counterDirectory.RegisterCategory(categoryName));
1599 BOOST_CHECK(counterDirectory.GetCategoryCount() == 1);
1600 BOOST_CHECK(category);
1602 // Buffer with enough space
1603 MockProfilingConnection mockProfilingConnection;
1604 MockBufferManager mockBuffer(1024);
1605 SendCounterPacket sendCounterPacket(mockProfilingConnection, mockBuffer);
1606 BOOST_CHECK_THROW(sendCounterPacket.SendCounterDirectoryPacket(counterDirectory), armnn::RuntimeException);
1609 BOOST_AUTO_TEST_CASE(SendCounterDirectoryPacketTest6)
1611 // Using a mock counter directory that allows to register invalid objects
1612 MockCounterDirectory counterDirectory;
1614 // Register an invalid device
1615 const std::string deviceName = "inv@lid dev!c€";
1616 const Device* device = nullptr;
1617 BOOST_CHECK_NO_THROW(device = counterDirectory.RegisterDevice(deviceName, 3));
1618 BOOST_CHECK(counterDirectory.GetDeviceCount() == 1);
1619 BOOST_CHECK(device);
1621 // Register an invalid counter set
1622 const std::string counterSetName = "inv@lid count€rs€t";
1623 const CounterSet* counterSet = nullptr;
1624 BOOST_CHECK_NO_THROW(counterSet = counterDirectory.RegisterCounterSet(counterSetName));
1625 BOOST_CHECK(counterDirectory.GetCounterSetCount() == 1);
1626 BOOST_CHECK(counterSet);
1628 // Register an invalid category associated to an invalid device and an invalid counter set
1629 const std::string categoryName = "c@t€gory";
1630 const Category* category = nullptr;
1631 BOOST_CHECK_NO_THROW(category = counterDirectory.RegisterCategory(categoryName,
1633 counterSet->m_Uid));
1634 BOOST_CHECK(counterDirectory.GetCategoryCount() == 1);
1635 BOOST_CHECK(category);
1637 // Buffer with enough space
1638 MockProfilingConnection mockProfilingConnection;
1639 MockBufferManager mockBuffer(1024);
1640 SendCounterPacket sendCounterPacket(mockProfilingConnection, mockBuffer);
1641 BOOST_CHECK_THROW(sendCounterPacket.SendCounterDirectoryPacket(counterDirectory), armnn::RuntimeException);
1644 BOOST_AUTO_TEST_CASE(SendCounterDirectoryPacketTest7)
1646 // Using a mock counter directory that allows to register invalid objects
1647 MockCounterDirectory counterDirectory;
1649 // Register an valid device
1650 const std::string deviceName = "valid device";
1651 const Device* device = nullptr;
1652 BOOST_CHECK_NO_THROW(device = counterDirectory.RegisterDevice(deviceName, 3));
1653 BOOST_CHECK(counterDirectory.GetDeviceCount() == 1);
1654 BOOST_CHECK(device);
1656 // Register an valid counter set
1657 const std::string counterSetName = "valid counterset";
1658 const CounterSet* counterSet = nullptr;
1659 BOOST_CHECK_NO_THROW(counterSet = counterDirectory.RegisterCounterSet(counterSetName));
1660 BOOST_CHECK(counterDirectory.GetCounterSetCount() == 1);
1661 BOOST_CHECK(counterSet);
1663 // Register an valid category associated to a valid device and a valid counter set
1664 const std::string categoryName = "category";
1665 const Category* category = nullptr;
1666 BOOST_CHECK_NO_THROW(category = counterDirectory.RegisterCategory(categoryName,
1668 counterSet->m_Uid));
1669 BOOST_CHECK(counterDirectory.GetCategoryCount() == 1);
1670 BOOST_CHECK(category);
1672 // Register an invalid counter associated to a valid category
1673 const Counter* counter = nullptr;
1674 BOOST_CHECK_NO_THROW(counter = counterDirectory.RegisterCounter(categoryName,
1679 "counter description",
1680 std::string("invalid counter units"),
1683 counterSet->m_Uid));
1684 BOOST_CHECK(counterDirectory.GetCounterCount() == 5);
1685 BOOST_CHECK(counter);
1687 // Buffer with enough space
1688 MockProfilingConnection mockProfilingConnection;
1689 MockBufferManager mockBuffer(1024);
1690 SendCounterPacket sendCounterPacket(mockProfilingConnection, mockBuffer);
1691 BOOST_CHECK_THROW(sendCounterPacket.SendCounterDirectoryPacket(counterDirectory), armnn::RuntimeException);
1694 BOOST_AUTO_TEST_CASE(SendThreadTest0)
1696 MockProfilingConnection mockProfilingConnection;
1697 MockStreamCounterBuffer mockStreamCounterBuffer(0);
1698 SendCounterPacket sendCounterPacket(mockProfilingConnection, mockStreamCounterBuffer);
1700 // Try to start the send thread many times, it must only start once
1702 sendCounterPacket.Start();
1703 BOOST_CHECK(sendCounterPacket.IsRunning());
1704 sendCounterPacket.Start();
1705 sendCounterPacket.Start();
1706 sendCounterPacket.Start();
1707 sendCounterPacket.Start();
1708 BOOST_CHECK(sendCounterPacket.IsRunning());
1710 std::this_thread::sleep_for(std::chrono::seconds(1));
1712 sendCounterPacket.Stop();
1713 BOOST_CHECK(!sendCounterPacket.IsRunning());
1716 BOOST_AUTO_TEST_CASE(SendThreadTest1)
1718 unsigned int totalWrittenSize = 0;
1720 MockProfilingConnection mockProfilingConnection;
1721 MockStreamCounterBuffer mockStreamCounterBuffer(1024);
1722 SendCounterPacket sendCounterPacket(mockProfilingConnection, mockStreamCounterBuffer);
1723 sendCounterPacket.Start();
1725 // Interleaving writes and reads to/from the buffer with pauses to test that the send thread actually waits for
1726 // something to become available for reading
1728 std::this_thread::sleep_for(std::chrono::seconds(1));
1730 CounterDirectory counterDirectory;
1731 sendCounterPacket.SendStreamMetaDataPacket();
1733 // Get the size of the Stream Metadata Packet
1734 std::string processName = GetProcessName().substr(0, 60);
1735 unsigned int processNameSize = processName.empty() ? 0 : boost::numeric_cast<unsigned int>(processName.size()) + 1;
1736 unsigned int streamMetadataPacketsize = 118 + processNameSize;
1737 totalWrittenSize += streamMetadataPacketsize;
1739 sendCounterPacket.SetReadyToRead();
1741 std::this_thread::sleep_for(std::chrono::milliseconds(100));
1743 sendCounterPacket.SendCounterDirectoryPacket(counterDirectory);
1745 // Get the size of the Counter Directory Packet
1746 unsigned int counterDirectoryPacketSize = 32;
1747 totalWrittenSize += counterDirectoryPacketSize;
1749 sendCounterPacket.SetReadyToRead();
1751 std::this_thread::sleep_for(std::chrono::milliseconds(100));
1753 sendCounterPacket.SendPeriodicCounterCapturePacket(123u,
1759 // Get the size of the Periodic Counter Capture Packet
1760 unsigned int periodicCounterCapturePacketSize = 28;
1761 totalWrittenSize += periodicCounterCapturePacketSize;
1763 sendCounterPacket.SetReadyToRead();
1765 std::this_thread::sleep_for(std::chrono::milliseconds(100));
1767 sendCounterPacket.SendPeriodicCounterCapturePacket(44u,
1772 // Get the size of the Periodic Counter Capture Packet
1773 periodicCounterCapturePacketSize = 22;
1774 totalWrittenSize += periodicCounterCapturePacketSize;
1776 sendCounterPacket.SendPeriodicCounterCapturePacket(1234u,
1785 // Get the size of the Periodic Counter Capture Packet
1786 periodicCounterCapturePacketSize = 46;
1787 totalWrittenSize += periodicCounterCapturePacketSize;
1789 sendCounterPacket.SendPeriodicCounterCapturePacket(997u,
1797 // Get the size of the Periodic Counter Capture Packet
1798 periodicCounterCapturePacketSize = 40;
1799 totalWrittenSize += periodicCounterCapturePacketSize;
1801 sendCounterPacket.SetReadyToRead();
1803 std::this_thread::sleep_for(std::chrono::milliseconds(100));
1805 sendCounterPacket.SendPeriodicCounterSelectionPacket(1000u, { 1345u, 254u, 4536u, 408u, 54u, 6323u, 428u, 1u, 6u });
1807 // Get the size of the Periodic Counter Capture Packet
1808 periodicCounterCapturePacketSize = 30;
1809 totalWrittenSize += periodicCounterCapturePacketSize;
1811 sendCounterPacket.SetReadyToRead();
1813 // To test an exact value of the "read size" in the mock buffer, wait two seconds to allow the send thread to
1814 // read all what's remaining in the buffer
1815 std::this_thread::sleep_for(std::chrono::seconds(2));
1817 sendCounterPacket.Stop();
1819 BOOST_CHECK(mockStreamCounterBuffer.GetCommittedSize() == totalWrittenSize);
1820 BOOST_CHECK(mockStreamCounterBuffer.GetReadableSize() == totalWrittenSize);
1821 BOOST_CHECK(mockStreamCounterBuffer.GetReadSize() == totalWrittenSize);
1824 BOOST_AUTO_TEST_CASE(SendThreadTest2)
1826 unsigned int totalWrittenSize = 0;
1828 MockProfilingConnection mockProfilingConnection;
1829 MockStreamCounterBuffer mockStreamCounterBuffer(1024);
1830 SendCounterPacket sendCounterPacket(mockProfilingConnection, mockStreamCounterBuffer);
1831 sendCounterPacket.Start();
1833 // Adding many spurious "ready to read" signals throughout the test to check that the send thread is
1834 // capable of handling unnecessary read requests
1836 std::this_thread::sleep_for(std::chrono::seconds(1));
1838 sendCounterPacket.SetReadyToRead();
1840 CounterDirectory counterDirectory;
1841 sendCounterPacket.SendStreamMetaDataPacket();
1843 // Get the size of the Stream Metadata Packet
1844 std::string processName = GetProcessName().substr(0, 60);
1845 unsigned int processNameSize = processName.empty() ? 0 : boost::numeric_cast<unsigned int>(processName.size()) + 1;
1846 unsigned int streamMetadataPacketsize = 118 + processNameSize;
1847 totalWrittenSize += streamMetadataPacketsize;
1849 sendCounterPacket.SetReadyToRead();
1851 std::this_thread::sleep_for(std::chrono::milliseconds(100));
1853 sendCounterPacket.SendCounterDirectoryPacket(counterDirectory);
1855 // Get the size of the Counter Directory Packet
1856 unsigned int counterDirectoryPacketSize = 32;
1857 totalWrittenSize += counterDirectoryPacketSize;
1859 sendCounterPacket.SetReadyToRead();
1860 sendCounterPacket.SetReadyToRead();
1862 std::this_thread::sleep_for(std::chrono::milliseconds(100));
1864 sendCounterPacket.SendPeriodicCounterCapturePacket(123u,
1870 // Get the size of the Periodic Counter Capture Packet
1871 unsigned int periodicCounterCapturePacketSize = 28;
1872 totalWrittenSize += periodicCounterCapturePacketSize;
1874 sendCounterPacket.SetReadyToRead();
1876 std::this_thread::sleep_for(std::chrono::milliseconds(100));
1878 sendCounterPacket.SetReadyToRead();
1879 sendCounterPacket.SetReadyToRead();
1880 sendCounterPacket.SetReadyToRead();
1882 std::this_thread::sleep_for(std::chrono::milliseconds(100));
1884 sendCounterPacket.SetReadyToRead();
1885 sendCounterPacket.SendPeriodicCounterCapturePacket(44u,
1890 // Get the size of the Periodic Counter Capture Packet
1891 periodicCounterCapturePacketSize = 22;
1892 totalWrittenSize += periodicCounterCapturePacketSize;
1894 sendCounterPacket.SendPeriodicCounterCapturePacket(1234u,
1903 // Get the size of the Periodic Counter Capture Packet
1904 periodicCounterCapturePacketSize = 46;
1905 totalWrittenSize += periodicCounterCapturePacketSize;
1907 sendCounterPacket.SetReadyToRead();
1908 sendCounterPacket.SendPeriodicCounterCapturePacket(997u,
1916 // Get the size of the Periodic Counter Capture Packet
1917 periodicCounterCapturePacketSize = 40;
1918 totalWrittenSize += periodicCounterCapturePacketSize;
1920 sendCounterPacket.SetReadyToRead();
1921 sendCounterPacket.SetReadyToRead();
1923 std::this_thread::sleep_for(std::chrono::milliseconds(100));
1925 sendCounterPacket.SendPeriodicCounterSelectionPacket(1000u, { 1345u, 254u, 4536u, 408u, 54u, 6323u, 428u, 1u, 6u });
1927 // Get the size of the Periodic Counter Capture Packet
1928 periodicCounterCapturePacketSize = 30;
1929 totalWrittenSize += periodicCounterCapturePacketSize;
1931 sendCounterPacket.SetReadyToRead();
1933 // To test an exact value of the "read size" in the mock buffer, wait two seconds to allow the send thread to
1934 // read all what's remaining in the buffer
1935 std::this_thread::sleep_for(std::chrono::seconds(2));
1937 sendCounterPacket.Stop();
1939 BOOST_CHECK(mockStreamCounterBuffer.GetCommittedSize() == totalWrittenSize);
1940 BOOST_CHECK(mockStreamCounterBuffer.GetReadableSize() == totalWrittenSize);
1941 BOOST_CHECK(mockStreamCounterBuffer.GetReadSize() == totalWrittenSize);
1944 BOOST_AUTO_TEST_CASE(SendThreadTest3)
1946 unsigned int totalWrittenSize = 0;
1948 MockProfilingConnection mockProfilingConnection;
1949 MockStreamCounterBuffer mockStreamCounterBuffer(1024);
1950 SendCounterPacket sendCounterPacket(mockProfilingConnection, mockStreamCounterBuffer);
1951 sendCounterPacket.Start();
1953 // Not using pauses or "grace periods" to stress test the send thread
1955 sendCounterPacket.SetReadyToRead();
1957 CounterDirectory counterDirectory;
1958 sendCounterPacket.SendStreamMetaDataPacket();
1960 // Get the size of the Stream Metadata Packet
1961 std::string processName = GetProcessName().substr(0, 60);
1962 unsigned int processNameSize = processName.empty() ? 0 : boost::numeric_cast<unsigned int>(processName.size()) + 1;
1963 unsigned int streamMetadataPacketsize = 118 + processNameSize;
1964 totalWrittenSize += streamMetadataPacketsize;
1966 sendCounterPacket.SetReadyToRead();
1967 sendCounterPacket.SendCounterDirectoryPacket(counterDirectory);
1969 // Get the size of the Counter Directory Packet
1970 unsigned int counterDirectoryPacketSize =32;
1971 totalWrittenSize += counterDirectoryPacketSize;
1973 sendCounterPacket.SetReadyToRead();
1974 sendCounterPacket.SetReadyToRead();
1975 sendCounterPacket.SendPeriodicCounterCapturePacket(123u,
1981 // Get the size of the Periodic Counter Capture Packet
1982 unsigned int periodicCounterCapturePacketSize = 28;
1983 totalWrittenSize += periodicCounterCapturePacketSize;
1985 sendCounterPacket.SetReadyToRead();
1986 sendCounterPacket.SetReadyToRead();
1987 sendCounterPacket.SetReadyToRead();
1988 sendCounterPacket.SetReadyToRead();
1989 sendCounterPacket.SetReadyToRead();
1990 sendCounterPacket.SendPeriodicCounterCapturePacket(44u,
1995 // Get the size of the Periodic Counter Capture Packet
1996 periodicCounterCapturePacketSize = 22;
1997 totalWrittenSize += periodicCounterCapturePacketSize;
1999 sendCounterPacket.SendPeriodicCounterCapturePacket(1234u,
2008 // Get the size of the Periodic Counter Capture Packet
2009 periodicCounterCapturePacketSize = 46;
2010 totalWrittenSize += periodicCounterCapturePacketSize;
2012 sendCounterPacket.SetReadyToRead();
2013 sendCounterPacket.SetReadyToRead();
2014 sendCounterPacket.SendPeriodicCounterCapturePacket(997u,
2022 // Get the size of the Periodic Counter Capture Packet
2023 periodicCounterCapturePacketSize = 40;
2024 totalWrittenSize += periodicCounterCapturePacketSize;
2026 sendCounterPacket.SetReadyToRead();
2027 sendCounterPacket.SetReadyToRead();
2028 sendCounterPacket.SendPeriodicCounterSelectionPacket(1000u, { 1345u, 254u, 4536u, 408u, 54u, 6323u, 428u, 1u, 6u });
2030 // Get the size of the Periodic Counter Capture Packet
2031 periodicCounterCapturePacketSize = 30;
2032 totalWrittenSize += periodicCounterCapturePacketSize;
2034 sendCounterPacket.SetReadyToRead();
2036 // Abruptly terminating the send thread, the amount of data sent may be less that the amount written (the send
2037 // thread is not guaranteed to flush the buffer)
2038 sendCounterPacket.Stop();
2040 BOOST_CHECK(mockStreamCounterBuffer.GetCommittedSize() == totalWrittenSize);
2041 BOOST_CHECK(mockStreamCounterBuffer.GetReadableSize() <= totalWrittenSize);
2042 BOOST_CHECK(mockStreamCounterBuffer.GetReadSize() <= totalWrittenSize);
2043 BOOST_CHECK(mockStreamCounterBuffer.GetReadSize() <= mockStreamCounterBuffer.GetReadableSize());
2044 BOOST_CHECK(mockStreamCounterBuffer.GetReadSize() <= mockStreamCounterBuffer.GetCommittedSize());
2047 BOOST_AUTO_TEST_SUITE_END()