blob: cba6ebd475efdd60b41ea0c4a0d8d656fca0bd22 [file] [log] [blame]
Francis Murtagh1f7db452019-08-14 09:49:34 +01001//
Jim Flynn6398a982020-05-27 17:05:21 +01002// Copyright © 2019 Arm Ltd and Contributors. All rights reserved.
Francis Murtagh1f7db452019-08-14 09:49:34 +01003// SPDX-License-Identifier: MIT
4//
5
Matteo Martincighd0613b52019-10-09 16:47:04 +01006#include "ProfilingTests.hpp"
Keith Davis33ed2212020-03-30 10:43:41 +01007#include "ProfilingTestUtils.hpp"
Teresa Charlin9bab4962019-09-06 12:28:35 +01008
James Conroy2dcd3fe2020-02-06 18:34:52 +00009#include <backends/BackendProfiling.hpp>
Jim Flynnbbfe6032020-07-20 16:57:44 +010010#include <common/include/EncodeVersion.hpp>
11#include <common/include/PacketVersionResolver.hpp>
12#include <common/include/SwTrace.hpp>
Matteo Martincigh8a837172019-10-04 17:01:07 +010013#include <CommandHandler.hpp>
Sadik Armaganb5f01b22019-09-18 17:29:00 +010014#include <ConnectionAcknowledgedCommandHandler.hpp>
Matteo Martincigh6db5f202019-09-05 12:02:04 +010015#include <CounterDirectory.hpp>
David Monahande803072020-01-30 12:44:23 +000016#include <CounterIdMap.hpp>
Matteo Martincigh6db5f202019-09-05 12:02:04 +010017#include <Holder.hpp>
Matteo Martincighe0e6efc2019-10-04 17:17:42 +010018#include <ICounterValues.hpp>
Francis Murtaghfcb8ef62019-09-20 15:40:09 +010019#include <PeriodicCounterCapture.hpp>
Matteo Martincigh6db5f202019-09-05 12:02:04 +010020#include <PeriodicCounterSelectionCommandHandler.hpp>
Jim Flynn4c9ed1d2022-01-23 23:57:20 +000021#include <armnn/profiling/ProfilingOptions.hpp>
Matteo Martincigh6db5f202019-09-05 12:02:04 +010022#include <ProfilingStateMachine.hpp>
Matteo Martincigh6db5f202019-09-05 12:02:04 +010023#include <ProfilingUtils.hpp>
James Conroy2dcd3fe2020-02-06 18:34:52 +000024#include <RegisterBackendCounters.hpp>
Narumol Prangnawarat48033692019-09-20 12:04:55 +010025#include <RequestCounterDirectoryCommandHandler.hpp>
Teresa Charlin9bab4962019-09-06 12:28:35 +010026#include <Runtime.hpp>
Matteo Martincigh6db5f202019-09-05 12:02:04 +010027#include <SocketProfilingConnection.hpp>
Matteo Martincighcdfb9412019-11-08 11:23:06 +000028#include <SendCounterPacket.hpp>
Sadik Armagan3896b472020-02-10 12:24:15 +000029#include <SendThread.hpp>
Matteo Martincighcdfb9412019-11-08 11:23:06 +000030#include <SendTimelinePacket.hpp>
Keith Davis02356de2019-08-26 18:28:17 +010031
Matteo Martincigh6db5f202019-09-05 12:02:04 +010032#include <armnn/Conversion.hpp>
Ferran Balaguer1b941722019-08-28 16:57:18 +010033
Matteo Martincigh54fb9572019-10-02 12:50:57 +010034#include <armnn/Utils.hpp>
Jan Eilers8eb25602020-03-09 12:13:48 +000035#include <armnn/utility/IgnoreUnused.hpp>
Matthew Sloyan371b70e2020-09-11 10:14:57 +010036#include <armnn/utility/NumericCast.hpp>
Matteo Martincigh54fb9572019-10-02 12:50:57 +010037
Jim Flynnbbfe6032020-07-20 16:57:44 +010038#include <common/include/CommandHandlerKey.hpp>
39#include <common/include/CommandHandlerRegistry.hpp>
40#include <common/include/SocketConnectionException.hpp>
41#include <common/include/Packet.hpp>
42
Sadik Armagan1625efc2021-06-10 18:24:34 +010043#include <doctest/doctest.h>
44
Sadik Armagan95e9efc2021-08-05 15:01:07 +010045#include <algorithm>
Nikhil Rajbc626052019-08-15 15:49:45 +010046#include <cstdint>
47#include <cstring>
Keith Davis3201eea2019-10-24 17:30:41 +010048#include <iostream>
Aron Virginas-Tare898db92019-08-22 12:56:34 +010049#include <limits>
Francis Murtagh11f99b42019-08-16 11:28:52 +010050#include <map>
Aron Virginas-Tare898db92019-08-22 12:56:34 +010051#include <random>
James Conroy2dcd3fe2020-02-06 18:34:52 +000052
Francis Murtagh1f7db452019-08-14 09:49:34 +010053
Cathal Corbett5aa9fd72022-02-25 15:33:28 +000054using namespace arm::pipe;
Finn Williams09ad6f92019-12-19 17:05:18 +000055using PacketType = MockProfilingConnection::PacketType;
Aron Virginas-Tare898db92019-08-22 12:56:34 +010056
Sadik Armagan1625efc2021-06-10 18:24:34 +010057TEST_SUITE("ExternalProfiling")
58{
59TEST_CASE("CheckCommandHandlerKeyComparisons")
Francis Murtagh1f7db452019-08-14 09:49:34 +010060{
Jim Flynnbbfe6032020-07-20 16:57:44 +010061 arm::pipe::CommandHandlerKey testKey1_0(1, 1, 1);
62 arm::pipe::CommandHandlerKey testKey1_1(1, 1, 1);
63 arm::pipe::CommandHandlerKey testKey1_2(1, 2, 1);
Jim Flynn397043f2019-10-17 17:37:10 +010064
Jim Flynnbbfe6032020-07-20 16:57:44 +010065 arm::pipe::CommandHandlerKey testKey0(0, 1, 1);
66 arm::pipe::CommandHandlerKey testKey1(0, 1, 1);
67 arm::pipe::CommandHandlerKey testKey2(0, 1, 1);
68 arm::pipe::CommandHandlerKey testKey3(0, 0, 0);
69 arm::pipe::CommandHandlerKey testKey4(0, 2, 2);
70 arm::pipe::CommandHandlerKey testKey5(0, 0, 2);
Jim Flynn397043f2019-10-17 17:37:10 +010071
Sadik Armagan1625efc2021-06-10 18:24:34 +010072 CHECK(testKey1_0 > testKey0);
73 CHECK(testKey1_0 == testKey1_1);
74 CHECK(testKey1_0 < testKey1_2);
Francis Murtagh1f7db452019-08-14 09:49:34 +010075
Sadik Armagan1625efc2021-06-10 18:24:34 +010076 CHECK(testKey1 < testKey4);
77 CHECK(testKey1 > testKey3);
78 CHECK(testKey1 <= testKey4);
79 CHECK(testKey1 >= testKey3);
80 CHECK(testKey1 <= testKey2);
81 CHECK(testKey1 >= testKey2);
82 CHECK(testKey1 == testKey2);
83 CHECK(testKey1 == testKey1);
Francis Murtagh1f7db452019-08-14 09:49:34 +010084
Sadik Armagan1625efc2021-06-10 18:24:34 +010085 CHECK(!(testKey1 == testKey5));
86 CHECK(!(testKey1 != testKey1));
87 CHECK(testKey1 != testKey5);
Francis Murtagh1f7db452019-08-14 09:49:34 +010088
Sadik Armagan1625efc2021-06-10 18:24:34 +010089 CHECK((testKey1 == testKey2 && testKey2 == testKey1));
90 CHECK((testKey0 == testKey1 && testKey1 == testKey2 && testKey0 == testKey2));
Francis Murtagh1f7db452019-08-14 09:49:34 +010091
Sadik Armagan1625efc2021-06-10 18:24:34 +010092 CHECK(testKey1.GetPacketId() == 1);
93 CHECK(testKey1.GetVersion() == 1);
Francis Murtagh1f7db452019-08-14 09:49:34 +010094
Jim Flynnbbfe6032020-07-20 16:57:44 +010095 std::vector<arm::pipe::CommandHandlerKey> vect = {
96 arm::pipe::CommandHandlerKey(0, 0, 1), arm::pipe::CommandHandlerKey(0, 2, 0),
97 arm::pipe::CommandHandlerKey(0, 1, 0), arm::pipe::CommandHandlerKey(0, 2, 1),
98 arm::pipe::CommandHandlerKey(0, 1, 1), arm::pipe::CommandHandlerKey(0, 0, 1),
99 arm::pipe::CommandHandlerKey(0, 2, 0), arm::pipe::CommandHandlerKey(0, 0, 0) };
Francis Murtagh1f7db452019-08-14 09:49:34 +0100100
101 std::sort(vect.begin(), vect.end());
102
Jim Flynnbbfe6032020-07-20 16:57:44 +0100103 std::vector<arm::pipe::CommandHandlerKey> expectedVect = {
104 arm::pipe::CommandHandlerKey(0, 0, 0), arm::pipe::CommandHandlerKey(0, 0, 1),
105 arm::pipe::CommandHandlerKey(0, 0, 1), arm::pipe::CommandHandlerKey(0, 1, 0),
106 arm::pipe::CommandHandlerKey(0, 1, 1), arm::pipe::CommandHandlerKey(0, 2, 0),
107 arm::pipe::CommandHandlerKey(0, 2, 0), arm::pipe::CommandHandlerKey(0, 2, 1) };
Francis Murtagh1f7db452019-08-14 09:49:34 +0100108
Sadik Armagan1625efc2021-06-10 18:24:34 +0100109 CHECK(vect == expectedVect);
Francis Murtagh1f7db452019-08-14 09:49:34 +0100110}
111
Sadik Armagan1625efc2021-06-10 18:24:34 +0100112TEST_CASE("CheckPacketKeyComparisons")
Jim Flynned25e0e2019-10-18 13:21:43 +0100113{
Jim Flynnbbfe6032020-07-20 16:57:44 +0100114 arm::pipe::PacketKey key0(0, 0);
115 arm::pipe::PacketKey key1(0, 0);
116 arm::pipe::PacketKey key2(0, 1);
117 arm::pipe::PacketKey key3(0, 2);
118 arm::pipe::PacketKey key4(1, 0);
119 arm::pipe::PacketKey key5(1, 0);
120 arm::pipe::PacketKey key6(1, 1);
Jim Flynned25e0e2019-10-18 13:21:43 +0100121
Sadik Armagan1625efc2021-06-10 18:24:34 +0100122 CHECK(!(key0 < key1));
123 CHECK(!(key0 > key1));
124 CHECK(key0 <= key1);
125 CHECK(key0 >= key1);
126 CHECK(key0 == key1);
127 CHECK(key0 < key2);
128 CHECK(key2 < key3);
129 CHECK(key3 > key0);
130 CHECK(key4 == key5);
131 CHECK(key4 > key0);
132 CHECK(key5 < key6);
133 CHECK(key5 <= key6);
134 CHECK(key5 != key6);
Jim Flynned25e0e2019-10-18 13:21:43 +0100135}
136
Sadik Armagan1625efc2021-06-10 18:24:34 +0100137TEST_CASE("CheckCommandHandler")
FinnWilliamsArm4833cea2019-09-17 16:53:53 +0100138{
Jim Flynnbbfe6032020-07-20 16:57:44 +0100139 arm::pipe::PacketVersionResolver packetVersionResolver;
Matteo Martincigh8a837172019-10-04 17:01:07 +0100140 ProfilingStateMachine profilingStateMachine;
FinnWilliamsArm4833cea2019-09-17 16:53:53 +0100141
Matteo Martincigh8a837172019-10-04 17:01:07 +0100142 TestProfilingConnectionBase testProfilingConnectionBase;
143 TestProfilingConnectionTimeoutError testProfilingConnectionTimeOutError;
144 TestProfilingConnectionArmnnError testProfilingConnectionArmnnError;
Keith Davis3201eea2019-10-24 17:30:41 +0100145 CounterDirectory counterDirectory;
146 MockBufferManager mockBuffer(1024);
Sadik Armagan3896b472020-02-10 12:24:15 +0000147 SendCounterPacket sendCounterPacket(mockBuffer);
148 SendThread sendThread(profilingStateMachine, mockBuffer, sendCounterPacket);
Matteo Martincighcdfb9412019-11-08 11:23:06 +0000149 SendTimelinePacket sendTimelinePacket(mockBuffer);
Jim Flynn6398a982020-05-27 17:05:21 +0100150 MockProfilingServiceStatus mockProfilingServiceStatus;
Matteo Martincighcdfb9412019-11-08 11:23:06 +0000151
Keith Davis3201eea2019-10-24 17:30:41 +0100152 ConnectionAcknowledgedCommandHandler connectionAcknowledgedCommandHandler(0, 1, 4194304, counterDirectory,
Matteo Martincighcdfb9412019-11-08 11:23:06 +0000153 sendCounterPacket, sendTimelinePacket,
Jim Flynn6398a982020-05-27 17:05:21 +0100154 profilingStateMachine,
155 mockProfilingServiceStatus);
Jim Flynnbbfe6032020-07-20 16:57:44 +0100156 arm::pipe::CommandHandlerRegistry commandHandlerRegistry;
FinnWilliamsArm4833cea2019-09-17 16:53:53 +0100157
Matteo Martincighc2728f92019-10-07 12:35:21 +0100158 commandHandlerRegistry.RegisterFunctor(&connectionAcknowledgedCommandHandler);
FinnWilliamsArm4833cea2019-09-17 16:53:53 +0100159
Matteo Martincigh8a837172019-10-04 17:01:07 +0100160 profilingStateMachine.TransitionToState(ProfilingState::NotConnected);
161 profilingStateMachine.TransitionToState(ProfilingState::WaitingForAck);
FinnWilliamsArm4833cea2019-09-17 16:53:53 +0100162
Keith Davis3201eea2019-10-24 17:30:41 +0100163 CommandHandler commandHandler0(1, true, commandHandlerRegistry, packetVersionResolver);
FinnWilliamsArm4833cea2019-09-17 16:53:53 +0100164
Colm Donelan2ba48d22019-11-29 09:10:59 +0000165 // This should start the command handler thread return the connection ack and put the profiling
166 // service into active state.
Matteo Martincigh8a837172019-10-04 17:01:07 +0100167 commandHandler0.Start(testProfilingConnectionBase);
Colm Donelan2ba48d22019-11-29 09:10:59 +0000168 // Try to start the send thread many times, it must only start once
Matteo Martincigh8a837172019-10-04 17:01:07 +0100169 commandHandler0.Start(testProfilingConnectionBase);
FinnWilliamsArm4833cea2019-09-17 16:53:53 +0100170
Colm Donelan2ba48d22019-11-29 09:10:59 +0000171 // This could take up to 20mSec but we'll check often.
172 for (int i = 0; i < 10; i++)
Matteo Martincigh8a837172019-10-04 17:01:07 +0100173 {
174 if (profilingStateMachine.GetCurrentState() == ProfilingState::Active)
FinnWilliamsArm4833cea2019-09-17 16:53:53 +0100175 {
Matteo Martincigh8a837172019-10-04 17:01:07 +0100176 break;
FinnWilliamsArm4833cea2019-09-17 16:53:53 +0100177 }
Colm Donelan2ba48d22019-11-29 09:10:59 +0000178 std::this_thread::sleep_for(std::chrono::milliseconds(2));
Matteo Martincigh8a837172019-10-04 17:01:07 +0100179 }
FinnWilliamsArm4833cea2019-09-17 16:53:53 +0100180
Sadik Armagan1625efc2021-06-10 18:24:34 +0100181 CHECK(profilingStateMachine.GetCurrentState() == ProfilingState::Active);
FinnWilliamsArm4833cea2019-09-17 16:53:53 +0100182
Colm Donelan2ba48d22019-11-29 09:10:59 +0000183 // Close the thread again.
184 commandHandler0.Stop();
185
186 profilingStateMachine.TransitionToState(ProfilingState::NotConnected);
187 profilingStateMachine.TransitionToState(ProfilingState::WaitingForAck);
188
189 // In this test we'll simulate a timeout without a connection ack packet being received.
190 // Stop after timeout is set so we expect the command handler to stop almost immediately.
191 CommandHandler commandHandler1(1, true, commandHandlerRegistry, packetVersionResolver);
192
193 commandHandler1.Start(testProfilingConnectionTimeOutError);
194 // Wait until we know a timeout exception has been sent at least once.
195 for (int i = 0; i < 10; i++)
196 {
197 if (testProfilingConnectionTimeOutError.ReadCalledCount())
198 {
199 break;
200 }
201 std::this_thread::sleep_for(std::chrono::milliseconds(2));
202 }
Colm Donelan2ba48d22019-11-29 09:10:59 +0000203
204 // The command handler loop should have stopped after the timeout.
Finn Williams09ad6f92019-12-19 17:05:18 +0000205 // wait for the timeout exception to be processed and the loop to break.
206 uint32_t timeout = 50;
207 uint32_t timeSlept = 0;
208 while (commandHandler1.IsRunning())
209 {
210 if (timeSlept >= timeout)
211 {
Sadik Armagan1625efc2021-06-10 18:24:34 +0100212 FAIL("Timeout: The command handler loop did not stop after the timeout");
Finn Williams09ad6f92019-12-19 17:05:18 +0000213 }
214 std::this_thread::sleep_for(std::chrono::milliseconds(1));
215 timeSlept ++;
216 }
Colm Donelan2ba48d22019-11-29 09:10:59 +0000217
218 commandHandler1.Stop();
219 // The state machine should never have received the ack so will still be in WaitingForAck.
Sadik Armagan1625efc2021-06-10 18:24:34 +0100220 CHECK(profilingStateMachine.GetCurrentState() == ProfilingState::WaitingForAck);
Colm Donelan2ba48d22019-11-29 09:10:59 +0000221
Finn Williams09ad6f92019-12-19 17:05:18 +0000222 // Now try sending a bad connection acknowledged packet
223 TestProfilingConnectionBadAckPacket testProfilingConnectionBadAckPacket;
224 commandHandler1.Start(testProfilingConnectionBadAckPacket);
225 commandHandler1.Stop();
226 // This should also not change the state machine
Sadik Armagan1625efc2021-06-10 18:24:34 +0100227 CHECK(profilingStateMachine.GetCurrentState() == ProfilingState::WaitingForAck);
Finn Williams09ad6f92019-12-19 17:05:18 +0000228
Colm Donelan2ba48d22019-11-29 09:10:59 +0000229 // Disable stop after timeout and now commandHandler1 should persist after a timeout
230 commandHandler1.SetStopAfterTimeout(false);
231 // Restart the thread.
232 commandHandler1.Start(testProfilingConnectionTimeOutError);
233
234 // Wait for at the three timeouts and the ack to be sent.
235 for (int i = 0; i < 10; i++)
236 {
237 if (testProfilingConnectionTimeOutError.ReadCalledCount() > 3)
238 {
239 break;
240 }
241 std::this_thread::sleep_for(std::chrono::milliseconds(2));
242 }
243 commandHandler1.Stop();
244
245 // Even after the 3 exceptions the ack packet should have transitioned the command handler to active.
Sadik Armagan1625efc2021-06-10 18:24:34 +0100246 CHECK(profilingStateMachine.GetCurrentState() == ProfilingState::Active);
Colm Donelan2ba48d22019-11-29 09:10:59 +0000247
248 // A command handler that gets exceptions other than timeouts should keep going.
249 CommandHandler commandHandler2(1, false, commandHandlerRegistry, packetVersionResolver);
FinnWilliamsArm4833cea2019-09-17 16:53:53 +0100250
Matteo Martincigh8a837172019-10-04 17:01:07 +0100251 commandHandler2.Start(testProfilingConnectionArmnnError);
252
Colm Donelan2ba48d22019-11-29 09:10:59 +0000253 // Wait for two exceptions to be thrown.
254 for (int i = 0; i < 10; i++)
255 {
256 if (testProfilingConnectionTimeOutError.ReadCalledCount() >= 2)
257 {
258 break;
259 }
260 std::this_thread::sleep_for(std::chrono::milliseconds(2));
261 }
FinnWilliamsArm4833cea2019-09-17 16:53:53 +0100262
Sadik Armagan1625efc2021-06-10 18:24:34 +0100263 CHECK(commandHandler2.IsRunning());
Matteo Martincigh8a837172019-10-04 17:01:07 +0100264 commandHandler2.Stop();
FinnWilliamsArm4833cea2019-09-17 16:53:53 +0100265}
266
Sadik Armagan1625efc2021-06-10 18:24:34 +0100267TEST_CASE("CheckEncodeVersion")
Nikhil Rajd88e47c2019-08-19 10:04:23 +0100268{
Jim Flynnbbfe6032020-07-20 16:57:44 +0100269 arm::pipe::Version version1(12);
Nikhil Rajd88e47c2019-08-19 10:04:23 +0100270
Sadik Armagan1625efc2021-06-10 18:24:34 +0100271 CHECK(version1.GetMajor() == 0);
272 CHECK(version1.GetMinor() == 0);
273 CHECK(version1.GetPatch() == 12);
Nikhil Rajd88e47c2019-08-19 10:04:23 +0100274
Jim Flynnbbfe6032020-07-20 16:57:44 +0100275 arm::pipe::Version version2(4108);
Nikhil Rajd88e47c2019-08-19 10:04:23 +0100276
Sadik Armagan1625efc2021-06-10 18:24:34 +0100277 CHECK(version2.GetMajor() == 0);
278 CHECK(version2.GetMinor() == 1);
279 CHECK(version2.GetPatch() == 12);
Nikhil Rajd88e47c2019-08-19 10:04:23 +0100280
Jim Flynnbbfe6032020-07-20 16:57:44 +0100281 arm::pipe::Version version3(4198412);
Nikhil Rajd88e47c2019-08-19 10:04:23 +0100282
Sadik Armagan1625efc2021-06-10 18:24:34 +0100283 CHECK(version3.GetMajor() == 1);
284 CHECK(version3.GetMinor() == 1);
285 CHECK(version3.GetPatch() == 12);
Nikhil Rajd88e47c2019-08-19 10:04:23 +0100286
Jim Flynnbbfe6032020-07-20 16:57:44 +0100287 arm::pipe::Version version4(0);
Nikhil Rajd88e47c2019-08-19 10:04:23 +0100288
Sadik Armagan1625efc2021-06-10 18:24:34 +0100289 CHECK(version4.GetMajor() == 0);
290 CHECK(version4.GetMinor() == 0);
291 CHECK(version4.GetPatch() == 0);
Nikhil Rajd88e47c2019-08-19 10:04:23 +0100292
Jim Flynnbbfe6032020-07-20 16:57:44 +0100293 arm::pipe::Version version5(1, 0, 0);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100294 CHECK(version5.GetEncodedValue() == 4194304);
Nikhil Rajd88e47c2019-08-19 10:04:23 +0100295}
296
Sadik Armagan1625efc2021-06-10 18:24:34 +0100297TEST_CASE("CheckPacketClass")
Nikhil Rajbc626052019-08-15 15:49:45 +0100298{
Keith Davis3201eea2019-10-24 17:30:41 +0100299 uint32_t length = 4;
Matteo Martincigh67ef2a52019-10-10 13:29:02 +0100300 std::unique_ptr<unsigned char[]> packetData0 = std::make_unique<unsigned char[]>(length);
301 std::unique_ptr<unsigned char[]> packetData1 = std::make_unique<unsigned char[]>(0);
302 std::unique_ptr<unsigned char[]> nullPacketData;
Nikhil Rajbc626052019-08-15 15:49:45 +0100303
Jim Flynnbbfe6032020-07-20 16:57:44 +0100304 arm::pipe::Packet packetTest0(472580096, length, packetData0);
Nikhil Rajbc626052019-08-15 15:49:45 +0100305
Sadik Armagan1625efc2021-06-10 18:24:34 +0100306 CHECK(packetTest0.GetHeader() == 472580096);
307 CHECK(packetTest0.GetPacketFamily() == 7);
308 CHECK(packetTest0.GetPacketId() == 43);
309 CHECK(packetTest0.GetLength() == length);
310 CHECK(packetTest0.GetPacketType() == 3);
311 CHECK(packetTest0.GetPacketClass() == 5);
Nikhil Rajbc626052019-08-15 15:49:45 +0100312
Sadik Armagan1625efc2021-06-10 18:24:34 +0100313 CHECK_THROWS_AS(arm::pipe::Packet packetTest1(472580096, 0, packetData1), arm::pipe::InvalidArgumentException);
314 CHECK_NOTHROW(arm::pipe::Packet packetTest2(472580096, 0, nullPacketData));
Nikhil Rajbc626052019-08-15 15:49:45 +0100315
Jim Flynnbbfe6032020-07-20 16:57:44 +0100316 arm::pipe::Packet packetTest3(472580096, 0, nullPacketData);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100317 CHECK(packetTest3.GetLength() == 0);
318 CHECK(packetTest3.GetData() == nullptr);
FinnWilliamsArma0c78712019-09-16 12:06:47 +0100319
Matteo Martincigh67ef2a52019-10-10 13:29:02 +0100320 const unsigned char* packetTest0Data = packetTest0.GetData();
Jim Flynnbbfe6032020-07-20 16:57:44 +0100321 arm::pipe::Packet packetTest4(std::move(packetTest0));
FinnWilliamsArma0c78712019-09-16 12:06:47 +0100322
Sadik Armagan1625efc2021-06-10 18:24:34 +0100323 CHECK(packetTest0.GetData() == nullptr);
324 CHECK(packetTest4.GetData() == packetTest0Data);
FinnWilliamsArma0c78712019-09-16 12:06:47 +0100325
Sadik Armagan1625efc2021-06-10 18:24:34 +0100326 CHECK(packetTest4.GetHeader() == 472580096);
327 CHECK(packetTest4.GetPacketFamily() == 7);
328 CHECK(packetTest4.GetPacketId() == 43);
329 CHECK(packetTest4.GetLength() == length);
330 CHECK(packetTest4.GetPacketType() == 3);
331 CHECK(packetTest4.GetPacketClass() == 5);
Nikhil Rajbc626052019-08-15 15:49:45 +0100332}
333
Sadik Armagan1625efc2021-06-10 18:24:34 +0100334TEST_CASE("CheckCommandHandlerFunctor")
Francis Murtagh11f99b42019-08-16 11:28:52 +0100335{
Francis Murtagh11f99b42019-08-16 11:28:52 +0100336 // Hard code the version as it will be the same during a single profiling session
337 uint32_t version = 1;
338
Jim Flynn397043f2019-10-17 17:37:10 +0100339 TestFunctorA testFunctorA(7, 461, version);
340 TestFunctorB testFunctorB(8, 963, version);
341 TestFunctorC testFunctorC(5, 983, version);
Francis Murtagh11f99b42019-08-16 11:28:52 +0100342
Jim Flynnbbfe6032020-07-20 16:57:44 +0100343 arm::pipe::CommandHandlerKey keyA(
344 testFunctorA.GetFamilyId(), testFunctorA.GetPacketId(), testFunctorA.GetVersion());
345 arm::pipe::CommandHandlerKey keyB(
346 testFunctorB.GetFamilyId(), testFunctorB.GetPacketId(), testFunctorB.GetVersion());
347 arm::pipe::CommandHandlerKey keyC(
348 testFunctorC.GetFamilyId(), testFunctorC.GetPacketId(), testFunctorC.GetVersion());
Francis Murtagh11f99b42019-08-16 11:28:52 +0100349
350 // Create the unwrapped map to simulate the Command Handler Registry
Jim Flynnbbfe6032020-07-20 16:57:44 +0100351 std::map<arm::pipe::CommandHandlerKey, arm::pipe::CommandHandlerFunctor*> registry;
Francis Murtagh11f99b42019-08-16 11:28:52 +0100352
353 registry.insert(std::make_pair(keyB, &testFunctorB));
354 registry.insert(std::make_pair(keyA, &testFunctorA));
355 registry.insert(std::make_pair(keyC, &testFunctorC));
356
357 // Check the order of the map is correct
358 auto it = registry.begin();
Sadik Armagan1625efc2021-06-10 18:24:34 +0100359 CHECK(it->first == keyC); // familyId == 5
Francis Murtagh11f99b42019-08-16 11:28:52 +0100360 it++;
Sadik Armagan1625efc2021-06-10 18:24:34 +0100361 CHECK(it->first == keyA); // familyId == 7
Francis Murtagh11f99b42019-08-16 11:28:52 +0100362 it++;
Sadik Armagan1625efc2021-06-10 18:24:34 +0100363 CHECK(it->first == keyB); // familyId == 8
Francis Murtagh11f99b42019-08-16 11:28:52 +0100364
Matteo Martincigh67ef2a52019-10-10 13:29:02 +0100365 std::unique_ptr<unsigned char[]> packetDataA;
366 std::unique_ptr<unsigned char[]> packetDataB;
367 std::unique_ptr<unsigned char[]> packetDataC;
FinnWilliamsArma0c78712019-09-16 12:06:47 +0100368
Jim Flynnbbfe6032020-07-20 16:57:44 +0100369 arm::pipe::Packet packetA(500000000, 0, packetDataA);
370 arm::pipe::Packet packetB(600000000, 0, packetDataB);
371 arm::pipe::Packet packetC(400000000, 0, packetDataC);
Francis Murtagh11f99b42019-08-16 11:28:52 +0100372
373 // Check the correct operator of derived class is called
Jim Flynnbbfe6032020-07-20 16:57:44 +0100374 registry.at(arm::pipe::CommandHandlerKey(
375 packetA.GetPacketFamily(), packetA.GetPacketId(), version))->operator()(packetA);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100376 CHECK(testFunctorA.GetCount() == 1);
377 CHECK(testFunctorB.GetCount() == 0);
378 CHECK(testFunctorC.GetCount() == 0);
Francis Murtagh11f99b42019-08-16 11:28:52 +0100379
Jim Flynnbbfe6032020-07-20 16:57:44 +0100380 registry.at(arm::pipe::CommandHandlerKey(
381 packetB.GetPacketFamily(), packetB.GetPacketId(), version))->operator()(packetB);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100382 CHECK(testFunctorA.GetCount() == 1);
383 CHECK(testFunctorB.GetCount() == 1);
384 CHECK(testFunctorC.GetCount() == 0);
Francis Murtagh11f99b42019-08-16 11:28:52 +0100385
Jim Flynnbbfe6032020-07-20 16:57:44 +0100386 registry.at(arm::pipe::CommandHandlerKey(
387 packetC.GetPacketFamily(), packetC.GetPacketId(), version))->operator()(packetC);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100388 CHECK(testFunctorA.GetCount() == 1);
389 CHECK(testFunctorB.GetCount() == 1);
390 CHECK(testFunctorC.GetCount() == 1);
Francis Murtagh11f99b42019-08-16 11:28:52 +0100391}
392
Sadik Armagan1625efc2021-06-10 18:24:34 +0100393TEST_CASE("CheckCommandHandlerRegistry")
Francis Murtagh94d79152019-08-16 17:45:07 +0100394{
395 // Hard code the version as it will be the same during a single profiling session
396 uint32_t version = 1;
397
Jim Flynn397043f2019-10-17 17:37:10 +0100398 TestFunctorA testFunctorA(7, 461, version);
399 TestFunctorB testFunctorB(8, 963, version);
400 TestFunctorC testFunctorC(5, 983, version);
Francis Murtagh94d79152019-08-16 17:45:07 +0100401
402 // Create the Command Handler Registry
Jim Flynnbbfe6032020-07-20 16:57:44 +0100403 arm::pipe::CommandHandlerRegistry registry;
Francis Murtagh94d79152019-08-16 17:45:07 +0100404
405 // Register multiple different derived classes
Matteo Martincighc2728f92019-10-07 12:35:21 +0100406 registry.RegisterFunctor(&testFunctorA);
407 registry.RegisterFunctor(&testFunctorB);
408 registry.RegisterFunctor(&testFunctorC);
Francis Murtagh94d79152019-08-16 17:45:07 +0100409
Matteo Martincigh67ef2a52019-10-10 13:29:02 +0100410 std::unique_ptr<unsigned char[]> packetDataA;
411 std::unique_ptr<unsigned char[]> packetDataB;
412 std::unique_ptr<unsigned char[]> packetDataC;
FinnWilliamsArma0c78712019-09-16 12:06:47 +0100413
Jim Flynnbbfe6032020-07-20 16:57:44 +0100414 arm::pipe::Packet packetA(500000000, 0, packetDataA);
415 arm::pipe::Packet packetB(600000000, 0, packetDataB);
416 arm::pipe::Packet packetC(400000000, 0, packetDataC);
Francis Murtagh94d79152019-08-16 17:45:07 +0100417
418 // Check the correct operator of derived class is called
Jim Flynn397043f2019-10-17 17:37:10 +0100419 registry.GetFunctor(packetA.GetPacketFamily(), packetA.GetPacketId(), version)->operator()(packetA);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100420 CHECK(testFunctorA.GetCount() == 1);
421 CHECK(testFunctorB.GetCount() == 0);
422 CHECK(testFunctorC.GetCount() == 0);
Francis Murtagh94d79152019-08-16 17:45:07 +0100423
Jim Flynn397043f2019-10-17 17:37:10 +0100424 registry.GetFunctor(packetB.GetPacketFamily(), packetB.GetPacketId(), version)->operator()(packetB);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100425 CHECK(testFunctorA.GetCount() == 1);
426 CHECK(testFunctorB.GetCount() == 1);
427 CHECK(testFunctorC.GetCount() == 0);
Francis Murtagh94d79152019-08-16 17:45:07 +0100428
Jim Flynn397043f2019-10-17 17:37:10 +0100429 registry.GetFunctor(packetC.GetPacketFamily(), packetC.GetPacketId(), version)->operator()(packetC);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100430 CHECK(testFunctorA.GetCount() == 1);
431 CHECK(testFunctorB.GetCount() == 1);
432 CHECK(testFunctorC.GetCount() == 1);
Francis Murtagh94d79152019-08-16 17:45:07 +0100433
434 // Re-register an existing key with a new function
Jim Flynn397043f2019-10-17 17:37:10 +0100435 registry.RegisterFunctor(&testFunctorC, testFunctorA.GetFamilyId(), testFunctorA.GetPacketId(), version);
436 registry.GetFunctor(packetA.GetPacketFamily(), packetA.GetPacketId(), version)->operator()(packetC);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100437 CHECK(testFunctorA.GetCount() == 1);
438 CHECK(testFunctorB.GetCount() == 1);
439 CHECK(testFunctorC.GetCount() == 2);
Francis Murtagh94d79152019-08-16 17:45:07 +0100440
441 // Check that non-existent key returns nullptr for its functor
Sadik Armagan1625efc2021-06-10 18:24:34 +0100442 CHECK_THROWS_AS(registry.GetFunctor(0, 0, 0), arm::pipe::ProfilingException);
Francis Murtagh94d79152019-08-16 17:45:07 +0100443}
444
Sadik Armagan1625efc2021-06-10 18:24:34 +0100445TEST_CASE("CheckPacketVersionResolver")
Aron Virginas-Tare898db92019-08-22 12:56:34 +0100446{
447 // Set up random number generator for generating packetId values
448 std::random_device device;
449 std::mt19937 generator(device());
450 std::uniform_int_distribution<uint32_t> distribution(std::numeric_limits<uint32_t>::min(),
451 std::numeric_limits<uint32_t>::max());
452
453 // NOTE: Expected version is always 1.0.0, regardless of packetId
Jim Flynnbbfe6032020-07-20 16:57:44 +0100454 const arm::pipe::Version expectedVersion(1, 0, 0);
Aron Virginas-Tare898db92019-08-22 12:56:34 +0100455
Jim Flynnbbfe6032020-07-20 16:57:44 +0100456 arm::pipe::PacketVersionResolver packetVersionResolver;
Aron Virginas-Tare898db92019-08-22 12:56:34 +0100457
458 constexpr unsigned int numTests = 10u;
459
460 for (unsigned int i = 0u; i < numTests; ++i)
461 {
Jim Flynned25e0e2019-10-18 13:21:43 +0100462 const uint32_t familyId = distribution(generator);
Aron Virginas-Tare898db92019-08-22 12:56:34 +0100463 const uint32_t packetId = distribution(generator);
Jim Flynnbbfe6032020-07-20 16:57:44 +0100464 arm::pipe::Version resolvedVersion = packetVersionResolver.ResolvePacketVersion(familyId, packetId);
Aron Virginas-Tare898db92019-08-22 12:56:34 +0100465
Sadik Armagan1625efc2021-06-10 18:24:34 +0100466 CHECK(resolvedVersion == expectedVersion);
Aron Virginas-Tare898db92019-08-22 12:56:34 +0100467 }
468}
Matteo Martincighd0613b52019-10-09 16:47:04 +0100469
Nikhil Raj3ecc5102019-09-03 15:55:33 +0100470void ProfilingCurrentStateThreadImpl(ProfilingStateMachine& states)
471{
472 ProfilingState newState = ProfilingState::NotConnected;
473 states.GetCurrentState();
474 states.TransitionToState(newState);
475}
476
Sadik Armagan1625efc2021-06-10 18:24:34 +0100477TEST_CASE("CheckProfilingStateMachine")
Nikhil Raj3ecc5102019-09-03 15:55:33 +0100478{
479 ProfilingStateMachine profilingState1(ProfilingState::Uninitialised);
480 profilingState1.TransitionToState(ProfilingState::Uninitialised);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100481 CHECK(profilingState1.GetCurrentState() == ProfilingState::Uninitialised);
Nikhil Raj3ecc5102019-09-03 15:55:33 +0100482
483 ProfilingStateMachine profilingState2(ProfilingState::Uninitialised);
484 profilingState2.TransitionToState(ProfilingState::NotConnected);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100485 CHECK(profilingState2.GetCurrentState() == ProfilingState::NotConnected);
Nikhil Raj3ecc5102019-09-03 15:55:33 +0100486
487 ProfilingStateMachine profilingState3(ProfilingState::NotConnected);
488 profilingState3.TransitionToState(ProfilingState::NotConnected);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100489 CHECK(profilingState3.GetCurrentState() == ProfilingState::NotConnected);
Nikhil Raj3ecc5102019-09-03 15:55:33 +0100490
491 ProfilingStateMachine profilingState4(ProfilingState::NotConnected);
492 profilingState4.TransitionToState(ProfilingState::WaitingForAck);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100493 CHECK(profilingState4.GetCurrentState() == ProfilingState::WaitingForAck);
Nikhil Raj3ecc5102019-09-03 15:55:33 +0100494
495 ProfilingStateMachine profilingState5(ProfilingState::WaitingForAck);
496 profilingState5.TransitionToState(ProfilingState::WaitingForAck);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100497 CHECK(profilingState5.GetCurrentState() == ProfilingState::WaitingForAck);
Nikhil Raj3ecc5102019-09-03 15:55:33 +0100498
499 ProfilingStateMachine profilingState6(ProfilingState::WaitingForAck);
500 profilingState6.TransitionToState(ProfilingState::Active);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100501 CHECK(profilingState6.GetCurrentState() == ProfilingState::Active);
Nikhil Raj3ecc5102019-09-03 15:55:33 +0100502
503 ProfilingStateMachine profilingState7(ProfilingState::Active);
504 profilingState7.TransitionToState(ProfilingState::NotConnected);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100505 CHECK(profilingState7.GetCurrentState() == ProfilingState::NotConnected);
Nikhil Raj3ecc5102019-09-03 15:55:33 +0100506
507 ProfilingStateMachine profilingState8(ProfilingState::Active);
508 profilingState8.TransitionToState(ProfilingState::Active);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100509 CHECK(profilingState8.GetCurrentState() == ProfilingState::Active);
Nikhil Raj3ecc5102019-09-03 15:55:33 +0100510
511 ProfilingStateMachine profilingState9(ProfilingState::Uninitialised);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100512 CHECK_THROWS_AS(profilingState9.TransitionToState(ProfilingState::WaitingForAck), armnn::Exception);
Nikhil Raj3ecc5102019-09-03 15:55:33 +0100513
514 ProfilingStateMachine profilingState10(ProfilingState::Uninitialised);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100515 CHECK_THROWS_AS(profilingState10.TransitionToState(ProfilingState::Active), armnn::Exception);
Nikhil Raj3ecc5102019-09-03 15:55:33 +0100516
517 ProfilingStateMachine profilingState11(ProfilingState::NotConnected);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100518 CHECK_THROWS_AS(profilingState11.TransitionToState(ProfilingState::Uninitialised), armnn::Exception);
Nikhil Raj3ecc5102019-09-03 15:55:33 +0100519
520 ProfilingStateMachine profilingState12(ProfilingState::NotConnected);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100521 CHECK_THROWS_AS(profilingState12.TransitionToState(ProfilingState::Active), armnn::Exception);
Nikhil Raj3ecc5102019-09-03 15:55:33 +0100522
523 ProfilingStateMachine profilingState13(ProfilingState::WaitingForAck);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100524 CHECK_THROWS_AS(profilingState13.TransitionToState(ProfilingState::Uninitialised), armnn::Exception);
Nikhil Raj3ecc5102019-09-03 15:55:33 +0100525
526 ProfilingStateMachine profilingState14(ProfilingState::WaitingForAck);
Jim Flynn53e46992019-10-14 12:31:10 +0100527 profilingState14.TransitionToState(ProfilingState::NotConnected);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100528 CHECK(profilingState14.GetCurrentState() == ProfilingState::NotConnected);
Nikhil Raj3ecc5102019-09-03 15:55:33 +0100529
530 ProfilingStateMachine profilingState15(ProfilingState::Active);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100531 CHECK_THROWS_AS(profilingState15.TransitionToState(ProfilingState::Uninitialised), armnn::Exception);
Nikhil Raj3ecc5102019-09-03 15:55:33 +0100532
Cathal Corbett5aa9fd72022-02-25 15:33:28 +0000533 ProfilingStateMachine profilingState16(ProfilingState::Active);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100534 CHECK_THROWS_AS(profilingState16.TransitionToState(ProfilingState::WaitingForAck), armnn::Exception);
Nikhil Raj3ecc5102019-09-03 15:55:33 +0100535
536 ProfilingStateMachine profilingState17(ProfilingState::Uninitialised);
537
Sadik Armagan95e9efc2021-08-05 15:01:07 +0100538 std::vector<std::thread> threads;
539 for (unsigned int i = 0; i < 5; ++i)
540 {
541 threads.push_back(std::thread(ProfilingCurrentStateThreadImpl, std::ref(profilingState17)));
542 }
543 std::for_each(threads.begin(), threads.end(), [](std::thread& theThread)
544 {
545 theThread.join();
546 });
Nikhil Raj3ecc5102019-09-03 15:55:33 +0100547
Sadik Armagan1625efc2021-06-10 18:24:34 +0100548 CHECK((profilingState17.GetCurrentState() == ProfilingState::NotConnected));
Nikhil Raj3ecc5102019-09-03 15:55:33 +0100549}
Aron Virginas-Tare898db92019-08-22 12:56:34 +0100550
Jim Flynn8355ec92019-09-17 12:29:50 +0100551void CaptureDataWriteThreadImpl(Holder& holder, uint32_t capturePeriod, const std::vector<uint16_t>& counterIds)
Francis Murtagh68f78d82019-09-04 16:42:29 +0100552{
Finn Williams032bc742020-02-12 11:02:34 +0000553 holder.SetCaptureData(capturePeriod, counterIds, {});
Francis Murtagh68f78d82019-09-04 16:42:29 +0100554}
555
Francis Murtaghbd707162019-09-09 11:26:44 +0100556void CaptureDataReadThreadImpl(const Holder& holder, CaptureData& captureData)
Francis Murtagh68f78d82019-09-04 16:42:29 +0100557{
558 captureData = holder.GetCaptureData();
559}
560
Sadik Armagan1625efc2021-06-10 18:24:34 +0100561TEST_CASE("CheckCaptureDataHolder")
Francis Murtagh68f78d82019-09-04 16:42:29 +0100562{
Francis Murtaghbd707162019-09-09 11:26:44 +0100563 std::map<uint32_t, std::vector<uint16_t>> periodIdMap;
564 std::vector<uint16_t> counterIds;
Jim Flynn8355ec92019-09-17 12:29:50 +0100565 uint32_t numThreads = 10;
566 for (uint32_t i = 0; i < numThreads; ++i)
Francis Murtaghbd707162019-09-09 11:26:44 +0100567 {
568 counterIds.emplace_back(i);
569 periodIdMap.insert(std::make_pair(i, counterIds));
570 }
Francis Murtagh68f78d82019-09-04 16:42:29 +0100571
Jim Flynn8355ec92019-09-17 12:29:50 +0100572 // Verify the read and write threads set the holder correctly
573 // and retrieve the expected values
Francis Murtagh68f78d82019-09-04 16:42:29 +0100574 Holder holder;
Sadik Armagan1625efc2021-06-10 18:24:34 +0100575 CHECK((holder.GetCaptureData()).GetCapturePeriod() == 0);
576 CHECK(((holder.GetCaptureData()).GetCounterIds()).empty());
Francis Murtagh68f78d82019-09-04 16:42:29 +0100577
578 // Check Holder functions
Francis Murtaghbd707162019-09-09 11:26:44 +0100579 std::thread thread1(CaptureDataWriteThreadImpl, std::ref(holder), 2, std::ref(periodIdMap[2]));
Francis Murtagh68f78d82019-09-04 16:42:29 +0100580 thread1.join();
Sadik Armagan1625efc2021-06-10 18:24:34 +0100581 CHECK((holder.GetCaptureData()).GetCapturePeriod() == 2);
582 CHECK((holder.GetCaptureData()).GetCounterIds() == periodIdMap[2]);
Jim Flynn8355ec92019-09-17 12:29:50 +0100583 // NOTE: now that we have some initial values in the holder we don't have to worry
584 // in the multi-threaded section below about a read thread accessing the holder
585 // before any write thread has gotten to it so we read period = 0, counterIds empty
586 // instead of period = 0, counterIds = {0} as will the case when write thread 0
587 // has executed.
Francis Murtagh68f78d82019-09-04 16:42:29 +0100588
589 CaptureData captureData;
590 std::thread thread2(CaptureDataReadThreadImpl, std::ref(holder), std::ref(captureData));
591 thread2.join();
Sadik Armagan1625efc2021-06-10 18:24:34 +0100592 CHECK(captureData.GetCapturePeriod() == 2);
593 CHECK(captureData.GetCounterIds() == periodIdMap[2]);
Francis Murtagh68f78d82019-09-04 16:42:29 +0100594
Jim Flynn8355ec92019-09-17 12:29:50 +0100595 std::map<uint32_t, CaptureData> captureDataIdMap;
596 for (uint32_t i = 0; i < numThreads; ++i)
597 {
598 CaptureData perThreadCaptureData;
599 captureDataIdMap.insert(std::make_pair(i, perThreadCaptureData));
600 }
601
Francis Murtaghbd707162019-09-09 11:26:44 +0100602 std::vector<std::thread> threadsVect;
Jim Flynn8355ec92019-09-17 12:29:50 +0100603 std::vector<std::thread> readThreadsVect;
604 for (uint32_t i = 0; i < numThreads; ++i)
Francis Murtaghbd707162019-09-09 11:26:44 +0100605 {
Keith Davis3201eea2019-10-24 17:30:41 +0100606 threadsVect.emplace_back(
607 std::thread(CaptureDataWriteThreadImpl, std::ref(holder), i, std::ref(periodIdMap[i])));
Francis Murtagh06965692019-09-05 16:29:01 +0100608
Jim Flynn8355ec92019-09-17 12:29:50 +0100609 // Verify that the CaptureData goes into the thread in a virgin state
Sadik Armagan1625efc2021-06-10 18:24:34 +0100610 CHECK(captureDataIdMap.at(i).GetCapturePeriod() == 0);
611 CHECK(captureDataIdMap.at(i).GetCounterIds().empty());
Keith Davis3201eea2019-10-24 17:30:41 +0100612 readThreadsVect.emplace_back(
613 std::thread(CaptureDataReadThreadImpl, std::ref(holder), std::ref(captureDataIdMap.at(i))));
Francis Murtaghbd707162019-09-09 11:26:44 +0100614 }
615
Jim Flynn8355ec92019-09-17 12:29:50 +0100616 for (uint32_t i = 0; i < numThreads; ++i)
Francis Murtaghbd707162019-09-09 11:26:44 +0100617 {
618 threadsVect[i].join();
Francis Murtaghbd707162019-09-09 11:26:44 +0100619 readThreadsVect[i].join();
620 }
Francis Murtagh68f78d82019-09-04 16:42:29 +0100621
Jim Flynn8355ec92019-09-17 12:29:50 +0100622 // Look at the CaptureData that each read thread has filled
623 // the capture period it read should match the counter ids entry
624 for (uint32_t i = 0; i < numThreads; ++i)
625 {
626 CaptureData perThreadCaptureData = captureDataIdMap.at(i);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100627 CHECK(perThreadCaptureData.GetCounterIds() == periodIdMap.at(perThreadCaptureData.GetCapturePeriod()));
Jim Flynn8355ec92019-09-17 12:29:50 +0100628 }
Matthew Bentham46d1c622019-09-13 12:45:04 +0100629}
Francis Murtagh68f78d82019-09-04 16:42:29 +0100630
Sadik Armagan1625efc2021-06-10 18:24:34 +0100631TEST_CASE("CaptureDataMethods")
Matthew Bentham46d1c622019-09-13 12:45:04 +0100632{
Jim Flynn8355ec92019-09-17 12:29:50 +0100633 // Check CaptureData setter and getter functions
Keith Davis3201eea2019-10-24 17:30:41 +0100634 std::vector<uint16_t> counterIds = { 42, 29, 13 };
Jim Flynn8355ec92019-09-17 12:29:50 +0100635 CaptureData captureData;
Sadik Armagan1625efc2021-06-10 18:24:34 +0100636 CHECK(captureData.GetCapturePeriod() == 0);
637 CHECK((captureData.GetCounterIds()).empty());
Jim Flynn8355ec92019-09-17 12:29:50 +0100638 captureData.SetCapturePeriod(150);
639 captureData.SetCounterIds(counterIds);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100640 CHECK(captureData.GetCapturePeriod() == 150);
641 CHECK(captureData.GetCounterIds() == counterIds);
Francis Murtagh68f78d82019-09-04 16:42:29 +0100642
Jim Flynn8355ec92019-09-17 12:29:50 +0100643 // Check assignment operator
Francis Murtagh68f78d82019-09-04 16:42:29 +0100644 CaptureData secondCaptureData;
Francis Murtagh68f78d82019-09-04 16:42:29 +0100645
Jim Flynn8355ec92019-09-17 12:29:50 +0100646 secondCaptureData = captureData;
Sadik Armagan1625efc2021-06-10 18:24:34 +0100647 CHECK(secondCaptureData.GetCapturePeriod() == 150);
648 CHECK(secondCaptureData.GetCounterIds() == counterIds);
Francis Murtagh68f78d82019-09-04 16:42:29 +0100649
650 // Check copy constructor
Jim Flynn8355ec92019-09-17 12:29:50 +0100651 CaptureData copyConstructedCaptureData(captureData);
Francis Murtagh68f78d82019-09-04 16:42:29 +0100652
Sadik Armagan1625efc2021-06-10 18:24:34 +0100653 CHECK(copyConstructedCaptureData.GetCapturePeriod() == 150);
654 CHECK(copyConstructedCaptureData.GetCounterIds() == counterIds);
Keith Davis02356de2019-08-26 18:28:17 +0100655}
Francis Murtagh68f78d82019-09-04 16:42:29 +0100656
Sadik Armagan1625efc2021-06-10 18:24:34 +0100657TEST_CASE("CheckProfilingServiceDisabled")
Keith Davis02356de2019-08-26 18:28:17 +0100658{
Jim Flynn4c9ed1d2022-01-23 23:57:20 +0000659 ProfilingOptions options;
Cathal Corbett5aa9fd72022-02-25 15:33:28 +0000660 ProfilingService profilingService;
Matteo Martincigha84edee2019-10-02 12:50:57 +0100661 profilingService.ResetExternalProfilingOptions(options, true);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100662 CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
Matteo Martincigh54fb9572019-10-02 12:50:57 +0100663 profilingService.Update();
Sadik Armagan1625efc2021-06-10 18:24:34 +0100664 CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
Keith Davis02356de2019-08-26 18:28:17 +0100665}
666
Sadik Armagan1625efc2021-06-10 18:24:34 +0100667TEST_CASE("CheckProfilingServiceCounterDirectory")
FinnWilliamsArmce2d9d12019-09-18 10:28:16 +0100668{
Jim Flynn4c9ed1d2022-01-23 23:57:20 +0000669 ProfilingOptions options;
Cathal Corbett5aa9fd72022-02-25 15:33:28 +0000670 ProfilingService profilingService;
Matteo Martincigha84edee2019-10-02 12:50:57 +0100671 profilingService.ResetExternalProfilingOptions(options, true);
FinnWilliamsArmce2d9d12019-09-18 10:28:16 +0100672
Matteo Martincigha84edee2019-10-02 12:50:57 +0100673 const ICounterDirectory& counterDirectory0 = profilingService.GetCounterDirectory();
Sadik Armagan1625efc2021-06-10 18:24:34 +0100674 CHECK(counterDirectory0.GetCounterCount() == 0);
Matteo Martincigh54fb9572019-10-02 12:50:57 +0100675 profilingService.Update();
Sadik Armagan1625efc2021-06-10 18:24:34 +0100676 CHECK(counterDirectory0.GetCounterCount() == 0);
FinnWilliamsArmce2d9d12019-09-18 10:28:16 +0100677
678 options.m_EnableProfiling = true;
Matteo Martincigha84edee2019-10-02 12:50:57 +0100679 profilingService.ResetExternalProfilingOptions(options);
FinnWilliamsArmce2d9d12019-09-18 10:28:16 +0100680
Matteo Martincigha84edee2019-10-02 12:50:57 +0100681 const ICounterDirectory& counterDirectory1 = profilingService.GetCounterDirectory();
Sadik Armagan1625efc2021-06-10 18:24:34 +0100682 CHECK(counterDirectory1.GetCounterCount() == 0);
Matteo Martincigh54fb9572019-10-02 12:50:57 +0100683 profilingService.Update();
Sadik Armagan1625efc2021-06-10 18:24:34 +0100684 CHECK(counterDirectory1.GetCounterCount() != 0);
Colm Donelan2ba48d22019-11-29 09:10:59 +0000685 // Reset the profiling service to stop any running thread
686 options.m_EnableProfiling = false;
687 profilingService.ResetExternalProfilingOptions(options, true);
FinnWilliamsArmce2d9d12019-09-18 10:28:16 +0100688}
689
Sadik Armagan1625efc2021-06-10 18:24:34 +0100690TEST_CASE("CheckProfilingServiceCounterValues")
FinnWilliamsArmf6e534a2019-09-16 15:45:42 +0100691{
Jim Flynn4c9ed1d2022-01-23 23:57:20 +0000692 ProfilingOptions options;
Keith Davis3201eea2019-10-24 17:30:41 +0100693 options.m_EnableProfiling = true;
Cathal Corbett5aa9fd72022-02-25 15:33:28 +0000694 ProfilingService profilingService;
Matteo Martincigha84edee2019-10-02 12:50:57 +0100695 profilingService.ResetExternalProfilingOptions(options, true);
696
Matteo Martincigh54fb9572019-10-02 12:50:57 +0100697 profilingService.Update();
Matteo Martincigha84edee2019-10-02 12:50:57 +0100698 const ICounterDirectory& counterDirectory = profilingService.GetCounterDirectory();
Keith Davis3201eea2019-10-24 17:30:41 +0100699 const Counters& counters = counterDirectory.GetCounters();
Sadik Armagan1625efc2021-06-10 18:24:34 +0100700 CHECK(!counters.empty());
Matteo Martincigha84edee2019-10-02 12:50:57 +0100701
FinnWilliamsArmf6e534a2019-09-16 15:45:42 +0100702 std::vector<std::thread> writers;
703
Sadik Armagan1625efc2021-06-10 18:24:34 +0100704 CHECK(!counters.empty());
Cathal Corbett5aa9fd72022-02-25 15:33:28 +0000705 uint16_t inferencesRun = INFERENCES_RUN;
Finn Williamsf3fcf322020-05-11 14:38:02 +0100706
707 // Test GetAbsoluteCounterValue
708 for (int i = 0; i < 4; ++i)
FinnWilliamsArmf6e534a2019-09-16 15:45:42 +0100709 {
Finn Williamsf3fcf322020-05-11 14:38:02 +0100710 // Increment and decrement the INFERENCES_RUN counter 250 times
Sadik Armagan95e9efc2021-08-05 15:01:07 +0100711 writers.push_back(std::thread([&profilingService, inferencesRun]()
Finn Williamsf3fcf322020-05-11 14:38:02 +0100712 {
713 for (int i = 0; i < 250; ++i)
714 {
Sadik Armagan95e9efc2021-08-05 15:01:07 +0100715 profilingService.IncrementCounterValue(inferencesRun);
Finn Williamsf3fcf322020-05-11 14:38:02 +0100716 }
717 }));
718 // Add 10 to the INFERENCES_RUN counter 200 times
Sadik Armagan95e9efc2021-08-05 15:01:07 +0100719 writers.push_back(std::thread([&profilingService, inferencesRun]()
Finn Williamsf3fcf322020-05-11 14:38:02 +0100720 {
721 for (int i = 0; i < 200; ++i)
722 {
Sadik Armagan95e9efc2021-08-05 15:01:07 +0100723 profilingService.AddCounterValue(inferencesRun, 10);
Finn Williamsf3fcf322020-05-11 14:38:02 +0100724 }
725 }));
726 // Subtract 5 from the INFERENCES_RUN counter 200 times
Sadik Armagan95e9efc2021-08-05 15:01:07 +0100727 writers.push_back(std::thread([&profilingService, inferencesRun]()
Finn Williamsf3fcf322020-05-11 14:38:02 +0100728 {
729 for (int i = 0; i < 200; ++i)
730 {
Sadik Armagan95e9efc2021-08-05 15:01:07 +0100731 profilingService.SubtractCounterValue(inferencesRun, 5);
Finn Williamsf3fcf322020-05-11 14:38:02 +0100732 }
733 }));
FinnWilliamsArmf6e534a2019-09-16 15:45:42 +0100734 }
FinnWilliamsArmf6e534a2019-09-16 15:45:42 +0100735 std::for_each(writers.begin(), writers.end(), mem_fn(&std::thread::join));
736
Finn Williamsf3fcf322020-05-11 14:38:02 +0100737 uint32_t absoluteCounterValue = 0;
FinnWilliamsArmf6e534a2019-09-16 15:45:42 +0100738
Sadik Armagan1625efc2021-06-10 18:24:34 +0100739 CHECK_NOTHROW(absoluteCounterValue = profilingService.GetAbsoluteCounterValue(INFERENCES_RUN));
740 CHECK(absoluteCounterValue == 5000);
Finn Williamsf3fcf322020-05-11 14:38:02 +0100741
742 // Test SetCounterValue
Sadik Armagan1625efc2021-06-10 18:24:34 +0100743 CHECK_NOTHROW(profilingService.SetCounterValue(INFERENCES_RUN, 0));
744 CHECK_NOTHROW(absoluteCounterValue = profilingService.GetAbsoluteCounterValue(INFERENCES_RUN));
745 CHECK(absoluteCounterValue == 0);
Finn Williamsf3fcf322020-05-11 14:38:02 +0100746
747 // Test GetDeltaCounterValue
748 writers.clear();
749 uint32_t deltaCounterValue = 0;
750 //Start a reading thread to randomly read the INFERENCES_RUN counter value
Sadik Armagan95e9efc2021-08-05 15:01:07 +0100751 std::thread reader([&profilingService, inferencesRun](uint32_t& deltaCounterValue)
Finn Williamsf3fcf322020-05-11 14:38:02 +0100752 {
753 for (int i = 0; i < 300; ++i)
754 {
Sadik Armagan95e9efc2021-08-05 15:01:07 +0100755 deltaCounterValue += profilingService.GetDeltaCounterValue(inferencesRun);
Finn Williamsf3fcf322020-05-11 14:38:02 +0100756 }
757 }, std::ref(deltaCounterValue));
758
759 for (int i = 0; i < 4; ++i)
760 {
761 // Increment and decrement the INFERENCES_RUN counter 250 times
Sadik Armagan95e9efc2021-08-05 15:01:07 +0100762 writers.push_back(std::thread([&profilingService, inferencesRun]()
Finn Williamsf3fcf322020-05-11 14:38:02 +0100763 {
764 for (int i = 0; i < 250; ++i)
765 {
Sadik Armagan95e9efc2021-08-05 15:01:07 +0100766 profilingService.IncrementCounterValue(inferencesRun);
Finn Williamsf3fcf322020-05-11 14:38:02 +0100767 }
768 }));
769 // Add 10 to the INFERENCES_RUN counter 200 times
Sadik Armagan95e9efc2021-08-05 15:01:07 +0100770 writers.push_back(std::thread([&profilingService, inferencesRun]()
Finn Williamsf3fcf322020-05-11 14:38:02 +0100771 {
772 for (int i = 0; i < 200; ++i)
773 {
Sadik Armagan95e9efc2021-08-05 15:01:07 +0100774 profilingService.AddCounterValue(inferencesRun, 10);
Finn Williamsf3fcf322020-05-11 14:38:02 +0100775 }
776 }));
777 // Subtract 5 from the INFERENCES_RUN counter 200 times
Sadik Armagan95e9efc2021-08-05 15:01:07 +0100778 writers.push_back(std::thread([&profilingService, inferencesRun]()
Finn Williamsf3fcf322020-05-11 14:38:02 +0100779 {
780 for (int i = 0; i < 200; ++i)
781 {
Sadik Armagan95e9efc2021-08-05 15:01:07 +0100782 profilingService.SubtractCounterValue(inferencesRun, 5);
Finn Williamsf3fcf322020-05-11 14:38:02 +0100783 }
784 }));
785 }
786
787 std::for_each(writers.begin(), writers.end(), mem_fn(&std::thread::join));
788 reader.join();
789
790 // Do one last read in case the reader stopped early
791 deltaCounterValue += profilingService.GetDeltaCounterValue(INFERENCES_RUN);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100792 CHECK(deltaCounterValue == 5000);
Finn Williamsf3fcf322020-05-11 14:38:02 +0100793
Colm Donelan2ba48d22019-11-29 09:10:59 +0000794 // Reset the profiling service to stop any running thread
795 options.m_EnableProfiling = false;
796 profilingService.ResetExternalProfilingOptions(options, true);
FinnWilliamsArmf6e534a2019-09-16 15:45:42 +0100797}
798
Sadik Armagan1625efc2021-06-10 18:24:34 +0100799TEST_CASE("CheckProfilingObjectUids")
Matteo Martincighab173e92019-09-05 12:02:04 +0100800{
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100801 uint16_t uid = 0;
Sadik Armagan1625efc2021-06-10 18:24:34 +0100802 CHECK_NOTHROW(uid = GetNextUid());
803 CHECK(uid >= 1);
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100804
805 uint16_t nextUid = 0;
Sadik Armagan1625efc2021-06-10 18:24:34 +0100806 CHECK_NOTHROW(nextUid = GetNextUid());
807 CHECK(nextUid > uid);
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100808
809 std::vector<uint16_t> counterUids;
Sadik Armagan1625efc2021-06-10 18:24:34 +0100810 CHECK_NOTHROW(counterUids = GetNextCounterUids(uid,0));
811 CHECK(counterUids.size() == 1);
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100812
813 std::vector<uint16_t> nextCounterUids;
Sadik Armagan1625efc2021-06-10 18:24:34 +0100814 CHECK_NOTHROW(nextCounterUids = GetNextCounterUids(nextUid, 2));
815 CHECK(nextCounterUids.size() == 2);
816 CHECK(nextCounterUids[0] > counterUids[0]);
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100817
818 std::vector<uint16_t> counterUidsMultiCore;
Francis Murtagh1e5afee2021-05-11 09:37:47 +0100819 uint16_t thirdUid = nextCounterUids[0];
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100820 uint16_t numberOfCores = 13;
Sadik Armagan1625efc2021-06-10 18:24:34 +0100821 CHECK_NOTHROW(counterUidsMultiCore = GetNextCounterUids(thirdUid, numberOfCores));
822 CHECK(counterUidsMultiCore.size() == numberOfCores);
823 CHECK(counterUidsMultiCore.front() >= nextCounterUids[0]);
Keith Davis3201eea2019-10-24 17:30:41 +0100824 for (size_t i = 1; i < numberOfCores; i++)
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100825 {
Sadik Armagan1625efc2021-06-10 18:24:34 +0100826 CHECK(counterUidsMultiCore[i] == counterUidsMultiCore[i - 1] + 1);
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100827 }
Sadik Armagan1625efc2021-06-10 18:24:34 +0100828 CHECK(counterUidsMultiCore.back() == counterUidsMultiCore.front() + numberOfCores - 1);
Matteo Martincighab173e92019-09-05 12:02:04 +0100829}
830
Sadik Armagan1625efc2021-06-10 18:24:34 +0100831TEST_CASE("CheckCounterDirectoryRegisterCategory")
Matteo Martincighab173e92019-09-05 12:02:04 +0100832{
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100833 CounterDirectory counterDirectory;
Sadik Armagan1625efc2021-06-10 18:24:34 +0100834 CHECK(counterDirectory.GetCategoryCount() == 0);
835 CHECK(counterDirectory.GetDeviceCount() == 0);
836 CHECK(counterDirectory.GetCounterSetCount() == 0);
837 CHECK(counterDirectory.GetCounterCount() == 0);
Matteo Martincighab173e92019-09-05 12:02:04 +0100838
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100839 // Register a category with an invalid name
840 const Category* noCategory = nullptr;
Cathal Corbett5aa9fd72022-02-25 15:33:28 +0000841 CHECK_THROWS_AS(noCategory = counterDirectory.RegisterCategory(""), arm::pipe::InvalidArgumentException);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100842 CHECK(counterDirectory.GetCategoryCount() == 0);
843 CHECK(!noCategory);
Matteo Martincighab173e92019-09-05 12:02:04 +0100844
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100845 // Register a category with an invalid name
Sadik Armagan1625efc2021-06-10 18:24:34 +0100846 CHECK_THROWS_AS(noCategory = counterDirectory.RegisterCategory("invalid category"),
Cathal Corbett5aa9fd72022-02-25 15:33:28 +0000847 arm::pipe::InvalidArgumentException);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100848 CHECK(counterDirectory.GetCategoryCount() == 0);
849 CHECK(!noCategory);
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100850
851 // Register a new category
852 const std::string categoryName = "some_category";
Keith Davis3201eea2019-10-24 17:30:41 +0100853 const Category* category = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +0100854 CHECK_NOTHROW(category = counterDirectory.RegisterCategory(categoryName));
855 CHECK(counterDirectory.GetCategoryCount() == 1);
856 CHECK(category);
857 CHECK(category->m_Name == categoryName);
858 CHECK(category->m_Counters.empty());
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100859
860 // Get the registered category
861 const Category* registeredCategory = counterDirectory.GetCategory(categoryName);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100862 CHECK(counterDirectory.GetCategoryCount() == 1);
863 CHECK(registeredCategory);
864 CHECK(registeredCategory == category);
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100865
866 // Try to get a category not registered
867 const Category* notRegisteredCategory = counterDirectory.GetCategory("not_registered_category");
Sadik Armagan1625efc2021-06-10 18:24:34 +0100868 CHECK(counterDirectory.GetCategoryCount() == 1);
869 CHECK(!notRegisteredCategory);
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100870
871 // Register a category already registered
872 const Category* anotherCategory = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +0100873 CHECK_THROWS_AS(anotherCategory = counterDirectory.RegisterCategory(categoryName),
Cathal Corbett5aa9fd72022-02-25 15:33:28 +0000874 arm::pipe::InvalidArgumentException);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100875 CHECK(counterDirectory.GetCategoryCount() == 1);
876 CHECK(!anotherCategory);
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100877
878 // Register a device for testing
879 const std::string deviceName = "some_device";
Keith Davis3201eea2019-10-24 17:30:41 +0100880 const Device* device = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +0100881 CHECK_NOTHROW(device = counterDirectory.RegisterDevice(deviceName));
882 CHECK(counterDirectory.GetDeviceCount() == 1);
883 CHECK(device);
884 CHECK(device->m_Uid >= 1);
885 CHECK(device->m_Name == deviceName);
886 CHECK(device->m_Cores == 0);
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100887
888 // Register a new category not associated to any device
889 const std::string categoryWoDeviceName = "some_category_without_device";
Keith Davis3201eea2019-10-24 17:30:41 +0100890 const Category* categoryWoDevice = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +0100891 CHECK_NOTHROW(categoryWoDevice = counterDirectory.RegisterCategory(categoryWoDeviceName));
892 CHECK(counterDirectory.GetCategoryCount() == 2);
893 CHECK(categoryWoDevice);
894 CHECK(categoryWoDevice->m_Name == categoryWoDeviceName);
895 CHECK(categoryWoDevice->m_Counters.empty());
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100896
Sadik Armagan4c998992020-02-25 12:44:44 +0000897 // Register a new category associated to an invalid device name (already exist)
898 const Category* categoryInvalidDeviceName = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +0100899 CHECK_THROWS_AS(categoryInvalidDeviceName =
Sadik Armagan4c998992020-02-25 12:44:44 +0000900 counterDirectory.RegisterCategory(categoryWoDeviceName),
Cathal Corbett5aa9fd72022-02-25 15:33:28 +0000901 arm::pipe::InvalidArgumentException);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100902 CHECK(counterDirectory.GetCategoryCount() == 2);
903 CHECK(!categoryInvalidDeviceName);
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100904
905 // Register a new category associated to a valid device
906 const std::string categoryWValidDeviceName = "some_category_with_valid_device";
Keith Davis3201eea2019-10-24 17:30:41 +0100907 const Category* categoryWValidDevice = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +0100908 CHECK_NOTHROW(categoryWValidDevice =
Sadik Armagan4c998992020-02-25 12:44:44 +0000909 counterDirectory.RegisterCategory(categoryWValidDeviceName));
Sadik Armagan1625efc2021-06-10 18:24:34 +0100910 CHECK(counterDirectory.GetCategoryCount() == 3);
911 CHECK(categoryWValidDevice);
912 CHECK(categoryWValidDevice != category);
913 CHECK(categoryWValidDevice->m_Name == categoryWValidDeviceName);
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100914
915 // Register a counter set for testing
916 const std::string counterSetName = "some_counter_set";
Keith Davis3201eea2019-10-24 17:30:41 +0100917 const CounterSet* counterSet = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +0100918 CHECK_NOTHROW(counterSet = counterDirectory.RegisterCounterSet(counterSetName));
919 CHECK(counterDirectory.GetCounterSetCount() == 1);
920 CHECK(counterSet);
921 CHECK(counterSet->m_Uid >= 1);
922 CHECK(counterSet->m_Name == counterSetName);
923 CHECK(counterSet->m_Count == 0);
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100924
925 // Register a new category not associated to any counter set
926 const std::string categoryWoCounterSetName = "some_category_without_counter_set";
Keith Davis3201eea2019-10-24 17:30:41 +0100927 const Category* categoryWoCounterSet = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +0100928 CHECK_NOTHROW(categoryWoCounterSet =
Sadik Armagan4c998992020-02-25 12:44:44 +0000929 counterDirectory.RegisterCategory(categoryWoCounterSetName));
Sadik Armagan1625efc2021-06-10 18:24:34 +0100930 CHECK(counterDirectory.GetCategoryCount() == 4);
931 CHECK(categoryWoCounterSet);
932 CHECK(categoryWoCounterSet->m_Name == categoryWoCounterSetName);
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100933
934 // Register a new category associated to a valid counter set
935 const std::string categoryWValidCounterSetName = "some_category_with_valid_counter_set";
Keith Davis3201eea2019-10-24 17:30:41 +0100936 const Category* categoryWValidCounterSet = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +0100937 CHECK_NOTHROW(categoryWValidCounterSet = counterDirectory.RegisterCategory(categoryWValidCounterSetName));
938 CHECK(counterDirectory.GetCategoryCount() == 5);
939 CHECK(categoryWValidCounterSet);
940 CHECK(categoryWValidCounterSet != category);
941 CHECK(categoryWValidCounterSet->m_Name == categoryWValidCounterSetName);
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100942
943 // Register a new category associated to a valid device and counter set
944 const std::string categoryWValidDeviceAndValidCounterSetName = "some_category_with_valid_device_and_counter_set";
Keith Davis3201eea2019-10-24 17:30:41 +0100945 const Category* categoryWValidDeviceAndValidCounterSet = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +0100946 CHECK_NOTHROW(categoryWValidDeviceAndValidCounterSet = counterDirectory.RegisterCategory(
Sadik Armagan4c998992020-02-25 12:44:44 +0000947 categoryWValidDeviceAndValidCounterSetName));
Sadik Armagan1625efc2021-06-10 18:24:34 +0100948 CHECK(counterDirectory.GetCategoryCount() == 6);
949 CHECK(categoryWValidDeviceAndValidCounterSet);
950 CHECK(categoryWValidDeviceAndValidCounterSet != category);
951 CHECK(categoryWValidDeviceAndValidCounterSet->m_Name == categoryWValidDeviceAndValidCounterSetName);
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100952}
953
Sadik Armagan1625efc2021-06-10 18:24:34 +0100954TEST_CASE("CheckCounterDirectoryRegisterDevice")
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100955{
956 CounterDirectory counterDirectory;
Sadik Armagan1625efc2021-06-10 18:24:34 +0100957 CHECK(counterDirectory.GetCategoryCount() == 0);
958 CHECK(counterDirectory.GetDeviceCount() == 0);
959 CHECK(counterDirectory.GetCounterSetCount() == 0);
960 CHECK(counterDirectory.GetCounterCount() == 0);
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100961
962 // Register a device with an invalid name
963 const Device* noDevice = nullptr;
Cathal Corbett5aa9fd72022-02-25 15:33:28 +0000964 CHECK_THROWS_AS(noDevice = counterDirectory.RegisterDevice(""), arm::pipe::InvalidArgumentException);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100965 CHECK(counterDirectory.GetDeviceCount() == 0);
966 CHECK(!noDevice);
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100967
968 // Register a device with an invalid name
Cathal Corbett5aa9fd72022-02-25 15:33:28 +0000969 CHECK_THROWS_AS(noDevice = counterDirectory.RegisterDevice("inv@lid nam€"), arm::pipe::InvalidArgumentException);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100970 CHECK(counterDirectory.GetDeviceCount() == 0);
971 CHECK(!noDevice);
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100972
973 // Register a new device with no cores or parent category
974 const std::string deviceName = "some_device";
Keith Davis3201eea2019-10-24 17:30:41 +0100975 const Device* device = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +0100976 CHECK_NOTHROW(device = counterDirectory.RegisterDevice(deviceName));
977 CHECK(counterDirectory.GetDeviceCount() == 1);
978 CHECK(device);
979 CHECK(device->m_Name == deviceName);
980 CHECK(device->m_Uid >= 1);
981 CHECK(device->m_Cores == 0);
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100982
Matteo Martincigh657ab2d2019-09-18 10:53:24 +0100983 // Try getting an unregistered device
984 const Device* unregisteredDevice = counterDirectory.GetDevice(9999);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100985 CHECK(!unregisteredDevice);
Matteo Martincigh657ab2d2019-09-18 10:53:24 +0100986
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100987 // Get the registered device
988 const Device* registeredDevice = counterDirectory.GetDevice(device->m_Uid);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100989 CHECK(counterDirectory.GetDeviceCount() == 1);
990 CHECK(registeredDevice);
991 CHECK(registeredDevice == device);
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100992
Matteo Martincigh657ab2d2019-09-18 10:53:24 +0100993 // Register a device with the name of a device already registered
994 const Device* deviceSameName = nullptr;
Cathal Corbett5aa9fd72022-02-25 15:33:28 +0000995 CHECK_THROWS_AS(deviceSameName = counterDirectory.RegisterDevice(deviceName), arm::pipe::InvalidArgumentException);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100996 CHECK(counterDirectory.GetDeviceCount() == 1);
997 CHECK(!deviceSameName);
Matteo Martincigh657ab2d2019-09-18 10:53:24 +0100998
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100999 // Register a new device with cores and no parent category
1000 const std::string deviceWCoresName = "some_device_with_cores";
Keith Davis3201eea2019-10-24 17:30:41 +01001001 const Device* deviceWCores = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001002 CHECK_NOTHROW(deviceWCores = counterDirectory.RegisterDevice(deviceWCoresName, 2));
1003 CHECK(counterDirectory.GetDeviceCount() == 2);
1004 CHECK(deviceWCores);
1005 CHECK(deviceWCores->m_Name == deviceWCoresName);
1006 CHECK(deviceWCores->m_Uid >= 1);
1007 CHECK(deviceWCores->m_Uid > device->m_Uid);
1008 CHECK(deviceWCores->m_Cores == 2);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001009
1010 // Get the registered device
1011 const Device* registeredDeviceWCores = counterDirectory.GetDevice(deviceWCores->m_Uid);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001012 CHECK(counterDirectory.GetDeviceCount() == 2);
1013 CHECK(registeredDeviceWCores);
1014 CHECK(registeredDeviceWCores == deviceWCores);
1015 CHECK(registeredDeviceWCores != device);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001016
1017 // Register a new device with cores and invalid parent category
1018 const std::string deviceWCoresWInvalidParentCategoryName = "some_device_with_cores_with_invalid_parent_category";
Keith Davis3201eea2019-10-24 17:30:41 +01001019 const Device* deviceWCoresWInvalidParentCategory = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001020 CHECK_THROWS_AS(deviceWCoresWInvalidParentCategory =
Keith Davis3201eea2019-10-24 17:30:41 +01001021 counterDirectory.RegisterDevice(deviceWCoresWInvalidParentCategoryName, 3, std::string("")),
Cathal Corbett5aa9fd72022-02-25 15:33:28 +00001022 arm::pipe::InvalidArgumentException);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001023 CHECK(counterDirectory.GetDeviceCount() == 2);
1024 CHECK(!deviceWCoresWInvalidParentCategory);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001025
1026 // Register a new device with cores and invalid parent category
1027 const std::string deviceWCoresWInvalidParentCategoryName2 = "some_device_with_cores_with_invalid_parent_category2";
Keith Davis3201eea2019-10-24 17:30:41 +01001028 const Device* deviceWCoresWInvalidParentCategory2 = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001029 CHECK_THROWS_AS(deviceWCoresWInvalidParentCategory2 = counterDirectory.RegisterDevice(
Keith Davis3201eea2019-10-24 17:30:41 +01001030 deviceWCoresWInvalidParentCategoryName2, 3, std::string("invalid_parent_category")),
Cathal Corbett5aa9fd72022-02-25 15:33:28 +00001031 arm::pipe::InvalidArgumentException);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001032 CHECK(counterDirectory.GetDeviceCount() == 2);
1033 CHECK(!deviceWCoresWInvalidParentCategory2);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001034
1035 // Register a category for testing
1036 const std::string categoryName = "some_category";
Keith Davis3201eea2019-10-24 17:30:41 +01001037 const Category* category = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001038 CHECK_NOTHROW(category = counterDirectory.RegisterCategory(categoryName));
1039 CHECK(counterDirectory.GetCategoryCount() == 1);
1040 CHECK(category);
1041 CHECK(category->m_Name == categoryName);
1042 CHECK(category->m_Counters.empty());
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001043
1044 // Register a new device with cores and valid parent category
1045 const std::string deviceWCoresWValidParentCategoryName = "some_device_with_cores_with_valid_parent_category";
Keith Davis3201eea2019-10-24 17:30:41 +01001046 const Device* deviceWCoresWValidParentCategory = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001047 CHECK_NOTHROW(deviceWCoresWValidParentCategory =
Keith Davis3201eea2019-10-24 17:30:41 +01001048 counterDirectory.RegisterDevice(deviceWCoresWValidParentCategoryName, 4, categoryName));
Sadik Armagan1625efc2021-06-10 18:24:34 +01001049 CHECK(counterDirectory.GetDeviceCount() == 3);
1050 CHECK(deviceWCoresWValidParentCategory);
1051 CHECK(deviceWCoresWValidParentCategory->m_Name == deviceWCoresWValidParentCategoryName);
1052 CHECK(deviceWCoresWValidParentCategory->m_Uid >= 1);
1053 CHECK(deviceWCoresWValidParentCategory->m_Uid > device->m_Uid);
1054 CHECK(deviceWCoresWValidParentCategory->m_Uid > deviceWCores->m_Uid);
1055 CHECK(deviceWCoresWValidParentCategory->m_Cores == 4);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001056}
1057
Sadik Armagan1625efc2021-06-10 18:24:34 +01001058TEST_CASE("CheckCounterDirectoryRegisterCounterSet")
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001059{
1060 CounterDirectory counterDirectory;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001061 CHECK(counterDirectory.GetCategoryCount() == 0);
1062 CHECK(counterDirectory.GetDeviceCount() == 0);
1063 CHECK(counterDirectory.GetCounterSetCount() == 0);
1064 CHECK(counterDirectory.GetCounterCount() == 0);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001065
1066 // Register a counter set with an invalid name
1067 const CounterSet* noCounterSet = nullptr;
Cathal Corbett5aa9fd72022-02-25 15:33:28 +00001068 CHECK_THROWS_AS(noCounterSet = counterDirectory.RegisterCounterSet(""), arm::pipe::InvalidArgumentException);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001069 CHECK(counterDirectory.GetCounterSetCount() == 0);
1070 CHECK(!noCounterSet);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001071
1072 // Register a counter set with an invalid name
Sadik Armagan1625efc2021-06-10 18:24:34 +01001073 CHECK_THROWS_AS(noCounterSet = counterDirectory.RegisterCounterSet("invalid name"),
Cathal Corbett5aa9fd72022-02-25 15:33:28 +00001074 arm::pipe::InvalidArgumentException);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001075 CHECK(counterDirectory.GetCounterSetCount() == 0);
1076 CHECK(!noCounterSet);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001077
1078 // Register a new counter set with no count or parent category
1079 const std::string counterSetName = "some_counter_set";
Keith Davis3201eea2019-10-24 17:30:41 +01001080 const CounterSet* counterSet = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001081 CHECK_NOTHROW(counterSet = counterDirectory.RegisterCounterSet(counterSetName));
1082 CHECK(counterDirectory.GetCounterSetCount() == 1);
1083 CHECK(counterSet);
1084 CHECK(counterSet->m_Name == counterSetName);
1085 CHECK(counterSet->m_Uid >= 1);
1086 CHECK(counterSet->m_Count == 0);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001087
Matteo Martincigh657ab2d2019-09-18 10:53:24 +01001088 // Try getting an unregistered counter set
1089 const CounterSet* unregisteredCounterSet = counterDirectory.GetCounterSet(9999);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001090 CHECK(!unregisteredCounterSet);
Matteo Martincigh657ab2d2019-09-18 10:53:24 +01001091
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001092 // Get the registered counter set
1093 const CounterSet* registeredCounterSet = counterDirectory.GetCounterSet(counterSet->m_Uid);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001094 CHECK(counterDirectory.GetCounterSetCount() == 1);
1095 CHECK(registeredCounterSet);
1096 CHECK(registeredCounterSet == counterSet);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001097
Matteo Martincigh657ab2d2019-09-18 10:53:24 +01001098 // Register a counter set with the name of a counter set already registered
1099 const CounterSet* counterSetSameName = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001100 CHECK_THROWS_AS(counterSetSameName = counterDirectory.RegisterCounterSet(counterSetName),
Cathal Corbett5aa9fd72022-02-25 15:33:28 +00001101 arm::pipe::InvalidArgumentException);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001102 CHECK(counterDirectory.GetCounterSetCount() == 1);
1103 CHECK(!counterSetSameName);
Matteo Martincigh657ab2d2019-09-18 10:53:24 +01001104
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001105 // Register a new counter set with count and no parent category
1106 const std::string counterSetWCountName = "some_counter_set_with_count";
Keith Davis3201eea2019-10-24 17:30:41 +01001107 const CounterSet* counterSetWCount = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001108 CHECK_NOTHROW(counterSetWCount = counterDirectory.RegisterCounterSet(counterSetWCountName, 37));
1109 CHECK(counterDirectory.GetCounterSetCount() == 2);
1110 CHECK(counterSetWCount);
1111 CHECK(counterSetWCount->m_Name == counterSetWCountName);
1112 CHECK(counterSetWCount->m_Uid >= 1);
1113 CHECK(counterSetWCount->m_Uid > counterSet->m_Uid);
1114 CHECK(counterSetWCount->m_Count == 37);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001115
1116 // Get the registered counter set
1117 const CounterSet* registeredCounterSetWCount = counterDirectory.GetCounterSet(counterSetWCount->m_Uid);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001118 CHECK(counterDirectory.GetCounterSetCount() == 2);
1119 CHECK(registeredCounterSetWCount);
1120 CHECK(registeredCounterSetWCount == counterSetWCount);
1121 CHECK(registeredCounterSetWCount != counterSet);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001122
1123 // Register a new counter set with count and invalid parent category
1124 const std::string counterSetWCountWInvalidParentCategoryName = "some_counter_set_with_count_"
1125 "with_invalid_parent_category";
1126 const CounterSet* counterSetWCountWInvalidParentCategory = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001127 CHECK_THROWS_AS(counterSetWCountWInvalidParentCategory = counterDirectory.RegisterCounterSet(
Keith Davis3201eea2019-10-24 17:30:41 +01001128 counterSetWCountWInvalidParentCategoryName, 42, std::string("")),
Cathal Corbett5aa9fd72022-02-25 15:33:28 +00001129 arm::pipe::InvalidArgumentException);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001130 CHECK(counterDirectory.GetCounterSetCount() == 2);
1131 CHECK(!counterSetWCountWInvalidParentCategory);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001132
1133 // Register a new counter set with count and invalid parent category
1134 const std::string counterSetWCountWInvalidParentCategoryName2 = "some_counter_set_with_count_"
1135 "with_invalid_parent_category2";
1136 const CounterSet* counterSetWCountWInvalidParentCategory2 = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001137 CHECK_THROWS_AS(counterSetWCountWInvalidParentCategory2 = counterDirectory.RegisterCounterSet(
Keith Davis3201eea2019-10-24 17:30:41 +01001138 counterSetWCountWInvalidParentCategoryName2, 42, std::string("invalid_parent_category")),
Cathal Corbett5aa9fd72022-02-25 15:33:28 +00001139 arm::pipe::InvalidArgumentException);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001140 CHECK(counterDirectory.GetCounterSetCount() == 2);
1141 CHECK(!counterSetWCountWInvalidParentCategory2);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001142
1143 // Register a category for testing
1144 const std::string categoryName = "some_category";
Keith Davis3201eea2019-10-24 17:30:41 +01001145 const Category* category = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001146 CHECK_NOTHROW(category = counterDirectory.RegisterCategory(categoryName));
1147 CHECK(counterDirectory.GetCategoryCount() == 1);
1148 CHECK(category);
1149 CHECK(category->m_Name == categoryName);
1150 CHECK(category->m_Counters.empty());
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001151
1152 // Register a new counter set with count and valid parent category
1153 const std::string counterSetWCountWValidParentCategoryName = "some_counter_set_with_count_"
1154 "with_valid_parent_category";
1155 const CounterSet* counterSetWCountWValidParentCategory = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001156 CHECK_NOTHROW(counterSetWCountWValidParentCategory = counterDirectory.RegisterCounterSet(
Keith Davis3201eea2019-10-24 17:30:41 +01001157 counterSetWCountWValidParentCategoryName, 42, categoryName));
Sadik Armagan1625efc2021-06-10 18:24:34 +01001158 CHECK(counterDirectory.GetCounterSetCount() == 3);
1159 CHECK(counterSetWCountWValidParentCategory);
1160 CHECK(counterSetWCountWValidParentCategory->m_Name == counterSetWCountWValidParentCategoryName);
1161 CHECK(counterSetWCountWValidParentCategory->m_Uid >= 1);
1162 CHECK(counterSetWCountWValidParentCategory->m_Uid > counterSet->m_Uid);
1163 CHECK(counterSetWCountWValidParentCategory->m_Uid > counterSetWCount->m_Uid);
1164 CHECK(counterSetWCountWValidParentCategory->m_Count == 42);
Matteo Martincigh657ab2d2019-09-18 10:53:24 +01001165
Sadik Armagan4c998992020-02-25 12:44:44 +00001166 // Register a counter set associated to a category with invalid name
Matteo Martincigh657ab2d2019-09-18 10:53:24 +01001167 const std::string counterSetSameCategoryName = "some_counter_set_with_invalid_parent_category";
Sadik Armagan4c998992020-02-25 12:44:44 +00001168 const std::string invalidCategoryName = "";
Keith Davis3201eea2019-10-24 17:30:41 +01001169 const CounterSet* counterSetSameCategory = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001170 CHECK_THROWS_AS(counterSetSameCategory =
Sadik Armagan4c998992020-02-25 12:44:44 +00001171 counterDirectory.RegisterCounterSet(counterSetSameCategoryName, 0, invalidCategoryName),
Cathal Corbett5aa9fd72022-02-25 15:33:28 +00001172 arm::pipe::InvalidArgumentException);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001173 CHECK(counterDirectory.GetCounterSetCount() == 3);
1174 CHECK(!counterSetSameCategory);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001175}
1176
Sadik Armagan1625efc2021-06-10 18:24:34 +01001177TEST_CASE("CheckCounterDirectoryRegisterCounter")
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001178{
1179 CounterDirectory counterDirectory;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001180 CHECK(counterDirectory.GetCategoryCount() == 0);
1181 CHECK(counterDirectory.GetDeviceCount() == 0);
1182 CHECK(counterDirectory.GetCounterSetCount() == 0);
1183 CHECK(counterDirectory.GetCounterCount() == 0);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001184
1185 // Register a counter with an invalid parent category name
1186 const Counter* noCounter = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001187 CHECK_THROWS_AS(noCounter =
Keith Davise394bd92019-12-02 15:12:19 +00001188 counterDirectory.RegisterCounter(armnn::profiling::BACKEND_ID,
1189 0,
1190 "",
1191 0,
1192 1,
1193 123.45f,
1194 "valid ",
1195 "name"),
Cathal Corbett5aa9fd72022-02-25 15:33:28 +00001196 arm::pipe::InvalidArgumentException);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001197 CHECK(counterDirectory.GetCounterCount() == 0);
1198 CHECK(!noCounter);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001199
1200 // Register a counter with an invalid parent category name
Sadik Armagan1625efc2021-06-10 18:24:34 +01001201 CHECK_THROWS_AS(noCounter = counterDirectory.RegisterCounter(armnn::profiling::BACKEND_ID,
Cathal Corbett5aa9fd72022-02-25 15:33:28 +00001202 1,
1203 "invalid parent category",
1204 0,
1205 1,
1206 123.45f,
1207 "valid name",
1208 "valid description"),
1209 arm::pipe::InvalidArgumentException);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001210 CHECK(counterDirectory.GetCounterCount() == 0);
1211 CHECK(!noCounter);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001212
1213 // Register a counter with an invalid class
Sadik Armagan1625efc2021-06-10 18:24:34 +01001214 CHECK_THROWS_AS(noCounter = counterDirectory.RegisterCounter(armnn::profiling::BACKEND_ID,
Cathal Corbett5aa9fd72022-02-25 15:33:28 +00001215 2,
1216 "valid_parent_category",
1217 2,
1218 1,
1219 123.45f,
1220 "valid "
1221 "name",
1222 "valid description"),
1223 arm::pipe::InvalidArgumentException);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001224 CHECK(counterDirectory.GetCounterCount() == 0);
1225 CHECK(!noCounter);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001226
1227 // Register a counter with an invalid interpolation
Sadik Armagan1625efc2021-06-10 18:24:34 +01001228 CHECK_THROWS_AS(noCounter = counterDirectory.RegisterCounter(armnn::profiling::BACKEND_ID,
Cathal Corbett5aa9fd72022-02-25 15:33:28 +00001229 4,
1230 "valid_parent_category",
1231 0,
1232 3,
1233 123.45f,
1234 "valid "
1235 "name",
1236 "valid description"),
1237 arm::pipe::InvalidArgumentException);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001238 CHECK(counterDirectory.GetCounterCount() == 0);
1239 CHECK(!noCounter);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001240
1241 // Register a counter with an invalid multiplier
Sadik Armagan1625efc2021-06-10 18:24:34 +01001242 CHECK_THROWS_AS(noCounter = counterDirectory.RegisterCounter(armnn::profiling::BACKEND_ID,
Cathal Corbett5aa9fd72022-02-25 15:33:28 +00001243 5,
1244 "valid_parent_category",
1245 0,
1246 1,
1247 .0f,
1248 "valid "
1249 "name",
1250 "valid description"),
1251 arm::pipe::InvalidArgumentException);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001252 CHECK(counterDirectory.GetCounterCount() == 0);
1253 CHECK(!noCounter);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001254
1255 // Register a counter with an invalid name
Sadik Armagan1625efc2021-06-10 18:24:34 +01001256 CHECK_THROWS_AS(
Keith Davise394bd92019-12-02 15:12:19 +00001257 noCounter = counterDirectory.RegisterCounter(armnn::profiling::BACKEND_ID,
1258 6,
1259 "valid_parent_category",
1260 0,
1261 1,
1262 123.45f,
1263 "",
1264 "valid description"),
Cathal Corbett5aa9fd72022-02-25 15:33:28 +00001265 arm::pipe::InvalidArgumentException);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001266 CHECK(counterDirectory.GetCounterCount() == 0);
1267 CHECK(!noCounter);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001268
1269 // Register a counter with an invalid name
Sadik Armagan1625efc2021-06-10 18:24:34 +01001270 CHECK_THROWS_AS(noCounter = counterDirectory.RegisterCounter(armnn::profiling::BACKEND_ID,
Cathal Corbett5aa9fd72022-02-25 15:33:28 +00001271 7,
1272 "valid_parent_category",
1273 0,
1274 1,
1275 123.45f,
1276 "invalid nam€",
1277 "valid description"),
1278 arm::pipe::InvalidArgumentException);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001279 CHECK(counterDirectory.GetCounterCount() == 0);
1280 CHECK(!noCounter);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001281
1282 // Register a counter with an invalid description
Sadik Armagan1625efc2021-06-10 18:24:34 +01001283 CHECK_THROWS_AS(noCounter =
Keith Davise394bd92019-12-02 15:12:19 +00001284 counterDirectory.RegisterCounter(armnn::profiling::BACKEND_ID,
1285 8,
1286 "valid_parent_category",
1287 0,
1288 1,
1289 123.45f,
1290 "valid name",
1291 ""),
Cathal Corbett5aa9fd72022-02-25 15:33:28 +00001292 arm::pipe::InvalidArgumentException);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001293 CHECK(counterDirectory.GetCounterCount() == 0);
1294 CHECK(!noCounter);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001295
1296 // Register a counter with an invalid description
Sadik Armagan1625efc2021-06-10 18:24:34 +01001297 CHECK_THROWS_AS(noCounter = counterDirectory.RegisterCounter(armnn::profiling::BACKEND_ID,
Cathal Corbett5aa9fd72022-02-25 15:33:28 +00001298 9,
1299 "valid_parent_category",
1300 0,
1301 1,
1302 123.45f,
1303 "valid "
1304 "name",
1305 "inv@lid description"),
1306 arm::pipe::InvalidArgumentException);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001307 CHECK(counterDirectory.GetCounterCount() == 0);
1308 CHECK(!noCounter);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001309
1310 // Register a counter with an invalid unit2
Sadik Armagan1625efc2021-06-10 18:24:34 +01001311 CHECK_THROWS_AS(noCounter = counterDirectory.RegisterCounter(armnn::profiling::BACKEND_ID,
Cathal Corbett5aa9fd72022-02-25 15:33:28 +00001312 10,
1313 "valid_parent_category",
1314 0,
1315 1,
1316 123.45f,
1317 "valid name",
1318 "valid description",
1319 std::string("Mb/s2")),
1320 arm::pipe::InvalidArgumentException);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001321 CHECK(counterDirectory.GetCounterCount() == 0);
1322 CHECK(!noCounter);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001323
1324 // Register a counter with a non-existing parent category name
Sadik Armagan1625efc2021-06-10 18:24:34 +01001325 CHECK_THROWS_AS(noCounter = counterDirectory.RegisterCounter(armnn::profiling::BACKEND_ID,
Cathal Corbett5aa9fd72022-02-25 15:33:28 +00001326 11,
1327 "invalid_parent_category",
1328 0,
1329 1,
1330 123.45f,
1331 "valid name",
1332 "valid description"),
1333 arm::pipe::InvalidArgumentException);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001334 CHECK(counterDirectory.GetCounterCount() == 0);
1335 CHECK(!noCounter);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001336
Matteo Martincigh657ab2d2019-09-18 10:53:24 +01001337 // Try getting an unregistered counter
1338 const Counter* unregisteredCounter = counterDirectory.GetCounter(9999);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001339 CHECK(!unregisteredCounter);
Matteo Martincigh657ab2d2019-09-18 10:53:24 +01001340
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001341 // Register a category for testing
1342 const std::string categoryName = "some_category";
Keith Davis3201eea2019-10-24 17:30:41 +01001343 const Category* category = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001344 CHECK_NOTHROW(category = counterDirectory.RegisterCategory(categoryName));
1345 CHECK(counterDirectory.GetCategoryCount() == 1);
1346 CHECK(category);
1347 CHECK(category->m_Name == categoryName);
1348 CHECK(category->m_Counters.empty());
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001349
1350 // Register a counter with a valid parent category name
1351 const Counter* counter = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001352 CHECK_NOTHROW(
Keith Davise394bd92019-12-02 15:12:19 +00001353 counter = counterDirectory.RegisterCounter(armnn::profiling::BACKEND_ID,
1354 12,
1355 categoryName,
1356 0,
1357 1,
1358 123.45f,
1359 "valid name",
1360 "valid description"));
Sadik Armagan1625efc2021-06-10 18:24:34 +01001361 CHECK(counterDirectory.GetCounterCount() == 1);
1362 CHECK(counter);
1363 CHECK(counter->m_MaxCounterUid == counter->m_Uid);
1364 CHECK(counter->m_Class == 0);
1365 CHECK(counter->m_Interpolation == 1);
1366 CHECK(counter->m_Multiplier == 123.45f);
1367 CHECK(counter->m_Name == "valid name");
1368 CHECK(counter->m_Description == "valid description");
1369 CHECK(counter->m_Units == "");
1370 CHECK(counter->m_DeviceUid == 0);
1371 CHECK(counter->m_CounterSetUid == 0);
1372 CHECK(category->m_Counters.size() == 1);
1373 CHECK(category->m_Counters.back() == counter->m_Uid);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001374
Matteo Martincigh657ab2d2019-09-18 10:53:24 +01001375 // Register a counter with a name of a counter already registered for the given parent category name
1376 const Counter* counterSameName = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001377 CHECK_THROWS_AS(counterSameName =
Keith Davise394bd92019-12-02 15:12:19 +00001378 counterDirectory.RegisterCounter(armnn::profiling::BACKEND_ID,
1379 13,
1380 categoryName,
1381 0,
1382 0,
1383 1.0f,
1384 "valid name",
1385 "valid description",
1386 std::string("description")),
Cathal Corbett5aa9fd72022-02-25 15:33:28 +00001387 arm::pipe::InvalidArgumentException);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001388 CHECK(counterDirectory.GetCounterCount() == 1);
1389 CHECK(!counterSameName);
Matteo Martincigh657ab2d2019-09-18 10:53:24 +01001390
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001391 // Register a counter with a valid parent category name and units
1392 const Counter* counterWUnits = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001393 CHECK_NOTHROW(counterWUnits = counterDirectory.RegisterCounter(armnn::profiling::BACKEND_ID,
Cathal Corbett5aa9fd72022-02-25 15:33:28 +00001394 14,
1395 categoryName,
1396 0,
1397 1,
1398 123.45f,
1399 "valid name 2",
1400 "valid description",
1401 std::string("Mnnsq2"))); // Units
Sadik Armagan1625efc2021-06-10 18:24:34 +01001402 CHECK(counterDirectory.GetCounterCount() == 2);
1403 CHECK(counterWUnits);
1404 CHECK(counterWUnits->m_Uid > counter->m_Uid);
1405 CHECK(counterWUnits->m_MaxCounterUid == counterWUnits->m_Uid);
1406 CHECK(counterWUnits->m_Class == 0);
1407 CHECK(counterWUnits->m_Interpolation == 1);
1408 CHECK(counterWUnits->m_Multiplier == 123.45f);
1409 CHECK(counterWUnits->m_Name == "valid name 2");
1410 CHECK(counterWUnits->m_Description == "valid description");
1411 CHECK(counterWUnits->m_Units == "Mnnsq2");
1412 CHECK(counterWUnits->m_DeviceUid == 0);
1413 CHECK(counterWUnits->m_CounterSetUid == 0);
1414 CHECK(category->m_Counters.size() == 2);
1415 CHECK(category->m_Counters.back() == counterWUnits->m_Uid);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001416
1417 // Register a counter with a valid parent category name and not associated with a device
1418 const Counter* counterWoDevice = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001419 CHECK_NOTHROW(counterWoDevice = counterDirectory.RegisterCounter(armnn::profiling::BACKEND_ID,
Cathal Corbett5aa9fd72022-02-25 15:33:28 +00001420 26,
1421 categoryName,
1422 0,
1423 1,
1424 123.45f,
1425 "valid name 3",
1426 "valid description",
1427 armnn::EmptyOptional(),// Units
1428 armnn::EmptyOptional(),// Number of cores
1429 0)); // Device UID
Sadik Armagan1625efc2021-06-10 18:24:34 +01001430 CHECK(counterDirectory.GetCounterCount() == 3);
1431 CHECK(counterWoDevice);
1432 CHECK(counterWoDevice->m_Uid > counter->m_Uid);
1433 CHECK(counterWoDevice->m_MaxCounterUid == counterWoDevice->m_Uid);
1434 CHECK(counterWoDevice->m_Class == 0);
1435 CHECK(counterWoDevice->m_Interpolation == 1);
1436 CHECK(counterWoDevice->m_Multiplier == 123.45f);
1437 CHECK(counterWoDevice->m_Name == "valid name 3");
1438 CHECK(counterWoDevice->m_Description == "valid description");
1439 CHECK(counterWoDevice->m_Units == "");
1440 CHECK(counterWoDevice->m_DeviceUid == 0);
1441 CHECK(counterWoDevice->m_CounterSetUid == 0);
1442 CHECK(category->m_Counters.size() == 3);
1443 CHECK(category->m_Counters.back() == counterWoDevice->m_Uid);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001444
1445 // Register a counter with a valid parent category name and associated to an invalid device
Sadik Armagan1625efc2021-06-10 18:24:34 +01001446 CHECK_THROWS_AS(noCounter = counterDirectory.RegisterCounter(armnn::profiling::BACKEND_ID,
Cathal Corbett5aa9fd72022-02-25 15:33:28 +00001447 15,
1448 categoryName,
1449 0,
1450 1,
1451 123.45f,
1452 "valid name 4",
1453 "valid description",
1454 armnn::EmptyOptional(), // Units
1455 armnn::EmptyOptional(), // Number of cores
1456 100), // Device UID
1457 arm::pipe::InvalidArgumentException);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001458 CHECK(counterDirectory.GetCounterCount() == 3);
1459 CHECK(!noCounter);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001460
1461 // Register a device for testing
1462 const std::string deviceName = "some_device";
Keith Davis3201eea2019-10-24 17:30:41 +01001463 const Device* device = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001464 CHECK_NOTHROW(device = counterDirectory.RegisterDevice(deviceName));
1465 CHECK(counterDirectory.GetDeviceCount() == 1);
1466 CHECK(device);
1467 CHECK(device->m_Name == deviceName);
1468 CHECK(device->m_Uid >= 1);
1469 CHECK(device->m_Cores == 0);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001470
1471 // Register a counter with a valid parent category name and associated to a device
1472 const Counter* counterWDevice = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001473 CHECK_NOTHROW(counterWDevice = counterDirectory.RegisterCounter(armnn::profiling::BACKEND_ID,
Cathal Corbett5aa9fd72022-02-25 15:33:28 +00001474 16,
1475 categoryName,
1476 0,
1477 1,
1478 123.45f,
1479 "valid name 5",
1480 std::string("valid description"),
1481 armnn::EmptyOptional(), // Units
1482 armnn::EmptyOptional(), // Number of cores
1483 device->m_Uid)); // Device UID
Sadik Armagan1625efc2021-06-10 18:24:34 +01001484 CHECK(counterDirectory.GetCounterCount() == 4);
1485 CHECK(counterWDevice);
1486 CHECK(counterWDevice->m_Uid > counter->m_Uid);
1487 CHECK(counterWDevice->m_MaxCounterUid == counterWDevice->m_Uid);
1488 CHECK(counterWDevice->m_Class == 0);
1489 CHECK(counterWDevice->m_Interpolation == 1);
1490 CHECK(counterWDevice->m_Multiplier == 123.45f);
1491 CHECK(counterWDevice->m_Name == "valid name 5");
1492 CHECK(counterWDevice->m_Description == "valid description");
1493 CHECK(counterWDevice->m_Units == "");
1494 CHECK(counterWDevice->m_DeviceUid == device->m_Uid);
1495 CHECK(counterWDevice->m_CounterSetUid == 0);
1496 CHECK(category->m_Counters.size() == 4);
1497 CHECK(category->m_Counters.back() == counterWDevice->m_Uid);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001498
1499 // Register a counter with a valid parent category name and not associated with a counter set
1500 const Counter* counterWoCounterSet = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001501 CHECK_NOTHROW(counterWoCounterSet = counterDirectory.RegisterCounter(armnn::profiling::BACKEND_ID,
Cathal Corbett5aa9fd72022-02-25 15:33:28 +00001502 17,
1503 categoryName,
1504 0,
1505 1,
1506 123.45f,
1507 "valid name 6",
1508 "valid description",
1509 armnn::EmptyOptional(),// Units
1510 armnn::EmptyOptional(),// No of cores
1511 armnn::EmptyOptional(),// Device UID
1512 0)); // CounterSet UID
Sadik Armagan1625efc2021-06-10 18:24:34 +01001513 CHECK(counterDirectory.GetCounterCount() == 5);
1514 CHECK(counterWoCounterSet);
1515 CHECK(counterWoCounterSet->m_Uid > counter->m_Uid);
1516 CHECK(counterWoCounterSet->m_MaxCounterUid == counterWoCounterSet->m_Uid);
1517 CHECK(counterWoCounterSet->m_Class == 0);
1518 CHECK(counterWoCounterSet->m_Interpolation == 1);
1519 CHECK(counterWoCounterSet->m_Multiplier == 123.45f);
1520 CHECK(counterWoCounterSet->m_Name == "valid name 6");
1521 CHECK(counterWoCounterSet->m_Description == "valid description");
1522 CHECK(counterWoCounterSet->m_Units == "");
1523 CHECK(counterWoCounterSet->m_DeviceUid == 0);
1524 CHECK(counterWoCounterSet->m_CounterSetUid == 0);
1525 CHECK(category->m_Counters.size() == 5);
1526 CHECK(category->m_Counters.back() == counterWoCounterSet->m_Uid);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001527
1528 // Register a counter with a valid parent category name and associated to an invalid counter set
Sadik Armagan1625efc2021-06-10 18:24:34 +01001529 CHECK_THROWS_AS(noCounter = counterDirectory.RegisterCounter(armnn::profiling::BACKEND_ID,
Cathal Corbett5aa9fd72022-02-25 15:33:28 +00001530 18,
1531 categoryName,
1532 0,
1533 1,
1534 123.45f,
1535 "valid ",
1536 "name 7",
1537 std::string("valid description"),
1538 armnn::EmptyOptional(), // Units
1539 armnn::EmptyOptional(), // Number of cores
1540 100), // Counter set UID
1541 arm::pipe::InvalidArgumentException);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001542 CHECK(counterDirectory.GetCounterCount() == 5);
1543 CHECK(!noCounter);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001544
1545 // Register a counter with a valid parent category name and with a given number of cores
1546 const Counter* counterWNumberOfCores = nullptr;
Keith Davis3201eea2019-10-24 17:30:41 +01001547 uint16_t numberOfCores = 15;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001548 CHECK_NOTHROW(counterWNumberOfCores = counterDirectory.RegisterCounter(
Keith Davise394bd92019-12-02 15:12:19 +00001549 armnn::profiling::BACKEND_ID, 50,
Keith Davis3201eea2019-10-24 17:30:41 +01001550 categoryName, 0, 1, 123.45f, "valid name 8", "valid description",
1551 armnn::EmptyOptional(), // Units
1552 numberOfCores, // Number of cores
1553 armnn::EmptyOptional(), // Device UID
1554 armnn::EmptyOptional())); // Counter set UID
Sadik Armagan1625efc2021-06-10 18:24:34 +01001555 CHECK(counterDirectory.GetCounterCount() == 20);
1556 CHECK(counterWNumberOfCores);
1557 CHECK(counterWNumberOfCores->m_Uid > counter->m_Uid);
1558 CHECK(counterWNumberOfCores->m_MaxCounterUid == counterWNumberOfCores->m_Uid + numberOfCores - 1);
1559 CHECK(counterWNumberOfCores->m_Class == 0);
1560 CHECK(counterWNumberOfCores->m_Interpolation == 1);
1561 CHECK(counterWNumberOfCores->m_Multiplier == 123.45f);
1562 CHECK(counterWNumberOfCores->m_Name == "valid name 8");
1563 CHECK(counterWNumberOfCores->m_Description == "valid description");
1564 CHECK(counterWNumberOfCores->m_Units == "");
1565 CHECK(counterWNumberOfCores->m_DeviceUid == 0);
1566 CHECK(counterWNumberOfCores->m_CounterSetUid == 0);
1567 CHECK(category->m_Counters.size() == 20);
Keith Davis3201eea2019-10-24 17:30:41 +01001568 for (size_t i = 0; i < numberOfCores; i++)
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001569 {
Sadik Armagan1625efc2021-06-10 18:24:34 +01001570 CHECK(category->m_Counters[category->m_Counters.size() - numberOfCores + i] ==
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001571 counterWNumberOfCores->m_Uid + i);
1572 }
1573
1574 // Register a multi-core device for testing
1575 const std::string multiCoreDeviceName = "some_multi_core_device";
Keith Davis3201eea2019-10-24 17:30:41 +01001576 const Device* multiCoreDevice = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001577 CHECK_NOTHROW(multiCoreDevice = counterDirectory.RegisterDevice(multiCoreDeviceName, 4));
1578 CHECK(counterDirectory.GetDeviceCount() == 2);
1579 CHECK(multiCoreDevice);
1580 CHECK(multiCoreDevice->m_Name == multiCoreDeviceName);
1581 CHECK(multiCoreDevice->m_Uid >= 1);
1582 CHECK(multiCoreDevice->m_Cores == 4);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001583
1584 // Register a counter with a valid parent category name and associated to the multi-core device
1585 const Counter* counterWMultiCoreDevice = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001586 CHECK_NOTHROW(counterWMultiCoreDevice = counterDirectory.RegisterCounter(
Keith Davise394bd92019-12-02 15:12:19 +00001587 armnn::profiling::BACKEND_ID, 19, categoryName, 0, 1,
1588 123.45f, "valid name 9", "valid description",
Keith Davis3201eea2019-10-24 17:30:41 +01001589 armnn::EmptyOptional(), // Units
1590 armnn::EmptyOptional(), // Number of cores
1591 multiCoreDevice->m_Uid, // Device UID
1592 armnn::EmptyOptional())); // Counter set UID
Sadik Armagan1625efc2021-06-10 18:24:34 +01001593 CHECK(counterDirectory.GetCounterCount() == 24);
1594 CHECK(counterWMultiCoreDevice);
1595 CHECK(counterWMultiCoreDevice->m_Uid > counter->m_Uid);
1596 CHECK(counterWMultiCoreDevice->m_MaxCounterUid ==
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001597 counterWMultiCoreDevice->m_Uid + multiCoreDevice->m_Cores - 1);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001598 CHECK(counterWMultiCoreDevice->m_Class == 0);
1599 CHECK(counterWMultiCoreDevice->m_Interpolation == 1);
1600 CHECK(counterWMultiCoreDevice->m_Multiplier == 123.45f);
1601 CHECK(counterWMultiCoreDevice->m_Name == "valid name 9");
1602 CHECK(counterWMultiCoreDevice->m_Description == "valid description");
1603 CHECK(counterWMultiCoreDevice->m_Units == "");
1604 CHECK(counterWMultiCoreDevice->m_DeviceUid == multiCoreDevice->m_Uid);
1605 CHECK(counterWMultiCoreDevice->m_CounterSetUid == 0);
1606 CHECK(category->m_Counters.size() == 24);
Keith Davis3201eea2019-10-24 17:30:41 +01001607 for (size_t i = 0; i < 4; i++)
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001608 {
Sadik Armagan1625efc2021-06-10 18:24:34 +01001609 CHECK(category->m_Counters[category->m_Counters.size() - 4 + i] == counterWMultiCoreDevice->m_Uid + i);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001610 }
1611
Matteo Martincigh657ab2d2019-09-18 10:53:24 +01001612 // Register a multi-core device associate to a parent category for testing
1613 const std::string multiCoreDeviceNameWParentCategory = "some_multi_core_device_with_parent_category";
Keith Davis3201eea2019-10-24 17:30:41 +01001614 const Device* multiCoreDeviceWParentCategory = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001615 CHECK_NOTHROW(multiCoreDeviceWParentCategory =
Keith Davis3201eea2019-10-24 17:30:41 +01001616 counterDirectory.RegisterDevice(multiCoreDeviceNameWParentCategory, 2, categoryName));
Sadik Armagan1625efc2021-06-10 18:24:34 +01001617 CHECK(counterDirectory.GetDeviceCount() == 3);
1618 CHECK(multiCoreDeviceWParentCategory);
1619 CHECK(multiCoreDeviceWParentCategory->m_Name == multiCoreDeviceNameWParentCategory);
1620 CHECK(multiCoreDeviceWParentCategory->m_Uid >= 1);
1621 CHECK(multiCoreDeviceWParentCategory->m_Cores == 2);
Matteo Martincigh657ab2d2019-09-18 10:53:24 +01001622
1623 // Register a counter with a valid parent category name and getting the number of cores of the multi-core device
1624 // associated to that category
1625 const Counter* counterWMultiCoreDeviceWParentCategory = nullptr;
Sadik Armagan4c998992020-02-25 12:44:44 +00001626 uint16_t numberOfCourse = multiCoreDeviceWParentCategory->m_Cores;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001627 CHECK_NOTHROW(counterWMultiCoreDeviceWParentCategory =
Jim Flynnbbfe6032020-07-20 16:57:44 +01001628 counterDirectory.RegisterCounter(
1629 armnn::profiling::BACKEND_ID,
1630 100,
1631 categoryName,
1632 0,
1633 1,
1634 123.45f,
1635 "valid name 10",
1636 "valid description",
1637 armnn::EmptyOptional(), // Units
1638 numberOfCourse, // Number of cores
1639 armnn::EmptyOptional(), // Device UID
1640 armnn::EmptyOptional()));// Counter set UID
Sadik Armagan1625efc2021-06-10 18:24:34 +01001641 CHECK(counterDirectory.GetCounterCount() == 26);
1642 CHECK(counterWMultiCoreDeviceWParentCategory);
1643 CHECK(counterWMultiCoreDeviceWParentCategory->m_Uid > counter->m_Uid);
1644 CHECK(counterWMultiCoreDeviceWParentCategory->m_MaxCounterUid ==
Matteo Martincigh657ab2d2019-09-18 10:53:24 +01001645 counterWMultiCoreDeviceWParentCategory->m_Uid + multiCoreDeviceWParentCategory->m_Cores - 1);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001646 CHECK(counterWMultiCoreDeviceWParentCategory->m_Class == 0);
1647 CHECK(counterWMultiCoreDeviceWParentCategory->m_Interpolation == 1);
1648 CHECK(counterWMultiCoreDeviceWParentCategory->m_Multiplier == 123.45f);
1649 CHECK(counterWMultiCoreDeviceWParentCategory->m_Name == "valid name 10");
1650 CHECK(counterWMultiCoreDeviceWParentCategory->m_Description == "valid description");
1651 CHECK(counterWMultiCoreDeviceWParentCategory->m_Units == "");
1652 CHECK(category->m_Counters.size() == 26);
Keith Davis3201eea2019-10-24 17:30:41 +01001653 for (size_t i = 0; i < 2; i++)
Matteo Martincigh657ab2d2019-09-18 10:53:24 +01001654 {
Sadik Armagan1625efc2021-06-10 18:24:34 +01001655 CHECK(category->m_Counters[category->m_Counters.size() - 2 + i] ==
Matteo Martincigh657ab2d2019-09-18 10:53:24 +01001656 counterWMultiCoreDeviceWParentCategory->m_Uid + i);
1657 }
1658
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001659 // Register a counter set for testing
1660 const std::string counterSetName = "some_counter_set";
Keith Davis3201eea2019-10-24 17:30:41 +01001661 const CounterSet* counterSet = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001662 CHECK_NOTHROW(counterSet = counterDirectory.RegisterCounterSet(counterSetName));
1663 CHECK(counterDirectory.GetCounterSetCount() == 1);
1664 CHECK(counterSet);
1665 CHECK(counterSet->m_Name == counterSetName);
1666 CHECK(counterSet->m_Uid >= 1);
1667 CHECK(counterSet->m_Count == 0);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001668
1669 // Register a counter with a valid parent category name and associated to a counter set
1670 const Counter* counterWCounterSet = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001671 CHECK_NOTHROW(counterWCounterSet = counterDirectory.RegisterCounter(
Keith Davise394bd92019-12-02 15:12:19 +00001672 armnn::profiling::BACKEND_ID, 300,
Keith Davis3201eea2019-10-24 17:30:41 +01001673 categoryName, 0, 1, 123.45f, "valid name 11", "valid description",
1674 armnn::EmptyOptional(), // Units
1675 0, // Number of cores
1676 armnn::EmptyOptional(), // Device UID
1677 counterSet->m_Uid)); // Counter set UID
Sadik Armagan1625efc2021-06-10 18:24:34 +01001678 CHECK(counterDirectory.GetCounterCount() == 27);
1679 CHECK(counterWCounterSet);
1680 CHECK(counterWCounterSet->m_Uid > counter->m_Uid);
1681 CHECK(counterWCounterSet->m_MaxCounterUid == counterWCounterSet->m_Uid);
1682 CHECK(counterWCounterSet->m_Class == 0);
1683 CHECK(counterWCounterSet->m_Interpolation == 1);
1684 CHECK(counterWCounterSet->m_Multiplier == 123.45f);
1685 CHECK(counterWCounterSet->m_Name == "valid name 11");
1686 CHECK(counterWCounterSet->m_Description == "valid description");
1687 CHECK(counterWCounterSet->m_Units == "");
1688 CHECK(counterWCounterSet->m_DeviceUid == 0);
1689 CHECK(counterWCounterSet->m_CounterSetUid == counterSet->m_Uid);
1690 CHECK(category->m_Counters.size() == 27);
1691 CHECK(category->m_Counters.back() == counterWCounterSet->m_Uid);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001692
1693 // Register a counter with a valid parent category name and associated to a device and a counter set
1694 const Counter* counterWDeviceWCounterSet = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001695 CHECK_NOTHROW(counterWDeviceWCounterSet = counterDirectory.RegisterCounter(
Keith Davise394bd92019-12-02 15:12:19 +00001696 armnn::profiling::BACKEND_ID, 23,
Keith Davis3201eea2019-10-24 17:30:41 +01001697 categoryName, 0, 1, 123.45f, "valid name 12", "valid description",
1698 armnn::EmptyOptional(), // Units
1699 1, // Number of cores
1700 device->m_Uid, // Device UID
1701 counterSet->m_Uid)); // Counter set UID
Sadik Armagan1625efc2021-06-10 18:24:34 +01001702 CHECK(counterDirectory.GetCounterCount() == 28);
1703 CHECK(counterWDeviceWCounterSet);
1704 CHECK(counterWDeviceWCounterSet->m_Uid > counter->m_Uid);
1705 CHECK(counterWDeviceWCounterSet->m_MaxCounterUid == counterWDeviceWCounterSet->m_Uid);
1706 CHECK(counterWDeviceWCounterSet->m_Class == 0);
1707 CHECK(counterWDeviceWCounterSet->m_Interpolation == 1);
1708 CHECK(counterWDeviceWCounterSet->m_Multiplier == 123.45f);
1709 CHECK(counterWDeviceWCounterSet->m_Name == "valid name 12");
1710 CHECK(counterWDeviceWCounterSet->m_Description == "valid description");
1711 CHECK(counterWDeviceWCounterSet->m_Units == "");
1712 CHECK(counterWDeviceWCounterSet->m_DeviceUid == device->m_Uid);
1713 CHECK(counterWDeviceWCounterSet->m_CounterSetUid == counterSet->m_Uid);
1714 CHECK(category->m_Counters.size() == 28);
1715 CHECK(category->m_Counters.back() == counterWDeviceWCounterSet->m_Uid);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001716
1717 // Register another category for testing
1718 const std::string anotherCategoryName = "some_other_category";
Keith Davis3201eea2019-10-24 17:30:41 +01001719 const Category* anotherCategory = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001720 CHECK_NOTHROW(anotherCategory = counterDirectory.RegisterCategory(anotherCategoryName));
1721 CHECK(counterDirectory.GetCategoryCount() == 2);
1722 CHECK(anotherCategory);
1723 CHECK(anotherCategory != category);
1724 CHECK(anotherCategory->m_Name == anotherCategoryName);
1725 CHECK(anotherCategory->m_Counters.empty());
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001726
1727 // Register a counter to the other category
1728 const Counter* anotherCounter = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001729 CHECK_NOTHROW(anotherCounter = counterDirectory.RegisterCounter(armnn::profiling::BACKEND_ID, 24,
Cathal Corbett5aa9fd72022-02-25 15:33:28 +00001730 anotherCategoryName, 1, 0, .00043f,
1731 "valid name", "valid description",
1732 armnn::EmptyOptional(), // Units
1733 armnn::EmptyOptional(), // Number of cores
1734 device->m_Uid, // Device UID
1735 counterSet->m_Uid)); // Counter set UID
Sadik Armagan1625efc2021-06-10 18:24:34 +01001736 CHECK(counterDirectory.GetCounterCount() == 29);
1737 CHECK(anotherCounter);
1738 CHECK(anotherCounter->m_MaxCounterUid == anotherCounter->m_Uid);
1739 CHECK(anotherCounter->m_Class == 1);
1740 CHECK(anotherCounter->m_Interpolation == 0);
1741 CHECK(anotherCounter->m_Multiplier == .00043f);
1742 CHECK(anotherCounter->m_Name == "valid name");
1743 CHECK(anotherCounter->m_Description == "valid description");
1744 CHECK(anotherCounter->m_Units == "");
1745 CHECK(anotherCounter->m_DeviceUid == device->m_Uid);
1746 CHECK(anotherCounter->m_CounterSetUid == counterSet->m_Uid);
1747 CHECK(anotherCategory->m_Counters.size() == 1);
1748 CHECK(anotherCategory->m_Counters.back() == anotherCounter->m_Uid);
Matteo Martincighab173e92019-09-05 12:02:04 +01001749}
1750
Sadik Armagan1625efc2021-06-10 18:24:34 +01001751TEST_CASE("CounterSelectionCommandHandlerParseData")
Ferran Balaguer1b941722019-08-28 16:57:18 +01001752{
Matteo Martincigh5d737fb2019-10-07 13:05:13 +01001753 ProfilingStateMachine profilingStateMachine;
1754
Ferran Balaguer1b941722019-08-28 16:57:18 +01001755 class TestCaptureThread : public IPeriodicCounterCapture
1756 {
Keith Davis3201eea2019-10-24 17:30:41 +01001757 void Start() override
1758 {}
1759 void Stop() override
1760 {}
Ferran Balaguer1b941722019-08-28 16:57:18 +01001761 };
1762
Matteo Martincighe8485382019-10-10 14:08:21 +01001763 class TestReadCounterValues : public IReadCounterValues
1764 {
Keith Davis3201eea2019-10-24 17:30:41 +01001765 bool IsCounterRegistered(uint16_t counterUid) const override
1766 {
Jan Eilers8eb25602020-03-09 12:13:48 +00001767 armnn::IgnoreUnused(counterUid);
Keith Davis3201eea2019-10-24 17:30:41 +01001768 return true;
1769 }
1770 uint16_t GetCounterCount() const override
1771 {
1772 return 0;
1773 }
Finn Williamsf3fcf322020-05-11 14:38:02 +01001774 uint32_t GetAbsoluteCounterValue(uint16_t counterUid) const override
1775 {
1776 armnn::IgnoreUnused(counterUid);
1777 return 0;
1778 }
1779 uint32_t GetDeltaCounterValue(uint16_t counterUid) override
Keith Davis3201eea2019-10-24 17:30:41 +01001780 {
Jan Eilers8eb25602020-03-09 12:13:48 +00001781 armnn::IgnoreUnused(counterUid);
Keith Davis3201eea2019-10-24 17:30:41 +01001782 return 0;
1783 }
Matteo Martincighe8485382019-10-10 14:08:21 +01001784 };
Jim Flynn397043f2019-10-17 17:37:10 +01001785 const uint32_t familyId = 0;
Ferran Balaguer1b941722019-08-28 16:57:18 +01001786 const uint32_t packetId = 0x40000;
1787
1788 uint32_t version = 1;
Finn Williams032bc742020-02-12 11:02:34 +00001789 const std::unordered_map<armnn::BackendId,
Cathal Corbett5aa9fd72022-02-25 15:33:28 +00001790 std::shared_ptr<IBackendProfilingContext>> backendProfilingContext;
Finn Williams032bc742020-02-12 11:02:34 +00001791 CounterIdMap counterIdMap;
Ferran Balaguer1b941722019-08-28 16:57:18 +01001792 Holder holder;
1793 TestCaptureThread captureThread;
Matteo Martincighe8485382019-10-10 14:08:21 +01001794 TestReadCounterValues readCounterValues;
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01001795 MockBufferManager mockBuffer(512);
Sadik Armagan3896b472020-02-10 12:24:15 +00001796 SendCounterPacket sendCounterPacket(mockBuffer);
1797 SendThread sendThread(profilingStateMachine, mockBuffer, sendCounterPacket);
Ferran Balaguer1b941722019-08-28 16:57:18 +01001798
Matthew Sloyan371b70e2020-09-11 10:14:57 +01001799 uint32_t sizeOfUint32 = armnn::numeric_cast<uint32_t>(sizeof(uint32_t));
1800 uint32_t sizeOfUint16 = armnn::numeric_cast<uint32_t>(sizeof(uint16_t));
Ferran Balaguer1b941722019-08-28 16:57:18 +01001801
1802 // Data with period and counters
Jim Flynn4c9ed1d2022-01-23 23:57:20 +00001803 uint32_t period1 = arm::pipe::LOWEST_CAPTURE_PERIOD;
Ferran Balaguer1b941722019-08-28 16:57:18 +01001804 uint32_t dataLength1 = 8;
Keith Davis3201eea2019-10-24 17:30:41 +01001805 uint32_t offset = 0;
Ferran Balaguer1b941722019-08-28 16:57:18 +01001806
Matteo Martincigh67ef2a52019-10-10 13:29:02 +01001807 std::unique_ptr<unsigned char[]> uniqueData1 = std::make_unique<unsigned char[]>(dataLength1);
Keith Davis3201eea2019-10-24 17:30:41 +01001808 unsigned char* data1 = reinterpret_cast<unsigned char*>(uniqueData1.get());
FinnWilliamsArma0c78712019-09-16 12:06:47 +01001809
Ferran Balaguer1b941722019-08-28 16:57:18 +01001810 WriteUint32(data1, offset, period1);
1811 offset += sizeOfUint32;
1812 WriteUint16(data1, offset, 4000);
1813 offset += sizeOfUint16;
1814 WriteUint16(data1, offset, 5000);
1815
Jim Flynnbbfe6032020-07-20 16:57:44 +01001816 arm::pipe::Packet packetA(packetId, dataLength1, uniqueData1);
Ferran Balaguer1b941722019-08-28 16:57:18 +01001817
Finn Williams032bc742020-02-12 11:02:34 +00001818 PeriodicCounterSelectionCommandHandler commandHandler(familyId, packetId, version, backendProfilingContext,
1819 counterIdMap, holder, 10000u, captureThread,
Keith Davis3201eea2019-10-24 17:30:41 +01001820 readCounterValues, sendCounterPacket, profilingStateMachine);
Ferran Balaguer1b941722019-08-28 16:57:18 +01001821
Matteo Martincighe8485382019-10-10 14:08:21 +01001822 profilingStateMachine.TransitionToState(ProfilingState::Uninitialised);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001823 CHECK_THROWS_AS(commandHandler(packetA), armnn::RuntimeException);
Matteo Martincighe8485382019-10-10 14:08:21 +01001824 profilingStateMachine.TransitionToState(ProfilingState::NotConnected);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001825 CHECK_THROWS_AS(commandHandler(packetA), armnn::RuntimeException);
Matteo Martincighe8485382019-10-10 14:08:21 +01001826 profilingStateMachine.TransitionToState(ProfilingState::WaitingForAck);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001827 CHECK_THROWS_AS(commandHandler(packetA), armnn::RuntimeException);
Matteo Martincighe8485382019-10-10 14:08:21 +01001828 profilingStateMachine.TransitionToState(ProfilingState::Active);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001829 CHECK_NOTHROW(commandHandler(packetA));
Matteo Martincighe8485382019-10-10 14:08:21 +01001830
1831 const std::vector<uint16_t> counterIdsA = holder.GetCaptureData().GetCounterIds();
Ferran Balaguer1b941722019-08-28 16:57:18 +01001832
Sadik Armagan1625efc2021-06-10 18:24:34 +01001833 CHECK(holder.GetCaptureData().GetCapturePeriod() == period1);
1834 CHECK(counterIdsA.size() == 2);
1835 CHECK(counterIdsA[0] == 4000);
1836 CHECK(counterIdsA[1] == 5000);
Ferran Balaguer1b941722019-08-28 16:57:18 +01001837
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01001838 auto readBuffer = mockBuffer.GetReadableBuffer();
Ferran Balaguer1b941722019-08-28 16:57:18 +01001839
1840 offset = 0;
1841
1842 uint32_t headerWord0 = ReadUint32(readBuffer, offset);
1843 offset += sizeOfUint32;
1844 uint32_t headerWord1 = ReadUint32(readBuffer, offset);
1845 offset += sizeOfUint32;
1846 uint32_t period = ReadUint32(readBuffer, offset);
1847
Sadik Armagan1625efc2021-06-10 18:24:34 +01001848 CHECK(((headerWord0 >> 26) & 0x3F) == 0); // packet family
1849 CHECK(((headerWord0 >> 16) & 0x3FF) == 4); // packet id
1850 CHECK(headerWord1 == 8); // data length
Jim Flynn4c9ed1d2022-01-23 23:57:20 +00001851 CHECK(period == arm::pipe::LOWEST_CAPTURE_PERIOD); // capture period
Ferran Balaguer1b941722019-08-28 16:57:18 +01001852
1853 uint16_t counterId = 0;
1854 offset += sizeOfUint32;
1855 counterId = ReadUint16(readBuffer, offset);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001856 CHECK(counterId == 4000);
Ferran Balaguer1b941722019-08-28 16:57:18 +01001857 offset += sizeOfUint16;
1858 counterId = ReadUint16(readBuffer, offset);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001859 CHECK(counterId == 5000);
Ferran Balaguer1b941722019-08-28 16:57:18 +01001860
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01001861 mockBuffer.MarkRead(readBuffer);
1862
Ferran Balaguer1b941722019-08-28 16:57:18 +01001863 // Data with period only
Colm Donelan02705242019-11-14 14:19:07 +00001864 uint32_t period2 = 9000; // We'll specify a value below LOWEST_CAPTURE_PERIOD. It should be pulled upwards.
Ferran Balaguer1b941722019-08-28 16:57:18 +01001865 uint32_t dataLength2 = 4;
Ferran Balaguer1b941722019-08-28 16:57:18 +01001866
Matteo Martincigh67ef2a52019-10-10 13:29:02 +01001867 std::unique_ptr<unsigned char[]> uniqueData2 = std::make_unique<unsigned char[]>(dataLength2);
Ferran Balaguer1b941722019-08-28 16:57:18 +01001868
FinnWilliamsArma0c78712019-09-16 12:06:47 +01001869 WriteUint32(reinterpret_cast<unsigned char*>(uniqueData2.get()), 0, period2);
1870
Jim Flynnbbfe6032020-07-20 16:57:44 +01001871 arm::pipe::Packet packetB(packetId, dataLength2, uniqueData2);
Ferran Balaguer1b941722019-08-28 16:57:18 +01001872
1873 commandHandler(packetB);
1874
Matteo Martincighe8485382019-10-10 14:08:21 +01001875 const std::vector<uint16_t> counterIdsB = holder.GetCaptureData().GetCounterIds();
Ferran Balaguer1b941722019-08-28 16:57:18 +01001876
Colm Donelan02705242019-11-14 14:19:07 +00001877 // Value should have been pulled up from 9000 to LOWEST_CAPTURE_PERIOD.
Jim Flynn4c9ed1d2022-01-23 23:57:20 +00001878 CHECK(holder.GetCaptureData().GetCapturePeriod() == arm::pipe::LOWEST_CAPTURE_PERIOD);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001879 CHECK(counterIdsB.size() == 0);
Ferran Balaguer1b941722019-08-28 16:57:18 +01001880
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01001881 readBuffer = mockBuffer.GetReadableBuffer();
Ferran Balaguer1b941722019-08-28 16:57:18 +01001882
1883 offset = 0;
1884
1885 headerWord0 = ReadUint32(readBuffer, offset);
1886 offset += sizeOfUint32;
1887 headerWord1 = ReadUint32(readBuffer, offset);
1888 offset += sizeOfUint32;
1889 period = ReadUint32(readBuffer, offset);
1890
Jim Flynn4c9ed1d2022-01-23 23:57:20 +00001891 CHECK(((headerWord0 >> 26) & 0x3F) == 0); // packet family
1892 CHECK(((headerWord0 >> 16) & 0x3FF) == 4); // packet id
1893 CHECK(headerWord1 == 4); // data length
1894 CHECK(period == arm::pipe::LOWEST_CAPTURE_PERIOD); // capture period
Ferran Balaguer1b941722019-08-28 16:57:18 +01001895}
1896
Sadik Armagan1625efc2021-06-10 18:24:34 +01001897TEST_CASE("CheckTimelineActivationAndDeactivation")
Keith Davis33ed2212020-03-30 10:43:41 +01001898{
1899 class TestReportStructure : public IReportStructure
1900 {
1901 public:
1902 virtual void ReportStructure() override
1903 {
1904 m_ReportStructureCalled = true;
1905 }
1906
1907 bool m_ReportStructureCalled = false;
1908 };
1909
1910 class TestNotifyBackends : public INotifyBackends
1911 {
1912 public:
1913 TestNotifyBackends() : m_timelineReporting(false) {}
1914 virtual void NotifyBackendsForTimelineReporting() override
1915 {
1916 m_TestNotifyBackendsCalled = m_timelineReporting.load();
1917 }
1918
1919 bool m_TestNotifyBackendsCalled = false;
1920 std::atomic<bool> m_timelineReporting;
1921 };
1922
Jim Flynnbbfe6032020-07-20 16:57:44 +01001923 arm::pipe::PacketVersionResolver packetVersionResolver;
Keith Davis33ed2212020-03-30 10:43:41 +01001924
1925 BufferManager bufferManager(512);
1926 SendTimelinePacket sendTimelinePacket(bufferManager);
1927 ProfilingStateMachine stateMachine;
1928 TestReportStructure testReportStructure;
1929 TestNotifyBackends testNotifyBackends;
1930
Cathal Corbett5aa9fd72022-02-25 15:33:28 +00001931 ActivateTimelineReportingCommandHandler activateTimelineReportingCommandHandler(0,
Keith Davis33ed2212020-03-30 10:43:41 +01001932 6,
1933 packetVersionResolver.ResolvePacketVersion(0, 6)
1934 .GetEncodedValue(),
1935 sendTimelinePacket,
1936 stateMachine,
1937 testReportStructure,
1938 testNotifyBackends.m_timelineReporting,
1939 testNotifyBackends);
1940
1941 // Write an "ActivateTimelineReporting" packet into the mock profiling connection, to simulate an input from an
1942 // external profiling service
1943 const uint32_t packetFamily1 = 0;
1944 const uint32_t packetId1 = 6;
1945 uint32_t packetHeader1 = ConstructHeader(packetFamily1, packetId1);
1946
1947 // Create the ActivateTimelineReportingPacket
Jim Flynnbbfe6032020-07-20 16:57:44 +01001948 arm::pipe::Packet ActivateTimelineReportingPacket(packetHeader1); // Length == 0
Keith Davis33ed2212020-03-30 10:43:41 +01001949
Sadik Armagan1625efc2021-06-10 18:24:34 +01001950 CHECK_THROWS_AS(
Keith Davis33ed2212020-03-30 10:43:41 +01001951 activateTimelineReportingCommandHandler.operator()(ActivateTimelineReportingPacket), armnn::Exception);
1952
1953 stateMachine.TransitionToState(ProfilingState::NotConnected);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001954 CHECK_THROWS_AS(
Keith Davis33ed2212020-03-30 10:43:41 +01001955 activateTimelineReportingCommandHandler.operator()(ActivateTimelineReportingPacket), armnn::Exception);
1956
1957 stateMachine.TransitionToState(ProfilingState::WaitingForAck);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001958 CHECK_THROWS_AS(
Keith Davis33ed2212020-03-30 10:43:41 +01001959 activateTimelineReportingCommandHandler.operator()(ActivateTimelineReportingPacket), armnn::Exception);
1960
1961 stateMachine.TransitionToState(ProfilingState::Active);
1962 activateTimelineReportingCommandHandler.operator()(ActivateTimelineReportingPacket);
1963
Sadik Armagan1625efc2021-06-10 18:24:34 +01001964 CHECK(testReportStructure.m_ReportStructureCalled);
1965 CHECK(testNotifyBackends.m_TestNotifyBackendsCalled);
1966 CHECK(testNotifyBackends.m_timelineReporting.load());
Keith Davis33ed2212020-03-30 10:43:41 +01001967
1968 DeactivateTimelineReportingCommandHandler deactivateTimelineReportingCommandHandler(0,
1969 7,
1970 packetVersionResolver.ResolvePacketVersion(0, 7).GetEncodedValue(),
1971 testNotifyBackends.m_timelineReporting,
1972 stateMachine,
1973 testNotifyBackends);
1974
1975 const uint32_t packetFamily2 = 0;
1976 const uint32_t packetId2 = 7;
1977 uint32_t packetHeader2 = ConstructHeader(packetFamily2, packetId2);
1978
1979 // Create the DeactivateTimelineReportingPacket
Jim Flynnbbfe6032020-07-20 16:57:44 +01001980 arm::pipe::Packet deactivateTimelineReportingPacket(packetHeader2); // Length == 0
Keith Davis33ed2212020-03-30 10:43:41 +01001981
1982 stateMachine.Reset();
Sadik Armagan1625efc2021-06-10 18:24:34 +01001983 CHECK_THROWS_AS(
Keith Davis33ed2212020-03-30 10:43:41 +01001984 deactivateTimelineReportingCommandHandler.operator()(deactivateTimelineReportingPacket), armnn::Exception);
1985
1986 stateMachine.TransitionToState(ProfilingState::NotConnected);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001987 CHECK_THROWS_AS(
Keith Davis33ed2212020-03-30 10:43:41 +01001988 deactivateTimelineReportingCommandHandler.operator()(deactivateTimelineReportingPacket), armnn::Exception);
1989
1990 stateMachine.TransitionToState(ProfilingState::WaitingForAck);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001991 CHECK_THROWS_AS(
Keith Davis33ed2212020-03-30 10:43:41 +01001992 deactivateTimelineReportingCommandHandler.operator()(deactivateTimelineReportingPacket), armnn::Exception);
1993
1994 stateMachine.TransitionToState(ProfilingState::Active);
1995 deactivateTimelineReportingCommandHandler.operator()(deactivateTimelineReportingPacket);
1996
Sadik Armagan1625efc2021-06-10 18:24:34 +01001997 CHECK(!testNotifyBackends.m_TestNotifyBackendsCalled);
1998 CHECK(!testNotifyBackends.m_timelineReporting.load());
Keith Davis33ed2212020-03-30 10:43:41 +01001999}
2000
Sadik Armagan1625efc2021-06-10 18:24:34 +01002001TEST_CASE("CheckProfilingServiceNotActive")
Keith Davis33ed2212020-03-30 10:43:41 +01002002{
2003 using namespace armnn;
Keith Davis33ed2212020-03-30 10:43:41 +01002004
2005 // Create runtime in which the test will run
2006 armnn::IRuntime::CreationOptions options;
2007 options.m_ProfilingOptions.m_EnableProfiling = true;
2008
Kevin Mayd92a6e42021-02-04 10:27:41 +00002009 armnn::RuntimeImpl runtime(options);
Cathal Corbett5aa9fd72022-02-25 15:33:28 +00002010 ProfilingServiceRuntimeHelper profilingServiceHelper(GetProfilingService(&runtime));
Keith Davis33ed2212020-03-30 10:43:41 +01002011 profilingServiceHelper.ForceTransitionToState(ProfilingState::NotConnected);
2012 profilingServiceHelper.ForceTransitionToState(ProfilingState::WaitingForAck);
2013 profilingServiceHelper.ForceTransitionToState(ProfilingState::Active);
2014
Cathal Corbett5aa9fd72022-02-25 15:33:28 +00002015 BufferManager& bufferManager = profilingServiceHelper.GetProfilingBufferManager();
Keith Davis33ed2212020-03-30 10:43:41 +01002016 auto readableBuffer = bufferManager.GetReadableBuffer();
2017
2018 // Profiling is enabled, the post-optimisation structure should be created
Sadik Armagan1625efc2021-06-10 18:24:34 +01002019 CHECK(readableBuffer == nullptr);
Keith Davis33ed2212020-03-30 10:43:41 +01002020}
2021
Sadik Armagan1625efc2021-06-10 18:24:34 +01002022TEST_CASE("CheckConnectionAcknowledged")
Sadik Armaganb5f01b22019-09-18 17:29:00 +01002023{
Keith Davis3201eea2019-10-24 17:30:41 +01002024 const uint32_t packetFamilyId = 0;
Sadik Armaganb5f01b22019-09-18 17:29:00 +01002025 const uint32_t connectionPacketId = 0x10000;
Keith Davis3201eea2019-10-24 17:30:41 +01002026 const uint32_t version = 1;
Sadik Armaganb5f01b22019-09-18 17:29:00 +01002027
Matthew Sloyan371b70e2020-09-11 10:14:57 +01002028 uint32_t sizeOfUint32 = armnn::numeric_cast<uint32_t>(sizeof(uint32_t));
2029 uint32_t sizeOfUint16 = armnn::numeric_cast<uint32_t>(sizeof(uint16_t));
Sadik Armaganb5f01b22019-09-18 17:29:00 +01002030
2031 // Data with period and counters
Keith Davis3201eea2019-10-24 17:30:41 +01002032 uint32_t period1 = 10;
Sadik Armaganb5f01b22019-09-18 17:29:00 +01002033 uint32_t dataLength1 = 8;
Keith Davis3201eea2019-10-24 17:30:41 +01002034 uint32_t offset = 0;
Sadik Armaganb5f01b22019-09-18 17:29:00 +01002035
Matteo Martincigh67ef2a52019-10-10 13:29:02 +01002036 std::unique_ptr<unsigned char[]> uniqueData1 = std::make_unique<unsigned char[]>(dataLength1);
Keith Davis3201eea2019-10-24 17:30:41 +01002037 unsigned char* data1 = reinterpret_cast<unsigned char*>(uniqueData1.get());
Sadik Armaganb5f01b22019-09-18 17:29:00 +01002038
2039 WriteUint32(data1, offset, period1);
2040 offset += sizeOfUint32;
2041 WriteUint16(data1, offset, 4000);
2042 offset += sizeOfUint16;
2043 WriteUint16(data1, offset, 5000);
2044
Jim Flynnbbfe6032020-07-20 16:57:44 +01002045 arm::pipe::Packet packetA(connectionPacketId, dataLength1, uniqueData1);
Sadik Armaganb5f01b22019-09-18 17:29:00 +01002046
2047 ProfilingStateMachine profilingState(ProfilingState::Uninitialised);
Sadik Armagan1625efc2021-06-10 18:24:34 +01002048 CHECK(profilingState.GetCurrentState() == ProfilingState::Uninitialised);
Keith Davis3201eea2019-10-24 17:30:41 +01002049 CounterDirectory counterDirectory;
2050 MockBufferManager mockBuffer(1024);
Sadik Armagan3896b472020-02-10 12:24:15 +00002051 SendCounterPacket sendCounterPacket(mockBuffer);
2052 SendThread sendThread(profilingState, mockBuffer, sendCounterPacket);
Matteo Martincighcdfb9412019-11-08 11:23:06 +00002053 SendTimelinePacket sendTimelinePacket(mockBuffer);
Jim Flynn6398a982020-05-27 17:05:21 +01002054 MockProfilingServiceStatus mockProfilingServiceStatus;
Sadik Armaganb5f01b22019-09-18 17:29:00 +01002055
Jim Flynn6398a982020-05-27 17:05:21 +01002056 ConnectionAcknowledgedCommandHandler commandHandler(packetFamilyId,
2057 connectionPacketId,
2058 version,
2059 counterDirectory,
2060 sendCounterPacket,
2061 sendTimelinePacket,
2062 profilingState,
2063 mockProfilingServiceStatus);
Sadik Armaganb5f01b22019-09-18 17:29:00 +01002064
2065 // command handler received packet on ProfilingState::Uninitialised
Sadik Armagan1625efc2021-06-10 18:24:34 +01002066 CHECK_THROWS_AS(commandHandler(packetA), armnn::Exception);
Sadik Armaganb5f01b22019-09-18 17:29:00 +01002067
2068 profilingState.TransitionToState(ProfilingState::NotConnected);
Sadik Armagan1625efc2021-06-10 18:24:34 +01002069 CHECK(profilingState.GetCurrentState() == ProfilingState::NotConnected);
Sadik Armaganb5f01b22019-09-18 17:29:00 +01002070 // command handler received packet on ProfilingState::NotConnected
Sadik Armagan1625efc2021-06-10 18:24:34 +01002071 CHECK_THROWS_AS(commandHandler(packetA), armnn::Exception);
Sadik Armaganb5f01b22019-09-18 17:29:00 +01002072
2073 profilingState.TransitionToState(ProfilingState::WaitingForAck);
Sadik Armagan1625efc2021-06-10 18:24:34 +01002074 CHECK(profilingState.GetCurrentState() == ProfilingState::WaitingForAck);
Sadik Armaganb5f01b22019-09-18 17:29:00 +01002075 // command handler received packet on ProfilingState::WaitingForAck
Sadik Armagan1625efc2021-06-10 18:24:34 +01002076 CHECK_NOTHROW(commandHandler(packetA));
2077 CHECK(profilingState.GetCurrentState() == ProfilingState::Active);
Sadik Armaganb5f01b22019-09-18 17:29:00 +01002078
2079 // command handler received packet on ProfilingState::Active
Sadik Armagan1625efc2021-06-10 18:24:34 +01002080 CHECK_NOTHROW(commandHandler(packetA));
2081 CHECK(profilingState.GetCurrentState() == ProfilingState::Active);
Sadik Armaganb5f01b22019-09-18 17:29:00 +01002082
2083 // command handler received different packet
2084 const uint32_t differentPacketId = 0x40000;
Jim Flynnbbfe6032020-07-20 16:57:44 +01002085 arm::pipe::Packet packetB(differentPacketId, dataLength1, uniqueData1);
Matteo Martincighd0613b52019-10-09 16:47:04 +01002086 profilingState.TransitionToState(ProfilingState::NotConnected);
2087 profilingState.TransitionToState(ProfilingState::WaitingForAck);
Jim Flynn6398a982020-05-27 17:05:21 +01002088 ConnectionAcknowledgedCommandHandler differentCommandHandler(packetFamilyId,
2089 differentPacketId,
2090 version,
2091 counterDirectory,
2092 sendCounterPacket,
2093 sendTimelinePacket,
2094 profilingState,
2095 mockProfilingServiceStatus);
Sadik Armagan1625efc2021-06-10 18:24:34 +01002096 CHECK_THROWS_AS(differentCommandHandler(packetB), armnn::Exception);
Sadik Armaganb5f01b22019-09-18 17:29:00 +01002097}
2098
Sadik Armagan1625efc2021-06-10 18:24:34 +01002099TEST_CASE("CheckSocketConnectionException")
Teresa Charlin9bab4962019-09-06 12:28:35 +01002100{
Sadik Armagana97a0be2020-03-03 10:44:56 +00002101 // Check that creating a SocketProfilingConnection armnnProfiling in an exception as the Gator UDS doesn't exist.
Sadik Armagan1625efc2021-06-10 18:24:34 +01002102 CHECK_THROWS_AS(new SocketProfilingConnection(), arm::pipe::SocketConnectionException);
Sadik Armagana97a0be2020-03-03 10:44:56 +00002103}
2104
Sadik Armagan1625efc2021-06-10 18:24:34 +01002105TEST_CASE("CheckSocketConnectionException2")
Sadik Armagana97a0be2020-03-03 10:44:56 +00002106{
2107 try
2108 {
2109 new SocketProfilingConnection();
2110 }
Jim Flynnbbfe6032020-07-20 16:57:44 +01002111 catch (const arm::pipe::SocketConnectionException& ex)
Sadik Armagana97a0be2020-03-03 10:44:56 +00002112 {
Sadik Armagan1625efc2021-06-10 18:24:34 +01002113 CHECK(ex.GetSocketFd() == 0);
2114 CHECK(ex.GetErrorNo() == ECONNREFUSED);
2115 CHECK(ex.what()
Sadik Armagana97a0be2020-03-03 10:44:56 +00002116 == std::string("SocketProfilingConnection: Cannot connect to stream socket: Connection refused"));
2117 }
Teresa Charlin9bab4962019-09-06 12:28:35 +01002118}
2119
Sadik Armagan1625efc2021-06-10 18:24:34 +01002120TEST_CASE("SwTraceIsValidCharTest")
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01002121{
2122 // Only ASCII 7-bit encoding supported
2123 for (unsigned char c = 0; c < 128; c++)
2124 {
Sadik Armagan1625efc2021-06-10 18:24:34 +01002125 CHECK(arm::pipe::SwTraceCharPolicy::IsValidChar(c));
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01002126 }
2127
2128 // Not ASCII
2129 for (unsigned char c = 255; c >= 128; c++)
2130 {
Sadik Armagan1625efc2021-06-10 18:24:34 +01002131 CHECK(!arm::pipe::SwTraceCharPolicy::IsValidChar(c));
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01002132 }
2133}
2134
Sadik Armagan1625efc2021-06-10 18:24:34 +01002135TEST_CASE("SwTraceIsValidNameCharTest")
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01002136{
2137 // Only alpha-numeric and underscore ASCII 7-bit encoding supported
2138 const unsigned char validChars[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_";
2139 for (unsigned char i = 0; i < sizeof(validChars) / sizeof(validChars[0]) - 1; i++)
2140 {
Sadik Armagan1625efc2021-06-10 18:24:34 +01002141 CHECK(arm::pipe::SwTraceNameCharPolicy::IsValidChar(validChars[i]));
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01002142 }
2143
2144 // Non alpha-numeric chars
2145 for (unsigned char c = 0; c < 48; c++)
2146 {
Sadik Armagan1625efc2021-06-10 18:24:34 +01002147 CHECK(!arm::pipe::SwTraceNameCharPolicy::IsValidChar(c));
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01002148 }
2149 for (unsigned char c = 58; c < 65; c++)
2150 {
Sadik Armagan1625efc2021-06-10 18:24:34 +01002151 CHECK(!arm::pipe::SwTraceNameCharPolicy::IsValidChar(c));
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01002152 }
2153 for (unsigned char c = 91; c < 95; c++)
2154 {
Sadik Armagan1625efc2021-06-10 18:24:34 +01002155 CHECK(!arm::pipe::SwTraceNameCharPolicy::IsValidChar(c));
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01002156 }
2157 for (unsigned char c = 96; c < 97; c++)
2158 {
Sadik Armagan1625efc2021-06-10 18:24:34 +01002159 CHECK(!arm::pipe::SwTraceNameCharPolicy::IsValidChar(c));
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01002160 }
2161 for (unsigned char c = 123; c < 128; c++)
2162 {
Sadik Armagan1625efc2021-06-10 18:24:34 +01002163 CHECK(!arm::pipe::SwTraceNameCharPolicy::IsValidChar(c));
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01002164 }
2165
2166 // Not ASCII
2167 for (unsigned char c = 255; c >= 128; c++)
2168 {
Sadik Armagan1625efc2021-06-10 18:24:34 +01002169 CHECK(!arm::pipe::SwTraceNameCharPolicy::IsValidChar(c));
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01002170 }
2171}
2172
Sadik Armagan1625efc2021-06-10 18:24:34 +01002173TEST_CASE("IsValidSwTraceStringTest")
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01002174{
2175 // Valid SWTrace strings
Sadik Armagan1625efc2021-06-10 18:24:34 +01002176 CHECK(arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceCharPolicy>(""));
2177 CHECK(arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceCharPolicy>("_"));
2178 CHECK(arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceCharPolicy>("0123"));
2179 CHECK(arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceCharPolicy>("valid_string"));
2180 CHECK(arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceCharPolicy>("VALID_string_456"));
2181 CHECK(arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceCharPolicy>(" "));
2182 CHECK(arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceCharPolicy>("valid string"));
2183 CHECK(arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceCharPolicy>("!$%"));
2184 CHECK(arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceCharPolicy>("valid|\\~string#123"));
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01002185
2186 // Invalid SWTrace strings
Sadik Armagan1625efc2021-06-10 18:24:34 +01002187 CHECK(!arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceCharPolicy>("€£"));
2188 CHECK(!arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceCharPolicy>("invalid‡string"));
2189 CHECK(!arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceCharPolicy>("12Ž34"));
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01002190}
2191
Sadik Armagan1625efc2021-06-10 18:24:34 +01002192TEST_CASE("IsValidSwTraceNameStringTest")
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01002193{
2194 // Valid SWTrace name strings
Sadik Armagan1625efc2021-06-10 18:24:34 +01002195 CHECK(arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceNameCharPolicy>(""));
2196 CHECK(arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceNameCharPolicy>("_"));
2197 CHECK(arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceNameCharPolicy>("0123"));
2198 CHECK(arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceNameCharPolicy>("valid_string"));
2199 CHECK(arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceNameCharPolicy>("VALID_string_456"));
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01002200
2201 // Invalid SWTrace name strings
Sadik Armagan1625efc2021-06-10 18:24:34 +01002202 CHECK(!arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceNameCharPolicy>(" "));
2203 CHECK(!arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceNameCharPolicy>("invalid string"));
2204 CHECK(!arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceNameCharPolicy>("!$%"));
2205 CHECK(!arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceNameCharPolicy>("invalid|\\~string#123"));
2206 CHECK(!arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceNameCharPolicy>("€£"));
2207 CHECK(!arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceNameCharPolicy>("invalid‡string"));
2208 CHECK(!arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceNameCharPolicy>("12Ž34"));
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01002209}
2210
2211template <typename SwTracePolicy>
2212void StringToSwTraceStringTestHelper(const std::string& testString, std::vector<uint32_t> buffer, size_t expectedSize)
2213{
2214 // Convert the test string to a SWTrace string
Sadik Armagan1625efc2021-06-10 18:24:34 +01002215 CHECK(arm::pipe::StringToSwTraceString<SwTracePolicy>(testString, buffer));
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01002216
2217 // The buffer must contain at least the length of the string
Sadik Armagan1625efc2021-06-10 18:24:34 +01002218 CHECK(!buffer.empty());
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01002219
2220 // The buffer must be of the expected size (in words)
Sadik Armagan1625efc2021-06-10 18:24:34 +01002221 CHECK(buffer.size() == expectedSize);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01002222
2223 // The first word of the byte must be the length of the string including the null-terminator
Sadik Armagan1625efc2021-06-10 18:24:34 +01002224 CHECK(buffer[0] == testString.size() + 1);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01002225
2226 // The contents of the buffer must match the test string
Sadik Armagan1625efc2021-06-10 18:24:34 +01002227 CHECK(std::memcmp(testString.data(), buffer.data() + 1, testString.size()) == 0);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01002228
2229 // The buffer must include the null-terminator at the end of the string
2230 size_t nullTerminatorIndex = sizeof(uint32_t) + testString.size();
Sadik Armagan1625efc2021-06-10 18:24:34 +01002231 CHECK(reinterpret_cast<unsigned char*>(buffer.data())[nullTerminatorIndex] == '\0');
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01002232}
2233
Sadik Armagan1625efc2021-06-10 18:24:34 +01002234TEST_CASE("StringToSwTraceStringTest")
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01002235{
2236 std::vector<uint32_t> buffer;
2237
2238 // Valid SWTrace strings (expected size in words)
Jim Flynnbbfe6032020-07-20 16:57:44 +01002239 StringToSwTraceStringTestHelper<arm::pipe::SwTraceCharPolicy>("", buffer, 2);
2240 StringToSwTraceStringTestHelper<arm::pipe::SwTraceCharPolicy>("_", buffer, 2);
2241 StringToSwTraceStringTestHelper<arm::pipe::SwTraceCharPolicy>("0123", buffer, 3);
2242 StringToSwTraceStringTestHelper<arm::pipe::SwTraceCharPolicy>("valid_string", buffer, 5);
2243 StringToSwTraceStringTestHelper<arm::pipe::SwTraceCharPolicy>("VALID_string_456", buffer, 6);
2244 StringToSwTraceStringTestHelper<arm::pipe::SwTraceCharPolicy>(" ", buffer, 2);
2245 StringToSwTraceStringTestHelper<arm::pipe::SwTraceCharPolicy>("valid string", buffer, 5);
2246 StringToSwTraceStringTestHelper<arm::pipe::SwTraceCharPolicy>("!$%", buffer, 2);
2247 StringToSwTraceStringTestHelper<arm::pipe::SwTraceCharPolicy>("valid|\\~string#123", buffer, 6);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01002248
2249 // Invalid SWTrace strings
Sadik Armagan1625efc2021-06-10 18:24:34 +01002250 CHECK(!arm::pipe::StringToSwTraceString<arm::pipe::SwTraceCharPolicy>("€£", buffer));
2251 CHECK(buffer.empty());
2252 CHECK(!arm::pipe::StringToSwTraceString<arm::pipe::SwTraceCharPolicy>("invalid‡string", buffer));
2253 CHECK(buffer.empty());
2254 CHECK(!arm::pipe::StringToSwTraceString<arm::pipe::SwTraceCharPolicy>("12Ž34", buffer));
2255 CHECK(buffer.empty());
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01002256}
2257
Sadik Armagan1625efc2021-06-10 18:24:34 +01002258TEST_CASE("StringToSwTraceNameStringTest")
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01002259{
2260 std::vector<uint32_t> buffer;
2261
2262 // Valid SWTrace namestrings (expected size in words)
Jim Flynnbbfe6032020-07-20 16:57:44 +01002263 StringToSwTraceStringTestHelper<arm::pipe::SwTraceNameCharPolicy>("", buffer, 2);
2264 StringToSwTraceStringTestHelper<arm::pipe::SwTraceNameCharPolicy>("_", buffer, 2);
2265 StringToSwTraceStringTestHelper<arm::pipe::SwTraceNameCharPolicy>("0123", buffer, 3);
2266 StringToSwTraceStringTestHelper<arm::pipe::SwTraceNameCharPolicy>("valid_string", buffer, 5);
2267 StringToSwTraceStringTestHelper<arm::pipe::SwTraceNameCharPolicy>("VALID_string_456", buffer, 6);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01002268
2269 // Invalid SWTrace namestrings
Sadik Armagan1625efc2021-06-10 18:24:34 +01002270 CHECK(!arm::pipe::StringToSwTraceString<arm::pipe::SwTraceNameCharPolicy>(" ", buffer));
2271 CHECK(buffer.empty());
2272 CHECK(!arm::pipe::StringToSwTraceString<arm::pipe::SwTraceNameCharPolicy>("invalid string", buffer));
2273 CHECK(buffer.empty());
2274 CHECK(!arm::pipe::StringToSwTraceString<arm::pipe::SwTraceNameCharPolicy>("!$%", buffer));
2275 CHECK(buffer.empty());
2276 CHECK(!arm::pipe::StringToSwTraceString<arm::pipe::SwTraceNameCharPolicy>("invalid|\\~string#123", buffer));
2277 CHECK(buffer.empty());
2278 CHECK(!arm::pipe::StringToSwTraceString<arm::pipe::SwTraceNameCharPolicy>("€£", buffer));
2279 CHECK(buffer.empty());
2280 CHECK(!arm::pipe::StringToSwTraceString<arm::pipe::SwTraceNameCharPolicy>("invalid‡string", buffer));
2281 CHECK(buffer.empty());
2282 CHECK(!arm::pipe::StringToSwTraceString<arm::pipe::SwTraceNameCharPolicy>("12Ž34", buffer));
2283 CHECK(buffer.empty());
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01002284}
2285
Sadik Armagan1625efc2021-06-10 18:24:34 +01002286TEST_CASE("CheckPeriodicCounterCaptureThread")
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002287{
Matteo Martincighe0e6efc2019-10-04 17:17:42 +01002288 class CaptureReader : public IReadCounterValues
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002289 {
2290 public:
Finn Williamsf4d59a62019-10-14 15:55:18 +01002291 CaptureReader(uint16_t counterSize)
2292 {
Keith Davis3201eea2019-10-24 17:30:41 +01002293 for (uint16_t i = 0; i < counterSize; ++i)
Finn Williamsf4d59a62019-10-14 15:55:18 +01002294 {
2295 m_Data[i] = 0;
2296 }
2297 m_CounterSize = counterSize;
2298 }
2299 //not used
Matteo Martincighe8485382019-10-10 14:08:21 +01002300 bool IsCounterRegistered(uint16_t counterUid) const override
2301 {
Jan Eilers8eb25602020-03-09 12:13:48 +00002302 armnn::IgnoreUnused(counterUid);
Finn Williamsf4d59a62019-10-14 15:55:18 +01002303 return false;
Matteo Martincighe8485382019-10-10 14:08:21 +01002304 }
2305
Matteo Martincighe0e6efc2019-10-04 17:17:42 +01002306 uint16_t GetCounterCount() const override
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002307 {
Finn Williamsf4d59a62019-10-14 15:55:18 +01002308 return m_CounterSize;
Matteo Martincighe0e6efc2019-10-04 17:17:42 +01002309 }
2310
Finn Williamsf3fcf322020-05-11 14:38:02 +01002311 uint32_t GetAbsoluteCounterValue(uint16_t counterUid) const override
2312 {
2313 if (counterUid > m_CounterSize)
2314 {
Sadik Armagan1625efc2021-06-10 18:24:34 +01002315 FAIL("Invalid counter Uid");
Finn Williamsf3fcf322020-05-11 14:38:02 +01002316 }
2317 return m_Data.at(counterUid).load();
2318 }
2319
2320 uint32_t GetDeltaCounterValue(uint16_t counterUid) override
Matteo Martincighe0e6efc2019-10-04 17:17:42 +01002321 {
Keith Davis3201eea2019-10-24 17:30:41 +01002322 if (counterUid > m_CounterSize)
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002323 {
Sadik Armagan1625efc2021-06-10 18:24:34 +01002324 FAIL("Invalid counter Uid");
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002325 }
Matteo Martincighe8485382019-10-10 14:08:21 +01002326 return m_Data.at(counterUid).load();
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002327 }
2328
Matteo Martincighe8485382019-10-10 14:08:21 +01002329 void SetCounterValue(uint16_t counterUid, uint32_t value)
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002330 {
Keith Davis3201eea2019-10-24 17:30:41 +01002331 if (counterUid > m_CounterSize)
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002332 {
Sadik Armagan1625efc2021-06-10 18:24:34 +01002333 FAIL("Invalid counter Uid");
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002334 }
Finn Williamsf4d59a62019-10-14 15:55:18 +01002335 m_Data.at(counterUid).store(value);
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002336 }
2337
2338 private:
Matteo Martincighe8485382019-10-10 14:08:21 +01002339 std::unordered_map<uint16_t, std::atomic<uint32_t>> m_Data;
Finn Williamsf4d59a62019-10-14 15:55:18 +01002340 uint16_t m_CounterSize;
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002341 };
2342
Matteo Martincigh5d737fb2019-10-07 13:05:13 +01002343 ProfilingStateMachine profilingStateMachine;
2344
Finn Williams032bc742020-02-12 11:02:34 +00002345 const std::unordered_map<armnn::BackendId,
Cathal Corbett5aa9fd72022-02-25 15:33:28 +00002346 std::shared_ptr<IBackendProfilingContext>> backendProfilingContext;
Finn Williams032bc742020-02-12 11:02:34 +00002347 CounterIdMap counterIdMap;
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002348 Holder data;
2349 std::vector<uint16_t> captureIds1 = { 0, 1 };
2350 std::vector<uint16_t> captureIds2;
2351
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01002352 MockBufferManager mockBuffer(512);
Sadik Armagan3896b472020-02-10 12:24:15 +00002353 SendCounterPacket sendCounterPacket(mockBuffer);
2354 SendThread sendThread(profilingStateMachine, mockBuffer, sendCounterPacket);
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002355
2356 std::vector<uint16_t> counterIds;
Finn Williamsf4d59a62019-10-14 15:55:18 +01002357 CaptureReader captureReader(2);
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002358
Keith Davis3201eea2019-10-24 17:30:41 +01002359 unsigned int valueA = 10;
2360 unsigned int valueB = 15;
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002361 unsigned int numSteps = 5;
2362
Finn Williams032bc742020-02-12 11:02:34 +00002363 PeriodicCounterCapture periodicCounterCapture(std::ref(data), std::ref(sendCounterPacket), captureReader,
2364 counterIdMap, backendProfilingContext);
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002365
Matteo Martincighe0e6efc2019-10-04 17:17:42 +01002366 for (unsigned int i = 0; i < numSteps; ++i)
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002367 {
Finn Williams032bc742020-02-12 11:02:34 +00002368 data.SetCaptureData(1, captureIds1, {});
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002369 captureReader.SetCounterValue(0, valueA * (i + 1));
2370 captureReader.SetCounterValue(1, valueB * (i + 1));
2371
2372 periodicCounterCapture.Start();
Finn Williamsf4d59a62019-10-14 15:55:18 +01002373 periodicCounterCapture.Stop();
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002374 }
2375
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01002376 auto buffer = mockBuffer.GetReadableBuffer();
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002377
2378 uint32_t headerWord0 = ReadUint32(buffer, 0);
2379 uint32_t headerWord1 = ReadUint32(buffer, 4);
2380
Sadik Armagan1625efc2021-06-10 18:24:34 +01002381 CHECK(((headerWord0 >> 26) & 0x0000003F) == 3); // packet family
2382 CHECK(((headerWord0 >> 19) & 0x0000007F) == 0); // packet class
2383 CHECK(((headerWord0 >> 16) & 0x00000007) == 0); // packet type
2384 CHECK(headerWord1 == 20);
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002385
Keith Davis3201eea2019-10-24 17:30:41 +01002386 uint32_t offset = 16;
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002387 uint16_t readIndex = ReadUint16(buffer, offset);
Sadik Armagan1625efc2021-06-10 18:24:34 +01002388 CHECK(0 == readIndex);
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002389
2390 offset += 2;
2391 uint32_t readValue = ReadUint32(buffer, offset);
Sadik Armagan1625efc2021-06-10 18:24:34 +01002392 CHECK((valueA * numSteps) == readValue);
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002393
2394 offset += 4;
2395 readIndex = ReadUint16(buffer, offset);
Sadik Armagan1625efc2021-06-10 18:24:34 +01002396 CHECK(1 == readIndex);
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002397
2398 offset += 2;
2399 readValue = ReadUint32(buffer, offset);
Sadik Armagan1625efc2021-06-10 18:24:34 +01002400 CHECK((valueB * numSteps) == readValue);
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002401}
2402
Sadik Armagan1625efc2021-06-10 18:24:34 +01002403TEST_CASE("RequestCounterDirectoryCommandHandlerTest1")
Narumol Prangnawarat48033692019-09-20 12:04:55 +01002404{
Jim Flynn397043f2019-10-17 17:37:10 +01002405 const uint32_t familyId = 0;
Matteo Martincigh8efc5002019-10-10 14:30:29 +01002406 const uint32_t packetId = 3;
Keith Davis3201eea2019-10-24 17:30:41 +01002407 const uint32_t version = 1;
Matteo Martincigh8efc5002019-10-10 14:30:29 +01002408 ProfilingStateMachine profilingStateMachine;
2409 CounterDirectory counterDirectory;
Matteo Martincigh9723d022019-11-13 10:56:41 +00002410 MockBufferManager mockBuffer1(1024);
Sadik Armagan3896b472020-02-10 12:24:15 +00002411 SendCounterPacket sendCounterPacket(mockBuffer1);
2412 SendThread sendThread(profilingStateMachine, mockBuffer1, sendCounterPacket);
Matteo Martincigh9723d022019-11-13 10:56:41 +00002413 MockBufferManager mockBuffer2(1024);
2414 SendTimelinePacket sendTimelinePacket(mockBuffer2);
Keith Davis3201eea2019-10-24 17:30:41 +01002415 RequestCounterDirectoryCommandHandler commandHandler(familyId, packetId, version, counterDirectory,
Matteo Martincigh9723d022019-11-13 10:56:41 +00002416 sendCounterPacket, sendTimelinePacket, profilingStateMachine);
Narumol Prangnawarat48033692019-09-20 12:04:55 +01002417
Matteo Martincigh8efc5002019-10-10 14:30:29 +01002418 const uint32_t wrongPacketId = 47;
Keith Davis3201eea2019-10-24 17:30:41 +01002419 const uint32_t wrongHeader = (wrongPacketId & 0x000003FF) << 16;
Narumol Prangnawarat48033692019-09-20 12:04:55 +01002420
Jim Flynnbbfe6032020-07-20 16:57:44 +01002421 arm::pipe::Packet wrongPacket(wrongHeader);
Matteo Martincigh8efc5002019-10-10 14:30:29 +01002422
2423 profilingStateMachine.TransitionToState(ProfilingState::Uninitialised);
Sadik Armagan1625efc2021-06-10 18:24:34 +01002424 CHECK_THROWS_AS(commandHandler(wrongPacket), armnn::RuntimeException); // Wrong profiling state
Matteo Martincigh8efc5002019-10-10 14:30:29 +01002425 profilingStateMachine.TransitionToState(ProfilingState::NotConnected);
Sadik Armagan1625efc2021-06-10 18:24:34 +01002426 CHECK_THROWS_AS(commandHandler(wrongPacket), armnn::RuntimeException); // Wrong profiling state
Matteo Martincigh8efc5002019-10-10 14:30:29 +01002427 profilingStateMachine.TransitionToState(ProfilingState::WaitingForAck);
Sadik Armagan1625efc2021-06-10 18:24:34 +01002428 CHECK_THROWS_AS(commandHandler(wrongPacket), armnn::RuntimeException); // Wrong profiling state
Matteo Martincigh8efc5002019-10-10 14:30:29 +01002429 profilingStateMachine.TransitionToState(ProfilingState::Active);
Sadik Armagan1625efc2021-06-10 18:24:34 +01002430 CHECK_THROWS_AS(commandHandler(wrongPacket), armnn::InvalidArgumentException); // Wrong packet
Matteo Martincigh8efc5002019-10-10 14:30:29 +01002431
2432 const uint32_t rightHeader = (packetId & 0x000003FF) << 16;
2433
Jim Flynnbbfe6032020-07-20 16:57:44 +01002434 arm::pipe::Packet rightPacket(rightHeader);
Matteo Martincigh8efc5002019-10-10 14:30:29 +01002435
Sadik Armagan1625efc2021-06-10 18:24:34 +01002436 CHECK_NOTHROW(commandHandler(rightPacket)); // Right packet
Narumol Prangnawarat48033692019-09-20 12:04:55 +01002437
Matteo Martincigh9723d022019-11-13 10:56:41 +00002438 auto readBuffer1 = mockBuffer1.GetReadableBuffer();
Narumol Prangnawarat48033692019-09-20 12:04:55 +01002439
Matteo Martincigh9723d022019-11-13 10:56:41 +00002440 uint32_t header1Word0 = ReadUint32(readBuffer1, 0);
2441 uint32_t header1Word1 = ReadUint32(readBuffer1, 4);
Narumol Prangnawarat48033692019-09-20 12:04:55 +01002442
Matteo Martincigh9723d022019-11-13 10:56:41 +00002443 // Counter directory packet
Sadik Armagan1625efc2021-06-10 18:24:34 +01002444 CHECK(((header1Word0 >> 26) & 0x0000003F) == 0); // packet family
2445 CHECK(((header1Word0 >> 16) & 0x000003FF) == 2); // packet id
2446 CHECK(header1Word1 == 24); // data length
Narumol Prangnawarat48033692019-09-20 12:04:55 +01002447
Matteo Martincigh9723d022019-11-13 10:56:41 +00002448 uint32_t bodyHeader1Word0 = ReadUint32(readBuffer1, 8);
Matthew Sloyan371b70e2020-09-11 10:14:57 +01002449 uint16_t deviceRecordCount = armnn::numeric_cast<uint16_t>(bodyHeader1Word0 >> 16);
Sadik Armagan1625efc2021-06-10 18:24:34 +01002450 CHECK(deviceRecordCount == 0); // device_records_count
Matteo Martincigh9723d022019-11-13 10:56:41 +00002451
2452 auto readBuffer2 = mockBuffer2.GetReadableBuffer();
2453
2454 uint32_t header2Word0 = ReadUint32(readBuffer2, 0);
2455 uint32_t header2Word1 = ReadUint32(readBuffer2, 4);
2456
2457 // Timeline message directory packet
Sadik Armagan1625efc2021-06-10 18:24:34 +01002458 CHECK(((header2Word0 >> 26) & 0x0000003F) == 1); // packet family
2459 CHECK(((header2Word0 >> 16) & 0x000003FF) == 0); // packet id
2460 CHECK(header2Word1 == 443); // data length
Narumol Prangnawarat48033692019-09-20 12:04:55 +01002461}
2462
Sadik Armagan1625efc2021-06-10 18:24:34 +01002463TEST_CASE("RequestCounterDirectoryCommandHandlerTest2")
Narumol Prangnawarat48033692019-09-20 12:04:55 +01002464{
Jim Flynn397043f2019-10-17 17:37:10 +01002465 const uint32_t familyId = 0;
Matteo Martincigh8efc5002019-10-10 14:30:29 +01002466 const uint32_t packetId = 3;
Keith Davis3201eea2019-10-24 17:30:41 +01002467 const uint32_t version = 1;
Matteo Martincigh8efc5002019-10-10 14:30:29 +01002468 ProfilingStateMachine profilingStateMachine;
2469 CounterDirectory counterDirectory;
Matteo Martincigh9723d022019-11-13 10:56:41 +00002470 MockBufferManager mockBuffer1(1024);
Sadik Armagan3896b472020-02-10 12:24:15 +00002471 SendCounterPacket sendCounterPacket(mockBuffer1);
2472 SendThread sendThread(profilingStateMachine, mockBuffer1, sendCounterPacket);
Matteo Martincigh9723d022019-11-13 10:56:41 +00002473 MockBufferManager mockBuffer2(1024);
2474 SendTimelinePacket sendTimelinePacket(mockBuffer2);
Keith Davis3201eea2019-10-24 17:30:41 +01002475 RequestCounterDirectoryCommandHandler commandHandler(familyId, packetId, version, counterDirectory,
Matteo Martincigh9723d022019-11-13 10:56:41 +00002476 sendCounterPacket, sendTimelinePacket, profilingStateMachine);
Matteo Martincigh8efc5002019-10-10 14:30:29 +01002477 const uint32_t header = (packetId & 0x000003FF) << 16;
Jim Flynnbbfe6032020-07-20 16:57:44 +01002478 const arm::pipe::Packet packet(header);
Narumol Prangnawarat48033692019-09-20 12:04:55 +01002479
Matteo Martincigh9723d022019-11-13 10:56:41 +00002480 const Device* device = counterDirectory.RegisterDevice("deviceA", 1);
Sadik Armagan1625efc2021-06-10 18:24:34 +01002481 CHECK(device != nullptr);
Narumol Prangnawarat48033692019-09-20 12:04:55 +01002482 const CounterSet* counterSet = counterDirectory.RegisterCounterSet("countersetA");
Sadik Armagan1625efc2021-06-10 18:24:34 +01002483 CHECK(counterSet != nullptr);
Sadik Armagan4c998992020-02-25 12:44:44 +00002484 counterDirectory.RegisterCategory("categoryA");
Keith Davise394bd92019-12-02 15:12:19 +00002485 counterDirectory.RegisterCounter(armnn::profiling::BACKEND_ID, 24,
2486 "categoryA", 0, 1, 2.0f, "counterA", "descA");
2487 counterDirectory.RegisterCounter(armnn::profiling::BACKEND_ID, 25,
2488 "categoryA", 1, 1, 3.0f, "counterB", "descB");
Narumol Prangnawarat48033692019-09-20 12:04:55 +01002489
Matteo Martincigh8efc5002019-10-10 14:30:29 +01002490 profilingStateMachine.TransitionToState(ProfilingState::Uninitialised);
Sadik Armagan1625efc2021-06-10 18:24:34 +01002491 CHECK_THROWS_AS(commandHandler(packet), armnn::RuntimeException); // Wrong profiling state
Matteo Martincigh8efc5002019-10-10 14:30:29 +01002492 profilingStateMachine.TransitionToState(ProfilingState::NotConnected);
Sadik Armagan1625efc2021-06-10 18:24:34 +01002493 CHECK_THROWS_AS(commandHandler(packet), armnn::RuntimeException); // Wrong profiling state
Matteo Martincigh8efc5002019-10-10 14:30:29 +01002494 profilingStateMachine.TransitionToState(ProfilingState::WaitingForAck);
Sadik Armagan1625efc2021-06-10 18:24:34 +01002495 CHECK_THROWS_AS(commandHandler(packet), armnn::RuntimeException); // Wrong profiling state
Matteo Martincigh8efc5002019-10-10 14:30:29 +01002496 profilingStateMachine.TransitionToState(ProfilingState::Active);
Sadik Armagan1625efc2021-06-10 18:24:34 +01002497 CHECK_NOTHROW(commandHandler(packet));
Narumol Prangnawarat48033692019-09-20 12:04:55 +01002498
Matteo Martincigh9723d022019-11-13 10:56:41 +00002499 auto readBuffer1 = mockBuffer1.GetReadableBuffer();
Narumol Prangnawarat48033692019-09-20 12:04:55 +01002500
Finn Williams985fecf2020-04-30 11:06:43 +01002501 const uint32_t header1Word0 = ReadUint32(readBuffer1, 0);
2502 const uint32_t header1Word1 = ReadUint32(readBuffer1, 4);
Narumol Prangnawarat48033692019-09-20 12:04:55 +01002503
Sadik Armagan1625efc2021-06-10 18:24:34 +01002504 CHECK(((header1Word0 >> 26) & 0x0000003F) == 0); // packet family
2505 CHECK(((header1Word0 >> 16) & 0x000003FF) == 2); // packet id
2506 CHECK(header1Word1 == 236); // data length
Narumol Prangnawarat48033692019-09-20 12:04:55 +01002507
Finn Williams985fecf2020-04-30 11:06:43 +01002508 const uint32_t bodyHeaderSizeBytes = bodyHeaderSize * sizeof(uint32_t);
Narumol Prangnawarat48033692019-09-20 12:04:55 +01002509
Finn Williams985fecf2020-04-30 11:06:43 +01002510 const uint32_t bodyHeader1Word0 = ReadUint32(readBuffer1, 8);
2511 const uint32_t bodyHeader1Word1 = ReadUint32(readBuffer1, 12);
2512 const uint32_t bodyHeader1Word2 = ReadUint32(readBuffer1, 16);
2513 const uint32_t bodyHeader1Word3 = ReadUint32(readBuffer1, 20);
2514 const uint32_t bodyHeader1Word4 = ReadUint32(readBuffer1, 24);
2515 const uint32_t bodyHeader1Word5 = ReadUint32(readBuffer1, 28);
Matthew Sloyan371b70e2020-09-11 10:14:57 +01002516 const uint16_t deviceRecordCount = armnn::numeric_cast<uint16_t>(bodyHeader1Word0 >> 16);
2517 const uint16_t counterSetRecordCount = armnn::numeric_cast<uint16_t>(bodyHeader1Word2 >> 16);
2518 const uint16_t categoryRecordCount = armnn::numeric_cast<uint16_t>(bodyHeader1Word4 >> 16);
Sadik Armagan1625efc2021-06-10 18:24:34 +01002519 CHECK(deviceRecordCount == 1); // device_records_count
2520 CHECK(bodyHeader1Word1 == 0 + bodyHeaderSizeBytes); // device_records_pointer_table_offset
2521 CHECK(counterSetRecordCount == 1); // counter_set_count
2522 CHECK(bodyHeader1Word3 == 4 + bodyHeaderSizeBytes); // counter_set_pointer_table_offset
2523 CHECK(categoryRecordCount == 1); // categories_count
2524 CHECK(bodyHeader1Word5 == 8 + bodyHeaderSizeBytes); // categories_pointer_table_offset
Finn Williams985fecf2020-04-30 11:06:43 +01002525
2526 const uint32_t deviceRecordOffset = ReadUint32(readBuffer1, 32);
Sadik Armagan1625efc2021-06-10 18:24:34 +01002527 CHECK(deviceRecordOffset == 12);
Narumol Prangnawarat48033692019-09-20 12:04:55 +01002528
Finn Williams985fecf2020-04-30 11:06:43 +01002529 const uint32_t counterSetRecordOffset = ReadUint32(readBuffer1, 36);
Sadik Armagan1625efc2021-06-10 18:24:34 +01002530 CHECK(counterSetRecordOffset == 28);
Narumol Prangnawarat48033692019-09-20 12:04:55 +01002531
Finn Williams985fecf2020-04-30 11:06:43 +01002532 const uint32_t categoryRecordOffset = ReadUint32(readBuffer1, 40);
Sadik Armagan1625efc2021-06-10 18:24:34 +01002533 CHECK(categoryRecordOffset == 48);
Matteo Martincigh9723d022019-11-13 10:56:41 +00002534
2535 auto readBuffer2 = mockBuffer2.GetReadableBuffer();
2536
Finn Williams985fecf2020-04-30 11:06:43 +01002537 const uint32_t header2Word0 = ReadUint32(readBuffer2, 0);
2538 const uint32_t header2Word1 = ReadUint32(readBuffer2, 4);
Matteo Martincigh9723d022019-11-13 10:56:41 +00002539
2540 // Timeline message directory packet
Sadik Armagan1625efc2021-06-10 18:24:34 +01002541 CHECK(((header2Word0 >> 26) & 0x0000003F) == 1); // packet family
2542 CHECK(((header2Word0 >> 16) & 0x000003FF) == 0); // packet id
2543 CHECK(header2Word1 == 443); // data length
Narumol Prangnawarat48033692019-09-20 12:04:55 +01002544}
2545
Sadik Armagan1625efc2021-06-10 18:24:34 +01002546TEST_CASE("CheckProfilingServiceGoodConnectionAcknowledgedPacket")
Matteo Martincigh54fb9572019-10-02 12:50:57 +01002547{
Finn Williamsa0de0562020-04-22 12:27:37 +01002548 unsigned int streamMetadataPacketsize = GetStreamMetaDataPacketSize();
Matteo Martincigh54fb9572019-10-02 12:50:57 +01002549
Jim Flynn53e46992019-10-14 12:31:10 +01002550 // Reset the profiling service to the uninitialized state
Jim Flynn4c9ed1d2022-01-23 23:57:20 +00002551 ProfilingOptions options;
Keith Davis3201eea2019-10-24 17:30:41 +01002552 options.m_EnableProfiling = true;
Cathal Corbett5aa9fd72022-02-25 15:33:28 +00002553 ProfilingService profilingService;
Matteo Martincigh54fb9572019-10-02 12:50:57 +01002554 profilingService.ResetExternalProfilingOptions(options, true);
2555
Sadik Armagan3184c902020-03-18 10:57:30 +00002556 // Swap the profiling connection factory in the profiling service instance with our mock one
2557 SwapProfilingConnectionFactoryHelper helper(profilingService);
2558
Matteo Martincigh54fb9572019-10-02 12:50:57 +01002559 // Bring the profiling service to the "WaitingForAck" state
Sadik Armagan1625efc2021-06-10 18:24:34 +01002560 CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
Keith Davis3201eea2019-10-24 17:30:41 +01002561 profilingService.Update(); // Initialize the counter directory
Sadik Armagan1625efc2021-06-10 18:24:34 +01002562 CHECK(profilingService.GetCurrentState() == ProfilingState::NotConnected);
Keith Davis3201eea2019-10-24 17:30:41 +01002563 profilingService.Update(); // Create the profiling connection
Matteo Martincigh54fb9572019-10-02 12:50:57 +01002564
Matteo Martincighd0613b52019-10-09 16:47:04 +01002565 // Get the mock profiling connection
2566 MockProfilingConnection* mockProfilingConnection = helper.GetMockProfilingConnection();
Sadik Armagan1625efc2021-06-10 18:24:34 +01002567 CHECK(mockProfilingConnection);
Matteo Martincighd0613b52019-10-09 16:47:04 +01002568
Matteo Martincighe8485382019-10-10 14:08:21 +01002569 // Remove the packets received so far
2570 mockProfilingConnection->Clear();
2571
Sadik Armagan1625efc2021-06-10 18:24:34 +01002572 CHECK(profilingService.GetCurrentState() == ProfilingState::WaitingForAck);
Keith Davis3201eea2019-10-24 17:30:41 +01002573 profilingService.Update(); // Start the command handler and the send thread
Matteo Martincighe8485382019-10-10 14:08:21 +01002574
2575 // Wait for the Stream Metadata packet to be sent
Sadik Armagan1625efc2021-06-10 18:24:34 +01002576 CHECK(helper.WaitForPacketsSent(
Finn Williams09ad6f92019-12-19 17:05:18 +00002577 mockProfilingConnection, PacketType::StreamMetaData, streamMetadataPacketsize) >= 1);
Matteo Martincigh54fb9572019-10-02 12:50:57 +01002578
2579 // Write a valid "Connection Acknowledged" packet into the mock profiling connection, to simulate a valid
2580 // reply from an external profiling service
2581
2582 // Connection Acknowledged Packet header (word 0, word 1 is always zero):
2583 // 26:31 [6] packet_family: Control Packet Family, value 0b000000
2584 // 16:25 [10] packet_id: Packet identifier, value 0b0000000001
2585 // 8:15 [8] reserved: Reserved, value 0b00000000
2586 // 0:7 [8] reserved: Reserved, value 0b00000000
2587 uint32_t packetFamily = 0;
2588 uint32_t packetId = 1;
Keith Davis3201eea2019-10-24 17:30:41 +01002589 uint32_t header = ((packetFamily & 0x0000003F) << 26) | ((packetId & 0x000003FF) << 16);
Matteo Martincigh54fb9572019-10-02 12:50:57 +01002590
Matteo Martincighd0613b52019-10-09 16:47:04 +01002591 // Create the Connection Acknowledged Packet
Jim Flynnbbfe6032020-07-20 16:57:44 +01002592 arm::pipe::Packet connectionAcknowledgedPacket(header);
Matteo Martincigh54fb9572019-10-02 12:50:57 +01002593
2594 // Write the packet to the mock profiling connection
2595 mockProfilingConnection->WritePacket(std::move(connectionAcknowledgedPacket));
2596
Colm Donelan2ba48d22019-11-29 09:10:59 +00002597 // Wait for the counter directory packet to ensure the ConnectionAcknowledgedCommandHandler has run.
Sadik Armagan1625efc2021-06-10 18:24:34 +01002598 CHECK(helper.WaitForPacketsSent(mockProfilingConnection, PacketType::CounterDirectory) == 1);
Matteo Martincigh54fb9572019-10-02 12:50:57 +01002599
2600 // The Connection Acknowledged Command Handler should have updated the profiling state accordingly
Sadik Armagan1625efc2021-06-10 18:24:34 +01002601 CHECK(profilingService.GetCurrentState() == ProfilingState::Active);
Matteo Martincighd0613b52019-10-09 16:47:04 +01002602
2603 // Reset the profiling service to stop any running thread
2604 options.m_EnableProfiling = false;
2605 profilingService.ResetExternalProfilingOptions(options, true);
Matteo Martincigh54fb9572019-10-02 12:50:57 +01002606}
2607
Sadik Armagan1625efc2021-06-10 18:24:34 +01002608TEST_CASE("CheckProfilingServiceGoodRequestCounterDirectoryPacket")
Matteo Martincigh8efc5002019-10-10 14:30:29 +01002609{
Matteo Martincigh8efc5002019-10-10 14:30:29 +01002610 // Reset the profiling service to the uninitialized state
Jim Flynn4c9ed1d2022-01-23 23:57:20 +00002611 ProfilingOptions options;
Keith Davis3201eea2019-10-24 17:30:41 +01002612 options.m_EnableProfiling = true;
Cathal Corbett5aa9fd72022-02-25 15:33:28 +00002613 ProfilingService profilingService;
Matteo Martincigh8efc5002019-10-10 14:30:29 +01002614 profilingService.ResetExternalProfilingOptions(options, true);
2615
Sadik Armagan3184c902020-03-18 10:57:30 +00002616 // Swap the profiling connection factory in the profiling service instance with our mock one
2617 SwapProfilingConnectionFactoryHelper helper(profilingService);
2618
Matteo Martincigh8efc5002019-10-10 14:30:29 +01002619 // Bring the profiling service to the "Active" state
Sadik Armagan1625efc2021-06-10 18:24:34 +01002620 CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
Keith Davis3201eea2019-10-24 17:30:41 +01002621 profilingService.Update(); // Initialize the counter directory
Sadik Armagan1625efc2021-06-10 18:24:34 +01002622 CHECK(profilingService.GetCurrentState() == ProfilingState::NotConnected);
Keith Davis3201eea2019-10-24 17:30:41 +01002623 profilingService.Update(); // Create the profiling connection
Sadik Armagan1625efc2021-06-10 18:24:34 +01002624 CHECK(profilingService.GetCurrentState() == ProfilingState::WaitingForAck);
Keith Davis3201eea2019-10-24 17:30:41 +01002625 profilingService.Update(); // Start the command handler and the send thread
Matteo Martincighe8485382019-10-10 14:08:21 +01002626
Colm Donelan2ba48d22019-11-29 09:10:59 +00002627 // Get the mock profiling connection
2628 MockProfilingConnection* mockProfilingConnection = helper.GetMockProfilingConnection();
Sadik Armagan1625efc2021-06-10 18:24:34 +01002629 CHECK(mockProfilingConnection);
Colm Donelan2ba48d22019-11-29 09:10:59 +00002630
Matteo Martincighe8485382019-10-10 14:08:21 +01002631 // Force the profiling service to the "Active" state
Matteo Martincigh8efc5002019-10-10 14:30:29 +01002632 helper.ForceTransitionToState(ProfilingState::Active);
Sadik Armagan1625efc2021-06-10 18:24:34 +01002633 CHECK(profilingService.GetCurrentState() == ProfilingState::Active);
Matteo Martincigh8efc5002019-10-10 14:30:29 +01002634
Matteo Martincigh8efc5002019-10-10 14:30:29 +01002635 // Write a valid "Request Counter Directory" packet into the mock profiling connection, to simulate a valid
2636 // reply from an external profiling service
2637
2638 // Request Counter Directory packet header (word 0, word 1 is always zero):
2639 // 26:31 [6] packet_family: Control Packet Family, value 0b000000
2640 // 16:25 [10] packet_id: Packet identifier, value 0b0000000011
2641 // 8:15 [8] reserved: Reserved, value 0b00000000
2642 // 0:7 [8] reserved: Reserved, value 0b00000000
2643 uint32_t packetFamily = 0;
2644 uint32_t packetId = 3;
Keith Davis3201eea2019-10-24 17:30:41 +01002645 uint32_t header = ((packetFamily & 0x0000003F) << 26) | ((packetId & 0x000003FF) << 16);
Matteo Martincigh8efc5002019-10-10 14:30:29 +01002646
2647 // Create the Request Counter Directory packet
Jim Flynnbbfe6032020-07-20 16:57:44 +01002648 arm::pipe::Packet requestCounterDirectoryPacket(header);
Matteo Martincigh8efc5002019-10-10 14:30:29 +01002649
2650 // Write the packet to the mock profiling connection
2651 mockProfilingConnection->WritePacket(std::move(requestCounterDirectoryPacket));
2652
Sadik Armagan4c998992020-02-25 12:44:44 +00002653 // Expecting one CounterDirectory Packet of length 652
Jim Flynn6398a982020-05-27 17:05:21 +01002654 // and one TimelineMessageDirectory packet of length 451
Sadik Armagan1625efc2021-06-10 18:24:34 +01002655 CHECK(helper.WaitForPacketsSent(mockProfilingConnection, PacketType::CounterDirectory, 652) == 1);
2656 CHECK(helper.WaitForPacketsSent(mockProfilingConnection, PacketType::TimelineMessageDirectory, 451) == 1);
Matteo Martincighe8485382019-10-10 14:08:21 +01002657
2658 // The Request Counter Directory Command Handler should not have updated the profiling state
Sadik Armagan1625efc2021-06-10 18:24:34 +01002659 CHECK(profilingService.GetCurrentState() == ProfilingState::Active);
Matteo Martincighe8485382019-10-10 14:08:21 +01002660
2661 // Reset the profiling service to stop any running thread
2662 options.m_EnableProfiling = false;
2663 profilingService.ResetExternalProfilingOptions(options, true);
2664}
2665
Sadik Armagan1625efc2021-06-10 18:24:34 +01002666TEST_CASE("CheckProfilingServiceBadPeriodicCounterSelectionPacketInvalidCounterUid")
Matteo Martincighe8485382019-10-10 14:08:21 +01002667{
Matteo Martincighe8485382019-10-10 14:08:21 +01002668 // Reset the profiling service to the uninitialized state
Jim Flynn4c9ed1d2022-01-23 23:57:20 +00002669 ProfilingOptions options;
Keith Davis3201eea2019-10-24 17:30:41 +01002670 options.m_EnableProfiling = true;
Cathal Corbett5aa9fd72022-02-25 15:33:28 +00002671 ProfilingService profilingService;
Matteo Martincighe8485382019-10-10 14:08:21 +01002672 profilingService.ResetExternalProfilingOptions(options, true);
2673
Sadik Armagan3184c902020-03-18 10:57:30 +00002674 // Swap the profiling connection factory in the profiling service instance with our mock one
2675 SwapProfilingConnectionFactoryHelper helper(profilingService);
2676
Matteo Martincighe8485382019-10-10 14:08:21 +01002677 // Bring the profiling service to the "Active" state
Sadik Armagan1625efc2021-06-10 18:24:34 +01002678 CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
Keith Davis3201eea2019-10-24 17:30:41 +01002679 profilingService.Update(); // Initialize the counter directory
Sadik Armagan1625efc2021-06-10 18:24:34 +01002680 CHECK(profilingService.GetCurrentState() == ProfilingState::NotConnected);
Keith Davis3201eea2019-10-24 17:30:41 +01002681 profilingService.Update(); // Create the profiling connection
Sadik Armagan1625efc2021-06-10 18:24:34 +01002682 CHECK(profilingService.GetCurrentState() == ProfilingState::WaitingForAck);
Keith Davis3201eea2019-10-24 17:30:41 +01002683 profilingService.Update(); // Start the command handler and the send thread
Matteo Martincighe8485382019-10-10 14:08:21 +01002684
Colm Donelan2ba48d22019-11-29 09:10:59 +00002685 // Get the mock profiling connection
2686 MockProfilingConnection* mockProfilingConnection = helper.GetMockProfilingConnection();
Sadik Armagan1625efc2021-06-10 18:24:34 +01002687 CHECK(mockProfilingConnection);
Colm Donelan2ba48d22019-11-29 09:10:59 +00002688
Matteo Martincighe8485382019-10-10 14:08:21 +01002689 // Force the profiling service to the "Active" state
2690 helper.ForceTransitionToState(ProfilingState::Active);
Sadik Armagan1625efc2021-06-10 18:24:34 +01002691 CHECK(profilingService.GetCurrentState() == ProfilingState::Active);
Matteo Martincighe8485382019-10-10 14:08:21 +01002692
Matteo Martincighe8485382019-10-10 14:08:21 +01002693 // Remove the packets received so far
2694 mockProfilingConnection->Clear();
2695
2696 // Write a "Periodic Counter Selection" packet into the mock profiling connection, to simulate an input from an
2697 // external profiling service
2698
2699 // Periodic Counter Selection packet header:
2700 // 26:31 [6] packet_family: Control Packet Family, value 0b000000
2701 // 16:25 [10] packet_id: Packet identifier, value 0b0000000100
2702 // 8:15 [8] reserved: Reserved, value 0b00000000
2703 // 0:7 [8] reserved: Reserved, value 0b00000000
2704 uint32_t packetFamily = 0;
2705 uint32_t packetId = 4;
Keith Davis3201eea2019-10-24 17:30:41 +01002706 uint32_t header = ((packetFamily & 0x0000003F) << 26) | ((packetId & 0x000003FF) << 16);
Matteo Martincighe8485382019-10-10 14:08:21 +01002707
Keith Davis3201eea2019-10-24 17:30:41 +01002708 uint32_t capturePeriod = 123456; // Some capture period (microseconds)
Matteo Martincighe8485382019-10-10 14:08:21 +01002709
2710 // Get the first valid counter UID
2711 const ICounterDirectory& counterDirectory = profilingService.GetCounterDirectory();
Keith Davis3201eea2019-10-24 17:30:41 +01002712 const Counters& counters = counterDirectory.GetCounters();
Sadik Armagan1625efc2021-06-10 18:24:34 +01002713 CHECK(counters.size() > 1);
Keith Davis3201eea2019-10-24 17:30:41 +01002714 uint16_t counterUidA = counters.begin()->first; // First valid counter UID
2715 uint16_t counterUidB = 9999; // Second invalid counter UID
Matteo Martincighe8485382019-10-10 14:08:21 +01002716
2717 uint32_t length = 8;
2718
2719 auto data = std::make_unique<unsigned char[]>(length);
2720 WriteUint32(data.get(), 0, capturePeriod);
2721 WriteUint16(data.get(), 4, counterUidA);
2722 WriteUint16(data.get(), 6, counterUidB);
2723
2724 // Create the Periodic Counter Selection packet
Jim Flynnbbfe6032020-07-20 16:57:44 +01002725 // Length > 0, this will start the Period Counter Capture thread
2726 arm::pipe::Packet periodicCounterSelectionPacket(header, length, data);
2727
Matteo Martincighe8485382019-10-10 14:08:21 +01002728
2729 // Write the packet to the mock profiling connection
2730 mockProfilingConnection->WritePacket(std::move(periodicCounterSelectionPacket));
2731
Finn Williams09ad6f92019-12-19 17:05:18 +00002732 // Expecting one Periodic Counter Selection packet of length 14
2733 // and at least one Periodic Counter Capture packet of length 22
Sadik Armagan1625efc2021-06-10 18:24:34 +01002734 CHECK(helper.WaitForPacketsSent(mockProfilingConnection, PacketType::PeriodicCounterSelection, 14) == 1);
2735 CHECK(helper.WaitForPacketsSent(mockProfilingConnection, PacketType::PeriodicCounterCapture, 22) >= 1);
Matteo Martincighe8485382019-10-10 14:08:21 +01002736
2737 // The Periodic Counter Selection Handler should not have updated the profiling state
Sadik Armagan1625efc2021-06-10 18:24:34 +01002738 CHECK(profilingService.GetCurrentState() == ProfilingState::Active);
Matteo Martincighe8485382019-10-10 14:08:21 +01002739
2740 // Reset the profiling service to stop any running thread
2741 options.m_EnableProfiling = false;
2742 profilingService.ResetExternalProfilingOptions(options, true);
2743}
2744
Sadik Armagan1625efc2021-06-10 18:24:34 +01002745TEST_CASE("CheckProfilingServiceGoodPeriodicCounterSelectionPacketNoCounters")
Matteo Martincighe8485382019-10-10 14:08:21 +01002746{
Matteo Martincighe8485382019-10-10 14:08:21 +01002747 // Reset the profiling service to the uninitialized state
Jim Flynn4c9ed1d2022-01-23 23:57:20 +00002748 ProfilingOptions options;
Keith Davis3201eea2019-10-24 17:30:41 +01002749 options.m_EnableProfiling = true;
Cathal Corbett5aa9fd72022-02-25 15:33:28 +00002750 ProfilingService profilingService;
Matteo Martincighe8485382019-10-10 14:08:21 +01002751 profilingService.ResetExternalProfilingOptions(options, true);
2752
Sadik Armagan3184c902020-03-18 10:57:30 +00002753 // Swap the profiling connection factory in the profiling service instance with our mock one
2754 SwapProfilingConnectionFactoryHelper helper(profilingService);
2755
Matteo Martincighe8485382019-10-10 14:08:21 +01002756 // Bring the profiling service to the "Active" state
Sadik Armagan1625efc2021-06-10 18:24:34 +01002757 CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
Keith Davis3201eea2019-10-24 17:30:41 +01002758 profilingService.Update(); // Initialize the counter directory
Sadik Armagan1625efc2021-06-10 18:24:34 +01002759 CHECK(profilingService.GetCurrentState() == ProfilingState::NotConnected);
Keith Davis3201eea2019-10-24 17:30:41 +01002760 profilingService.Update(); // Create the profiling connection
Sadik Armagan1625efc2021-06-10 18:24:34 +01002761 CHECK(profilingService.GetCurrentState() == ProfilingState::WaitingForAck);
Keith Davis3201eea2019-10-24 17:30:41 +01002762 profilingService.Update(); // Start the command handler and the send thread
Matteo Martincighe8485382019-10-10 14:08:21 +01002763
Colm Donelan2ba48d22019-11-29 09:10:59 +00002764 // Get the mock profiling connection
2765 MockProfilingConnection* mockProfilingConnection = helper.GetMockProfilingConnection();
Sadik Armagan1625efc2021-06-10 18:24:34 +01002766 CHECK(mockProfilingConnection);
Colm Donelan2ba48d22019-11-29 09:10:59 +00002767
Matteo Martincighe8485382019-10-10 14:08:21 +01002768 // Wait for the Stream Metadata packet the be sent
2769 // (we are not testing the connection acknowledgement here so it will be ignored by this test)
Finn Williams09ad6f92019-12-19 17:05:18 +00002770 helper.WaitForPacketsSent(mockProfilingConnection, PacketType::StreamMetaData);
Matteo Martincighe8485382019-10-10 14:08:21 +01002771
2772 // Force the profiling service to the "Active" state
2773 helper.ForceTransitionToState(ProfilingState::Active);
Sadik Armagan1625efc2021-06-10 18:24:34 +01002774 CHECK(profilingService.GetCurrentState() == ProfilingState::Active);
Matteo Martincighe8485382019-10-10 14:08:21 +01002775
Matteo Martincighe8485382019-10-10 14:08:21 +01002776 // Write a "Periodic Counter Selection" packet into the mock profiling connection, to simulate an input from an
2777 // external profiling service
2778
2779 // Periodic Counter Selection packet header:
2780 // 26:31 [6] packet_family: Control Packet Family, value 0b000000
2781 // 16:25 [10] packet_id: Packet identifier, value 0b0000000100
2782 // 8:15 [8] reserved: Reserved, value 0b00000000
2783 // 0:7 [8] reserved: Reserved, value 0b00000000
2784 uint32_t packetFamily = 0;
2785 uint32_t packetId = 4;
Keith Davis3201eea2019-10-24 17:30:41 +01002786 uint32_t header = ((packetFamily & 0x0000003F) << 26) | ((packetId & 0x000003FF) << 16);
Matteo Martincighe8485382019-10-10 14:08:21 +01002787
2788 // Create the Periodic Counter Selection packet
Jim Flynnbbfe6032020-07-20 16:57:44 +01002789 // Length == 0, this will disable the collection of counters
2790 arm::pipe::Packet periodicCounterSelectionPacket(header);
Matteo Martincighe8485382019-10-10 14:08:21 +01002791
2792 // Write the packet to the mock profiling connection
2793 mockProfilingConnection->WritePacket(std::move(periodicCounterSelectionPacket));
2794
Finn Williams09ad6f92019-12-19 17:05:18 +00002795 // Wait for the Periodic Counter Selection packet of length 12 to be sent
2796 // The size of the expected Periodic Counter Selection (echos the sent one)
Sadik Armagan1625efc2021-06-10 18:24:34 +01002797 CHECK(helper.WaitForPacketsSent(mockProfilingConnection, PacketType::PeriodicCounterSelection, 12) == 1);
Matteo Martincighe8485382019-10-10 14:08:21 +01002798
2799 // The Periodic Counter Selection Handler should not have updated the profiling state
Sadik Armagan1625efc2021-06-10 18:24:34 +01002800 CHECK(profilingService.GetCurrentState() == ProfilingState::Active);
Matteo Martincighe8485382019-10-10 14:08:21 +01002801
Finn Williams09ad6f92019-12-19 17:05:18 +00002802 // No Periodic Counter packets are expected
Sadik Armagan1625efc2021-06-10 18:24:34 +01002803 CHECK(helper.WaitForPacketsSent(mockProfilingConnection, PacketType::PeriodicCounterCapture, 0, 0) == 0);
Matteo Martincighe8485382019-10-10 14:08:21 +01002804
2805 // Reset the profiling service to stop any running thread
2806 options.m_EnableProfiling = false;
2807 profilingService.ResetExternalProfilingOptions(options, true);
2808}
2809
Sadik Armagan1625efc2021-06-10 18:24:34 +01002810TEST_CASE("CheckProfilingServiceGoodPeriodicCounterSelectionPacketSingleCounter")
Matteo Martincighe8485382019-10-10 14:08:21 +01002811{
Matteo Martincighe8485382019-10-10 14:08:21 +01002812 // Reset the profiling service to the uninitialized state
Jim Flynn4c9ed1d2022-01-23 23:57:20 +00002813 ProfilingOptions options;
Keith Davis3201eea2019-10-24 17:30:41 +01002814 options.m_EnableProfiling = true;
Cathal Corbett5aa9fd72022-02-25 15:33:28 +00002815 ProfilingService profilingService;
Matteo Martincighe8485382019-10-10 14:08:21 +01002816 profilingService.ResetExternalProfilingOptions(options, true);
2817
Sadik Armagan3184c902020-03-18 10:57:30 +00002818 // Swap the profiling connection factory in the profiling service instance with our mock one
2819 SwapProfilingConnectionFactoryHelper helper(profilingService);
2820
Matteo Martincighe8485382019-10-10 14:08:21 +01002821 // Bring the profiling service to the "Active" state
Sadik Armagan1625efc2021-06-10 18:24:34 +01002822 CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
Keith Davis3201eea2019-10-24 17:30:41 +01002823 profilingService.Update(); // Initialize the counter directory
Sadik Armagan1625efc2021-06-10 18:24:34 +01002824 CHECK(profilingService.GetCurrentState() == ProfilingState::NotConnected);
Keith Davis3201eea2019-10-24 17:30:41 +01002825 profilingService.Update(); // Create the profiling connection
Sadik Armagan1625efc2021-06-10 18:24:34 +01002826 CHECK(profilingService.GetCurrentState() == ProfilingState::WaitingForAck);
Keith Davis3201eea2019-10-24 17:30:41 +01002827 profilingService.Update(); // Start the command handler and the send thread
Matteo Martincighe8485382019-10-10 14:08:21 +01002828
Colm Donelan2ba48d22019-11-29 09:10:59 +00002829 // Get the mock profiling connection
2830 MockProfilingConnection* mockProfilingConnection = helper.GetMockProfilingConnection();
Sadik Armagan1625efc2021-06-10 18:24:34 +01002831 CHECK(mockProfilingConnection);
Colm Donelan2ba48d22019-11-29 09:10:59 +00002832
Finn Williams09ad6f92019-12-19 17:05:18 +00002833 // Wait for the Stream Metadata packet to be sent
Matteo Martincighe8485382019-10-10 14:08:21 +01002834 // (we are not testing the connection acknowledgement here so it will be ignored by this test)
Finn Williams09ad6f92019-12-19 17:05:18 +00002835 helper.WaitForPacketsSent(mockProfilingConnection, PacketType::StreamMetaData);
Matteo Martincighe8485382019-10-10 14:08:21 +01002836
2837 // Force the profiling service to the "Active" state
2838 helper.ForceTransitionToState(ProfilingState::Active);
Sadik Armagan1625efc2021-06-10 18:24:34 +01002839 CHECK(profilingService.GetCurrentState() == ProfilingState::Active);
Matteo Martincighe8485382019-10-10 14:08:21 +01002840
Matteo Martincighe8485382019-10-10 14:08:21 +01002841 // Write a "Periodic Counter Selection" packet into the mock profiling connection, to simulate an input from an
2842 // external profiling service
2843
2844 // Periodic Counter Selection packet header:
2845 // 26:31 [6] packet_family: Control Packet Family, value 0b000000
2846 // 16:25 [10] packet_id: Packet identifier, value 0b0000000100
2847 // 8:15 [8] reserved: Reserved, value 0b00000000
2848 // 0:7 [8] reserved: Reserved, value 0b00000000
2849 uint32_t packetFamily = 0;
2850 uint32_t packetId = 4;
Keith Davis3201eea2019-10-24 17:30:41 +01002851 uint32_t header = ((packetFamily & 0x0000003F) << 26) | ((packetId & 0x000003FF) << 16);
Matteo Martincighe8485382019-10-10 14:08:21 +01002852
Keith Davis3201eea2019-10-24 17:30:41 +01002853 uint32_t capturePeriod = 123456; // Some capture period (microseconds)
Matteo Martincighe8485382019-10-10 14:08:21 +01002854
2855 // Get the first valid counter UID
2856 const ICounterDirectory& counterDirectory = profilingService.GetCounterDirectory();
Keith Davis3201eea2019-10-24 17:30:41 +01002857 const Counters& counters = counterDirectory.GetCounters();
Sadik Armagan1625efc2021-06-10 18:24:34 +01002858 CHECK(!counters.empty());
Keith Davis3201eea2019-10-24 17:30:41 +01002859 uint16_t counterUid = counters.begin()->first; // Valid counter UID
Matteo Martincighe8485382019-10-10 14:08:21 +01002860
2861 uint32_t length = 6;
2862
2863 auto data = std::make_unique<unsigned char[]>(length);
2864 WriteUint32(data.get(), 0, capturePeriod);
2865 WriteUint16(data.get(), 4, counterUid);
2866
2867 // Create the Periodic Counter Selection packet
Jim Flynnbbfe6032020-07-20 16:57:44 +01002868 // Length > 0, this will start the Period Counter Capture thread
2869 arm::pipe::Packet periodicCounterSelectionPacket(header, length, data);
Matteo Martincighe8485382019-10-10 14:08:21 +01002870
2871 // Write the packet to the mock profiling connection
2872 mockProfilingConnection->WritePacket(std::move(periodicCounterSelectionPacket));
2873
Finn Williams09ad6f92019-12-19 17:05:18 +00002874 // Expecting one Periodic Counter Selection packet of length 14
2875 // and at least one Periodic Counter Capture packet of length 22
Sadik Armagan1625efc2021-06-10 18:24:34 +01002876 CHECK(helper.WaitForPacketsSent(mockProfilingConnection, PacketType::PeriodicCounterSelection, 14) == 1);
2877 CHECK(helper.WaitForPacketsSent(mockProfilingConnection, PacketType::PeriodicCounterCapture, 22) >= 1);
Matteo Martincighe8485382019-10-10 14:08:21 +01002878
2879 // The Periodic Counter Selection Handler should not have updated the profiling state
Sadik Armagan1625efc2021-06-10 18:24:34 +01002880 CHECK(profilingService.GetCurrentState() == ProfilingState::Active);
Matteo Martincighe8485382019-10-10 14:08:21 +01002881
2882 // Reset the profiling service to stop any running thread
2883 options.m_EnableProfiling = false;
2884 profilingService.ResetExternalProfilingOptions(options, true);
2885}
2886
Sadik Armagan1625efc2021-06-10 18:24:34 +01002887TEST_CASE("CheckProfilingServiceGoodPeriodicCounterSelectionPacketMultipleCounters")
Matteo Martincighe8485382019-10-10 14:08:21 +01002888{
Matteo Martincighe8485382019-10-10 14:08:21 +01002889 // Reset the profiling service to the uninitialized state
Jim Flynn4c9ed1d2022-01-23 23:57:20 +00002890 ProfilingOptions options;
Keith Davis3201eea2019-10-24 17:30:41 +01002891 options.m_EnableProfiling = true;
Cathal Corbett5aa9fd72022-02-25 15:33:28 +00002892 ProfilingService profilingService;
Matteo Martincighe8485382019-10-10 14:08:21 +01002893 profilingService.ResetExternalProfilingOptions(options, true);
2894
Sadik Armagan3184c902020-03-18 10:57:30 +00002895 // Swap the profiling connection factory in the profiling service instance with our mock one
2896 SwapProfilingConnectionFactoryHelper helper(profilingService);
2897
Matteo Martincighe8485382019-10-10 14:08:21 +01002898 // Bring the profiling service to the "Active" state
Sadik Armagan1625efc2021-06-10 18:24:34 +01002899 CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
Keith Davis3201eea2019-10-24 17:30:41 +01002900 profilingService.Update(); // Initialize the counter directory
Sadik Armagan1625efc2021-06-10 18:24:34 +01002901 CHECK(profilingService.GetCurrentState() == ProfilingState::NotConnected);
Keith Davis3201eea2019-10-24 17:30:41 +01002902 profilingService.Update(); // Create the profiling connection
Sadik Armagan1625efc2021-06-10 18:24:34 +01002903 CHECK(profilingService.GetCurrentState() == ProfilingState::WaitingForAck);
Keith Davis3201eea2019-10-24 17:30:41 +01002904 profilingService.Update(); // Start the command handler and the send thread
Matteo Martincighe8485382019-10-10 14:08:21 +01002905
Colm Donelan2ba48d22019-11-29 09:10:59 +00002906 // Get the mock profiling connection
2907 MockProfilingConnection* mockProfilingConnection = helper.GetMockProfilingConnection();
Sadik Armagan1625efc2021-06-10 18:24:34 +01002908 CHECK(mockProfilingConnection);
Colm Donelan2ba48d22019-11-29 09:10:59 +00002909
Matteo Martincighe8485382019-10-10 14:08:21 +01002910 // Wait for the Stream Metadata packet the be sent
2911 // (we are not testing the connection acknowledgement here so it will be ignored by this test)
Finn Williams09ad6f92019-12-19 17:05:18 +00002912 helper.WaitForPacketsSent(mockProfilingConnection, PacketType::StreamMetaData);
Matteo Martincighe8485382019-10-10 14:08:21 +01002913
2914 // Force the profiling service to the "Active" state
2915 helper.ForceTransitionToState(ProfilingState::Active);
Sadik Armagan1625efc2021-06-10 18:24:34 +01002916 CHECK(profilingService.GetCurrentState() == ProfilingState::Active);
Matteo Martincighe8485382019-10-10 14:08:21 +01002917
Matteo Martincighe8485382019-10-10 14:08:21 +01002918 // Write a "Periodic Counter Selection" packet into the mock profiling connection, to simulate an input from an
2919 // external profiling service
2920
2921 // Periodic Counter Selection packet header:
2922 // 26:31 [6] packet_family: Control Packet Family, value 0b000000
2923 // 16:25 [10] packet_id: Packet identifier, value 0b0000000100
2924 // 8:15 [8] reserved: Reserved, value 0b00000000
2925 // 0:7 [8] reserved: Reserved, value 0b00000000
2926 uint32_t packetFamily = 0;
2927 uint32_t packetId = 4;
Keith Davis3201eea2019-10-24 17:30:41 +01002928 uint32_t header = ((packetFamily & 0x0000003F) << 26) | ((packetId & 0x000003FF) << 16);
Matteo Martincighe8485382019-10-10 14:08:21 +01002929
Keith Davis3201eea2019-10-24 17:30:41 +01002930 uint32_t capturePeriod = 123456; // Some capture period (microseconds)
Matteo Martincighe8485382019-10-10 14:08:21 +01002931
2932 // Get the first valid counter UID
2933 const ICounterDirectory& counterDirectory = profilingService.GetCounterDirectory();
Keith Davis3201eea2019-10-24 17:30:41 +01002934 const Counters& counters = counterDirectory.GetCounters();
Sadik Armagan1625efc2021-06-10 18:24:34 +01002935 CHECK(counters.size() > 1);
Keith Davis3201eea2019-10-24 17:30:41 +01002936 uint16_t counterUidA = counters.begin()->first; // First valid counter UID
2937 uint16_t counterUidB = (counters.begin()++)->first; // Second valid counter UID
Matteo Martincighe8485382019-10-10 14:08:21 +01002938
2939 uint32_t length = 8;
2940
2941 auto data = std::make_unique<unsigned char[]>(length);
2942 WriteUint32(data.get(), 0, capturePeriod);
2943 WriteUint16(data.get(), 4, counterUidA);
2944 WriteUint16(data.get(), 6, counterUidB);
2945
2946 // Create the Periodic Counter Selection packet
Jim Flynnbbfe6032020-07-20 16:57:44 +01002947 // Length > 0, this will start the Period Counter Capture thread
2948 arm::pipe::Packet periodicCounterSelectionPacket(header, length, data);
Matteo Martincighe8485382019-10-10 14:08:21 +01002949
2950 // Write the packet to the mock profiling connection
2951 mockProfilingConnection->WritePacket(std::move(periodicCounterSelectionPacket));
2952
Finn Williams09ad6f92019-12-19 17:05:18 +00002953 // Expecting one PeriodicCounterSelection Packet with a length of 16
2954 // And at least one PeriodicCounterCapture Packet with a length of 28
Sadik Armagan1625efc2021-06-10 18:24:34 +01002955 CHECK(helper.WaitForPacketsSent(mockProfilingConnection, PacketType::PeriodicCounterSelection, 16) == 1);
2956 CHECK(helper.WaitForPacketsSent(mockProfilingConnection, PacketType::PeriodicCounterCapture, 28) >= 1);
Matteo Martincighe8485382019-10-10 14:08:21 +01002957
2958 // The Periodic Counter Selection Handler should not have updated the profiling state
Sadik Armagan1625efc2021-06-10 18:24:34 +01002959 CHECK(profilingService.GetCurrentState() == ProfilingState::Active);
Matteo Martincigh8efc5002019-10-10 14:30:29 +01002960
2961 // Reset the profiling service to stop any running thread
2962 options.m_EnableProfiling = false;
2963 profilingService.ResetExternalProfilingOptions(options, true);
2964}
2965
Sadik Armagan1625efc2021-06-10 18:24:34 +01002966TEST_CASE("CheckProfilingServiceDisconnect")
Jim Flynn53e46992019-10-14 12:31:10 +01002967{
Jim Flynn53e46992019-10-14 12:31:10 +01002968 // Reset the profiling service to the uninitialized state
Jim Flynn4c9ed1d2022-01-23 23:57:20 +00002969 ProfilingOptions options;
Keith Davis3201eea2019-10-24 17:30:41 +01002970 options.m_EnableProfiling = true;
Cathal Corbett5aa9fd72022-02-25 15:33:28 +00002971 ProfilingService profilingService;
Jim Flynn53e46992019-10-14 12:31:10 +01002972 profilingService.ResetExternalProfilingOptions(options, true);
2973
Sadik Armagan3184c902020-03-18 10:57:30 +00002974 // Swap the profiling connection factory in the profiling service instance with our mock one
2975 SwapProfilingConnectionFactoryHelper helper(profilingService);
2976
Jim Flynn53e46992019-10-14 12:31:10 +01002977 // Try to disconnect the profiling service while in the "Uninitialised" state
Sadik Armagan1625efc2021-06-10 18:24:34 +01002978 CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
Jim Flynn53e46992019-10-14 12:31:10 +01002979 profilingService.Disconnect();
Sadik Armagan1625efc2021-06-10 18:24:34 +01002980 CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised); // The state should not change
Jim Flynn53e46992019-10-14 12:31:10 +01002981
2982 // Try to disconnect the profiling service while in the "NotConnected" state
Keith Davis3201eea2019-10-24 17:30:41 +01002983 profilingService.Update(); // Initialize the counter directory
Sadik Armagan1625efc2021-06-10 18:24:34 +01002984 CHECK(profilingService.GetCurrentState() == ProfilingState::NotConnected);
Jim Flynn53e46992019-10-14 12:31:10 +01002985 profilingService.Disconnect();
Sadik Armagan1625efc2021-06-10 18:24:34 +01002986 CHECK(profilingService.GetCurrentState() == ProfilingState::NotConnected); // The state should not change
Jim Flynn53e46992019-10-14 12:31:10 +01002987
2988 // Try to disconnect the profiling service while in the "WaitingForAck" state
Keith Davis3201eea2019-10-24 17:30:41 +01002989 profilingService.Update(); // Create the profiling connection
Sadik Armagan1625efc2021-06-10 18:24:34 +01002990 CHECK(profilingService.GetCurrentState() == ProfilingState::WaitingForAck);
Jim Flynn53e46992019-10-14 12:31:10 +01002991 profilingService.Disconnect();
Sadik Armagan1625efc2021-06-10 18:24:34 +01002992 CHECK(profilingService.GetCurrentState() == ProfilingState::WaitingForAck); // The state should not change
Jim Flynn53e46992019-10-14 12:31:10 +01002993
2994 // Try to disconnect the profiling service while in the "Active" state
Keith Davis3201eea2019-10-24 17:30:41 +01002995 profilingService.Update(); // Start the command handler and the send thread
Jim Flynn53e46992019-10-14 12:31:10 +01002996
Colm Donelan2ba48d22019-11-29 09:10:59 +00002997 // Get the mock profiling connection
2998 MockProfilingConnection* mockProfilingConnection = helper.GetMockProfilingConnection();
Sadik Armagan1625efc2021-06-10 18:24:34 +01002999 CHECK(mockProfilingConnection);
Colm Donelan2ba48d22019-11-29 09:10:59 +00003000
Jim Flynn53e46992019-10-14 12:31:10 +01003001 // Wait for the Stream Metadata packet the be sent
3002 // (we are not testing the connection acknowledgement here so it will be ignored by this test)
Finn Williams09ad6f92019-12-19 17:05:18 +00003003 helper.WaitForPacketsSent(mockProfilingConnection, PacketType::StreamMetaData);
Jim Flynn53e46992019-10-14 12:31:10 +01003004
3005 // Force the profiling service to the "Active" state
3006 helper.ForceTransitionToState(ProfilingState::Active);
Sadik Armagan1625efc2021-06-10 18:24:34 +01003007 CHECK(profilingService.GetCurrentState() == ProfilingState::Active);
Jim Flynn53e46992019-10-14 12:31:10 +01003008
Jim Flynn53e46992019-10-14 12:31:10 +01003009 // Check that the profiling connection is open
Sadik Armagan1625efc2021-06-10 18:24:34 +01003010 CHECK(mockProfilingConnection->IsOpen());
Jim Flynn53e46992019-10-14 12:31:10 +01003011
3012 profilingService.Disconnect();
Sadik Armagan1625efc2021-06-10 18:24:34 +01003013 CHECK(profilingService.GetCurrentState() == ProfilingState::NotConnected); // The state should have changed
Jim Flynn53e46992019-10-14 12:31:10 +01003014
3015 // Check that the profiling connection has been reset
3016 mockProfilingConnection = helper.GetMockProfilingConnection();
Sadik Armagan1625efc2021-06-10 18:24:34 +01003017 CHECK(mockProfilingConnection == nullptr);
Jim Flynn53e46992019-10-14 12:31:10 +01003018
3019 // Reset the profiling service to stop any running thread
3020 options.m_EnableProfiling = false;
3021 profilingService.ResetExternalProfilingOptions(options, true);
3022}
3023
Sadik Armagan1625efc2021-06-10 18:24:34 +01003024TEST_CASE("CheckProfilingServiceGoodPerJobCounterSelectionPacket")
Matteo Martincigh994b5342019-10-11 17:19:56 +01003025{
Matteo Martincigh994b5342019-10-11 17:19:56 +01003026 // Reset the profiling service to the uninitialized state
Jim Flynn4c9ed1d2022-01-23 23:57:20 +00003027 ProfilingOptions options;
Keith Davis3201eea2019-10-24 17:30:41 +01003028 options.m_EnableProfiling = true;
Cathal Corbett5aa9fd72022-02-25 15:33:28 +00003029 ProfilingService profilingService;
Matteo Martincigh994b5342019-10-11 17:19:56 +01003030 profilingService.ResetExternalProfilingOptions(options, true);
3031
Sadik Armagan3184c902020-03-18 10:57:30 +00003032 // Swap the profiling connection factory in the profiling service instance with our mock one
3033 SwapProfilingConnectionFactoryHelper helper(profilingService);
3034
Matteo Martincigh994b5342019-10-11 17:19:56 +01003035 // Bring the profiling service to the "Active" state
Sadik Armagan1625efc2021-06-10 18:24:34 +01003036 CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
Keith Davis3201eea2019-10-24 17:30:41 +01003037 profilingService.Update(); // Initialize the counter directory
Sadik Armagan1625efc2021-06-10 18:24:34 +01003038 CHECK(profilingService.GetCurrentState() == ProfilingState::NotConnected);
Keith Davis3201eea2019-10-24 17:30:41 +01003039 profilingService.Update(); // Create the profiling connection
Sadik Armagan1625efc2021-06-10 18:24:34 +01003040 CHECK(profilingService.GetCurrentState() == ProfilingState::WaitingForAck);
Keith Davis3201eea2019-10-24 17:30:41 +01003041 profilingService.Update(); // Start the command handler and the send thread
Matteo Martincigh994b5342019-10-11 17:19:56 +01003042
Colm Donelan2ba48d22019-11-29 09:10:59 +00003043 // Get the mock profiling connection
3044 MockProfilingConnection* mockProfilingConnection = helper.GetMockProfilingConnection();
Sadik Armagan1625efc2021-06-10 18:24:34 +01003045 CHECK(mockProfilingConnection);
Colm Donelan2ba48d22019-11-29 09:10:59 +00003046
Matteo Martincigh994b5342019-10-11 17:19:56 +01003047 // Wait for the Stream Metadata packet the be sent
3048 // (we are not testing the connection acknowledgement here so it will be ignored by this test)
Finn Williams09ad6f92019-12-19 17:05:18 +00003049 helper.WaitForPacketsSent(mockProfilingConnection, PacketType::StreamMetaData);
Matteo Martincigh994b5342019-10-11 17:19:56 +01003050
3051 // Force the profiling service to the "Active" state
3052 helper.ForceTransitionToState(ProfilingState::Active);
Sadik Armagan1625efc2021-06-10 18:24:34 +01003053 CHECK(profilingService.GetCurrentState() == ProfilingState::Active);
Matteo Martincigh994b5342019-10-11 17:19:56 +01003054
Matteo Martincigh994b5342019-10-11 17:19:56 +01003055 // Write a "Per-Job Counter Selection" packet into the mock profiling connection, to simulate an input from an
3056 // external profiling service
3057
3058 // Per-Job Counter Selection packet header:
3059 // 26:31 [6] packet_family: Control Packet Family, value 0b000000
3060 // 16:25 [10] packet_id: Packet identifier, value 0b0000000100
3061 // 8:15 [8] reserved: Reserved, value 0b00000000
3062 // 0:7 [8] reserved: Reserved, value 0b00000000
3063 uint32_t packetFamily = 0;
3064 uint32_t packetId = 5;
Keith Davis3201eea2019-10-24 17:30:41 +01003065 uint32_t header = ((packetFamily & 0x0000003F) << 26) | ((packetId & 0x000003FF) << 16);
Matteo Martincigh994b5342019-10-11 17:19:56 +01003066
3067 // Create the Per-Job Counter Selection packet
Jim Flynnbbfe6032020-07-20 16:57:44 +01003068 // Length == 0, this will disable the collection of counters
3069 arm::pipe::Packet periodicCounterSelectionPacket(header);
Matteo Martincigh994b5342019-10-11 17:19:56 +01003070
3071 // Write the packet to the mock profiling connection
3072 mockProfilingConnection->WritePacket(std::move(periodicCounterSelectionPacket));
3073
3074 // Wait for a bit (must at least be the delay value of the mock profiling connection) to make sure that
3075 // the Per-Job Counter Selection packet gets processed by the profiling service
Colm Donelan2ba48d22019-11-29 09:10:59 +00003076 std::this_thread::sleep_for(std::chrono::milliseconds(5));
Matteo Martincigh994b5342019-10-11 17:19:56 +01003077
Matteo Martincigh994b5342019-10-11 17:19:56 +01003078 // The Per-Job Counter Selection Command Handler should not have updated the profiling state
Sadik Armagan1625efc2021-06-10 18:24:34 +01003079 CHECK(profilingService.GetCurrentState() == ProfilingState::Active);
Matteo Martincigh994b5342019-10-11 17:19:56 +01003080
Finn Williams09ad6f92019-12-19 17:05:18 +00003081 // The Per-Job Counter Selection packets are dropped silently, so there should be no reply coming
3082 // from the profiling service
3083 const auto StreamMetaDataSize = static_cast<unsigned long>(
3084 helper.WaitForPacketsSent(mockProfilingConnection, PacketType::StreamMetaData, 0, 0));
Sadik Armagan1625efc2021-06-10 18:24:34 +01003085 CHECK(StreamMetaDataSize == mockProfilingConnection->GetWrittenDataSize());
Finn Williams09ad6f92019-12-19 17:05:18 +00003086
Matteo Martincigh994b5342019-10-11 17:19:56 +01003087 // Reset the profiling service to stop any running thread
3088 options.m_EnableProfiling = false;
3089 profilingService.ResetExternalProfilingOptions(options, true);
3090}
3091
Sadik Armagan1625efc2021-06-10 18:24:34 +01003092TEST_CASE("CheckConfigureProfilingServiceOn")
Jim Flynn672d06e2019-10-15 10:18:11 +01003093{
Jim Flynn4c9ed1d2022-01-23 23:57:20 +00003094 ProfilingOptions options;
Keith Davis3201eea2019-10-24 17:30:41 +01003095 options.m_EnableProfiling = true;
Cathal Corbett5aa9fd72022-02-25 15:33:28 +00003096 ProfilingService profilingService;
Sadik Armagan1625efc2021-06-10 18:24:34 +01003097 CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
Jim Flynn672d06e2019-10-15 10:18:11 +01003098 profilingService.ConfigureProfilingService(options);
3099 // should get as far as NOT_CONNECTED
Sadik Armagan1625efc2021-06-10 18:24:34 +01003100 CHECK(profilingService.GetCurrentState() == ProfilingState::NotConnected);
Jim Flynn672d06e2019-10-15 10:18:11 +01003101 // Reset the profiling service to stop any running thread
3102 options.m_EnableProfiling = false;
3103 profilingService.ResetExternalProfilingOptions(options, true);
3104}
3105
Sadik Armagan1625efc2021-06-10 18:24:34 +01003106TEST_CASE("CheckConfigureProfilingServiceOff")
Jim Flynn672d06e2019-10-15 10:18:11 +01003107{
Jim Flynn4c9ed1d2022-01-23 23:57:20 +00003108 ProfilingOptions options;
Cathal Corbett5aa9fd72022-02-25 15:33:28 +00003109 ProfilingService profilingService;
Sadik Armagan1625efc2021-06-10 18:24:34 +01003110 CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
Jim Flynn672d06e2019-10-15 10:18:11 +01003111 profilingService.ConfigureProfilingService(options);
3112 // should not move from Uninitialised
Sadik Armagan1625efc2021-06-10 18:24:34 +01003113 CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
Jim Flynn672d06e2019-10-15 10:18:11 +01003114 // Reset the profiling service to stop any running thread
3115 options.m_EnableProfiling = false;
3116 profilingService.ResetExternalProfilingOptions(options, true);
3117}
3118
Sadik Armagan1625efc2021-06-10 18:24:34 +01003119TEST_CASE("CheckProfilingServiceEnabled")
Colm Donelan2ba48d22019-11-29 09:10:59 +00003120{
3121 // Locally reduce log level to "Warning", as this test needs to parse a warning message from the standard output
3122 LogLevelSwapper logLevelSwapper(armnn::LogSeverity::Warning);
Jim Flynn4c9ed1d2022-01-23 23:57:20 +00003123 ProfilingOptions options;
Colm Donelan2ba48d22019-11-29 09:10:59 +00003124 options.m_EnableProfiling = true;
Cathal Corbett5aa9fd72022-02-25 15:33:28 +00003125 ProfilingService profilingService;
Colm Donelan2ba48d22019-11-29 09:10:59 +00003126 profilingService.ResetExternalProfilingOptions(options, true);
Sadik Armagan1625efc2021-06-10 18:24:34 +01003127 CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
Colm Donelan2ba48d22019-11-29 09:10:59 +00003128 profilingService.Update();
Sadik Armagan1625efc2021-06-10 18:24:34 +01003129 CHECK(profilingService.GetCurrentState() == ProfilingState::NotConnected);
Colm Donelan2ba48d22019-11-29 09:10:59 +00003130
3131 // Redirect the output to a local stream so that we can parse the warning message
3132 std::stringstream ss;
3133 StreamRedirector streamRedirector(std::cout, ss.rdbuf());
3134 profilingService.Update();
Finn Williams09ad6f92019-12-19 17:05:18 +00003135
3136 // Reset the profiling service to stop any running thread
3137 options.m_EnableProfiling = false;
3138 profilingService.ResetExternalProfilingOptions(options, true);
3139
Colm Donelan2ba48d22019-11-29 09:10:59 +00003140 streamRedirector.CancelRedirect();
3141
3142 // Check that the expected error has occurred and logged to the standard output
David Monahana8837bf2020-04-16 10:01:56 +01003143 if (ss.str().find("Cannot connect to stream socket: Connection refused") == std::string::npos)
Colm Donelan2ba48d22019-11-29 09:10:59 +00003144 {
3145 std::cout << ss.str();
Sadik Armagan1625efc2021-06-10 18:24:34 +01003146 FAIL("Expected string not found.");
Colm Donelan2ba48d22019-11-29 09:10:59 +00003147 }
Colm Donelan2ba48d22019-11-29 09:10:59 +00003148}
3149
Sadik Armagan1625efc2021-06-10 18:24:34 +01003150TEST_CASE("CheckProfilingServiceEnabledRuntime")
Colm Donelan2ba48d22019-11-29 09:10:59 +00003151{
3152 // Locally reduce log level to "Warning", as this test needs to parse a warning message from the standard output
3153 LogLevelSwapper logLevelSwapper(armnn::LogSeverity::Warning);
Jim Flynn4c9ed1d2022-01-23 23:57:20 +00003154 ProfilingOptions options;
Cathal Corbett5aa9fd72022-02-25 15:33:28 +00003155 ProfilingService profilingService;
Colm Donelan2ba48d22019-11-29 09:10:59 +00003156 profilingService.ResetExternalProfilingOptions(options, true);
Sadik Armagan1625efc2021-06-10 18:24:34 +01003157 CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
Colm Donelan2ba48d22019-11-29 09:10:59 +00003158 profilingService.Update();
Sadik Armagan1625efc2021-06-10 18:24:34 +01003159 CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
Colm Donelan2ba48d22019-11-29 09:10:59 +00003160 options.m_EnableProfiling = true;
3161 profilingService.ResetExternalProfilingOptions(options);
Sadik Armagan1625efc2021-06-10 18:24:34 +01003162 CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
Colm Donelan2ba48d22019-11-29 09:10:59 +00003163 profilingService.Update();
Sadik Armagan1625efc2021-06-10 18:24:34 +01003164 CHECK(profilingService.GetCurrentState() == ProfilingState::NotConnected);
Colm Donelan2ba48d22019-11-29 09:10:59 +00003165
3166 // Redirect the output to a local stream so that we can parse the warning message
3167 std::stringstream ss;
3168 StreamRedirector streamRedirector(std::cout, ss.rdbuf());
3169 profilingService.Update();
3170
Finn Williams09ad6f92019-12-19 17:05:18 +00003171 // Reset the profiling service to stop any running thread
3172 options.m_EnableProfiling = false;
3173 profilingService.ResetExternalProfilingOptions(options, true);
3174
Colm Donelan2ba48d22019-11-29 09:10:59 +00003175 streamRedirector.CancelRedirect();
3176
3177 // Check that the expected error has occurred and logged to the standard output
David Monahana8837bf2020-04-16 10:01:56 +01003178 if (ss.str().find("Cannot connect to stream socket: Connection refused") == std::string::npos)
Colm Donelan2ba48d22019-11-29 09:10:59 +00003179 {
3180 std::cout << ss.str();
Sadik Armagan1625efc2021-06-10 18:24:34 +01003181 FAIL("Expected string not found.");
Colm Donelan2ba48d22019-11-29 09:10:59 +00003182 }
Colm Donelan2ba48d22019-11-29 09:10:59 +00003183}
3184
Sadik Armagan1625efc2021-06-10 18:24:34 +01003185TEST_CASE("CheckProfilingServiceBadConnectionAcknowledgedPacket")
Colm Donelan2ba48d22019-11-29 09:10:59 +00003186{
3187 // Locally reduce log level to "Warning", as this test needs to parse a warning message from the standard output
3188 LogLevelSwapper logLevelSwapper(armnn::LogSeverity::Warning);
Sadik Armagan3184c902020-03-18 10:57:30 +00003189
Colm Donelan2ba48d22019-11-29 09:10:59 +00003190
3191 // Redirect the standard output to a local stream so that we can parse the warning message
3192 std::stringstream ss;
3193 StreamRedirector streamRedirector(std::cout, ss.rdbuf());
3194
Colm Donelan2ba48d22019-11-29 09:10:59 +00003195 // Reset the profiling service to the uninitialized state
Jim Flynn4c9ed1d2022-01-23 23:57:20 +00003196 ProfilingOptions options;
Colm Donelan2ba48d22019-11-29 09:10:59 +00003197 options.m_EnableProfiling = true;
Cathal Corbett5aa9fd72022-02-25 15:33:28 +00003198 ProfilingService profilingService;
Colm Donelan2ba48d22019-11-29 09:10:59 +00003199 profilingService.ResetExternalProfilingOptions(options, true);
3200
Sadik Armagan3184c902020-03-18 10:57:30 +00003201 // Swap the profiling connection factory in the profiling service instance with our mock one
3202 SwapProfilingConnectionFactoryHelper helper(profilingService);
3203
Colm Donelan2ba48d22019-11-29 09:10:59 +00003204 // Bring the profiling service to the "WaitingForAck" state
Sadik Armagan1625efc2021-06-10 18:24:34 +01003205 CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
Colm Donelan2ba48d22019-11-29 09:10:59 +00003206 profilingService.Update(); // Initialize the counter directory
Sadik Armagan1625efc2021-06-10 18:24:34 +01003207 CHECK(profilingService.GetCurrentState() == ProfilingState::NotConnected);
Colm Donelan2ba48d22019-11-29 09:10:59 +00003208 profilingService.Update(); // Create the profiling connection
3209
3210 // Get the mock profiling connection
3211 MockProfilingConnection* mockProfilingConnection = helper.GetMockProfilingConnection();
Sadik Armagan1625efc2021-06-10 18:24:34 +01003212 CHECK(mockProfilingConnection);
Colm Donelan2ba48d22019-11-29 09:10:59 +00003213
Sadik Armagan1625efc2021-06-10 18:24:34 +01003214 CHECK(profilingService.GetCurrentState() == ProfilingState::WaitingForAck);
Colm Donelan2ba48d22019-11-29 09:10:59 +00003215
3216 // Connection Acknowledged Packet header (word 0, word 1 is always zero):
3217 // 26:31 [6] packet_family: Control Packet Family, value 0b000000
3218 // 16:25 [10] packet_id: Packet identifier, value 0b0000000001
3219 // 8:15 [8] reserved: Reserved, value 0b00000000
3220 // 0:7 [8] reserved: Reserved, value 0b00000000
3221 uint32_t packetFamily = 0;
3222 uint32_t packetId = 37; // Wrong packet id!!!
3223 uint32_t header = ((packetFamily & 0x0000003F) << 26) | ((packetId & 0x000003FF) << 16);
3224
3225 // Create the Connection Acknowledged Packet
Jim Flynnbbfe6032020-07-20 16:57:44 +01003226 arm::pipe::Packet connectionAcknowledgedPacket(header);
Finn Williams09ad6f92019-12-19 17:05:18 +00003227 // Write an invalid "Connection Acknowledged" packet into the mock profiling connection, to simulate an invalid
3228 // reply from an external profiling service
Colm Donelan2ba48d22019-11-29 09:10:59 +00003229 mockProfilingConnection->WritePacket(std::move(connectionAcknowledgedPacket));
3230
Finn Williams09ad6f92019-12-19 17:05:18 +00003231 // Start the command thread
3232 profilingService.Update();
3233
3234 // Wait for the command thread to join
3235 options.m_EnableProfiling = false;
3236 profilingService.ResetExternalProfilingOptions(options, true);
Colm Donelan2ba48d22019-11-29 09:10:59 +00003237
3238 streamRedirector.CancelRedirect();
3239
3240 // Check that the expected error has occurred and logged to the standard output
David Monahana8837bf2020-04-16 10:01:56 +01003241 if (ss.str().find("Functor with requested PacketId=37 and Version=4194304 does not exist") == std::string::npos)
Colm Donelan2ba48d22019-11-29 09:10:59 +00003242 {
3243 std::cout << ss.str();
Sadik Armagan1625efc2021-06-10 18:24:34 +01003244 FAIL("Expected string not found.");
Colm Donelan2ba48d22019-11-29 09:10:59 +00003245 }
Colm Donelan2ba48d22019-11-29 09:10:59 +00003246}
3247
Sadik Armagan1625efc2021-06-10 18:24:34 +01003248TEST_CASE("CheckProfilingServiceBadRequestCounterDirectoryPacket")
Colm Donelan2ba48d22019-11-29 09:10:59 +00003249{
3250 // Locally reduce log level to "Warning", as this test needs to parse a warning message from the standard output
3251 LogLevelSwapper logLevelSwapper(armnn::LogSeverity::Warning);
Colm Donelan2ba48d22019-11-29 09:10:59 +00003252
3253 // Redirect the standard output to a local stream so that we can parse the warning message
3254 std::stringstream ss;
3255 StreamRedirector streamRedirector(std::cout, ss.rdbuf());
3256
3257 // Reset the profiling service to the uninitialized state
Jim Flynn4c9ed1d2022-01-23 23:57:20 +00003258 ProfilingOptions options;
Colm Donelan2ba48d22019-11-29 09:10:59 +00003259 options.m_EnableProfiling = true;
Cathal Corbett5aa9fd72022-02-25 15:33:28 +00003260 ProfilingService profilingService;
Colm Donelan2ba48d22019-11-29 09:10:59 +00003261 profilingService.ResetExternalProfilingOptions(options, true);
3262
Sadik Armagan3184c902020-03-18 10:57:30 +00003263 // Swap the profiling connection factory in the profiling service instance with our mock one
3264 SwapProfilingConnectionFactoryHelper helper(profilingService);
3265
Colm Donelan2ba48d22019-11-29 09:10:59 +00003266 // Bring the profiling service to the "Active" state
Sadik Armagan1625efc2021-06-10 18:24:34 +01003267 CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
Colm Donelan2ba48d22019-11-29 09:10:59 +00003268 helper.ForceTransitionToState(ProfilingState::NotConnected);
Sadik Armagan1625efc2021-06-10 18:24:34 +01003269 CHECK(profilingService.GetCurrentState() == ProfilingState::NotConnected);
Colm Donelan2ba48d22019-11-29 09:10:59 +00003270 profilingService.Update(); // Create the profiling connection
Sadik Armagan1625efc2021-06-10 18:24:34 +01003271 CHECK(profilingService.GetCurrentState() == ProfilingState::WaitingForAck);
Colm Donelan2ba48d22019-11-29 09:10:59 +00003272
3273 // Get the mock profiling connection
3274 MockProfilingConnection* mockProfilingConnection = helper.GetMockProfilingConnection();
Sadik Armagan1625efc2021-06-10 18:24:34 +01003275 CHECK(mockProfilingConnection);
Colm Donelan2ba48d22019-11-29 09:10:59 +00003276
Colm Donelan2ba48d22019-11-29 09:10:59 +00003277 // Write a valid "Request Counter Directory" packet into the mock profiling connection, to simulate a valid
3278 // reply from an external profiling service
3279
3280 // Request Counter Directory packet header (word 0, word 1 is always zero):
3281 // 26:31 [6] packet_family: Control Packet Family, value 0b000000
3282 // 16:25 [10] packet_id: Packet identifier, value 0b0000000011
3283 // 8:15 [8] reserved: Reserved, value 0b00000000
3284 // 0:7 [8] reserved: Reserved, value 0b00000000
3285 uint32_t packetFamily = 0;
3286 uint32_t packetId = 123; // Wrong packet id!!!
3287 uint32_t header = ((packetFamily & 0x0000003F) << 26) | ((packetId & 0x000003FF) << 16);
3288
3289 // Create the Request Counter Directory packet
Jim Flynnbbfe6032020-07-20 16:57:44 +01003290 arm::pipe::Packet requestCounterDirectoryPacket(header);
Colm Donelan2ba48d22019-11-29 09:10:59 +00003291
3292 // Write the packet to the mock profiling connection
3293 mockProfilingConnection->WritePacket(std::move(requestCounterDirectoryPacket));
3294
Finn Williams09ad6f92019-12-19 17:05:18 +00003295 // Start the command handler and the send thread
3296 profilingService.Update();
3297
3298 // Reset the profiling service to stop and join any running thread
3299 options.m_EnableProfiling = false;
3300 profilingService.ResetExternalProfilingOptions(options, true);
Colm Donelan2ba48d22019-11-29 09:10:59 +00003301
3302 streamRedirector.CancelRedirect();
3303
3304 // Check that the expected error has occurred and logged to the standard output
David Monahana8837bf2020-04-16 10:01:56 +01003305 if (ss.str().find("Functor with requested PacketId=123 and Version=4194304 does not exist") == std::string::npos)
Colm Donelan2ba48d22019-11-29 09:10:59 +00003306 {
3307 std::cout << ss.str();
Sadik Armagan1625efc2021-06-10 18:24:34 +01003308 FAIL("Expected string not found.");
Colm Donelan2ba48d22019-11-29 09:10:59 +00003309 }
Colm Donelan2ba48d22019-11-29 09:10:59 +00003310}
3311
Sadik Armagan1625efc2021-06-10 18:24:34 +01003312TEST_CASE("CheckProfilingServiceBadPeriodicCounterSelectionPacket")
Colm Donelan2ba48d22019-11-29 09:10:59 +00003313{
3314 // Locally reduce log level to "Warning", as this test needs to parse a warning message from the standard output
3315 LogLevelSwapper logLevelSwapper(armnn::LogSeverity::Warning);
Colm Donelan2ba48d22019-11-29 09:10:59 +00003316
3317 // Redirect the standard output to a local stream so that we can parse the warning message
3318 std::stringstream ss;
3319 StreamRedirector streamRedirector(std::cout, ss.rdbuf());
3320
3321 // Reset the profiling service to the uninitialized state
Jim Flynn4c9ed1d2022-01-23 23:57:20 +00003322 ProfilingOptions options;
Colm Donelan2ba48d22019-11-29 09:10:59 +00003323 options.m_EnableProfiling = true;
Cathal Corbett5aa9fd72022-02-25 15:33:28 +00003324 ProfilingService profilingService;
Colm Donelan2ba48d22019-11-29 09:10:59 +00003325 profilingService.ResetExternalProfilingOptions(options, true);
3326
Sadik Armagan3184c902020-03-18 10:57:30 +00003327 // Swap the profiling connection factory in the profiling service instance with our mock one
3328 SwapProfilingConnectionFactoryHelper helper(profilingService);
3329
Colm Donelan2ba48d22019-11-29 09:10:59 +00003330 // Bring the profiling service to the "Active" state
Sadik Armagan1625efc2021-06-10 18:24:34 +01003331 CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
Colm Donelan2ba48d22019-11-29 09:10:59 +00003332 profilingService.Update(); // Initialize the counter directory
Sadik Armagan1625efc2021-06-10 18:24:34 +01003333 CHECK(profilingService.GetCurrentState() == ProfilingState::NotConnected);
Colm Donelan2ba48d22019-11-29 09:10:59 +00003334 profilingService.Update(); // Create the profiling connection
Sadik Armagan1625efc2021-06-10 18:24:34 +01003335 CHECK(profilingService.GetCurrentState() == ProfilingState::WaitingForAck);
Colm Donelan2ba48d22019-11-29 09:10:59 +00003336 profilingService.Update(); // Start the command handler and the send thread
3337
3338 // Get the mock profiling connection
3339 MockProfilingConnection* mockProfilingConnection = helper.GetMockProfilingConnection();
Sadik Armagan1625efc2021-06-10 18:24:34 +01003340 CHECK(mockProfilingConnection);
Colm Donelan2ba48d22019-11-29 09:10:59 +00003341
Colm Donelan2ba48d22019-11-29 09:10:59 +00003342 // Write a "Periodic Counter Selection" packet into the mock profiling connection, to simulate an input from an
3343 // external profiling service
3344
3345 // Periodic Counter Selection packet header:
3346 // 26:31 [6] packet_family: Control Packet Family, value 0b000000
3347 // 16:25 [10] packet_id: Packet identifier, value 0b0000000100
3348 // 8:15 [8] reserved: Reserved, value 0b00000000
3349 // 0:7 [8] reserved: Reserved, value 0b00000000
3350 uint32_t packetFamily = 0;
3351 uint32_t packetId = 999; // Wrong packet id!!!
3352 uint32_t header = ((packetFamily & 0x0000003F) << 26) | ((packetId & 0x000003FF) << 16);
3353
3354 // Create the Periodic Counter Selection packet
Jim Flynnbbfe6032020-07-20 16:57:44 +01003355 // Length == 0, this will disable the collection of counters
3356 arm::pipe::Packet periodicCounterSelectionPacket(header);
Colm Donelan2ba48d22019-11-29 09:10:59 +00003357
3358 // Write the packet to the mock profiling connection
3359 mockProfilingConnection->WritePacket(std::move(periodicCounterSelectionPacket));
Finn Williams09ad6f92019-12-19 17:05:18 +00003360 profilingService.Update();
Colm Donelan2ba48d22019-11-29 09:10:59 +00003361
Finn Williams09ad6f92019-12-19 17:05:18 +00003362 // Reset the profiling service to stop any running thread
3363 options.m_EnableProfiling = false;
3364 profilingService.ResetExternalProfilingOptions(options, true);
Colm Donelan2ba48d22019-11-29 09:10:59 +00003365
3366 // Check that the expected error has occurred and logged to the standard output
3367 streamRedirector.CancelRedirect();
3368
3369 // Check that the expected error has occurred and logged to the standard output
David Monahana8837bf2020-04-16 10:01:56 +01003370 if (ss.str().find("Functor with requested PacketId=999 and Version=4194304 does not exist") == std::string::npos)
Colm Donelan2ba48d22019-11-29 09:10:59 +00003371 {
3372 std::cout << ss.str();
Sadik Armagan1625efc2021-06-10 18:24:34 +01003373 FAIL("Expected string not found.");
Colm Donelan2ba48d22019-11-29 09:10:59 +00003374 }
Colm Donelan2ba48d22019-11-29 09:10:59 +00003375}
Jim Flynn97897022020-02-02 12:52:59 +00003376
Sadik Armagan1625efc2021-06-10 18:24:34 +01003377TEST_CASE("CheckCounterIdMap")
David Monahande803072020-01-30 12:44:23 +00003378{
3379 CounterIdMap counterIdMap;
Sadik Armagan1625efc2021-06-10 18:24:34 +01003380 CHECK_THROWS_AS(counterIdMap.GetBackendId(0), armnn::Exception);
3381 CHECK_THROWS_AS(counterIdMap.GetGlobalId(0, armnn::profiling::BACKEND_ID), armnn::Exception);
David Monahande803072020-01-30 12:44:23 +00003382
3383 uint16_t globalCounterIds = 0;
3384
3385 armnn::BackendId cpuRefId(armnn::Compute::CpuRef);
3386 armnn::BackendId cpuAccId(armnn::Compute::CpuAcc);
3387
3388 std::vector<uint16_t> cpuRefCounters = {0, 1, 2, 3};
3389 std::vector<uint16_t> cpuAccCounters = {0, 1};
3390
3391 for (uint16_t backendCounterId : cpuRefCounters)
3392 {
3393 counterIdMap.RegisterMapping(globalCounterIds, backendCounterId, cpuRefId);
3394 ++globalCounterIds;
3395 }
3396 for (uint16_t backendCounterId : cpuAccCounters)
3397 {
3398 counterIdMap.RegisterMapping(globalCounterIds, backendCounterId, cpuAccId);
3399 ++globalCounterIds;
3400 }
3401
Sadik Armagan1625efc2021-06-10 18:24:34 +01003402 CHECK(counterIdMap.GetBackendId(0) == (std::pair<uint16_t, armnn::BackendId>(0, cpuRefId)));
3403 CHECK(counterIdMap.GetBackendId(1) == (std::pair<uint16_t, armnn::BackendId>(1, cpuRefId)));
3404 CHECK(counterIdMap.GetBackendId(2) == (std::pair<uint16_t, armnn::BackendId>(2, cpuRefId)));
3405 CHECK(counterIdMap.GetBackendId(3) == (std::pair<uint16_t, armnn::BackendId>(3, cpuRefId)));
3406 CHECK(counterIdMap.GetBackendId(4) == (std::pair<uint16_t, armnn::BackendId>(0, cpuAccId)));
3407 CHECK(counterIdMap.GetBackendId(5) == (std::pair<uint16_t, armnn::BackendId>(1, cpuAccId)));
David Monahande803072020-01-30 12:44:23 +00003408
Sadik Armagan1625efc2021-06-10 18:24:34 +01003409 CHECK(counterIdMap.GetGlobalId(0, cpuRefId) == 0);
3410 CHECK(counterIdMap.GetGlobalId(1, cpuRefId) == 1);
3411 CHECK(counterIdMap.GetGlobalId(2, cpuRefId) == 2);
3412 CHECK(counterIdMap.GetGlobalId(3, cpuRefId) == 3);
3413 CHECK(counterIdMap.GetGlobalId(0, cpuAccId) == 4);
3414 CHECK(counterIdMap.GetGlobalId(1, cpuAccId) == 5);
David Monahande803072020-01-30 12:44:23 +00003415}
Colm Donelan2ba48d22019-11-29 09:10:59 +00003416
Sadik Armagan1625efc2021-06-10 18:24:34 +01003417TEST_CASE("CheckRegisterBackendCounters")
Jim Flynn97897022020-02-02 12:52:59 +00003418{
Cathal Corbett5aa9fd72022-02-25 15:33:28 +00003419 uint16_t globalCounterIds = INFERENCES_RUN;
Jim Flynn97897022020-02-02 12:52:59 +00003420 armnn::BackendId cpuRefId(armnn::Compute::CpuRef);
3421
Jim Flynn97897022020-02-02 12:52:59 +00003422 // Reset the profiling service to the uninitialized state
Jim Flynn4c9ed1d2022-01-23 23:57:20 +00003423 ProfilingOptions options;
Jim Flynn97897022020-02-02 12:52:59 +00003424 options.m_EnableProfiling = true;
Sadik Armagan3184c902020-03-18 10:57:30 +00003425 ProfilingService profilingService;
Jim Flynn97897022020-02-02 12:52:59 +00003426 profilingService.ResetExternalProfilingOptions(options, true);
3427
Sadik Armagan3184c902020-03-18 10:57:30 +00003428 RegisterBackendCounters registerBackendCounters(globalCounterIds, cpuRefId, profilingService);
3429
3430
3431
Sadik Armagan1625efc2021-06-10 18:24:34 +01003432 CHECK(profilingService.GetCounterDirectory().GetCategories().empty());
Jim Flynn97897022020-02-02 12:52:59 +00003433 registerBackendCounters.RegisterCategory("categoryOne");
3434 auto categoryOnePtr = profilingService.GetCounterDirectory().GetCategory("categoryOne");
Sadik Armagan1625efc2021-06-10 18:24:34 +01003435 CHECK(categoryOnePtr);
Jim Flynn97897022020-02-02 12:52:59 +00003436
Sadik Armagan1625efc2021-06-10 18:24:34 +01003437 CHECK(profilingService.GetCounterDirectory().GetDevices().empty());
Jim Flynn97897022020-02-02 12:52:59 +00003438 globalCounterIds = registerBackendCounters.RegisterDevice("deviceOne");
3439 auto deviceOnePtr = profilingService.GetCounterDirectory().GetDevice(globalCounterIds);
Sadik Armagan1625efc2021-06-10 18:24:34 +01003440 CHECK(deviceOnePtr);
3441 CHECK(deviceOnePtr->m_Name == "deviceOne");
Jim Flynn97897022020-02-02 12:52:59 +00003442
Sadik Armagan1625efc2021-06-10 18:24:34 +01003443 CHECK(profilingService.GetCounterDirectory().GetCounterSets().empty());
Jim Flynn97897022020-02-02 12:52:59 +00003444 globalCounterIds = registerBackendCounters.RegisterCounterSet("counterSetOne");
3445 auto counterSetOnePtr = profilingService.GetCounterDirectory().GetCounterSet(globalCounterIds);
Sadik Armagan1625efc2021-06-10 18:24:34 +01003446 CHECK(counterSetOnePtr);
3447 CHECK(counterSetOnePtr->m_Name == "counterSetOne");
Jim Flynn97897022020-02-02 12:52:59 +00003448
3449 uint16_t newGlobalCounterId = registerBackendCounters.RegisterCounter(0,
3450 "categoryOne",
3451 0,
3452 0,
3453 1.f,
3454 "CounterOne",
3455 "first test counter");
Cathal Corbett5aa9fd72022-02-25 15:33:28 +00003456 CHECK((newGlobalCounterId = INFERENCES_RUN + 1));
Jim Flynn97897022020-02-02 12:52:59 +00003457 uint16_t mappedGlobalId = profilingService.GetCounterMappings().GetGlobalId(0, cpuRefId);
Sadik Armagan1625efc2021-06-10 18:24:34 +01003458 CHECK(mappedGlobalId == newGlobalCounterId);
Jim Flynn97897022020-02-02 12:52:59 +00003459 auto backendMapping = profilingService.GetCounterMappings().GetBackendId(newGlobalCounterId);
Sadik Armagan1625efc2021-06-10 18:24:34 +01003460 CHECK(backendMapping.first == 0);
3461 CHECK(backendMapping.second == cpuRefId);
Jim Flynn97897022020-02-02 12:52:59 +00003462
3463 // Reset the profiling service to stop any running thread
3464 options.m_EnableProfiling = false;
3465 profilingService.ResetExternalProfilingOptions(options, true);
3466}
3467
Sadik Armagan1625efc2021-06-10 18:24:34 +01003468TEST_CASE("CheckCounterStatusQuery")
James Conroy2dcd3fe2020-02-06 18:34:52 +00003469{
Jim Flynn4c9ed1d2022-01-23 23:57:20 +00003470 ProfilingOptions options;
3471 options.m_EnableProfiling = true;
James Conroy2dcd3fe2020-02-06 18:34:52 +00003472
3473 // Reset the profiling service to the uninitialized state
Sadik Armagan3184c902020-03-18 10:57:30 +00003474 ProfilingService profilingService;
Jim Flynn4c9ed1d2022-01-23 23:57:20 +00003475 profilingService.ResetExternalProfilingOptions(options, true);
James Conroy2dcd3fe2020-02-06 18:34:52 +00003476
3477 const armnn::BackendId cpuRefId(armnn::Compute::CpuRef);
3478 const armnn::BackendId cpuAccId(armnn::Compute::CpuAcc);
3479
3480 // Create BackendProfiling for each backend
3481 BackendProfiling backendProfilingCpuRef(options, profilingService, cpuRefId);
3482 BackendProfiling backendProfilingCpuAcc(options, profilingService, cpuAccId);
3483
Cathal Corbett5aa9fd72022-02-25 15:33:28 +00003484 uint16_t initialNumGlobalCounterIds = INFERENCES_RUN;
James Conroy2dcd3fe2020-02-06 18:34:52 +00003485
3486 // Create RegisterBackendCounters for CpuRef
Sadik Armagan3184c902020-03-18 10:57:30 +00003487 RegisterBackendCounters registerBackendCountersCpuRef(initialNumGlobalCounterIds, cpuRefId, profilingService);
James Conroy2dcd3fe2020-02-06 18:34:52 +00003488
3489 // Create 'testCategory' in CounterDirectory (backend agnostic)
Sadik Armagan1625efc2021-06-10 18:24:34 +01003490 CHECK(profilingService.GetCounterDirectory().GetCategories().empty());
James Conroy2dcd3fe2020-02-06 18:34:52 +00003491 registerBackendCountersCpuRef.RegisterCategory("testCategory");
3492 auto categoryOnePtr = profilingService.GetCounterDirectory().GetCategory("testCategory");
Sadik Armagan1625efc2021-06-10 18:24:34 +01003493 CHECK(categoryOnePtr);
James Conroy2dcd3fe2020-02-06 18:34:52 +00003494
3495 // Counters:
3496 // Global | Local | Backend
3497 // 5 | 0 | CpuRef
3498 // 6 | 1 | CpuRef
3499 // 7 | 1 | CpuAcc
3500
3501 std::vector<uint16_t> cpuRefCounters = {0, 1};
3502 std::vector<uint16_t> cpuAccCounters = {0};
3503
3504 // Register the backend counters for CpuRef and validate GetGlobalId and GetBackendId
3505 uint16_t currentNumGlobalCounterIds = registerBackendCountersCpuRef.RegisterCounter(
3506 0, "testCategory", 0, 0, 1.f, "CpuRefCounter0", "Zeroth CpuRef Counter");
Sadik Armagan1625efc2021-06-10 18:24:34 +01003507 CHECK(currentNumGlobalCounterIds == initialNumGlobalCounterIds + 1);
James Conroy2dcd3fe2020-02-06 18:34:52 +00003508 uint16_t mappedGlobalId = profilingService.GetCounterMappings().GetGlobalId(0, cpuRefId);
Sadik Armagan1625efc2021-06-10 18:24:34 +01003509 CHECK(mappedGlobalId == currentNumGlobalCounterIds);
James Conroy2dcd3fe2020-02-06 18:34:52 +00003510 auto backendMapping = profilingService.GetCounterMappings().GetBackendId(currentNumGlobalCounterIds);
Sadik Armagan1625efc2021-06-10 18:24:34 +01003511 CHECK(backendMapping.first == 0);
3512 CHECK(backendMapping.second == cpuRefId);
James Conroy2dcd3fe2020-02-06 18:34:52 +00003513
3514 currentNumGlobalCounterIds = registerBackendCountersCpuRef.RegisterCounter(
3515 1, "testCategory", 0, 0, 1.f, "CpuRefCounter1", "First CpuRef Counter");
Sadik Armagan1625efc2021-06-10 18:24:34 +01003516 CHECK(currentNumGlobalCounterIds == initialNumGlobalCounterIds + 2);
James Conroy2dcd3fe2020-02-06 18:34:52 +00003517 mappedGlobalId = profilingService.GetCounterMappings().GetGlobalId(1, cpuRefId);
Sadik Armagan1625efc2021-06-10 18:24:34 +01003518 CHECK(mappedGlobalId == currentNumGlobalCounterIds);
James Conroy2dcd3fe2020-02-06 18:34:52 +00003519 backendMapping = profilingService.GetCounterMappings().GetBackendId(currentNumGlobalCounterIds);
Sadik Armagan1625efc2021-06-10 18:24:34 +01003520 CHECK(backendMapping.first == 1);
3521 CHECK(backendMapping.second == cpuRefId);
James Conroy2dcd3fe2020-02-06 18:34:52 +00003522
3523 // Create RegisterBackendCounters for CpuAcc
Sadik Armagan3184c902020-03-18 10:57:30 +00003524 RegisterBackendCounters registerBackendCountersCpuAcc(currentNumGlobalCounterIds, cpuAccId, profilingService);
James Conroy2dcd3fe2020-02-06 18:34:52 +00003525
3526 // Register the backend counter for CpuAcc and validate GetGlobalId and GetBackendId
3527 currentNumGlobalCounterIds = registerBackendCountersCpuAcc.RegisterCounter(
3528 0, "testCategory", 0, 0, 1.f, "CpuAccCounter0", "Zeroth CpuAcc Counter");
Sadik Armagan1625efc2021-06-10 18:24:34 +01003529 CHECK(currentNumGlobalCounterIds == initialNumGlobalCounterIds + 3);
James Conroy2dcd3fe2020-02-06 18:34:52 +00003530 mappedGlobalId = profilingService.GetCounterMappings().GetGlobalId(0, cpuAccId);
Sadik Armagan1625efc2021-06-10 18:24:34 +01003531 CHECK(mappedGlobalId == currentNumGlobalCounterIds);
James Conroy2dcd3fe2020-02-06 18:34:52 +00003532 backendMapping = profilingService.GetCounterMappings().GetBackendId(currentNumGlobalCounterIds);
Sadik Armagan1625efc2021-06-10 18:24:34 +01003533 CHECK(backendMapping.first == 0);
3534 CHECK(backendMapping.second == cpuAccId);
James Conroy2dcd3fe2020-02-06 18:34:52 +00003535
3536 // Create vectors for active counters
3537 const std::vector<uint16_t> activeGlobalCounterIds = {5}; // CpuRef(0) activated
3538 const std::vector<uint16_t> newActiveGlobalCounterIds = {6, 7}; // CpuRef(0) and CpuAcc(1) activated
3539
3540 const uint32_t capturePeriod = 200;
3541 const uint32_t newCapturePeriod = 100;
3542
3543 // Set capture period and active counters in CaptureData
Finn Williams032bc742020-02-12 11:02:34 +00003544 profilingService.SetCaptureData(capturePeriod, activeGlobalCounterIds, {});
James Conroy2dcd3fe2020-02-06 18:34:52 +00003545
3546 // Get vector of active counters for CpuRef and CpuAcc backends
3547 std::vector<CounterStatus> cpuRefCounterStatus = backendProfilingCpuRef.GetActiveCounters();
3548 std::vector<CounterStatus> cpuAccCounterStatus = backendProfilingCpuAcc.GetActiveCounters();
Sadik Armagan1625efc2021-06-10 18:24:34 +01003549 CHECK_EQ(cpuRefCounterStatus.size(), 1);
3550 CHECK_EQ(cpuAccCounterStatus.size(), 0);
James Conroy2dcd3fe2020-02-06 18:34:52 +00003551
3552 // Check active CpuRef counter
Sadik Armagan1625efc2021-06-10 18:24:34 +01003553 CHECK_EQ(cpuRefCounterStatus[0].m_GlobalCounterId, activeGlobalCounterIds[0]);
3554 CHECK_EQ(cpuRefCounterStatus[0].m_BackendCounterId, cpuRefCounters[0]);
3555 CHECK_EQ(cpuRefCounterStatus[0].m_SamplingRateInMicroseconds, capturePeriod);
3556 CHECK_EQ(cpuRefCounterStatus[0].m_Enabled, true);
James Conroy2dcd3fe2020-02-06 18:34:52 +00003557
3558 // Check inactive CpuRef counter
3559 CounterStatus inactiveCpuRefCounter = backendProfilingCpuRef.GetCounterStatus(cpuRefCounters[1]);
Sadik Armagan1625efc2021-06-10 18:24:34 +01003560 CHECK_EQ(inactiveCpuRefCounter.m_GlobalCounterId, 6);
3561 CHECK_EQ(inactiveCpuRefCounter.m_BackendCounterId, cpuRefCounters[1]);
3562 CHECK_EQ(inactiveCpuRefCounter.m_SamplingRateInMicroseconds, 0);
3563 CHECK_EQ(inactiveCpuRefCounter.m_Enabled, false);
James Conroy2dcd3fe2020-02-06 18:34:52 +00003564
3565 // Check inactive CpuAcc counter
3566 CounterStatus inactiveCpuAccCounter = backendProfilingCpuAcc.GetCounterStatus(cpuAccCounters[0]);
Sadik Armagan1625efc2021-06-10 18:24:34 +01003567 CHECK_EQ(inactiveCpuAccCounter.m_GlobalCounterId, 7);
3568 CHECK_EQ(inactiveCpuAccCounter.m_BackendCounterId, cpuAccCounters[0]);
3569 CHECK_EQ(inactiveCpuAccCounter.m_SamplingRateInMicroseconds, 0);
3570 CHECK_EQ(inactiveCpuAccCounter.m_Enabled, false);
James Conroy2dcd3fe2020-02-06 18:34:52 +00003571
3572 // Set new capture period and new active counters in CaptureData
Finn Williams032bc742020-02-12 11:02:34 +00003573 profilingService.SetCaptureData(newCapturePeriod, newActiveGlobalCounterIds, {});
James Conroy2dcd3fe2020-02-06 18:34:52 +00003574
3575 // Get vector of active counters for CpuRef and CpuAcc backends
3576 cpuRefCounterStatus = backendProfilingCpuRef.GetActiveCounters();
3577 cpuAccCounterStatus = backendProfilingCpuAcc.GetActiveCounters();
Sadik Armagan1625efc2021-06-10 18:24:34 +01003578 CHECK_EQ(cpuRefCounterStatus.size(), 1);
3579 CHECK_EQ(cpuAccCounterStatus.size(), 1);
James Conroy2dcd3fe2020-02-06 18:34:52 +00003580
3581 // Check active CpuRef counter
Sadik Armagan1625efc2021-06-10 18:24:34 +01003582 CHECK_EQ(cpuRefCounterStatus[0].m_GlobalCounterId, newActiveGlobalCounterIds[0]);
3583 CHECK_EQ(cpuRefCounterStatus[0].m_BackendCounterId, cpuRefCounters[1]);
3584 CHECK_EQ(cpuRefCounterStatus[0].m_SamplingRateInMicroseconds, newCapturePeriod);
3585 CHECK_EQ(cpuRefCounterStatus[0].m_Enabled, true);
James Conroy2dcd3fe2020-02-06 18:34:52 +00003586
3587 // Check active CpuAcc counter
Sadik Armagan1625efc2021-06-10 18:24:34 +01003588 CHECK_EQ(cpuAccCounterStatus[0].m_GlobalCounterId, newActiveGlobalCounterIds[1]);
3589 CHECK_EQ(cpuAccCounterStatus[0].m_BackendCounterId, cpuAccCounters[0]);
3590 CHECK_EQ(cpuAccCounterStatus[0].m_SamplingRateInMicroseconds, newCapturePeriod);
3591 CHECK_EQ(cpuAccCounterStatus[0].m_Enabled, true);
James Conroy2dcd3fe2020-02-06 18:34:52 +00003592
3593 // Check inactive CpuRef counter
3594 inactiveCpuRefCounter = backendProfilingCpuRef.GetCounterStatus(cpuRefCounters[0]);
Sadik Armagan1625efc2021-06-10 18:24:34 +01003595 CHECK_EQ(inactiveCpuRefCounter.m_GlobalCounterId, 5);
3596 CHECK_EQ(inactiveCpuRefCounter.m_BackendCounterId, cpuRefCounters[0]);
3597 CHECK_EQ(inactiveCpuRefCounter.m_SamplingRateInMicroseconds, 0);
3598 CHECK_EQ(inactiveCpuRefCounter.m_Enabled, false);
James Conroy2dcd3fe2020-02-06 18:34:52 +00003599
3600 // Reset the profiling service to stop any running thread
Jim Flynn4c9ed1d2022-01-23 23:57:20 +00003601 options.m_EnableProfiling = false;
3602 profilingService.ResetExternalProfilingOptions(options, true);
James Conroy2dcd3fe2020-02-06 18:34:52 +00003603}
3604
Sadik Armagan1625efc2021-06-10 18:24:34 +01003605TEST_CASE("CheckRegisterCounters")
Sadik Armagancab588a2020-02-17 11:33:31 +00003606{
Jim Flynn4c9ed1d2022-01-23 23:57:20 +00003607 ProfilingOptions options;
3608 options.m_EnableProfiling = true;
Sadik Armagancab588a2020-02-17 11:33:31 +00003609 MockBufferManager mockBuffer(1024);
Sadik Armagan3184c902020-03-18 10:57:30 +00003610
Sadik Armagancab588a2020-02-17 11:33:31 +00003611 CaptureData captureData;
Jim Flynn4c9ed1d2022-01-23 23:57:20 +00003612 MockProfilingService mockProfilingService(mockBuffer, options.m_EnableProfiling, captureData);
Sadik Armagancab588a2020-02-17 11:33:31 +00003613 armnn::BackendId cpuRefId(armnn::Compute::CpuRef);
3614
3615 mockProfilingService.RegisterMapping(6, 0, cpuRefId);
3616 mockProfilingService.RegisterMapping(7, 1, cpuRefId);
3617 mockProfilingService.RegisterMapping(8, 2, cpuRefId);
3618
Cathal Corbett5aa9fd72022-02-25 15:33:28 +00003619 BackendProfiling backendProfiling(options,
Sadik Armagancab588a2020-02-17 11:33:31 +00003620 mockProfilingService,
3621 cpuRefId);
3622
Cathal Corbett5aa9fd72022-02-25 15:33:28 +00003623 Timestamp timestamp;
Sadik Armagancab588a2020-02-17 11:33:31 +00003624 timestamp.timestamp = 1000998;
3625 timestamp.counterValues.emplace_back(0, 700);
3626 timestamp.counterValues.emplace_back(2, 93);
Cathal Corbett5aa9fd72022-02-25 15:33:28 +00003627 std::vector<Timestamp> timestamps;
Sadik Armagancab588a2020-02-17 11:33:31 +00003628 timestamps.push_back(timestamp);
3629 backendProfiling.ReportCounters(timestamps);
3630
3631 auto readBuffer = mockBuffer.GetReadableBuffer();
3632
3633 uint32_t headerWord0 = ReadUint32(readBuffer, 0);
3634 uint32_t headerWord1 = ReadUint32(readBuffer, 4);
3635 uint64_t readTimestamp = ReadUint64(readBuffer, 8);
3636
Sadik Armagan1625efc2021-06-10 18:24:34 +01003637 CHECK(((headerWord0 >> 26) & 0x0000003F) == 3); // packet family
3638 CHECK(((headerWord0 >> 19) & 0x0000007F) == 0); // packet class
3639 CHECK(((headerWord0 >> 16) & 0x00000007) == 0); // packet type
3640 CHECK(headerWord1 == 20); // data length
3641 CHECK(1000998 == readTimestamp); // capture period
Sadik Armagancab588a2020-02-17 11:33:31 +00003642
3643 uint32_t offset = 16;
3644 // Check Counter Index
3645 uint16_t readIndex = ReadUint16(readBuffer, offset);
Sadik Armagan1625efc2021-06-10 18:24:34 +01003646 CHECK(6 == readIndex);
Sadik Armagancab588a2020-02-17 11:33:31 +00003647
3648 // Check Counter Value
3649 offset += 2;
3650 uint32_t readValue = ReadUint32(readBuffer, offset);
Sadik Armagan1625efc2021-06-10 18:24:34 +01003651 CHECK(700 == readValue);
Sadik Armagancab588a2020-02-17 11:33:31 +00003652
3653 // Check Counter Index
3654 offset += 4;
3655 readIndex = ReadUint16(readBuffer, offset);
Sadik Armagan1625efc2021-06-10 18:24:34 +01003656 CHECK(8 == readIndex);
Sadik Armagancab588a2020-02-17 11:33:31 +00003657
3658 // Check Counter Value
3659 offset += 2;
3660 readValue = ReadUint32(readBuffer, offset);
Sadik Armagan1625efc2021-06-10 18:24:34 +01003661 CHECK(93 == readValue);
Sadik Armagancab588a2020-02-17 11:33:31 +00003662}
3663
Sadik Armagan1625efc2021-06-10 18:24:34 +01003664TEST_CASE("CheckFileFormat") {
Isabella Gottardia0687ee2020-03-11 18:04:20 +00003665 // Locally reduce log level to "Warning", as this test needs to parse a warning message from the standard output
3666 LogLevelSwapper logLevelSwapper(armnn::LogSeverity::Warning);
3667
3668 // Create profiling options.
Jim Flynn4c9ed1d2022-01-23 23:57:20 +00003669 ProfilingOptions options;
Isabella Gottardia0687ee2020-03-11 18:04:20 +00003670 options.m_EnableProfiling = true;
3671 // Check the default value set to binary
Sadik Armagan1625efc2021-06-10 18:24:34 +01003672 CHECK(options.m_FileFormat == "binary");
Isabella Gottardia0687ee2020-03-11 18:04:20 +00003673
3674 // Change file format to an unsupported value
3675 options.m_FileFormat = "json";
3676 // Enable the profiling service
Cathal Corbett5aa9fd72022-02-25 15:33:28 +00003677 ProfilingService profilingService;
Isabella Gottardia0687ee2020-03-11 18:04:20 +00003678 profilingService.ResetExternalProfilingOptions(options, true);
3679 // Start the command handler and the send thread
3680 profilingService.Update();
Sadik Armagan1625efc2021-06-10 18:24:34 +01003681 CHECK(profilingService.GetCurrentState()==ProfilingState::NotConnected);
Isabella Gottardia0687ee2020-03-11 18:04:20 +00003682
3683 // Redirect the output to a local stream so that we can parse the warning message
3684 std::stringstream ss;
3685 StreamRedirector streamRedirector(std::cout, ss.rdbuf());
3686
3687 // When Update is called and the current state is ProfilingState::NotConnected
3688 // an exception will be raised from GetProfilingConnection and displayed as warning in the output local stream
3689 profilingService.Update();
3690
3691 streamRedirector.CancelRedirect();
3692
3693 // Check that the expected error has occurred and logged to the standard output
David Monahana8837bf2020-04-16 10:01:56 +01003694 if (ss.str().find("Unsupported profiling file format, only binary is supported") == std::string::npos)
Isabella Gottardia0687ee2020-03-11 18:04:20 +00003695 {
3696 std::cout << ss.str();
Sadik Armagan1625efc2021-06-10 18:24:34 +01003697 FAIL("Expected string not found.");
Isabella Gottardia0687ee2020-03-11 18:04:20 +00003698 }
3699}
3700
Sadik Armagan1625efc2021-06-10 18:24:34 +01003701}