aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt2
-rw-r--r--include/armnn/profiling/ILocalPacketHandler.hpp28
-rw-r--r--profiling/common/include/Packet.hpp2
-rw-r--r--src/profiling/FileOnlyProfilingConnection.cpp240
-rw-r--r--src/profiling/FileOnlyProfilingConnection.hpp64
-rw-r--r--src/profiling/test/FileOnlyProfilingDecoratorTests.cpp26
-rw-r--r--src/profiling/test/RequestCountersPacketHandler.cpp78
-rw-r--r--src/profiling/test/RequestCountersPacketHandler.hpp47
-rw-r--r--src/profiling/test/TestTimelinePacketHandler.hpp4
9 files changed, 300 insertions, 191 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index c2c4cc6672..9b9b19fc83 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -689,6 +689,8 @@ if(BUILD_UNIT_TESTS)
src/profiling/test/ProfilingTests.hpp
src/profiling/test/ProfilingTestUtils.cpp
src/profiling/test/ProfilingTestUtils.hpp
+ src/profiling/test/RequestCountersPacketHandler.cpp
+ src/profiling/test/RequestCountersPacketHandler.hpp
src/profiling/test/SendCounterPacketTests.cpp
src/profiling/test/SendCounterPacketTests.hpp
src/profiling/test/TestTimelinePacketHandler.cpp
diff --git a/include/armnn/profiling/ILocalPacketHandler.hpp b/include/armnn/profiling/ILocalPacketHandler.hpp
index a2b9d5fd56..158c0eb852 100644
--- a/include/armnn/profiling/ILocalPacketHandler.hpp
+++ b/include/armnn/profiling/ILocalPacketHandler.hpp
@@ -17,9 +17,32 @@ namespace armnn
namespace profiling
{
+
+enum class TargetEndianness
+{
+ BeWire,
+ LeWire
+};
+
// forward declare to prevent a circular dependency
class Packet;
-class IProfilingConnection;
+
+// the handlers need to be able to do two
+// things to service the FileOnlyProfilingConnection
+// and any other implementation of IProfilingConnection
+// set the endianness and write a packet back i.e.
+// return a packet and close the connection
+class IInternalProfilingConnection
+{
+public:
+ virtual ~IInternalProfilingConnection() {};
+
+ virtual void SetEndianess(const TargetEndianness& endianness) = 0;
+
+ virtual void ReturnPacket(Packet& packet) = 0;
+
+ virtual void Close() = 0;
+};
class ILocalPacketHandler
{
@@ -37,7 +60,8 @@ public:
/// Set a profiling connection on the handler. Only need to implement this
/// function if the handler will be writing data back to the profiled application.
- virtual void SetConnection(IProfilingConnection* profilingConnection) {armnn::IgnoreUnused(profilingConnection);}
+ virtual void SetConnection(IInternalProfilingConnection* profilingConnection)
+ {armnn::IgnoreUnused(profilingConnection);}
};
using ILocalPacketHandlerPtr = std::unique_ptr<ILocalPacketHandler>;
diff --git a/profiling/common/include/Packet.hpp b/profiling/common/include/Packet.hpp
index c1f2796804..23c3124bad 100644
--- a/profiling/common/include/Packet.hpp
+++ b/profiling/common/include/Packet.hpp
@@ -20,6 +20,8 @@ class Packet
public:
Packet()
: m_Header(0)
+ , m_PacketFamily(0)
+ , m_PacketId(0)
, m_Length(0)
, m_Data(nullptr)
{}
diff --git a/src/profiling/FileOnlyProfilingConnection.cpp b/src/profiling/FileOnlyProfilingConnection.cpp
index 1d4e23b7aa..1e26aaa472 100644
--- a/src/profiling/FileOnlyProfilingConnection.cpp
+++ b/src/profiling/FileOnlyProfilingConnection.cpp
@@ -8,6 +8,7 @@
#include <armnn/Exceptions.hpp>
#include <common/include/Constants.hpp>
+#include <common/include/ProfilingException.hpp>
#include <algorithm>
#include <boost/numeric/conversion/cast.hpp>
@@ -20,160 +21,107 @@ namespace armnn
namespace profiling
{
-FileOnlyProfilingConnection::~FileOnlyProfilingConnection()
-{
- Close();
-}
-
-bool FileOnlyProfilingConnection::IsOpen() const
+std::vector<uint32_t> StreamMetaDataProcessor::GetHeadersAccepted()
{
- // This type of connection is always open.
- return true;
+ std::vector<uint32_t> headers;
+ headers.push_back(m_MetaDataPacketHeader);
+ return headers;
}
-void FileOnlyProfilingConnection::Close()
+void StreamMetaDataProcessor::HandlePacket(const Packet& packet)
{
- // Dump any unread packets out of the queue.
- size_t initialSize = m_PacketQueue.size();
- for (size_t i = 0; i < initialSize; ++i)
+ if (packet.GetHeader() != m_MetaDataPacketHeader)
{
- m_PacketQueue.pop();
+ throw armnnProfiling::ProfilingException("StreamMetaDataProcessor can only handle Stream Meta Data Packets");
}
- // dispose of the processing thread
- m_KeepRunning.store(false);
- if (m_LocalHandlersThread.joinable())
+ // determine the endianness of the protocol
+ TargetEndianness endianness;
+ if (ToUint32(packet.GetData(),TargetEndianness::BeWire) == armnnProfiling::PIPE_MAGIC)
{
- // make sure the thread wakes up and sees it has to stop
- m_ConditionPacketReadable.notify_one();
- m_LocalHandlersThread.join();
+ endianness = TargetEndianness::BeWire;
}
-}
-
-bool FileOnlyProfilingConnection::WaitForStreamMeta(const unsigned char* buffer, uint32_t length)
-{
- IgnoreUnused(length);
-
- // The first word, stream_metadata_identifer, should always be 0.
- if (ToUint32(buffer, TargetEndianness::BeWire) != 0)
+ else if (ToUint32(packet.GetData(), TargetEndianness::LeWire) == armnnProfiling::PIPE_MAGIC)
{
- Fail("Protocol error. The stream_metadata_identifer was not 0.");
+ endianness = TargetEndianness::LeWire;
}
-
- // Before we interpret the length we need to read the pipe_magic word to determine endianness.
- if (ToUint32(buffer + 8, TargetEndianness::BeWire) == armnnProfiling::PIPE_MAGIC)
+ else
{
- m_Endianness = TargetEndianness::BeWire;
+ throw armnnProfiling::ProfilingException("Protocol read error. Unable to read PIPE_MAGIC value.");
}
- else if (ToUint32(buffer + 8, TargetEndianness::LeWire) == armnnProfiling::PIPE_MAGIC)
+ m_FileOnlyProfilingConnection->SetEndianess(endianness);
+ // send back the acknowledgement
+ std::unique_ptr<unsigned char[]> uniqueNullPtr = nullptr;
+ Packet returnPacket(0x10000, 0, uniqueNullPtr);
+ m_FileOnlyProfilingConnection->ReturnPacket(returnPacket);
+}
+
+uint32_t StreamMetaDataProcessor::ToUint32(const unsigned char* data, TargetEndianness endianness)
+{
+ // Extract the first 4 bytes starting at data and push them into a 32bit integer based on the
+ // specified endianness.
+ if (endianness == TargetEndianness::BeWire)
{
- m_Endianness = TargetEndianness::LeWire;
+ return static_cast<uint32_t>(data[0]) << 24 | static_cast<uint32_t>(data[1]) << 16 |
+ static_cast<uint32_t>(data[2]) << 8 | static_cast<uint32_t>(data[3]);
}
else
{
- Fail("Protocol read error. Unable to read PIPE_MAGIC value.");
+ return static_cast<uint32_t>(data[3]) << 24 | static_cast<uint32_t>(data[2]) << 16 |
+ static_cast<uint32_t>(data[1]) << 8 | static_cast<uint32_t>(data[0]);
}
- return true;
}
-void FileOnlyProfilingConnection::SendConnectionAck()
+FileOnlyProfilingConnection::~FileOnlyProfilingConnection()
{
- if (!m_QuietOp)
+ try
{
- std::cout << "Sending connection acknowledgement." << std::endl;
+ Close();
}
- std::unique_ptr<unsigned char[]> uniqueNullPtr = nullptr;
+ catch (...)
{
- std::lock_guard<std::mutex> lck(m_PacketAvailableMutex);
- m_PacketQueue.push(Packet(0x10000, 0, uniqueNullPtr));
+ // do nothing
}
- m_ConditionPacketAvailable.notify_one();
}
-bool FileOnlyProfilingConnection::SendCounterSelectionPacket()
+bool FileOnlyProfilingConnection::IsOpen() const
{
- uint32_t uint16_t_size = sizeof(uint16_t);
- uint32_t uint32_t_size = sizeof(uint32_t);
-
- uint32_t offset = 0;
- uint32_t bodySize = uint32_t_size + boost::numeric_cast<uint32_t>(m_IdList.size()) * uint16_t_size;
-
- auto uniqueData = std::make_unique<unsigned char[]>(bodySize);
- unsigned char* data = reinterpret_cast<unsigned char*>(uniqueData.get());
-
- // Copy capturePeriod
- WriteUint32(data, offset, m_Options.m_CapturePeriod);
+ // This type of connection is always open.
+ return true;
+}
- // Copy m_IdList
- offset += uint32_t_size;
- for (const uint16_t& id : m_IdList)
+void FileOnlyProfilingConnection::Close()
+{
+ // Dump any unread packets out of the queue.
+ size_t initialSize = m_PacketQueue.size();
+ for (size_t i = 0; i < initialSize; ++i)
{
- WriteUint16(data, offset, id);
- offset += uint16_t_size;
+ m_PacketQueue.pop();
}
-
+ // dispose of the processing thread
+ m_KeepRunning.store(false);
+ if (m_LocalHandlersThread.joinable())
{
- std::lock_guard<std::mutex> lck(m_PacketAvailableMutex);
- m_PacketQueue.push(Packet(0x40000, bodySize, uniqueData));
+ // make sure the thread wakes up and sees it has to stop
+ m_ConditionPacketReadable.notify_one();
+ m_LocalHandlersThread.join();
}
- m_ConditionPacketAvailable.notify_one();
-
- return true;
}
bool FileOnlyProfilingConnection::WritePacket(const unsigned char* buffer, uint32_t length)
{
ARMNN_ASSERT(buffer);
Packet packet = ReceivePacket(buffer, length);
+ ForwardPacketToHandlers(packet);
+ return true;
+}
- // Read Header and determine case
- uint32_t outgoingHeaderAsWords[2];
- PackageActivity packageActivity = GetPackageActivity(packet, outgoingHeaderAsWords);
-
- switch (packageActivity)
+void FileOnlyProfilingConnection::ReturnPacket(Packet& packet)
+{
{
- case PackageActivity::StreamMetaData:
- {
- if (!WaitForStreamMeta(buffer, length))
- {
- return EXIT_FAILURE;
- }
-
- SendConnectionAck();
- break;
- }
- case PackageActivity::CounterDirectory:
- {
- std::unique_ptr<unsigned char[]> uniqueCounterData = std::make_unique<unsigned char[]>(length - 8);
-
- std::memcpy(uniqueCounterData.get(), buffer + 8, length - 8);
-
- Packet directoryPacket(outgoingHeaderAsWords[0], length - 8, uniqueCounterData);
-
- armnn::profiling::PacketVersionResolver packetVersionResolver;
- DirectoryCaptureCommandHandler directoryCaptureCommandHandler(
- 0, 2, packetVersionResolver.ResolvePacketVersion(0, 2).GetEncodedValue());
- directoryCaptureCommandHandler.operator()(directoryPacket);
- const ICounterDirectory& counterDirectory = directoryCaptureCommandHandler.GetCounterDirectory();
- for (auto& category : counterDirectory.GetCategories())
- {
- // Remember we need to translate the Uid's from our CounterDirectory instance to the parent one.
- std::vector<uint16_t> translatedCounters;
- for (auto const& copyUid : category->m_Counters)
- {
- translatedCounters.emplace_back(directoryCaptureCommandHandler.TranslateUIDCopyToOriginal(copyUid));
- }
- m_IdList.insert(std::end(m_IdList), std::begin(translatedCounters), std::end(translatedCounters));
- }
- SendCounterSelectionPacket();
- break;
- }
- default:
- {
- break;
- }
+ std::lock_guard<std::mutex> lck(m_PacketAvailableMutex);
+ m_PacketQueue.push(std::move(packet));
}
- ForwardPacketToHandlers(packet);
- return true;
+ m_ConditionPacketAvailable.notify_one();
}
Packet FileOnlyProfilingConnection::ReadPacket(uint32_t timeout)
@@ -182,11 +130,12 @@ Packet FileOnlyProfilingConnection::ReadPacket(uint32_t timeout)
// Here we are using m_PacketQueue.empty() as a predicate variable
// The conditional variable will wait until packetQueue is not empty or until a timeout
- if(!m_ConditionPacketAvailable.wait_for(lck,
- std::chrono::milliseconds(timeout),
- [&]{return !m_PacketQueue.empty();}))
+ if (!m_ConditionPacketAvailable.wait_for(lck,
+ std::chrono::milliseconds(timeout),
+ [&]{return !m_PacketQueue.empty();}))
{
- throw armnn::TimeoutException("Thread has timed out as per requested time limit");
+ Packet empty;
+ return empty;
}
Packet returnedPacket = std::move(m_PacketQueue.front());
@@ -194,40 +143,6 @@ Packet FileOnlyProfilingConnection::ReadPacket(uint32_t timeout)
return returnedPacket;
}
-PackageActivity FileOnlyProfilingConnection::GetPackageActivity(const Packet& packet, uint32_t headerAsWords[2])
-{
- headerAsWords[0] = packet.GetHeader();
- headerAsWords[1] = packet.GetLength();
- if (headerAsWords[0] == 0x20000) // Packet family = 0 Packet Id = 2
- {
- return PackageActivity::CounterDirectory;
- }
- else if (headerAsWords[0] == 0) // Packet family = 0 Packet Id = 0
- {
- return PackageActivity::StreamMetaData;
- }
- else
- {
- return PackageActivity::Unknown;
- }
-}
-
-uint32_t FileOnlyProfilingConnection::ToUint32(const unsigned char* data, TargetEndianness endianness)
-{
- // Extract the first 4 bytes starting at data and push them into a 32bit integer based on the
- // specified endianness.
- if (endianness == TargetEndianness::BeWire)
- {
- return static_cast<uint32_t>(data[0]) << 24 | static_cast<uint32_t>(data[1]) << 16 |
- static_cast<uint32_t>(data[2]) << 8 | static_cast<uint32_t>(data[3]);
- }
- else
- {
- return static_cast<uint32_t>(data[3]) << 24 | static_cast<uint32_t>(data[2]) << 16 |
- static_cast<uint32_t>(data[1]) << 8 | static_cast<uint32_t>(data[0]);
- }
-}
-
void FileOnlyProfilingConnection::Fail(const std::string& errorMessage)
{
Close();
@@ -290,13 +205,13 @@ void FileOnlyProfilingConnection::ForwardPacketToHandlers(Packet& packet)
{
return;
}
- if (m_KeepRunning.load() == false)
+ if (!m_KeepRunning.load())
{
return;
}
{
std::unique_lock<std::mutex> readableListLock(m_ReadableMutex);
- if (m_KeepRunning.load() == false)
+ if (!m_KeepRunning.load())
{
return;
}
@@ -367,9 +282,24 @@ void FileOnlyProfilingConnection::DispatchPacketToHandlers(const Packet& packet)
auto iter = m_IndexedHandlers.find(packet.GetHeader());
if (iter != m_IndexedHandlers.end())
{
- for (auto &delegate : iter->second)
+ for (auto& delegate : iter->second)
{
- delegate->HandlePacket(packet);
+ try
+ {
+ delegate->HandlePacket(packet);
+ }
+ catch (const armnnProfiling::ProfilingException& ex)
+ {
+ Fail(ex.what());
+ }
+ catch (const std::exception& ex)
+ {
+ Fail(ex.what());
+ }
+ catch (...)
+ {
+ Fail("handler failed");
+ }
}
}
}
diff --git a/src/profiling/FileOnlyProfilingConnection.hpp b/src/profiling/FileOnlyProfilingConnection.hpp
index 3776dbcbdb..b19b983ebc 100644
--- a/src/profiling/FileOnlyProfilingConnection.hpp
+++ b/src/profiling/FileOnlyProfilingConnection.hpp
@@ -25,43 +25,54 @@ namespace armnn
namespace profiling
{
-enum class TargetEndianness
-{
- BeWire,
- LeWire
-};
+// forward declaration
+class FileOnlyProfilingConnection;
-enum class PackageActivity
+class StreamMetaDataProcessor : public ILocalPacketHandler
{
- StreamMetaData,
- CounterDirectory,
- Unknown
+public:
+ explicit StreamMetaDataProcessor(FileOnlyProfilingConnection* fileOnlyProfilingConnection) :
+ m_FileOnlyProfilingConnection(fileOnlyProfilingConnection),
+ m_MetaDataPacketHeader(ConstructHeader(0, 0)) {};
+
+ std::vector<uint32_t> GetHeadersAccepted() override;
+
+ void HandlePacket(const Packet& packet) override;
+
+private:
+ FileOnlyProfilingConnection* m_FileOnlyProfilingConnection;
+ uint32_t m_MetaDataPacketHeader;
+
+ static uint32_t ToUint32(const unsigned char* data, TargetEndianness endianness);
};
-class FileOnlyProfilingConnection : public IProfilingConnection
+class FileOnlyProfilingConnection : public IProfilingConnection, public IInternalProfilingConnection
{
public:
- FileOnlyProfilingConnection(const Runtime::CreationOptions::ExternalProfilingOptions& options,
- const bool quietOp = true)
+ explicit FileOnlyProfilingConnection(const Runtime::CreationOptions::ExternalProfilingOptions& options)
: m_Options(options)
- , m_QuietOp(quietOp)
- , m_Endianness(TargetEndianness::LeWire) // Set a sensible default. WaitForStreamMeta will set a real value.
+ , m_Endianness(TargetEndianness::LeWire) // Set a sensible default.
+ // StreamMetaDataProcessor will set a real value.
, m_IsRunning(false)
, m_KeepRunning(false)
, m_Timeout(1000)
{
- for (ILocalPacketHandlerSharedPtr localPacketHandler : options.m_LocalPacketHandlers)
+ // add the StreamMetaDataProcessor
+ auto streamMetaDataProcessor = std::make_shared<StreamMetaDataProcessor>(this);
+ AddLocalPacketHandler(streamMetaDataProcessor);
+ // and any additional ones added by the users
+ for (const ILocalPacketHandlerSharedPtr& localPacketHandler : options.m_LocalPacketHandlers)
{
AddLocalPacketHandler(localPacketHandler);
}
- if (!options.m_LocalPacketHandlers.empty())
+ if (!m_PacketHandlers.empty())
{
StartProcessingThread();
}
// NOTE: could add timeout to the external profiling options
};
- ~FileOnlyProfilingConnection();
+ ~FileOnlyProfilingConnection() override;
bool IsOpen() const override;
@@ -73,30 +84,25 @@ public:
// Sending a packet back to ArmNN.
Packet ReadPacket(uint32_t timeout) override;
+ void SetEndianess(const TargetEndianness& endianness) override //IInternalProfilingConnection
+ {
+ m_Endianness = endianness;
+ }
+
+ void ReturnPacket(Packet& packet) override; //IInternalProfilingConnection
+
private:
void AddLocalPacketHandler(ILocalPacketHandlerSharedPtr localPacketHandler);
void StartProcessingThread();
void ClearReadableList();
void DispatchPacketToHandlers(const Packet& packet);
- bool WaitForStreamMeta(const unsigned char* buffer, uint32_t length);
-
- uint32_t ToUint32(const unsigned char* data, TargetEndianness endianness);
-
- void SendConnectionAck();
-
- bool SendCounterSelectionPacket();
-
- PackageActivity GetPackageActivity(const Packet& packet, uint32_t headerAsWords[2]);
-
void Fail(const std::string& errorMessage);
void ForwardPacketToHandlers(Packet& packet);
void ServiceLocalHandlers();
Runtime::CreationOptions::ExternalProfilingOptions m_Options;
- bool m_QuietOp;
- std::vector<uint16_t> m_IdList;
std::queue<Packet> m_PacketQueue;
TargetEndianness m_Endianness;
diff --git a/src/profiling/test/FileOnlyProfilingDecoratorTests.cpp b/src/profiling/test/FileOnlyProfilingDecoratorTests.cpp
index 80236ae4eb..aa877a10e9 100644
--- a/src/profiling/test/FileOnlyProfilingDecoratorTests.cpp
+++ b/src/profiling/test/FileOnlyProfilingDecoratorTests.cpp
@@ -49,8 +49,11 @@ std::string UniqueFileName()
BOOST_AUTO_TEST_CASE(TestFileOnlyProfiling)
{
- // This test requires the CpuRef backend to be enabled
- if(!BackendRegistryInstance().IsBackendRegistered("CpuRef"))
+ // This test requires at least one backend registry to be enabled
+ // which can execute a NormalizationLayer
+ if (BackendRegistryInstance().IsBackendRegistered(GetComputeDeviceAsCString(armnn::Compute::CpuRef)) ||
+ BackendRegistryInstance().IsBackendRegistered(GetComputeDeviceAsCString(armnn::Compute::CpuAcc)) ||
+ BackendRegistryInstance().IsBackendRegistered(GetComputeDeviceAsCString(armnn::Compute::GpuAcc)))
{
return;
}
@@ -87,13 +90,30 @@ BOOST_AUTO_TEST_CASE(TestFileOnlyProfiling)
normalize->GetOutputSlot(0).SetTensorInfo(TensorInfo({ 1, 1, 4, 4 }, DataType::Float32));
// optimize the network
- std::vector<armnn::BackendId> backends = { armnn::Compute::CpuRef };
+ std::vector<armnn::BackendId> backends =
+ { armnn::Compute::CpuRef, armnn::Compute::CpuAcc, armnn::Compute::GpuAcc };
IOptimizedNetworkPtr optNet = Optimize(*net, backends, runtime.GetDeviceSpec());
// Load it into the runtime. It should succeed.
armnn::NetworkId netId;
BOOST_TEST(runtime.LoadNetwork(netId, std::move(optNet)) == Status::Success);
+ // Creates structures for input & output.
+ std::vector<float> inputData(16);
+ std::vector<float> outputData(16);
+
+ InputTensors inputTensors
+ {
+ {0, ConstTensor(runtime.GetInputTensorInfo(netId, 0), inputData.data())}
+ };
+ OutputTensors outputTensors
+ {
+ {0, Tensor(runtime.GetOutputTensorInfo(netId, 0), outputData.data())}
+ };
+
+ // Does the inference.
+ runtime.EnqueueWorkload(netId, inputTensors, outputTensors);
+
static_cast<TestTimelinePacketHandler*>(localPacketHandlerPtr.get())->WaitOnInferenceCompletion(3000);
}
diff --git a/src/profiling/test/RequestCountersPacketHandler.cpp b/src/profiling/test/RequestCountersPacketHandler.cpp
new file mode 100644
index 0000000000..76c4b0cdc6
--- /dev/null
+++ b/src/profiling/test/RequestCountersPacketHandler.cpp
@@ -0,0 +1,78 @@
+//
+// Copyright © 2020 Arm Ltd. All rights reserved.
+// SPDX-License-Identifier: MIT
+//
+
+#include "RequestCountersPacketHandler.hpp"
+
+#include "DirectoryCaptureCommandHandler.hpp"
+#include "PacketVersionResolver.hpp"
+
+#include <common/include/ProfilingException.hpp>
+
+namespace armnn
+{
+
+namespace profiling
+{
+
+std::vector<uint32_t> RequestCountersPacketHandler::GetHeadersAccepted()
+{
+ std::vector<uint32_t> headers;
+ headers.push_back(m_CounterDirectoryMessageHeader); // counter directory
+ return headers;
+}
+
+void RequestCountersPacketHandler::HandlePacket(const Packet& packet)
+{
+ if (packet.GetHeader() != m_CounterDirectoryMessageHeader)
+ {
+ return;
+ }
+ armnn::profiling::PacketVersionResolver packetVersionResolver;
+ DirectoryCaptureCommandHandler directoryCaptureCommandHandler(
+ 0, 2, packetVersionResolver.ResolvePacketVersion(0, 2).GetEncodedValue());
+ directoryCaptureCommandHandler.operator()(packet);
+ const ICounterDirectory& counterDirectory = directoryCaptureCommandHandler.GetCounterDirectory();
+ for (auto& category : counterDirectory.GetCategories())
+ {
+ // Remember we need to translate the Uid's from our CounterDirectory instance to the parent one.
+ std::vector<uint16_t> translatedCounters;
+ for (auto const& copyUid : category->m_Counters)
+ {
+ translatedCounters.emplace_back(directoryCaptureCommandHandler.TranslateUIDCopyToOriginal(copyUid));
+ }
+ m_IdList.insert(std::end(m_IdList), std::begin(translatedCounters), std::end(translatedCounters));
+ }
+ SendCounterSelectionPacket();
+}
+
+void RequestCountersPacketHandler::SendCounterSelectionPacket()
+{
+ uint32_t uint16_t_size = sizeof(uint16_t);
+ uint32_t uint32_t_size = sizeof(uint32_t);
+
+ uint32_t offset = 0;
+ uint32_t bodySize = uint32_t_size + boost::numeric_cast<uint32_t>(m_IdList.size()) * uint16_t_size;
+
+ auto uniqueData = std::make_unique<unsigned char[]>(bodySize);
+ auto data = reinterpret_cast<unsigned char*>(uniqueData.get());
+
+ // Copy capturePeriod
+ WriteUint32(data, offset, m_CapturePeriod);
+
+ // Copy m_IdList
+ offset += uint32_t_size;
+ for (const uint16_t& id : m_IdList)
+ {
+ WriteUint16(data, offset, id);
+ offset += uint16_t_size;
+ }
+
+ Packet packet(0x40000, bodySize, uniqueData);
+ m_Connection->ReturnPacket(packet);
+}
+
+} // namespace profiling
+
+} // namespace armnn \ No newline at end of file
diff --git a/src/profiling/test/RequestCountersPacketHandler.hpp b/src/profiling/test/RequestCountersPacketHandler.hpp
new file mode 100644
index 0000000000..203edcc9df
--- /dev/null
+++ b/src/profiling/test/RequestCountersPacketHandler.hpp
@@ -0,0 +1,47 @@
+//
+// Copyright © 2020 Arm Ltd. All rights reserved.
+// SPDX-License-Identifier: MIT
+//
+
+#pragma once
+
+#include <armnn/Types.hpp>
+#include <armnn/profiling/ILocalPacketHandler.hpp>
+#include "Packet.hpp"
+#include "ProfilingUtils.hpp"
+
+namespace armnn
+{
+
+namespace profiling
+{
+
+class RequestCountersPacketHandler : public ILocalPacketHandler
+{
+public:
+ explicit RequestCountersPacketHandler(uint32_t capturePeriod = LOWEST_CAPTURE_PERIOD) :
+ m_CapturePeriod(capturePeriod),
+ m_Connection(nullptr),
+ m_CounterDirectoryMessageHeader(ConstructHeader(0, 2)) {}
+
+ std::vector<uint32_t> GetHeadersAccepted() override; // ILocalPacketHandler
+
+ void HandlePacket(const Packet& packet) override; // ILocalPacketHandler
+
+ void SetConnection(IInternalProfilingConnection* profilingConnection) override // ILocalPacketHandler
+ {
+ m_Connection = profilingConnection;
+ }
+
+private:
+ uint32_t m_CapturePeriod;
+ IInternalProfilingConnection* m_Connection;
+ uint32_t m_CounterDirectoryMessageHeader;
+ std::vector<uint16_t> m_IdList;
+
+ void SendCounterSelectionPacket();
+};
+
+} // namespace profiling
+
+} // namespace armnn \ No newline at end of file
diff --git a/src/profiling/test/TestTimelinePacketHandler.hpp b/src/profiling/test/TestTimelinePacketHandler.hpp
index 67395254fc..6cc6a0c086 100644
--- a/src/profiling/test/TestTimelinePacketHandler.hpp
+++ b/src/profiling/test/TestTimelinePacketHandler.hpp
@@ -66,7 +66,7 @@ public:
const TimelineModel& GetTimelineModel() const {return m_TimelineModel;}
- virtual void SetConnection(IProfilingConnection* profilingConnection) override // ILocalPacketHandler
+ virtual void SetConnection(IInternalProfilingConnection* profilingConnection) override // ILocalPacketHandler
{
m_Connection = profilingConnection;
}
@@ -74,7 +74,7 @@ public:
private:
void ProcessDirectoryPacket(const Packet& packet);
void ProcessMessagePacket(const Packet& packet);
- IProfilingConnection* m_Connection;
+ IInternalProfilingConnection* m_Connection;
std::mutex m_InferenceCompletedMutex;
std::condition_variable m_InferenceCompletedConditionVariable;
bool m_InferenceCompleted;