blob: d70239ef1a1522b5eb2ccf88f5cb041c8ca217b1 [file] [log] [blame]
Ferran Balaguer1b941722019-08-28 16:57:18 +01001//
2// Copyright © 2019 Arm Ltd. All rights reserved.
3// SPDX-License-Identifier: MIT
4//
5
6#pragma once
7
Matteo Martincigh24e8f922019-09-19 11:57:46 +01008#include <SendCounterPacket.hpp>
9#include <ProfilingUtils.hpp>
Matteo Martincighe8485382019-10-10 14:08:21 +010010#include <IProfilingConnectionFactory.hpp>
Ferran Balaguer1b941722019-08-28 16:57:18 +010011
12#include <armnn/Exceptions.hpp>
Matteo Martincigh24e8f922019-09-19 11:57:46 +010013#include <armnn/Optional.hpp>
14#include <armnn/Conversion.hpp>
Ferran Balaguer1b941722019-08-28 16:57:18 +010015
Matteo Martincighd0613b52019-10-09 16:47:04 +010016#include <boost/assert.hpp>
Matteo Martincigh24e8f922019-09-19 11:57:46 +010017#include <boost/numeric/conversion/cast.hpp>
Ferran Balaguer1b941722019-08-28 16:57:18 +010018
Matteo Martincigh24e8f922019-09-19 11:57:46 +010019namespace armnn
20{
Ferran Balaguer1b941722019-08-28 16:57:18 +010021
Matteo Martincigh24e8f922019-09-19 11:57:46 +010022namespace profiling
23{
Matteo Martincighd0613b52019-10-09 16:47:04 +010024
Matteo Martincigh24e8f922019-09-19 11:57:46 +010025class MockProfilingConnection : public IProfilingConnection
26{
27public:
28 MockProfilingConnection()
29 : m_IsOpen(true)
Matteo Martincigh54fb9572019-10-02 12:50:57 +010030 , m_WrittenData()
31 , m_Packet()
Matteo Martincigh24e8f922019-09-19 11:57:46 +010032 {}
33
Matteo Martincighd0613b52019-10-09 16:47:04 +010034 bool IsOpen() const override
35 {
36 std::lock_guard<std::mutex> lock(m_Mutex);
Matteo Martincigh24e8f922019-09-19 11:57:46 +010037
Matteo Martincighd0613b52019-10-09 16:47:04 +010038 return m_IsOpen;
39 }
40
41 void Close() override
42 {
43 std::lock_guard<std::mutex> lock(m_Mutex);
44
45 m_IsOpen = false;
46 }
Matteo Martincigh24e8f922019-09-19 11:57:46 +010047
48 bool WritePacket(const unsigned char* buffer, uint32_t length) override
49 {
Matteo Martincigh5d737fb2019-10-07 13:05:13 +010050 if (buffer == nullptr || length == 0)
51 {
52 return false;
53 }
Matteo Martincigh24e8f922019-09-19 11:57:46 +010054
Matteo Martincighd0613b52019-10-09 16:47:04 +010055 std::lock_guard<std::mutex> lock(m_Mutex);
56
Narumol Prangnawarat0ec068f2019-09-30 16:20:20 +010057 m_WrittenData.push_back(length);
Matteo Martincigh5d737fb2019-10-07 13:05:13 +010058 return true;
Narumol Prangnawarat0ec068f2019-09-30 16:20:20 +010059 }
Matteo Martincigh54fb9572019-10-02 12:50:57 +010060 bool WritePacket(Packet&& packet)
61 {
Matteo Martincighd0613b52019-10-09 16:47:04 +010062 std::lock_guard<std::mutex> lock(m_Mutex);
63
Matteo Martincigh54fb9572019-10-02 12:50:57 +010064 m_Packet = std::move(packet);
65 return true;
66 }
Narumol Prangnawarat0ec068f2019-09-30 16:20:20 +010067
Matteo Martincigh54fb9572019-10-02 12:50:57 +010068 Packet ReadPacket(uint32_t timeout) override
69 {
70 // Simulate a delay in the reading process
Matteo Martincighd0613b52019-10-09 16:47:04 +010071 std::this_thread::sleep_for(std::chrono::milliseconds(timeout));
72
73 std::lock_guard<std::mutex> lock(m_Mutex);
Matteo Martincigh54fb9572019-10-02 12:50:57 +010074
75 return std::move(m_Packet);
76 }
Narumol Prangnawarat0ec068f2019-09-30 16:20:20 +010077
Matteo Martincighe8485382019-10-10 14:08:21 +010078 const std::vector<uint32_t> GetWrittenData()
Matteo Martincighd0613b52019-10-09 16:47:04 +010079 {
80 std::lock_guard<std::mutex> lock(m_Mutex);
Matteo Martincigh5d737fb2019-10-07 13:05:13 +010081
Matteo Martincighe8485382019-10-10 14:08:21 +010082 std::vector<uint32_t> writtenData = m_WrittenData;
83 m_WrittenData.clear();
84 return writtenData;
Matteo Martincighd0613b52019-10-09 16:47:04 +010085 }
86
87 void Clear()
88 {
89 std::lock_guard<std::mutex> lock(m_Mutex);
90
91 m_WrittenData.clear();
92 }
Narumol Prangnawarat0ec068f2019-09-30 16:20:20 +010093
94private:
95 bool m_IsOpen;
96 std::vector<uint32_t> m_WrittenData;
Matteo Martincigh54fb9572019-10-02 12:50:57 +010097 Packet m_Packet;
Matteo Martincighd0613b52019-10-09 16:47:04 +010098 mutable std::mutex m_Mutex;
Narumol Prangnawarat0ec068f2019-09-30 16:20:20 +010099};
100
Matteo Martincighe8485382019-10-10 14:08:21 +0100101class MockProfilingConnectionFactory : public IProfilingConnectionFactory
102{
103public:
104 IProfilingConnectionPtr GetProfilingConnection(const ExternalProfilingOptions& options) const override
105 {
106 return std::make_unique<MockProfilingConnection>();
107 }
108};
109
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100110class MockPacketBuffer : public IPacketBuffer
Ferran Balaguer1b941722019-08-28 16:57:18 +0100111{
112public:
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100113 MockPacketBuffer(unsigned int maxSize)
Matteo Martincigh61d6f732019-10-03 11:21:18 +0100114 : m_MaxSize(maxSize)
115 , m_Size(0)
116 , m_Data(std::make_unique<unsigned char[]>(m_MaxSize))
117 {}
Ferran Balaguer1b941722019-08-28 16:57:18 +0100118
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100119 ~MockPacketBuffer() {}
120
121 const unsigned char* const GetReadableData() const override { return m_Data.get(); }
122
123 unsigned int GetSize() const override { return m_Size; }
124
Matteo Martincigh61d6f732019-10-03 11:21:18 +0100125 void MarkRead() override { m_Size = 0; }
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100126
127 void Commit(unsigned int size) override { m_Size = size; }
128
129 void Release() override { m_Size = 0; }
130
131 unsigned char* GetWritableData() override { return m_Data.get(); }
132
133private:
134 unsigned int m_MaxSize;
135 unsigned int m_Size;
136 std::unique_ptr<unsigned char[]> m_Data;
137};
138
139class MockBufferManager : public IBufferManager
140{
141public:
142 MockBufferManager(unsigned int size)
143 : m_BufferSize(size),
144 m_Buffer(std::make_unique<MockPacketBuffer>(size)) {}
145
146 ~MockBufferManager() {}
147
Matteo Martincigh2ffcc412019-11-05 11:47:40 +0000148 IPacketBufferPtr Reserve(unsigned int requestedSize, unsigned int& reservedSize) override
Ferran Balaguer1b941722019-08-28 16:57:18 +0100149 {
150 if (requestedSize > m_BufferSize)
151 {
152 reservedSize = m_BufferSize;
153 }
154 else
155 {
156 reservedSize = requestedSize;
157 }
158
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100159 return std::move(m_Buffer);
Ferran Balaguer1b941722019-08-28 16:57:18 +0100160 }
161
Matteo Martincigh2ffcc412019-11-05 11:47:40 +0000162 void Commit(IPacketBufferPtr& packetBuffer, unsigned int size) override
Ferran Balaguer1b941722019-08-28 16:57:18 +0100163 {
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100164 packetBuffer->Commit(size);
165 m_Buffer = std::move(packetBuffer);
Ferran Balaguer1b941722019-08-28 16:57:18 +0100166 }
167
Matteo Martincigh2ffcc412019-11-05 11:47:40 +0000168 IPacketBufferPtr GetReadableBuffer() override
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100169 {
170 return std::move(m_Buffer);
171 }
172
Matteo Martincigh2ffcc412019-11-05 11:47:40 +0000173 void Release(IPacketBufferPtr& packetBuffer) override
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100174 {
175 packetBuffer->Release();
176 m_Buffer = std::move(packetBuffer);
177 }
178
Matteo Martincigh2ffcc412019-11-05 11:47:40 +0000179 void MarkRead(IPacketBufferPtr& packetBuffer) override
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100180 {
181 packetBuffer->MarkRead();
182 m_Buffer = std::move(packetBuffer);
183 }
Ferran Balaguer1b941722019-08-28 16:57:18 +0100184
185private:
186 unsigned int m_BufferSize;
Matteo Martincigh2ffcc412019-11-05 11:47:40 +0000187 IPacketBufferPtr m_Buffer;
Ferran Balaguer1b941722019-08-28 16:57:18 +0100188};
189
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100190class MockStreamCounterBuffer : public IBufferManager
Matteo Martincigh24e8f922019-09-19 11:57:46 +0100191{
192public:
Matteo Martincigh61d6f732019-10-03 11:21:18 +0100193 MockStreamCounterBuffer(unsigned int maxBufferSize = 4096)
194 : m_MaxBufferSize(maxBufferSize)
195 , m_BufferList()
196 , m_CommittedSize(0)
197 , m_ReadableSize(0)
198 , m_ReadSize(0)
199 {}
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100200 ~MockStreamCounterBuffer() {}
Matteo Martincigh24e8f922019-09-19 11:57:46 +0100201
Matteo Martincigh61d6f732019-10-03 11:21:18 +0100202 IPacketBufferPtr Reserve(unsigned int requestedSize, unsigned int& reservedSize) override
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100203 {
Matteo Martincighd0613b52019-10-09 16:47:04 +0100204 std::lock_guard<std::mutex> lock(m_Mutex);
Matteo Martincigh61d6f732019-10-03 11:21:18 +0100205
206 reservedSize = 0;
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100207 if (requestedSize > m_MaxBufferSize)
Narumol Prangnawarat7be47ef2019-09-27 18:00:11 +0100208 {
Matteo Martincigh61d6f732019-10-03 11:21:18 +0100209 throw armnn::InvalidArgumentException("The maximum buffer size that can be requested is [" +
210 std::to_string(m_MaxBufferSize) + "] bytes");
Narumol Prangnawarat7be47ef2019-09-27 18:00:11 +0100211 }
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100212 reservedSize = requestedSize;
Matteo Martincigh61d6f732019-10-03 11:21:18 +0100213 return std::make_unique<MockPacketBuffer>(requestedSize);
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100214 }
215
Matteo Martincigh61d6f732019-10-03 11:21:18 +0100216 void Commit(IPacketBufferPtr& packetBuffer, unsigned int size) override
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100217 {
Matteo Martincighd0613b52019-10-09 16:47:04 +0100218 std::lock_guard<std::mutex> lock(m_Mutex);
Matteo Martincigh61d6f732019-10-03 11:21:18 +0100219
220 packetBuffer->Commit(size);
221 m_BufferList.push_back(std::move(packetBuffer));
Matteo Martincigh24e8f922019-09-19 11:57:46 +0100222 m_CommittedSize += size;
223 }
224
Matteo Martincigh61d6f732019-10-03 11:21:18 +0100225 void Release(IPacketBufferPtr& packetBuffer) override
Matteo Martincigh24e8f922019-09-19 11:57:46 +0100226 {
Matteo Martincighd0613b52019-10-09 16:47:04 +0100227 std::lock_guard<std::mutex> lock(m_Mutex);
Matteo Martincigh61d6f732019-10-03 11:21:18 +0100228
229 packetBuffer->Release();
Matteo Martincigh24e8f922019-09-19 11:57:46 +0100230 }
231
Matteo Martincigh61d6f732019-10-03 11:21:18 +0100232 IPacketBufferPtr GetReadableBuffer() override
Matteo Martincigh24e8f922019-09-19 11:57:46 +0100233 {
Matteo Martincighd0613b52019-10-09 16:47:04 +0100234 std::lock_guard<std::mutex> lock(m_Mutex);
Matteo Martincigh61d6f732019-10-03 11:21:18 +0100235
236 if (m_BufferList.empty())
Matteo Martincigh24e8f922019-09-19 11:57:46 +0100237 {
Matteo Martincigh61d6f732019-10-03 11:21:18 +0100238 return nullptr;
Matteo Martincigh24e8f922019-09-19 11:57:46 +0100239 }
Matteo Martincigh61d6f732019-10-03 11:21:18 +0100240 IPacketBufferPtr buffer = std::move(m_BufferList.back());
241 m_BufferList.pop_back();
242 m_ReadableSize += buffer->GetSize();
243 return buffer;
Matteo Martincigh24e8f922019-09-19 11:57:46 +0100244 }
245
Matteo Martincigh61d6f732019-10-03 11:21:18 +0100246 void MarkRead(IPacketBufferPtr& packetBuffer) override
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100247 {
Matteo Martincighd0613b52019-10-09 16:47:04 +0100248 std::lock_guard<std::mutex> lock(m_Mutex);
Matteo Martincigh61d6f732019-10-03 11:21:18 +0100249
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100250 m_ReadSize += packetBuffer->GetSize();
251 packetBuffer->MarkRead();
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100252 }
253
Matteo Martincigh61d6f732019-10-03 11:21:18 +0100254 unsigned int GetCommittedSize() const { return m_CommittedSize; }
255 unsigned int GetReadableSize() const { return m_ReadableSize; }
256 unsigned int GetReadSize() const { return m_ReadSize; }
Matteo Martincigh24e8f922019-09-19 11:57:46 +0100257
258private:
Matteo Martincigh61d6f732019-10-03 11:21:18 +0100259 // The maximum buffer size when creating a new buffer
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100260 unsigned int m_MaxBufferSize;
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100261
Matteo Martincigh61d6f732019-10-03 11:21:18 +0100262 // A list of buffers
263 std::vector<IPacketBufferPtr> m_BufferList;
Matteo Martincigh24e8f922019-09-19 11:57:46 +0100264
Matteo Martincigh61d6f732019-10-03 11:21:18 +0100265 // The mutex to synchronize this mock's methods
266 std::mutex m_Mutex;
267
268 // The total size of the buffers that has been committed for reading
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100269 unsigned int m_CommittedSize;
Matteo Martincigh24e8f922019-09-19 11:57:46 +0100270
Matteo Martincigh61d6f732019-10-03 11:21:18 +0100271 // The total size of the buffers that can be read
272 unsigned int m_ReadableSize;
273
274 // The total size of the buffers that has already been read
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100275 unsigned int m_ReadSize;
Matteo Martincigh24e8f922019-09-19 11:57:46 +0100276};
277
Ferran Balaguer1b941722019-08-28 16:57:18 +0100278class MockSendCounterPacket : public ISendCounterPacket
279{
280public:
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100281 MockSendCounterPacket(IBufferManager& sendBuffer) : m_BufferManager(sendBuffer) {}
Ferran Balaguer1b941722019-08-28 16:57:18 +0100282
283 void SendStreamMetaDataPacket() override
284 {
285 std::string message("SendStreamMetaDataPacket");
286 unsigned int reserved = 0;
Matteo Martincigh2ffcc412019-11-05 11:47:40 +0000287 IPacketBufferPtr buffer = m_BufferManager.Reserve(1024, reserved);
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100288 memcpy(buffer->GetWritableData(), message.c_str(), static_cast<unsigned int>(message.size()) + 1);
289 m_BufferManager.Commit(buffer, reserved);
Ferran Balaguer1b941722019-08-28 16:57:18 +0100290 }
291
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +0100292 void SendCounterDirectoryPacket(const ICounterDirectory& counterDirectory) override
Ferran Balaguer1b941722019-08-28 16:57:18 +0100293 {
294 std::string message("SendCounterDirectoryPacket");
295 unsigned int reserved = 0;
Matteo Martincigh2ffcc412019-11-05 11:47:40 +0000296 IPacketBufferPtr buffer = m_BufferManager.Reserve(1024, reserved);
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100297 memcpy(buffer->GetWritableData(), message.c_str(), static_cast<unsigned int>(message.size()) + 1);
298 m_BufferManager.Commit(buffer, reserved);
Ferran Balaguer1b941722019-08-28 16:57:18 +0100299 }
300
301 void SendPeriodicCounterCapturePacket(uint64_t timestamp,
302 const std::vector<std::pair<uint16_t, uint32_t>>& values) override
303 {
304 std::string message("SendPeriodicCounterCapturePacket");
305 unsigned int reserved = 0;
Matteo Martincigh2ffcc412019-11-05 11:47:40 +0000306 IPacketBufferPtr buffer = m_BufferManager.Reserve(1024, reserved);
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100307 memcpy(buffer->GetWritableData(), message.c_str(), static_cast<unsigned int>(message.size()) + 1);
308 m_BufferManager.Commit(buffer, reserved);
Ferran Balaguer1b941722019-08-28 16:57:18 +0100309 }
310
311 void SendPeriodicCounterSelectionPacket(uint32_t capturePeriod,
312 const std::vector<uint16_t>& selectedCounterIds) override
313 {
314 std::string message("SendPeriodicCounterSelectionPacket");
315 unsigned int reserved = 0;
Matteo Martincigh2ffcc412019-11-05 11:47:40 +0000316 IPacketBufferPtr buffer = m_BufferManager.Reserve(1024, reserved);
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100317 memcpy(buffer->GetWritableData(), message.c_str(), static_cast<unsigned int>(message.size()) + 1);
318 m_BufferManager.Commit(buffer, reserved);
Ferran Balaguer1b941722019-08-28 16:57:18 +0100319 }
320
Matteo Martincigh24e8f922019-09-19 11:57:46 +0100321 void SetReadyToRead() override {}
Ferran Balaguer1b941722019-08-28 16:57:18 +0100322
323private:
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100324 IBufferManager& m_BufferManager;
Ferran Balaguer1b941722019-08-28 16:57:18 +0100325};
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +0100326
327class MockCounterDirectory : public ICounterDirectory
328{
329public:
330 MockCounterDirectory() = default;
331 ~MockCounterDirectory() = default;
332
333 // Register profiling objects
334 const Category* RegisterCategory(const std::string& categoryName,
335 const armnn::Optional<uint16_t>& deviceUid = armnn::EmptyOptional(),
336 const armnn::Optional<uint16_t>& counterSetUid = armnn::EmptyOptional())
337 {
338 // Get the device UID
339 uint16_t deviceUidValue = deviceUid.has_value() ? deviceUid.value() : 0;
340
341 // Get the counter set UID
342 uint16_t counterSetUidValue = counterSetUid.has_value() ? counterSetUid.value() : 0;
343
344 // Create the category
345 CategoryPtr category = std::make_unique<Category>(categoryName, deviceUidValue, counterSetUidValue);
346 BOOST_ASSERT(category);
347
348 // Get the raw category pointer
349 const Category* categoryPtr = category.get();
350 BOOST_ASSERT(categoryPtr);
351
352 // Register the category
353 m_Categories.insert(std::move(category));
354
355 return categoryPtr;
356 }
357
358 const Device* RegisterDevice(const std::string& deviceName,
359 uint16_t cores = 0,
360 const armnn::Optional<std::string>& parentCategoryName = armnn::EmptyOptional())
361 {
362 // Get the device UID
363 uint16_t deviceUid = GetNextUid();
364
365 // Create the device
366 DevicePtr device = std::make_unique<Device>(deviceUid, deviceName, cores);
367 BOOST_ASSERT(device);
368
369 // Get the raw device pointer
370 const Device* devicePtr = device.get();
371 BOOST_ASSERT(devicePtr);
372
373 // Register the device
374 m_Devices.insert(std::make_pair(deviceUid, std::move(device)));
375
376 // Connect the counter set to the parent category, if required
377 if (parentCategoryName.has_value())
378 {
379 // Set the counter set UID in the parent category
380 Category* parentCategory = const_cast<Category*>(GetCategory(parentCategoryName.value()));
381 BOOST_ASSERT(parentCategory);
382 parentCategory->m_DeviceUid = deviceUid;
383 }
384
385 return devicePtr;
386 }
387
388 const CounterSet* RegisterCounterSet(
389 const std::string& counterSetName,
390 uint16_t count = 0,
391 const armnn::Optional<std::string>& parentCategoryName = armnn::EmptyOptional())
392 {
393 // Get the counter set UID
394 uint16_t counterSetUid = GetNextUid();
395
396 // Create the counter set
397 CounterSetPtr counterSet = std::make_unique<CounterSet>(counterSetUid, counterSetName, count);
398 BOOST_ASSERT(counterSet);
399
400 // Get the raw counter set pointer
401 const CounterSet* counterSetPtr = counterSet.get();
402 BOOST_ASSERT(counterSetPtr);
403
404 // Register the counter set
405 m_CounterSets.insert(std::make_pair(counterSetUid, std::move(counterSet)));
406
407 // Connect the counter set to the parent category, if required
408 if (parentCategoryName.has_value())
409 {
410 // Set the counter set UID in the parent category
411 Category* parentCategory = const_cast<Category*>(GetCategory(parentCategoryName.value()));
412 BOOST_ASSERT(parentCategory);
413 parentCategory->m_CounterSetUid = counterSetUid;
414 }
415
416 return counterSetPtr;
417 }
418
419 const Counter* RegisterCounter(const std::string& parentCategoryName,
420 uint16_t counterClass,
421 uint16_t interpolation,
422 double multiplier,
423 const std::string& name,
424 const std::string& description,
425 const armnn::Optional<std::string>& units = armnn::EmptyOptional(),
426 const armnn::Optional<uint16_t>& numberOfCores = armnn::EmptyOptional(),
427 const armnn::Optional<uint16_t>& deviceUid = armnn::EmptyOptional(),
428 const armnn::Optional<uint16_t>& counterSetUid = armnn::EmptyOptional())
429 {
430 // Get the number of cores from the argument only
431 uint16_t deviceCores = numberOfCores.has_value() ? numberOfCores.value() : 0;
432
433 // Get the device UID
434 uint16_t deviceUidValue = deviceUid.has_value() ? deviceUid.value() : 0;
435
436 // Get the counter set UID
437 uint16_t counterSetUidValue = counterSetUid.has_value() ? counterSetUid.value() : 0;
438
439 // Get the counter UIDs and calculate the max counter UID
440 std::vector<uint16_t> counterUids = GetNextCounterUids(deviceCores);
441 BOOST_ASSERT(!counterUids.empty());
442 uint16_t maxCounterUid = deviceCores <= 1 ? counterUids.front() : counterUids.back();
443
444 // Get the counter units
445 const std::string unitsValue = units.has_value() ? units.value() : "";
446
447 // Create the counter
448 CounterPtr counter = std::make_shared<Counter>(counterUids.front(),
449 maxCounterUid,
450 counterClass,
451 interpolation,
452 multiplier,
453 name,
454 description,
455 unitsValue,
456 deviceUidValue,
457 counterSetUidValue);
458 BOOST_ASSERT(counter);
459
460 // Get the raw counter pointer
461 const Counter* counterPtr = counter.get();
462 BOOST_ASSERT(counterPtr);
463
464 // Process multiple counters if necessary
465 for (uint16_t counterUid : counterUids)
466 {
467 // Connect the counter to the parent category
468 Category* parentCategory = const_cast<Category*>(GetCategory(parentCategoryName));
469 BOOST_ASSERT(parentCategory);
470 parentCategory->m_Counters.push_back(counterUid);
471
472 // Register the counter
473 m_Counters.insert(std::make_pair(counterUid, counter));
474 }
475
476 return counterPtr;
477 }
478
479 // Getters for counts
480 uint16_t GetCategoryCount() const override { return boost::numeric_cast<uint16_t>(m_Categories.size()); }
481 uint16_t GetDeviceCount() const override { return boost::numeric_cast<uint16_t>(m_Devices.size()); }
482 uint16_t GetCounterSetCount() const override { return boost::numeric_cast<uint16_t>(m_CounterSets.size()); }
483 uint16_t GetCounterCount() const override { return boost::numeric_cast<uint16_t>(m_Counters.size()); }
484
485 // Getters for collections
486 const Categories& GetCategories() const override { return m_Categories; }
487 const Devices& GetDevices() const override { return m_Devices; }
488 const CounterSets& GetCounterSets() const override { return m_CounterSets; }
489 const Counters& GetCounters() const override { return m_Counters; }
490
491 // Getters for profiling objects
492 const Category* GetCategory(const std::string& name) const override
493 {
494 auto it = std::find_if(m_Categories.begin(), m_Categories.end(), [&name](const CategoryPtr& category)
495 {
496 BOOST_ASSERT(category);
497
498 return category->m_Name == name;
499 });
500
501 if (it == m_Categories.end())
502 {
503 return nullptr;
504 }
505
506 return it->get();
507 }
508
509 const Device* GetDevice(uint16_t uid) const override
510 {
511 return nullptr; // Not used by the unit tests
512 }
513
514 const CounterSet* GetCounterSet(uint16_t uid) const override
515 {
516 return nullptr; // Not used by the unit tests
517 }
518
519 const Counter* GetCounter(uint16_t uid) const override
520 {
521 return nullptr; // Not used by the unit tests
522 }
523
524private:
525 Categories m_Categories;
526 Devices m_Devices;
527 CounterSets m_CounterSets;
528 Counters m_Counters;
529};
530
531class SendCounterPacketTest : public SendCounterPacket
532{
533public:
Matteo Martincigh5d737fb2019-10-07 13:05:13 +0100534 SendCounterPacketTest(ProfilingStateMachine& profilingStateMachine, IBufferManager& buffer)
535 : SendCounterPacket(profilingStateMachine, buffer)
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +0100536 {}
537
538 bool CreateDeviceRecordTest(const DevicePtr& device,
539 DeviceRecord& deviceRecord,
540 std::string& errorMessage)
541 {
542 return CreateDeviceRecord(device, deviceRecord, errorMessage);
543 }
544
545 bool CreateCounterSetRecordTest(const CounterSetPtr& counterSet,
546 CounterSetRecord& counterSetRecord,
547 std::string& errorMessage)
548 {
549 return CreateCounterSetRecord(counterSet, counterSetRecord, errorMessage);
550 }
551
552 bool CreateEventRecordTest(const CounterPtr& counter,
553 EventRecord& eventRecord,
554 std::string& errorMessage)
555 {
556 return CreateEventRecord(counter, eventRecord, errorMessage);
557 }
558
559 bool CreateCategoryRecordTest(const CategoryPtr& category,
560 const Counters& counters,
561 CategoryRecord& categoryRecord,
562 std::string& errorMessage)
563 {
564 return CreateCategoryRecord(category, counters, categoryRecord, errorMessage);
565 }
566};
Matteo Martincigh24e8f922019-09-19 11:57:46 +0100567
568} // namespace profiling
569
570} // namespace armnn