blob: 12a0105563e13c42964c4a33b3a8d2c2ff052f2c [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
Aron Virginas-Tare898db92019-08-22 12:56:34 +010054using namespace armnn::profiling;
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
533 ProfilingStateMachine profilingState16(armnn::profiling::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;
Sadik Armagan3184c902020-03-18 10:57:30 +0000660 armnn::profiling::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;
Sadik Armagan3184c902020-03-18 10:57:30 +0000670 armnn::profiling::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;
Sadik Armagan3184c902020-03-18 10:57:30 +0000694 armnn::profiling::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());
Sadik Armagan95e9efc2021-08-05 15:01:07 +0100705 uint16_t inferencesRun = armnn::profiling::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;
Sadik Armagan1625efc2021-06-10 18:24:34 +0100841 CHECK_THROWS_AS(noCategory = counterDirectory.RegisterCategory(""), armnn::InvalidArgumentException);
842 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"),
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100847 armnn::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),
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100874 armnn::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),
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100901 armnn::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;
Sadik Armagan1625efc2021-06-10 18:24:34 +0100964 CHECK_THROWS_AS(noDevice = counterDirectory.RegisterDevice(""), armnn::InvalidArgumentException);
965 CHECK(counterDirectory.GetDeviceCount() == 0);
966 CHECK(!noDevice);
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100967
968 // Register a device with an invalid name
Sadik Armagan1625efc2021-06-10 18:24:34 +0100969 CHECK_THROWS_AS(noDevice = counterDirectory.RegisterDevice("inv@lid nam€"), armnn::InvalidArgumentException);
970 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;
Sadik Armagan1625efc2021-06-10 18:24:34 +0100995 CHECK_THROWS_AS(deviceSameName = counterDirectory.RegisterDevice(deviceName), armnn::InvalidArgumentException);
996 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("")),
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001022 armnn::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")),
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001031 armnn::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;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001068 CHECK_THROWS_AS(noCounterSet = counterDirectory.RegisterCounterSet(""), armnn::InvalidArgumentException);
1069 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"),
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001074 armnn::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),
Matteo Martincigh657ab2d2019-09-18 10:53:24 +01001101 armnn::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("")),
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001129 armnn::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")),
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001139 armnn::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),
Matteo Martincigh657ab2d2019-09-18 10:53:24 +01001172 armnn::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"),
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001196 armnn::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,
Keith Davise394bd92019-12-02 15:12:19 +00001202 1,
1203 "invalid parent category",
1204 0,
1205 1,
1206 123.45f,
1207 "valid name",
1208 "valid description"),
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001209 armnn::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,
Keith Davise394bd92019-12-02 15:12:19 +00001215 2,
1216 "valid_parent_category",
1217 2,
1218 1,
1219 123.45f,
1220 "valid "
1221 "name",
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001222 "valid description"),
1223 armnn::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,
Keith Davise394bd92019-12-02 15:12:19 +00001229 4,
1230 "valid_parent_category",
1231 0,
1232 3,
1233 123.45f,
1234 "valid "
1235 "name",
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001236 "valid description"),
1237 armnn::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,
Keith Davise394bd92019-12-02 15:12:19 +00001243 5,
1244 "valid_parent_category",
1245 0,
1246 1,
1247 .0f,
1248 "valid "
1249 "name",
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001250 "valid description"),
1251 armnn::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"),
Keith Davis3201eea2019-10-24 17:30:41 +01001265 armnn::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,
Keith Davise394bd92019-12-02 15:12:19 +00001271 7,
1272 "valid_parent_category",
1273 0,
1274 1,
1275 123.45f,
1276 "invalid nam€",
1277 "valid description"),
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001278 armnn::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 ""),
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001292 armnn::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,
Keith Davise394bd92019-12-02 15:12:19 +00001298 9,
1299 "valid_parent_category",
1300 0,
1301 1,
1302 123.45f,
1303 "valid "
1304 "name",
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001305 "inv@lid description"),
1306 armnn::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,
Keith Davise394bd92019-12-02 15:12:19 +00001312 10,
1313 "valid_parent_category",
1314 0,
1315 1,
1316 123.45f,
1317 "valid name",
1318 "valid description",
1319 std::string("Mb/s2")),
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001320 armnn::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,
Keith Davise394bd92019-12-02 15:12:19 +00001326 11,
1327 "invalid_parent_category",
1328 0,
1329 1,
1330 123.45f,
1331 "valid name",
1332 "valid description"),
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001333 armnn::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")),
Matteo Martincigh657ab2d2019-09-18 10:53:24 +01001387 armnn::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,
Keith Davise394bd92019-12-02 15:12:19 +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,
Jim Flynnbbfe6032020-07-20 16:57:44 +01001420 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,
Keith Davise394bd92019-12-02 15:12:19 +00001447 15,
1448 categoryName,
1449 0,
1450 1,
1451 123.45f,
1452 "valid name 4",
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001453 "valid description",
Keith Davis3201eea2019-10-24 17:30:41 +01001454 armnn::EmptyOptional(), // Units
1455 armnn::EmptyOptional(), // Number of cores
1456 100), // Device UID
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001457 armnn::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,
Keith Davise394bd92019-12-02 15:12:19 +00001474 16,
1475 categoryName,
1476 0,
1477 1,
1478 123.45f,
1479 "valid name 5",
1480 std::string("valid description"),
Jim Flynnbbfe6032020-07-20 16:57:44 +01001481 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,
Keith Davise394bd92019-12-02 15:12:19 +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
Jim Flynnbbfe6032020-07-20 16:57:44 +01001512 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,
Keith Davise394bd92019-12-02 15:12:19 +00001530 18,
1531 categoryName,
1532 0,
1533 1,
1534 123.45f,
1535 "valid ",
1536 "name 7",
1537 std::string("valid description"),
Keith Davis3201eea2019-10-24 17:30:41 +01001538 armnn::EmptyOptional(), // Units
1539 armnn::EmptyOptional(), // Number of cores
Keith Davise394bd92019-12-02 15:12:19 +00001540 100), // Counter set UID
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001541 armnn::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,
Keith Davise394bd92019-12-02 15:12:19 +00001730 anotherCategoryName, 1, 0, .00043f,
Keith Davis3201eea2019-10-24 17:30:41 +01001731 "valid name", "valid description",
Jim Flynnbbfe6032020-07-20 16:57:44 +01001732 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,
1790 std::shared_ptr<armnn::profiling::IBackendProfilingContext>> backendProfilingContext;
1791 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
1931 profiling::ActivateTimelineReportingCommandHandler activateTimelineReportingCommandHandler(0,
1932 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;
2004 using namespace armnn::profiling;
2005
2006 // Create runtime in which the test will run
2007 armnn::IRuntime::CreationOptions options;
2008 options.m_ProfilingOptions.m_EnableProfiling = true;
2009
Kevin Mayd92a6e42021-02-04 10:27:41 +00002010 armnn::RuntimeImpl runtime(options);
Keith Davis33ed2212020-03-30 10:43:41 +01002011 profiling::ProfilingServiceRuntimeHelper profilingServiceHelper(GetProfilingService(&runtime));
2012 profilingServiceHelper.ForceTransitionToState(ProfilingState::NotConnected);
2013 profilingServiceHelper.ForceTransitionToState(ProfilingState::WaitingForAck);
2014 profilingServiceHelper.ForceTransitionToState(ProfilingState::Active);
2015
2016 profiling::BufferManager& bufferManager = profilingServiceHelper.GetProfilingBufferManager();
2017 auto readableBuffer = bufferManager.GetReadableBuffer();
2018
2019 // Profiling is enabled, the post-optimisation structure should be created
Sadik Armagan1625efc2021-06-10 18:24:34 +01002020 CHECK(readableBuffer == nullptr);
Keith Davis33ed2212020-03-30 10:43:41 +01002021}
2022
Sadik Armagan1625efc2021-06-10 18:24:34 +01002023TEST_CASE("CheckConnectionAcknowledged")
Sadik Armaganb5f01b22019-09-18 17:29:00 +01002024{
Keith Davis3201eea2019-10-24 17:30:41 +01002025 const uint32_t packetFamilyId = 0;
Sadik Armaganb5f01b22019-09-18 17:29:00 +01002026 const uint32_t connectionPacketId = 0x10000;
Keith Davis3201eea2019-10-24 17:30:41 +01002027 const uint32_t version = 1;
Sadik Armaganb5f01b22019-09-18 17:29:00 +01002028
Matthew Sloyan371b70e2020-09-11 10:14:57 +01002029 uint32_t sizeOfUint32 = armnn::numeric_cast<uint32_t>(sizeof(uint32_t));
2030 uint32_t sizeOfUint16 = armnn::numeric_cast<uint32_t>(sizeof(uint16_t));
Sadik Armaganb5f01b22019-09-18 17:29:00 +01002031
2032 // Data with period and counters
Keith Davis3201eea2019-10-24 17:30:41 +01002033 uint32_t period1 = 10;
Sadik Armaganb5f01b22019-09-18 17:29:00 +01002034 uint32_t dataLength1 = 8;
Keith Davis3201eea2019-10-24 17:30:41 +01002035 uint32_t offset = 0;
Sadik Armaganb5f01b22019-09-18 17:29:00 +01002036
Matteo Martincigh67ef2a52019-10-10 13:29:02 +01002037 std::unique_ptr<unsigned char[]> uniqueData1 = std::make_unique<unsigned char[]>(dataLength1);
Keith Davis3201eea2019-10-24 17:30:41 +01002038 unsigned char* data1 = reinterpret_cast<unsigned char*>(uniqueData1.get());
Sadik Armaganb5f01b22019-09-18 17:29:00 +01002039
2040 WriteUint32(data1, offset, period1);
2041 offset += sizeOfUint32;
2042 WriteUint16(data1, offset, 4000);
2043 offset += sizeOfUint16;
2044 WriteUint16(data1, offset, 5000);
2045
Jim Flynnbbfe6032020-07-20 16:57:44 +01002046 arm::pipe::Packet packetA(connectionPacketId, dataLength1, uniqueData1);
Sadik Armaganb5f01b22019-09-18 17:29:00 +01002047
2048 ProfilingStateMachine profilingState(ProfilingState::Uninitialised);
Sadik Armagan1625efc2021-06-10 18:24:34 +01002049 CHECK(profilingState.GetCurrentState() == ProfilingState::Uninitialised);
Keith Davis3201eea2019-10-24 17:30:41 +01002050 CounterDirectory counterDirectory;
2051 MockBufferManager mockBuffer(1024);
Sadik Armagan3896b472020-02-10 12:24:15 +00002052 SendCounterPacket sendCounterPacket(mockBuffer);
2053 SendThread sendThread(profilingState, mockBuffer, sendCounterPacket);
Matteo Martincighcdfb9412019-11-08 11:23:06 +00002054 SendTimelinePacket sendTimelinePacket(mockBuffer);
Jim Flynn6398a982020-05-27 17:05:21 +01002055 MockProfilingServiceStatus mockProfilingServiceStatus;
Sadik Armaganb5f01b22019-09-18 17:29:00 +01002056
Jim Flynn6398a982020-05-27 17:05:21 +01002057 ConnectionAcknowledgedCommandHandler commandHandler(packetFamilyId,
2058 connectionPacketId,
2059 version,
2060 counterDirectory,
2061 sendCounterPacket,
2062 sendTimelinePacket,
2063 profilingState,
2064 mockProfilingServiceStatus);
Sadik Armaganb5f01b22019-09-18 17:29:00 +01002065
2066 // command handler received packet on ProfilingState::Uninitialised
Sadik Armagan1625efc2021-06-10 18:24:34 +01002067 CHECK_THROWS_AS(commandHandler(packetA), armnn::Exception);
Sadik Armaganb5f01b22019-09-18 17:29:00 +01002068
2069 profilingState.TransitionToState(ProfilingState::NotConnected);
Sadik Armagan1625efc2021-06-10 18:24:34 +01002070 CHECK(profilingState.GetCurrentState() == ProfilingState::NotConnected);
Sadik Armaganb5f01b22019-09-18 17:29:00 +01002071 // command handler received packet on ProfilingState::NotConnected
Sadik Armagan1625efc2021-06-10 18:24:34 +01002072 CHECK_THROWS_AS(commandHandler(packetA), armnn::Exception);
Sadik Armaganb5f01b22019-09-18 17:29:00 +01002073
2074 profilingState.TransitionToState(ProfilingState::WaitingForAck);
Sadik Armagan1625efc2021-06-10 18:24:34 +01002075 CHECK(profilingState.GetCurrentState() == ProfilingState::WaitingForAck);
Sadik Armaganb5f01b22019-09-18 17:29:00 +01002076 // command handler received packet on ProfilingState::WaitingForAck
Sadik Armagan1625efc2021-06-10 18:24:34 +01002077 CHECK_NOTHROW(commandHandler(packetA));
2078 CHECK(profilingState.GetCurrentState() == ProfilingState::Active);
Sadik Armaganb5f01b22019-09-18 17:29:00 +01002079
2080 // command handler received packet on ProfilingState::Active
Sadik Armagan1625efc2021-06-10 18:24:34 +01002081 CHECK_NOTHROW(commandHandler(packetA));
2082 CHECK(profilingState.GetCurrentState() == ProfilingState::Active);
Sadik Armaganb5f01b22019-09-18 17:29:00 +01002083
2084 // command handler received different packet
2085 const uint32_t differentPacketId = 0x40000;
Jim Flynnbbfe6032020-07-20 16:57:44 +01002086 arm::pipe::Packet packetB(differentPacketId, dataLength1, uniqueData1);
Matteo Martincighd0613b52019-10-09 16:47:04 +01002087 profilingState.TransitionToState(ProfilingState::NotConnected);
2088 profilingState.TransitionToState(ProfilingState::WaitingForAck);
Jim Flynn6398a982020-05-27 17:05:21 +01002089 ConnectionAcknowledgedCommandHandler differentCommandHandler(packetFamilyId,
2090 differentPacketId,
2091 version,
2092 counterDirectory,
2093 sendCounterPacket,
2094 sendTimelinePacket,
2095 profilingState,
2096 mockProfilingServiceStatus);
Sadik Armagan1625efc2021-06-10 18:24:34 +01002097 CHECK_THROWS_AS(differentCommandHandler(packetB), armnn::Exception);
Sadik Armaganb5f01b22019-09-18 17:29:00 +01002098}
2099
Sadik Armagan1625efc2021-06-10 18:24:34 +01002100TEST_CASE("CheckSocketConnectionException")
Teresa Charlin9bab4962019-09-06 12:28:35 +01002101{
Sadik Armagana97a0be2020-03-03 10:44:56 +00002102 // Check that creating a SocketProfilingConnection armnnProfiling in an exception as the Gator UDS doesn't exist.
Sadik Armagan1625efc2021-06-10 18:24:34 +01002103 CHECK_THROWS_AS(new SocketProfilingConnection(), arm::pipe::SocketConnectionException);
Sadik Armagana97a0be2020-03-03 10:44:56 +00002104}
2105
Sadik Armagan1625efc2021-06-10 18:24:34 +01002106TEST_CASE("CheckSocketConnectionException2")
Sadik Armagana97a0be2020-03-03 10:44:56 +00002107{
2108 try
2109 {
2110 new SocketProfilingConnection();
2111 }
Jim Flynnbbfe6032020-07-20 16:57:44 +01002112 catch (const arm::pipe::SocketConnectionException& ex)
Sadik Armagana97a0be2020-03-03 10:44:56 +00002113 {
Sadik Armagan1625efc2021-06-10 18:24:34 +01002114 CHECK(ex.GetSocketFd() == 0);
2115 CHECK(ex.GetErrorNo() == ECONNREFUSED);
2116 CHECK(ex.what()
Sadik Armagana97a0be2020-03-03 10:44:56 +00002117 == std::string("SocketProfilingConnection: Cannot connect to stream socket: Connection refused"));
2118 }
Teresa Charlin9bab4962019-09-06 12:28:35 +01002119}
2120
Sadik Armagan1625efc2021-06-10 18:24:34 +01002121TEST_CASE("SwTraceIsValidCharTest")
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01002122{
2123 // Only ASCII 7-bit encoding supported
2124 for (unsigned char c = 0; c < 128; c++)
2125 {
Sadik Armagan1625efc2021-06-10 18:24:34 +01002126 CHECK(arm::pipe::SwTraceCharPolicy::IsValidChar(c));
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01002127 }
2128
2129 // Not ASCII
2130 for (unsigned char c = 255; c >= 128; c++)
2131 {
Sadik Armagan1625efc2021-06-10 18:24:34 +01002132 CHECK(!arm::pipe::SwTraceCharPolicy::IsValidChar(c));
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01002133 }
2134}
2135
Sadik Armagan1625efc2021-06-10 18:24:34 +01002136TEST_CASE("SwTraceIsValidNameCharTest")
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01002137{
2138 // Only alpha-numeric and underscore ASCII 7-bit encoding supported
2139 const unsigned char validChars[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_";
2140 for (unsigned char i = 0; i < sizeof(validChars) / sizeof(validChars[0]) - 1; i++)
2141 {
Sadik Armagan1625efc2021-06-10 18:24:34 +01002142 CHECK(arm::pipe::SwTraceNameCharPolicy::IsValidChar(validChars[i]));
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01002143 }
2144
2145 // Non alpha-numeric chars
2146 for (unsigned char c = 0; c < 48; c++)
2147 {
Sadik Armagan1625efc2021-06-10 18:24:34 +01002148 CHECK(!arm::pipe::SwTraceNameCharPolicy::IsValidChar(c));
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01002149 }
2150 for (unsigned char c = 58; c < 65; c++)
2151 {
Sadik Armagan1625efc2021-06-10 18:24:34 +01002152 CHECK(!arm::pipe::SwTraceNameCharPolicy::IsValidChar(c));
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01002153 }
2154 for (unsigned char c = 91; c < 95; c++)
2155 {
Sadik Armagan1625efc2021-06-10 18:24:34 +01002156 CHECK(!arm::pipe::SwTraceNameCharPolicy::IsValidChar(c));
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01002157 }
2158 for (unsigned char c = 96; c < 97; c++)
2159 {
Sadik Armagan1625efc2021-06-10 18:24:34 +01002160 CHECK(!arm::pipe::SwTraceNameCharPolicy::IsValidChar(c));
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01002161 }
2162 for (unsigned char c = 123; c < 128; c++)
2163 {
Sadik Armagan1625efc2021-06-10 18:24:34 +01002164 CHECK(!arm::pipe::SwTraceNameCharPolicy::IsValidChar(c));
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01002165 }
2166
2167 // Not ASCII
2168 for (unsigned char c = 255; c >= 128; c++)
2169 {
Sadik Armagan1625efc2021-06-10 18:24:34 +01002170 CHECK(!arm::pipe::SwTraceNameCharPolicy::IsValidChar(c));
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01002171 }
2172}
2173
Sadik Armagan1625efc2021-06-10 18:24:34 +01002174TEST_CASE("IsValidSwTraceStringTest")
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01002175{
2176 // Valid SWTrace strings
Sadik Armagan1625efc2021-06-10 18:24:34 +01002177 CHECK(arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceCharPolicy>(""));
2178 CHECK(arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceCharPolicy>("_"));
2179 CHECK(arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceCharPolicy>("0123"));
2180 CHECK(arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceCharPolicy>("valid_string"));
2181 CHECK(arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceCharPolicy>("VALID_string_456"));
2182 CHECK(arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceCharPolicy>(" "));
2183 CHECK(arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceCharPolicy>("valid string"));
2184 CHECK(arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceCharPolicy>("!$%"));
2185 CHECK(arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceCharPolicy>("valid|\\~string#123"));
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01002186
2187 // Invalid SWTrace strings
Sadik Armagan1625efc2021-06-10 18:24:34 +01002188 CHECK(!arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceCharPolicy>("€£"));
2189 CHECK(!arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceCharPolicy>("invalid‡string"));
2190 CHECK(!arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceCharPolicy>("12Ž34"));
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01002191}
2192
Sadik Armagan1625efc2021-06-10 18:24:34 +01002193TEST_CASE("IsValidSwTraceNameStringTest")
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01002194{
2195 // Valid SWTrace name strings
Sadik Armagan1625efc2021-06-10 18:24:34 +01002196 CHECK(arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceNameCharPolicy>(""));
2197 CHECK(arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceNameCharPolicy>("_"));
2198 CHECK(arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceNameCharPolicy>("0123"));
2199 CHECK(arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceNameCharPolicy>("valid_string"));
2200 CHECK(arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceNameCharPolicy>("VALID_string_456"));
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01002201
2202 // Invalid SWTrace name strings
Sadik Armagan1625efc2021-06-10 18:24:34 +01002203 CHECK(!arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceNameCharPolicy>(" "));
2204 CHECK(!arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceNameCharPolicy>("invalid string"));
2205 CHECK(!arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceNameCharPolicy>("!$%"));
2206 CHECK(!arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceNameCharPolicy>("invalid|\\~string#123"));
2207 CHECK(!arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceNameCharPolicy>("€£"));
2208 CHECK(!arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceNameCharPolicy>("invalid‡string"));
2209 CHECK(!arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceNameCharPolicy>("12Ž34"));
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01002210}
2211
2212template <typename SwTracePolicy>
2213void StringToSwTraceStringTestHelper(const std::string& testString, std::vector<uint32_t> buffer, size_t expectedSize)
2214{
2215 // Convert the test string to a SWTrace string
Sadik Armagan1625efc2021-06-10 18:24:34 +01002216 CHECK(arm::pipe::StringToSwTraceString<SwTracePolicy>(testString, buffer));
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01002217
2218 // The buffer must contain at least the length of the string
Sadik Armagan1625efc2021-06-10 18:24:34 +01002219 CHECK(!buffer.empty());
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01002220
2221 // The buffer must be of the expected size (in words)
Sadik Armagan1625efc2021-06-10 18:24:34 +01002222 CHECK(buffer.size() == expectedSize);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01002223
2224 // The first word of the byte must be the length of the string including the null-terminator
Sadik Armagan1625efc2021-06-10 18:24:34 +01002225 CHECK(buffer[0] == testString.size() + 1);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01002226
2227 // The contents of the buffer must match the test string
Sadik Armagan1625efc2021-06-10 18:24:34 +01002228 CHECK(std::memcmp(testString.data(), buffer.data() + 1, testString.size()) == 0);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01002229
2230 // The buffer must include the null-terminator at the end of the string
2231 size_t nullTerminatorIndex = sizeof(uint32_t) + testString.size();
Sadik Armagan1625efc2021-06-10 18:24:34 +01002232 CHECK(reinterpret_cast<unsigned char*>(buffer.data())[nullTerminatorIndex] == '\0');
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01002233}
2234
Sadik Armagan1625efc2021-06-10 18:24:34 +01002235TEST_CASE("StringToSwTraceStringTest")
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01002236{
2237 std::vector<uint32_t> buffer;
2238
2239 // Valid SWTrace strings (expected size in words)
Jim Flynnbbfe6032020-07-20 16:57:44 +01002240 StringToSwTraceStringTestHelper<arm::pipe::SwTraceCharPolicy>("", buffer, 2);
2241 StringToSwTraceStringTestHelper<arm::pipe::SwTraceCharPolicy>("_", buffer, 2);
2242 StringToSwTraceStringTestHelper<arm::pipe::SwTraceCharPolicy>("0123", buffer, 3);
2243 StringToSwTraceStringTestHelper<arm::pipe::SwTraceCharPolicy>("valid_string", buffer, 5);
2244 StringToSwTraceStringTestHelper<arm::pipe::SwTraceCharPolicy>("VALID_string_456", buffer, 6);
2245 StringToSwTraceStringTestHelper<arm::pipe::SwTraceCharPolicy>(" ", buffer, 2);
2246 StringToSwTraceStringTestHelper<arm::pipe::SwTraceCharPolicy>("valid string", buffer, 5);
2247 StringToSwTraceStringTestHelper<arm::pipe::SwTraceCharPolicy>("!$%", buffer, 2);
2248 StringToSwTraceStringTestHelper<arm::pipe::SwTraceCharPolicy>("valid|\\~string#123", buffer, 6);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01002249
2250 // Invalid SWTrace strings
Sadik Armagan1625efc2021-06-10 18:24:34 +01002251 CHECK(!arm::pipe::StringToSwTraceString<arm::pipe::SwTraceCharPolicy>("€£", buffer));
2252 CHECK(buffer.empty());
2253 CHECK(!arm::pipe::StringToSwTraceString<arm::pipe::SwTraceCharPolicy>("invalid‡string", buffer));
2254 CHECK(buffer.empty());
2255 CHECK(!arm::pipe::StringToSwTraceString<arm::pipe::SwTraceCharPolicy>("12Ž34", buffer));
2256 CHECK(buffer.empty());
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01002257}
2258
Sadik Armagan1625efc2021-06-10 18:24:34 +01002259TEST_CASE("StringToSwTraceNameStringTest")
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01002260{
2261 std::vector<uint32_t> buffer;
2262
2263 // Valid SWTrace namestrings (expected size in words)
Jim Flynnbbfe6032020-07-20 16:57:44 +01002264 StringToSwTraceStringTestHelper<arm::pipe::SwTraceNameCharPolicy>("", buffer, 2);
2265 StringToSwTraceStringTestHelper<arm::pipe::SwTraceNameCharPolicy>("_", buffer, 2);
2266 StringToSwTraceStringTestHelper<arm::pipe::SwTraceNameCharPolicy>("0123", buffer, 3);
2267 StringToSwTraceStringTestHelper<arm::pipe::SwTraceNameCharPolicy>("valid_string", buffer, 5);
2268 StringToSwTraceStringTestHelper<arm::pipe::SwTraceNameCharPolicy>("VALID_string_456", buffer, 6);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01002269
2270 // Invalid SWTrace namestrings
Sadik Armagan1625efc2021-06-10 18:24:34 +01002271 CHECK(!arm::pipe::StringToSwTraceString<arm::pipe::SwTraceNameCharPolicy>(" ", buffer));
2272 CHECK(buffer.empty());
2273 CHECK(!arm::pipe::StringToSwTraceString<arm::pipe::SwTraceNameCharPolicy>("invalid string", buffer));
2274 CHECK(buffer.empty());
2275 CHECK(!arm::pipe::StringToSwTraceString<arm::pipe::SwTraceNameCharPolicy>("!$%", buffer));
2276 CHECK(buffer.empty());
2277 CHECK(!arm::pipe::StringToSwTraceString<arm::pipe::SwTraceNameCharPolicy>("invalid|\\~string#123", buffer));
2278 CHECK(buffer.empty());
2279 CHECK(!arm::pipe::StringToSwTraceString<arm::pipe::SwTraceNameCharPolicy>("€£", buffer));
2280 CHECK(buffer.empty());
2281 CHECK(!arm::pipe::StringToSwTraceString<arm::pipe::SwTraceNameCharPolicy>("invalid‡string", buffer));
2282 CHECK(buffer.empty());
2283 CHECK(!arm::pipe::StringToSwTraceString<arm::pipe::SwTraceNameCharPolicy>("12Ž34", buffer));
2284 CHECK(buffer.empty());
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01002285}
2286
Sadik Armagan1625efc2021-06-10 18:24:34 +01002287TEST_CASE("CheckPeriodicCounterCaptureThread")
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002288{
Matteo Martincighe0e6efc2019-10-04 17:17:42 +01002289 class CaptureReader : public IReadCounterValues
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002290 {
2291 public:
Finn Williamsf4d59a62019-10-14 15:55:18 +01002292 CaptureReader(uint16_t counterSize)
2293 {
Keith Davis3201eea2019-10-24 17:30:41 +01002294 for (uint16_t i = 0; i < counterSize; ++i)
Finn Williamsf4d59a62019-10-14 15:55:18 +01002295 {
2296 m_Data[i] = 0;
2297 }
2298 m_CounterSize = counterSize;
2299 }
2300 //not used
Matteo Martincighe8485382019-10-10 14:08:21 +01002301 bool IsCounterRegistered(uint16_t counterUid) const override
2302 {
Jan Eilers8eb25602020-03-09 12:13:48 +00002303 armnn::IgnoreUnused(counterUid);
Finn Williamsf4d59a62019-10-14 15:55:18 +01002304 return false;
Matteo Martincighe8485382019-10-10 14:08:21 +01002305 }
2306
Matteo Martincighe0e6efc2019-10-04 17:17:42 +01002307 uint16_t GetCounterCount() const override
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002308 {
Finn Williamsf4d59a62019-10-14 15:55:18 +01002309 return m_CounterSize;
Matteo Martincighe0e6efc2019-10-04 17:17:42 +01002310 }
2311
Finn Williamsf3fcf322020-05-11 14:38:02 +01002312 uint32_t GetAbsoluteCounterValue(uint16_t counterUid) const override
2313 {
2314 if (counterUid > m_CounterSize)
2315 {
Sadik Armagan1625efc2021-06-10 18:24:34 +01002316 FAIL("Invalid counter Uid");
Finn Williamsf3fcf322020-05-11 14:38:02 +01002317 }
2318 return m_Data.at(counterUid).load();
2319 }
2320
2321 uint32_t GetDeltaCounterValue(uint16_t counterUid) override
Matteo Martincighe0e6efc2019-10-04 17:17:42 +01002322 {
Keith Davis3201eea2019-10-24 17:30:41 +01002323 if (counterUid > m_CounterSize)
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002324 {
Sadik Armagan1625efc2021-06-10 18:24:34 +01002325 FAIL("Invalid counter Uid");
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002326 }
Matteo Martincighe8485382019-10-10 14:08:21 +01002327 return m_Data.at(counterUid).load();
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002328 }
2329
Matteo Martincighe8485382019-10-10 14:08:21 +01002330 void SetCounterValue(uint16_t counterUid, uint32_t value)
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002331 {
Keith Davis3201eea2019-10-24 17:30:41 +01002332 if (counterUid > m_CounterSize)
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002333 {
Sadik Armagan1625efc2021-06-10 18:24:34 +01002334 FAIL("Invalid counter Uid");
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002335 }
Finn Williamsf4d59a62019-10-14 15:55:18 +01002336 m_Data.at(counterUid).store(value);
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002337 }
2338
2339 private:
Matteo Martincighe8485382019-10-10 14:08:21 +01002340 std::unordered_map<uint16_t, std::atomic<uint32_t>> m_Data;
Finn Williamsf4d59a62019-10-14 15:55:18 +01002341 uint16_t m_CounterSize;
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002342 };
2343
Matteo Martincigh5d737fb2019-10-07 13:05:13 +01002344 ProfilingStateMachine profilingStateMachine;
2345
Finn Williams032bc742020-02-12 11:02:34 +00002346 const std::unordered_map<armnn::BackendId,
2347 std::shared_ptr<armnn::profiling::IBackendProfilingContext>> backendProfilingContext;
2348 CounterIdMap counterIdMap;
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002349 Holder data;
2350 std::vector<uint16_t> captureIds1 = { 0, 1 };
2351 std::vector<uint16_t> captureIds2;
2352
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01002353 MockBufferManager mockBuffer(512);
Sadik Armagan3896b472020-02-10 12:24:15 +00002354 SendCounterPacket sendCounterPacket(mockBuffer);
2355 SendThread sendThread(profilingStateMachine, mockBuffer, sendCounterPacket);
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002356
2357 std::vector<uint16_t> counterIds;
Finn Williamsf4d59a62019-10-14 15:55:18 +01002358 CaptureReader captureReader(2);
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002359
Keith Davis3201eea2019-10-24 17:30:41 +01002360 unsigned int valueA = 10;
2361 unsigned int valueB = 15;
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002362 unsigned int numSteps = 5;
2363
Finn Williams032bc742020-02-12 11:02:34 +00002364 PeriodicCounterCapture periodicCounterCapture(std::ref(data), std::ref(sendCounterPacket), captureReader,
2365 counterIdMap, backendProfilingContext);
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002366
Matteo Martincighe0e6efc2019-10-04 17:17:42 +01002367 for (unsigned int i = 0; i < numSteps; ++i)
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002368 {
Finn Williams032bc742020-02-12 11:02:34 +00002369 data.SetCaptureData(1, captureIds1, {});
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002370 captureReader.SetCounterValue(0, valueA * (i + 1));
2371 captureReader.SetCounterValue(1, valueB * (i + 1));
2372
2373 periodicCounterCapture.Start();
Finn Williamsf4d59a62019-10-14 15:55:18 +01002374 periodicCounterCapture.Stop();
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002375 }
2376
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01002377 auto buffer = mockBuffer.GetReadableBuffer();
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002378
2379 uint32_t headerWord0 = ReadUint32(buffer, 0);
2380 uint32_t headerWord1 = ReadUint32(buffer, 4);
2381
Sadik Armagan1625efc2021-06-10 18:24:34 +01002382 CHECK(((headerWord0 >> 26) & 0x0000003F) == 3); // packet family
2383 CHECK(((headerWord0 >> 19) & 0x0000007F) == 0); // packet class
2384 CHECK(((headerWord0 >> 16) & 0x00000007) == 0); // packet type
2385 CHECK(headerWord1 == 20);
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002386
Keith Davis3201eea2019-10-24 17:30:41 +01002387 uint32_t offset = 16;
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002388 uint16_t readIndex = ReadUint16(buffer, offset);
Sadik Armagan1625efc2021-06-10 18:24:34 +01002389 CHECK(0 == readIndex);
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002390
2391 offset += 2;
2392 uint32_t readValue = ReadUint32(buffer, offset);
Sadik Armagan1625efc2021-06-10 18:24:34 +01002393 CHECK((valueA * numSteps) == readValue);
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002394
2395 offset += 4;
2396 readIndex = ReadUint16(buffer, offset);
Sadik Armagan1625efc2021-06-10 18:24:34 +01002397 CHECK(1 == readIndex);
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002398
2399 offset += 2;
2400 readValue = ReadUint32(buffer, offset);
Sadik Armagan1625efc2021-06-10 18:24:34 +01002401 CHECK((valueB * numSteps) == readValue);
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002402}
2403
Sadik Armagan1625efc2021-06-10 18:24:34 +01002404TEST_CASE("RequestCounterDirectoryCommandHandlerTest1")
Narumol Prangnawarat48033692019-09-20 12:04:55 +01002405{
Jim Flynn397043f2019-10-17 17:37:10 +01002406 const uint32_t familyId = 0;
Matteo Martincigh8efc5002019-10-10 14:30:29 +01002407 const uint32_t packetId = 3;
Keith Davis3201eea2019-10-24 17:30:41 +01002408 const uint32_t version = 1;
Matteo Martincigh8efc5002019-10-10 14:30:29 +01002409 ProfilingStateMachine profilingStateMachine;
2410 CounterDirectory counterDirectory;
Matteo Martincigh9723d022019-11-13 10:56:41 +00002411 MockBufferManager mockBuffer1(1024);
Sadik Armagan3896b472020-02-10 12:24:15 +00002412 SendCounterPacket sendCounterPacket(mockBuffer1);
2413 SendThread sendThread(profilingStateMachine, mockBuffer1, sendCounterPacket);
Matteo Martincigh9723d022019-11-13 10:56:41 +00002414 MockBufferManager mockBuffer2(1024);
2415 SendTimelinePacket sendTimelinePacket(mockBuffer2);
Keith Davis3201eea2019-10-24 17:30:41 +01002416 RequestCounterDirectoryCommandHandler commandHandler(familyId, packetId, version, counterDirectory,
Matteo Martincigh9723d022019-11-13 10:56:41 +00002417 sendCounterPacket, sendTimelinePacket, profilingStateMachine);
Narumol Prangnawarat48033692019-09-20 12:04:55 +01002418
Matteo Martincigh8efc5002019-10-10 14:30:29 +01002419 const uint32_t wrongPacketId = 47;
Keith Davis3201eea2019-10-24 17:30:41 +01002420 const uint32_t wrongHeader = (wrongPacketId & 0x000003FF) << 16;
Narumol Prangnawarat48033692019-09-20 12:04:55 +01002421
Jim Flynnbbfe6032020-07-20 16:57:44 +01002422 arm::pipe::Packet wrongPacket(wrongHeader);
Matteo Martincigh8efc5002019-10-10 14:30:29 +01002423
2424 profilingStateMachine.TransitionToState(ProfilingState::Uninitialised);
Sadik Armagan1625efc2021-06-10 18:24:34 +01002425 CHECK_THROWS_AS(commandHandler(wrongPacket), armnn::RuntimeException); // Wrong profiling state
Matteo Martincigh8efc5002019-10-10 14:30:29 +01002426 profilingStateMachine.TransitionToState(ProfilingState::NotConnected);
Sadik Armagan1625efc2021-06-10 18:24:34 +01002427 CHECK_THROWS_AS(commandHandler(wrongPacket), armnn::RuntimeException); // Wrong profiling state
Matteo Martincigh8efc5002019-10-10 14:30:29 +01002428 profilingStateMachine.TransitionToState(ProfilingState::WaitingForAck);
Sadik Armagan1625efc2021-06-10 18:24:34 +01002429 CHECK_THROWS_AS(commandHandler(wrongPacket), armnn::RuntimeException); // Wrong profiling state
Matteo Martincigh8efc5002019-10-10 14:30:29 +01002430 profilingStateMachine.TransitionToState(ProfilingState::Active);
Sadik Armagan1625efc2021-06-10 18:24:34 +01002431 CHECK_THROWS_AS(commandHandler(wrongPacket), armnn::InvalidArgumentException); // Wrong packet
Matteo Martincigh8efc5002019-10-10 14:30:29 +01002432
2433 const uint32_t rightHeader = (packetId & 0x000003FF) << 16;
2434
Jim Flynnbbfe6032020-07-20 16:57:44 +01002435 arm::pipe::Packet rightPacket(rightHeader);
Matteo Martincigh8efc5002019-10-10 14:30:29 +01002436
Sadik Armagan1625efc2021-06-10 18:24:34 +01002437 CHECK_NOTHROW(commandHandler(rightPacket)); // Right packet
Narumol Prangnawarat48033692019-09-20 12:04:55 +01002438
Matteo Martincigh9723d022019-11-13 10:56:41 +00002439 auto readBuffer1 = mockBuffer1.GetReadableBuffer();
Narumol Prangnawarat48033692019-09-20 12:04:55 +01002440
Matteo Martincigh9723d022019-11-13 10:56:41 +00002441 uint32_t header1Word0 = ReadUint32(readBuffer1, 0);
2442 uint32_t header1Word1 = ReadUint32(readBuffer1, 4);
Narumol Prangnawarat48033692019-09-20 12:04:55 +01002443
Matteo Martincigh9723d022019-11-13 10:56:41 +00002444 // Counter directory packet
Sadik Armagan1625efc2021-06-10 18:24:34 +01002445 CHECK(((header1Word0 >> 26) & 0x0000003F) == 0); // packet family
2446 CHECK(((header1Word0 >> 16) & 0x000003FF) == 2); // packet id
2447 CHECK(header1Word1 == 24); // data length
Narumol Prangnawarat48033692019-09-20 12:04:55 +01002448
Matteo Martincigh9723d022019-11-13 10:56:41 +00002449 uint32_t bodyHeader1Word0 = ReadUint32(readBuffer1, 8);
Matthew Sloyan371b70e2020-09-11 10:14:57 +01002450 uint16_t deviceRecordCount = armnn::numeric_cast<uint16_t>(bodyHeader1Word0 >> 16);
Sadik Armagan1625efc2021-06-10 18:24:34 +01002451 CHECK(deviceRecordCount == 0); // device_records_count
Matteo Martincigh9723d022019-11-13 10:56:41 +00002452
2453 auto readBuffer2 = mockBuffer2.GetReadableBuffer();
2454
2455 uint32_t header2Word0 = ReadUint32(readBuffer2, 0);
2456 uint32_t header2Word1 = ReadUint32(readBuffer2, 4);
2457
2458 // Timeline message directory packet
Sadik Armagan1625efc2021-06-10 18:24:34 +01002459 CHECK(((header2Word0 >> 26) & 0x0000003F) == 1); // packet family
2460 CHECK(((header2Word0 >> 16) & 0x000003FF) == 0); // packet id
2461 CHECK(header2Word1 == 443); // data length
Narumol Prangnawarat48033692019-09-20 12:04:55 +01002462}
2463
Sadik Armagan1625efc2021-06-10 18:24:34 +01002464TEST_CASE("RequestCounterDirectoryCommandHandlerTest2")
Narumol Prangnawarat48033692019-09-20 12:04:55 +01002465{
Jim Flynn397043f2019-10-17 17:37:10 +01002466 const uint32_t familyId = 0;
Matteo Martincigh8efc5002019-10-10 14:30:29 +01002467 const uint32_t packetId = 3;
Keith Davis3201eea2019-10-24 17:30:41 +01002468 const uint32_t version = 1;
Matteo Martincigh8efc5002019-10-10 14:30:29 +01002469 ProfilingStateMachine profilingStateMachine;
2470 CounterDirectory counterDirectory;
Matteo Martincigh9723d022019-11-13 10:56:41 +00002471 MockBufferManager mockBuffer1(1024);
Sadik Armagan3896b472020-02-10 12:24:15 +00002472 SendCounterPacket sendCounterPacket(mockBuffer1);
2473 SendThread sendThread(profilingStateMachine, mockBuffer1, sendCounterPacket);
Matteo Martincigh9723d022019-11-13 10:56:41 +00002474 MockBufferManager mockBuffer2(1024);
2475 SendTimelinePacket sendTimelinePacket(mockBuffer2);
Keith Davis3201eea2019-10-24 17:30:41 +01002476 RequestCounterDirectoryCommandHandler commandHandler(familyId, packetId, version, counterDirectory,
Matteo Martincigh9723d022019-11-13 10:56:41 +00002477 sendCounterPacket, sendTimelinePacket, profilingStateMachine);
Matteo Martincigh8efc5002019-10-10 14:30:29 +01002478 const uint32_t header = (packetId & 0x000003FF) << 16;
Jim Flynnbbfe6032020-07-20 16:57:44 +01002479 const arm::pipe::Packet packet(header);
Narumol Prangnawarat48033692019-09-20 12:04:55 +01002480
Matteo Martincigh9723d022019-11-13 10:56:41 +00002481 const Device* device = counterDirectory.RegisterDevice("deviceA", 1);
Sadik Armagan1625efc2021-06-10 18:24:34 +01002482 CHECK(device != nullptr);
Narumol Prangnawarat48033692019-09-20 12:04:55 +01002483 const CounterSet* counterSet = counterDirectory.RegisterCounterSet("countersetA");
Sadik Armagan1625efc2021-06-10 18:24:34 +01002484 CHECK(counterSet != nullptr);
Sadik Armagan4c998992020-02-25 12:44:44 +00002485 counterDirectory.RegisterCategory("categoryA");
Keith Davise394bd92019-12-02 15:12:19 +00002486 counterDirectory.RegisterCounter(armnn::profiling::BACKEND_ID, 24,
2487 "categoryA", 0, 1, 2.0f, "counterA", "descA");
2488 counterDirectory.RegisterCounter(armnn::profiling::BACKEND_ID, 25,
2489 "categoryA", 1, 1, 3.0f, "counterB", "descB");
Narumol Prangnawarat48033692019-09-20 12:04:55 +01002490
Matteo Martincigh8efc5002019-10-10 14:30:29 +01002491 profilingStateMachine.TransitionToState(ProfilingState::Uninitialised);
Sadik Armagan1625efc2021-06-10 18:24:34 +01002492 CHECK_THROWS_AS(commandHandler(packet), armnn::RuntimeException); // Wrong profiling state
Matteo Martincigh8efc5002019-10-10 14:30:29 +01002493 profilingStateMachine.TransitionToState(ProfilingState::NotConnected);
Sadik Armagan1625efc2021-06-10 18:24:34 +01002494 CHECK_THROWS_AS(commandHandler(packet), armnn::RuntimeException); // Wrong profiling state
Matteo Martincigh8efc5002019-10-10 14:30:29 +01002495 profilingStateMachine.TransitionToState(ProfilingState::WaitingForAck);
Sadik Armagan1625efc2021-06-10 18:24:34 +01002496 CHECK_THROWS_AS(commandHandler(packet), armnn::RuntimeException); // Wrong profiling state
Matteo Martincigh8efc5002019-10-10 14:30:29 +01002497 profilingStateMachine.TransitionToState(ProfilingState::Active);
Sadik Armagan1625efc2021-06-10 18:24:34 +01002498 CHECK_NOTHROW(commandHandler(packet));
Narumol Prangnawarat48033692019-09-20 12:04:55 +01002499
Matteo Martincigh9723d022019-11-13 10:56:41 +00002500 auto readBuffer1 = mockBuffer1.GetReadableBuffer();
Narumol Prangnawarat48033692019-09-20 12:04:55 +01002501
Finn Williams985fecf2020-04-30 11:06:43 +01002502 const uint32_t header1Word0 = ReadUint32(readBuffer1, 0);
2503 const uint32_t header1Word1 = ReadUint32(readBuffer1, 4);
Narumol Prangnawarat48033692019-09-20 12:04:55 +01002504
Sadik Armagan1625efc2021-06-10 18:24:34 +01002505 CHECK(((header1Word0 >> 26) & 0x0000003F) == 0); // packet family
2506 CHECK(((header1Word0 >> 16) & 0x000003FF) == 2); // packet id
2507 CHECK(header1Word1 == 236); // data length
Narumol Prangnawarat48033692019-09-20 12:04:55 +01002508
Finn Williams985fecf2020-04-30 11:06:43 +01002509 const uint32_t bodyHeaderSizeBytes = bodyHeaderSize * sizeof(uint32_t);
Narumol Prangnawarat48033692019-09-20 12:04:55 +01002510
Finn Williams985fecf2020-04-30 11:06:43 +01002511 const uint32_t bodyHeader1Word0 = ReadUint32(readBuffer1, 8);
2512 const uint32_t bodyHeader1Word1 = ReadUint32(readBuffer1, 12);
2513 const uint32_t bodyHeader1Word2 = ReadUint32(readBuffer1, 16);
2514 const uint32_t bodyHeader1Word3 = ReadUint32(readBuffer1, 20);
2515 const uint32_t bodyHeader1Word4 = ReadUint32(readBuffer1, 24);
2516 const uint32_t bodyHeader1Word5 = ReadUint32(readBuffer1, 28);
Matthew Sloyan371b70e2020-09-11 10:14:57 +01002517 const uint16_t deviceRecordCount = armnn::numeric_cast<uint16_t>(bodyHeader1Word0 >> 16);
2518 const uint16_t counterSetRecordCount = armnn::numeric_cast<uint16_t>(bodyHeader1Word2 >> 16);
2519 const uint16_t categoryRecordCount = armnn::numeric_cast<uint16_t>(bodyHeader1Word4 >> 16);
Sadik Armagan1625efc2021-06-10 18:24:34 +01002520 CHECK(deviceRecordCount == 1); // device_records_count
2521 CHECK(bodyHeader1Word1 == 0 + bodyHeaderSizeBytes); // device_records_pointer_table_offset
2522 CHECK(counterSetRecordCount == 1); // counter_set_count
2523 CHECK(bodyHeader1Word3 == 4 + bodyHeaderSizeBytes); // counter_set_pointer_table_offset
2524 CHECK(categoryRecordCount == 1); // categories_count
2525 CHECK(bodyHeader1Word5 == 8 + bodyHeaderSizeBytes); // categories_pointer_table_offset
Finn Williams985fecf2020-04-30 11:06:43 +01002526
2527 const uint32_t deviceRecordOffset = ReadUint32(readBuffer1, 32);
Sadik Armagan1625efc2021-06-10 18:24:34 +01002528 CHECK(deviceRecordOffset == 12);
Narumol Prangnawarat48033692019-09-20 12:04:55 +01002529
Finn Williams985fecf2020-04-30 11:06:43 +01002530 const uint32_t counterSetRecordOffset = ReadUint32(readBuffer1, 36);
Sadik Armagan1625efc2021-06-10 18:24:34 +01002531 CHECK(counterSetRecordOffset == 28);
Narumol Prangnawarat48033692019-09-20 12:04:55 +01002532
Finn Williams985fecf2020-04-30 11:06:43 +01002533 const uint32_t categoryRecordOffset = ReadUint32(readBuffer1, 40);
Sadik Armagan1625efc2021-06-10 18:24:34 +01002534 CHECK(categoryRecordOffset == 48);
Matteo Martincigh9723d022019-11-13 10:56:41 +00002535
2536 auto readBuffer2 = mockBuffer2.GetReadableBuffer();
2537
Finn Williams985fecf2020-04-30 11:06:43 +01002538 const uint32_t header2Word0 = ReadUint32(readBuffer2, 0);
2539 const uint32_t header2Word1 = ReadUint32(readBuffer2, 4);
Matteo Martincigh9723d022019-11-13 10:56:41 +00002540
2541 // Timeline message directory packet
Sadik Armagan1625efc2021-06-10 18:24:34 +01002542 CHECK(((header2Word0 >> 26) & 0x0000003F) == 1); // packet family
2543 CHECK(((header2Word0 >> 16) & 0x000003FF) == 0); // packet id
2544 CHECK(header2Word1 == 443); // data length
Narumol Prangnawarat48033692019-09-20 12:04:55 +01002545}
2546
Sadik Armagan1625efc2021-06-10 18:24:34 +01002547TEST_CASE("CheckProfilingServiceGoodConnectionAcknowledgedPacket")
Matteo Martincigh54fb9572019-10-02 12:50:57 +01002548{
Finn Williamsa0de0562020-04-22 12:27:37 +01002549 unsigned int streamMetadataPacketsize = GetStreamMetaDataPacketSize();
Matteo Martincigh54fb9572019-10-02 12:50:57 +01002550
Jim Flynn53e46992019-10-14 12:31:10 +01002551 // Reset the profiling service to the uninitialized state
Jim Flynn4c9ed1d2022-01-23 23:57:20 +00002552 ProfilingOptions options;
Keith Davis3201eea2019-10-24 17:30:41 +01002553 options.m_EnableProfiling = true;
Sadik Armagan3184c902020-03-18 10:57:30 +00002554 armnn::profiling::ProfilingService profilingService;
Matteo Martincigh54fb9572019-10-02 12:50:57 +01002555 profilingService.ResetExternalProfilingOptions(options, true);
2556
Sadik Armagan3184c902020-03-18 10:57:30 +00002557 // Swap the profiling connection factory in the profiling service instance with our mock one
2558 SwapProfilingConnectionFactoryHelper helper(profilingService);
2559
Matteo Martincigh54fb9572019-10-02 12:50:57 +01002560 // Bring the profiling service to the "WaitingForAck" state
Sadik Armagan1625efc2021-06-10 18:24:34 +01002561 CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
Keith Davis3201eea2019-10-24 17:30:41 +01002562 profilingService.Update(); // Initialize the counter directory
Sadik Armagan1625efc2021-06-10 18:24:34 +01002563 CHECK(profilingService.GetCurrentState() == ProfilingState::NotConnected);
Keith Davis3201eea2019-10-24 17:30:41 +01002564 profilingService.Update(); // Create the profiling connection
Matteo Martincigh54fb9572019-10-02 12:50:57 +01002565
Matteo Martincighd0613b52019-10-09 16:47:04 +01002566 // Get the mock profiling connection
2567 MockProfilingConnection* mockProfilingConnection = helper.GetMockProfilingConnection();
Sadik Armagan1625efc2021-06-10 18:24:34 +01002568 CHECK(mockProfilingConnection);
Matteo Martincighd0613b52019-10-09 16:47:04 +01002569
Matteo Martincighe8485382019-10-10 14:08:21 +01002570 // Remove the packets received so far
2571 mockProfilingConnection->Clear();
2572
Sadik Armagan1625efc2021-06-10 18:24:34 +01002573 CHECK(profilingService.GetCurrentState() == ProfilingState::WaitingForAck);
Keith Davis3201eea2019-10-24 17:30:41 +01002574 profilingService.Update(); // Start the command handler and the send thread
Matteo Martincighe8485382019-10-10 14:08:21 +01002575
2576 // Wait for the Stream Metadata packet to be sent
Sadik Armagan1625efc2021-06-10 18:24:34 +01002577 CHECK(helper.WaitForPacketsSent(
Finn Williams09ad6f92019-12-19 17:05:18 +00002578 mockProfilingConnection, PacketType::StreamMetaData, streamMetadataPacketsize) >= 1);
Matteo Martincigh54fb9572019-10-02 12:50:57 +01002579
2580 // Write a valid "Connection Acknowledged" packet into the mock profiling connection, to simulate a valid
2581 // reply from an external profiling service
2582
2583 // Connection Acknowledged Packet header (word 0, word 1 is always zero):
2584 // 26:31 [6] packet_family: Control Packet Family, value 0b000000
2585 // 16:25 [10] packet_id: Packet identifier, value 0b0000000001
2586 // 8:15 [8] reserved: Reserved, value 0b00000000
2587 // 0:7 [8] reserved: Reserved, value 0b00000000
2588 uint32_t packetFamily = 0;
2589 uint32_t packetId = 1;
Keith Davis3201eea2019-10-24 17:30:41 +01002590 uint32_t header = ((packetFamily & 0x0000003F) << 26) | ((packetId & 0x000003FF) << 16);
Matteo Martincigh54fb9572019-10-02 12:50:57 +01002591
Matteo Martincighd0613b52019-10-09 16:47:04 +01002592 // Create the Connection Acknowledged Packet
Jim Flynnbbfe6032020-07-20 16:57:44 +01002593 arm::pipe::Packet connectionAcknowledgedPacket(header);
Matteo Martincigh54fb9572019-10-02 12:50:57 +01002594
2595 // Write the packet to the mock profiling connection
2596 mockProfilingConnection->WritePacket(std::move(connectionAcknowledgedPacket));
2597
Colm Donelan2ba48d22019-11-29 09:10:59 +00002598 // Wait for the counter directory packet to ensure the ConnectionAcknowledgedCommandHandler has run.
Sadik Armagan1625efc2021-06-10 18:24:34 +01002599 CHECK(helper.WaitForPacketsSent(mockProfilingConnection, PacketType::CounterDirectory) == 1);
Matteo Martincigh54fb9572019-10-02 12:50:57 +01002600
2601 // The Connection Acknowledged Command Handler should have updated the profiling state accordingly
Sadik Armagan1625efc2021-06-10 18:24:34 +01002602 CHECK(profilingService.GetCurrentState() == ProfilingState::Active);
Matteo Martincighd0613b52019-10-09 16:47:04 +01002603
2604 // Reset the profiling service to stop any running thread
2605 options.m_EnableProfiling = false;
2606 profilingService.ResetExternalProfilingOptions(options, true);
Matteo Martincigh54fb9572019-10-02 12:50:57 +01002607}
2608
Sadik Armagan1625efc2021-06-10 18:24:34 +01002609TEST_CASE("CheckProfilingServiceGoodRequestCounterDirectoryPacket")
Matteo Martincigh8efc5002019-10-10 14:30:29 +01002610{
Matteo Martincigh8efc5002019-10-10 14:30:29 +01002611 // Reset the profiling service to the uninitialized state
Jim Flynn4c9ed1d2022-01-23 23:57:20 +00002612 ProfilingOptions options;
Keith Davis3201eea2019-10-24 17:30:41 +01002613 options.m_EnableProfiling = true;
Sadik Armagan3184c902020-03-18 10:57:30 +00002614 armnn::profiling::ProfilingService profilingService;
Matteo Martincigh8efc5002019-10-10 14:30:29 +01002615 profilingService.ResetExternalProfilingOptions(options, true);
2616
Sadik Armagan3184c902020-03-18 10:57:30 +00002617 // Swap the profiling connection factory in the profiling service instance with our mock one
2618 SwapProfilingConnectionFactoryHelper helper(profilingService);
2619
Matteo Martincigh8efc5002019-10-10 14:30:29 +01002620 // Bring the profiling service to the "Active" state
Sadik Armagan1625efc2021-06-10 18:24:34 +01002621 CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
Keith Davis3201eea2019-10-24 17:30:41 +01002622 profilingService.Update(); // Initialize the counter directory
Sadik Armagan1625efc2021-06-10 18:24:34 +01002623 CHECK(profilingService.GetCurrentState() == ProfilingState::NotConnected);
Keith Davis3201eea2019-10-24 17:30:41 +01002624 profilingService.Update(); // Create the profiling connection
Sadik Armagan1625efc2021-06-10 18:24:34 +01002625 CHECK(profilingService.GetCurrentState() == ProfilingState::WaitingForAck);
Keith Davis3201eea2019-10-24 17:30:41 +01002626 profilingService.Update(); // Start the command handler and the send thread
Matteo Martincighe8485382019-10-10 14:08:21 +01002627
Colm Donelan2ba48d22019-11-29 09:10:59 +00002628 // Get the mock profiling connection
2629 MockProfilingConnection* mockProfilingConnection = helper.GetMockProfilingConnection();
Sadik Armagan1625efc2021-06-10 18:24:34 +01002630 CHECK(mockProfilingConnection);
Colm Donelan2ba48d22019-11-29 09:10:59 +00002631
Matteo Martincighe8485382019-10-10 14:08:21 +01002632 // Force the profiling service to the "Active" state
Matteo Martincigh8efc5002019-10-10 14:30:29 +01002633 helper.ForceTransitionToState(ProfilingState::Active);
Sadik Armagan1625efc2021-06-10 18:24:34 +01002634 CHECK(profilingService.GetCurrentState() == ProfilingState::Active);
Matteo Martincigh8efc5002019-10-10 14:30:29 +01002635
Matteo Martincigh8efc5002019-10-10 14:30:29 +01002636 // Write a valid "Request Counter Directory" packet into the mock profiling connection, to simulate a valid
2637 // reply from an external profiling service
2638
2639 // Request Counter Directory packet header (word 0, word 1 is always zero):
2640 // 26:31 [6] packet_family: Control Packet Family, value 0b000000
2641 // 16:25 [10] packet_id: Packet identifier, value 0b0000000011
2642 // 8:15 [8] reserved: Reserved, value 0b00000000
2643 // 0:7 [8] reserved: Reserved, value 0b00000000
2644 uint32_t packetFamily = 0;
2645 uint32_t packetId = 3;
Keith Davis3201eea2019-10-24 17:30:41 +01002646 uint32_t header = ((packetFamily & 0x0000003F) << 26) | ((packetId & 0x000003FF) << 16);
Matteo Martincigh8efc5002019-10-10 14:30:29 +01002647
2648 // Create the Request Counter Directory packet
Jim Flynnbbfe6032020-07-20 16:57:44 +01002649 arm::pipe::Packet requestCounterDirectoryPacket(header);
Matteo Martincigh8efc5002019-10-10 14:30:29 +01002650
2651 // Write the packet to the mock profiling connection
2652 mockProfilingConnection->WritePacket(std::move(requestCounterDirectoryPacket));
2653
Sadik Armagan4c998992020-02-25 12:44:44 +00002654 // Expecting one CounterDirectory Packet of length 652
Jim Flynn6398a982020-05-27 17:05:21 +01002655 // and one TimelineMessageDirectory packet of length 451
Sadik Armagan1625efc2021-06-10 18:24:34 +01002656 CHECK(helper.WaitForPacketsSent(mockProfilingConnection, PacketType::CounterDirectory, 652) == 1);
2657 CHECK(helper.WaitForPacketsSent(mockProfilingConnection, PacketType::TimelineMessageDirectory, 451) == 1);
Matteo Martincighe8485382019-10-10 14:08:21 +01002658
2659 // The Request Counter Directory Command Handler should not have updated the profiling state
Sadik Armagan1625efc2021-06-10 18:24:34 +01002660 CHECK(profilingService.GetCurrentState() == ProfilingState::Active);
Matteo Martincighe8485382019-10-10 14:08:21 +01002661
2662 // Reset the profiling service to stop any running thread
2663 options.m_EnableProfiling = false;
2664 profilingService.ResetExternalProfilingOptions(options, true);
2665}
2666
Sadik Armagan1625efc2021-06-10 18:24:34 +01002667TEST_CASE("CheckProfilingServiceBadPeriodicCounterSelectionPacketInvalidCounterUid")
Matteo Martincighe8485382019-10-10 14:08:21 +01002668{
Matteo Martincighe8485382019-10-10 14:08:21 +01002669 // Reset the profiling service to the uninitialized state
Jim Flynn4c9ed1d2022-01-23 23:57:20 +00002670 ProfilingOptions options;
Keith Davis3201eea2019-10-24 17:30:41 +01002671 options.m_EnableProfiling = true;
Sadik Armagan3184c902020-03-18 10:57:30 +00002672 armnn::profiling::ProfilingService profilingService;
Matteo Martincighe8485382019-10-10 14:08:21 +01002673 profilingService.ResetExternalProfilingOptions(options, true);
2674
Sadik Armagan3184c902020-03-18 10:57:30 +00002675 // Swap the profiling connection factory in the profiling service instance with our mock one
2676 SwapProfilingConnectionFactoryHelper helper(profilingService);
2677
Matteo Martincighe8485382019-10-10 14:08:21 +01002678 // Bring the profiling service to the "Active" state
Sadik Armagan1625efc2021-06-10 18:24:34 +01002679 CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
Keith Davis3201eea2019-10-24 17:30:41 +01002680 profilingService.Update(); // Initialize the counter directory
Sadik Armagan1625efc2021-06-10 18:24:34 +01002681 CHECK(profilingService.GetCurrentState() == ProfilingState::NotConnected);
Keith Davis3201eea2019-10-24 17:30:41 +01002682 profilingService.Update(); // Create the profiling connection
Sadik Armagan1625efc2021-06-10 18:24:34 +01002683 CHECK(profilingService.GetCurrentState() == ProfilingState::WaitingForAck);
Keith Davis3201eea2019-10-24 17:30:41 +01002684 profilingService.Update(); // Start the command handler and the send thread
Matteo Martincighe8485382019-10-10 14:08:21 +01002685
Colm Donelan2ba48d22019-11-29 09:10:59 +00002686 // Get the mock profiling connection
2687 MockProfilingConnection* mockProfilingConnection = helper.GetMockProfilingConnection();
Sadik Armagan1625efc2021-06-10 18:24:34 +01002688 CHECK(mockProfilingConnection);
Colm Donelan2ba48d22019-11-29 09:10:59 +00002689
Matteo Martincighe8485382019-10-10 14:08:21 +01002690 // Force the profiling service to the "Active" state
2691 helper.ForceTransitionToState(ProfilingState::Active);
Sadik Armagan1625efc2021-06-10 18:24:34 +01002692 CHECK(profilingService.GetCurrentState() == ProfilingState::Active);
Matteo Martincighe8485382019-10-10 14:08:21 +01002693
Matteo Martincighe8485382019-10-10 14:08:21 +01002694 // Remove the packets received so far
2695 mockProfilingConnection->Clear();
2696
2697 // Write a "Periodic Counter Selection" packet into the mock profiling connection, to simulate an input from an
2698 // external profiling service
2699
2700 // Periodic Counter Selection packet header:
2701 // 26:31 [6] packet_family: Control Packet Family, value 0b000000
2702 // 16:25 [10] packet_id: Packet identifier, value 0b0000000100
2703 // 8:15 [8] reserved: Reserved, value 0b00000000
2704 // 0:7 [8] reserved: Reserved, value 0b00000000
2705 uint32_t packetFamily = 0;
2706 uint32_t packetId = 4;
Keith Davis3201eea2019-10-24 17:30:41 +01002707 uint32_t header = ((packetFamily & 0x0000003F) << 26) | ((packetId & 0x000003FF) << 16);
Matteo Martincighe8485382019-10-10 14:08:21 +01002708
Keith Davis3201eea2019-10-24 17:30:41 +01002709 uint32_t capturePeriod = 123456; // Some capture period (microseconds)
Matteo Martincighe8485382019-10-10 14:08:21 +01002710
2711 // Get the first valid counter UID
2712 const ICounterDirectory& counterDirectory = profilingService.GetCounterDirectory();
Keith Davis3201eea2019-10-24 17:30:41 +01002713 const Counters& counters = counterDirectory.GetCounters();
Sadik Armagan1625efc2021-06-10 18:24:34 +01002714 CHECK(counters.size() > 1);
Keith Davis3201eea2019-10-24 17:30:41 +01002715 uint16_t counterUidA = counters.begin()->first; // First valid counter UID
2716 uint16_t counterUidB = 9999; // Second invalid counter UID
Matteo Martincighe8485382019-10-10 14:08:21 +01002717
2718 uint32_t length = 8;
2719
2720 auto data = std::make_unique<unsigned char[]>(length);
2721 WriteUint32(data.get(), 0, capturePeriod);
2722 WriteUint16(data.get(), 4, counterUidA);
2723 WriteUint16(data.get(), 6, counterUidB);
2724
2725 // Create the Periodic Counter Selection packet
Jim Flynnbbfe6032020-07-20 16:57:44 +01002726 // Length > 0, this will start the Period Counter Capture thread
2727 arm::pipe::Packet periodicCounterSelectionPacket(header, length, data);
2728
Matteo Martincighe8485382019-10-10 14:08:21 +01002729
2730 // Write the packet to the mock profiling connection
2731 mockProfilingConnection->WritePacket(std::move(periodicCounterSelectionPacket));
2732
Finn Williams09ad6f92019-12-19 17:05:18 +00002733 // Expecting one Periodic Counter Selection packet of length 14
2734 // and at least one Periodic Counter Capture packet of length 22
Sadik Armagan1625efc2021-06-10 18:24:34 +01002735 CHECK(helper.WaitForPacketsSent(mockProfilingConnection, PacketType::PeriodicCounterSelection, 14) == 1);
2736 CHECK(helper.WaitForPacketsSent(mockProfilingConnection, PacketType::PeriodicCounterCapture, 22) >= 1);
Matteo Martincighe8485382019-10-10 14:08:21 +01002737
2738 // The Periodic Counter Selection Handler should not have updated the profiling state
Sadik Armagan1625efc2021-06-10 18:24:34 +01002739 CHECK(profilingService.GetCurrentState() == ProfilingState::Active);
Matteo Martincighe8485382019-10-10 14:08:21 +01002740
2741 // Reset the profiling service to stop any running thread
2742 options.m_EnableProfiling = false;
2743 profilingService.ResetExternalProfilingOptions(options, true);
2744}
2745
Sadik Armagan1625efc2021-06-10 18:24:34 +01002746TEST_CASE("CheckProfilingServiceGoodPeriodicCounterSelectionPacketNoCounters")
Matteo Martincighe8485382019-10-10 14:08:21 +01002747{
Matteo Martincighe8485382019-10-10 14:08:21 +01002748 // Reset the profiling service to the uninitialized state
Jim Flynn4c9ed1d2022-01-23 23:57:20 +00002749 ProfilingOptions options;
Keith Davis3201eea2019-10-24 17:30:41 +01002750 options.m_EnableProfiling = true;
Sadik Armagan3184c902020-03-18 10:57:30 +00002751 armnn::profiling::ProfilingService profilingService;
Matteo Martincighe8485382019-10-10 14:08:21 +01002752 profilingService.ResetExternalProfilingOptions(options, true);
2753
Sadik Armagan3184c902020-03-18 10:57:30 +00002754 // Swap the profiling connection factory in the profiling service instance with our mock one
2755 SwapProfilingConnectionFactoryHelper helper(profilingService);
2756
Matteo Martincighe8485382019-10-10 14:08:21 +01002757 // Bring the profiling service to the "Active" state
Sadik Armagan1625efc2021-06-10 18:24:34 +01002758 CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
Keith Davis3201eea2019-10-24 17:30:41 +01002759 profilingService.Update(); // Initialize the counter directory
Sadik Armagan1625efc2021-06-10 18:24:34 +01002760 CHECK(profilingService.GetCurrentState() == ProfilingState::NotConnected);
Keith Davis3201eea2019-10-24 17:30:41 +01002761 profilingService.Update(); // Create the profiling connection
Sadik Armagan1625efc2021-06-10 18:24:34 +01002762 CHECK(profilingService.GetCurrentState() == ProfilingState::WaitingForAck);
Keith Davis3201eea2019-10-24 17:30:41 +01002763 profilingService.Update(); // Start the command handler and the send thread
Matteo Martincighe8485382019-10-10 14:08:21 +01002764
Colm Donelan2ba48d22019-11-29 09:10:59 +00002765 // Get the mock profiling connection
2766 MockProfilingConnection* mockProfilingConnection = helper.GetMockProfilingConnection();
Sadik Armagan1625efc2021-06-10 18:24:34 +01002767 CHECK(mockProfilingConnection);
Colm Donelan2ba48d22019-11-29 09:10:59 +00002768
Matteo Martincighe8485382019-10-10 14:08:21 +01002769 // Wait for the Stream Metadata packet the be sent
2770 // (we are not testing the connection acknowledgement here so it will be ignored by this test)
Finn Williams09ad6f92019-12-19 17:05:18 +00002771 helper.WaitForPacketsSent(mockProfilingConnection, PacketType::StreamMetaData);
Matteo Martincighe8485382019-10-10 14:08:21 +01002772
2773 // Force the profiling service to the "Active" state
2774 helper.ForceTransitionToState(ProfilingState::Active);
Sadik Armagan1625efc2021-06-10 18:24:34 +01002775 CHECK(profilingService.GetCurrentState() == ProfilingState::Active);
Matteo Martincighe8485382019-10-10 14:08:21 +01002776
Matteo Martincighe8485382019-10-10 14:08:21 +01002777 // Write a "Periodic Counter Selection" packet into the mock profiling connection, to simulate an input from an
2778 // external profiling service
2779
2780 // Periodic Counter Selection packet header:
2781 // 26:31 [6] packet_family: Control Packet Family, value 0b000000
2782 // 16:25 [10] packet_id: Packet identifier, value 0b0000000100
2783 // 8:15 [8] reserved: Reserved, value 0b00000000
2784 // 0:7 [8] reserved: Reserved, value 0b00000000
2785 uint32_t packetFamily = 0;
2786 uint32_t packetId = 4;
Keith Davis3201eea2019-10-24 17:30:41 +01002787 uint32_t header = ((packetFamily & 0x0000003F) << 26) | ((packetId & 0x000003FF) << 16);
Matteo Martincighe8485382019-10-10 14:08:21 +01002788
2789 // Create the Periodic Counter Selection packet
Jim Flynnbbfe6032020-07-20 16:57:44 +01002790 // Length == 0, this will disable the collection of counters
2791 arm::pipe::Packet periodicCounterSelectionPacket(header);
Matteo Martincighe8485382019-10-10 14:08:21 +01002792
2793 // Write the packet to the mock profiling connection
2794 mockProfilingConnection->WritePacket(std::move(periodicCounterSelectionPacket));
2795
Finn Williams09ad6f92019-12-19 17:05:18 +00002796 // Wait for the Periodic Counter Selection packet of length 12 to be sent
2797 // The size of the expected Periodic Counter Selection (echos the sent one)
Sadik Armagan1625efc2021-06-10 18:24:34 +01002798 CHECK(helper.WaitForPacketsSent(mockProfilingConnection, PacketType::PeriodicCounterSelection, 12) == 1);
Matteo Martincighe8485382019-10-10 14:08:21 +01002799
2800 // The Periodic Counter Selection Handler should not have updated the profiling state
Sadik Armagan1625efc2021-06-10 18:24:34 +01002801 CHECK(profilingService.GetCurrentState() == ProfilingState::Active);
Matteo Martincighe8485382019-10-10 14:08:21 +01002802
Finn Williams09ad6f92019-12-19 17:05:18 +00002803 // No Periodic Counter packets are expected
Sadik Armagan1625efc2021-06-10 18:24:34 +01002804 CHECK(helper.WaitForPacketsSent(mockProfilingConnection, PacketType::PeriodicCounterCapture, 0, 0) == 0);
Matteo Martincighe8485382019-10-10 14:08:21 +01002805
2806 // Reset the profiling service to stop any running thread
2807 options.m_EnableProfiling = false;
2808 profilingService.ResetExternalProfilingOptions(options, true);
2809}
2810
Sadik Armagan1625efc2021-06-10 18:24:34 +01002811TEST_CASE("CheckProfilingServiceGoodPeriodicCounterSelectionPacketSingleCounter")
Matteo Martincighe8485382019-10-10 14:08:21 +01002812{
Matteo Martincighe8485382019-10-10 14:08:21 +01002813 // Reset the profiling service to the uninitialized state
Jim Flynn4c9ed1d2022-01-23 23:57:20 +00002814 ProfilingOptions options;
Keith Davis3201eea2019-10-24 17:30:41 +01002815 options.m_EnableProfiling = true;
Sadik Armagan3184c902020-03-18 10:57:30 +00002816 armnn::profiling::ProfilingService profilingService;
Matteo Martincighe8485382019-10-10 14:08:21 +01002817 profilingService.ResetExternalProfilingOptions(options, true);
2818
Sadik Armagan3184c902020-03-18 10:57:30 +00002819 // Swap the profiling connection factory in the profiling service instance with our mock one
2820 SwapProfilingConnectionFactoryHelper helper(profilingService);
2821
Matteo Martincighe8485382019-10-10 14:08:21 +01002822 // Bring the profiling service to the "Active" state
Sadik Armagan1625efc2021-06-10 18:24:34 +01002823 CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
Keith Davis3201eea2019-10-24 17:30:41 +01002824 profilingService.Update(); // Initialize the counter directory
Sadik Armagan1625efc2021-06-10 18:24:34 +01002825 CHECK(profilingService.GetCurrentState() == ProfilingState::NotConnected);
Keith Davis3201eea2019-10-24 17:30:41 +01002826 profilingService.Update(); // Create the profiling connection
Sadik Armagan1625efc2021-06-10 18:24:34 +01002827 CHECK(profilingService.GetCurrentState() == ProfilingState::WaitingForAck);
Keith Davis3201eea2019-10-24 17:30:41 +01002828 profilingService.Update(); // Start the command handler and the send thread
Matteo Martincighe8485382019-10-10 14:08:21 +01002829
Colm Donelan2ba48d22019-11-29 09:10:59 +00002830 // Get the mock profiling connection
2831 MockProfilingConnection* mockProfilingConnection = helper.GetMockProfilingConnection();
Sadik Armagan1625efc2021-06-10 18:24:34 +01002832 CHECK(mockProfilingConnection);
Colm Donelan2ba48d22019-11-29 09:10:59 +00002833
Finn Williams09ad6f92019-12-19 17:05:18 +00002834 // Wait for the Stream Metadata packet to be sent
Matteo Martincighe8485382019-10-10 14:08:21 +01002835 // (we are not testing the connection acknowledgement here so it will be ignored by this test)
Finn Williams09ad6f92019-12-19 17:05:18 +00002836 helper.WaitForPacketsSent(mockProfilingConnection, PacketType::StreamMetaData);
Matteo Martincighe8485382019-10-10 14:08:21 +01002837
2838 // Force the profiling service to the "Active" state
2839 helper.ForceTransitionToState(ProfilingState::Active);
Sadik Armagan1625efc2021-06-10 18:24:34 +01002840 CHECK(profilingService.GetCurrentState() == ProfilingState::Active);
Matteo Martincighe8485382019-10-10 14:08:21 +01002841
Matteo Martincighe8485382019-10-10 14:08:21 +01002842 // Write a "Periodic Counter Selection" packet into the mock profiling connection, to simulate an input from an
2843 // external profiling service
2844
2845 // Periodic Counter Selection packet header:
2846 // 26:31 [6] packet_family: Control Packet Family, value 0b000000
2847 // 16:25 [10] packet_id: Packet identifier, value 0b0000000100
2848 // 8:15 [8] reserved: Reserved, value 0b00000000
2849 // 0:7 [8] reserved: Reserved, value 0b00000000
2850 uint32_t packetFamily = 0;
2851 uint32_t packetId = 4;
Keith Davis3201eea2019-10-24 17:30:41 +01002852 uint32_t header = ((packetFamily & 0x0000003F) << 26) | ((packetId & 0x000003FF) << 16);
Matteo Martincighe8485382019-10-10 14:08:21 +01002853
Keith Davis3201eea2019-10-24 17:30:41 +01002854 uint32_t capturePeriod = 123456; // Some capture period (microseconds)
Matteo Martincighe8485382019-10-10 14:08:21 +01002855
2856 // Get the first valid counter UID
2857 const ICounterDirectory& counterDirectory = profilingService.GetCounterDirectory();
Keith Davis3201eea2019-10-24 17:30:41 +01002858 const Counters& counters = counterDirectory.GetCounters();
Sadik Armagan1625efc2021-06-10 18:24:34 +01002859 CHECK(!counters.empty());
Keith Davis3201eea2019-10-24 17:30:41 +01002860 uint16_t counterUid = counters.begin()->first; // Valid counter UID
Matteo Martincighe8485382019-10-10 14:08:21 +01002861
2862 uint32_t length = 6;
2863
2864 auto data = std::make_unique<unsigned char[]>(length);
2865 WriteUint32(data.get(), 0, capturePeriod);
2866 WriteUint16(data.get(), 4, counterUid);
2867
2868 // Create the Periodic Counter Selection packet
Jim Flynnbbfe6032020-07-20 16:57:44 +01002869 // Length > 0, this will start the Period Counter Capture thread
2870 arm::pipe::Packet periodicCounterSelectionPacket(header, length, data);
Matteo Martincighe8485382019-10-10 14:08:21 +01002871
2872 // Write the packet to the mock profiling connection
2873 mockProfilingConnection->WritePacket(std::move(periodicCounterSelectionPacket));
2874
Finn Williams09ad6f92019-12-19 17:05:18 +00002875 // Expecting one Periodic Counter Selection packet of length 14
2876 // and at least one Periodic Counter Capture packet of length 22
Sadik Armagan1625efc2021-06-10 18:24:34 +01002877 CHECK(helper.WaitForPacketsSent(mockProfilingConnection, PacketType::PeriodicCounterSelection, 14) == 1);
2878 CHECK(helper.WaitForPacketsSent(mockProfilingConnection, PacketType::PeriodicCounterCapture, 22) >= 1);
Matteo Martincighe8485382019-10-10 14:08:21 +01002879
2880 // The Periodic Counter Selection Handler should not have updated the profiling state
Sadik Armagan1625efc2021-06-10 18:24:34 +01002881 CHECK(profilingService.GetCurrentState() == ProfilingState::Active);
Matteo Martincighe8485382019-10-10 14:08:21 +01002882
2883 // Reset the profiling service to stop any running thread
2884 options.m_EnableProfiling = false;
2885 profilingService.ResetExternalProfilingOptions(options, true);
2886}
2887
Sadik Armagan1625efc2021-06-10 18:24:34 +01002888TEST_CASE("CheckProfilingServiceGoodPeriodicCounterSelectionPacketMultipleCounters")
Matteo Martincighe8485382019-10-10 14:08:21 +01002889{
Matteo Martincighe8485382019-10-10 14:08:21 +01002890 // Reset the profiling service to the uninitialized state
Jim Flynn4c9ed1d2022-01-23 23:57:20 +00002891 ProfilingOptions options;
Keith Davis3201eea2019-10-24 17:30:41 +01002892 options.m_EnableProfiling = true;
Sadik Armagan3184c902020-03-18 10:57:30 +00002893 armnn::profiling::ProfilingService profilingService;
Matteo Martincighe8485382019-10-10 14:08:21 +01002894 profilingService.ResetExternalProfilingOptions(options, true);
2895
Sadik Armagan3184c902020-03-18 10:57:30 +00002896 // Swap the profiling connection factory in the profiling service instance with our mock one
2897 SwapProfilingConnectionFactoryHelper helper(profilingService);
2898
Matteo Martincighe8485382019-10-10 14:08:21 +01002899 // Bring the profiling service to the "Active" state
Sadik Armagan1625efc2021-06-10 18:24:34 +01002900 CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
Keith Davis3201eea2019-10-24 17:30:41 +01002901 profilingService.Update(); // Initialize the counter directory
Sadik Armagan1625efc2021-06-10 18:24:34 +01002902 CHECK(profilingService.GetCurrentState() == ProfilingState::NotConnected);
Keith Davis3201eea2019-10-24 17:30:41 +01002903 profilingService.Update(); // Create the profiling connection
Sadik Armagan1625efc2021-06-10 18:24:34 +01002904 CHECK(profilingService.GetCurrentState() == ProfilingState::WaitingForAck);
Keith Davis3201eea2019-10-24 17:30:41 +01002905 profilingService.Update(); // Start the command handler and the send thread
Matteo Martincighe8485382019-10-10 14:08:21 +01002906
Colm Donelan2ba48d22019-11-29 09:10:59 +00002907 // Get the mock profiling connection
2908 MockProfilingConnection* mockProfilingConnection = helper.GetMockProfilingConnection();
Sadik Armagan1625efc2021-06-10 18:24:34 +01002909 CHECK(mockProfilingConnection);
Colm Donelan2ba48d22019-11-29 09:10:59 +00002910
Matteo Martincighe8485382019-10-10 14:08:21 +01002911 // Wait for the Stream Metadata packet the be sent
2912 // (we are not testing the connection acknowledgement here so it will be ignored by this test)
Finn Williams09ad6f92019-12-19 17:05:18 +00002913 helper.WaitForPacketsSent(mockProfilingConnection, PacketType::StreamMetaData);
Matteo Martincighe8485382019-10-10 14:08:21 +01002914
2915 // Force the profiling service to the "Active" state
2916 helper.ForceTransitionToState(ProfilingState::Active);
Sadik Armagan1625efc2021-06-10 18:24:34 +01002917 CHECK(profilingService.GetCurrentState() == ProfilingState::Active);
Matteo Martincighe8485382019-10-10 14:08:21 +01002918
Matteo Martincighe8485382019-10-10 14:08:21 +01002919 // Write a "Periodic Counter Selection" packet into the mock profiling connection, to simulate an input from an
2920 // external profiling service
2921
2922 // Periodic Counter Selection packet header:
2923 // 26:31 [6] packet_family: Control Packet Family, value 0b000000
2924 // 16:25 [10] packet_id: Packet identifier, value 0b0000000100
2925 // 8:15 [8] reserved: Reserved, value 0b00000000
2926 // 0:7 [8] reserved: Reserved, value 0b00000000
2927 uint32_t packetFamily = 0;
2928 uint32_t packetId = 4;
Keith Davis3201eea2019-10-24 17:30:41 +01002929 uint32_t header = ((packetFamily & 0x0000003F) << 26) | ((packetId & 0x000003FF) << 16);
Matteo Martincighe8485382019-10-10 14:08:21 +01002930
Keith Davis3201eea2019-10-24 17:30:41 +01002931 uint32_t capturePeriod = 123456; // Some capture period (microseconds)
Matteo Martincighe8485382019-10-10 14:08:21 +01002932
2933 // Get the first valid counter UID
2934 const ICounterDirectory& counterDirectory = profilingService.GetCounterDirectory();
Keith Davis3201eea2019-10-24 17:30:41 +01002935 const Counters& counters = counterDirectory.GetCounters();
Sadik Armagan1625efc2021-06-10 18:24:34 +01002936 CHECK(counters.size() > 1);
Keith Davis3201eea2019-10-24 17:30:41 +01002937 uint16_t counterUidA = counters.begin()->first; // First valid counter UID
2938 uint16_t counterUidB = (counters.begin()++)->first; // Second valid counter UID
Matteo Martincighe8485382019-10-10 14:08:21 +01002939
2940 uint32_t length = 8;
2941
2942 auto data = std::make_unique<unsigned char[]>(length);
2943 WriteUint32(data.get(), 0, capturePeriod);
2944 WriteUint16(data.get(), 4, counterUidA);
2945 WriteUint16(data.get(), 6, counterUidB);
2946
2947 // Create the Periodic Counter Selection packet
Jim Flynnbbfe6032020-07-20 16:57:44 +01002948 // Length > 0, this will start the Period Counter Capture thread
2949 arm::pipe::Packet periodicCounterSelectionPacket(header, length, data);
Matteo Martincighe8485382019-10-10 14:08:21 +01002950
2951 // Write the packet to the mock profiling connection
2952 mockProfilingConnection->WritePacket(std::move(periodicCounterSelectionPacket));
2953
Finn Williams09ad6f92019-12-19 17:05:18 +00002954 // Expecting one PeriodicCounterSelection Packet with a length of 16
2955 // And at least one PeriodicCounterCapture Packet with a length of 28
Sadik Armagan1625efc2021-06-10 18:24:34 +01002956 CHECK(helper.WaitForPacketsSent(mockProfilingConnection, PacketType::PeriodicCounterSelection, 16) == 1);
2957 CHECK(helper.WaitForPacketsSent(mockProfilingConnection, PacketType::PeriodicCounterCapture, 28) >= 1);
Matteo Martincighe8485382019-10-10 14:08:21 +01002958
2959 // The Periodic Counter Selection Handler should not have updated the profiling state
Sadik Armagan1625efc2021-06-10 18:24:34 +01002960 CHECK(profilingService.GetCurrentState() == ProfilingState::Active);
Matteo Martincigh8efc5002019-10-10 14:30:29 +01002961
2962 // Reset the profiling service to stop any running thread
2963 options.m_EnableProfiling = false;
2964 profilingService.ResetExternalProfilingOptions(options, true);
2965}
2966
Sadik Armagan1625efc2021-06-10 18:24:34 +01002967TEST_CASE("CheckProfilingServiceDisconnect")
Jim Flynn53e46992019-10-14 12:31:10 +01002968{
Jim Flynn53e46992019-10-14 12:31:10 +01002969 // Reset the profiling service to the uninitialized state
Jim Flynn4c9ed1d2022-01-23 23:57:20 +00002970 ProfilingOptions options;
Keith Davis3201eea2019-10-24 17:30:41 +01002971 options.m_EnableProfiling = true;
Sadik Armagan3184c902020-03-18 10:57:30 +00002972 armnn::profiling::ProfilingService profilingService;
Jim Flynn53e46992019-10-14 12:31:10 +01002973 profilingService.ResetExternalProfilingOptions(options, true);
2974
Sadik Armagan3184c902020-03-18 10:57:30 +00002975 // Swap the profiling connection factory in the profiling service instance with our mock one
2976 SwapProfilingConnectionFactoryHelper helper(profilingService);
2977
Jim Flynn53e46992019-10-14 12:31:10 +01002978 // Try to disconnect the profiling service while in the "Uninitialised" state
Sadik Armagan1625efc2021-06-10 18:24:34 +01002979 CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
Jim Flynn53e46992019-10-14 12:31:10 +01002980 profilingService.Disconnect();
Sadik Armagan1625efc2021-06-10 18:24:34 +01002981 CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised); // The state should not change
Jim Flynn53e46992019-10-14 12:31:10 +01002982
2983 // Try to disconnect the profiling service while in the "NotConnected" state
Keith Davis3201eea2019-10-24 17:30:41 +01002984 profilingService.Update(); // Initialize the counter directory
Sadik Armagan1625efc2021-06-10 18:24:34 +01002985 CHECK(profilingService.GetCurrentState() == ProfilingState::NotConnected);
Jim Flynn53e46992019-10-14 12:31:10 +01002986 profilingService.Disconnect();
Sadik Armagan1625efc2021-06-10 18:24:34 +01002987 CHECK(profilingService.GetCurrentState() == ProfilingState::NotConnected); // The state should not change
Jim Flynn53e46992019-10-14 12:31:10 +01002988
2989 // Try to disconnect the profiling service while in the "WaitingForAck" state
Keith Davis3201eea2019-10-24 17:30:41 +01002990 profilingService.Update(); // Create the profiling connection
Sadik Armagan1625efc2021-06-10 18:24:34 +01002991 CHECK(profilingService.GetCurrentState() == ProfilingState::WaitingForAck);
Jim Flynn53e46992019-10-14 12:31:10 +01002992 profilingService.Disconnect();
Sadik Armagan1625efc2021-06-10 18:24:34 +01002993 CHECK(profilingService.GetCurrentState() == ProfilingState::WaitingForAck); // The state should not change
Jim Flynn53e46992019-10-14 12:31:10 +01002994
2995 // Try to disconnect the profiling service while in the "Active" state
Keith Davis3201eea2019-10-24 17:30:41 +01002996 profilingService.Update(); // Start the command handler and the send thread
Jim Flynn53e46992019-10-14 12:31:10 +01002997
Colm Donelan2ba48d22019-11-29 09:10:59 +00002998 // Get the mock profiling connection
2999 MockProfilingConnection* mockProfilingConnection = helper.GetMockProfilingConnection();
Sadik Armagan1625efc2021-06-10 18:24:34 +01003000 CHECK(mockProfilingConnection);
Colm Donelan2ba48d22019-11-29 09:10:59 +00003001
Jim Flynn53e46992019-10-14 12:31:10 +01003002 // Wait for the Stream Metadata packet the be sent
3003 // (we are not testing the connection acknowledgement here so it will be ignored by this test)
Finn Williams09ad6f92019-12-19 17:05:18 +00003004 helper.WaitForPacketsSent(mockProfilingConnection, PacketType::StreamMetaData);
Jim Flynn53e46992019-10-14 12:31:10 +01003005
3006 // Force the profiling service to the "Active" state
3007 helper.ForceTransitionToState(ProfilingState::Active);
Sadik Armagan1625efc2021-06-10 18:24:34 +01003008 CHECK(profilingService.GetCurrentState() == ProfilingState::Active);
Jim Flynn53e46992019-10-14 12:31:10 +01003009
Jim Flynn53e46992019-10-14 12:31:10 +01003010 // Check that the profiling connection is open
Sadik Armagan1625efc2021-06-10 18:24:34 +01003011 CHECK(mockProfilingConnection->IsOpen());
Jim Flynn53e46992019-10-14 12:31:10 +01003012
3013 profilingService.Disconnect();
Sadik Armagan1625efc2021-06-10 18:24:34 +01003014 CHECK(profilingService.GetCurrentState() == ProfilingState::NotConnected); // The state should have changed
Jim Flynn53e46992019-10-14 12:31:10 +01003015
3016 // Check that the profiling connection has been reset
3017 mockProfilingConnection = helper.GetMockProfilingConnection();
Sadik Armagan1625efc2021-06-10 18:24:34 +01003018 CHECK(mockProfilingConnection == nullptr);
Jim Flynn53e46992019-10-14 12:31:10 +01003019
3020 // Reset the profiling service to stop any running thread
3021 options.m_EnableProfiling = false;
3022 profilingService.ResetExternalProfilingOptions(options, true);
3023}
3024
Sadik Armagan1625efc2021-06-10 18:24:34 +01003025TEST_CASE("CheckProfilingServiceGoodPerJobCounterSelectionPacket")
Matteo Martincigh994b5342019-10-11 17:19:56 +01003026{
Matteo Martincigh994b5342019-10-11 17:19:56 +01003027 // Reset the profiling service to the uninitialized state
Jim Flynn4c9ed1d2022-01-23 23:57:20 +00003028 ProfilingOptions options;
Keith Davis3201eea2019-10-24 17:30:41 +01003029 options.m_EnableProfiling = true;
Sadik Armagan3184c902020-03-18 10:57:30 +00003030 armnn::profiling::ProfilingService profilingService;
Matteo Martincigh994b5342019-10-11 17:19:56 +01003031 profilingService.ResetExternalProfilingOptions(options, true);
3032
Sadik Armagan3184c902020-03-18 10:57:30 +00003033 // Swap the profiling connection factory in the profiling service instance with our mock one
3034 SwapProfilingConnectionFactoryHelper helper(profilingService);
3035
Matteo Martincigh994b5342019-10-11 17:19:56 +01003036 // Bring the profiling service to the "Active" state
Sadik Armagan1625efc2021-06-10 18:24:34 +01003037 CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
Keith Davis3201eea2019-10-24 17:30:41 +01003038 profilingService.Update(); // Initialize the counter directory
Sadik Armagan1625efc2021-06-10 18:24:34 +01003039 CHECK(profilingService.GetCurrentState() == ProfilingState::NotConnected);
Keith Davis3201eea2019-10-24 17:30:41 +01003040 profilingService.Update(); // Create the profiling connection
Sadik Armagan1625efc2021-06-10 18:24:34 +01003041 CHECK(profilingService.GetCurrentState() == ProfilingState::WaitingForAck);
Keith Davis3201eea2019-10-24 17:30:41 +01003042 profilingService.Update(); // Start the command handler and the send thread
Matteo Martincigh994b5342019-10-11 17:19:56 +01003043
Colm Donelan2ba48d22019-11-29 09:10:59 +00003044 // Get the mock profiling connection
3045 MockProfilingConnection* mockProfilingConnection = helper.GetMockProfilingConnection();
Sadik Armagan1625efc2021-06-10 18:24:34 +01003046 CHECK(mockProfilingConnection);
Colm Donelan2ba48d22019-11-29 09:10:59 +00003047
Matteo Martincigh994b5342019-10-11 17:19:56 +01003048 // Wait for the Stream Metadata packet the be sent
3049 // (we are not testing the connection acknowledgement here so it will be ignored by this test)
Finn Williams09ad6f92019-12-19 17:05:18 +00003050 helper.WaitForPacketsSent(mockProfilingConnection, PacketType::StreamMetaData);
Matteo Martincigh994b5342019-10-11 17:19:56 +01003051
3052 // Force the profiling service to the "Active" state
3053 helper.ForceTransitionToState(ProfilingState::Active);
Sadik Armagan1625efc2021-06-10 18:24:34 +01003054 CHECK(profilingService.GetCurrentState() == ProfilingState::Active);
Matteo Martincigh994b5342019-10-11 17:19:56 +01003055
Matteo Martincigh994b5342019-10-11 17:19:56 +01003056 // Write a "Per-Job Counter Selection" packet into the mock profiling connection, to simulate an input from an
3057 // external profiling service
3058
3059 // Per-Job Counter Selection packet header:
3060 // 26:31 [6] packet_family: Control Packet Family, value 0b000000
3061 // 16:25 [10] packet_id: Packet identifier, value 0b0000000100
3062 // 8:15 [8] reserved: Reserved, value 0b00000000
3063 // 0:7 [8] reserved: Reserved, value 0b00000000
3064 uint32_t packetFamily = 0;
3065 uint32_t packetId = 5;
Keith Davis3201eea2019-10-24 17:30:41 +01003066 uint32_t header = ((packetFamily & 0x0000003F) << 26) | ((packetId & 0x000003FF) << 16);
Matteo Martincigh994b5342019-10-11 17:19:56 +01003067
3068 // Create the Per-Job Counter Selection packet
Jim Flynnbbfe6032020-07-20 16:57:44 +01003069 // Length == 0, this will disable the collection of counters
3070 arm::pipe::Packet periodicCounterSelectionPacket(header);
Matteo Martincigh994b5342019-10-11 17:19:56 +01003071
3072 // Write the packet to the mock profiling connection
3073 mockProfilingConnection->WritePacket(std::move(periodicCounterSelectionPacket));
3074
3075 // Wait for a bit (must at least be the delay value of the mock profiling connection) to make sure that
3076 // the Per-Job Counter Selection packet gets processed by the profiling service
Colm Donelan2ba48d22019-11-29 09:10:59 +00003077 std::this_thread::sleep_for(std::chrono::milliseconds(5));
Matteo Martincigh994b5342019-10-11 17:19:56 +01003078
Matteo Martincigh994b5342019-10-11 17:19:56 +01003079 // The Per-Job Counter Selection Command Handler should not have updated the profiling state
Sadik Armagan1625efc2021-06-10 18:24:34 +01003080 CHECK(profilingService.GetCurrentState() == ProfilingState::Active);
Matteo Martincigh994b5342019-10-11 17:19:56 +01003081
Finn Williams09ad6f92019-12-19 17:05:18 +00003082 // The Per-Job Counter Selection packets are dropped silently, so there should be no reply coming
3083 // from the profiling service
3084 const auto StreamMetaDataSize = static_cast<unsigned long>(
3085 helper.WaitForPacketsSent(mockProfilingConnection, PacketType::StreamMetaData, 0, 0));
Sadik Armagan1625efc2021-06-10 18:24:34 +01003086 CHECK(StreamMetaDataSize == mockProfilingConnection->GetWrittenDataSize());
Finn Williams09ad6f92019-12-19 17:05:18 +00003087
Matteo Martincigh994b5342019-10-11 17:19:56 +01003088 // Reset the profiling service to stop any running thread
3089 options.m_EnableProfiling = false;
3090 profilingService.ResetExternalProfilingOptions(options, true);
3091}
3092
Sadik Armagan1625efc2021-06-10 18:24:34 +01003093TEST_CASE("CheckConfigureProfilingServiceOn")
Jim Flynn672d06e2019-10-15 10:18:11 +01003094{
Jim Flynn4c9ed1d2022-01-23 23:57:20 +00003095 ProfilingOptions options;
Keith Davis3201eea2019-10-24 17:30:41 +01003096 options.m_EnableProfiling = true;
Sadik Armagan3184c902020-03-18 10:57:30 +00003097 armnn::profiling::ProfilingService profilingService;
Sadik Armagan1625efc2021-06-10 18:24:34 +01003098 CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
Jim Flynn672d06e2019-10-15 10:18:11 +01003099 profilingService.ConfigureProfilingService(options);
3100 // should get as far as NOT_CONNECTED
Sadik Armagan1625efc2021-06-10 18:24:34 +01003101 CHECK(profilingService.GetCurrentState() == ProfilingState::NotConnected);
Jim Flynn672d06e2019-10-15 10:18:11 +01003102 // Reset the profiling service to stop any running thread
3103 options.m_EnableProfiling = false;
3104 profilingService.ResetExternalProfilingOptions(options, true);
3105}
3106
Sadik Armagan1625efc2021-06-10 18:24:34 +01003107TEST_CASE("CheckConfigureProfilingServiceOff")
Jim Flynn672d06e2019-10-15 10:18:11 +01003108{
Jim Flynn4c9ed1d2022-01-23 23:57:20 +00003109 ProfilingOptions options;
Sadik Armagan3184c902020-03-18 10:57:30 +00003110 armnn::profiling::ProfilingService profilingService;
Sadik Armagan1625efc2021-06-10 18:24:34 +01003111 CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
Jim Flynn672d06e2019-10-15 10:18:11 +01003112 profilingService.ConfigureProfilingService(options);
3113 // should not move from Uninitialised
Sadik Armagan1625efc2021-06-10 18:24:34 +01003114 CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
Jim Flynn672d06e2019-10-15 10:18:11 +01003115 // Reset the profiling service to stop any running thread
3116 options.m_EnableProfiling = false;
3117 profilingService.ResetExternalProfilingOptions(options, true);
3118}
3119
Sadik Armagan1625efc2021-06-10 18:24:34 +01003120TEST_CASE("CheckProfilingServiceEnabled")
Colm Donelan2ba48d22019-11-29 09:10:59 +00003121{
3122 // Locally reduce log level to "Warning", as this test needs to parse a warning message from the standard output
3123 LogLevelSwapper logLevelSwapper(armnn::LogSeverity::Warning);
Jim Flynn4c9ed1d2022-01-23 23:57:20 +00003124 ProfilingOptions options;
Colm Donelan2ba48d22019-11-29 09:10:59 +00003125 options.m_EnableProfiling = true;
Sadik Armagan3184c902020-03-18 10:57:30 +00003126 armnn::profiling::ProfilingService profilingService;
Colm Donelan2ba48d22019-11-29 09:10:59 +00003127 profilingService.ResetExternalProfilingOptions(options, true);
Sadik Armagan1625efc2021-06-10 18:24:34 +01003128 CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
Colm Donelan2ba48d22019-11-29 09:10:59 +00003129 profilingService.Update();
Sadik Armagan1625efc2021-06-10 18:24:34 +01003130 CHECK(profilingService.GetCurrentState() == ProfilingState::NotConnected);
Colm Donelan2ba48d22019-11-29 09:10:59 +00003131
3132 // Redirect the output to a local stream so that we can parse the warning message
3133 std::stringstream ss;
3134 StreamRedirector streamRedirector(std::cout, ss.rdbuf());
3135 profilingService.Update();
Finn Williams09ad6f92019-12-19 17:05:18 +00003136
3137 // Reset the profiling service to stop any running thread
3138 options.m_EnableProfiling = false;
3139 profilingService.ResetExternalProfilingOptions(options, true);
3140
Colm Donelan2ba48d22019-11-29 09:10:59 +00003141 streamRedirector.CancelRedirect();
3142
3143 // Check that the expected error has occurred and logged to the standard output
David Monahana8837bf2020-04-16 10:01:56 +01003144 if (ss.str().find("Cannot connect to stream socket: Connection refused") == std::string::npos)
Colm Donelan2ba48d22019-11-29 09:10:59 +00003145 {
3146 std::cout << ss.str();
Sadik Armagan1625efc2021-06-10 18:24:34 +01003147 FAIL("Expected string not found.");
Colm Donelan2ba48d22019-11-29 09:10:59 +00003148 }
Colm Donelan2ba48d22019-11-29 09:10:59 +00003149}
3150
Sadik Armagan1625efc2021-06-10 18:24:34 +01003151TEST_CASE("CheckProfilingServiceEnabledRuntime")
Colm Donelan2ba48d22019-11-29 09:10:59 +00003152{
3153 // Locally reduce log level to "Warning", as this test needs to parse a warning message from the standard output
3154 LogLevelSwapper logLevelSwapper(armnn::LogSeverity::Warning);
Jim Flynn4c9ed1d2022-01-23 23:57:20 +00003155 ProfilingOptions options;
Sadik Armagan3184c902020-03-18 10:57:30 +00003156 armnn::profiling::ProfilingService profilingService;
Colm Donelan2ba48d22019-11-29 09:10:59 +00003157 profilingService.ResetExternalProfilingOptions(options, true);
Sadik Armagan1625efc2021-06-10 18:24:34 +01003158 CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
Colm Donelan2ba48d22019-11-29 09:10:59 +00003159 profilingService.Update();
Sadik Armagan1625efc2021-06-10 18:24:34 +01003160 CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
Colm Donelan2ba48d22019-11-29 09:10:59 +00003161 options.m_EnableProfiling = true;
3162 profilingService.ResetExternalProfilingOptions(options);
Sadik Armagan1625efc2021-06-10 18:24:34 +01003163 CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
Colm Donelan2ba48d22019-11-29 09:10:59 +00003164 profilingService.Update();
Sadik Armagan1625efc2021-06-10 18:24:34 +01003165 CHECK(profilingService.GetCurrentState() == ProfilingState::NotConnected);
Colm Donelan2ba48d22019-11-29 09:10:59 +00003166
3167 // Redirect the output to a local stream so that we can parse the warning message
3168 std::stringstream ss;
3169 StreamRedirector streamRedirector(std::cout, ss.rdbuf());
3170 profilingService.Update();
3171
Finn Williams09ad6f92019-12-19 17:05:18 +00003172 // Reset the profiling service to stop any running thread
3173 options.m_EnableProfiling = false;
3174 profilingService.ResetExternalProfilingOptions(options, true);
3175
Colm Donelan2ba48d22019-11-29 09:10:59 +00003176 streamRedirector.CancelRedirect();
3177
3178 // Check that the expected error has occurred and logged to the standard output
David Monahana8837bf2020-04-16 10:01:56 +01003179 if (ss.str().find("Cannot connect to stream socket: Connection refused") == std::string::npos)
Colm Donelan2ba48d22019-11-29 09:10:59 +00003180 {
3181 std::cout << ss.str();
Sadik Armagan1625efc2021-06-10 18:24:34 +01003182 FAIL("Expected string not found.");
Colm Donelan2ba48d22019-11-29 09:10:59 +00003183 }
Colm Donelan2ba48d22019-11-29 09:10:59 +00003184}
3185
Sadik Armagan1625efc2021-06-10 18:24:34 +01003186TEST_CASE("CheckProfilingServiceBadConnectionAcknowledgedPacket")
Colm Donelan2ba48d22019-11-29 09:10:59 +00003187{
3188 // Locally reduce log level to "Warning", as this test needs to parse a warning message from the standard output
3189 LogLevelSwapper logLevelSwapper(armnn::LogSeverity::Warning);
Sadik Armagan3184c902020-03-18 10:57:30 +00003190
Colm Donelan2ba48d22019-11-29 09:10:59 +00003191
3192 // Redirect the standard output to a local stream so that we can parse the warning message
3193 std::stringstream ss;
3194 StreamRedirector streamRedirector(std::cout, ss.rdbuf());
3195
Colm Donelan2ba48d22019-11-29 09:10:59 +00003196 // Reset the profiling service to the uninitialized state
Jim Flynn4c9ed1d2022-01-23 23:57:20 +00003197 ProfilingOptions options;
Colm Donelan2ba48d22019-11-29 09:10:59 +00003198 options.m_EnableProfiling = true;
Sadik Armagan3184c902020-03-18 10:57:30 +00003199 armnn::profiling::ProfilingService profilingService;
Colm Donelan2ba48d22019-11-29 09:10:59 +00003200 profilingService.ResetExternalProfilingOptions(options, true);
3201
Sadik Armagan3184c902020-03-18 10:57:30 +00003202 // Swap the profiling connection factory in the profiling service instance with our mock one
3203 SwapProfilingConnectionFactoryHelper helper(profilingService);
3204
Colm Donelan2ba48d22019-11-29 09:10:59 +00003205 // Bring the profiling service to the "WaitingForAck" state
Sadik Armagan1625efc2021-06-10 18:24:34 +01003206 CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
Colm Donelan2ba48d22019-11-29 09:10:59 +00003207 profilingService.Update(); // Initialize the counter directory
Sadik Armagan1625efc2021-06-10 18:24:34 +01003208 CHECK(profilingService.GetCurrentState() == ProfilingState::NotConnected);
Colm Donelan2ba48d22019-11-29 09:10:59 +00003209 profilingService.Update(); // Create the profiling connection
3210
3211 // Get the mock profiling connection
3212 MockProfilingConnection* mockProfilingConnection = helper.GetMockProfilingConnection();
Sadik Armagan1625efc2021-06-10 18:24:34 +01003213 CHECK(mockProfilingConnection);
Colm Donelan2ba48d22019-11-29 09:10:59 +00003214
Sadik Armagan1625efc2021-06-10 18:24:34 +01003215 CHECK(profilingService.GetCurrentState() == ProfilingState::WaitingForAck);
Colm Donelan2ba48d22019-11-29 09:10:59 +00003216
3217 // Connection Acknowledged Packet header (word 0, word 1 is always zero):
3218 // 26:31 [6] packet_family: Control Packet Family, value 0b000000
3219 // 16:25 [10] packet_id: Packet identifier, value 0b0000000001
3220 // 8:15 [8] reserved: Reserved, value 0b00000000
3221 // 0:7 [8] reserved: Reserved, value 0b00000000
3222 uint32_t packetFamily = 0;
3223 uint32_t packetId = 37; // Wrong packet id!!!
3224 uint32_t header = ((packetFamily & 0x0000003F) << 26) | ((packetId & 0x000003FF) << 16);
3225
3226 // Create the Connection Acknowledged Packet
Jim Flynnbbfe6032020-07-20 16:57:44 +01003227 arm::pipe::Packet connectionAcknowledgedPacket(header);
Finn Williams09ad6f92019-12-19 17:05:18 +00003228 // Write an invalid "Connection Acknowledged" packet into the mock profiling connection, to simulate an invalid
3229 // reply from an external profiling service
Colm Donelan2ba48d22019-11-29 09:10:59 +00003230 mockProfilingConnection->WritePacket(std::move(connectionAcknowledgedPacket));
3231
Finn Williams09ad6f92019-12-19 17:05:18 +00003232 // Start the command thread
3233 profilingService.Update();
3234
3235 // Wait for the command thread to join
3236 options.m_EnableProfiling = false;
3237 profilingService.ResetExternalProfilingOptions(options, true);
Colm Donelan2ba48d22019-11-29 09:10:59 +00003238
3239 streamRedirector.CancelRedirect();
3240
3241 // Check that the expected error has occurred and logged to the standard output
David Monahana8837bf2020-04-16 10:01:56 +01003242 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 +00003243 {
3244 std::cout << ss.str();
Sadik Armagan1625efc2021-06-10 18:24:34 +01003245 FAIL("Expected string not found.");
Colm Donelan2ba48d22019-11-29 09:10:59 +00003246 }
Colm Donelan2ba48d22019-11-29 09:10:59 +00003247}
3248
Sadik Armagan1625efc2021-06-10 18:24:34 +01003249TEST_CASE("CheckProfilingServiceBadRequestCounterDirectoryPacket")
Colm Donelan2ba48d22019-11-29 09:10:59 +00003250{
3251 // Locally reduce log level to "Warning", as this test needs to parse a warning message from the standard output
3252 LogLevelSwapper logLevelSwapper(armnn::LogSeverity::Warning);
Colm Donelan2ba48d22019-11-29 09:10:59 +00003253
3254 // Redirect the standard output to a local stream so that we can parse the warning message
3255 std::stringstream ss;
3256 StreamRedirector streamRedirector(std::cout, ss.rdbuf());
3257
3258 // Reset the profiling service to the uninitialized state
Jim Flynn4c9ed1d2022-01-23 23:57:20 +00003259 ProfilingOptions options;
Colm Donelan2ba48d22019-11-29 09:10:59 +00003260 options.m_EnableProfiling = true;
Sadik Armagan3184c902020-03-18 10:57:30 +00003261 armnn::profiling::ProfilingService profilingService;
Colm Donelan2ba48d22019-11-29 09:10:59 +00003262 profilingService.ResetExternalProfilingOptions(options, true);
3263
Sadik Armagan3184c902020-03-18 10:57:30 +00003264 // Swap the profiling connection factory in the profiling service instance with our mock one
3265 SwapProfilingConnectionFactoryHelper helper(profilingService);
3266
Colm Donelan2ba48d22019-11-29 09:10:59 +00003267 // Bring the profiling service to the "Active" state
Sadik Armagan1625efc2021-06-10 18:24:34 +01003268 CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
Colm Donelan2ba48d22019-11-29 09:10:59 +00003269 helper.ForceTransitionToState(ProfilingState::NotConnected);
Sadik Armagan1625efc2021-06-10 18:24:34 +01003270 CHECK(profilingService.GetCurrentState() == ProfilingState::NotConnected);
Colm Donelan2ba48d22019-11-29 09:10:59 +00003271 profilingService.Update(); // Create the profiling connection
Sadik Armagan1625efc2021-06-10 18:24:34 +01003272 CHECK(profilingService.GetCurrentState() == ProfilingState::WaitingForAck);
Colm Donelan2ba48d22019-11-29 09:10:59 +00003273
3274 // Get the mock profiling connection
3275 MockProfilingConnection* mockProfilingConnection = helper.GetMockProfilingConnection();
Sadik Armagan1625efc2021-06-10 18:24:34 +01003276 CHECK(mockProfilingConnection);
Colm Donelan2ba48d22019-11-29 09:10:59 +00003277
Colm Donelan2ba48d22019-11-29 09:10:59 +00003278 // Write a valid "Request Counter Directory" packet into the mock profiling connection, to simulate a valid
3279 // reply from an external profiling service
3280
3281 // Request Counter Directory packet header (word 0, word 1 is always zero):
3282 // 26:31 [6] packet_family: Control Packet Family, value 0b000000
3283 // 16:25 [10] packet_id: Packet identifier, value 0b0000000011
3284 // 8:15 [8] reserved: Reserved, value 0b00000000
3285 // 0:7 [8] reserved: Reserved, value 0b00000000
3286 uint32_t packetFamily = 0;
3287 uint32_t packetId = 123; // Wrong packet id!!!
3288 uint32_t header = ((packetFamily & 0x0000003F) << 26) | ((packetId & 0x000003FF) << 16);
3289
3290 // Create the Request Counter Directory packet
Jim Flynnbbfe6032020-07-20 16:57:44 +01003291 arm::pipe::Packet requestCounterDirectoryPacket(header);
Colm Donelan2ba48d22019-11-29 09:10:59 +00003292
3293 // Write the packet to the mock profiling connection
3294 mockProfilingConnection->WritePacket(std::move(requestCounterDirectoryPacket));
3295
Finn Williams09ad6f92019-12-19 17:05:18 +00003296 // Start the command handler and the send thread
3297 profilingService.Update();
3298
3299 // Reset the profiling service to stop and join any running thread
3300 options.m_EnableProfiling = false;
3301 profilingService.ResetExternalProfilingOptions(options, true);
Colm Donelan2ba48d22019-11-29 09:10:59 +00003302
3303 streamRedirector.CancelRedirect();
3304
3305 // Check that the expected error has occurred and logged to the standard output
David Monahana8837bf2020-04-16 10:01:56 +01003306 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 +00003307 {
3308 std::cout << ss.str();
Sadik Armagan1625efc2021-06-10 18:24:34 +01003309 FAIL("Expected string not found.");
Colm Donelan2ba48d22019-11-29 09:10:59 +00003310 }
Colm Donelan2ba48d22019-11-29 09:10:59 +00003311}
3312
Sadik Armagan1625efc2021-06-10 18:24:34 +01003313TEST_CASE("CheckProfilingServiceBadPeriodicCounterSelectionPacket")
Colm Donelan2ba48d22019-11-29 09:10:59 +00003314{
3315 // Locally reduce log level to "Warning", as this test needs to parse a warning message from the standard output
3316 LogLevelSwapper logLevelSwapper(armnn::LogSeverity::Warning);
Colm Donelan2ba48d22019-11-29 09:10:59 +00003317
3318 // Redirect the standard output to a local stream so that we can parse the warning message
3319 std::stringstream ss;
3320 StreamRedirector streamRedirector(std::cout, ss.rdbuf());
3321
3322 // Reset the profiling service to the uninitialized state
Jim Flynn4c9ed1d2022-01-23 23:57:20 +00003323 ProfilingOptions options;
Colm Donelan2ba48d22019-11-29 09:10:59 +00003324 options.m_EnableProfiling = true;
Sadik Armagan3184c902020-03-18 10:57:30 +00003325 armnn::profiling::ProfilingService profilingService;
Colm Donelan2ba48d22019-11-29 09:10:59 +00003326 profilingService.ResetExternalProfilingOptions(options, true);
3327
Sadik Armagan3184c902020-03-18 10:57:30 +00003328 // Swap the profiling connection factory in the profiling service instance with our mock one
3329 SwapProfilingConnectionFactoryHelper helper(profilingService);
3330
Colm Donelan2ba48d22019-11-29 09:10:59 +00003331 // Bring the profiling service to the "Active" state
Sadik Armagan1625efc2021-06-10 18:24:34 +01003332 CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
Colm Donelan2ba48d22019-11-29 09:10:59 +00003333 profilingService.Update(); // Initialize the counter directory
Sadik Armagan1625efc2021-06-10 18:24:34 +01003334 CHECK(profilingService.GetCurrentState() == ProfilingState::NotConnected);
Colm Donelan2ba48d22019-11-29 09:10:59 +00003335 profilingService.Update(); // Create the profiling connection
Sadik Armagan1625efc2021-06-10 18:24:34 +01003336 CHECK(profilingService.GetCurrentState() == ProfilingState::WaitingForAck);
Colm Donelan2ba48d22019-11-29 09:10:59 +00003337 profilingService.Update(); // Start the command handler and the send thread
3338
3339 // Get the mock profiling connection
3340 MockProfilingConnection* mockProfilingConnection = helper.GetMockProfilingConnection();
Sadik Armagan1625efc2021-06-10 18:24:34 +01003341 CHECK(mockProfilingConnection);
Colm Donelan2ba48d22019-11-29 09:10:59 +00003342
Colm Donelan2ba48d22019-11-29 09:10:59 +00003343 // Write a "Periodic Counter Selection" packet into the mock profiling connection, to simulate an input from an
3344 // external profiling service
3345
3346 // Periodic Counter Selection packet header:
3347 // 26:31 [6] packet_family: Control Packet Family, value 0b000000
3348 // 16:25 [10] packet_id: Packet identifier, value 0b0000000100
3349 // 8:15 [8] reserved: Reserved, value 0b00000000
3350 // 0:7 [8] reserved: Reserved, value 0b00000000
3351 uint32_t packetFamily = 0;
3352 uint32_t packetId = 999; // Wrong packet id!!!
3353 uint32_t header = ((packetFamily & 0x0000003F) << 26) | ((packetId & 0x000003FF) << 16);
3354
3355 // Create the Periodic Counter Selection packet
Jim Flynnbbfe6032020-07-20 16:57:44 +01003356 // Length == 0, this will disable the collection of counters
3357 arm::pipe::Packet periodicCounterSelectionPacket(header);
Colm Donelan2ba48d22019-11-29 09:10:59 +00003358
3359 // Write the packet to the mock profiling connection
3360 mockProfilingConnection->WritePacket(std::move(periodicCounterSelectionPacket));
Finn Williams09ad6f92019-12-19 17:05:18 +00003361 profilingService.Update();
Colm Donelan2ba48d22019-11-29 09:10:59 +00003362
Finn Williams09ad6f92019-12-19 17:05:18 +00003363 // Reset the profiling service to stop any running thread
3364 options.m_EnableProfiling = false;
3365 profilingService.ResetExternalProfilingOptions(options, true);
Colm Donelan2ba48d22019-11-29 09:10:59 +00003366
3367 // Check that the expected error has occurred and logged to the standard output
3368 streamRedirector.CancelRedirect();
3369
3370 // Check that the expected error has occurred and logged to the standard output
David Monahana8837bf2020-04-16 10:01:56 +01003371 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 +00003372 {
3373 std::cout << ss.str();
Sadik Armagan1625efc2021-06-10 18:24:34 +01003374 FAIL("Expected string not found.");
Colm Donelan2ba48d22019-11-29 09:10:59 +00003375 }
Colm Donelan2ba48d22019-11-29 09:10:59 +00003376}
Jim Flynn97897022020-02-02 12:52:59 +00003377
Sadik Armagan1625efc2021-06-10 18:24:34 +01003378TEST_CASE("CheckCounterIdMap")
David Monahande803072020-01-30 12:44:23 +00003379{
3380 CounterIdMap counterIdMap;
Sadik Armagan1625efc2021-06-10 18:24:34 +01003381 CHECK_THROWS_AS(counterIdMap.GetBackendId(0), armnn::Exception);
3382 CHECK_THROWS_AS(counterIdMap.GetGlobalId(0, armnn::profiling::BACKEND_ID), armnn::Exception);
David Monahande803072020-01-30 12:44:23 +00003383
3384 uint16_t globalCounterIds = 0;
3385
3386 armnn::BackendId cpuRefId(armnn::Compute::CpuRef);
3387 armnn::BackendId cpuAccId(armnn::Compute::CpuAcc);
3388
3389 std::vector<uint16_t> cpuRefCounters = {0, 1, 2, 3};
3390 std::vector<uint16_t> cpuAccCounters = {0, 1};
3391
3392 for (uint16_t backendCounterId : cpuRefCounters)
3393 {
3394 counterIdMap.RegisterMapping(globalCounterIds, backendCounterId, cpuRefId);
3395 ++globalCounterIds;
3396 }
3397 for (uint16_t backendCounterId : cpuAccCounters)
3398 {
3399 counterIdMap.RegisterMapping(globalCounterIds, backendCounterId, cpuAccId);
3400 ++globalCounterIds;
3401 }
3402
Sadik Armagan1625efc2021-06-10 18:24:34 +01003403 CHECK(counterIdMap.GetBackendId(0) == (std::pair<uint16_t, armnn::BackendId>(0, cpuRefId)));
3404 CHECK(counterIdMap.GetBackendId(1) == (std::pair<uint16_t, armnn::BackendId>(1, cpuRefId)));
3405 CHECK(counterIdMap.GetBackendId(2) == (std::pair<uint16_t, armnn::BackendId>(2, cpuRefId)));
3406 CHECK(counterIdMap.GetBackendId(3) == (std::pair<uint16_t, armnn::BackendId>(3, cpuRefId)));
3407 CHECK(counterIdMap.GetBackendId(4) == (std::pair<uint16_t, armnn::BackendId>(0, cpuAccId)));
3408 CHECK(counterIdMap.GetBackendId(5) == (std::pair<uint16_t, armnn::BackendId>(1, cpuAccId)));
David Monahande803072020-01-30 12:44:23 +00003409
Sadik Armagan1625efc2021-06-10 18:24:34 +01003410 CHECK(counterIdMap.GetGlobalId(0, cpuRefId) == 0);
3411 CHECK(counterIdMap.GetGlobalId(1, cpuRefId) == 1);
3412 CHECK(counterIdMap.GetGlobalId(2, cpuRefId) == 2);
3413 CHECK(counterIdMap.GetGlobalId(3, cpuRefId) == 3);
3414 CHECK(counterIdMap.GetGlobalId(0, cpuAccId) == 4);
3415 CHECK(counterIdMap.GetGlobalId(1, cpuAccId) == 5);
David Monahande803072020-01-30 12:44:23 +00003416}
Colm Donelan2ba48d22019-11-29 09:10:59 +00003417
Sadik Armagan1625efc2021-06-10 18:24:34 +01003418TEST_CASE("CheckRegisterBackendCounters")
Jim Flynn97897022020-02-02 12:52:59 +00003419{
3420 uint16_t globalCounterIds = armnn::profiling::INFERENCES_RUN;
3421 armnn::BackendId cpuRefId(armnn::Compute::CpuRef);
3422
Jim Flynn97897022020-02-02 12:52:59 +00003423 // Reset the profiling service to the uninitialized state
Jim Flynn4c9ed1d2022-01-23 23:57:20 +00003424 ProfilingOptions options;
Jim Flynn97897022020-02-02 12:52:59 +00003425 options.m_EnableProfiling = true;
Sadik Armagan3184c902020-03-18 10:57:30 +00003426 ProfilingService profilingService;
Jim Flynn97897022020-02-02 12:52:59 +00003427 profilingService.ResetExternalProfilingOptions(options, true);
3428
Sadik Armagan3184c902020-03-18 10:57:30 +00003429 RegisterBackendCounters registerBackendCounters(globalCounterIds, cpuRefId, profilingService);
3430
3431
3432
Sadik Armagan1625efc2021-06-10 18:24:34 +01003433 CHECK(profilingService.GetCounterDirectory().GetCategories().empty());
Jim Flynn97897022020-02-02 12:52:59 +00003434 registerBackendCounters.RegisterCategory("categoryOne");
3435 auto categoryOnePtr = profilingService.GetCounterDirectory().GetCategory("categoryOne");
Sadik Armagan1625efc2021-06-10 18:24:34 +01003436 CHECK(categoryOnePtr);
Jim Flynn97897022020-02-02 12:52:59 +00003437
Sadik Armagan1625efc2021-06-10 18:24:34 +01003438 CHECK(profilingService.GetCounterDirectory().GetDevices().empty());
Jim Flynn97897022020-02-02 12:52:59 +00003439 globalCounterIds = registerBackendCounters.RegisterDevice("deviceOne");
3440 auto deviceOnePtr = profilingService.GetCounterDirectory().GetDevice(globalCounterIds);
Sadik Armagan1625efc2021-06-10 18:24:34 +01003441 CHECK(deviceOnePtr);
3442 CHECK(deviceOnePtr->m_Name == "deviceOne");
Jim Flynn97897022020-02-02 12:52:59 +00003443
Sadik Armagan1625efc2021-06-10 18:24:34 +01003444 CHECK(profilingService.GetCounterDirectory().GetCounterSets().empty());
Jim Flynn97897022020-02-02 12:52:59 +00003445 globalCounterIds = registerBackendCounters.RegisterCounterSet("counterSetOne");
3446 auto counterSetOnePtr = profilingService.GetCounterDirectory().GetCounterSet(globalCounterIds);
Sadik Armagan1625efc2021-06-10 18:24:34 +01003447 CHECK(counterSetOnePtr);
3448 CHECK(counterSetOnePtr->m_Name == "counterSetOne");
Jim Flynn97897022020-02-02 12:52:59 +00003449
3450 uint16_t newGlobalCounterId = registerBackendCounters.RegisterCounter(0,
3451 "categoryOne",
3452 0,
3453 0,
3454 1.f,
3455 "CounterOne",
3456 "first test counter");
Sadik Armagan1625efc2021-06-10 18:24:34 +01003457 CHECK((newGlobalCounterId = armnn::profiling::INFERENCES_RUN + 1));
Jim Flynn97897022020-02-02 12:52:59 +00003458 uint16_t mappedGlobalId = profilingService.GetCounterMappings().GetGlobalId(0, cpuRefId);
Sadik Armagan1625efc2021-06-10 18:24:34 +01003459 CHECK(mappedGlobalId == newGlobalCounterId);
Jim Flynn97897022020-02-02 12:52:59 +00003460 auto backendMapping = profilingService.GetCounterMappings().GetBackendId(newGlobalCounterId);
Sadik Armagan1625efc2021-06-10 18:24:34 +01003461 CHECK(backendMapping.first == 0);
3462 CHECK(backendMapping.second == cpuRefId);
Jim Flynn97897022020-02-02 12:52:59 +00003463
3464 // Reset the profiling service to stop any running thread
3465 options.m_EnableProfiling = false;
3466 profilingService.ResetExternalProfilingOptions(options, true);
3467}
3468
Sadik Armagan1625efc2021-06-10 18:24:34 +01003469TEST_CASE("CheckCounterStatusQuery")
James Conroy2dcd3fe2020-02-06 18:34:52 +00003470{
Jim Flynn4c9ed1d2022-01-23 23:57:20 +00003471 ProfilingOptions options;
3472 options.m_EnableProfiling = true;
James Conroy2dcd3fe2020-02-06 18:34:52 +00003473
3474 // Reset the profiling service to the uninitialized state
Sadik Armagan3184c902020-03-18 10:57:30 +00003475 ProfilingService profilingService;
Jim Flynn4c9ed1d2022-01-23 23:57:20 +00003476 profilingService.ResetExternalProfilingOptions(options, true);
James Conroy2dcd3fe2020-02-06 18:34:52 +00003477
3478 const armnn::BackendId cpuRefId(armnn::Compute::CpuRef);
3479 const armnn::BackendId cpuAccId(armnn::Compute::CpuAcc);
3480
3481 // Create BackendProfiling for each backend
3482 BackendProfiling backendProfilingCpuRef(options, profilingService, cpuRefId);
3483 BackendProfiling backendProfilingCpuAcc(options, profilingService, cpuAccId);
3484
3485 uint16_t initialNumGlobalCounterIds = armnn::profiling::INFERENCES_RUN;
3486
3487 // Create RegisterBackendCounters for CpuRef
Sadik Armagan3184c902020-03-18 10:57:30 +00003488 RegisterBackendCounters registerBackendCountersCpuRef(initialNumGlobalCounterIds, cpuRefId, profilingService);
James Conroy2dcd3fe2020-02-06 18:34:52 +00003489
3490 // Create 'testCategory' in CounterDirectory (backend agnostic)
Sadik Armagan1625efc2021-06-10 18:24:34 +01003491 CHECK(profilingService.GetCounterDirectory().GetCategories().empty());
James Conroy2dcd3fe2020-02-06 18:34:52 +00003492 registerBackendCountersCpuRef.RegisterCategory("testCategory");
3493 auto categoryOnePtr = profilingService.GetCounterDirectory().GetCategory("testCategory");
Sadik Armagan1625efc2021-06-10 18:24:34 +01003494 CHECK(categoryOnePtr);
James Conroy2dcd3fe2020-02-06 18:34:52 +00003495
3496 // Counters:
3497 // Global | Local | Backend
3498 // 5 | 0 | CpuRef
3499 // 6 | 1 | CpuRef
3500 // 7 | 1 | CpuAcc
3501
3502 std::vector<uint16_t> cpuRefCounters = {0, 1};
3503 std::vector<uint16_t> cpuAccCounters = {0};
3504
3505 // Register the backend counters for CpuRef and validate GetGlobalId and GetBackendId
3506 uint16_t currentNumGlobalCounterIds = registerBackendCountersCpuRef.RegisterCounter(
3507 0, "testCategory", 0, 0, 1.f, "CpuRefCounter0", "Zeroth CpuRef Counter");
Sadik Armagan1625efc2021-06-10 18:24:34 +01003508 CHECK(currentNumGlobalCounterIds == initialNumGlobalCounterIds + 1);
James Conroy2dcd3fe2020-02-06 18:34:52 +00003509 uint16_t mappedGlobalId = profilingService.GetCounterMappings().GetGlobalId(0, cpuRefId);
Sadik Armagan1625efc2021-06-10 18:24:34 +01003510 CHECK(mappedGlobalId == currentNumGlobalCounterIds);
James Conroy2dcd3fe2020-02-06 18:34:52 +00003511 auto backendMapping = profilingService.GetCounterMappings().GetBackendId(currentNumGlobalCounterIds);
Sadik Armagan1625efc2021-06-10 18:24:34 +01003512 CHECK(backendMapping.first == 0);
3513 CHECK(backendMapping.second == cpuRefId);
James Conroy2dcd3fe2020-02-06 18:34:52 +00003514
3515 currentNumGlobalCounterIds = registerBackendCountersCpuRef.RegisterCounter(
3516 1, "testCategory", 0, 0, 1.f, "CpuRefCounter1", "First CpuRef Counter");
Sadik Armagan1625efc2021-06-10 18:24:34 +01003517 CHECK(currentNumGlobalCounterIds == initialNumGlobalCounterIds + 2);
James Conroy2dcd3fe2020-02-06 18:34:52 +00003518 mappedGlobalId = profilingService.GetCounterMappings().GetGlobalId(1, cpuRefId);
Sadik Armagan1625efc2021-06-10 18:24:34 +01003519 CHECK(mappedGlobalId == currentNumGlobalCounterIds);
James Conroy2dcd3fe2020-02-06 18:34:52 +00003520 backendMapping = profilingService.GetCounterMappings().GetBackendId(currentNumGlobalCounterIds);
Sadik Armagan1625efc2021-06-10 18:24:34 +01003521 CHECK(backendMapping.first == 1);
3522 CHECK(backendMapping.second == cpuRefId);
James Conroy2dcd3fe2020-02-06 18:34:52 +00003523
3524 // Create RegisterBackendCounters for CpuAcc
Sadik Armagan3184c902020-03-18 10:57:30 +00003525 RegisterBackendCounters registerBackendCountersCpuAcc(currentNumGlobalCounterIds, cpuAccId, profilingService);
James Conroy2dcd3fe2020-02-06 18:34:52 +00003526
3527 // Register the backend counter for CpuAcc and validate GetGlobalId and GetBackendId
3528 currentNumGlobalCounterIds = registerBackendCountersCpuAcc.RegisterCounter(
3529 0, "testCategory", 0, 0, 1.f, "CpuAccCounter0", "Zeroth CpuAcc Counter");
Sadik Armagan1625efc2021-06-10 18:24:34 +01003530 CHECK(currentNumGlobalCounterIds == initialNumGlobalCounterIds + 3);
James Conroy2dcd3fe2020-02-06 18:34:52 +00003531 mappedGlobalId = profilingService.GetCounterMappings().GetGlobalId(0, cpuAccId);
Sadik Armagan1625efc2021-06-10 18:24:34 +01003532 CHECK(mappedGlobalId == currentNumGlobalCounterIds);
James Conroy2dcd3fe2020-02-06 18:34:52 +00003533 backendMapping = profilingService.GetCounterMappings().GetBackendId(currentNumGlobalCounterIds);
Sadik Armagan1625efc2021-06-10 18:24:34 +01003534 CHECK(backendMapping.first == 0);
3535 CHECK(backendMapping.second == cpuAccId);
James Conroy2dcd3fe2020-02-06 18:34:52 +00003536
3537 // Create vectors for active counters
3538 const std::vector<uint16_t> activeGlobalCounterIds = {5}; // CpuRef(0) activated
3539 const std::vector<uint16_t> newActiveGlobalCounterIds = {6, 7}; // CpuRef(0) and CpuAcc(1) activated
3540
3541 const uint32_t capturePeriod = 200;
3542 const uint32_t newCapturePeriod = 100;
3543
3544 // Set capture period and active counters in CaptureData
Finn Williams032bc742020-02-12 11:02:34 +00003545 profilingService.SetCaptureData(capturePeriod, activeGlobalCounterIds, {});
James Conroy2dcd3fe2020-02-06 18:34:52 +00003546
3547 // Get vector of active counters for CpuRef and CpuAcc backends
3548 std::vector<CounterStatus> cpuRefCounterStatus = backendProfilingCpuRef.GetActiveCounters();
3549 std::vector<CounterStatus> cpuAccCounterStatus = backendProfilingCpuAcc.GetActiveCounters();
Sadik Armagan1625efc2021-06-10 18:24:34 +01003550 CHECK_EQ(cpuRefCounterStatus.size(), 1);
3551 CHECK_EQ(cpuAccCounterStatus.size(), 0);
James Conroy2dcd3fe2020-02-06 18:34:52 +00003552
3553 // Check active CpuRef counter
Sadik Armagan1625efc2021-06-10 18:24:34 +01003554 CHECK_EQ(cpuRefCounterStatus[0].m_GlobalCounterId, activeGlobalCounterIds[0]);
3555 CHECK_EQ(cpuRefCounterStatus[0].m_BackendCounterId, cpuRefCounters[0]);
3556 CHECK_EQ(cpuRefCounterStatus[0].m_SamplingRateInMicroseconds, capturePeriod);
3557 CHECK_EQ(cpuRefCounterStatus[0].m_Enabled, true);
James Conroy2dcd3fe2020-02-06 18:34:52 +00003558
3559 // Check inactive CpuRef counter
3560 CounterStatus inactiveCpuRefCounter = backendProfilingCpuRef.GetCounterStatus(cpuRefCounters[1]);
Sadik Armagan1625efc2021-06-10 18:24:34 +01003561 CHECK_EQ(inactiveCpuRefCounter.m_GlobalCounterId, 6);
3562 CHECK_EQ(inactiveCpuRefCounter.m_BackendCounterId, cpuRefCounters[1]);
3563 CHECK_EQ(inactiveCpuRefCounter.m_SamplingRateInMicroseconds, 0);
3564 CHECK_EQ(inactiveCpuRefCounter.m_Enabled, false);
James Conroy2dcd3fe2020-02-06 18:34:52 +00003565
3566 // Check inactive CpuAcc counter
3567 CounterStatus inactiveCpuAccCounter = backendProfilingCpuAcc.GetCounterStatus(cpuAccCounters[0]);
Sadik Armagan1625efc2021-06-10 18:24:34 +01003568 CHECK_EQ(inactiveCpuAccCounter.m_GlobalCounterId, 7);
3569 CHECK_EQ(inactiveCpuAccCounter.m_BackendCounterId, cpuAccCounters[0]);
3570 CHECK_EQ(inactiveCpuAccCounter.m_SamplingRateInMicroseconds, 0);
3571 CHECK_EQ(inactiveCpuAccCounter.m_Enabled, false);
James Conroy2dcd3fe2020-02-06 18:34:52 +00003572
3573 // Set new capture period and new active counters in CaptureData
Finn Williams032bc742020-02-12 11:02:34 +00003574 profilingService.SetCaptureData(newCapturePeriod, newActiveGlobalCounterIds, {});
James Conroy2dcd3fe2020-02-06 18:34:52 +00003575
3576 // Get vector of active counters for CpuRef and CpuAcc backends
3577 cpuRefCounterStatus = backendProfilingCpuRef.GetActiveCounters();
3578 cpuAccCounterStatus = backendProfilingCpuAcc.GetActiveCounters();
Sadik Armagan1625efc2021-06-10 18:24:34 +01003579 CHECK_EQ(cpuRefCounterStatus.size(), 1);
3580 CHECK_EQ(cpuAccCounterStatus.size(), 1);
James Conroy2dcd3fe2020-02-06 18:34:52 +00003581
3582 // Check active CpuRef counter
Sadik Armagan1625efc2021-06-10 18:24:34 +01003583 CHECK_EQ(cpuRefCounterStatus[0].m_GlobalCounterId, newActiveGlobalCounterIds[0]);
3584 CHECK_EQ(cpuRefCounterStatus[0].m_BackendCounterId, cpuRefCounters[1]);
3585 CHECK_EQ(cpuRefCounterStatus[0].m_SamplingRateInMicroseconds, newCapturePeriod);
3586 CHECK_EQ(cpuRefCounterStatus[0].m_Enabled, true);
James Conroy2dcd3fe2020-02-06 18:34:52 +00003587
3588 // Check active CpuAcc counter
Sadik Armagan1625efc2021-06-10 18:24:34 +01003589 CHECK_EQ(cpuAccCounterStatus[0].m_GlobalCounterId, newActiveGlobalCounterIds[1]);
3590 CHECK_EQ(cpuAccCounterStatus[0].m_BackendCounterId, cpuAccCounters[0]);
3591 CHECK_EQ(cpuAccCounterStatus[0].m_SamplingRateInMicroseconds, newCapturePeriod);
3592 CHECK_EQ(cpuAccCounterStatus[0].m_Enabled, true);
James Conroy2dcd3fe2020-02-06 18:34:52 +00003593
3594 // Check inactive CpuRef counter
3595 inactiveCpuRefCounter = backendProfilingCpuRef.GetCounterStatus(cpuRefCounters[0]);
Sadik Armagan1625efc2021-06-10 18:24:34 +01003596 CHECK_EQ(inactiveCpuRefCounter.m_GlobalCounterId, 5);
3597 CHECK_EQ(inactiveCpuRefCounter.m_BackendCounterId, cpuRefCounters[0]);
3598 CHECK_EQ(inactiveCpuRefCounter.m_SamplingRateInMicroseconds, 0);
3599 CHECK_EQ(inactiveCpuRefCounter.m_Enabled, false);
James Conroy2dcd3fe2020-02-06 18:34:52 +00003600
3601 // Reset the profiling service to stop any running thread
Jim Flynn4c9ed1d2022-01-23 23:57:20 +00003602 options.m_EnableProfiling = false;
3603 profilingService.ResetExternalProfilingOptions(options, true);
James Conroy2dcd3fe2020-02-06 18:34:52 +00003604}
3605
Sadik Armagan1625efc2021-06-10 18:24:34 +01003606TEST_CASE("CheckRegisterCounters")
Sadik Armagancab588a2020-02-17 11:33:31 +00003607{
Jim Flynn4c9ed1d2022-01-23 23:57:20 +00003608 ProfilingOptions options;
3609 options.m_EnableProfiling = true;
Sadik Armagancab588a2020-02-17 11:33:31 +00003610 MockBufferManager mockBuffer(1024);
Sadik Armagan3184c902020-03-18 10:57:30 +00003611
Sadik Armagancab588a2020-02-17 11:33:31 +00003612 CaptureData captureData;
Jim Flynn4c9ed1d2022-01-23 23:57:20 +00003613 MockProfilingService mockProfilingService(mockBuffer, options.m_EnableProfiling, captureData);
Sadik Armagancab588a2020-02-17 11:33:31 +00003614 armnn::BackendId cpuRefId(armnn::Compute::CpuRef);
3615
3616 mockProfilingService.RegisterMapping(6, 0, cpuRefId);
3617 mockProfilingService.RegisterMapping(7, 1, cpuRefId);
3618 mockProfilingService.RegisterMapping(8, 2, cpuRefId);
3619
3620 armnn::profiling::BackendProfiling backendProfiling(options,
3621 mockProfilingService,
3622 cpuRefId);
3623
3624 armnn::profiling::Timestamp timestamp;
3625 timestamp.timestamp = 1000998;
3626 timestamp.counterValues.emplace_back(0, 700);
3627 timestamp.counterValues.emplace_back(2, 93);
3628 std::vector<armnn::profiling::Timestamp> timestamps;
3629 timestamps.push_back(timestamp);
3630 backendProfiling.ReportCounters(timestamps);
3631
3632 auto readBuffer = mockBuffer.GetReadableBuffer();
3633
3634 uint32_t headerWord0 = ReadUint32(readBuffer, 0);
3635 uint32_t headerWord1 = ReadUint32(readBuffer, 4);
3636 uint64_t readTimestamp = ReadUint64(readBuffer, 8);
3637
Sadik Armagan1625efc2021-06-10 18:24:34 +01003638 CHECK(((headerWord0 >> 26) & 0x0000003F) == 3); // packet family
3639 CHECK(((headerWord0 >> 19) & 0x0000007F) == 0); // packet class
3640 CHECK(((headerWord0 >> 16) & 0x00000007) == 0); // packet type
3641 CHECK(headerWord1 == 20); // data length
3642 CHECK(1000998 == readTimestamp); // capture period
Sadik Armagancab588a2020-02-17 11:33:31 +00003643
3644 uint32_t offset = 16;
3645 // Check Counter Index
3646 uint16_t readIndex = ReadUint16(readBuffer, offset);
Sadik Armagan1625efc2021-06-10 18:24:34 +01003647 CHECK(6 == readIndex);
Sadik Armagancab588a2020-02-17 11:33:31 +00003648
3649 // Check Counter Value
3650 offset += 2;
3651 uint32_t readValue = ReadUint32(readBuffer, offset);
Sadik Armagan1625efc2021-06-10 18:24:34 +01003652 CHECK(700 == readValue);
Sadik Armagancab588a2020-02-17 11:33:31 +00003653
3654 // Check Counter Index
3655 offset += 4;
3656 readIndex = ReadUint16(readBuffer, offset);
Sadik Armagan1625efc2021-06-10 18:24:34 +01003657 CHECK(8 == readIndex);
Sadik Armagancab588a2020-02-17 11:33:31 +00003658
3659 // Check Counter Value
3660 offset += 2;
3661 readValue = ReadUint32(readBuffer, offset);
Sadik Armagan1625efc2021-06-10 18:24:34 +01003662 CHECK(93 == readValue);
Sadik Armagancab588a2020-02-17 11:33:31 +00003663}
3664
Sadik Armagan1625efc2021-06-10 18:24:34 +01003665TEST_CASE("CheckFileFormat") {
Isabella Gottardia0687ee2020-03-11 18:04:20 +00003666 // Locally reduce log level to "Warning", as this test needs to parse a warning message from the standard output
3667 LogLevelSwapper logLevelSwapper(armnn::LogSeverity::Warning);
3668
3669 // Create profiling options.
Jim Flynn4c9ed1d2022-01-23 23:57:20 +00003670 ProfilingOptions options;
Isabella Gottardia0687ee2020-03-11 18:04:20 +00003671 options.m_EnableProfiling = true;
3672 // Check the default value set to binary
Sadik Armagan1625efc2021-06-10 18:24:34 +01003673 CHECK(options.m_FileFormat == "binary");
Isabella Gottardia0687ee2020-03-11 18:04:20 +00003674
3675 // Change file format to an unsupported value
3676 options.m_FileFormat = "json";
3677 // Enable the profiling service
3678 armnn::profiling::ProfilingService profilingService;
3679 profilingService.ResetExternalProfilingOptions(options, true);
3680 // Start the command handler and the send thread
3681 profilingService.Update();
Sadik Armagan1625efc2021-06-10 18:24:34 +01003682 CHECK(profilingService.GetCurrentState()==ProfilingState::NotConnected);
Isabella Gottardia0687ee2020-03-11 18:04:20 +00003683
3684 // Redirect the output to a local stream so that we can parse the warning message
3685 std::stringstream ss;
3686 StreamRedirector streamRedirector(std::cout, ss.rdbuf());
3687
3688 // When Update is called and the current state is ProfilingState::NotConnected
3689 // an exception will be raised from GetProfilingConnection and displayed as warning in the output local stream
3690 profilingService.Update();
3691
3692 streamRedirector.CancelRedirect();
3693
3694 // Check that the expected error has occurred and logged to the standard output
David Monahana8837bf2020-04-16 10:01:56 +01003695 if (ss.str().find("Unsupported profiling file format, only binary is supported") == std::string::npos)
Isabella Gottardia0687ee2020-03-11 18:04:20 +00003696 {
3697 std::cout << ss.str();
Sadik Armagan1625efc2021-06-10 18:24:34 +01003698 FAIL("Expected string not found.");
Isabella Gottardia0687ee2020-03-11 18:04:20 +00003699 }
3700}
3701
Sadik Armagan1625efc2021-06-10 18:24:34 +01003702}