13 #include <common/include/Constants.hpp> 15 #include <boost/format.hpp> 16 #include <boost/numeric/conversion/cast.hpp> 35 const uint32_t infoSize =
numeric_cast<uint32_t>(info.size()) + 1;
36 const uint32_t hardwareVersionSize =
numeric_cast<uint32_t>(hardwareVersion.size()) + 1;
37 const uint32_t softwareVersionSize =
numeric_cast<uint32_t>(softwareVersion.size()) + 1;
38 const uint32_t processNameSize =
numeric_cast<uint32_t>(processName.size()) + 1;
40 const uint32_t sizeUint32 =
sizeof(uint32_t);
42 const uint32_t headerSize = 2 * sizeUint32;
43 const uint32_t bodySize = 10 * sizeUint32;
44 const uint32_t packetVersionCountSize = sizeUint32;
53 const uint32_t packetVersionEntries = 6;
55 const uint32_t payloadSize =
numeric_cast<uint32_t>(infoSize + hardwareVersionSize + softwareVersionSize +
56 processNameSize + packetVersionCountSize +
57 (packetVersionEntries * 2 * sizeUint32));
59 const uint32_t totalSize = headerSize + bodySize + payloadSize;
61 uint32_t reserved = 0;
65 if (writeBuffer ==
nullptr || reserved < totalSize)
67 CancelOperationAndThrow<BufferExhaustion>(
69 boost::str(boost::format(
"No space left in buffer. Unable to reserve (%1%) bytes.") % totalSize));
78 WriteUint32(writeBuffer, offset, totalSize - headerSize);
83 WriteUint32(writeBuffer, offset, armnnProfiling::PIPE_MAGIC);
90 WriteUint32(writeBuffer, offset, numeric_cast<uint32_t>(pid));
92 uint32_t poolOffset = bodySize;
95 poolOffset += infoSize;
98 poolOffset += hardwareVersionSize;
100 offset += sizeUint32;
101 poolOffset += softwareVersionSize;
103 offset += sizeUint32;
104 poolOffset += processNameSize;
106 offset += sizeUint32;
108 offset += sizeUint32;
114 memcpy(&writeBuffer->GetWritableData()[offset], info.c_str(), infoSize);
118 memcpy(&writeBuffer->GetWritableData()[offset], hardwareVersion.c_str(), hardwareVersionSize);
119 offset += hardwareVersionSize;
120 memcpy(&writeBuffer->GetWritableData()[offset], softwareVersion.c_str(), softwareVersionSize);
121 offset += softwareVersionSize;
122 memcpy(&writeBuffer->GetWritableData()[offset], processName.c_str(), processNameSize);
123 offset += processNameSize;
125 if (packetVersionEntries)
128 WriteUint32(writeBuffer, offset, packetVersionEntries << 16);
131 uint32_t packetFamily = 0;
132 uint32_t packetId = 0;
134 offset += sizeUint32;
135 for (uint32_t i = 0; i < packetVersionEntries - 1; ++i)
137 WriteUint32(writeBuffer, offset, ((packetFamily & 0x3F) << 26) | ((packetId++ & 0x3FF) << 16));
138 offset += sizeUint32;
140 offset += sizeUint32;
146 WriteUint32(writeBuffer, offset, ((packetFamily & 0x3F) << 26) | ((packetId & 0x3FF) << 16));
147 offset += sizeUint32;
153 CancelOperationAndThrow<RuntimeException>(writeBuffer,
"Error processing packet.");
156 m_BufferManager.
Commit(writeBuffer, totalSize,
false);
162 std::string& errorMessage)
164 using namespace boost::numeric;
168 const std::string& categoryName = category->m_Name;
172 std::vector<uint16_t> categoryCounters;
173 for (
size_t counterIndex = 0; counterIndex < category->m_Counters.size(); ++counterIndex)
175 uint16_t counterUid = category->m_Counters.at(counterIndex);
176 auto it = counters.find(counterUid);
177 if (it == counters.end())
179 errorMessage = boost::str(boost::format(
"Counter (%1%) not found in category (%2%)")
180 % counterUid % category->m_Name );
186 if (counterUid == counter->m_MaxCounterUid)
188 categoryCounters.emplace_back(counterUid);
191 if (categoryCounters.empty())
193 errorMessage = boost::str(boost::format(
"No valid counters found in category (%1%)")% categoryName);
201 std::vector<uint32_t> categoryNameBuffer;
202 if (!StringToSwTraceString<SwTraceNameCharPolicy>(categoryName, categoryNameBuffer))
204 errorMessage = boost::str(boost::format(
"Cannot convert the name of category (%1%) to an SWTrace namestring")
212 const uint32_t categoryRecordWord1 =
static_cast<uint32_t
>(categoryCounters.size()) << 16;
217 const uint32_t categoryRecordWord2 =
static_cast<uint32_t
>(3u *
uint32_t_size);
220 const size_t counterCount = categoryCounters.size();
221 std::vector<EventRecord> eventRecords(counterCount);
222 std::vector<uint32_t> eventRecordOffsets(counterCount, 0);
223 size_t eventRecordsSize = 0;
224 uint32_t eventRecordsOffset =
225 numeric_cast<uint32_t>((eventRecords.size() + categoryNameBuffer.size()) * uint32_t_size);
226 for (
size_t counterIndex = 0, eventRecordIndex = 0, eventRecordOffsetIndex = 0;
227 counterIndex < counterCount;
228 counterIndex++, eventRecordIndex++, eventRecordOffsetIndex++)
230 uint16_t counterUid = categoryCounters.at(counterIndex);
231 auto it = counters.find(counterUid);
234 EventRecord& eventRecord = eventRecords.at(eventRecordIndex);
241 eventRecordsSize += eventRecord.size();
244 eventRecordOffsets[eventRecordOffsetIndex] = eventRecordsOffset;
250 const uint32_t categoryRecordWord3 =
numeric_cast<uint32_t>((3u + eventRecordOffsets.size()) * uint32_t_size);
253 const size_t categoryRecordSize = 3u +
255 eventRecordOffsets.size() +
256 categoryNameBuffer.size() +
260 categoryRecord.resize(categoryRecordSize);
264 categoryRecord[0] = categoryRecordWord1;
265 categoryRecord[1] = categoryRecordWord2;
266 categoryRecord[2] = categoryRecordWord3;
267 auto offset = categoryRecord.begin() + 3u;
268 std::copy(eventRecordOffsets.begin(), eventRecordOffsets.end(), offset);
269 offset += eventRecordOffsets.size();
270 std::copy(categoryNameBuffer.begin(), categoryNameBuffer.end(), offset);
271 offset += categoryNameBuffer.size();
272 for (
const EventRecord& eventRecord : eventRecords)
274 std::copy(eventRecord.begin(), eventRecord.end(), offset);
275 offset += eventRecord.size();
284 std::string& errorMessage)
288 uint16_t deviceUid = device->m_Uid;
289 const std::string& deviceName = device->m_Name;
290 uint16_t deviceCores = device->m_Cores;
297 const uint32_t deviceRecordWord0 = (
static_cast<uint32_t
>(deviceUid) << 16) |
298 (
static_cast<uint32_t
>(deviceCores));
302 const uint32_t deviceRecordWord1 = 8u;
306 std::vector<uint32_t> deviceNameBuffer;
307 if (!StringToSwTraceString<SwTraceCharPolicy>(deviceName, deviceNameBuffer))
309 errorMessage = boost::str(boost::format(
"Cannot convert the name of device %1% (%2%) to an SWTrace string")
316 const size_t deviceRecordSize = 2u +
317 deviceNameBuffer.size();
321 deviceRecord.resize(deviceRecordSize);
324 deviceRecord[0] = deviceRecordWord0;
325 deviceRecord[1] = deviceRecordWord1;
326 auto offset = deviceRecord.begin() + 2u;
327 std::copy(deviceNameBuffer.begin(), deviceNameBuffer.end(), offset);
334 std::string& errorMessage)
338 uint16_t counterSetUid = counterSet->m_Uid;
339 const std::string& counterSetName = counterSet->m_Name;
340 uint16_t counterSetCount = counterSet->m_Count;
347 const uint32_t counterSetRecordWord0 = (
static_cast<uint32_t
>(counterSetUid) << 16) |
348 (
static_cast<uint32_t
>(counterSetCount));
352 const uint32_t counterSetRecordWord1 = 8u;
356 std::vector<uint32_t> counterSetNameBuffer;
357 if (!StringToSwTraceString<SwTraceNameCharPolicy>(counterSet->m_Name, counterSetNameBuffer))
359 errorMessage = boost::str(boost::format(
"Cannot convert the name of counter set %1% (%2%) to " 360 "an SWTrace namestring")
367 const size_t counterSetRecordSize = 2u +
368 counterSetNameBuffer.size();
372 counterSetRecord.resize(counterSetRecordSize);
375 counterSetRecord[0] = counterSetRecordWord0;
376 counterSetRecord[1] = counterSetRecordWord1;
377 auto offset = counterSetRecord.begin() + 2u;
378 std::copy(counterSetNameBuffer.begin(), counterSetNameBuffer.end(), offset);
385 std::string& errorMessage)
387 using namespace boost::numeric;
391 uint16_t counterUid = counter->m_Uid;
392 uint16_t maxCounterUid = counter->m_MaxCounterUid;
393 uint16_t deviceUid = counter->m_DeviceUid;
394 uint16_t counterSetUid = counter->m_CounterSetUid;
395 uint16_t counterClass = counter->m_Class;
396 uint16_t counterInterpolation = counter->m_Interpolation;
397 double counterMultiplier = counter->m_Multiplier;
398 const std::string& counterName = counter->m_Name;
399 const std::string& counterDescription = counter->m_Description;
400 const std::string& counterUnits = counter->m_Units;
403 ARMNN_ASSERT(counterInterpolation == 0 || counterInterpolation == 1);
413 const size_t eventRecordBlockSize = 8u;
422 const uint32_t eventRecordWord0 = (
static_cast<uint32_t
>(maxCounterUid) << 16) |
423 (
static_cast<uint32_t
>(counterUid));
430 const uint32_t eventRecordWord1 = (
static_cast<uint32_t
>(deviceUid) << 16) |
431 (
static_cast<uint32_t
>(counterSetUid));
436 const uint32_t eventRecordWord2 = (
static_cast<uint32_t
>(counterClass) << 16) |
437 (
static_cast<uint32_t
>(counterInterpolation));
442 uint32_t multiplier[2] = { 0u, 0u };
443 ARMNN_ASSERT(
sizeof(counterMultiplier) ==
sizeof(multiplier));
444 std::memcpy(multiplier, &counterMultiplier,
sizeof(multiplier));
445 const uint32_t eventRecordWord3 = multiplier[0];
446 const uint32_t eventRecordWord4 = multiplier[1];
450 const uint32_t eventRecordWord5 =
static_cast<uint32_t
>(eventRecordBlockSize *
uint32_t_size);
453 std::vector<uint32_t> counterNameBuffer;
454 if (!StringToSwTraceString<SwTraceCharPolicy>(counterName, counterNameBuffer))
456 errorMessage = boost::str(boost::format(
"Cannot convert the name of counter %1% (name: %2%) " 457 "to an SWTrace string")
466 uint32_t eventRecordWord6 =
467 static_cast<uint32_t
>((counterNameBuffer.size() + eventRecordBlockSize) * uint32_t_size);
470 std::vector<uint32_t> counterDescriptionBuffer;
471 if (!StringToSwTraceString<SwTraceCharPolicy>(counterDescription, counterDescriptionBuffer))
473 errorMessage = boost::str(boost::format(
"Cannot convert the description of counter %1% (description: %2%) " 474 "to an SWTrace string")
483 bool includeUnits = !counterUnits.empty();
485 const uint32_t eventRecordWord7 = includeUnits ?
492 std::vector<uint32_t> counterUnitsBuffer;
496 if (!StringToSwTraceString<SwTraceNameCharPolicy>(counterUnits, counterUnitsBuffer))
498 errorMessage = boost::str(boost::format(
"Cannot convert the units of counter %1% (units: %2%) " 499 "to an SWTrace string")
507 const size_t eventRecordSize = eventRecordBlockSize +
508 counterNameBuffer.size() +
509 counterDescriptionBuffer.size() +
510 counterUnitsBuffer.size();
513 eventRecord.resize(eventRecordSize);
517 eventRecord[0] = eventRecordWord0;
518 eventRecord[1] = eventRecordWord1;
519 eventRecord[2] = eventRecordWord2;
520 eventRecord[3] = eventRecordWord3;
521 eventRecord[4] = eventRecordWord4;
522 eventRecord[5] = eventRecordWord5;
523 eventRecord[6] = eventRecordWord6;
524 eventRecord[7] = eventRecordWord7;
525 auto offset = eventRecord.begin() + 8u;
526 std::copy(counterNameBuffer.begin(), counterNameBuffer.end(), offset);
527 offset += counterNameBuffer.size();
528 std::copy(counterDescriptionBuffer.begin(), counterDescriptionBuffer.end(), offset);
531 offset += counterDescriptionBuffer.size();
532 std::copy(counterUnitsBuffer.begin(), counterUnitsBuffer.end(), offset);
541 using namespace boost::numeric;
550 const size_t packetHeaderSize = 2u;
551 const size_t bodyHeaderSize = 6u;
552 const uint32_t bodyHeaderSizeBytes = bodyHeaderSize *
uint32_t_size;
555 uint32_t pointerTableOffset = 0;
562 std::vector<DeviceRecord> deviceRecords(deviceCount);
564 std::vector<uint32_t> deviceRecordOffsets(deviceCount, 0);
565 size_t deviceRecordsSize = 0;
566 size_t deviceIndex = 0;
567 size_t deviceRecordOffsetIndex = 0;
569 pointerTableOffset =
numeric_cast<uint32_t>(deviceCount * uint32_t_size +
570 counterSetCount * uint32_t_size +
572 for (
auto it = devices.begin(); it != devices.end(); it++)
575 DeviceRecord& deviceRecord = deviceRecords.at(deviceIndex);
577 std::string errorMessage;
580 CancelOperationAndThrow<RuntimeException>(errorMessage);
584 deviceRecordsSize += deviceRecord.size();
587 deviceRecordOffsets[deviceRecordOffsetIndex] = pointerTableOffset;
591 deviceRecordOffsetIndex++;
599 std::vector<CounterSetRecord> counterSetRecords(counterSetCount);
601 std::vector<uint32_t> counterSetRecordOffsets(counterSetCount, 0);
602 size_t counterSetRecordsSize = 0;
603 size_t counterSetIndex = 0;
604 size_t counterSetRecordOffsetIndex = 0;
607 for (
auto it = counterSets.begin(); it != counterSets.end(); it++)
612 std::string errorMessage;
615 CancelOperationAndThrow<RuntimeException>(errorMessage);
619 counterSetRecordsSize += counterSetRecord.size();
622 counterSetRecordOffsets[counterSetRecordOffsetIndex] = pointerTableOffset;
626 counterSetRecordOffsetIndex++;
634 std::vector<CategoryRecord> categoryRecords(categoryCount);
636 std::vector<uint32_t> categoryRecordOffsets(categoryCount, 0);
637 size_t categoryRecordsSize = 0;
638 size_t categoryIndex = 0;
639 size_t categoryRecordOffsetIndex = 0;
642 for (
auto it = categories.begin(); it != categories.end(); it++)
645 CategoryRecord& categoryRecord = categoryRecords.at(categoryIndex);
647 std::string errorMessage;
650 CancelOperationAndThrow<RuntimeException>(errorMessage);
654 categoryRecordsSize += categoryRecord.size();
657 categoryRecordOffsets[categoryRecordOffsetIndex] = pointerTableOffset;
661 categoryRecordOffsetIndex++;
665 const size_t counterDirectoryPacketDataLength =
667 deviceRecordOffsets.size() +
668 counterSetRecordOffsets.size() +
669 categoryRecordOffsets.size() +
671 counterSetRecordsSize +
675 const size_t counterDirectoryPacketSize = packetHeaderSize +
676 counterDirectoryPacketDataLength;
679 std::vector<uint32_t> counterDirectoryPacket(counterDirectoryPacketSize, 0);
690 uint32_t packetFamily = 0;
691 uint32_t packetId = 2;
692 uint32_t packetHeaderWord0 = ((packetFamily & 0x3F) << 26) | ((packetId & 0x3FF) << 16);
699 uint32_t packetHeader[2]
712 const uint32_t bodyHeaderWord0 =
static_cast<uint32_t
>(deviceCount) << 16;
716 const uint32_t bodyHeaderWord1 = bodyHeaderSizeBytes;
723 const uint32_t bodyHeaderWord2 =
static_cast<uint32_t
>(counterSetCount) << 16;
727 const uint32_t bodyHeaderWord3 =
728 numeric_cast<uint32_t>(deviceRecordOffsets.size() * uint32_t_size
729 + bodyHeaderSizeBytes);
734 const uint32_t bodyHeaderWord4 =
static_cast<uint32_t
>(categoryCount) << 16;
738 const uint32_t bodyHeaderWord5 =
740 deviceRecordOffsets.size() * uint32_t_size +
741 counterSetRecordOffsets.size() * uint32_t_size
742 + bodyHeaderSizeBytes);
745 const uint32_t bodyHeader[bodyHeaderSize]
757 auto counterDirectoryPacketOffset = counterDirectoryPacket.begin();
759 std::copy(packetHeader, packetHeader + packetHeaderSize, counterDirectoryPacketOffset);
760 counterDirectoryPacketOffset += packetHeaderSize;
762 std::copy(bodyHeader, bodyHeader + bodyHeaderSize, counterDirectoryPacketOffset);
763 counterDirectoryPacketOffset += bodyHeaderSize;
765 std::copy(deviceRecordOffsets.begin(), deviceRecordOffsets.end(), counterDirectoryPacketOffset);
766 counterDirectoryPacketOffset += deviceRecordOffsets.size();
768 std::copy(counterSetRecordOffsets.begin(), counterSetRecordOffsets.end(), counterDirectoryPacketOffset);
769 counterDirectoryPacketOffset += counterSetRecordOffsets.size();
771 std::copy(categoryRecordOffsets.begin(), categoryRecordOffsets.end(), counterDirectoryPacketOffset);
772 counterDirectoryPacketOffset += categoryRecordOffsets.size();
776 std::copy(deviceRecord.begin(), deviceRecord.end(), counterDirectoryPacketOffset);
777 counterDirectoryPacketOffset += deviceRecord.size();
782 std::copy(counterSetRecord.begin(), counterSetRecord.end(), counterDirectoryPacketOffset);
783 counterDirectoryPacketOffset += counterSetRecord.size();
788 std::copy(categoryRecord.begin(), categoryRecord.end(), counterDirectoryPacketOffset);
789 counterDirectoryPacketOffset += categoryRecord.size();
797 uint32_t reserved = 0;
798 IPacketBufferPtr writeBuffer = m_BufferManager.Reserve(totalSize, reserved);
800 if (writeBuffer ==
nullptr || reserved < totalSize)
802 CancelOperationAndThrow<BufferExhaustion>(
804 boost::str(boost::format(
"No space left in buffer. Unable to reserve (%1%) bytes.") % totalSize));
811 for (uint32_t counterDirectoryPacketWord : counterDirectoryPacket)
813 WriteUint32(writeBuffer, offset, counterDirectoryPacketWord);
817 m_BufferManager.Commit(writeBuffer, totalSize);
824 uint32_t uint64_t_size =
sizeof(uint64_t);
826 uint32_t packetFamily = 3;
827 uint32_t packetClass = 0;
828 uint32_t packetType = 0;
830 uint32_t bodySize = uint64_t_size +
numeric_cast<uint32_t>(values.size()) * (uint16_t_size + uint32_t_size);
831 uint32_t totalSize = headerSize + bodySize;
833 uint32_t reserved = 0;
835 IPacketBufferPtr writeBuffer = m_BufferManager.Reserve(totalSize, reserved);
837 if (writeBuffer ==
nullptr || reserved < totalSize)
839 CancelOperationAndThrow<BufferExhaustion>(
841 boost::str(boost::format(
"No space left in buffer. Unable to reserve (%1%) bytes.") % totalSize));
847 ((packetFamily & 0x0000003F) << 26) |
848 ((packetClass & 0x0000007F) << 19) |
849 ((packetType & 0x00000007) << 16));
858 offset += uint64_t_size;
859 for (
const auto& pair: values)
863 WriteUint32(writeBuffer, offset, pair.counterValue);
867 m_BufferManager.Commit(writeBuffer, totalSize);
871 const std::vector<uint16_t>& selectedCounterIds)
876 uint32_t packetFamily = 0;
877 uint32_t packetId = 4;
879 uint32_t bodySize = uint32_t_size +
numeric_cast<uint32_t>(selectedCounterIds.size()) * uint16_t_size;
880 uint32_t totalSize = headerSize + bodySize;
882 uint32_t reserved = 0;
884 IPacketBufferPtr writeBuffer = m_BufferManager.Reserve(totalSize, reserved);
886 if (writeBuffer ==
nullptr || reserved < totalSize)
888 CancelOperationAndThrow<BufferExhaustion>(
890 boost::str(boost::format(
"No space left in buffer. Unable to reserve (%1%) bytes.") % totalSize));
894 WriteUint32(writeBuffer, offset, ((packetFamily & 0x3F) << 26) | ((packetId & 0x3FF) << 16));
904 for(
const uint16_t&
id: selectedCounterIds)
910 m_BufferManager.Commit(writeBuffer, totalSize);
virtual IPacketBufferPtr Reserve(unsigned int requestedSize, unsigned int &reservedSize)=0
std::vector< uint32_t > CounterSetRecord
std::vector< CounterValue > IndexValuePairsVector
std::vector< uint32_t > DeviceRecord
std::string GetHardwareVersion()
void WriteUint16(const IPacketBufferPtr &packetBuffer, unsigned int offset, uint16_t value)
void WriteUint32(const IPacketBufferPtr &packetBuffer, unsigned int offset, uint32_t value)
bool CreateDeviceRecord(const DevicePtr &device, DeviceRecord &deviceRecord, std::string &errorMessage)
void SendCounterDirectoryPacket(const ICounterDirectory &counterDirectory) override
Create and write a CounterDirectoryPacket from the parameters to the buffer.
std::unordered_map< uint16_t, CounterPtr > Counters
#define ARMNN_NO_CONVERSION_WARN_END
std::unique_ptr< Device > DevicePtr
std::string GetProcessName()
void SendStreamMetaDataPacket() override
Create and write a StreamMetaDataPacket in the buffer.
std::unique_ptr< CounterSet > CounterSetPtr
virtual void Commit(IPacketBufferPtr &packetBuffer, unsigned int size, bool notifyConsumer=true)=0
Copyright (c) 2020 ARM Limited.
virtual const CounterSets & GetCounterSets() const =0
std::string GetSoftwareInfo()
virtual uint16_t GetCategoryCount() const =0
constexpr uint32_t EncodeVersion(uint32_t major, uint32_t minor, uint32_t patch)
std::unordered_map< uint16_t, CounterSetPtr > CounterSets
virtual const Categories & GetCategories() const =0
std::vector< uint32_t > EventRecord
virtual const Devices & GetDevices() const =0
std::shared_ptr< Counter > CounterPtr
void SendPeriodicCounterCapturePacket(uint64_t timestamp, const IndexValuePairsVector &values) override
Create and write a PeriodicCounterCapturePacket from the parameters to the buffer.
bool CreateCounterSetRecord(const CounterSetPtr &counterSet, CounterSetRecord &counterSetRecord, std::string &errorMessage)
virtual uint16_t GetDeviceCount() const =0
#define ARMNN_ASSERT(COND)
std::enable_if_t< std::is_unsigned< Source >::value &&std::is_unsigned< Dest >::value, Dest > numeric_cast(Source source)
#define MAX_METADATA_PACKET_LENGTH
void WriteUint64(const std::unique_ptr< IPacketBuffer > &packetBuffer, unsigned int offset, uint64_t value)
std::unordered_set< CategoryPtr > Categories
virtual uint16_t GetCounterSetCount() const =0
#define ARMNN_NO_CONVERSION_WARN_BEGIN
std::string GetSoftwareVersion()
void SendPeriodicCounterSelectionPacket(uint32_t capturePeriod, const std::vector< uint16_t > &selectedCounterIds) override
Create and write a PeriodicCounterSelectionPacket from the parameters to the buffer.
std::vector< uint32_t > CategoryRecord
std::unique_ptr< Category > CategoryPtr
virtual const Counters & GetCounters() const =0
std::unordered_map< uint16_t, DevicePtr > Devices
bool CreateEventRecord(const CounterPtr &counter, EventRecord &eventRecord, std::string &errorMessage)
std::unique_ptr< IPacketBuffer > IPacketBufferPtr
bool CreateCategoryRecord(const CategoryPtr &category, const Counters &counters, CategoryRecord &categoryRecord, std::string &errorMessage)