14 #include <boost/format.hpp> 15 #include <boost/numeric/conversion/cast.hpp> 36 uint32_t infoSize =
numeric_cast<uint32_t>(info.size()) > 0 ? numeric_cast<uint32_t>(info.size()) + 1 : 0;
37 uint32_t hardwareVersionSize =
numeric_cast<uint32_t>(hardwareVersion.size()) > 0 ?
38 numeric_cast<uint32_t>(hardwareVersion.size()) + 1 : 0;
39 uint32_t softwareVersionSize =
numeric_cast<uint32_t>(softwareVersion.size()) > 0 ?
40 numeric_cast<uint32_t>(softwareVersion.size()) + 1 : 0;
41 uint32_t processNameSize =
numeric_cast<uint32_t>(processName.size()) > 0 ?
42 numeric_cast<uint32_t>(processName.size()) + 1 : 0;
44 uint32_t sizeUint32 =
numeric_cast<uint32_t>(
sizeof(uint32_t));
46 uint32_t headerSize = 2 * sizeUint32;
47 uint32_t bodySize = 10 * sizeUint32;
48 uint32_t packetVersionCountSize = sizeUint32;
57 uint32_t packetVersionEntries = 6;
59 uint32_t payloadSize =
numeric_cast<uint32_t>(infoSize + hardwareVersionSize + softwareVersionSize +
60 processNameSize + packetVersionCountSize +
61 (packetVersionEntries * 2 * sizeUint32));
63 uint32_t totalSize = headerSize + bodySize + payloadSize;
65 uint32_t reserved = 0;
69 if (writeBuffer ==
nullptr || reserved < totalSize)
71 CancelOperationAndThrow<BufferExhaustion>(
73 boost::str(boost::format(
"No space left in buffer. Unable to reserve (%1%) bytes.") % totalSize));
82 WriteUint32(writeBuffer, offset, totalSize - headerSize);
94 WriteUint32(writeBuffer, offset, numeric_cast<uint32_t>(pid));
96 uint32_t poolOffset = bodySize;
97 WriteUint32(writeBuffer, offset, infoSize ? poolOffset : 0);
99 poolOffset += infoSize;
100 WriteUint32(writeBuffer, offset, hardwareVersionSize ? poolOffset : 0);
101 offset += sizeUint32;
102 poolOffset += hardwareVersionSize;
103 WriteUint32(writeBuffer, offset, softwareVersionSize ? poolOffset : 0);
104 offset += sizeUint32;
105 poolOffset += softwareVersionSize;
106 WriteUint32(writeBuffer, offset, processNameSize ? poolOffset : 0);
107 offset += sizeUint32;
108 poolOffset += processNameSize;
109 WriteUint32(writeBuffer, offset, packetVersionEntries ? poolOffset : 0);
110 offset += sizeUint32;
112 offset += sizeUint32;
118 memcpy(&writeBuffer->GetWritableData()[offset], info.c_str(), infoSize);
122 if (hardwareVersionSize)
124 memcpy(&writeBuffer->GetWritableData()[offset], hardwareVersion.c_str(), hardwareVersionSize);
125 offset += hardwareVersionSize;
128 if (softwareVersionSize)
130 memcpy(&writeBuffer->GetWritableData()[offset], softwareVersion.c_str(), softwareVersionSize);
131 offset += softwareVersionSize;
136 memcpy(&writeBuffer->GetWritableData()[offset], processName.c_str(), processNameSize);
137 offset += processNameSize;
140 if (packetVersionEntries)
143 WriteUint32(writeBuffer, offset, packetVersionEntries << 16);
146 uint32_t packetFamily = 0;
147 uint32_t packetId = 0;
149 offset += sizeUint32;
150 for (uint32_t i = 0; i < packetVersionEntries - 1; ++i)
152 WriteUint32(writeBuffer, offset, ((packetFamily & 0x3F) << 26) | ((packetId++ & 0x3FF) << 16));
153 offset += sizeUint32;
155 offset += sizeUint32;
161 WriteUint32(writeBuffer, offset, ((packetFamily & 0x3F) << 26) | ((packetId & 0x3FF) << 16));
162 offset += sizeUint32;
168 CancelOperationAndThrow<RuntimeException>(writeBuffer,
"Error processing packet.");
171 m_BufferManager.
Commit(writeBuffer, totalSize,
false);
177 std::string& errorMessage)
179 using namespace boost::numeric;
181 BOOST_ASSERT(category);
183 const std::string& categoryName = category->m_Name;
184 const std::vector<uint16_t> categoryCounters = category->m_Counters;
186 BOOST_ASSERT(!categoryName.empty());
194 uint32_t categoryRecordWord1 =
static_cast<uint32_t
>(categoryCounters.size()) << 16;
199 uint32_t categoryRecordWord2 = 0;
203 std::vector<uint32_t> categoryNameBuffer;
204 if (!StringToSwTraceString<SwTraceNameCharPolicy>(categoryName, categoryNameBuffer))
206 errorMessage = boost::str(boost::format(
"Cannot convert the name of category \"%1%\" to an SWTrace namestring")
212 size_t counterCount = categoryCounters.size();
213 std::vector<EventRecord> eventRecords(counterCount);
214 std::vector<uint32_t> eventRecordOffsets(counterCount, 0);
215 size_t eventRecordsSize = 0;
216 uint32_t eventRecordsOffset =
217 numeric_cast<uint32_t>((eventRecords.size() + categoryNameBuffer.size()) * uint32_t_size);
218 for (
size_t counterIndex = 0, eventRecordIndex = 0, eventRecordOffsetIndex = 0;
219 counterIndex < counterCount;
220 counterIndex++, eventRecordIndex++, eventRecordOffsetIndex++)
222 uint16_t counterUid = categoryCounters.at(counterIndex);
223 auto it = counters.find(counterUid);
224 BOOST_ASSERT(it != counters.end());
227 EventRecord& eventRecord = eventRecords.at(eventRecordIndex);
234 eventRecordsSize += eventRecord.size();
237 eventRecordOffsets[eventRecordOffsetIndex] = eventRecordsOffset;
246 size_t categoryRecordSize = 3u +
248 eventRecordOffsets.size() +
249 categoryNameBuffer.size() +
253 categoryRecord.resize(categoryRecordSize);
257 categoryRecord[0] = categoryRecordWord1;
258 categoryRecord[1] = categoryRecordWord2;
259 categoryRecord[2] = categoryRecordWord3;
260 auto offset = categoryRecord.begin() + 3u;
261 std::copy(eventRecordOffsets.begin(), eventRecordOffsets.end(), offset);
262 offset += eventRecordOffsets.size();
263 std::copy(categoryNameBuffer.begin(), categoryNameBuffer.end(), offset);
264 offset += categoryNameBuffer.size();
265 for (
const EventRecord& eventRecord : eventRecords)
267 std::copy(eventRecord.begin(), eventRecord.end(), offset);
268 offset += eventRecord.size();
277 std::string& errorMessage)
279 BOOST_ASSERT(device);
281 uint16_t deviceUid = device->m_Uid;
282 const std::string& deviceName = device->m_Name;
283 uint16_t deviceCores = device->m_Cores;
285 BOOST_ASSERT(!deviceName.empty());
290 uint32_t deviceRecordWord0 = (
static_cast<uint32_t
>(deviceUid) << 16) |
291 (
static_cast<uint32_t
>(deviceCores));
295 uint32_t deviceRecordWord1 = 0;
299 std::vector<uint32_t> deviceNameBuffer;
300 if (!StringToSwTraceString<SwTraceCharPolicy>(deviceName, deviceNameBuffer))
302 errorMessage = boost::str(boost::format(
"Cannot convert the name of device %1% (\"%2%\") to an SWTrace string")
309 size_t deviceRecordSize = 2u +
310 deviceNameBuffer.size();
314 deviceRecord.resize(deviceRecordSize);
317 deviceRecord[0] = deviceRecordWord0;
318 deviceRecord[1] = deviceRecordWord1;
319 auto offset = deviceRecord.begin() + 2u;
320 std::copy(deviceNameBuffer.begin(), deviceNameBuffer.end(), offset);
327 std::string& errorMessage)
329 BOOST_ASSERT(counterSet);
331 uint16_t counterSetUid = counterSet->m_Uid;
332 const std::string& counterSetName = counterSet->m_Name;
333 uint16_t counterSetCount = counterSet->m_Count;
335 BOOST_ASSERT(!counterSetName.empty());
340 uint32_t counterSetRecordWord0 = (
static_cast<uint32_t
>(counterSetUid) << 16) |
341 (
static_cast<uint32_t
>(counterSetCount));
345 uint32_t counterSetRecordWord1 = 0;
349 std::vector<uint32_t> counterSetNameBuffer;
350 if (!StringToSwTraceString<SwTraceNameCharPolicy>(counterSet->m_Name, counterSetNameBuffer))
352 errorMessage = boost::str(boost::format(
"Cannot convert the name of counter set %1% (\"%2%\") to " 353 "an SWTrace namestring")
360 size_t counterSetRecordSize = 2u +
361 counterSetNameBuffer.size();
365 counterSetRecord.resize(counterSetRecordSize);
368 counterSetRecord[0] = counterSetRecordWord0;
369 counterSetRecord[1] = counterSetRecordWord1;
370 auto offset = counterSetRecord.begin() + 2u;
371 std::copy(counterSetNameBuffer.begin(), counterSetNameBuffer.end(), offset);
378 std::string& errorMessage)
380 using namespace boost::numeric;
382 BOOST_ASSERT(counter);
384 uint16_t counterUid = counter->m_Uid;
385 uint16_t maxCounterUid = counter->m_MaxCounterUid;
386 uint16_t deviceUid = counter->m_DeviceUid;
387 uint16_t counterSetUid = counter->m_CounterSetUid;
388 uint16_t counterClass = counter->m_Class;
389 uint16_t counterInterpolation = counter->m_Interpolation;
390 double counterMultiplier = counter->m_Multiplier;
391 const std::string& counterName = counter->m_Name;
392 const std::string& counterDescription = counter->m_Description;
393 const std::string& counterUnits = counter->m_Units;
395 BOOST_ASSERT(counterClass == 0 || counterClass == 1);
396 BOOST_ASSERT(counterInterpolation == 0 || counterInterpolation == 1);
397 BOOST_ASSERT(counterMultiplier);
409 uint32_t eventRecordWord0 = (
static_cast<uint32_t
>(maxCounterUid) << 16) |
410 (
static_cast<uint32_t
>(counterUid));
417 uint32_t eventRecordWord1 = (
static_cast<uint32_t
>(deviceUid) << 16) |
418 (
static_cast<uint32_t
>(counterSetUid));
423 uint32_t eventRecordWord2 = (
static_cast<uint32_t
>(counterClass) << 16) |
424 (
static_cast<uint32_t
>(counterInterpolation));
429 uint32_t multiplier[2] = { 0u, 0u };
430 BOOST_ASSERT(
sizeof(counterMultiplier) ==
sizeof(multiplier));
431 std::memcpy(multiplier, &counterMultiplier,
sizeof(multiplier));
432 uint32_t eventRecordWord3 = multiplier[0];
433 uint32_t eventRecordWord4 = multiplier[1];
437 uint32_t eventRecordWord5 = 0;
441 std::vector<uint32_t> counterNameBuffer;
442 if (!StringToSwTraceString<SwTraceCharPolicy>(counterName, counterNameBuffer))
444 errorMessage = boost::str(boost::format(
"Cannot convert the name of counter %1% (name: \"%2%\") " 445 "to an SWTrace string")
457 std::vector<uint32_t> counterDescriptionBuffer;
458 if (!StringToSwTraceString<SwTraceCharPolicy>(counterDescription, counterDescriptionBuffer))
460 errorMessage = boost::str(boost::format(
"Cannot convert the description of counter %1% (description: \"%2%\") " 461 "to an SWTrace string")
470 bool includeUnits = !counterUnits.empty();
472 uint32_t eventRecordWord7 = includeUnits ?
478 std::vector<uint32_t> counterUnitsBuffer;
482 if (!StringToSwTraceString<SwTraceNameCharPolicy>(counterUnits, counterUnitsBuffer))
484 errorMessage = boost::str(boost::format(
"Cannot convert the units of counter %1% (units: \"%2%\") " 485 "to an SWTrace string")
493 size_t eventRecordSize = 8u +
497 counterNameBuffer.size() +
498 counterDescriptionBuffer.size() +
499 counterUnitsBuffer.size();
502 eventRecord.resize(eventRecordSize);
506 eventRecord[0] = eventRecordWord0;
507 eventRecord[1] = eventRecordWord1;
508 eventRecord[2] = eventRecordWord2;
509 eventRecord[3] = eventRecordWord3;
510 eventRecord[4] = eventRecordWord4;
511 eventRecord[5] = eventRecordWord5;
512 eventRecord[6] = eventRecordWord6;
513 eventRecord[7] = eventRecordWord7;
514 auto offset = eventRecord.begin() + 8u;
515 std::copy(counterNameBuffer.begin(), counterNameBuffer.end(), offset);
516 offset += counterNameBuffer.size();
517 std::copy(counterDescriptionBuffer.begin(), counterDescriptionBuffer.end(), offset);
520 offset += counterDescriptionBuffer.size();
521 std::copy(counterUnitsBuffer.begin(), counterUnitsBuffer.end(), offset);
530 using namespace boost::numeric;
539 size_t packetHeaderSize = 2u;
540 size_t bodyHeaderSize = 6u;
543 uint32_t pointerTableOffset = 0;
550 std::vector<DeviceRecord> deviceRecords(deviceCount);
552 std::vector<uint32_t> deviceRecordOffsets(deviceCount, 0);
553 size_t deviceRecordsSize = 0;
554 size_t deviceIndex = 0;
555 size_t deviceRecordOffsetIndex = 0;
556 for (
auto it = devices.begin(); it != devices.end(); it++)
559 DeviceRecord& deviceRecord = deviceRecords.at(deviceIndex);
561 std::string errorMessage;
564 CancelOperationAndThrow<RuntimeException>(errorMessage);
568 deviceRecordsSize += deviceRecord.size();
571 deviceRecordOffsets[deviceRecordOffsetIndex] = pointerTableOffset;
575 deviceRecordOffsetIndex++;
583 std::vector<CounterSetRecord> counterSetRecords(counterSetCount);
585 std::vector<uint32_t> counterSetRecordOffsets(counterSetCount, 0);
586 size_t counterSetRecordsSize = 0;
587 size_t counterSetIndex = 0;
588 size_t counterSetRecordOffsetIndex = 0;
589 for (
auto it = counterSets.begin(); it != counterSets.end(); it++)
594 std::string errorMessage;
597 CancelOperationAndThrow<RuntimeException>(errorMessage);
601 counterSetRecordsSize += counterSetRecord.size();
604 counterSetRecordOffsets[counterSetRecordOffsetIndex] = pointerTableOffset;
608 counterSetRecordOffsetIndex++;
616 std::vector<CategoryRecord> categoryRecords(categoryCount);
618 std::vector<uint32_t> categoryRecordOffsets(categoryCount, 0);
619 size_t categoryRecordsSize = 0;
620 size_t categoryIndex = 0;
621 size_t categoryRecordOffsetIndex = 0;
622 for (
auto it = categories.begin(); it != categories.end(); it++)
625 CategoryRecord& categoryRecord = categoryRecords.at(categoryIndex);
627 std::string errorMessage;
630 CancelOperationAndThrow<RuntimeException>(errorMessage);
634 categoryRecordsSize += categoryRecord.size();
637 categoryRecordOffsets[categoryRecordOffsetIndex] = pointerTableOffset;
641 categoryRecordOffsetIndex++;
647 size_t counterDirectoryPacketDataLength =
649 deviceRecordOffsets.size() +
650 counterSetRecordOffsets.size() +
651 categoryRecordOffsets.size() +
653 counterSetRecordsSize +
657 size_t counterDirectoryPacketSize = packetHeaderSize +
658 counterDirectoryPacketDataLength;
662 std::vector<uint32_t> counterDirectoryPacket(counterDirectoryPacketSize, 0);
673 uint32_t packetFamily = 0;
674 uint32_t packetId = 2;
675 uint32_t packetHeaderWord0 = ((packetFamily & 0x3F) << 26) | ((packetId & 0x3FF) << 16);
682 uint32_t packetHeader[2]
695 uint32_t bodyHeaderWord0 =
static_cast<uint32_t
>(deviceCount) << 16;
699 uint32_t bodyHeaderWord1 = 0;
705 uint32_t bodyHeaderWord2 =
static_cast<uint32_t
>(counterSetCount) << 16;
709 uint32_t bodyHeaderWord3 =
717 uint32_t bodyHeaderWord4 =
static_cast<uint32_t
>(categoryCount) << 16;
721 uint32_t bodyHeaderWord5 =
722 numeric_cast<uint32_t>(deviceRecordOffsets.size() * uint32_t_size +
727 uint32_t bodyHeader[6]
739 auto counterDirectoryPacketOffset = counterDirectoryPacket.begin();
741 std::copy(packetHeader, packetHeader + packetHeaderSize, counterDirectoryPacketOffset);
742 counterDirectoryPacketOffset += packetHeaderSize;
744 std::copy(bodyHeader, bodyHeader + bodyHeaderSize, counterDirectoryPacketOffset);
745 counterDirectoryPacketOffset += bodyHeaderSize;
747 std::copy(deviceRecordOffsets.begin(), deviceRecordOffsets.end(), counterDirectoryPacketOffset);
748 counterDirectoryPacketOffset += deviceRecordOffsets.size();
750 std::copy(counterSetRecordOffsets.begin(), counterSetRecordOffsets.end(), counterDirectoryPacketOffset);
751 counterDirectoryPacketOffset += counterSetRecordOffsets.size();
753 std::copy(categoryRecordOffsets.begin(), categoryRecordOffsets.end(), counterDirectoryPacketOffset);
754 counterDirectoryPacketOffset += categoryRecordOffsets.size();
758 std::copy(deviceRecord.begin(), deviceRecord.end(), counterDirectoryPacketOffset);
759 counterDirectoryPacketOffset += deviceRecord.size();
764 std::copy(counterSetRecord.begin(), counterSetRecord.end(), counterDirectoryPacketOffset);
765 counterDirectoryPacketOffset += counterSetRecord.size();
770 std::copy(categoryRecord.begin(), categoryRecord.end(), counterDirectoryPacketOffset);
771 counterDirectoryPacketOffset += categoryRecord.size();
779 uint32_t reserved = 0;
780 IPacketBufferPtr writeBuffer = m_BufferManager.Reserve(totalSize, reserved);
782 if (writeBuffer ==
nullptr || reserved < totalSize)
784 CancelOperationAndThrow<BufferExhaustion>(
786 boost::str(boost::format(
"No space left in buffer. Unable to reserve (%1%) bytes.") % totalSize));
793 for (uint32_t counterDirectoryPacketWord : counterDirectoryPacket)
795 WriteUint32(writeBuffer, offset, counterDirectoryPacketWord);
799 m_BufferManager.Commit(writeBuffer, totalSize);
806 uint32_t uint64_t_size =
sizeof(uint64_t);
808 uint32_t packetFamily = 3;
809 uint32_t packetClass = 0;
810 uint32_t packetType = 0;
812 uint32_t bodySize = uint64_t_size +
numeric_cast<uint32_t>(values.size()) * (uint16_t_size + uint32_t_size);
813 uint32_t totalSize = headerSize + bodySize;
815 uint32_t reserved = 0;
817 IPacketBufferPtr writeBuffer = m_BufferManager.Reserve(totalSize, reserved);
819 if (writeBuffer ==
nullptr || reserved < totalSize)
821 CancelOperationAndThrow<BufferExhaustion>(
823 boost::str(boost::format(
"No space left in buffer. Unable to reserve (%1%) bytes.") % totalSize));
829 ((packetFamily & 0x0000003F) << 26) |
830 ((packetClass & 0x0000007F) << 19) |
831 ((packetType & 0x00000007) << 16));
840 offset += uint64_t_size;
841 for (
const auto& pair: values)
845 WriteUint32(writeBuffer, offset, pair.counterValue);
849 m_BufferManager.Commit(writeBuffer, totalSize);
853 const std::vector<uint16_t>& selectedCounterIds)
858 uint32_t packetFamily = 0;
859 uint32_t packetId = 4;
861 uint32_t bodySize = uint32_t_size +
numeric_cast<uint32_t>(selectedCounterIds.size()) * uint16_t_size;
862 uint32_t totalSize = headerSize + bodySize;
864 uint32_t reserved = 0;
866 IPacketBufferPtr writeBuffer = m_BufferManager.Reserve(totalSize, reserved);
868 if (writeBuffer ==
nullptr || reserved < totalSize)
870 CancelOperationAndThrow<BufferExhaustion>(
872 boost::str(boost::format(
"No space left in buffer. Unable to reserve (%1%) bytes.") % totalSize));
876 WriteUint32(writeBuffer, offset, ((packetFamily & 0x3F) << 26) | ((packetId & 0x3FF) << 16));
886 for(
const uint16_t&
id: selectedCounterIds)
892 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
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
static const unsigned int PIPE_MAGIC
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)