xref: /aosp_15_r20/external/armnn/src/profiling/test/ProfilingTests.cpp (revision 89c4ff92f2867872bb9e2354d150bf0c8c502810)
1*89c4ff92SAndroid Build Coastguard Worker //
2*89c4ff92SAndroid Build Coastguard Worker // Copyright © 2019 Arm Ltd and Contributors. All rights reserved.
3*89c4ff92SAndroid Build Coastguard Worker // SPDX-License-Identifier: MIT
4*89c4ff92SAndroid Build Coastguard Worker //
5*89c4ff92SAndroid Build Coastguard Worker 
6*89c4ff92SAndroid Build Coastguard Worker #include "ProfilingTests.hpp"
7*89c4ff92SAndroid Build Coastguard Worker #include "ProfilingTestUtils.hpp"
8*89c4ff92SAndroid Build Coastguard Worker #include <Runtime.hpp>
9*89c4ff92SAndroid Build Coastguard Worker #include <ArmNNProfilingServiceInitialiser.hpp>
10*89c4ff92SAndroid Build Coastguard Worker 
11*89c4ff92SAndroid Build Coastguard Worker #include <client/src/CommandHandler.hpp>
12*89c4ff92SAndroid Build Coastguard Worker #include <client/src/ConnectionAcknowledgedCommandHandler.hpp>
13*89c4ff92SAndroid Build Coastguard Worker #include <client/src/PeriodicCounterCapture.hpp>
14*89c4ff92SAndroid Build Coastguard Worker #include <client/src/PeriodicCounterSelectionCommandHandler.hpp>
15*89c4ff92SAndroid Build Coastguard Worker #include <client/src/ProfilingStateMachine.hpp>
16*89c4ff92SAndroid Build Coastguard Worker #include <client/src/ProfilingUtils.hpp>
17*89c4ff92SAndroid Build Coastguard Worker #include <client/src/RegisterBackendCounters.hpp>
18*89c4ff92SAndroid Build Coastguard Worker #include <client/src/RequestCounterDirectoryCommandHandler.hpp>
19*89c4ff92SAndroid Build Coastguard Worker #include <client/src/SocketProfilingConnection.hpp>
20*89c4ff92SAndroid Build Coastguard Worker #include <client/src/SendCounterPacket.hpp>
21*89c4ff92SAndroid Build Coastguard Worker #include <client/src/SendThread.hpp>
22*89c4ff92SAndroid Build Coastguard Worker #include <client/src/SendTimelinePacket.hpp>
23*89c4ff92SAndroid Build Coastguard Worker #include <client/src/backends/BackendProfiling.hpp>
24*89c4ff92SAndroid Build Coastguard Worker 
25*89c4ff92SAndroid Build Coastguard Worker #include <armnn/Utils.hpp>
26*89c4ff92SAndroid Build Coastguard Worker 
27*89c4ff92SAndroid Build Coastguard Worker #include <armnn/profiling/ArmNNProfiling.hpp>
28*89c4ff92SAndroid Build Coastguard Worker 
29*89c4ff92SAndroid Build Coastguard Worker #include <client/include/CounterIdMap.hpp>
30*89c4ff92SAndroid Build Coastguard Worker #include <client/include/Holder.hpp>
31*89c4ff92SAndroid Build Coastguard Worker #include <client/include/ICounterValues.hpp>
32*89c4ff92SAndroid Build Coastguard Worker #include <client/include/ProfilingOptions.hpp>
33*89c4ff92SAndroid Build Coastguard Worker 
34*89c4ff92SAndroid Build Coastguard Worker #include <common/include/CommandHandlerKey.hpp>
35*89c4ff92SAndroid Build Coastguard Worker #include <common/include/CommandHandlerRegistry.hpp>
36*89c4ff92SAndroid Build Coastguard Worker #include <common/include/CounterDirectory.hpp>
37*89c4ff92SAndroid Build Coastguard Worker #include <common/include/EncodeVersion.hpp>
38*89c4ff92SAndroid Build Coastguard Worker #include <common/include/IgnoreUnused.hpp>
39*89c4ff92SAndroid Build Coastguard Worker #include <common/include/NumericCast.hpp>
40*89c4ff92SAndroid Build Coastguard Worker #include <common/include/Packet.hpp>
41*89c4ff92SAndroid Build Coastguard Worker #include <common/include/PacketVersionResolver.hpp>
42*89c4ff92SAndroid Build Coastguard Worker #include <common/include/SocketConnectionException.hpp>
43*89c4ff92SAndroid Build Coastguard Worker #include <common/include/SwTrace.hpp>
44*89c4ff92SAndroid Build Coastguard Worker 
45*89c4ff92SAndroid Build Coastguard Worker #include <doctest/doctest.h>
46*89c4ff92SAndroid Build Coastguard Worker 
47*89c4ff92SAndroid Build Coastguard Worker #include <algorithm>
48*89c4ff92SAndroid Build Coastguard Worker #include <cstdint>
49*89c4ff92SAndroid Build Coastguard Worker #include <cstring>
50*89c4ff92SAndroid Build Coastguard Worker #include <iostream>
51*89c4ff92SAndroid Build Coastguard Worker #include <limits>
52*89c4ff92SAndroid Build Coastguard Worker #include <map>
53*89c4ff92SAndroid Build Coastguard Worker #include <random>
54*89c4ff92SAndroid Build Coastguard Worker 
55*89c4ff92SAndroid Build Coastguard Worker 
56*89c4ff92SAndroid Build Coastguard Worker using namespace arm::pipe;
57*89c4ff92SAndroid Build Coastguard Worker using PacketType = MockProfilingConnection::PacketType;
58*89c4ff92SAndroid Build Coastguard Worker 
59*89c4ff92SAndroid Build Coastguard Worker TEST_SUITE("ExternalProfiling")
60*89c4ff92SAndroid Build Coastguard Worker {
61*89c4ff92SAndroid Build Coastguard Worker TEST_CASE("CheckCommandHandlerKeyComparisons")
62*89c4ff92SAndroid Build Coastguard Worker {
63*89c4ff92SAndroid Build Coastguard Worker     arm::pipe::CommandHandlerKey testKey1_0(1, 1, 1);
64*89c4ff92SAndroid Build Coastguard Worker     arm::pipe::CommandHandlerKey testKey1_1(1, 1, 1);
65*89c4ff92SAndroid Build Coastguard Worker     arm::pipe::CommandHandlerKey testKey1_2(1, 2, 1);
66*89c4ff92SAndroid Build Coastguard Worker 
67*89c4ff92SAndroid Build Coastguard Worker     arm::pipe::CommandHandlerKey testKey0(0, 1, 1);
68*89c4ff92SAndroid Build Coastguard Worker     arm::pipe::CommandHandlerKey testKey1(0, 1, 1);
69*89c4ff92SAndroid Build Coastguard Worker     arm::pipe::CommandHandlerKey testKey2(0, 1, 1);
70*89c4ff92SAndroid Build Coastguard Worker     arm::pipe::CommandHandlerKey testKey3(0, 0, 0);
71*89c4ff92SAndroid Build Coastguard Worker     arm::pipe::CommandHandlerKey testKey4(0, 2, 2);
72*89c4ff92SAndroid Build Coastguard Worker     arm::pipe::CommandHandlerKey testKey5(0, 0, 2);
73*89c4ff92SAndroid Build Coastguard Worker 
74*89c4ff92SAndroid Build Coastguard Worker     CHECK(testKey1_0 > testKey0);
75*89c4ff92SAndroid Build Coastguard Worker     CHECK(testKey1_0 == testKey1_1);
76*89c4ff92SAndroid Build Coastguard Worker     CHECK(testKey1_0 < testKey1_2);
77*89c4ff92SAndroid Build Coastguard Worker 
78*89c4ff92SAndroid Build Coastguard Worker     CHECK(testKey1 < testKey4);
79*89c4ff92SAndroid Build Coastguard Worker     CHECK(testKey1 > testKey3);
80*89c4ff92SAndroid Build Coastguard Worker     CHECK(testKey1 <= testKey4);
81*89c4ff92SAndroid Build Coastguard Worker     CHECK(testKey1 >= testKey3);
82*89c4ff92SAndroid Build Coastguard Worker     CHECK(testKey1 <= testKey2);
83*89c4ff92SAndroid Build Coastguard Worker     CHECK(testKey1 >= testKey2);
84*89c4ff92SAndroid Build Coastguard Worker     CHECK(testKey1 == testKey2);
85*89c4ff92SAndroid Build Coastguard Worker     CHECK(testKey1 == testKey1);
86*89c4ff92SAndroid Build Coastguard Worker 
87*89c4ff92SAndroid Build Coastguard Worker     CHECK(!(testKey1 == testKey5));
88*89c4ff92SAndroid Build Coastguard Worker     CHECK(!(testKey1 != testKey1));
89*89c4ff92SAndroid Build Coastguard Worker     CHECK(testKey1 != testKey5);
90*89c4ff92SAndroid Build Coastguard Worker 
91*89c4ff92SAndroid Build Coastguard Worker     CHECK((testKey1 == testKey2 && testKey2 == testKey1));
92*89c4ff92SAndroid Build Coastguard Worker     CHECK((testKey0 == testKey1 && testKey1 == testKey2 && testKey0 == testKey2));
93*89c4ff92SAndroid Build Coastguard Worker 
94*89c4ff92SAndroid Build Coastguard Worker     CHECK(testKey1.GetPacketId() == 1);
95*89c4ff92SAndroid Build Coastguard Worker     CHECK(testKey1.GetVersion() == 1);
96*89c4ff92SAndroid Build Coastguard Worker 
97*89c4ff92SAndroid Build Coastguard Worker     std::vector<arm::pipe::CommandHandlerKey> vect = {
98*89c4ff92SAndroid Build Coastguard Worker         arm::pipe::CommandHandlerKey(0, 0, 1), arm::pipe::CommandHandlerKey(0, 2, 0),
99*89c4ff92SAndroid Build Coastguard Worker         arm::pipe::CommandHandlerKey(0, 1, 0), arm::pipe::CommandHandlerKey(0, 2, 1),
100*89c4ff92SAndroid Build Coastguard Worker         arm::pipe::CommandHandlerKey(0, 1, 1), arm::pipe::CommandHandlerKey(0, 0, 1),
101*89c4ff92SAndroid Build Coastguard Worker         arm::pipe::CommandHandlerKey(0, 2, 0), arm::pipe::CommandHandlerKey(0, 0, 0) };
102*89c4ff92SAndroid Build Coastguard Worker 
103*89c4ff92SAndroid Build Coastguard Worker     std::sort(vect.begin(), vect.end());
104*89c4ff92SAndroid Build Coastguard Worker 
105*89c4ff92SAndroid Build Coastguard Worker     std::vector<arm::pipe::CommandHandlerKey> expectedVect = {
106*89c4ff92SAndroid Build Coastguard Worker         arm::pipe::CommandHandlerKey(0, 0, 0), arm::pipe::CommandHandlerKey(0, 0, 1),
107*89c4ff92SAndroid Build Coastguard Worker         arm::pipe::CommandHandlerKey(0, 0, 1), arm::pipe::CommandHandlerKey(0, 1, 0),
108*89c4ff92SAndroid Build Coastguard Worker         arm::pipe::CommandHandlerKey(0, 1, 1), arm::pipe::CommandHandlerKey(0, 2, 0),
109*89c4ff92SAndroid Build Coastguard Worker         arm::pipe::CommandHandlerKey(0, 2, 0), arm::pipe::CommandHandlerKey(0, 2, 1) };
110*89c4ff92SAndroid Build Coastguard Worker 
111*89c4ff92SAndroid Build Coastguard Worker     CHECK(vect == expectedVect);
112*89c4ff92SAndroid Build Coastguard Worker }
113*89c4ff92SAndroid Build Coastguard Worker 
114*89c4ff92SAndroid Build Coastguard Worker TEST_CASE("CheckPacketKeyComparisons")
115*89c4ff92SAndroid Build Coastguard Worker {
116*89c4ff92SAndroid Build Coastguard Worker     arm::pipe::PacketKey key0(0, 0);
117*89c4ff92SAndroid Build Coastguard Worker     arm::pipe::PacketKey key1(0, 0);
118*89c4ff92SAndroid Build Coastguard Worker     arm::pipe::PacketKey key2(0, 1);
119*89c4ff92SAndroid Build Coastguard Worker     arm::pipe::PacketKey key3(0, 2);
120*89c4ff92SAndroid Build Coastguard Worker     arm::pipe::PacketKey key4(1, 0);
121*89c4ff92SAndroid Build Coastguard Worker     arm::pipe::PacketKey key5(1, 0);
122*89c4ff92SAndroid Build Coastguard Worker     arm::pipe::PacketKey key6(1, 1);
123*89c4ff92SAndroid Build Coastguard Worker 
124*89c4ff92SAndroid Build Coastguard Worker     CHECK(!(key0 < key1));
125*89c4ff92SAndroid Build Coastguard Worker     CHECK(!(key0 > key1));
126*89c4ff92SAndroid Build Coastguard Worker     CHECK(key0 <= key1);
127*89c4ff92SAndroid Build Coastguard Worker     CHECK(key0 >= key1);
128*89c4ff92SAndroid Build Coastguard Worker     CHECK(key0 == key1);
129*89c4ff92SAndroid Build Coastguard Worker     CHECK(key0 < key2);
130*89c4ff92SAndroid Build Coastguard Worker     CHECK(key2 < key3);
131*89c4ff92SAndroid Build Coastguard Worker     CHECK(key3 > key0);
132*89c4ff92SAndroid Build Coastguard Worker     CHECK(key4 == key5);
133*89c4ff92SAndroid Build Coastguard Worker     CHECK(key4 > key0);
134*89c4ff92SAndroid Build Coastguard Worker     CHECK(key5 < key6);
135*89c4ff92SAndroid Build Coastguard Worker     CHECK(key5 <= key6);
136*89c4ff92SAndroid Build Coastguard Worker     CHECK(key5 != key6);
137*89c4ff92SAndroid Build Coastguard Worker }
138*89c4ff92SAndroid Build Coastguard Worker 
139*89c4ff92SAndroid Build Coastguard Worker TEST_CASE("CheckCommandHandler")
140*89c4ff92SAndroid Build Coastguard Worker {
141*89c4ff92SAndroid Build Coastguard Worker     LogLevelSwapper logLevelSwapper(arm::pipe::LogSeverity::Fatal);
142*89c4ff92SAndroid Build Coastguard Worker 
143*89c4ff92SAndroid Build Coastguard Worker     arm::pipe::PacketVersionResolver packetVersionResolver;
144*89c4ff92SAndroid Build Coastguard Worker     ProfilingStateMachine profilingStateMachine;
145*89c4ff92SAndroid Build Coastguard Worker 
146*89c4ff92SAndroid Build Coastguard Worker     TestProfilingConnectionBase testProfilingConnectionBase;
147*89c4ff92SAndroid Build Coastguard Worker     TestProfilingConnectionTimeoutError testProfilingConnectionTimeOutError;
148*89c4ff92SAndroid Build Coastguard Worker     TestProfilingConnectionArmnnError testProfilingConnectionArmnnError;
149*89c4ff92SAndroid Build Coastguard Worker     CounterDirectory counterDirectory;
150*89c4ff92SAndroid Build Coastguard Worker     MockBufferManager mockBuffer(1024);
151*89c4ff92SAndroid Build Coastguard Worker     SendCounterPacket sendCounterPacket(mockBuffer,
152*89c4ff92SAndroid Build Coastguard Worker                                         arm::pipe::ARMNN_SOFTWARE_INFO,
153*89c4ff92SAndroid Build Coastguard Worker                                         arm::pipe::ARMNN_SOFTWARE_VERSION,
154*89c4ff92SAndroid Build Coastguard Worker                                         arm::pipe::ARMNN_HARDWARE_VERSION);
155*89c4ff92SAndroid Build Coastguard Worker     SendThread sendThread(profilingStateMachine, mockBuffer, sendCounterPacket);
156*89c4ff92SAndroid Build Coastguard Worker     SendTimelinePacket sendTimelinePacket(mockBuffer);
157*89c4ff92SAndroid Build Coastguard Worker     MockProfilingServiceStatus mockProfilingServiceStatus;
158*89c4ff92SAndroid Build Coastguard Worker 
159*89c4ff92SAndroid Build Coastguard Worker     ConnectionAcknowledgedCommandHandler connectionAcknowledgedCommandHandler(0, 1, 4194304, counterDirectory,
160*89c4ff92SAndroid Build Coastguard Worker                                                                               sendCounterPacket, sendTimelinePacket,
161*89c4ff92SAndroid Build Coastguard Worker                                                                               profilingStateMachine,
162*89c4ff92SAndroid Build Coastguard Worker                                                                               mockProfilingServiceStatus);
163*89c4ff92SAndroid Build Coastguard Worker     arm::pipe::CommandHandlerRegistry commandHandlerRegistry;
164*89c4ff92SAndroid Build Coastguard Worker 
165*89c4ff92SAndroid Build Coastguard Worker     commandHandlerRegistry.RegisterFunctor(&connectionAcknowledgedCommandHandler);
166*89c4ff92SAndroid Build Coastguard Worker 
167*89c4ff92SAndroid Build Coastguard Worker     profilingStateMachine.TransitionToState(ProfilingState::NotConnected);
168*89c4ff92SAndroid Build Coastguard Worker     profilingStateMachine.TransitionToState(ProfilingState::WaitingForAck);
169*89c4ff92SAndroid Build Coastguard Worker 
170*89c4ff92SAndroid Build Coastguard Worker     CommandHandler commandHandler0(1, true, commandHandlerRegistry, packetVersionResolver);
171*89c4ff92SAndroid Build Coastguard Worker 
172*89c4ff92SAndroid Build Coastguard Worker     // This should start the command handler thread return the connection ack and put the profiling
173*89c4ff92SAndroid Build Coastguard Worker     // service into active state.
174*89c4ff92SAndroid Build Coastguard Worker     commandHandler0.Start(testProfilingConnectionBase);
175*89c4ff92SAndroid Build Coastguard Worker     // Try to start the send thread many times, it must only start once
176*89c4ff92SAndroid Build Coastguard Worker     commandHandler0.Start(testProfilingConnectionBase);
177*89c4ff92SAndroid Build Coastguard Worker 
178*89c4ff92SAndroid Build Coastguard Worker     // This could take up to 20mSec but we'll check often.
179*89c4ff92SAndroid Build Coastguard Worker     for (int i = 0; i < 10; i++)
180*89c4ff92SAndroid Build Coastguard Worker     {
181*89c4ff92SAndroid Build Coastguard Worker         if (profilingStateMachine.GetCurrentState() == ProfilingState::Active)
182*89c4ff92SAndroid Build Coastguard Worker         {
183*89c4ff92SAndroid Build Coastguard Worker             break;
184*89c4ff92SAndroid Build Coastguard Worker         }
185*89c4ff92SAndroid Build Coastguard Worker         std::this_thread::sleep_for(std::chrono::milliseconds(2));
186*89c4ff92SAndroid Build Coastguard Worker     }
187*89c4ff92SAndroid Build Coastguard Worker 
188*89c4ff92SAndroid Build Coastguard Worker     CHECK(profilingStateMachine.GetCurrentState() == ProfilingState::Active);
189*89c4ff92SAndroid Build Coastguard Worker 
190*89c4ff92SAndroid Build Coastguard Worker     // Close the thread again.
191*89c4ff92SAndroid Build Coastguard Worker     commandHandler0.Stop();
192*89c4ff92SAndroid Build Coastguard Worker 
193*89c4ff92SAndroid Build Coastguard Worker     profilingStateMachine.TransitionToState(ProfilingState::NotConnected);
194*89c4ff92SAndroid Build Coastguard Worker     profilingStateMachine.TransitionToState(ProfilingState::WaitingForAck);
195*89c4ff92SAndroid Build Coastguard Worker 
196*89c4ff92SAndroid Build Coastguard Worker     // In this test we'll simulate a timeout without a connection ack packet being received.
197*89c4ff92SAndroid Build Coastguard Worker     // Stop after timeout is set so we expect the command handler to stop almost immediately.
198*89c4ff92SAndroid Build Coastguard Worker     CommandHandler commandHandler1(1, true, commandHandlerRegistry, packetVersionResolver);
199*89c4ff92SAndroid Build Coastguard Worker 
200*89c4ff92SAndroid Build Coastguard Worker     commandHandler1.Start(testProfilingConnectionTimeOutError);
201*89c4ff92SAndroid Build Coastguard Worker     // Wait until we know a timeout exception has been sent at least once.
202*89c4ff92SAndroid Build Coastguard Worker     for (int i = 0; i < 10; i++)
203*89c4ff92SAndroid Build Coastguard Worker     {
204*89c4ff92SAndroid Build Coastguard Worker         if (testProfilingConnectionTimeOutError.ReadCalledCount())
205*89c4ff92SAndroid Build Coastguard Worker         {
206*89c4ff92SAndroid Build Coastguard Worker             break;
207*89c4ff92SAndroid Build Coastguard Worker         }
208*89c4ff92SAndroid Build Coastguard Worker         std::this_thread::sleep_for(std::chrono::milliseconds(2));
209*89c4ff92SAndroid Build Coastguard Worker     }
210*89c4ff92SAndroid Build Coastguard Worker 
211*89c4ff92SAndroid Build Coastguard Worker     // The command handler loop should have stopped after the timeout.
212*89c4ff92SAndroid Build Coastguard Worker     // wait for the timeout exception to be processed and the loop to break.
213*89c4ff92SAndroid Build Coastguard Worker     uint32_t timeout   = 50;
214*89c4ff92SAndroid Build Coastguard Worker     uint32_t timeSlept = 0;
215*89c4ff92SAndroid Build Coastguard Worker     while (commandHandler1.IsRunning())
216*89c4ff92SAndroid Build Coastguard Worker     {
217*89c4ff92SAndroid Build Coastguard Worker         if (timeSlept >= timeout)
218*89c4ff92SAndroid Build Coastguard Worker         {
219*89c4ff92SAndroid Build Coastguard Worker             FAIL("Timeout: The command handler loop did not stop after the timeout");
220*89c4ff92SAndroid Build Coastguard Worker         }
221*89c4ff92SAndroid Build Coastguard Worker         std::this_thread::sleep_for(std::chrono::milliseconds(1));
222*89c4ff92SAndroid Build Coastguard Worker         timeSlept ++;
223*89c4ff92SAndroid Build Coastguard Worker     }
224*89c4ff92SAndroid Build Coastguard Worker 
225*89c4ff92SAndroid Build Coastguard Worker     commandHandler1.Stop();
226*89c4ff92SAndroid Build Coastguard Worker     // The state machine should never have received the ack so will still be in WaitingForAck.
227*89c4ff92SAndroid Build Coastguard Worker     CHECK(profilingStateMachine.GetCurrentState() == ProfilingState::WaitingForAck);
228*89c4ff92SAndroid Build Coastguard Worker 
229*89c4ff92SAndroid Build Coastguard Worker     // Now try sending a bad connection acknowledged packet
230*89c4ff92SAndroid Build Coastguard Worker     TestProfilingConnectionBadAckPacket testProfilingConnectionBadAckPacket;
231*89c4ff92SAndroid Build Coastguard Worker     commandHandler1.Start(testProfilingConnectionBadAckPacket);
232*89c4ff92SAndroid Build Coastguard Worker     commandHandler1.Stop();
233*89c4ff92SAndroid Build Coastguard Worker     // This should also not change the state machine
234*89c4ff92SAndroid Build Coastguard Worker     CHECK(profilingStateMachine.GetCurrentState() == ProfilingState::WaitingForAck);
235*89c4ff92SAndroid Build Coastguard Worker 
236*89c4ff92SAndroid Build Coastguard Worker     // Disable stop after timeout and now commandHandler1 should persist after a timeout
237*89c4ff92SAndroid Build Coastguard Worker     commandHandler1.SetStopAfterTimeout(false);
238*89c4ff92SAndroid Build Coastguard Worker     // Restart the thread.
239*89c4ff92SAndroid Build Coastguard Worker     commandHandler1.Start(testProfilingConnectionTimeOutError);
240*89c4ff92SAndroid Build Coastguard Worker 
241*89c4ff92SAndroid Build Coastguard Worker     // Wait for at the three timeouts and the ack to be sent.
242*89c4ff92SAndroid Build Coastguard Worker     for (int i = 0; i < 10; i++)
243*89c4ff92SAndroid Build Coastguard Worker     {
244*89c4ff92SAndroid Build Coastguard Worker         if (testProfilingConnectionTimeOutError.ReadCalledCount() > 3)
245*89c4ff92SAndroid Build Coastguard Worker         {
246*89c4ff92SAndroid Build Coastguard Worker             break;
247*89c4ff92SAndroid Build Coastguard Worker         }
248*89c4ff92SAndroid Build Coastguard Worker         std::this_thread::sleep_for(std::chrono::milliseconds(2));
249*89c4ff92SAndroid Build Coastguard Worker     }
250*89c4ff92SAndroid Build Coastguard Worker     commandHandler1.Stop();
251*89c4ff92SAndroid Build Coastguard Worker 
252*89c4ff92SAndroid Build Coastguard Worker     // Even after the 3 exceptions the ack packet should have transitioned the command handler to active.
253*89c4ff92SAndroid Build Coastguard Worker     CHECK(profilingStateMachine.GetCurrentState() == ProfilingState::Active);
254*89c4ff92SAndroid Build Coastguard Worker 
255*89c4ff92SAndroid Build Coastguard Worker     // A command handler that gets exceptions other than timeouts should keep going.
256*89c4ff92SAndroid Build Coastguard Worker     CommandHandler commandHandler2(1, false, commandHandlerRegistry, packetVersionResolver);
257*89c4ff92SAndroid Build Coastguard Worker 
258*89c4ff92SAndroid Build Coastguard Worker     commandHandler2.Start(testProfilingConnectionArmnnError);
259*89c4ff92SAndroid Build Coastguard Worker 
260*89c4ff92SAndroid Build Coastguard Worker     // Wait for two exceptions to be thrown.
261*89c4ff92SAndroid Build Coastguard Worker     for (int i = 0; i < 10; i++)
262*89c4ff92SAndroid Build Coastguard Worker     {
263*89c4ff92SAndroid Build Coastguard Worker         if (testProfilingConnectionTimeOutError.ReadCalledCount() >= 2)
264*89c4ff92SAndroid Build Coastguard Worker         {
265*89c4ff92SAndroid Build Coastguard Worker             break;
266*89c4ff92SAndroid Build Coastguard Worker         }
267*89c4ff92SAndroid Build Coastguard Worker         std::this_thread::sleep_for(std::chrono::milliseconds(2));
268*89c4ff92SAndroid Build Coastguard Worker     }
269*89c4ff92SAndroid Build Coastguard Worker 
270*89c4ff92SAndroid Build Coastguard Worker     CHECK(commandHandler2.IsRunning());
271*89c4ff92SAndroid Build Coastguard Worker     commandHandler2.Stop();
272*89c4ff92SAndroid Build Coastguard Worker }
273*89c4ff92SAndroid Build Coastguard Worker 
274*89c4ff92SAndroid Build Coastguard Worker TEST_CASE("CheckEncodeVersion")
275*89c4ff92SAndroid Build Coastguard Worker {
276*89c4ff92SAndroid Build Coastguard Worker     arm::pipe::Version version1(12);
277*89c4ff92SAndroid Build Coastguard Worker 
278*89c4ff92SAndroid Build Coastguard Worker     CHECK(version1.GetMajor() == 0);
279*89c4ff92SAndroid Build Coastguard Worker     CHECK(version1.GetMinor() == 0);
280*89c4ff92SAndroid Build Coastguard Worker     CHECK(version1.GetPatch() == 12);
281*89c4ff92SAndroid Build Coastguard Worker 
282*89c4ff92SAndroid Build Coastguard Worker     arm::pipe::Version version2(4108);
283*89c4ff92SAndroid Build Coastguard Worker 
284*89c4ff92SAndroid Build Coastguard Worker     CHECK(version2.GetMajor() == 0);
285*89c4ff92SAndroid Build Coastguard Worker     CHECK(version2.GetMinor() == 1);
286*89c4ff92SAndroid Build Coastguard Worker     CHECK(version2.GetPatch() == 12);
287*89c4ff92SAndroid Build Coastguard Worker 
288*89c4ff92SAndroid Build Coastguard Worker     arm::pipe::Version version3(4198412);
289*89c4ff92SAndroid Build Coastguard Worker 
290*89c4ff92SAndroid Build Coastguard Worker     CHECK(version3.GetMajor() == 1);
291*89c4ff92SAndroid Build Coastguard Worker     CHECK(version3.GetMinor() == 1);
292*89c4ff92SAndroid Build Coastguard Worker     CHECK(version3.GetPatch() == 12);
293*89c4ff92SAndroid Build Coastguard Worker 
294*89c4ff92SAndroid Build Coastguard Worker     arm::pipe::Version version4(0);
295*89c4ff92SAndroid Build Coastguard Worker 
296*89c4ff92SAndroid Build Coastguard Worker     CHECK(version4.GetMajor() == 0);
297*89c4ff92SAndroid Build Coastguard Worker     CHECK(version4.GetMinor() == 0);
298*89c4ff92SAndroid Build Coastguard Worker     CHECK(version4.GetPatch() == 0);
299*89c4ff92SAndroid Build Coastguard Worker 
300*89c4ff92SAndroid Build Coastguard Worker     arm::pipe::Version version5(1, 0, 0);
301*89c4ff92SAndroid Build Coastguard Worker     CHECK(version5.GetEncodedValue() == 4194304);
302*89c4ff92SAndroid Build Coastguard Worker }
303*89c4ff92SAndroid Build Coastguard Worker 
304*89c4ff92SAndroid Build Coastguard Worker TEST_CASE("CheckPacketClass")
305*89c4ff92SAndroid Build Coastguard Worker {
306*89c4ff92SAndroid Build Coastguard Worker     uint32_t length                              = 4;
307*89c4ff92SAndroid Build Coastguard Worker     std::unique_ptr<unsigned char[]> packetData0 = std::make_unique<unsigned char[]>(length);
308*89c4ff92SAndroid Build Coastguard Worker     std::unique_ptr<unsigned char[]> packetData1 = std::make_unique<unsigned char[]>(0);
309*89c4ff92SAndroid Build Coastguard Worker     std::unique_ptr<unsigned char[]> nullPacketData;
310*89c4ff92SAndroid Build Coastguard Worker 
311*89c4ff92SAndroid Build Coastguard Worker     arm::pipe::Packet packetTest0(472580096, length, packetData0);
312*89c4ff92SAndroid Build Coastguard Worker 
313*89c4ff92SAndroid Build Coastguard Worker     CHECK(packetTest0.GetHeader() == 472580096);
314*89c4ff92SAndroid Build Coastguard Worker     CHECK(packetTest0.GetPacketFamily() == 7);
315*89c4ff92SAndroid Build Coastguard Worker     CHECK(packetTest0.GetPacketId() == 43);
316*89c4ff92SAndroid Build Coastguard Worker     CHECK(packetTest0.GetLength() == length);
317*89c4ff92SAndroid Build Coastguard Worker     CHECK(packetTest0.GetPacketType() == 3);
318*89c4ff92SAndroid Build Coastguard Worker     CHECK(packetTest0.GetPacketClass() == 5);
319*89c4ff92SAndroid Build Coastguard Worker 
320*89c4ff92SAndroid Build Coastguard Worker     CHECK_THROWS_AS(arm::pipe::Packet packetTest1(472580096, 0, packetData1), arm::pipe::InvalidArgumentException);
321*89c4ff92SAndroid Build Coastguard Worker     CHECK_NOTHROW(arm::pipe::Packet packetTest2(472580096, 0, nullPacketData));
322*89c4ff92SAndroid Build Coastguard Worker 
323*89c4ff92SAndroid Build Coastguard Worker     arm::pipe::Packet packetTest3(472580096, 0, nullPacketData);
324*89c4ff92SAndroid Build Coastguard Worker     CHECK(packetTest3.GetLength() == 0);
325*89c4ff92SAndroid Build Coastguard Worker     CHECK(packetTest3.GetData() == nullptr);
326*89c4ff92SAndroid Build Coastguard Worker 
327*89c4ff92SAndroid Build Coastguard Worker     const unsigned char* packetTest0Data = packetTest0.GetData();
328*89c4ff92SAndroid Build Coastguard Worker     arm::pipe::Packet packetTest4(std::move(packetTest0));
329*89c4ff92SAndroid Build Coastguard Worker 
330*89c4ff92SAndroid Build Coastguard Worker     CHECK(packetTest0.GetData() == nullptr);
331*89c4ff92SAndroid Build Coastguard Worker     CHECK(packetTest4.GetData() == packetTest0Data);
332*89c4ff92SAndroid Build Coastguard Worker 
333*89c4ff92SAndroid Build Coastguard Worker     CHECK(packetTest4.GetHeader() == 472580096);
334*89c4ff92SAndroid Build Coastguard Worker     CHECK(packetTest4.GetPacketFamily() == 7);
335*89c4ff92SAndroid Build Coastguard Worker     CHECK(packetTest4.GetPacketId() == 43);
336*89c4ff92SAndroid Build Coastguard Worker     CHECK(packetTest4.GetLength() == length);
337*89c4ff92SAndroid Build Coastguard Worker     CHECK(packetTest4.GetPacketType() == 3);
338*89c4ff92SAndroid Build Coastguard Worker     CHECK(packetTest4.GetPacketClass() == 5);
339*89c4ff92SAndroid Build Coastguard Worker }
340*89c4ff92SAndroid Build Coastguard Worker 
341*89c4ff92SAndroid Build Coastguard Worker TEST_CASE("CheckCommandHandlerFunctor")
342*89c4ff92SAndroid Build Coastguard Worker {
343*89c4ff92SAndroid Build Coastguard Worker     // Hard code the version as it will be the same during a single profiling session
344*89c4ff92SAndroid Build Coastguard Worker     uint32_t version = 1;
345*89c4ff92SAndroid Build Coastguard Worker 
346*89c4ff92SAndroid Build Coastguard Worker     TestFunctorA testFunctorA(7, 461, version);
347*89c4ff92SAndroid Build Coastguard Worker     TestFunctorB testFunctorB(8, 963, version);
348*89c4ff92SAndroid Build Coastguard Worker     TestFunctorC testFunctorC(5, 983, version);
349*89c4ff92SAndroid Build Coastguard Worker 
350*89c4ff92SAndroid Build Coastguard Worker     arm::pipe::CommandHandlerKey keyA(
351*89c4ff92SAndroid Build Coastguard Worker         testFunctorA.GetFamilyId(), testFunctorA.GetPacketId(), testFunctorA.GetVersion());
352*89c4ff92SAndroid Build Coastguard Worker     arm::pipe::CommandHandlerKey keyB(
353*89c4ff92SAndroid Build Coastguard Worker         testFunctorB.GetFamilyId(), testFunctorB.GetPacketId(), testFunctorB.GetVersion());
354*89c4ff92SAndroid Build Coastguard Worker     arm::pipe::CommandHandlerKey keyC(
355*89c4ff92SAndroid Build Coastguard Worker         testFunctorC.GetFamilyId(), testFunctorC.GetPacketId(), testFunctorC.GetVersion());
356*89c4ff92SAndroid Build Coastguard Worker 
357*89c4ff92SAndroid Build Coastguard Worker     // Create the unwrapped map to simulate the Command Handler Registry
358*89c4ff92SAndroid Build Coastguard Worker     std::map<arm::pipe::CommandHandlerKey, arm::pipe::CommandHandlerFunctor*> registry;
359*89c4ff92SAndroid Build Coastguard Worker 
360*89c4ff92SAndroid Build Coastguard Worker     registry.insert(std::make_pair(keyB, &testFunctorB));
361*89c4ff92SAndroid Build Coastguard Worker     registry.insert(std::make_pair(keyA, &testFunctorA));
362*89c4ff92SAndroid Build Coastguard Worker     registry.insert(std::make_pair(keyC, &testFunctorC));
363*89c4ff92SAndroid Build Coastguard Worker 
364*89c4ff92SAndroid Build Coastguard Worker     // Check the order of the map is correct
365*89c4ff92SAndroid Build Coastguard Worker     auto it = registry.begin();
366*89c4ff92SAndroid Build Coastguard Worker     CHECK(it->first == keyC);    // familyId == 5
367*89c4ff92SAndroid Build Coastguard Worker     it++;
368*89c4ff92SAndroid Build Coastguard Worker     CHECK(it->first == keyA);    // familyId == 7
369*89c4ff92SAndroid Build Coastguard Worker     it++;
370*89c4ff92SAndroid Build Coastguard Worker     CHECK(it->first == keyB);    // familyId == 8
371*89c4ff92SAndroid Build Coastguard Worker 
372*89c4ff92SAndroid Build Coastguard Worker     std::unique_ptr<unsigned char[]> packetDataA;
373*89c4ff92SAndroid Build Coastguard Worker     std::unique_ptr<unsigned char[]> packetDataB;
374*89c4ff92SAndroid Build Coastguard Worker     std::unique_ptr<unsigned char[]> packetDataC;
375*89c4ff92SAndroid Build Coastguard Worker 
376*89c4ff92SAndroid Build Coastguard Worker     arm::pipe::Packet packetA(500000000, 0, packetDataA);
377*89c4ff92SAndroid Build Coastguard Worker     arm::pipe::Packet packetB(600000000, 0, packetDataB);
378*89c4ff92SAndroid Build Coastguard Worker     arm::pipe::Packet packetC(400000000, 0, packetDataC);
379*89c4ff92SAndroid Build Coastguard Worker 
380*89c4ff92SAndroid Build Coastguard Worker     // Check the correct operator of derived class is called
381*89c4ff92SAndroid Build Coastguard Worker     registry.at(arm::pipe::CommandHandlerKey(
382*89c4ff92SAndroid Build Coastguard Worker         packetA.GetPacketFamily(), packetA.GetPacketId(), version))->operator()(packetA);
383*89c4ff92SAndroid Build Coastguard Worker     CHECK(testFunctorA.GetCount() == 1);
384*89c4ff92SAndroid Build Coastguard Worker     CHECK(testFunctorB.GetCount() == 0);
385*89c4ff92SAndroid Build Coastguard Worker     CHECK(testFunctorC.GetCount() == 0);
386*89c4ff92SAndroid Build Coastguard Worker 
387*89c4ff92SAndroid Build Coastguard Worker     registry.at(arm::pipe::CommandHandlerKey(
388*89c4ff92SAndroid Build Coastguard Worker         packetB.GetPacketFamily(), packetB.GetPacketId(), version))->operator()(packetB);
389*89c4ff92SAndroid Build Coastguard Worker     CHECK(testFunctorA.GetCount() == 1);
390*89c4ff92SAndroid Build Coastguard Worker     CHECK(testFunctorB.GetCount() == 1);
391*89c4ff92SAndroid Build Coastguard Worker     CHECK(testFunctorC.GetCount() == 0);
392*89c4ff92SAndroid Build Coastguard Worker 
393*89c4ff92SAndroid Build Coastguard Worker     registry.at(arm::pipe::CommandHandlerKey(
394*89c4ff92SAndroid Build Coastguard Worker         packetC.GetPacketFamily(), packetC.GetPacketId(), version))->operator()(packetC);
395*89c4ff92SAndroid Build Coastguard Worker     CHECK(testFunctorA.GetCount() == 1);
396*89c4ff92SAndroid Build Coastguard Worker     CHECK(testFunctorB.GetCount() == 1);
397*89c4ff92SAndroid Build Coastguard Worker     CHECK(testFunctorC.GetCount() == 1);
398*89c4ff92SAndroid Build Coastguard Worker }
399*89c4ff92SAndroid Build Coastguard Worker 
400*89c4ff92SAndroid Build Coastguard Worker TEST_CASE("CheckCommandHandlerRegistry")
401*89c4ff92SAndroid Build Coastguard Worker {
402*89c4ff92SAndroid Build Coastguard Worker     // Hard code the version as it will be the same during a single profiling session
403*89c4ff92SAndroid Build Coastguard Worker     uint32_t version = 1;
404*89c4ff92SAndroid Build Coastguard Worker 
405*89c4ff92SAndroid Build Coastguard Worker     TestFunctorA testFunctorA(7, 461, version);
406*89c4ff92SAndroid Build Coastguard Worker     TestFunctorB testFunctorB(8, 963, version);
407*89c4ff92SAndroid Build Coastguard Worker     TestFunctorC testFunctorC(5, 983, version);
408*89c4ff92SAndroid Build Coastguard Worker 
409*89c4ff92SAndroid Build Coastguard Worker     // Create the Command Handler Registry
410*89c4ff92SAndroid Build Coastguard Worker     arm::pipe::CommandHandlerRegistry registry;
411*89c4ff92SAndroid Build Coastguard Worker 
412*89c4ff92SAndroid Build Coastguard Worker     // Register multiple different derived classes
413*89c4ff92SAndroid Build Coastguard Worker     registry.RegisterFunctor(&testFunctorA);
414*89c4ff92SAndroid Build Coastguard Worker     registry.RegisterFunctor(&testFunctorB);
415*89c4ff92SAndroid Build Coastguard Worker     registry.RegisterFunctor(&testFunctorC);
416*89c4ff92SAndroid Build Coastguard Worker 
417*89c4ff92SAndroid Build Coastguard Worker     std::unique_ptr<unsigned char[]> packetDataA;
418*89c4ff92SAndroid Build Coastguard Worker     std::unique_ptr<unsigned char[]> packetDataB;
419*89c4ff92SAndroid Build Coastguard Worker     std::unique_ptr<unsigned char[]> packetDataC;
420*89c4ff92SAndroid Build Coastguard Worker 
421*89c4ff92SAndroid Build Coastguard Worker     arm::pipe::Packet packetA(500000000, 0, packetDataA);
422*89c4ff92SAndroid Build Coastguard Worker     arm::pipe::Packet packetB(600000000, 0, packetDataB);
423*89c4ff92SAndroid Build Coastguard Worker     arm::pipe::Packet packetC(400000000, 0, packetDataC);
424*89c4ff92SAndroid Build Coastguard Worker 
425*89c4ff92SAndroid Build Coastguard Worker     // Check the correct operator of derived class is called
426*89c4ff92SAndroid Build Coastguard Worker     registry.GetFunctor(packetA.GetPacketFamily(), packetA.GetPacketId(), version)->operator()(packetA);
427*89c4ff92SAndroid Build Coastguard Worker     CHECK(testFunctorA.GetCount() == 1);
428*89c4ff92SAndroid Build Coastguard Worker     CHECK(testFunctorB.GetCount() == 0);
429*89c4ff92SAndroid Build Coastguard Worker     CHECK(testFunctorC.GetCount() == 0);
430*89c4ff92SAndroid Build Coastguard Worker 
431*89c4ff92SAndroid Build Coastguard Worker     registry.GetFunctor(packetB.GetPacketFamily(), packetB.GetPacketId(), version)->operator()(packetB);
432*89c4ff92SAndroid Build Coastguard Worker     CHECK(testFunctorA.GetCount() == 1);
433*89c4ff92SAndroid Build Coastguard Worker     CHECK(testFunctorB.GetCount() == 1);
434*89c4ff92SAndroid Build Coastguard Worker     CHECK(testFunctorC.GetCount() == 0);
435*89c4ff92SAndroid Build Coastguard Worker 
436*89c4ff92SAndroid Build Coastguard Worker     registry.GetFunctor(packetC.GetPacketFamily(), packetC.GetPacketId(), version)->operator()(packetC);
437*89c4ff92SAndroid Build Coastguard Worker     CHECK(testFunctorA.GetCount() == 1);
438*89c4ff92SAndroid Build Coastguard Worker     CHECK(testFunctorB.GetCount() == 1);
439*89c4ff92SAndroid Build Coastguard Worker     CHECK(testFunctorC.GetCount() == 1);
440*89c4ff92SAndroid Build Coastguard Worker 
441*89c4ff92SAndroid Build Coastguard Worker     // Re-register an existing key with a new function
442*89c4ff92SAndroid Build Coastguard Worker     registry.RegisterFunctor(&testFunctorC, testFunctorA.GetFamilyId(), testFunctorA.GetPacketId(), version);
443*89c4ff92SAndroid Build Coastguard Worker     registry.GetFunctor(packetA.GetPacketFamily(), packetA.GetPacketId(), version)->operator()(packetC);
444*89c4ff92SAndroid Build Coastguard Worker     CHECK(testFunctorA.GetCount() == 1);
445*89c4ff92SAndroid Build Coastguard Worker     CHECK(testFunctorB.GetCount() == 1);
446*89c4ff92SAndroid Build Coastguard Worker     CHECK(testFunctorC.GetCount() == 2);
447*89c4ff92SAndroid Build Coastguard Worker 
448*89c4ff92SAndroid Build Coastguard Worker     // Check that non-existent key returns nullptr for its functor
449*89c4ff92SAndroid Build Coastguard Worker     CHECK_THROWS_AS(registry.GetFunctor(0, 0, 0), arm::pipe::ProfilingException);
450*89c4ff92SAndroid Build Coastguard Worker }
451*89c4ff92SAndroid Build Coastguard Worker 
452*89c4ff92SAndroid Build Coastguard Worker TEST_CASE("CheckPacketVersionResolver")
453*89c4ff92SAndroid Build Coastguard Worker {
454*89c4ff92SAndroid Build Coastguard Worker     // Set up random number generator for generating packetId values
455*89c4ff92SAndroid Build Coastguard Worker     std::random_device device;
456*89c4ff92SAndroid Build Coastguard Worker     std::mt19937 generator(device());
457*89c4ff92SAndroid Build Coastguard Worker     std::uniform_int_distribution<uint32_t> distribution(std::numeric_limits<uint32_t>::min(),
458*89c4ff92SAndroid Build Coastguard Worker                                                          std::numeric_limits<uint32_t>::max());
459*89c4ff92SAndroid Build Coastguard Worker 
460*89c4ff92SAndroid Build Coastguard Worker     // NOTE: Expected version is always 1.0.0, regardless of packetId
461*89c4ff92SAndroid Build Coastguard Worker     const arm::pipe::Version expectedVersion(1, 0, 0);
462*89c4ff92SAndroid Build Coastguard Worker 
463*89c4ff92SAndroid Build Coastguard Worker     arm::pipe::PacketVersionResolver packetVersionResolver;
464*89c4ff92SAndroid Build Coastguard Worker 
465*89c4ff92SAndroid Build Coastguard Worker     constexpr unsigned int numTests = 10u;
466*89c4ff92SAndroid Build Coastguard Worker 
467*89c4ff92SAndroid Build Coastguard Worker     for (unsigned int i = 0u; i < numTests; ++i)
468*89c4ff92SAndroid Build Coastguard Worker     {
469*89c4ff92SAndroid Build Coastguard Worker         const uint32_t familyId = distribution(generator);
470*89c4ff92SAndroid Build Coastguard Worker         const uint32_t packetId = distribution(generator);
471*89c4ff92SAndroid Build Coastguard Worker         arm::pipe::Version resolvedVersion = packetVersionResolver.ResolvePacketVersion(familyId, packetId);
472*89c4ff92SAndroid Build Coastguard Worker 
473*89c4ff92SAndroid Build Coastguard Worker         CHECK(resolvedVersion == expectedVersion);
474*89c4ff92SAndroid Build Coastguard Worker     }
475*89c4ff92SAndroid Build Coastguard Worker }
476*89c4ff92SAndroid Build Coastguard Worker 
ProfilingCurrentStateThreadImpl(ProfilingStateMachine & states)477*89c4ff92SAndroid Build Coastguard Worker void ProfilingCurrentStateThreadImpl(ProfilingStateMachine& states)
478*89c4ff92SAndroid Build Coastguard Worker {
479*89c4ff92SAndroid Build Coastguard Worker     ProfilingState newState = ProfilingState::NotConnected;
480*89c4ff92SAndroid Build Coastguard Worker     states.GetCurrentState();
481*89c4ff92SAndroid Build Coastguard Worker     states.TransitionToState(newState);
482*89c4ff92SAndroid Build Coastguard Worker }
483*89c4ff92SAndroid Build Coastguard Worker 
484*89c4ff92SAndroid Build Coastguard Worker TEST_CASE("CheckProfilingStateMachine")
485*89c4ff92SAndroid Build Coastguard Worker {
486*89c4ff92SAndroid Build Coastguard Worker     ProfilingStateMachine profilingState1(ProfilingState::Uninitialised);
487*89c4ff92SAndroid Build Coastguard Worker     profilingState1.TransitionToState(ProfilingState::Uninitialised);
488*89c4ff92SAndroid Build Coastguard Worker     CHECK(profilingState1.GetCurrentState() == ProfilingState::Uninitialised);
489*89c4ff92SAndroid Build Coastguard Worker 
490*89c4ff92SAndroid Build Coastguard Worker     ProfilingStateMachine profilingState2(ProfilingState::Uninitialised);
491*89c4ff92SAndroid Build Coastguard Worker     profilingState2.TransitionToState(ProfilingState::NotConnected);
492*89c4ff92SAndroid Build Coastguard Worker     CHECK(profilingState2.GetCurrentState() == ProfilingState::NotConnected);
493*89c4ff92SAndroid Build Coastguard Worker 
494*89c4ff92SAndroid Build Coastguard Worker     ProfilingStateMachine profilingState3(ProfilingState::NotConnected);
495*89c4ff92SAndroid Build Coastguard Worker     profilingState3.TransitionToState(ProfilingState::NotConnected);
496*89c4ff92SAndroid Build Coastguard Worker     CHECK(profilingState3.GetCurrentState() == ProfilingState::NotConnected);
497*89c4ff92SAndroid Build Coastguard Worker 
498*89c4ff92SAndroid Build Coastguard Worker     ProfilingStateMachine profilingState4(ProfilingState::NotConnected);
499*89c4ff92SAndroid Build Coastguard Worker     profilingState4.TransitionToState(ProfilingState::WaitingForAck);
500*89c4ff92SAndroid Build Coastguard Worker     CHECK(profilingState4.GetCurrentState() == ProfilingState::WaitingForAck);
501*89c4ff92SAndroid Build Coastguard Worker 
502*89c4ff92SAndroid Build Coastguard Worker     ProfilingStateMachine profilingState5(ProfilingState::WaitingForAck);
503*89c4ff92SAndroid Build Coastguard Worker     profilingState5.TransitionToState(ProfilingState::WaitingForAck);
504*89c4ff92SAndroid Build Coastguard Worker     CHECK(profilingState5.GetCurrentState() == ProfilingState::WaitingForAck);
505*89c4ff92SAndroid Build Coastguard Worker 
506*89c4ff92SAndroid Build Coastguard Worker     ProfilingStateMachine profilingState6(ProfilingState::WaitingForAck);
507*89c4ff92SAndroid Build Coastguard Worker     profilingState6.TransitionToState(ProfilingState::Active);
508*89c4ff92SAndroid Build Coastguard Worker     CHECK(profilingState6.GetCurrentState() == ProfilingState::Active);
509*89c4ff92SAndroid Build Coastguard Worker 
510*89c4ff92SAndroid Build Coastguard Worker     ProfilingStateMachine profilingState7(ProfilingState::Active);
511*89c4ff92SAndroid Build Coastguard Worker     profilingState7.TransitionToState(ProfilingState::NotConnected);
512*89c4ff92SAndroid Build Coastguard Worker     CHECK(profilingState7.GetCurrentState() == ProfilingState::NotConnected);
513*89c4ff92SAndroid Build Coastguard Worker 
514*89c4ff92SAndroid Build Coastguard Worker     ProfilingStateMachine profilingState8(ProfilingState::Active);
515*89c4ff92SAndroid Build Coastguard Worker     profilingState8.TransitionToState(ProfilingState::Active);
516*89c4ff92SAndroid Build Coastguard Worker     CHECK(profilingState8.GetCurrentState() == ProfilingState::Active);
517*89c4ff92SAndroid Build Coastguard Worker 
518*89c4ff92SAndroid Build Coastguard Worker     ProfilingStateMachine profilingState9(ProfilingState::Uninitialised);
519*89c4ff92SAndroid Build Coastguard Worker     CHECK_THROWS_AS(profilingState9.TransitionToState(ProfilingState::WaitingForAck), arm::pipe::ProfilingException);
520*89c4ff92SAndroid Build Coastguard Worker 
521*89c4ff92SAndroid Build Coastguard Worker     ProfilingStateMachine profilingState10(ProfilingState::Uninitialised);
522*89c4ff92SAndroid Build Coastguard Worker     CHECK_THROWS_AS(profilingState10.TransitionToState(ProfilingState::Active), arm::pipe::ProfilingException);
523*89c4ff92SAndroid Build Coastguard Worker 
524*89c4ff92SAndroid Build Coastguard Worker     ProfilingStateMachine profilingState11(ProfilingState::NotConnected);
525*89c4ff92SAndroid Build Coastguard Worker     CHECK_THROWS_AS(profilingState11.TransitionToState(ProfilingState::Uninitialised), arm::pipe::ProfilingException);
526*89c4ff92SAndroid Build Coastguard Worker 
527*89c4ff92SAndroid Build Coastguard Worker     ProfilingStateMachine profilingState12(ProfilingState::NotConnected);
528*89c4ff92SAndroid Build Coastguard Worker     CHECK_THROWS_AS(profilingState12.TransitionToState(ProfilingState::Active), arm::pipe::ProfilingException);
529*89c4ff92SAndroid Build Coastguard Worker 
530*89c4ff92SAndroid Build Coastguard Worker     ProfilingStateMachine profilingState13(ProfilingState::WaitingForAck);
531*89c4ff92SAndroid Build Coastguard Worker     CHECK_THROWS_AS(profilingState13.TransitionToState(ProfilingState::Uninitialised), arm::pipe::ProfilingException);
532*89c4ff92SAndroid Build Coastguard Worker 
533*89c4ff92SAndroid Build Coastguard Worker     ProfilingStateMachine profilingState14(ProfilingState::WaitingForAck);
534*89c4ff92SAndroid Build Coastguard Worker     profilingState14.TransitionToState(ProfilingState::NotConnected);
535*89c4ff92SAndroid Build Coastguard Worker     CHECK(profilingState14.GetCurrentState() == ProfilingState::NotConnected);
536*89c4ff92SAndroid Build Coastguard Worker 
537*89c4ff92SAndroid Build Coastguard Worker     ProfilingStateMachine profilingState15(ProfilingState::Active);
538*89c4ff92SAndroid Build Coastguard Worker     CHECK_THROWS_AS(profilingState15.TransitionToState(ProfilingState::Uninitialised), arm::pipe::ProfilingException);
539*89c4ff92SAndroid Build Coastguard Worker 
540*89c4ff92SAndroid Build Coastguard Worker     ProfilingStateMachine profilingState16(ProfilingState::Active);
541*89c4ff92SAndroid Build Coastguard Worker     CHECK_THROWS_AS(profilingState16.TransitionToState(ProfilingState::WaitingForAck), arm::pipe::ProfilingException);
542*89c4ff92SAndroid Build Coastguard Worker 
543*89c4ff92SAndroid Build Coastguard Worker     ProfilingStateMachine profilingState17(ProfilingState::Uninitialised);
544*89c4ff92SAndroid Build Coastguard Worker 
545*89c4ff92SAndroid Build Coastguard Worker     std::vector<std::thread> threads;
546*89c4ff92SAndroid Build Coastguard Worker     for (unsigned int i = 0; i < 5; ++i)
547*89c4ff92SAndroid Build Coastguard Worker     {
548*89c4ff92SAndroid Build Coastguard Worker         threads.push_back(std::thread(ProfilingCurrentStateThreadImpl, std::ref(profilingState17)));
549*89c4ff92SAndroid Build Coastguard Worker     }
550*89c4ff92SAndroid Build Coastguard Worker     std::for_each(threads.begin(), threads.end(), [](std::thread& theThread)
__anona15fbe1f0102(std::thread& theThread) 551*89c4ff92SAndroid Build Coastguard Worker     {
552*89c4ff92SAndroid Build Coastguard Worker         theThread.join();
553*89c4ff92SAndroid Build Coastguard Worker     });
554*89c4ff92SAndroid Build Coastguard Worker 
555*89c4ff92SAndroid Build Coastguard Worker     CHECK((profilingState17.GetCurrentState() == ProfilingState::NotConnected));
556*89c4ff92SAndroid Build Coastguard Worker }
557*89c4ff92SAndroid Build Coastguard Worker 
CaptureDataWriteThreadImpl(Holder & holder,uint32_t capturePeriod,const std::vector<uint16_t> & counterIds)558*89c4ff92SAndroid Build Coastguard Worker void CaptureDataWriteThreadImpl(Holder& holder, uint32_t capturePeriod, const std::vector<uint16_t>& counterIds)
559*89c4ff92SAndroid Build Coastguard Worker {
560*89c4ff92SAndroid Build Coastguard Worker     holder.SetCaptureData(capturePeriod, counterIds, {});
561*89c4ff92SAndroid Build Coastguard Worker }
562*89c4ff92SAndroid Build Coastguard Worker 
CaptureDataReadThreadImpl(const Holder & holder,CaptureData & captureData)563*89c4ff92SAndroid Build Coastguard Worker void CaptureDataReadThreadImpl(const Holder& holder, CaptureData& captureData)
564*89c4ff92SAndroid Build Coastguard Worker {
565*89c4ff92SAndroid Build Coastguard Worker     captureData = holder.GetCaptureData();
566*89c4ff92SAndroid Build Coastguard Worker }
567*89c4ff92SAndroid Build Coastguard Worker 
568*89c4ff92SAndroid Build Coastguard Worker TEST_CASE("CheckCaptureDataHolder")
569*89c4ff92SAndroid Build Coastguard Worker {
570*89c4ff92SAndroid Build Coastguard Worker     std::map<uint32_t, std::vector<uint16_t>> periodIdMap;
571*89c4ff92SAndroid Build Coastguard Worker     std::vector<uint16_t> counterIds;
572*89c4ff92SAndroid Build Coastguard Worker     uint32_t numThreads = 10;
573*89c4ff92SAndroid Build Coastguard Worker     for (uint32_t i = 0; i < numThreads; ++i)
574*89c4ff92SAndroid Build Coastguard Worker     {
575*89c4ff92SAndroid Build Coastguard Worker         counterIds.emplace_back(i);
576*89c4ff92SAndroid Build Coastguard Worker         periodIdMap.insert(std::make_pair(i, counterIds));
577*89c4ff92SAndroid Build Coastguard Worker     }
578*89c4ff92SAndroid Build Coastguard Worker 
579*89c4ff92SAndroid Build Coastguard Worker     // Verify the read and write threads set the holder correctly
580*89c4ff92SAndroid Build Coastguard Worker     // and retrieve the expected values
581*89c4ff92SAndroid Build Coastguard Worker     Holder holder;
582*89c4ff92SAndroid Build Coastguard Worker     CHECK((holder.GetCaptureData()).GetCapturePeriod() == 0);
583*89c4ff92SAndroid Build Coastguard Worker     CHECK(((holder.GetCaptureData()).GetCounterIds()).empty());
584*89c4ff92SAndroid Build Coastguard Worker 
585*89c4ff92SAndroid Build Coastguard Worker     // Check Holder functions
586*89c4ff92SAndroid Build Coastguard Worker     std::thread thread1(CaptureDataWriteThreadImpl, std::ref(holder), 2, std::ref(periodIdMap[2]));
587*89c4ff92SAndroid Build Coastguard Worker     thread1.join();
588*89c4ff92SAndroid Build Coastguard Worker     CHECK((holder.GetCaptureData()).GetCapturePeriod() == 2);
589*89c4ff92SAndroid Build Coastguard Worker     CHECK((holder.GetCaptureData()).GetCounterIds() == periodIdMap[2]);
590*89c4ff92SAndroid Build Coastguard Worker     // NOTE: now that we have some initial values in the holder we don't have to worry
591*89c4ff92SAndroid Build Coastguard Worker     //       in the multi-threaded section below about a read thread accessing the holder
592*89c4ff92SAndroid Build Coastguard Worker     //       before any write thread has gotten to it so we read period = 0, counterIds empty
593*89c4ff92SAndroid Build Coastguard Worker     //       instead of period = 0, counterIds = {0} as will the case when write thread 0
594*89c4ff92SAndroid Build Coastguard Worker     //       has executed.
595*89c4ff92SAndroid Build Coastguard Worker 
596*89c4ff92SAndroid Build Coastguard Worker     CaptureData captureData;
597*89c4ff92SAndroid Build Coastguard Worker     std::thread thread2(CaptureDataReadThreadImpl, std::ref(holder), std::ref(captureData));
598*89c4ff92SAndroid Build Coastguard Worker     thread2.join();
599*89c4ff92SAndroid Build Coastguard Worker     CHECK(captureData.GetCapturePeriod() == 2);
600*89c4ff92SAndroid Build Coastguard Worker     CHECK(captureData.GetCounterIds() == periodIdMap[2]);
601*89c4ff92SAndroid Build Coastguard Worker 
602*89c4ff92SAndroid Build Coastguard Worker     std::map<uint32_t, CaptureData> captureDataIdMap;
603*89c4ff92SAndroid Build Coastguard Worker     for (uint32_t i = 0; i < numThreads; ++i)
604*89c4ff92SAndroid Build Coastguard Worker     {
605*89c4ff92SAndroid Build Coastguard Worker         CaptureData perThreadCaptureData;
606*89c4ff92SAndroid Build Coastguard Worker         captureDataIdMap.insert(std::make_pair(i, perThreadCaptureData));
607*89c4ff92SAndroid Build Coastguard Worker     }
608*89c4ff92SAndroid Build Coastguard Worker 
609*89c4ff92SAndroid Build Coastguard Worker     std::vector<std::thread> threadsVect;
610*89c4ff92SAndroid Build Coastguard Worker     std::vector<std::thread> readThreadsVect;
611*89c4ff92SAndroid Build Coastguard Worker     for (uint32_t i = 0; i < numThreads; ++i)
612*89c4ff92SAndroid Build Coastguard Worker     {
613*89c4ff92SAndroid Build Coastguard Worker         threadsVect.emplace_back(
614*89c4ff92SAndroid Build Coastguard Worker             std::thread(CaptureDataWriteThreadImpl, std::ref(holder), i, std::ref(periodIdMap[i])));
615*89c4ff92SAndroid Build Coastguard Worker 
616*89c4ff92SAndroid Build Coastguard Worker         // Verify that the CaptureData goes into the thread in a virgin state
617*89c4ff92SAndroid Build Coastguard Worker         CHECK(captureDataIdMap.at(i).GetCapturePeriod() == 0);
618*89c4ff92SAndroid Build Coastguard Worker         CHECK(captureDataIdMap.at(i).GetCounterIds().empty());
619*89c4ff92SAndroid Build Coastguard Worker         readThreadsVect.emplace_back(
620*89c4ff92SAndroid Build Coastguard Worker             std::thread(CaptureDataReadThreadImpl, std::ref(holder), std::ref(captureDataIdMap.at(i))));
621*89c4ff92SAndroid Build Coastguard Worker     }
622*89c4ff92SAndroid Build Coastguard Worker 
623*89c4ff92SAndroid Build Coastguard Worker     for (uint32_t i = 0; i < numThreads; ++i)
624*89c4ff92SAndroid Build Coastguard Worker     {
625*89c4ff92SAndroid Build Coastguard Worker         threadsVect[i].join();
626*89c4ff92SAndroid Build Coastguard Worker         readThreadsVect[i].join();
627*89c4ff92SAndroid Build Coastguard Worker     }
628*89c4ff92SAndroid Build Coastguard Worker 
629*89c4ff92SAndroid Build Coastguard Worker     // Look at the CaptureData that each read thread has filled
630*89c4ff92SAndroid Build Coastguard Worker     // the capture period it read should match the counter ids entry
631*89c4ff92SAndroid Build Coastguard Worker     for (uint32_t i = 0; i < numThreads; ++i)
632*89c4ff92SAndroid Build Coastguard Worker     {
633*89c4ff92SAndroid Build Coastguard Worker         CaptureData perThreadCaptureData = captureDataIdMap.at(i);
634*89c4ff92SAndroid Build Coastguard Worker         CHECK(perThreadCaptureData.GetCounterIds() == periodIdMap.at(perThreadCaptureData.GetCapturePeriod()));
635*89c4ff92SAndroid Build Coastguard Worker     }
636*89c4ff92SAndroid Build Coastguard Worker }
637*89c4ff92SAndroid Build Coastguard Worker 
638*89c4ff92SAndroid Build Coastguard Worker TEST_CASE("CaptureDataMethods")
639*89c4ff92SAndroid Build Coastguard Worker {
640*89c4ff92SAndroid Build Coastguard Worker     // Check CaptureData setter and getter functions
641*89c4ff92SAndroid Build Coastguard Worker     std::vector<uint16_t> counterIds = { 42, 29, 13 };
642*89c4ff92SAndroid Build Coastguard Worker     CaptureData captureData;
643*89c4ff92SAndroid Build Coastguard Worker     CHECK(captureData.GetCapturePeriod() == 0);
644*89c4ff92SAndroid Build Coastguard Worker     CHECK((captureData.GetCounterIds()).empty());
645*89c4ff92SAndroid Build Coastguard Worker     captureData.SetCapturePeriod(150);
646*89c4ff92SAndroid Build Coastguard Worker     captureData.SetCounterIds(counterIds);
647*89c4ff92SAndroid Build Coastguard Worker     CHECK(captureData.GetCapturePeriod() == 150);
648*89c4ff92SAndroid Build Coastguard Worker     CHECK(captureData.GetCounterIds() == counterIds);
649*89c4ff92SAndroid Build Coastguard Worker 
650*89c4ff92SAndroid Build Coastguard Worker     // Check assignment operator
651*89c4ff92SAndroid Build Coastguard Worker     CaptureData secondCaptureData;
652*89c4ff92SAndroid Build Coastguard Worker 
653*89c4ff92SAndroid Build Coastguard Worker     secondCaptureData = captureData;
654*89c4ff92SAndroid Build Coastguard Worker     CHECK(secondCaptureData.GetCapturePeriod() == 150);
655*89c4ff92SAndroid Build Coastguard Worker     CHECK(secondCaptureData.GetCounterIds() == counterIds);
656*89c4ff92SAndroid Build Coastguard Worker 
657*89c4ff92SAndroid Build Coastguard Worker     // Check copy constructor
658*89c4ff92SAndroid Build Coastguard Worker     CaptureData copyConstructedCaptureData(captureData);
659*89c4ff92SAndroid Build Coastguard Worker 
660*89c4ff92SAndroid Build Coastguard Worker     CHECK(copyConstructedCaptureData.GetCapturePeriod() == 150);
661*89c4ff92SAndroid Build Coastguard Worker     CHECK(copyConstructedCaptureData.GetCounterIds() == counterIds);
662*89c4ff92SAndroid Build Coastguard Worker }
663*89c4ff92SAndroid Build Coastguard Worker 
664*89c4ff92SAndroid Build Coastguard Worker TEST_CASE("CheckProfilingServiceDisabled")
665*89c4ff92SAndroid Build Coastguard Worker {
666*89c4ff92SAndroid Build Coastguard Worker     ProfilingOptions options;
667*89c4ff92SAndroid Build Coastguard Worker     armnn::ArmNNProfilingServiceInitialiser initialiser;
668*89c4ff92SAndroid Build Coastguard Worker     ProfilingService profilingService(arm::pipe::MAX_ARMNN_COUNTER,
669*89c4ff92SAndroid Build Coastguard Worker                                       initialiser,
670*89c4ff92SAndroid Build Coastguard Worker                                       arm::pipe::ARMNN_SOFTWARE_INFO,
671*89c4ff92SAndroid Build Coastguard Worker                                       arm::pipe::ARMNN_SOFTWARE_VERSION,
672*89c4ff92SAndroid Build Coastguard Worker                                       arm::pipe::ARMNN_HARDWARE_VERSION);
673*89c4ff92SAndroid Build Coastguard Worker     profilingService.ResetExternalProfilingOptions(options, true);
674*89c4ff92SAndroid Build Coastguard Worker     CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
675*89c4ff92SAndroid Build Coastguard Worker     profilingService.Update();
676*89c4ff92SAndroid Build Coastguard Worker     CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
677*89c4ff92SAndroid Build Coastguard Worker }
678*89c4ff92SAndroid Build Coastguard Worker 
679*89c4ff92SAndroid Build Coastguard Worker TEST_CASE("CheckProfilingServiceCounterDirectory")
680*89c4ff92SAndroid Build Coastguard Worker {
681*89c4ff92SAndroid Build Coastguard Worker     ProfilingOptions options;
682*89c4ff92SAndroid Build Coastguard Worker     armnn::ArmNNProfilingServiceInitialiser initialiser;
683*89c4ff92SAndroid Build Coastguard Worker     ProfilingService profilingService(arm::pipe::MAX_ARMNN_COUNTER,
684*89c4ff92SAndroid Build Coastguard Worker                                       initialiser,
685*89c4ff92SAndroid Build Coastguard Worker                                       arm::pipe::ARMNN_SOFTWARE_INFO,
686*89c4ff92SAndroid Build Coastguard Worker                                       arm::pipe::ARMNN_SOFTWARE_VERSION,
687*89c4ff92SAndroid Build Coastguard Worker                                       arm::pipe::ARMNN_HARDWARE_VERSION);
688*89c4ff92SAndroid Build Coastguard Worker     profilingService.ResetExternalProfilingOptions(options, true);
689*89c4ff92SAndroid Build Coastguard Worker 
690*89c4ff92SAndroid Build Coastguard Worker     const ICounterDirectory& counterDirectory0 = profilingService.GetCounterDirectory();
691*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterDirectory0.GetCounterCount() == 0);
692*89c4ff92SAndroid Build Coastguard Worker     profilingService.Update();
693*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterDirectory0.GetCounterCount() == 0);
694*89c4ff92SAndroid Build Coastguard Worker 
695*89c4ff92SAndroid Build Coastguard Worker     options.m_EnableProfiling = true;
696*89c4ff92SAndroid Build Coastguard Worker     profilingService.ResetExternalProfilingOptions(options);
697*89c4ff92SAndroid Build Coastguard Worker 
698*89c4ff92SAndroid Build Coastguard Worker     const ICounterDirectory& counterDirectory1 = profilingService.GetCounterDirectory();
699*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterDirectory1.GetCounterCount() == 0);
700*89c4ff92SAndroid Build Coastguard Worker     profilingService.Update();
701*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterDirectory1.GetCounterCount() != 0);
702*89c4ff92SAndroid Build Coastguard Worker     // Reset the profiling service to stop any running thread
703*89c4ff92SAndroid Build Coastguard Worker     options.m_EnableProfiling = false;
704*89c4ff92SAndroid Build Coastguard Worker     profilingService.ResetExternalProfilingOptions(options, true);
705*89c4ff92SAndroid Build Coastguard Worker }
706*89c4ff92SAndroid Build Coastguard Worker 
707*89c4ff92SAndroid Build Coastguard Worker TEST_CASE("CheckProfilingServiceCounterValues")
708*89c4ff92SAndroid Build Coastguard Worker {
709*89c4ff92SAndroid Build Coastguard Worker     ProfilingOptions options;
710*89c4ff92SAndroid Build Coastguard Worker     options.m_EnableProfiling          = true;
711*89c4ff92SAndroid Build Coastguard Worker     armnn::ArmNNProfilingServiceInitialiser initialiser;
712*89c4ff92SAndroid Build Coastguard Worker     ProfilingService profilingService(arm::pipe::MAX_ARMNN_COUNTER,
713*89c4ff92SAndroid Build Coastguard Worker                                       initialiser,
714*89c4ff92SAndroid Build Coastguard Worker                                       arm::pipe::ARMNN_SOFTWARE_INFO,
715*89c4ff92SAndroid Build Coastguard Worker                                       arm::pipe::ARMNN_SOFTWARE_VERSION,
716*89c4ff92SAndroid Build Coastguard Worker                                       arm::pipe::ARMNN_HARDWARE_VERSION);
717*89c4ff92SAndroid Build Coastguard Worker     profilingService.ResetExternalProfilingOptions(options, true);
718*89c4ff92SAndroid Build Coastguard Worker 
719*89c4ff92SAndroid Build Coastguard Worker     profilingService.Update();
720*89c4ff92SAndroid Build Coastguard Worker     const ICounterDirectory& counterDirectory = profilingService.GetCounterDirectory();
721*89c4ff92SAndroid Build Coastguard Worker     const Counters& counters                  = counterDirectory.GetCounters();
722*89c4ff92SAndroid Build Coastguard Worker     CHECK(!counters.empty());
723*89c4ff92SAndroid Build Coastguard Worker 
724*89c4ff92SAndroid Build Coastguard Worker     std::vector<std::thread> writers;
725*89c4ff92SAndroid Build Coastguard Worker 
726*89c4ff92SAndroid Build Coastguard Worker     CHECK(!counters.empty());
727*89c4ff92SAndroid Build Coastguard Worker     uint16_t inferencesRun = INFERENCES_RUN;
728*89c4ff92SAndroid Build Coastguard Worker 
729*89c4ff92SAndroid Build Coastguard Worker     // Test GetAbsoluteCounterValue
730*89c4ff92SAndroid Build Coastguard Worker     for (int i = 0; i < 4; ++i)
731*89c4ff92SAndroid Build Coastguard Worker     {
732*89c4ff92SAndroid Build Coastguard Worker         // Increment and decrement the INFERENCES_RUN counter 250 times
733*89c4ff92SAndroid Build Coastguard Worker         writers.push_back(std::thread([&profilingService, inferencesRun]()
__anona15fbe1f0202() 734*89c4ff92SAndroid Build Coastguard Worker                                       {
735*89c4ff92SAndroid Build Coastguard Worker                                           for (int i = 0; i < 250; ++i)
736*89c4ff92SAndroid Build Coastguard Worker                                           {
737*89c4ff92SAndroid Build Coastguard Worker                                               profilingService.IncrementCounterValue(inferencesRun);
738*89c4ff92SAndroid Build Coastguard Worker                                           }
739*89c4ff92SAndroid Build Coastguard Worker                                       }));
740*89c4ff92SAndroid Build Coastguard Worker         // Add 10 to the INFERENCES_RUN counter 200 times
741*89c4ff92SAndroid Build Coastguard Worker         writers.push_back(std::thread([&profilingService, inferencesRun]()
__anona15fbe1f0302() 742*89c4ff92SAndroid Build Coastguard Worker                                       {
743*89c4ff92SAndroid Build Coastguard Worker                                           for (int i = 0; i < 200; ++i)
744*89c4ff92SAndroid Build Coastguard Worker                                           {
745*89c4ff92SAndroid Build Coastguard Worker                                               profilingService.AddCounterValue(inferencesRun, 10);
746*89c4ff92SAndroid Build Coastguard Worker                                           }
747*89c4ff92SAndroid Build Coastguard Worker                                       }));
748*89c4ff92SAndroid Build Coastguard Worker         // Subtract 5 from the INFERENCES_RUN counter 200 times
749*89c4ff92SAndroid Build Coastguard Worker         writers.push_back(std::thread([&profilingService, inferencesRun]()
__anona15fbe1f0402() 750*89c4ff92SAndroid Build Coastguard Worker                                       {
751*89c4ff92SAndroid Build Coastguard Worker                                           for (int i = 0; i < 200; ++i)
752*89c4ff92SAndroid Build Coastguard Worker                                           {
753*89c4ff92SAndroid Build Coastguard Worker                                               profilingService.SubtractCounterValue(inferencesRun, 5);
754*89c4ff92SAndroid Build Coastguard Worker                                           }
755*89c4ff92SAndroid Build Coastguard Worker                                       }));
756*89c4ff92SAndroid Build Coastguard Worker     }
757*89c4ff92SAndroid Build Coastguard Worker     std::for_each(writers.begin(), writers.end(), mem_fn(&std::thread::join));
758*89c4ff92SAndroid Build Coastguard Worker 
759*89c4ff92SAndroid Build Coastguard Worker     uint32_t absoluteCounterValue = 0;
760*89c4ff92SAndroid Build Coastguard Worker 
761*89c4ff92SAndroid Build Coastguard Worker     CHECK_NOTHROW(absoluteCounterValue = profilingService.GetAbsoluteCounterValue(INFERENCES_RUN));
762*89c4ff92SAndroid Build Coastguard Worker     CHECK(absoluteCounterValue == 5000);
763*89c4ff92SAndroid Build Coastguard Worker 
764*89c4ff92SAndroid Build Coastguard Worker     // Test SetCounterValue
765*89c4ff92SAndroid Build Coastguard Worker     CHECK_NOTHROW(profilingService.SetCounterValue(INFERENCES_RUN, 0));
766*89c4ff92SAndroid Build Coastguard Worker     CHECK_NOTHROW(absoluteCounterValue = profilingService.GetAbsoluteCounterValue(INFERENCES_RUN));
767*89c4ff92SAndroid Build Coastguard Worker     CHECK(absoluteCounterValue == 0);
768*89c4ff92SAndroid Build Coastguard Worker 
769*89c4ff92SAndroid Build Coastguard Worker     // Test GetDeltaCounterValue
770*89c4ff92SAndroid Build Coastguard Worker     writers.clear();
771*89c4ff92SAndroid Build Coastguard Worker     uint32_t deltaCounterValue = 0;
772*89c4ff92SAndroid Build Coastguard Worker     //Start a reading thread to randomly read the INFERENCES_RUN counter value
773*89c4ff92SAndroid Build Coastguard Worker     std::thread reader([&profilingService, inferencesRun](uint32_t& deltaCounterValue)
__anona15fbe1f0502(uint32_t& deltaCounterValue) 774*89c4ff92SAndroid Build Coastguard Worker                        {
775*89c4ff92SAndroid Build Coastguard Worker                            for (int i = 0; i < 300; ++i)
776*89c4ff92SAndroid Build Coastguard Worker                            {
777*89c4ff92SAndroid Build Coastguard Worker                                deltaCounterValue += profilingService.GetDeltaCounterValue(inferencesRun);
778*89c4ff92SAndroid Build Coastguard Worker                            }
779*89c4ff92SAndroid Build Coastguard Worker                        }, std::ref(deltaCounterValue));
780*89c4ff92SAndroid Build Coastguard Worker 
781*89c4ff92SAndroid Build Coastguard Worker     for (int i = 0; i < 4; ++i)
782*89c4ff92SAndroid Build Coastguard Worker     {
783*89c4ff92SAndroid Build Coastguard Worker         // Increment and decrement the INFERENCES_RUN counter 250 times
784*89c4ff92SAndroid Build Coastguard Worker         writers.push_back(std::thread([&profilingService, inferencesRun]()
__anona15fbe1f0602() 785*89c4ff92SAndroid Build Coastguard Worker                                       {
786*89c4ff92SAndroid Build Coastguard Worker                                           for (int i = 0; i < 250; ++i)
787*89c4ff92SAndroid Build Coastguard Worker                                           {
788*89c4ff92SAndroid Build Coastguard Worker                                               profilingService.IncrementCounterValue(inferencesRun);
789*89c4ff92SAndroid Build Coastguard Worker                                           }
790*89c4ff92SAndroid Build Coastguard Worker                                       }));
791*89c4ff92SAndroid Build Coastguard Worker         // Add 10 to the INFERENCES_RUN counter 200 times
792*89c4ff92SAndroid Build Coastguard Worker         writers.push_back(std::thread([&profilingService, inferencesRun]()
__anona15fbe1f0702() 793*89c4ff92SAndroid Build Coastguard Worker                                       {
794*89c4ff92SAndroid Build Coastguard Worker                                           for (int i = 0; i < 200; ++i)
795*89c4ff92SAndroid Build Coastguard Worker                                           {
796*89c4ff92SAndroid Build Coastguard Worker                                               profilingService.AddCounterValue(inferencesRun, 10);
797*89c4ff92SAndroid Build Coastguard Worker                                           }
798*89c4ff92SAndroid Build Coastguard Worker                                       }));
799*89c4ff92SAndroid Build Coastguard Worker         // Subtract 5 from the INFERENCES_RUN counter 200 times
800*89c4ff92SAndroid Build Coastguard Worker         writers.push_back(std::thread([&profilingService, inferencesRun]()
__anona15fbe1f0802() 801*89c4ff92SAndroid Build Coastguard Worker                                       {
802*89c4ff92SAndroid Build Coastguard Worker                                           for (int i = 0; i < 200; ++i)
803*89c4ff92SAndroid Build Coastguard Worker                                           {
804*89c4ff92SAndroid Build Coastguard Worker                                               profilingService.SubtractCounterValue(inferencesRun, 5);
805*89c4ff92SAndroid Build Coastguard Worker                                           }
806*89c4ff92SAndroid Build Coastguard Worker                                       }));
807*89c4ff92SAndroid Build Coastguard Worker     }
808*89c4ff92SAndroid Build Coastguard Worker 
809*89c4ff92SAndroid Build Coastguard Worker     std::for_each(writers.begin(), writers.end(), mem_fn(&std::thread::join));
810*89c4ff92SAndroid Build Coastguard Worker     reader.join();
811*89c4ff92SAndroid Build Coastguard Worker 
812*89c4ff92SAndroid Build Coastguard Worker     // Do one last read in case the reader stopped early
813*89c4ff92SAndroid Build Coastguard Worker     deltaCounterValue += profilingService.GetDeltaCounterValue(INFERENCES_RUN);
814*89c4ff92SAndroid Build Coastguard Worker     CHECK(deltaCounterValue == 5000);
815*89c4ff92SAndroid Build Coastguard Worker 
816*89c4ff92SAndroid Build Coastguard Worker     // Reset the profiling service to stop any running thread
817*89c4ff92SAndroid Build Coastguard Worker     options.m_EnableProfiling = false;
818*89c4ff92SAndroid Build Coastguard Worker     profilingService.ResetExternalProfilingOptions(options, true);
819*89c4ff92SAndroid Build Coastguard Worker }
820*89c4ff92SAndroid Build Coastguard Worker 
821*89c4ff92SAndroid Build Coastguard Worker TEST_CASE("CheckProfilingObjectUids")
822*89c4ff92SAndroid Build Coastguard Worker {
823*89c4ff92SAndroid Build Coastguard Worker     uint16_t uid = 0;
824*89c4ff92SAndroid Build Coastguard Worker     CHECK_NOTHROW(uid = GetNextUid());
825*89c4ff92SAndroid Build Coastguard Worker     CHECK(uid >= 1);
826*89c4ff92SAndroid Build Coastguard Worker 
827*89c4ff92SAndroid Build Coastguard Worker     uint16_t nextUid = 0;
828*89c4ff92SAndroid Build Coastguard Worker     CHECK_NOTHROW(nextUid = GetNextUid());
829*89c4ff92SAndroid Build Coastguard Worker     CHECK(nextUid > uid);
830*89c4ff92SAndroid Build Coastguard Worker 
831*89c4ff92SAndroid Build Coastguard Worker     std::vector<uint16_t> counterUids;
832*89c4ff92SAndroid Build Coastguard Worker     CHECK_NOTHROW(counterUids = GetNextCounterUids(uid,0));
833*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterUids.size() == 1);
834*89c4ff92SAndroid Build Coastguard Worker 
835*89c4ff92SAndroid Build Coastguard Worker     std::vector<uint16_t> nextCounterUids;
836*89c4ff92SAndroid Build Coastguard Worker     CHECK_NOTHROW(nextCounterUids = GetNextCounterUids(nextUid, 2));
837*89c4ff92SAndroid Build Coastguard Worker     CHECK(nextCounterUids.size() == 2);
838*89c4ff92SAndroid Build Coastguard Worker     CHECK(nextCounterUids[0] > counterUids[0]);
839*89c4ff92SAndroid Build Coastguard Worker 
840*89c4ff92SAndroid Build Coastguard Worker     std::vector<uint16_t> counterUidsMultiCore;
841*89c4ff92SAndroid Build Coastguard Worker     uint16_t thirdUid = nextCounterUids[0];
842*89c4ff92SAndroid Build Coastguard Worker     uint16_t numberOfCores = 13;
843*89c4ff92SAndroid Build Coastguard Worker     CHECK_NOTHROW(counterUidsMultiCore = GetNextCounterUids(thirdUid, numberOfCores));
844*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterUidsMultiCore.size() == numberOfCores);
845*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterUidsMultiCore.front() >= nextCounterUids[0]);
846*89c4ff92SAndroid Build Coastguard Worker     for (size_t i = 1; i < numberOfCores; i++)
847*89c4ff92SAndroid Build Coastguard Worker     {
848*89c4ff92SAndroid Build Coastguard Worker         CHECK(counterUidsMultiCore[i] == counterUidsMultiCore[i - 1] + 1);
849*89c4ff92SAndroid Build Coastguard Worker     }
850*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterUidsMultiCore.back() == counterUidsMultiCore.front() + numberOfCores - 1);
851*89c4ff92SAndroid Build Coastguard Worker }
852*89c4ff92SAndroid Build Coastguard Worker 
853*89c4ff92SAndroid Build Coastguard Worker TEST_CASE("CheckCounterDirectoryRegisterCategory")
854*89c4ff92SAndroid Build Coastguard Worker {
855*89c4ff92SAndroid Build Coastguard Worker     CounterDirectory counterDirectory;
856*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterDirectory.GetCategoryCount() == 0);
857*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterDirectory.GetDeviceCount() == 0);
858*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterDirectory.GetCounterSetCount() == 0);
859*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterDirectory.GetCounterCount() == 0);
860*89c4ff92SAndroid Build Coastguard Worker 
861*89c4ff92SAndroid Build Coastguard Worker     // Register a category with an invalid name
862*89c4ff92SAndroid Build Coastguard Worker     const Category* noCategory = nullptr;
863*89c4ff92SAndroid Build Coastguard Worker     CHECK_THROWS_AS(noCategory = counterDirectory.RegisterCategory(""), arm::pipe::InvalidArgumentException);
864*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterDirectory.GetCategoryCount() == 0);
865*89c4ff92SAndroid Build Coastguard Worker     CHECK(!noCategory);
866*89c4ff92SAndroid Build Coastguard Worker 
867*89c4ff92SAndroid Build Coastguard Worker     // Register a category with an invalid name
868*89c4ff92SAndroid Build Coastguard Worker     CHECK_THROWS_AS(noCategory = counterDirectory.RegisterCategory("invalid category"),
869*89c4ff92SAndroid Build Coastguard Worker                       arm::pipe::InvalidArgumentException);
870*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterDirectory.GetCategoryCount() == 0);
871*89c4ff92SAndroid Build Coastguard Worker     CHECK(!noCategory);
872*89c4ff92SAndroid Build Coastguard Worker 
873*89c4ff92SAndroid Build Coastguard Worker     // Register a new category
874*89c4ff92SAndroid Build Coastguard Worker     const std::string categoryName = "some_category";
875*89c4ff92SAndroid Build Coastguard Worker     const Category* category       = nullptr;
876*89c4ff92SAndroid Build Coastguard Worker     CHECK_NOTHROW(category = counterDirectory.RegisterCategory(categoryName));
877*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterDirectory.GetCategoryCount() == 1);
878*89c4ff92SAndroid Build Coastguard Worker     CHECK(category);
879*89c4ff92SAndroid Build Coastguard Worker     CHECK(category->m_Name == categoryName);
880*89c4ff92SAndroid Build Coastguard Worker     CHECK(category->m_Counters.empty());
881*89c4ff92SAndroid Build Coastguard Worker 
882*89c4ff92SAndroid Build Coastguard Worker     // Get the registered category
883*89c4ff92SAndroid Build Coastguard Worker     const Category* registeredCategory = counterDirectory.GetCategory(categoryName);
884*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterDirectory.GetCategoryCount() == 1);
885*89c4ff92SAndroid Build Coastguard Worker     CHECK(registeredCategory);
886*89c4ff92SAndroid Build Coastguard Worker     CHECK(registeredCategory == category);
887*89c4ff92SAndroid Build Coastguard Worker 
888*89c4ff92SAndroid Build Coastguard Worker     // Try to get a category not registered
889*89c4ff92SAndroid Build Coastguard Worker     const Category* notRegisteredCategory = counterDirectory.GetCategory("not_registered_category");
890*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterDirectory.GetCategoryCount() == 1);
891*89c4ff92SAndroid Build Coastguard Worker     CHECK(!notRegisteredCategory);
892*89c4ff92SAndroid Build Coastguard Worker 
893*89c4ff92SAndroid Build Coastguard Worker     // Register a category already registered
894*89c4ff92SAndroid Build Coastguard Worker     const Category* anotherCategory = nullptr;
895*89c4ff92SAndroid Build Coastguard Worker     CHECK_THROWS_AS(anotherCategory = counterDirectory.RegisterCategory(categoryName),
896*89c4ff92SAndroid Build Coastguard Worker                       arm::pipe::InvalidArgumentException);
897*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterDirectory.GetCategoryCount() == 1);
898*89c4ff92SAndroid Build Coastguard Worker     CHECK(!anotherCategory);
899*89c4ff92SAndroid Build Coastguard Worker 
900*89c4ff92SAndroid Build Coastguard Worker     // Register a device for testing
901*89c4ff92SAndroid Build Coastguard Worker     const std::string deviceName = "some_device";
902*89c4ff92SAndroid Build Coastguard Worker     const Device* device         = nullptr;
903*89c4ff92SAndroid Build Coastguard Worker     CHECK_NOTHROW(device = counterDirectory.RegisterDevice(deviceName));
904*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterDirectory.GetDeviceCount() == 1);
905*89c4ff92SAndroid Build Coastguard Worker     CHECK(device);
906*89c4ff92SAndroid Build Coastguard Worker     CHECK(device->m_Uid >= 1);
907*89c4ff92SAndroid Build Coastguard Worker     CHECK(device->m_Name == deviceName);
908*89c4ff92SAndroid Build Coastguard Worker     CHECK(device->m_Cores == 0);
909*89c4ff92SAndroid Build Coastguard Worker 
910*89c4ff92SAndroid Build Coastguard Worker     // Register a new category not associated to any device
911*89c4ff92SAndroid Build Coastguard Worker     const std::string categoryWoDeviceName = "some_category_without_device";
912*89c4ff92SAndroid Build Coastguard Worker     const Category* categoryWoDevice       = nullptr;
913*89c4ff92SAndroid Build Coastguard Worker     CHECK_NOTHROW(categoryWoDevice = counterDirectory.RegisterCategory(categoryWoDeviceName));
914*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterDirectory.GetCategoryCount() == 2);
915*89c4ff92SAndroid Build Coastguard Worker     CHECK(categoryWoDevice);
916*89c4ff92SAndroid Build Coastguard Worker     CHECK(categoryWoDevice->m_Name == categoryWoDeviceName);
917*89c4ff92SAndroid Build Coastguard Worker     CHECK(categoryWoDevice->m_Counters.empty());
918*89c4ff92SAndroid Build Coastguard Worker 
919*89c4ff92SAndroid Build Coastguard Worker     // Register a new category associated to an invalid device name (already exist)
920*89c4ff92SAndroid Build Coastguard Worker     const Category* categoryInvalidDeviceName = nullptr;
921*89c4ff92SAndroid Build Coastguard Worker     CHECK_THROWS_AS(categoryInvalidDeviceName =
922*89c4ff92SAndroid Build Coastguard Worker                           counterDirectory.RegisterCategory(categoryWoDeviceName),
923*89c4ff92SAndroid Build Coastguard Worker                       arm::pipe::InvalidArgumentException);
924*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterDirectory.GetCategoryCount() == 2);
925*89c4ff92SAndroid Build Coastguard Worker     CHECK(!categoryInvalidDeviceName);
926*89c4ff92SAndroid Build Coastguard Worker 
927*89c4ff92SAndroid Build Coastguard Worker     // Register a new category associated to a valid device
928*89c4ff92SAndroid Build Coastguard Worker     const std::string categoryWValidDeviceName = "some_category_with_valid_device";
929*89c4ff92SAndroid Build Coastguard Worker     const Category* categoryWValidDevice       = nullptr;
930*89c4ff92SAndroid Build Coastguard Worker     CHECK_NOTHROW(categoryWValidDevice =
931*89c4ff92SAndroid Build Coastguard Worker                              counterDirectory.RegisterCategory(categoryWValidDeviceName));
932*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterDirectory.GetCategoryCount() == 3);
933*89c4ff92SAndroid Build Coastguard Worker     CHECK(categoryWValidDevice);
934*89c4ff92SAndroid Build Coastguard Worker     CHECK(categoryWValidDevice != category);
935*89c4ff92SAndroid Build Coastguard Worker     CHECK(categoryWValidDevice->m_Name == categoryWValidDeviceName);
936*89c4ff92SAndroid Build Coastguard Worker 
937*89c4ff92SAndroid Build Coastguard Worker     // Register a counter set for testing
938*89c4ff92SAndroid Build Coastguard Worker     const std::string counterSetName = "some_counter_set";
939*89c4ff92SAndroid Build Coastguard Worker     const CounterSet* counterSet     = nullptr;
940*89c4ff92SAndroid Build Coastguard Worker     CHECK_NOTHROW(counterSet = counterDirectory.RegisterCounterSet(counterSetName));
941*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterDirectory.GetCounterSetCount() == 1);
942*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterSet);
943*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterSet->m_Uid >= 1);
944*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterSet->m_Name == counterSetName);
945*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterSet->m_Count == 0);
946*89c4ff92SAndroid Build Coastguard Worker 
947*89c4ff92SAndroid Build Coastguard Worker     // Register a new category not associated to any counter set
948*89c4ff92SAndroid Build Coastguard Worker     const std::string categoryWoCounterSetName = "some_category_without_counter_set";
949*89c4ff92SAndroid Build Coastguard Worker     const Category* categoryWoCounterSet       = nullptr;
950*89c4ff92SAndroid Build Coastguard Worker     CHECK_NOTHROW(categoryWoCounterSet =
951*89c4ff92SAndroid Build Coastguard Worker                              counterDirectory.RegisterCategory(categoryWoCounterSetName));
952*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterDirectory.GetCategoryCount() == 4);
953*89c4ff92SAndroid Build Coastguard Worker     CHECK(categoryWoCounterSet);
954*89c4ff92SAndroid Build Coastguard Worker     CHECK(categoryWoCounterSet->m_Name == categoryWoCounterSetName);
955*89c4ff92SAndroid Build Coastguard Worker 
956*89c4ff92SAndroid Build Coastguard Worker     // Register a new category associated to a valid counter set
957*89c4ff92SAndroid Build Coastguard Worker     const std::string categoryWValidCounterSetName = "some_category_with_valid_counter_set";
958*89c4ff92SAndroid Build Coastguard Worker     const Category* categoryWValidCounterSet       = nullptr;
959*89c4ff92SAndroid Build Coastguard Worker     CHECK_NOTHROW(categoryWValidCounterSet = counterDirectory.RegisterCategory(categoryWValidCounterSetName));
960*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterDirectory.GetCategoryCount() == 5);
961*89c4ff92SAndroid Build Coastguard Worker     CHECK(categoryWValidCounterSet);
962*89c4ff92SAndroid Build Coastguard Worker     CHECK(categoryWValidCounterSet != category);
963*89c4ff92SAndroid Build Coastguard Worker     CHECK(categoryWValidCounterSet->m_Name == categoryWValidCounterSetName);
964*89c4ff92SAndroid Build Coastguard Worker 
965*89c4ff92SAndroid Build Coastguard Worker     // Register a new category associated to a valid device and counter set
966*89c4ff92SAndroid Build Coastguard Worker     const std::string categoryWValidDeviceAndValidCounterSetName = "some_category_with_valid_device_and_counter_set";
967*89c4ff92SAndroid Build Coastguard Worker     const Category* categoryWValidDeviceAndValidCounterSet       = nullptr;
968*89c4ff92SAndroid Build Coastguard Worker     CHECK_NOTHROW(categoryWValidDeviceAndValidCounterSet = counterDirectory.RegisterCategory(
969*89c4ff92SAndroid Build Coastguard Worker                              categoryWValidDeviceAndValidCounterSetName));
970*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterDirectory.GetCategoryCount() == 6);
971*89c4ff92SAndroid Build Coastguard Worker     CHECK(categoryWValidDeviceAndValidCounterSet);
972*89c4ff92SAndroid Build Coastguard Worker     CHECK(categoryWValidDeviceAndValidCounterSet != category);
973*89c4ff92SAndroid Build Coastguard Worker     CHECK(categoryWValidDeviceAndValidCounterSet->m_Name == categoryWValidDeviceAndValidCounterSetName);
974*89c4ff92SAndroid Build Coastguard Worker }
975*89c4ff92SAndroid Build Coastguard Worker 
976*89c4ff92SAndroid Build Coastguard Worker TEST_CASE("CheckCounterDirectoryRegisterDevice")
977*89c4ff92SAndroid Build Coastguard Worker {
978*89c4ff92SAndroid Build Coastguard Worker     CounterDirectory counterDirectory;
979*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterDirectory.GetCategoryCount() == 0);
980*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterDirectory.GetDeviceCount() == 0);
981*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterDirectory.GetCounterSetCount() == 0);
982*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterDirectory.GetCounterCount() == 0);
983*89c4ff92SAndroid Build Coastguard Worker 
984*89c4ff92SAndroid Build Coastguard Worker     // Register a device with an invalid name
985*89c4ff92SAndroid Build Coastguard Worker     const Device* noDevice = nullptr;
986*89c4ff92SAndroid Build Coastguard Worker     CHECK_THROWS_AS(noDevice = counterDirectory.RegisterDevice(""), arm::pipe::InvalidArgumentException);
987*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterDirectory.GetDeviceCount() == 0);
988*89c4ff92SAndroid Build Coastguard Worker     CHECK(!noDevice);
989*89c4ff92SAndroid Build Coastguard Worker 
990*89c4ff92SAndroid Build Coastguard Worker     // Register a device with an invalid name
991*89c4ff92SAndroid Build Coastguard Worker     CHECK_THROWS_AS(noDevice = counterDirectory.RegisterDevice("inv@lid nam€"), arm::pipe::InvalidArgumentException);
992*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterDirectory.GetDeviceCount() == 0);
993*89c4ff92SAndroid Build Coastguard Worker     CHECK(!noDevice);
994*89c4ff92SAndroid Build Coastguard Worker 
995*89c4ff92SAndroid Build Coastguard Worker     // Register a new device with no cores or parent category
996*89c4ff92SAndroid Build Coastguard Worker     const std::string deviceName = "some_device";
997*89c4ff92SAndroid Build Coastguard Worker     const Device* device         = nullptr;
998*89c4ff92SAndroid Build Coastguard Worker     CHECK_NOTHROW(device = counterDirectory.RegisterDevice(deviceName));
999*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterDirectory.GetDeviceCount() == 1);
1000*89c4ff92SAndroid Build Coastguard Worker     CHECK(device);
1001*89c4ff92SAndroid Build Coastguard Worker     CHECK(device->m_Name == deviceName);
1002*89c4ff92SAndroid Build Coastguard Worker     CHECK(device->m_Uid >= 1);
1003*89c4ff92SAndroid Build Coastguard Worker     CHECK(device->m_Cores == 0);
1004*89c4ff92SAndroid Build Coastguard Worker 
1005*89c4ff92SAndroid Build Coastguard Worker     // Try getting an unregistered device
1006*89c4ff92SAndroid Build Coastguard Worker     const Device* unregisteredDevice = counterDirectory.GetDevice(9999);
1007*89c4ff92SAndroid Build Coastguard Worker     CHECK(!unregisteredDevice);
1008*89c4ff92SAndroid Build Coastguard Worker 
1009*89c4ff92SAndroid Build Coastguard Worker     // Get the registered device
1010*89c4ff92SAndroid Build Coastguard Worker     const Device* registeredDevice = counterDirectory.GetDevice(device->m_Uid);
1011*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterDirectory.GetDeviceCount() == 1);
1012*89c4ff92SAndroid Build Coastguard Worker     CHECK(registeredDevice);
1013*89c4ff92SAndroid Build Coastguard Worker     CHECK(registeredDevice == device);
1014*89c4ff92SAndroid Build Coastguard Worker 
1015*89c4ff92SAndroid Build Coastguard Worker     // Register a device with the name of a device already registered
1016*89c4ff92SAndroid Build Coastguard Worker     const Device* deviceSameName = nullptr;
1017*89c4ff92SAndroid Build Coastguard Worker     CHECK_THROWS_AS(deviceSameName = counterDirectory.RegisterDevice(deviceName),
1018*89c4ff92SAndroid Build Coastguard Worker                                      arm::pipe::InvalidArgumentException);
1019*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterDirectory.GetDeviceCount() == 1);
1020*89c4ff92SAndroid Build Coastguard Worker     CHECK(!deviceSameName);
1021*89c4ff92SAndroid Build Coastguard Worker 
1022*89c4ff92SAndroid Build Coastguard Worker     // Register a new device with cores and no parent category
1023*89c4ff92SAndroid Build Coastguard Worker     const std::string deviceWCoresName = "some_device_with_cores";
1024*89c4ff92SAndroid Build Coastguard Worker     const Device* deviceWCores         = nullptr;
1025*89c4ff92SAndroid Build Coastguard Worker     CHECK_NOTHROW(deviceWCores = counterDirectory.RegisterDevice(deviceWCoresName, 2));
1026*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterDirectory.GetDeviceCount() == 2);
1027*89c4ff92SAndroid Build Coastguard Worker     CHECK(deviceWCores);
1028*89c4ff92SAndroid Build Coastguard Worker     CHECK(deviceWCores->m_Name == deviceWCoresName);
1029*89c4ff92SAndroid Build Coastguard Worker     CHECK(deviceWCores->m_Uid >= 1);
1030*89c4ff92SAndroid Build Coastguard Worker     CHECK(deviceWCores->m_Uid > device->m_Uid);
1031*89c4ff92SAndroid Build Coastguard Worker     CHECK(deviceWCores->m_Cores == 2);
1032*89c4ff92SAndroid Build Coastguard Worker 
1033*89c4ff92SAndroid Build Coastguard Worker     // Get the registered device
1034*89c4ff92SAndroid Build Coastguard Worker     const Device* registeredDeviceWCores = counterDirectory.GetDevice(deviceWCores->m_Uid);
1035*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterDirectory.GetDeviceCount() == 2);
1036*89c4ff92SAndroid Build Coastguard Worker     CHECK(registeredDeviceWCores);
1037*89c4ff92SAndroid Build Coastguard Worker     CHECK(registeredDeviceWCores == deviceWCores);
1038*89c4ff92SAndroid Build Coastguard Worker     CHECK(registeredDeviceWCores != device);
1039*89c4ff92SAndroid Build Coastguard Worker 
1040*89c4ff92SAndroid Build Coastguard Worker     // Register a new device with cores and invalid parent category
1041*89c4ff92SAndroid Build Coastguard Worker     const std::string deviceWCoresWInvalidParentCategoryName = "some_device_with_cores_with_invalid_parent_category";
1042*89c4ff92SAndroid Build Coastguard Worker     const Device* deviceWCoresWInvalidParentCategory         = nullptr;
1043*89c4ff92SAndroid Build Coastguard Worker     CHECK_THROWS_AS(deviceWCoresWInvalidParentCategory =
1044*89c4ff92SAndroid Build Coastguard Worker                           counterDirectory.RegisterDevice(deviceWCoresWInvalidParentCategoryName, 3, std::string("")),
1045*89c4ff92SAndroid Build Coastguard Worker                       arm::pipe::InvalidArgumentException);
1046*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterDirectory.GetDeviceCount() == 2);
1047*89c4ff92SAndroid Build Coastguard Worker     CHECK(!deviceWCoresWInvalidParentCategory);
1048*89c4ff92SAndroid Build Coastguard Worker 
1049*89c4ff92SAndroid Build Coastguard Worker     // Register a new device with cores and invalid parent category
1050*89c4ff92SAndroid Build Coastguard Worker     const std::string deviceWCoresWInvalidParentCategoryName2 = "some_device_with_cores_with_invalid_parent_category2";
1051*89c4ff92SAndroid Build Coastguard Worker     const Device* deviceWCoresWInvalidParentCategory2         = nullptr;
1052*89c4ff92SAndroid Build Coastguard Worker     CHECK_THROWS_AS(deviceWCoresWInvalidParentCategory2 = counterDirectory.RegisterDevice(
1053*89c4ff92SAndroid Build Coastguard Worker                           deviceWCoresWInvalidParentCategoryName2, 3, std::string("invalid_parent_category")),
1054*89c4ff92SAndroid Build Coastguard Worker                       arm::pipe::InvalidArgumentException);
1055*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterDirectory.GetDeviceCount() == 2);
1056*89c4ff92SAndroid Build Coastguard Worker     CHECK(!deviceWCoresWInvalidParentCategory2);
1057*89c4ff92SAndroid Build Coastguard Worker 
1058*89c4ff92SAndroid Build Coastguard Worker     // Register a category for testing
1059*89c4ff92SAndroid Build Coastguard Worker     const std::string categoryName = "some_category";
1060*89c4ff92SAndroid Build Coastguard Worker     const Category* category       = nullptr;
1061*89c4ff92SAndroid Build Coastguard Worker     CHECK_NOTHROW(category = counterDirectory.RegisterCategory(categoryName));
1062*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterDirectory.GetCategoryCount() == 1);
1063*89c4ff92SAndroid Build Coastguard Worker     CHECK(category);
1064*89c4ff92SAndroid Build Coastguard Worker     CHECK(category->m_Name == categoryName);
1065*89c4ff92SAndroid Build Coastguard Worker     CHECK(category->m_Counters.empty());
1066*89c4ff92SAndroid Build Coastguard Worker 
1067*89c4ff92SAndroid Build Coastguard Worker     // Register a new device with cores and valid parent category
1068*89c4ff92SAndroid Build Coastguard Worker     const std::string deviceWCoresWValidParentCategoryName = "some_device_with_cores_with_valid_parent_category";
1069*89c4ff92SAndroid Build Coastguard Worker     const Device* deviceWCoresWValidParentCategory         = nullptr;
1070*89c4ff92SAndroid Build Coastguard Worker     CHECK_NOTHROW(deviceWCoresWValidParentCategory =
1071*89c4ff92SAndroid Build Coastguard Worker                              counterDirectory.RegisterDevice(deviceWCoresWValidParentCategoryName, 4, categoryName));
1072*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterDirectory.GetDeviceCount() == 3);
1073*89c4ff92SAndroid Build Coastguard Worker     CHECK(deviceWCoresWValidParentCategory);
1074*89c4ff92SAndroid Build Coastguard Worker     CHECK(deviceWCoresWValidParentCategory->m_Name == deviceWCoresWValidParentCategoryName);
1075*89c4ff92SAndroid Build Coastguard Worker     CHECK(deviceWCoresWValidParentCategory->m_Uid >= 1);
1076*89c4ff92SAndroid Build Coastguard Worker     CHECK(deviceWCoresWValidParentCategory->m_Uid > device->m_Uid);
1077*89c4ff92SAndroid Build Coastguard Worker     CHECK(deviceWCoresWValidParentCategory->m_Uid > deviceWCores->m_Uid);
1078*89c4ff92SAndroid Build Coastguard Worker     CHECK(deviceWCoresWValidParentCategory->m_Cores == 4);
1079*89c4ff92SAndroid Build Coastguard Worker }
1080*89c4ff92SAndroid Build Coastguard Worker 
1081*89c4ff92SAndroid Build Coastguard Worker TEST_CASE("CheckCounterDirectoryRegisterCounterSet")
1082*89c4ff92SAndroid Build Coastguard Worker {
1083*89c4ff92SAndroid Build Coastguard Worker     CounterDirectory counterDirectory;
1084*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterDirectory.GetCategoryCount() == 0);
1085*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterDirectory.GetDeviceCount() == 0);
1086*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterDirectory.GetCounterSetCount() == 0);
1087*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterDirectory.GetCounterCount() == 0);
1088*89c4ff92SAndroid Build Coastguard Worker 
1089*89c4ff92SAndroid Build Coastguard Worker     // Register a counter set with an invalid name
1090*89c4ff92SAndroid Build Coastguard Worker     const CounterSet* noCounterSet = nullptr;
1091*89c4ff92SAndroid Build Coastguard Worker     CHECK_THROWS_AS(noCounterSet = counterDirectory.RegisterCounterSet(""), arm::pipe::InvalidArgumentException);
1092*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterDirectory.GetCounterSetCount() == 0);
1093*89c4ff92SAndroid Build Coastguard Worker     CHECK(!noCounterSet);
1094*89c4ff92SAndroid Build Coastguard Worker 
1095*89c4ff92SAndroid Build Coastguard Worker     // Register a counter set with an invalid name
1096*89c4ff92SAndroid Build Coastguard Worker     CHECK_THROWS_AS(noCounterSet = counterDirectory.RegisterCounterSet("invalid name"),
1097*89c4ff92SAndroid Build Coastguard Worker                       arm::pipe::InvalidArgumentException);
1098*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterDirectory.GetCounterSetCount() == 0);
1099*89c4ff92SAndroid Build Coastguard Worker     CHECK(!noCounterSet);
1100*89c4ff92SAndroid Build Coastguard Worker 
1101*89c4ff92SAndroid Build Coastguard Worker     // Register a new counter set with no count or parent category
1102*89c4ff92SAndroid Build Coastguard Worker     const std::string counterSetName = "some_counter_set";
1103*89c4ff92SAndroid Build Coastguard Worker     const CounterSet* counterSet     = nullptr;
1104*89c4ff92SAndroid Build Coastguard Worker     CHECK_NOTHROW(counterSet = counterDirectory.RegisterCounterSet(counterSetName));
1105*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterDirectory.GetCounterSetCount() == 1);
1106*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterSet);
1107*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterSet->m_Name == counterSetName);
1108*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterSet->m_Uid >= 1);
1109*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterSet->m_Count == 0);
1110*89c4ff92SAndroid Build Coastguard Worker 
1111*89c4ff92SAndroid Build Coastguard Worker     // Try getting an unregistered counter set
1112*89c4ff92SAndroid Build Coastguard Worker     const CounterSet* unregisteredCounterSet = counterDirectory.GetCounterSet(9999);
1113*89c4ff92SAndroid Build Coastguard Worker     CHECK(!unregisteredCounterSet);
1114*89c4ff92SAndroid Build Coastguard Worker 
1115*89c4ff92SAndroid Build Coastguard Worker     // Get the registered counter set
1116*89c4ff92SAndroid Build Coastguard Worker     const CounterSet* registeredCounterSet = counterDirectory.GetCounterSet(counterSet->m_Uid);
1117*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterDirectory.GetCounterSetCount() == 1);
1118*89c4ff92SAndroid Build Coastguard Worker     CHECK(registeredCounterSet);
1119*89c4ff92SAndroid Build Coastguard Worker     CHECK(registeredCounterSet == counterSet);
1120*89c4ff92SAndroid Build Coastguard Worker 
1121*89c4ff92SAndroid Build Coastguard Worker     // Register a counter set with the name of a counter set already registered
1122*89c4ff92SAndroid Build Coastguard Worker     const CounterSet* counterSetSameName = nullptr;
1123*89c4ff92SAndroid Build Coastguard Worker     CHECK_THROWS_AS(counterSetSameName = counterDirectory.RegisterCounterSet(counterSetName),
1124*89c4ff92SAndroid Build Coastguard Worker                       arm::pipe::InvalidArgumentException);
1125*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterDirectory.GetCounterSetCount() == 1);
1126*89c4ff92SAndroid Build Coastguard Worker     CHECK(!counterSetSameName);
1127*89c4ff92SAndroid Build Coastguard Worker 
1128*89c4ff92SAndroid Build Coastguard Worker     // Register a new counter set with count and no parent category
1129*89c4ff92SAndroid Build Coastguard Worker     const std::string counterSetWCountName = "some_counter_set_with_count";
1130*89c4ff92SAndroid Build Coastguard Worker     const CounterSet* counterSetWCount     = nullptr;
1131*89c4ff92SAndroid Build Coastguard Worker     CHECK_NOTHROW(counterSetWCount = counterDirectory.RegisterCounterSet(counterSetWCountName, 37));
1132*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterDirectory.GetCounterSetCount() == 2);
1133*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterSetWCount);
1134*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterSetWCount->m_Name == counterSetWCountName);
1135*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterSetWCount->m_Uid >= 1);
1136*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterSetWCount->m_Uid > counterSet->m_Uid);
1137*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterSetWCount->m_Count == 37);
1138*89c4ff92SAndroid Build Coastguard Worker 
1139*89c4ff92SAndroid Build Coastguard Worker     // Get the registered counter set
1140*89c4ff92SAndroid Build Coastguard Worker     const CounterSet* registeredCounterSetWCount = counterDirectory.GetCounterSet(counterSetWCount->m_Uid);
1141*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterDirectory.GetCounterSetCount() == 2);
1142*89c4ff92SAndroid Build Coastguard Worker     CHECK(registeredCounterSetWCount);
1143*89c4ff92SAndroid Build Coastguard Worker     CHECK(registeredCounterSetWCount == counterSetWCount);
1144*89c4ff92SAndroid Build Coastguard Worker     CHECK(registeredCounterSetWCount != counterSet);
1145*89c4ff92SAndroid Build Coastguard Worker 
1146*89c4ff92SAndroid Build Coastguard Worker     // Register a new counter set with count and invalid parent category
1147*89c4ff92SAndroid Build Coastguard Worker     const std::string counterSetWCountWInvalidParentCategoryName = "some_counter_set_with_count_"
1148*89c4ff92SAndroid Build Coastguard Worker                                                                    "with_invalid_parent_category";
1149*89c4ff92SAndroid Build Coastguard Worker     const CounterSet* counterSetWCountWInvalidParentCategory = nullptr;
1150*89c4ff92SAndroid Build Coastguard Worker     CHECK_THROWS_AS(counterSetWCountWInvalidParentCategory = counterDirectory.RegisterCounterSet(
1151*89c4ff92SAndroid Build Coastguard Worker                           counterSetWCountWInvalidParentCategoryName, 42, std::string("")),
1152*89c4ff92SAndroid Build Coastguard Worker                       arm::pipe::InvalidArgumentException);
1153*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterDirectory.GetCounterSetCount() == 2);
1154*89c4ff92SAndroid Build Coastguard Worker     CHECK(!counterSetWCountWInvalidParentCategory);
1155*89c4ff92SAndroid Build Coastguard Worker 
1156*89c4ff92SAndroid Build Coastguard Worker     // Register a new counter set with count and invalid parent category
1157*89c4ff92SAndroid Build Coastguard Worker     const std::string counterSetWCountWInvalidParentCategoryName2 = "some_counter_set_with_count_"
1158*89c4ff92SAndroid Build Coastguard Worker                                                                     "with_invalid_parent_category2";
1159*89c4ff92SAndroid Build Coastguard Worker     const CounterSet* counterSetWCountWInvalidParentCategory2 = nullptr;
1160*89c4ff92SAndroid Build Coastguard Worker     CHECK_THROWS_AS(counterSetWCountWInvalidParentCategory2 = counterDirectory.RegisterCounterSet(
1161*89c4ff92SAndroid Build Coastguard Worker                           counterSetWCountWInvalidParentCategoryName2, 42, std::string("invalid_parent_category")),
1162*89c4ff92SAndroid Build Coastguard Worker                       arm::pipe::InvalidArgumentException);
1163*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterDirectory.GetCounterSetCount() == 2);
1164*89c4ff92SAndroid Build Coastguard Worker     CHECK(!counterSetWCountWInvalidParentCategory2);
1165*89c4ff92SAndroid Build Coastguard Worker 
1166*89c4ff92SAndroid Build Coastguard Worker     // Register a category for testing
1167*89c4ff92SAndroid Build Coastguard Worker     const std::string categoryName = "some_category";
1168*89c4ff92SAndroid Build Coastguard Worker     const Category* category       = nullptr;
1169*89c4ff92SAndroid Build Coastguard Worker     CHECK_NOTHROW(category = counterDirectory.RegisterCategory(categoryName));
1170*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterDirectory.GetCategoryCount() == 1);
1171*89c4ff92SAndroid Build Coastguard Worker     CHECK(category);
1172*89c4ff92SAndroid Build Coastguard Worker     CHECK(category->m_Name == categoryName);
1173*89c4ff92SAndroid Build Coastguard Worker     CHECK(category->m_Counters.empty());
1174*89c4ff92SAndroid Build Coastguard Worker 
1175*89c4ff92SAndroid Build Coastguard Worker     // Register a new counter set with count and valid parent category
1176*89c4ff92SAndroid Build Coastguard Worker     const std::string counterSetWCountWValidParentCategoryName = "some_counter_set_with_count_"
1177*89c4ff92SAndroid Build Coastguard Worker                                                                  "with_valid_parent_category";
1178*89c4ff92SAndroid Build Coastguard Worker     const CounterSet* counterSetWCountWValidParentCategory = nullptr;
1179*89c4ff92SAndroid Build Coastguard Worker     CHECK_NOTHROW(counterSetWCountWValidParentCategory = counterDirectory.RegisterCounterSet(
1180*89c4ff92SAndroid Build Coastguard Worker                              counterSetWCountWValidParentCategoryName, 42, categoryName));
1181*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterDirectory.GetCounterSetCount() == 3);
1182*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterSetWCountWValidParentCategory);
1183*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterSetWCountWValidParentCategory->m_Name == counterSetWCountWValidParentCategoryName);
1184*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterSetWCountWValidParentCategory->m_Uid >= 1);
1185*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterSetWCountWValidParentCategory->m_Uid > counterSet->m_Uid);
1186*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterSetWCountWValidParentCategory->m_Uid > counterSetWCount->m_Uid);
1187*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterSetWCountWValidParentCategory->m_Count == 42);
1188*89c4ff92SAndroid Build Coastguard Worker 
1189*89c4ff92SAndroid Build Coastguard Worker     // Register a counter set associated to a category with invalid name
1190*89c4ff92SAndroid Build Coastguard Worker     const std::string counterSetSameCategoryName = "some_counter_set_with_invalid_parent_category";
1191*89c4ff92SAndroid Build Coastguard Worker     const std::string invalidCategoryName = "";
1192*89c4ff92SAndroid Build Coastguard Worker     const CounterSet* counterSetSameCategory     = nullptr;
1193*89c4ff92SAndroid Build Coastguard Worker     CHECK_THROWS_AS(counterSetSameCategory =
1194*89c4ff92SAndroid Build Coastguard Worker                           counterDirectory.RegisterCounterSet(counterSetSameCategoryName, 0, invalidCategoryName),
1195*89c4ff92SAndroid Build Coastguard Worker                       arm::pipe::InvalidArgumentException);
1196*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterDirectory.GetCounterSetCount() == 3);
1197*89c4ff92SAndroid Build Coastguard Worker     CHECK(!counterSetSameCategory);
1198*89c4ff92SAndroid Build Coastguard Worker }
1199*89c4ff92SAndroid Build Coastguard Worker 
1200*89c4ff92SAndroid Build Coastguard Worker TEST_CASE("CheckCounterDirectoryRegisterCounter")
1201*89c4ff92SAndroid Build Coastguard Worker {
1202*89c4ff92SAndroid Build Coastguard Worker     CounterDirectory counterDirectory;
1203*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterDirectory.GetCategoryCount() == 0);
1204*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterDirectory.GetDeviceCount() == 0);
1205*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterDirectory.GetCounterSetCount() == 0);
1206*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterDirectory.GetCounterCount() == 0);
1207*89c4ff92SAndroid Build Coastguard Worker 
1208*89c4ff92SAndroid Build Coastguard Worker     // Register a counter with an invalid parent category name
1209*89c4ff92SAndroid Build Coastguard Worker     const Counter* noCounter = nullptr;
1210*89c4ff92SAndroid Build Coastguard Worker     CHECK_THROWS_AS(noCounter =
1211*89c4ff92SAndroid Build Coastguard Worker                           counterDirectory.RegisterCounter(armnn::profiling::BACKEND_ID,
1212*89c4ff92SAndroid Build Coastguard Worker                                                            0,
1213*89c4ff92SAndroid Build Coastguard Worker                                                            "",
1214*89c4ff92SAndroid Build Coastguard Worker                                                            0,
1215*89c4ff92SAndroid Build Coastguard Worker                                                            1,
1216*89c4ff92SAndroid Build Coastguard Worker                                                            123.45f,
1217*89c4ff92SAndroid Build Coastguard Worker                                                            "valid ",
1218*89c4ff92SAndroid Build Coastguard Worker                                                            "name"),
1219*89c4ff92SAndroid Build Coastguard Worker                       arm::pipe::InvalidArgumentException);
1220*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterDirectory.GetCounterCount() == 0);
1221*89c4ff92SAndroid Build Coastguard Worker     CHECK(!noCounter);
1222*89c4ff92SAndroid Build Coastguard Worker 
1223*89c4ff92SAndroid Build Coastguard Worker     // Register a counter with an invalid parent category name
1224*89c4ff92SAndroid Build Coastguard Worker     CHECK_THROWS_AS(noCounter = counterDirectory.RegisterCounter(armnn::profiling::BACKEND_ID,
1225*89c4ff92SAndroid Build Coastguard Worker                                                                  1,
1226*89c4ff92SAndroid Build Coastguard Worker                                                                  "invalid parent category",
1227*89c4ff92SAndroid Build Coastguard Worker                                                                  0,
1228*89c4ff92SAndroid Build Coastguard Worker                                                                  1,
1229*89c4ff92SAndroid Build Coastguard Worker                                                                  123.45f,
1230*89c4ff92SAndroid Build Coastguard Worker                                                                  "valid name",
1231*89c4ff92SAndroid Build Coastguard Worker                                                                  "valid description"),
1232*89c4ff92SAndroid Build Coastguard Worker                       arm::pipe::InvalidArgumentException);
1233*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterDirectory.GetCounterCount() == 0);
1234*89c4ff92SAndroid Build Coastguard Worker     CHECK(!noCounter);
1235*89c4ff92SAndroid Build Coastguard Worker 
1236*89c4ff92SAndroid Build Coastguard Worker     // Register a counter with an invalid class
1237*89c4ff92SAndroid Build Coastguard Worker     CHECK_THROWS_AS(noCounter = counterDirectory.RegisterCounter(armnn::profiling::BACKEND_ID,
1238*89c4ff92SAndroid Build Coastguard Worker                                                                  2,
1239*89c4ff92SAndroid Build Coastguard Worker                                                                  "valid_parent_category",
1240*89c4ff92SAndroid Build Coastguard Worker                                                                  2,
1241*89c4ff92SAndroid Build Coastguard Worker                                                                  1,
1242*89c4ff92SAndroid Build Coastguard Worker                                                                  123.45f,
1243*89c4ff92SAndroid Build Coastguard Worker                                                                  "valid "
1244*89c4ff92SAndroid Build Coastguard Worker                                                                  "name",
1245*89c4ff92SAndroid Build Coastguard Worker                                                                  "valid description"),
1246*89c4ff92SAndroid Build Coastguard Worker                       arm::pipe::InvalidArgumentException);
1247*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterDirectory.GetCounterCount() == 0);
1248*89c4ff92SAndroid Build Coastguard Worker     CHECK(!noCounter);
1249*89c4ff92SAndroid Build Coastguard Worker 
1250*89c4ff92SAndroid Build Coastguard Worker     // Register a counter with an invalid interpolation
1251*89c4ff92SAndroid Build Coastguard Worker     CHECK_THROWS_AS(noCounter = counterDirectory.RegisterCounter(armnn::profiling::BACKEND_ID,
1252*89c4ff92SAndroid Build Coastguard Worker                                                                  4,
1253*89c4ff92SAndroid Build Coastguard Worker                                                                  "valid_parent_category",
1254*89c4ff92SAndroid Build Coastguard Worker                                                                  0,
1255*89c4ff92SAndroid Build Coastguard Worker                                                                  3,
1256*89c4ff92SAndroid Build Coastguard Worker                                                                  123.45f,
1257*89c4ff92SAndroid Build Coastguard Worker                                                                  "valid "
1258*89c4ff92SAndroid Build Coastguard Worker                                                                  "name",
1259*89c4ff92SAndroid Build Coastguard Worker                                                                  "valid description"),
1260*89c4ff92SAndroid Build Coastguard Worker                       arm::pipe::InvalidArgumentException);
1261*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterDirectory.GetCounterCount() == 0);
1262*89c4ff92SAndroid Build Coastguard Worker     CHECK(!noCounter);
1263*89c4ff92SAndroid Build Coastguard Worker 
1264*89c4ff92SAndroid Build Coastguard Worker     // Register a counter with an invalid multiplier
1265*89c4ff92SAndroid Build Coastguard Worker     CHECK_THROWS_AS(noCounter = counterDirectory.RegisterCounter(armnn::profiling::BACKEND_ID,
1266*89c4ff92SAndroid Build Coastguard Worker                                                                  5,
1267*89c4ff92SAndroid Build Coastguard Worker                                                                  "valid_parent_category",
1268*89c4ff92SAndroid Build Coastguard Worker                                                                  0,
1269*89c4ff92SAndroid Build Coastguard Worker                                                                  1,
1270*89c4ff92SAndroid Build Coastguard Worker                                                                  .0f,
1271*89c4ff92SAndroid Build Coastguard Worker                                                                  "valid "
1272*89c4ff92SAndroid Build Coastguard Worker                                                                  "name",
1273*89c4ff92SAndroid Build Coastguard Worker                                                                  "valid description"),
1274*89c4ff92SAndroid Build Coastguard Worker                       arm::pipe::InvalidArgumentException);
1275*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterDirectory.GetCounterCount() == 0);
1276*89c4ff92SAndroid Build Coastguard Worker     CHECK(!noCounter);
1277*89c4ff92SAndroid Build Coastguard Worker 
1278*89c4ff92SAndroid Build Coastguard Worker     // Register a counter with an invalid name
1279*89c4ff92SAndroid Build Coastguard Worker     CHECK_THROWS_AS(
1280*89c4ff92SAndroid Build Coastguard Worker         noCounter = counterDirectory.RegisterCounter(armnn::profiling::BACKEND_ID,
1281*89c4ff92SAndroid Build Coastguard Worker                                                      6,
1282*89c4ff92SAndroid Build Coastguard Worker                                                      "valid_parent_category",
1283*89c4ff92SAndroid Build Coastguard Worker                                                      0,
1284*89c4ff92SAndroid Build Coastguard Worker                                                      1,
1285*89c4ff92SAndroid Build Coastguard Worker                                                      123.45f,
1286*89c4ff92SAndroid Build Coastguard Worker                                                      "",
1287*89c4ff92SAndroid Build Coastguard Worker                                                      "valid description"),
1288*89c4ff92SAndroid Build Coastguard Worker         arm::pipe::InvalidArgumentException);
1289*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterDirectory.GetCounterCount() == 0);
1290*89c4ff92SAndroid Build Coastguard Worker     CHECK(!noCounter);
1291*89c4ff92SAndroid Build Coastguard Worker 
1292*89c4ff92SAndroid Build Coastguard Worker     // Register a counter with an invalid name
1293*89c4ff92SAndroid Build Coastguard Worker     CHECK_THROWS_AS(noCounter = counterDirectory.RegisterCounter(armnn::profiling::BACKEND_ID,
1294*89c4ff92SAndroid Build Coastguard Worker                                                                  7,
1295*89c4ff92SAndroid Build Coastguard Worker                                                                  "valid_parent_category",
1296*89c4ff92SAndroid Build Coastguard Worker                                                                  0,
1297*89c4ff92SAndroid Build Coastguard Worker                                                                  1,
1298*89c4ff92SAndroid Build Coastguard Worker                                                                  123.45f,
1299*89c4ff92SAndroid Build Coastguard Worker                                                                  "invalid nam€",
1300*89c4ff92SAndroid Build Coastguard Worker                                                                  "valid description"),
1301*89c4ff92SAndroid Build Coastguard Worker                       arm::pipe::InvalidArgumentException);
1302*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterDirectory.GetCounterCount() == 0);
1303*89c4ff92SAndroid Build Coastguard Worker     CHECK(!noCounter);
1304*89c4ff92SAndroid Build Coastguard Worker 
1305*89c4ff92SAndroid Build Coastguard Worker     // Register a counter with an invalid description
1306*89c4ff92SAndroid Build Coastguard Worker     CHECK_THROWS_AS(noCounter =
1307*89c4ff92SAndroid Build Coastguard Worker                           counterDirectory.RegisterCounter(armnn::profiling::BACKEND_ID,
1308*89c4ff92SAndroid Build Coastguard Worker                                                            8,
1309*89c4ff92SAndroid Build Coastguard Worker                                                            "valid_parent_category",
1310*89c4ff92SAndroid Build Coastguard Worker                                                            0,
1311*89c4ff92SAndroid Build Coastguard Worker                                                            1,
1312*89c4ff92SAndroid Build Coastguard Worker                                                            123.45f,
1313*89c4ff92SAndroid Build Coastguard Worker                                                            "valid name",
1314*89c4ff92SAndroid Build Coastguard Worker                                                            ""),
1315*89c4ff92SAndroid Build Coastguard Worker                       arm::pipe::InvalidArgumentException);
1316*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterDirectory.GetCounterCount() == 0);
1317*89c4ff92SAndroid Build Coastguard Worker     CHECK(!noCounter);
1318*89c4ff92SAndroid Build Coastguard Worker 
1319*89c4ff92SAndroid Build Coastguard Worker     // Register a counter with an invalid description
1320*89c4ff92SAndroid Build Coastguard Worker     CHECK_THROWS_AS(noCounter = counterDirectory.RegisterCounter(armnn::profiling::BACKEND_ID,
1321*89c4ff92SAndroid Build Coastguard Worker                                                                  9,
1322*89c4ff92SAndroid Build Coastguard Worker                                                                  "valid_parent_category",
1323*89c4ff92SAndroid Build Coastguard Worker                                                                  0,
1324*89c4ff92SAndroid Build Coastguard Worker                                                                  1,
1325*89c4ff92SAndroid Build Coastguard Worker                                                                  123.45f,
1326*89c4ff92SAndroid Build Coastguard Worker                                                                  "valid "
1327*89c4ff92SAndroid Build Coastguard Worker                                                                  "name",
1328*89c4ff92SAndroid Build Coastguard Worker                                                                  "inv@lid description"),
1329*89c4ff92SAndroid Build Coastguard Worker                       arm::pipe::InvalidArgumentException);
1330*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterDirectory.GetCounterCount() == 0);
1331*89c4ff92SAndroid Build Coastguard Worker     CHECK(!noCounter);
1332*89c4ff92SAndroid Build Coastguard Worker 
1333*89c4ff92SAndroid Build Coastguard Worker     // Register a counter with an invalid unit2
1334*89c4ff92SAndroid Build Coastguard Worker     CHECK_THROWS_AS(noCounter = counterDirectory.RegisterCounter(armnn::profiling::BACKEND_ID,
1335*89c4ff92SAndroid Build Coastguard Worker                                                                  10,
1336*89c4ff92SAndroid Build Coastguard Worker                                                                  "valid_parent_category",
1337*89c4ff92SAndroid Build Coastguard Worker                                                                  0,
1338*89c4ff92SAndroid Build Coastguard Worker                                                                  1,
1339*89c4ff92SAndroid Build Coastguard Worker                                                                  123.45f,
1340*89c4ff92SAndroid Build Coastguard Worker                                                                  "valid name",
1341*89c4ff92SAndroid Build Coastguard Worker                                                                  "valid description",
1342*89c4ff92SAndroid Build Coastguard Worker                                                                  std::string("Mb/s2")),
1343*89c4ff92SAndroid Build Coastguard Worker                       arm::pipe::InvalidArgumentException);
1344*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterDirectory.GetCounterCount() == 0);
1345*89c4ff92SAndroid Build Coastguard Worker     CHECK(!noCounter);
1346*89c4ff92SAndroid Build Coastguard Worker 
1347*89c4ff92SAndroid Build Coastguard Worker     // Register a counter with a non-existing parent category name
1348*89c4ff92SAndroid Build Coastguard Worker     CHECK_THROWS_AS(noCounter = counterDirectory.RegisterCounter(armnn::profiling::BACKEND_ID,
1349*89c4ff92SAndroid Build Coastguard Worker                                                                  11,
1350*89c4ff92SAndroid Build Coastguard Worker                                                                  "invalid_parent_category",
1351*89c4ff92SAndroid Build Coastguard Worker                                                                  0,
1352*89c4ff92SAndroid Build Coastguard Worker                                                                  1,
1353*89c4ff92SAndroid Build Coastguard Worker                                                                  123.45f,
1354*89c4ff92SAndroid Build Coastguard Worker                                                                  "valid name",
1355*89c4ff92SAndroid Build Coastguard Worker                                                                  "valid description"),
1356*89c4ff92SAndroid Build Coastguard Worker                       arm::pipe::InvalidArgumentException);
1357*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterDirectory.GetCounterCount() == 0);
1358*89c4ff92SAndroid Build Coastguard Worker     CHECK(!noCounter);
1359*89c4ff92SAndroid Build Coastguard Worker 
1360*89c4ff92SAndroid Build Coastguard Worker     // Try getting an unregistered counter
1361*89c4ff92SAndroid Build Coastguard Worker     const Counter* unregisteredCounter = counterDirectory.GetCounter(9999);
1362*89c4ff92SAndroid Build Coastguard Worker     CHECK(!unregisteredCounter);
1363*89c4ff92SAndroid Build Coastguard Worker 
1364*89c4ff92SAndroid Build Coastguard Worker     // Register a category for testing
1365*89c4ff92SAndroid Build Coastguard Worker     const std::string categoryName = "some_category";
1366*89c4ff92SAndroid Build Coastguard Worker     const Category* category       = nullptr;
1367*89c4ff92SAndroid Build Coastguard Worker     CHECK_NOTHROW(category = counterDirectory.RegisterCategory(categoryName));
1368*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterDirectory.GetCategoryCount() == 1);
1369*89c4ff92SAndroid Build Coastguard Worker     CHECK(category);
1370*89c4ff92SAndroid Build Coastguard Worker     CHECK(category->m_Name == categoryName);
1371*89c4ff92SAndroid Build Coastguard Worker     CHECK(category->m_Counters.empty());
1372*89c4ff92SAndroid Build Coastguard Worker 
1373*89c4ff92SAndroid Build Coastguard Worker     // Register a counter with a valid parent category name
1374*89c4ff92SAndroid Build Coastguard Worker     const Counter* counter = nullptr;
1375*89c4ff92SAndroid Build Coastguard Worker     CHECK_NOTHROW(
1376*89c4ff92SAndroid Build Coastguard Worker         counter = counterDirectory.RegisterCounter(armnn::profiling::BACKEND_ID,
1377*89c4ff92SAndroid Build Coastguard Worker                                                    12,
1378*89c4ff92SAndroid Build Coastguard Worker                                                    categoryName,
1379*89c4ff92SAndroid Build Coastguard Worker                                                    0,
1380*89c4ff92SAndroid Build Coastguard Worker                                                    1,
1381*89c4ff92SAndroid Build Coastguard Worker                                                    123.45f,
1382*89c4ff92SAndroid Build Coastguard Worker                                                    "valid name",
1383*89c4ff92SAndroid Build Coastguard Worker                                                    "valid description"));
1384*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterDirectory.GetCounterCount() == 1);
1385*89c4ff92SAndroid Build Coastguard Worker     CHECK(counter);
1386*89c4ff92SAndroid Build Coastguard Worker     CHECK(counter->m_MaxCounterUid == counter->m_Uid);
1387*89c4ff92SAndroid Build Coastguard Worker     CHECK(counter->m_Class == 0);
1388*89c4ff92SAndroid Build Coastguard Worker     CHECK(counter->m_Interpolation == 1);
1389*89c4ff92SAndroid Build Coastguard Worker     CHECK(counter->m_Multiplier == 123.45f);
1390*89c4ff92SAndroid Build Coastguard Worker     CHECK(counter->m_Name == "valid name");
1391*89c4ff92SAndroid Build Coastguard Worker     CHECK(counter->m_Description == "valid description");
1392*89c4ff92SAndroid Build Coastguard Worker     CHECK(counter->m_Units == "");
1393*89c4ff92SAndroid Build Coastguard Worker     CHECK(counter->m_DeviceUid == 0);
1394*89c4ff92SAndroid Build Coastguard Worker     CHECK(counter->m_CounterSetUid == 0);
1395*89c4ff92SAndroid Build Coastguard Worker     CHECK(category->m_Counters.size() == 1);
1396*89c4ff92SAndroid Build Coastguard Worker     CHECK(category->m_Counters.back() == counter->m_Uid);
1397*89c4ff92SAndroid Build Coastguard Worker 
1398*89c4ff92SAndroid Build Coastguard Worker     // Register a counter with a name of a counter already registered for the given parent category name
1399*89c4ff92SAndroid Build Coastguard Worker     const Counter* counterSameName = nullptr;
1400*89c4ff92SAndroid Build Coastguard Worker     CHECK_THROWS_AS(counterSameName =
1401*89c4ff92SAndroid Build Coastguard Worker                           counterDirectory.RegisterCounter(armnn::profiling::BACKEND_ID,
1402*89c4ff92SAndroid Build Coastguard Worker                                                            13,
1403*89c4ff92SAndroid Build Coastguard Worker                                                            categoryName,
1404*89c4ff92SAndroid Build Coastguard Worker                                                            0,
1405*89c4ff92SAndroid Build Coastguard Worker                                                            0,
1406*89c4ff92SAndroid Build Coastguard Worker                                                            1.0f,
1407*89c4ff92SAndroid Build Coastguard Worker                                                            "valid name",
1408*89c4ff92SAndroid Build Coastguard Worker                                                            "valid description",
1409*89c4ff92SAndroid Build Coastguard Worker                                                            std::string("description")),
1410*89c4ff92SAndroid Build Coastguard Worker                       arm::pipe::InvalidArgumentException);
1411*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterDirectory.GetCounterCount() == 1);
1412*89c4ff92SAndroid Build Coastguard Worker     CHECK(!counterSameName);
1413*89c4ff92SAndroid Build Coastguard Worker 
1414*89c4ff92SAndroid Build Coastguard Worker     // Register a counter with a valid parent category name and units
1415*89c4ff92SAndroid Build Coastguard Worker     const Counter* counterWUnits = nullptr;
1416*89c4ff92SAndroid Build Coastguard Worker     CHECK_NOTHROW(counterWUnits = counterDirectory.RegisterCounter(armnn::profiling::BACKEND_ID,
1417*89c4ff92SAndroid Build Coastguard Worker                                                                    14,
1418*89c4ff92SAndroid Build Coastguard Worker                                                                    categoryName,
1419*89c4ff92SAndroid Build Coastguard Worker                                                                    0,
1420*89c4ff92SAndroid Build Coastguard Worker                                                                    1,
1421*89c4ff92SAndroid Build Coastguard Worker                                                                    123.45f,
1422*89c4ff92SAndroid Build Coastguard Worker                                                                    "valid name 2",
1423*89c4ff92SAndroid Build Coastguard Worker                                                                    "valid description",
1424*89c4ff92SAndroid Build Coastguard Worker                                                                    std::string("Mnnsq2")));    // Units
1425*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterDirectory.GetCounterCount() == 2);
1426*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterWUnits);
1427*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterWUnits->m_Uid > counter->m_Uid);
1428*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterWUnits->m_MaxCounterUid == counterWUnits->m_Uid);
1429*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterWUnits->m_Class == 0);
1430*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterWUnits->m_Interpolation == 1);
1431*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterWUnits->m_Multiplier == 123.45f);
1432*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterWUnits->m_Name == "valid name 2");
1433*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterWUnits->m_Description == "valid description");
1434*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterWUnits->m_Units == "Mnnsq2");
1435*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterWUnits->m_DeviceUid == 0);
1436*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterWUnits->m_CounterSetUid == 0);
1437*89c4ff92SAndroid Build Coastguard Worker     CHECK(category->m_Counters.size() == 2);
1438*89c4ff92SAndroid Build Coastguard Worker     CHECK(category->m_Counters.back() == counterWUnits->m_Uid);
1439*89c4ff92SAndroid Build Coastguard Worker 
1440*89c4ff92SAndroid Build Coastguard Worker     // Register a counter with a valid parent category name and not associated with a device
1441*89c4ff92SAndroid Build Coastguard Worker     const Counter* counterWoDevice = nullptr;
1442*89c4ff92SAndroid Build Coastguard Worker     CHECK_NOTHROW(counterWoDevice = counterDirectory.RegisterCounter(armnn::profiling::BACKEND_ID,
1443*89c4ff92SAndroid Build Coastguard Worker                                                                      26,
1444*89c4ff92SAndroid Build Coastguard Worker                                                                      categoryName,
1445*89c4ff92SAndroid Build Coastguard Worker                                                                      0,
1446*89c4ff92SAndroid Build Coastguard Worker                                                                      1,
1447*89c4ff92SAndroid Build Coastguard Worker                                                                      123.45f,
1448*89c4ff92SAndroid Build Coastguard Worker                                                                      "valid name 3",
1449*89c4ff92SAndroid Build Coastguard Worker                                                                      "valid description",
1450*89c4ff92SAndroid Build Coastguard Worker                                                                      arm::pipe::EmptyOptional(),// Units
1451*89c4ff92SAndroid Build Coastguard Worker                                                                      arm::pipe::EmptyOptional(),// Number of cores
1452*89c4ff92SAndroid Build Coastguard Worker                                                                      0));                   // Device UID
1453*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterDirectory.GetCounterCount() == 3);
1454*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterWoDevice);
1455*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterWoDevice->m_Uid > counter->m_Uid);
1456*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterWoDevice->m_MaxCounterUid == counterWoDevice->m_Uid);
1457*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterWoDevice->m_Class == 0);
1458*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterWoDevice->m_Interpolation == 1);
1459*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterWoDevice->m_Multiplier == 123.45f);
1460*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterWoDevice->m_Name == "valid name 3");
1461*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterWoDevice->m_Description == "valid description");
1462*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterWoDevice->m_Units == "");
1463*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterWoDevice->m_DeviceUid == 0);
1464*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterWoDevice->m_CounterSetUid == 0);
1465*89c4ff92SAndroid Build Coastguard Worker     CHECK(category->m_Counters.size() == 3);
1466*89c4ff92SAndroid Build Coastguard Worker     CHECK(category->m_Counters.back() == counterWoDevice->m_Uid);
1467*89c4ff92SAndroid Build Coastguard Worker 
1468*89c4ff92SAndroid Build Coastguard Worker     // Register a counter with a valid parent category name and associated to an invalid device
1469*89c4ff92SAndroid Build Coastguard Worker     CHECK_THROWS_AS(noCounter = counterDirectory.RegisterCounter(armnn::profiling::BACKEND_ID,
1470*89c4ff92SAndroid Build Coastguard Worker                                                                 15,
1471*89c4ff92SAndroid Build Coastguard Worker                                                                 categoryName,
1472*89c4ff92SAndroid Build Coastguard Worker                                                                 0,
1473*89c4ff92SAndroid Build Coastguard Worker                                                                 1,
1474*89c4ff92SAndroid Build Coastguard Worker                                                                 123.45f,
1475*89c4ff92SAndroid Build Coastguard Worker                                                                 "valid name 4",
1476*89c4ff92SAndroid Build Coastguard Worker                                                                 "valid description",
1477*89c4ff92SAndroid Build Coastguard Worker                                                                 arm::pipe::EmptyOptional(),    // Units
1478*89c4ff92SAndroid Build Coastguard Worker                                                                 arm::pipe::EmptyOptional(),    // Number of cores
1479*89c4ff92SAndroid Build Coastguard Worker                                                                 100),                      // Device UID
1480*89c4ff92SAndroid Build Coastguard Worker                       arm::pipe::InvalidArgumentException);
1481*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterDirectory.GetCounterCount() == 3);
1482*89c4ff92SAndroid Build Coastguard Worker     CHECK(!noCounter);
1483*89c4ff92SAndroid Build Coastguard Worker 
1484*89c4ff92SAndroid Build Coastguard Worker     // Register a device for testing
1485*89c4ff92SAndroid Build Coastguard Worker     const std::string deviceName = "some_device";
1486*89c4ff92SAndroid Build Coastguard Worker     const Device* device         = nullptr;
1487*89c4ff92SAndroid Build Coastguard Worker     CHECK_NOTHROW(device = counterDirectory.RegisterDevice(deviceName));
1488*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterDirectory.GetDeviceCount() == 1);
1489*89c4ff92SAndroid Build Coastguard Worker     CHECK(device);
1490*89c4ff92SAndroid Build Coastguard Worker     CHECK(device->m_Name == deviceName);
1491*89c4ff92SAndroid Build Coastguard Worker     CHECK(device->m_Uid >= 1);
1492*89c4ff92SAndroid Build Coastguard Worker     CHECK(device->m_Cores == 0);
1493*89c4ff92SAndroid Build Coastguard Worker 
1494*89c4ff92SAndroid Build Coastguard Worker     // Register a counter with a valid parent category name and associated to a device
1495*89c4ff92SAndroid Build Coastguard Worker     const Counter* counterWDevice = nullptr;
1496*89c4ff92SAndroid Build Coastguard Worker     CHECK_NOTHROW(counterWDevice = counterDirectory.RegisterCounter(armnn::profiling::BACKEND_ID,
1497*89c4ff92SAndroid Build Coastguard Worker                                                                     16,
1498*89c4ff92SAndroid Build Coastguard Worker                                                                     categoryName,
1499*89c4ff92SAndroid Build Coastguard Worker                                                                     0,
1500*89c4ff92SAndroid Build Coastguard Worker                                                                     1,
1501*89c4ff92SAndroid Build Coastguard Worker                                                                     123.45f,
1502*89c4ff92SAndroid Build Coastguard Worker                                                                     "valid name 5",
1503*89c4ff92SAndroid Build Coastguard Worker                                                                     std::string("valid description"),
1504*89c4ff92SAndroid Build Coastguard Worker                                                                     arm::pipe::EmptyOptional(), // Units
1505*89c4ff92SAndroid Build Coastguard Worker                                                                     arm::pipe::EmptyOptional(), // Number of cores
1506*89c4ff92SAndroid Build Coastguard Worker                                                                     device->m_Uid));        // Device UID
1507*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterDirectory.GetCounterCount() == 4);
1508*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterWDevice);
1509*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterWDevice->m_Uid > counter->m_Uid);
1510*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterWDevice->m_MaxCounterUid == counterWDevice->m_Uid);
1511*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterWDevice->m_Class == 0);
1512*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterWDevice->m_Interpolation == 1);
1513*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterWDevice->m_Multiplier == 123.45f);
1514*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterWDevice->m_Name == "valid name 5");
1515*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterWDevice->m_Description == "valid description");
1516*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterWDevice->m_Units == "");
1517*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterWDevice->m_DeviceUid == device->m_Uid);
1518*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterWDevice->m_CounterSetUid == 0);
1519*89c4ff92SAndroid Build Coastguard Worker     CHECK(category->m_Counters.size() == 4);
1520*89c4ff92SAndroid Build Coastguard Worker     CHECK(category->m_Counters.back() == counterWDevice->m_Uid);
1521*89c4ff92SAndroid Build Coastguard Worker 
1522*89c4ff92SAndroid Build Coastguard Worker     // Register a counter with a valid parent category name and not associated with a counter set
1523*89c4ff92SAndroid Build Coastguard Worker     const Counter* counterWoCounterSet = nullptr;
1524*89c4ff92SAndroid Build Coastguard Worker     CHECK_NOTHROW(counterWoCounterSet = counterDirectory.RegisterCounter(armnn::profiling::BACKEND_ID,
1525*89c4ff92SAndroid Build Coastguard Worker                                                                          17,
1526*89c4ff92SAndroid Build Coastguard Worker                                                                          categoryName,
1527*89c4ff92SAndroid Build Coastguard Worker                                                                          0,
1528*89c4ff92SAndroid Build Coastguard Worker                                                                          1,
1529*89c4ff92SAndroid Build Coastguard Worker                                                                          123.45f,
1530*89c4ff92SAndroid Build Coastguard Worker                                                                          "valid name 6",
1531*89c4ff92SAndroid Build Coastguard Worker                                                                          "valid description",
1532*89c4ff92SAndroid Build Coastguard Worker                                                                          arm::pipe::EmptyOptional(),// Units
1533*89c4ff92SAndroid Build Coastguard Worker                                                                          arm::pipe::EmptyOptional(),// No of cores
1534*89c4ff92SAndroid Build Coastguard Worker                                                                          arm::pipe::EmptyOptional(),// Device UID
1535*89c4ff92SAndroid Build Coastguard Worker                                                                          0));               // CounterSet UID
1536*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterDirectory.GetCounterCount() == 5);
1537*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterWoCounterSet);
1538*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterWoCounterSet->m_Uid > counter->m_Uid);
1539*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterWoCounterSet->m_MaxCounterUid == counterWoCounterSet->m_Uid);
1540*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterWoCounterSet->m_Class == 0);
1541*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterWoCounterSet->m_Interpolation == 1);
1542*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterWoCounterSet->m_Multiplier == 123.45f);
1543*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterWoCounterSet->m_Name == "valid name 6");
1544*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterWoCounterSet->m_Description == "valid description");
1545*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterWoCounterSet->m_Units == "");
1546*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterWoCounterSet->m_DeviceUid == 0);
1547*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterWoCounterSet->m_CounterSetUid == 0);
1548*89c4ff92SAndroid Build Coastguard Worker     CHECK(category->m_Counters.size() == 5);
1549*89c4ff92SAndroid Build Coastguard Worker     CHECK(category->m_Counters.back() == counterWoCounterSet->m_Uid);
1550*89c4ff92SAndroid Build Coastguard Worker 
1551*89c4ff92SAndroid Build Coastguard Worker     // Register a counter with a valid parent category name and associated to an invalid counter set
1552*89c4ff92SAndroid Build Coastguard Worker     CHECK_THROWS_AS(noCounter = counterDirectory.RegisterCounter(armnn::profiling::BACKEND_ID,
1553*89c4ff92SAndroid Build Coastguard Worker                                                                  18,
1554*89c4ff92SAndroid Build Coastguard Worker                                                                  categoryName,
1555*89c4ff92SAndroid Build Coastguard Worker                                                                  0,
1556*89c4ff92SAndroid Build Coastguard Worker                                                                  1,
1557*89c4ff92SAndroid Build Coastguard Worker                                                                  123.45f,
1558*89c4ff92SAndroid Build Coastguard Worker                                                                  "valid ",
1559*89c4ff92SAndroid Build Coastguard Worker                                                                  "name 7",
1560*89c4ff92SAndroid Build Coastguard Worker                                                                  std::string("valid description"),
1561*89c4ff92SAndroid Build Coastguard Worker                                                                  arm::pipe::EmptyOptional(),    // Units
1562*89c4ff92SAndroid Build Coastguard Worker                                                                  arm::pipe::EmptyOptional(),    // Number of cores
1563*89c4ff92SAndroid Build Coastguard Worker                                                                  100),            // Counter set UID
1564*89c4ff92SAndroid Build Coastguard Worker                       arm::pipe::InvalidArgumentException);
1565*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterDirectory.GetCounterCount() == 5);
1566*89c4ff92SAndroid Build Coastguard Worker     CHECK(!noCounter);
1567*89c4ff92SAndroid Build Coastguard Worker 
1568*89c4ff92SAndroid Build Coastguard Worker     // Register a counter with a valid parent category name and with a given number of cores
1569*89c4ff92SAndroid Build Coastguard Worker     const Counter* counterWNumberOfCores = nullptr;
1570*89c4ff92SAndroid Build Coastguard Worker     uint16_t numberOfCores               = 15;
1571*89c4ff92SAndroid Build Coastguard Worker     CHECK_NOTHROW(counterWNumberOfCores = counterDirectory.RegisterCounter(
1572*89c4ff92SAndroid Build Coastguard Worker                              armnn::profiling::BACKEND_ID, 50,
1573*89c4ff92SAndroid Build Coastguard Worker                              categoryName, 0, 1, 123.45f, "valid name 8", "valid description",
1574*89c4ff92SAndroid Build Coastguard Worker                              arm::pipe::EmptyOptional(),      // Units
1575*89c4ff92SAndroid Build Coastguard Worker                              numberOfCores,               // Number of cores
1576*89c4ff92SAndroid Build Coastguard Worker                              arm::pipe::EmptyOptional(),      // Device UID
1577*89c4ff92SAndroid Build Coastguard Worker                              arm::pipe::EmptyOptional()));    // Counter set UID
1578*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterDirectory.GetCounterCount() == 20);
1579*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterWNumberOfCores);
1580*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterWNumberOfCores->m_Uid > counter->m_Uid);
1581*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterWNumberOfCores->m_MaxCounterUid == counterWNumberOfCores->m_Uid + numberOfCores - 1);
1582*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterWNumberOfCores->m_Class == 0);
1583*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterWNumberOfCores->m_Interpolation == 1);
1584*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterWNumberOfCores->m_Multiplier == 123.45f);
1585*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterWNumberOfCores->m_Name == "valid name 8");
1586*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterWNumberOfCores->m_Description == "valid description");
1587*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterWNumberOfCores->m_Units == "");
1588*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterWNumberOfCores->m_DeviceUid == 0);
1589*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterWNumberOfCores->m_CounterSetUid == 0);
1590*89c4ff92SAndroid Build Coastguard Worker     CHECK(category->m_Counters.size() == 20);
1591*89c4ff92SAndroid Build Coastguard Worker     for (size_t i = 0; i < numberOfCores; i++)
1592*89c4ff92SAndroid Build Coastguard Worker     {
1593*89c4ff92SAndroid Build Coastguard Worker         CHECK(category->m_Counters[category->m_Counters.size() - numberOfCores + i] ==
1594*89c4ff92SAndroid Build Coastguard Worker                     counterWNumberOfCores->m_Uid + i);
1595*89c4ff92SAndroid Build Coastguard Worker     }
1596*89c4ff92SAndroid Build Coastguard Worker 
1597*89c4ff92SAndroid Build Coastguard Worker     // Register a multi-core device for testing
1598*89c4ff92SAndroid Build Coastguard Worker     const std::string multiCoreDeviceName = "some_multi_core_device";
1599*89c4ff92SAndroid Build Coastguard Worker     const Device* multiCoreDevice         = nullptr;
1600*89c4ff92SAndroid Build Coastguard Worker     CHECK_NOTHROW(multiCoreDevice = counterDirectory.RegisterDevice(multiCoreDeviceName, 4));
1601*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterDirectory.GetDeviceCount() == 2);
1602*89c4ff92SAndroid Build Coastguard Worker     CHECK(multiCoreDevice);
1603*89c4ff92SAndroid Build Coastguard Worker     CHECK(multiCoreDevice->m_Name == multiCoreDeviceName);
1604*89c4ff92SAndroid Build Coastguard Worker     CHECK(multiCoreDevice->m_Uid >= 1);
1605*89c4ff92SAndroid Build Coastguard Worker     CHECK(multiCoreDevice->m_Cores == 4);
1606*89c4ff92SAndroid Build Coastguard Worker 
1607*89c4ff92SAndroid Build Coastguard Worker     // Register a counter with a valid parent category name and associated to the multi-core device
1608*89c4ff92SAndroid Build Coastguard Worker     const Counter* counterWMultiCoreDevice = nullptr;
1609*89c4ff92SAndroid Build Coastguard Worker     CHECK_NOTHROW(counterWMultiCoreDevice = counterDirectory.RegisterCounter(
1610*89c4ff92SAndroid Build Coastguard Worker                              armnn::profiling::BACKEND_ID, 19, categoryName, 0, 1,
1611*89c4ff92SAndroid Build Coastguard Worker                              123.45f, "valid name 9", "valid description",
1612*89c4ff92SAndroid Build Coastguard Worker                              arm::pipe::EmptyOptional(),      // Units
1613*89c4ff92SAndroid Build Coastguard Worker                              arm::pipe::EmptyOptional(),      // Number of cores
1614*89c4ff92SAndroid Build Coastguard Worker                              multiCoreDevice->m_Uid,      // Device UID
1615*89c4ff92SAndroid Build Coastguard Worker                              arm::pipe::EmptyOptional()));    // Counter set UID
1616*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterDirectory.GetCounterCount() == 24);
1617*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterWMultiCoreDevice);
1618*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterWMultiCoreDevice->m_Uid > counter->m_Uid);
1619*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterWMultiCoreDevice->m_MaxCounterUid ==
1620*89c4ff92SAndroid Build Coastguard Worker                 counterWMultiCoreDevice->m_Uid + multiCoreDevice->m_Cores - 1);
1621*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterWMultiCoreDevice->m_Class == 0);
1622*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterWMultiCoreDevice->m_Interpolation == 1);
1623*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterWMultiCoreDevice->m_Multiplier == 123.45f);
1624*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterWMultiCoreDevice->m_Name == "valid name 9");
1625*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterWMultiCoreDevice->m_Description == "valid description");
1626*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterWMultiCoreDevice->m_Units == "");
1627*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterWMultiCoreDevice->m_DeviceUid == multiCoreDevice->m_Uid);
1628*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterWMultiCoreDevice->m_CounterSetUid == 0);
1629*89c4ff92SAndroid Build Coastguard Worker     CHECK(category->m_Counters.size() == 24);
1630*89c4ff92SAndroid Build Coastguard Worker     for (size_t i = 0; i < 4; i++)
1631*89c4ff92SAndroid Build Coastguard Worker     {
1632*89c4ff92SAndroid Build Coastguard Worker         CHECK(category->m_Counters[category->m_Counters.size() - 4 + i] == counterWMultiCoreDevice->m_Uid + i);
1633*89c4ff92SAndroid Build Coastguard Worker     }
1634*89c4ff92SAndroid Build Coastguard Worker 
1635*89c4ff92SAndroid Build Coastguard Worker     // Register a multi-core device associate to a parent category for testing
1636*89c4ff92SAndroid Build Coastguard Worker     const std::string multiCoreDeviceNameWParentCategory = "some_multi_core_device_with_parent_category";
1637*89c4ff92SAndroid Build Coastguard Worker     const Device* multiCoreDeviceWParentCategory         = nullptr;
1638*89c4ff92SAndroid Build Coastguard Worker     CHECK_NOTHROW(multiCoreDeviceWParentCategory =
1639*89c4ff92SAndroid Build Coastguard Worker                              counterDirectory.RegisterDevice(multiCoreDeviceNameWParentCategory, 2, categoryName));
1640*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterDirectory.GetDeviceCount() == 3);
1641*89c4ff92SAndroid Build Coastguard Worker     CHECK(multiCoreDeviceWParentCategory);
1642*89c4ff92SAndroid Build Coastguard Worker     CHECK(multiCoreDeviceWParentCategory->m_Name == multiCoreDeviceNameWParentCategory);
1643*89c4ff92SAndroid Build Coastguard Worker     CHECK(multiCoreDeviceWParentCategory->m_Uid >= 1);
1644*89c4ff92SAndroid Build Coastguard Worker     CHECK(multiCoreDeviceWParentCategory->m_Cores == 2);
1645*89c4ff92SAndroid Build Coastguard Worker 
1646*89c4ff92SAndroid Build Coastguard Worker     // Register a counter with a valid parent category name and getting the number of cores of the multi-core device
1647*89c4ff92SAndroid Build Coastguard Worker     // associated to that category
1648*89c4ff92SAndroid Build Coastguard Worker     const Counter* counterWMultiCoreDeviceWParentCategory = nullptr;
1649*89c4ff92SAndroid Build Coastguard Worker     uint16_t numberOfCourse = multiCoreDeviceWParentCategory->m_Cores;
1650*89c4ff92SAndroid Build Coastguard Worker     CHECK_NOTHROW(counterWMultiCoreDeviceWParentCategory =
1651*89c4ff92SAndroid Build Coastguard Worker                                                 counterDirectory.RegisterCounter(
1652*89c4ff92SAndroid Build Coastguard Worker                                                     armnn::profiling::BACKEND_ID,
1653*89c4ff92SAndroid Build Coastguard Worker                                                     100,
1654*89c4ff92SAndroid Build Coastguard Worker                                                     categoryName,
1655*89c4ff92SAndroid Build Coastguard Worker                                                     0,
1656*89c4ff92SAndroid Build Coastguard Worker                                                     1,
1657*89c4ff92SAndroid Build Coastguard Worker                                                     123.45f,
1658*89c4ff92SAndroid Build Coastguard Worker                                                     "valid name 10",
1659*89c4ff92SAndroid Build Coastguard Worker                                                     "valid description",
1660*89c4ff92SAndroid Build Coastguard Worker                                                     arm::pipe::EmptyOptional(),  // Units
1661*89c4ff92SAndroid Build Coastguard Worker                                                     numberOfCourse,          // Number of cores
1662*89c4ff92SAndroid Build Coastguard Worker                                                     arm::pipe::EmptyOptional(),  // Device UID
1663*89c4ff92SAndroid Build Coastguard Worker                                                     arm::pipe::EmptyOptional()));// Counter set UID
1664*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterDirectory.GetCounterCount() == 26);
1665*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterWMultiCoreDeviceWParentCategory);
1666*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterWMultiCoreDeviceWParentCategory->m_Uid > counter->m_Uid);
1667*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterWMultiCoreDeviceWParentCategory->m_MaxCounterUid ==
1668*89c4ff92SAndroid Build Coastguard Worker                 counterWMultiCoreDeviceWParentCategory->m_Uid + multiCoreDeviceWParentCategory->m_Cores - 1);
1669*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterWMultiCoreDeviceWParentCategory->m_Class == 0);
1670*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterWMultiCoreDeviceWParentCategory->m_Interpolation == 1);
1671*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterWMultiCoreDeviceWParentCategory->m_Multiplier == 123.45f);
1672*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterWMultiCoreDeviceWParentCategory->m_Name == "valid name 10");
1673*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterWMultiCoreDeviceWParentCategory->m_Description == "valid description");
1674*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterWMultiCoreDeviceWParentCategory->m_Units == "");
1675*89c4ff92SAndroid Build Coastguard Worker     CHECK(category->m_Counters.size() == 26);
1676*89c4ff92SAndroid Build Coastguard Worker     for (size_t i = 0; i < 2; i++)
1677*89c4ff92SAndroid Build Coastguard Worker     {
1678*89c4ff92SAndroid Build Coastguard Worker         CHECK(category->m_Counters[category->m_Counters.size() - 2 + i] ==
1679*89c4ff92SAndroid Build Coastguard Worker                     counterWMultiCoreDeviceWParentCategory->m_Uid + i);
1680*89c4ff92SAndroid Build Coastguard Worker     }
1681*89c4ff92SAndroid Build Coastguard Worker 
1682*89c4ff92SAndroid Build Coastguard Worker     // Register a counter set for testing
1683*89c4ff92SAndroid Build Coastguard Worker     const std::string counterSetName = "some_counter_set";
1684*89c4ff92SAndroid Build Coastguard Worker     const CounterSet* counterSet     = nullptr;
1685*89c4ff92SAndroid Build Coastguard Worker     CHECK_NOTHROW(counterSet = counterDirectory.RegisterCounterSet(counterSetName));
1686*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterDirectory.GetCounterSetCount() == 1);
1687*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterSet);
1688*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterSet->m_Name == counterSetName);
1689*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterSet->m_Uid >= 1);
1690*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterSet->m_Count == 0);
1691*89c4ff92SAndroid Build Coastguard Worker 
1692*89c4ff92SAndroid Build Coastguard Worker     // Register a counter with a valid parent category name and associated to a counter set
1693*89c4ff92SAndroid Build Coastguard Worker     const Counter* counterWCounterSet = nullptr;
1694*89c4ff92SAndroid Build Coastguard Worker     CHECK_NOTHROW(counterWCounterSet = counterDirectory.RegisterCounter(
1695*89c4ff92SAndroid Build Coastguard Worker                              armnn::profiling::BACKEND_ID, 300,
1696*89c4ff92SAndroid Build Coastguard Worker                              categoryName, 0, 1, 123.45f, "valid name 11", "valid description",
1697*89c4ff92SAndroid Build Coastguard Worker                              arm::pipe::EmptyOptional(),    // Units
1698*89c4ff92SAndroid Build Coastguard Worker                              0,                         // Number of cores
1699*89c4ff92SAndroid Build Coastguard Worker                              arm::pipe::EmptyOptional(),    // Device UID
1700*89c4ff92SAndroid Build Coastguard Worker                              counterSet->m_Uid));       // Counter set UID
1701*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterDirectory.GetCounterCount() == 27);
1702*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterWCounterSet);
1703*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterWCounterSet->m_Uid > counter->m_Uid);
1704*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterWCounterSet->m_MaxCounterUid == counterWCounterSet->m_Uid);
1705*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterWCounterSet->m_Class == 0);
1706*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterWCounterSet->m_Interpolation == 1);
1707*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterWCounterSet->m_Multiplier == 123.45f);
1708*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterWCounterSet->m_Name == "valid name 11");
1709*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterWCounterSet->m_Description == "valid description");
1710*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterWCounterSet->m_Units == "");
1711*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterWCounterSet->m_DeviceUid == 0);
1712*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterWCounterSet->m_CounterSetUid == counterSet->m_Uid);
1713*89c4ff92SAndroid Build Coastguard Worker     CHECK(category->m_Counters.size() == 27);
1714*89c4ff92SAndroid Build Coastguard Worker     CHECK(category->m_Counters.back() == counterWCounterSet->m_Uid);
1715*89c4ff92SAndroid Build Coastguard Worker 
1716*89c4ff92SAndroid Build Coastguard Worker     // Register a counter with a valid parent category name and associated to a device and a counter set
1717*89c4ff92SAndroid Build Coastguard Worker     const Counter* counterWDeviceWCounterSet = nullptr;
1718*89c4ff92SAndroid Build Coastguard Worker     CHECK_NOTHROW(counterWDeviceWCounterSet = counterDirectory.RegisterCounter(
1719*89c4ff92SAndroid Build Coastguard Worker                              armnn::profiling::BACKEND_ID, 23,
1720*89c4ff92SAndroid Build Coastguard Worker                              categoryName, 0, 1, 123.45f, "valid name 12", "valid description",
1721*89c4ff92SAndroid Build Coastguard Worker                              arm::pipe::EmptyOptional(),    // Units
1722*89c4ff92SAndroid Build Coastguard Worker                              1,                         // Number of cores
1723*89c4ff92SAndroid Build Coastguard Worker                              device->m_Uid,             // Device UID
1724*89c4ff92SAndroid Build Coastguard Worker                              counterSet->m_Uid));       // Counter set UID
1725*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterDirectory.GetCounterCount() == 28);
1726*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterWDeviceWCounterSet);
1727*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterWDeviceWCounterSet->m_Uid > counter->m_Uid);
1728*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterWDeviceWCounterSet->m_MaxCounterUid == counterWDeviceWCounterSet->m_Uid);
1729*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterWDeviceWCounterSet->m_Class == 0);
1730*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterWDeviceWCounterSet->m_Interpolation == 1);
1731*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterWDeviceWCounterSet->m_Multiplier == 123.45f);
1732*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterWDeviceWCounterSet->m_Name == "valid name 12");
1733*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterWDeviceWCounterSet->m_Description == "valid description");
1734*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterWDeviceWCounterSet->m_Units == "");
1735*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterWDeviceWCounterSet->m_DeviceUid == device->m_Uid);
1736*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterWDeviceWCounterSet->m_CounterSetUid == counterSet->m_Uid);
1737*89c4ff92SAndroid Build Coastguard Worker     CHECK(category->m_Counters.size() == 28);
1738*89c4ff92SAndroid Build Coastguard Worker     CHECK(category->m_Counters.back() == counterWDeviceWCounterSet->m_Uid);
1739*89c4ff92SAndroid Build Coastguard Worker 
1740*89c4ff92SAndroid Build Coastguard Worker     // Register another category for testing
1741*89c4ff92SAndroid Build Coastguard Worker     const std::string anotherCategoryName = "some_other_category";
1742*89c4ff92SAndroid Build Coastguard Worker     const Category* anotherCategory       = nullptr;
1743*89c4ff92SAndroid Build Coastguard Worker     CHECK_NOTHROW(anotherCategory = counterDirectory.RegisterCategory(anotherCategoryName));
1744*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterDirectory.GetCategoryCount() == 2);
1745*89c4ff92SAndroid Build Coastguard Worker     CHECK(anotherCategory);
1746*89c4ff92SAndroid Build Coastguard Worker     CHECK(anotherCategory != category);
1747*89c4ff92SAndroid Build Coastguard Worker     CHECK(anotherCategory->m_Name == anotherCategoryName);
1748*89c4ff92SAndroid Build Coastguard Worker     CHECK(anotherCategory->m_Counters.empty());
1749*89c4ff92SAndroid Build Coastguard Worker 
1750*89c4ff92SAndroid Build Coastguard Worker     // Register a counter to the other category
1751*89c4ff92SAndroid Build Coastguard Worker     const Counter* anotherCounter = nullptr;
1752*89c4ff92SAndroid Build Coastguard Worker     CHECK_NOTHROW(anotherCounter = counterDirectory.RegisterCounter(armnn::profiling::BACKEND_ID, 24,
1753*89c4ff92SAndroid Build Coastguard Worker                                                                     anotherCategoryName, 1, 0, .00043f,
1754*89c4ff92SAndroid Build Coastguard Worker                                                                     "valid name", "valid description",
1755*89c4ff92SAndroid Build Coastguard Worker                                                                     arm::pipe::EmptyOptional(), // Units
1756*89c4ff92SAndroid Build Coastguard Worker                                                                     arm::pipe::EmptyOptional(), // Number of cores
1757*89c4ff92SAndroid Build Coastguard Worker                                                                     device->m_Uid,          // Device UID
1758*89c4ff92SAndroid Build Coastguard Worker                                                                     counterSet->m_Uid));    // Counter set UID
1759*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterDirectory.GetCounterCount() == 29);
1760*89c4ff92SAndroid Build Coastguard Worker     CHECK(anotherCounter);
1761*89c4ff92SAndroid Build Coastguard Worker     CHECK(anotherCounter->m_MaxCounterUid == anotherCounter->m_Uid);
1762*89c4ff92SAndroid Build Coastguard Worker     CHECK(anotherCounter->m_Class == 1);
1763*89c4ff92SAndroid Build Coastguard Worker     CHECK(anotherCounter->m_Interpolation == 0);
1764*89c4ff92SAndroid Build Coastguard Worker     CHECK(anotherCounter->m_Multiplier == .00043f);
1765*89c4ff92SAndroid Build Coastguard Worker     CHECK(anotherCounter->m_Name == "valid name");
1766*89c4ff92SAndroid Build Coastguard Worker     CHECK(anotherCounter->m_Description == "valid description");
1767*89c4ff92SAndroid Build Coastguard Worker     CHECK(anotherCounter->m_Units == "");
1768*89c4ff92SAndroid Build Coastguard Worker     CHECK(anotherCounter->m_DeviceUid == device->m_Uid);
1769*89c4ff92SAndroid Build Coastguard Worker     CHECK(anotherCounter->m_CounterSetUid == counterSet->m_Uid);
1770*89c4ff92SAndroid Build Coastguard Worker     CHECK(anotherCategory->m_Counters.size() == 1);
1771*89c4ff92SAndroid Build Coastguard Worker     CHECK(anotherCategory->m_Counters.back() == anotherCounter->m_Uid);
1772*89c4ff92SAndroid Build Coastguard Worker }
1773*89c4ff92SAndroid Build Coastguard Worker 
1774*89c4ff92SAndroid Build Coastguard Worker TEST_CASE("CounterSelectionCommandHandlerParseData")
1775*89c4ff92SAndroid Build Coastguard Worker {
1776*89c4ff92SAndroid Build Coastguard Worker     ProfilingStateMachine profilingStateMachine;
1777*89c4ff92SAndroid Build Coastguard Worker 
1778*89c4ff92SAndroid Build Coastguard Worker     class TestCaptureThread : public IPeriodicCounterCapture
1779*89c4ff92SAndroid Build Coastguard Worker     {
Start()1780*89c4ff92SAndroid Build Coastguard Worker         void Start() override
1781*89c4ff92SAndroid Build Coastguard Worker         {}
Stop()1782*89c4ff92SAndroid Build Coastguard Worker         void Stop() override
1783*89c4ff92SAndroid Build Coastguard Worker         {}
1784*89c4ff92SAndroid Build Coastguard Worker     };
1785*89c4ff92SAndroid Build Coastguard Worker 
1786*89c4ff92SAndroid Build Coastguard Worker     class TestReadCounterValues : public IReadCounterValues
1787*89c4ff92SAndroid Build Coastguard Worker     {
IsCounterRegistered(uint16_t counterUid) const1788*89c4ff92SAndroid Build Coastguard Worker         bool IsCounterRegistered(uint16_t counterUid) const override
1789*89c4ff92SAndroid Build Coastguard Worker         {
1790*89c4ff92SAndroid Build Coastguard Worker             arm::pipe::IgnoreUnused(counterUid);
1791*89c4ff92SAndroid Build Coastguard Worker             return true;
1792*89c4ff92SAndroid Build Coastguard Worker         }
IsCounterRegistered(const std::string & counterName) const1793*89c4ff92SAndroid Build Coastguard Worker         bool IsCounterRegistered(const std::string& counterName) const override
1794*89c4ff92SAndroid Build Coastguard Worker         {
1795*89c4ff92SAndroid Build Coastguard Worker             arm::pipe::IgnoreUnused(counterName);
1796*89c4ff92SAndroid Build Coastguard Worker             return true;
1797*89c4ff92SAndroid Build Coastguard Worker         }
GetCounterCount() const1798*89c4ff92SAndroid Build Coastguard Worker         uint16_t GetCounterCount() const override
1799*89c4ff92SAndroid Build Coastguard Worker         {
1800*89c4ff92SAndroid Build Coastguard Worker             return 0;
1801*89c4ff92SAndroid Build Coastguard Worker         }
GetAbsoluteCounterValue(uint16_t counterUid) const1802*89c4ff92SAndroid Build Coastguard Worker         uint32_t GetAbsoluteCounterValue(uint16_t counterUid) const override
1803*89c4ff92SAndroid Build Coastguard Worker         {
1804*89c4ff92SAndroid Build Coastguard Worker             arm::pipe::IgnoreUnused(counterUid);
1805*89c4ff92SAndroid Build Coastguard Worker             return 0;
1806*89c4ff92SAndroid Build Coastguard Worker         }
GetDeltaCounterValue(uint16_t counterUid)1807*89c4ff92SAndroid Build Coastguard Worker         uint32_t GetDeltaCounterValue(uint16_t counterUid) override
1808*89c4ff92SAndroid Build Coastguard Worker         {
1809*89c4ff92SAndroid Build Coastguard Worker             arm::pipe::IgnoreUnused(counterUid);
1810*89c4ff92SAndroid Build Coastguard Worker             return 0;
1811*89c4ff92SAndroid Build Coastguard Worker         }
1812*89c4ff92SAndroid Build Coastguard Worker     };
1813*89c4ff92SAndroid Build Coastguard Worker     const uint32_t familyId = 0;
1814*89c4ff92SAndroid Build Coastguard Worker     const uint32_t packetId = 0x40000;
1815*89c4ff92SAndroid Build Coastguard Worker 
1816*89c4ff92SAndroid Build Coastguard Worker     uint32_t version = 1;
1817*89c4ff92SAndroid Build Coastguard Worker     const std::unordered_map<std::string,
1818*89c4ff92SAndroid Build Coastguard Worker             std::shared_ptr<IBackendProfilingContext>> backendProfilingContext;
1819*89c4ff92SAndroid Build Coastguard Worker     CounterIdMap counterIdMap;
1820*89c4ff92SAndroid Build Coastguard Worker     Holder holder;
1821*89c4ff92SAndroid Build Coastguard Worker     TestCaptureThread captureThread;
1822*89c4ff92SAndroid Build Coastguard Worker     TestReadCounterValues readCounterValues;
1823*89c4ff92SAndroid Build Coastguard Worker     MockBufferManager mockBuffer(512);
1824*89c4ff92SAndroid Build Coastguard Worker     SendCounterPacket sendCounterPacket(mockBuffer,
1825*89c4ff92SAndroid Build Coastguard Worker                                         arm::pipe::ARMNN_SOFTWARE_INFO,
1826*89c4ff92SAndroid Build Coastguard Worker                                         arm::pipe::ARMNN_SOFTWARE_VERSION,
1827*89c4ff92SAndroid Build Coastguard Worker                                         arm::pipe::ARMNN_HARDWARE_VERSION);
1828*89c4ff92SAndroid Build Coastguard Worker     SendThread sendThread(profilingStateMachine, mockBuffer, sendCounterPacket);
1829*89c4ff92SAndroid Build Coastguard Worker 
1830*89c4ff92SAndroid Build Coastguard Worker     uint32_t sizeOfUint32 = arm::pipe::numeric_cast<uint32_t>(sizeof(uint32_t));
1831*89c4ff92SAndroid Build Coastguard Worker     uint32_t sizeOfUint16 = arm::pipe::numeric_cast<uint32_t>(sizeof(uint16_t));
1832*89c4ff92SAndroid Build Coastguard Worker 
1833*89c4ff92SAndroid Build Coastguard Worker     // Data with period and counters
1834*89c4ff92SAndroid Build Coastguard Worker     uint32_t period1     = arm::pipe::LOWEST_CAPTURE_PERIOD;
1835*89c4ff92SAndroid Build Coastguard Worker     uint32_t dataLength1 = 8;
1836*89c4ff92SAndroid Build Coastguard Worker     uint32_t offset      = 0;
1837*89c4ff92SAndroid Build Coastguard Worker 
1838*89c4ff92SAndroid Build Coastguard Worker     std::unique_ptr<unsigned char[]> uniqueData1 = std::make_unique<unsigned char[]>(dataLength1);
1839*89c4ff92SAndroid Build Coastguard Worker     unsigned char* data1                         = reinterpret_cast<unsigned char*>(uniqueData1.get());
1840*89c4ff92SAndroid Build Coastguard Worker 
1841*89c4ff92SAndroid Build Coastguard Worker     WriteUint32(data1, offset, period1);
1842*89c4ff92SAndroid Build Coastguard Worker     offset += sizeOfUint32;
1843*89c4ff92SAndroid Build Coastguard Worker     WriteUint16(data1, offset, 4000);
1844*89c4ff92SAndroid Build Coastguard Worker     offset += sizeOfUint16;
1845*89c4ff92SAndroid Build Coastguard Worker     WriteUint16(data1, offset, 5000);
1846*89c4ff92SAndroid Build Coastguard Worker 
1847*89c4ff92SAndroid Build Coastguard Worker     arm::pipe::Packet packetA(packetId, dataLength1, uniqueData1);
1848*89c4ff92SAndroid Build Coastguard Worker 
1849*89c4ff92SAndroid Build Coastguard Worker     PeriodicCounterSelectionCommandHandler commandHandler(familyId, packetId, version, backendProfilingContext,
1850*89c4ff92SAndroid Build Coastguard Worker                                                           counterIdMap, holder, 10000u, captureThread,
1851*89c4ff92SAndroid Build Coastguard Worker                                                           readCounterValues, sendCounterPacket, profilingStateMachine);
1852*89c4ff92SAndroid Build Coastguard Worker 
1853*89c4ff92SAndroid Build Coastguard Worker     profilingStateMachine.TransitionToState(ProfilingState::Uninitialised);
1854*89c4ff92SAndroid Build Coastguard Worker     CHECK_THROWS_AS(commandHandler(packetA), arm::pipe::ProfilingException);
1855*89c4ff92SAndroid Build Coastguard Worker     profilingStateMachine.TransitionToState(ProfilingState::NotConnected);
1856*89c4ff92SAndroid Build Coastguard Worker     CHECK_THROWS_AS(commandHandler(packetA), arm::pipe::ProfilingException);
1857*89c4ff92SAndroid Build Coastguard Worker     profilingStateMachine.TransitionToState(ProfilingState::WaitingForAck);
1858*89c4ff92SAndroid Build Coastguard Worker     CHECK_THROWS_AS(commandHandler(packetA), arm::pipe::ProfilingException);
1859*89c4ff92SAndroid Build Coastguard Worker     profilingStateMachine.TransitionToState(ProfilingState::Active);
1860*89c4ff92SAndroid Build Coastguard Worker     CHECK_NOTHROW(commandHandler(packetA));
1861*89c4ff92SAndroid Build Coastguard Worker 
1862*89c4ff92SAndroid Build Coastguard Worker     const std::vector<uint16_t> counterIdsA = holder.GetCaptureData().GetCounterIds();
1863*89c4ff92SAndroid Build Coastguard Worker 
1864*89c4ff92SAndroid Build Coastguard Worker     CHECK(holder.GetCaptureData().GetCapturePeriod() == period1);
1865*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterIdsA.size() == 2);
1866*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterIdsA[0] == 4000);
1867*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterIdsA[1] == 5000);
1868*89c4ff92SAndroid Build Coastguard Worker 
1869*89c4ff92SAndroid Build Coastguard Worker     auto readBuffer = mockBuffer.GetReadableBuffer();
1870*89c4ff92SAndroid Build Coastguard Worker 
1871*89c4ff92SAndroid Build Coastguard Worker     offset = 0;
1872*89c4ff92SAndroid Build Coastguard Worker 
1873*89c4ff92SAndroid Build Coastguard Worker     uint32_t headerWord0 = ReadUint32(readBuffer, offset);
1874*89c4ff92SAndroid Build Coastguard Worker     offset += sizeOfUint32;
1875*89c4ff92SAndroid Build Coastguard Worker     uint32_t headerWord1 = ReadUint32(readBuffer, offset);
1876*89c4ff92SAndroid Build Coastguard Worker     offset += sizeOfUint32;
1877*89c4ff92SAndroid Build Coastguard Worker     uint32_t period = ReadUint32(readBuffer, offset);
1878*89c4ff92SAndroid Build Coastguard Worker 
1879*89c4ff92SAndroid Build Coastguard Worker     CHECK(((headerWord0 >> 26) & 0x3F) == 0);             // packet family
1880*89c4ff92SAndroid Build Coastguard Worker     CHECK(((headerWord0 >> 16) & 0x3FF) == 4);            // packet id
1881*89c4ff92SAndroid Build Coastguard Worker     CHECK(headerWord1 == 8);                              // data length
1882*89c4ff92SAndroid Build Coastguard Worker     CHECK(period ==  arm::pipe::LOWEST_CAPTURE_PERIOD);   // capture period
1883*89c4ff92SAndroid Build Coastguard Worker 
1884*89c4ff92SAndroid Build Coastguard Worker     uint16_t counterId = 0;
1885*89c4ff92SAndroid Build Coastguard Worker     offset += sizeOfUint32;
1886*89c4ff92SAndroid Build Coastguard Worker     counterId = ReadUint16(readBuffer, offset);
1887*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterId == 4000);
1888*89c4ff92SAndroid Build Coastguard Worker     offset += sizeOfUint16;
1889*89c4ff92SAndroid Build Coastguard Worker     counterId = ReadUint16(readBuffer, offset);
1890*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterId == 5000);
1891*89c4ff92SAndroid Build Coastguard Worker 
1892*89c4ff92SAndroid Build Coastguard Worker     mockBuffer.MarkRead(readBuffer);
1893*89c4ff92SAndroid Build Coastguard Worker 
1894*89c4ff92SAndroid Build Coastguard Worker     // Data with period only
1895*89c4ff92SAndroid Build Coastguard Worker     uint32_t period2     = 9000; // We'll specify a value below LOWEST_CAPTURE_PERIOD. It should be pulled upwards.
1896*89c4ff92SAndroid Build Coastguard Worker     uint32_t dataLength2 = 4;
1897*89c4ff92SAndroid Build Coastguard Worker 
1898*89c4ff92SAndroid Build Coastguard Worker     std::unique_ptr<unsigned char[]> uniqueData2 = std::make_unique<unsigned char[]>(dataLength2);
1899*89c4ff92SAndroid Build Coastguard Worker 
1900*89c4ff92SAndroid Build Coastguard Worker     WriteUint32(reinterpret_cast<unsigned char*>(uniqueData2.get()), 0, period2);
1901*89c4ff92SAndroid Build Coastguard Worker 
1902*89c4ff92SAndroid Build Coastguard Worker     arm::pipe::Packet packetB(packetId, dataLength2, uniqueData2);
1903*89c4ff92SAndroid Build Coastguard Worker 
1904*89c4ff92SAndroid Build Coastguard Worker     commandHandler(packetB);
1905*89c4ff92SAndroid Build Coastguard Worker 
1906*89c4ff92SAndroid Build Coastguard Worker     const std::vector<uint16_t> counterIdsB = holder.GetCaptureData().GetCounterIds();
1907*89c4ff92SAndroid Build Coastguard Worker 
1908*89c4ff92SAndroid Build Coastguard Worker     // Value should have been pulled up from 9000 to LOWEST_CAPTURE_PERIOD.
1909*89c4ff92SAndroid Build Coastguard Worker     CHECK(holder.GetCaptureData().GetCapturePeriod() ==  arm::pipe::LOWEST_CAPTURE_PERIOD);
1910*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterIdsB.size() == 0);
1911*89c4ff92SAndroid Build Coastguard Worker 
1912*89c4ff92SAndroid Build Coastguard Worker     readBuffer = mockBuffer.GetReadableBuffer();
1913*89c4ff92SAndroid Build Coastguard Worker 
1914*89c4ff92SAndroid Build Coastguard Worker     offset = 0;
1915*89c4ff92SAndroid Build Coastguard Worker 
1916*89c4ff92SAndroid Build Coastguard Worker     headerWord0 = ReadUint32(readBuffer, offset);
1917*89c4ff92SAndroid Build Coastguard Worker     offset += sizeOfUint32;
1918*89c4ff92SAndroid Build Coastguard Worker     headerWord1 = ReadUint32(readBuffer, offset);
1919*89c4ff92SAndroid Build Coastguard Worker     offset += sizeOfUint32;
1920*89c4ff92SAndroid Build Coastguard Worker     period = ReadUint32(readBuffer, offset);
1921*89c4ff92SAndroid Build Coastguard Worker 
1922*89c4ff92SAndroid Build Coastguard Worker     CHECK(((headerWord0 >> 26) & 0x3F) == 0);          // packet family
1923*89c4ff92SAndroid Build Coastguard Worker     CHECK(((headerWord0 >> 16) & 0x3FF) == 4);         // packet id
1924*89c4ff92SAndroid Build Coastguard Worker     CHECK(headerWord1 == 4);                           // data length
1925*89c4ff92SAndroid Build Coastguard Worker     CHECK(period == arm::pipe::LOWEST_CAPTURE_PERIOD); // capture period
1926*89c4ff92SAndroid Build Coastguard Worker }
1927*89c4ff92SAndroid Build Coastguard Worker 
1928*89c4ff92SAndroid Build Coastguard Worker TEST_CASE("CheckTimelineActivationAndDeactivation")
1929*89c4ff92SAndroid Build Coastguard Worker {
1930*89c4ff92SAndroid Build Coastguard Worker     class TestReportStructure : public IReportStructure
1931*89c4ff92SAndroid Build Coastguard Worker     {
1932*89c4ff92SAndroid Build Coastguard Worker         public:
ReportStructure(arm::pipe::IProfilingService & profilingService)1933*89c4ff92SAndroid Build Coastguard Worker         virtual void ReportStructure(arm::pipe::IProfilingService& profilingService) override
1934*89c4ff92SAndroid Build Coastguard Worker         {
1935*89c4ff92SAndroid Build Coastguard Worker             arm::pipe::IgnoreUnused(profilingService);
1936*89c4ff92SAndroid Build Coastguard Worker             m_ReportStructureCalled = true;
1937*89c4ff92SAndroid Build Coastguard Worker         }
1938*89c4ff92SAndroid Build Coastguard Worker 
1939*89c4ff92SAndroid Build Coastguard Worker         bool m_ReportStructureCalled = false;
1940*89c4ff92SAndroid Build Coastguard Worker     };
1941*89c4ff92SAndroid Build Coastguard Worker 
1942*89c4ff92SAndroid Build Coastguard Worker     class TestNotifyBackends : public INotifyBackends
1943*89c4ff92SAndroid Build Coastguard Worker     {
1944*89c4ff92SAndroid Build Coastguard Worker         public:
TestNotifyBackends()1945*89c4ff92SAndroid Build Coastguard Worker         TestNotifyBackends() : m_timelineReporting(false) {}
NotifyBackendsForTimelineReporting()1946*89c4ff92SAndroid Build Coastguard Worker         virtual void NotifyBackendsForTimelineReporting() override
1947*89c4ff92SAndroid Build Coastguard Worker         {
1948*89c4ff92SAndroid Build Coastguard Worker             m_TestNotifyBackendsCalled = m_timelineReporting.load();
1949*89c4ff92SAndroid Build Coastguard Worker         }
1950*89c4ff92SAndroid Build Coastguard Worker 
1951*89c4ff92SAndroid Build Coastguard Worker         bool m_TestNotifyBackendsCalled = false;
1952*89c4ff92SAndroid Build Coastguard Worker         std::atomic<bool> m_timelineReporting;
1953*89c4ff92SAndroid Build Coastguard Worker     };
1954*89c4ff92SAndroid Build Coastguard Worker 
1955*89c4ff92SAndroid Build Coastguard Worker     arm::pipe::PacketVersionResolver packetVersionResolver;
1956*89c4ff92SAndroid Build Coastguard Worker 
1957*89c4ff92SAndroid Build Coastguard Worker     BufferManager bufferManager(512);
1958*89c4ff92SAndroid Build Coastguard Worker     SendTimelinePacket sendTimelinePacket(bufferManager);
1959*89c4ff92SAndroid Build Coastguard Worker     ProfilingStateMachine stateMachine;
1960*89c4ff92SAndroid Build Coastguard Worker     TestReportStructure testReportStructure;
1961*89c4ff92SAndroid Build Coastguard Worker     TestNotifyBackends testNotifyBackends;
1962*89c4ff92SAndroid Build Coastguard Worker     armnn::ArmNNProfilingServiceInitialiser initialiser;
1963*89c4ff92SAndroid Build Coastguard Worker     ProfilingService profilingService(arm::pipe::MAX_ARMNN_COUNTER,
1964*89c4ff92SAndroid Build Coastguard Worker                                       initialiser,
1965*89c4ff92SAndroid Build Coastguard Worker                                       arm::pipe::ARMNN_SOFTWARE_INFO,
1966*89c4ff92SAndroid Build Coastguard Worker                                       arm::pipe::ARMNN_SOFTWARE_VERSION,
1967*89c4ff92SAndroid Build Coastguard Worker                                       arm::pipe::ARMNN_HARDWARE_VERSION);
1968*89c4ff92SAndroid Build Coastguard Worker 
1969*89c4ff92SAndroid Build Coastguard Worker 
1970*89c4ff92SAndroid Build Coastguard Worker     ActivateTimelineReportingCommandHandler activateTimelineReportingCommandHandler(0,
1971*89c4ff92SAndroid Build Coastguard Worker                                                            6,
1972*89c4ff92SAndroid Build Coastguard Worker                                                            packetVersionResolver.ResolvePacketVersion(0, 6)
1973*89c4ff92SAndroid Build Coastguard Worker                                                            .GetEncodedValue(),
1974*89c4ff92SAndroid Build Coastguard Worker                                                            sendTimelinePacket,
1975*89c4ff92SAndroid Build Coastguard Worker                                                            stateMachine,
1976*89c4ff92SAndroid Build Coastguard Worker                                                            testReportStructure,
1977*89c4ff92SAndroid Build Coastguard Worker                                                            testNotifyBackends.m_timelineReporting,
1978*89c4ff92SAndroid Build Coastguard Worker                                                            testNotifyBackends,
1979*89c4ff92SAndroid Build Coastguard Worker                                                            profilingService);
1980*89c4ff92SAndroid Build Coastguard Worker 
1981*89c4ff92SAndroid Build Coastguard Worker     // Write an "ActivateTimelineReporting" packet into the mock profiling connection, to simulate an input from an
1982*89c4ff92SAndroid Build Coastguard Worker     // external profiling service
1983*89c4ff92SAndroid Build Coastguard Worker     const uint32_t packetFamily1 = 0;
1984*89c4ff92SAndroid Build Coastguard Worker     const uint32_t packetId1     = 6;
1985*89c4ff92SAndroid Build Coastguard Worker     uint32_t packetHeader1 = ConstructHeader(packetFamily1, packetId1);
1986*89c4ff92SAndroid Build Coastguard Worker 
1987*89c4ff92SAndroid Build Coastguard Worker     // Create the ActivateTimelineReportingPacket
1988*89c4ff92SAndroid Build Coastguard Worker     arm::pipe::Packet ActivateTimelineReportingPacket(packetHeader1); // Length == 0
1989*89c4ff92SAndroid Build Coastguard Worker 
1990*89c4ff92SAndroid Build Coastguard Worker     CHECK_THROWS_AS(
1991*89c4ff92SAndroid Build Coastguard Worker         activateTimelineReportingCommandHandler.operator()(ActivateTimelineReportingPacket),
1992*89c4ff92SAndroid Build Coastguard Worker                                                            arm::pipe::ProfilingException);
1993*89c4ff92SAndroid Build Coastguard Worker 
1994*89c4ff92SAndroid Build Coastguard Worker     stateMachine.TransitionToState(ProfilingState::NotConnected);
1995*89c4ff92SAndroid Build Coastguard Worker     CHECK_THROWS_AS(
1996*89c4ff92SAndroid Build Coastguard Worker         activateTimelineReportingCommandHandler.operator()(ActivateTimelineReportingPacket),
1997*89c4ff92SAndroid Build Coastguard Worker                                                            arm::pipe::ProfilingException);
1998*89c4ff92SAndroid Build Coastguard Worker 
1999*89c4ff92SAndroid Build Coastguard Worker     stateMachine.TransitionToState(ProfilingState::WaitingForAck);
2000*89c4ff92SAndroid Build Coastguard Worker     CHECK_THROWS_AS(
2001*89c4ff92SAndroid Build Coastguard Worker         activateTimelineReportingCommandHandler.operator()(ActivateTimelineReportingPacket),
2002*89c4ff92SAndroid Build Coastguard Worker                                                            arm::pipe::ProfilingException);
2003*89c4ff92SAndroid Build Coastguard Worker 
2004*89c4ff92SAndroid Build Coastguard Worker     stateMachine.TransitionToState(ProfilingState::Active);
2005*89c4ff92SAndroid Build Coastguard Worker     activateTimelineReportingCommandHandler.operator()(ActivateTimelineReportingPacket);
2006*89c4ff92SAndroid Build Coastguard Worker 
2007*89c4ff92SAndroid Build Coastguard Worker     CHECK(testReportStructure.m_ReportStructureCalled);
2008*89c4ff92SAndroid Build Coastguard Worker     CHECK(testNotifyBackends.m_TestNotifyBackendsCalled);
2009*89c4ff92SAndroid Build Coastguard Worker     CHECK(testNotifyBackends.m_timelineReporting.load());
2010*89c4ff92SAndroid Build Coastguard Worker 
2011*89c4ff92SAndroid Build Coastguard Worker     DeactivateTimelineReportingCommandHandler deactivateTimelineReportingCommandHandler(0,
2012*89c4ff92SAndroid Build Coastguard Worker                                                   7,
2013*89c4ff92SAndroid Build Coastguard Worker                                                   packetVersionResolver.ResolvePacketVersion(0, 7).GetEncodedValue(),
2014*89c4ff92SAndroid Build Coastguard Worker                                                   testNotifyBackends.m_timelineReporting,
2015*89c4ff92SAndroid Build Coastguard Worker                                                   stateMachine,
2016*89c4ff92SAndroid Build Coastguard Worker                                                   testNotifyBackends);
2017*89c4ff92SAndroid Build Coastguard Worker 
2018*89c4ff92SAndroid Build Coastguard Worker     const uint32_t packetFamily2 = 0;
2019*89c4ff92SAndroid Build Coastguard Worker     const uint32_t packetId2     = 7;
2020*89c4ff92SAndroid Build Coastguard Worker     uint32_t packetHeader2 = ConstructHeader(packetFamily2, packetId2);
2021*89c4ff92SAndroid Build Coastguard Worker 
2022*89c4ff92SAndroid Build Coastguard Worker     // Create the DeactivateTimelineReportingPacket
2023*89c4ff92SAndroid Build Coastguard Worker     arm::pipe::Packet deactivateTimelineReportingPacket(packetHeader2); // Length == 0
2024*89c4ff92SAndroid Build Coastguard Worker 
2025*89c4ff92SAndroid Build Coastguard Worker     stateMachine.Reset();
2026*89c4ff92SAndroid Build Coastguard Worker     CHECK_THROWS_AS(
2027*89c4ff92SAndroid Build Coastguard Worker         deactivateTimelineReportingCommandHandler.operator()(deactivateTimelineReportingPacket),
2028*89c4ff92SAndroid Build Coastguard Worker                                                              arm::pipe::ProfilingException);
2029*89c4ff92SAndroid Build Coastguard Worker 
2030*89c4ff92SAndroid Build Coastguard Worker     stateMachine.TransitionToState(ProfilingState::NotConnected);
2031*89c4ff92SAndroid Build Coastguard Worker     CHECK_THROWS_AS(
2032*89c4ff92SAndroid Build Coastguard Worker         deactivateTimelineReportingCommandHandler.operator()(deactivateTimelineReportingPacket),
2033*89c4ff92SAndroid Build Coastguard Worker                                                              arm::pipe::ProfilingException);
2034*89c4ff92SAndroid Build Coastguard Worker 
2035*89c4ff92SAndroid Build Coastguard Worker     stateMachine.TransitionToState(ProfilingState::WaitingForAck);
2036*89c4ff92SAndroid Build Coastguard Worker     CHECK_THROWS_AS(
2037*89c4ff92SAndroid Build Coastguard Worker         deactivateTimelineReportingCommandHandler.operator()(deactivateTimelineReportingPacket),
2038*89c4ff92SAndroid Build Coastguard Worker                                                              arm::pipe::ProfilingException);
2039*89c4ff92SAndroid Build Coastguard Worker 
2040*89c4ff92SAndroid Build Coastguard Worker     stateMachine.TransitionToState(ProfilingState::Active);
2041*89c4ff92SAndroid Build Coastguard Worker     deactivateTimelineReportingCommandHandler.operator()(deactivateTimelineReportingPacket);
2042*89c4ff92SAndroid Build Coastguard Worker 
2043*89c4ff92SAndroid Build Coastguard Worker     CHECK(!testNotifyBackends.m_TestNotifyBackendsCalled);
2044*89c4ff92SAndroid Build Coastguard Worker     CHECK(!testNotifyBackends.m_timelineReporting.load());
2045*89c4ff92SAndroid Build Coastguard Worker }
2046*89c4ff92SAndroid Build Coastguard Worker 
2047*89c4ff92SAndroid Build Coastguard Worker TEST_CASE("CheckProfilingServiceNotActive")
2048*89c4ff92SAndroid Build Coastguard Worker {
2049*89c4ff92SAndroid Build Coastguard Worker     using namespace armnn;
2050*89c4ff92SAndroid Build Coastguard Worker 
2051*89c4ff92SAndroid Build Coastguard Worker     // Create runtime in which the test will run
2052*89c4ff92SAndroid Build Coastguard Worker     armnn::IRuntime::CreationOptions options;
2053*89c4ff92SAndroid Build Coastguard Worker     options.m_ProfilingOptions.m_EnableProfiling = true;
2054*89c4ff92SAndroid Build Coastguard Worker 
2055*89c4ff92SAndroid Build Coastguard Worker     armnn::RuntimeImpl runtime(options);
2056*89c4ff92SAndroid Build Coastguard Worker     armnn::ArmNNProfilingServiceInitialiser initialiser;
2057*89c4ff92SAndroid Build Coastguard Worker     ProfilingServiceRuntimeHelper profilingServiceHelper(
2058*89c4ff92SAndroid Build Coastguard Worker         arm::pipe::MAX_ARMNN_COUNTER, initialiser, GetProfilingService(&runtime));
2059*89c4ff92SAndroid Build Coastguard Worker     profilingServiceHelper.ForceTransitionToState(ProfilingState::NotConnected);
2060*89c4ff92SAndroid Build Coastguard Worker     profilingServiceHelper.ForceTransitionToState(ProfilingState::WaitingForAck);
2061*89c4ff92SAndroid Build Coastguard Worker     profilingServiceHelper.ForceTransitionToState(ProfilingState::Active);
2062*89c4ff92SAndroid Build Coastguard Worker 
2063*89c4ff92SAndroid Build Coastguard Worker     BufferManager& bufferManager = profilingServiceHelper.GetProfilingBufferManager();
2064*89c4ff92SAndroid Build Coastguard Worker     auto readableBuffer = bufferManager.GetReadableBuffer();
2065*89c4ff92SAndroid Build Coastguard Worker 
2066*89c4ff92SAndroid Build Coastguard Worker     // Profiling is enabled, the post-optimisation structure should be created
2067*89c4ff92SAndroid Build Coastguard Worker     CHECK(readableBuffer == nullptr);
2068*89c4ff92SAndroid Build Coastguard Worker }
2069*89c4ff92SAndroid Build Coastguard Worker 
2070*89c4ff92SAndroid Build Coastguard Worker TEST_CASE("CheckConnectionAcknowledged")
2071*89c4ff92SAndroid Build Coastguard Worker {
2072*89c4ff92SAndroid Build Coastguard Worker     const uint32_t packetFamilyId     = 0;
2073*89c4ff92SAndroid Build Coastguard Worker     const uint32_t connectionPacketId = 0x10000;
2074*89c4ff92SAndroid Build Coastguard Worker     const uint32_t version            = 1;
2075*89c4ff92SAndroid Build Coastguard Worker 
2076*89c4ff92SAndroid Build Coastguard Worker     uint32_t sizeOfUint32 = arm::pipe::numeric_cast<uint32_t>(sizeof(uint32_t));
2077*89c4ff92SAndroid Build Coastguard Worker     uint32_t sizeOfUint16 = arm::pipe::numeric_cast<uint32_t>(sizeof(uint16_t));
2078*89c4ff92SAndroid Build Coastguard Worker 
2079*89c4ff92SAndroid Build Coastguard Worker     // Data with period and counters
2080*89c4ff92SAndroid Build Coastguard Worker     uint32_t period1     = 10;
2081*89c4ff92SAndroid Build Coastguard Worker     uint32_t dataLength1 = 8;
2082*89c4ff92SAndroid Build Coastguard Worker     uint32_t offset      = 0;
2083*89c4ff92SAndroid Build Coastguard Worker 
2084*89c4ff92SAndroid Build Coastguard Worker     std::unique_ptr<unsigned char[]> uniqueData1 = std::make_unique<unsigned char[]>(dataLength1);
2085*89c4ff92SAndroid Build Coastguard Worker     unsigned char* data1                         = reinterpret_cast<unsigned char*>(uniqueData1.get());
2086*89c4ff92SAndroid Build Coastguard Worker 
2087*89c4ff92SAndroid Build Coastguard Worker     WriteUint32(data1, offset, period1);
2088*89c4ff92SAndroid Build Coastguard Worker     offset += sizeOfUint32;
2089*89c4ff92SAndroid Build Coastguard Worker     WriteUint16(data1, offset, 4000);
2090*89c4ff92SAndroid Build Coastguard Worker     offset += sizeOfUint16;
2091*89c4ff92SAndroid Build Coastguard Worker     WriteUint16(data1, offset, 5000);
2092*89c4ff92SAndroid Build Coastguard Worker 
2093*89c4ff92SAndroid Build Coastguard Worker     arm::pipe::Packet packetA(connectionPacketId, dataLength1, uniqueData1);
2094*89c4ff92SAndroid Build Coastguard Worker 
2095*89c4ff92SAndroid Build Coastguard Worker     ProfilingStateMachine profilingState(ProfilingState::Uninitialised);
2096*89c4ff92SAndroid Build Coastguard Worker     CHECK(profilingState.GetCurrentState() == ProfilingState::Uninitialised);
2097*89c4ff92SAndroid Build Coastguard Worker     CounterDirectory counterDirectory;
2098*89c4ff92SAndroid Build Coastguard Worker     MockBufferManager mockBuffer(1024);
2099*89c4ff92SAndroid Build Coastguard Worker     SendCounterPacket sendCounterPacket(mockBuffer,
2100*89c4ff92SAndroid Build Coastguard Worker                                         arm::pipe::ARMNN_SOFTWARE_INFO,
2101*89c4ff92SAndroid Build Coastguard Worker                                         arm::pipe::ARMNN_SOFTWARE_VERSION,
2102*89c4ff92SAndroid Build Coastguard Worker                                         arm::pipe::ARMNN_HARDWARE_VERSION);
2103*89c4ff92SAndroid Build Coastguard Worker     SendThread sendThread(profilingState, mockBuffer, sendCounterPacket);
2104*89c4ff92SAndroid Build Coastguard Worker     SendTimelinePacket sendTimelinePacket(mockBuffer);
2105*89c4ff92SAndroid Build Coastguard Worker     MockProfilingServiceStatus mockProfilingServiceStatus;
2106*89c4ff92SAndroid Build Coastguard Worker 
2107*89c4ff92SAndroid Build Coastguard Worker     ConnectionAcknowledgedCommandHandler commandHandler(packetFamilyId,
2108*89c4ff92SAndroid Build Coastguard Worker                                                         connectionPacketId,
2109*89c4ff92SAndroid Build Coastguard Worker                                                         version,
2110*89c4ff92SAndroid Build Coastguard Worker                                                         counterDirectory,
2111*89c4ff92SAndroid Build Coastguard Worker                                                         sendCounterPacket,
2112*89c4ff92SAndroid Build Coastguard Worker                                                         sendTimelinePacket,
2113*89c4ff92SAndroid Build Coastguard Worker                                                         profilingState,
2114*89c4ff92SAndroid Build Coastguard Worker                                                         mockProfilingServiceStatus);
2115*89c4ff92SAndroid Build Coastguard Worker 
2116*89c4ff92SAndroid Build Coastguard Worker     // command handler received packet on ProfilingState::Uninitialised
2117*89c4ff92SAndroid Build Coastguard Worker     CHECK_THROWS_AS(commandHandler(packetA), arm::pipe::ProfilingException);
2118*89c4ff92SAndroid Build Coastguard Worker 
2119*89c4ff92SAndroid Build Coastguard Worker     profilingState.TransitionToState(ProfilingState::NotConnected);
2120*89c4ff92SAndroid Build Coastguard Worker     CHECK(profilingState.GetCurrentState() == ProfilingState::NotConnected);
2121*89c4ff92SAndroid Build Coastguard Worker     // command handler received packet on ProfilingState::NotConnected
2122*89c4ff92SAndroid Build Coastguard Worker     CHECK_THROWS_AS(commandHandler(packetA), arm::pipe::ProfilingException);
2123*89c4ff92SAndroid Build Coastguard Worker 
2124*89c4ff92SAndroid Build Coastguard Worker     profilingState.TransitionToState(ProfilingState::WaitingForAck);
2125*89c4ff92SAndroid Build Coastguard Worker     CHECK(profilingState.GetCurrentState() == ProfilingState::WaitingForAck);
2126*89c4ff92SAndroid Build Coastguard Worker     // command handler received packet on ProfilingState::WaitingForAck
2127*89c4ff92SAndroid Build Coastguard Worker     CHECK_NOTHROW(commandHandler(packetA));
2128*89c4ff92SAndroid Build Coastguard Worker     CHECK(profilingState.GetCurrentState() == ProfilingState::Active);
2129*89c4ff92SAndroid Build Coastguard Worker 
2130*89c4ff92SAndroid Build Coastguard Worker     // command handler received packet on ProfilingState::Active
2131*89c4ff92SAndroid Build Coastguard Worker     CHECK_NOTHROW(commandHandler(packetA));
2132*89c4ff92SAndroid Build Coastguard Worker     CHECK(profilingState.GetCurrentState() == ProfilingState::Active);
2133*89c4ff92SAndroid Build Coastguard Worker 
2134*89c4ff92SAndroid Build Coastguard Worker     // command handler received different packet
2135*89c4ff92SAndroid Build Coastguard Worker     const uint32_t differentPacketId = 0x40000;
2136*89c4ff92SAndroid Build Coastguard Worker     arm::pipe::Packet packetB(differentPacketId, dataLength1, uniqueData1);
2137*89c4ff92SAndroid Build Coastguard Worker     profilingState.TransitionToState(ProfilingState::NotConnected);
2138*89c4ff92SAndroid Build Coastguard Worker     profilingState.TransitionToState(ProfilingState::WaitingForAck);
2139*89c4ff92SAndroid Build Coastguard Worker     ConnectionAcknowledgedCommandHandler differentCommandHandler(packetFamilyId,
2140*89c4ff92SAndroid Build Coastguard Worker                                                                  differentPacketId,
2141*89c4ff92SAndroid Build Coastguard Worker                                                                  version,
2142*89c4ff92SAndroid Build Coastguard Worker                                                                  counterDirectory,
2143*89c4ff92SAndroid Build Coastguard Worker                                                                  sendCounterPacket,
2144*89c4ff92SAndroid Build Coastguard Worker                                                                  sendTimelinePacket,
2145*89c4ff92SAndroid Build Coastguard Worker                                                                  profilingState,
2146*89c4ff92SAndroid Build Coastguard Worker                                                                  mockProfilingServiceStatus);
2147*89c4ff92SAndroid Build Coastguard Worker     CHECK_THROWS_AS(differentCommandHandler(packetB), arm::pipe::ProfilingException);
2148*89c4ff92SAndroid Build Coastguard Worker }
2149*89c4ff92SAndroid Build Coastguard Worker 
2150*89c4ff92SAndroid Build Coastguard Worker TEST_CASE("CheckSocketConnectionException")
2151*89c4ff92SAndroid Build Coastguard Worker {
2152*89c4ff92SAndroid Build Coastguard Worker     // Check that creating a SocketProfilingConnection armnnProfiling in an exception as the Gator UDS doesn't exist.
2153*89c4ff92SAndroid Build Coastguard Worker     CHECK_THROWS_AS(new SocketProfilingConnection(), arm::pipe::SocketConnectionException);
2154*89c4ff92SAndroid Build Coastguard Worker }
2155*89c4ff92SAndroid Build Coastguard Worker 
2156*89c4ff92SAndroid Build Coastguard Worker TEST_CASE("CheckSocketConnectionException2")
2157*89c4ff92SAndroid Build Coastguard Worker {
2158*89c4ff92SAndroid Build Coastguard Worker     try
2159*89c4ff92SAndroid Build Coastguard Worker     {
2160*89c4ff92SAndroid Build Coastguard Worker         new SocketProfilingConnection();
2161*89c4ff92SAndroid Build Coastguard Worker     }
2162*89c4ff92SAndroid Build Coastguard Worker     catch (const arm::pipe::SocketConnectionException& ex)
2163*89c4ff92SAndroid Build Coastguard Worker     {
2164*89c4ff92SAndroid Build Coastguard Worker         CHECK(ex.GetSocketFd() == 0);
2165*89c4ff92SAndroid Build Coastguard Worker         CHECK(ex.GetErrorNo() == ECONNREFUSED);
2166*89c4ff92SAndroid Build Coastguard Worker         CHECK(ex.what()
2167*89c4ff92SAndroid Build Coastguard Worker                     == std::string("SocketProfilingConnection: Cannot connect to stream socket: Connection refused"));
2168*89c4ff92SAndroid Build Coastguard Worker     }
2169*89c4ff92SAndroid Build Coastguard Worker }
2170*89c4ff92SAndroid Build Coastguard Worker 
2171*89c4ff92SAndroid Build Coastguard Worker TEST_CASE("SwTraceIsValidCharTest")
2172*89c4ff92SAndroid Build Coastguard Worker {
2173*89c4ff92SAndroid Build Coastguard Worker     // Only ASCII 7-bit encoding supported
2174*89c4ff92SAndroid Build Coastguard Worker     for (unsigned char c = 0; c < 128; c++)
2175*89c4ff92SAndroid Build Coastguard Worker     {
2176*89c4ff92SAndroid Build Coastguard Worker         CHECK(arm::pipe::SwTraceCharPolicy::IsValidChar(c));
2177*89c4ff92SAndroid Build Coastguard Worker     }
2178*89c4ff92SAndroid Build Coastguard Worker 
2179*89c4ff92SAndroid Build Coastguard Worker     // Not ASCII
2180*89c4ff92SAndroid Build Coastguard Worker     for (unsigned char c = 255; c >= 128; c++)
2181*89c4ff92SAndroid Build Coastguard Worker     {
2182*89c4ff92SAndroid Build Coastguard Worker         CHECK(!arm::pipe::SwTraceCharPolicy::IsValidChar(c));
2183*89c4ff92SAndroid Build Coastguard Worker     }
2184*89c4ff92SAndroid Build Coastguard Worker }
2185*89c4ff92SAndroid Build Coastguard Worker 
2186*89c4ff92SAndroid Build Coastguard Worker TEST_CASE("SwTraceIsValidNameCharTest")
2187*89c4ff92SAndroid Build Coastguard Worker {
2188*89c4ff92SAndroid Build Coastguard Worker     // Only alpha-numeric and underscore ASCII 7-bit encoding supported
2189*89c4ff92SAndroid Build Coastguard Worker     const unsigned char validChars[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_";
2190*89c4ff92SAndroid Build Coastguard Worker     for (unsigned char i = 0; i < sizeof(validChars) / sizeof(validChars[0]) - 1; i++)
2191*89c4ff92SAndroid Build Coastguard Worker     {
2192*89c4ff92SAndroid Build Coastguard Worker         CHECK(arm::pipe::SwTraceNameCharPolicy::IsValidChar(validChars[i]));
2193*89c4ff92SAndroid Build Coastguard Worker     }
2194*89c4ff92SAndroid Build Coastguard Worker 
2195*89c4ff92SAndroid Build Coastguard Worker     // Non alpha-numeric chars
2196*89c4ff92SAndroid Build Coastguard Worker     for (unsigned char c = 0; c < 48; c++)
2197*89c4ff92SAndroid Build Coastguard Worker     {
2198*89c4ff92SAndroid Build Coastguard Worker         CHECK(!arm::pipe::SwTraceNameCharPolicy::IsValidChar(c));
2199*89c4ff92SAndroid Build Coastguard Worker     }
2200*89c4ff92SAndroid Build Coastguard Worker     for (unsigned char c = 58; c < 65; c++)
2201*89c4ff92SAndroid Build Coastguard Worker     {
2202*89c4ff92SAndroid Build Coastguard Worker         CHECK(!arm::pipe::SwTraceNameCharPolicy::IsValidChar(c));
2203*89c4ff92SAndroid Build Coastguard Worker     }
2204*89c4ff92SAndroid Build Coastguard Worker     for (unsigned char c = 91; c < 95; c++)
2205*89c4ff92SAndroid Build Coastguard Worker     {
2206*89c4ff92SAndroid Build Coastguard Worker         CHECK(!arm::pipe::SwTraceNameCharPolicy::IsValidChar(c));
2207*89c4ff92SAndroid Build Coastguard Worker     }
2208*89c4ff92SAndroid Build Coastguard Worker     for (unsigned char c = 96; c < 97; c++)
2209*89c4ff92SAndroid Build Coastguard Worker     {
2210*89c4ff92SAndroid Build Coastguard Worker         CHECK(!arm::pipe::SwTraceNameCharPolicy::IsValidChar(c));
2211*89c4ff92SAndroid Build Coastguard Worker     }
2212*89c4ff92SAndroid Build Coastguard Worker     for (unsigned char c = 123; c < 128; c++)
2213*89c4ff92SAndroid Build Coastguard Worker     {
2214*89c4ff92SAndroid Build Coastguard Worker         CHECK(!arm::pipe::SwTraceNameCharPolicy::IsValidChar(c));
2215*89c4ff92SAndroid Build Coastguard Worker     }
2216*89c4ff92SAndroid Build Coastguard Worker 
2217*89c4ff92SAndroid Build Coastguard Worker     // Not ASCII
2218*89c4ff92SAndroid Build Coastguard Worker     for (unsigned char c = 255; c >= 128; c++)
2219*89c4ff92SAndroid Build Coastguard Worker     {
2220*89c4ff92SAndroid Build Coastguard Worker         CHECK(!arm::pipe::SwTraceNameCharPolicy::IsValidChar(c));
2221*89c4ff92SAndroid Build Coastguard Worker     }
2222*89c4ff92SAndroid Build Coastguard Worker }
2223*89c4ff92SAndroid Build Coastguard Worker 
2224*89c4ff92SAndroid Build Coastguard Worker TEST_CASE("IsValidSwTraceStringTest")
2225*89c4ff92SAndroid Build Coastguard Worker {
2226*89c4ff92SAndroid Build Coastguard Worker     // Valid SWTrace strings
2227*89c4ff92SAndroid Build Coastguard Worker     CHECK(arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceCharPolicy>(""));
2228*89c4ff92SAndroid Build Coastguard Worker     CHECK(arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceCharPolicy>("_"));
2229*89c4ff92SAndroid Build Coastguard Worker     CHECK(arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceCharPolicy>("0123"));
2230*89c4ff92SAndroid Build Coastguard Worker     CHECK(arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceCharPolicy>("valid_string"));
2231*89c4ff92SAndroid Build Coastguard Worker     CHECK(arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceCharPolicy>("VALID_string_456"));
2232*89c4ff92SAndroid Build Coastguard Worker     CHECK(arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceCharPolicy>(" "));
2233*89c4ff92SAndroid Build Coastguard Worker     CHECK(arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceCharPolicy>("valid string"));
2234*89c4ff92SAndroid Build Coastguard Worker     CHECK(arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceCharPolicy>("!$%"));
2235*89c4ff92SAndroid Build Coastguard Worker     CHECK(arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceCharPolicy>("valid|\\~string#123"));
2236*89c4ff92SAndroid Build Coastguard Worker 
2237*89c4ff92SAndroid Build Coastguard Worker     // Invalid SWTrace strings
2238*89c4ff92SAndroid Build Coastguard Worker     CHECK(!arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceCharPolicy>("€£"));
2239*89c4ff92SAndroid Build Coastguard Worker     CHECK(!arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceCharPolicy>("invalid‡string"));
2240*89c4ff92SAndroid Build Coastguard Worker     CHECK(!arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceCharPolicy>("12Ž34"));
2241*89c4ff92SAndroid Build Coastguard Worker }
2242*89c4ff92SAndroid Build Coastguard Worker 
2243*89c4ff92SAndroid Build Coastguard Worker TEST_CASE("IsValidSwTraceNameStringTest")
2244*89c4ff92SAndroid Build Coastguard Worker {
2245*89c4ff92SAndroid Build Coastguard Worker     // Valid SWTrace name strings
2246*89c4ff92SAndroid Build Coastguard Worker     CHECK(arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceNameCharPolicy>(""));
2247*89c4ff92SAndroid Build Coastguard Worker     CHECK(arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceNameCharPolicy>("_"));
2248*89c4ff92SAndroid Build Coastguard Worker     CHECK(arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceNameCharPolicy>("0123"));
2249*89c4ff92SAndroid Build Coastguard Worker     CHECK(arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceNameCharPolicy>("valid_string"));
2250*89c4ff92SAndroid Build Coastguard Worker     CHECK(arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceNameCharPolicy>("VALID_string_456"));
2251*89c4ff92SAndroid Build Coastguard Worker 
2252*89c4ff92SAndroid Build Coastguard Worker     // Invalid SWTrace name strings
2253*89c4ff92SAndroid Build Coastguard Worker     CHECK(!arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceNameCharPolicy>(" "));
2254*89c4ff92SAndroid Build Coastguard Worker     CHECK(!arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceNameCharPolicy>("invalid string"));
2255*89c4ff92SAndroid Build Coastguard Worker     CHECK(!arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceNameCharPolicy>("!$%"));
2256*89c4ff92SAndroid Build Coastguard Worker     CHECK(!arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceNameCharPolicy>("invalid|\\~string#123"));
2257*89c4ff92SAndroid Build Coastguard Worker     CHECK(!arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceNameCharPolicy>("€£"));
2258*89c4ff92SAndroid Build Coastguard Worker     CHECK(!arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceNameCharPolicy>("invalid‡string"));
2259*89c4ff92SAndroid Build Coastguard Worker     CHECK(!arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceNameCharPolicy>("12Ž34"));
2260*89c4ff92SAndroid Build Coastguard Worker }
2261*89c4ff92SAndroid Build Coastguard Worker 
2262*89c4ff92SAndroid Build Coastguard Worker template <typename SwTracePolicy>
StringToSwTraceStringTestHelper(const std::string & testString,std::vector<uint32_t> buffer,size_t expectedSize)2263*89c4ff92SAndroid Build Coastguard Worker void StringToSwTraceStringTestHelper(const std::string& testString, std::vector<uint32_t> buffer, size_t expectedSize)
2264*89c4ff92SAndroid Build Coastguard Worker {
2265*89c4ff92SAndroid Build Coastguard Worker     // Convert the test string to a SWTrace string
2266*89c4ff92SAndroid Build Coastguard Worker     CHECK(arm::pipe::StringToSwTraceString<SwTracePolicy>(testString, buffer));
2267*89c4ff92SAndroid Build Coastguard Worker 
2268*89c4ff92SAndroid Build Coastguard Worker     // The buffer must contain at least the length of the string
2269*89c4ff92SAndroid Build Coastguard Worker     CHECK(!buffer.empty());
2270*89c4ff92SAndroid Build Coastguard Worker 
2271*89c4ff92SAndroid Build Coastguard Worker     // The buffer must be of the expected size (in words)
2272*89c4ff92SAndroid Build Coastguard Worker     CHECK(buffer.size() == expectedSize);
2273*89c4ff92SAndroid Build Coastguard Worker 
2274*89c4ff92SAndroid Build Coastguard Worker     // The first word of the byte must be the length of the string including the null-terminator
2275*89c4ff92SAndroid Build Coastguard Worker     CHECK(buffer[0] == testString.size() + 1);
2276*89c4ff92SAndroid Build Coastguard Worker 
2277*89c4ff92SAndroid Build Coastguard Worker     // The contents of the buffer must match the test string
2278*89c4ff92SAndroid Build Coastguard Worker     CHECK(std::memcmp(testString.data(), buffer.data() + 1, testString.size()) == 0);
2279*89c4ff92SAndroid Build Coastguard Worker 
2280*89c4ff92SAndroid Build Coastguard Worker     // The buffer must include the null-terminator at the end of the string
2281*89c4ff92SAndroid Build Coastguard Worker     size_t nullTerminatorIndex = sizeof(uint32_t) + testString.size();
2282*89c4ff92SAndroid Build Coastguard Worker     CHECK(reinterpret_cast<unsigned char*>(buffer.data())[nullTerminatorIndex] == '\0');
2283*89c4ff92SAndroid Build Coastguard Worker }
2284*89c4ff92SAndroid Build Coastguard Worker 
2285*89c4ff92SAndroid Build Coastguard Worker TEST_CASE("StringToSwTraceStringTest")
2286*89c4ff92SAndroid Build Coastguard Worker {
2287*89c4ff92SAndroid Build Coastguard Worker     std::vector<uint32_t> buffer;
2288*89c4ff92SAndroid Build Coastguard Worker 
2289*89c4ff92SAndroid Build Coastguard Worker     // Valid SWTrace strings (expected size in words)
2290*89c4ff92SAndroid Build Coastguard Worker     StringToSwTraceStringTestHelper<arm::pipe::SwTraceCharPolicy>("", buffer, 2);
2291*89c4ff92SAndroid Build Coastguard Worker     StringToSwTraceStringTestHelper<arm::pipe::SwTraceCharPolicy>("_", buffer, 2);
2292*89c4ff92SAndroid Build Coastguard Worker     StringToSwTraceStringTestHelper<arm::pipe::SwTraceCharPolicy>("0123", buffer, 3);
2293*89c4ff92SAndroid Build Coastguard Worker     StringToSwTraceStringTestHelper<arm::pipe::SwTraceCharPolicy>("valid_string", buffer, 5);
2294*89c4ff92SAndroid Build Coastguard Worker     StringToSwTraceStringTestHelper<arm::pipe::SwTraceCharPolicy>("VALID_string_456", buffer, 6);
2295*89c4ff92SAndroid Build Coastguard Worker     StringToSwTraceStringTestHelper<arm::pipe::SwTraceCharPolicy>(" ", buffer, 2);
2296*89c4ff92SAndroid Build Coastguard Worker     StringToSwTraceStringTestHelper<arm::pipe::SwTraceCharPolicy>("valid string", buffer, 5);
2297*89c4ff92SAndroid Build Coastguard Worker     StringToSwTraceStringTestHelper<arm::pipe::SwTraceCharPolicy>("!$%", buffer, 2);
2298*89c4ff92SAndroid Build Coastguard Worker     StringToSwTraceStringTestHelper<arm::pipe::SwTraceCharPolicy>("valid|\\~string#123", buffer, 6);
2299*89c4ff92SAndroid Build Coastguard Worker 
2300*89c4ff92SAndroid Build Coastguard Worker     // Invalid SWTrace strings
2301*89c4ff92SAndroid Build Coastguard Worker     CHECK(!arm::pipe::StringToSwTraceString<arm::pipe::SwTraceCharPolicy>("€£", buffer));
2302*89c4ff92SAndroid Build Coastguard Worker     CHECK(buffer.empty());
2303*89c4ff92SAndroid Build Coastguard Worker     CHECK(!arm::pipe::StringToSwTraceString<arm::pipe::SwTraceCharPolicy>("invalid‡string", buffer));
2304*89c4ff92SAndroid Build Coastguard Worker     CHECK(buffer.empty());
2305*89c4ff92SAndroid Build Coastguard Worker     CHECK(!arm::pipe::StringToSwTraceString<arm::pipe::SwTraceCharPolicy>("12Ž34", buffer));
2306*89c4ff92SAndroid Build Coastguard Worker     CHECK(buffer.empty());
2307*89c4ff92SAndroid Build Coastguard Worker }
2308*89c4ff92SAndroid Build Coastguard Worker 
2309*89c4ff92SAndroid Build Coastguard Worker TEST_CASE("StringToSwTraceNameStringTest")
2310*89c4ff92SAndroid Build Coastguard Worker {
2311*89c4ff92SAndroid Build Coastguard Worker     std::vector<uint32_t> buffer;
2312*89c4ff92SAndroid Build Coastguard Worker 
2313*89c4ff92SAndroid Build Coastguard Worker     // Valid SWTrace namestrings (expected size in words)
2314*89c4ff92SAndroid Build Coastguard Worker     StringToSwTraceStringTestHelper<arm::pipe::SwTraceNameCharPolicy>("", buffer, 2);
2315*89c4ff92SAndroid Build Coastguard Worker     StringToSwTraceStringTestHelper<arm::pipe::SwTraceNameCharPolicy>("_", buffer, 2);
2316*89c4ff92SAndroid Build Coastguard Worker     StringToSwTraceStringTestHelper<arm::pipe::SwTraceNameCharPolicy>("0123", buffer, 3);
2317*89c4ff92SAndroid Build Coastguard Worker     StringToSwTraceStringTestHelper<arm::pipe::SwTraceNameCharPolicy>("valid_string", buffer, 5);
2318*89c4ff92SAndroid Build Coastguard Worker     StringToSwTraceStringTestHelper<arm::pipe::SwTraceNameCharPolicy>("VALID_string_456", buffer, 6);
2319*89c4ff92SAndroid Build Coastguard Worker 
2320*89c4ff92SAndroid Build Coastguard Worker     // Invalid SWTrace namestrings
2321*89c4ff92SAndroid Build Coastguard Worker     CHECK(!arm::pipe::StringToSwTraceString<arm::pipe::SwTraceNameCharPolicy>(" ", buffer));
2322*89c4ff92SAndroid Build Coastguard Worker     CHECK(buffer.empty());
2323*89c4ff92SAndroid Build Coastguard Worker     CHECK(!arm::pipe::StringToSwTraceString<arm::pipe::SwTraceNameCharPolicy>("invalid string", buffer));
2324*89c4ff92SAndroid Build Coastguard Worker     CHECK(buffer.empty());
2325*89c4ff92SAndroid Build Coastguard Worker     CHECK(!arm::pipe::StringToSwTraceString<arm::pipe::SwTraceNameCharPolicy>("!$%", buffer));
2326*89c4ff92SAndroid Build Coastguard Worker     CHECK(buffer.empty());
2327*89c4ff92SAndroid Build Coastguard Worker     CHECK(!arm::pipe::StringToSwTraceString<arm::pipe::SwTraceNameCharPolicy>("invalid|\\~string#123", buffer));
2328*89c4ff92SAndroid Build Coastguard Worker     CHECK(buffer.empty());
2329*89c4ff92SAndroid Build Coastguard Worker     CHECK(!arm::pipe::StringToSwTraceString<arm::pipe::SwTraceNameCharPolicy>("€£", buffer));
2330*89c4ff92SAndroid Build Coastguard Worker     CHECK(buffer.empty());
2331*89c4ff92SAndroid Build Coastguard Worker     CHECK(!arm::pipe::StringToSwTraceString<arm::pipe::SwTraceNameCharPolicy>("invalid‡string", buffer));
2332*89c4ff92SAndroid Build Coastguard Worker     CHECK(buffer.empty());
2333*89c4ff92SAndroid Build Coastguard Worker     CHECK(!arm::pipe::StringToSwTraceString<arm::pipe::SwTraceNameCharPolicy>("12Ž34", buffer));
2334*89c4ff92SAndroid Build Coastguard Worker     CHECK(buffer.empty());
2335*89c4ff92SAndroid Build Coastguard Worker }
2336*89c4ff92SAndroid Build Coastguard Worker 
2337*89c4ff92SAndroid Build Coastguard Worker TEST_CASE("CheckPeriodicCounterCaptureThread")
2338*89c4ff92SAndroid Build Coastguard Worker {
2339*89c4ff92SAndroid Build Coastguard Worker     class CaptureReader : public IReadCounterValues
2340*89c4ff92SAndroid Build Coastguard Worker     {
2341*89c4ff92SAndroid Build Coastguard Worker     public:
CaptureReader(uint16_t counterSize)2342*89c4ff92SAndroid Build Coastguard Worker         CaptureReader(uint16_t counterSize)
2343*89c4ff92SAndroid Build Coastguard Worker         {
2344*89c4ff92SAndroid Build Coastguard Worker             for (uint16_t i = 0; i < counterSize; ++i)
2345*89c4ff92SAndroid Build Coastguard Worker             {
2346*89c4ff92SAndroid Build Coastguard Worker                 m_Data[i] = 0;
2347*89c4ff92SAndroid Build Coastguard Worker             }
2348*89c4ff92SAndroid Build Coastguard Worker             m_CounterSize = counterSize;
2349*89c4ff92SAndroid Build Coastguard Worker         }
2350*89c4ff92SAndroid Build Coastguard Worker         //not used
IsCounterRegistered(uint16_t counterUid) const2351*89c4ff92SAndroid Build Coastguard Worker         bool IsCounterRegistered(uint16_t counterUid) const override
2352*89c4ff92SAndroid Build Coastguard Worker         {
2353*89c4ff92SAndroid Build Coastguard Worker             arm::pipe::IgnoreUnused(counterUid);
2354*89c4ff92SAndroid Build Coastguard Worker             return false;
2355*89c4ff92SAndroid Build Coastguard Worker         }
IsCounterRegistered(const std::string & counterName) const2356*89c4ff92SAndroid Build Coastguard Worker         bool IsCounterRegistered(const std::string& counterName) const override
2357*89c4ff92SAndroid Build Coastguard Worker         {
2358*89c4ff92SAndroid Build Coastguard Worker             arm::pipe::IgnoreUnused(counterName);
2359*89c4ff92SAndroid Build Coastguard Worker             return false;
2360*89c4ff92SAndroid Build Coastguard Worker         }
GetCounterCount() const2361*89c4ff92SAndroid Build Coastguard Worker         uint16_t GetCounterCount() const override
2362*89c4ff92SAndroid Build Coastguard Worker         {
2363*89c4ff92SAndroid Build Coastguard Worker             return m_CounterSize;
2364*89c4ff92SAndroid Build Coastguard Worker         }
2365*89c4ff92SAndroid Build Coastguard Worker 
GetAbsoluteCounterValue(uint16_t counterUid) const2366*89c4ff92SAndroid Build Coastguard Worker         uint32_t GetAbsoluteCounterValue(uint16_t counterUid) const override
2367*89c4ff92SAndroid Build Coastguard Worker         {
2368*89c4ff92SAndroid Build Coastguard Worker             if (counterUid > m_CounterSize)
2369*89c4ff92SAndroid Build Coastguard Worker             {
2370*89c4ff92SAndroid Build Coastguard Worker                 FAIL("Invalid counter Uid");
2371*89c4ff92SAndroid Build Coastguard Worker             }
2372*89c4ff92SAndroid Build Coastguard Worker             return m_Data.at(counterUid).load();
2373*89c4ff92SAndroid Build Coastguard Worker         }
2374*89c4ff92SAndroid Build Coastguard Worker 
GetDeltaCounterValue(uint16_t counterUid)2375*89c4ff92SAndroid Build Coastguard Worker         uint32_t GetDeltaCounterValue(uint16_t counterUid)  override
2376*89c4ff92SAndroid Build Coastguard Worker         {
2377*89c4ff92SAndroid Build Coastguard Worker             if (counterUid > m_CounterSize)
2378*89c4ff92SAndroid Build Coastguard Worker             {
2379*89c4ff92SAndroid Build Coastguard Worker                 FAIL("Invalid counter Uid");
2380*89c4ff92SAndroid Build Coastguard Worker             }
2381*89c4ff92SAndroid Build Coastguard Worker             return m_Data.at(counterUid).load();
2382*89c4ff92SAndroid Build Coastguard Worker         }
2383*89c4ff92SAndroid Build Coastguard Worker 
SetCounterValue(uint16_t counterUid,uint32_t value)2384*89c4ff92SAndroid Build Coastguard Worker         void SetCounterValue(uint16_t counterUid, uint32_t value)
2385*89c4ff92SAndroid Build Coastguard Worker         {
2386*89c4ff92SAndroid Build Coastguard Worker             if (counterUid > m_CounterSize)
2387*89c4ff92SAndroid Build Coastguard Worker             {
2388*89c4ff92SAndroid Build Coastguard Worker                 FAIL("Invalid counter Uid");
2389*89c4ff92SAndroid Build Coastguard Worker             }
2390*89c4ff92SAndroid Build Coastguard Worker             m_Data.at(counterUid).store(value);
2391*89c4ff92SAndroid Build Coastguard Worker         }
2392*89c4ff92SAndroid Build Coastguard Worker 
2393*89c4ff92SAndroid Build Coastguard Worker     private:
2394*89c4ff92SAndroid Build Coastguard Worker         std::unordered_map<uint16_t, std::atomic<uint32_t>> m_Data;
2395*89c4ff92SAndroid Build Coastguard Worker         uint16_t m_CounterSize;
2396*89c4ff92SAndroid Build Coastguard Worker     };
2397*89c4ff92SAndroid Build Coastguard Worker 
2398*89c4ff92SAndroid Build Coastguard Worker     ProfilingStateMachine profilingStateMachine;
2399*89c4ff92SAndroid Build Coastguard Worker 
2400*89c4ff92SAndroid Build Coastguard Worker     const std::unordered_map<std::string,
2401*89c4ff92SAndroid Build Coastguard Worker             std::shared_ptr<IBackendProfilingContext>> backendProfilingContext;
2402*89c4ff92SAndroid Build Coastguard Worker     CounterIdMap counterIdMap;
2403*89c4ff92SAndroid Build Coastguard Worker     Holder data;
2404*89c4ff92SAndroid Build Coastguard Worker     std::vector<uint16_t> captureIds1 = { 0, 1 };
2405*89c4ff92SAndroid Build Coastguard Worker     std::vector<uint16_t> captureIds2;
2406*89c4ff92SAndroid Build Coastguard Worker 
2407*89c4ff92SAndroid Build Coastguard Worker     MockBufferManager mockBuffer(512);
2408*89c4ff92SAndroid Build Coastguard Worker     SendCounterPacket sendCounterPacket(mockBuffer,
2409*89c4ff92SAndroid Build Coastguard Worker                                         arm::pipe::ARMNN_SOFTWARE_INFO,
2410*89c4ff92SAndroid Build Coastguard Worker                                         arm::pipe::ARMNN_SOFTWARE_VERSION,
2411*89c4ff92SAndroid Build Coastguard Worker                                         arm::pipe::ARMNN_HARDWARE_VERSION);
2412*89c4ff92SAndroid Build Coastguard Worker     SendThread sendThread(profilingStateMachine, mockBuffer, sendCounterPacket);
2413*89c4ff92SAndroid Build Coastguard Worker 
2414*89c4ff92SAndroid Build Coastguard Worker     std::vector<uint16_t> counterIds;
2415*89c4ff92SAndroid Build Coastguard Worker     CaptureReader captureReader(2);
2416*89c4ff92SAndroid Build Coastguard Worker 
2417*89c4ff92SAndroid Build Coastguard Worker     unsigned int valueA   = 10;
2418*89c4ff92SAndroid Build Coastguard Worker     unsigned int valueB   = 15;
2419*89c4ff92SAndroid Build Coastguard Worker     unsigned int numSteps = 5;
2420*89c4ff92SAndroid Build Coastguard Worker 
2421*89c4ff92SAndroid Build Coastguard Worker     PeriodicCounterCapture periodicCounterCapture(std::ref(data), std::ref(sendCounterPacket), captureReader,
2422*89c4ff92SAndroid Build Coastguard Worker                                                   counterIdMap, backendProfilingContext);
2423*89c4ff92SAndroid Build Coastguard Worker 
2424*89c4ff92SAndroid Build Coastguard Worker     for (unsigned int i = 0; i < numSteps; ++i)
2425*89c4ff92SAndroid Build Coastguard Worker     {
2426*89c4ff92SAndroid Build Coastguard Worker         data.SetCaptureData(1, captureIds1, {});
2427*89c4ff92SAndroid Build Coastguard Worker         captureReader.SetCounterValue(0, valueA * (i + 1));
2428*89c4ff92SAndroid Build Coastguard Worker         captureReader.SetCounterValue(1, valueB * (i + 1));
2429*89c4ff92SAndroid Build Coastguard Worker 
2430*89c4ff92SAndroid Build Coastguard Worker         periodicCounterCapture.Start();
2431*89c4ff92SAndroid Build Coastguard Worker         periodicCounterCapture.Stop();
2432*89c4ff92SAndroid Build Coastguard Worker     }
2433*89c4ff92SAndroid Build Coastguard Worker 
2434*89c4ff92SAndroid Build Coastguard Worker     auto buffer = mockBuffer.GetReadableBuffer();
2435*89c4ff92SAndroid Build Coastguard Worker 
2436*89c4ff92SAndroid Build Coastguard Worker     uint32_t headerWord0 = ReadUint32(buffer, 0);
2437*89c4ff92SAndroid Build Coastguard Worker     uint32_t headerWord1 = ReadUint32(buffer, 4);
2438*89c4ff92SAndroid Build Coastguard Worker 
2439*89c4ff92SAndroid Build Coastguard Worker     CHECK(((headerWord0 >> 26) & 0x0000003F) == 3);    // packet family
2440*89c4ff92SAndroid Build Coastguard Worker     CHECK(((headerWord0 >> 19) & 0x0000007F) == 0);    // packet class
2441*89c4ff92SAndroid Build Coastguard Worker     CHECK(((headerWord0 >> 16) & 0x00000007) == 0);    // packet type
2442*89c4ff92SAndroid Build Coastguard Worker     CHECK(headerWord1 == 20);
2443*89c4ff92SAndroid Build Coastguard Worker 
2444*89c4ff92SAndroid Build Coastguard Worker     uint32_t offset    = 16;
2445*89c4ff92SAndroid Build Coastguard Worker     uint16_t readIndex = ReadUint16(buffer, offset);
2446*89c4ff92SAndroid Build Coastguard Worker     CHECK(0 == readIndex);
2447*89c4ff92SAndroid Build Coastguard Worker 
2448*89c4ff92SAndroid Build Coastguard Worker     offset += 2;
2449*89c4ff92SAndroid Build Coastguard Worker     uint32_t readValue = ReadUint32(buffer, offset);
2450*89c4ff92SAndroid Build Coastguard Worker     CHECK((valueA * numSteps) == readValue);
2451*89c4ff92SAndroid Build Coastguard Worker 
2452*89c4ff92SAndroid Build Coastguard Worker     offset += 4;
2453*89c4ff92SAndroid Build Coastguard Worker     readIndex = ReadUint16(buffer, offset);
2454*89c4ff92SAndroid Build Coastguard Worker     CHECK(1 == readIndex);
2455*89c4ff92SAndroid Build Coastguard Worker 
2456*89c4ff92SAndroid Build Coastguard Worker     offset += 2;
2457*89c4ff92SAndroid Build Coastguard Worker     readValue = ReadUint32(buffer, offset);
2458*89c4ff92SAndroid Build Coastguard Worker     CHECK((valueB * numSteps) == readValue);
2459*89c4ff92SAndroid Build Coastguard Worker }
2460*89c4ff92SAndroid Build Coastguard Worker 
2461*89c4ff92SAndroid Build Coastguard Worker TEST_CASE("RequestCounterDirectoryCommandHandlerTest1")
2462*89c4ff92SAndroid Build Coastguard Worker {
2463*89c4ff92SAndroid Build Coastguard Worker     const uint32_t familyId = 0;
2464*89c4ff92SAndroid Build Coastguard Worker     const uint32_t packetId = 3;
2465*89c4ff92SAndroid Build Coastguard Worker     const uint32_t version  = 1;
2466*89c4ff92SAndroid Build Coastguard Worker     ProfilingStateMachine profilingStateMachine;
2467*89c4ff92SAndroid Build Coastguard Worker     CounterDirectory counterDirectory;
2468*89c4ff92SAndroid Build Coastguard Worker     MockBufferManager mockBuffer1(1024);
2469*89c4ff92SAndroid Build Coastguard Worker     SendCounterPacket sendCounterPacket(mockBuffer1,
2470*89c4ff92SAndroid Build Coastguard Worker                                         arm::pipe::ARMNN_SOFTWARE_INFO,
2471*89c4ff92SAndroid Build Coastguard Worker                                         arm::pipe::ARMNN_SOFTWARE_VERSION,
2472*89c4ff92SAndroid Build Coastguard Worker                                         arm::pipe::ARMNN_HARDWARE_VERSION);
2473*89c4ff92SAndroid Build Coastguard Worker     SendThread sendThread(profilingStateMachine, mockBuffer1, sendCounterPacket);
2474*89c4ff92SAndroid Build Coastguard Worker     MockBufferManager mockBuffer2(1024);
2475*89c4ff92SAndroid Build Coastguard Worker     SendTimelinePacket sendTimelinePacket(mockBuffer2);
2476*89c4ff92SAndroid Build Coastguard Worker     RequestCounterDirectoryCommandHandler commandHandler(familyId, packetId, version, counterDirectory,
2477*89c4ff92SAndroid Build Coastguard Worker                                                          sendCounterPacket, sendTimelinePacket, profilingStateMachine);
2478*89c4ff92SAndroid Build Coastguard Worker 
2479*89c4ff92SAndroid Build Coastguard Worker     const uint32_t wrongPacketId = 47;
2480*89c4ff92SAndroid Build Coastguard Worker     const uint32_t wrongHeader   = (wrongPacketId & 0x000003FF) << 16;
2481*89c4ff92SAndroid Build Coastguard Worker 
2482*89c4ff92SAndroid Build Coastguard Worker     arm::pipe::Packet wrongPacket(wrongHeader);
2483*89c4ff92SAndroid Build Coastguard Worker 
2484*89c4ff92SAndroid Build Coastguard Worker     profilingStateMachine.TransitionToState(ProfilingState::Uninitialised);
2485*89c4ff92SAndroid Build Coastguard Worker     CHECK_THROWS_AS(commandHandler(wrongPacket), arm::pipe::ProfilingException); // Wrong profiling state
2486*89c4ff92SAndroid Build Coastguard Worker     profilingStateMachine.TransitionToState(ProfilingState::NotConnected);
2487*89c4ff92SAndroid Build Coastguard Worker     CHECK_THROWS_AS(commandHandler(wrongPacket), arm::pipe::ProfilingException); // Wrong profiling state
2488*89c4ff92SAndroid Build Coastguard Worker     profilingStateMachine.TransitionToState(ProfilingState::WaitingForAck);
2489*89c4ff92SAndroid Build Coastguard Worker     CHECK_THROWS_AS(commandHandler(wrongPacket), arm::pipe::ProfilingException); // Wrong profiling state
2490*89c4ff92SAndroid Build Coastguard Worker     profilingStateMachine.TransitionToState(ProfilingState::Active);
2491*89c4ff92SAndroid Build Coastguard Worker     CHECK_THROWS_AS(commandHandler(wrongPacket), arm::pipe::InvalidArgumentException); // Wrong packet
2492*89c4ff92SAndroid Build Coastguard Worker 
2493*89c4ff92SAndroid Build Coastguard Worker     const uint32_t rightHeader = (packetId & 0x000003FF) << 16;
2494*89c4ff92SAndroid Build Coastguard Worker 
2495*89c4ff92SAndroid Build Coastguard Worker     arm::pipe::Packet rightPacket(rightHeader);
2496*89c4ff92SAndroid Build Coastguard Worker 
2497*89c4ff92SAndroid Build Coastguard Worker     CHECK_NOTHROW(commandHandler(rightPacket)); // Right packet
2498*89c4ff92SAndroid Build Coastguard Worker 
2499*89c4ff92SAndroid Build Coastguard Worker     auto readBuffer1 = mockBuffer1.GetReadableBuffer();
2500*89c4ff92SAndroid Build Coastguard Worker 
2501*89c4ff92SAndroid Build Coastguard Worker     uint32_t header1Word0 = ReadUint32(readBuffer1, 0);
2502*89c4ff92SAndroid Build Coastguard Worker     uint32_t header1Word1 = ReadUint32(readBuffer1, 4);
2503*89c4ff92SAndroid Build Coastguard Worker 
2504*89c4ff92SAndroid Build Coastguard Worker     // Counter directory packet
2505*89c4ff92SAndroid Build Coastguard Worker     CHECK(((header1Word0 >> 26) & 0x0000003F) == 0); // packet family
2506*89c4ff92SAndroid Build Coastguard Worker     CHECK(((header1Word0 >> 16) & 0x000003FF) == 2); // packet id
2507*89c4ff92SAndroid Build Coastguard Worker     CHECK(header1Word1 == 24);                       // data length
2508*89c4ff92SAndroid Build Coastguard Worker 
2509*89c4ff92SAndroid Build Coastguard Worker     uint32_t bodyHeader1Word0   = ReadUint32(readBuffer1, 8);
2510*89c4ff92SAndroid Build Coastguard Worker     uint16_t deviceRecordCount = arm::pipe::numeric_cast<uint16_t>(bodyHeader1Word0 >> 16);
2511*89c4ff92SAndroid Build Coastguard Worker     CHECK(deviceRecordCount == 0); // device_records_count
2512*89c4ff92SAndroid Build Coastguard Worker 
2513*89c4ff92SAndroid Build Coastguard Worker     auto readBuffer2 = mockBuffer2.GetReadableBuffer();
2514*89c4ff92SAndroid Build Coastguard Worker 
2515*89c4ff92SAndroid Build Coastguard Worker     uint32_t header2Word0 = ReadUint32(readBuffer2, 0);
2516*89c4ff92SAndroid Build Coastguard Worker     uint32_t header2Word1 = ReadUint32(readBuffer2, 4);
2517*89c4ff92SAndroid Build Coastguard Worker 
2518*89c4ff92SAndroid Build Coastguard Worker     // Timeline message directory packet
2519*89c4ff92SAndroid Build Coastguard Worker     CHECK(((header2Word0 >> 26) & 0x0000003F) == 1); // packet family
2520*89c4ff92SAndroid Build Coastguard Worker     CHECK(((header2Word0 >> 16) & 0x000003FF) == 0); // packet id
2521*89c4ff92SAndroid Build Coastguard Worker     CHECK(header2Word1 == 443);                      // data length
2522*89c4ff92SAndroid Build Coastguard Worker }
2523*89c4ff92SAndroid Build Coastguard Worker 
2524*89c4ff92SAndroid Build Coastguard Worker TEST_CASE("RequestCounterDirectoryCommandHandlerTest2")
2525*89c4ff92SAndroid Build Coastguard Worker {
2526*89c4ff92SAndroid Build Coastguard Worker     const uint32_t familyId = 0;
2527*89c4ff92SAndroid Build Coastguard Worker     const uint32_t packetId = 3;
2528*89c4ff92SAndroid Build Coastguard Worker     const uint32_t version  = 1;
2529*89c4ff92SAndroid Build Coastguard Worker     ProfilingStateMachine profilingStateMachine;
2530*89c4ff92SAndroid Build Coastguard Worker     CounterDirectory counterDirectory;
2531*89c4ff92SAndroid Build Coastguard Worker     MockBufferManager mockBuffer1(1024);
2532*89c4ff92SAndroid Build Coastguard Worker     SendCounterPacket sendCounterPacket(mockBuffer1,
2533*89c4ff92SAndroid Build Coastguard Worker                                         arm::pipe::ARMNN_SOFTWARE_INFO,
2534*89c4ff92SAndroid Build Coastguard Worker                                         arm::pipe::ARMNN_SOFTWARE_VERSION,
2535*89c4ff92SAndroid Build Coastguard Worker                                         arm::pipe::ARMNN_HARDWARE_VERSION);
2536*89c4ff92SAndroid Build Coastguard Worker     SendThread sendThread(profilingStateMachine, mockBuffer1, sendCounterPacket);
2537*89c4ff92SAndroid Build Coastguard Worker     MockBufferManager mockBuffer2(1024);
2538*89c4ff92SAndroid Build Coastguard Worker     SendTimelinePacket sendTimelinePacket(mockBuffer2);
2539*89c4ff92SAndroid Build Coastguard Worker     RequestCounterDirectoryCommandHandler commandHandler(familyId, packetId, version, counterDirectory,
2540*89c4ff92SAndroid Build Coastguard Worker                                                          sendCounterPacket, sendTimelinePacket, profilingStateMachine);
2541*89c4ff92SAndroid Build Coastguard Worker     const uint32_t header = (packetId & 0x000003FF) << 16;
2542*89c4ff92SAndroid Build Coastguard Worker     const arm::pipe::Packet packet(header);
2543*89c4ff92SAndroid Build Coastguard Worker 
2544*89c4ff92SAndroid Build Coastguard Worker     const Device* device = counterDirectory.RegisterDevice("deviceA", 1);
2545*89c4ff92SAndroid Build Coastguard Worker     CHECK(device != nullptr);
2546*89c4ff92SAndroid Build Coastguard Worker     const CounterSet* counterSet = counterDirectory.RegisterCounterSet("countersetA");
2547*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterSet != nullptr);
2548*89c4ff92SAndroid Build Coastguard Worker     counterDirectory.RegisterCategory("categoryA");
2549*89c4ff92SAndroid Build Coastguard Worker     counterDirectory.RegisterCounter(armnn::profiling::BACKEND_ID, 24,
2550*89c4ff92SAndroid Build Coastguard Worker                                      "categoryA", 0, 1, 2.0f, "counterA", "descA");
2551*89c4ff92SAndroid Build Coastguard Worker     counterDirectory.RegisterCounter(armnn::profiling::BACKEND_ID, 25,
2552*89c4ff92SAndroid Build Coastguard Worker                                      "categoryA", 1, 1, 3.0f, "counterB", "descB");
2553*89c4ff92SAndroid Build Coastguard Worker 
2554*89c4ff92SAndroid Build Coastguard Worker     profilingStateMachine.TransitionToState(ProfilingState::Uninitialised);
2555*89c4ff92SAndroid Build Coastguard Worker     CHECK_THROWS_AS(commandHandler(packet), arm::pipe::ProfilingException);    // Wrong profiling state
2556*89c4ff92SAndroid Build Coastguard Worker     profilingStateMachine.TransitionToState(ProfilingState::NotConnected);
2557*89c4ff92SAndroid Build Coastguard Worker     CHECK_THROWS_AS(commandHandler(packet), arm::pipe::ProfilingException);    // Wrong profiling state
2558*89c4ff92SAndroid Build Coastguard Worker     profilingStateMachine.TransitionToState(ProfilingState::WaitingForAck);
2559*89c4ff92SAndroid Build Coastguard Worker     CHECK_THROWS_AS(commandHandler(packet), arm::pipe::ProfilingException);    // Wrong profiling state
2560*89c4ff92SAndroid Build Coastguard Worker     profilingStateMachine.TransitionToState(ProfilingState::Active);
2561*89c4ff92SAndroid Build Coastguard Worker     CHECK_NOTHROW(commandHandler(packet));
2562*89c4ff92SAndroid Build Coastguard Worker 
2563*89c4ff92SAndroid Build Coastguard Worker     auto readBuffer1 = mockBuffer1.GetReadableBuffer();
2564*89c4ff92SAndroid Build Coastguard Worker 
2565*89c4ff92SAndroid Build Coastguard Worker     const uint32_t header1Word0 = ReadUint32(readBuffer1, 0);
2566*89c4ff92SAndroid Build Coastguard Worker     const uint32_t header1Word1 = ReadUint32(readBuffer1, 4);
2567*89c4ff92SAndroid Build Coastguard Worker 
2568*89c4ff92SAndroid Build Coastguard Worker     CHECK(((header1Word0 >> 26) & 0x0000003F) == 0); // packet family
2569*89c4ff92SAndroid Build Coastguard Worker     CHECK(((header1Word0 >> 16) & 0x000003FF) == 2); // packet id
2570*89c4ff92SAndroid Build Coastguard Worker     CHECK(header1Word1 == 236);                      // data length
2571*89c4ff92SAndroid Build Coastguard Worker 
2572*89c4ff92SAndroid Build Coastguard Worker     const uint32_t bodyHeaderSizeBytes = bodyHeaderSize * sizeof(uint32_t);
2573*89c4ff92SAndroid Build Coastguard Worker 
2574*89c4ff92SAndroid Build Coastguard Worker     const uint32_t bodyHeader1Word0      = ReadUint32(readBuffer1, 8);
2575*89c4ff92SAndroid Build Coastguard Worker     const uint32_t bodyHeader1Word1      = ReadUint32(readBuffer1, 12);
2576*89c4ff92SAndroid Build Coastguard Worker     const uint32_t bodyHeader1Word2      = ReadUint32(readBuffer1, 16);
2577*89c4ff92SAndroid Build Coastguard Worker     const uint32_t bodyHeader1Word3      = ReadUint32(readBuffer1, 20);
2578*89c4ff92SAndroid Build Coastguard Worker     const uint32_t bodyHeader1Word4      = ReadUint32(readBuffer1, 24);
2579*89c4ff92SAndroid Build Coastguard Worker     const uint32_t bodyHeader1Word5      = ReadUint32(readBuffer1, 28);
2580*89c4ff92SAndroid Build Coastguard Worker     const uint16_t deviceRecordCount     = arm::pipe::numeric_cast<uint16_t>(bodyHeader1Word0 >> 16);
2581*89c4ff92SAndroid Build Coastguard Worker     const uint16_t counterSetRecordCount = arm::pipe::numeric_cast<uint16_t>(bodyHeader1Word2 >> 16);
2582*89c4ff92SAndroid Build Coastguard Worker     const uint16_t categoryRecordCount   = arm::pipe::numeric_cast<uint16_t>(bodyHeader1Word4 >> 16);
2583*89c4ff92SAndroid Build Coastguard Worker     CHECK(deviceRecordCount == 1);                      // device_records_count
2584*89c4ff92SAndroid Build Coastguard Worker     CHECK(bodyHeader1Word1 == 0 + bodyHeaderSizeBytes);      // device_records_pointer_table_offset
2585*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterSetRecordCount == 1);                  // counter_set_count
2586*89c4ff92SAndroid Build Coastguard Worker     CHECK(bodyHeader1Word3 == 4 + bodyHeaderSizeBytes);      // counter_set_pointer_table_offset
2587*89c4ff92SAndroid Build Coastguard Worker     CHECK(categoryRecordCount == 1);                    // categories_count
2588*89c4ff92SAndroid Build Coastguard Worker     CHECK(bodyHeader1Word5 == 8 + bodyHeaderSizeBytes);      // categories_pointer_table_offset
2589*89c4ff92SAndroid Build Coastguard Worker 
2590*89c4ff92SAndroid Build Coastguard Worker     const uint32_t deviceRecordOffset = ReadUint32(readBuffer1, 32);
2591*89c4ff92SAndroid Build Coastguard Worker     CHECK(deviceRecordOffset == 12);
2592*89c4ff92SAndroid Build Coastguard Worker 
2593*89c4ff92SAndroid Build Coastguard Worker     const uint32_t counterSetRecordOffset = ReadUint32(readBuffer1, 36);
2594*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterSetRecordOffset == 28);
2595*89c4ff92SAndroid Build Coastguard Worker 
2596*89c4ff92SAndroid Build Coastguard Worker     const uint32_t categoryRecordOffset = ReadUint32(readBuffer1, 40);
2597*89c4ff92SAndroid Build Coastguard Worker     CHECK(categoryRecordOffset == 48);
2598*89c4ff92SAndroid Build Coastguard Worker 
2599*89c4ff92SAndroid Build Coastguard Worker     auto readBuffer2 = mockBuffer2.GetReadableBuffer();
2600*89c4ff92SAndroid Build Coastguard Worker 
2601*89c4ff92SAndroid Build Coastguard Worker     const uint32_t header2Word0 = ReadUint32(readBuffer2, 0);
2602*89c4ff92SAndroid Build Coastguard Worker     const uint32_t header2Word1 = ReadUint32(readBuffer2, 4);
2603*89c4ff92SAndroid Build Coastguard Worker 
2604*89c4ff92SAndroid Build Coastguard Worker     // Timeline message directory packet
2605*89c4ff92SAndroid Build Coastguard Worker     CHECK(((header2Word0 >> 26) & 0x0000003F) == 1); // packet family
2606*89c4ff92SAndroid Build Coastguard Worker     CHECK(((header2Word0 >> 16) & 0x000003FF) == 0); // packet id
2607*89c4ff92SAndroid Build Coastguard Worker     CHECK(header2Word1 == 443);                      // data length
2608*89c4ff92SAndroid Build Coastguard Worker }
2609*89c4ff92SAndroid Build Coastguard Worker 
2610*89c4ff92SAndroid Build Coastguard Worker TEST_CASE("CheckProfilingServiceGoodConnectionAcknowledgedPacket")
2611*89c4ff92SAndroid Build Coastguard Worker {
2612*89c4ff92SAndroid Build Coastguard Worker     unsigned int streamMetadataPacketsize = GetStreamMetaDataPacketSize();
2613*89c4ff92SAndroid Build Coastguard Worker 
2614*89c4ff92SAndroid Build Coastguard Worker     // Reset the profiling service to the uninitialized state
2615*89c4ff92SAndroid Build Coastguard Worker     ProfilingOptions options;
2616*89c4ff92SAndroid Build Coastguard Worker     options.m_EnableProfiling          = true;
2617*89c4ff92SAndroid Build Coastguard Worker     armnn::ArmNNProfilingServiceInitialiser initialiser;
2618*89c4ff92SAndroid Build Coastguard Worker     ProfilingService profilingService(arm::pipe::MAX_ARMNN_COUNTER,
2619*89c4ff92SAndroid Build Coastguard Worker                                       initialiser,
2620*89c4ff92SAndroid Build Coastguard Worker                                       arm::pipe::ARMNN_SOFTWARE_INFO,
2621*89c4ff92SAndroid Build Coastguard Worker                                       arm::pipe::ARMNN_SOFTWARE_VERSION,
2622*89c4ff92SAndroid Build Coastguard Worker                                       arm::pipe::ARMNN_HARDWARE_VERSION);
2623*89c4ff92SAndroid Build Coastguard Worker     profilingService.ResetExternalProfilingOptions(options, true);
2624*89c4ff92SAndroid Build Coastguard Worker 
2625*89c4ff92SAndroid Build Coastguard Worker     // Swap the profiling connection factory in the profiling service instance with our mock one
2626*89c4ff92SAndroid Build Coastguard Worker     SwapProfilingConnectionFactoryHelper helper(arm::pipe::MAX_ARMNN_COUNTER, initialiser, profilingService);
2627*89c4ff92SAndroid Build Coastguard Worker 
2628*89c4ff92SAndroid Build Coastguard Worker     // Bring the profiling service to the "WaitingForAck" state
2629*89c4ff92SAndroid Build Coastguard Worker     CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
2630*89c4ff92SAndroid Build Coastguard Worker     profilingService.Update();    // Initialize the counter directory
2631*89c4ff92SAndroid Build Coastguard Worker     CHECK(profilingService.GetCurrentState() == ProfilingState::NotConnected);
2632*89c4ff92SAndroid Build Coastguard Worker     profilingService.Update();    // Create the profiling connection
2633*89c4ff92SAndroid Build Coastguard Worker 
2634*89c4ff92SAndroid Build Coastguard Worker     // Get the mock profiling connection
2635*89c4ff92SAndroid Build Coastguard Worker     MockProfilingConnection* mockProfilingConnection = helper.GetMockProfilingConnection();
2636*89c4ff92SAndroid Build Coastguard Worker     CHECK(mockProfilingConnection);
2637*89c4ff92SAndroid Build Coastguard Worker 
2638*89c4ff92SAndroid Build Coastguard Worker     // Remove the packets received so far
2639*89c4ff92SAndroid Build Coastguard Worker     mockProfilingConnection->Clear();
2640*89c4ff92SAndroid Build Coastguard Worker 
2641*89c4ff92SAndroid Build Coastguard Worker     CHECK(profilingService.GetCurrentState() == ProfilingState::WaitingForAck);
2642*89c4ff92SAndroid Build Coastguard Worker     profilingService.Update();    // Start the command handler and the send thread
2643*89c4ff92SAndroid Build Coastguard Worker 
2644*89c4ff92SAndroid Build Coastguard Worker     // Wait for the Stream Metadata packet to be sent
2645*89c4ff92SAndroid Build Coastguard Worker     CHECK(helper.WaitForPacketsSent(
2646*89c4ff92SAndroid Build Coastguard Worker             mockProfilingConnection, PacketType::StreamMetaData, streamMetadataPacketsize) >= 1);
2647*89c4ff92SAndroid Build Coastguard Worker 
2648*89c4ff92SAndroid Build Coastguard Worker     // Write a valid "Connection Acknowledged" packet into the mock profiling connection, to simulate a valid
2649*89c4ff92SAndroid Build Coastguard Worker     // reply from an external profiling service
2650*89c4ff92SAndroid Build Coastguard Worker 
2651*89c4ff92SAndroid Build Coastguard Worker     // Connection Acknowledged Packet header (word 0, word 1 is always zero):
2652*89c4ff92SAndroid Build Coastguard Worker     // 26:31 [6]  packet_family: Control Packet Family, value 0b000000
2653*89c4ff92SAndroid Build Coastguard Worker     // 16:25 [10] packet_id: Packet identifier, value 0b0000000001
2654*89c4ff92SAndroid Build Coastguard Worker     // 8:15  [8]  reserved: Reserved, value 0b00000000
2655*89c4ff92SAndroid Build Coastguard Worker     // 0:7   [8]  reserved: Reserved, value 0b00000000
2656*89c4ff92SAndroid Build Coastguard Worker     uint32_t packetFamily = 0;
2657*89c4ff92SAndroid Build Coastguard Worker     uint32_t packetId     = 1;
2658*89c4ff92SAndroid Build Coastguard Worker     uint32_t header       = ((packetFamily & 0x0000003F) << 26) | ((packetId & 0x000003FF) << 16);
2659*89c4ff92SAndroid Build Coastguard Worker 
2660*89c4ff92SAndroid Build Coastguard Worker     // Create the Connection Acknowledged Packet
2661*89c4ff92SAndroid Build Coastguard Worker     arm::pipe::Packet connectionAcknowledgedPacket(header);
2662*89c4ff92SAndroid Build Coastguard Worker 
2663*89c4ff92SAndroid Build Coastguard Worker     // Write the packet to the mock profiling connection
2664*89c4ff92SAndroid Build Coastguard Worker     mockProfilingConnection->WritePacket(std::move(connectionAcknowledgedPacket));
2665*89c4ff92SAndroid Build Coastguard Worker 
2666*89c4ff92SAndroid Build Coastguard Worker     // Wait for the counter directory packet to ensure the ConnectionAcknowledgedCommandHandler has run.
2667*89c4ff92SAndroid Build Coastguard Worker     CHECK(helper.WaitForPacketsSent(mockProfilingConnection, PacketType::CounterDirectory) == 1);
2668*89c4ff92SAndroid Build Coastguard Worker 
2669*89c4ff92SAndroid Build Coastguard Worker     // The Connection Acknowledged Command Handler should have updated the profiling state accordingly
2670*89c4ff92SAndroid Build Coastguard Worker     CHECK(profilingService.GetCurrentState() == ProfilingState::Active);
2671*89c4ff92SAndroid Build Coastguard Worker 
2672*89c4ff92SAndroid Build Coastguard Worker     // Reset the profiling service to stop any running thread
2673*89c4ff92SAndroid Build Coastguard Worker     options.m_EnableProfiling = false;
2674*89c4ff92SAndroid Build Coastguard Worker     profilingService.ResetExternalProfilingOptions(options, true);
2675*89c4ff92SAndroid Build Coastguard Worker }
2676*89c4ff92SAndroid Build Coastguard Worker 
2677*89c4ff92SAndroid Build Coastguard Worker TEST_CASE("CheckProfilingServiceGoodRequestCounterDirectoryPacket")
2678*89c4ff92SAndroid Build Coastguard Worker {
2679*89c4ff92SAndroid Build Coastguard Worker     // Reset the profiling service to the uninitialized state
2680*89c4ff92SAndroid Build Coastguard Worker     ProfilingOptions options;
2681*89c4ff92SAndroid Build Coastguard Worker     options.m_EnableProfiling          = true;
2682*89c4ff92SAndroid Build Coastguard Worker     armnn::ArmNNProfilingServiceInitialiser initialiser;
2683*89c4ff92SAndroid Build Coastguard Worker     ProfilingService profilingService(arm::pipe::MAX_ARMNN_COUNTER,
2684*89c4ff92SAndroid Build Coastguard Worker                                       initialiser,
2685*89c4ff92SAndroid Build Coastguard Worker                                       arm::pipe::ARMNN_SOFTWARE_INFO,
2686*89c4ff92SAndroid Build Coastguard Worker                                       arm::pipe::ARMNN_SOFTWARE_VERSION,
2687*89c4ff92SAndroid Build Coastguard Worker                                       arm::pipe::ARMNN_HARDWARE_VERSION);
2688*89c4ff92SAndroid Build Coastguard Worker     profilingService.ResetExternalProfilingOptions(options, true);
2689*89c4ff92SAndroid Build Coastguard Worker 
2690*89c4ff92SAndroid Build Coastguard Worker     // Swap the profiling connection factory in the profiling service instance with our mock one
2691*89c4ff92SAndroid Build Coastguard Worker     SwapProfilingConnectionFactoryHelper helper(arm::pipe::MAX_ARMNN_COUNTER, initialiser, profilingService);
2692*89c4ff92SAndroid Build Coastguard Worker 
2693*89c4ff92SAndroid Build Coastguard Worker     // Bring the profiling service to the "Active" state
2694*89c4ff92SAndroid Build Coastguard Worker     CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
2695*89c4ff92SAndroid Build Coastguard Worker     profilingService.Update();    // Initialize the counter directory
2696*89c4ff92SAndroid Build Coastguard Worker     CHECK(profilingService.GetCurrentState() == ProfilingState::NotConnected);
2697*89c4ff92SAndroid Build Coastguard Worker     profilingService.Update();    // Create the profiling connection
2698*89c4ff92SAndroid Build Coastguard Worker     CHECK(profilingService.GetCurrentState() == ProfilingState::WaitingForAck);
2699*89c4ff92SAndroid Build Coastguard Worker     profilingService.Update();    // Start the command handler and the send thread
2700*89c4ff92SAndroid Build Coastguard Worker 
2701*89c4ff92SAndroid Build Coastguard Worker     // Get the mock profiling connection
2702*89c4ff92SAndroid Build Coastguard Worker     MockProfilingConnection* mockProfilingConnection = helper.GetMockProfilingConnection();
2703*89c4ff92SAndroid Build Coastguard Worker     CHECK(mockProfilingConnection);
2704*89c4ff92SAndroid Build Coastguard Worker 
2705*89c4ff92SAndroid Build Coastguard Worker     // Force the profiling service to the "Active" state
2706*89c4ff92SAndroid Build Coastguard Worker     helper.ForceTransitionToState(ProfilingState::Active);
2707*89c4ff92SAndroid Build Coastguard Worker     CHECK(profilingService.GetCurrentState() == ProfilingState::Active);
2708*89c4ff92SAndroid Build Coastguard Worker 
2709*89c4ff92SAndroid Build Coastguard Worker     // Write a valid "Request Counter Directory" packet into the mock profiling connection, to simulate a valid
2710*89c4ff92SAndroid Build Coastguard Worker     // reply from an external profiling service
2711*89c4ff92SAndroid Build Coastguard Worker 
2712*89c4ff92SAndroid Build Coastguard Worker     // Request Counter Directory packet header (word 0, word 1 is always zero):
2713*89c4ff92SAndroid Build Coastguard Worker     // 26:31 [6]  packet_family: Control Packet Family, value 0b000000
2714*89c4ff92SAndroid Build Coastguard Worker     // 16:25 [10] packet_id: Packet identifier, value 0b0000000011
2715*89c4ff92SAndroid Build Coastguard Worker     // 8:15  [8]  reserved: Reserved, value 0b00000000
2716*89c4ff92SAndroid Build Coastguard Worker     // 0:7   [8]  reserved: Reserved, value 0b00000000
2717*89c4ff92SAndroid Build Coastguard Worker     uint32_t packetFamily = 0;
2718*89c4ff92SAndroid Build Coastguard Worker     uint32_t packetId     = 3;
2719*89c4ff92SAndroid Build Coastguard Worker     uint32_t header       = ((packetFamily & 0x0000003F) << 26) | ((packetId & 0x000003FF) << 16);
2720*89c4ff92SAndroid Build Coastguard Worker 
2721*89c4ff92SAndroid Build Coastguard Worker     // Create the Request Counter Directory packet
2722*89c4ff92SAndroid Build Coastguard Worker     arm::pipe::Packet requestCounterDirectoryPacket(header);
2723*89c4ff92SAndroid Build Coastguard Worker 
2724*89c4ff92SAndroid Build Coastguard Worker     // Write the packet to the mock profiling connection
2725*89c4ff92SAndroid Build Coastguard Worker     mockProfilingConnection->WritePacket(std::move(requestCounterDirectoryPacket));
2726*89c4ff92SAndroid Build Coastguard Worker 
2727*89c4ff92SAndroid Build Coastguard Worker     // Expecting one CounterDirectory Packet of length 652
2728*89c4ff92SAndroid Build Coastguard Worker     // and one TimelineMessageDirectory packet of length 451
2729*89c4ff92SAndroid Build Coastguard Worker     CHECK(helper.WaitForPacketsSent(mockProfilingConnection, PacketType::CounterDirectory, 652) == 1);
2730*89c4ff92SAndroid Build Coastguard Worker     CHECK(helper.WaitForPacketsSent(mockProfilingConnection, PacketType::TimelineMessageDirectory, 451) == 1);
2731*89c4ff92SAndroid Build Coastguard Worker 
2732*89c4ff92SAndroid Build Coastguard Worker     // The Request Counter Directory Command Handler should not have updated the profiling state
2733*89c4ff92SAndroid Build Coastguard Worker     CHECK(profilingService.GetCurrentState() == ProfilingState::Active);
2734*89c4ff92SAndroid Build Coastguard Worker 
2735*89c4ff92SAndroid Build Coastguard Worker     // Reset the profiling service to stop any running thread
2736*89c4ff92SAndroid Build Coastguard Worker     options.m_EnableProfiling = false;
2737*89c4ff92SAndroid Build Coastguard Worker     profilingService.ResetExternalProfilingOptions(options, true);
2738*89c4ff92SAndroid Build Coastguard Worker }
2739*89c4ff92SAndroid Build Coastguard Worker 
2740*89c4ff92SAndroid Build Coastguard Worker TEST_CASE("CheckProfilingServiceBadPeriodicCounterSelectionPacketInvalidCounterUid")
2741*89c4ff92SAndroid Build Coastguard Worker {
2742*89c4ff92SAndroid Build Coastguard Worker     // Reset the profiling service to the uninitialized state
2743*89c4ff92SAndroid Build Coastguard Worker     ProfilingOptions options;
2744*89c4ff92SAndroid Build Coastguard Worker     options.m_EnableProfiling          = true;
2745*89c4ff92SAndroid Build Coastguard Worker     armnn::ArmNNProfilingServiceInitialiser initialiser;
2746*89c4ff92SAndroid Build Coastguard Worker     ProfilingService profilingService(arm::pipe::MAX_ARMNN_COUNTER,
2747*89c4ff92SAndroid Build Coastguard Worker                                       initialiser,
2748*89c4ff92SAndroid Build Coastguard Worker                                       arm::pipe::ARMNN_SOFTWARE_INFO,
2749*89c4ff92SAndroid Build Coastguard Worker                                       arm::pipe::ARMNN_SOFTWARE_VERSION,
2750*89c4ff92SAndroid Build Coastguard Worker                                       arm::pipe::ARMNN_HARDWARE_VERSION);
2751*89c4ff92SAndroid Build Coastguard Worker     profilingService.ResetExternalProfilingOptions(options, true);
2752*89c4ff92SAndroid Build Coastguard Worker 
2753*89c4ff92SAndroid Build Coastguard Worker     // Swap the profiling connection factory in the profiling service instance with our mock one
2754*89c4ff92SAndroid Build Coastguard Worker     SwapProfilingConnectionFactoryHelper helper(arm::pipe::MAX_ARMNN_COUNTER, initialiser, profilingService);
2755*89c4ff92SAndroid Build Coastguard Worker 
2756*89c4ff92SAndroid Build Coastguard Worker     // Bring the profiling service to the "Active" state
2757*89c4ff92SAndroid Build Coastguard Worker     CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
2758*89c4ff92SAndroid Build Coastguard Worker     profilingService.Update();    // Initialize the counter directory
2759*89c4ff92SAndroid Build Coastguard Worker     CHECK(profilingService.GetCurrentState() == ProfilingState::NotConnected);
2760*89c4ff92SAndroid Build Coastguard Worker     profilingService.Update();    // Create the profiling connection
2761*89c4ff92SAndroid Build Coastguard Worker     CHECK(profilingService.GetCurrentState() == ProfilingState::WaitingForAck);
2762*89c4ff92SAndroid Build Coastguard Worker     profilingService.Update();    // Start the command handler and the send thread
2763*89c4ff92SAndroid Build Coastguard Worker 
2764*89c4ff92SAndroid Build Coastguard Worker     // Get the mock profiling connection
2765*89c4ff92SAndroid Build Coastguard Worker     MockProfilingConnection* mockProfilingConnection = helper.GetMockProfilingConnection();
2766*89c4ff92SAndroid Build Coastguard Worker     CHECK(mockProfilingConnection);
2767*89c4ff92SAndroid Build Coastguard Worker 
2768*89c4ff92SAndroid Build Coastguard Worker     // Force the profiling service to the "Active" state
2769*89c4ff92SAndroid Build Coastguard Worker     helper.ForceTransitionToState(ProfilingState::Active);
2770*89c4ff92SAndroid Build Coastguard Worker     CHECK(profilingService.GetCurrentState() == ProfilingState::Active);
2771*89c4ff92SAndroid Build Coastguard Worker 
2772*89c4ff92SAndroid Build Coastguard Worker     // Remove the packets received so far
2773*89c4ff92SAndroid Build Coastguard Worker     mockProfilingConnection->Clear();
2774*89c4ff92SAndroid Build Coastguard Worker 
2775*89c4ff92SAndroid Build Coastguard Worker     // Write a "Periodic Counter Selection" packet into the mock profiling connection, to simulate an input from an
2776*89c4ff92SAndroid Build Coastguard Worker     // external profiling service
2777*89c4ff92SAndroid Build Coastguard Worker 
2778*89c4ff92SAndroid Build Coastguard Worker     // Periodic Counter Selection packet header:
2779*89c4ff92SAndroid Build Coastguard Worker     // 26:31 [6]  packet_family: Control Packet Family, value 0b000000
2780*89c4ff92SAndroid Build Coastguard Worker     // 16:25 [10] packet_id: Packet identifier, value 0b0000000100
2781*89c4ff92SAndroid Build Coastguard Worker     // 8:15  [8]  reserved: Reserved, value 0b00000000
2782*89c4ff92SAndroid Build Coastguard Worker     // 0:7   [8]  reserved: Reserved, value 0b00000000
2783*89c4ff92SAndroid Build Coastguard Worker     uint32_t packetFamily = 0;
2784*89c4ff92SAndroid Build Coastguard Worker     uint32_t packetId     = 4;
2785*89c4ff92SAndroid Build Coastguard Worker     uint32_t header       = ((packetFamily & 0x0000003F) << 26) | ((packetId & 0x000003FF) << 16);
2786*89c4ff92SAndroid Build Coastguard Worker 
2787*89c4ff92SAndroid Build Coastguard Worker     uint32_t capturePeriod = 123456;    // Some capture period (microseconds)
2788*89c4ff92SAndroid Build Coastguard Worker 
2789*89c4ff92SAndroid Build Coastguard Worker     // Get the first valid counter UID
2790*89c4ff92SAndroid Build Coastguard Worker     const ICounterDirectory& counterDirectory = profilingService.GetCounterDirectory();
2791*89c4ff92SAndroid Build Coastguard Worker     const Counters& counters                  = counterDirectory.GetCounters();
2792*89c4ff92SAndroid Build Coastguard Worker     CHECK(counters.size() > 1);
2793*89c4ff92SAndroid Build Coastguard Worker     uint16_t counterUidA = counters.begin()->first;    // First valid counter UID
2794*89c4ff92SAndroid Build Coastguard Worker     uint16_t counterUidB = 9999;                       // Second invalid counter UID
2795*89c4ff92SAndroid Build Coastguard Worker 
2796*89c4ff92SAndroid Build Coastguard Worker     uint32_t length = 8;
2797*89c4ff92SAndroid Build Coastguard Worker 
2798*89c4ff92SAndroid Build Coastguard Worker     auto data = std::make_unique<unsigned char[]>(length);
2799*89c4ff92SAndroid Build Coastguard Worker     WriteUint32(data.get(), 0, capturePeriod);
2800*89c4ff92SAndroid Build Coastguard Worker     WriteUint16(data.get(), 4, counterUidA);
2801*89c4ff92SAndroid Build Coastguard Worker     WriteUint16(data.get(), 6, counterUidB);
2802*89c4ff92SAndroid Build Coastguard Worker 
2803*89c4ff92SAndroid Build Coastguard Worker     // Create the Periodic Counter Selection packet
2804*89c4ff92SAndroid Build Coastguard Worker     // Length > 0, this will start the Period Counter Capture thread
2805*89c4ff92SAndroid Build Coastguard Worker     arm::pipe::Packet periodicCounterSelectionPacket(header, length, data);
2806*89c4ff92SAndroid Build Coastguard Worker 
2807*89c4ff92SAndroid Build Coastguard Worker 
2808*89c4ff92SAndroid Build Coastguard Worker     // Write the packet to the mock profiling connection
2809*89c4ff92SAndroid Build Coastguard Worker     mockProfilingConnection->WritePacket(std::move(periodicCounterSelectionPacket));
2810*89c4ff92SAndroid Build Coastguard Worker 
2811*89c4ff92SAndroid Build Coastguard Worker     // Expecting one Periodic Counter Selection packet of length 14
2812*89c4ff92SAndroid Build Coastguard Worker     // and at least one Periodic Counter Capture packet of length 22
2813*89c4ff92SAndroid Build Coastguard Worker     CHECK(helper.WaitForPacketsSent(mockProfilingConnection, PacketType::PeriodicCounterSelection, 14) == 1);
2814*89c4ff92SAndroid Build Coastguard Worker     CHECK(helper.WaitForPacketsSent(mockProfilingConnection, PacketType::PeriodicCounterCapture, 22) >= 1);
2815*89c4ff92SAndroid Build Coastguard Worker 
2816*89c4ff92SAndroid Build Coastguard Worker     // The Periodic Counter Selection Handler should not have updated the profiling state
2817*89c4ff92SAndroid Build Coastguard Worker     CHECK(profilingService.GetCurrentState() == ProfilingState::Active);
2818*89c4ff92SAndroid Build Coastguard Worker 
2819*89c4ff92SAndroid Build Coastguard Worker     // Reset the profiling service to stop any running thread
2820*89c4ff92SAndroid Build Coastguard Worker     options.m_EnableProfiling = false;
2821*89c4ff92SAndroid Build Coastguard Worker     profilingService.ResetExternalProfilingOptions(options, true);
2822*89c4ff92SAndroid Build Coastguard Worker }
2823*89c4ff92SAndroid Build Coastguard Worker 
2824*89c4ff92SAndroid Build Coastguard Worker TEST_CASE("CheckProfilingServiceGoodPeriodicCounterSelectionPacketNoCounters")
2825*89c4ff92SAndroid Build Coastguard Worker {
2826*89c4ff92SAndroid Build Coastguard Worker     // Reset the profiling service to the uninitialized state
2827*89c4ff92SAndroid Build Coastguard Worker     ProfilingOptions options;
2828*89c4ff92SAndroid Build Coastguard Worker     options.m_EnableProfiling          = true;
2829*89c4ff92SAndroid Build Coastguard Worker     armnn::ArmNNProfilingServiceInitialiser initialiser;
2830*89c4ff92SAndroid Build Coastguard Worker     ProfilingService profilingService(arm::pipe::MAX_ARMNN_COUNTER,
2831*89c4ff92SAndroid Build Coastguard Worker                                       initialiser,
2832*89c4ff92SAndroid Build Coastguard Worker                                       arm::pipe::ARMNN_SOFTWARE_INFO,
2833*89c4ff92SAndroid Build Coastguard Worker                                       arm::pipe::ARMNN_SOFTWARE_VERSION,
2834*89c4ff92SAndroid Build Coastguard Worker                                       arm::pipe::ARMNN_HARDWARE_VERSION);
2835*89c4ff92SAndroid Build Coastguard Worker     profilingService.ResetExternalProfilingOptions(options, true);
2836*89c4ff92SAndroid Build Coastguard Worker 
2837*89c4ff92SAndroid Build Coastguard Worker     // Swap the profiling connection factory in the profiling service instance with our mock one
2838*89c4ff92SAndroid Build Coastguard Worker     SwapProfilingConnectionFactoryHelper helper(arm::pipe::MAX_ARMNN_COUNTER, initialiser, profilingService);
2839*89c4ff92SAndroid Build Coastguard Worker 
2840*89c4ff92SAndroid Build Coastguard Worker     // Bring the profiling service to the "Active" state
2841*89c4ff92SAndroid Build Coastguard Worker     CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
2842*89c4ff92SAndroid Build Coastguard Worker     profilingService.Update();    // Initialize the counter directory
2843*89c4ff92SAndroid Build Coastguard Worker     CHECK(profilingService.GetCurrentState() == ProfilingState::NotConnected);
2844*89c4ff92SAndroid Build Coastguard Worker     profilingService.Update();    // Create the profiling connection
2845*89c4ff92SAndroid Build Coastguard Worker     CHECK(profilingService.GetCurrentState() == ProfilingState::WaitingForAck);
2846*89c4ff92SAndroid Build Coastguard Worker     profilingService.Update();    // Start the command handler and the send thread
2847*89c4ff92SAndroid Build Coastguard Worker 
2848*89c4ff92SAndroid Build Coastguard Worker     // Get the mock profiling connection
2849*89c4ff92SAndroid Build Coastguard Worker     MockProfilingConnection* mockProfilingConnection = helper.GetMockProfilingConnection();
2850*89c4ff92SAndroid Build Coastguard Worker     CHECK(mockProfilingConnection);
2851*89c4ff92SAndroid Build Coastguard Worker 
2852*89c4ff92SAndroid Build Coastguard Worker     // Wait for the Stream Metadata packet the be sent
2853*89c4ff92SAndroid Build Coastguard Worker     // (we are not testing the connection acknowledgement here so it will be ignored by this test)
2854*89c4ff92SAndroid Build Coastguard Worker     helper.WaitForPacketsSent(mockProfilingConnection, PacketType::StreamMetaData);
2855*89c4ff92SAndroid Build Coastguard Worker 
2856*89c4ff92SAndroid Build Coastguard Worker     // Force the profiling service to the "Active" state
2857*89c4ff92SAndroid Build Coastguard Worker     helper.ForceTransitionToState(ProfilingState::Active);
2858*89c4ff92SAndroid Build Coastguard Worker     CHECK(profilingService.GetCurrentState() == ProfilingState::Active);
2859*89c4ff92SAndroid Build Coastguard Worker 
2860*89c4ff92SAndroid Build Coastguard Worker     // Write a "Periodic Counter Selection" packet into the mock profiling connection, to simulate an input from an
2861*89c4ff92SAndroid Build Coastguard Worker     // external profiling service
2862*89c4ff92SAndroid Build Coastguard Worker 
2863*89c4ff92SAndroid Build Coastguard Worker     // Periodic Counter Selection packet header:
2864*89c4ff92SAndroid Build Coastguard Worker     // 26:31 [6]  packet_family: Control Packet Family, value 0b000000
2865*89c4ff92SAndroid Build Coastguard Worker     // 16:25 [10] packet_id: Packet identifier, value 0b0000000100
2866*89c4ff92SAndroid Build Coastguard Worker     // 8:15  [8]  reserved: Reserved, value 0b00000000
2867*89c4ff92SAndroid Build Coastguard Worker     // 0:7   [8]  reserved: Reserved, value 0b00000000
2868*89c4ff92SAndroid Build Coastguard Worker     uint32_t packetFamily = 0;
2869*89c4ff92SAndroid Build Coastguard Worker     uint32_t packetId     = 4;
2870*89c4ff92SAndroid Build Coastguard Worker     uint32_t header       = ((packetFamily & 0x0000003F) << 26) | ((packetId & 0x000003FF) << 16);
2871*89c4ff92SAndroid Build Coastguard Worker 
2872*89c4ff92SAndroid Build Coastguard Worker     // Create the Periodic Counter Selection packet
2873*89c4ff92SAndroid Build Coastguard Worker     // Length == 0, this will disable the collection of counters
2874*89c4ff92SAndroid Build Coastguard Worker     arm::pipe::Packet periodicCounterSelectionPacket(header);
2875*89c4ff92SAndroid Build Coastguard Worker 
2876*89c4ff92SAndroid Build Coastguard Worker     // Write the packet to the mock profiling connection
2877*89c4ff92SAndroid Build Coastguard Worker     mockProfilingConnection->WritePacket(std::move(periodicCounterSelectionPacket));
2878*89c4ff92SAndroid Build Coastguard Worker 
2879*89c4ff92SAndroid Build Coastguard Worker     // Wait for the Periodic Counter Selection packet of length 12 to be sent
2880*89c4ff92SAndroid Build Coastguard Worker     // The size of the expected Periodic Counter Selection (echos the sent one)
2881*89c4ff92SAndroid Build Coastguard Worker     CHECK(helper.WaitForPacketsSent(mockProfilingConnection, PacketType::PeriodicCounterSelection, 12) == 1);
2882*89c4ff92SAndroid Build Coastguard Worker 
2883*89c4ff92SAndroid Build Coastguard Worker     // The Periodic Counter Selection Handler should not have updated the profiling state
2884*89c4ff92SAndroid Build Coastguard Worker     CHECK(profilingService.GetCurrentState() == ProfilingState::Active);
2885*89c4ff92SAndroid Build Coastguard Worker 
2886*89c4ff92SAndroid Build Coastguard Worker     // No Periodic Counter packets are expected
2887*89c4ff92SAndroid Build Coastguard Worker     CHECK(helper.WaitForPacketsSent(mockProfilingConnection, PacketType::PeriodicCounterCapture, 0, 0) == 0);
2888*89c4ff92SAndroid Build Coastguard Worker 
2889*89c4ff92SAndroid Build Coastguard Worker     // Reset the profiling service to stop any running thread
2890*89c4ff92SAndroid Build Coastguard Worker     options.m_EnableProfiling = false;
2891*89c4ff92SAndroid Build Coastguard Worker     profilingService.ResetExternalProfilingOptions(options, true);
2892*89c4ff92SAndroid Build Coastguard Worker }
2893*89c4ff92SAndroid Build Coastguard Worker 
2894*89c4ff92SAndroid Build Coastguard Worker TEST_CASE("CheckProfilingServiceGoodPeriodicCounterSelectionPacketSingleCounter")
2895*89c4ff92SAndroid Build Coastguard Worker {
2896*89c4ff92SAndroid Build Coastguard Worker     // Reset the profiling service to the uninitialized state
2897*89c4ff92SAndroid Build Coastguard Worker     ProfilingOptions options;
2898*89c4ff92SAndroid Build Coastguard Worker     options.m_EnableProfiling          = true;
2899*89c4ff92SAndroid Build Coastguard Worker     armnn::ArmNNProfilingServiceInitialiser initialiser;
2900*89c4ff92SAndroid Build Coastguard Worker     ProfilingService profilingService(arm::pipe::MAX_ARMNN_COUNTER,
2901*89c4ff92SAndroid Build Coastguard Worker                                       initialiser,
2902*89c4ff92SAndroid Build Coastguard Worker                                       arm::pipe::ARMNN_SOFTWARE_INFO,
2903*89c4ff92SAndroid Build Coastguard Worker                                       arm::pipe::ARMNN_SOFTWARE_VERSION,
2904*89c4ff92SAndroid Build Coastguard Worker                                       arm::pipe::ARMNN_HARDWARE_VERSION);
2905*89c4ff92SAndroid Build Coastguard Worker     profilingService.ResetExternalProfilingOptions(options, true);
2906*89c4ff92SAndroid Build Coastguard Worker 
2907*89c4ff92SAndroid Build Coastguard Worker     // Swap the profiling connection factory in the profiling service instance with our mock one
2908*89c4ff92SAndroid Build Coastguard Worker     SwapProfilingConnectionFactoryHelper helper(arm::pipe::MAX_ARMNN_COUNTER, initialiser, profilingService);
2909*89c4ff92SAndroid Build Coastguard Worker 
2910*89c4ff92SAndroid Build Coastguard Worker     // Bring the profiling service to the "Active" state
2911*89c4ff92SAndroid Build Coastguard Worker     CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
2912*89c4ff92SAndroid Build Coastguard Worker     profilingService.Update();    // Initialize the counter directory
2913*89c4ff92SAndroid Build Coastguard Worker     CHECK(profilingService.GetCurrentState() == ProfilingState::NotConnected);
2914*89c4ff92SAndroid Build Coastguard Worker     profilingService.Update();    // Create the profiling connection
2915*89c4ff92SAndroid Build Coastguard Worker     CHECK(profilingService.GetCurrentState() == ProfilingState::WaitingForAck);
2916*89c4ff92SAndroid Build Coastguard Worker     profilingService.Update();    // Start the command handler and the send thread
2917*89c4ff92SAndroid Build Coastguard Worker 
2918*89c4ff92SAndroid Build Coastguard Worker     // Get the mock profiling connection
2919*89c4ff92SAndroid Build Coastguard Worker     MockProfilingConnection* mockProfilingConnection = helper.GetMockProfilingConnection();
2920*89c4ff92SAndroid Build Coastguard Worker     CHECK(mockProfilingConnection);
2921*89c4ff92SAndroid Build Coastguard Worker 
2922*89c4ff92SAndroid Build Coastguard Worker     // Wait for the Stream Metadata packet to be sent
2923*89c4ff92SAndroid Build Coastguard Worker     // (we are not testing the connection acknowledgement here so it will be ignored by this test)
2924*89c4ff92SAndroid Build Coastguard Worker     helper.WaitForPacketsSent(mockProfilingConnection, PacketType::StreamMetaData);
2925*89c4ff92SAndroid Build Coastguard Worker 
2926*89c4ff92SAndroid Build Coastguard Worker     // Force the profiling service to the "Active" state
2927*89c4ff92SAndroid Build Coastguard Worker     helper.ForceTransitionToState(ProfilingState::Active);
2928*89c4ff92SAndroid Build Coastguard Worker     CHECK(profilingService.GetCurrentState() == ProfilingState::Active);
2929*89c4ff92SAndroid Build Coastguard Worker 
2930*89c4ff92SAndroid Build Coastguard Worker     // Write a "Periodic Counter Selection" packet into the mock profiling connection, to simulate an input from an
2931*89c4ff92SAndroid Build Coastguard Worker     // external profiling service
2932*89c4ff92SAndroid Build Coastguard Worker 
2933*89c4ff92SAndroid Build Coastguard Worker     // Periodic Counter Selection packet header:
2934*89c4ff92SAndroid Build Coastguard Worker     // 26:31 [6]  packet_family: Control Packet Family, value 0b000000
2935*89c4ff92SAndroid Build Coastguard Worker     // 16:25 [10] packet_id: Packet identifier, value 0b0000000100
2936*89c4ff92SAndroid Build Coastguard Worker     // 8:15  [8]  reserved: Reserved, value 0b00000000
2937*89c4ff92SAndroid Build Coastguard Worker     // 0:7   [8]  reserved: Reserved, value 0b00000000
2938*89c4ff92SAndroid Build Coastguard Worker     uint32_t packetFamily = 0;
2939*89c4ff92SAndroid Build Coastguard Worker     uint32_t packetId     = 4;
2940*89c4ff92SAndroid Build Coastguard Worker     uint32_t header       = ((packetFamily & 0x0000003F) << 26) | ((packetId & 0x000003FF) << 16);
2941*89c4ff92SAndroid Build Coastguard Worker 
2942*89c4ff92SAndroid Build Coastguard Worker     uint32_t capturePeriod = 123456;    // Some capture period (microseconds)
2943*89c4ff92SAndroid Build Coastguard Worker 
2944*89c4ff92SAndroid Build Coastguard Worker     // Get the first valid counter UID
2945*89c4ff92SAndroid Build Coastguard Worker     const ICounterDirectory& counterDirectory = profilingService.GetCounterDirectory();
2946*89c4ff92SAndroid Build Coastguard Worker     const Counters& counters                  = counterDirectory.GetCounters();
2947*89c4ff92SAndroid Build Coastguard Worker     CHECK(!counters.empty());
2948*89c4ff92SAndroid Build Coastguard Worker     uint16_t counterUid = counters.begin()->first;    // Valid counter UID
2949*89c4ff92SAndroid Build Coastguard Worker 
2950*89c4ff92SAndroid Build Coastguard Worker     uint32_t length = 6;
2951*89c4ff92SAndroid Build Coastguard Worker 
2952*89c4ff92SAndroid Build Coastguard Worker     auto data = std::make_unique<unsigned char[]>(length);
2953*89c4ff92SAndroid Build Coastguard Worker     WriteUint32(data.get(), 0, capturePeriod);
2954*89c4ff92SAndroid Build Coastguard Worker     WriteUint16(data.get(), 4, counterUid);
2955*89c4ff92SAndroid Build Coastguard Worker 
2956*89c4ff92SAndroid Build Coastguard Worker     // Create the Periodic Counter Selection packet
2957*89c4ff92SAndroid Build Coastguard Worker     // Length > 0, this will start the Period Counter Capture thread
2958*89c4ff92SAndroid Build Coastguard Worker     arm::pipe::Packet periodicCounterSelectionPacket(header, length, data);
2959*89c4ff92SAndroid Build Coastguard Worker 
2960*89c4ff92SAndroid Build Coastguard Worker     // Write the packet to the mock profiling connection
2961*89c4ff92SAndroid Build Coastguard Worker     mockProfilingConnection->WritePacket(std::move(periodicCounterSelectionPacket));
2962*89c4ff92SAndroid Build Coastguard Worker 
2963*89c4ff92SAndroid Build Coastguard Worker     // Expecting one Periodic Counter Selection packet of length 14
2964*89c4ff92SAndroid Build Coastguard Worker     // and at least one Periodic Counter Capture packet of length 22
2965*89c4ff92SAndroid Build Coastguard Worker     CHECK(helper.WaitForPacketsSent(mockProfilingConnection, PacketType::PeriodicCounterSelection, 14) == 1);
2966*89c4ff92SAndroid Build Coastguard Worker     CHECK(helper.WaitForPacketsSent(mockProfilingConnection, PacketType::PeriodicCounterCapture, 22) >= 1);
2967*89c4ff92SAndroid Build Coastguard Worker 
2968*89c4ff92SAndroid Build Coastguard Worker     // The Periodic Counter Selection Handler should not have updated the profiling state
2969*89c4ff92SAndroid Build Coastguard Worker     CHECK(profilingService.GetCurrentState() == ProfilingState::Active);
2970*89c4ff92SAndroid Build Coastguard Worker 
2971*89c4ff92SAndroid Build Coastguard Worker     // Reset the profiling service to stop any running thread
2972*89c4ff92SAndroid Build Coastguard Worker     options.m_EnableProfiling = false;
2973*89c4ff92SAndroid Build Coastguard Worker     profilingService.ResetExternalProfilingOptions(options, true);
2974*89c4ff92SAndroid Build Coastguard Worker }
2975*89c4ff92SAndroid Build Coastguard Worker 
2976*89c4ff92SAndroid Build Coastguard Worker TEST_CASE("CheckProfilingServiceGoodPeriodicCounterSelectionPacketMultipleCounters")
2977*89c4ff92SAndroid Build Coastguard Worker {
2978*89c4ff92SAndroid Build Coastguard Worker     // Reset the profiling service to the uninitialized state
2979*89c4ff92SAndroid Build Coastguard Worker     ProfilingOptions options;
2980*89c4ff92SAndroid Build Coastguard Worker     options.m_EnableProfiling          = true;
2981*89c4ff92SAndroid Build Coastguard Worker     armnn::ArmNNProfilingServiceInitialiser initialiser;
2982*89c4ff92SAndroid Build Coastguard Worker     ProfilingService profilingService(arm::pipe::MAX_ARMNN_COUNTER,
2983*89c4ff92SAndroid Build Coastguard Worker                                       initialiser,
2984*89c4ff92SAndroid Build Coastguard Worker                                       arm::pipe::ARMNN_SOFTWARE_INFO,
2985*89c4ff92SAndroid Build Coastguard Worker                                       arm::pipe::ARMNN_SOFTWARE_VERSION,
2986*89c4ff92SAndroid Build Coastguard Worker                                       arm::pipe::ARMNN_HARDWARE_VERSION);
2987*89c4ff92SAndroid Build Coastguard Worker     profilingService.ResetExternalProfilingOptions(options, true);
2988*89c4ff92SAndroid Build Coastguard Worker 
2989*89c4ff92SAndroid Build Coastguard Worker     // Swap the profiling connection factory in the profiling service instance with our mock one
2990*89c4ff92SAndroid Build Coastguard Worker     SwapProfilingConnectionFactoryHelper helper(arm::pipe::MAX_ARMNN_COUNTER, initialiser, profilingService);
2991*89c4ff92SAndroid Build Coastguard Worker 
2992*89c4ff92SAndroid Build Coastguard Worker     // Bring the profiling service to the "Active" state
2993*89c4ff92SAndroid Build Coastguard Worker     CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
2994*89c4ff92SAndroid Build Coastguard Worker     profilingService.Update();    // Initialize the counter directory
2995*89c4ff92SAndroid Build Coastguard Worker     CHECK(profilingService.GetCurrentState() == ProfilingState::NotConnected);
2996*89c4ff92SAndroid Build Coastguard Worker     profilingService.Update();    // Create the profiling connection
2997*89c4ff92SAndroid Build Coastguard Worker     CHECK(profilingService.GetCurrentState() == ProfilingState::WaitingForAck);
2998*89c4ff92SAndroid Build Coastguard Worker     profilingService.Update();    // Start the command handler and the send thread
2999*89c4ff92SAndroid Build Coastguard Worker 
3000*89c4ff92SAndroid Build Coastguard Worker     // Get the mock profiling connection
3001*89c4ff92SAndroid Build Coastguard Worker     MockProfilingConnection* mockProfilingConnection = helper.GetMockProfilingConnection();
3002*89c4ff92SAndroid Build Coastguard Worker     CHECK(mockProfilingConnection);
3003*89c4ff92SAndroid Build Coastguard Worker 
3004*89c4ff92SAndroid Build Coastguard Worker     // Wait for the Stream Metadata packet the be sent
3005*89c4ff92SAndroid Build Coastguard Worker     // (we are not testing the connection acknowledgement here so it will be ignored by this test)
3006*89c4ff92SAndroid Build Coastguard Worker     helper.WaitForPacketsSent(mockProfilingConnection, PacketType::StreamMetaData);
3007*89c4ff92SAndroid Build Coastguard Worker 
3008*89c4ff92SAndroid Build Coastguard Worker     // Force the profiling service to the "Active" state
3009*89c4ff92SAndroid Build Coastguard Worker     helper.ForceTransitionToState(ProfilingState::Active);
3010*89c4ff92SAndroid Build Coastguard Worker     CHECK(profilingService.GetCurrentState() == ProfilingState::Active);
3011*89c4ff92SAndroid Build Coastguard Worker 
3012*89c4ff92SAndroid Build Coastguard Worker     // Write a "Periodic Counter Selection" packet into the mock profiling connection, to simulate an input from an
3013*89c4ff92SAndroid Build Coastguard Worker     // external profiling service
3014*89c4ff92SAndroid Build Coastguard Worker 
3015*89c4ff92SAndroid Build Coastguard Worker     // Periodic Counter Selection packet header:
3016*89c4ff92SAndroid Build Coastguard Worker     // 26:31 [6]  packet_family: Control Packet Family, value 0b000000
3017*89c4ff92SAndroid Build Coastguard Worker     // 16:25 [10] packet_id: Packet identifier, value 0b0000000100
3018*89c4ff92SAndroid Build Coastguard Worker     // 8:15  [8]  reserved: Reserved, value 0b00000000
3019*89c4ff92SAndroid Build Coastguard Worker     // 0:7   [8]  reserved: Reserved, value 0b00000000
3020*89c4ff92SAndroid Build Coastguard Worker     uint32_t packetFamily = 0;
3021*89c4ff92SAndroid Build Coastguard Worker     uint32_t packetId     = 4;
3022*89c4ff92SAndroid Build Coastguard Worker     uint32_t header       = ((packetFamily & 0x0000003F) << 26) | ((packetId & 0x000003FF) << 16);
3023*89c4ff92SAndroid Build Coastguard Worker 
3024*89c4ff92SAndroid Build Coastguard Worker     uint32_t capturePeriod = 123456;    // Some capture period (microseconds)
3025*89c4ff92SAndroid Build Coastguard Worker 
3026*89c4ff92SAndroid Build Coastguard Worker     // Get the first valid counter UID
3027*89c4ff92SAndroid Build Coastguard Worker     const ICounterDirectory& counterDirectory = profilingService.GetCounterDirectory();
3028*89c4ff92SAndroid Build Coastguard Worker     const Counters& counters                  = counterDirectory.GetCounters();
3029*89c4ff92SAndroid Build Coastguard Worker     CHECK(counters.size() > 1);
3030*89c4ff92SAndroid Build Coastguard Worker     uint16_t counterUidA = counters.begin()->first;        // First valid counter UID
3031*89c4ff92SAndroid Build Coastguard Worker     uint16_t counterUidB = (counters.begin()++)->first;    // Second valid counter UID
3032*89c4ff92SAndroid Build Coastguard Worker 
3033*89c4ff92SAndroid Build Coastguard Worker     uint32_t length = 8;
3034*89c4ff92SAndroid Build Coastguard Worker 
3035*89c4ff92SAndroid Build Coastguard Worker     auto data = std::make_unique<unsigned char[]>(length);
3036*89c4ff92SAndroid Build Coastguard Worker     WriteUint32(data.get(), 0, capturePeriod);
3037*89c4ff92SAndroid Build Coastguard Worker     WriteUint16(data.get(), 4, counterUidA);
3038*89c4ff92SAndroid Build Coastguard Worker     WriteUint16(data.get(), 6, counterUidB);
3039*89c4ff92SAndroid Build Coastguard Worker 
3040*89c4ff92SAndroid Build Coastguard Worker     // Create the Periodic Counter Selection packet
3041*89c4ff92SAndroid Build Coastguard Worker     // Length > 0, this will start the Period Counter Capture thread
3042*89c4ff92SAndroid Build Coastguard Worker     arm::pipe::Packet periodicCounterSelectionPacket(header, length, data);
3043*89c4ff92SAndroid Build Coastguard Worker 
3044*89c4ff92SAndroid Build Coastguard Worker     // Write the packet to the mock profiling connection
3045*89c4ff92SAndroid Build Coastguard Worker     mockProfilingConnection->WritePacket(std::move(periodicCounterSelectionPacket));
3046*89c4ff92SAndroid Build Coastguard Worker 
3047*89c4ff92SAndroid Build Coastguard Worker     // Expecting one PeriodicCounterSelection Packet with a length of 16
3048*89c4ff92SAndroid Build Coastguard Worker     // And at least one PeriodicCounterCapture Packet with a length of 28
3049*89c4ff92SAndroid Build Coastguard Worker     CHECK(helper.WaitForPacketsSent(mockProfilingConnection, PacketType::PeriodicCounterSelection, 16) == 1);
3050*89c4ff92SAndroid Build Coastguard Worker     CHECK(helper.WaitForPacketsSent(mockProfilingConnection, PacketType::PeriodicCounterCapture, 28) >= 1);
3051*89c4ff92SAndroid Build Coastguard Worker 
3052*89c4ff92SAndroid Build Coastguard Worker     // The Periodic Counter Selection Handler should not have updated the profiling state
3053*89c4ff92SAndroid Build Coastguard Worker     CHECK(profilingService.GetCurrentState() == ProfilingState::Active);
3054*89c4ff92SAndroid Build Coastguard Worker 
3055*89c4ff92SAndroid Build Coastguard Worker     // Reset the profiling service to stop any running thread
3056*89c4ff92SAndroid Build Coastguard Worker     options.m_EnableProfiling = false;
3057*89c4ff92SAndroid Build Coastguard Worker     profilingService.ResetExternalProfilingOptions(options, true);
3058*89c4ff92SAndroid Build Coastguard Worker }
3059*89c4ff92SAndroid Build Coastguard Worker 
3060*89c4ff92SAndroid Build Coastguard Worker TEST_CASE("CheckProfilingServiceDisconnect")
3061*89c4ff92SAndroid Build Coastguard Worker {
3062*89c4ff92SAndroid Build Coastguard Worker     // Reset the profiling service to the uninitialized state
3063*89c4ff92SAndroid Build Coastguard Worker     ProfilingOptions options;
3064*89c4ff92SAndroid Build Coastguard Worker     options.m_EnableProfiling          = true;
3065*89c4ff92SAndroid Build Coastguard Worker     armnn::ArmNNProfilingServiceInitialiser initialiser;
3066*89c4ff92SAndroid Build Coastguard Worker     ProfilingService profilingService(arm::pipe::MAX_ARMNN_COUNTER,
3067*89c4ff92SAndroid Build Coastguard Worker                                       initialiser,
3068*89c4ff92SAndroid Build Coastguard Worker                                       arm::pipe::ARMNN_SOFTWARE_INFO,
3069*89c4ff92SAndroid Build Coastguard Worker                                       arm::pipe::ARMNN_SOFTWARE_VERSION,
3070*89c4ff92SAndroid Build Coastguard Worker                                       arm::pipe::ARMNN_HARDWARE_VERSION);
3071*89c4ff92SAndroid Build Coastguard Worker     profilingService.ResetExternalProfilingOptions(options, true);
3072*89c4ff92SAndroid Build Coastguard Worker 
3073*89c4ff92SAndroid Build Coastguard Worker     // Swap the profiling connection factory in the profiling service instance with our mock one
3074*89c4ff92SAndroid Build Coastguard Worker     SwapProfilingConnectionFactoryHelper helper(arm::pipe::MAX_ARMNN_COUNTER, initialiser, profilingService);
3075*89c4ff92SAndroid Build Coastguard Worker 
3076*89c4ff92SAndroid Build Coastguard Worker     // Try to disconnect the profiling service while in the "Uninitialised" state
3077*89c4ff92SAndroid Build Coastguard Worker     CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
3078*89c4ff92SAndroid Build Coastguard Worker     profilingService.Disconnect();
3079*89c4ff92SAndroid Build Coastguard Worker     CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);    // The state should not change
3080*89c4ff92SAndroid Build Coastguard Worker 
3081*89c4ff92SAndroid Build Coastguard Worker     // Try to disconnect the profiling service while in the "NotConnected" state
3082*89c4ff92SAndroid Build Coastguard Worker     profilingService.Update();    // Initialize the counter directory
3083*89c4ff92SAndroid Build Coastguard Worker     CHECK(profilingService.GetCurrentState() == ProfilingState::NotConnected);
3084*89c4ff92SAndroid Build Coastguard Worker     profilingService.Disconnect();
3085*89c4ff92SAndroid Build Coastguard Worker     CHECK(profilingService.GetCurrentState() == ProfilingState::NotConnected);    // The state should not change
3086*89c4ff92SAndroid Build Coastguard Worker 
3087*89c4ff92SAndroid Build Coastguard Worker     // Try to disconnect the profiling service while in the "WaitingForAck" state
3088*89c4ff92SAndroid Build Coastguard Worker     profilingService.Update();    // Create the profiling connection
3089*89c4ff92SAndroid Build Coastguard Worker     CHECK(profilingService.GetCurrentState() == ProfilingState::WaitingForAck);
3090*89c4ff92SAndroid Build Coastguard Worker     profilingService.Disconnect();
3091*89c4ff92SAndroid Build Coastguard Worker     CHECK(profilingService.GetCurrentState() == ProfilingState::WaitingForAck);    // The state should not change
3092*89c4ff92SAndroid Build Coastguard Worker 
3093*89c4ff92SAndroid Build Coastguard Worker     // Try to disconnect the profiling service while in the "Active" state
3094*89c4ff92SAndroid Build Coastguard Worker     profilingService.Update();    // Start the command handler and the send thread
3095*89c4ff92SAndroid Build Coastguard Worker 
3096*89c4ff92SAndroid Build Coastguard Worker     // Get the mock profiling connection
3097*89c4ff92SAndroid Build Coastguard Worker     MockProfilingConnection* mockProfilingConnection = helper.GetMockProfilingConnection();
3098*89c4ff92SAndroid Build Coastguard Worker     CHECK(mockProfilingConnection);
3099*89c4ff92SAndroid Build Coastguard Worker 
3100*89c4ff92SAndroid Build Coastguard Worker     // Wait for the Stream Metadata packet the be sent
3101*89c4ff92SAndroid Build Coastguard Worker     // (we are not testing the connection acknowledgement here so it will be ignored by this test)
3102*89c4ff92SAndroid Build Coastguard Worker     helper.WaitForPacketsSent(mockProfilingConnection, PacketType::StreamMetaData);
3103*89c4ff92SAndroid Build Coastguard Worker 
3104*89c4ff92SAndroid Build Coastguard Worker     // Force the profiling service to the "Active" state
3105*89c4ff92SAndroid Build Coastguard Worker     helper.ForceTransitionToState(ProfilingState::Active);
3106*89c4ff92SAndroid Build Coastguard Worker     CHECK(profilingService.GetCurrentState() == ProfilingState::Active);
3107*89c4ff92SAndroid Build Coastguard Worker 
3108*89c4ff92SAndroid Build Coastguard Worker     // Check that the profiling connection is open
3109*89c4ff92SAndroid Build Coastguard Worker     CHECK(mockProfilingConnection->IsOpen());
3110*89c4ff92SAndroid Build Coastguard Worker 
3111*89c4ff92SAndroid Build Coastguard Worker     profilingService.Disconnect();
3112*89c4ff92SAndroid Build Coastguard Worker     CHECK(profilingService.GetCurrentState() == ProfilingState::NotConnected);   // The state should have changed
3113*89c4ff92SAndroid Build Coastguard Worker 
3114*89c4ff92SAndroid Build Coastguard Worker     // Check that the profiling connection has been reset
3115*89c4ff92SAndroid Build Coastguard Worker     mockProfilingConnection = helper.GetMockProfilingConnection();
3116*89c4ff92SAndroid Build Coastguard Worker     CHECK(mockProfilingConnection == nullptr);
3117*89c4ff92SAndroid Build Coastguard Worker 
3118*89c4ff92SAndroid Build Coastguard Worker     // Reset the profiling service to stop any running thread
3119*89c4ff92SAndroid Build Coastguard Worker     options.m_EnableProfiling = false;
3120*89c4ff92SAndroid Build Coastguard Worker     profilingService.ResetExternalProfilingOptions(options, true);
3121*89c4ff92SAndroid Build Coastguard Worker }
3122*89c4ff92SAndroid Build Coastguard Worker 
3123*89c4ff92SAndroid Build Coastguard Worker TEST_CASE("CheckProfilingServiceGoodPerJobCounterSelectionPacket")
3124*89c4ff92SAndroid Build Coastguard Worker {
3125*89c4ff92SAndroid Build Coastguard Worker     // Reset the profiling service to the uninitialized state
3126*89c4ff92SAndroid Build Coastguard Worker     ProfilingOptions options;
3127*89c4ff92SAndroid Build Coastguard Worker     options.m_EnableProfiling          = true;
3128*89c4ff92SAndroid Build Coastguard Worker     armnn::ArmNNProfilingServiceInitialiser initialiser;
3129*89c4ff92SAndroid Build Coastguard Worker     ProfilingService profilingService(arm::pipe::MAX_ARMNN_COUNTER,
3130*89c4ff92SAndroid Build Coastguard Worker                                       initialiser,
3131*89c4ff92SAndroid Build Coastguard Worker                                       arm::pipe::ARMNN_SOFTWARE_INFO,
3132*89c4ff92SAndroid Build Coastguard Worker                                       arm::pipe::ARMNN_SOFTWARE_VERSION,
3133*89c4ff92SAndroid Build Coastguard Worker                                       arm::pipe::ARMNN_HARDWARE_VERSION);
3134*89c4ff92SAndroid Build Coastguard Worker     profilingService.ResetExternalProfilingOptions(options, true);
3135*89c4ff92SAndroid Build Coastguard Worker 
3136*89c4ff92SAndroid Build Coastguard Worker     // Swap the profiling connection factory in the profiling service instance with our mock one
3137*89c4ff92SAndroid Build Coastguard Worker     SwapProfilingConnectionFactoryHelper helper(arm::pipe::MAX_ARMNN_COUNTER, initialiser, profilingService);
3138*89c4ff92SAndroid Build Coastguard Worker 
3139*89c4ff92SAndroid Build Coastguard Worker     // Bring the profiling service to the "Active" state
3140*89c4ff92SAndroid Build Coastguard Worker     CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
3141*89c4ff92SAndroid Build Coastguard Worker     profilingService.Update();    // Initialize the counter directory
3142*89c4ff92SAndroid Build Coastguard Worker     CHECK(profilingService.GetCurrentState() == ProfilingState::NotConnected);
3143*89c4ff92SAndroid Build Coastguard Worker     profilingService.Update();    // Create the profiling connection
3144*89c4ff92SAndroid Build Coastguard Worker     CHECK(profilingService.GetCurrentState() == ProfilingState::WaitingForAck);
3145*89c4ff92SAndroid Build Coastguard Worker     profilingService.Update();    // Start the command handler and the send thread
3146*89c4ff92SAndroid Build Coastguard Worker 
3147*89c4ff92SAndroid Build Coastguard Worker     // Get the mock profiling connection
3148*89c4ff92SAndroid Build Coastguard Worker     MockProfilingConnection* mockProfilingConnection = helper.GetMockProfilingConnection();
3149*89c4ff92SAndroid Build Coastguard Worker     CHECK(mockProfilingConnection);
3150*89c4ff92SAndroid Build Coastguard Worker 
3151*89c4ff92SAndroid Build Coastguard Worker     // Wait for the Stream Metadata packet the be sent
3152*89c4ff92SAndroid Build Coastguard Worker     // (we are not testing the connection acknowledgement here so it will be ignored by this test)
3153*89c4ff92SAndroid Build Coastguard Worker     helper.WaitForPacketsSent(mockProfilingConnection, PacketType::StreamMetaData);
3154*89c4ff92SAndroid Build Coastguard Worker 
3155*89c4ff92SAndroid Build Coastguard Worker     // Force the profiling service to the "Active" state
3156*89c4ff92SAndroid Build Coastguard Worker     helper.ForceTransitionToState(ProfilingState::Active);
3157*89c4ff92SAndroid Build Coastguard Worker     CHECK(profilingService.GetCurrentState() == ProfilingState::Active);
3158*89c4ff92SAndroid Build Coastguard Worker 
3159*89c4ff92SAndroid Build Coastguard Worker     // Write a "Per-Job Counter Selection" packet into the mock profiling connection, to simulate an input from an
3160*89c4ff92SAndroid Build Coastguard Worker     // external profiling service
3161*89c4ff92SAndroid Build Coastguard Worker 
3162*89c4ff92SAndroid Build Coastguard Worker     // Per-Job Counter Selection packet header:
3163*89c4ff92SAndroid Build Coastguard Worker     // 26:31 [6]  packet_family: Control Packet Family, value 0b000000
3164*89c4ff92SAndroid Build Coastguard Worker     // 16:25 [10] packet_id: Packet identifier, value 0b0000000100
3165*89c4ff92SAndroid Build Coastguard Worker     // 8:15  [8]  reserved: Reserved, value 0b00000000
3166*89c4ff92SAndroid Build Coastguard Worker     // 0:7   [8]  reserved: Reserved, value 0b00000000
3167*89c4ff92SAndroid Build Coastguard Worker     uint32_t packetFamily = 0;
3168*89c4ff92SAndroid Build Coastguard Worker     uint32_t packetId     = 5;
3169*89c4ff92SAndroid Build Coastguard Worker     uint32_t header       = ((packetFamily & 0x0000003F) << 26) | ((packetId & 0x000003FF) << 16);
3170*89c4ff92SAndroid Build Coastguard Worker 
3171*89c4ff92SAndroid Build Coastguard Worker     // Create the Per-Job Counter Selection packet
3172*89c4ff92SAndroid Build Coastguard Worker     // Length == 0, this will disable the collection of counters
3173*89c4ff92SAndroid Build Coastguard Worker     arm::pipe::Packet periodicCounterSelectionPacket(header);
3174*89c4ff92SAndroid Build Coastguard Worker 
3175*89c4ff92SAndroid Build Coastguard Worker     // Write the packet to the mock profiling connection
3176*89c4ff92SAndroid Build Coastguard Worker     mockProfilingConnection->WritePacket(std::move(periodicCounterSelectionPacket));
3177*89c4ff92SAndroid Build Coastguard Worker 
3178*89c4ff92SAndroid Build Coastguard Worker     // Wait for a bit (must at least be the delay value of the mock profiling connection) to make sure that
3179*89c4ff92SAndroid Build Coastguard Worker     // the Per-Job Counter Selection packet gets processed by the profiling service
3180*89c4ff92SAndroid Build Coastguard Worker     std::this_thread::sleep_for(std::chrono::milliseconds(5));
3181*89c4ff92SAndroid Build Coastguard Worker 
3182*89c4ff92SAndroid Build Coastguard Worker     // The Per-Job Counter Selection Command Handler should not have updated the profiling state
3183*89c4ff92SAndroid Build Coastguard Worker     CHECK(profilingService.GetCurrentState() == ProfilingState::Active);
3184*89c4ff92SAndroid Build Coastguard Worker 
3185*89c4ff92SAndroid Build Coastguard Worker     // The Per-Job Counter Selection packets are dropped silently, so there should be no reply coming
3186*89c4ff92SAndroid Build Coastguard Worker     // from the profiling service
3187*89c4ff92SAndroid Build Coastguard Worker     const auto StreamMetaDataSize = static_cast<unsigned long>(
3188*89c4ff92SAndroid Build Coastguard Worker             helper.WaitForPacketsSent(mockProfilingConnection, PacketType::StreamMetaData, 0, 0));
3189*89c4ff92SAndroid Build Coastguard Worker     CHECK(StreamMetaDataSize == mockProfilingConnection->GetWrittenDataSize());
3190*89c4ff92SAndroid Build Coastguard Worker 
3191*89c4ff92SAndroid Build Coastguard Worker     // Reset the profiling service to stop any running thread
3192*89c4ff92SAndroid Build Coastguard Worker     options.m_EnableProfiling = false;
3193*89c4ff92SAndroid Build Coastguard Worker     profilingService.ResetExternalProfilingOptions(options, true);
3194*89c4ff92SAndroid Build Coastguard Worker }
3195*89c4ff92SAndroid Build Coastguard Worker 
3196*89c4ff92SAndroid Build Coastguard Worker TEST_CASE("CheckConfigureProfilingServiceOn")
3197*89c4ff92SAndroid Build Coastguard Worker {
3198*89c4ff92SAndroid Build Coastguard Worker     ProfilingOptions options;
3199*89c4ff92SAndroid Build Coastguard Worker     options.m_EnableProfiling          = true;
3200*89c4ff92SAndroid Build Coastguard Worker     armnn::ArmNNProfilingServiceInitialiser initialiser;
3201*89c4ff92SAndroid Build Coastguard Worker     ProfilingService profilingService(arm::pipe::MAX_ARMNN_COUNTER,
3202*89c4ff92SAndroid Build Coastguard Worker                                       initialiser,
3203*89c4ff92SAndroid Build Coastguard Worker                                       arm::pipe::ARMNN_SOFTWARE_INFO,
3204*89c4ff92SAndroid Build Coastguard Worker                                       arm::pipe::ARMNN_SOFTWARE_VERSION,
3205*89c4ff92SAndroid Build Coastguard Worker                                       arm::pipe::ARMNN_HARDWARE_VERSION);
3206*89c4ff92SAndroid Build Coastguard Worker     CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
3207*89c4ff92SAndroid Build Coastguard Worker     profilingService.ConfigureProfilingService(options);
3208*89c4ff92SAndroid Build Coastguard Worker     // should get as far as NOT_CONNECTED
3209*89c4ff92SAndroid Build Coastguard Worker     CHECK(profilingService.GetCurrentState() == ProfilingState::NotConnected);
3210*89c4ff92SAndroid Build Coastguard Worker     // Reset the profiling service to stop any running thread
3211*89c4ff92SAndroid Build Coastguard Worker     options.m_EnableProfiling = false;
3212*89c4ff92SAndroid Build Coastguard Worker     profilingService.ResetExternalProfilingOptions(options, true);
3213*89c4ff92SAndroid Build Coastguard Worker }
3214*89c4ff92SAndroid Build Coastguard Worker 
3215*89c4ff92SAndroid Build Coastguard Worker TEST_CASE("CheckConfigureProfilingServiceOff")
3216*89c4ff92SAndroid Build Coastguard Worker {
3217*89c4ff92SAndroid Build Coastguard Worker     ProfilingOptions options;
3218*89c4ff92SAndroid Build Coastguard Worker     armnn::ArmNNProfilingServiceInitialiser initialiser;
3219*89c4ff92SAndroid Build Coastguard Worker     ProfilingService profilingService(arm::pipe::MAX_ARMNN_COUNTER,
3220*89c4ff92SAndroid Build Coastguard Worker                                       initialiser,
3221*89c4ff92SAndroid Build Coastguard Worker                                       arm::pipe::ARMNN_SOFTWARE_INFO,
3222*89c4ff92SAndroid Build Coastguard Worker                                       arm::pipe::ARMNN_SOFTWARE_VERSION,
3223*89c4ff92SAndroid Build Coastguard Worker                                       arm::pipe::ARMNN_HARDWARE_VERSION);
3224*89c4ff92SAndroid Build Coastguard Worker     CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
3225*89c4ff92SAndroid Build Coastguard Worker     profilingService.ConfigureProfilingService(options);
3226*89c4ff92SAndroid Build Coastguard Worker     // should not move from Uninitialised
3227*89c4ff92SAndroid Build Coastguard Worker     CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
3228*89c4ff92SAndroid Build Coastguard Worker     // Reset the profiling service to stop any running thread
3229*89c4ff92SAndroid Build Coastguard Worker     options.m_EnableProfiling = false;
3230*89c4ff92SAndroid Build Coastguard Worker     profilingService.ResetExternalProfilingOptions(options, true);
3231*89c4ff92SAndroid Build Coastguard Worker }
3232*89c4ff92SAndroid Build Coastguard Worker 
3233*89c4ff92SAndroid Build Coastguard Worker TEST_CASE("CheckProfilingServiceEnabled")
3234*89c4ff92SAndroid Build Coastguard Worker {
3235*89c4ff92SAndroid Build Coastguard Worker     // Locally reduce log level to "Warning", as this test needs to parse a warning message from the standard output
3236*89c4ff92SAndroid Build Coastguard Worker     LogLevelSwapper logLevelSwapper(arm::pipe::LogSeverity::Warning);
3237*89c4ff92SAndroid Build Coastguard Worker 
3238*89c4ff92SAndroid Build Coastguard Worker     // Redirect the output to a local stream so that we can parse the warning message
3239*89c4ff92SAndroid Build Coastguard Worker     std::stringstream ss;
3240*89c4ff92SAndroid Build Coastguard Worker     StreamRedirector streamRedirector(std::cout, ss.rdbuf());
3241*89c4ff92SAndroid Build Coastguard Worker 
3242*89c4ff92SAndroid Build Coastguard Worker     ProfilingOptions options;
3243*89c4ff92SAndroid Build Coastguard Worker     options.m_EnableProfiling          = true;
3244*89c4ff92SAndroid Build Coastguard Worker     armnn::ArmNNProfilingServiceInitialiser initialiser;
3245*89c4ff92SAndroid Build Coastguard Worker     ProfilingService profilingService(arm::pipe::MAX_ARMNN_COUNTER,
3246*89c4ff92SAndroid Build Coastguard Worker                                       initialiser,
3247*89c4ff92SAndroid Build Coastguard Worker                                       arm::pipe::ARMNN_SOFTWARE_INFO,
3248*89c4ff92SAndroid Build Coastguard Worker                                       arm::pipe::ARMNN_SOFTWARE_VERSION,
3249*89c4ff92SAndroid Build Coastguard Worker                                       arm::pipe::ARMNN_HARDWARE_VERSION);
3250*89c4ff92SAndroid Build Coastguard Worker     profilingService.ResetExternalProfilingOptions(options, true);
3251*89c4ff92SAndroid Build Coastguard Worker     CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
3252*89c4ff92SAndroid Build Coastguard Worker     profilingService.Update();
3253*89c4ff92SAndroid Build Coastguard Worker     CHECK(profilingService.GetCurrentState() == ProfilingState::NotConnected);
3254*89c4ff92SAndroid Build Coastguard Worker 
3255*89c4ff92SAndroid Build Coastguard Worker     profilingService.Update();
3256*89c4ff92SAndroid Build Coastguard Worker 
3257*89c4ff92SAndroid Build Coastguard Worker     // Reset the profiling service to stop any running thread
3258*89c4ff92SAndroid Build Coastguard Worker     options.m_EnableProfiling = false;
3259*89c4ff92SAndroid Build Coastguard Worker     profilingService.ResetExternalProfilingOptions(options, true);
3260*89c4ff92SAndroid Build Coastguard Worker 
3261*89c4ff92SAndroid Build Coastguard Worker     streamRedirector.CancelRedirect();
3262*89c4ff92SAndroid Build Coastguard Worker 
3263*89c4ff92SAndroid Build Coastguard Worker     // Check that the expected error has occurred and logged to the standard output
3264*89c4ff92SAndroid Build Coastguard Worker     if (ss.str().find("Cannot connect to stream socket: Connection refused") == std::string::npos)
3265*89c4ff92SAndroid Build Coastguard Worker     {
3266*89c4ff92SAndroid Build Coastguard Worker         std::cout << ss.str();
3267*89c4ff92SAndroid Build Coastguard Worker         FAIL("Expected string not found.");
3268*89c4ff92SAndroid Build Coastguard Worker     }
3269*89c4ff92SAndroid Build Coastguard Worker }
3270*89c4ff92SAndroid Build Coastguard Worker 
3271*89c4ff92SAndroid Build Coastguard Worker TEST_CASE("CheckProfilingServiceEnabledRuntime")
3272*89c4ff92SAndroid Build Coastguard Worker {
3273*89c4ff92SAndroid Build Coastguard Worker     // Locally reduce log level to "Warning", as this test needs to parse a warning message from the standard output
3274*89c4ff92SAndroid Build Coastguard Worker     LogLevelSwapper logLevelSwapper(arm::pipe::LogSeverity::Warning);
3275*89c4ff92SAndroid Build Coastguard Worker 
3276*89c4ff92SAndroid Build Coastguard Worker     // Redirect the output to a local stream so that we can parse the warning message
3277*89c4ff92SAndroid Build Coastguard Worker     std::stringstream ss;
3278*89c4ff92SAndroid Build Coastguard Worker     StreamRedirector streamRedirector(std::cout, ss.rdbuf());
3279*89c4ff92SAndroid Build Coastguard Worker 
3280*89c4ff92SAndroid Build Coastguard Worker     ProfilingOptions options;
3281*89c4ff92SAndroid Build Coastguard Worker     armnn::ArmNNProfilingServiceInitialiser initialiser;
3282*89c4ff92SAndroid Build Coastguard Worker     ProfilingService profilingService(arm::pipe::MAX_ARMNN_COUNTER,
3283*89c4ff92SAndroid Build Coastguard Worker                                       initialiser,
3284*89c4ff92SAndroid Build Coastguard Worker                                       arm::pipe::ARMNN_SOFTWARE_INFO,
3285*89c4ff92SAndroid Build Coastguard Worker                                       arm::pipe::ARMNN_SOFTWARE_VERSION,
3286*89c4ff92SAndroid Build Coastguard Worker                                       arm::pipe::ARMNN_HARDWARE_VERSION);
3287*89c4ff92SAndroid Build Coastguard Worker     profilingService.ResetExternalProfilingOptions(options, true);
3288*89c4ff92SAndroid Build Coastguard Worker     CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
3289*89c4ff92SAndroid Build Coastguard Worker     profilingService.Update();
3290*89c4ff92SAndroid Build Coastguard Worker     CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
3291*89c4ff92SAndroid Build Coastguard Worker     options.m_EnableProfiling = true;
3292*89c4ff92SAndroid Build Coastguard Worker     profilingService.ResetExternalProfilingOptions(options);
3293*89c4ff92SAndroid Build Coastguard Worker     CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
3294*89c4ff92SAndroid Build Coastguard Worker     profilingService.Update();
3295*89c4ff92SAndroid Build Coastguard Worker     CHECK(profilingService.GetCurrentState() == ProfilingState::NotConnected);
3296*89c4ff92SAndroid Build Coastguard Worker 
3297*89c4ff92SAndroid Build Coastguard Worker     profilingService.Update();
3298*89c4ff92SAndroid Build Coastguard Worker 
3299*89c4ff92SAndroid Build Coastguard Worker     // Reset the profiling service to stop any running thread
3300*89c4ff92SAndroid Build Coastguard Worker     options.m_EnableProfiling = false;
3301*89c4ff92SAndroid Build Coastguard Worker     profilingService.ResetExternalProfilingOptions(options, true);
3302*89c4ff92SAndroid Build Coastguard Worker 
3303*89c4ff92SAndroid Build Coastguard Worker     streamRedirector.CancelRedirect();
3304*89c4ff92SAndroid Build Coastguard Worker 
3305*89c4ff92SAndroid Build Coastguard Worker     // Check that the expected error has occurred and logged to the standard output
3306*89c4ff92SAndroid Build Coastguard Worker     if (ss.str().find("Cannot connect to stream socket: Connection refused") == std::string::npos)
3307*89c4ff92SAndroid Build Coastguard Worker     {
3308*89c4ff92SAndroid Build Coastguard Worker         std::cout << ss.str();
3309*89c4ff92SAndroid Build Coastguard Worker         FAIL("Expected string not found.");
3310*89c4ff92SAndroid Build Coastguard Worker     }
3311*89c4ff92SAndroid Build Coastguard Worker }
3312*89c4ff92SAndroid Build Coastguard Worker 
3313*89c4ff92SAndroid Build Coastguard Worker TEST_CASE("CheckProfilingServiceBadConnectionAcknowledgedPacket")
3314*89c4ff92SAndroid Build Coastguard Worker {
3315*89c4ff92SAndroid Build Coastguard Worker     // Locally reduce log level to "Warning", as this test needs to parse a warning message from the standard output
3316*89c4ff92SAndroid Build Coastguard Worker     LogLevelSwapper logLevelSwapper(arm::pipe::LogSeverity::Warning);
3317*89c4ff92SAndroid Build Coastguard Worker 
3318*89c4ff92SAndroid Build Coastguard Worker     // Redirect the standard output to a local stream so that we can parse the warning message
3319*89c4ff92SAndroid Build Coastguard Worker     std::stringstream ss;
3320*89c4ff92SAndroid Build Coastguard Worker     StreamRedirector streamRedirector(std::cout, ss.rdbuf());
3321*89c4ff92SAndroid Build Coastguard Worker 
3322*89c4ff92SAndroid Build Coastguard Worker     // Reset the profiling service to the uninitialized state
3323*89c4ff92SAndroid Build Coastguard Worker     ProfilingOptions options;
3324*89c4ff92SAndroid Build Coastguard Worker     options.m_EnableProfiling          = true;
3325*89c4ff92SAndroid Build Coastguard Worker     armnn::ArmNNProfilingServiceInitialiser initialiser;
3326*89c4ff92SAndroid Build Coastguard Worker     ProfilingService profilingService(arm::pipe::MAX_ARMNN_COUNTER,
3327*89c4ff92SAndroid Build Coastguard Worker                                       initialiser,
3328*89c4ff92SAndroid Build Coastguard Worker                                       arm::pipe::ARMNN_SOFTWARE_INFO,
3329*89c4ff92SAndroid Build Coastguard Worker                                       arm::pipe::ARMNN_SOFTWARE_VERSION,
3330*89c4ff92SAndroid Build Coastguard Worker                                       arm::pipe::ARMNN_HARDWARE_VERSION);
3331*89c4ff92SAndroid Build Coastguard Worker     profilingService.ResetExternalProfilingOptions(options, true);
3332*89c4ff92SAndroid Build Coastguard Worker 
3333*89c4ff92SAndroid Build Coastguard Worker     // Swap the profiling connection factory in the profiling service instance with our mock one
3334*89c4ff92SAndroid Build Coastguard Worker     SwapProfilingConnectionFactoryHelper helper(arm::pipe::MAX_ARMNN_COUNTER, initialiser, profilingService);
3335*89c4ff92SAndroid Build Coastguard Worker 
3336*89c4ff92SAndroid Build Coastguard Worker     // Bring the profiling service to the "WaitingForAck" state
3337*89c4ff92SAndroid Build Coastguard Worker     CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
3338*89c4ff92SAndroid Build Coastguard Worker     profilingService.Update();    // Initialize the counter directory
3339*89c4ff92SAndroid Build Coastguard Worker     CHECK(profilingService.GetCurrentState() == ProfilingState::NotConnected);
3340*89c4ff92SAndroid Build Coastguard Worker     profilingService.Update();    // Create the profiling connection
3341*89c4ff92SAndroid Build Coastguard Worker 
3342*89c4ff92SAndroid Build Coastguard Worker     // Get the mock profiling connection
3343*89c4ff92SAndroid Build Coastguard Worker     MockProfilingConnection* mockProfilingConnection = helper.GetMockProfilingConnection();
3344*89c4ff92SAndroid Build Coastguard Worker     CHECK(mockProfilingConnection);
3345*89c4ff92SAndroid Build Coastguard Worker 
3346*89c4ff92SAndroid Build Coastguard Worker     CHECK(profilingService.GetCurrentState() == ProfilingState::WaitingForAck);
3347*89c4ff92SAndroid Build Coastguard Worker 
3348*89c4ff92SAndroid Build Coastguard Worker     // Connection Acknowledged Packet header (word 0, word 1 is always zero):
3349*89c4ff92SAndroid Build Coastguard Worker     // 26:31 [6]  packet_family: Control Packet Family, value 0b000000
3350*89c4ff92SAndroid Build Coastguard Worker     // 16:25 [10] packet_id: Packet identifier, value 0b0000000001
3351*89c4ff92SAndroid Build Coastguard Worker     // 8:15  [8]  reserved: Reserved, value 0b00000000
3352*89c4ff92SAndroid Build Coastguard Worker     // 0:7   [8]  reserved: Reserved, value 0b00000000
3353*89c4ff92SAndroid Build Coastguard Worker     uint32_t packetFamily = 0;
3354*89c4ff92SAndroid Build Coastguard Worker     uint32_t packetId     = 37;    // Wrong packet id!!!
3355*89c4ff92SAndroid Build Coastguard Worker     uint32_t header       = ((packetFamily & 0x0000003F) << 26) | ((packetId & 0x000003FF) << 16);
3356*89c4ff92SAndroid Build Coastguard Worker 
3357*89c4ff92SAndroid Build Coastguard Worker     // Create the Connection Acknowledged Packet
3358*89c4ff92SAndroid Build Coastguard Worker     arm::pipe::Packet connectionAcknowledgedPacket(header);
3359*89c4ff92SAndroid Build Coastguard Worker     // Write an invalid "Connection Acknowledged" packet into the mock profiling connection, to simulate an invalid
3360*89c4ff92SAndroid Build Coastguard Worker     // reply from an external profiling service
3361*89c4ff92SAndroid Build Coastguard Worker     mockProfilingConnection->WritePacket(std::move(connectionAcknowledgedPacket));
3362*89c4ff92SAndroid Build Coastguard Worker 
3363*89c4ff92SAndroid Build Coastguard Worker     // Start the command thread
3364*89c4ff92SAndroid Build Coastguard Worker     profilingService.Update();
3365*89c4ff92SAndroid Build Coastguard Worker 
3366*89c4ff92SAndroid Build Coastguard Worker     // Wait for the command thread to join
3367*89c4ff92SAndroid Build Coastguard Worker     options.m_EnableProfiling = false;
3368*89c4ff92SAndroid Build Coastguard Worker     profilingService.ResetExternalProfilingOptions(options, true);
3369*89c4ff92SAndroid Build Coastguard Worker 
3370*89c4ff92SAndroid Build Coastguard Worker     streamRedirector.CancelRedirect();
3371*89c4ff92SAndroid Build Coastguard Worker 
3372*89c4ff92SAndroid Build Coastguard Worker     // Check that the expected error has occurred and logged to the standard output
3373*89c4ff92SAndroid Build Coastguard Worker     if (ss.str().find("Functor with requested PacketId=37 and Version=4194304 does not exist") == std::string::npos)
3374*89c4ff92SAndroid Build Coastguard Worker     {
3375*89c4ff92SAndroid Build Coastguard Worker         std::cout << ss.str();
3376*89c4ff92SAndroid Build Coastguard Worker         FAIL("Expected string not found.");
3377*89c4ff92SAndroid Build Coastguard Worker     }
3378*89c4ff92SAndroid Build Coastguard Worker }
3379*89c4ff92SAndroid Build Coastguard Worker 
3380*89c4ff92SAndroid Build Coastguard Worker TEST_CASE("CheckProfilingServiceBadRequestCounterDirectoryPacket")
3381*89c4ff92SAndroid Build Coastguard Worker {
3382*89c4ff92SAndroid Build Coastguard Worker     // Locally reduce log level to "Warning", as this test needs to parse a warning message from the standard output
3383*89c4ff92SAndroid Build Coastguard Worker     LogLevelSwapper logLevelSwapper(arm::pipe::LogSeverity::Warning);
3384*89c4ff92SAndroid Build Coastguard Worker 
3385*89c4ff92SAndroid Build Coastguard Worker     // Redirect the standard output to a local stream so that we can parse the warning message
3386*89c4ff92SAndroid Build Coastguard Worker     std::stringstream ss;
3387*89c4ff92SAndroid Build Coastguard Worker     StreamRedirector streamRedirector(std::cout, ss.rdbuf());
3388*89c4ff92SAndroid Build Coastguard Worker 
3389*89c4ff92SAndroid Build Coastguard Worker     // Reset the profiling service to the uninitialized state
3390*89c4ff92SAndroid Build Coastguard Worker     ProfilingOptions options;
3391*89c4ff92SAndroid Build Coastguard Worker     options.m_EnableProfiling          = true;
3392*89c4ff92SAndroid Build Coastguard Worker     armnn::ArmNNProfilingServiceInitialiser initialiser;
3393*89c4ff92SAndroid Build Coastguard Worker     ProfilingService profilingService(arm::pipe::MAX_ARMNN_COUNTER,
3394*89c4ff92SAndroid Build Coastguard Worker                                       initialiser,
3395*89c4ff92SAndroid Build Coastguard Worker                                       arm::pipe::ARMNN_SOFTWARE_INFO,
3396*89c4ff92SAndroid Build Coastguard Worker                                       arm::pipe::ARMNN_SOFTWARE_VERSION,
3397*89c4ff92SAndroid Build Coastguard Worker                                       arm::pipe::ARMNN_HARDWARE_VERSION);
3398*89c4ff92SAndroid Build Coastguard Worker     profilingService.ResetExternalProfilingOptions(options, true);
3399*89c4ff92SAndroid Build Coastguard Worker 
3400*89c4ff92SAndroid Build Coastguard Worker     // Swap the profiling connection factory in the profiling service instance with our mock one
3401*89c4ff92SAndroid Build Coastguard Worker     SwapProfilingConnectionFactoryHelper helper(arm::pipe::MAX_ARMNN_COUNTER, initialiser, profilingService);
3402*89c4ff92SAndroid Build Coastguard Worker 
3403*89c4ff92SAndroid Build Coastguard Worker     // Bring the profiling service to the "Active" state
3404*89c4ff92SAndroid Build Coastguard Worker     CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
3405*89c4ff92SAndroid Build Coastguard Worker     helper.ForceTransitionToState(ProfilingState::NotConnected);
3406*89c4ff92SAndroid Build Coastguard Worker     CHECK(profilingService.GetCurrentState() == ProfilingState::NotConnected);
3407*89c4ff92SAndroid Build Coastguard Worker     profilingService.Update();    // Create the profiling connection
3408*89c4ff92SAndroid Build Coastguard Worker     CHECK(profilingService.GetCurrentState() == ProfilingState::WaitingForAck);
3409*89c4ff92SAndroid Build Coastguard Worker 
3410*89c4ff92SAndroid Build Coastguard Worker     // Get the mock profiling connection
3411*89c4ff92SAndroid Build Coastguard Worker     MockProfilingConnection* mockProfilingConnection = helper.GetMockProfilingConnection();
3412*89c4ff92SAndroid Build Coastguard Worker     CHECK(mockProfilingConnection);
3413*89c4ff92SAndroid Build Coastguard Worker 
3414*89c4ff92SAndroid Build Coastguard Worker     // Write a valid "Request Counter Directory" packet into the mock profiling connection, to simulate a valid
3415*89c4ff92SAndroid Build Coastguard Worker     // reply from an external profiling service
3416*89c4ff92SAndroid Build Coastguard Worker 
3417*89c4ff92SAndroid Build Coastguard Worker     // Request Counter Directory packet header (word 0, word 1 is always zero):
3418*89c4ff92SAndroid Build Coastguard Worker     // 26:31 [6]  packet_family: Control Packet Family, value 0b000000
3419*89c4ff92SAndroid Build Coastguard Worker     // 16:25 [10] packet_id: Packet identifier, value 0b0000000011
3420*89c4ff92SAndroid Build Coastguard Worker     // 8:15  [8]  reserved: Reserved, value 0b00000000
3421*89c4ff92SAndroid Build Coastguard Worker     // 0:7   [8]  reserved: Reserved, value 0b00000000
3422*89c4ff92SAndroid Build Coastguard Worker     uint32_t packetFamily = 0;
3423*89c4ff92SAndroid Build Coastguard Worker     uint32_t packetId     = 123;    // Wrong packet id!!!
3424*89c4ff92SAndroid Build Coastguard Worker     uint32_t header       = ((packetFamily & 0x0000003F) << 26) | ((packetId & 0x000003FF) << 16);
3425*89c4ff92SAndroid Build Coastguard Worker 
3426*89c4ff92SAndroid Build Coastguard Worker     // Create the Request Counter Directory packet
3427*89c4ff92SAndroid Build Coastguard Worker     arm::pipe::Packet requestCounterDirectoryPacket(header);
3428*89c4ff92SAndroid Build Coastguard Worker 
3429*89c4ff92SAndroid Build Coastguard Worker     // Write the packet to the mock profiling connection
3430*89c4ff92SAndroid Build Coastguard Worker     mockProfilingConnection->WritePacket(std::move(requestCounterDirectoryPacket));
3431*89c4ff92SAndroid Build Coastguard Worker 
3432*89c4ff92SAndroid Build Coastguard Worker     // Start the command handler and the send thread
3433*89c4ff92SAndroid Build Coastguard Worker     profilingService.Update();
3434*89c4ff92SAndroid Build Coastguard Worker 
3435*89c4ff92SAndroid Build Coastguard Worker     // Reset the profiling service to stop and join any running thread
3436*89c4ff92SAndroid Build Coastguard Worker     options.m_EnableProfiling = false;
3437*89c4ff92SAndroid Build Coastguard Worker     profilingService.ResetExternalProfilingOptions(options, true);
3438*89c4ff92SAndroid Build Coastguard Worker 
3439*89c4ff92SAndroid Build Coastguard Worker     streamRedirector.CancelRedirect();
3440*89c4ff92SAndroid Build Coastguard Worker 
3441*89c4ff92SAndroid Build Coastguard Worker     // Check that the expected error has occurred and logged to the standard output
3442*89c4ff92SAndroid Build Coastguard Worker     if (ss.str().find("Functor with requested PacketId=123 and Version=4194304 does not exist") == std::string::npos)
3443*89c4ff92SAndroid Build Coastguard Worker     {
3444*89c4ff92SAndroid Build Coastguard Worker         std::cout << ss.str();
3445*89c4ff92SAndroid Build Coastguard Worker         FAIL("Expected string not found.");
3446*89c4ff92SAndroid Build Coastguard Worker     }
3447*89c4ff92SAndroid Build Coastguard Worker }
3448*89c4ff92SAndroid Build Coastguard Worker 
3449*89c4ff92SAndroid Build Coastguard Worker TEST_CASE("CheckProfilingServiceBadPeriodicCounterSelectionPacket")
3450*89c4ff92SAndroid Build Coastguard Worker {
3451*89c4ff92SAndroid Build Coastguard Worker     // Locally reduce log level to "Warning", as this test needs to parse a warning message from the standard output
3452*89c4ff92SAndroid Build Coastguard Worker     LogLevelSwapper logLevelSwapper(arm::pipe::LogSeverity::Warning);
3453*89c4ff92SAndroid Build Coastguard Worker 
3454*89c4ff92SAndroid Build Coastguard Worker     // Redirect the standard output to a local stream so that we can parse the warning message
3455*89c4ff92SAndroid Build Coastguard Worker     std::stringstream ss;
3456*89c4ff92SAndroid Build Coastguard Worker     StreamRedirector streamRedirector(std::cout, ss.rdbuf());
3457*89c4ff92SAndroid Build Coastguard Worker 
3458*89c4ff92SAndroid Build Coastguard Worker     // Reset the profiling service to the uninitialized state
3459*89c4ff92SAndroid Build Coastguard Worker     ProfilingOptions options;
3460*89c4ff92SAndroid Build Coastguard Worker     options.m_EnableProfiling          = true;
3461*89c4ff92SAndroid Build Coastguard Worker     armnn::ArmNNProfilingServiceInitialiser initialiser;
3462*89c4ff92SAndroid Build Coastguard Worker     ProfilingService profilingService(arm::pipe::MAX_ARMNN_COUNTER,
3463*89c4ff92SAndroid Build Coastguard Worker                                       initialiser,
3464*89c4ff92SAndroid Build Coastguard Worker                                       arm::pipe::ARMNN_SOFTWARE_INFO,
3465*89c4ff92SAndroid Build Coastguard Worker                                       arm::pipe::ARMNN_SOFTWARE_VERSION,
3466*89c4ff92SAndroid Build Coastguard Worker                                       arm::pipe::ARMNN_HARDWARE_VERSION);
3467*89c4ff92SAndroid Build Coastguard Worker     profilingService.ResetExternalProfilingOptions(options, true);
3468*89c4ff92SAndroid Build Coastguard Worker 
3469*89c4ff92SAndroid Build Coastguard Worker     // Swap the profiling connection factory in the profiling service instance with our mock one
3470*89c4ff92SAndroid Build Coastguard Worker     SwapProfilingConnectionFactoryHelper helper(arm::pipe::MAX_ARMNN_COUNTER, initialiser, profilingService);
3471*89c4ff92SAndroid Build Coastguard Worker 
3472*89c4ff92SAndroid Build Coastguard Worker     // Bring the profiling service to the "Active" state
3473*89c4ff92SAndroid Build Coastguard Worker     CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
3474*89c4ff92SAndroid Build Coastguard Worker     profilingService.Update();    // Initialize the counter directory
3475*89c4ff92SAndroid Build Coastguard Worker     CHECK(profilingService.GetCurrentState() == ProfilingState::NotConnected);
3476*89c4ff92SAndroid Build Coastguard Worker     profilingService.Update();    // Create the profiling connection
3477*89c4ff92SAndroid Build Coastguard Worker     CHECK(profilingService.GetCurrentState() == ProfilingState::WaitingForAck);
3478*89c4ff92SAndroid Build Coastguard Worker     profilingService.Update();    // Start the command handler and the send thread
3479*89c4ff92SAndroid Build Coastguard Worker 
3480*89c4ff92SAndroid Build Coastguard Worker     // Get the mock profiling connection
3481*89c4ff92SAndroid Build Coastguard Worker     MockProfilingConnection* mockProfilingConnection = helper.GetMockProfilingConnection();
3482*89c4ff92SAndroid Build Coastguard Worker     CHECK(mockProfilingConnection);
3483*89c4ff92SAndroid Build Coastguard Worker 
3484*89c4ff92SAndroid Build Coastguard Worker     // Write a "Periodic Counter Selection" packet into the mock profiling connection, to simulate an input from an
3485*89c4ff92SAndroid Build Coastguard Worker     // external profiling service
3486*89c4ff92SAndroid Build Coastguard Worker 
3487*89c4ff92SAndroid Build Coastguard Worker     // Periodic Counter Selection packet header:
3488*89c4ff92SAndroid Build Coastguard Worker     // 26:31 [6]  packet_family: Control Packet Family, value 0b000000
3489*89c4ff92SAndroid Build Coastguard Worker     // 16:25 [10] packet_id: Packet identifier, value 0b0000000100
3490*89c4ff92SAndroid Build Coastguard Worker     // 8:15  [8]  reserved: Reserved, value 0b00000000
3491*89c4ff92SAndroid Build Coastguard Worker     // 0:7   [8]  reserved: Reserved, value 0b00000000
3492*89c4ff92SAndroid Build Coastguard Worker     uint32_t packetFamily = 0;
3493*89c4ff92SAndroid Build Coastguard Worker     uint32_t packetId     = 999;    // Wrong packet id!!!
3494*89c4ff92SAndroid Build Coastguard Worker     uint32_t header       = ((packetFamily & 0x0000003F) << 26) | ((packetId & 0x000003FF) << 16);
3495*89c4ff92SAndroid Build Coastguard Worker 
3496*89c4ff92SAndroid Build Coastguard Worker     // Create the Periodic Counter Selection packet
3497*89c4ff92SAndroid Build Coastguard Worker     // Length == 0, this will disable the collection of counters
3498*89c4ff92SAndroid Build Coastguard Worker     arm::pipe::Packet periodicCounterSelectionPacket(header);
3499*89c4ff92SAndroid Build Coastguard Worker 
3500*89c4ff92SAndroid Build Coastguard Worker     // Write the packet to the mock profiling connection
3501*89c4ff92SAndroid Build Coastguard Worker     mockProfilingConnection->WritePacket(std::move(periodicCounterSelectionPacket));
3502*89c4ff92SAndroid Build Coastguard Worker     profilingService.Update();
3503*89c4ff92SAndroid Build Coastguard Worker 
3504*89c4ff92SAndroid Build Coastguard Worker     // Reset the profiling service to stop any running thread
3505*89c4ff92SAndroid Build Coastguard Worker     options.m_EnableProfiling = false;
3506*89c4ff92SAndroid Build Coastguard Worker     profilingService.ResetExternalProfilingOptions(options, true);
3507*89c4ff92SAndroid Build Coastguard Worker 
3508*89c4ff92SAndroid Build Coastguard Worker     // Check that the expected error has occurred and logged to the standard output
3509*89c4ff92SAndroid Build Coastguard Worker     streamRedirector.CancelRedirect();
3510*89c4ff92SAndroid Build Coastguard Worker 
3511*89c4ff92SAndroid Build Coastguard Worker     // Check that the expected error has occurred and logged to the standard output
3512*89c4ff92SAndroid Build Coastguard Worker     if (ss.str().find("Functor with requested PacketId=999 and Version=4194304 does not exist") == std::string::npos)
3513*89c4ff92SAndroid Build Coastguard Worker     {
3514*89c4ff92SAndroid Build Coastguard Worker         std::cout << ss.str();
3515*89c4ff92SAndroid Build Coastguard Worker         FAIL("Expected string not found.");
3516*89c4ff92SAndroid Build Coastguard Worker     }
3517*89c4ff92SAndroid Build Coastguard Worker }
3518*89c4ff92SAndroid Build Coastguard Worker 
3519*89c4ff92SAndroid Build Coastguard Worker TEST_CASE("CheckCounterIdMap")
3520*89c4ff92SAndroid Build Coastguard Worker {
3521*89c4ff92SAndroid Build Coastguard Worker     CounterIdMap counterIdMap;
3522*89c4ff92SAndroid Build Coastguard Worker     CHECK_THROWS_AS(counterIdMap.GetBackendId(0), arm::pipe::ProfilingException);
3523*89c4ff92SAndroid Build Coastguard Worker     CHECK_THROWS_AS(counterIdMap.GetGlobalId(0, armnn::profiling::BACKEND_ID), arm::pipe::ProfilingException);
3524*89c4ff92SAndroid Build Coastguard Worker 
3525*89c4ff92SAndroid Build Coastguard Worker     uint16_t globalCounterIds = 0;
3526*89c4ff92SAndroid Build Coastguard Worker 
3527*89c4ff92SAndroid Build Coastguard Worker     std::string cpuRefId(GetComputeDeviceAsCString(armnn::Compute::CpuRef));
3528*89c4ff92SAndroid Build Coastguard Worker     std::string cpuAccId(GetComputeDeviceAsCString(armnn::Compute::CpuAcc));
3529*89c4ff92SAndroid Build Coastguard Worker 
3530*89c4ff92SAndroid Build Coastguard Worker     std::vector<uint16_t> cpuRefCounters = {0, 1, 2, 3};
3531*89c4ff92SAndroid Build Coastguard Worker     std::vector<uint16_t> cpuAccCounters = {0, 1};
3532*89c4ff92SAndroid Build Coastguard Worker 
3533*89c4ff92SAndroid Build Coastguard Worker     for (uint16_t backendCounterId : cpuRefCounters)
3534*89c4ff92SAndroid Build Coastguard Worker     {
3535*89c4ff92SAndroid Build Coastguard Worker         counterIdMap.RegisterMapping(globalCounterIds, backendCounterId, cpuRefId);
3536*89c4ff92SAndroid Build Coastguard Worker         ++globalCounterIds;
3537*89c4ff92SAndroid Build Coastguard Worker     }
3538*89c4ff92SAndroid Build Coastguard Worker     for (uint16_t backendCounterId : cpuAccCounters)
3539*89c4ff92SAndroid Build Coastguard Worker     {
3540*89c4ff92SAndroid Build Coastguard Worker         counterIdMap.RegisterMapping(globalCounterIds, backendCounterId, cpuAccId);
3541*89c4ff92SAndroid Build Coastguard Worker         ++globalCounterIds;
3542*89c4ff92SAndroid Build Coastguard Worker     }
3543*89c4ff92SAndroid Build Coastguard Worker 
3544*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterIdMap.GetBackendId(0) == (std::pair<uint16_t, std::string>(0, cpuRefId)));
3545*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterIdMap.GetBackendId(1) == (std::pair<uint16_t, std::string>(1, cpuRefId)));
3546*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterIdMap.GetBackendId(2) == (std::pair<uint16_t, std::string>(2, cpuRefId)));
3547*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterIdMap.GetBackendId(3) == (std::pair<uint16_t, std::string>(3, cpuRefId)));
3548*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterIdMap.GetBackendId(4) == (std::pair<uint16_t, std::string>(0, cpuAccId)));
3549*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterIdMap.GetBackendId(5) == (std::pair<uint16_t, std::string>(1, cpuAccId)));
3550*89c4ff92SAndroid Build Coastguard Worker 
3551*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterIdMap.GetGlobalId(0, cpuRefId) == 0);
3552*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterIdMap.GetGlobalId(1, cpuRefId) == 1);
3553*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterIdMap.GetGlobalId(2, cpuRefId) == 2);
3554*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterIdMap.GetGlobalId(3, cpuRefId) == 3);
3555*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterIdMap.GetGlobalId(0, cpuAccId) == 4);
3556*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterIdMap.GetGlobalId(1, cpuAccId) == 5);
3557*89c4ff92SAndroid Build Coastguard Worker }
3558*89c4ff92SAndroid Build Coastguard Worker 
3559*89c4ff92SAndroid Build Coastguard Worker TEST_CASE("CheckRegisterBackendCounters")
3560*89c4ff92SAndroid Build Coastguard Worker {
3561*89c4ff92SAndroid Build Coastguard Worker     uint16_t globalCounterIds = INFERENCES_RUN;
3562*89c4ff92SAndroid Build Coastguard Worker     std::string cpuRefId(GetComputeDeviceAsCString(armnn::Compute::CpuRef));
3563*89c4ff92SAndroid Build Coastguard Worker 
3564*89c4ff92SAndroid Build Coastguard Worker     // Reset the profiling service to the uninitialized state
3565*89c4ff92SAndroid Build Coastguard Worker     ProfilingOptions options;
3566*89c4ff92SAndroid Build Coastguard Worker     options.m_EnableProfiling          = true;
3567*89c4ff92SAndroid Build Coastguard Worker     armnn::ArmNNProfilingServiceInitialiser initialiser;
3568*89c4ff92SAndroid Build Coastguard Worker     ProfilingService profilingService(arm::pipe::MAX_ARMNN_COUNTER,
3569*89c4ff92SAndroid Build Coastguard Worker                                       initialiser,
3570*89c4ff92SAndroid Build Coastguard Worker                                       arm::pipe::ARMNN_SOFTWARE_INFO,
3571*89c4ff92SAndroid Build Coastguard Worker                                       arm::pipe::ARMNN_SOFTWARE_VERSION,
3572*89c4ff92SAndroid Build Coastguard Worker                                       arm::pipe::ARMNN_HARDWARE_VERSION);
3573*89c4ff92SAndroid Build Coastguard Worker     profilingService.ResetExternalProfilingOptions(options, true);
3574*89c4ff92SAndroid Build Coastguard Worker 
3575*89c4ff92SAndroid Build Coastguard Worker     RegisterBackendCounters registerBackendCounters(globalCounterIds, cpuRefId, profilingService);
3576*89c4ff92SAndroid Build Coastguard Worker 
3577*89c4ff92SAndroid Build Coastguard Worker 
3578*89c4ff92SAndroid Build Coastguard Worker 
3579*89c4ff92SAndroid Build Coastguard Worker     CHECK(profilingService.GetCounterDirectory().GetCategories().empty());
3580*89c4ff92SAndroid Build Coastguard Worker     registerBackendCounters.RegisterCategory("categoryOne");
3581*89c4ff92SAndroid Build Coastguard Worker     auto categoryOnePtr = profilingService.GetCounterDirectory().GetCategory("categoryOne");
3582*89c4ff92SAndroid Build Coastguard Worker     CHECK(categoryOnePtr);
3583*89c4ff92SAndroid Build Coastguard Worker 
3584*89c4ff92SAndroid Build Coastguard Worker     CHECK(profilingService.GetCounterDirectory().GetDevices().empty());
3585*89c4ff92SAndroid Build Coastguard Worker     globalCounterIds = registerBackendCounters.RegisterDevice("deviceOne");
3586*89c4ff92SAndroid Build Coastguard Worker     auto deviceOnePtr = profilingService.GetCounterDirectory().GetDevice(globalCounterIds);
3587*89c4ff92SAndroid Build Coastguard Worker     CHECK(deviceOnePtr);
3588*89c4ff92SAndroid Build Coastguard Worker     CHECK(deviceOnePtr->m_Name == "deviceOne");
3589*89c4ff92SAndroid Build Coastguard Worker 
3590*89c4ff92SAndroid Build Coastguard Worker     CHECK(profilingService.GetCounterDirectory().GetCounterSets().empty());
3591*89c4ff92SAndroid Build Coastguard Worker     globalCounterIds = registerBackendCounters.RegisterCounterSet("counterSetOne");
3592*89c4ff92SAndroid Build Coastguard Worker     auto counterSetOnePtr = profilingService.GetCounterDirectory().GetCounterSet(globalCounterIds);
3593*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterSetOnePtr);
3594*89c4ff92SAndroid Build Coastguard Worker     CHECK(counterSetOnePtr->m_Name == "counterSetOne");
3595*89c4ff92SAndroid Build Coastguard Worker 
3596*89c4ff92SAndroid Build Coastguard Worker     uint16_t newGlobalCounterId = registerBackendCounters.RegisterCounter(0,
3597*89c4ff92SAndroid Build Coastguard Worker                                                                           "categoryOne",
3598*89c4ff92SAndroid Build Coastguard Worker                                                                           0,
3599*89c4ff92SAndroid Build Coastguard Worker                                                                           0,
3600*89c4ff92SAndroid Build Coastguard Worker                                                                           1.f,
3601*89c4ff92SAndroid Build Coastguard Worker                                                                           "CounterOne",
3602*89c4ff92SAndroid Build Coastguard Worker                                                                           "first test counter");
3603*89c4ff92SAndroid Build Coastguard Worker     CHECK((newGlobalCounterId = INFERENCES_RUN + 1));
3604*89c4ff92SAndroid Build Coastguard Worker     uint16_t mappedGlobalId = profilingService.GetCounterMappings().GetGlobalId(0, cpuRefId);
3605*89c4ff92SAndroid Build Coastguard Worker     CHECK(mappedGlobalId == newGlobalCounterId);
3606*89c4ff92SAndroid Build Coastguard Worker     auto backendMapping = profilingService.GetCounterMappings().GetBackendId(newGlobalCounterId);
3607*89c4ff92SAndroid Build Coastguard Worker     CHECK(backendMapping.first == 0);
3608*89c4ff92SAndroid Build Coastguard Worker     CHECK(backendMapping.second == cpuRefId);
3609*89c4ff92SAndroid Build Coastguard Worker 
3610*89c4ff92SAndroid Build Coastguard Worker     // Reset the profiling service to stop any running thread
3611*89c4ff92SAndroid Build Coastguard Worker     options.m_EnableProfiling = false;
3612*89c4ff92SAndroid Build Coastguard Worker     profilingService.ResetExternalProfilingOptions(options, true);
3613*89c4ff92SAndroid Build Coastguard Worker }
3614*89c4ff92SAndroid Build Coastguard Worker 
3615*89c4ff92SAndroid Build Coastguard Worker TEST_CASE("CheckCounterStatusQuery")
3616*89c4ff92SAndroid Build Coastguard Worker {
3617*89c4ff92SAndroid Build Coastguard Worker     ProfilingOptions options;
3618*89c4ff92SAndroid Build Coastguard Worker     options.m_EnableProfiling = true;
3619*89c4ff92SAndroid Build Coastguard Worker 
3620*89c4ff92SAndroid Build Coastguard Worker     // Reset the profiling service to the uninitialized state
3621*89c4ff92SAndroid Build Coastguard Worker     armnn::ArmNNProfilingServiceInitialiser initialiser;
3622*89c4ff92SAndroid Build Coastguard Worker     ProfilingService profilingService(arm::pipe::MAX_ARMNN_COUNTER,
3623*89c4ff92SAndroid Build Coastguard Worker                                       initialiser,
3624*89c4ff92SAndroid Build Coastguard Worker                                       arm::pipe::ARMNN_SOFTWARE_INFO,
3625*89c4ff92SAndroid Build Coastguard Worker                                       arm::pipe::ARMNN_SOFTWARE_VERSION,
3626*89c4ff92SAndroid Build Coastguard Worker                                       arm::pipe::ARMNN_HARDWARE_VERSION);
3627*89c4ff92SAndroid Build Coastguard Worker     profilingService.ResetExternalProfilingOptions(options, true);
3628*89c4ff92SAndroid Build Coastguard Worker 
3629*89c4ff92SAndroid Build Coastguard Worker     const std::string cpuRefId(GetComputeDeviceAsCString(armnn::Compute::CpuRef));
3630*89c4ff92SAndroid Build Coastguard Worker     const std::string cpuAccId(GetComputeDeviceAsCString(armnn::Compute::CpuAcc));
3631*89c4ff92SAndroid Build Coastguard Worker 
3632*89c4ff92SAndroid Build Coastguard Worker     // Create BackendProfiling for each backend
3633*89c4ff92SAndroid Build Coastguard Worker     BackendProfiling backendProfilingCpuRef(options, profilingService, cpuRefId);
3634*89c4ff92SAndroid Build Coastguard Worker     BackendProfiling backendProfilingCpuAcc(options, profilingService, cpuAccId);
3635*89c4ff92SAndroid Build Coastguard Worker 
3636*89c4ff92SAndroid Build Coastguard Worker     uint16_t initialNumGlobalCounterIds = INFERENCES_RUN;
3637*89c4ff92SAndroid Build Coastguard Worker 
3638*89c4ff92SAndroid Build Coastguard Worker     // Create RegisterBackendCounters for CpuRef
3639*89c4ff92SAndroid Build Coastguard Worker     RegisterBackendCounters registerBackendCountersCpuRef(initialNumGlobalCounterIds, cpuRefId, profilingService);
3640*89c4ff92SAndroid Build Coastguard Worker 
3641*89c4ff92SAndroid Build Coastguard Worker     // Create 'testCategory' in CounterDirectory (backend agnostic)
3642*89c4ff92SAndroid Build Coastguard Worker     CHECK(profilingService.GetCounterDirectory().GetCategories().empty());
3643*89c4ff92SAndroid Build Coastguard Worker     registerBackendCountersCpuRef.RegisterCategory("testCategory");
3644*89c4ff92SAndroid Build Coastguard Worker     auto categoryOnePtr = profilingService.GetCounterDirectory().GetCategory("testCategory");
3645*89c4ff92SAndroid Build Coastguard Worker     CHECK(categoryOnePtr);
3646*89c4ff92SAndroid Build Coastguard Worker 
3647*89c4ff92SAndroid Build Coastguard Worker     // Counters:
3648*89c4ff92SAndroid Build Coastguard Worker     // Global | Local | Backend
3649*89c4ff92SAndroid Build Coastguard Worker     //    5   |   0   | CpuRef
3650*89c4ff92SAndroid Build Coastguard Worker     //    6   |   1   | CpuRef
3651*89c4ff92SAndroid Build Coastguard Worker     //    7   |   1   | CpuAcc
3652*89c4ff92SAndroid Build Coastguard Worker 
3653*89c4ff92SAndroid Build Coastguard Worker     std::vector<uint16_t> cpuRefCounters = {0, 1};
3654*89c4ff92SAndroid Build Coastguard Worker     std::vector<uint16_t> cpuAccCounters = {0};
3655*89c4ff92SAndroid Build Coastguard Worker 
3656*89c4ff92SAndroid Build Coastguard Worker     // Register the backend counters for CpuRef and validate GetGlobalId and GetBackendId
3657*89c4ff92SAndroid Build Coastguard Worker     uint16_t currentNumGlobalCounterIds = registerBackendCountersCpuRef.RegisterCounter(
3658*89c4ff92SAndroid Build Coastguard Worker             0, "testCategory", 0, 0, 1.f, "CpuRefCounter0", "Zeroth CpuRef Counter");
3659*89c4ff92SAndroid Build Coastguard Worker     CHECK(currentNumGlobalCounterIds == initialNumGlobalCounterIds + 1);
3660*89c4ff92SAndroid Build Coastguard Worker     uint16_t mappedGlobalId = profilingService.GetCounterMappings().GetGlobalId(0, cpuRefId);
3661*89c4ff92SAndroid Build Coastguard Worker     CHECK(mappedGlobalId == currentNumGlobalCounterIds);
3662*89c4ff92SAndroid Build Coastguard Worker     auto backendMapping = profilingService.GetCounterMappings().GetBackendId(currentNumGlobalCounterIds);
3663*89c4ff92SAndroid Build Coastguard Worker     CHECK(backendMapping.first == 0);
3664*89c4ff92SAndroid Build Coastguard Worker     CHECK(backendMapping.second == cpuRefId);
3665*89c4ff92SAndroid Build Coastguard Worker 
3666*89c4ff92SAndroid Build Coastguard Worker     currentNumGlobalCounterIds = registerBackendCountersCpuRef.RegisterCounter(
3667*89c4ff92SAndroid Build Coastguard Worker             1, "testCategory", 0, 0, 1.f, "CpuRefCounter1", "First CpuRef Counter");
3668*89c4ff92SAndroid Build Coastguard Worker     CHECK(currentNumGlobalCounterIds == initialNumGlobalCounterIds + 2);
3669*89c4ff92SAndroid Build Coastguard Worker     mappedGlobalId = profilingService.GetCounterMappings().GetGlobalId(1, cpuRefId);
3670*89c4ff92SAndroid Build Coastguard Worker     CHECK(mappedGlobalId == currentNumGlobalCounterIds);
3671*89c4ff92SAndroid Build Coastguard Worker     backendMapping = profilingService.GetCounterMappings().GetBackendId(currentNumGlobalCounterIds);
3672*89c4ff92SAndroid Build Coastguard Worker     CHECK(backendMapping.first == 1);
3673*89c4ff92SAndroid Build Coastguard Worker     CHECK(backendMapping.second == cpuRefId);
3674*89c4ff92SAndroid Build Coastguard Worker 
3675*89c4ff92SAndroid Build Coastguard Worker     // Create RegisterBackendCounters for CpuAcc
3676*89c4ff92SAndroid Build Coastguard Worker     RegisterBackendCounters registerBackendCountersCpuAcc(currentNumGlobalCounterIds, cpuAccId, profilingService);
3677*89c4ff92SAndroid Build Coastguard Worker 
3678*89c4ff92SAndroid Build Coastguard Worker     // Register the backend counter for CpuAcc and validate GetGlobalId and GetBackendId
3679*89c4ff92SAndroid Build Coastguard Worker     currentNumGlobalCounterIds = registerBackendCountersCpuAcc.RegisterCounter(
3680*89c4ff92SAndroid Build Coastguard Worker             0, "testCategory", 0, 0, 1.f, "CpuAccCounter0", "Zeroth CpuAcc Counter");
3681*89c4ff92SAndroid Build Coastguard Worker     CHECK(currentNumGlobalCounterIds == initialNumGlobalCounterIds + 3);
3682*89c4ff92SAndroid Build Coastguard Worker     mappedGlobalId = profilingService.GetCounterMappings().GetGlobalId(0, cpuAccId);
3683*89c4ff92SAndroid Build Coastguard Worker     CHECK(mappedGlobalId == currentNumGlobalCounterIds);
3684*89c4ff92SAndroid Build Coastguard Worker     backendMapping = profilingService.GetCounterMappings().GetBackendId(currentNumGlobalCounterIds);
3685*89c4ff92SAndroid Build Coastguard Worker     CHECK(backendMapping.first == 0);
3686*89c4ff92SAndroid Build Coastguard Worker     CHECK(backendMapping.second == cpuAccId);
3687*89c4ff92SAndroid Build Coastguard Worker 
3688*89c4ff92SAndroid Build Coastguard Worker     // Create vectors for active counters
3689*89c4ff92SAndroid Build Coastguard Worker     const std::vector<uint16_t> activeGlobalCounterIds = {5}; // CpuRef(0) activated
3690*89c4ff92SAndroid Build Coastguard Worker     const std::vector<uint16_t> newActiveGlobalCounterIds = {6, 7}; // CpuRef(0) and CpuAcc(1) activated
3691*89c4ff92SAndroid Build Coastguard Worker 
3692*89c4ff92SAndroid Build Coastguard Worker     const uint32_t capturePeriod = 200;
3693*89c4ff92SAndroid Build Coastguard Worker     const uint32_t newCapturePeriod = 100;
3694*89c4ff92SAndroid Build Coastguard Worker 
3695*89c4ff92SAndroid Build Coastguard Worker     // Set capture period and active counters in CaptureData
3696*89c4ff92SAndroid Build Coastguard Worker     profilingService.SetCaptureData(capturePeriod, activeGlobalCounterIds, {});
3697*89c4ff92SAndroid Build Coastguard Worker 
3698*89c4ff92SAndroid Build Coastguard Worker     // Get vector of active counters for CpuRef and CpuAcc backends
3699*89c4ff92SAndroid Build Coastguard Worker     std::vector<CounterStatus> cpuRefCounterStatus = backendProfilingCpuRef.GetActiveCounters();
3700*89c4ff92SAndroid Build Coastguard Worker     std::vector<CounterStatus> cpuAccCounterStatus = backendProfilingCpuAcc.GetActiveCounters();
3701*89c4ff92SAndroid Build Coastguard Worker     CHECK_EQ(cpuRefCounterStatus.size(), 1);
3702*89c4ff92SAndroid Build Coastguard Worker     CHECK_EQ(cpuAccCounterStatus.size(), 0);
3703*89c4ff92SAndroid Build Coastguard Worker 
3704*89c4ff92SAndroid Build Coastguard Worker     // Check active CpuRef counter
3705*89c4ff92SAndroid Build Coastguard Worker     CHECK_EQ(cpuRefCounterStatus[0].m_GlobalCounterId, activeGlobalCounterIds[0]);
3706*89c4ff92SAndroid Build Coastguard Worker     CHECK_EQ(cpuRefCounterStatus[0].m_BackendCounterId, cpuRefCounters[0]);
3707*89c4ff92SAndroid Build Coastguard Worker     CHECK_EQ(cpuRefCounterStatus[0].m_SamplingRateInMicroseconds, capturePeriod);
3708*89c4ff92SAndroid Build Coastguard Worker     CHECK_EQ(cpuRefCounterStatus[0].m_Enabled, true);
3709*89c4ff92SAndroid Build Coastguard Worker 
3710*89c4ff92SAndroid Build Coastguard Worker     // Check inactive CpuRef counter
3711*89c4ff92SAndroid Build Coastguard Worker     CounterStatus inactiveCpuRefCounter = backendProfilingCpuRef.GetCounterStatus(cpuRefCounters[1]);
3712*89c4ff92SAndroid Build Coastguard Worker     CHECK_EQ(inactiveCpuRefCounter.m_GlobalCounterId, 6);
3713*89c4ff92SAndroid Build Coastguard Worker     CHECK_EQ(inactiveCpuRefCounter.m_BackendCounterId, cpuRefCounters[1]);
3714*89c4ff92SAndroid Build Coastguard Worker     CHECK_EQ(inactiveCpuRefCounter.m_SamplingRateInMicroseconds, 0);
3715*89c4ff92SAndroid Build Coastguard Worker     CHECK_EQ(inactiveCpuRefCounter.m_Enabled, false);
3716*89c4ff92SAndroid Build Coastguard Worker 
3717*89c4ff92SAndroid Build Coastguard Worker     // Check inactive CpuAcc counter
3718*89c4ff92SAndroid Build Coastguard Worker     CounterStatus inactiveCpuAccCounter = backendProfilingCpuAcc.GetCounterStatus(cpuAccCounters[0]);
3719*89c4ff92SAndroid Build Coastguard Worker     CHECK_EQ(inactiveCpuAccCounter.m_GlobalCounterId, 7);
3720*89c4ff92SAndroid Build Coastguard Worker     CHECK_EQ(inactiveCpuAccCounter.m_BackendCounterId, cpuAccCounters[0]);
3721*89c4ff92SAndroid Build Coastguard Worker     CHECK_EQ(inactiveCpuAccCounter.m_SamplingRateInMicroseconds, 0);
3722*89c4ff92SAndroid Build Coastguard Worker     CHECK_EQ(inactiveCpuAccCounter.m_Enabled, false);
3723*89c4ff92SAndroid Build Coastguard Worker 
3724*89c4ff92SAndroid Build Coastguard Worker     // Set new capture period and new active counters in CaptureData
3725*89c4ff92SAndroid Build Coastguard Worker     profilingService.SetCaptureData(newCapturePeriod, newActiveGlobalCounterIds, {});
3726*89c4ff92SAndroid Build Coastguard Worker 
3727*89c4ff92SAndroid Build Coastguard Worker     // Get vector of active counters for CpuRef and CpuAcc backends
3728*89c4ff92SAndroid Build Coastguard Worker     cpuRefCounterStatus = backendProfilingCpuRef.GetActiveCounters();
3729*89c4ff92SAndroid Build Coastguard Worker     cpuAccCounterStatus = backendProfilingCpuAcc.GetActiveCounters();
3730*89c4ff92SAndroid Build Coastguard Worker     CHECK_EQ(cpuRefCounterStatus.size(), 1);
3731*89c4ff92SAndroid Build Coastguard Worker     CHECK_EQ(cpuAccCounterStatus.size(), 1);
3732*89c4ff92SAndroid Build Coastguard Worker 
3733*89c4ff92SAndroid Build Coastguard Worker     // Check active CpuRef counter
3734*89c4ff92SAndroid Build Coastguard Worker     CHECK_EQ(cpuRefCounterStatus[0].m_GlobalCounterId, newActiveGlobalCounterIds[0]);
3735*89c4ff92SAndroid Build Coastguard Worker     CHECK_EQ(cpuRefCounterStatus[0].m_BackendCounterId, cpuRefCounters[1]);
3736*89c4ff92SAndroid Build Coastguard Worker     CHECK_EQ(cpuRefCounterStatus[0].m_SamplingRateInMicroseconds, newCapturePeriod);
3737*89c4ff92SAndroid Build Coastguard Worker     CHECK_EQ(cpuRefCounterStatus[0].m_Enabled, true);
3738*89c4ff92SAndroid Build Coastguard Worker 
3739*89c4ff92SAndroid Build Coastguard Worker     // Check active CpuAcc counter
3740*89c4ff92SAndroid Build Coastguard Worker     CHECK_EQ(cpuAccCounterStatus[0].m_GlobalCounterId, newActiveGlobalCounterIds[1]);
3741*89c4ff92SAndroid Build Coastguard Worker     CHECK_EQ(cpuAccCounterStatus[0].m_BackendCounterId, cpuAccCounters[0]);
3742*89c4ff92SAndroid Build Coastguard Worker     CHECK_EQ(cpuAccCounterStatus[0].m_SamplingRateInMicroseconds, newCapturePeriod);
3743*89c4ff92SAndroid Build Coastguard Worker     CHECK_EQ(cpuAccCounterStatus[0].m_Enabled, true);
3744*89c4ff92SAndroid Build Coastguard Worker 
3745*89c4ff92SAndroid Build Coastguard Worker     // Check inactive CpuRef counter
3746*89c4ff92SAndroid Build Coastguard Worker     inactiveCpuRefCounter = backendProfilingCpuRef.GetCounterStatus(cpuRefCounters[0]);
3747*89c4ff92SAndroid Build Coastguard Worker     CHECK_EQ(inactiveCpuRefCounter.m_GlobalCounterId, 5);
3748*89c4ff92SAndroid Build Coastguard Worker     CHECK_EQ(inactiveCpuRefCounter.m_BackendCounterId, cpuRefCounters[0]);
3749*89c4ff92SAndroid Build Coastguard Worker     CHECK_EQ(inactiveCpuRefCounter.m_SamplingRateInMicroseconds, 0);
3750*89c4ff92SAndroid Build Coastguard Worker     CHECK_EQ(inactiveCpuRefCounter.m_Enabled, false);
3751*89c4ff92SAndroid Build Coastguard Worker 
3752*89c4ff92SAndroid Build Coastguard Worker     // Reset the profiling service to stop any running thread
3753*89c4ff92SAndroid Build Coastguard Worker     options.m_EnableProfiling = false;
3754*89c4ff92SAndroid Build Coastguard Worker     profilingService.ResetExternalProfilingOptions(options, true);
3755*89c4ff92SAndroid Build Coastguard Worker }
3756*89c4ff92SAndroid Build Coastguard Worker 
3757*89c4ff92SAndroid Build Coastguard Worker TEST_CASE("CheckRegisterCounters")
3758*89c4ff92SAndroid Build Coastguard Worker {
3759*89c4ff92SAndroid Build Coastguard Worker     ProfilingOptions options;
3760*89c4ff92SAndroid Build Coastguard Worker     options.m_EnableProfiling = true;
3761*89c4ff92SAndroid Build Coastguard Worker     MockBufferManager mockBuffer(1024);
3762*89c4ff92SAndroid Build Coastguard Worker 
3763*89c4ff92SAndroid Build Coastguard Worker     CaptureData captureData;
3764*89c4ff92SAndroid Build Coastguard Worker 
3765*89c4ff92SAndroid Build Coastguard Worker     armnn::ArmNNProfilingServiceInitialiser initialiser;
3766*89c4ff92SAndroid Build Coastguard Worker     MockProfilingService mockProfilingService(
3767*89c4ff92SAndroid Build Coastguard Worker         arm::pipe::MAX_ARMNN_COUNTER, initialiser, mockBuffer, options.m_EnableProfiling, captureData);
3768*89c4ff92SAndroid Build Coastguard Worker     std::string cpuRefId(GetComputeDeviceAsCString(armnn::Compute::CpuRef));
3769*89c4ff92SAndroid Build Coastguard Worker 
3770*89c4ff92SAndroid Build Coastguard Worker     mockProfilingService.RegisterMapping(6, 0, cpuRefId);
3771*89c4ff92SAndroid Build Coastguard Worker     mockProfilingService.RegisterMapping(7, 1, cpuRefId);
3772*89c4ff92SAndroid Build Coastguard Worker     mockProfilingService.RegisterMapping(8, 2, cpuRefId);
3773*89c4ff92SAndroid Build Coastguard Worker 
3774*89c4ff92SAndroid Build Coastguard Worker     BackendProfiling backendProfiling(options,
3775*89c4ff92SAndroid Build Coastguard Worker                                                         mockProfilingService,
3776*89c4ff92SAndroid Build Coastguard Worker                                                         cpuRefId);
3777*89c4ff92SAndroid Build Coastguard Worker 
3778*89c4ff92SAndroid Build Coastguard Worker     Timestamp timestamp;
3779*89c4ff92SAndroid Build Coastguard Worker     timestamp.timestamp = 1000998;
3780*89c4ff92SAndroid Build Coastguard Worker     timestamp.counterValues.emplace_back(0, 700);
3781*89c4ff92SAndroid Build Coastguard Worker     timestamp.counterValues.emplace_back(2, 93);
3782*89c4ff92SAndroid Build Coastguard Worker     std::vector<Timestamp> timestamps;
3783*89c4ff92SAndroid Build Coastguard Worker     timestamps.push_back(timestamp);
3784*89c4ff92SAndroid Build Coastguard Worker     backendProfiling.ReportCounters(timestamps);
3785*89c4ff92SAndroid Build Coastguard Worker 
3786*89c4ff92SAndroid Build Coastguard Worker     auto readBuffer = mockBuffer.GetReadableBuffer();
3787*89c4ff92SAndroid Build Coastguard Worker 
3788*89c4ff92SAndroid Build Coastguard Worker     uint32_t headerWord0 = ReadUint32(readBuffer, 0);
3789*89c4ff92SAndroid Build Coastguard Worker     uint32_t headerWord1 = ReadUint32(readBuffer, 4);
3790*89c4ff92SAndroid Build Coastguard Worker     uint64_t readTimestamp = ReadUint64(readBuffer, 8);
3791*89c4ff92SAndroid Build Coastguard Worker 
3792*89c4ff92SAndroid Build Coastguard Worker     CHECK(((headerWord0 >> 26) & 0x0000003F) == 3); // packet family
3793*89c4ff92SAndroid Build Coastguard Worker     CHECK(((headerWord0 >> 19) & 0x0000007F) == 0); // packet class
3794*89c4ff92SAndroid Build Coastguard Worker     CHECK(((headerWord0 >> 16) & 0x00000007) == 0); // packet type
3795*89c4ff92SAndroid Build Coastguard Worker     CHECK(headerWord1 == 20);                       // data length
3796*89c4ff92SAndroid Build Coastguard Worker     CHECK(1000998 == readTimestamp);                // capture period
3797*89c4ff92SAndroid Build Coastguard Worker 
3798*89c4ff92SAndroid Build Coastguard Worker     uint32_t offset = 16;
3799*89c4ff92SAndroid Build Coastguard Worker     // Check Counter Index
3800*89c4ff92SAndroid Build Coastguard Worker     uint16_t readIndex = ReadUint16(readBuffer, offset);
3801*89c4ff92SAndroid Build Coastguard Worker     CHECK(6 == readIndex);
3802*89c4ff92SAndroid Build Coastguard Worker 
3803*89c4ff92SAndroid Build Coastguard Worker     // Check Counter Value
3804*89c4ff92SAndroid Build Coastguard Worker     offset += 2;
3805*89c4ff92SAndroid Build Coastguard Worker     uint32_t readValue = ReadUint32(readBuffer, offset);
3806*89c4ff92SAndroid Build Coastguard Worker     CHECK(700 == readValue);
3807*89c4ff92SAndroid Build Coastguard Worker 
3808*89c4ff92SAndroid Build Coastguard Worker     // Check Counter Index
3809*89c4ff92SAndroid Build Coastguard Worker     offset += 4;
3810*89c4ff92SAndroid Build Coastguard Worker     readIndex = ReadUint16(readBuffer, offset);
3811*89c4ff92SAndroid Build Coastguard Worker     CHECK(8 == readIndex);
3812*89c4ff92SAndroid Build Coastguard Worker 
3813*89c4ff92SAndroid Build Coastguard Worker     // Check Counter Value
3814*89c4ff92SAndroid Build Coastguard Worker     offset += 2;
3815*89c4ff92SAndroid Build Coastguard Worker     readValue = ReadUint32(readBuffer, offset);
3816*89c4ff92SAndroid Build Coastguard Worker     CHECK(93 == readValue);
3817*89c4ff92SAndroid Build Coastguard Worker }
3818*89c4ff92SAndroid Build Coastguard Worker 
3819*89c4ff92SAndroid Build Coastguard Worker TEST_CASE("CheckFileFormat") {
3820*89c4ff92SAndroid Build Coastguard Worker     // Locally reduce log level to "Warning", as this test needs to parse a warning message from the standard output
3821*89c4ff92SAndroid Build Coastguard Worker     LogLevelSwapper logLevelSwapper(arm::pipe::LogSeverity::Warning);
3822*89c4ff92SAndroid Build Coastguard Worker 
3823*89c4ff92SAndroid Build Coastguard Worker     // Redirect the output to a local stream so that we can parse the warning message
3824*89c4ff92SAndroid Build Coastguard Worker     std::stringstream ss;
3825*89c4ff92SAndroid Build Coastguard Worker     StreamRedirector streamRedirector(std::cout, ss.rdbuf());
3826*89c4ff92SAndroid Build Coastguard Worker 
3827*89c4ff92SAndroid Build Coastguard Worker     // Create profiling options.
3828*89c4ff92SAndroid Build Coastguard Worker     ProfilingOptions options;
3829*89c4ff92SAndroid Build Coastguard Worker     options.m_EnableProfiling = true;
3830*89c4ff92SAndroid Build Coastguard Worker     // Check the default value set to binary
3831*89c4ff92SAndroid Build Coastguard Worker     CHECK(options.m_FileFormat == "binary");
3832*89c4ff92SAndroid Build Coastguard Worker 
3833*89c4ff92SAndroid Build Coastguard Worker     // Change file format to an unsupported value
3834*89c4ff92SAndroid Build Coastguard Worker     options.m_FileFormat = "json";
3835*89c4ff92SAndroid Build Coastguard Worker     // Enable the profiling service
3836*89c4ff92SAndroid Build Coastguard Worker     armnn::ArmNNProfilingServiceInitialiser initialiser;
3837*89c4ff92SAndroid Build Coastguard Worker     ProfilingService profilingService(arm::pipe::MAX_ARMNN_COUNTER,
3838*89c4ff92SAndroid Build Coastguard Worker                                       initialiser,
3839*89c4ff92SAndroid Build Coastguard Worker                                       arm::pipe::ARMNN_SOFTWARE_INFO,
3840*89c4ff92SAndroid Build Coastguard Worker                                       arm::pipe::ARMNN_SOFTWARE_VERSION,
3841*89c4ff92SAndroid Build Coastguard Worker                                       arm::pipe::ARMNN_HARDWARE_VERSION);
3842*89c4ff92SAndroid Build Coastguard Worker     profilingService.ResetExternalProfilingOptions(options, true);
3843*89c4ff92SAndroid Build Coastguard Worker     // Start the command handler and the send thread
3844*89c4ff92SAndroid Build Coastguard Worker     profilingService.Update();
3845*89c4ff92SAndroid Build Coastguard Worker     CHECK(profilingService.GetCurrentState()==ProfilingState::NotConnected);
3846*89c4ff92SAndroid Build Coastguard Worker 
3847*89c4ff92SAndroid Build Coastguard Worker     // When Update is called and the current state is ProfilingState::NotConnected
3848*89c4ff92SAndroid Build Coastguard Worker     // an exception will be raised from GetProfilingConnection and displayed as warning in the output local stream
3849*89c4ff92SAndroid Build Coastguard Worker     profilingService.Update();
3850*89c4ff92SAndroid Build Coastguard Worker 
3851*89c4ff92SAndroid Build Coastguard Worker     streamRedirector.CancelRedirect();
3852*89c4ff92SAndroid Build Coastguard Worker 
3853*89c4ff92SAndroid Build Coastguard Worker     // Check that the expected error has occurred and logged to the standard output
3854*89c4ff92SAndroid Build Coastguard Worker     if (ss.str().find("Unsupported profiling file format, only binary is supported") == std::string::npos)
3855*89c4ff92SAndroid Build Coastguard Worker     {
3856*89c4ff92SAndroid Build Coastguard Worker         std::cout << ss.str();
3857*89c4ff92SAndroid Build Coastguard Worker         FAIL("Expected string not found.");
3858*89c4ff92SAndroid Build Coastguard Worker     }
3859*89c4ff92SAndroid Build Coastguard Worker }
3860*89c4ff92SAndroid Build Coastguard Worker 
3861*89c4ff92SAndroid Build Coastguard Worker }
3862