blob: 439eff0a79a732a479b5592c766f65e9ff326e49 [file] [log] [blame]
David Monahanc1536d62020-02-12 15:52:35 +00001//
Nikhil Raj9d1786e2023-01-03 16:43:02 +00002// Copyright © 2020, 2023 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"
David Monahanc1536d62020-02-12 15:52:35 +00007#include "MockBackendId.hpp"
Jim Flynn4c9ed1d2022-01-23 23:57:20 +00008#include "ProfilingOptionsConverter.hpp"
David Monahanc1536d62020-02-12 15:52:35 +00009
Sadik Armagana097d2a2021-11-24 15:47:28 +000010#include <TestUtils.hpp>
Sadik Armagan3184c902020-03-18 10:57:30 +000011
David Monahanc1536d62020-02-12 15:52:35 +000012#include <armnn/BackendId.hpp>
Finn Williams032bc742020-02-12 11:02:34 +000013#include <armnn/Logging.hpp>
Jim Flynnc454ac92022-03-16 18:43:18 +000014
15#include <armnn/profiling/ArmNNProfiling.hpp>
Jim Flynnc454ac92022-03-16 18:43:18 +000016
17#include <armnn/utility/IgnoreUnused.hpp>
18
Cathal Corbett3464ba12022-03-04 11:36:39 +000019#include <armnnTestUtils/MockBackend.hpp>
Finn Williams032bc742020-02-12 11:02:34 +000020
Jim Flynn27761832022-03-20 21:52:17 +000021#include <client/include/CounterIdMap.hpp>
22#include <client/include/Holder.hpp>
23#include <client/include/ISendTimelinePacket.hpp>
24#include <client/include/ProfilingOptions.hpp>
25
Jim Flynn3e9bc192022-03-23 23:01:26 +000026#include <client/src/PeriodicCounterCapture.hpp>
27#include <client/src/PeriodicCounterSelectionCommandHandler.hpp>
28#include <client/src/ProfilingStateMachine.hpp>
29#include <client/src/ProfilingUtils.hpp>
30#include <client/src/RequestCounterDirectoryCommandHandler.hpp>
31
32#include <client/src/backends/BackendProfiling.hpp>
33
Jim Flynnc454ac92022-03-16 18:43:18 +000034#include <common/include/CounterDirectory.hpp>
Jim Flynn3e9bc192022-03-23 23:01:26 +000035#include <common/include/PacketVersionResolver.hpp>
Jim Flynnc454ac92022-03-16 18:43:18 +000036
37#include <doctest/doctest.h>
38
39#include <vector>
40#include <cstdint>
41#include <limits>
Jim Flynn6c9f17d2022-03-10 23:13:01 +000042
43namespace arm
44{
45
46namespace pipe
47{
48
49struct LogLevelSwapper
50{
51public:
52 LogLevelSwapper(arm::pipe::LogSeverity severity)
53 {
54 // Set the new log level
55 arm::pipe::ConfigureLogging(true, true, severity);
56 }
57 ~LogLevelSwapper()
58 {
59 // The default log level for unit tests is "Fatal"
60 arm::pipe::ConfigureLogging(true, true, arm::pipe::LogSeverity::Fatal);
61 }
62};
63
64} // namespace pipe
65
66} // namespace arm
67
Cathal Corbett5aa9fd72022-02-25 15:33:28 +000068using namespace arm::pipe;
Finn Williams032bc742020-02-12 11:02:34 +000069
70class ReadCounterVals : public IReadCounterValues
71{
72 virtual bool IsCounterRegistered(uint16_t counterUid) const override
73 {
74 return (counterUid > 4 && counterUid < 11);
75 }
Jim Flynn34430252022-03-04 15:03:58 +000076 virtual bool IsCounterRegistered(const std::string& counterName) const override
77 {
78 armnn::IgnoreUnused(counterName);
79 return false;
80 }
Finn Williams032bc742020-02-12 11:02:34 +000081 virtual uint16_t GetCounterCount() const override
82 {
83 return 1;
84 }
Finn Williamsf3fcf322020-05-11 14:38:02 +010085 virtual uint32_t GetAbsoluteCounterValue(uint16_t counterUid) const override
86 {
87 return counterUid;
88 }
89 virtual uint32_t GetDeltaCounterValue(uint16_t counterUid) override
Finn Williams032bc742020-02-12 11:02:34 +000090 {
91 return counterUid;
92 }
93};
94
95class MockBackendSendCounterPacket : public ISendCounterPacket
96{
97public:
98 using IndexValuePairsVector = std::vector<CounterValue>;
99
100 /// Create and write a StreamMetaDataPacket in the buffer
101 virtual void SendStreamMetaDataPacket() {}
102
103 /// Create and write a CounterDirectoryPacket from the parameters to the buffer.
104 virtual void SendCounterDirectoryPacket(const ICounterDirectory& counterDirectory)
105 {
Jan Eilers8eb25602020-03-09 12:13:48 +0000106 armnn::IgnoreUnused(counterDirectory);
Finn Williams032bc742020-02-12 11:02:34 +0000107 }
108
109 /// Create and write a PeriodicCounterCapturePacket from the parameters to the buffer.
110 virtual void SendPeriodicCounterCapturePacket(uint64_t timestamp, const IndexValuePairsVector& values)
111 {
112 m_timestamps.emplace_back(Timestamp{timestamp, values});
113 }
114
115 /// Create and write a PeriodicCounterSelectionPacket from the parameters to the buffer.
116 virtual void SendPeriodicCounterSelectionPacket(uint32_t capturePeriod,
117 const std::vector<uint16_t>& selectedCounterIds)
118 {
Jan Eilers8eb25602020-03-09 12:13:48 +0000119 armnn::IgnoreUnused(capturePeriod);
120 armnn::IgnoreUnused(selectedCounterIds);
Finn Williams032bc742020-02-12 11:02:34 +0000121 }
122
123 std::vector<Timestamp> GetTimestamps()
124 {
125 return m_timestamps;
126 }
127
128 void ClearTimestamps()
129 {
130 m_timestamps.clear();
131 }
132
133private:
134 std::vector<Timestamp> m_timestamps;
135};
136
Jim Flynnbbfe6032020-07-20 16:57:44 +0100137arm::pipe::Packet PacketWriter(uint32_t period, std::vector<uint16_t> countervalues)
Finn Williams032bc742020-02-12 11:02:34 +0000138{
139 const uint32_t packetId = 0x40000;
140 uint32_t offset = 0;
141 uint32_t dataLength = static_cast<uint32_t>(4 + countervalues.size() * 2);
142 std::unique_ptr<unsigned char[]> uniqueData = std::make_unique<unsigned char[]>(dataLength);
143 unsigned char* data1 = reinterpret_cast<unsigned char*>(uniqueData.get());
144
145 WriteUint32(data1, offset, period);
146 offset += 4;
147 for (auto countervalue : countervalues)
148 {
149 WriteUint16(data1, offset, countervalue);
150 offset += 2;
151 }
152
153 return {packetId, dataLength, uniqueData};
154}
155
Sadik Armagan1625efc2021-06-10 18:24:34 +0100156TEST_SUITE("BackendProfilingTestSuite")
157{
158TEST_CASE("BackendProfilingCounterRegisterMockBackendTest")
David Monahanc1536d62020-02-12 15:52:35 +0000159{
Jim Flynn6c9f17d2022-03-10 23:13:01 +0000160 arm::pipe::LogLevelSwapper logLevelSwapper(arm::pipe::LogSeverity::Fatal);
161
David Monahanc1536d62020-02-12 15:52:35 +0000162 // Reset the profiling service to the uninitialized state
163 armnn::IRuntime::CreationOptions options;
Finn Williams45a73622020-05-15 18:41:05 +0100164 options.m_ProfilingOptions.m_EnableProfiling = true;
David Monahanc1536d62020-02-12 15:52:35 +0000165
166 armnn::MockBackendInitialiser initialiser;
167 // Create a runtime
Kevin Mayd92a6e42021-02-04 10:27:41 +0000168 armnn::RuntimeImpl runtime(options);
David Monahanc1536d62020-02-12 15:52:35 +0000169
170 // Check if the MockBackends 3 dummy counters {0, 1, 2-5 (four cores)} are registered
171 armnn::BackendId mockId = armnn::MockBackendId();
Nikhil Raj1bc497e2023-05-08 16:16:33 +0100172
173 CHECK(GetProfilingService(&runtime).IsCategoryRegistered("MockCounters"));
174 CHECK(GetProfilingService(&runtime).IsCounterRegistered("Mock Counter One"));
175 CHECK(GetProfilingService(&runtime).IsCounterRegistered("Mock Counter Two"));
176 CHECK(GetProfilingService(&runtime).IsCounterRegistered("Mock MultiCore Counter"));
177
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(
Jim Flynn9c85b412022-03-16 00:27:43 +0000202 arm::pipe::MAX_ARMNN_COUNTER,
203 initialiser,
204 arm::pipe::ARMNN_SOFTWARE_INFO,
205 arm::pipe::ARMNN_SOFTWARE_VERSION,
206 arm::pipe::ARMNN_HARDWARE_VERSION);
Finn Williams032bc742020-02-12 11:02:34 +0000207
Cathal Corbett5aa9fd72022-02-25 15:33:28 +0000208 std::unique_ptr<IBackendProfiling> cpuBackendProfilingPtr =
Jim Flynn34430252022-03-04 15:03:58 +0000209 std::make_unique<BackendProfiling>(options, *profilingService.get(), cpuAccId);
Cathal Corbett5aa9fd72022-02-25 15:33:28 +0000210 std::unique_ptr<IBackendProfiling> gpuBackendProfilingPtr =
Jim Flynn34430252022-03-04 15:03:58 +0000211 std::make_unique<BackendProfiling>(options, *profilingService.get(), gpuAccId);
Finn Williams032bc742020-02-12 11:02:34 +0000212
Cathal Corbett5aa9fd72022-02-25 15:33:28 +0000213 std::shared_ptr<IBackendProfilingContext> cpuProfilingContextPtr =
Finn Williams032bc742020-02-12 11:02:34 +0000214 std::make_shared<armnn::MockBackendProfilingContext>(cpuBackendProfilingPtr);
Cathal Corbett5aa9fd72022-02-25 15:33:28 +0000215 std::shared_ptr<IBackendProfilingContext> gpuProfilingContextPtr =
Finn Williams032bc742020-02-12 11:02:34 +0000216 std::make_shared<armnn::MockBackendProfilingContext>(gpuBackendProfilingPtr);
217
Cathal Corbett6f073722022-03-04 12:11:09 +0000218 std::unordered_map<std::string,
Cathal Corbett5aa9fd72022-02-25 15:33:28 +0000219 std::shared_ptr<IBackendProfilingContext>> backendProfilingContexts;
Finn Williams032bc742020-02-12 11:02:34 +0000220
221 backendProfilingContexts[cpuAccId] = cpuProfilingContextPtr;
222 backendProfilingContexts[gpuAccId] = gpuProfilingContextPtr;
223
224 uint16_t globalId = 5;
225
226 counterIdMap.RegisterMapping(globalId++, 0, cpuAccId);
227 counterIdMap.RegisterMapping(globalId++, 1, cpuAccId);
228 counterIdMap.RegisterMapping(globalId++, 2, cpuAccId);
229
230 counterIdMap.RegisterMapping(globalId++, 0, gpuAccId);
231 counterIdMap.RegisterMapping(globalId++, 1, gpuAccId);
232 counterIdMap.RegisterMapping(globalId++, 2, gpuAccId);
233
234 backendProfilingContexts[cpuAccId] = cpuProfilingContextPtr;
235 backendProfilingContexts[gpuAccId] = gpuProfilingContextPtr;
236
237 PeriodicCounterCapture periodicCounterCapture(holder, sendCounterPacket, readCounterVals,
238 counterIdMap, backendProfilingContexts);
239
240 uint16_t maxArmnnCounterId = 4;
241
242 PeriodicCounterSelectionCommandHandler periodicCounterSelectionCommandHandler(0,
243 4,
244 packetVersionResolver.ResolvePacketVersion(0, 4).GetEncodedValue(),
245 backendProfilingContexts,
246 counterIdMap,
247 holder,
248 maxArmnnCounterId,
249 periodicCounterCapture,
250 readCounterVals,
251 sendCounterPacket,
252 stateMachine);
253
254 stateMachine.TransitionToState(ProfilingState::NotConnected);
255 stateMachine.TransitionToState(ProfilingState::WaitingForAck);
256 stateMachine.TransitionToState(ProfilingState::Active);
257
258 uint32_t period = 12345u;
259
260 std::vector<uint16_t> cpuCounters{5, 6, 7};
261 std::vector<uint16_t> gpuCounters{8, 9, 10};
262
263 // Request only gpu counters
264 periodicCounterSelectionCommandHandler(PacketWriter(period, gpuCounters));
265 periodicCounterCapture.Stop();
266
Cathal Corbett6f073722022-03-04 12:11:09 +0000267 std::set<std::string> activeIds = holder.GetCaptureData().GetActiveBackends();
Sadik Armagan1625efc2021-06-10 18:24:34 +0100268 CHECK(activeIds.size() == 1);
269 CHECK((activeIds.find(gpuAccId) != activeIds.end()));
Finn Williams032bc742020-02-12 11:02:34 +0000270
271 std::vector<Timestamp> recievedTimestamp = sendCounterPacket.GetTimestamps();
272
Sadik Armagan1625efc2021-06-10 18:24:34 +0100273 CHECK(recievedTimestamp[0].timestamp == period);
274 CHECK(recievedTimestamp.size() == 1);
275 CHECK(recievedTimestamp[0].counterValues.size() == gpuCounters.size());
Finn Williams032bc742020-02-12 11:02:34 +0000276 for (unsigned long i=0; i< gpuCounters.size(); ++i)
277 {
Sadik Armagan1625efc2021-06-10 18:24:34 +0100278 CHECK(recievedTimestamp[0].counterValues[i].counterId == gpuCounters[i]);
279 CHECK(recievedTimestamp[0].counterValues[i].counterValue == i + 1u);
Finn Williams032bc742020-02-12 11:02:34 +0000280 }
281 sendCounterPacket.ClearTimestamps();
282
283 // Request only cpu counters
284 periodicCounterSelectionCommandHandler(PacketWriter(period, cpuCounters));
285 periodicCounterCapture.Stop();
286
287 activeIds = holder.GetCaptureData().GetActiveBackends();
Sadik Armagan1625efc2021-06-10 18:24:34 +0100288 CHECK(activeIds.size() == 1);
289 CHECK((activeIds.find(cpuAccId) != activeIds.end()));
Finn Williams032bc742020-02-12 11:02:34 +0000290
291 recievedTimestamp = sendCounterPacket.GetTimestamps();
292
Sadik Armagan1625efc2021-06-10 18:24:34 +0100293 CHECK(recievedTimestamp[0].timestamp == period);
294 CHECK(recievedTimestamp.size() == 1);
295 CHECK(recievedTimestamp[0].counterValues.size() == cpuCounters.size());
Finn Williams032bc742020-02-12 11:02:34 +0000296 for (unsigned long i=0; i< cpuCounters.size(); ++i)
297 {
Sadik Armagan1625efc2021-06-10 18:24:34 +0100298 CHECK(recievedTimestamp[0].counterValues[i].counterId == cpuCounters[i]);
299 CHECK(recievedTimestamp[0].counterValues[i].counterValue == i + 1u);
Finn Williams032bc742020-02-12 11:02:34 +0000300 }
301 sendCounterPacket.ClearTimestamps();
302
303 // Request combination of cpu & gpu counters with new period
304 period = 12222u;
305 periodicCounterSelectionCommandHandler(PacketWriter(period, {cpuCounters[0], gpuCounters[2],
306 gpuCounters[1], cpuCounters[1], gpuCounters[0]}));
307 periodicCounterCapture.Stop();
308
309 activeIds = holder.GetCaptureData().GetActiveBackends();
Sadik Armagan1625efc2021-06-10 18:24:34 +0100310 CHECK(activeIds.size() == 2);
311 CHECK((activeIds.find(cpuAccId) != activeIds.end()));
312 CHECK((activeIds.find(gpuAccId) != activeIds.end()));
Finn Williams032bc742020-02-12 11:02:34 +0000313
314 recievedTimestamp = sendCounterPacket.GetTimestamps();
Sadik Armagan1625efc2021-06-10 18:24:34 +0100315//
316 CHECK(recievedTimestamp[0].timestamp == period);
317 CHECK(recievedTimestamp[1].timestamp == period);
Finn Williams032bc742020-02-12 11:02:34 +0000318
Sadik Armagan1625efc2021-06-10 18:24:34 +0100319 CHECK(recievedTimestamp.size() == 2);
320 CHECK(recievedTimestamp[0].counterValues.size() == 2);
321 CHECK(recievedTimestamp[1].counterValues.size() == gpuCounters.size());
Finn Williams032bc742020-02-12 11:02:34 +0000322
Sadik Armagan1625efc2021-06-10 18:24:34 +0100323 CHECK(recievedTimestamp[0].counterValues[0].counterId == cpuCounters[0]);
324 CHECK(recievedTimestamp[0].counterValues[0].counterValue == 1u);
325 CHECK(recievedTimestamp[0].counterValues[1].counterId == cpuCounters[1]);
326 CHECK(recievedTimestamp[0].counterValues[1].counterValue == 2u);
Finn Williams032bc742020-02-12 11:02:34 +0000327
328 for (unsigned long i=0; i< gpuCounters.size(); ++i)
329 {
Sadik Armagan1625efc2021-06-10 18:24:34 +0100330 CHECK(recievedTimestamp[1].counterValues[i].counterId == gpuCounters[i]);
331 CHECK(recievedTimestamp[1].counterValues[i].counterValue == i + 1u);
Finn Williams032bc742020-02-12 11:02:34 +0000332 }
333
334 sendCounterPacket.ClearTimestamps();
335
336 // Request all counters
337 std::vector<uint16_t> counterValues;
338 counterValues.insert(counterValues.begin(), cpuCounters.begin(), cpuCounters.end());
339 counterValues.insert(counterValues.begin(), gpuCounters.begin(), gpuCounters.end());
340
341 periodicCounterSelectionCommandHandler(PacketWriter(period, counterValues));
342 periodicCounterCapture.Stop();
343
344 activeIds = holder.GetCaptureData().GetActiveBackends();
Sadik Armagan1625efc2021-06-10 18:24:34 +0100345 CHECK(activeIds.size() == 2);
346 CHECK((activeIds.find(cpuAccId) != activeIds.end()));
347 CHECK((activeIds.find(gpuAccId) != activeIds.end()));
Finn Williams032bc742020-02-12 11:02:34 +0000348
349 recievedTimestamp = sendCounterPacket.GetTimestamps();
350
Sadik Armagan1625efc2021-06-10 18:24:34 +0100351 CHECK(recievedTimestamp[0].counterValues.size() == cpuCounters.size());
Finn Williams032bc742020-02-12 11:02:34 +0000352 for (unsigned long i=0; i< cpuCounters.size(); ++i)
353 {
Sadik Armagan1625efc2021-06-10 18:24:34 +0100354 CHECK(recievedTimestamp[0].counterValues[i].counterId == cpuCounters[i]);
355 CHECK(recievedTimestamp[0].counterValues[i].counterValue == i + 1u);
Finn Williams032bc742020-02-12 11:02:34 +0000356 }
357
Sadik Armagan1625efc2021-06-10 18:24:34 +0100358 CHECK(recievedTimestamp[1].counterValues.size() == gpuCounters.size());
Finn Williams032bc742020-02-12 11:02:34 +0000359 for (unsigned long i=0; i< gpuCounters.size(); ++i)
360 {
Sadik Armagan1625efc2021-06-10 18:24:34 +0100361 CHECK(recievedTimestamp[1].counterValues[i].counterId == gpuCounters[i]);
362 CHECK(recievedTimestamp[1].counterValues[i].counterValue == i + 1u);
Finn Williams032bc742020-02-12 11:02:34 +0000363 }
364 sendCounterPacket.ClearTimestamps();
365
366 // Request random counters with duplicates and invalid counters
367 counterValues = {0, 0, 200, cpuCounters[2], gpuCounters[0],3 ,30, cpuCounters[0],cpuCounters[2], gpuCounters[1], 3,
368 90, 0, 30, gpuCounters[0], gpuCounters[0]};
369
370 periodicCounterSelectionCommandHandler(PacketWriter(period, counterValues));
371 periodicCounterCapture.Stop();
372
373 activeIds = holder.GetCaptureData().GetActiveBackends();
Sadik Armagan1625efc2021-06-10 18:24:34 +0100374 CHECK(activeIds.size() == 2);
375 CHECK((activeIds.find(cpuAccId) != activeIds.end()));
376 CHECK((activeIds.find(gpuAccId) != activeIds.end()));
Finn Williams032bc742020-02-12 11:02:34 +0000377
378 recievedTimestamp = sendCounterPacket.GetTimestamps();
379
Sadik Armagan1625efc2021-06-10 18:24:34 +0100380 CHECK(recievedTimestamp.size() == 2);
Finn Williams032bc742020-02-12 11:02:34 +0000381
Sadik Armagan1625efc2021-06-10 18:24:34 +0100382 CHECK(recievedTimestamp[0].counterValues.size() == 2);
Finn Williams032bc742020-02-12 11:02:34 +0000383
Sadik Armagan1625efc2021-06-10 18:24:34 +0100384 CHECK(recievedTimestamp[0].counterValues[0].counterId == cpuCounters[0]);
385 CHECK(recievedTimestamp[0].counterValues[0].counterValue == 1u);
386 CHECK(recievedTimestamp[0].counterValues[1].counterId == cpuCounters[2]);
387 CHECK(recievedTimestamp[0].counterValues[1].counterValue == 3u);
Finn Williams032bc742020-02-12 11:02:34 +0000388
Sadik Armagan1625efc2021-06-10 18:24:34 +0100389 CHECK(recievedTimestamp[1].counterValues.size() == 2);
Finn Williams032bc742020-02-12 11:02:34 +0000390
Sadik Armagan1625efc2021-06-10 18:24:34 +0100391 CHECK(recievedTimestamp[1].counterValues[0].counterId == gpuCounters[0]);
392 CHECK(recievedTimestamp[1].counterValues[0].counterValue == 1u);
393 CHECK(recievedTimestamp[1].counterValues[1].counterId == gpuCounters[1]);
394 CHECK(recievedTimestamp[1].counterValues[1].counterValue == 2u);
Finn Williams032bc742020-02-12 11:02:34 +0000395
396 sendCounterPacket.ClearTimestamps();
397
398 // Request no counters
399 periodicCounterSelectionCommandHandler(PacketWriter(period, {}));
400 periodicCounterCapture.Stop();
401
402 activeIds = holder.GetCaptureData().GetActiveBackends();
Sadik Armagan1625efc2021-06-10 18:24:34 +0100403 CHECK(activeIds.size() == 0);
Finn Williams032bc742020-02-12 11:02:34 +0000404
405 recievedTimestamp = sendCounterPacket.GetTimestamps();
Sadik Armagan1625efc2021-06-10 18:24:34 +0100406 CHECK(recievedTimestamp.size() == 0);
Finn Williams032bc742020-02-12 11:02:34 +0000407
408 sendCounterPacket.ClearTimestamps();
409
410 // Request period of zero
411 periodicCounterSelectionCommandHandler(PacketWriter(0, counterValues));
412 periodicCounterCapture.Stop();
413
414 activeIds = holder.GetCaptureData().GetActiveBackends();
Sadik Armagan1625efc2021-06-10 18:24:34 +0100415 CHECK(activeIds.size() == 0);
Finn Williams032bc742020-02-12 11:02:34 +0000416
417 recievedTimestamp = sendCounterPacket.GetTimestamps();
Sadik Armagan1625efc2021-06-10 18:24:34 +0100418 CHECK(recievedTimestamp.size() == 0);
Finn Williams032bc742020-02-12 11:02:34 +0000419}
420
Sadik Armagan1625efc2021-06-10 18:24:34 +0100421TEST_CASE("TestBackendCounterLogging")
Finn Williams032bc742020-02-12 11:02:34 +0000422{
423 std::stringstream ss;
424
425 struct StreamRedirector
426 {
427 public:
428 StreamRedirector(std::ostream &stream, std::streambuf *newStreamBuffer)
429 : m_Stream(stream), m_BackupBuffer(m_Stream.rdbuf(newStreamBuffer))
430 {}
431
432 ~StreamRedirector()
433 { m_Stream.rdbuf(m_BackupBuffer); }
434
435 private:
436 std::ostream &m_Stream;
437 std::streambuf *m_BackupBuffer;
438 };
439
440 Holder holder;
Jim Flynnbbfe6032020-07-20 16:57:44 +0100441 arm::pipe::PacketVersionResolver packetVersionResolver;
Finn Williams032bc742020-02-12 11:02:34 +0000442 ProfilingStateMachine stateMachine;
443 ReadCounterVals readCounterVals;
444 StreamRedirector redirect(std::cout, ss.rdbuf());
445 CounterIdMap counterIdMap;
446 MockBackendSendCounterPacket sendCounterPacket;
447
Cathal Corbett6f073722022-03-04 12:11:09 +0000448 const std::string cpuAccId(GetComputeDeviceAsCString(armnn::Compute::CpuAcc));
449 const std::string gpuAccId(GetComputeDeviceAsCString(armnn::Compute::GpuAcc));
Finn Williams032bc742020-02-12 11:02:34 +0000450
Jim Flynn4c9ed1d2022-01-23 23:57:20 +0000451 ProfilingOptions options;
452 options.m_EnableProfiling = true;
Finn Williams032bc742020-02-12 11:02:34 +0000453
Jim Flynn34430252022-03-04 15:03:58 +0000454 armnn::ArmNNProfilingServiceInitialiser initialiser;
455 std::unique_ptr<IProfilingService> profilingService = arm::pipe::IProfilingService::CreateProfilingService(
Jim Flynn9c85b412022-03-16 00:27:43 +0000456 arm::pipe::MAX_ARMNN_COUNTER,
457 initialiser,
458 arm::pipe::ARMNN_SOFTWARE_INFO,
459 arm::pipe::ARMNN_SOFTWARE_VERSION,
460 arm::pipe::ARMNN_HARDWARE_VERSION);
Finn Williams032bc742020-02-12 11:02:34 +0000461
Cathal Corbett5aa9fd72022-02-25 15:33:28 +0000462 std::unique_ptr<IBackendProfiling> cpuBackendProfilingPtr =
Jim Flynn34430252022-03-04 15:03:58 +0000463 std::make_unique<BackendProfiling>(options, *profilingService.get(), cpuAccId);
Finn Williams032bc742020-02-12 11:02:34 +0000464
Cathal Corbett5aa9fd72022-02-25 15:33:28 +0000465 std::shared_ptr<IBackendProfilingContext> cpuProfilingContextPtr =
Finn Williams032bc742020-02-12 11:02:34 +0000466 std::make_shared<armnn::MockBackendProfilingContext>(cpuBackendProfilingPtr);
467
Cathal Corbett6f073722022-03-04 12:11:09 +0000468 std::unordered_map<std::string,
Cathal Corbett5aa9fd72022-02-25 15:33:28 +0000469 std::shared_ptr<IBackendProfilingContext>> backendProfilingContexts;
Finn Williams032bc742020-02-12 11:02:34 +0000470
471 uint16_t globalId = 5;
472 counterIdMap.RegisterMapping(globalId, 0, cpuAccId);
473 backendProfilingContexts[cpuAccId] = cpuProfilingContextPtr;
474
475 PeriodicCounterCapture periodicCounterCapture(holder, sendCounterPacket, readCounterVals,
476 counterIdMap, backendProfilingContexts);
477
478 uint16_t maxArmnnCounterId = 4;
479
480 PeriodicCounterSelectionCommandHandler periodicCounterSelectionCommandHandler(0,
481 4,
482 packetVersionResolver.ResolvePacketVersion(0, 4).GetEncodedValue(),
483 backendProfilingContexts,
484 counterIdMap,
485 holder,
486 maxArmnnCounterId,
487 periodicCounterCapture,
488 readCounterVals,
489 sendCounterPacket,
490 stateMachine);
491
492 stateMachine.TransitionToState(ProfilingState::NotConnected);
493 stateMachine.TransitionToState(ProfilingState::WaitingForAck);
494 stateMachine.TransitionToState(ProfilingState::Active);
495
496 uint32_t period = 15939u;
497
Jim Flynn6c9f17d2022-03-10 23:13:01 +0000498 arm::pipe::SetAllLoggingSinks(true, false, false);
499 arm::pipe::SetLogFilter(arm::pipe::LogSeverity::Warning);
Finn Williams032bc742020-02-12 11:02:34 +0000500 periodicCounterSelectionCommandHandler(PacketWriter(period, {5}));
501 periodicCounterCapture.Stop();
Jim Flynn6c9f17d2022-03-10 23:13:01 +0000502 arm::pipe::SetLogFilter(arm::pipe::LogSeverity::Fatal);
Finn Williams032bc742020-02-12 11:02:34 +0000503
Sadik Armagan1625efc2021-06-10 18:24:34 +0100504 CHECK(ss.str().find("ActivateCounters example test error") != std::string::npos);
Finn Williams032bc742020-02-12 11:02:34 +0000505}
506
Sadik Armagan1625efc2021-06-10 18:24:34 +0100507TEST_CASE("BackendProfilingContextGetSendTimelinePacket")
Colm Donelanfcb802b2020-02-13 20:47:08 +0000508{
Jim Flynn6c9f17d2022-03-10 23:13:01 +0000509 arm::pipe::LogLevelSwapper logLevelSwapper(arm::pipe::LogSeverity::Fatal);
510
Colm Donelanfcb802b2020-02-13 20:47:08 +0000511 // Reset the profiling service to the uninitialized state
512 armnn::IRuntime::CreationOptions options;
513 options.m_ProfilingOptions.m_EnableProfiling = true;
Jim Flynn34430252022-03-04 15:03:58 +0000514
515 armnn::ArmNNProfilingServiceInitialiser psInitialiser;
516 std::unique_ptr<IProfilingService> profilingService = arm::pipe::IProfilingService::CreateProfilingService(
Jim Flynn9c85b412022-03-16 00:27:43 +0000517 arm::pipe::MAX_ARMNN_COUNTER,
518 psInitialiser,
519 arm::pipe::ARMNN_SOFTWARE_INFO,
520 arm::pipe::ARMNN_SOFTWARE_VERSION,
521 arm::pipe::ARMNN_HARDWARE_VERSION);
Jim Flynn34430252022-03-04 15:03:58 +0000522
523 profilingService->ConfigureProfilingService(
Jim Flynn4c9ed1d2022-01-23 23:57:20 +0000524 ConvertExternalProfilingOptions(options.m_ProfilingOptions), true);
Colm Donelanfcb802b2020-02-13 20:47:08 +0000525
526 armnn::MockBackendInitialiser initialiser;
527 // Create a runtime. During this the mock backend will be registered and context returned.
528 armnn::IRuntimePtr runtime(armnn::IRuntime::Create(options));
529 armnn::MockBackendProfilingService mockProfilingService = armnn::MockBackendProfilingService::Instance();
Jim Flynn34430252022-03-04 15:03:58 +0000530 armnn::MockBackendProfilingContext* mockBackEndProfilingContext = mockProfilingService.GetContext();
Colm Donelanfcb802b2020-02-13 20:47:08 +0000531 // Check that there is a valid context set.
Sadik Armagan1625efc2021-06-10 18:24:34 +0100532 CHECK(mockBackEndProfilingContext);
Colm Donelanfcb802b2020-02-13 20:47:08 +0000533 armnn::IBackendInternal::IBackendProfilingPtr& backendProfilingIface =
534 mockBackEndProfilingContext->GetBackendProfiling();
Sadik Armagan1625efc2021-06-10 18:24:34 +0100535 CHECK(backendProfilingIface);
Colm Donelanfcb802b2020-02-13 20:47:08 +0000536
537 // Now for the meat of the test. We're just going to send a random packet and make sure there
538 // are no exceptions or errors. The sending of packets is already tested in SendTimelinePacketTests.
Cathal Corbett5aa9fd72022-02-25 15:33:28 +0000539 std::unique_ptr<ISendTimelinePacket> timelinePacket =
Colm Donelanfcb802b2020-02-13 20:47:08 +0000540 backendProfilingIface->GetSendTimelinePacket();
541 // Send TimelineEntityClassBinaryPacket
542 const uint64_t entityBinaryPacketProfilingGuid = 123456u;
543 timelinePacket->SendTimelineEntityBinaryPacket(entityBinaryPacketProfilingGuid);
544 timelinePacket->Commit();
545
546 // Reset the profiling servie after the test.
547 options.m_ProfilingOptions.m_EnableProfiling = false;
Jim Flynn34430252022-03-04 15:03:58 +0000548 profilingService->ResetExternalProfilingOptions(
Jim Flynn4c9ed1d2022-01-23 23:57:20 +0000549 ConvertExternalProfilingOptions(options.m_ProfilingOptions), true);
Colm Donelanfcb802b2020-02-13 20:47:08 +0000550}
551
Sadik Armagan1625efc2021-06-10 18:24:34 +0100552TEST_CASE("GetProfilingGuidGenerator")
Colm Donelanfcb802b2020-02-13 20:47:08 +0000553{
Jim Flynn6c9f17d2022-03-10 23:13:01 +0000554 arm::pipe::LogLevelSwapper logLevelSwapper(arm::pipe::LogSeverity::Fatal);
555
Colm Donelanfcb802b2020-02-13 20:47:08 +0000556 // Reset the profiling service to the uninitialized state
557 armnn::IRuntime::CreationOptions options;
558 options.m_ProfilingOptions.m_EnableProfiling = true;
Colm Donelanfcb802b2020-02-13 20:47:08 +0000559
560 armnn::MockBackendInitialiser initialiser;
561 // Create a runtime. During this the mock backend will be registered and context returned.
562 armnn::IRuntimePtr runtime(armnn::IRuntime::Create(options));
563 armnn::MockBackendProfilingService mockProfilingService = armnn::MockBackendProfilingService::Instance();
564 armnn::MockBackendProfilingContext *mockBackEndProfilingContext = mockProfilingService.GetContext();
565 // Check that there is a valid context set.
Sadik Armagan1625efc2021-06-10 18:24:34 +0100566 CHECK(mockBackEndProfilingContext);
Colm Donelanfcb802b2020-02-13 20:47:08 +0000567 armnn::IBackendInternal::IBackendProfilingPtr& backendProfilingIface =
568 mockBackEndProfilingContext->GetBackendProfiling();
Sadik Armagan1625efc2021-06-10 18:24:34 +0100569 CHECK(backendProfilingIface);
Colm Donelanfcb802b2020-02-13 20:47:08 +0000570
571 // 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 +0000572 IProfilingGuidGenerator& guidGenerator = backendProfilingIface->GetProfilingGuidGenerator();
573 const ProfilingDynamicGuid& firstGuid = guidGenerator.NextGuid();
574 const ProfilingDynamicGuid& secondGuid = guidGenerator.NextGuid();
Sadik Armagan1625efc2021-06-10 18:24:34 +0100575 CHECK(secondGuid > firstGuid);
Colm Donelanfcb802b2020-02-13 20:47:08 +0000576
577 // Reset the profiling servie after the test.
578 options.m_ProfilingOptions.m_EnableProfiling = false;
Colm Donelanfcb802b2020-02-13 20:47:08 +0000579}
580
Sadik Armagan1625efc2021-06-10 18:24:34 +0100581}