blob: b641b5c3362ad06a40856215e8695a2e6f7b9c2c [file] [log] [blame]
Francis Murtagh1f7db452019-08-14 09:49:34 +01001//
Tracy Narine2883a862024-02-26 15:05:11 +00002// Copyright © 2019, 2024 Arm Ltd and Contributors. All rights reserved.
Francis Murtagh1f7db452019-08-14 09:49:34 +01003// SPDX-License-Identifier: MIT
4//
5
Matteo Martincighd0613b52019-10-09 16:47:04 +01006#include "ProfilingTests.hpp"
Keith Davis33ed2212020-03-30 10:43:41 +01007#include "ProfilingTestUtils.hpp"
Teresa Charlin9bab4962019-09-06 12:28:35 +01008#include <Runtime.hpp>
Jim Flynn3e9bc192022-03-23 23:01:26 +00009#include <ArmNNProfilingServiceInitialiser.hpp>
10
11#include <client/src/CommandHandler.hpp>
12#include <client/src/ConnectionAcknowledgedCommandHandler.hpp>
13#include <client/src/PeriodicCounterCapture.hpp>
14#include <client/src/PeriodicCounterSelectionCommandHandler.hpp>
15#include <client/src/ProfilingStateMachine.hpp>
16#include <client/src/ProfilingUtils.hpp>
17#include <client/src/RegisterBackendCounters.hpp>
18#include <client/src/RequestCounterDirectoryCommandHandler.hpp>
19#include <client/src/SocketProfilingConnection.hpp>
20#include <client/src/SendCounterPacket.hpp>
21#include <client/src/SendThread.hpp>
22#include <client/src/SendTimelinePacket.hpp>
23#include <client/src/backends/BackendProfiling.hpp>
Keith Davis02356de2019-08-26 18:28:17 +010024
Matteo Martincigh54fb9572019-10-02 12:50:57 +010025#include <armnn/Utils.hpp>
Jim Flynn75c14f42022-03-10 22:05:42 +000026
27#include <armnn/profiling/ArmNNProfiling.hpp>
Jim Flynn75c14f42022-03-10 22:05:42 +000028
Jim Flynn27761832022-03-20 21:52:17 +000029#include <client/include/CounterIdMap.hpp>
30#include <client/include/Holder.hpp>
31#include <client/include/ICounterValues.hpp>
32#include <client/include/ProfilingOptions.hpp>
33
Jim Flynnbbfe6032020-07-20 16:57:44 +010034#include <common/include/CommandHandlerKey.hpp>
35#include <common/include/CommandHandlerRegistry.hpp>
Jim Flynnc454ac92022-03-16 18:43:18 +000036#include <common/include/CounterDirectory.hpp>
Jim Flynn75c14f42022-03-10 22:05:42 +000037#include <common/include/EncodeVersion.hpp>
Jim Flynn9265a882022-03-10 23:35:26 +000038#include <common/include/IgnoreUnused.hpp>
Jim Flynn75c14f42022-03-10 22:05:42 +000039#include <common/include/NumericCast.hpp>
Jim Flynnbbfe6032020-07-20 16:57:44 +010040#include <common/include/Packet.hpp>
Jim Flynn75c14f42022-03-10 22:05:42 +000041#include <common/include/PacketVersionResolver.hpp>
42#include <common/include/SocketConnectionException.hpp>
43#include <common/include/SwTrace.hpp>
Jim Flynnbbfe6032020-07-20 16:57:44 +010044
Sadik Armagan1625efc2021-06-10 18:24:34 +010045#include <doctest/doctest.h>
46
Sadik Armagan95e9efc2021-08-05 15:01:07 +010047#include <algorithm>
Nikhil Rajbc626052019-08-15 15:49:45 +010048#include <cstdint>
49#include <cstring>
Keith Davis3201eea2019-10-24 17:30:41 +010050#include <iostream>
Aron Virginas-Tare898db92019-08-22 12:56:34 +010051#include <limits>
Francis Murtagh11f99b42019-08-16 11:28:52 +010052#include <map>
Aron Virginas-Tare898db92019-08-22 12:56:34 +010053#include <random>
James Conroy2dcd3fe2020-02-06 18:34:52 +000054
Francis Murtagh1f7db452019-08-14 09:49:34 +010055
Cathal Corbett5aa9fd72022-02-25 15:33:28 +000056using namespace arm::pipe;
Finn Williams09ad6f92019-12-19 17:05:18 +000057using PacketType = MockProfilingConnection::PacketType;
Aron Virginas-Tare898db92019-08-22 12:56:34 +010058
Sadik Armagan1625efc2021-06-10 18:24:34 +010059TEST_SUITE("ExternalProfiling")
60{
Tracy Narine2883a862024-02-26 15:05:11 +000061
62#if !defined(__APPLE__)
63
Sadik Armagan1625efc2021-06-10 18:24:34 +010064TEST_CASE("CheckCommandHandlerKeyComparisons")
Francis Murtagh1f7db452019-08-14 09:49:34 +010065{
Jim Flynnbbfe6032020-07-20 16:57:44 +010066 arm::pipe::CommandHandlerKey testKey1_0(1, 1, 1);
67 arm::pipe::CommandHandlerKey testKey1_1(1, 1, 1);
68 arm::pipe::CommandHandlerKey testKey1_2(1, 2, 1);
Jim Flynn397043f2019-10-17 17:37:10 +010069
Jim Flynnbbfe6032020-07-20 16:57:44 +010070 arm::pipe::CommandHandlerKey testKey0(0, 1, 1);
71 arm::pipe::CommandHandlerKey testKey1(0, 1, 1);
72 arm::pipe::CommandHandlerKey testKey2(0, 1, 1);
73 arm::pipe::CommandHandlerKey testKey3(0, 0, 0);
74 arm::pipe::CommandHandlerKey testKey4(0, 2, 2);
75 arm::pipe::CommandHandlerKey testKey5(0, 0, 2);
Jim Flynn397043f2019-10-17 17:37:10 +010076
Sadik Armagan1625efc2021-06-10 18:24:34 +010077 CHECK(testKey1_0 > testKey0);
78 CHECK(testKey1_0 == testKey1_1);
79 CHECK(testKey1_0 < testKey1_2);
Francis Murtagh1f7db452019-08-14 09:49:34 +010080
Sadik Armagan1625efc2021-06-10 18:24:34 +010081 CHECK(testKey1 < testKey4);
82 CHECK(testKey1 > testKey3);
83 CHECK(testKey1 <= testKey4);
84 CHECK(testKey1 >= testKey3);
85 CHECK(testKey1 <= testKey2);
86 CHECK(testKey1 >= testKey2);
87 CHECK(testKey1 == testKey2);
88 CHECK(testKey1 == testKey1);
Francis Murtagh1f7db452019-08-14 09:49:34 +010089
Sadik Armagan1625efc2021-06-10 18:24:34 +010090 CHECK(!(testKey1 == testKey5));
91 CHECK(!(testKey1 != testKey1));
92 CHECK(testKey1 != testKey5);
Francis Murtagh1f7db452019-08-14 09:49:34 +010093
Sadik Armagan1625efc2021-06-10 18:24:34 +010094 CHECK((testKey1 == testKey2 && testKey2 == testKey1));
95 CHECK((testKey0 == testKey1 && testKey1 == testKey2 && testKey0 == testKey2));
Francis Murtagh1f7db452019-08-14 09:49:34 +010096
Sadik Armagan1625efc2021-06-10 18:24:34 +010097 CHECK(testKey1.GetPacketId() == 1);
98 CHECK(testKey1.GetVersion() == 1);
Francis Murtagh1f7db452019-08-14 09:49:34 +010099
Jim Flynnbbfe6032020-07-20 16:57:44 +0100100 std::vector<arm::pipe::CommandHandlerKey> vect = {
101 arm::pipe::CommandHandlerKey(0, 0, 1), arm::pipe::CommandHandlerKey(0, 2, 0),
102 arm::pipe::CommandHandlerKey(0, 1, 0), arm::pipe::CommandHandlerKey(0, 2, 1),
103 arm::pipe::CommandHandlerKey(0, 1, 1), arm::pipe::CommandHandlerKey(0, 0, 1),
104 arm::pipe::CommandHandlerKey(0, 2, 0), arm::pipe::CommandHandlerKey(0, 0, 0) };
Francis Murtagh1f7db452019-08-14 09:49:34 +0100105
106 std::sort(vect.begin(), vect.end());
107
Jim Flynnbbfe6032020-07-20 16:57:44 +0100108 std::vector<arm::pipe::CommandHandlerKey> expectedVect = {
109 arm::pipe::CommandHandlerKey(0, 0, 0), arm::pipe::CommandHandlerKey(0, 0, 1),
110 arm::pipe::CommandHandlerKey(0, 0, 1), arm::pipe::CommandHandlerKey(0, 1, 0),
111 arm::pipe::CommandHandlerKey(0, 1, 1), arm::pipe::CommandHandlerKey(0, 2, 0),
112 arm::pipe::CommandHandlerKey(0, 2, 0), arm::pipe::CommandHandlerKey(0, 2, 1) };
Francis Murtagh1f7db452019-08-14 09:49:34 +0100113
Sadik Armagan1625efc2021-06-10 18:24:34 +0100114 CHECK(vect == expectedVect);
Francis Murtagh1f7db452019-08-14 09:49:34 +0100115}
116
Sadik Armagan1625efc2021-06-10 18:24:34 +0100117TEST_CASE("CheckPacketKeyComparisons")
Jim Flynned25e0e2019-10-18 13:21:43 +0100118{
Jim Flynnbbfe6032020-07-20 16:57:44 +0100119 arm::pipe::PacketKey key0(0, 0);
120 arm::pipe::PacketKey key1(0, 0);
121 arm::pipe::PacketKey key2(0, 1);
122 arm::pipe::PacketKey key3(0, 2);
123 arm::pipe::PacketKey key4(1, 0);
124 arm::pipe::PacketKey key5(1, 0);
125 arm::pipe::PacketKey key6(1, 1);
Jim Flynned25e0e2019-10-18 13:21:43 +0100126
Sadik Armagan1625efc2021-06-10 18:24:34 +0100127 CHECK(!(key0 < key1));
128 CHECK(!(key0 > key1));
129 CHECK(key0 <= key1);
130 CHECK(key0 >= key1);
131 CHECK(key0 == key1);
132 CHECK(key0 < key2);
133 CHECK(key2 < key3);
134 CHECK(key3 > key0);
135 CHECK(key4 == key5);
136 CHECK(key4 > key0);
137 CHECK(key5 < key6);
138 CHECK(key5 <= key6);
139 CHECK(key5 != key6);
Jim Flynned25e0e2019-10-18 13:21:43 +0100140}
141
Sadik Armagan1625efc2021-06-10 18:24:34 +0100142TEST_CASE("CheckCommandHandler")
FinnWilliamsArm4833cea2019-09-17 16:53:53 +0100143{
Jim Flynn6c9f17d2022-03-10 23:13:01 +0000144 LogLevelSwapper logLevelSwapper(arm::pipe::LogSeverity::Fatal);
145
Jim Flynnbbfe6032020-07-20 16:57:44 +0100146 arm::pipe::PacketVersionResolver packetVersionResolver;
Matteo Martincigh8a837172019-10-04 17:01:07 +0100147 ProfilingStateMachine profilingStateMachine;
FinnWilliamsArm4833cea2019-09-17 16:53:53 +0100148
Matteo Martincigh8a837172019-10-04 17:01:07 +0100149 TestProfilingConnectionBase testProfilingConnectionBase;
150 TestProfilingConnectionTimeoutError testProfilingConnectionTimeOutError;
151 TestProfilingConnectionArmnnError testProfilingConnectionArmnnError;
Keith Davis3201eea2019-10-24 17:30:41 +0100152 CounterDirectory counterDirectory;
153 MockBufferManager mockBuffer(1024);
Jim Flynn9c85b412022-03-16 00:27:43 +0000154 SendCounterPacket sendCounterPacket(mockBuffer,
155 arm::pipe::ARMNN_SOFTWARE_INFO,
156 arm::pipe::ARMNN_SOFTWARE_VERSION,
157 arm::pipe::ARMNN_HARDWARE_VERSION);
Sadik Armagan3896b472020-02-10 12:24:15 +0000158 SendThread sendThread(profilingStateMachine, mockBuffer, sendCounterPacket);
Matteo Martincighcdfb9412019-11-08 11:23:06 +0000159 SendTimelinePacket sendTimelinePacket(mockBuffer);
Jim Flynn6398a982020-05-27 17:05:21 +0100160 MockProfilingServiceStatus mockProfilingServiceStatus;
Matteo Martincighcdfb9412019-11-08 11:23:06 +0000161
Keith Davis3201eea2019-10-24 17:30:41 +0100162 ConnectionAcknowledgedCommandHandler connectionAcknowledgedCommandHandler(0, 1, 4194304, counterDirectory,
Matteo Martincighcdfb9412019-11-08 11:23:06 +0000163 sendCounterPacket, sendTimelinePacket,
Jim Flynn6398a982020-05-27 17:05:21 +0100164 profilingStateMachine,
165 mockProfilingServiceStatus);
Jim Flynnbbfe6032020-07-20 16:57:44 +0100166 arm::pipe::CommandHandlerRegistry commandHandlerRegistry;
FinnWilliamsArm4833cea2019-09-17 16:53:53 +0100167
Matteo Martincighc2728f92019-10-07 12:35:21 +0100168 commandHandlerRegistry.RegisterFunctor(&connectionAcknowledgedCommandHandler);
FinnWilliamsArm4833cea2019-09-17 16:53:53 +0100169
Matteo Martincigh8a837172019-10-04 17:01:07 +0100170 profilingStateMachine.TransitionToState(ProfilingState::NotConnected);
171 profilingStateMachine.TransitionToState(ProfilingState::WaitingForAck);
FinnWilliamsArm4833cea2019-09-17 16:53:53 +0100172
Keith Davis3201eea2019-10-24 17:30:41 +0100173 CommandHandler commandHandler0(1, true, commandHandlerRegistry, packetVersionResolver);
FinnWilliamsArm4833cea2019-09-17 16:53:53 +0100174
Colm Donelan2ba48d22019-11-29 09:10:59 +0000175 // This should start the command handler thread return the connection ack and put the profiling
176 // service into active state.
Matteo Martincigh8a837172019-10-04 17:01:07 +0100177 commandHandler0.Start(testProfilingConnectionBase);
Colm Donelan2ba48d22019-11-29 09:10:59 +0000178 // Try to start the send thread many times, it must only start once
Matteo Martincigh8a837172019-10-04 17:01:07 +0100179 commandHandler0.Start(testProfilingConnectionBase);
FinnWilliamsArm4833cea2019-09-17 16:53:53 +0100180
Colm Donelan2ba48d22019-11-29 09:10:59 +0000181 // This could take up to 20mSec but we'll check often.
182 for (int i = 0; i < 10; i++)
Matteo Martincigh8a837172019-10-04 17:01:07 +0100183 {
184 if (profilingStateMachine.GetCurrentState() == ProfilingState::Active)
FinnWilliamsArm4833cea2019-09-17 16:53:53 +0100185 {
Matteo Martincigh8a837172019-10-04 17:01:07 +0100186 break;
FinnWilliamsArm4833cea2019-09-17 16:53:53 +0100187 }
Colm Donelan2ba48d22019-11-29 09:10:59 +0000188 std::this_thread::sleep_for(std::chrono::milliseconds(2));
Matteo Martincigh8a837172019-10-04 17:01:07 +0100189 }
FinnWilliamsArm4833cea2019-09-17 16:53:53 +0100190
Sadik Armagan1625efc2021-06-10 18:24:34 +0100191 CHECK(profilingStateMachine.GetCurrentState() == ProfilingState::Active);
FinnWilliamsArm4833cea2019-09-17 16:53:53 +0100192
Colm Donelan2ba48d22019-11-29 09:10:59 +0000193 // Close the thread again.
194 commandHandler0.Stop();
195
196 profilingStateMachine.TransitionToState(ProfilingState::NotConnected);
197 profilingStateMachine.TransitionToState(ProfilingState::WaitingForAck);
198
199 // In this test we'll simulate a timeout without a connection ack packet being received.
200 // Stop after timeout is set so we expect the command handler to stop almost immediately.
201 CommandHandler commandHandler1(1, true, commandHandlerRegistry, packetVersionResolver);
202
203 commandHandler1.Start(testProfilingConnectionTimeOutError);
204 // Wait until we know a timeout exception has been sent at least once.
205 for (int i = 0; i < 10; i++)
206 {
207 if (testProfilingConnectionTimeOutError.ReadCalledCount())
208 {
209 break;
210 }
211 std::this_thread::sleep_for(std::chrono::milliseconds(2));
212 }
Colm Donelan2ba48d22019-11-29 09:10:59 +0000213
214 // The command handler loop should have stopped after the timeout.
Finn Williams09ad6f92019-12-19 17:05:18 +0000215 // wait for the timeout exception to be processed and the loop to break.
216 uint32_t timeout = 50;
217 uint32_t timeSlept = 0;
218 while (commandHandler1.IsRunning())
219 {
220 if (timeSlept >= timeout)
221 {
Sadik Armagan1625efc2021-06-10 18:24:34 +0100222 FAIL("Timeout: The command handler loop did not stop after the timeout");
Finn Williams09ad6f92019-12-19 17:05:18 +0000223 }
224 std::this_thread::sleep_for(std::chrono::milliseconds(1));
225 timeSlept ++;
226 }
Colm Donelan2ba48d22019-11-29 09:10:59 +0000227
228 commandHandler1.Stop();
229 // The state machine should never have received the ack so will still be in WaitingForAck.
Sadik Armagan1625efc2021-06-10 18:24:34 +0100230 CHECK(profilingStateMachine.GetCurrentState() == ProfilingState::WaitingForAck);
Colm Donelan2ba48d22019-11-29 09:10:59 +0000231
Finn Williams09ad6f92019-12-19 17:05:18 +0000232 // Now try sending a bad connection acknowledged packet
233 TestProfilingConnectionBadAckPacket testProfilingConnectionBadAckPacket;
234 commandHandler1.Start(testProfilingConnectionBadAckPacket);
235 commandHandler1.Stop();
236 // This should also not change the state machine
Sadik Armagan1625efc2021-06-10 18:24:34 +0100237 CHECK(profilingStateMachine.GetCurrentState() == ProfilingState::WaitingForAck);
Finn Williams09ad6f92019-12-19 17:05:18 +0000238
Colm Donelan2ba48d22019-11-29 09:10:59 +0000239 // Disable stop after timeout and now commandHandler1 should persist after a timeout
240 commandHandler1.SetStopAfterTimeout(false);
241 // Restart the thread.
242 commandHandler1.Start(testProfilingConnectionTimeOutError);
243
244 // Wait for at the three timeouts and the ack to be sent.
245 for (int i = 0; i < 10; i++)
246 {
247 if (testProfilingConnectionTimeOutError.ReadCalledCount() > 3)
248 {
249 break;
250 }
251 std::this_thread::sleep_for(std::chrono::milliseconds(2));
252 }
253 commandHandler1.Stop();
254
255 // Even after the 3 exceptions the ack packet should have transitioned the command handler to active.
Sadik Armagan1625efc2021-06-10 18:24:34 +0100256 CHECK(profilingStateMachine.GetCurrentState() == ProfilingState::Active);
Colm Donelan2ba48d22019-11-29 09:10:59 +0000257
258 // A command handler that gets exceptions other than timeouts should keep going.
259 CommandHandler commandHandler2(1, false, commandHandlerRegistry, packetVersionResolver);
FinnWilliamsArm4833cea2019-09-17 16:53:53 +0100260
Matteo Martincigh8a837172019-10-04 17:01:07 +0100261 commandHandler2.Start(testProfilingConnectionArmnnError);
262
Colm Donelan2ba48d22019-11-29 09:10:59 +0000263 // Wait for two exceptions to be thrown.
264 for (int i = 0; i < 10; i++)
265 {
266 if (testProfilingConnectionTimeOutError.ReadCalledCount() >= 2)
267 {
268 break;
269 }
270 std::this_thread::sleep_for(std::chrono::milliseconds(2));
271 }
FinnWilliamsArm4833cea2019-09-17 16:53:53 +0100272
Sadik Armagan1625efc2021-06-10 18:24:34 +0100273 CHECK(commandHandler2.IsRunning());
Matteo Martincigh8a837172019-10-04 17:01:07 +0100274 commandHandler2.Stop();
FinnWilliamsArm4833cea2019-09-17 16:53:53 +0100275}
276
Sadik Armagan1625efc2021-06-10 18:24:34 +0100277TEST_CASE("CheckEncodeVersion")
Nikhil Rajd88e47c2019-08-19 10:04:23 +0100278{
Jim Flynnbbfe6032020-07-20 16:57:44 +0100279 arm::pipe::Version version1(12);
Nikhil Rajd88e47c2019-08-19 10:04:23 +0100280
Sadik Armagan1625efc2021-06-10 18:24:34 +0100281 CHECK(version1.GetMajor() == 0);
282 CHECK(version1.GetMinor() == 0);
283 CHECK(version1.GetPatch() == 12);
Nikhil Rajd88e47c2019-08-19 10:04:23 +0100284
Jim Flynnbbfe6032020-07-20 16:57:44 +0100285 arm::pipe::Version version2(4108);
Nikhil Rajd88e47c2019-08-19 10:04:23 +0100286
Sadik Armagan1625efc2021-06-10 18:24:34 +0100287 CHECK(version2.GetMajor() == 0);
288 CHECK(version2.GetMinor() == 1);
289 CHECK(version2.GetPatch() == 12);
Nikhil Rajd88e47c2019-08-19 10:04:23 +0100290
Jim Flynnbbfe6032020-07-20 16:57:44 +0100291 arm::pipe::Version version3(4198412);
Nikhil Rajd88e47c2019-08-19 10:04:23 +0100292
Sadik Armagan1625efc2021-06-10 18:24:34 +0100293 CHECK(version3.GetMajor() == 1);
294 CHECK(version3.GetMinor() == 1);
295 CHECK(version3.GetPatch() == 12);
Nikhil Rajd88e47c2019-08-19 10:04:23 +0100296
Jim Flynnbbfe6032020-07-20 16:57:44 +0100297 arm::pipe::Version version4(0);
Nikhil Rajd88e47c2019-08-19 10:04:23 +0100298
Sadik Armagan1625efc2021-06-10 18:24:34 +0100299 CHECK(version4.GetMajor() == 0);
300 CHECK(version4.GetMinor() == 0);
301 CHECK(version4.GetPatch() == 0);
Nikhil Rajd88e47c2019-08-19 10:04:23 +0100302
Jim Flynnbbfe6032020-07-20 16:57:44 +0100303 arm::pipe::Version version5(1, 0, 0);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100304 CHECK(version5.GetEncodedValue() == 4194304);
Nikhil Rajd88e47c2019-08-19 10:04:23 +0100305}
306
Sadik Armagan1625efc2021-06-10 18:24:34 +0100307TEST_CASE("CheckPacketClass")
Nikhil Rajbc626052019-08-15 15:49:45 +0100308{
Keith Davis3201eea2019-10-24 17:30:41 +0100309 uint32_t length = 4;
Matteo Martincigh67ef2a52019-10-10 13:29:02 +0100310 std::unique_ptr<unsigned char[]> packetData0 = std::make_unique<unsigned char[]>(length);
311 std::unique_ptr<unsigned char[]> packetData1 = std::make_unique<unsigned char[]>(0);
312 std::unique_ptr<unsigned char[]> nullPacketData;
Nikhil Rajbc626052019-08-15 15:49:45 +0100313
Jim Flynnbbfe6032020-07-20 16:57:44 +0100314 arm::pipe::Packet packetTest0(472580096, length, packetData0);
Nikhil Rajbc626052019-08-15 15:49:45 +0100315
Sadik Armagan1625efc2021-06-10 18:24:34 +0100316 CHECK(packetTest0.GetHeader() == 472580096);
317 CHECK(packetTest0.GetPacketFamily() == 7);
318 CHECK(packetTest0.GetPacketId() == 43);
319 CHECK(packetTest0.GetLength() == length);
320 CHECK(packetTest0.GetPacketType() == 3);
321 CHECK(packetTest0.GetPacketClass() == 5);
Nikhil Rajbc626052019-08-15 15:49:45 +0100322
Sadik Armagan1625efc2021-06-10 18:24:34 +0100323 CHECK_THROWS_AS(arm::pipe::Packet packetTest1(472580096, 0, packetData1), arm::pipe::InvalidArgumentException);
324 CHECK_NOTHROW(arm::pipe::Packet packetTest2(472580096, 0, nullPacketData));
Nikhil Rajbc626052019-08-15 15:49:45 +0100325
Jim Flynnbbfe6032020-07-20 16:57:44 +0100326 arm::pipe::Packet packetTest3(472580096, 0, nullPacketData);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100327 CHECK(packetTest3.GetLength() == 0);
328 CHECK(packetTest3.GetData() == nullptr);
FinnWilliamsArma0c78712019-09-16 12:06:47 +0100329
Matteo Martincigh67ef2a52019-10-10 13:29:02 +0100330 const unsigned char* packetTest0Data = packetTest0.GetData();
Jim Flynnbbfe6032020-07-20 16:57:44 +0100331 arm::pipe::Packet packetTest4(std::move(packetTest0));
FinnWilliamsArma0c78712019-09-16 12:06:47 +0100332
Sadik Armagan1625efc2021-06-10 18:24:34 +0100333 CHECK(packetTest0.GetData() == nullptr);
334 CHECK(packetTest4.GetData() == packetTest0Data);
FinnWilliamsArma0c78712019-09-16 12:06:47 +0100335
Sadik Armagan1625efc2021-06-10 18:24:34 +0100336 CHECK(packetTest4.GetHeader() == 472580096);
337 CHECK(packetTest4.GetPacketFamily() == 7);
338 CHECK(packetTest4.GetPacketId() == 43);
339 CHECK(packetTest4.GetLength() == length);
340 CHECK(packetTest4.GetPacketType() == 3);
341 CHECK(packetTest4.GetPacketClass() == 5);
Nikhil Rajbc626052019-08-15 15:49:45 +0100342}
343
Sadik Armagan1625efc2021-06-10 18:24:34 +0100344TEST_CASE("CheckCommandHandlerFunctor")
Francis Murtagh11f99b42019-08-16 11:28:52 +0100345{
Francis Murtagh11f99b42019-08-16 11:28:52 +0100346 // Hard code the version as it will be the same during a single profiling session
347 uint32_t version = 1;
348
Jim Flynn397043f2019-10-17 17:37:10 +0100349 TestFunctorA testFunctorA(7, 461, version);
350 TestFunctorB testFunctorB(8, 963, version);
351 TestFunctorC testFunctorC(5, 983, version);
Francis Murtagh11f99b42019-08-16 11:28:52 +0100352
Jim Flynnbbfe6032020-07-20 16:57:44 +0100353 arm::pipe::CommandHandlerKey keyA(
354 testFunctorA.GetFamilyId(), testFunctorA.GetPacketId(), testFunctorA.GetVersion());
355 arm::pipe::CommandHandlerKey keyB(
356 testFunctorB.GetFamilyId(), testFunctorB.GetPacketId(), testFunctorB.GetVersion());
357 arm::pipe::CommandHandlerKey keyC(
358 testFunctorC.GetFamilyId(), testFunctorC.GetPacketId(), testFunctorC.GetVersion());
Francis Murtagh11f99b42019-08-16 11:28:52 +0100359
360 // Create the unwrapped map to simulate the Command Handler Registry
Jim Flynnbbfe6032020-07-20 16:57:44 +0100361 std::map<arm::pipe::CommandHandlerKey, arm::pipe::CommandHandlerFunctor*> registry;
Francis Murtagh11f99b42019-08-16 11:28:52 +0100362
363 registry.insert(std::make_pair(keyB, &testFunctorB));
364 registry.insert(std::make_pair(keyA, &testFunctorA));
365 registry.insert(std::make_pair(keyC, &testFunctorC));
366
367 // Check the order of the map is correct
368 auto it = registry.begin();
Sadik Armagan1625efc2021-06-10 18:24:34 +0100369 CHECK(it->first == keyC); // familyId == 5
Francis Murtagh11f99b42019-08-16 11:28:52 +0100370 it++;
Sadik Armagan1625efc2021-06-10 18:24:34 +0100371 CHECK(it->first == keyA); // familyId == 7
Francis Murtagh11f99b42019-08-16 11:28:52 +0100372 it++;
Sadik Armagan1625efc2021-06-10 18:24:34 +0100373 CHECK(it->first == keyB); // familyId == 8
Francis Murtagh11f99b42019-08-16 11:28:52 +0100374
Matteo Martincigh67ef2a52019-10-10 13:29:02 +0100375 std::unique_ptr<unsigned char[]> packetDataA;
376 std::unique_ptr<unsigned char[]> packetDataB;
377 std::unique_ptr<unsigned char[]> packetDataC;
FinnWilliamsArma0c78712019-09-16 12:06:47 +0100378
Jim Flynnbbfe6032020-07-20 16:57:44 +0100379 arm::pipe::Packet packetA(500000000, 0, packetDataA);
380 arm::pipe::Packet packetB(600000000, 0, packetDataB);
381 arm::pipe::Packet packetC(400000000, 0, packetDataC);
Francis Murtagh11f99b42019-08-16 11:28:52 +0100382
383 // Check the correct operator of derived class is called
Jim Flynnbbfe6032020-07-20 16:57:44 +0100384 registry.at(arm::pipe::CommandHandlerKey(
385 packetA.GetPacketFamily(), packetA.GetPacketId(), version))->operator()(packetA);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100386 CHECK(testFunctorA.GetCount() == 1);
387 CHECK(testFunctorB.GetCount() == 0);
388 CHECK(testFunctorC.GetCount() == 0);
Francis Murtagh11f99b42019-08-16 11:28:52 +0100389
Jim Flynnbbfe6032020-07-20 16:57:44 +0100390 registry.at(arm::pipe::CommandHandlerKey(
391 packetB.GetPacketFamily(), packetB.GetPacketId(), version))->operator()(packetB);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100392 CHECK(testFunctorA.GetCount() == 1);
393 CHECK(testFunctorB.GetCount() == 1);
394 CHECK(testFunctorC.GetCount() == 0);
Francis Murtagh11f99b42019-08-16 11:28:52 +0100395
Jim Flynnbbfe6032020-07-20 16:57:44 +0100396 registry.at(arm::pipe::CommandHandlerKey(
397 packetC.GetPacketFamily(), packetC.GetPacketId(), version))->operator()(packetC);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100398 CHECK(testFunctorA.GetCount() == 1);
399 CHECK(testFunctorB.GetCount() == 1);
400 CHECK(testFunctorC.GetCount() == 1);
Francis Murtagh11f99b42019-08-16 11:28:52 +0100401}
402
Sadik Armagan1625efc2021-06-10 18:24:34 +0100403TEST_CASE("CheckCommandHandlerRegistry")
Francis Murtagh94d79152019-08-16 17:45:07 +0100404{
405 // Hard code the version as it will be the same during a single profiling session
406 uint32_t version = 1;
407
Jim Flynn397043f2019-10-17 17:37:10 +0100408 TestFunctorA testFunctorA(7, 461, version);
409 TestFunctorB testFunctorB(8, 963, version);
410 TestFunctorC testFunctorC(5, 983, version);
Francis Murtagh94d79152019-08-16 17:45:07 +0100411
412 // Create the Command Handler Registry
Jim Flynnbbfe6032020-07-20 16:57:44 +0100413 arm::pipe::CommandHandlerRegistry registry;
Francis Murtagh94d79152019-08-16 17:45:07 +0100414
415 // Register multiple different derived classes
Matteo Martincighc2728f92019-10-07 12:35:21 +0100416 registry.RegisterFunctor(&testFunctorA);
417 registry.RegisterFunctor(&testFunctorB);
418 registry.RegisterFunctor(&testFunctorC);
Francis Murtagh94d79152019-08-16 17:45:07 +0100419
Matteo Martincigh67ef2a52019-10-10 13:29:02 +0100420 std::unique_ptr<unsigned char[]> packetDataA;
421 std::unique_ptr<unsigned char[]> packetDataB;
422 std::unique_ptr<unsigned char[]> packetDataC;
FinnWilliamsArma0c78712019-09-16 12:06:47 +0100423
Jim Flynnbbfe6032020-07-20 16:57:44 +0100424 arm::pipe::Packet packetA(500000000, 0, packetDataA);
425 arm::pipe::Packet packetB(600000000, 0, packetDataB);
426 arm::pipe::Packet packetC(400000000, 0, packetDataC);
Francis Murtagh94d79152019-08-16 17:45:07 +0100427
428 // Check the correct operator of derived class is called
Jim Flynn397043f2019-10-17 17:37:10 +0100429 registry.GetFunctor(packetA.GetPacketFamily(), packetA.GetPacketId(), version)->operator()(packetA);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100430 CHECK(testFunctorA.GetCount() == 1);
431 CHECK(testFunctorB.GetCount() == 0);
432 CHECK(testFunctorC.GetCount() == 0);
Francis Murtagh94d79152019-08-16 17:45:07 +0100433
Jim Flynn397043f2019-10-17 17:37:10 +0100434 registry.GetFunctor(packetB.GetPacketFamily(), packetB.GetPacketId(), version)->operator()(packetB);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100435 CHECK(testFunctorA.GetCount() == 1);
436 CHECK(testFunctorB.GetCount() == 1);
437 CHECK(testFunctorC.GetCount() == 0);
Francis Murtagh94d79152019-08-16 17:45:07 +0100438
Jim Flynn397043f2019-10-17 17:37:10 +0100439 registry.GetFunctor(packetC.GetPacketFamily(), packetC.GetPacketId(), version)->operator()(packetC);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100440 CHECK(testFunctorA.GetCount() == 1);
441 CHECK(testFunctorB.GetCount() == 1);
442 CHECK(testFunctorC.GetCount() == 1);
Francis Murtagh94d79152019-08-16 17:45:07 +0100443
444 // Re-register an existing key with a new function
Jim Flynn397043f2019-10-17 17:37:10 +0100445 registry.RegisterFunctor(&testFunctorC, testFunctorA.GetFamilyId(), testFunctorA.GetPacketId(), version);
446 registry.GetFunctor(packetA.GetPacketFamily(), packetA.GetPacketId(), version)->operator()(packetC);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100447 CHECK(testFunctorA.GetCount() == 1);
448 CHECK(testFunctorB.GetCount() == 1);
449 CHECK(testFunctorC.GetCount() == 2);
Francis Murtagh94d79152019-08-16 17:45:07 +0100450
451 // Check that non-existent key returns nullptr for its functor
Sadik Armagan1625efc2021-06-10 18:24:34 +0100452 CHECK_THROWS_AS(registry.GetFunctor(0, 0, 0), arm::pipe::ProfilingException);
Francis Murtagh94d79152019-08-16 17:45:07 +0100453}
454
Sadik Armagan1625efc2021-06-10 18:24:34 +0100455TEST_CASE("CheckPacketVersionResolver")
Aron Virginas-Tare898db92019-08-22 12:56:34 +0100456{
457 // Set up random number generator for generating packetId values
458 std::random_device device;
459 std::mt19937 generator(device());
460 std::uniform_int_distribution<uint32_t> distribution(std::numeric_limits<uint32_t>::min(),
461 std::numeric_limits<uint32_t>::max());
462
463 // NOTE: Expected version is always 1.0.0, regardless of packetId
Jim Flynnbbfe6032020-07-20 16:57:44 +0100464 const arm::pipe::Version expectedVersion(1, 0, 0);
Aron Virginas-Tare898db92019-08-22 12:56:34 +0100465
Jim Flynnbbfe6032020-07-20 16:57:44 +0100466 arm::pipe::PacketVersionResolver packetVersionResolver;
Aron Virginas-Tare898db92019-08-22 12:56:34 +0100467
468 constexpr unsigned int numTests = 10u;
469
470 for (unsigned int i = 0u; i < numTests; ++i)
471 {
Jim Flynned25e0e2019-10-18 13:21:43 +0100472 const uint32_t familyId = distribution(generator);
Aron Virginas-Tare898db92019-08-22 12:56:34 +0100473 const uint32_t packetId = distribution(generator);
Jim Flynnbbfe6032020-07-20 16:57:44 +0100474 arm::pipe::Version resolvedVersion = packetVersionResolver.ResolvePacketVersion(familyId, packetId);
Aron Virginas-Tare898db92019-08-22 12:56:34 +0100475
Sadik Armagan1625efc2021-06-10 18:24:34 +0100476 CHECK(resolvedVersion == expectedVersion);
Aron Virginas-Tare898db92019-08-22 12:56:34 +0100477 }
478}
Matteo Martincighd0613b52019-10-09 16:47:04 +0100479
Nikhil Raj3ecc5102019-09-03 15:55:33 +0100480void ProfilingCurrentStateThreadImpl(ProfilingStateMachine& states)
481{
482 ProfilingState newState = ProfilingState::NotConnected;
483 states.GetCurrentState();
484 states.TransitionToState(newState);
485}
486
Sadik Armagan1625efc2021-06-10 18:24:34 +0100487TEST_CASE("CheckProfilingStateMachine")
Nikhil Raj3ecc5102019-09-03 15:55:33 +0100488{
489 ProfilingStateMachine profilingState1(ProfilingState::Uninitialised);
490 profilingState1.TransitionToState(ProfilingState::Uninitialised);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100491 CHECK(profilingState1.GetCurrentState() == ProfilingState::Uninitialised);
Nikhil Raj3ecc5102019-09-03 15:55:33 +0100492
493 ProfilingStateMachine profilingState2(ProfilingState::Uninitialised);
494 profilingState2.TransitionToState(ProfilingState::NotConnected);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100495 CHECK(profilingState2.GetCurrentState() == ProfilingState::NotConnected);
Nikhil Raj3ecc5102019-09-03 15:55:33 +0100496
497 ProfilingStateMachine profilingState3(ProfilingState::NotConnected);
498 profilingState3.TransitionToState(ProfilingState::NotConnected);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100499 CHECK(profilingState3.GetCurrentState() == ProfilingState::NotConnected);
Nikhil Raj3ecc5102019-09-03 15:55:33 +0100500
501 ProfilingStateMachine profilingState4(ProfilingState::NotConnected);
502 profilingState4.TransitionToState(ProfilingState::WaitingForAck);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100503 CHECK(profilingState4.GetCurrentState() == ProfilingState::WaitingForAck);
Nikhil Raj3ecc5102019-09-03 15:55:33 +0100504
505 ProfilingStateMachine profilingState5(ProfilingState::WaitingForAck);
506 profilingState5.TransitionToState(ProfilingState::WaitingForAck);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100507 CHECK(profilingState5.GetCurrentState() == ProfilingState::WaitingForAck);
Nikhil Raj3ecc5102019-09-03 15:55:33 +0100508
509 ProfilingStateMachine profilingState6(ProfilingState::WaitingForAck);
510 profilingState6.TransitionToState(ProfilingState::Active);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100511 CHECK(profilingState6.GetCurrentState() == ProfilingState::Active);
Nikhil Raj3ecc5102019-09-03 15:55:33 +0100512
513 ProfilingStateMachine profilingState7(ProfilingState::Active);
514 profilingState7.TransitionToState(ProfilingState::NotConnected);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100515 CHECK(profilingState7.GetCurrentState() == ProfilingState::NotConnected);
Nikhil Raj3ecc5102019-09-03 15:55:33 +0100516
517 ProfilingStateMachine profilingState8(ProfilingState::Active);
518 profilingState8.TransitionToState(ProfilingState::Active);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100519 CHECK(profilingState8.GetCurrentState() == ProfilingState::Active);
Nikhil Raj3ecc5102019-09-03 15:55:33 +0100520
521 ProfilingStateMachine profilingState9(ProfilingState::Uninitialised);
Jim Flynnf9db3ef2022-03-08 21:23:44 +0000522 CHECK_THROWS_AS(profilingState9.TransitionToState(ProfilingState::WaitingForAck), arm::pipe::ProfilingException);
Nikhil Raj3ecc5102019-09-03 15:55:33 +0100523
524 ProfilingStateMachine profilingState10(ProfilingState::Uninitialised);
Jim Flynnf9db3ef2022-03-08 21:23:44 +0000525 CHECK_THROWS_AS(profilingState10.TransitionToState(ProfilingState::Active), arm::pipe::ProfilingException);
Nikhil Raj3ecc5102019-09-03 15:55:33 +0100526
527 ProfilingStateMachine profilingState11(ProfilingState::NotConnected);
Jim Flynnf9db3ef2022-03-08 21:23:44 +0000528 CHECK_THROWS_AS(profilingState11.TransitionToState(ProfilingState::Uninitialised), arm::pipe::ProfilingException);
Nikhil Raj3ecc5102019-09-03 15:55:33 +0100529
530 ProfilingStateMachine profilingState12(ProfilingState::NotConnected);
Jim Flynnf9db3ef2022-03-08 21:23:44 +0000531 CHECK_THROWS_AS(profilingState12.TransitionToState(ProfilingState::Active), arm::pipe::ProfilingException);
Nikhil Raj3ecc5102019-09-03 15:55:33 +0100532
533 ProfilingStateMachine profilingState13(ProfilingState::WaitingForAck);
Jim Flynnf9db3ef2022-03-08 21:23:44 +0000534 CHECK_THROWS_AS(profilingState13.TransitionToState(ProfilingState::Uninitialised), arm::pipe::ProfilingException);
Nikhil Raj3ecc5102019-09-03 15:55:33 +0100535
536 ProfilingStateMachine profilingState14(ProfilingState::WaitingForAck);
Jim Flynn53e46992019-10-14 12:31:10 +0100537 profilingState14.TransitionToState(ProfilingState::NotConnected);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100538 CHECK(profilingState14.GetCurrentState() == ProfilingState::NotConnected);
Nikhil Raj3ecc5102019-09-03 15:55:33 +0100539
540 ProfilingStateMachine profilingState15(ProfilingState::Active);
Jim Flynnf9db3ef2022-03-08 21:23:44 +0000541 CHECK_THROWS_AS(profilingState15.TransitionToState(ProfilingState::Uninitialised), arm::pipe::ProfilingException);
Nikhil Raj3ecc5102019-09-03 15:55:33 +0100542
Cathal Corbett5aa9fd72022-02-25 15:33:28 +0000543 ProfilingStateMachine profilingState16(ProfilingState::Active);
Jim Flynnf9db3ef2022-03-08 21:23:44 +0000544 CHECK_THROWS_AS(profilingState16.TransitionToState(ProfilingState::WaitingForAck), arm::pipe::ProfilingException);
Nikhil Raj3ecc5102019-09-03 15:55:33 +0100545
546 ProfilingStateMachine profilingState17(ProfilingState::Uninitialised);
547
Sadik Armagan95e9efc2021-08-05 15:01:07 +0100548 std::vector<std::thread> threads;
549 for (unsigned int i = 0; i < 5; ++i)
550 {
551 threads.push_back(std::thread(ProfilingCurrentStateThreadImpl, std::ref(profilingState17)));
552 }
553 std::for_each(threads.begin(), threads.end(), [](std::thread& theThread)
554 {
555 theThread.join();
556 });
Nikhil Raj3ecc5102019-09-03 15:55:33 +0100557
Sadik Armagan1625efc2021-06-10 18:24:34 +0100558 CHECK((profilingState17.GetCurrentState() == ProfilingState::NotConnected));
Nikhil Raj3ecc5102019-09-03 15:55:33 +0100559}
Aron Virginas-Tare898db92019-08-22 12:56:34 +0100560
Jim Flynn8355ec92019-09-17 12:29:50 +0100561void CaptureDataWriteThreadImpl(Holder& holder, uint32_t capturePeriod, const std::vector<uint16_t>& counterIds)
Francis Murtagh68f78d82019-09-04 16:42:29 +0100562{
Finn Williams032bc742020-02-12 11:02:34 +0000563 holder.SetCaptureData(capturePeriod, counterIds, {});
Francis Murtagh68f78d82019-09-04 16:42:29 +0100564}
565
Francis Murtaghbd707162019-09-09 11:26:44 +0100566void CaptureDataReadThreadImpl(const Holder& holder, CaptureData& captureData)
Francis Murtagh68f78d82019-09-04 16:42:29 +0100567{
568 captureData = holder.GetCaptureData();
569}
570
Sadik Armagan1625efc2021-06-10 18:24:34 +0100571TEST_CASE("CheckCaptureDataHolder")
Francis Murtagh68f78d82019-09-04 16:42:29 +0100572{
Francis Murtaghbd707162019-09-09 11:26:44 +0100573 std::map<uint32_t, std::vector<uint16_t>> periodIdMap;
574 std::vector<uint16_t> counterIds;
Jim Flynn8355ec92019-09-17 12:29:50 +0100575 uint32_t numThreads = 10;
576 for (uint32_t i = 0; i < numThreads; ++i)
Francis Murtaghbd707162019-09-09 11:26:44 +0100577 {
578 counterIds.emplace_back(i);
579 periodIdMap.insert(std::make_pair(i, counterIds));
580 }
Francis Murtagh68f78d82019-09-04 16:42:29 +0100581
Jim Flynn8355ec92019-09-17 12:29:50 +0100582 // Verify the read and write threads set the holder correctly
583 // and retrieve the expected values
Francis Murtagh68f78d82019-09-04 16:42:29 +0100584 Holder holder;
Sadik Armagan1625efc2021-06-10 18:24:34 +0100585 CHECK((holder.GetCaptureData()).GetCapturePeriod() == 0);
586 CHECK(((holder.GetCaptureData()).GetCounterIds()).empty());
Francis Murtagh68f78d82019-09-04 16:42:29 +0100587
588 // Check Holder functions
Francis Murtaghbd707162019-09-09 11:26:44 +0100589 std::thread thread1(CaptureDataWriteThreadImpl, std::ref(holder), 2, std::ref(periodIdMap[2]));
Francis Murtagh68f78d82019-09-04 16:42:29 +0100590 thread1.join();
Sadik Armagan1625efc2021-06-10 18:24:34 +0100591 CHECK((holder.GetCaptureData()).GetCapturePeriod() == 2);
592 CHECK((holder.GetCaptureData()).GetCounterIds() == periodIdMap[2]);
Jim Flynn8355ec92019-09-17 12:29:50 +0100593 // NOTE: now that we have some initial values in the holder we don't have to worry
594 // in the multi-threaded section below about a read thread accessing the holder
595 // before any write thread has gotten to it so we read period = 0, counterIds empty
596 // instead of period = 0, counterIds = {0} as will the case when write thread 0
597 // has executed.
Francis Murtagh68f78d82019-09-04 16:42:29 +0100598
599 CaptureData captureData;
600 std::thread thread2(CaptureDataReadThreadImpl, std::ref(holder), std::ref(captureData));
601 thread2.join();
Sadik Armagan1625efc2021-06-10 18:24:34 +0100602 CHECK(captureData.GetCapturePeriod() == 2);
603 CHECK(captureData.GetCounterIds() == periodIdMap[2]);
Francis Murtagh68f78d82019-09-04 16:42:29 +0100604
Jim Flynn8355ec92019-09-17 12:29:50 +0100605 std::map<uint32_t, CaptureData> captureDataIdMap;
606 for (uint32_t i = 0; i < numThreads; ++i)
607 {
608 CaptureData perThreadCaptureData;
609 captureDataIdMap.insert(std::make_pair(i, perThreadCaptureData));
610 }
611
Francis Murtaghbd707162019-09-09 11:26:44 +0100612 std::vector<std::thread> threadsVect;
Jim Flynn8355ec92019-09-17 12:29:50 +0100613 std::vector<std::thread> readThreadsVect;
614 for (uint32_t i = 0; i < numThreads; ++i)
Francis Murtaghbd707162019-09-09 11:26:44 +0100615 {
Keith Davis3201eea2019-10-24 17:30:41 +0100616 threadsVect.emplace_back(
617 std::thread(CaptureDataWriteThreadImpl, std::ref(holder), i, std::ref(periodIdMap[i])));
Francis Murtagh06965692019-09-05 16:29:01 +0100618
Jim Flynn8355ec92019-09-17 12:29:50 +0100619 // Verify that the CaptureData goes into the thread in a virgin state
Sadik Armagan1625efc2021-06-10 18:24:34 +0100620 CHECK(captureDataIdMap.at(i).GetCapturePeriod() == 0);
621 CHECK(captureDataIdMap.at(i).GetCounterIds().empty());
Keith Davis3201eea2019-10-24 17:30:41 +0100622 readThreadsVect.emplace_back(
623 std::thread(CaptureDataReadThreadImpl, std::ref(holder), std::ref(captureDataIdMap.at(i))));
Francis Murtaghbd707162019-09-09 11:26:44 +0100624 }
625
Jim Flynn8355ec92019-09-17 12:29:50 +0100626 for (uint32_t i = 0; i < numThreads; ++i)
Francis Murtaghbd707162019-09-09 11:26:44 +0100627 {
628 threadsVect[i].join();
Francis Murtaghbd707162019-09-09 11:26:44 +0100629 readThreadsVect[i].join();
630 }
Francis Murtagh68f78d82019-09-04 16:42:29 +0100631
Jim Flynn8355ec92019-09-17 12:29:50 +0100632 // Look at the CaptureData that each read thread has filled
633 // the capture period it read should match the counter ids entry
634 for (uint32_t i = 0; i < numThreads; ++i)
635 {
636 CaptureData perThreadCaptureData = captureDataIdMap.at(i);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100637 CHECK(perThreadCaptureData.GetCounterIds() == periodIdMap.at(perThreadCaptureData.GetCapturePeriod()));
Jim Flynn8355ec92019-09-17 12:29:50 +0100638 }
Matthew Bentham46d1c622019-09-13 12:45:04 +0100639}
Francis Murtagh68f78d82019-09-04 16:42:29 +0100640
Sadik Armagan1625efc2021-06-10 18:24:34 +0100641TEST_CASE("CaptureDataMethods")
Matthew Bentham46d1c622019-09-13 12:45:04 +0100642{
Jim Flynn8355ec92019-09-17 12:29:50 +0100643 // Check CaptureData setter and getter functions
Keith Davis3201eea2019-10-24 17:30:41 +0100644 std::vector<uint16_t> counterIds = { 42, 29, 13 };
Jim Flynn8355ec92019-09-17 12:29:50 +0100645 CaptureData captureData;
Sadik Armagan1625efc2021-06-10 18:24:34 +0100646 CHECK(captureData.GetCapturePeriod() == 0);
647 CHECK((captureData.GetCounterIds()).empty());
Jim Flynn8355ec92019-09-17 12:29:50 +0100648 captureData.SetCapturePeriod(150);
649 captureData.SetCounterIds(counterIds);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100650 CHECK(captureData.GetCapturePeriod() == 150);
651 CHECK(captureData.GetCounterIds() == counterIds);
Francis Murtagh68f78d82019-09-04 16:42:29 +0100652
Jim Flynn8355ec92019-09-17 12:29:50 +0100653 // Check assignment operator
Francis Murtagh68f78d82019-09-04 16:42:29 +0100654 CaptureData secondCaptureData;
Francis Murtagh68f78d82019-09-04 16:42:29 +0100655
Jim Flynn8355ec92019-09-17 12:29:50 +0100656 secondCaptureData = captureData;
Sadik Armagan1625efc2021-06-10 18:24:34 +0100657 CHECK(secondCaptureData.GetCapturePeriod() == 150);
658 CHECK(secondCaptureData.GetCounterIds() == counterIds);
Francis Murtagh68f78d82019-09-04 16:42:29 +0100659
660 // Check copy constructor
Jim Flynn8355ec92019-09-17 12:29:50 +0100661 CaptureData copyConstructedCaptureData(captureData);
Francis Murtagh68f78d82019-09-04 16:42:29 +0100662
Sadik Armagan1625efc2021-06-10 18:24:34 +0100663 CHECK(copyConstructedCaptureData.GetCapturePeriod() == 150);
664 CHECK(copyConstructedCaptureData.GetCounterIds() == counterIds);
Keith Davis02356de2019-08-26 18:28:17 +0100665}
Francis Murtagh68f78d82019-09-04 16:42:29 +0100666
Sadik Armagan1625efc2021-06-10 18:24:34 +0100667TEST_CASE("CheckProfilingServiceDisabled")
Keith Davis02356de2019-08-26 18:28:17 +0100668{
Jim Flynn4c9ed1d2022-01-23 23:57:20 +0000669 ProfilingOptions options;
Jim Flynn34430252022-03-04 15:03:58 +0000670 armnn::ArmNNProfilingServiceInitialiser initialiser;
Jim Flynn9c85b412022-03-16 00:27:43 +0000671 ProfilingService profilingService(arm::pipe::MAX_ARMNN_COUNTER,
672 initialiser,
673 arm::pipe::ARMNN_SOFTWARE_INFO,
674 arm::pipe::ARMNN_SOFTWARE_VERSION,
675 arm::pipe::ARMNN_HARDWARE_VERSION);
Matteo Martincigha84edee2019-10-02 12:50:57 +0100676 profilingService.ResetExternalProfilingOptions(options, true);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100677 CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
Matteo Martincigh54fb9572019-10-02 12:50:57 +0100678 profilingService.Update();
Sadik Armagan1625efc2021-06-10 18:24:34 +0100679 CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
Keith Davis02356de2019-08-26 18:28:17 +0100680}
681
Sadik Armagan1625efc2021-06-10 18:24:34 +0100682TEST_CASE("CheckProfilingServiceCounterDirectory")
FinnWilliamsArmce2d9d12019-09-18 10:28:16 +0100683{
Jim Flynn4c9ed1d2022-01-23 23:57:20 +0000684 ProfilingOptions options;
Jim Flynn34430252022-03-04 15:03:58 +0000685 armnn::ArmNNProfilingServiceInitialiser initialiser;
Jim Flynn9c85b412022-03-16 00:27:43 +0000686 ProfilingService profilingService(arm::pipe::MAX_ARMNN_COUNTER,
687 initialiser,
688 arm::pipe::ARMNN_SOFTWARE_INFO,
689 arm::pipe::ARMNN_SOFTWARE_VERSION,
690 arm::pipe::ARMNN_HARDWARE_VERSION);
Matteo Martincigha84edee2019-10-02 12:50:57 +0100691 profilingService.ResetExternalProfilingOptions(options, true);
FinnWilliamsArmce2d9d12019-09-18 10:28:16 +0100692
Matteo Martincigha84edee2019-10-02 12:50:57 +0100693 const ICounterDirectory& counterDirectory0 = profilingService.GetCounterDirectory();
Sadik Armagan1625efc2021-06-10 18:24:34 +0100694 CHECK(counterDirectory0.GetCounterCount() == 0);
Matteo Martincigh54fb9572019-10-02 12:50:57 +0100695 profilingService.Update();
Sadik Armagan1625efc2021-06-10 18:24:34 +0100696 CHECK(counterDirectory0.GetCounterCount() == 0);
FinnWilliamsArmce2d9d12019-09-18 10:28:16 +0100697
698 options.m_EnableProfiling = true;
Matteo Martincigha84edee2019-10-02 12:50:57 +0100699 profilingService.ResetExternalProfilingOptions(options);
FinnWilliamsArmce2d9d12019-09-18 10:28:16 +0100700
Matteo Martincigha84edee2019-10-02 12:50:57 +0100701 const ICounterDirectory& counterDirectory1 = profilingService.GetCounterDirectory();
Sadik Armagan1625efc2021-06-10 18:24:34 +0100702 CHECK(counterDirectory1.GetCounterCount() == 0);
Matteo Martincigh54fb9572019-10-02 12:50:57 +0100703 profilingService.Update();
Sadik Armagan1625efc2021-06-10 18:24:34 +0100704 CHECK(counterDirectory1.GetCounterCount() != 0);
Colm Donelan2ba48d22019-11-29 09:10:59 +0000705 // Reset the profiling service to stop any running thread
706 options.m_EnableProfiling = false;
707 profilingService.ResetExternalProfilingOptions(options, true);
FinnWilliamsArmce2d9d12019-09-18 10:28:16 +0100708}
709
Sadik Armagan1625efc2021-06-10 18:24:34 +0100710TEST_CASE("CheckProfilingServiceCounterValues")
FinnWilliamsArmf6e534a2019-09-16 15:45:42 +0100711{
Jim Flynn4c9ed1d2022-01-23 23:57:20 +0000712 ProfilingOptions options;
Keith Davis3201eea2019-10-24 17:30:41 +0100713 options.m_EnableProfiling = true;
Jim Flynn34430252022-03-04 15:03:58 +0000714 armnn::ArmNNProfilingServiceInitialiser initialiser;
Jim Flynn9c85b412022-03-16 00:27:43 +0000715 ProfilingService profilingService(arm::pipe::MAX_ARMNN_COUNTER,
716 initialiser,
717 arm::pipe::ARMNN_SOFTWARE_INFO,
718 arm::pipe::ARMNN_SOFTWARE_VERSION,
719 arm::pipe::ARMNN_HARDWARE_VERSION);
Matteo Martincigha84edee2019-10-02 12:50:57 +0100720 profilingService.ResetExternalProfilingOptions(options, true);
721
Matteo Martincigh54fb9572019-10-02 12:50:57 +0100722 profilingService.Update();
Matteo Martincigha84edee2019-10-02 12:50:57 +0100723 const ICounterDirectory& counterDirectory = profilingService.GetCounterDirectory();
Keith Davis3201eea2019-10-24 17:30:41 +0100724 const Counters& counters = counterDirectory.GetCounters();
Sadik Armagan1625efc2021-06-10 18:24:34 +0100725 CHECK(!counters.empty());
Matteo Martincigha84edee2019-10-02 12:50:57 +0100726
FinnWilliamsArmf6e534a2019-09-16 15:45:42 +0100727 std::vector<std::thread> writers;
728
Sadik Armagan1625efc2021-06-10 18:24:34 +0100729 CHECK(!counters.empty());
Cathal Corbett5aa9fd72022-02-25 15:33:28 +0000730 uint16_t inferencesRun = INFERENCES_RUN;
Finn Williamsf3fcf322020-05-11 14:38:02 +0100731
732 // Test GetAbsoluteCounterValue
733 for (int i = 0; i < 4; ++i)
FinnWilliamsArmf6e534a2019-09-16 15:45:42 +0100734 {
Finn Williamsf3fcf322020-05-11 14:38:02 +0100735 // Increment and decrement the INFERENCES_RUN counter 250 times
Sadik Armagan95e9efc2021-08-05 15:01:07 +0100736 writers.push_back(std::thread([&profilingService, inferencesRun]()
Finn Williamsf3fcf322020-05-11 14:38:02 +0100737 {
738 for (int i = 0; i < 250; ++i)
739 {
Sadik Armagan95e9efc2021-08-05 15:01:07 +0100740 profilingService.IncrementCounterValue(inferencesRun);
Finn Williamsf3fcf322020-05-11 14:38:02 +0100741 }
742 }));
743 // Add 10 to the INFERENCES_RUN counter 200 times
Sadik Armagan95e9efc2021-08-05 15:01:07 +0100744 writers.push_back(std::thread([&profilingService, inferencesRun]()
Finn Williamsf3fcf322020-05-11 14:38:02 +0100745 {
746 for (int i = 0; i < 200; ++i)
747 {
Sadik Armagan95e9efc2021-08-05 15:01:07 +0100748 profilingService.AddCounterValue(inferencesRun, 10);
Finn Williamsf3fcf322020-05-11 14:38:02 +0100749 }
750 }));
751 // Subtract 5 from the INFERENCES_RUN counter 200 times
Sadik Armagan95e9efc2021-08-05 15:01:07 +0100752 writers.push_back(std::thread([&profilingService, inferencesRun]()
Finn Williamsf3fcf322020-05-11 14:38:02 +0100753 {
754 for (int i = 0; i < 200; ++i)
755 {
Sadik Armagan95e9efc2021-08-05 15:01:07 +0100756 profilingService.SubtractCounterValue(inferencesRun, 5);
Finn Williamsf3fcf322020-05-11 14:38:02 +0100757 }
758 }));
FinnWilliamsArmf6e534a2019-09-16 15:45:42 +0100759 }
FinnWilliamsArmf6e534a2019-09-16 15:45:42 +0100760 std::for_each(writers.begin(), writers.end(), mem_fn(&std::thread::join));
761
Finn Williamsf3fcf322020-05-11 14:38:02 +0100762 uint32_t absoluteCounterValue = 0;
FinnWilliamsArmf6e534a2019-09-16 15:45:42 +0100763
Sadik Armagan1625efc2021-06-10 18:24:34 +0100764 CHECK_NOTHROW(absoluteCounterValue = profilingService.GetAbsoluteCounterValue(INFERENCES_RUN));
765 CHECK(absoluteCounterValue == 5000);
Finn Williamsf3fcf322020-05-11 14:38:02 +0100766
767 // Test SetCounterValue
Sadik Armagan1625efc2021-06-10 18:24:34 +0100768 CHECK_NOTHROW(profilingService.SetCounterValue(INFERENCES_RUN, 0));
769 CHECK_NOTHROW(absoluteCounterValue = profilingService.GetAbsoluteCounterValue(INFERENCES_RUN));
770 CHECK(absoluteCounterValue == 0);
Finn Williamsf3fcf322020-05-11 14:38:02 +0100771
772 // Test GetDeltaCounterValue
773 writers.clear();
774 uint32_t deltaCounterValue = 0;
775 //Start a reading thread to randomly read the INFERENCES_RUN counter value
Sadik Armagan95e9efc2021-08-05 15:01:07 +0100776 std::thread reader([&profilingService, inferencesRun](uint32_t& deltaCounterValue)
Finn Williamsf3fcf322020-05-11 14:38:02 +0100777 {
778 for (int i = 0; i < 300; ++i)
779 {
Sadik Armagan95e9efc2021-08-05 15:01:07 +0100780 deltaCounterValue += profilingService.GetDeltaCounterValue(inferencesRun);
Finn Williamsf3fcf322020-05-11 14:38:02 +0100781 }
782 }, std::ref(deltaCounterValue));
783
784 for (int i = 0; i < 4; ++i)
785 {
786 // Increment and decrement the INFERENCES_RUN counter 250 times
Sadik Armagan95e9efc2021-08-05 15:01:07 +0100787 writers.push_back(std::thread([&profilingService, inferencesRun]()
Finn Williamsf3fcf322020-05-11 14:38:02 +0100788 {
789 for (int i = 0; i < 250; ++i)
790 {
Sadik Armagan95e9efc2021-08-05 15:01:07 +0100791 profilingService.IncrementCounterValue(inferencesRun);
Finn Williamsf3fcf322020-05-11 14:38:02 +0100792 }
793 }));
794 // Add 10 to the INFERENCES_RUN counter 200 times
Sadik Armagan95e9efc2021-08-05 15:01:07 +0100795 writers.push_back(std::thread([&profilingService, inferencesRun]()
Finn Williamsf3fcf322020-05-11 14:38:02 +0100796 {
797 for (int i = 0; i < 200; ++i)
798 {
Sadik Armagan95e9efc2021-08-05 15:01:07 +0100799 profilingService.AddCounterValue(inferencesRun, 10);
Finn Williamsf3fcf322020-05-11 14:38:02 +0100800 }
801 }));
802 // Subtract 5 from the INFERENCES_RUN counter 200 times
Sadik Armagan95e9efc2021-08-05 15:01:07 +0100803 writers.push_back(std::thread([&profilingService, inferencesRun]()
Finn Williamsf3fcf322020-05-11 14:38:02 +0100804 {
805 for (int i = 0; i < 200; ++i)
806 {
Sadik Armagan95e9efc2021-08-05 15:01:07 +0100807 profilingService.SubtractCounterValue(inferencesRun, 5);
Finn Williamsf3fcf322020-05-11 14:38:02 +0100808 }
809 }));
810 }
811
812 std::for_each(writers.begin(), writers.end(), mem_fn(&std::thread::join));
813 reader.join();
814
815 // Do one last read in case the reader stopped early
816 deltaCounterValue += profilingService.GetDeltaCounterValue(INFERENCES_RUN);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100817 CHECK(deltaCounterValue == 5000);
Finn Williamsf3fcf322020-05-11 14:38:02 +0100818
Colm Donelan2ba48d22019-11-29 09:10:59 +0000819 // Reset the profiling service to stop any running thread
820 options.m_EnableProfiling = false;
821 profilingService.ResetExternalProfilingOptions(options, true);
FinnWilliamsArmf6e534a2019-09-16 15:45:42 +0100822}
823
Sadik Armagan1625efc2021-06-10 18:24:34 +0100824TEST_CASE("CheckProfilingObjectUids")
Matteo Martincighab173e92019-09-05 12:02:04 +0100825{
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100826 uint16_t uid = 0;
Sadik Armagan1625efc2021-06-10 18:24:34 +0100827 CHECK_NOTHROW(uid = GetNextUid());
828 CHECK(uid >= 1);
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100829
830 uint16_t nextUid = 0;
Sadik Armagan1625efc2021-06-10 18:24:34 +0100831 CHECK_NOTHROW(nextUid = GetNextUid());
832 CHECK(nextUid > uid);
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100833
834 std::vector<uint16_t> counterUids;
Sadik Armagan1625efc2021-06-10 18:24:34 +0100835 CHECK_NOTHROW(counterUids = GetNextCounterUids(uid,0));
836 CHECK(counterUids.size() == 1);
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100837
838 std::vector<uint16_t> nextCounterUids;
Sadik Armagan1625efc2021-06-10 18:24:34 +0100839 CHECK_NOTHROW(nextCounterUids = GetNextCounterUids(nextUid, 2));
840 CHECK(nextCounterUids.size() == 2);
841 CHECK(nextCounterUids[0] > counterUids[0]);
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100842
843 std::vector<uint16_t> counterUidsMultiCore;
Francis Murtagh1e5afee2021-05-11 09:37:47 +0100844 uint16_t thirdUid = nextCounterUids[0];
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100845 uint16_t numberOfCores = 13;
Sadik Armagan1625efc2021-06-10 18:24:34 +0100846 CHECK_NOTHROW(counterUidsMultiCore = GetNextCounterUids(thirdUid, numberOfCores));
847 CHECK(counterUidsMultiCore.size() == numberOfCores);
848 CHECK(counterUidsMultiCore.front() >= nextCounterUids[0]);
Keith Davis3201eea2019-10-24 17:30:41 +0100849 for (size_t i = 1; i < numberOfCores; i++)
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100850 {
Sadik Armagan1625efc2021-06-10 18:24:34 +0100851 CHECK(counterUidsMultiCore[i] == counterUidsMultiCore[i - 1] + 1);
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100852 }
Sadik Armagan1625efc2021-06-10 18:24:34 +0100853 CHECK(counterUidsMultiCore.back() == counterUidsMultiCore.front() + numberOfCores - 1);
Matteo Martincighab173e92019-09-05 12:02:04 +0100854}
855
Sadik Armagan1625efc2021-06-10 18:24:34 +0100856TEST_CASE("CheckCounterDirectoryRegisterCategory")
Matteo Martincighab173e92019-09-05 12:02:04 +0100857{
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100858 CounterDirectory counterDirectory;
Sadik Armagan1625efc2021-06-10 18:24:34 +0100859 CHECK(counterDirectory.GetCategoryCount() == 0);
860 CHECK(counterDirectory.GetDeviceCount() == 0);
861 CHECK(counterDirectory.GetCounterSetCount() == 0);
862 CHECK(counterDirectory.GetCounterCount() == 0);
Matteo Martincighab173e92019-09-05 12:02:04 +0100863
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100864 // Register a category with an invalid name
865 const Category* noCategory = nullptr;
Cathal Corbett5aa9fd72022-02-25 15:33:28 +0000866 CHECK_THROWS_AS(noCategory = counterDirectory.RegisterCategory(""), arm::pipe::InvalidArgumentException);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100867 CHECK(counterDirectory.GetCategoryCount() == 0);
868 CHECK(!noCategory);
Matteo Martincighab173e92019-09-05 12:02:04 +0100869
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100870 // Register a category with an invalid name
Sadik Armagan1625efc2021-06-10 18:24:34 +0100871 CHECK_THROWS_AS(noCategory = counterDirectory.RegisterCategory("invalid category"),
Cathal Corbett5aa9fd72022-02-25 15:33:28 +0000872 arm::pipe::InvalidArgumentException);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100873 CHECK(counterDirectory.GetCategoryCount() == 0);
874 CHECK(!noCategory);
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100875
876 // Register a new category
877 const std::string categoryName = "some_category";
Keith Davis3201eea2019-10-24 17:30:41 +0100878 const Category* category = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +0100879 CHECK_NOTHROW(category = counterDirectory.RegisterCategory(categoryName));
880 CHECK(counterDirectory.GetCategoryCount() == 1);
881 CHECK(category);
882 CHECK(category->m_Name == categoryName);
883 CHECK(category->m_Counters.empty());
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100884
885 // Get the registered category
886 const Category* registeredCategory = counterDirectory.GetCategory(categoryName);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100887 CHECK(counterDirectory.GetCategoryCount() == 1);
888 CHECK(registeredCategory);
889 CHECK(registeredCategory == category);
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100890
891 // Try to get a category not registered
892 const Category* notRegisteredCategory = counterDirectory.GetCategory("not_registered_category");
Sadik Armagan1625efc2021-06-10 18:24:34 +0100893 CHECK(counterDirectory.GetCategoryCount() == 1);
894 CHECK(!notRegisteredCategory);
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100895
896 // Register a category already registered
897 const Category* anotherCategory = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +0100898 CHECK_THROWS_AS(anotherCategory = counterDirectory.RegisterCategory(categoryName),
Cathal Corbett5aa9fd72022-02-25 15:33:28 +0000899 arm::pipe::InvalidArgumentException);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100900 CHECK(counterDirectory.GetCategoryCount() == 1);
901 CHECK(!anotherCategory);
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100902
903 // Register a device for testing
904 const std::string deviceName = "some_device";
Keith Davis3201eea2019-10-24 17:30:41 +0100905 const Device* device = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +0100906 CHECK_NOTHROW(device = counterDirectory.RegisterDevice(deviceName));
907 CHECK(counterDirectory.GetDeviceCount() == 1);
908 CHECK(device);
909 CHECK(device->m_Uid >= 1);
910 CHECK(device->m_Name == deviceName);
911 CHECK(device->m_Cores == 0);
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100912
913 // Register a new category not associated to any device
914 const std::string categoryWoDeviceName = "some_category_without_device";
Keith Davis3201eea2019-10-24 17:30:41 +0100915 const Category* categoryWoDevice = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +0100916 CHECK_NOTHROW(categoryWoDevice = counterDirectory.RegisterCategory(categoryWoDeviceName));
917 CHECK(counterDirectory.GetCategoryCount() == 2);
918 CHECK(categoryWoDevice);
919 CHECK(categoryWoDevice->m_Name == categoryWoDeviceName);
920 CHECK(categoryWoDevice->m_Counters.empty());
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100921
Sadik Armagan4c998992020-02-25 12:44:44 +0000922 // Register a new category associated to an invalid device name (already exist)
923 const Category* categoryInvalidDeviceName = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +0100924 CHECK_THROWS_AS(categoryInvalidDeviceName =
Sadik Armagan4c998992020-02-25 12:44:44 +0000925 counterDirectory.RegisterCategory(categoryWoDeviceName),
Cathal Corbett5aa9fd72022-02-25 15:33:28 +0000926 arm::pipe::InvalidArgumentException);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100927 CHECK(counterDirectory.GetCategoryCount() == 2);
928 CHECK(!categoryInvalidDeviceName);
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100929
930 // Register a new category associated to a valid device
931 const std::string categoryWValidDeviceName = "some_category_with_valid_device";
Keith Davis3201eea2019-10-24 17:30:41 +0100932 const Category* categoryWValidDevice = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +0100933 CHECK_NOTHROW(categoryWValidDevice =
Sadik Armagan4c998992020-02-25 12:44:44 +0000934 counterDirectory.RegisterCategory(categoryWValidDeviceName));
Sadik Armagan1625efc2021-06-10 18:24:34 +0100935 CHECK(counterDirectory.GetCategoryCount() == 3);
936 CHECK(categoryWValidDevice);
937 CHECK(categoryWValidDevice != category);
938 CHECK(categoryWValidDevice->m_Name == categoryWValidDeviceName);
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100939
940 // Register a counter set for testing
941 const std::string counterSetName = "some_counter_set";
Keith Davis3201eea2019-10-24 17:30:41 +0100942 const CounterSet* counterSet = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +0100943 CHECK_NOTHROW(counterSet = counterDirectory.RegisterCounterSet(counterSetName));
944 CHECK(counterDirectory.GetCounterSetCount() == 1);
945 CHECK(counterSet);
946 CHECK(counterSet->m_Uid >= 1);
947 CHECK(counterSet->m_Name == counterSetName);
948 CHECK(counterSet->m_Count == 0);
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100949
950 // Register a new category not associated to any counter set
951 const std::string categoryWoCounterSetName = "some_category_without_counter_set";
Keith Davis3201eea2019-10-24 17:30:41 +0100952 const Category* categoryWoCounterSet = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +0100953 CHECK_NOTHROW(categoryWoCounterSet =
Sadik Armagan4c998992020-02-25 12:44:44 +0000954 counterDirectory.RegisterCategory(categoryWoCounterSetName));
Sadik Armagan1625efc2021-06-10 18:24:34 +0100955 CHECK(counterDirectory.GetCategoryCount() == 4);
956 CHECK(categoryWoCounterSet);
957 CHECK(categoryWoCounterSet->m_Name == categoryWoCounterSetName);
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100958
959 // Register a new category associated to a valid counter set
960 const std::string categoryWValidCounterSetName = "some_category_with_valid_counter_set";
Keith Davis3201eea2019-10-24 17:30:41 +0100961 const Category* categoryWValidCounterSet = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +0100962 CHECK_NOTHROW(categoryWValidCounterSet = counterDirectory.RegisterCategory(categoryWValidCounterSetName));
963 CHECK(counterDirectory.GetCategoryCount() == 5);
964 CHECK(categoryWValidCounterSet);
965 CHECK(categoryWValidCounterSet != category);
966 CHECK(categoryWValidCounterSet->m_Name == categoryWValidCounterSetName);
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100967
968 // Register a new category associated to a valid device and counter set
969 const std::string categoryWValidDeviceAndValidCounterSetName = "some_category_with_valid_device_and_counter_set";
Keith Davis3201eea2019-10-24 17:30:41 +0100970 const Category* categoryWValidDeviceAndValidCounterSet = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +0100971 CHECK_NOTHROW(categoryWValidDeviceAndValidCounterSet = counterDirectory.RegisterCategory(
Sadik Armagan4c998992020-02-25 12:44:44 +0000972 categoryWValidDeviceAndValidCounterSetName));
Sadik Armagan1625efc2021-06-10 18:24:34 +0100973 CHECK(counterDirectory.GetCategoryCount() == 6);
974 CHECK(categoryWValidDeviceAndValidCounterSet);
975 CHECK(categoryWValidDeviceAndValidCounterSet != category);
976 CHECK(categoryWValidDeviceAndValidCounterSet->m_Name == categoryWValidDeviceAndValidCounterSetName);
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100977}
978
Sadik Armagan1625efc2021-06-10 18:24:34 +0100979TEST_CASE("CheckCounterDirectoryRegisterDevice")
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100980{
981 CounterDirectory counterDirectory;
Sadik Armagan1625efc2021-06-10 18:24:34 +0100982 CHECK(counterDirectory.GetCategoryCount() == 0);
983 CHECK(counterDirectory.GetDeviceCount() == 0);
984 CHECK(counterDirectory.GetCounterSetCount() == 0);
985 CHECK(counterDirectory.GetCounterCount() == 0);
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100986
987 // Register a device with an invalid name
988 const Device* noDevice = nullptr;
Cathal Corbett5aa9fd72022-02-25 15:33:28 +0000989 CHECK_THROWS_AS(noDevice = counterDirectory.RegisterDevice(""), arm::pipe::InvalidArgumentException);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100990 CHECK(counterDirectory.GetDeviceCount() == 0);
991 CHECK(!noDevice);
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100992
993 // Register a device with an invalid name
Cathal Corbett5aa9fd72022-02-25 15:33:28 +0000994 CHECK_THROWS_AS(noDevice = counterDirectory.RegisterDevice("inv@lid nam€"), arm::pipe::InvalidArgumentException);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100995 CHECK(counterDirectory.GetDeviceCount() == 0);
996 CHECK(!noDevice);
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100997
998 // Register a new device with no cores or parent category
999 const std::string deviceName = "some_device";
Keith Davis3201eea2019-10-24 17:30:41 +01001000 const Device* device = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001001 CHECK_NOTHROW(device = counterDirectory.RegisterDevice(deviceName));
1002 CHECK(counterDirectory.GetDeviceCount() == 1);
1003 CHECK(device);
1004 CHECK(device->m_Name == deviceName);
1005 CHECK(device->m_Uid >= 1);
1006 CHECK(device->m_Cores == 0);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001007
Matteo Martincigh657ab2d2019-09-18 10:53:24 +01001008 // Try getting an unregistered device
1009 const Device* unregisteredDevice = counterDirectory.GetDevice(9999);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001010 CHECK(!unregisteredDevice);
Matteo Martincigh657ab2d2019-09-18 10:53:24 +01001011
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001012 // Get the registered device
1013 const Device* registeredDevice = counterDirectory.GetDevice(device->m_Uid);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001014 CHECK(counterDirectory.GetDeviceCount() == 1);
1015 CHECK(registeredDevice);
1016 CHECK(registeredDevice == device);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001017
Matteo Martincigh657ab2d2019-09-18 10:53:24 +01001018 // Register a device with the name of a device already registered
1019 const Device* deviceSameName = nullptr;
Jim Flynnf9db3ef2022-03-08 21:23:44 +00001020 CHECK_THROWS_AS(deviceSameName = counterDirectory.RegisterDevice(deviceName),
1021 arm::pipe::InvalidArgumentException);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001022 CHECK(counterDirectory.GetDeviceCount() == 1);
1023 CHECK(!deviceSameName);
Matteo Martincigh657ab2d2019-09-18 10:53:24 +01001024
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001025 // Register a new device with cores and no parent category
1026 const std::string deviceWCoresName = "some_device_with_cores";
Keith Davis3201eea2019-10-24 17:30:41 +01001027 const Device* deviceWCores = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001028 CHECK_NOTHROW(deviceWCores = counterDirectory.RegisterDevice(deviceWCoresName, 2));
1029 CHECK(counterDirectory.GetDeviceCount() == 2);
1030 CHECK(deviceWCores);
1031 CHECK(deviceWCores->m_Name == deviceWCoresName);
1032 CHECK(deviceWCores->m_Uid >= 1);
1033 CHECK(deviceWCores->m_Uid > device->m_Uid);
1034 CHECK(deviceWCores->m_Cores == 2);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001035
1036 // Get the registered device
1037 const Device* registeredDeviceWCores = counterDirectory.GetDevice(deviceWCores->m_Uid);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001038 CHECK(counterDirectory.GetDeviceCount() == 2);
1039 CHECK(registeredDeviceWCores);
1040 CHECK(registeredDeviceWCores == deviceWCores);
1041 CHECK(registeredDeviceWCores != device);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001042
1043 // Register a new device with cores and invalid parent category
1044 const std::string deviceWCoresWInvalidParentCategoryName = "some_device_with_cores_with_invalid_parent_category";
Keith Davis3201eea2019-10-24 17:30:41 +01001045 const Device* deviceWCoresWInvalidParentCategory = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001046 CHECK_THROWS_AS(deviceWCoresWInvalidParentCategory =
Keith Davis3201eea2019-10-24 17:30:41 +01001047 counterDirectory.RegisterDevice(deviceWCoresWInvalidParentCategoryName, 3, std::string("")),
Cathal Corbett5aa9fd72022-02-25 15:33:28 +00001048 arm::pipe::InvalidArgumentException);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001049 CHECK(counterDirectory.GetDeviceCount() == 2);
1050 CHECK(!deviceWCoresWInvalidParentCategory);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001051
1052 // Register a new device with cores and invalid parent category
1053 const std::string deviceWCoresWInvalidParentCategoryName2 = "some_device_with_cores_with_invalid_parent_category2";
Keith Davis3201eea2019-10-24 17:30:41 +01001054 const Device* deviceWCoresWInvalidParentCategory2 = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001055 CHECK_THROWS_AS(deviceWCoresWInvalidParentCategory2 = counterDirectory.RegisterDevice(
Keith Davis3201eea2019-10-24 17:30:41 +01001056 deviceWCoresWInvalidParentCategoryName2, 3, std::string("invalid_parent_category")),
Cathal Corbett5aa9fd72022-02-25 15:33:28 +00001057 arm::pipe::InvalidArgumentException);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001058 CHECK(counterDirectory.GetDeviceCount() == 2);
1059 CHECK(!deviceWCoresWInvalidParentCategory2);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001060
1061 // Register a category for testing
1062 const std::string categoryName = "some_category";
Keith Davis3201eea2019-10-24 17:30:41 +01001063 const Category* category = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001064 CHECK_NOTHROW(category = counterDirectory.RegisterCategory(categoryName));
1065 CHECK(counterDirectory.GetCategoryCount() == 1);
1066 CHECK(category);
1067 CHECK(category->m_Name == categoryName);
1068 CHECK(category->m_Counters.empty());
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001069
1070 // Register a new device with cores and valid parent category
1071 const std::string deviceWCoresWValidParentCategoryName = "some_device_with_cores_with_valid_parent_category";
Keith Davis3201eea2019-10-24 17:30:41 +01001072 const Device* deviceWCoresWValidParentCategory = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001073 CHECK_NOTHROW(deviceWCoresWValidParentCategory =
Keith Davis3201eea2019-10-24 17:30:41 +01001074 counterDirectory.RegisterDevice(deviceWCoresWValidParentCategoryName, 4, categoryName));
Sadik Armagan1625efc2021-06-10 18:24:34 +01001075 CHECK(counterDirectory.GetDeviceCount() == 3);
1076 CHECK(deviceWCoresWValidParentCategory);
1077 CHECK(deviceWCoresWValidParentCategory->m_Name == deviceWCoresWValidParentCategoryName);
1078 CHECK(deviceWCoresWValidParentCategory->m_Uid >= 1);
1079 CHECK(deviceWCoresWValidParentCategory->m_Uid > device->m_Uid);
1080 CHECK(deviceWCoresWValidParentCategory->m_Uid > deviceWCores->m_Uid);
1081 CHECK(deviceWCoresWValidParentCategory->m_Cores == 4);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001082}
1083
Sadik Armagan1625efc2021-06-10 18:24:34 +01001084TEST_CASE("CheckCounterDirectoryRegisterCounterSet")
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001085{
1086 CounterDirectory counterDirectory;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001087 CHECK(counterDirectory.GetCategoryCount() == 0);
1088 CHECK(counterDirectory.GetDeviceCount() == 0);
1089 CHECK(counterDirectory.GetCounterSetCount() == 0);
1090 CHECK(counterDirectory.GetCounterCount() == 0);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001091
1092 // Register a counter set with an invalid name
1093 const CounterSet* noCounterSet = nullptr;
Cathal Corbett5aa9fd72022-02-25 15:33:28 +00001094 CHECK_THROWS_AS(noCounterSet = counterDirectory.RegisterCounterSet(""), arm::pipe::InvalidArgumentException);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001095 CHECK(counterDirectory.GetCounterSetCount() == 0);
1096 CHECK(!noCounterSet);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001097
1098 // Register a counter set with an invalid name
Sadik Armagan1625efc2021-06-10 18:24:34 +01001099 CHECK_THROWS_AS(noCounterSet = counterDirectory.RegisterCounterSet("invalid name"),
Cathal Corbett5aa9fd72022-02-25 15:33:28 +00001100 arm::pipe::InvalidArgumentException);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001101 CHECK(counterDirectory.GetCounterSetCount() == 0);
1102 CHECK(!noCounterSet);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001103
1104 // Register a new counter set with no count or parent category
1105 const std::string counterSetName = "some_counter_set";
Keith Davis3201eea2019-10-24 17:30:41 +01001106 const CounterSet* counterSet = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001107 CHECK_NOTHROW(counterSet = counterDirectory.RegisterCounterSet(counterSetName));
1108 CHECK(counterDirectory.GetCounterSetCount() == 1);
1109 CHECK(counterSet);
1110 CHECK(counterSet->m_Name == counterSetName);
1111 CHECK(counterSet->m_Uid >= 1);
1112 CHECK(counterSet->m_Count == 0);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001113
Matteo Martincigh657ab2d2019-09-18 10:53:24 +01001114 // Try getting an unregistered counter set
1115 const CounterSet* unregisteredCounterSet = counterDirectory.GetCounterSet(9999);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001116 CHECK(!unregisteredCounterSet);
Matteo Martincigh657ab2d2019-09-18 10:53:24 +01001117
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001118 // Get the registered counter set
1119 const CounterSet* registeredCounterSet = counterDirectory.GetCounterSet(counterSet->m_Uid);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001120 CHECK(counterDirectory.GetCounterSetCount() == 1);
1121 CHECK(registeredCounterSet);
1122 CHECK(registeredCounterSet == counterSet);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001123
Matteo Martincigh657ab2d2019-09-18 10:53:24 +01001124 // Register a counter set with the name of a counter set already registered
1125 const CounterSet* counterSetSameName = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001126 CHECK_THROWS_AS(counterSetSameName = counterDirectory.RegisterCounterSet(counterSetName),
Cathal Corbett5aa9fd72022-02-25 15:33:28 +00001127 arm::pipe::InvalidArgumentException);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001128 CHECK(counterDirectory.GetCounterSetCount() == 1);
1129 CHECK(!counterSetSameName);
Matteo Martincigh657ab2d2019-09-18 10:53:24 +01001130
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001131 // Register a new counter set with count and no parent category
1132 const std::string counterSetWCountName = "some_counter_set_with_count";
Keith Davis3201eea2019-10-24 17:30:41 +01001133 const CounterSet* counterSetWCount = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001134 CHECK_NOTHROW(counterSetWCount = counterDirectory.RegisterCounterSet(counterSetWCountName, 37));
1135 CHECK(counterDirectory.GetCounterSetCount() == 2);
1136 CHECK(counterSetWCount);
1137 CHECK(counterSetWCount->m_Name == counterSetWCountName);
1138 CHECK(counterSetWCount->m_Uid >= 1);
1139 CHECK(counterSetWCount->m_Uid > counterSet->m_Uid);
1140 CHECK(counterSetWCount->m_Count == 37);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001141
1142 // Get the registered counter set
1143 const CounterSet* registeredCounterSetWCount = counterDirectory.GetCounterSet(counterSetWCount->m_Uid);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001144 CHECK(counterDirectory.GetCounterSetCount() == 2);
1145 CHECK(registeredCounterSetWCount);
1146 CHECK(registeredCounterSetWCount == counterSetWCount);
1147 CHECK(registeredCounterSetWCount != counterSet);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001148
1149 // Register a new counter set with count and invalid parent category
1150 const std::string counterSetWCountWInvalidParentCategoryName = "some_counter_set_with_count_"
1151 "with_invalid_parent_category";
1152 const CounterSet* counterSetWCountWInvalidParentCategory = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001153 CHECK_THROWS_AS(counterSetWCountWInvalidParentCategory = counterDirectory.RegisterCounterSet(
Keith Davis3201eea2019-10-24 17:30:41 +01001154 counterSetWCountWInvalidParentCategoryName, 42, std::string("")),
Cathal Corbett5aa9fd72022-02-25 15:33:28 +00001155 arm::pipe::InvalidArgumentException);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001156 CHECK(counterDirectory.GetCounterSetCount() == 2);
1157 CHECK(!counterSetWCountWInvalidParentCategory);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001158
1159 // Register a new counter set with count and invalid parent category
1160 const std::string counterSetWCountWInvalidParentCategoryName2 = "some_counter_set_with_count_"
1161 "with_invalid_parent_category2";
1162 const CounterSet* counterSetWCountWInvalidParentCategory2 = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001163 CHECK_THROWS_AS(counterSetWCountWInvalidParentCategory2 = counterDirectory.RegisterCounterSet(
Keith Davis3201eea2019-10-24 17:30:41 +01001164 counterSetWCountWInvalidParentCategoryName2, 42, std::string("invalid_parent_category")),
Cathal Corbett5aa9fd72022-02-25 15:33:28 +00001165 arm::pipe::InvalidArgumentException);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001166 CHECK(counterDirectory.GetCounterSetCount() == 2);
1167 CHECK(!counterSetWCountWInvalidParentCategory2);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001168
1169 // Register a category for testing
1170 const std::string categoryName = "some_category";
Keith Davis3201eea2019-10-24 17:30:41 +01001171 const Category* category = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001172 CHECK_NOTHROW(category = counterDirectory.RegisterCategory(categoryName));
1173 CHECK(counterDirectory.GetCategoryCount() == 1);
1174 CHECK(category);
1175 CHECK(category->m_Name == categoryName);
1176 CHECK(category->m_Counters.empty());
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001177
1178 // Register a new counter set with count and valid parent category
1179 const std::string counterSetWCountWValidParentCategoryName = "some_counter_set_with_count_"
1180 "with_valid_parent_category";
1181 const CounterSet* counterSetWCountWValidParentCategory = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001182 CHECK_NOTHROW(counterSetWCountWValidParentCategory = counterDirectory.RegisterCounterSet(
Keith Davis3201eea2019-10-24 17:30:41 +01001183 counterSetWCountWValidParentCategoryName, 42, categoryName));
Sadik Armagan1625efc2021-06-10 18:24:34 +01001184 CHECK(counterDirectory.GetCounterSetCount() == 3);
1185 CHECK(counterSetWCountWValidParentCategory);
1186 CHECK(counterSetWCountWValidParentCategory->m_Name == counterSetWCountWValidParentCategoryName);
1187 CHECK(counterSetWCountWValidParentCategory->m_Uid >= 1);
1188 CHECK(counterSetWCountWValidParentCategory->m_Uid > counterSet->m_Uid);
1189 CHECK(counterSetWCountWValidParentCategory->m_Uid > counterSetWCount->m_Uid);
1190 CHECK(counterSetWCountWValidParentCategory->m_Count == 42);
Matteo Martincigh657ab2d2019-09-18 10:53:24 +01001191
Sadik Armagan4c998992020-02-25 12:44:44 +00001192 // Register a counter set associated to a category with invalid name
Matteo Martincigh657ab2d2019-09-18 10:53:24 +01001193 const std::string counterSetSameCategoryName = "some_counter_set_with_invalid_parent_category";
Sadik Armagan4c998992020-02-25 12:44:44 +00001194 const std::string invalidCategoryName = "";
Keith Davis3201eea2019-10-24 17:30:41 +01001195 const CounterSet* counterSetSameCategory = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001196 CHECK_THROWS_AS(counterSetSameCategory =
Sadik Armagan4c998992020-02-25 12:44:44 +00001197 counterDirectory.RegisterCounterSet(counterSetSameCategoryName, 0, invalidCategoryName),
Cathal Corbett5aa9fd72022-02-25 15:33:28 +00001198 arm::pipe::InvalidArgumentException);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001199 CHECK(counterDirectory.GetCounterSetCount() == 3);
1200 CHECK(!counterSetSameCategory);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001201}
1202
Sadik Armagan1625efc2021-06-10 18:24:34 +01001203TEST_CASE("CheckCounterDirectoryRegisterCounter")
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001204{
1205 CounterDirectory counterDirectory;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001206 CHECK(counterDirectory.GetCategoryCount() == 0);
1207 CHECK(counterDirectory.GetDeviceCount() == 0);
1208 CHECK(counterDirectory.GetCounterSetCount() == 0);
1209 CHECK(counterDirectory.GetCounterCount() == 0);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001210
1211 // Register a counter with an invalid parent category name
1212 const Counter* noCounter = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001213 CHECK_THROWS_AS(noCounter =
Keith Davise394bd92019-12-02 15:12:19 +00001214 counterDirectory.RegisterCounter(armnn::profiling::BACKEND_ID,
1215 0,
1216 "",
1217 0,
1218 1,
1219 123.45f,
1220 "valid ",
1221 "name"),
Cathal Corbett5aa9fd72022-02-25 15:33:28 +00001222 arm::pipe::InvalidArgumentException);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001223 CHECK(counterDirectory.GetCounterCount() == 0);
1224 CHECK(!noCounter);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001225
1226 // Register a counter with an invalid parent category name
Sadik Armagan1625efc2021-06-10 18:24:34 +01001227 CHECK_THROWS_AS(noCounter = counterDirectory.RegisterCounter(armnn::profiling::BACKEND_ID,
Cathal Corbett5aa9fd72022-02-25 15:33:28 +00001228 1,
1229 "invalid parent category",
1230 0,
1231 1,
1232 123.45f,
1233 "valid name",
1234 "valid description"),
1235 arm::pipe::InvalidArgumentException);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001236 CHECK(counterDirectory.GetCounterCount() == 0);
1237 CHECK(!noCounter);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001238
1239 // Register a counter with an invalid class
Sadik Armagan1625efc2021-06-10 18:24:34 +01001240 CHECK_THROWS_AS(noCounter = counterDirectory.RegisterCounter(armnn::profiling::BACKEND_ID,
Cathal Corbett5aa9fd72022-02-25 15:33:28 +00001241 2,
1242 "valid_parent_category",
1243 2,
1244 1,
1245 123.45f,
1246 "valid "
1247 "name",
1248 "valid description"),
1249 arm::pipe::InvalidArgumentException);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001250 CHECK(counterDirectory.GetCounterCount() == 0);
1251 CHECK(!noCounter);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001252
1253 // Register a counter with an invalid interpolation
Sadik Armagan1625efc2021-06-10 18:24:34 +01001254 CHECK_THROWS_AS(noCounter = counterDirectory.RegisterCounter(armnn::profiling::BACKEND_ID,
Cathal Corbett5aa9fd72022-02-25 15:33:28 +00001255 4,
1256 "valid_parent_category",
1257 0,
1258 3,
1259 123.45f,
1260 "valid "
1261 "name",
1262 "valid description"),
1263 arm::pipe::InvalidArgumentException);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001264 CHECK(counterDirectory.GetCounterCount() == 0);
1265 CHECK(!noCounter);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001266
1267 // Register a counter with an invalid multiplier
Sadik Armagan1625efc2021-06-10 18:24:34 +01001268 CHECK_THROWS_AS(noCounter = counterDirectory.RegisterCounter(armnn::profiling::BACKEND_ID,
Cathal Corbett5aa9fd72022-02-25 15:33:28 +00001269 5,
1270 "valid_parent_category",
1271 0,
1272 1,
1273 .0f,
1274 "valid "
1275 "name",
1276 "valid description"),
1277 arm::pipe::InvalidArgumentException);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001278 CHECK(counterDirectory.GetCounterCount() == 0);
1279 CHECK(!noCounter);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001280
1281 // Register a counter with an invalid name
Sadik Armagan1625efc2021-06-10 18:24:34 +01001282 CHECK_THROWS_AS(
Keith Davise394bd92019-12-02 15:12:19 +00001283 noCounter = counterDirectory.RegisterCounter(armnn::profiling::BACKEND_ID,
1284 6,
1285 "valid_parent_category",
1286 0,
1287 1,
1288 123.45f,
1289 "",
1290 "valid description"),
Cathal Corbett5aa9fd72022-02-25 15:33:28 +00001291 arm::pipe::InvalidArgumentException);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001292 CHECK(counterDirectory.GetCounterCount() == 0);
1293 CHECK(!noCounter);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001294
1295 // Register a counter with an invalid name
Sadik Armagan1625efc2021-06-10 18:24:34 +01001296 CHECK_THROWS_AS(noCounter = counterDirectory.RegisterCounter(armnn::profiling::BACKEND_ID,
Cathal Corbett5aa9fd72022-02-25 15:33:28 +00001297 7,
1298 "valid_parent_category",
1299 0,
1300 1,
1301 123.45f,
1302 "invalid nam€",
1303 "valid description"),
1304 arm::pipe::InvalidArgumentException);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001305 CHECK(counterDirectory.GetCounterCount() == 0);
1306 CHECK(!noCounter);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001307
1308 // Register a counter with an invalid description
Sadik Armagan1625efc2021-06-10 18:24:34 +01001309 CHECK_THROWS_AS(noCounter =
Keith Davise394bd92019-12-02 15:12:19 +00001310 counterDirectory.RegisterCounter(armnn::profiling::BACKEND_ID,
1311 8,
1312 "valid_parent_category",
1313 0,
1314 1,
1315 123.45f,
1316 "valid name",
1317 ""),
Cathal Corbett5aa9fd72022-02-25 15:33:28 +00001318 arm::pipe::InvalidArgumentException);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001319 CHECK(counterDirectory.GetCounterCount() == 0);
1320 CHECK(!noCounter);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001321
1322 // Register a counter with an invalid description
Sadik Armagan1625efc2021-06-10 18:24:34 +01001323 CHECK_THROWS_AS(noCounter = counterDirectory.RegisterCounter(armnn::profiling::BACKEND_ID,
Cathal Corbett5aa9fd72022-02-25 15:33:28 +00001324 9,
1325 "valid_parent_category",
1326 0,
1327 1,
1328 123.45f,
1329 "valid "
1330 "name",
1331 "inv@lid description"),
1332 arm::pipe::InvalidArgumentException);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001333 CHECK(counterDirectory.GetCounterCount() == 0);
1334 CHECK(!noCounter);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001335
1336 // Register a counter with an invalid unit2
Sadik Armagan1625efc2021-06-10 18:24:34 +01001337 CHECK_THROWS_AS(noCounter = counterDirectory.RegisterCounter(armnn::profiling::BACKEND_ID,
Cathal Corbett5aa9fd72022-02-25 15:33:28 +00001338 10,
1339 "valid_parent_category",
1340 0,
1341 1,
1342 123.45f,
1343 "valid name",
1344 "valid description",
1345 std::string("Mb/s2")),
1346 arm::pipe::InvalidArgumentException);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001347 CHECK(counterDirectory.GetCounterCount() == 0);
1348 CHECK(!noCounter);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001349
1350 // Register a counter with a non-existing parent category name
Sadik Armagan1625efc2021-06-10 18:24:34 +01001351 CHECK_THROWS_AS(noCounter = counterDirectory.RegisterCounter(armnn::profiling::BACKEND_ID,
Cathal Corbett5aa9fd72022-02-25 15:33:28 +00001352 11,
1353 "invalid_parent_category",
1354 0,
1355 1,
1356 123.45f,
1357 "valid name",
1358 "valid description"),
1359 arm::pipe::InvalidArgumentException);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001360 CHECK(counterDirectory.GetCounterCount() == 0);
1361 CHECK(!noCounter);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001362
Matteo Martincigh657ab2d2019-09-18 10:53:24 +01001363 // Try getting an unregistered counter
1364 const Counter* unregisteredCounter = counterDirectory.GetCounter(9999);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001365 CHECK(!unregisteredCounter);
Matteo Martincigh657ab2d2019-09-18 10:53:24 +01001366
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001367 // Register a category for testing
1368 const std::string categoryName = "some_category";
Keith Davis3201eea2019-10-24 17:30:41 +01001369 const Category* category = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001370 CHECK_NOTHROW(category = counterDirectory.RegisterCategory(categoryName));
1371 CHECK(counterDirectory.GetCategoryCount() == 1);
1372 CHECK(category);
1373 CHECK(category->m_Name == categoryName);
1374 CHECK(category->m_Counters.empty());
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001375
1376 // Register a counter with a valid parent category name
1377 const Counter* counter = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001378 CHECK_NOTHROW(
Keith Davise394bd92019-12-02 15:12:19 +00001379 counter = counterDirectory.RegisterCounter(armnn::profiling::BACKEND_ID,
1380 12,
1381 categoryName,
1382 0,
1383 1,
1384 123.45f,
1385 "valid name",
1386 "valid description"));
Sadik Armagan1625efc2021-06-10 18:24:34 +01001387 CHECK(counterDirectory.GetCounterCount() == 1);
1388 CHECK(counter);
1389 CHECK(counter->m_MaxCounterUid == counter->m_Uid);
1390 CHECK(counter->m_Class == 0);
1391 CHECK(counter->m_Interpolation == 1);
1392 CHECK(counter->m_Multiplier == 123.45f);
1393 CHECK(counter->m_Name == "valid name");
1394 CHECK(counter->m_Description == "valid description");
1395 CHECK(counter->m_Units == "");
1396 CHECK(counter->m_DeviceUid == 0);
1397 CHECK(counter->m_CounterSetUid == 0);
1398 CHECK(category->m_Counters.size() == 1);
1399 CHECK(category->m_Counters.back() == counter->m_Uid);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001400
Matteo Martincigh657ab2d2019-09-18 10:53:24 +01001401 // Register a counter with a name of a counter already registered for the given parent category name
1402 const Counter* counterSameName = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001403 CHECK_THROWS_AS(counterSameName =
Keith Davise394bd92019-12-02 15:12:19 +00001404 counterDirectory.RegisterCounter(armnn::profiling::BACKEND_ID,
1405 13,
1406 categoryName,
1407 0,
1408 0,
1409 1.0f,
1410 "valid name",
1411 "valid description",
1412 std::string("description")),
Cathal Corbett5aa9fd72022-02-25 15:33:28 +00001413 arm::pipe::InvalidArgumentException);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001414 CHECK(counterDirectory.GetCounterCount() == 1);
1415 CHECK(!counterSameName);
Matteo Martincigh657ab2d2019-09-18 10:53:24 +01001416
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001417 // Register a counter with a valid parent category name and units
1418 const Counter* counterWUnits = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001419 CHECK_NOTHROW(counterWUnits = counterDirectory.RegisterCounter(armnn::profiling::BACKEND_ID,
Cathal Corbett5aa9fd72022-02-25 15:33:28 +00001420 14,
1421 categoryName,
1422 0,
1423 1,
1424 123.45f,
1425 "valid name 2",
1426 "valid description",
1427 std::string("Mnnsq2"))); // Units
Sadik Armagan1625efc2021-06-10 18:24:34 +01001428 CHECK(counterDirectory.GetCounterCount() == 2);
1429 CHECK(counterWUnits);
1430 CHECK(counterWUnits->m_Uid > counter->m_Uid);
1431 CHECK(counterWUnits->m_MaxCounterUid == counterWUnits->m_Uid);
1432 CHECK(counterWUnits->m_Class == 0);
1433 CHECK(counterWUnits->m_Interpolation == 1);
1434 CHECK(counterWUnits->m_Multiplier == 123.45f);
1435 CHECK(counterWUnits->m_Name == "valid name 2");
1436 CHECK(counterWUnits->m_Description == "valid description");
1437 CHECK(counterWUnits->m_Units == "Mnnsq2");
1438 CHECK(counterWUnits->m_DeviceUid == 0);
1439 CHECK(counterWUnits->m_CounterSetUid == 0);
1440 CHECK(category->m_Counters.size() == 2);
1441 CHECK(category->m_Counters.back() == counterWUnits->m_Uid);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001442
1443 // Register a counter with a valid parent category name and not associated with a device
1444 const Counter* counterWoDevice = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001445 CHECK_NOTHROW(counterWoDevice = counterDirectory.RegisterCounter(armnn::profiling::BACKEND_ID,
Cathal Corbett5aa9fd72022-02-25 15:33:28 +00001446 26,
1447 categoryName,
1448 0,
1449 1,
1450 123.45f,
1451 "valid name 3",
1452 "valid description",
Jim Flynndecd08b2022-03-13 22:35:46 +00001453 arm::pipe::EmptyOptional(),// Units
1454 arm::pipe::EmptyOptional(),// Number of cores
Cathal Corbett5aa9fd72022-02-25 15:33:28 +00001455 0)); // Device UID
Sadik Armagan1625efc2021-06-10 18:24:34 +01001456 CHECK(counterDirectory.GetCounterCount() == 3);
1457 CHECK(counterWoDevice);
1458 CHECK(counterWoDevice->m_Uid > counter->m_Uid);
1459 CHECK(counterWoDevice->m_MaxCounterUid == counterWoDevice->m_Uid);
1460 CHECK(counterWoDevice->m_Class == 0);
1461 CHECK(counterWoDevice->m_Interpolation == 1);
1462 CHECK(counterWoDevice->m_Multiplier == 123.45f);
1463 CHECK(counterWoDevice->m_Name == "valid name 3");
1464 CHECK(counterWoDevice->m_Description == "valid description");
1465 CHECK(counterWoDevice->m_Units == "");
1466 CHECK(counterWoDevice->m_DeviceUid == 0);
1467 CHECK(counterWoDevice->m_CounterSetUid == 0);
1468 CHECK(category->m_Counters.size() == 3);
1469 CHECK(category->m_Counters.back() == counterWoDevice->m_Uid);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001470
1471 // Register a counter with a valid parent category name and associated to an invalid device
Sadik Armagan1625efc2021-06-10 18:24:34 +01001472 CHECK_THROWS_AS(noCounter = counterDirectory.RegisterCounter(armnn::profiling::BACKEND_ID,
Cathal Corbett5aa9fd72022-02-25 15:33:28 +00001473 15,
1474 categoryName,
1475 0,
1476 1,
1477 123.45f,
1478 "valid name 4",
1479 "valid description",
Jim Flynndecd08b2022-03-13 22:35:46 +00001480 arm::pipe::EmptyOptional(), // Units
1481 arm::pipe::EmptyOptional(), // Number of cores
Cathal Corbett5aa9fd72022-02-25 15:33:28 +00001482 100), // Device UID
1483 arm::pipe::InvalidArgumentException);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001484 CHECK(counterDirectory.GetCounterCount() == 3);
1485 CHECK(!noCounter);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001486
1487 // Register a device for testing
1488 const std::string deviceName = "some_device";
Keith Davis3201eea2019-10-24 17:30:41 +01001489 const Device* device = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001490 CHECK_NOTHROW(device = counterDirectory.RegisterDevice(deviceName));
1491 CHECK(counterDirectory.GetDeviceCount() == 1);
1492 CHECK(device);
1493 CHECK(device->m_Name == deviceName);
1494 CHECK(device->m_Uid >= 1);
1495 CHECK(device->m_Cores == 0);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001496
1497 // Register a counter with a valid parent category name and associated to a device
1498 const Counter* counterWDevice = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001499 CHECK_NOTHROW(counterWDevice = counterDirectory.RegisterCounter(armnn::profiling::BACKEND_ID,
Cathal Corbett5aa9fd72022-02-25 15:33:28 +00001500 16,
1501 categoryName,
1502 0,
1503 1,
1504 123.45f,
1505 "valid name 5",
1506 std::string("valid description"),
Jim Flynndecd08b2022-03-13 22:35:46 +00001507 arm::pipe::EmptyOptional(), // Units
1508 arm::pipe::EmptyOptional(), // Number of cores
Cathal Corbett5aa9fd72022-02-25 15:33:28 +00001509 device->m_Uid)); // Device UID
Sadik Armagan1625efc2021-06-10 18:24:34 +01001510 CHECK(counterDirectory.GetCounterCount() == 4);
1511 CHECK(counterWDevice);
1512 CHECK(counterWDevice->m_Uid > counter->m_Uid);
1513 CHECK(counterWDevice->m_MaxCounterUid == counterWDevice->m_Uid);
1514 CHECK(counterWDevice->m_Class == 0);
1515 CHECK(counterWDevice->m_Interpolation == 1);
1516 CHECK(counterWDevice->m_Multiplier == 123.45f);
1517 CHECK(counterWDevice->m_Name == "valid name 5");
1518 CHECK(counterWDevice->m_Description == "valid description");
1519 CHECK(counterWDevice->m_Units == "");
1520 CHECK(counterWDevice->m_DeviceUid == device->m_Uid);
1521 CHECK(counterWDevice->m_CounterSetUid == 0);
1522 CHECK(category->m_Counters.size() == 4);
1523 CHECK(category->m_Counters.back() == counterWDevice->m_Uid);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001524
1525 // Register a counter with a valid parent category name and not associated with a counter set
1526 const Counter* counterWoCounterSet = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001527 CHECK_NOTHROW(counterWoCounterSet = counterDirectory.RegisterCounter(armnn::profiling::BACKEND_ID,
Cathal Corbett5aa9fd72022-02-25 15:33:28 +00001528 17,
1529 categoryName,
1530 0,
1531 1,
1532 123.45f,
1533 "valid name 6",
1534 "valid description",
Jim Flynndecd08b2022-03-13 22:35:46 +00001535 arm::pipe::EmptyOptional(),// Units
1536 arm::pipe::EmptyOptional(),// No of cores
1537 arm::pipe::EmptyOptional(),// Device UID
Cathal Corbett5aa9fd72022-02-25 15:33:28 +00001538 0)); // CounterSet UID
Sadik Armagan1625efc2021-06-10 18:24:34 +01001539 CHECK(counterDirectory.GetCounterCount() == 5);
1540 CHECK(counterWoCounterSet);
1541 CHECK(counterWoCounterSet->m_Uid > counter->m_Uid);
1542 CHECK(counterWoCounterSet->m_MaxCounterUid == counterWoCounterSet->m_Uid);
1543 CHECK(counterWoCounterSet->m_Class == 0);
1544 CHECK(counterWoCounterSet->m_Interpolation == 1);
1545 CHECK(counterWoCounterSet->m_Multiplier == 123.45f);
1546 CHECK(counterWoCounterSet->m_Name == "valid name 6");
1547 CHECK(counterWoCounterSet->m_Description == "valid description");
1548 CHECK(counterWoCounterSet->m_Units == "");
1549 CHECK(counterWoCounterSet->m_DeviceUid == 0);
1550 CHECK(counterWoCounterSet->m_CounterSetUid == 0);
1551 CHECK(category->m_Counters.size() == 5);
1552 CHECK(category->m_Counters.back() == counterWoCounterSet->m_Uid);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001553
1554 // Register a counter with a valid parent category name and associated to an invalid counter set
Sadik Armagan1625efc2021-06-10 18:24:34 +01001555 CHECK_THROWS_AS(noCounter = counterDirectory.RegisterCounter(armnn::profiling::BACKEND_ID,
Cathal Corbett5aa9fd72022-02-25 15:33:28 +00001556 18,
1557 categoryName,
1558 0,
1559 1,
1560 123.45f,
1561 "valid ",
1562 "name 7",
1563 std::string("valid description"),
Jim Flynndecd08b2022-03-13 22:35:46 +00001564 arm::pipe::EmptyOptional(), // Units
1565 arm::pipe::EmptyOptional(), // Number of cores
Cathal Corbett5aa9fd72022-02-25 15:33:28 +00001566 100), // Counter set UID
1567 arm::pipe::InvalidArgumentException);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001568 CHECK(counterDirectory.GetCounterCount() == 5);
1569 CHECK(!noCounter);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001570
1571 // Register a counter with a valid parent category name and with a given number of cores
1572 const Counter* counterWNumberOfCores = nullptr;
Keith Davis3201eea2019-10-24 17:30:41 +01001573 uint16_t numberOfCores = 15;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001574 CHECK_NOTHROW(counterWNumberOfCores = counterDirectory.RegisterCounter(
Keith Davise394bd92019-12-02 15:12:19 +00001575 armnn::profiling::BACKEND_ID, 50,
Keith Davis3201eea2019-10-24 17:30:41 +01001576 categoryName, 0, 1, 123.45f, "valid name 8", "valid description",
Jim Flynndecd08b2022-03-13 22:35:46 +00001577 arm::pipe::EmptyOptional(), // Units
Keith Davis3201eea2019-10-24 17:30:41 +01001578 numberOfCores, // Number of cores
Jim Flynndecd08b2022-03-13 22:35:46 +00001579 arm::pipe::EmptyOptional(), // Device UID
1580 arm::pipe::EmptyOptional())); // Counter set UID
Sadik Armagan1625efc2021-06-10 18:24:34 +01001581 CHECK(counterDirectory.GetCounterCount() == 20);
1582 CHECK(counterWNumberOfCores);
1583 CHECK(counterWNumberOfCores->m_Uid > counter->m_Uid);
1584 CHECK(counterWNumberOfCores->m_MaxCounterUid == counterWNumberOfCores->m_Uid + numberOfCores - 1);
1585 CHECK(counterWNumberOfCores->m_Class == 0);
1586 CHECK(counterWNumberOfCores->m_Interpolation == 1);
1587 CHECK(counterWNumberOfCores->m_Multiplier == 123.45f);
1588 CHECK(counterWNumberOfCores->m_Name == "valid name 8");
1589 CHECK(counterWNumberOfCores->m_Description == "valid description");
1590 CHECK(counterWNumberOfCores->m_Units == "");
1591 CHECK(counterWNumberOfCores->m_DeviceUid == 0);
1592 CHECK(counterWNumberOfCores->m_CounterSetUid == 0);
1593 CHECK(category->m_Counters.size() == 20);
Keith Davis3201eea2019-10-24 17:30:41 +01001594 for (size_t i = 0; i < numberOfCores; i++)
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001595 {
Sadik Armagan1625efc2021-06-10 18:24:34 +01001596 CHECK(category->m_Counters[category->m_Counters.size() - numberOfCores + i] ==
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001597 counterWNumberOfCores->m_Uid + i);
1598 }
1599
1600 // Register a multi-core device for testing
1601 const std::string multiCoreDeviceName = "some_multi_core_device";
Keith Davis3201eea2019-10-24 17:30:41 +01001602 const Device* multiCoreDevice = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001603 CHECK_NOTHROW(multiCoreDevice = counterDirectory.RegisterDevice(multiCoreDeviceName, 4));
1604 CHECK(counterDirectory.GetDeviceCount() == 2);
1605 CHECK(multiCoreDevice);
1606 CHECK(multiCoreDevice->m_Name == multiCoreDeviceName);
1607 CHECK(multiCoreDevice->m_Uid >= 1);
1608 CHECK(multiCoreDevice->m_Cores == 4);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001609
1610 // Register a counter with a valid parent category name and associated to the multi-core device
1611 const Counter* counterWMultiCoreDevice = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001612 CHECK_NOTHROW(counterWMultiCoreDevice = counterDirectory.RegisterCounter(
Keith Davise394bd92019-12-02 15:12:19 +00001613 armnn::profiling::BACKEND_ID, 19, categoryName, 0, 1,
1614 123.45f, "valid name 9", "valid description",
Jim Flynndecd08b2022-03-13 22:35:46 +00001615 arm::pipe::EmptyOptional(), // Units
1616 arm::pipe::EmptyOptional(), // Number of cores
Keith Davis3201eea2019-10-24 17:30:41 +01001617 multiCoreDevice->m_Uid, // Device UID
Jim Flynndecd08b2022-03-13 22:35:46 +00001618 arm::pipe::EmptyOptional())); // Counter set UID
Sadik Armagan1625efc2021-06-10 18:24:34 +01001619 CHECK(counterDirectory.GetCounterCount() == 24);
1620 CHECK(counterWMultiCoreDevice);
1621 CHECK(counterWMultiCoreDevice->m_Uid > counter->m_Uid);
1622 CHECK(counterWMultiCoreDevice->m_MaxCounterUid ==
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001623 counterWMultiCoreDevice->m_Uid + multiCoreDevice->m_Cores - 1);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001624 CHECK(counterWMultiCoreDevice->m_Class == 0);
1625 CHECK(counterWMultiCoreDevice->m_Interpolation == 1);
1626 CHECK(counterWMultiCoreDevice->m_Multiplier == 123.45f);
1627 CHECK(counterWMultiCoreDevice->m_Name == "valid name 9");
1628 CHECK(counterWMultiCoreDevice->m_Description == "valid description");
1629 CHECK(counterWMultiCoreDevice->m_Units == "");
1630 CHECK(counterWMultiCoreDevice->m_DeviceUid == multiCoreDevice->m_Uid);
1631 CHECK(counterWMultiCoreDevice->m_CounterSetUid == 0);
1632 CHECK(category->m_Counters.size() == 24);
Keith Davis3201eea2019-10-24 17:30:41 +01001633 for (size_t i = 0; i < 4; i++)
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001634 {
Sadik Armagan1625efc2021-06-10 18:24:34 +01001635 CHECK(category->m_Counters[category->m_Counters.size() - 4 + i] == counterWMultiCoreDevice->m_Uid + i);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001636 }
1637
Matteo Martincigh657ab2d2019-09-18 10:53:24 +01001638 // Register a multi-core device associate to a parent category for testing
1639 const std::string multiCoreDeviceNameWParentCategory = "some_multi_core_device_with_parent_category";
Keith Davis3201eea2019-10-24 17:30:41 +01001640 const Device* multiCoreDeviceWParentCategory = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001641 CHECK_NOTHROW(multiCoreDeviceWParentCategory =
Keith Davis3201eea2019-10-24 17:30:41 +01001642 counterDirectory.RegisterDevice(multiCoreDeviceNameWParentCategory, 2, categoryName));
Sadik Armagan1625efc2021-06-10 18:24:34 +01001643 CHECK(counterDirectory.GetDeviceCount() == 3);
1644 CHECK(multiCoreDeviceWParentCategory);
1645 CHECK(multiCoreDeviceWParentCategory->m_Name == multiCoreDeviceNameWParentCategory);
1646 CHECK(multiCoreDeviceWParentCategory->m_Uid >= 1);
1647 CHECK(multiCoreDeviceWParentCategory->m_Cores == 2);
Matteo Martincigh657ab2d2019-09-18 10:53:24 +01001648
1649 // Register a counter with a valid parent category name and getting the number of cores of the multi-core device
1650 // associated to that category
1651 const Counter* counterWMultiCoreDeviceWParentCategory = nullptr;
Sadik Armagan4c998992020-02-25 12:44:44 +00001652 uint16_t numberOfCourse = multiCoreDeviceWParentCategory->m_Cores;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001653 CHECK_NOTHROW(counterWMultiCoreDeviceWParentCategory =
Jim Flynnbbfe6032020-07-20 16:57:44 +01001654 counterDirectory.RegisterCounter(
1655 armnn::profiling::BACKEND_ID,
1656 100,
1657 categoryName,
1658 0,
1659 1,
1660 123.45f,
1661 "valid name 10",
1662 "valid description",
Jim Flynndecd08b2022-03-13 22:35:46 +00001663 arm::pipe::EmptyOptional(), // Units
Jim Flynnbbfe6032020-07-20 16:57:44 +01001664 numberOfCourse, // Number of cores
Jim Flynndecd08b2022-03-13 22:35:46 +00001665 arm::pipe::EmptyOptional(), // Device UID
1666 arm::pipe::EmptyOptional()));// Counter set UID
Sadik Armagan1625efc2021-06-10 18:24:34 +01001667 CHECK(counterDirectory.GetCounterCount() == 26);
1668 CHECK(counterWMultiCoreDeviceWParentCategory);
1669 CHECK(counterWMultiCoreDeviceWParentCategory->m_Uid > counter->m_Uid);
1670 CHECK(counterWMultiCoreDeviceWParentCategory->m_MaxCounterUid ==
Matteo Martincigh657ab2d2019-09-18 10:53:24 +01001671 counterWMultiCoreDeviceWParentCategory->m_Uid + multiCoreDeviceWParentCategory->m_Cores - 1);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001672 CHECK(counterWMultiCoreDeviceWParentCategory->m_Class == 0);
1673 CHECK(counterWMultiCoreDeviceWParentCategory->m_Interpolation == 1);
1674 CHECK(counterWMultiCoreDeviceWParentCategory->m_Multiplier == 123.45f);
1675 CHECK(counterWMultiCoreDeviceWParentCategory->m_Name == "valid name 10");
1676 CHECK(counterWMultiCoreDeviceWParentCategory->m_Description == "valid description");
1677 CHECK(counterWMultiCoreDeviceWParentCategory->m_Units == "");
1678 CHECK(category->m_Counters.size() == 26);
Keith Davis3201eea2019-10-24 17:30:41 +01001679 for (size_t i = 0; i < 2; i++)
Matteo Martincigh657ab2d2019-09-18 10:53:24 +01001680 {
Sadik Armagan1625efc2021-06-10 18:24:34 +01001681 CHECK(category->m_Counters[category->m_Counters.size() - 2 + i] ==
Matteo Martincigh657ab2d2019-09-18 10:53:24 +01001682 counterWMultiCoreDeviceWParentCategory->m_Uid + i);
1683 }
1684
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001685 // Register a counter set for testing
1686 const std::string counterSetName = "some_counter_set";
Keith Davis3201eea2019-10-24 17:30:41 +01001687 const CounterSet* counterSet = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001688 CHECK_NOTHROW(counterSet = counterDirectory.RegisterCounterSet(counterSetName));
1689 CHECK(counterDirectory.GetCounterSetCount() == 1);
1690 CHECK(counterSet);
1691 CHECK(counterSet->m_Name == counterSetName);
1692 CHECK(counterSet->m_Uid >= 1);
1693 CHECK(counterSet->m_Count == 0);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001694
1695 // Register a counter with a valid parent category name and associated to a counter set
1696 const Counter* counterWCounterSet = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001697 CHECK_NOTHROW(counterWCounterSet = counterDirectory.RegisterCounter(
Keith Davise394bd92019-12-02 15:12:19 +00001698 armnn::profiling::BACKEND_ID, 300,
Keith Davis3201eea2019-10-24 17:30:41 +01001699 categoryName, 0, 1, 123.45f, "valid name 11", "valid description",
Jim Flynndecd08b2022-03-13 22:35:46 +00001700 arm::pipe::EmptyOptional(), // Units
Keith Davis3201eea2019-10-24 17:30:41 +01001701 0, // Number of cores
Jim Flynndecd08b2022-03-13 22:35:46 +00001702 arm::pipe::EmptyOptional(), // Device UID
Keith Davis3201eea2019-10-24 17:30:41 +01001703 counterSet->m_Uid)); // Counter set UID
Sadik Armagan1625efc2021-06-10 18:24:34 +01001704 CHECK(counterDirectory.GetCounterCount() == 27);
1705 CHECK(counterWCounterSet);
1706 CHECK(counterWCounterSet->m_Uid > counter->m_Uid);
1707 CHECK(counterWCounterSet->m_MaxCounterUid == counterWCounterSet->m_Uid);
1708 CHECK(counterWCounterSet->m_Class == 0);
1709 CHECK(counterWCounterSet->m_Interpolation == 1);
1710 CHECK(counterWCounterSet->m_Multiplier == 123.45f);
1711 CHECK(counterWCounterSet->m_Name == "valid name 11");
1712 CHECK(counterWCounterSet->m_Description == "valid description");
1713 CHECK(counterWCounterSet->m_Units == "");
1714 CHECK(counterWCounterSet->m_DeviceUid == 0);
1715 CHECK(counterWCounterSet->m_CounterSetUid == counterSet->m_Uid);
1716 CHECK(category->m_Counters.size() == 27);
1717 CHECK(category->m_Counters.back() == counterWCounterSet->m_Uid);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001718
1719 // Register a counter with a valid parent category name and associated to a device and a counter set
1720 const Counter* counterWDeviceWCounterSet = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001721 CHECK_NOTHROW(counterWDeviceWCounterSet = counterDirectory.RegisterCounter(
Keith Davise394bd92019-12-02 15:12:19 +00001722 armnn::profiling::BACKEND_ID, 23,
Keith Davis3201eea2019-10-24 17:30:41 +01001723 categoryName, 0, 1, 123.45f, "valid name 12", "valid description",
Jim Flynndecd08b2022-03-13 22:35:46 +00001724 arm::pipe::EmptyOptional(), // Units
Keith Davis3201eea2019-10-24 17:30:41 +01001725 1, // Number of cores
1726 device->m_Uid, // Device UID
1727 counterSet->m_Uid)); // Counter set UID
Sadik Armagan1625efc2021-06-10 18:24:34 +01001728 CHECK(counterDirectory.GetCounterCount() == 28);
1729 CHECK(counterWDeviceWCounterSet);
1730 CHECK(counterWDeviceWCounterSet->m_Uid > counter->m_Uid);
1731 CHECK(counterWDeviceWCounterSet->m_MaxCounterUid == counterWDeviceWCounterSet->m_Uid);
1732 CHECK(counterWDeviceWCounterSet->m_Class == 0);
1733 CHECK(counterWDeviceWCounterSet->m_Interpolation == 1);
1734 CHECK(counterWDeviceWCounterSet->m_Multiplier == 123.45f);
1735 CHECK(counterWDeviceWCounterSet->m_Name == "valid name 12");
1736 CHECK(counterWDeviceWCounterSet->m_Description == "valid description");
1737 CHECK(counterWDeviceWCounterSet->m_Units == "");
1738 CHECK(counterWDeviceWCounterSet->m_DeviceUid == device->m_Uid);
1739 CHECK(counterWDeviceWCounterSet->m_CounterSetUid == counterSet->m_Uid);
1740 CHECK(category->m_Counters.size() == 28);
1741 CHECK(category->m_Counters.back() == counterWDeviceWCounterSet->m_Uid);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001742
1743 // Register another category for testing
1744 const std::string anotherCategoryName = "some_other_category";
Keith Davis3201eea2019-10-24 17:30:41 +01001745 const Category* anotherCategory = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001746 CHECK_NOTHROW(anotherCategory = counterDirectory.RegisterCategory(anotherCategoryName));
1747 CHECK(counterDirectory.GetCategoryCount() == 2);
1748 CHECK(anotherCategory);
1749 CHECK(anotherCategory != category);
1750 CHECK(anotherCategory->m_Name == anotherCategoryName);
1751 CHECK(anotherCategory->m_Counters.empty());
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001752
1753 // Register a counter to the other category
1754 const Counter* anotherCounter = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001755 CHECK_NOTHROW(anotherCounter = counterDirectory.RegisterCounter(armnn::profiling::BACKEND_ID, 24,
Cathal Corbett5aa9fd72022-02-25 15:33:28 +00001756 anotherCategoryName, 1, 0, .00043f,
1757 "valid name", "valid description",
Jim Flynndecd08b2022-03-13 22:35:46 +00001758 arm::pipe::EmptyOptional(), // Units
1759 arm::pipe::EmptyOptional(), // Number of cores
Cathal Corbett5aa9fd72022-02-25 15:33:28 +00001760 device->m_Uid, // Device UID
1761 counterSet->m_Uid)); // Counter set UID
Sadik Armagan1625efc2021-06-10 18:24:34 +01001762 CHECK(counterDirectory.GetCounterCount() == 29);
1763 CHECK(anotherCounter);
1764 CHECK(anotherCounter->m_MaxCounterUid == anotherCounter->m_Uid);
1765 CHECK(anotherCounter->m_Class == 1);
1766 CHECK(anotherCounter->m_Interpolation == 0);
1767 CHECK(anotherCounter->m_Multiplier == .00043f);
1768 CHECK(anotherCounter->m_Name == "valid name");
1769 CHECK(anotherCounter->m_Description == "valid description");
1770 CHECK(anotherCounter->m_Units == "");
1771 CHECK(anotherCounter->m_DeviceUid == device->m_Uid);
1772 CHECK(anotherCounter->m_CounterSetUid == counterSet->m_Uid);
1773 CHECK(anotherCategory->m_Counters.size() == 1);
1774 CHECK(anotherCategory->m_Counters.back() == anotherCounter->m_Uid);
Matteo Martincighab173e92019-09-05 12:02:04 +01001775}
1776
Sadik Armagan1625efc2021-06-10 18:24:34 +01001777TEST_CASE("CounterSelectionCommandHandlerParseData")
Ferran Balaguer1b941722019-08-28 16:57:18 +01001778{
Matteo Martincigh5d737fb2019-10-07 13:05:13 +01001779 ProfilingStateMachine profilingStateMachine;
1780
Ferran Balaguer1b941722019-08-28 16:57:18 +01001781 class TestCaptureThread : public IPeriodicCounterCapture
1782 {
Keith Davis3201eea2019-10-24 17:30:41 +01001783 void Start() override
1784 {}
1785 void Stop() override
1786 {}
Ferran Balaguer1b941722019-08-28 16:57:18 +01001787 };
1788
Matteo Martincighe8485382019-10-10 14:08:21 +01001789 class TestReadCounterValues : public IReadCounterValues
1790 {
Keith Davis3201eea2019-10-24 17:30:41 +01001791 bool IsCounterRegistered(uint16_t counterUid) const override
1792 {
Jim Flynn9265a882022-03-10 23:35:26 +00001793 arm::pipe::IgnoreUnused(counterUid);
Keith Davis3201eea2019-10-24 17:30:41 +01001794 return true;
1795 }
Jim Flynn34430252022-03-04 15:03:58 +00001796 bool IsCounterRegistered(const std::string& counterName) const override
1797 {
Jim Flynn9265a882022-03-10 23:35:26 +00001798 arm::pipe::IgnoreUnused(counterName);
Jim Flynn34430252022-03-04 15:03:58 +00001799 return true;
1800 }
Keith Davis3201eea2019-10-24 17:30:41 +01001801 uint16_t GetCounterCount() const override
1802 {
1803 return 0;
1804 }
Finn Williamsf3fcf322020-05-11 14:38:02 +01001805 uint32_t GetAbsoluteCounterValue(uint16_t counterUid) const override
1806 {
Jim Flynn9265a882022-03-10 23:35:26 +00001807 arm::pipe::IgnoreUnused(counterUid);
Finn Williamsf3fcf322020-05-11 14:38:02 +01001808 return 0;
1809 }
1810 uint32_t GetDeltaCounterValue(uint16_t counterUid) override
Keith Davis3201eea2019-10-24 17:30:41 +01001811 {
Jim Flynn9265a882022-03-10 23:35:26 +00001812 arm::pipe::IgnoreUnused(counterUid);
Keith Davis3201eea2019-10-24 17:30:41 +01001813 return 0;
1814 }
Matteo Martincighe8485382019-10-10 14:08:21 +01001815 };
Jim Flynn397043f2019-10-17 17:37:10 +01001816 const uint32_t familyId = 0;
Ferran Balaguer1b941722019-08-28 16:57:18 +01001817 const uint32_t packetId = 0x40000;
1818
1819 uint32_t version = 1;
Cathal Corbett6f073722022-03-04 12:11:09 +00001820 const std::unordered_map<std::string,
Cathal Corbett5aa9fd72022-02-25 15:33:28 +00001821 std::shared_ptr<IBackendProfilingContext>> backendProfilingContext;
Finn Williams032bc742020-02-12 11:02:34 +00001822 CounterIdMap counterIdMap;
Ferran Balaguer1b941722019-08-28 16:57:18 +01001823 Holder holder;
1824 TestCaptureThread captureThread;
Matteo Martincighe8485382019-10-10 14:08:21 +01001825 TestReadCounterValues readCounterValues;
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01001826 MockBufferManager mockBuffer(512);
Jim Flynn9c85b412022-03-16 00:27:43 +00001827 SendCounterPacket sendCounterPacket(mockBuffer,
1828 arm::pipe::ARMNN_SOFTWARE_INFO,
1829 arm::pipe::ARMNN_SOFTWARE_VERSION,
1830 arm::pipe::ARMNN_HARDWARE_VERSION);
Sadik Armagan3896b472020-02-10 12:24:15 +00001831 SendThread sendThread(profilingStateMachine, mockBuffer, sendCounterPacket);
Ferran Balaguer1b941722019-08-28 16:57:18 +01001832
Jim Flynn75c14f42022-03-10 22:05:42 +00001833 uint32_t sizeOfUint32 = arm::pipe::numeric_cast<uint32_t>(sizeof(uint32_t));
1834 uint32_t sizeOfUint16 = arm::pipe::numeric_cast<uint32_t>(sizeof(uint16_t));
Ferran Balaguer1b941722019-08-28 16:57:18 +01001835
1836 // Data with period and counters
Jim Flynn4c9ed1d2022-01-23 23:57:20 +00001837 uint32_t period1 = arm::pipe::LOWEST_CAPTURE_PERIOD;
Ferran Balaguer1b941722019-08-28 16:57:18 +01001838 uint32_t dataLength1 = 8;
Keith Davis3201eea2019-10-24 17:30:41 +01001839 uint32_t offset = 0;
Ferran Balaguer1b941722019-08-28 16:57:18 +01001840
Matteo Martincigh67ef2a52019-10-10 13:29:02 +01001841 std::unique_ptr<unsigned char[]> uniqueData1 = std::make_unique<unsigned char[]>(dataLength1);
Keith Davis3201eea2019-10-24 17:30:41 +01001842 unsigned char* data1 = reinterpret_cast<unsigned char*>(uniqueData1.get());
FinnWilliamsArma0c78712019-09-16 12:06:47 +01001843
Ferran Balaguer1b941722019-08-28 16:57:18 +01001844 WriteUint32(data1, offset, period1);
1845 offset += sizeOfUint32;
1846 WriteUint16(data1, offset, 4000);
1847 offset += sizeOfUint16;
1848 WriteUint16(data1, offset, 5000);
1849
Jim Flynnbbfe6032020-07-20 16:57:44 +01001850 arm::pipe::Packet packetA(packetId, dataLength1, uniqueData1);
Ferran Balaguer1b941722019-08-28 16:57:18 +01001851
Finn Williams032bc742020-02-12 11:02:34 +00001852 PeriodicCounterSelectionCommandHandler commandHandler(familyId, packetId, version, backendProfilingContext,
1853 counterIdMap, holder, 10000u, captureThread,
Keith Davis3201eea2019-10-24 17:30:41 +01001854 readCounterValues, sendCounterPacket, profilingStateMachine);
Ferran Balaguer1b941722019-08-28 16:57:18 +01001855
Matteo Martincighe8485382019-10-10 14:08:21 +01001856 profilingStateMachine.TransitionToState(ProfilingState::Uninitialised);
Jim Flynnf9db3ef2022-03-08 21:23:44 +00001857 CHECK_THROWS_AS(commandHandler(packetA), arm::pipe::ProfilingException);
Matteo Martincighe8485382019-10-10 14:08:21 +01001858 profilingStateMachine.TransitionToState(ProfilingState::NotConnected);
Jim Flynnf9db3ef2022-03-08 21:23:44 +00001859 CHECK_THROWS_AS(commandHandler(packetA), arm::pipe::ProfilingException);
Matteo Martincighe8485382019-10-10 14:08:21 +01001860 profilingStateMachine.TransitionToState(ProfilingState::WaitingForAck);
Jim Flynnf9db3ef2022-03-08 21:23:44 +00001861 CHECK_THROWS_AS(commandHandler(packetA), arm::pipe::ProfilingException);
Matteo Martincighe8485382019-10-10 14:08:21 +01001862 profilingStateMachine.TransitionToState(ProfilingState::Active);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001863 CHECK_NOTHROW(commandHandler(packetA));
Matteo Martincighe8485382019-10-10 14:08:21 +01001864
1865 const std::vector<uint16_t> counterIdsA = holder.GetCaptureData().GetCounterIds();
Ferran Balaguer1b941722019-08-28 16:57:18 +01001866
Sadik Armagan1625efc2021-06-10 18:24:34 +01001867 CHECK(holder.GetCaptureData().GetCapturePeriod() == period1);
1868 CHECK(counterIdsA.size() == 2);
1869 CHECK(counterIdsA[0] == 4000);
1870 CHECK(counterIdsA[1] == 5000);
Ferran Balaguer1b941722019-08-28 16:57:18 +01001871
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01001872 auto readBuffer = mockBuffer.GetReadableBuffer();
Ferran Balaguer1b941722019-08-28 16:57:18 +01001873
1874 offset = 0;
1875
1876 uint32_t headerWord0 = ReadUint32(readBuffer, offset);
1877 offset += sizeOfUint32;
1878 uint32_t headerWord1 = ReadUint32(readBuffer, offset);
1879 offset += sizeOfUint32;
1880 uint32_t period = ReadUint32(readBuffer, offset);
1881
Sadik Armagan1625efc2021-06-10 18:24:34 +01001882 CHECK(((headerWord0 >> 26) & 0x3F) == 0); // packet family
1883 CHECK(((headerWord0 >> 16) & 0x3FF) == 4); // packet id
1884 CHECK(headerWord1 == 8); // data length
Jim Flynn4c9ed1d2022-01-23 23:57:20 +00001885 CHECK(period == arm::pipe::LOWEST_CAPTURE_PERIOD); // capture period
Ferran Balaguer1b941722019-08-28 16:57:18 +01001886
1887 uint16_t counterId = 0;
1888 offset += sizeOfUint32;
1889 counterId = ReadUint16(readBuffer, offset);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001890 CHECK(counterId == 4000);
Ferran Balaguer1b941722019-08-28 16:57:18 +01001891 offset += sizeOfUint16;
1892 counterId = ReadUint16(readBuffer, offset);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001893 CHECK(counterId == 5000);
Ferran Balaguer1b941722019-08-28 16:57:18 +01001894
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01001895 mockBuffer.MarkRead(readBuffer);
1896
Ferran Balaguer1b941722019-08-28 16:57:18 +01001897 // Data with period only
Colm Donelan02705242019-11-14 14:19:07 +00001898 uint32_t period2 = 9000; // We'll specify a value below LOWEST_CAPTURE_PERIOD. It should be pulled upwards.
Ferran Balaguer1b941722019-08-28 16:57:18 +01001899 uint32_t dataLength2 = 4;
Ferran Balaguer1b941722019-08-28 16:57:18 +01001900
Matteo Martincigh67ef2a52019-10-10 13:29:02 +01001901 std::unique_ptr<unsigned char[]> uniqueData2 = std::make_unique<unsigned char[]>(dataLength2);
Ferran Balaguer1b941722019-08-28 16:57:18 +01001902
FinnWilliamsArma0c78712019-09-16 12:06:47 +01001903 WriteUint32(reinterpret_cast<unsigned char*>(uniqueData2.get()), 0, period2);
1904
Jim Flynnbbfe6032020-07-20 16:57:44 +01001905 arm::pipe::Packet packetB(packetId, dataLength2, uniqueData2);
Ferran Balaguer1b941722019-08-28 16:57:18 +01001906
1907 commandHandler(packetB);
1908
Matteo Martincighe8485382019-10-10 14:08:21 +01001909 const std::vector<uint16_t> counterIdsB = holder.GetCaptureData().GetCounterIds();
Ferran Balaguer1b941722019-08-28 16:57:18 +01001910
Colm Donelan02705242019-11-14 14:19:07 +00001911 // Value should have been pulled up from 9000 to LOWEST_CAPTURE_PERIOD.
Jim Flynn4c9ed1d2022-01-23 23:57:20 +00001912 CHECK(holder.GetCaptureData().GetCapturePeriod() == arm::pipe::LOWEST_CAPTURE_PERIOD);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001913 CHECK(counterIdsB.size() == 0);
Ferran Balaguer1b941722019-08-28 16:57:18 +01001914
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01001915 readBuffer = mockBuffer.GetReadableBuffer();
Ferran Balaguer1b941722019-08-28 16:57:18 +01001916
1917 offset = 0;
1918
1919 headerWord0 = ReadUint32(readBuffer, offset);
1920 offset += sizeOfUint32;
1921 headerWord1 = ReadUint32(readBuffer, offset);
1922 offset += sizeOfUint32;
1923 period = ReadUint32(readBuffer, offset);
1924
Jim Flynn4c9ed1d2022-01-23 23:57:20 +00001925 CHECK(((headerWord0 >> 26) & 0x3F) == 0); // packet family
1926 CHECK(((headerWord0 >> 16) & 0x3FF) == 4); // packet id
1927 CHECK(headerWord1 == 4); // data length
1928 CHECK(period == arm::pipe::LOWEST_CAPTURE_PERIOD); // capture period
Ferran Balaguer1b941722019-08-28 16:57:18 +01001929}
1930
Sadik Armagan1625efc2021-06-10 18:24:34 +01001931TEST_CASE("CheckTimelineActivationAndDeactivation")
Keith Davis33ed2212020-03-30 10:43:41 +01001932{
1933 class TestReportStructure : public IReportStructure
1934 {
1935 public:
Jim Flynn9c85b412022-03-16 00:27:43 +00001936 virtual void ReportStructure(arm::pipe::IProfilingService& profilingService) override
Keith Davis33ed2212020-03-30 10:43:41 +01001937 {
Jim Flynn9c85b412022-03-16 00:27:43 +00001938 arm::pipe::IgnoreUnused(profilingService);
Keith Davis33ed2212020-03-30 10:43:41 +01001939 m_ReportStructureCalled = true;
1940 }
1941
1942 bool m_ReportStructureCalled = false;
1943 };
1944
1945 class TestNotifyBackends : public INotifyBackends
1946 {
1947 public:
1948 TestNotifyBackends() : m_timelineReporting(false) {}
1949 virtual void NotifyBackendsForTimelineReporting() override
1950 {
1951 m_TestNotifyBackendsCalled = m_timelineReporting.load();
1952 }
1953
1954 bool m_TestNotifyBackendsCalled = false;
1955 std::atomic<bool> m_timelineReporting;
1956 };
1957
Jim Flynnbbfe6032020-07-20 16:57:44 +01001958 arm::pipe::PacketVersionResolver packetVersionResolver;
Keith Davis33ed2212020-03-30 10:43:41 +01001959
1960 BufferManager bufferManager(512);
1961 SendTimelinePacket sendTimelinePacket(bufferManager);
1962 ProfilingStateMachine stateMachine;
1963 TestReportStructure testReportStructure;
1964 TestNotifyBackends testNotifyBackends;
Jim Flynn9c85b412022-03-16 00:27:43 +00001965 armnn::ArmNNProfilingServiceInitialiser initialiser;
1966 ProfilingService profilingService(arm::pipe::MAX_ARMNN_COUNTER,
1967 initialiser,
1968 arm::pipe::ARMNN_SOFTWARE_INFO,
1969 arm::pipe::ARMNN_SOFTWARE_VERSION,
1970 arm::pipe::ARMNN_HARDWARE_VERSION);
1971
Keith Davis33ed2212020-03-30 10:43:41 +01001972
Cathal Corbett5aa9fd72022-02-25 15:33:28 +00001973 ActivateTimelineReportingCommandHandler activateTimelineReportingCommandHandler(0,
Keith Davis33ed2212020-03-30 10:43:41 +01001974 6,
1975 packetVersionResolver.ResolvePacketVersion(0, 6)
1976 .GetEncodedValue(),
1977 sendTimelinePacket,
1978 stateMachine,
1979 testReportStructure,
1980 testNotifyBackends.m_timelineReporting,
Jim Flynn9c85b412022-03-16 00:27:43 +00001981 testNotifyBackends,
1982 profilingService);
Keith Davis33ed2212020-03-30 10:43:41 +01001983
1984 // Write an "ActivateTimelineReporting" packet into the mock profiling connection, to simulate an input from an
1985 // external profiling service
1986 const uint32_t packetFamily1 = 0;
1987 const uint32_t packetId1 = 6;
1988 uint32_t packetHeader1 = ConstructHeader(packetFamily1, packetId1);
1989
1990 // Create the ActivateTimelineReportingPacket
Jim Flynnbbfe6032020-07-20 16:57:44 +01001991 arm::pipe::Packet ActivateTimelineReportingPacket(packetHeader1); // Length == 0
Keith Davis33ed2212020-03-30 10:43:41 +01001992
Sadik Armagan1625efc2021-06-10 18:24:34 +01001993 CHECK_THROWS_AS(
Jim Flynnf9db3ef2022-03-08 21:23:44 +00001994 activateTimelineReportingCommandHandler.operator()(ActivateTimelineReportingPacket),
1995 arm::pipe::ProfilingException);
Keith Davis33ed2212020-03-30 10:43:41 +01001996
1997 stateMachine.TransitionToState(ProfilingState::NotConnected);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001998 CHECK_THROWS_AS(
Jim Flynnf9db3ef2022-03-08 21:23:44 +00001999 activateTimelineReportingCommandHandler.operator()(ActivateTimelineReportingPacket),
2000 arm::pipe::ProfilingException);
Keith Davis33ed2212020-03-30 10:43:41 +01002001
2002 stateMachine.TransitionToState(ProfilingState::WaitingForAck);
Sadik Armagan1625efc2021-06-10 18:24:34 +01002003 CHECK_THROWS_AS(
Jim Flynnf9db3ef2022-03-08 21:23:44 +00002004 activateTimelineReportingCommandHandler.operator()(ActivateTimelineReportingPacket),
2005 arm::pipe::ProfilingException);
Keith Davis33ed2212020-03-30 10:43:41 +01002006
2007 stateMachine.TransitionToState(ProfilingState::Active);
2008 activateTimelineReportingCommandHandler.operator()(ActivateTimelineReportingPacket);
2009
Sadik Armagan1625efc2021-06-10 18:24:34 +01002010 CHECK(testReportStructure.m_ReportStructureCalled);
2011 CHECK(testNotifyBackends.m_TestNotifyBackendsCalled);
2012 CHECK(testNotifyBackends.m_timelineReporting.load());
Keith Davis33ed2212020-03-30 10:43:41 +01002013
2014 DeactivateTimelineReportingCommandHandler deactivateTimelineReportingCommandHandler(0,
2015 7,
2016 packetVersionResolver.ResolvePacketVersion(0, 7).GetEncodedValue(),
2017 testNotifyBackends.m_timelineReporting,
2018 stateMachine,
2019 testNotifyBackends);
2020
2021 const uint32_t packetFamily2 = 0;
2022 const uint32_t packetId2 = 7;
2023 uint32_t packetHeader2 = ConstructHeader(packetFamily2, packetId2);
2024
2025 // Create the DeactivateTimelineReportingPacket
Jim Flynnbbfe6032020-07-20 16:57:44 +01002026 arm::pipe::Packet deactivateTimelineReportingPacket(packetHeader2); // Length == 0
Keith Davis33ed2212020-03-30 10:43:41 +01002027
2028 stateMachine.Reset();
Sadik Armagan1625efc2021-06-10 18:24:34 +01002029 CHECK_THROWS_AS(
Jim Flynnf9db3ef2022-03-08 21:23:44 +00002030 deactivateTimelineReportingCommandHandler.operator()(deactivateTimelineReportingPacket),
2031 arm::pipe::ProfilingException);
Keith Davis33ed2212020-03-30 10:43:41 +01002032
2033 stateMachine.TransitionToState(ProfilingState::NotConnected);
Sadik Armagan1625efc2021-06-10 18:24:34 +01002034 CHECK_THROWS_AS(
Jim Flynnf9db3ef2022-03-08 21:23:44 +00002035 deactivateTimelineReportingCommandHandler.operator()(deactivateTimelineReportingPacket),
2036 arm::pipe::ProfilingException);
Keith Davis33ed2212020-03-30 10:43:41 +01002037
2038 stateMachine.TransitionToState(ProfilingState::WaitingForAck);
Sadik Armagan1625efc2021-06-10 18:24:34 +01002039 CHECK_THROWS_AS(
Jim Flynnf9db3ef2022-03-08 21:23:44 +00002040 deactivateTimelineReportingCommandHandler.operator()(deactivateTimelineReportingPacket),
2041 arm::pipe::ProfilingException);
Keith Davis33ed2212020-03-30 10:43:41 +01002042
2043 stateMachine.TransitionToState(ProfilingState::Active);
2044 deactivateTimelineReportingCommandHandler.operator()(deactivateTimelineReportingPacket);
2045
Sadik Armagan1625efc2021-06-10 18:24:34 +01002046 CHECK(!testNotifyBackends.m_TestNotifyBackendsCalled);
2047 CHECK(!testNotifyBackends.m_timelineReporting.load());
Keith Davis33ed2212020-03-30 10:43:41 +01002048}
2049
Sadik Armagan1625efc2021-06-10 18:24:34 +01002050TEST_CASE("CheckProfilingServiceNotActive")
Keith Davis33ed2212020-03-30 10:43:41 +01002051{
2052 using namespace armnn;
Keith Davis33ed2212020-03-30 10:43:41 +01002053
2054 // Create runtime in which the test will run
2055 armnn::IRuntime::CreationOptions options;
2056 options.m_ProfilingOptions.m_EnableProfiling = true;
2057
Kevin Mayd92a6e42021-02-04 10:27:41 +00002058 armnn::RuntimeImpl runtime(options);
Jim Flynn34430252022-03-04 15:03:58 +00002059 armnn::ArmNNProfilingServiceInitialiser initialiser;
2060 ProfilingServiceRuntimeHelper profilingServiceHelper(
2061 arm::pipe::MAX_ARMNN_COUNTER, initialiser, GetProfilingService(&runtime));
Keith Davis33ed2212020-03-30 10:43:41 +01002062 profilingServiceHelper.ForceTransitionToState(ProfilingState::NotConnected);
2063 profilingServiceHelper.ForceTransitionToState(ProfilingState::WaitingForAck);
2064 profilingServiceHelper.ForceTransitionToState(ProfilingState::Active);
2065
Cathal Corbett5aa9fd72022-02-25 15:33:28 +00002066 BufferManager& bufferManager = profilingServiceHelper.GetProfilingBufferManager();
Keith Davis33ed2212020-03-30 10:43:41 +01002067 auto readableBuffer = bufferManager.GetReadableBuffer();
2068
2069 // Profiling is enabled, the post-optimisation structure should be created
Sadik Armagan1625efc2021-06-10 18:24:34 +01002070 CHECK(readableBuffer == nullptr);
Keith Davis33ed2212020-03-30 10:43:41 +01002071}
2072
Sadik Armagan1625efc2021-06-10 18:24:34 +01002073TEST_CASE("CheckConnectionAcknowledged")
Sadik Armaganb5f01b22019-09-18 17:29:00 +01002074{
Keith Davis3201eea2019-10-24 17:30:41 +01002075 const uint32_t packetFamilyId = 0;
Sadik Armaganb5f01b22019-09-18 17:29:00 +01002076 const uint32_t connectionPacketId = 0x10000;
Keith Davis3201eea2019-10-24 17:30:41 +01002077 const uint32_t version = 1;
Sadik Armaganb5f01b22019-09-18 17:29:00 +01002078
Jim Flynn75c14f42022-03-10 22:05:42 +00002079 uint32_t sizeOfUint32 = arm::pipe::numeric_cast<uint32_t>(sizeof(uint32_t));
2080 uint32_t sizeOfUint16 = arm::pipe::numeric_cast<uint32_t>(sizeof(uint16_t));
Sadik Armaganb5f01b22019-09-18 17:29:00 +01002081
2082 // Data with period and counters
Keith Davis3201eea2019-10-24 17:30:41 +01002083 uint32_t period1 = 10;
Sadik Armaganb5f01b22019-09-18 17:29:00 +01002084 uint32_t dataLength1 = 8;
Keith Davis3201eea2019-10-24 17:30:41 +01002085 uint32_t offset = 0;
Sadik Armaganb5f01b22019-09-18 17:29:00 +01002086
Matteo Martincigh67ef2a52019-10-10 13:29:02 +01002087 std::unique_ptr<unsigned char[]> uniqueData1 = std::make_unique<unsigned char[]>(dataLength1);
Keith Davis3201eea2019-10-24 17:30:41 +01002088 unsigned char* data1 = reinterpret_cast<unsigned char*>(uniqueData1.get());
Sadik Armaganb5f01b22019-09-18 17:29:00 +01002089
2090 WriteUint32(data1, offset, period1);
2091 offset += sizeOfUint32;
2092 WriteUint16(data1, offset, 4000);
2093 offset += sizeOfUint16;
2094 WriteUint16(data1, offset, 5000);
2095
Jim Flynnbbfe6032020-07-20 16:57:44 +01002096 arm::pipe::Packet packetA(connectionPacketId, dataLength1, uniqueData1);
Sadik Armaganb5f01b22019-09-18 17:29:00 +01002097
2098 ProfilingStateMachine profilingState(ProfilingState::Uninitialised);
Sadik Armagan1625efc2021-06-10 18:24:34 +01002099 CHECK(profilingState.GetCurrentState() == ProfilingState::Uninitialised);
Keith Davis3201eea2019-10-24 17:30:41 +01002100 CounterDirectory counterDirectory;
2101 MockBufferManager mockBuffer(1024);
Jim Flynn9c85b412022-03-16 00:27:43 +00002102 SendCounterPacket sendCounterPacket(mockBuffer,
2103 arm::pipe::ARMNN_SOFTWARE_INFO,
2104 arm::pipe::ARMNN_SOFTWARE_VERSION,
2105 arm::pipe::ARMNN_HARDWARE_VERSION);
Sadik Armagan3896b472020-02-10 12:24:15 +00002106 SendThread sendThread(profilingState, mockBuffer, sendCounterPacket);
Matteo Martincighcdfb9412019-11-08 11:23:06 +00002107 SendTimelinePacket sendTimelinePacket(mockBuffer);
Jim Flynn6398a982020-05-27 17:05:21 +01002108 MockProfilingServiceStatus mockProfilingServiceStatus;
Sadik Armaganb5f01b22019-09-18 17:29:00 +01002109
Jim Flynn6398a982020-05-27 17:05:21 +01002110 ConnectionAcknowledgedCommandHandler commandHandler(packetFamilyId,
2111 connectionPacketId,
2112 version,
2113 counterDirectory,
2114 sendCounterPacket,
2115 sendTimelinePacket,
2116 profilingState,
2117 mockProfilingServiceStatus);
Sadik Armaganb5f01b22019-09-18 17:29:00 +01002118
2119 // command handler received packet on ProfilingState::Uninitialised
Jim Flynnf9db3ef2022-03-08 21:23:44 +00002120 CHECK_THROWS_AS(commandHandler(packetA), arm::pipe::ProfilingException);
Sadik Armaganb5f01b22019-09-18 17:29:00 +01002121
2122 profilingState.TransitionToState(ProfilingState::NotConnected);
Sadik Armagan1625efc2021-06-10 18:24:34 +01002123 CHECK(profilingState.GetCurrentState() == ProfilingState::NotConnected);
Sadik Armaganb5f01b22019-09-18 17:29:00 +01002124 // command handler received packet on ProfilingState::NotConnected
Jim Flynnf9db3ef2022-03-08 21:23:44 +00002125 CHECK_THROWS_AS(commandHandler(packetA), arm::pipe::ProfilingException);
Sadik Armaganb5f01b22019-09-18 17:29:00 +01002126
2127 profilingState.TransitionToState(ProfilingState::WaitingForAck);
Sadik Armagan1625efc2021-06-10 18:24:34 +01002128 CHECK(profilingState.GetCurrentState() == ProfilingState::WaitingForAck);
Sadik Armaganb5f01b22019-09-18 17:29:00 +01002129 // command handler received packet on ProfilingState::WaitingForAck
Sadik Armagan1625efc2021-06-10 18:24:34 +01002130 CHECK_NOTHROW(commandHandler(packetA));
2131 CHECK(profilingState.GetCurrentState() == ProfilingState::Active);
Sadik Armaganb5f01b22019-09-18 17:29:00 +01002132
2133 // command handler received packet on ProfilingState::Active
Sadik Armagan1625efc2021-06-10 18:24:34 +01002134 CHECK_NOTHROW(commandHandler(packetA));
2135 CHECK(profilingState.GetCurrentState() == ProfilingState::Active);
Sadik Armaganb5f01b22019-09-18 17:29:00 +01002136
2137 // command handler received different packet
2138 const uint32_t differentPacketId = 0x40000;
Jim Flynnbbfe6032020-07-20 16:57:44 +01002139 arm::pipe::Packet packetB(differentPacketId, dataLength1, uniqueData1);
Matteo Martincighd0613b52019-10-09 16:47:04 +01002140 profilingState.TransitionToState(ProfilingState::NotConnected);
2141 profilingState.TransitionToState(ProfilingState::WaitingForAck);
Jim Flynn6398a982020-05-27 17:05:21 +01002142 ConnectionAcknowledgedCommandHandler differentCommandHandler(packetFamilyId,
2143 differentPacketId,
2144 version,
2145 counterDirectory,
2146 sendCounterPacket,
2147 sendTimelinePacket,
2148 profilingState,
2149 mockProfilingServiceStatus);
Jim Flynnf9db3ef2022-03-08 21:23:44 +00002150 CHECK_THROWS_AS(differentCommandHandler(packetB), arm::pipe::ProfilingException);
Sadik Armaganb5f01b22019-09-18 17:29:00 +01002151}
2152
Sadik Armagan1625efc2021-06-10 18:24:34 +01002153TEST_CASE("CheckSocketConnectionException")
Teresa Charlin9bab4962019-09-06 12:28:35 +01002154{
Sadik Armagana97a0be2020-03-03 10:44:56 +00002155 // Check that creating a SocketProfilingConnection armnnProfiling in an exception as the Gator UDS doesn't exist.
Sadik Armagan1625efc2021-06-10 18:24:34 +01002156 CHECK_THROWS_AS(new SocketProfilingConnection(), arm::pipe::SocketConnectionException);
Sadik Armagana97a0be2020-03-03 10:44:56 +00002157}
2158
Sadik Armagan1625efc2021-06-10 18:24:34 +01002159TEST_CASE("CheckSocketConnectionException2")
Sadik Armagana97a0be2020-03-03 10:44:56 +00002160{
2161 try
2162 {
2163 new SocketProfilingConnection();
2164 }
Jim Flynnbbfe6032020-07-20 16:57:44 +01002165 catch (const arm::pipe::SocketConnectionException& ex)
Sadik Armagana97a0be2020-03-03 10:44:56 +00002166 {
Sadik Armagan1625efc2021-06-10 18:24:34 +01002167 CHECK(ex.GetSocketFd() == 0);
2168 CHECK(ex.GetErrorNo() == ECONNREFUSED);
2169 CHECK(ex.what()
Sadik Armagana97a0be2020-03-03 10:44:56 +00002170 == std::string("SocketProfilingConnection: Cannot connect to stream socket: Connection refused"));
2171 }
Teresa Charlin9bab4962019-09-06 12:28:35 +01002172}
2173
Sadik Armagan1625efc2021-06-10 18:24:34 +01002174TEST_CASE("SwTraceIsValidCharTest")
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01002175{
2176 // Only ASCII 7-bit encoding supported
2177 for (unsigned char c = 0; c < 128; c++)
2178 {
Sadik Armagan1625efc2021-06-10 18:24:34 +01002179 CHECK(arm::pipe::SwTraceCharPolicy::IsValidChar(c));
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01002180 }
2181
2182 // Not ASCII
2183 for (unsigned char c = 255; c >= 128; c++)
2184 {
Sadik Armagan1625efc2021-06-10 18:24:34 +01002185 CHECK(!arm::pipe::SwTraceCharPolicy::IsValidChar(c));
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01002186 }
2187}
2188
Sadik Armagan1625efc2021-06-10 18:24:34 +01002189TEST_CASE("SwTraceIsValidNameCharTest")
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01002190{
2191 // Only alpha-numeric and underscore ASCII 7-bit encoding supported
2192 const unsigned char validChars[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_";
2193 for (unsigned char i = 0; i < sizeof(validChars) / sizeof(validChars[0]) - 1; i++)
2194 {
Sadik Armagan1625efc2021-06-10 18:24:34 +01002195 CHECK(arm::pipe::SwTraceNameCharPolicy::IsValidChar(validChars[i]));
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01002196 }
2197
2198 // Non alpha-numeric chars
2199 for (unsigned char c = 0; c < 48; c++)
2200 {
Sadik Armagan1625efc2021-06-10 18:24:34 +01002201 CHECK(!arm::pipe::SwTraceNameCharPolicy::IsValidChar(c));
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01002202 }
2203 for (unsigned char c = 58; c < 65; c++)
2204 {
Sadik Armagan1625efc2021-06-10 18:24:34 +01002205 CHECK(!arm::pipe::SwTraceNameCharPolicy::IsValidChar(c));
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01002206 }
2207 for (unsigned char c = 91; c < 95; c++)
2208 {
Sadik Armagan1625efc2021-06-10 18:24:34 +01002209 CHECK(!arm::pipe::SwTraceNameCharPolicy::IsValidChar(c));
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01002210 }
2211 for (unsigned char c = 96; c < 97; c++)
2212 {
Sadik Armagan1625efc2021-06-10 18:24:34 +01002213 CHECK(!arm::pipe::SwTraceNameCharPolicy::IsValidChar(c));
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01002214 }
2215 for (unsigned char c = 123; c < 128; c++)
2216 {
Sadik Armagan1625efc2021-06-10 18:24:34 +01002217 CHECK(!arm::pipe::SwTraceNameCharPolicy::IsValidChar(c));
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01002218 }
2219
2220 // Not ASCII
2221 for (unsigned char c = 255; c >= 128; c++)
2222 {
Sadik Armagan1625efc2021-06-10 18:24:34 +01002223 CHECK(!arm::pipe::SwTraceNameCharPolicy::IsValidChar(c));
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01002224 }
2225}
2226
Sadik Armagan1625efc2021-06-10 18:24:34 +01002227TEST_CASE("IsValidSwTraceStringTest")
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01002228{
2229 // Valid SWTrace strings
Sadik Armagan1625efc2021-06-10 18:24:34 +01002230 CHECK(arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceCharPolicy>(""));
2231 CHECK(arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceCharPolicy>("_"));
2232 CHECK(arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceCharPolicy>("0123"));
2233 CHECK(arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceCharPolicy>("valid_string"));
2234 CHECK(arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceCharPolicy>("VALID_string_456"));
2235 CHECK(arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceCharPolicy>(" "));
2236 CHECK(arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceCharPolicy>("valid string"));
2237 CHECK(arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceCharPolicy>("!$%"));
2238 CHECK(arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceCharPolicy>("valid|\\~string#123"));
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01002239
2240 // Invalid SWTrace strings
Sadik Armagan1625efc2021-06-10 18:24:34 +01002241 CHECK(!arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceCharPolicy>("€£"));
2242 CHECK(!arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceCharPolicy>("invalid‡string"));
2243 CHECK(!arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceCharPolicy>("12Ž34"));
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01002244}
2245
Sadik Armagan1625efc2021-06-10 18:24:34 +01002246TEST_CASE("IsValidSwTraceNameStringTest")
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01002247{
2248 // Valid SWTrace name strings
Sadik Armagan1625efc2021-06-10 18:24:34 +01002249 CHECK(arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceNameCharPolicy>(""));
2250 CHECK(arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceNameCharPolicy>("_"));
2251 CHECK(arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceNameCharPolicy>("0123"));
2252 CHECK(arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceNameCharPolicy>("valid_string"));
2253 CHECK(arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceNameCharPolicy>("VALID_string_456"));
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01002254
2255 // Invalid SWTrace name strings
Sadik Armagan1625efc2021-06-10 18:24:34 +01002256 CHECK(!arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceNameCharPolicy>(" "));
2257 CHECK(!arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceNameCharPolicy>("invalid string"));
2258 CHECK(!arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceNameCharPolicy>("!$%"));
2259 CHECK(!arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceNameCharPolicy>("invalid|\\~string#123"));
2260 CHECK(!arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceNameCharPolicy>("€£"));
2261 CHECK(!arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceNameCharPolicy>("invalid‡string"));
2262 CHECK(!arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceNameCharPolicy>("12Ž34"));
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01002263}
2264
2265template <typename SwTracePolicy>
2266void StringToSwTraceStringTestHelper(const std::string& testString, std::vector<uint32_t> buffer, size_t expectedSize)
2267{
2268 // Convert the test string to a SWTrace string
Sadik Armagan1625efc2021-06-10 18:24:34 +01002269 CHECK(arm::pipe::StringToSwTraceString<SwTracePolicy>(testString, buffer));
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01002270
2271 // The buffer must contain at least the length of the string
Sadik Armagan1625efc2021-06-10 18:24:34 +01002272 CHECK(!buffer.empty());
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01002273
2274 // The buffer must be of the expected size (in words)
Sadik Armagan1625efc2021-06-10 18:24:34 +01002275 CHECK(buffer.size() == expectedSize);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01002276
2277 // The first word of the byte must be the length of the string including the null-terminator
Sadik Armagan1625efc2021-06-10 18:24:34 +01002278 CHECK(buffer[0] == testString.size() + 1);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01002279
2280 // The contents of the buffer must match the test string
Sadik Armagan1625efc2021-06-10 18:24:34 +01002281 CHECK(std::memcmp(testString.data(), buffer.data() + 1, testString.size()) == 0);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01002282
2283 // The buffer must include the null-terminator at the end of the string
2284 size_t nullTerminatorIndex = sizeof(uint32_t) + testString.size();
Sadik Armagan1625efc2021-06-10 18:24:34 +01002285 CHECK(reinterpret_cast<unsigned char*>(buffer.data())[nullTerminatorIndex] == '\0');
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01002286}
2287
Sadik Armagan1625efc2021-06-10 18:24:34 +01002288TEST_CASE("StringToSwTraceStringTest")
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01002289{
2290 std::vector<uint32_t> buffer;
2291
2292 // Valid SWTrace strings (expected size in words)
Jim Flynnbbfe6032020-07-20 16:57:44 +01002293 StringToSwTraceStringTestHelper<arm::pipe::SwTraceCharPolicy>("", buffer, 2);
2294 StringToSwTraceStringTestHelper<arm::pipe::SwTraceCharPolicy>("_", buffer, 2);
2295 StringToSwTraceStringTestHelper<arm::pipe::SwTraceCharPolicy>("0123", buffer, 3);
2296 StringToSwTraceStringTestHelper<arm::pipe::SwTraceCharPolicy>("valid_string", buffer, 5);
2297 StringToSwTraceStringTestHelper<arm::pipe::SwTraceCharPolicy>("VALID_string_456", buffer, 6);
2298 StringToSwTraceStringTestHelper<arm::pipe::SwTraceCharPolicy>(" ", buffer, 2);
2299 StringToSwTraceStringTestHelper<arm::pipe::SwTraceCharPolicy>("valid string", buffer, 5);
2300 StringToSwTraceStringTestHelper<arm::pipe::SwTraceCharPolicy>("!$%", buffer, 2);
2301 StringToSwTraceStringTestHelper<arm::pipe::SwTraceCharPolicy>("valid|\\~string#123", buffer, 6);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01002302
2303 // Invalid SWTrace strings
Sadik Armagan1625efc2021-06-10 18:24:34 +01002304 CHECK(!arm::pipe::StringToSwTraceString<arm::pipe::SwTraceCharPolicy>("€£", buffer));
2305 CHECK(buffer.empty());
2306 CHECK(!arm::pipe::StringToSwTraceString<arm::pipe::SwTraceCharPolicy>("invalid‡string", buffer));
2307 CHECK(buffer.empty());
2308 CHECK(!arm::pipe::StringToSwTraceString<arm::pipe::SwTraceCharPolicy>("12Ž34", buffer));
2309 CHECK(buffer.empty());
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01002310}
2311
Sadik Armagan1625efc2021-06-10 18:24:34 +01002312TEST_CASE("StringToSwTraceNameStringTest")
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01002313{
2314 std::vector<uint32_t> buffer;
2315
2316 // Valid SWTrace namestrings (expected size in words)
Jim Flynnbbfe6032020-07-20 16:57:44 +01002317 StringToSwTraceStringTestHelper<arm::pipe::SwTraceNameCharPolicy>("", buffer, 2);
2318 StringToSwTraceStringTestHelper<arm::pipe::SwTraceNameCharPolicy>("_", buffer, 2);
2319 StringToSwTraceStringTestHelper<arm::pipe::SwTraceNameCharPolicy>("0123", buffer, 3);
2320 StringToSwTraceStringTestHelper<arm::pipe::SwTraceNameCharPolicy>("valid_string", buffer, 5);
2321 StringToSwTraceStringTestHelper<arm::pipe::SwTraceNameCharPolicy>("VALID_string_456", buffer, 6);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01002322
2323 // Invalid SWTrace namestrings
Sadik Armagan1625efc2021-06-10 18:24:34 +01002324 CHECK(!arm::pipe::StringToSwTraceString<arm::pipe::SwTraceNameCharPolicy>(" ", buffer));
2325 CHECK(buffer.empty());
2326 CHECK(!arm::pipe::StringToSwTraceString<arm::pipe::SwTraceNameCharPolicy>("invalid string", buffer));
2327 CHECK(buffer.empty());
2328 CHECK(!arm::pipe::StringToSwTraceString<arm::pipe::SwTraceNameCharPolicy>("!$%", buffer));
2329 CHECK(buffer.empty());
2330 CHECK(!arm::pipe::StringToSwTraceString<arm::pipe::SwTraceNameCharPolicy>("invalid|\\~string#123", buffer));
2331 CHECK(buffer.empty());
2332 CHECK(!arm::pipe::StringToSwTraceString<arm::pipe::SwTraceNameCharPolicy>("€£", buffer));
2333 CHECK(buffer.empty());
2334 CHECK(!arm::pipe::StringToSwTraceString<arm::pipe::SwTraceNameCharPolicy>("invalid‡string", buffer));
2335 CHECK(buffer.empty());
2336 CHECK(!arm::pipe::StringToSwTraceString<arm::pipe::SwTraceNameCharPolicy>("12Ž34", buffer));
2337 CHECK(buffer.empty());
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01002338}
2339
Sadik Armagan1625efc2021-06-10 18:24:34 +01002340TEST_CASE("CheckPeriodicCounterCaptureThread")
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002341{
Matteo Martincighe0e6efc2019-10-04 17:17:42 +01002342 class CaptureReader : public IReadCounterValues
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002343 {
2344 public:
Finn Williamsf4d59a62019-10-14 15:55:18 +01002345 CaptureReader(uint16_t counterSize)
2346 {
Keith Davis3201eea2019-10-24 17:30:41 +01002347 for (uint16_t i = 0; i < counterSize; ++i)
Finn Williamsf4d59a62019-10-14 15:55:18 +01002348 {
2349 m_Data[i] = 0;
2350 }
2351 m_CounterSize = counterSize;
2352 }
2353 //not used
Matteo Martincighe8485382019-10-10 14:08:21 +01002354 bool IsCounterRegistered(uint16_t counterUid) const override
2355 {
Jim Flynn9265a882022-03-10 23:35:26 +00002356 arm::pipe::IgnoreUnused(counterUid);
Finn Williamsf4d59a62019-10-14 15:55:18 +01002357 return false;
Matteo Martincighe8485382019-10-10 14:08:21 +01002358 }
Jim Flynn34430252022-03-04 15:03:58 +00002359 bool IsCounterRegistered(const std::string& counterName) const override
2360 {
Jim Flynn9265a882022-03-10 23:35:26 +00002361 arm::pipe::IgnoreUnused(counterName);
Jim Flynn34430252022-03-04 15:03:58 +00002362 return false;
2363 }
Matteo Martincighe0e6efc2019-10-04 17:17:42 +01002364 uint16_t GetCounterCount() const override
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002365 {
Finn Williamsf4d59a62019-10-14 15:55:18 +01002366 return m_CounterSize;
Matteo Martincighe0e6efc2019-10-04 17:17:42 +01002367 }
2368
Finn Williamsf3fcf322020-05-11 14:38:02 +01002369 uint32_t GetAbsoluteCounterValue(uint16_t counterUid) const override
2370 {
2371 if (counterUid > m_CounterSize)
2372 {
Sadik Armagan1625efc2021-06-10 18:24:34 +01002373 FAIL("Invalid counter Uid");
Finn Williamsf3fcf322020-05-11 14:38:02 +01002374 }
2375 return m_Data.at(counterUid).load();
2376 }
2377
2378 uint32_t GetDeltaCounterValue(uint16_t counterUid) override
Matteo Martincighe0e6efc2019-10-04 17:17:42 +01002379 {
Keith Davis3201eea2019-10-24 17:30:41 +01002380 if (counterUid > m_CounterSize)
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002381 {
Sadik Armagan1625efc2021-06-10 18:24:34 +01002382 FAIL("Invalid counter Uid");
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002383 }
Matteo Martincighe8485382019-10-10 14:08:21 +01002384 return m_Data.at(counterUid).load();
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002385 }
2386
Matteo Martincighe8485382019-10-10 14:08:21 +01002387 void SetCounterValue(uint16_t counterUid, uint32_t value)
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002388 {
Keith Davis3201eea2019-10-24 17:30:41 +01002389 if (counterUid > m_CounterSize)
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002390 {
Sadik Armagan1625efc2021-06-10 18:24:34 +01002391 FAIL("Invalid counter Uid");
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002392 }
Finn Williamsf4d59a62019-10-14 15:55:18 +01002393 m_Data.at(counterUid).store(value);
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002394 }
2395
2396 private:
Matteo Martincighe8485382019-10-10 14:08:21 +01002397 std::unordered_map<uint16_t, std::atomic<uint32_t>> m_Data;
Finn Williamsf4d59a62019-10-14 15:55:18 +01002398 uint16_t m_CounterSize;
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002399 };
2400
Matteo Martincigh5d737fb2019-10-07 13:05:13 +01002401 ProfilingStateMachine profilingStateMachine;
2402
Cathal Corbett6f073722022-03-04 12:11:09 +00002403 const std::unordered_map<std::string,
Cathal Corbett5aa9fd72022-02-25 15:33:28 +00002404 std::shared_ptr<IBackendProfilingContext>> backendProfilingContext;
Finn Williams032bc742020-02-12 11:02:34 +00002405 CounterIdMap counterIdMap;
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002406 Holder data;
2407 std::vector<uint16_t> captureIds1 = { 0, 1 };
2408 std::vector<uint16_t> captureIds2;
2409
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01002410 MockBufferManager mockBuffer(512);
Jim Flynn9c85b412022-03-16 00:27:43 +00002411 SendCounterPacket sendCounterPacket(mockBuffer,
2412 arm::pipe::ARMNN_SOFTWARE_INFO,
2413 arm::pipe::ARMNN_SOFTWARE_VERSION,
2414 arm::pipe::ARMNN_HARDWARE_VERSION);
Sadik Armagan3896b472020-02-10 12:24:15 +00002415 SendThread sendThread(profilingStateMachine, mockBuffer, sendCounterPacket);
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002416
2417 std::vector<uint16_t> counterIds;
Finn Williamsf4d59a62019-10-14 15:55:18 +01002418 CaptureReader captureReader(2);
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002419
Keith Davis3201eea2019-10-24 17:30:41 +01002420 unsigned int valueA = 10;
2421 unsigned int valueB = 15;
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002422 unsigned int numSteps = 5;
2423
Finn Williams032bc742020-02-12 11:02:34 +00002424 PeriodicCounterCapture periodicCounterCapture(std::ref(data), std::ref(sendCounterPacket), captureReader,
2425 counterIdMap, backendProfilingContext);
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002426
Matteo Martincighe0e6efc2019-10-04 17:17:42 +01002427 for (unsigned int i = 0; i < numSteps; ++i)
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002428 {
Finn Williams032bc742020-02-12 11:02:34 +00002429 data.SetCaptureData(1, captureIds1, {});
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002430 captureReader.SetCounterValue(0, valueA * (i + 1));
2431 captureReader.SetCounterValue(1, valueB * (i + 1));
2432
2433 periodicCounterCapture.Start();
Finn Williamsf4d59a62019-10-14 15:55:18 +01002434 periodicCounterCapture.Stop();
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002435 }
2436
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01002437 auto buffer = mockBuffer.GetReadableBuffer();
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002438
2439 uint32_t headerWord0 = ReadUint32(buffer, 0);
2440 uint32_t headerWord1 = ReadUint32(buffer, 4);
2441
Sadik Armagan1625efc2021-06-10 18:24:34 +01002442 CHECK(((headerWord0 >> 26) & 0x0000003F) == 3); // packet family
2443 CHECK(((headerWord0 >> 19) & 0x0000007F) == 0); // packet class
2444 CHECK(((headerWord0 >> 16) & 0x00000007) == 0); // packet type
2445 CHECK(headerWord1 == 20);
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002446
Keith Davis3201eea2019-10-24 17:30:41 +01002447 uint32_t offset = 16;
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002448 uint16_t readIndex = ReadUint16(buffer, offset);
Sadik Armagan1625efc2021-06-10 18:24:34 +01002449 CHECK(0 == readIndex);
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002450
2451 offset += 2;
2452 uint32_t readValue = ReadUint32(buffer, offset);
Sadik Armagan1625efc2021-06-10 18:24:34 +01002453 CHECK((valueA * numSteps) == readValue);
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002454
2455 offset += 4;
2456 readIndex = ReadUint16(buffer, offset);
Sadik Armagan1625efc2021-06-10 18:24:34 +01002457 CHECK(1 == readIndex);
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002458
2459 offset += 2;
2460 readValue = ReadUint32(buffer, offset);
Sadik Armagan1625efc2021-06-10 18:24:34 +01002461 CHECK((valueB * numSteps) == readValue);
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002462}
2463
Sadik Armagan1625efc2021-06-10 18:24:34 +01002464TEST_CASE("RequestCounterDirectoryCommandHandlerTest1")
Narumol Prangnawarat48033692019-09-20 12:04:55 +01002465{
Jim Flynn397043f2019-10-17 17:37:10 +01002466 const uint32_t familyId = 0;
Matteo Martincigh8efc5002019-10-10 14:30:29 +01002467 const uint32_t packetId = 3;
Keith Davis3201eea2019-10-24 17:30:41 +01002468 const uint32_t version = 1;
Matteo Martincigh8efc5002019-10-10 14:30:29 +01002469 ProfilingStateMachine profilingStateMachine;
2470 CounterDirectory counterDirectory;
Matteo Martincigh9723d022019-11-13 10:56:41 +00002471 MockBufferManager mockBuffer1(1024);
Jim Flynn9c85b412022-03-16 00:27:43 +00002472 SendCounterPacket sendCounterPacket(mockBuffer1,
2473 arm::pipe::ARMNN_SOFTWARE_INFO,
2474 arm::pipe::ARMNN_SOFTWARE_VERSION,
2475 arm::pipe::ARMNN_HARDWARE_VERSION);
Sadik Armagan3896b472020-02-10 12:24:15 +00002476 SendThread sendThread(profilingStateMachine, mockBuffer1, sendCounterPacket);
Matteo Martincigh9723d022019-11-13 10:56:41 +00002477 MockBufferManager mockBuffer2(1024);
2478 SendTimelinePacket sendTimelinePacket(mockBuffer2);
Keith Davis3201eea2019-10-24 17:30:41 +01002479 RequestCounterDirectoryCommandHandler commandHandler(familyId, packetId, version, counterDirectory,
Matteo Martincigh9723d022019-11-13 10:56:41 +00002480 sendCounterPacket, sendTimelinePacket, profilingStateMachine);
Narumol Prangnawarat48033692019-09-20 12:04:55 +01002481
Matteo Martincigh8efc5002019-10-10 14:30:29 +01002482 const uint32_t wrongPacketId = 47;
Keith Davis3201eea2019-10-24 17:30:41 +01002483 const uint32_t wrongHeader = (wrongPacketId & 0x000003FF) << 16;
Narumol Prangnawarat48033692019-09-20 12:04:55 +01002484
Jim Flynnbbfe6032020-07-20 16:57:44 +01002485 arm::pipe::Packet wrongPacket(wrongHeader);
Matteo Martincigh8efc5002019-10-10 14:30:29 +01002486
2487 profilingStateMachine.TransitionToState(ProfilingState::Uninitialised);
Jim Flynnf9db3ef2022-03-08 21:23:44 +00002488 CHECK_THROWS_AS(commandHandler(wrongPacket), arm::pipe::ProfilingException); // Wrong profiling state
Matteo Martincigh8efc5002019-10-10 14:30:29 +01002489 profilingStateMachine.TransitionToState(ProfilingState::NotConnected);
Jim Flynnf9db3ef2022-03-08 21:23:44 +00002490 CHECK_THROWS_AS(commandHandler(wrongPacket), arm::pipe::ProfilingException); // Wrong profiling state
Matteo Martincigh8efc5002019-10-10 14:30:29 +01002491 profilingStateMachine.TransitionToState(ProfilingState::WaitingForAck);
Jim Flynnf9db3ef2022-03-08 21:23:44 +00002492 CHECK_THROWS_AS(commandHandler(wrongPacket), arm::pipe::ProfilingException); // Wrong profiling state
Matteo Martincigh8efc5002019-10-10 14:30:29 +01002493 profilingStateMachine.TransitionToState(ProfilingState::Active);
Jim Flynnf9db3ef2022-03-08 21:23:44 +00002494 CHECK_THROWS_AS(commandHandler(wrongPacket), arm::pipe::InvalidArgumentException); // Wrong packet
Matteo Martincigh8efc5002019-10-10 14:30:29 +01002495
2496 const uint32_t rightHeader = (packetId & 0x000003FF) << 16;
2497
Jim Flynnbbfe6032020-07-20 16:57:44 +01002498 arm::pipe::Packet rightPacket(rightHeader);
Matteo Martincigh8efc5002019-10-10 14:30:29 +01002499
Sadik Armagan1625efc2021-06-10 18:24:34 +01002500 CHECK_NOTHROW(commandHandler(rightPacket)); // Right packet
Narumol Prangnawarat48033692019-09-20 12:04:55 +01002501
Matteo Martincigh9723d022019-11-13 10:56:41 +00002502 auto readBuffer1 = mockBuffer1.GetReadableBuffer();
Narumol Prangnawarat48033692019-09-20 12:04:55 +01002503
Matteo Martincigh9723d022019-11-13 10:56:41 +00002504 uint32_t header1Word0 = ReadUint32(readBuffer1, 0);
2505 uint32_t header1Word1 = ReadUint32(readBuffer1, 4);
Narumol Prangnawarat48033692019-09-20 12:04:55 +01002506
Matteo Martincigh9723d022019-11-13 10:56:41 +00002507 // Counter directory packet
Sadik Armagan1625efc2021-06-10 18:24:34 +01002508 CHECK(((header1Word0 >> 26) & 0x0000003F) == 0); // packet family
2509 CHECK(((header1Word0 >> 16) & 0x000003FF) == 2); // packet id
2510 CHECK(header1Word1 == 24); // data length
Narumol Prangnawarat48033692019-09-20 12:04:55 +01002511
Matteo Martincigh9723d022019-11-13 10:56:41 +00002512 uint32_t bodyHeader1Word0 = ReadUint32(readBuffer1, 8);
Jim Flynn75c14f42022-03-10 22:05:42 +00002513 uint16_t deviceRecordCount = arm::pipe::numeric_cast<uint16_t>(bodyHeader1Word0 >> 16);
Sadik Armagan1625efc2021-06-10 18:24:34 +01002514 CHECK(deviceRecordCount == 0); // device_records_count
Matteo Martincigh9723d022019-11-13 10:56:41 +00002515
2516 auto readBuffer2 = mockBuffer2.GetReadableBuffer();
2517
2518 uint32_t header2Word0 = ReadUint32(readBuffer2, 0);
2519 uint32_t header2Word1 = ReadUint32(readBuffer2, 4);
2520
2521 // Timeline message directory packet
Sadik Armagan1625efc2021-06-10 18:24:34 +01002522 CHECK(((header2Word0 >> 26) & 0x0000003F) == 1); // packet family
2523 CHECK(((header2Word0 >> 16) & 0x000003FF) == 0); // packet id
2524 CHECK(header2Word1 == 443); // data length
Narumol Prangnawarat48033692019-09-20 12:04:55 +01002525}
2526
Sadik Armagan1625efc2021-06-10 18:24:34 +01002527TEST_CASE("RequestCounterDirectoryCommandHandlerTest2")
Narumol Prangnawarat48033692019-09-20 12:04:55 +01002528{
Jim Flynn397043f2019-10-17 17:37:10 +01002529 const uint32_t familyId = 0;
Matteo Martincigh8efc5002019-10-10 14:30:29 +01002530 const uint32_t packetId = 3;
Keith Davis3201eea2019-10-24 17:30:41 +01002531 const uint32_t version = 1;
Matteo Martincigh8efc5002019-10-10 14:30:29 +01002532 ProfilingStateMachine profilingStateMachine;
2533 CounterDirectory counterDirectory;
Matteo Martincigh9723d022019-11-13 10:56:41 +00002534 MockBufferManager mockBuffer1(1024);
Jim Flynn9c85b412022-03-16 00:27:43 +00002535 SendCounterPacket sendCounterPacket(mockBuffer1,
2536 arm::pipe::ARMNN_SOFTWARE_INFO,
2537 arm::pipe::ARMNN_SOFTWARE_VERSION,
2538 arm::pipe::ARMNN_HARDWARE_VERSION);
Sadik Armagan3896b472020-02-10 12:24:15 +00002539 SendThread sendThread(profilingStateMachine, mockBuffer1, sendCounterPacket);
Matteo Martincigh9723d022019-11-13 10:56:41 +00002540 MockBufferManager mockBuffer2(1024);
2541 SendTimelinePacket sendTimelinePacket(mockBuffer2);
Keith Davis3201eea2019-10-24 17:30:41 +01002542 RequestCounterDirectoryCommandHandler commandHandler(familyId, packetId, version, counterDirectory,
Matteo Martincigh9723d022019-11-13 10:56:41 +00002543 sendCounterPacket, sendTimelinePacket, profilingStateMachine);
Matteo Martincigh8efc5002019-10-10 14:30:29 +01002544 const uint32_t header = (packetId & 0x000003FF) << 16;
Jim Flynnbbfe6032020-07-20 16:57:44 +01002545 const arm::pipe::Packet packet(header);
Narumol Prangnawarat48033692019-09-20 12:04:55 +01002546
Matteo Martincigh9723d022019-11-13 10:56:41 +00002547 const Device* device = counterDirectory.RegisterDevice("deviceA", 1);
Sadik Armagan1625efc2021-06-10 18:24:34 +01002548 CHECK(device != nullptr);
Narumol Prangnawarat48033692019-09-20 12:04:55 +01002549 const CounterSet* counterSet = counterDirectory.RegisterCounterSet("countersetA");
Sadik Armagan1625efc2021-06-10 18:24:34 +01002550 CHECK(counterSet != nullptr);
Sadik Armagan4c998992020-02-25 12:44:44 +00002551 counterDirectory.RegisterCategory("categoryA");
Keith Davise394bd92019-12-02 15:12:19 +00002552 counterDirectory.RegisterCounter(armnn::profiling::BACKEND_ID, 24,
2553 "categoryA", 0, 1, 2.0f, "counterA", "descA");
2554 counterDirectory.RegisterCounter(armnn::profiling::BACKEND_ID, 25,
2555 "categoryA", 1, 1, 3.0f, "counterB", "descB");
Narumol Prangnawarat48033692019-09-20 12:04:55 +01002556
Matteo Martincigh8efc5002019-10-10 14:30:29 +01002557 profilingStateMachine.TransitionToState(ProfilingState::Uninitialised);
Jim Flynnf9db3ef2022-03-08 21:23:44 +00002558 CHECK_THROWS_AS(commandHandler(packet), arm::pipe::ProfilingException); // Wrong profiling state
Matteo Martincigh8efc5002019-10-10 14:30:29 +01002559 profilingStateMachine.TransitionToState(ProfilingState::NotConnected);
Jim Flynnf9db3ef2022-03-08 21:23:44 +00002560 CHECK_THROWS_AS(commandHandler(packet), arm::pipe::ProfilingException); // Wrong profiling state
Matteo Martincigh8efc5002019-10-10 14:30:29 +01002561 profilingStateMachine.TransitionToState(ProfilingState::WaitingForAck);
Jim Flynnf9db3ef2022-03-08 21:23:44 +00002562 CHECK_THROWS_AS(commandHandler(packet), arm::pipe::ProfilingException); // Wrong profiling state
Matteo Martincigh8efc5002019-10-10 14:30:29 +01002563 profilingStateMachine.TransitionToState(ProfilingState::Active);
Sadik Armagan1625efc2021-06-10 18:24:34 +01002564 CHECK_NOTHROW(commandHandler(packet));
Narumol Prangnawarat48033692019-09-20 12:04:55 +01002565
Matteo Martincigh9723d022019-11-13 10:56:41 +00002566 auto readBuffer1 = mockBuffer1.GetReadableBuffer();
Narumol Prangnawarat48033692019-09-20 12:04:55 +01002567
Finn Williams985fecf2020-04-30 11:06:43 +01002568 const uint32_t header1Word0 = ReadUint32(readBuffer1, 0);
2569 const uint32_t header1Word1 = ReadUint32(readBuffer1, 4);
Narumol Prangnawarat48033692019-09-20 12:04:55 +01002570
Sadik Armagan1625efc2021-06-10 18:24:34 +01002571 CHECK(((header1Word0 >> 26) & 0x0000003F) == 0); // packet family
2572 CHECK(((header1Word0 >> 16) & 0x000003FF) == 2); // packet id
2573 CHECK(header1Word1 == 236); // data length
Narumol Prangnawarat48033692019-09-20 12:04:55 +01002574
Finn Williams985fecf2020-04-30 11:06:43 +01002575 const uint32_t bodyHeaderSizeBytes = bodyHeaderSize * sizeof(uint32_t);
Narumol Prangnawarat48033692019-09-20 12:04:55 +01002576
Finn Williams985fecf2020-04-30 11:06:43 +01002577 const uint32_t bodyHeader1Word0 = ReadUint32(readBuffer1, 8);
2578 const uint32_t bodyHeader1Word1 = ReadUint32(readBuffer1, 12);
2579 const uint32_t bodyHeader1Word2 = ReadUint32(readBuffer1, 16);
2580 const uint32_t bodyHeader1Word3 = ReadUint32(readBuffer1, 20);
2581 const uint32_t bodyHeader1Word4 = ReadUint32(readBuffer1, 24);
2582 const uint32_t bodyHeader1Word5 = ReadUint32(readBuffer1, 28);
Jim Flynn75c14f42022-03-10 22:05:42 +00002583 const uint16_t deviceRecordCount = arm::pipe::numeric_cast<uint16_t>(bodyHeader1Word0 >> 16);
2584 const uint16_t counterSetRecordCount = arm::pipe::numeric_cast<uint16_t>(bodyHeader1Word2 >> 16);
2585 const uint16_t categoryRecordCount = arm::pipe::numeric_cast<uint16_t>(bodyHeader1Word4 >> 16);
Sadik Armagan1625efc2021-06-10 18:24:34 +01002586 CHECK(deviceRecordCount == 1); // device_records_count
2587 CHECK(bodyHeader1Word1 == 0 + bodyHeaderSizeBytes); // device_records_pointer_table_offset
2588 CHECK(counterSetRecordCount == 1); // counter_set_count
2589 CHECK(bodyHeader1Word3 == 4 + bodyHeaderSizeBytes); // counter_set_pointer_table_offset
2590 CHECK(categoryRecordCount == 1); // categories_count
2591 CHECK(bodyHeader1Word5 == 8 + bodyHeaderSizeBytes); // categories_pointer_table_offset
Finn Williams985fecf2020-04-30 11:06:43 +01002592
2593 const uint32_t deviceRecordOffset = ReadUint32(readBuffer1, 32);
Sadik Armagan1625efc2021-06-10 18:24:34 +01002594 CHECK(deviceRecordOffset == 12);
Narumol Prangnawarat48033692019-09-20 12:04:55 +01002595
Finn Williams985fecf2020-04-30 11:06:43 +01002596 const uint32_t counterSetRecordOffset = ReadUint32(readBuffer1, 36);
Sadik Armagan1625efc2021-06-10 18:24:34 +01002597 CHECK(counterSetRecordOffset == 28);
Narumol Prangnawarat48033692019-09-20 12:04:55 +01002598
Finn Williams985fecf2020-04-30 11:06:43 +01002599 const uint32_t categoryRecordOffset = ReadUint32(readBuffer1, 40);
Sadik Armagan1625efc2021-06-10 18:24:34 +01002600 CHECK(categoryRecordOffset == 48);
Matteo Martincigh9723d022019-11-13 10:56:41 +00002601
2602 auto readBuffer2 = mockBuffer2.GetReadableBuffer();
2603
Finn Williams985fecf2020-04-30 11:06:43 +01002604 const uint32_t header2Word0 = ReadUint32(readBuffer2, 0);
2605 const uint32_t header2Word1 = ReadUint32(readBuffer2, 4);
Matteo Martincigh9723d022019-11-13 10:56:41 +00002606
2607 // Timeline message directory packet
Sadik Armagan1625efc2021-06-10 18:24:34 +01002608 CHECK(((header2Word0 >> 26) & 0x0000003F) == 1); // packet family
2609 CHECK(((header2Word0 >> 16) & 0x000003FF) == 0); // packet id
2610 CHECK(header2Word1 == 443); // data length
Narumol Prangnawarat48033692019-09-20 12:04:55 +01002611}
2612
Sadik Armagan1625efc2021-06-10 18:24:34 +01002613TEST_CASE("CheckProfilingServiceGoodConnectionAcknowledgedPacket")
Matteo Martincigh54fb9572019-10-02 12:50:57 +01002614{
Finn Williamsa0de0562020-04-22 12:27:37 +01002615 unsigned int streamMetadataPacketsize = GetStreamMetaDataPacketSize();
Matteo Martincigh54fb9572019-10-02 12:50:57 +01002616
Jim Flynn53e46992019-10-14 12:31:10 +01002617 // Reset the profiling service to the uninitialized state
Jim Flynn4c9ed1d2022-01-23 23:57:20 +00002618 ProfilingOptions options;
Keith Davis3201eea2019-10-24 17:30:41 +01002619 options.m_EnableProfiling = true;
Jim Flynn34430252022-03-04 15:03:58 +00002620 armnn::ArmNNProfilingServiceInitialiser initialiser;
Jim Flynn9c85b412022-03-16 00:27:43 +00002621 ProfilingService profilingService(arm::pipe::MAX_ARMNN_COUNTER,
2622 initialiser,
2623 arm::pipe::ARMNN_SOFTWARE_INFO,
2624 arm::pipe::ARMNN_SOFTWARE_VERSION,
2625 arm::pipe::ARMNN_HARDWARE_VERSION);
Matteo Martincigh54fb9572019-10-02 12:50:57 +01002626 profilingService.ResetExternalProfilingOptions(options, true);
2627
Sadik Armagan3184c902020-03-18 10:57:30 +00002628 // Swap the profiling connection factory in the profiling service instance with our mock one
Jim Flynn34430252022-03-04 15:03:58 +00002629 SwapProfilingConnectionFactoryHelper helper(arm::pipe::MAX_ARMNN_COUNTER, initialiser, profilingService);
Sadik Armagan3184c902020-03-18 10:57:30 +00002630
Matteo Martincigh54fb9572019-10-02 12:50:57 +01002631 // Bring the profiling service to the "WaitingForAck" state
Sadik Armagan1625efc2021-06-10 18:24:34 +01002632 CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
Keith Davis3201eea2019-10-24 17:30:41 +01002633 profilingService.Update(); // Initialize the counter directory
Sadik Armagan1625efc2021-06-10 18:24:34 +01002634 CHECK(profilingService.GetCurrentState() == ProfilingState::NotConnected);
Keith Davis3201eea2019-10-24 17:30:41 +01002635 profilingService.Update(); // Create the profiling connection
Matteo Martincigh54fb9572019-10-02 12:50:57 +01002636
Matteo Martincighd0613b52019-10-09 16:47:04 +01002637 // Get the mock profiling connection
2638 MockProfilingConnection* mockProfilingConnection = helper.GetMockProfilingConnection();
Sadik Armagan1625efc2021-06-10 18:24:34 +01002639 CHECK(mockProfilingConnection);
Matteo Martincighd0613b52019-10-09 16:47:04 +01002640
Matteo Martincighe8485382019-10-10 14:08:21 +01002641 // Remove the packets received so far
2642 mockProfilingConnection->Clear();
2643
Sadik Armagan1625efc2021-06-10 18:24:34 +01002644 CHECK(profilingService.GetCurrentState() == ProfilingState::WaitingForAck);
Keith Davis3201eea2019-10-24 17:30:41 +01002645 profilingService.Update(); // Start the command handler and the send thread
Matteo Martincighe8485382019-10-10 14:08:21 +01002646
2647 // Wait for the Stream Metadata packet to be sent
Sadik Armagan1625efc2021-06-10 18:24:34 +01002648 CHECK(helper.WaitForPacketsSent(
Finn Williams09ad6f92019-12-19 17:05:18 +00002649 mockProfilingConnection, PacketType::StreamMetaData, streamMetadataPacketsize) >= 1);
Matteo Martincigh54fb9572019-10-02 12:50:57 +01002650
2651 // Write a valid "Connection Acknowledged" packet into the mock profiling connection, to simulate a valid
2652 // reply from an external profiling service
2653
2654 // Connection Acknowledged Packet header (word 0, word 1 is always zero):
2655 // 26:31 [6] packet_family: Control Packet Family, value 0b000000
2656 // 16:25 [10] packet_id: Packet identifier, value 0b0000000001
2657 // 8:15 [8] reserved: Reserved, value 0b00000000
2658 // 0:7 [8] reserved: Reserved, value 0b00000000
2659 uint32_t packetFamily = 0;
2660 uint32_t packetId = 1;
Keith Davis3201eea2019-10-24 17:30:41 +01002661 uint32_t header = ((packetFamily & 0x0000003F) << 26) | ((packetId & 0x000003FF) << 16);
Matteo Martincigh54fb9572019-10-02 12:50:57 +01002662
Matteo Martincighd0613b52019-10-09 16:47:04 +01002663 // Create the Connection Acknowledged Packet
Jim Flynnbbfe6032020-07-20 16:57:44 +01002664 arm::pipe::Packet connectionAcknowledgedPacket(header);
Matteo Martincigh54fb9572019-10-02 12:50:57 +01002665
2666 // Write the packet to the mock profiling connection
2667 mockProfilingConnection->WritePacket(std::move(connectionAcknowledgedPacket));
2668
Colm Donelan2ba48d22019-11-29 09:10:59 +00002669 // Wait for the counter directory packet to ensure the ConnectionAcknowledgedCommandHandler has run.
Sadik Armagan1625efc2021-06-10 18:24:34 +01002670 CHECK(helper.WaitForPacketsSent(mockProfilingConnection, PacketType::CounterDirectory) == 1);
Matteo Martincigh54fb9572019-10-02 12:50:57 +01002671
2672 // The Connection Acknowledged Command Handler should have updated the profiling state accordingly
Sadik Armagan1625efc2021-06-10 18:24:34 +01002673 CHECK(profilingService.GetCurrentState() == ProfilingState::Active);
Matteo Martincighd0613b52019-10-09 16:47:04 +01002674
2675 // Reset the profiling service to stop any running thread
2676 options.m_EnableProfiling = false;
2677 profilingService.ResetExternalProfilingOptions(options, true);
Matteo Martincigh54fb9572019-10-02 12:50:57 +01002678}
2679
Sadik Armagan1625efc2021-06-10 18:24:34 +01002680TEST_CASE("CheckProfilingServiceGoodRequestCounterDirectoryPacket")
Matteo Martincigh8efc5002019-10-10 14:30:29 +01002681{
Matteo Martincigh8efc5002019-10-10 14:30:29 +01002682 // Reset the profiling service to the uninitialized state
Jim Flynn4c9ed1d2022-01-23 23:57:20 +00002683 ProfilingOptions options;
Keith Davis3201eea2019-10-24 17:30:41 +01002684 options.m_EnableProfiling = true;
Jim Flynn34430252022-03-04 15:03:58 +00002685 armnn::ArmNNProfilingServiceInitialiser initialiser;
Jim Flynn9c85b412022-03-16 00:27:43 +00002686 ProfilingService profilingService(arm::pipe::MAX_ARMNN_COUNTER,
2687 initialiser,
2688 arm::pipe::ARMNN_SOFTWARE_INFO,
2689 arm::pipe::ARMNN_SOFTWARE_VERSION,
2690 arm::pipe::ARMNN_HARDWARE_VERSION);
Matteo Martincigh8efc5002019-10-10 14:30:29 +01002691 profilingService.ResetExternalProfilingOptions(options, true);
2692
Sadik Armagan3184c902020-03-18 10:57:30 +00002693 // Swap the profiling connection factory in the profiling service instance with our mock one
Jim Flynn34430252022-03-04 15:03:58 +00002694 SwapProfilingConnectionFactoryHelper helper(arm::pipe::MAX_ARMNN_COUNTER, initialiser, profilingService);
Sadik Armagan3184c902020-03-18 10:57:30 +00002695
Matteo Martincigh8efc5002019-10-10 14:30:29 +01002696 // Bring the profiling service to the "Active" state
Sadik Armagan1625efc2021-06-10 18:24:34 +01002697 CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
Keith Davis3201eea2019-10-24 17:30:41 +01002698 profilingService.Update(); // Initialize the counter directory
Sadik Armagan1625efc2021-06-10 18:24:34 +01002699 CHECK(profilingService.GetCurrentState() == ProfilingState::NotConnected);
Keith Davis3201eea2019-10-24 17:30:41 +01002700 profilingService.Update(); // Create the profiling connection
Sadik Armagan1625efc2021-06-10 18:24:34 +01002701 CHECK(profilingService.GetCurrentState() == ProfilingState::WaitingForAck);
Keith Davis3201eea2019-10-24 17:30:41 +01002702 profilingService.Update(); // Start the command handler and the send thread
Matteo Martincighe8485382019-10-10 14:08:21 +01002703
Colm Donelan2ba48d22019-11-29 09:10:59 +00002704 // Get the mock profiling connection
2705 MockProfilingConnection* mockProfilingConnection = helper.GetMockProfilingConnection();
Sadik Armagan1625efc2021-06-10 18:24:34 +01002706 CHECK(mockProfilingConnection);
Colm Donelan2ba48d22019-11-29 09:10:59 +00002707
Matteo Martincighe8485382019-10-10 14:08:21 +01002708 // Force the profiling service to the "Active" state
Matteo Martincigh8efc5002019-10-10 14:30:29 +01002709 helper.ForceTransitionToState(ProfilingState::Active);
Sadik Armagan1625efc2021-06-10 18:24:34 +01002710 CHECK(profilingService.GetCurrentState() == ProfilingState::Active);
Matteo Martincigh8efc5002019-10-10 14:30:29 +01002711
Matteo Martincigh8efc5002019-10-10 14:30:29 +01002712 // Write a valid "Request Counter Directory" packet into the mock profiling connection, to simulate a valid
2713 // reply from an external profiling service
2714
2715 // Request Counter Directory packet header (word 0, word 1 is always zero):
2716 // 26:31 [6] packet_family: Control Packet Family, value 0b000000
2717 // 16:25 [10] packet_id: Packet identifier, value 0b0000000011
2718 // 8:15 [8] reserved: Reserved, value 0b00000000
2719 // 0:7 [8] reserved: Reserved, value 0b00000000
2720 uint32_t packetFamily = 0;
2721 uint32_t packetId = 3;
Keith Davis3201eea2019-10-24 17:30:41 +01002722 uint32_t header = ((packetFamily & 0x0000003F) << 26) | ((packetId & 0x000003FF) << 16);
Matteo Martincigh8efc5002019-10-10 14:30:29 +01002723
2724 // Create the Request Counter Directory packet
Jim Flynnbbfe6032020-07-20 16:57:44 +01002725 arm::pipe::Packet requestCounterDirectoryPacket(header);
Matteo Martincigh8efc5002019-10-10 14:30:29 +01002726
2727 // Write the packet to the mock profiling connection
2728 mockProfilingConnection->WritePacket(std::move(requestCounterDirectoryPacket));
2729
Sadik Armagan4c998992020-02-25 12:44:44 +00002730 // Expecting one CounterDirectory Packet of length 652
Jim Flynn6398a982020-05-27 17:05:21 +01002731 // and one TimelineMessageDirectory packet of length 451
Sadik Armagan1625efc2021-06-10 18:24:34 +01002732 CHECK(helper.WaitForPacketsSent(mockProfilingConnection, PacketType::CounterDirectory, 652) == 1);
2733 CHECK(helper.WaitForPacketsSent(mockProfilingConnection, PacketType::TimelineMessageDirectory, 451) == 1);
Matteo Martincighe8485382019-10-10 14:08:21 +01002734
2735 // The Request Counter Directory Command Handler should not have updated the profiling state
Sadik Armagan1625efc2021-06-10 18:24:34 +01002736 CHECK(profilingService.GetCurrentState() == ProfilingState::Active);
Matteo Martincighe8485382019-10-10 14:08:21 +01002737
2738 // Reset the profiling service to stop any running thread
2739 options.m_EnableProfiling = false;
2740 profilingService.ResetExternalProfilingOptions(options, true);
2741}
2742
Sadik Armagan1625efc2021-06-10 18:24:34 +01002743TEST_CASE("CheckProfilingServiceBadPeriodicCounterSelectionPacketInvalidCounterUid")
Matteo Martincighe8485382019-10-10 14:08:21 +01002744{
Matteo Martincighe8485382019-10-10 14:08:21 +01002745 // Reset the profiling service to the uninitialized state
Jim Flynn4c9ed1d2022-01-23 23:57:20 +00002746 ProfilingOptions options;
Keith Davis3201eea2019-10-24 17:30:41 +01002747 options.m_EnableProfiling = true;
Jim Flynn34430252022-03-04 15:03:58 +00002748 armnn::ArmNNProfilingServiceInitialiser initialiser;
Jim Flynn9c85b412022-03-16 00:27:43 +00002749 ProfilingService profilingService(arm::pipe::MAX_ARMNN_COUNTER,
2750 initialiser,
2751 arm::pipe::ARMNN_SOFTWARE_INFO,
2752 arm::pipe::ARMNN_SOFTWARE_VERSION,
2753 arm::pipe::ARMNN_HARDWARE_VERSION);
Matteo Martincighe8485382019-10-10 14:08:21 +01002754 profilingService.ResetExternalProfilingOptions(options, true);
2755
Sadik Armagan3184c902020-03-18 10:57:30 +00002756 // Swap the profiling connection factory in the profiling service instance with our mock one
Jim Flynn34430252022-03-04 15:03:58 +00002757 SwapProfilingConnectionFactoryHelper helper(arm::pipe::MAX_ARMNN_COUNTER, initialiser, profilingService);
Sadik Armagan3184c902020-03-18 10:57:30 +00002758
Matteo Martincighe8485382019-10-10 14:08:21 +01002759 // Bring the profiling service to the "Active" state
Sadik Armagan1625efc2021-06-10 18:24:34 +01002760 CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
Keith Davis3201eea2019-10-24 17:30:41 +01002761 profilingService.Update(); // Initialize the counter directory
Sadik Armagan1625efc2021-06-10 18:24:34 +01002762 CHECK(profilingService.GetCurrentState() == ProfilingState::NotConnected);
Keith Davis3201eea2019-10-24 17:30:41 +01002763 profilingService.Update(); // Create the profiling connection
Sadik Armagan1625efc2021-06-10 18:24:34 +01002764 CHECK(profilingService.GetCurrentState() == ProfilingState::WaitingForAck);
Keith Davis3201eea2019-10-24 17:30:41 +01002765 profilingService.Update(); // Start the command handler and the send thread
Matteo Martincighe8485382019-10-10 14:08:21 +01002766
Colm Donelan2ba48d22019-11-29 09:10:59 +00002767 // Get the mock profiling connection
2768 MockProfilingConnection* mockProfilingConnection = helper.GetMockProfilingConnection();
Sadik Armagan1625efc2021-06-10 18:24:34 +01002769 CHECK(mockProfilingConnection);
Colm Donelan2ba48d22019-11-29 09:10:59 +00002770
Matteo Martincighe8485382019-10-10 14:08:21 +01002771 // Force the profiling service to the "Active" state
2772 helper.ForceTransitionToState(ProfilingState::Active);
Sadik Armagan1625efc2021-06-10 18:24:34 +01002773 CHECK(profilingService.GetCurrentState() == ProfilingState::Active);
Matteo Martincighe8485382019-10-10 14:08:21 +01002774
Matteo Martincighe8485382019-10-10 14:08:21 +01002775 // Remove the packets received so far
2776 mockProfilingConnection->Clear();
2777
2778 // Write a "Periodic Counter Selection" packet into the mock profiling connection, to simulate an input from an
2779 // external profiling service
2780
2781 // Periodic Counter Selection packet header:
2782 // 26:31 [6] packet_family: Control Packet Family, value 0b000000
2783 // 16:25 [10] packet_id: Packet identifier, value 0b0000000100
2784 // 8:15 [8] reserved: Reserved, value 0b00000000
2785 // 0:7 [8] reserved: Reserved, value 0b00000000
2786 uint32_t packetFamily = 0;
2787 uint32_t packetId = 4;
Keith Davis3201eea2019-10-24 17:30:41 +01002788 uint32_t header = ((packetFamily & 0x0000003F) << 26) | ((packetId & 0x000003FF) << 16);
Matteo Martincighe8485382019-10-10 14:08:21 +01002789
Keith Davis3201eea2019-10-24 17:30:41 +01002790 uint32_t capturePeriod = 123456; // Some capture period (microseconds)
Matteo Martincighe8485382019-10-10 14:08:21 +01002791
2792 // Get the first valid counter UID
2793 const ICounterDirectory& counterDirectory = profilingService.GetCounterDirectory();
Keith Davis3201eea2019-10-24 17:30:41 +01002794 const Counters& counters = counterDirectory.GetCounters();
Sadik Armagan1625efc2021-06-10 18:24:34 +01002795 CHECK(counters.size() > 1);
Keith Davis3201eea2019-10-24 17:30:41 +01002796 uint16_t counterUidA = counters.begin()->first; // First valid counter UID
2797 uint16_t counterUidB = 9999; // Second invalid counter UID
Matteo Martincighe8485382019-10-10 14:08:21 +01002798
2799 uint32_t length = 8;
2800
2801 auto data = std::make_unique<unsigned char[]>(length);
2802 WriteUint32(data.get(), 0, capturePeriod);
2803 WriteUint16(data.get(), 4, counterUidA);
2804 WriteUint16(data.get(), 6, counterUidB);
2805
2806 // Create the Periodic Counter Selection packet
Jim Flynnbbfe6032020-07-20 16:57:44 +01002807 // Length > 0, this will start the Period Counter Capture thread
2808 arm::pipe::Packet periodicCounterSelectionPacket(header, length, data);
2809
Matteo Martincighe8485382019-10-10 14:08:21 +01002810
2811 // Write the packet to the mock profiling connection
2812 mockProfilingConnection->WritePacket(std::move(periodicCounterSelectionPacket));
2813
Finn Williams09ad6f92019-12-19 17:05:18 +00002814 // Expecting one Periodic Counter Selection packet of length 14
2815 // and at least one Periodic Counter Capture packet of length 22
Sadik Armagan1625efc2021-06-10 18:24:34 +01002816 CHECK(helper.WaitForPacketsSent(mockProfilingConnection, PacketType::PeriodicCounterSelection, 14) == 1);
2817 CHECK(helper.WaitForPacketsSent(mockProfilingConnection, PacketType::PeriodicCounterCapture, 22) >= 1);
Matteo Martincighe8485382019-10-10 14:08:21 +01002818
2819 // The Periodic Counter Selection Handler should not have updated the profiling state
Sadik Armagan1625efc2021-06-10 18:24:34 +01002820 CHECK(profilingService.GetCurrentState() == ProfilingState::Active);
Matteo Martincighe8485382019-10-10 14:08:21 +01002821
2822 // Reset the profiling service to stop any running thread
2823 options.m_EnableProfiling = false;
2824 profilingService.ResetExternalProfilingOptions(options, true);
2825}
2826
Sadik Armagan1625efc2021-06-10 18:24:34 +01002827TEST_CASE("CheckProfilingServiceGoodPeriodicCounterSelectionPacketNoCounters")
Matteo Martincighe8485382019-10-10 14:08:21 +01002828{
Matteo Martincighe8485382019-10-10 14:08:21 +01002829 // Reset the profiling service to the uninitialized state
Jim Flynn4c9ed1d2022-01-23 23:57:20 +00002830 ProfilingOptions options;
Keith Davis3201eea2019-10-24 17:30:41 +01002831 options.m_EnableProfiling = true;
Jim Flynn34430252022-03-04 15:03:58 +00002832 armnn::ArmNNProfilingServiceInitialiser initialiser;
Jim Flynn9c85b412022-03-16 00:27:43 +00002833 ProfilingService profilingService(arm::pipe::MAX_ARMNN_COUNTER,
2834 initialiser,
2835 arm::pipe::ARMNN_SOFTWARE_INFO,
2836 arm::pipe::ARMNN_SOFTWARE_VERSION,
2837 arm::pipe::ARMNN_HARDWARE_VERSION);
Matteo Martincighe8485382019-10-10 14:08:21 +01002838 profilingService.ResetExternalProfilingOptions(options, true);
2839
Sadik Armagan3184c902020-03-18 10:57:30 +00002840 // Swap the profiling connection factory in the profiling service instance with our mock one
Jim Flynn34430252022-03-04 15:03:58 +00002841 SwapProfilingConnectionFactoryHelper helper(arm::pipe::MAX_ARMNN_COUNTER, initialiser, profilingService);
Sadik Armagan3184c902020-03-18 10:57:30 +00002842
Matteo Martincighe8485382019-10-10 14:08:21 +01002843 // Bring the profiling service to the "Active" state
Sadik Armagan1625efc2021-06-10 18:24:34 +01002844 CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
Keith Davis3201eea2019-10-24 17:30:41 +01002845 profilingService.Update(); // Initialize the counter directory
Sadik Armagan1625efc2021-06-10 18:24:34 +01002846 CHECK(profilingService.GetCurrentState() == ProfilingState::NotConnected);
Keith Davis3201eea2019-10-24 17:30:41 +01002847 profilingService.Update(); // Create the profiling connection
Sadik Armagan1625efc2021-06-10 18:24:34 +01002848 CHECK(profilingService.GetCurrentState() == ProfilingState::WaitingForAck);
Keith Davis3201eea2019-10-24 17:30:41 +01002849 profilingService.Update(); // Start the command handler and the send thread
Matteo Martincighe8485382019-10-10 14:08:21 +01002850
Colm Donelan2ba48d22019-11-29 09:10:59 +00002851 // Get the mock profiling connection
2852 MockProfilingConnection* mockProfilingConnection = helper.GetMockProfilingConnection();
Sadik Armagan1625efc2021-06-10 18:24:34 +01002853 CHECK(mockProfilingConnection);
Colm Donelan2ba48d22019-11-29 09:10:59 +00002854
Matteo Martincighe8485382019-10-10 14:08:21 +01002855 // Wait for the Stream Metadata packet the be sent
2856 // (we are not testing the connection acknowledgement here so it will be ignored by this test)
Finn Williams09ad6f92019-12-19 17:05:18 +00002857 helper.WaitForPacketsSent(mockProfilingConnection, PacketType::StreamMetaData);
Matteo Martincighe8485382019-10-10 14:08:21 +01002858
2859 // Force the profiling service to the "Active" state
2860 helper.ForceTransitionToState(ProfilingState::Active);
Sadik Armagan1625efc2021-06-10 18:24:34 +01002861 CHECK(profilingService.GetCurrentState() == ProfilingState::Active);
Matteo Martincighe8485382019-10-10 14:08:21 +01002862
Matteo Martincighe8485382019-10-10 14:08:21 +01002863 // Write a "Periodic Counter Selection" packet into the mock profiling connection, to simulate an input from an
2864 // external profiling service
2865
2866 // Periodic Counter Selection packet header:
2867 // 26:31 [6] packet_family: Control Packet Family, value 0b000000
2868 // 16:25 [10] packet_id: Packet identifier, value 0b0000000100
2869 // 8:15 [8] reserved: Reserved, value 0b00000000
2870 // 0:7 [8] reserved: Reserved, value 0b00000000
2871 uint32_t packetFamily = 0;
2872 uint32_t packetId = 4;
Keith Davis3201eea2019-10-24 17:30:41 +01002873 uint32_t header = ((packetFamily & 0x0000003F) << 26) | ((packetId & 0x000003FF) << 16);
Matteo Martincighe8485382019-10-10 14:08:21 +01002874
2875 // Create the Periodic Counter Selection packet
Jim Flynnbbfe6032020-07-20 16:57:44 +01002876 // Length == 0, this will disable the collection of counters
2877 arm::pipe::Packet periodicCounterSelectionPacket(header);
Matteo Martincighe8485382019-10-10 14:08:21 +01002878
2879 // Write the packet to the mock profiling connection
2880 mockProfilingConnection->WritePacket(std::move(periodicCounterSelectionPacket));
2881
Finn Williams09ad6f92019-12-19 17:05:18 +00002882 // Wait for the Periodic Counter Selection packet of length 12 to be sent
2883 // The size of the expected Periodic Counter Selection (echos the sent one)
Sadik Armagan1625efc2021-06-10 18:24:34 +01002884 CHECK(helper.WaitForPacketsSent(mockProfilingConnection, PacketType::PeriodicCounterSelection, 12) == 1);
Matteo Martincighe8485382019-10-10 14:08:21 +01002885
2886 // The Periodic Counter Selection Handler should not have updated the profiling state
Sadik Armagan1625efc2021-06-10 18:24:34 +01002887 CHECK(profilingService.GetCurrentState() == ProfilingState::Active);
Matteo Martincighe8485382019-10-10 14:08:21 +01002888
Finn Williams09ad6f92019-12-19 17:05:18 +00002889 // No Periodic Counter packets are expected
Sadik Armagan1625efc2021-06-10 18:24:34 +01002890 CHECK(helper.WaitForPacketsSent(mockProfilingConnection, PacketType::PeriodicCounterCapture, 0, 0) == 0);
Matteo Martincighe8485382019-10-10 14:08:21 +01002891
2892 // Reset the profiling service to stop any running thread
2893 options.m_EnableProfiling = false;
2894 profilingService.ResetExternalProfilingOptions(options, true);
2895}
2896
Sadik Armagan1625efc2021-06-10 18:24:34 +01002897TEST_CASE("CheckProfilingServiceGoodPeriodicCounterSelectionPacketSingleCounter")
Matteo Martincighe8485382019-10-10 14:08:21 +01002898{
Matteo Martincighe8485382019-10-10 14:08:21 +01002899 // Reset the profiling service to the uninitialized state
Jim Flynn4c9ed1d2022-01-23 23:57:20 +00002900 ProfilingOptions options;
Keith Davis3201eea2019-10-24 17:30:41 +01002901 options.m_EnableProfiling = true;
Jim Flynn34430252022-03-04 15:03:58 +00002902 armnn::ArmNNProfilingServiceInitialiser initialiser;
Jim Flynn9c85b412022-03-16 00:27:43 +00002903 ProfilingService profilingService(arm::pipe::MAX_ARMNN_COUNTER,
2904 initialiser,
2905 arm::pipe::ARMNN_SOFTWARE_INFO,
2906 arm::pipe::ARMNN_SOFTWARE_VERSION,
2907 arm::pipe::ARMNN_HARDWARE_VERSION);
Matteo Martincighe8485382019-10-10 14:08:21 +01002908 profilingService.ResetExternalProfilingOptions(options, true);
2909
Sadik Armagan3184c902020-03-18 10:57:30 +00002910 // Swap the profiling connection factory in the profiling service instance with our mock one
Jim Flynn34430252022-03-04 15:03:58 +00002911 SwapProfilingConnectionFactoryHelper helper(arm::pipe::MAX_ARMNN_COUNTER, initialiser, profilingService);
Sadik Armagan3184c902020-03-18 10:57:30 +00002912
Matteo Martincighe8485382019-10-10 14:08:21 +01002913 // Bring the profiling service to the "Active" state
Sadik Armagan1625efc2021-06-10 18:24:34 +01002914 CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
Keith Davis3201eea2019-10-24 17:30:41 +01002915 profilingService.Update(); // Initialize the counter directory
Sadik Armagan1625efc2021-06-10 18:24:34 +01002916 CHECK(profilingService.GetCurrentState() == ProfilingState::NotConnected);
Keith Davis3201eea2019-10-24 17:30:41 +01002917 profilingService.Update(); // Create the profiling connection
Sadik Armagan1625efc2021-06-10 18:24:34 +01002918 CHECK(profilingService.GetCurrentState() == ProfilingState::WaitingForAck);
Keith Davis3201eea2019-10-24 17:30:41 +01002919 profilingService.Update(); // Start the command handler and the send thread
Matteo Martincighe8485382019-10-10 14:08:21 +01002920
Colm Donelan2ba48d22019-11-29 09:10:59 +00002921 // Get the mock profiling connection
2922 MockProfilingConnection* mockProfilingConnection = helper.GetMockProfilingConnection();
Sadik Armagan1625efc2021-06-10 18:24:34 +01002923 CHECK(mockProfilingConnection);
Colm Donelan2ba48d22019-11-29 09:10:59 +00002924
Finn Williams09ad6f92019-12-19 17:05:18 +00002925 // Wait for the Stream Metadata packet to be sent
Matteo Martincighe8485382019-10-10 14:08:21 +01002926 // (we are not testing the connection acknowledgement here so it will be ignored by this test)
Finn Williams09ad6f92019-12-19 17:05:18 +00002927 helper.WaitForPacketsSent(mockProfilingConnection, PacketType::StreamMetaData);
Matteo Martincighe8485382019-10-10 14:08:21 +01002928
2929 // Force the profiling service to the "Active" state
2930 helper.ForceTransitionToState(ProfilingState::Active);
Sadik Armagan1625efc2021-06-10 18:24:34 +01002931 CHECK(profilingService.GetCurrentState() == ProfilingState::Active);
Matteo Martincighe8485382019-10-10 14:08:21 +01002932
Matteo Martincighe8485382019-10-10 14:08:21 +01002933 // Write a "Periodic Counter Selection" packet into the mock profiling connection, to simulate an input from an
2934 // external profiling service
2935
2936 // Periodic Counter Selection packet header:
2937 // 26:31 [6] packet_family: Control Packet Family, value 0b000000
2938 // 16:25 [10] packet_id: Packet identifier, value 0b0000000100
2939 // 8:15 [8] reserved: Reserved, value 0b00000000
2940 // 0:7 [8] reserved: Reserved, value 0b00000000
2941 uint32_t packetFamily = 0;
2942 uint32_t packetId = 4;
Keith Davis3201eea2019-10-24 17:30:41 +01002943 uint32_t header = ((packetFamily & 0x0000003F) << 26) | ((packetId & 0x000003FF) << 16);
Matteo Martincighe8485382019-10-10 14:08:21 +01002944
Keith Davis3201eea2019-10-24 17:30:41 +01002945 uint32_t capturePeriod = 123456; // Some capture period (microseconds)
Matteo Martincighe8485382019-10-10 14:08:21 +01002946
2947 // Get the first valid counter UID
2948 const ICounterDirectory& counterDirectory = profilingService.GetCounterDirectory();
Keith Davis3201eea2019-10-24 17:30:41 +01002949 const Counters& counters = counterDirectory.GetCounters();
Sadik Armagan1625efc2021-06-10 18:24:34 +01002950 CHECK(!counters.empty());
Keith Davis3201eea2019-10-24 17:30:41 +01002951 uint16_t counterUid = counters.begin()->first; // Valid counter UID
Matteo Martincighe8485382019-10-10 14:08:21 +01002952
2953 uint32_t length = 6;
2954
2955 auto data = std::make_unique<unsigned char[]>(length);
2956 WriteUint32(data.get(), 0, capturePeriod);
2957 WriteUint16(data.get(), 4, counterUid);
2958
2959 // Create the Periodic Counter Selection packet
Jim Flynnbbfe6032020-07-20 16:57:44 +01002960 // Length > 0, this will start the Period Counter Capture thread
2961 arm::pipe::Packet periodicCounterSelectionPacket(header, length, data);
Matteo Martincighe8485382019-10-10 14:08:21 +01002962
2963 // Write the packet to the mock profiling connection
2964 mockProfilingConnection->WritePacket(std::move(periodicCounterSelectionPacket));
2965
Finn Williams09ad6f92019-12-19 17:05:18 +00002966 // Expecting one Periodic Counter Selection packet of length 14
2967 // and at least one Periodic Counter Capture packet of length 22
Sadik Armagan1625efc2021-06-10 18:24:34 +01002968 CHECK(helper.WaitForPacketsSent(mockProfilingConnection, PacketType::PeriodicCounterSelection, 14) == 1);
2969 CHECK(helper.WaitForPacketsSent(mockProfilingConnection, PacketType::PeriodicCounterCapture, 22) >= 1);
Matteo Martincighe8485382019-10-10 14:08:21 +01002970
2971 // The Periodic Counter Selection Handler should not have updated the profiling state
Sadik Armagan1625efc2021-06-10 18:24:34 +01002972 CHECK(profilingService.GetCurrentState() == ProfilingState::Active);
Matteo Martincighe8485382019-10-10 14:08:21 +01002973
2974 // Reset the profiling service to stop any running thread
2975 options.m_EnableProfiling = false;
2976 profilingService.ResetExternalProfilingOptions(options, true);
2977}
2978
Sadik Armagan1625efc2021-06-10 18:24:34 +01002979TEST_CASE("CheckProfilingServiceGoodPeriodicCounterSelectionPacketMultipleCounters")
Matteo Martincighe8485382019-10-10 14:08:21 +01002980{
Matteo Martincighe8485382019-10-10 14:08:21 +01002981 // Reset the profiling service to the uninitialized state
Jim Flynn4c9ed1d2022-01-23 23:57:20 +00002982 ProfilingOptions options;
Keith Davis3201eea2019-10-24 17:30:41 +01002983 options.m_EnableProfiling = true;
Jim Flynn34430252022-03-04 15:03:58 +00002984 armnn::ArmNNProfilingServiceInitialiser initialiser;
Jim Flynn9c85b412022-03-16 00:27:43 +00002985 ProfilingService profilingService(arm::pipe::MAX_ARMNN_COUNTER,
2986 initialiser,
2987 arm::pipe::ARMNN_SOFTWARE_INFO,
2988 arm::pipe::ARMNN_SOFTWARE_VERSION,
2989 arm::pipe::ARMNN_HARDWARE_VERSION);
Matteo Martincighe8485382019-10-10 14:08:21 +01002990 profilingService.ResetExternalProfilingOptions(options, true);
2991
Sadik Armagan3184c902020-03-18 10:57:30 +00002992 // Swap the profiling connection factory in the profiling service instance with our mock one
Jim Flynn34430252022-03-04 15:03:58 +00002993 SwapProfilingConnectionFactoryHelper helper(arm::pipe::MAX_ARMNN_COUNTER, initialiser, profilingService);
Sadik Armagan3184c902020-03-18 10:57:30 +00002994
Matteo Martincighe8485382019-10-10 14:08:21 +01002995 // Bring the profiling service to the "Active" state
Sadik Armagan1625efc2021-06-10 18:24:34 +01002996 CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
Keith Davis3201eea2019-10-24 17:30:41 +01002997 profilingService.Update(); // Initialize the counter directory
Sadik Armagan1625efc2021-06-10 18:24:34 +01002998 CHECK(profilingService.GetCurrentState() == ProfilingState::NotConnected);
Keith Davis3201eea2019-10-24 17:30:41 +01002999 profilingService.Update(); // Create the profiling connection
Sadik Armagan1625efc2021-06-10 18:24:34 +01003000 CHECK(profilingService.GetCurrentState() == ProfilingState::WaitingForAck);
Keith Davis3201eea2019-10-24 17:30:41 +01003001 profilingService.Update(); // Start the command handler and the send thread
Matteo Martincighe8485382019-10-10 14:08:21 +01003002
Colm Donelan2ba48d22019-11-29 09:10:59 +00003003 // Get the mock profiling connection
3004 MockProfilingConnection* mockProfilingConnection = helper.GetMockProfilingConnection();
Sadik Armagan1625efc2021-06-10 18:24:34 +01003005 CHECK(mockProfilingConnection);
Colm Donelan2ba48d22019-11-29 09:10:59 +00003006
Matteo Martincighe8485382019-10-10 14:08:21 +01003007 // Wait for the Stream Metadata packet the be sent
3008 // (we are not testing the connection acknowledgement here so it will be ignored by this test)
Finn Williams09ad6f92019-12-19 17:05:18 +00003009 helper.WaitForPacketsSent(mockProfilingConnection, PacketType::StreamMetaData);
Matteo Martincighe8485382019-10-10 14:08:21 +01003010
3011 // Force the profiling service to the "Active" state
3012 helper.ForceTransitionToState(ProfilingState::Active);
Sadik Armagan1625efc2021-06-10 18:24:34 +01003013 CHECK(profilingService.GetCurrentState() == ProfilingState::Active);
Matteo Martincighe8485382019-10-10 14:08:21 +01003014
Matteo Martincighe8485382019-10-10 14:08:21 +01003015 // Write a "Periodic Counter Selection" packet into the mock profiling connection, to simulate an input from an
3016 // external profiling service
3017
3018 // Periodic Counter Selection packet header:
3019 // 26:31 [6] packet_family: Control Packet Family, value 0b000000
3020 // 16:25 [10] packet_id: Packet identifier, value 0b0000000100
3021 // 8:15 [8] reserved: Reserved, value 0b00000000
3022 // 0:7 [8] reserved: Reserved, value 0b00000000
3023 uint32_t packetFamily = 0;
3024 uint32_t packetId = 4;
Keith Davis3201eea2019-10-24 17:30:41 +01003025 uint32_t header = ((packetFamily & 0x0000003F) << 26) | ((packetId & 0x000003FF) << 16);
Matteo Martincighe8485382019-10-10 14:08:21 +01003026
Keith Davis3201eea2019-10-24 17:30:41 +01003027 uint32_t capturePeriod = 123456; // Some capture period (microseconds)
Matteo Martincighe8485382019-10-10 14:08:21 +01003028
3029 // Get the first valid counter UID
3030 const ICounterDirectory& counterDirectory = profilingService.GetCounterDirectory();
Keith Davis3201eea2019-10-24 17:30:41 +01003031 const Counters& counters = counterDirectory.GetCounters();
Sadik Armagan1625efc2021-06-10 18:24:34 +01003032 CHECK(counters.size() > 1);
Keith Davis3201eea2019-10-24 17:30:41 +01003033 uint16_t counterUidA = counters.begin()->first; // First valid counter UID
3034 uint16_t counterUidB = (counters.begin()++)->first; // Second valid counter UID
Matteo Martincighe8485382019-10-10 14:08:21 +01003035
3036 uint32_t length = 8;
3037
3038 auto data = std::make_unique<unsigned char[]>(length);
3039 WriteUint32(data.get(), 0, capturePeriod);
3040 WriteUint16(data.get(), 4, counterUidA);
3041 WriteUint16(data.get(), 6, counterUidB);
3042
3043 // Create the Periodic Counter Selection packet
Jim Flynnbbfe6032020-07-20 16:57:44 +01003044 // Length > 0, this will start the Period Counter Capture thread
3045 arm::pipe::Packet periodicCounterSelectionPacket(header, length, data);
Matteo Martincighe8485382019-10-10 14:08:21 +01003046
3047 // Write the packet to the mock profiling connection
3048 mockProfilingConnection->WritePacket(std::move(periodicCounterSelectionPacket));
3049
Finn Williams09ad6f92019-12-19 17:05:18 +00003050 // Expecting one PeriodicCounterSelection Packet with a length of 16
3051 // And at least one PeriodicCounterCapture Packet with a length of 28
Sadik Armagan1625efc2021-06-10 18:24:34 +01003052 CHECK(helper.WaitForPacketsSent(mockProfilingConnection, PacketType::PeriodicCounterSelection, 16) == 1);
3053 CHECK(helper.WaitForPacketsSent(mockProfilingConnection, PacketType::PeriodicCounterCapture, 28) >= 1);
Matteo Martincighe8485382019-10-10 14:08:21 +01003054
3055 // The Periodic Counter Selection Handler should not have updated the profiling state
Sadik Armagan1625efc2021-06-10 18:24:34 +01003056 CHECK(profilingService.GetCurrentState() == ProfilingState::Active);
Matteo Martincigh8efc5002019-10-10 14:30:29 +01003057
3058 // Reset the profiling service to stop any running thread
3059 options.m_EnableProfiling = false;
3060 profilingService.ResetExternalProfilingOptions(options, true);
3061}
3062
Sadik Armagan1625efc2021-06-10 18:24:34 +01003063TEST_CASE("CheckProfilingServiceDisconnect")
Jim Flynn53e46992019-10-14 12:31:10 +01003064{
Jim Flynn53e46992019-10-14 12:31:10 +01003065 // Reset the profiling service to the uninitialized state
Jim Flynn4c9ed1d2022-01-23 23:57:20 +00003066 ProfilingOptions options;
Keith Davis3201eea2019-10-24 17:30:41 +01003067 options.m_EnableProfiling = true;
Jim Flynn34430252022-03-04 15:03:58 +00003068 armnn::ArmNNProfilingServiceInitialiser initialiser;
Jim Flynn9c85b412022-03-16 00:27:43 +00003069 ProfilingService profilingService(arm::pipe::MAX_ARMNN_COUNTER,
3070 initialiser,
3071 arm::pipe::ARMNN_SOFTWARE_INFO,
3072 arm::pipe::ARMNN_SOFTWARE_VERSION,
3073 arm::pipe::ARMNN_HARDWARE_VERSION);
Jim Flynn53e46992019-10-14 12:31:10 +01003074 profilingService.ResetExternalProfilingOptions(options, true);
3075
Sadik Armagan3184c902020-03-18 10:57:30 +00003076 // Swap the profiling connection factory in the profiling service instance with our mock one
Jim Flynn34430252022-03-04 15:03:58 +00003077 SwapProfilingConnectionFactoryHelper helper(arm::pipe::MAX_ARMNN_COUNTER, initialiser, profilingService);
Sadik Armagan3184c902020-03-18 10:57:30 +00003078
Jim Flynn53e46992019-10-14 12:31:10 +01003079 // Try to disconnect the profiling service while in the "Uninitialised" state
Sadik Armagan1625efc2021-06-10 18:24:34 +01003080 CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
Jim Flynn53e46992019-10-14 12:31:10 +01003081 profilingService.Disconnect();
Sadik Armagan1625efc2021-06-10 18:24:34 +01003082 CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised); // The state should not change
Jim Flynn53e46992019-10-14 12:31:10 +01003083
3084 // Try to disconnect the profiling service while in the "NotConnected" state
Keith Davis3201eea2019-10-24 17:30:41 +01003085 profilingService.Update(); // Initialize the counter directory
Sadik Armagan1625efc2021-06-10 18:24:34 +01003086 CHECK(profilingService.GetCurrentState() == ProfilingState::NotConnected);
Jim Flynn53e46992019-10-14 12:31:10 +01003087 profilingService.Disconnect();
Sadik Armagan1625efc2021-06-10 18:24:34 +01003088 CHECK(profilingService.GetCurrentState() == ProfilingState::NotConnected); // The state should not change
Jim Flynn53e46992019-10-14 12:31:10 +01003089
3090 // Try to disconnect the profiling service while in the "WaitingForAck" state
Keith Davis3201eea2019-10-24 17:30:41 +01003091 profilingService.Update(); // Create the profiling connection
Sadik Armagan1625efc2021-06-10 18:24:34 +01003092 CHECK(profilingService.GetCurrentState() == ProfilingState::WaitingForAck);
Jim Flynn53e46992019-10-14 12:31:10 +01003093 profilingService.Disconnect();
Sadik Armagan1625efc2021-06-10 18:24:34 +01003094 CHECK(profilingService.GetCurrentState() == ProfilingState::WaitingForAck); // The state should not change
Jim Flynn53e46992019-10-14 12:31:10 +01003095
3096 // Try to disconnect the profiling service while in the "Active" state
Keith Davis3201eea2019-10-24 17:30:41 +01003097 profilingService.Update(); // Start the command handler and the send thread
Jim Flynn53e46992019-10-14 12:31:10 +01003098
Colm Donelan2ba48d22019-11-29 09:10:59 +00003099 // Get the mock profiling connection
3100 MockProfilingConnection* mockProfilingConnection = helper.GetMockProfilingConnection();
Sadik Armagan1625efc2021-06-10 18:24:34 +01003101 CHECK(mockProfilingConnection);
Colm Donelan2ba48d22019-11-29 09:10:59 +00003102
Jim Flynn53e46992019-10-14 12:31:10 +01003103 // Wait for the Stream Metadata packet the be sent
3104 // (we are not testing the connection acknowledgement here so it will be ignored by this test)
Finn Williams09ad6f92019-12-19 17:05:18 +00003105 helper.WaitForPacketsSent(mockProfilingConnection, PacketType::StreamMetaData);
Jim Flynn53e46992019-10-14 12:31:10 +01003106
3107 // Force the profiling service to the "Active" state
3108 helper.ForceTransitionToState(ProfilingState::Active);
Sadik Armagan1625efc2021-06-10 18:24:34 +01003109 CHECK(profilingService.GetCurrentState() == ProfilingState::Active);
Jim Flynn53e46992019-10-14 12:31:10 +01003110
Jim Flynn53e46992019-10-14 12:31:10 +01003111 // Check that the profiling connection is open
Sadik Armagan1625efc2021-06-10 18:24:34 +01003112 CHECK(mockProfilingConnection->IsOpen());
Jim Flynn53e46992019-10-14 12:31:10 +01003113
3114 profilingService.Disconnect();
Sadik Armagan1625efc2021-06-10 18:24:34 +01003115 CHECK(profilingService.GetCurrentState() == ProfilingState::NotConnected); // The state should have changed
Jim Flynn53e46992019-10-14 12:31:10 +01003116
3117 // Check that the profiling connection has been reset
3118 mockProfilingConnection = helper.GetMockProfilingConnection();
Sadik Armagan1625efc2021-06-10 18:24:34 +01003119 CHECK(mockProfilingConnection == nullptr);
Jim Flynn53e46992019-10-14 12:31:10 +01003120
3121 // Reset the profiling service to stop any running thread
3122 options.m_EnableProfiling = false;
3123 profilingService.ResetExternalProfilingOptions(options, true);
3124}
3125
Sadik Armagan1625efc2021-06-10 18:24:34 +01003126TEST_CASE("CheckProfilingServiceGoodPerJobCounterSelectionPacket")
Matteo Martincigh994b5342019-10-11 17:19:56 +01003127{
Matteo Martincigh994b5342019-10-11 17:19:56 +01003128 // Reset the profiling service to the uninitialized state
Jim Flynn4c9ed1d2022-01-23 23:57:20 +00003129 ProfilingOptions options;
Keith Davis3201eea2019-10-24 17:30:41 +01003130 options.m_EnableProfiling = true;
Jim Flynn34430252022-03-04 15:03:58 +00003131 armnn::ArmNNProfilingServiceInitialiser initialiser;
Jim Flynn9c85b412022-03-16 00:27:43 +00003132 ProfilingService profilingService(arm::pipe::MAX_ARMNN_COUNTER,
3133 initialiser,
3134 arm::pipe::ARMNN_SOFTWARE_INFO,
3135 arm::pipe::ARMNN_SOFTWARE_VERSION,
3136 arm::pipe::ARMNN_HARDWARE_VERSION);
Matteo Martincigh994b5342019-10-11 17:19:56 +01003137 profilingService.ResetExternalProfilingOptions(options, true);
3138
Sadik Armagan3184c902020-03-18 10:57:30 +00003139 // Swap the profiling connection factory in the profiling service instance with our mock one
Jim Flynn34430252022-03-04 15:03:58 +00003140 SwapProfilingConnectionFactoryHelper helper(arm::pipe::MAX_ARMNN_COUNTER, initialiser, profilingService);
Sadik Armagan3184c902020-03-18 10:57:30 +00003141
Matteo Martincigh994b5342019-10-11 17:19:56 +01003142 // Bring the profiling service to the "Active" state
Sadik Armagan1625efc2021-06-10 18:24:34 +01003143 CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
Keith Davis3201eea2019-10-24 17:30:41 +01003144 profilingService.Update(); // Initialize the counter directory
Sadik Armagan1625efc2021-06-10 18:24:34 +01003145 CHECK(profilingService.GetCurrentState() == ProfilingState::NotConnected);
Keith Davis3201eea2019-10-24 17:30:41 +01003146 profilingService.Update(); // Create the profiling connection
Sadik Armagan1625efc2021-06-10 18:24:34 +01003147 CHECK(profilingService.GetCurrentState() == ProfilingState::WaitingForAck);
Keith Davis3201eea2019-10-24 17:30:41 +01003148 profilingService.Update(); // Start the command handler and the send thread
Matteo Martincigh994b5342019-10-11 17:19:56 +01003149
Colm Donelan2ba48d22019-11-29 09:10:59 +00003150 // Get the mock profiling connection
3151 MockProfilingConnection* mockProfilingConnection = helper.GetMockProfilingConnection();
Sadik Armagan1625efc2021-06-10 18:24:34 +01003152 CHECK(mockProfilingConnection);
Colm Donelan2ba48d22019-11-29 09:10:59 +00003153
Matteo Martincigh994b5342019-10-11 17:19:56 +01003154 // Wait for the Stream Metadata packet the be sent
3155 // (we are not testing the connection acknowledgement here so it will be ignored by this test)
Finn Williams09ad6f92019-12-19 17:05:18 +00003156 helper.WaitForPacketsSent(mockProfilingConnection, PacketType::StreamMetaData);
Matteo Martincigh994b5342019-10-11 17:19:56 +01003157
3158 // Force the profiling service to the "Active" state
3159 helper.ForceTransitionToState(ProfilingState::Active);
Sadik Armagan1625efc2021-06-10 18:24:34 +01003160 CHECK(profilingService.GetCurrentState() == ProfilingState::Active);
Matteo Martincigh994b5342019-10-11 17:19:56 +01003161
Matteo Martincigh994b5342019-10-11 17:19:56 +01003162 // Write a "Per-Job Counter Selection" packet into the mock profiling connection, to simulate an input from an
3163 // external profiling service
3164
3165 // Per-Job Counter Selection packet header:
3166 // 26:31 [6] packet_family: Control Packet Family, value 0b000000
3167 // 16:25 [10] packet_id: Packet identifier, value 0b0000000100
3168 // 8:15 [8] reserved: Reserved, value 0b00000000
3169 // 0:7 [8] reserved: Reserved, value 0b00000000
3170 uint32_t packetFamily = 0;
3171 uint32_t packetId = 5;
Keith Davis3201eea2019-10-24 17:30:41 +01003172 uint32_t header = ((packetFamily & 0x0000003F) << 26) | ((packetId & 0x000003FF) << 16);
Matteo Martincigh994b5342019-10-11 17:19:56 +01003173
3174 // Create the Per-Job Counter Selection packet
Jim Flynnbbfe6032020-07-20 16:57:44 +01003175 // Length == 0, this will disable the collection of counters
3176 arm::pipe::Packet periodicCounterSelectionPacket(header);
Matteo Martincigh994b5342019-10-11 17:19:56 +01003177
3178 // Write the packet to the mock profiling connection
3179 mockProfilingConnection->WritePacket(std::move(periodicCounterSelectionPacket));
3180
3181 // Wait for a bit (must at least be the delay value of the mock profiling connection) to make sure that
3182 // the Per-Job Counter Selection packet gets processed by the profiling service
Colm Donelan2ba48d22019-11-29 09:10:59 +00003183 std::this_thread::sleep_for(std::chrono::milliseconds(5));
Matteo Martincigh994b5342019-10-11 17:19:56 +01003184
Matteo Martincigh994b5342019-10-11 17:19:56 +01003185 // The Per-Job Counter Selection Command Handler should not have updated the profiling state
Sadik Armagan1625efc2021-06-10 18:24:34 +01003186 CHECK(profilingService.GetCurrentState() == ProfilingState::Active);
Matteo Martincigh994b5342019-10-11 17:19:56 +01003187
Finn Williams09ad6f92019-12-19 17:05:18 +00003188 // The Per-Job Counter Selection packets are dropped silently, so there should be no reply coming
3189 // from the profiling service
3190 const auto StreamMetaDataSize = static_cast<unsigned long>(
3191 helper.WaitForPacketsSent(mockProfilingConnection, PacketType::StreamMetaData, 0, 0));
Sadik Armagan1625efc2021-06-10 18:24:34 +01003192 CHECK(StreamMetaDataSize == mockProfilingConnection->GetWrittenDataSize());
Finn Williams09ad6f92019-12-19 17:05:18 +00003193
Matteo Martincigh994b5342019-10-11 17:19:56 +01003194 // Reset the profiling service to stop any running thread
3195 options.m_EnableProfiling = false;
3196 profilingService.ResetExternalProfilingOptions(options, true);
3197}
3198
Sadik Armagan1625efc2021-06-10 18:24:34 +01003199TEST_CASE("CheckConfigureProfilingServiceOn")
Jim Flynn672d06e2019-10-15 10:18:11 +01003200{
Jim Flynn4c9ed1d2022-01-23 23:57:20 +00003201 ProfilingOptions options;
Keith Davis3201eea2019-10-24 17:30:41 +01003202 options.m_EnableProfiling = true;
Jim Flynn34430252022-03-04 15:03:58 +00003203 armnn::ArmNNProfilingServiceInitialiser initialiser;
Jim Flynn9c85b412022-03-16 00:27:43 +00003204 ProfilingService profilingService(arm::pipe::MAX_ARMNN_COUNTER,
3205 initialiser,
3206 arm::pipe::ARMNN_SOFTWARE_INFO,
3207 arm::pipe::ARMNN_SOFTWARE_VERSION,
3208 arm::pipe::ARMNN_HARDWARE_VERSION);
Sadik Armagan1625efc2021-06-10 18:24:34 +01003209 CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
Jim Flynn672d06e2019-10-15 10:18:11 +01003210 profilingService.ConfigureProfilingService(options);
3211 // should get as far as NOT_CONNECTED
Sadik Armagan1625efc2021-06-10 18:24:34 +01003212 CHECK(profilingService.GetCurrentState() == ProfilingState::NotConnected);
Jim Flynn672d06e2019-10-15 10:18:11 +01003213 // Reset the profiling service to stop any running thread
3214 options.m_EnableProfiling = false;
3215 profilingService.ResetExternalProfilingOptions(options, true);
3216}
3217
Sadik Armagan1625efc2021-06-10 18:24:34 +01003218TEST_CASE("CheckConfigureProfilingServiceOff")
Jim Flynn672d06e2019-10-15 10:18:11 +01003219{
Jim Flynn4c9ed1d2022-01-23 23:57:20 +00003220 ProfilingOptions options;
Jim Flynn34430252022-03-04 15:03:58 +00003221 armnn::ArmNNProfilingServiceInitialiser initialiser;
Jim Flynn9c85b412022-03-16 00:27:43 +00003222 ProfilingService profilingService(arm::pipe::MAX_ARMNN_COUNTER,
3223 initialiser,
3224 arm::pipe::ARMNN_SOFTWARE_INFO,
3225 arm::pipe::ARMNN_SOFTWARE_VERSION,
3226 arm::pipe::ARMNN_HARDWARE_VERSION);
Sadik Armagan1625efc2021-06-10 18:24:34 +01003227 CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
Jim Flynn672d06e2019-10-15 10:18:11 +01003228 profilingService.ConfigureProfilingService(options);
3229 // should not move from Uninitialised
Sadik Armagan1625efc2021-06-10 18:24:34 +01003230 CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
Jim Flynn672d06e2019-10-15 10:18:11 +01003231 // Reset the profiling service to stop any running thread
3232 options.m_EnableProfiling = false;
3233 profilingService.ResetExternalProfilingOptions(options, true);
3234}
3235
Sadik Armagan1625efc2021-06-10 18:24:34 +01003236TEST_CASE("CheckProfilingServiceEnabled")
Colm Donelan2ba48d22019-11-29 09:10:59 +00003237{
3238 // Locally reduce log level to "Warning", as this test needs to parse a warning message from the standard output
Jim Flynn6c9f17d2022-03-10 23:13:01 +00003239 LogLevelSwapper logLevelSwapper(arm::pipe::LogSeverity::Warning);
3240
3241 // Redirect the output to a local stream so that we can parse the warning message
3242 std::stringstream ss;
3243 StreamRedirector streamRedirector(std::cout, ss.rdbuf());
3244
Jim Flynn4c9ed1d2022-01-23 23:57:20 +00003245 ProfilingOptions options;
Colm Donelan2ba48d22019-11-29 09:10:59 +00003246 options.m_EnableProfiling = true;
Jim Flynn34430252022-03-04 15:03:58 +00003247 armnn::ArmNNProfilingServiceInitialiser initialiser;
Jim Flynn9c85b412022-03-16 00:27:43 +00003248 ProfilingService profilingService(arm::pipe::MAX_ARMNN_COUNTER,
3249 initialiser,
3250 arm::pipe::ARMNN_SOFTWARE_INFO,
3251 arm::pipe::ARMNN_SOFTWARE_VERSION,
3252 arm::pipe::ARMNN_HARDWARE_VERSION);
Colm Donelan2ba48d22019-11-29 09:10:59 +00003253 profilingService.ResetExternalProfilingOptions(options, true);
Sadik Armagan1625efc2021-06-10 18:24:34 +01003254 CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
Colm Donelan2ba48d22019-11-29 09:10:59 +00003255 profilingService.Update();
Sadik Armagan1625efc2021-06-10 18:24:34 +01003256 CHECK(profilingService.GetCurrentState() == ProfilingState::NotConnected);
Colm Donelan2ba48d22019-11-29 09:10:59 +00003257
Colm Donelan2ba48d22019-11-29 09:10:59 +00003258 profilingService.Update();
Finn Williams09ad6f92019-12-19 17:05:18 +00003259
3260 // Reset the profiling service to stop any running thread
3261 options.m_EnableProfiling = false;
3262 profilingService.ResetExternalProfilingOptions(options, true);
3263
Colm Donelan2ba48d22019-11-29 09:10:59 +00003264 streamRedirector.CancelRedirect();
3265
3266 // Check that the expected error has occurred and logged to the standard output
David Monahana8837bf2020-04-16 10:01:56 +01003267 if (ss.str().find("Cannot connect to stream socket: Connection refused") == std::string::npos)
Colm Donelan2ba48d22019-11-29 09:10:59 +00003268 {
3269 std::cout << ss.str();
Sadik Armagan1625efc2021-06-10 18:24:34 +01003270 FAIL("Expected string not found.");
Colm Donelan2ba48d22019-11-29 09:10:59 +00003271 }
Colm Donelan2ba48d22019-11-29 09:10:59 +00003272}
3273
Sadik Armagan1625efc2021-06-10 18:24:34 +01003274TEST_CASE("CheckProfilingServiceEnabledRuntime")
Colm Donelan2ba48d22019-11-29 09:10:59 +00003275{
3276 // Locally reduce log level to "Warning", as this test needs to parse a warning message from the standard output
Jim Flynn6c9f17d2022-03-10 23:13:01 +00003277 LogLevelSwapper logLevelSwapper(arm::pipe::LogSeverity::Warning);
3278
3279 // Redirect the output to a local stream so that we can parse the warning message
3280 std::stringstream ss;
3281 StreamRedirector streamRedirector(std::cout, ss.rdbuf());
3282
Jim Flynn4c9ed1d2022-01-23 23:57:20 +00003283 ProfilingOptions options;
Jim Flynn34430252022-03-04 15:03:58 +00003284 armnn::ArmNNProfilingServiceInitialiser initialiser;
Jim Flynn9c85b412022-03-16 00:27:43 +00003285 ProfilingService profilingService(arm::pipe::MAX_ARMNN_COUNTER,
3286 initialiser,
3287 arm::pipe::ARMNN_SOFTWARE_INFO,
3288 arm::pipe::ARMNN_SOFTWARE_VERSION,
3289 arm::pipe::ARMNN_HARDWARE_VERSION);
Colm Donelan2ba48d22019-11-29 09:10:59 +00003290 profilingService.ResetExternalProfilingOptions(options, true);
Sadik Armagan1625efc2021-06-10 18:24:34 +01003291 CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
Colm Donelan2ba48d22019-11-29 09:10:59 +00003292 profilingService.Update();
Sadik Armagan1625efc2021-06-10 18:24:34 +01003293 CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
Colm Donelan2ba48d22019-11-29 09:10:59 +00003294 options.m_EnableProfiling = true;
3295 profilingService.ResetExternalProfilingOptions(options);
Sadik Armagan1625efc2021-06-10 18:24:34 +01003296 CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
Colm Donelan2ba48d22019-11-29 09:10:59 +00003297 profilingService.Update();
Sadik Armagan1625efc2021-06-10 18:24:34 +01003298 CHECK(profilingService.GetCurrentState() == ProfilingState::NotConnected);
Colm Donelan2ba48d22019-11-29 09:10:59 +00003299
Colm Donelan2ba48d22019-11-29 09:10:59 +00003300 profilingService.Update();
3301
Finn Williams09ad6f92019-12-19 17:05:18 +00003302 // Reset the profiling service to stop any running thread
3303 options.m_EnableProfiling = false;
3304 profilingService.ResetExternalProfilingOptions(options, true);
3305
Colm Donelan2ba48d22019-11-29 09:10:59 +00003306 streamRedirector.CancelRedirect();
3307
3308 // Check that the expected error has occurred and logged to the standard output
David Monahana8837bf2020-04-16 10:01:56 +01003309 if (ss.str().find("Cannot connect to stream socket: Connection refused") == std::string::npos)
Colm Donelan2ba48d22019-11-29 09:10:59 +00003310 {
3311 std::cout << ss.str();
Sadik Armagan1625efc2021-06-10 18:24:34 +01003312 FAIL("Expected string not found.");
Colm Donelan2ba48d22019-11-29 09:10:59 +00003313 }
Colm Donelan2ba48d22019-11-29 09:10:59 +00003314}
3315
Sadik Armagan1625efc2021-06-10 18:24:34 +01003316TEST_CASE("CheckProfilingServiceBadConnectionAcknowledgedPacket")
Colm Donelan2ba48d22019-11-29 09:10:59 +00003317{
3318 // Locally reduce log level to "Warning", as this test needs to parse a warning message from the standard output
Jim Flynn6c9f17d2022-03-10 23:13:01 +00003319 LogLevelSwapper logLevelSwapper(arm::pipe::LogSeverity::Warning);
Colm Donelan2ba48d22019-11-29 09:10:59 +00003320
3321 // Redirect the standard output to a local stream so that we can parse the warning message
3322 std::stringstream ss;
3323 StreamRedirector streamRedirector(std::cout, ss.rdbuf());
3324
Colm Donelan2ba48d22019-11-29 09:10:59 +00003325 // Reset the profiling service to the uninitialized state
Jim Flynn4c9ed1d2022-01-23 23:57:20 +00003326 ProfilingOptions options;
Colm Donelan2ba48d22019-11-29 09:10:59 +00003327 options.m_EnableProfiling = true;
Jim Flynn34430252022-03-04 15:03:58 +00003328 armnn::ArmNNProfilingServiceInitialiser initialiser;
Jim Flynn9c85b412022-03-16 00:27:43 +00003329 ProfilingService profilingService(arm::pipe::MAX_ARMNN_COUNTER,
3330 initialiser,
3331 arm::pipe::ARMNN_SOFTWARE_INFO,
3332 arm::pipe::ARMNN_SOFTWARE_VERSION,
3333 arm::pipe::ARMNN_HARDWARE_VERSION);
Colm Donelan2ba48d22019-11-29 09:10:59 +00003334 profilingService.ResetExternalProfilingOptions(options, true);
3335
Sadik Armagan3184c902020-03-18 10:57:30 +00003336 // Swap the profiling connection factory in the profiling service instance with our mock one
Jim Flynn34430252022-03-04 15:03:58 +00003337 SwapProfilingConnectionFactoryHelper helper(arm::pipe::MAX_ARMNN_COUNTER, initialiser, profilingService);
Sadik Armagan3184c902020-03-18 10:57:30 +00003338
Colm Donelan2ba48d22019-11-29 09:10:59 +00003339 // Bring the profiling service to the "WaitingForAck" state
Sadik Armagan1625efc2021-06-10 18:24:34 +01003340 CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
Colm Donelan2ba48d22019-11-29 09:10:59 +00003341 profilingService.Update(); // Initialize the counter directory
Sadik Armagan1625efc2021-06-10 18:24:34 +01003342 CHECK(profilingService.GetCurrentState() == ProfilingState::NotConnected);
Colm Donelan2ba48d22019-11-29 09:10:59 +00003343 profilingService.Update(); // Create the profiling connection
3344
3345 // Get the mock profiling connection
3346 MockProfilingConnection* mockProfilingConnection = helper.GetMockProfilingConnection();
Sadik Armagan1625efc2021-06-10 18:24:34 +01003347 CHECK(mockProfilingConnection);
Colm Donelan2ba48d22019-11-29 09:10:59 +00003348
Sadik Armagan1625efc2021-06-10 18:24:34 +01003349 CHECK(profilingService.GetCurrentState() == ProfilingState::WaitingForAck);
Colm Donelan2ba48d22019-11-29 09:10:59 +00003350
3351 // Connection Acknowledged Packet header (word 0, word 1 is always zero):
3352 // 26:31 [6] packet_family: Control Packet Family, value 0b000000
3353 // 16:25 [10] packet_id: Packet identifier, value 0b0000000001
3354 // 8:15 [8] reserved: Reserved, value 0b00000000
3355 // 0:7 [8] reserved: Reserved, value 0b00000000
3356 uint32_t packetFamily = 0;
3357 uint32_t packetId = 37; // Wrong packet id!!!
3358 uint32_t header = ((packetFamily & 0x0000003F) << 26) | ((packetId & 0x000003FF) << 16);
3359
3360 // Create the Connection Acknowledged Packet
Jim Flynnbbfe6032020-07-20 16:57:44 +01003361 arm::pipe::Packet connectionAcknowledgedPacket(header);
Finn Williams09ad6f92019-12-19 17:05:18 +00003362 // Write an invalid "Connection Acknowledged" packet into the mock profiling connection, to simulate an invalid
3363 // reply from an external profiling service
Colm Donelan2ba48d22019-11-29 09:10:59 +00003364 mockProfilingConnection->WritePacket(std::move(connectionAcknowledgedPacket));
3365
Finn Williams09ad6f92019-12-19 17:05:18 +00003366 // Start the command thread
3367 profilingService.Update();
3368
3369 // Wait for the command thread to join
3370 options.m_EnableProfiling = false;
3371 profilingService.ResetExternalProfilingOptions(options, true);
Colm Donelan2ba48d22019-11-29 09:10:59 +00003372
3373 streamRedirector.CancelRedirect();
3374
3375 // Check that the expected error has occurred and logged to the standard output
David Monahana8837bf2020-04-16 10:01:56 +01003376 if (ss.str().find("Functor with requested PacketId=37 and Version=4194304 does not exist") == std::string::npos)
Colm Donelan2ba48d22019-11-29 09:10:59 +00003377 {
3378 std::cout << ss.str();
Sadik Armagan1625efc2021-06-10 18:24:34 +01003379 FAIL("Expected string not found.");
Colm Donelan2ba48d22019-11-29 09:10:59 +00003380 }
Colm Donelan2ba48d22019-11-29 09:10:59 +00003381}
3382
Sadik Armagan1625efc2021-06-10 18:24:34 +01003383TEST_CASE("CheckProfilingServiceBadRequestCounterDirectoryPacket")
Colm Donelan2ba48d22019-11-29 09:10:59 +00003384{
3385 // Locally reduce log level to "Warning", as this test needs to parse a warning message from the standard output
Jim Flynn6c9f17d2022-03-10 23:13:01 +00003386 LogLevelSwapper logLevelSwapper(arm::pipe::LogSeverity::Warning);
Colm Donelan2ba48d22019-11-29 09:10:59 +00003387
3388 // Redirect the standard output to a local stream so that we can parse the warning message
3389 std::stringstream ss;
3390 StreamRedirector streamRedirector(std::cout, ss.rdbuf());
3391
3392 // Reset the profiling service to the uninitialized state
Jim Flynn4c9ed1d2022-01-23 23:57:20 +00003393 ProfilingOptions options;
Colm Donelan2ba48d22019-11-29 09:10:59 +00003394 options.m_EnableProfiling = true;
Jim Flynn34430252022-03-04 15:03:58 +00003395 armnn::ArmNNProfilingServiceInitialiser initialiser;
Jim Flynn9c85b412022-03-16 00:27:43 +00003396 ProfilingService profilingService(arm::pipe::MAX_ARMNN_COUNTER,
3397 initialiser,
3398 arm::pipe::ARMNN_SOFTWARE_INFO,
3399 arm::pipe::ARMNN_SOFTWARE_VERSION,
3400 arm::pipe::ARMNN_HARDWARE_VERSION);
Colm Donelan2ba48d22019-11-29 09:10:59 +00003401 profilingService.ResetExternalProfilingOptions(options, true);
3402
Sadik Armagan3184c902020-03-18 10:57:30 +00003403 // Swap the profiling connection factory in the profiling service instance with our mock one
Jim Flynn34430252022-03-04 15:03:58 +00003404 SwapProfilingConnectionFactoryHelper helper(arm::pipe::MAX_ARMNN_COUNTER, initialiser, profilingService);
Sadik Armagan3184c902020-03-18 10:57:30 +00003405
Colm Donelan2ba48d22019-11-29 09:10:59 +00003406 // Bring the profiling service to the "Active" state
Sadik Armagan1625efc2021-06-10 18:24:34 +01003407 CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
Colm Donelan2ba48d22019-11-29 09:10:59 +00003408 helper.ForceTransitionToState(ProfilingState::NotConnected);
Sadik Armagan1625efc2021-06-10 18:24:34 +01003409 CHECK(profilingService.GetCurrentState() == ProfilingState::NotConnected);
Colm Donelan2ba48d22019-11-29 09:10:59 +00003410 profilingService.Update(); // Create the profiling connection
Sadik Armagan1625efc2021-06-10 18:24:34 +01003411 CHECK(profilingService.GetCurrentState() == ProfilingState::WaitingForAck);
Colm Donelan2ba48d22019-11-29 09:10:59 +00003412
3413 // Get the mock profiling connection
3414 MockProfilingConnection* mockProfilingConnection = helper.GetMockProfilingConnection();
Sadik Armagan1625efc2021-06-10 18:24:34 +01003415 CHECK(mockProfilingConnection);
Colm Donelan2ba48d22019-11-29 09:10:59 +00003416
Colm Donelan2ba48d22019-11-29 09:10:59 +00003417 // Write a valid "Request Counter Directory" packet into the mock profiling connection, to simulate a valid
3418 // reply from an external profiling service
3419
3420 // Request Counter Directory packet header (word 0, word 1 is always zero):
3421 // 26:31 [6] packet_family: Control Packet Family, value 0b000000
3422 // 16:25 [10] packet_id: Packet identifier, value 0b0000000011
3423 // 8:15 [8] reserved: Reserved, value 0b00000000
3424 // 0:7 [8] reserved: Reserved, value 0b00000000
3425 uint32_t packetFamily = 0;
3426 uint32_t packetId = 123; // Wrong packet id!!!
3427 uint32_t header = ((packetFamily & 0x0000003F) << 26) | ((packetId & 0x000003FF) << 16);
3428
3429 // Create the Request Counter Directory packet
Jim Flynnbbfe6032020-07-20 16:57:44 +01003430 arm::pipe::Packet requestCounterDirectoryPacket(header);
Colm Donelan2ba48d22019-11-29 09:10:59 +00003431
3432 // Write the packet to the mock profiling connection
3433 mockProfilingConnection->WritePacket(std::move(requestCounterDirectoryPacket));
3434
Finn Williams09ad6f92019-12-19 17:05:18 +00003435 // Start the command handler and the send thread
3436 profilingService.Update();
3437
3438 // Reset the profiling service to stop and join any running thread
3439 options.m_EnableProfiling = false;
3440 profilingService.ResetExternalProfilingOptions(options, true);
Colm Donelan2ba48d22019-11-29 09:10:59 +00003441
3442 streamRedirector.CancelRedirect();
3443
3444 // Check that the expected error has occurred and logged to the standard output
David Monahana8837bf2020-04-16 10:01:56 +01003445 if (ss.str().find("Functor with requested PacketId=123 and Version=4194304 does not exist") == std::string::npos)
Colm Donelan2ba48d22019-11-29 09:10:59 +00003446 {
3447 std::cout << ss.str();
Sadik Armagan1625efc2021-06-10 18:24:34 +01003448 FAIL("Expected string not found.");
Colm Donelan2ba48d22019-11-29 09:10:59 +00003449 }
Colm Donelan2ba48d22019-11-29 09:10:59 +00003450}
3451
Sadik Armagan1625efc2021-06-10 18:24:34 +01003452TEST_CASE("CheckProfilingServiceBadPeriodicCounterSelectionPacket")
Colm Donelan2ba48d22019-11-29 09:10:59 +00003453{
3454 // Locally reduce log level to "Warning", as this test needs to parse a warning message from the standard output
Jim Flynn6c9f17d2022-03-10 23:13:01 +00003455 LogLevelSwapper logLevelSwapper(arm::pipe::LogSeverity::Warning);
Colm Donelan2ba48d22019-11-29 09:10:59 +00003456
3457 // Redirect the standard output to a local stream so that we can parse the warning message
3458 std::stringstream ss;
3459 StreamRedirector streamRedirector(std::cout, ss.rdbuf());
3460
3461 // Reset the profiling service to the uninitialized state
Jim Flynn4c9ed1d2022-01-23 23:57:20 +00003462 ProfilingOptions options;
Colm Donelan2ba48d22019-11-29 09:10:59 +00003463 options.m_EnableProfiling = true;
Jim Flynn34430252022-03-04 15:03:58 +00003464 armnn::ArmNNProfilingServiceInitialiser initialiser;
Jim Flynn9c85b412022-03-16 00:27:43 +00003465 ProfilingService profilingService(arm::pipe::MAX_ARMNN_COUNTER,
3466 initialiser,
3467 arm::pipe::ARMNN_SOFTWARE_INFO,
3468 arm::pipe::ARMNN_SOFTWARE_VERSION,
3469 arm::pipe::ARMNN_HARDWARE_VERSION);
Colm Donelan2ba48d22019-11-29 09:10:59 +00003470 profilingService.ResetExternalProfilingOptions(options, true);
3471
Sadik Armagan3184c902020-03-18 10:57:30 +00003472 // Swap the profiling connection factory in the profiling service instance with our mock one
Jim Flynn34430252022-03-04 15:03:58 +00003473 SwapProfilingConnectionFactoryHelper helper(arm::pipe::MAX_ARMNN_COUNTER, initialiser, profilingService);
Sadik Armagan3184c902020-03-18 10:57:30 +00003474
Colm Donelan2ba48d22019-11-29 09:10:59 +00003475 // Bring the profiling service to the "Active" state
Sadik Armagan1625efc2021-06-10 18:24:34 +01003476 CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
Colm Donelan2ba48d22019-11-29 09:10:59 +00003477 profilingService.Update(); // Initialize the counter directory
Sadik Armagan1625efc2021-06-10 18:24:34 +01003478 CHECK(profilingService.GetCurrentState() == ProfilingState::NotConnected);
Colm Donelan2ba48d22019-11-29 09:10:59 +00003479 profilingService.Update(); // Create the profiling connection
Sadik Armagan1625efc2021-06-10 18:24:34 +01003480 CHECK(profilingService.GetCurrentState() == ProfilingState::WaitingForAck);
Colm Donelan2ba48d22019-11-29 09:10:59 +00003481 profilingService.Update(); // Start the command handler and the send thread
3482
3483 // Get the mock profiling connection
3484 MockProfilingConnection* mockProfilingConnection = helper.GetMockProfilingConnection();
Sadik Armagan1625efc2021-06-10 18:24:34 +01003485 CHECK(mockProfilingConnection);
Colm Donelan2ba48d22019-11-29 09:10:59 +00003486
Colm Donelan2ba48d22019-11-29 09:10:59 +00003487 // Write a "Periodic Counter Selection" packet into the mock profiling connection, to simulate an input from an
3488 // external profiling service
3489
3490 // Periodic Counter Selection packet header:
3491 // 26:31 [6] packet_family: Control Packet Family, value 0b000000
3492 // 16:25 [10] packet_id: Packet identifier, value 0b0000000100
3493 // 8:15 [8] reserved: Reserved, value 0b00000000
3494 // 0:7 [8] reserved: Reserved, value 0b00000000
3495 uint32_t packetFamily = 0;
3496 uint32_t packetId = 999; // Wrong packet id!!!
3497 uint32_t header = ((packetFamily & 0x0000003F) << 26) | ((packetId & 0x000003FF) << 16);
3498
3499 // Create the Periodic Counter Selection packet
Jim Flynnbbfe6032020-07-20 16:57:44 +01003500 // Length == 0, this will disable the collection of counters
3501 arm::pipe::Packet periodicCounterSelectionPacket(header);
Colm Donelan2ba48d22019-11-29 09:10:59 +00003502
3503 // Write the packet to the mock profiling connection
3504 mockProfilingConnection->WritePacket(std::move(periodicCounterSelectionPacket));
Finn Williams09ad6f92019-12-19 17:05:18 +00003505 profilingService.Update();
Colm Donelan2ba48d22019-11-29 09:10:59 +00003506
Finn Williams09ad6f92019-12-19 17:05:18 +00003507 // Reset the profiling service to stop any running thread
3508 options.m_EnableProfiling = false;
3509 profilingService.ResetExternalProfilingOptions(options, true);
Colm Donelan2ba48d22019-11-29 09:10:59 +00003510
3511 // Check that the expected error has occurred and logged to the standard output
3512 streamRedirector.CancelRedirect();
3513
3514 // Check that the expected error has occurred and logged to the standard output
David Monahana8837bf2020-04-16 10:01:56 +01003515 if (ss.str().find("Functor with requested PacketId=999 and Version=4194304 does not exist") == std::string::npos)
Colm Donelan2ba48d22019-11-29 09:10:59 +00003516 {
3517 std::cout << ss.str();
Sadik Armagan1625efc2021-06-10 18:24:34 +01003518 FAIL("Expected string not found.");
Colm Donelan2ba48d22019-11-29 09:10:59 +00003519 }
Colm Donelan2ba48d22019-11-29 09:10:59 +00003520}
Jim Flynn97897022020-02-02 12:52:59 +00003521
Sadik Armagan1625efc2021-06-10 18:24:34 +01003522TEST_CASE("CheckCounterIdMap")
David Monahande803072020-01-30 12:44:23 +00003523{
3524 CounterIdMap counterIdMap;
Jim Flynnf9db3ef2022-03-08 21:23:44 +00003525 CHECK_THROWS_AS(counterIdMap.GetBackendId(0), arm::pipe::ProfilingException);
3526 CHECK_THROWS_AS(counterIdMap.GetGlobalId(0, armnn::profiling::BACKEND_ID), arm::pipe::ProfilingException);
David Monahande803072020-01-30 12:44:23 +00003527
3528 uint16_t globalCounterIds = 0;
3529
Cathal Corbett6f073722022-03-04 12:11:09 +00003530 std::string cpuRefId(GetComputeDeviceAsCString(armnn::Compute::CpuRef));
3531 std::string cpuAccId(GetComputeDeviceAsCString(armnn::Compute::CpuAcc));
David Monahande803072020-01-30 12:44:23 +00003532
3533 std::vector<uint16_t> cpuRefCounters = {0, 1, 2, 3};
3534 std::vector<uint16_t> cpuAccCounters = {0, 1};
3535
3536 for (uint16_t backendCounterId : cpuRefCounters)
3537 {
3538 counterIdMap.RegisterMapping(globalCounterIds, backendCounterId, cpuRefId);
3539 ++globalCounterIds;
3540 }
3541 for (uint16_t backendCounterId : cpuAccCounters)
3542 {
3543 counterIdMap.RegisterMapping(globalCounterIds, backendCounterId, cpuAccId);
3544 ++globalCounterIds;
3545 }
3546
Cathal Corbett6f073722022-03-04 12:11:09 +00003547 CHECK(counterIdMap.GetBackendId(0) == (std::pair<uint16_t, std::string>(0, cpuRefId)));
3548 CHECK(counterIdMap.GetBackendId(1) == (std::pair<uint16_t, std::string>(1, cpuRefId)));
3549 CHECK(counterIdMap.GetBackendId(2) == (std::pair<uint16_t, std::string>(2, cpuRefId)));
3550 CHECK(counterIdMap.GetBackendId(3) == (std::pair<uint16_t, std::string>(3, cpuRefId)));
3551 CHECK(counterIdMap.GetBackendId(4) == (std::pair<uint16_t, std::string>(0, cpuAccId)));
3552 CHECK(counterIdMap.GetBackendId(5) == (std::pair<uint16_t, std::string>(1, cpuAccId)));
David Monahande803072020-01-30 12:44:23 +00003553
Sadik Armagan1625efc2021-06-10 18:24:34 +01003554 CHECK(counterIdMap.GetGlobalId(0, cpuRefId) == 0);
3555 CHECK(counterIdMap.GetGlobalId(1, cpuRefId) == 1);
3556 CHECK(counterIdMap.GetGlobalId(2, cpuRefId) == 2);
3557 CHECK(counterIdMap.GetGlobalId(3, cpuRefId) == 3);
3558 CHECK(counterIdMap.GetGlobalId(0, cpuAccId) == 4);
3559 CHECK(counterIdMap.GetGlobalId(1, cpuAccId) == 5);
David Monahande803072020-01-30 12:44:23 +00003560}
Colm Donelan2ba48d22019-11-29 09:10:59 +00003561
Sadik Armagan1625efc2021-06-10 18:24:34 +01003562TEST_CASE("CheckRegisterBackendCounters")
Jim Flynn97897022020-02-02 12:52:59 +00003563{
Cathal Corbett5aa9fd72022-02-25 15:33:28 +00003564 uint16_t globalCounterIds = INFERENCES_RUN;
Cathal Corbett6f073722022-03-04 12:11:09 +00003565 std::string cpuRefId(GetComputeDeviceAsCString(armnn::Compute::CpuRef));
Jim Flynn97897022020-02-02 12:52:59 +00003566
Jim Flynn97897022020-02-02 12:52:59 +00003567 // Reset the profiling service to the uninitialized state
Jim Flynn4c9ed1d2022-01-23 23:57:20 +00003568 ProfilingOptions options;
Jim Flynn97897022020-02-02 12:52:59 +00003569 options.m_EnableProfiling = true;
Jim Flynn34430252022-03-04 15:03:58 +00003570 armnn::ArmNNProfilingServiceInitialiser initialiser;
Jim Flynn9c85b412022-03-16 00:27:43 +00003571 ProfilingService profilingService(arm::pipe::MAX_ARMNN_COUNTER,
3572 initialiser,
3573 arm::pipe::ARMNN_SOFTWARE_INFO,
3574 arm::pipe::ARMNN_SOFTWARE_VERSION,
3575 arm::pipe::ARMNN_HARDWARE_VERSION);
Jim Flynn97897022020-02-02 12:52:59 +00003576 profilingService.ResetExternalProfilingOptions(options, true);
3577
Sadik Armagan3184c902020-03-18 10:57:30 +00003578 RegisterBackendCounters registerBackendCounters(globalCounterIds, cpuRefId, profilingService);
3579
3580
3581
Sadik Armagan1625efc2021-06-10 18:24:34 +01003582 CHECK(profilingService.GetCounterDirectory().GetCategories().empty());
Jim Flynn97897022020-02-02 12:52:59 +00003583 registerBackendCounters.RegisterCategory("categoryOne");
3584 auto categoryOnePtr = profilingService.GetCounterDirectory().GetCategory("categoryOne");
Sadik Armagan1625efc2021-06-10 18:24:34 +01003585 CHECK(categoryOnePtr);
Jim Flynn97897022020-02-02 12:52:59 +00003586
Sadik Armagan1625efc2021-06-10 18:24:34 +01003587 CHECK(profilingService.GetCounterDirectory().GetDevices().empty());
Jim Flynn97897022020-02-02 12:52:59 +00003588 globalCounterIds = registerBackendCounters.RegisterDevice("deviceOne");
3589 auto deviceOnePtr = profilingService.GetCounterDirectory().GetDevice(globalCounterIds);
Sadik Armagan1625efc2021-06-10 18:24:34 +01003590 CHECK(deviceOnePtr);
3591 CHECK(deviceOnePtr->m_Name == "deviceOne");
Jim Flynn97897022020-02-02 12:52:59 +00003592
Sadik Armagan1625efc2021-06-10 18:24:34 +01003593 CHECK(profilingService.GetCounterDirectory().GetCounterSets().empty());
Jim Flynn97897022020-02-02 12:52:59 +00003594 globalCounterIds = registerBackendCounters.RegisterCounterSet("counterSetOne");
3595 auto counterSetOnePtr = profilingService.GetCounterDirectory().GetCounterSet(globalCounterIds);
Sadik Armagan1625efc2021-06-10 18:24:34 +01003596 CHECK(counterSetOnePtr);
3597 CHECK(counterSetOnePtr->m_Name == "counterSetOne");
Jim Flynn97897022020-02-02 12:52:59 +00003598
3599 uint16_t newGlobalCounterId = registerBackendCounters.RegisterCounter(0,
3600 "categoryOne",
3601 0,
3602 0,
3603 1.f,
3604 "CounterOne",
3605 "first test counter");
Cathal Corbett5aa9fd72022-02-25 15:33:28 +00003606 CHECK((newGlobalCounterId = INFERENCES_RUN + 1));
Jim Flynn97897022020-02-02 12:52:59 +00003607 uint16_t mappedGlobalId = profilingService.GetCounterMappings().GetGlobalId(0, cpuRefId);
Sadik Armagan1625efc2021-06-10 18:24:34 +01003608 CHECK(mappedGlobalId == newGlobalCounterId);
Jim Flynn97897022020-02-02 12:52:59 +00003609 auto backendMapping = profilingService.GetCounterMappings().GetBackendId(newGlobalCounterId);
Sadik Armagan1625efc2021-06-10 18:24:34 +01003610 CHECK(backendMapping.first == 0);
3611 CHECK(backendMapping.second == cpuRefId);
Jim Flynn97897022020-02-02 12:52:59 +00003612
3613 // Reset the profiling service to stop any running thread
3614 options.m_EnableProfiling = false;
3615 profilingService.ResetExternalProfilingOptions(options, true);
3616}
3617
Sadik Armagan1625efc2021-06-10 18:24:34 +01003618TEST_CASE("CheckCounterStatusQuery")
James Conroy2dcd3fe2020-02-06 18:34:52 +00003619{
Jim Flynn4c9ed1d2022-01-23 23:57:20 +00003620 ProfilingOptions options;
3621 options.m_EnableProfiling = true;
James Conroy2dcd3fe2020-02-06 18:34:52 +00003622
3623 // Reset the profiling service to the uninitialized state
Jim Flynn34430252022-03-04 15:03:58 +00003624 armnn::ArmNNProfilingServiceInitialiser initialiser;
Jim Flynn9c85b412022-03-16 00:27:43 +00003625 ProfilingService profilingService(arm::pipe::MAX_ARMNN_COUNTER,
3626 initialiser,
3627 arm::pipe::ARMNN_SOFTWARE_INFO,
3628 arm::pipe::ARMNN_SOFTWARE_VERSION,
3629 arm::pipe::ARMNN_HARDWARE_VERSION);
Jim Flynn4c9ed1d2022-01-23 23:57:20 +00003630 profilingService.ResetExternalProfilingOptions(options, true);
James Conroy2dcd3fe2020-02-06 18:34:52 +00003631
Cathal Corbett6f073722022-03-04 12:11:09 +00003632 const std::string cpuRefId(GetComputeDeviceAsCString(armnn::Compute::CpuRef));
3633 const std::string cpuAccId(GetComputeDeviceAsCString(armnn::Compute::CpuAcc));
James Conroy2dcd3fe2020-02-06 18:34:52 +00003634
3635 // Create BackendProfiling for each backend
3636 BackendProfiling backendProfilingCpuRef(options, profilingService, cpuRefId);
3637 BackendProfiling backendProfilingCpuAcc(options, profilingService, cpuAccId);
3638
Cathal Corbett5aa9fd72022-02-25 15:33:28 +00003639 uint16_t initialNumGlobalCounterIds = INFERENCES_RUN;
James Conroy2dcd3fe2020-02-06 18:34:52 +00003640
3641 // Create RegisterBackendCounters for CpuRef
Sadik Armagan3184c902020-03-18 10:57:30 +00003642 RegisterBackendCounters registerBackendCountersCpuRef(initialNumGlobalCounterIds, cpuRefId, profilingService);
James Conroy2dcd3fe2020-02-06 18:34:52 +00003643
3644 // Create 'testCategory' in CounterDirectory (backend agnostic)
Sadik Armagan1625efc2021-06-10 18:24:34 +01003645 CHECK(profilingService.GetCounterDirectory().GetCategories().empty());
James Conroy2dcd3fe2020-02-06 18:34:52 +00003646 registerBackendCountersCpuRef.RegisterCategory("testCategory");
3647 auto categoryOnePtr = profilingService.GetCounterDirectory().GetCategory("testCategory");
Sadik Armagan1625efc2021-06-10 18:24:34 +01003648 CHECK(categoryOnePtr);
James Conroy2dcd3fe2020-02-06 18:34:52 +00003649
3650 // Counters:
3651 // Global | Local | Backend
3652 // 5 | 0 | CpuRef
3653 // 6 | 1 | CpuRef
3654 // 7 | 1 | CpuAcc
3655
3656 std::vector<uint16_t> cpuRefCounters = {0, 1};
3657 std::vector<uint16_t> cpuAccCounters = {0};
3658
3659 // Register the backend counters for CpuRef and validate GetGlobalId and GetBackendId
3660 uint16_t currentNumGlobalCounterIds = registerBackendCountersCpuRef.RegisterCounter(
3661 0, "testCategory", 0, 0, 1.f, "CpuRefCounter0", "Zeroth CpuRef Counter");
Sadik Armagan1625efc2021-06-10 18:24:34 +01003662 CHECK(currentNumGlobalCounterIds == initialNumGlobalCounterIds + 1);
James Conroy2dcd3fe2020-02-06 18:34:52 +00003663 uint16_t mappedGlobalId = profilingService.GetCounterMappings().GetGlobalId(0, cpuRefId);
Sadik Armagan1625efc2021-06-10 18:24:34 +01003664 CHECK(mappedGlobalId == currentNumGlobalCounterIds);
James Conroy2dcd3fe2020-02-06 18:34:52 +00003665 auto backendMapping = profilingService.GetCounterMappings().GetBackendId(currentNumGlobalCounterIds);
Sadik Armagan1625efc2021-06-10 18:24:34 +01003666 CHECK(backendMapping.first == 0);
3667 CHECK(backendMapping.second == cpuRefId);
James Conroy2dcd3fe2020-02-06 18:34:52 +00003668
3669 currentNumGlobalCounterIds = registerBackendCountersCpuRef.RegisterCounter(
3670 1, "testCategory", 0, 0, 1.f, "CpuRefCounter1", "First CpuRef Counter");
Sadik Armagan1625efc2021-06-10 18:24:34 +01003671 CHECK(currentNumGlobalCounterIds == initialNumGlobalCounterIds + 2);
James Conroy2dcd3fe2020-02-06 18:34:52 +00003672 mappedGlobalId = profilingService.GetCounterMappings().GetGlobalId(1, cpuRefId);
Sadik Armagan1625efc2021-06-10 18:24:34 +01003673 CHECK(mappedGlobalId == currentNumGlobalCounterIds);
James Conroy2dcd3fe2020-02-06 18:34:52 +00003674 backendMapping = profilingService.GetCounterMappings().GetBackendId(currentNumGlobalCounterIds);
Sadik Armagan1625efc2021-06-10 18:24:34 +01003675 CHECK(backendMapping.first == 1);
3676 CHECK(backendMapping.second == cpuRefId);
James Conroy2dcd3fe2020-02-06 18:34:52 +00003677
3678 // Create RegisterBackendCounters for CpuAcc
Sadik Armagan3184c902020-03-18 10:57:30 +00003679 RegisterBackendCounters registerBackendCountersCpuAcc(currentNumGlobalCounterIds, cpuAccId, profilingService);
James Conroy2dcd3fe2020-02-06 18:34:52 +00003680
3681 // Register the backend counter for CpuAcc and validate GetGlobalId and GetBackendId
3682 currentNumGlobalCounterIds = registerBackendCountersCpuAcc.RegisterCounter(
3683 0, "testCategory", 0, 0, 1.f, "CpuAccCounter0", "Zeroth CpuAcc Counter");
Sadik Armagan1625efc2021-06-10 18:24:34 +01003684 CHECK(currentNumGlobalCounterIds == initialNumGlobalCounterIds + 3);
James Conroy2dcd3fe2020-02-06 18:34:52 +00003685 mappedGlobalId = profilingService.GetCounterMappings().GetGlobalId(0, cpuAccId);
Sadik Armagan1625efc2021-06-10 18:24:34 +01003686 CHECK(mappedGlobalId == currentNumGlobalCounterIds);
James Conroy2dcd3fe2020-02-06 18:34:52 +00003687 backendMapping = profilingService.GetCounterMappings().GetBackendId(currentNumGlobalCounterIds);
Sadik Armagan1625efc2021-06-10 18:24:34 +01003688 CHECK(backendMapping.first == 0);
3689 CHECK(backendMapping.second == cpuAccId);
James Conroy2dcd3fe2020-02-06 18:34:52 +00003690
3691 // Create vectors for active counters
3692 const std::vector<uint16_t> activeGlobalCounterIds = {5}; // CpuRef(0) activated
3693 const std::vector<uint16_t> newActiveGlobalCounterIds = {6, 7}; // CpuRef(0) and CpuAcc(1) activated
3694
3695 const uint32_t capturePeriod = 200;
3696 const uint32_t newCapturePeriod = 100;
3697
3698 // Set capture period and active counters in CaptureData
Finn Williams032bc742020-02-12 11:02:34 +00003699 profilingService.SetCaptureData(capturePeriod, activeGlobalCounterIds, {});
James Conroy2dcd3fe2020-02-06 18:34:52 +00003700
3701 // Get vector of active counters for CpuRef and CpuAcc backends
3702 std::vector<CounterStatus> cpuRefCounterStatus = backendProfilingCpuRef.GetActiveCounters();
3703 std::vector<CounterStatus> cpuAccCounterStatus = backendProfilingCpuAcc.GetActiveCounters();
Sadik Armagan1625efc2021-06-10 18:24:34 +01003704 CHECK_EQ(cpuRefCounterStatus.size(), 1);
3705 CHECK_EQ(cpuAccCounterStatus.size(), 0);
James Conroy2dcd3fe2020-02-06 18:34:52 +00003706
3707 // Check active CpuRef counter
Sadik Armagan1625efc2021-06-10 18:24:34 +01003708 CHECK_EQ(cpuRefCounterStatus[0].m_GlobalCounterId, activeGlobalCounterIds[0]);
3709 CHECK_EQ(cpuRefCounterStatus[0].m_BackendCounterId, cpuRefCounters[0]);
3710 CHECK_EQ(cpuRefCounterStatus[0].m_SamplingRateInMicroseconds, capturePeriod);
3711 CHECK_EQ(cpuRefCounterStatus[0].m_Enabled, true);
James Conroy2dcd3fe2020-02-06 18:34:52 +00003712
3713 // Check inactive CpuRef counter
3714 CounterStatus inactiveCpuRefCounter = backendProfilingCpuRef.GetCounterStatus(cpuRefCounters[1]);
Sadik Armagan1625efc2021-06-10 18:24:34 +01003715 CHECK_EQ(inactiveCpuRefCounter.m_GlobalCounterId, 6);
3716 CHECK_EQ(inactiveCpuRefCounter.m_BackendCounterId, cpuRefCounters[1]);
3717 CHECK_EQ(inactiveCpuRefCounter.m_SamplingRateInMicroseconds, 0);
3718 CHECK_EQ(inactiveCpuRefCounter.m_Enabled, false);
James Conroy2dcd3fe2020-02-06 18:34:52 +00003719
3720 // Check inactive CpuAcc counter
3721 CounterStatus inactiveCpuAccCounter = backendProfilingCpuAcc.GetCounterStatus(cpuAccCounters[0]);
Sadik Armagan1625efc2021-06-10 18:24:34 +01003722 CHECK_EQ(inactiveCpuAccCounter.m_GlobalCounterId, 7);
3723 CHECK_EQ(inactiveCpuAccCounter.m_BackendCounterId, cpuAccCounters[0]);
3724 CHECK_EQ(inactiveCpuAccCounter.m_SamplingRateInMicroseconds, 0);
3725 CHECK_EQ(inactiveCpuAccCounter.m_Enabled, false);
James Conroy2dcd3fe2020-02-06 18:34:52 +00003726
3727 // Set new capture period and new active counters in CaptureData
Finn Williams032bc742020-02-12 11:02:34 +00003728 profilingService.SetCaptureData(newCapturePeriod, newActiveGlobalCounterIds, {});
James Conroy2dcd3fe2020-02-06 18:34:52 +00003729
3730 // Get vector of active counters for CpuRef and CpuAcc backends
3731 cpuRefCounterStatus = backendProfilingCpuRef.GetActiveCounters();
3732 cpuAccCounterStatus = backendProfilingCpuAcc.GetActiveCounters();
Sadik Armagan1625efc2021-06-10 18:24:34 +01003733 CHECK_EQ(cpuRefCounterStatus.size(), 1);
3734 CHECK_EQ(cpuAccCounterStatus.size(), 1);
James Conroy2dcd3fe2020-02-06 18:34:52 +00003735
3736 // Check active CpuRef counter
Sadik Armagan1625efc2021-06-10 18:24:34 +01003737 CHECK_EQ(cpuRefCounterStatus[0].m_GlobalCounterId, newActiveGlobalCounterIds[0]);
3738 CHECK_EQ(cpuRefCounterStatus[0].m_BackendCounterId, cpuRefCounters[1]);
3739 CHECK_EQ(cpuRefCounterStatus[0].m_SamplingRateInMicroseconds, newCapturePeriod);
3740 CHECK_EQ(cpuRefCounterStatus[0].m_Enabled, true);
James Conroy2dcd3fe2020-02-06 18:34:52 +00003741
3742 // Check active CpuAcc counter
Sadik Armagan1625efc2021-06-10 18:24:34 +01003743 CHECK_EQ(cpuAccCounterStatus[0].m_GlobalCounterId, newActiveGlobalCounterIds[1]);
3744 CHECK_EQ(cpuAccCounterStatus[0].m_BackendCounterId, cpuAccCounters[0]);
3745 CHECK_EQ(cpuAccCounterStatus[0].m_SamplingRateInMicroseconds, newCapturePeriod);
3746 CHECK_EQ(cpuAccCounterStatus[0].m_Enabled, true);
James Conroy2dcd3fe2020-02-06 18:34:52 +00003747
3748 // Check inactive CpuRef counter
3749 inactiveCpuRefCounter = backendProfilingCpuRef.GetCounterStatus(cpuRefCounters[0]);
Sadik Armagan1625efc2021-06-10 18:24:34 +01003750 CHECK_EQ(inactiveCpuRefCounter.m_GlobalCounterId, 5);
3751 CHECK_EQ(inactiveCpuRefCounter.m_BackendCounterId, cpuRefCounters[0]);
3752 CHECK_EQ(inactiveCpuRefCounter.m_SamplingRateInMicroseconds, 0);
3753 CHECK_EQ(inactiveCpuRefCounter.m_Enabled, false);
James Conroy2dcd3fe2020-02-06 18:34:52 +00003754
3755 // Reset the profiling service to stop any running thread
Jim Flynn4c9ed1d2022-01-23 23:57:20 +00003756 options.m_EnableProfiling = false;
3757 profilingService.ResetExternalProfilingOptions(options, true);
James Conroy2dcd3fe2020-02-06 18:34:52 +00003758}
3759
Sadik Armagan1625efc2021-06-10 18:24:34 +01003760TEST_CASE("CheckRegisterCounters")
Sadik Armagancab588a2020-02-17 11:33:31 +00003761{
Jim Flynn4c9ed1d2022-01-23 23:57:20 +00003762 ProfilingOptions options;
3763 options.m_EnableProfiling = true;
Sadik Armagancab588a2020-02-17 11:33:31 +00003764 MockBufferManager mockBuffer(1024);
Sadik Armagan3184c902020-03-18 10:57:30 +00003765
Sadik Armagancab588a2020-02-17 11:33:31 +00003766 CaptureData captureData;
Jim Flynn34430252022-03-04 15:03:58 +00003767
3768 armnn::ArmNNProfilingServiceInitialiser initialiser;
3769 MockProfilingService mockProfilingService(
3770 arm::pipe::MAX_ARMNN_COUNTER, initialiser, mockBuffer, options.m_EnableProfiling, captureData);
Cathal Corbett6f073722022-03-04 12:11:09 +00003771 std::string cpuRefId(GetComputeDeviceAsCString(armnn::Compute::CpuRef));
Sadik Armagancab588a2020-02-17 11:33:31 +00003772
3773 mockProfilingService.RegisterMapping(6, 0, cpuRefId);
3774 mockProfilingService.RegisterMapping(7, 1, cpuRefId);
3775 mockProfilingService.RegisterMapping(8, 2, cpuRefId);
3776
Cathal Corbett5aa9fd72022-02-25 15:33:28 +00003777 BackendProfiling backendProfiling(options,
Sadik Armagancab588a2020-02-17 11:33:31 +00003778 mockProfilingService,
3779 cpuRefId);
3780
Cathal Corbett5aa9fd72022-02-25 15:33:28 +00003781 Timestamp timestamp;
Sadik Armagancab588a2020-02-17 11:33:31 +00003782 timestamp.timestamp = 1000998;
3783 timestamp.counterValues.emplace_back(0, 700);
3784 timestamp.counterValues.emplace_back(2, 93);
Cathal Corbett5aa9fd72022-02-25 15:33:28 +00003785 std::vector<Timestamp> timestamps;
Sadik Armagancab588a2020-02-17 11:33:31 +00003786 timestamps.push_back(timestamp);
3787 backendProfiling.ReportCounters(timestamps);
3788
3789 auto readBuffer = mockBuffer.GetReadableBuffer();
3790
3791 uint32_t headerWord0 = ReadUint32(readBuffer, 0);
3792 uint32_t headerWord1 = ReadUint32(readBuffer, 4);
3793 uint64_t readTimestamp = ReadUint64(readBuffer, 8);
3794
Sadik Armagan1625efc2021-06-10 18:24:34 +01003795 CHECK(((headerWord0 >> 26) & 0x0000003F) == 3); // packet family
3796 CHECK(((headerWord0 >> 19) & 0x0000007F) == 0); // packet class
3797 CHECK(((headerWord0 >> 16) & 0x00000007) == 0); // packet type
3798 CHECK(headerWord1 == 20); // data length
3799 CHECK(1000998 == readTimestamp); // capture period
Sadik Armagancab588a2020-02-17 11:33:31 +00003800
3801 uint32_t offset = 16;
3802 // Check Counter Index
3803 uint16_t readIndex = ReadUint16(readBuffer, offset);
Sadik Armagan1625efc2021-06-10 18:24:34 +01003804 CHECK(6 == readIndex);
Sadik Armagancab588a2020-02-17 11:33:31 +00003805
3806 // Check Counter Value
3807 offset += 2;
3808 uint32_t readValue = ReadUint32(readBuffer, offset);
Sadik Armagan1625efc2021-06-10 18:24:34 +01003809 CHECK(700 == readValue);
Sadik Armagancab588a2020-02-17 11:33:31 +00003810
3811 // Check Counter Index
3812 offset += 4;
3813 readIndex = ReadUint16(readBuffer, offset);
Sadik Armagan1625efc2021-06-10 18:24:34 +01003814 CHECK(8 == readIndex);
Sadik Armagancab588a2020-02-17 11:33:31 +00003815
3816 // Check Counter Value
3817 offset += 2;
3818 readValue = ReadUint32(readBuffer, offset);
Sadik Armagan1625efc2021-06-10 18:24:34 +01003819 CHECK(93 == readValue);
Sadik Armagancab588a2020-02-17 11:33:31 +00003820}
3821
Sadik Armagan1625efc2021-06-10 18:24:34 +01003822TEST_CASE("CheckFileFormat") {
Isabella Gottardia0687ee2020-03-11 18:04:20 +00003823 // Locally reduce log level to "Warning", as this test needs to parse a warning message from the standard output
Jim Flynn6c9f17d2022-03-10 23:13:01 +00003824 LogLevelSwapper logLevelSwapper(arm::pipe::LogSeverity::Warning);
3825
3826 // Redirect the output to a local stream so that we can parse the warning message
3827 std::stringstream ss;
3828 StreamRedirector streamRedirector(std::cout, ss.rdbuf());
Isabella Gottardia0687ee2020-03-11 18:04:20 +00003829
3830 // Create profiling options.
Jim Flynn4c9ed1d2022-01-23 23:57:20 +00003831 ProfilingOptions options;
Isabella Gottardia0687ee2020-03-11 18:04:20 +00003832 options.m_EnableProfiling = true;
3833 // Check the default value set to binary
Sadik Armagan1625efc2021-06-10 18:24:34 +01003834 CHECK(options.m_FileFormat == "binary");
Isabella Gottardia0687ee2020-03-11 18:04:20 +00003835
3836 // Change file format to an unsupported value
3837 options.m_FileFormat = "json";
3838 // Enable the profiling service
Jim Flynn34430252022-03-04 15:03:58 +00003839 armnn::ArmNNProfilingServiceInitialiser initialiser;
Jim Flynn9c85b412022-03-16 00:27:43 +00003840 ProfilingService profilingService(arm::pipe::MAX_ARMNN_COUNTER,
3841 initialiser,
3842 arm::pipe::ARMNN_SOFTWARE_INFO,
3843 arm::pipe::ARMNN_SOFTWARE_VERSION,
3844 arm::pipe::ARMNN_HARDWARE_VERSION);
Isabella Gottardia0687ee2020-03-11 18:04:20 +00003845 profilingService.ResetExternalProfilingOptions(options, true);
3846 // Start the command handler and the send thread
3847 profilingService.Update();
Sadik Armagan1625efc2021-06-10 18:24:34 +01003848 CHECK(profilingService.GetCurrentState()==ProfilingState::NotConnected);
Isabella Gottardia0687ee2020-03-11 18:04:20 +00003849
Isabella Gottardia0687ee2020-03-11 18:04:20 +00003850 // When Update is called and the current state is ProfilingState::NotConnected
3851 // an exception will be raised from GetProfilingConnection and displayed as warning in the output local stream
3852 profilingService.Update();
3853
3854 streamRedirector.CancelRedirect();
3855
3856 // Check that the expected error has occurred and logged to the standard output
David Monahana8837bf2020-04-16 10:01:56 +01003857 if (ss.str().find("Unsupported profiling file format, only binary is supported") == std::string::npos)
Isabella Gottardia0687ee2020-03-11 18:04:20 +00003858 {
3859 std::cout << ss.str();
Sadik Armagan1625efc2021-06-10 18:24:34 +01003860 FAIL("Expected string not found.");
Isabella Gottardia0687ee2020-03-11 18:04:20 +00003861 }
3862}
3863
Tracy Narine2883a862024-02-26 15:05:11 +00003864#endif
3865
Sadik Armagan1625efc2021-06-10 18:24:34 +01003866}