blob: 253ff4a8fc94e94ade1bc36e41cd137ea5202ba0 [file] [log] [blame]
David Monahanc1536d62020-02-12 15:52:35 +00001//
Jim Flynnbbfe6032020-07-20 16:57:44 +01002// Copyright © 2020 Arm Ltd and Contributors. All rights reserved.
David Monahanc1536d62020-02-12 15:52:35 +00003// SPDX-License-Identifier: MIT
4//
5
Jim Flynn34430252022-03-04 15:03:58 +00006#include "ArmNNProfilingServiceInitialiser.hpp"
Finn Williams032bc742020-02-12 11:02:34 +00007#include "CounterDirectory.hpp"
8#include "CounterIdMap.hpp"
9#include "Holder.hpp"
David Monahanc1536d62020-02-12 15:52:35 +000010#include "MockBackendId.hpp"
Finn Williams032bc742020-02-12 11:02:34 +000011#include "PeriodicCounterCapture.hpp"
12#include "PeriodicCounterSelectionCommandHandler.hpp"
Jim Flynn4c9ed1d2022-01-23 23:57:20 +000013#include "ProfilingOptionsConverter.hpp"
Finn Williams032bc742020-02-12 11:02:34 +000014#include "ProfilingStateMachine.hpp"
15#include "ProfilingUtils.hpp"
16#include "RequestCounterDirectoryCommandHandler.hpp"
David Monahanc1536d62020-02-12 15:52:35 +000017
Sadik Armagana097d2a2021-11-24 15:47:28 +000018#include <TestUtils.hpp>
Sadik Armagan3184c902020-03-18 10:57:30 +000019
Jan Eilers8eb25602020-03-09 12:13:48 +000020#include <armnn/utility/IgnoreUnused.hpp>
David Monahanc1536d62020-02-12 15:52:35 +000021#include <armnn/BackendId.hpp>
Finn Williams032bc742020-02-12 11:02:34 +000022#include <armnn/Logging.hpp>
Colm Donelanfcb802b2020-02-13 20:47:08 +000023#include <armnn/profiling/ISendTimelinePacket.hpp>
Jim Flynn4c9ed1d2022-01-23 23:57:20 +000024#include <armnn/profiling/ProfilingOptions.hpp>
Cathal Corbett3464ba12022-03-04 11:36:39 +000025#include <armnnTestUtils/MockBackend.hpp>
Finn Williams032bc742020-02-12 11:02:34 +000026
Sadik Armagan1625efc2021-06-10 18:24:34 +010027#include <doctest/doctest.h>
David Monahanc1536d62020-02-12 15:52:35 +000028#include <vector>
29
Finn Williams032bc742020-02-12 11:02:34 +000030#include <cstdint>
31#include <limits>
32#include <backends/BackendProfiling.hpp>
33
Jim Flynn6c9f17d2022-03-10 23:13:01 +000034
35namespace arm
36{
37
38namespace pipe
39{
40
41struct LogLevelSwapper
42{
43public:
44 LogLevelSwapper(arm::pipe::LogSeverity severity)
45 {
46 // Set the new log level
47 arm::pipe::ConfigureLogging(true, true, severity);
48 }
49 ~LogLevelSwapper()
50 {
51 // The default log level for unit tests is "Fatal"
52 arm::pipe::ConfigureLogging(true, true, arm::pipe::LogSeverity::Fatal);
53 }
54};
55
56} // namespace pipe
57
58} // namespace arm
59
Cathal Corbett5aa9fd72022-02-25 15:33:28 +000060using namespace arm::pipe;
Finn Williams032bc742020-02-12 11:02:34 +000061
62class ReadCounterVals : public IReadCounterValues
63{
64 virtual bool IsCounterRegistered(uint16_t counterUid) const override
65 {
66 return (counterUid > 4 && counterUid < 11);
67 }
Jim Flynn34430252022-03-04 15:03:58 +000068 virtual bool IsCounterRegistered(const std::string& counterName) const override
69 {
70 armnn::IgnoreUnused(counterName);
71 return false;
72 }
Finn Williams032bc742020-02-12 11:02:34 +000073 virtual uint16_t GetCounterCount() const override
74 {
75 return 1;
76 }
Finn Williamsf3fcf322020-05-11 14:38:02 +010077 virtual uint32_t GetAbsoluteCounterValue(uint16_t counterUid) const override
78 {
79 return counterUid;
80 }
81 virtual uint32_t GetDeltaCounterValue(uint16_t counterUid) override
Finn Williams032bc742020-02-12 11:02:34 +000082 {
83 return counterUid;
84 }
85};
86
87class MockBackendSendCounterPacket : public ISendCounterPacket
88{
89public:
90 using IndexValuePairsVector = std::vector<CounterValue>;
91
92 /// Create and write a StreamMetaDataPacket in the buffer
93 virtual void SendStreamMetaDataPacket() {}
94
95 /// Create and write a CounterDirectoryPacket from the parameters to the buffer.
96 virtual void SendCounterDirectoryPacket(const ICounterDirectory& counterDirectory)
97 {
Jan Eilers8eb25602020-03-09 12:13:48 +000098 armnn::IgnoreUnused(counterDirectory);
Finn Williams032bc742020-02-12 11:02:34 +000099 }
100
101 /// Create and write a PeriodicCounterCapturePacket from the parameters to the buffer.
102 virtual void SendPeriodicCounterCapturePacket(uint64_t timestamp, const IndexValuePairsVector& values)
103 {
104 m_timestamps.emplace_back(Timestamp{timestamp, values});
105 }
106
107 /// Create and write a PeriodicCounterSelectionPacket from the parameters to the buffer.
108 virtual void SendPeriodicCounterSelectionPacket(uint32_t capturePeriod,
109 const std::vector<uint16_t>& selectedCounterIds)
110 {
Jan Eilers8eb25602020-03-09 12:13:48 +0000111 armnn::IgnoreUnused(capturePeriod);
112 armnn::IgnoreUnused(selectedCounterIds);
Finn Williams032bc742020-02-12 11:02:34 +0000113 }
114
115 std::vector<Timestamp> GetTimestamps()
116 {
117 return m_timestamps;
118 }
119
120 void ClearTimestamps()
121 {
122 m_timestamps.clear();
123 }
124
125private:
126 std::vector<Timestamp> m_timestamps;
127};
128
Jim Flynnbbfe6032020-07-20 16:57:44 +0100129arm::pipe::Packet PacketWriter(uint32_t period, std::vector<uint16_t> countervalues)
Finn Williams032bc742020-02-12 11:02:34 +0000130{
131 const uint32_t packetId = 0x40000;
132 uint32_t offset = 0;
133 uint32_t dataLength = static_cast<uint32_t>(4 + countervalues.size() * 2);
134 std::unique_ptr<unsigned char[]> uniqueData = std::make_unique<unsigned char[]>(dataLength);
135 unsigned char* data1 = reinterpret_cast<unsigned char*>(uniqueData.get());
136
137 WriteUint32(data1, offset, period);
138 offset += 4;
139 for (auto countervalue : countervalues)
140 {
141 WriteUint16(data1, offset, countervalue);
142 offset += 2;
143 }
144
145 return {packetId, dataLength, uniqueData};
146}
147
Sadik Armagan1625efc2021-06-10 18:24:34 +0100148TEST_SUITE("BackendProfilingTestSuite")
149{
150TEST_CASE("BackendProfilingCounterRegisterMockBackendTest")
David Monahanc1536d62020-02-12 15:52:35 +0000151{
Jim Flynn6c9f17d2022-03-10 23:13:01 +0000152 arm::pipe::LogLevelSwapper logLevelSwapper(arm::pipe::LogSeverity::Fatal);
153
David Monahanc1536d62020-02-12 15:52:35 +0000154 // Reset the profiling service to the uninitialized state
155 armnn::IRuntime::CreationOptions options;
Finn Williams45a73622020-05-15 18:41:05 +0100156 options.m_ProfilingOptions.m_EnableProfiling = true;
David Monahanc1536d62020-02-12 15:52:35 +0000157
158 armnn::MockBackendInitialiser initialiser;
159 // Create a runtime
Kevin Mayd92a6e42021-02-04 10:27:41 +0000160 armnn::RuntimeImpl runtime(options);
David Monahanc1536d62020-02-12 15:52:35 +0000161
Narumol Prangnawarat060bad52020-11-20 16:17:48 +0000162 unsigned int shiftedId = 0;
163
Nikhil Raj01bc02d2021-05-07 17:07:09 +0100164 if (armnn::BackendRegistry().IsBackendRegistered("EthosNAcc"))
165 {
166 shiftedId = 4;
167 }
Narumol Prangnawarat060bad52020-11-20 16:17:48 +0000168
David Monahanc1536d62020-02-12 15:52:35 +0000169 // Check if the MockBackends 3 dummy counters {0, 1, 2-5 (four cores)} are registered
170 armnn::BackendId mockId = armnn::MockBackendId();
Cathal Corbett5aa9fd72022-02-25 15:33:28 +0000171 const ICounterMappings& counterMap = GetProfilingService(&runtime).GetCounterMappings();
Sadik Armagan1625efc2021-06-10 18:24:34 +0100172 CHECK(counterMap.GetGlobalId(0, mockId) == 5 + shiftedId);
173 CHECK(counterMap.GetGlobalId(1, mockId) == 6 + shiftedId);
174 CHECK(counterMap.GetGlobalId(2, mockId) == 7 + shiftedId);
175 CHECK(counterMap.GetGlobalId(3, mockId) == 8 + shiftedId);
176 CHECK(counterMap.GetGlobalId(4, mockId) == 9 + shiftedId);
177 CHECK(counterMap.GetGlobalId(5, mockId) == 10 + shiftedId);
David Monahanc1536d62020-02-12 15:52:35 +0000178 options.m_ProfilingOptions.m_EnableProfiling = false;
Jim Flynn4c9ed1d2022-01-23 23:57:20 +0000179 GetProfilingService(&runtime).ResetExternalProfilingOptions(
180 ConvertExternalProfilingOptions(options.m_ProfilingOptions), true);
David Monahanc1536d62020-02-12 15:52:35 +0000181}
182
Sadik Armagan1625efc2021-06-10 18:24:34 +0100183TEST_CASE("TestBackendCounters")
Finn Williams032bc742020-02-12 11:02:34 +0000184{
Jim Flynn6c9f17d2022-03-10 23:13:01 +0000185 arm::pipe::LogLevelSwapper logLevelSwapper(arm::pipe::LogSeverity::Fatal);
186
Finn Williams032bc742020-02-12 11:02:34 +0000187 Holder holder;
Jim Flynnbbfe6032020-07-20 16:57:44 +0100188 arm::pipe::PacketVersionResolver packetVersionResolver;
Finn Williams032bc742020-02-12 11:02:34 +0000189 ProfilingStateMachine stateMachine;
190 ReadCounterVals readCounterVals;
191 CounterIdMap counterIdMap;
192 MockBackendSendCounterPacket sendCounterPacket;
193
Cathal Corbett6f073722022-03-04 12:11:09 +0000194 const std::string cpuAccId(GetComputeDeviceAsCString(armnn::Compute::CpuAcc));
195 const std::string gpuAccId(GetComputeDeviceAsCString(armnn::Compute::GpuAcc));
Finn Williams032bc742020-02-12 11:02:34 +0000196
Jim Flynn4c9ed1d2022-01-23 23:57:20 +0000197 ProfilingOptions options;
198 options.m_EnableProfiling = true;
Finn Williams032bc742020-02-12 11:02:34 +0000199
Jim Flynn34430252022-03-04 15:03:58 +0000200 armnn::ArmNNProfilingServiceInitialiser initialiser;
201 std::unique_ptr<IProfilingService> profilingService = arm::pipe::IProfilingService::CreateProfilingService(
202 arm::pipe::MAX_ARMNN_COUNTER, initialiser);
Finn Williams032bc742020-02-12 11:02:34 +0000203
Cathal Corbett5aa9fd72022-02-25 15:33:28 +0000204 std::unique_ptr<IBackendProfiling> cpuBackendProfilingPtr =
Jim Flynn34430252022-03-04 15:03:58 +0000205 std::make_unique<BackendProfiling>(options, *profilingService.get(), cpuAccId);
Cathal Corbett5aa9fd72022-02-25 15:33:28 +0000206 std::unique_ptr<IBackendProfiling> gpuBackendProfilingPtr =
Jim Flynn34430252022-03-04 15:03:58 +0000207 std::make_unique<BackendProfiling>(options, *profilingService.get(), gpuAccId);
Finn Williams032bc742020-02-12 11:02:34 +0000208
Cathal Corbett5aa9fd72022-02-25 15:33:28 +0000209 std::shared_ptr<IBackendProfilingContext> cpuProfilingContextPtr =
Finn Williams032bc742020-02-12 11:02:34 +0000210 std::make_shared<armnn::MockBackendProfilingContext>(cpuBackendProfilingPtr);
Cathal Corbett5aa9fd72022-02-25 15:33:28 +0000211 std::shared_ptr<IBackendProfilingContext> gpuProfilingContextPtr =
Finn Williams032bc742020-02-12 11:02:34 +0000212 std::make_shared<armnn::MockBackendProfilingContext>(gpuBackendProfilingPtr);
213
Cathal Corbett6f073722022-03-04 12:11:09 +0000214 std::unordered_map<std::string,
Cathal Corbett5aa9fd72022-02-25 15:33:28 +0000215 std::shared_ptr<IBackendProfilingContext>> backendProfilingContexts;
Finn Williams032bc742020-02-12 11:02:34 +0000216
217 backendProfilingContexts[cpuAccId] = cpuProfilingContextPtr;
218 backendProfilingContexts[gpuAccId] = gpuProfilingContextPtr;
219
220 uint16_t globalId = 5;
221
222 counterIdMap.RegisterMapping(globalId++, 0, cpuAccId);
223 counterIdMap.RegisterMapping(globalId++, 1, cpuAccId);
224 counterIdMap.RegisterMapping(globalId++, 2, cpuAccId);
225
226 counterIdMap.RegisterMapping(globalId++, 0, gpuAccId);
227 counterIdMap.RegisterMapping(globalId++, 1, gpuAccId);
228 counterIdMap.RegisterMapping(globalId++, 2, gpuAccId);
229
230 backendProfilingContexts[cpuAccId] = cpuProfilingContextPtr;
231 backendProfilingContexts[gpuAccId] = gpuProfilingContextPtr;
232
233 PeriodicCounterCapture periodicCounterCapture(holder, sendCounterPacket, readCounterVals,
234 counterIdMap, backendProfilingContexts);
235
236 uint16_t maxArmnnCounterId = 4;
237
238 PeriodicCounterSelectionCommandHandler periodicCounterSelectionCommandHandler(0,
239 4,
240 packetVersionResolver.ResolvePacketVersion(0, 4).GetEncodedValue(),
241 backendProfilingContexts,
242 counterIdMap,
243 holder,
244 maxArmnnCounterId,
245 periodicCounterCapture,
246 readCounterVals,
247 sendCounterPacket,
248 stateMachine);
249
250 stateMachine.TransitionToState(ProfilingState::NotConnected);
251 stateMachine.TransitionToState(ProfilingState::WaitingForAck);
252 stateMachine.TransitionToState(ProfilingState::Active);
253
254 uint32_t period = 12345u;
255
256 std::vector<uint16_t> cpuCounters{5, 6, 7};
257 std::vector<uint16_t> gpuCounters{8, 9, 10};
258
259 // Request only gpu counters
260 periodicCounterSelectionCommandHandler(PacketWriter(period, gpuCounters));
261 periodicCounterCapture.Stop();
262
Cathal Corbett6f073722022-03-04 12:11:09 +0000263 std::set<std::string> activeIds = holder.GetCaptureData().GetActiveBackends();
Sadik Armagan1625efc2021-06-10 18:24:34 +0100264 CHECK(activeIds.size() == 1);
265 CHECK((activeIds.find(gpuAccId) != activeIds.end()));
Finn Williams032bc742020-02-12 11:02:34 +0000266
267 std::vector<Timestamp> recievedTimestamp = sendCounterPacket.GetTimestamps();
268
Sadik Armagan1625efc2021-06-10 18:24:34 +0100269 CHECK(recievedTimestamp[0].timestamp == period);
270 CHECK(recievedTimestamp.size() == 1);
271 CHECK(recievedTimestamp[0].counterValues.size() == gpuCounters.size());
Finn Williams032bc742020-02-12 11:02:34 +0000272 for (unsigned long i=0; i< gpuCounters.size(); ++i)
273 {
Sadik Armagan1625efc2021-06-10 18:24:34 +0100274 CHECK(recievedTimestamp[0].counterValues[i].counterId == gpuCounters[i]);
275 CHECK(recievedTimestamp[0].counterValues[i].counterValue == i + 1u);
Finn Williams032bc742020-02-12 11:02:34 +0000276 }
277 sendCounterPacket.ClearTimestamps();
278
279 // Request only cpu counters
280 periodicCounterSelectionCommandHandler(PacketWriter(period, cpuCounters));
281 periodicCounterCapture.Stop();
282
283 activeIds = holder.GetCaptureData().GetActiveBackends();
Sadik Armagan1625efc2021-06-10 18:24:34 +0100284 CHECK(activeIds.size() == 1);
285 CHECK((activeIds.find(cpuAccId) != activeIds.end()));
Finn Williams032bc742020-02-12 11:02:34 +0000286
287 recievedTimestamp = sendCounterPacket.GetTimestamps();
288
Sadik Armagan1625efc2021-06-10 18:24:34 +0100289 CHECK(recievedTimestamp[0].timestamp == period);
290 CHECK(recievedTimestamp.size() == 1);
291 CHECK(recievedTimestamp[0].counterValues.size() == cpuCounters.size());
Finn Williams032bc742020-02-12 11:02:34 +0000292 for (unsigned long i=0; i< cpuCounters.size(); ++i)
293 {
Sadik Armagan1625efc2021-06-10 18:24:34 +0100294 CHECK(recievedTimestamp[0].counterValues[i].counterId == cpuCounters[i]);
295 CHECK(recievedTimestamp[0].counterValues[i].counterValue == i + 1u);
Finn Williams032bc742020-02-12 11:02:34 +0000296 }
297 sendCounterPacket.ClearTimestamps();
298
299 // Request combination of cpu & gpu counters with new period
300 period = 12222u;
301 periodicCounterSelectionCommandHandler(PacketWriter(period, {cpuCounters[0], gpuCounters[2],
302 gpuCounters[1], cpuCounters[1], gpuCounters[0]}));
303 periodicCounterCapture.Stop();
304
305 activeIds = holder.GetCaptureData().GetActiveBackends();
Sadik Armagan1625efc2021-06-10 18:24:34 +0100306 CHECK(activeIds.size() == 2);
307 CHECK((activeIds.find(cpuAccId) != activeIds.end()));
308 CHECK((activeIds.find(gpuAccId) != activeIds.end()));
Finn Williams032bc742020-02-12 11:02:34 +0000309
310 recievedTimestamp = sendCounterPacket.GetTimestamps();
Sadik Armagan1625efc2021-06-10 18:24:34 +0100311//
312 CHECK(recievedTimestamp[0].timestamp == period);
313 CHECK(recievedTimestamp[1].timestamp == period);
Finn Williams032bc742020-02-12 11:02:34 +0000314
Sadik Armagan1625efc2021-06-10 18:24:34 +0100315 CHECK(recievedTimestamp.size() == 2);
316 CHECK(recievedTimestamp[0].counterValues.size() == 2);
317 CHECK(recievedTimestamp[1].counterValues.size() == gpuCounters.size());
Finn Williams032bc742020-02-12 11:02:34 +0000318
Sadik Armagan1625efc2021-06-10 18:24:34 +0100319 CHECK(recievedTimestamp[0].counterValues[0].counterId == cpuCounters[0]);
320 CHECK(recievedTimestamp[0].counterValues[0].counterValue == 1u);
321 CHECK(recievedTimestamp[0].counterValues[1].counterId == cpuCounters[1]);
322 CHECK(recievedTimestamp[0].counterValues[1].counterValue == 2u);
Finn Williams032bc742020-02-12 11:02:34 +0000323
324 for (unsigned long i=0; i< gpuCounters.size(); ++i)
325 {
Sadik Armagan1625efc2021-06-10 18:24:34 +0100326 CHECK(recievedTimestamp[1].counterValues[i].counterId == gpuCounters[i]);
327 CHECK(recievedTimestamp[1].counterValues[i].counterValue == i + 1u);
Finn Williams032bc742020-02-12 11:02:34 +0000328 }
329
330 sendCounterPacket.ClearTimestamps();
331
332 // Request all counters
333 std::vector<uint16_t> counterValues;
334 counterValues.insert(counterValues.begin(), cpuCounters.begin(), cpuCounters.end());
335 counterValues.insert(counterValues.begin(), gpuCounters.begin(), gpuCounters.end());
336
337 periodicCounterSelectionCommandHandler(PacketWriter(period, counterValues));
338 periodicCounterCapture.Stop();
339
340 activeIds = holder.GetCaptureData().GetActiveBackends();
Sadik Armagan1625efc2021-06-10 18:24:34 +0100341 CHECK(activeIds.size() == 2);
342 CHECK((activeIds.find(cpuAccId) != activeIds.end()));
343 CHECK((activeIds.find(gpuAccId) != activeIds.end()));
Finn Williams032bc742020-02-12 11:02:34 +0000344
345 recievedTimestamp = sendCounterPacket.GetTimestamps();
346
Sadik Armagan1625efc2021-06-10 18:24:34 +0100347 CHECK(recievedTimestamp[0].counterValues.size() == cpuCounters.size());
Finn Williams032bc742020-02-12 11:02:34 +0000348 for (unsigned long i=0; i< cpuCounters.size(); ++i)
349 {
Sadik Armagan1625efc2021-06-10 18:24:34 +0100350 CHECK(recievedTimestamp[0].counterValues[i].counterId == cpuCounters[i]);
351 CHECK(recievedTimestamp[0].counterValues[i].counterValue == i + 1u);
Finn Williams032bc742020-02-12 11:02:34 +0000352 }
353
Sadik Armagan1625efc2021-06-10 18:24:34 +0100354 CHECK(recievedTimestamp[1].counterValues.size() == gpuCounters.size());
Finn Williams032bc742020-02-12 11:02:34 +0000355 for (unsigned long i=0; i< gpuCounters.size(); ++i)
356 {
Sadik Armagan1625efc2021-06-10 18:24:34 +0100357 CHECK(recievedTimestamp[1].counterValues[i].counterId == gpuCounters[i]);
358 CHECK(recievedTimestamp[1].counterValues[i].counterValue == i + 1u);
Finn Williams032bc742020-02-12 11:02:34 +0000359 }
360 sendCounterPacket.ClearTimestamps();
361
362 // Request random counters with duplicates and invalid counters
363 counterValues = {0, 0, 200, cpuCounters[2], gpuCounters[0],3 ,30, cpuCounters[0],cpuCounters[2], gpuCounters[1], 3,
364 90, 0, 30, gpuCounters[0], gpuCounters[0]};
365
366 periodicCounterSelectionCommandHandler(PacketWriter(period, counterValues));
367 periodicCounterCapture.Stop();
368
369 activeIds = holder.GetCaptureData().GetActiveBackends();
Sadik Armagan1625efc2021-06-10 18:24:34 +0100370 CHECK(activeIds.size() == 2);
371 CHECK((activeIds.find(cpuAccId) != activeIds.end()));
372 CHECK((activeIds.find(gpuAccId) != activeIds.end()));
Finn Williams032bc742020-02-12 11:02:34 +0000373
374 recievedTimestamp = sendCounterPacket.GetTimestamps();
375
Sadik Armagan1625efc2021-06-10 18:24:34 +0100376 CHECK(recievedTimestamp.size() == 2);
Finn Williams032bc742020-02-12 11:02:34 +0000377
Sadik Armagan1625efc2021-06-10 18:24:34 +0100378 CHECK(recievedTimestamp[0].counterValues.size() == 2);
Finn Williams032bc742020-02-12 11:02:34 +0000379
Sadik Armagan1625efc2021-06-10 18:24:34 +0100380 CHECK(recievedTimestamp[0].counterValues[0].counterId == cpuCounters[0]);
381 CHECK(recievedTimestamp[0].counterValues[0].counterValue == 1u);
382 CHECK(recievedTimestamp[0].counterValues[1].counterId == cpuCounters[2]);
383 CHECK(recievedTimestamp[0].counterValues[1].counterValue == 3u);
Finn Williams032bc742020-02-12 11:02:34 +0000384
Sadik Armagan1625efc2021-06-10 18:24:34 +0100385 CHECK(recievedTimestamp[1].counterValues.size() == 2);
Finn Williams032bc742020-02-12 11:02:34 +0000386
Sadik Armagan1625efc2021-06-10 18:24:34 +0100387 CHECK(recievedTimestamp[1].counterValues[0].counterId == gpuCounters[0]);
388 CHECK(recievedTimestamp[1].counterValues[0].counterValue == 1u);
389 CHECK(recievedTimestamp[1].counterValues[1].counterId == gpuCounters[1]);
390 CHECK(recievedTimestamp[1].counterValues[1].counterValue == 2u);
Finn Williams032bc742020-02-12 11:02:34 +0000391
392 sendCounterPacket.ClearTimestamps();
393
394 // Request no counters
395 periodicCounterSelectionCommandHandler(PacketWriter(period, {}));
396 periodicCounterCapture.Stop();
397
398 activeIds = holder.GetCaptureData().GetActiveBackends();
Sadik Armagan1625efc2021-06-10 18:24:34 +0100399 CHECK(activeIds.size() == 0);
Finn Williams032bc742020-02-12 11:02:34 +0000400
401 recievedTimestamp = sendCounterPacket.GetTimestamps();
Sadik Armagan1625efc2021-06-10 18:24:34 +0100402 CHECK(recievedTimestamp.size() == 0);
Finn Williams032bc742020-02-12 11:02:34 +0000403
404 sendCounterPacket.ClearTimestamps();
405
406 // Request period of zero
407 periodicCounterSelectionCommandHandler(PacketWriter(0, counterValues));
408 periodicCounterCapture.Stop();
409
410 activeIds = holder.GetCaptureData().GetActiveBackends();
Sadik Armagan1625efc2021-06-10 18:24:34 +0100411 CHECK(activeIds.size() == 0);
Finn Williams032bc742020-02-12 11:02:34 +0000412
413 recievedTimestamp = sendCounterPacket.GetTimestamps();
Sadik Armagan1625efc2021-06-10 18:24:34 +0100414 CHECK(recievedTimestamp.size() == 0);
Finn Williams032bc742020-02-12 11:02:34 +0000415}
416
Sadik Armagan1625efc2021-06-10 18:24:34 +0100417TEST_CASE("TestBackendCounterLogging")
Finn Williams032bc742020-02-12 11:02:34 +0000418{
419 std::stringstream ss;
420
421 struct StreamRedirector
422 {
423 public:
424 StreamRedirector(std::ostream &stream, std::streambuf *newStreamBuffer)
425 : m_Stream(stream), m_BackupBuffer(m_Stream.rdbuf(newStreamBuffer))
426 {}
427
428 ~StreamRedirector()
429 { m_Stream.rdbuf(m_BackupBuffer); }
430
431 private:
432 std::ostream &m_Stream;
433 std::streambuf *m_BackupBuffer;
434 };
435
436 Holder holder;
Jim Flynnbbfe6032020-07-20 16:57:44 +0100437 arm::pipe::PacketVersionResolver packetVersionResolver;
Finn Williams032bc742020-02-12 11:02:34 +0000438 ProfilingStateMachine stateMachine;
439 ReadCounterVals readCounterVals;
440 StreamRedirector redirect(std::cout, ss.rdbuf());
441 CounterIdMap counterIdMap;
442 MockBackendSendCounterPacket sendCounterPacket;
443
Cathal Corbett6f073722022-03-04 12:11:09 +0000444 const std::string cpuAccId(GetComputeDeviceAsCString(armnn::Compute::CpuAcc));
445 const std::string gpuAccId(GetComputeDeviceAsCString(armnn::Compute::GpuAcc));
Finn Williams032bc742020-02-12 11:02:34 +0000446
Jim Flynn4c9ed1d2022-01-23 23:57:20 +0000447 ProfilingOptions options;
448 options.m_EnableProfiling = true;
Finn Williams032bc742020-02-12 11:02:34 +0000449
Jim Flynn34430252022-03-04 15:03:58 +0000450 armnn::ArmNNProfilingServiceInitialiser initialiser;
451 std::unique_ptr<IProfilingService> profilingService = arm::pipe::IProfilingService::CreateProfilingService(
452 arm::pipe::MAX_ARMNN_COUNTER, initialiser);
Finn Williams032bc742020-02-12 11:02:34 +0000453
Cathal Corbett5aa9fd72022-02-25 15:33:28 +0000454 std::unique_ptr<IBackendProfiling> cpuBackendProfilingPtr =
Jim Flynn34430252022-03-04 15:03:58 +0000455 std::make_unique<BackendProfiling>(options, *profilingService.get(), cpuAccId);
Finn Williams032bc742020-02-12 11:02:34 +0000456
Cathal Corbett5aa9fd72022-02-25 15:33:28 +0000457 std::shared_ptr<IBackendProfilingContext> cpuProfilingContextPtr =
Finn Williams032bc742020-02-12 11:02:34 +0000458 std::make_shared<armnn::MockBackendProfilingContext>(cpuBackendProfilingPtr);
459
Cathal Corbett6f073722022-03-04 12:11:09 +0000460 std::unordered_map<std::string,
Cathal Corbett5aa9fd72022-02-25 15:33:28 +0000461 std::shared_ptr<IBackendProfilingContext>> backendProfilingContexts;
Finn Williams032bc742020-02-12 11:02:34 +0000462
463 uint16_t globalId = 5;
464 counterIdMap.RegisterMapping(globalId, 0, cpuAccId);
465 backendProfilingContexts[cpuAccId] = cpuProfilingContextPtr;
466
467 PeriodicCounterCapture periodicCounterCapture(holder, sendCounterPacket, readCounterVals,
468 counterIdMap, backendProfilingContexts);
469
470 uint16_t maxArmnnCounterId = 4;
471
472 PeriodicCounterSelectionCommandHandler periodicCounterSelectionCommandHandler(0,
473 4,
474 packetVersionResolver.ResolvePacketVersion(0, 4).GetEncodedValue(),
475 backendProfilingContexts,
476 counterIdMap,
477 holder,
478 maxArmnnCounterId,
479 periodicCounterCapture,
480 readCounterVals,
481 sendCounterPacket,
482 stateMachine);
483
484 stateMachine.TransitionToState(ProfilingState::NotConnected);
485 stateMachine.TransitionToState(ProfilingState::WaitingForAck);
486 stateMachine.TransitionToState(ProfilingState::Active);
487
488 uint32_t period = 15939u;
489
Jim Flynn6c9f17d2022-03-10 23:13:01 +0000490 arm::pipe::SetAllLoggingSinks(true, false, false);
491 arm::pipe::SetLogFilter(arm::pipe::LogSeverity::Warning);
Finn Williams032bc742020-02-12 11:02:34 +0000492 periodicCounterSelectionCommandHandler(PacketWriter(period, {5}));
493 periodicCounterCapture.Stop();
Jim Flynn6c9f17d2022-03-10 23:13:01 +0000494 arm::pipe::SetLogFilter(arm::pipe::LogSeverity::Fatal);
Finn Williams032bc742020-02-12 11:02:34 +0000495
Sadik Armagan1625efc2021-06-10 18:24:34 +0100496 CHECK(ss.str().find("ActivateCounters example test error") != std::string::npos);
Finn Williams032bc742020-02-12 11:02:34 +0000497}
498
Sadik Armagan1625efc2021-06-10 18:24:34 +0100499TEST_CASE("BackendProfilingContextGetSendTimelinePacket")
Colm Donelanfcb802b2020-02-13 20:47:08 +0000500{
Jim Flynn6c9f17d2022-03-10 23:13:01 +0000501 arm::pipe::LogLevelSwapper logLevelSwapper(arm::pipe::LogSeverity::Fatal);
502
Colm Donelanfcb802b2020-02-13 20:47:08 +0000503 // Reset the profiling service to the uninitialized state
504 armnn::IRuntime::CreationOptions options;
505 options.m_ProfilingOptions.m_EnableProfiling = true;
Jim Flynn34430252022-03-04 15:03:58 +0000506
507 armnn::ArmNNProfilingServiceInitialiser psInitialiser;
508 std::unique_ptr<IProfilingService> profilingService = arm::pipe::IProfilingService::CreateProfilingService(
509 arm::pipe::MAX_ARMNN_COUNTER, psInitialiser);
510
511 profilingService->ConfigureProfilingService(
Jim Flynn4c9ed1d2022-01-23 23:57:20 +0000512 ConvertExternalProfilingOptions(options.m_ProfilingOptions), true);
Colm Donelanfcb802b2020-02-13 20:47:08 +0000513
514 armnn::MockBackendInitialiser initialiser;
515 // Create a runtime. During this the mock backend will be registered and context returned.
516 armnn::IRuntimePtr runtime(armnn::IRuntime::Create(options));
517 armnn::MockBackendProfilingService mockProfilingService = armnn::MockBackendProfilingService::Instance();
Jim Flynn34430252022-03-04 15:03:58 +0000518 armnn::MockBackendProfilingContext* mockBackEndProfilingContext = mockProfilingService.GetContext();
Colm Donelanfcb802b2020-02-13 20:47:08 +0000519 // Check that there is a valid context set.
Sadik Armagan1625efc2021-06-10 18:24:34 +0100520 CHECK(mockBackEndProfilingContext);
Colm Donelanfcb802b2020-02-13 20:47:08 +0000521 armnn::IBackendInternal::IBackendProfilingPtr& backendProfilingIface =
522 mockBackEndProfilingContext->GetBackendProfiling();
Sadik Armagan1625efc2021-06-10 18:24:34 +0100523 CHECK(backendProfilingIface);
Colm Donelanfcb802b2020-02-13 20:47:08 +0000524
525 // Now for the meat of the test. We're just going to send a random packet and make sure there
526 // are no exceptions or errors. The sending of packets is already tested in SendTimelinePacketTests.
Cathal Corbett5aa9fd72022-02-25 15:33:28 +0000527 std::unique_ptr<ISendTimelinePacket> timelinePacket =
Colm Donelanfcb802b2020-02-13 20:47:08 +0000528 backendProfilingIface->GetSendTimelinePacket();
529 // Send TimelineEntityClassBinaryPacket
530 const uint64_t entityBinaryPacketProfilingGuid = 123456u;
531 timelinePacket->SendTimelineEntityBinaryPacket(entityBinaryPacketProfilingGuid);
532 timelinePacket->Commit();
533
534 // Reset the profiling servie after the test.
535 options.m_ProfilingOptions.m_EnableProfiling = false;
Jim Flynn34430252022-03-04 15:03:58 +0000536 profilingService->ResetExternalProfilingOptions(
Jim Flynn4c9ed1d2022-01-23 23:57:20 +0000537 ConvertExternalProfilingOptions(options.m_ProfilingOptions), true);
Colm Donelanfcb802b2020-02-13 20:47:08 +0000538}
539
Sadik Armagan1625efc2021-06-10 18:24:34 +0100540TEST_CASE("GetProfilingGuidGenerator")
Colm Donelanfcb802b2020-02-13 20:47:08 +0000541{
Jim Flynn6c9f17d2022-03-10 23:13:01 +0000542 arm::pipe::LogLevelSwapper logLevelSwapper(arm::pipe::LogSeverity::Fatal);
543
Colm Donelanfcb802b2020-02-13 20:47:08 +0000544 // Reset the profiling service to the uninitialized state
545 armnn::IRuntime::CreationOptions options;
546 options.m_ProfilingOptions.m_EnableProfiling = true;
Colm Donelanfcb802b2020-02-13 20:47:08 +0000547
548 armnn::MockBackendInitialiser initialiser;
549 // Create a runtime. During this the mock backend will be registered and context returned.
550 armnn::IRuntimePtr runtime(armnn::IRuntime::Create(options));
551 armnn::MockBackendProfilingService mockProfilingService = armnn::MockBackendProfilingService::Instance();
552 armnn::MockBackendProfilingContext *mockBackEndProfilingContext = mockProfilingService.GetContext();
553 // Check that there is a valid context set.
Sadik Armagan1625efc2021-06-10 18:24:34 +0100554 CHECK(mockBackEndProfilingContext);
Colm Donelanfcb802b2020-02-13 20:47:08 +0000555 armnn::IBackendInternal::IBackendProfilingPtr& backendProfilingIface =
556 mockBackEndProfilingContext->GetBackendProfiling();
Sadik Armagan1625efc2021-06-10 18:24:34 +0100557 CHECK(backendProfilingIface);
Colm Donelanfcb802b2020-02-13 20:47:08 +0000558
559 // Get the Guid generator and check the getting two Guid's results in the second being greater than the first.
Cathal Corbett5aa9fd72022-02-25 15:33:28 +0000560 IProfilingGuidGenerator& guidGenerator = backendProfilingIface->GetProfilingGuidGenerator();
561 const ProfilingDynamicGuid& firstGuid = guidGenerator.NextGuid();
562 const ProfilingDynamicGuid& secondGuid = guidGenerator.NextGuid();
Sadik Armagan1625efc2021-06-10 18:24:34 +0100563 CHECK(secondGuid > firstGuid);
Colm Donelanfcb802b2020-02-13 20:47:08 +0000564
565 // Reset the profiling servie after the test.
566 options.m_ProfilingOptions.m_EnableProfiling = false;
Colm Donelanfcb802b2020-02-13 20:47:08 +0000567}
568
Sadik Armagan1625efc2021-06-10 18:24:34 +0100569}