src/profiling/ProfilingConnectionFactory.hpp
src/profiling/IBufferWrapper.hpp
src/profiling/ISendCounterPacket.hpp
+ src/profiling/SendCounterPacket.hpp
+ src/profiling/SendCounterPacket.cpp
+ src/profiling/ProfilingUtils.hpp
+ src/profiling/ProfilingUtils.cpp
third-party/half/half.hpp
)
--- /dev/null
+//
+// Copyright © 2017 Arm Ltd. All rights reserved.
+// SPDX-License-Identifier: MIT
+//
+
+#include "ProfilingUtils.hpp"
+
+#include <boost/assert.hpp>
+
+namespace armnn
+{
+
+namespace profiling
+{
+
+void WriteUint32(unsigned char* buffer, unsigned int offset, uint32_t value)
+{
+ BOOST_ASSERT(buffer);
+
+ buffer[offset] = static_cast<unsigned char>(value & 0xFF);
+ buffer[offset + 1] = static_cast<unsigned char>((value >> 8) & 0xFF);
+ buffer[offset + 2] = static_cast<unsigned char>((value >> 16) & 0xFF);
+ buffer[offset + 3] = static_cast<unsigned char>((value >> 24) & 0xFF);
+}
+
+void WriteUint16(unsigned char* buffer, unsigned int offset, uint16_t value)
+{
+ BOOST_ASSERT(buffer != nullptr);
+
+ buffer[offset] = static_cast<unsigned char>(value & 0xFF);
+ buffer[offset + 1] = static_cast<unsigned char>((value >> 8) & 0xFF);
+}
+
+uint32_t ReadUint32(const unsigned char* buffer, unsigned int offset)
+{
+ BOOST_ASSERT(buffer);
+
+ uint32_t value = 0;
+ value = static_cast<uint32_t>(buffer[offset]);
+ value |= static_cast<uint32_t>(buffer[offset + 1]) << 8;
+ value |= static_cast<uint32_t>(buffer[offset + 2]) << 16;
+ value |= static_cast<uint32_t>(buffer[offset + 3]) << 24;
+ return value;
+}
+
+uint16_t ReadUint16(const unsigned char* buffer, unsigned int offset)
+{
+ BOOST_ASSERT(buffer);
+
+ uint32_t value = 0;
+ value = static_cast<uint32_t>(buffer[offset]);
+ value |= static_cast<uint32_t>(buffer[offset + 1]) << 8;
+ return static_cast<uint16_t>(value);
+}
+
+} // namespace profiling
+
+} // namespace armnn
\ No newline at end of file
--- /dev/null
+//
+// Copyright © 2017 Arm Ltd. All rights reserved.
+// SPDX-License-Identifier: MIT
+//
+
+#pragma once
+
+#include <stdint.h>
+
+namespace armnn
+{
+
+namespace profiling
+{
+
+void WriteUint32(unsigned char* buffer, unsigned int offset, uint32_t value);
+
+void WriteUint16(unsigned char* buffer, unsigned int offset, uint16_t value);
+
+uint32_t ReadUint32(const unsigned char* buffer, unsigned int offset);
+
+uint16_t ReadUint16(const unsigned char* buffer, unsigned int offset);
+
+} // namespace profiling
+
+} // namespace armnn
\ No newline at end of file
--- /dev/null
+//
+// Copyright © 2017 Arm Ltd. All rights reserved.
+// SPDX-License-Identifier: MIT
+//
+
+#include "SendCounterPacket.hpp"
+#include "EncodeVersion.hpp"
+#include "ProfilingUtils.hpp"
+
+#include <armnn/Exceptions.hpp>
+
+#include <boost/format.hpp>
+#include <boost/numeric/conversion/cast.hpp>
+
+#include <unistd.h>
+
+namespace armnn
+{
+
+namespace profiling
+{
+
+using boost::numeric_cast;
+
+void SendCounterPacket::SendStreamMetaDataPacket()
+{
+ throw armnn::UnimplementedException();
+}
+
+void SendCounterPacket::SendCounterDirectoryPacket(const Category& category, const std::vector<Counter>& counters)
+{
+ throw armnn::UnimplementedException();
+}
+
+void SendCounterPacket::SendPeriodicCounterCapturePacket(uint64_t timestamp, const std::vector<uint32_t>& counterValues,
+ const std::vector<uint16_t>& counterUids)
+{
+ throw armnn::UnimplementedException();
+}
+
+void SendCounterPacket::SendPeriodicCounterSelectionPacket(uint32_t capturePeriod,
+ const std::vector<uint16_t>& selectedCounterIds)
+{
+ uint32_t packetFamily = 0;
+ uint32_t packetId = 4;
+ uint32_t headerSize = numeric_cast<uint32_t>(2 * sizeof(uint32_t));
+ uint32_t bodySize = numeric_cast<uint32_t>((1 * sizeof(uint32_t)) + (selectedCounterIds.size() * sizeof(uint16_t)));
+ uint32_t totalSize = headerSize + bodySize;
+ uint32_t offset = 0;
+ uint32_t reserved = 0;
+
+ unsigned char* writeBuffer = m_Buffer.Reserve(totalSize, reserved);
+
+ if (reserved < totalSize)
+ {
+ // Cancel the operation.
+ m_Buffer.Commit(0);
+ throw RuntimeException(boost::str(boost::format("No space left in buffer. Unable to reserve (%1%) bytes.")
+ % totalSize));
+ }
+
+ if (writeBuffer == nullptr)
+ {
+ // Cancel the operation.
+ m_Buffer.Commit(0);
+ throw RuntimeException("Error reserving buffer memory.");
+ }
+
+ // Create header.
+ WriteUint32(writeBuffer, offset, ((packetFamily & 0x3F) << 26) | ((packetId & 0x3FF) << 16));
+ offset += numeric_cast<uint32_t>(sizeof(uint32_t));
+ WriteUint32(writeBuffer, offset, bodySize);
+
+ // Copy capturePeriod.
+ offset += numeric_cast<uint32_t>(sizeof(uint32_t));
+ WriteUint32(writeBuffer, offset, capturePeriod);
+
+ // Copy selectedCounterIds.
+ offset += numeric_cast<uint32_t>(sizeof(uint32_t));
+ for(const uint16_t& id: selectedCounterIds)
+ {
+ WriteUint16(writeBuffer, offset, id);
+ offset += numeric_cast<uint32_t>(sizeof(uint16_t));
+ }
+
+ m_Buffer.Commit(totalSize);
+}
+
+void SendCounterPacket::SetReadyToRead()
+{
+ m_ReadyToRead = true;
+}
+
+} // namespace profiling
+
+} // namespace armnn
\ No newline at end of file
--- /dev/null
+//
+// Copyright © 2017 Arm Ltd. All rights reserved.
+// SPDX-License-Identifier: MIT
+//
+
+#pragma once
+
+#include "IBufferWrapper.hpp"
+#include "ISendCounterPacket.hpp"
+#include "CounterDirectory.hpp"
+
+namespace armnn
+{
+
+namespace profiling
+{
+
+class SendCounterPacket : public ISendCounterPacket
+{
+public:
+ SendCounterPacket(IBufferWrapper& buffer) : m_Buffer(buffer), m_ReadyToRead(false) {}
+
+ void SendStreamMetaDataPacket() override;
+
+ void SendCounterDirectoryPacket(const Category& category, const std::vector<Counter>& counters) override;
+
+ void SendPeriodicCounterCapturePacket(uint64_t timestamp, const std::vector<uint32_t>& counterValues,
+ const std::vector<uint16_t>& counterUids) override;
+
+ void SendPeriodicCounterSelectionPacket(uint32_t capturePeriod,
+ const std::vector<uint16_t>& selectedCounterIds) override;
+
+ void SetReadyToRead() override;
+
+private:
+ IBufferWrapper& m_Buffer;
+ bool m_ReadyToRead;
+};
+
+} // namespace profiling
+
+} // namespace armnn
+
// SPDX-License-Identifier: MIT
//
-#include "../IBufferWrapper.hpp"
-#include "../ISendCounterPacket.hpp"
+#include "../SendCounterPacket.hpp"
+#include "../ProfilingUtils.hpp"
+
+#include <armnn/Exceptions.hpp>
-#include <iostream>
#include <boost/test/unit_test.hpp>
+#include <iostream>
BOOST_AUTO_TEST_SUITE(SendCounterPacketTests)
class MockBuffer : public IBufferWrapper
{
public:
- MockBuffer() : m_Buffer() {}
+ MockBuffer(unsigned int size)
+ : m_BufferSize(size),
+ m_Buffer(std::make_unique<unsigned char[]>(size)) {}
unsigned char* Reserve(unsigned int requestedSize, unsigned int& reservedSize) override
{
reservedSize = requestedSize;
}
- return m_Buffer;
+ return m_Buffer.get();
}
void Commit(unsigned int size) override {}
const unsigned char* GetReadBuffer(unsigned int& size) override
{
- size = static_cast<unsigned int>(strlen(reinterpret_cast<const char*>(m_Buffer)) + 1);
- return m_Buffer;
+ size = static_cast<unsigned int>(strlen(reinterpret_cast<const char*>(m_Buffer.get())) + 1);
+ return m_Buffer.get();
}
void Release( unsigned int size) override {}
private:
- static const unsigned int m_BufferSize = 512;
- unsigned char m_Buffer[m_BufferSize];
+ unsigned int m_BufferSize;
+ std::unique_ptr<unsigned char[]> m_Buffer;
};
class MockSendCounterPacket : public ISendCounterPacket
{
unsigned int size = 0;
- MockBuffer mockBuffer;
+ MockBuffer mockBuffer(512);
MockSendCounterPacket sendCounterPacket(mockBuffer);
sendCounterPacket.SendStreamMetaDataPacket();
}
+BOOST_AUTO_TEST_CASE(SendPeriodicCounterSelectionPacketTest)
+{
+ // Error no space left in buffer
+ MockBuffer mockBuffer1(10);
+ SendCounterPacket sendPacket1(mockBuffer1);
+
+ uint32_t capturePeriod = 1000;
+ std::vector<uint16_t> selectedCounterIds;
+ BOOST_CHECK_THROW(sendPacket1.SendPeriodicCounterSelectionPacket(capturePeriod, selectedCounterIds),
+ armnn::Exception);
+
+ // Packet without any counters
+ MockBuffer mockBuffer2(512);
+ SendCounterPacket sendPacket2(mockBuffer2);
+
+ sendPacket2.SendPeriodicCounterSelectionPacket(capturePeriod, selectedCounterIds);
+ unsigned int sizeRead = 0;
+ const unsigned char* readBuffer2 = mockBuffer2.GetReadBuffer(sizeRead);
+
+ uint32_t headerWord0 = ReadUint32(readBuffer2, 0);
+ uint32_t headerWord1 = ReadUint32(readBuffer2, 4);
+ uint32_t period = ReadUint32(readBuffer2, 8);
+
+ BOOST_TEST(((headerWord0 >> 26) & 0x3F) == 0); // packet family
+ BOOST_TEST(((headerWord0 >> 16) & 0x3FF) == 4); // packet id
+ BOOST_TEST(headerWord1 == 4); // data lenght
+ BOOST_TEST(period == 1000); // capture period
+
+ // Full packet message
+ MockBuffer mockBuffer3(512);
+ SendCounterPacket sendPacket3(mockBuffer3);
+
+ selectedCounterIds.reserve(5);
+ selectedCounterIds.emplace_back(100);
+ selectedCounterIds.emplace_back(200);
+ selectedCounterIds.emplace_back(300);
+ selectedCounterIds.emplace_back(400);
+ selectedCounterIds.emplace_back(500);
+ sendPacket3.SendPeriodicCounterSelectionPacket(capturePeriod, selectedCounterIds);
+ sizeRead = 0;
+ const unsigned char* readBuffer3 = mockBuffer3.GetReadBuffer(sizeRead);
+
+ headerWord0 = ReadUint32(readBuffer3, 0);
+ headerWord1 = ReadUint32(readBuffer3, 4);
+ period = ReadUint32(readBuffer3, 8);
+
+ BOOST_TEST(((headerWord0 >> 26) & 0x3F) == 0); // packet family
+ BOOST_TEST(((headerWord0 >> 16) & 0x3FF) == 4); // packet id
+ BOOST_TEST(headerWord1 == 14); // data lenght
+ BOOST_TEST(period == 1000); // capture period
+
+ uint16_t counterId = 0;
+ uint32_t offset = 12;
+
+ // Counter Ids
+ for(const uint16_t& id : selectedCounterIds)
+ {
+ counterId = ReadUint16(readBuffer3, offset);
+ BOOST_TEST(counterId == id);
+ offset += 2;
+ }
+}
+
BOOST_AUTO_TEST_SUITE_END()