blob: e0629b391367cbabdc3feb490c139fd420cbc537 [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>
21#include <ProfilingStateMachine.hpp>
Matteo Martincigh6db5f202019-09-05 12:02:04 +010022#include <ProfilingUtils.hpp>
James Conroy2dcd3fe2020-02-06 18:34:52 +000023#include <RegisterBackendCounters.hpp>
Narumol Prangnawarat48033692019-09-20 12:04:55 +010024#include <RequestCounterDirectoryCommandHandler.hpp>
Teresa Charlin9bab4962019-09-06 12:28:35 +010025#include <Runtime.hpp>
Matteo Martincigh6db5f202019-09-05 12:02:04 +010026#include <SocketProfilingConnection.hpp>
Matteo Martincighcdfb9412019-11-08 11:23:06 +000027#include <SendCounterPacket.hpp>
Sadik Armagan3896b472020-02-10 12:24:15 +000028#include <SendThread.hpp>
Matteo Martincighcdfb9412019-11-08 11:23:06 +000029#include <SendTimelinePacket.hpp>
Keith Davis02356de2019-08-26 18:28:17 +010030
Matteo Martincigh6db5f202019-09-05 12:02:04 +010031#include <armnn/Conversion.hpp>
Colm Donelan02705242019-11-14 14:19:07 +000032#include <armnn/Types.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
Nikhil Rajbc626052019-08-15 15:49:45 +010045#include <cstdint>
46#include <cstring>
Keith Davis3201eea2019-10-24 17:30:41 +010047#include <iostream>
Aron Virginas-Tare898db92019-08-22 12:56:34 +010048#include <limits>
Francis Murtagh11f99b42019-08-16 11:28:52 +010049#include <map>
Aron Virginas-Tare898db92019-08-22 12:56:34 +010050#include <random>
James Conroy2dcd3fe2020-02-06 18:34:52 +000051
Francis Murtagh1f7db452019-08-14 09:49:34 +010052
Aron Virginas-Tare898db92019-08-22 12:56:34 +010053using namespace armnn::profiling;
Finn Williams09ad6f92019-12-19 17:05:18 +000054using PacketType = MockProfilingConnection::PacketType;
Aron Virginas-Tare898db92019-08-22 12:56:34 +010055
Sadik Armagan1625efc2021-06-10 18:24:34 +010056TEST_SUITE("ExternalProfiling")
57{
58TEST_CASE("CheckCommandHandlerKeyComparisons")
Francis Murtagh1f7db452019-08-14 09:49:34 +010059{
Jim Flynnbbfe6032020-07-20 16:57:44 +010060 arm::pipe::CommandHandlerKey testKey1_0(1, 1, 1);
61 arm::pipe::CommandHandlerKey testKey1_1(1, 1, 1);
62 arm::pipe::CommandHandlerKey testKey1_2(1, 2, 1);
Jim Flynn397043f2019-10-17 17:37:10 +010063
Jim Flynnbbfe6032020-07-20 16:57:44 +010064 arm::pipe::CommandHandlerKey testKey0(0, 1, 1);
65 arm::pipe::CommandHandlerKey testKey1(0, 1, 1);
66 arm::pipe::CommandHandlerKey testKey2(0, 1, 1);
67 arm::pipe::CommandHandlerKey testKey3(0, 0, 0);
68 arm::pipe::CommandHandlerKey testKey4(0, 2, 2);
69 arm::pipe::CommandHandlerKey testKey5(0, 0, 2);
Jim Flynn397043f2019-10-17 17:37:10 +010070
Sadik Armagan1625efc2021-06-10 18:24:34 +010071 CHECK(testKey1_0 > testKey0);
72 CHECK(testKey1_0 == testKey1_1);
73 CHECK(testKey1_0 < testKey1_2);
Francis Murtagh1f7db452019-08-14 09:49:34 +010074
Sadik Armagan1625efc2021-06-10 18:24:34 +010075 CHECK(testKey1 < testKey4);
76 CHECK(testKey1 > testKey3);
77 CHECK(testKey1 <= testKey4);
78 CHECK(testKey1 >= testKey3);
79 CHECK(testKey1 <= testKey2);
80 CHECK(testKey1 >= testKey2);
81 CHECK(testKey1 == testKey2);
82 CHECK(testKey1 == testKey1);
Francis Murtagh1f7db452019-08-14 09:49:34 +010083
Sadik Armagan1625efc2021-06-10 18:24:34 +010084 CHECK(!(testKey1 == testKey5));
85 CHECK(!(testKey1 != testKey1));
86 CHECK(testKey1 != testKey5);
Francis Murtagh1f7db452019-08-14 09:49:34 +010087
Sadik Armagan1625efc2021-06-10 18:24:34 +010088 CHECK((testKey1 == testKey2 && testKey2 == testKey1));
89 CHECK((testKey0 == testKey1 && testKey1 == testKey2 && testKey0 == testKey2));
Francis Murtagh1f7db452019-08-14 09:49:34 +010090
Sadik Armagan1625efc2021-06-10 18:24:34 +010091 CHECK(testKey1.GetPacketId() == 1);
92 CHECK(testKey1.GetVersion() == 1);
Francis Murtagh1f7db452019-08-14 09:49:34 +010093
Jim Flynnbbfe6032020-07-20 16:57:44 +010094 std::vector<arm::pipe::CommandHandlerKey> vect = {
95 arm::pipe::CommandHandlerKey(0, 0, 1), arm::pipe::CommandHandlerKey(0, 2, 0),
96 arm::pipe::CommandHandlerKey(0, 1, 0), arm::pipe::CommandHandlerKey(0, 2, 1),
97 arm::pipe::CommandHandlerKey(0, 1, 1), arm::pipe::CommandHandlerKey(0, 0, 1),
98 arm::pipe::CommandHandlerKey(0, 2, 0), arm::pipe::CommandHandlerKey(0, 0, 0) };
Francis Murtagh1f7db452019-08-14 09:49:34 +010099
100 std::sort(vect.begin(), vect.end());
101
Jim Flynnbbfe6032020-07-20 16:57:44 +0100102 std::vector<arm::pipe::CommandHandlerKey> expectedVect = {
103 arm::pipe::CommandHandlerKey(0, 0, 0), arm::pipe::CommandHandlerKey(0, 0, 1),
104 arm::pipe::CommandHandlerKey(0, 0, 1), arm::pipe::CommandHandlerKey(0, 1, 0),
105 arm::pipe::CommandHandlerKey(0, 1, 1), arm::pipe::CommandHandlerKey(0, 2, 0),
106 arm::pipe::CommandHandlerKey(0, 2, 0), arm::pipe::CommandHandlerKey(0, 2, 1) };
Francis Murtagh1f7db452019-08-14 09:49:34 +0100107
Sadik Armagan1625efc2021-06-10 18:24:34 +0100108 CHECK(vect == expectedVect);
Francis Murtagh1f7db452019-08-14 09:49:34 +0100109}
110
Sadik Armagan1625efc2021-06-10 18:24:34 +0100111TEST_CASE("CheckPacketKeyComparisons")
Jim Flynned25e0e2019-10-18 13:21:43 +0100112{
Jim Flynnbbfe6032020-07-20 16:57:44 +0100113 arm::pipe::PacketKey key0(0, 0);
114 arm::pipe::PacketKey key1(0, 0);
115 arm::pipe::PacketKey key2(0, 1);
116 arm::pipe::PacketKey key3(0, 2);
117 arm::pipe::PacketKey key4(1, 0);
118 arm::pipe::PacketKey key5(1, 0);
119 arm::pipe::PacketKey key6(1, 1);
Jim Flynned25e0e2019-10-18 13:21:43 +0100120
Sadik Armagan1625efc2021-06-10 18:24:34 +0100121 CHECK(!(key0 < key1));
122 CHECK(!(key0 > key1));
123 CHECK(key0 <= key1);
124 CHECK(key0 >= key1);
125 CHECK(key0 == key1);
126 CHECK(key0 < key2);
127 CHECK(key2 < key3);
128 CHECK(key3 > key0);
129 CHECK(key4 == key5);
130 CHECK(key4 > key0);
131 CHECK(key5 < key6);
132 CHECK(key5 <= key6);
133 CHECK(key5 != key6);
Jim Flynned25e0e2019-10-18 13:21:43 +0100134}
135
Sadik Armagan1625efc2021-06-10 18:24:34 +0100136TEST_CASE("CheckCommandHandler")
FinnWilliamsArm4833cea2019-09-17 16:53:53 +0100137{
Jim Flynnbbfe6032020-07-20 16:57:44 +0100138 arm::pipe::PacketVersionResolver packetVersionResolver;
Matteo Martincigh8a837172019-10-04 17:01:07 +0100139 ProfilingStateMachine profilingStateMachine;
FinnWilliamsArm4833cea2019-09-17 16:53:53 +0100140
Matteo Martincigh8a837172019-10-04 17:01:07 +0100141 TestProfilingConnectionBase testProfilingConnectionBase;
142 TestProfilingConnectionTimeoutError testProfilingConnectionTimeOutError;
143 TestProfilingConnectionArmnnError testProfilingConnectionArmnnError;
Keith Davis3201eea2019-10-24 17:30:41 +0100144 CounterDirectory counterDirectory;
145 MockBufferManager mockBuffer(1024);
Sadik Armagan3896b472020-02-10 12:24:15 +0000146 SendCounterPacket sendCounterPacket(mockBuffer);
147 SendThread sendThread(profilingStateMachine, mockBuffer, sendCounterPacket);
Matteo Martincighcdfb9412019-11-08 11:23:06 +0000148 SendTimelinePacket sendTimelinePacket(mockBuffer);
Jim Flynn6398a982020-05-27 17:05:21 +0100149 MockProfilingServiceStatus mockProfilingServiceStatus;
Matteo Martincighcdfb9412019-11-08 11:23:06 +0000150
Keith Davis3201eea2019-10-24 17:30:41 +0100151 ConnectionAcknowledgedCommandHandler connectionAcknowledgedCommandHandler(0, 1, 4194304, counterDirectory,
Matteo Martincighcdfb9412019-11-08 11:23:06 +0000152 sendCounterPacket, sendTimelinePacket,
Jim Flynn6398a982020-05-27 17:05:21 +0100153 profilingStateMachine,
154 mockProfilingServiceStatus);
Jim Flynnbbfe6032020-07-20 16:57:44 +0100155 arm::pipe::CommandHandlerRegistry commandHandlerRegistry;
FinnWilliamsArm4833cea2019-09-17 16:53:53 +0100156
Matteo Martincighc2728f92019-10-07 12:35:21 +0100157 commandHandlerRegistry.RegisterFunctor(&connectionAcknowledgedCommandHandler);
FinnWilliamsArm4833cea2019-09-17 16:53:53 +0100158
Matteo Martincigh8a837172019-10-04 17:01:07 +0100159 profilingStateMachine.TransitionToState(ProfilingState::NotConnected);
160 profilingStateMachine.TransitionToState(ProfilingState::WaitingForAck);
FinnWilliamsArm4833cea2019-09-17 16:53:53 +0100161
Keith Davis3201eea2019-10-24 17:30:41 +0100162 CommandHandler commandHandler0(1, true, commandHandlerRegistry, packetVersionResolver);
FinnWilliamsArm4833cea2019-09-17 16:53:53 +0100163
Colm Donelan2ba48d22019-11-29 09:10:59 +0000164 // This should start the command handler thread return the connection ack and put the profiling
165 // service into active state.
Matteo Martincigh8a837172019-10-04 17:01:07 +0100166 commandHandler0.Start(testProfilingConnectionBase);
Colm Donelan2ba48d22019-11-29 09:10:59 +0000167 // Try to start the send thread many times, it must only start once
Matteo Martincigh8a837172019-10-04 17:01:07 +0100168 commandHandler0.Start(testProfilingConnectionBase);
FinnWilliamsArm4833cea2019-09-17 16:53:53 +0100169
Colm Donelan2ba48d22019-11-29 09:10:59 +0000170 // This could take up to 20mSec but we'll check often.
171 for (int i = 0; i < 10; i++)
Matteo Martincigh8a837172019-10-04 17:01:07 +0100172 {
173 if (profilingStateMachine.GetCurrentState() == ProfilingState::Active)
FinnWilliamsArm4833cea2019-09-17 16:53:53 +0100174 {
Matteo Martincigh8a837172019-10-04 17:01:07 +0100175 break;
FinnWilliamsArm4833cea2019-09-17 16:53:53 +0100176 }
Colm Donelan2ba48d22019-11-29 09:10:59 +0000177 std::this_thread::sleep_for(std::chrono::milliseconds(2));
Matteo Martincigh8a837172019-10-04 17:01:07 +0100178 }
FinnWilliamsArm4833cea2019-09-17 16:53:53 +0100179
Sadik Armagan1625efc2021-06-10 18:24:34 +0100180 CHECK(profilingStateMachine.GetCurrentState() == ProfilingState::Active);
FinnWilliamsArm4833cea2019-09-17 16:53:53 +0100181
Colm Donelan2ba48d22019-11-29 09:10:59 +0000182 // Close the thread again.
183 commandHandler0.Stop();
184
185 profilingStateMachine.TransitionToState(ProfilingState::NotConnected);
186 profilingStateMachine.TransitionToState(ProfilingState::WaitingForAck);
187
188 // In this test we'll simulate a timeout without a connection ack packet being received.
189 // Stop after timeout is set so we expect the command handler to stop almost immediately.
190 CommandHandler commandHandler1(1, true, commandHandlerRegistry, packetVersionResolver);
191
192 commandHandler1.Start(testProfilingConnectionTimeOutError);
193 // Wait until we know a timeout exception has been sent at least once.
194 for (int i = 0; i < 10; i++)
195 {
196 if (testProfilingConnectionTimeOutError.ReadCalledCount())
197 {
198 break;
199 }
200 std::this_thread::sleep_for(std::chrono::milliseconds(2));
201 }
Colm Donelan2ba48d22019-11-29 09:10:59 +0000202
203 // The command handler loop should have stopped after the timeout.
Finn Williams09ad6f92019-12-19 17:05:18 +0000204 // wait for the timeout exception to be processed and the loop to break.
205 uint32_t timeout = 50;
206 uint32_t timeSlept = 0;
207 while (commandHandler1.IsRunning())
208 {
209 if (timeSlept >= timeout)
210 {
Sadik Armagan1625efc2021-06-10 18:24:34 +0100211 FAIL("Timeout: The command handler loop did not stop after the timeout");
Finn Williams09ad6f92019-12-19 17:05:18 +0000212 }
213 std::this_thread::sleep_for(std::chrono::milliseconds(1));
214 timeSlept ++;
215 }
Colm Donelan2ba48d22019-11-29 09:10:59 +0000216
217 commandHandler1.Stop();
218 // The state machine should never have received the ack so will still be in WaitingForAck.
Sadik Armagan1625efc2021-06-10 18:24:34 +0100219 CHECK(profilingStateMachine.GetCurrentState() == ProfilingState::WaitingForAck);
Colm Donelan2ba48d22019-11-29 09:10:59 +0000220
Finn Williams09ad6f92019-12-19 17:05:18 +0000221 // Now try sending a bad connection acknowledged packet
222 TestProfilingConnectionBadAckPacket testProfilingConnectionBadAckPacket;
223 commandHandler1.Start(testProfilingConnectionBadAckPacket);
224 commandHandler1.Stop();
225 // This should also not change the state machine
Sadik Armagan1625efc2021-06-10 18:24:34 +0100226 CHECK(profilingStateMachine.GetCurrentState() == ProfilingState::WaitingForAck);
Finn Williams09ad6f92019-12-19 17:05:18 +0000227
Colm Donelan2ba48d22019-11-29 09:10:59 +0000228 // Disable stop after timeout and now commandHandler1 should persist after a timeout
229 commandHandler1.SetStopAfterTimeout(false);
230 // Restart the thread.
231 commandHandler1.Start(testProfilingConnectionTimeOutError);
232
233 // Wait for at the three timeouts and the ack to be sent.
234 for (int i = 0; i < 10; i++)
235 {
236 if (testProfilingConnectionTimeOutError.ReadCalledCount() > 3)
237 {
238 break;
239 }
240 std::this_thread::sleep_for(std::chrono::milliseconds(2));
241 }
242 commandHandler1.Stop();
243
244 // Even after the 3 exceptions the ack packet should have transitioned the command handler to active.
Sadik Armagan1625efc2021-06-10 18:24:34 +0100245 CHECK(profilingStateMachine.GetCurrentState() == ProfilingState::Active);
Colm Donelan2ba48d22019-11-29 09:10:59 +0000246
247 // A command handler that gets exceptions other than timeouts should keep going.
248 CommandHandler commandHandler2(1, false, commandHandlerRegistry, packetVersionResolver);
FinnWilliamsArm4833cea2019-09-17 16:53:53 +0100249
Matteo Martincigh8a837172019-10-04 17:01:07 +0100250 commandHandler2.Start(testProfilingConnectionArmnnError);
251
Colm Donelan2ba48d22019-11-29 09:10:59 +0000252 // Wait for two exceptions to be thrown.
253 for (int i = 0; i < 10; i++)
254 {
255 if (testProfilingConnectionTimeOutError.ReadCalledCount() >= 2)
256 {
257 break;
258 }
259 std::this_thread::sleep_for(std::chrono::milliseconds(2));
260 }
FinnWilliamsArm4833cea2019-09-17 16:53:53 +0100261
Sadik Armagan1625efc2021-06-10 18:24:34 +0100262 CHECK(commandHandler2.IsRunning());
Matteo Martincigh8a837172019-10-04 17:01:07 +0100263 commandHandler2.Stop();
FinnWilliamsArm4833cea2019-09-17 16:53:53 +0100264}
265
Sadik Armagan1625efc2021-06-10 18:24:34 +0100266TEST_CASE("CheckEncodeVersion")
Nikhil Rajd88e47c2019-08-19 10:04:23 +0100267{
Jim Flynnbbfe6032020-07-20 16:57:44 +0100268 arm::pipe::Version version1(12);
Nikhil Rajd88e47c2019-08-19 10:04:23 +0100269
Sadik Armagan1625efc2021-06-10 18:24:34 +0100270 CHECK(version1.GetMajor() == 0);
271 CHECK(version1.GetMinor() == 0);
272 CHECK(version1.GetPatch() == 12);
Nikhil Rajd88e47c2019-08-19 10:04:23 +0100273
Jim Flynnbbfe6032020-07-20 16:57:44 +0100274 arm::pipe::Version version2(4108);
Nikhil Rajd88e47c2019-08-19 10:04:23 +0100275
Sadik Armagan1625efc2021-06-10 18:24:34 +0100276 CHECK(version2.GetMajor() == 0);
277 CHECK(version2.GetMinor() == 1);
278 CHECK(version2.GetPatch() == 12);
Nikhil Rajd88e47c2019-08-19 10:04:23 +0100279
Jim Flynnbbfe6032020-07-20 16:57:44 +0100280 arm::pipe::Version version3(4198412);
Nikhil Rajd88e47c2019-08-19 10:04:23 +0100281
Sadik Armagan1625efc2021-06-10 18:24:34 +0100282 CHECK(version3.GetMajor() == 1);
283 CHECK(version3.GetMinor() == 1);
284 CHECK(version3.GetPatch() == 12);
Nikhil Rajd88e47c2019-08-19 10:04:23 +0100285
Jim Flynnbbfe6032020-07-20 16:57:44 +0100286 arm::pipe::Version version4(0);
Nikhil Rajd88e47c2019-08-19 10:04:23 +0100287
Sadik Armagan1625efc2021-06-10 18:24:34 +0100288 CHECK(version4.GetMajor() == 0);
289 CHECK(version4.GetMinor() == 0);
290 CHECK(version4.GetPatch() == 0);
Nikhil Rajd88e47c2019-08-19 10:04:23 +0100291
Jim Flynnbbfe6032020-07-20 16:57:44 +0100292 arm::pipe::Version version5(1, 0, 0);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100293 CHECK(version5.GetEncodedValue() == 4194304);
Nikhil Rajd88e47c2019-08-19 10:04:23 +0100294}
295
Sadik Armagan1625efc2021-06-10 18:24:34 +0100296TEST_CASE("CheckPacketClass")
Nikhil Rajbc626052019-08-15 15:49:45 +0100297{
Keith Davis3201eea2019-10-24 17:30:41 +0100298 uint32_t length = 4;
Matteo Martincigh67ef2a52019-10-10 13:29:02 +0100299 std::unique_ptr<unsigned char[]> packetData0 = std::make_unique<unsigned char[]>(length);
300 std::unique_ptr<unsigned char[]> packetData1 = std::make_unique<unsigned char[]>(0);
301 std::unique_ptr<unsigned char[]> nullPacketData;
Nikhil Rajbc626052019-08-15 15:49:45 +0100302
Jim Flynnbbfe6032020-07-20 16:57:44 +0100303 arm::pipe::Packet packetTest0(472580096, length, packetData0);
Nikhil Rajbc626052019-08-15 15:49:45 +0100304
Sadik Armagan1625efc2021-06-10 18:24:34 +0100305 CHECK(packetTest0.GetHeader() == 472580096);
306 CHECK(packetTest0.GetPacketFamily() == 7);
307 CHECK(packetTest0.GetPacketId() == 43);
308 CHECK(packetTest0.GetLength() == length);
309 CHECK(packetTest0.GetPacketType() == 3);
310 CHECK(packetTest0.GetPacketClass() == 5);
Nikhil Rajbc626052019-08-15 15:49:45 +0100311
Sadik Armagan1625efc2021-06-10 18:24:34 +0100312 CHECK_THROWS_AS(arm::pipe::Packet packetTest1(472580096, 0, packetData1), arm::pipe::InvalidArgumentException);
313 CHECK_NOTHROW(arm::pipe::Packet packetTest2(472580096, 0, nullPacketData));
Nikhil Rajbc626052019-08-15 15:49:45 +0100314
Jim Flynnbbfe6032020-07-20 16:57:44 +0100315 arm::pipe::Packet packetTest3(472580096, 0, nullPacketData);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100316 CHECK(packetTest3.GetLength() == 0);
317 CHECK(packetTest3.GetData() == nullptr);
FinnWilliamsArma0c78712019-09-16 12:06:47 +0100318
Matteo Martincigh67ef2a52019-10-10 13:29:02 +0100319 const unsigned char* packetTest0Data = packetTest0.GetData();
Jim Flynnbbfe6032020-07-20 16:57:44 +0100320 arm::pipe::Packet packetTest4(std::move(packetTest0));
FinnWilliamsArma0c78712019-09-16 12:06:47 +0100321
Sadik Armagan1625efc2021-06-10 18:24:34 +0100322 CHECK(packetTest0.GetData() == nullptr);
323 CHECK(packetTest4.GetData() == packetTest0Data);
FinnWilliamsArma0c78712019-09-16 12:06:47 +0100324
Sadik Armagan1625efc2021-06-10 18:24:34 +0100325 CHECK(packetTest4.GetHeader() == 472580096);
326 CHECK(packetTest4.GetPacketFamily() == 7);
327 CHECK(packetTest4.GetPacketId() == 43);
328 CHECK(packetTest4.GetLength() == length);
329 CHECK(packetTest4.GetPacketType() == 3);
330 CHECK(packetTest4.GetPacketClass() == 5);
Nikhil Rajbc626052019-08-15 15:49:45 +0100331}
332
Sadik Armagan1625efc2021-06-10 18:24:34 +0100333TEST_CASE("CheckCommandHandlerFunctor")
Francis Murtagh11f99b42019-08-16 11:28:52 +0100334{
Francis Murtagh11f99b42019-08-16 11:28:52 +0100335 // Hard code the version as it will be the same during a single profiling session
336 uint32_t version = 1;
337
Jim Flynn397043f2019-10-17 17:37:10 +0100338 TestFunctorA testFunctorA(7, 461, version);
339 TestFunctorB testFunctorB(8, 963, version);
340 TestFunctorC testFunctorC(5, 983, version);
Francis Murtagh11f99b42019-08-16 11:28:52 +0100341
Jim Flynnbbfe6032020-07-20 16:57:44 +0100342 arm::pipe::CommandHandlerKey keyA(
343 testFunctorA.GetFamilyId(), testFunctorA.GetPacketId(), testFunctorA.GetVersion());
344 arm::pipe::CommandHandlerKey keyB(
345 testFunctorB.GetFamilyId(), testFunctorB.GetPacketId(), testFunctorB.GetVersion());
346 arm::pipe::CommandHandlerKey keyC(
347 testFunctorC.GetFamilyId(), testFunctorC.GetPacketId(), testFunctorC.GetVersion());
Francis Murtagh11f99b42019-08-16 11:28:52 +0100348
349 // Create the unwrapped map to simulate the Command Handler Registry
Jim Flynnbbfe6032020-07-20 16:57:44 +0100350 std::map<arm::pipe::CommandHandlerKey, arm::pipe::CommandHandlerFunctor*> registry;
Francis Murtagh11f99b42019-08-16 11:28:52 +0100351
352 registry.insert(std::make_pair(keyB, &testFunctorB));
353 registry.insert(std::make_pair(keyA, &testFunctorA));
354 registry.insert(std::make_pair(keyC, &testFunctorC));
355
356 // Check the order of the map is correct
357 auto it = registry.begin();
Sadik Armagan1625efc2021-06-10 18:24:34 +0100358 CHECK(it->first == keyC); // familyId == 5
Francis Murtagh11f99b42019-08-16 11:28:52 +0100359 it++;
Sadik Armagan1625efc2021-06-10 18:24:34 +0100360 CHECK(it->first == keyA); // familyId == 7
Francis Murtagh11f99b42019-08-16 11:28:52 +0100361 it++;
Sadik Armagan1625efc2021-06-10 18:24:34 +0100362 CHECK(it->first == keyB); // familyId == 8
Francis Murtagh11f99b42019-08-16 11:28:52 +0100363
Matteo Martincigh67ef2a52019-10-10 13:29:02 +0100364 std::unique_ptr<unsigned char[]> packetDataA;
365 std::unique_ptr<unsigned char[]> packetDataB;
366 std::unique_ptr<unsigned char[]> packetDataC;
FinnWilliamsArma0c78712019-09-16 12:06:47 +0100367
Jim Flynnbbfe6032020-07-20 16:57:44 +0100368 arm::pipe::Packet packetA(500000000, 0, packetDataA);
369 arm::pipe::Packet packetB(600000000, 0, packetDataB);
370 arm::pipe::Packet packetC(400000000, 0, packetDataC);
Francis Murtagh11f99b42019-08-16 11:28:52 +0100371
372 // Check the correct operator of derived class is called
Jim Flynnbbfe6032020-07-20 16:57:44 +0100373 registry.at(arm::pipe::CommandHandlerKey(
374 packetA.GetPacketFamily(), packetA.GetPacketId(), version))->operator()(packetA);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100375 CHECK(testFunctorA.GetCount() == 1);
376 CHECK(testFunctorB.GetCount() == 0);
377 CHECK(testFunctorC.GetCount() == 0);
Francis Murtagh11f99b42019-08-16 11:28:52 +0100378
Jim Flynnbbfe6032020-07-20 16:57:44 +0100379 registry.at(arm::pipe::CommandHandlerKey(
380 packetB.GetPacketFamily(), packetB.GetPacketId(), version))->operator()(packetB);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100381 CHECK(testFunctorA.GetCount() == 1);
382 CHECK(testFunctorB.GetCount() == 1);
383 CHECK(testFunctorC.GetCount() == 0);
Francis Murtagh11f99b42019-08-16 11:28:52 +0100384
Jim Flynnbbfe6032020-07-20 16:57:44 +0100385 registry.at(arm::pipe::CommandHandlerKey(
386 packetC.GetPacketFamily(), packetC.GetPacketId(), version))->operator()(packetC);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100387 CHECK(testFunctorA.GetCount() == 1);
388 CHECK(testFunctorB.GetCount() == 1);
389 CHECK(testFunctorC.GetCount() == 1);
Francis Murtagh11f99b42019-08-16 11:28:52 +0100390}
391
Sadik Armagan1625efc2021-06-10 18:24:34 +0100392TEST_CASE("CheckCommandHandlerRegistry")
Francis Murtagh94d79152019-08-16 17:45:07 +0100393{
394 // Hard code the version as it will be the same during a single profiling session
395 uint32_t version = 1;
396
Jim Flynn397043f2019-10-17 17:37:10 +0100397 TestFunctorA testFunctorA(7, 461, version);
398 TestFunctorB testFunctorB(8, 963, version);
399 TestFunctorC testFunctorC(5, 983, version);
Francis Murtagh94d79152019-08-16 17:45:07 +0100400
401 // Create the Command Handler Registry
Jim Flynnbbfe6032020-07-20 16:57:44 +0100402 arm::pipe::CommandHandlerRegistry registry;
Francis Murtagh94d79152019-08-16 17:45:07 +0100403
404 // Register multiple different derived classes
Matteo Martincighc2728f92019-10-07 12:35:21 +0100405 registry.RegisterFunctor(&testFunctorA);
406 registry.RegisterFunctor(&testFunctorB);
407 registry.RegisterFunctor(&testFunctorC);
Francis Murtagh94d79152019-08-16 17:45:07 +0100408
Matteo Martincigh67ef2a52019-10-10 13:29:02 +0100409 std::unique_ptr<unsigned char[]> packetDataA;
410 std::unique_ptr<unsigned char[]> packetDataB;
411 std::unique_ptr<unsigned char[]> packetDataC;
FinnWilliamsArma0c78712019-09-16 12:06:47 +0100412
Jim Flynnbbfe6032020-07-20 16:57:44 +0100413 arm::pipe::Packet packetA(500000000, 0, packetDataA);
414 arm::pipe::Packet packetB(600000000, 0, packetDataB);
415 arm::pipe::Packet packetC(400000000, 0, packetDataC);
Francis Murtagh94d79152019-08-16 17:45:07 +0100416
417 // Check the correct operator of derived class is called
Jim Flynn397043f2019-10-17 17:37:10 +0100418 registry.GetFunctor(packetA.GetPacketFamily(), packetA.GetPacketId(), version)->operator()(packetA);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100419 CHECK(testFunctorA.GetCount() == 1);
420 CHECK(testFunctorB.GetCount() == 0);
421 CHECK(testFunctorC.GetCount() == 0);
Francis Murtagh94d79152019-08-16 17:45:07 +0100422
Jim Flynn397043f2019-10-17 17:37:10 +0100423 registry.GetFunctor(packetB.GetPacketFamily(), packetB.GetPacketId(), version)->operator()(packetB);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100424 CHECK(testFunctorA.GetCount() == 1);
425 CHECK(testFunctorB.GetCount() == 1);
426 CHECK(testFunctorC.GetCount() == 0);
Francis Murtagh94d79152019-08-16 17:45:07 +0100427
Jim Flynn397043f2019-10-17 17:37:10 +0100428 registry.GetFunctor(packetC.GetPacketFamily(), packetC.GetPacketId(), version)->operator()(packetC);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100429 CHECK(testFunctorA.GetCount() == 1);
430 CHECK(testFunctorB.GetCount() == 1);
431 CHECK(testFunctorC.GetCount() == 1);
Francis Murtagh94d79152019-08-16 17:45:07 +0100432
433 // Re-register an existing key with a new function
Jim Flynn397043f2019-10-17 17:37:10 +0100434 registry.RegisterFunctor(&testFunctorC, testFunctorA.GetFamilyId(), testFunctorA.GetPacketId(), version);
435 registry.GetFunctor(packetA.GetPacketFamily(), packetA.GetPacketId(), version)->operator()(packetC);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100436 CHECK(testFunctorA.GetCount() == 1);
437 CHECK(testFunctorB.GetCount() == 1);
438 CHECK(testFunctorC.GetCount() == 2);
Francis Murtagh94d79152019-08-16 17:45:07 +0100439
440 // Check that non-existent key returns nullptr for its functor
Sadik Armagan1625efc2021-06-10 18:24:34 +0100441 CHECK_THROWS_AS(registry.GetFunctor(0, 0, 0), arm::pipe::ProfilingException);
Francis Murtagh94d79152019-08-16 17:45:07 +0100442}
443
Sadik Armagan1625efc2021-06-10 18:24:34 +0100444TEST_CASE("CheckPacketVersionResolver")
Aron Virginas-Tare898db92019-08-22 12:56:34 +0100445{
446 // Set up random number generator for generating packetId values
447 std::random_device device;
448 std::mt19937 generator(device());
449 std::uniform_int_distribution<uint32_t> distribution(std::numeric_limits<uint32_t>::min(),
450 std::numeric_limits<uint32_t>::max());
451
452 // NOTE: Expected version is always 1.0.0, regardless of packetId
Jim Flynnbbfe6032020-07-20 16:57:44 +0100453 const arm::pipe::Version expectedVersion(1, 0, 0);
Aron Virginas-Tare898db92019-08-22 12:56:34 +0100454
Jim Flynnbbfe6032020-07-20 16:57:44 +0100455 arm::pipe::PacketVersionResolver packetVersionResolver;
Aron Virginas-Tare898db92019-08-22 12:56:34 +0100456
457 constexpr unsigned int numTests = 10u;
458
459 for (unsigned int i = 0u; i < numTests; ++i)
460 {
Jim Flynned25e0e2019-10-18 13:21:43 +0100461 const uint32_t familyId = distribution(generator);
Aron Virginas-Tare898db92019-08-22 12:56:34 +0100462 const uint32_t packetId = distribution(generator);
Jim Flynnbbfe6032020-07-20 16:57:44 +0100463 arm::pipe::Version resolvedVersion = packetVersionResolver.ResolvePacketVersion(familyId, packetId);
Aron Virginas-Tare898db92019-08-22 12:56:34 +0100464
Sadik Armagan1625efc2021-06-10 18:24:34 +0100465 CHECK(resolvedVersion == expectedVersion);
Aron Virginas-Tare898db92019-08-22 12:56:34 +0100466 }
467}
Matteo Martincighd0613b52019-10-09 16:47:04 +0100468
Nikhil Raj3ecc5102019-09-03 15:55:33 +0100469void ProfilingCurrentStateThreadImpl(ProfilingStateMachine& states)
470{
471 ProfilingState newState = ProfilingState::NotConnected;
472 states.GetCurrentState();
473 states.TransitionToState(newState);
474}
475
Sadik Armagan1625efc2021-06-10 18:24:34 +0100476TEST_CASE("CheckProfilingStateMachine")
Nikhil Raj3ecc5102019-09-03 15:55:33 +0100477{
478 ProfilingStateMachine profilingState1(ProfilingState::Uninitialised);
479 profilingState1.TransitionToState(ProfilingState::Uninitialised);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100480 CHECK(profilingState1.GetCurrentState() == ProfilingState::Uninitialised);
Nikhil Raj3ecc5102019-09-03 15:55:33 +0100481
482 ProfilingStateMachine profilingState2(ProfilingState::Uninitialised);
483 profilingState2.TransitionToState(ProfilingState::NotConnected);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100484 CHECK(profilingState2.GetCurrentState() == ProfilingState::NotConnected);
Nikhil Raj3ecc5102019-09-03 15:55:33 +0100485
486 ProfilingStateMachine profilingState3(ProfilingState::NotConnected);
487 profilingState3.TransitionToState(ProfilingState::NotConnected);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100488 CHECK(profilingState3.GetCurrentState() == ProfilingState::NotConnected);
Nikhil Raj3ecc5102019-09-03 15:55:33 +0100489
490 ProfilingStateMachine profilingState4(ProfilingState::NotConnected);
491 profilingState4.TransitionToState(ProfilingState::WaitingForAck);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100492 CHECK(profilingState4.GetCurrentState() == ProfilingState::WaitingForAck);
Nikhil Raj3ecc5102019-09-03 15:55:33 +0100493
494 ProfilingStateMachine profilingState5(ProfilingState::WaitingForAck);
495 profilingState5.TransitionToState(ProfilingState::WaitingForAck);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100496 CHECK(profilingState5.GetCurrentState() == ProfilingState::WaitingForAck);
Nikhil Raj3ecc5102019-09-03 15:55:33 +0100497
498 ProfilingStateMachine profilingState6(ProfilingState::WaitingForAck);
499 profilingState6.TransitionToState(ProfilingState::Active);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100500 CHECK(profilingState6.GetCurrentState() == ProfilingState::Active);
Nikhil Raj3ecc5102019-09-03 15:55:33 +0100501
502 ProfilingStateMachine profilingState7(ProfilingState::Active);
503 profilingState7.TransitionToState(ProfilingState::NotConnected);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100504 CHECK(profilingState7.GetCurrentState() == ProfilingState::NotConnected);
Nikhil Raj3ecc5102019-09-03 15:55:33 +0100505
506 ProfilingStateMachine profilingState8(ProfilingState::Active);
507 profilingState8.TransitionToState(ProfilingState::Active);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100508 CHECK(profilingState8.GetCurrentState() == ProfilingState::Active);
Nikhil Raj3ecc5102019-09-03 15:55:33 +0100509
510 ProfilingStateMachine profilingState9(ProfilingState::Uninitialised);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100511 CHECK_THROWS_AS(profilingState9.TransitionToState(ProfilingState::WaitingForAck), armnn::Exception);
Nikhil Raj3ecc5102019-09-03 15:55:33 +0100512
513 ProfilingStateMachine profilingState10(ProfilingState::Uninitialised);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100514 CHECK_THROWS_AS(profilingState10.TransitionToState(ProfilingState::Active), armnn::Exception);
Nikhil Raj3ecc5102019-09-03 15:55:33 +0100515
516 ProfilingStateMachine profilingState11(ProfilingState::NotConnected);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100517 CHECK_THROWS_AS(profilingState11.TransitionToState(ProfilingState::Uninitialised), armnn::Exception);
Nikhil Raj3ecc5102019-09-03 15:55:33 +0100518
519 ProfilingStateMachine profilingState12(ProfilingState::NotConnected);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100520 CHECK_THROWS_AS(profilingState12.TransitionToState(ProfilingState::Active), armnn::Exception);
Nikhil Raj3ecc5102019-09-03 15:55:33 +0100521
522 ProfilingStateMachine profilingState13(ProfilingState::WaitingForAck);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100523 CHECK_THROWS_AS(profilingState13.TransitionToState(ProfilingState::Uninitialised), armnn::Exception);
Nikhil Raj3ecc5102019-09-03 15:55:33 +0100524
525 ProfilingStateMachine profilingState14(ProfilingState::WaitingForAck);
Jim Flynn53e46992019-10-14 12:31:10 +0100526 profilingState14.TransitionToState(ProfilingState::NotConnected);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100527 CHECK(profilingState14.GetCurrentState() == ProfilingState::NotConnected);
Nikhil Raj3ecc5102019-09-03 15:55:33 +0100528
529 ProfilingStateMachine profilingState15(ProfilingState::Active);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100530 CHECK_THROWS_AS(profilingState15.TransitionToState(ProfilingState::Uninitialised), armnn::Exception);
Nikhil Raj3ecc5102019-09-03 15:55:33 +0100531
532 ProfilingStateMachine profilingState16(armnn::profiling::ProfilingState::Active);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100533 CHECK_THROWS_AS(profilingState16.TransitionToState(ProfilingState::WaitingForAck), armnn::Exception);
Nikhil Raj3ecc5102019-09-03 15:55:33 +0100534
535 ProfilingStateMachine profilingState17(ProfilingState::Uninitialised);
536
Keith Davis3201eea2019-10-24 17:30:41 +0100537 std::thread thread1(ProfilingCurrentStateThreadImpl, std::ref(profilingState17));
538 std::thread thread2(ProfilingCurrentStateThreadImpl, std::ref(profilingState17));
539 std::thread thread3(ProfilingCurrentStateThreadImpl, std::ref(profilingState17));
540 std::thread thread4(ProfilingCurrentStateThreadImpl, std::ref(profilingState17));
541 std::thread thread5(ProfilingCurrentStateThreadImpl, std::ref(profilingState17));
Nikhil Raj3ecc5102019-09-03 15:55:33 +0100542
543 thread1.join();
544 thread2.join();
545 thread3.join();
546 thread4.join();
547 thread5.join();
548
Sadik Armagan1625efc2021-06-10 18:24:34 +0100549 CHECK((profilingState17.GetCurrentState() == ProfilingState::NotConnected));
Nikhil Raj3ecc5102019-09-03 15:55:33 +0100550}
Aron Virginas-Tare898db92019-08-22 12:56:34 +0100551
Jim Flynn8355ec92019-09-17 12:29:50 +0100552void CaptureDataWriteThreadImpl(Holder& holder, uint32_t capturePeriod, const std::vector<uint16_t>& counterIds)
Francis Murtagh68f78d82019-09-04 16:42:29 +0100553{
Finn Williams032bc742020-02-12 11:02:34 +0000554 holder.SetCaptureData(capturePeriod, counterIds, {});
Francis Murtagh68f78d82019-09-04 16:42:29 +0100555}
556
Francis Murtaghbd707162019-09-09 11:26:44 +0100557void CaptureDataReadThreadImpl(const Holder& holder, CaptureData& captureData)
Francis Murtagh68f78d82019-09-04 16:42:29 +0100558{
559 captureData = holder.GetCaptureData();
560}
561
Sadik Armagan1625efc2021-06-10 18:24:34 +0100562TEST_CASE("CheckCaptureDataHolder")
Francis Murtagh68f78d82019-09-04 16:42:29 +0100563{
Francis Murtaghbd707162019-09-09 11:26:44 +0100564 std::map<uint32_t, std::vector<uint16_t>> periodIdMap;
565 std::vector<uint16_t> counterIds;
Jim Flynn8355ec92019-09-17 12:29:50 +0100566 uint32_t numThreads = 10;
567 for (uint32_t i = 0; i < numThreads; ++i)
Francis Murtaghbd707162019-09-09 11:26:44 +0100568 {
569 counterIds.emplace_back(i);
570 periodIdMap.insert(std::make_pair(i, counterIds));
571 }
Francis Murtagh68f78d82019-09-04 16:42:29 +0100572
Jim Flynn8355ec92019-09-17 12:29:50 +0100573 // Verify the read and write threads set the holder correctly
574 // and retrieve the expected values
Francis Murtagh68f78d82019-09-04 16:42:29 +0100575 Holder holder;
Sadik Armagan1625efc2021-06-10 18:24:34 +0100576 CHECK((holder.GetCaptureData()).GetCapturePeriod() == 0);
577 CHECK(((holder.GetCaptureData()).GetCounterIds()).empty());
Francis Murtagh68f78d82019-09-04 16:42:29 +0100578
579 // Check Holder functions
Francis Murtaghbd707162019-09-09 11:26:44 +0100580 std::thread thread1(CaptureDataWriteThreadImpl, std::ref(holder), 2, std::ref(periodIdMap[2]));
Francis Murtagh68f78d82019-09-04 16:42:29 +0100581 thread1.join();
Sadik Armagan1625efc2021-06-10 18:24:34 +0100582 CHECK((holder.GetCaptureData()).GetCapturePeriod() == 2);
583 CHECK((holder.GetCaptureData()).GetCounterIds() == periodIdMap[2]);
Jim Flynn8355ec92019-09-17 12:29:50 +0100584 // NOTE: now that we have some initial values in the holder we don't have to worry
585 // in the multi-threaded section below about a read thread accessing the holder
586 // before any write thread has gotten to it so we read period = 0, counterIds empty
587 // instead of period = 0, counterIds = {0} as will the case when write thread 0
588 // has executed.
Francis Murtagh68f78d82019-09-04 16:42:29 +0100589
590 CaptureData captureData;
591 std::thread thread2(CaptureDataReadThreadImpl, std::ref(holder), std::ref(captureData));
592 thread2.join();
Sadik Armagan1625efc2021-06-10 18:24:34 +0100593 CHECK(captureData.GetCapturePeriod() == 2);
594 CHECK(captureData.GetCounterIds() == periodIdMap[2]);
Francis Murtagh68f78d82019-09-04 16:42:29 +0100595
Jim Flynn8355ec92019-09-17 12:29:50 +0100596 std::map<uint32_t, CaptureData> captureDataIdMap;
597 for (uint32_t i = 0; i < numThreads; ++i)
598 {
599 CaptureData perThreadCaptureData;
600 captureDataIdMap.insert(std::make_pair(i, perThreadCaptureData));
601 }
602
Francis Murtaghbd707162019-09-09 11:26:44 +0100603 std::vector<std::thread> threadsVect;
Jim Flynn8355ec92019-09-17 12:29:50 +0100604 std::vector<std::thread> readThreadsVect;
605 for (uint32_t i = 0; i < numThreads; ++i)
Francis Murtaghbd707162019-09-09 11:26:44 +0100606 {
Keith Davis3201eea2019-10-24 17:30:41 +0100607 threadsVect.emplace_back(
608 std::thread(CaptureDataWriteThreadImpl, std::ref(holder), i, std::ref(periodIdMap[i])));
Francis Murtagh06965692019-09-05 16:29:01 +0100609
Jim Flynn8355ec92019-09-17 12:29:50 +0100610 // Verify that the CaptureData goes into the thread in a virgin state
Sadik Armagan1625efc2021-06-10 18:24:34 +0100611 CHECK(captureDataIdMap.at(i).GetCapturePeriod() == 0);
612 CHECK(captureDataIdMap.at(i).GetCounterIds().empty());
Keith Davis3201eea2019-10-24 17:30:41 +0100613 readThreadsVect.emplace_back(
614 std::thread(CaptureDataReadThreadImpl, std::ref(holder), std::ref(captureDataIdMap.at(i))));
Francis Murtaghbd707162019-09-09 11:26:44 +0100615 }
616
Jim Flynn8355ec92019-09-17 12:29:50 +0100617 for (uint32_t i = 0; i < numThreads; ++i)
Francis Murtaghbd707162019-09-09 11:26:44 +0100618 {
619 threadsVect[i].join();
Francis Murtaghbd707162019-09-09 11:26:44 +0100620 readThreadsVect[i].join();
621 }
Francis Murtagh68f78d82019-09-04 16:42:29 +0100622
Jim Flynn8355ec92019-09-17 12:29:50 +0100623 // Look at the CaptureData that each read thread has filled
624 // the capture period it read should match the counter ids entry
625 for (uint32_t i = 0; i < numThreads; ++i)
626 {
627 CaptureData perThreadCaptureData = captureDataIdMap.at(i);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100628 CHECK(perThreadCaptureData.GetCounterIds() == periodIdMap.at(perThreadCaptureData.GetCapturePeriod()));
Jim Flynn8355ec92019-09-17 12:29:50 +0100629 }
Matthew Bentham46d1c622019-09-13 12:45:04 +0100630}
Francis Murtagh68f78d82019-09-04 16:42:29 +0100631
Sadik Armagan1625efc2021-06-10 18:24:34 +0100632TEST_CASE("CaptureDataMethods")
Matthew Bentham46d1c622019-09-13 12:45:04 +0100633{
Jim Flynn8355ec92019-09-17 12:29:50 +0100634 // Check CaptureData setter and getter functions
Keith Davis3201eea2019-10-24 17:30:41 +0100635 std::vector<uint16_t> counterIds = { 42, 29, 13 };
Jim Flynn8355ec92019-09-17 12:29:50 +0100636 CaptureData captureData;
Sadik Armagan1625efc2021-06-10 18:24:34 +0100637 CHECK(captureData.GetCapturePeriod() == 0);
638 CHECK((captureData.GetCounterIds()).empty());
Jim Flynn8355ec92019-09-17 12:29:50 +0100639 captureData.SetCapturePeriod(150);
640 captureData.SetCounterIds(counterIds);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100641 CHECK(captureData.GetCapturePeriod() == 150);
642 CHECK(captureData.GetCounterIds() == counterIds);
Francis Murtagh68f78d82019-09-04 16:42:29 +0100643
Jim Flynn8355ec92019-09-17 12:29:50 +0100644 // Check assignment operator
Francis Murtagh68f78d82019-09-04 16:42:29 +0100645 CaptureData secondCaptureData;
Francis Murtagh68f78d82019-09-04 16:42:29 +0100646
Jim Flynn8355ec92019-09-17 12:29:50 +0100647 secondCaptureData = captureData;
Sadik Armagan1625efc2021-06-10 18:24:34 +0100648 CHECK(secondCaptureData.GetCapturePeriod() == 150);
649 CHECK(secondCaptureData.GetCounterIds() == counterIds);
Francis Murtagh68f78d82019-09-04 16:42:29 +0100650
651 // Check copy constructor
Jim Flynn8355ec92019-09-17 12:29:50 +0100652 CaptureData copyConstructedCaptureData(captureData);
Francis Murtagh68f78d82019-09-04 16:42:29 +0100653
Sadik Armagan1625efc2021-06-10 18:24:34 +0100654 CHECK(copyConstructedCaptureData.GetCapturePeriod() == 150);
655 CHECK(copyConstructedCaptureData.GetCounterIds() == counterIds);
Keith Davis02356de2019-08-26 18:28:17 +0100656}
Francis Murtagh68f78d82019-09-04 16:42:29 +0100657
Sadik Armagan1625efc2021-06-10 18:24:34 +0100658TEST_CASE("CheckProfilingServiceDisabled")
Keith Davis02356de2019-08-26 18:28:17 +0100659{
Kevin Mayd92a6e42021-02-04 10:27:41 +0000660 armnn::IRuntime::CreationOptions::ExternalProfilingOptions options;
Sadik Armagan3184c902020-03-18 10:57:30 +0000661 armnn::profiling::ProfilingService profilingService;
Matteo Martincigha84edee2019-10-02 12:50:57 +0100662 profilingService.ResetExternalProfilingOptions(options, true);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100663 CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
Matteo Martincigh54fb9572019-10-02 12:50:57 +0100664 profilingService.Update();
Sadik Armagan1625efc2021-06-10 18:24:34 +0100665 CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
Keith Davis02356de2019-08-26 18:28:17 +0100666}
667
Sadik Armagan1625efc2021-06-10 18:24:34 +0100668TEST_CASE("CheckProfilingServiceCounterDirectory")
FinnWilliamsArmce2d9d12019-09-18 10:28:16 +0100669{
Kevin Mayd92a6e42021-02-04 10:27:41 +0000670 armnn::IRuntime::CreationOptions::ExternalProfilingOptions options;
Sadik Armagan3184c902020-03-18 10:57:30 +0000671 armnn::profiling::ProfilingService profilingService;
Matteo Martincigha84edee2019-10-02 12:50:57 +0100672 profilingService.ResetExternalProfilingOptions(options, true);
FinnWilliamsArmce2d9d12019-09-18 10:28:16 +0100673
Matteo Martincigha84edee2019-10-02 12:50:57 +0100674 const ICounterDirectory& counterDirectory0 = profilingService.GetCounterDirectory();
Sadik Armagan1625efc2021-06-10 18:24:34 +0100675 CHECK(counterDirectory0.GetCounterCount() == 0);
Matteo Martincigh54fb9572019-10-02 12:50:57 +0100676 profilingService.Update();
Sadik Armagan1625efc2021-06-10 18:24:34 +0100677 CHECK(counterDirectory0.GetCounterCount() == 0);
FinnWilliamsArmce2d9d12019-09-18 10:28:16 +0100678
679 options.m_EnableProfiling = true;
Matteo Martincigha84edee2019-10-02 12:50:57 +0100680 profilingService.ResetExternalProfilingOptions(options);
FinnWilliamsArmce2d9d12019-09-18 10:28:16 +0100681
Matteo Martincigha84edee2019-10-02 12:50:57 +0100682 const ICounterDirectory& counterDirectory1 = profilingService.GetCounterDirectory();
Sadik Armagan1625efc2021-06-10 18:24:34 +0100683 CHECK(counterDirectory1.GetCounterCount() == 0);
Matteo Martincigh54fb9572019-10-02 12:50:57 +0100684 profilingService.Update();
Sadik Armagan1625efc2021-06-10 18:24:34 +0100685 CHECK(counterDirectory1.GetCounterCount() != 0);
Colm Donelan2ba48d22019-11-29 09:10:59 +0000686 // Reset the profiling service to stop any running thread
687 options.m_EnableProfiling = false;
688 profilingService.ResetExternalProfilingOptions(options, true);
FinnWilliamsArmce2d9d12019-09-18 10:28:16 +0100689}
690
Sadik Armagan1625efc2021-06-10 18:24:34 +0100691TEST_CASE("CheckProfilingServiceCounterValues")
FinnWilliamsArmf6e534a2019-09-16 15:45:42 +0100692{
Kevin Mayd92a6e42021-02-04 10:27:41 +0000693 armnn::IRuntime::CreationOptions::ExternalProfilingOptions options;
Keith Davis3201eea2019-10-24 17:30:41 +0100694 options.m_EnableProfiling = true;
Sadik Armagan3184c902020-03-18 10:57:30 +0000695 armnn::profiling::ProfilingService profilingService;
Matteo Martincigha84edee2019-10-02 12:50:57 +0100696 profilingService.ResetExternalProfilingOptions(options, true);
697
Matteo Martincigh54fb9572019-10-02 12:50:57 +0100698 profilingService.Update();
Matteo Martincigha84edee2019-10-02 12:50:57 +0100699 const ICounterDirectory& counterDirectory = profilingService.GetCounterDirectory();
Keith Davis3201eea2019-10-24 17:30:41 +0100700 const Counters& counters = counterDirectory.GetCounters();
Sadik Armagan1625efc2021-06-10 18:24:34 +0100701 CHECK(!counters.empty());
Matteo Martincigha84edee2019-10-02 12:50:57 +0100702
FinnWilliamsArmf6e534a2019-09-16 15:45:42 +0100703 std::vector<std::thread> writers;
704
Sadik Armagan1625efc2021-06-10 18:24:34 +0100705 CHECK(!counters.empty());
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
711 writers.push_back(std::thread([&profilingService]()
712 {
713 for (int i = 0; i < 250; ++i)
714 {
715 profilingService.IncrementCounterValue(INFERENCES_RUN);
716 }
717 }));
718 // Add 10 to the INFERENCES_RUN counter 200 times
719 writers.push_back(std::thread([&profilingService]()
720 {
721 for (int i = 0; i < 200; ++i)
722 {
723 profilingService.AddCounterValue(INFERENCES_RUN, 10);
724 }
725 }));
726 // Subtract 5 from the INFERENCES_RUN counter 200 times
727 writers.push_back(std::thread([&profilingService]()
728 {
729 for (int i = 0; i < 200; ++i)
730 {
731 profilingService.SubtractCounterValue(INFERENCES_RUN, 5);
732 }
733 }));
FinnWilliamsArmf6e534a2019-09-16 15:45:42 +0100734 }
Finn Williamsf3fcf322020-05-11 14:38:02 +0100735
FinnWilliamsArmf6e534a2019-09-16 15:45:42 +0100736 std::for_each(writers.begin(), writers.end(), mem_fn(&std::thread::join));
737
Finn Williamsf3fcf322020-05-11 14:38:02 +0100738 uint32_t absoluteCounterValue = 0;
FinnWilliamsArmf6e534a2019-09-16 15:45:42 +0100739
Sadik Armagan1625efc2021-06-10 18:24:34 +0100740 CHECK_NOTHROW(absoluteCounterValue = profilingService.GetAbsoluteCounterValue(INFERENCES_RUN));
741 CHECK(absoluteCounterValue == 5000);
Finn Williamsf3fcf322020-05-11 14:38:02 +0100742
743 // Test SetCounterValue
Sadik Armagan1625efc2021-06-10 18:24:34 +0100744 CHECK_NOTHROW(profilingService.SetCounterValue(INFERENCES_RUN, 0));
745 CHECK_NOTHROW(absoluteCounterValue = profilingService.GetAbsoluteCounterValue(INFERENCES_RUN));
746 CHECK(absoluteCounterValue == 0);
Finn Williamsf3fcf322020-05-11 14:38:02 +0100747
748 // Test GetDeltaCounterValue
749 writers.clear();
750 uint32_t deltaCounterValue = 0;
751 //Start a reading thread to randomly read the INFERENCES_RUN counter value
752 std::thread reader([&profilingService](uint32_t& deltaCounterValue)
753 {
754 for (int i = 0; i < 300; ++i)
755 {
756 deltaCounterValue += profilingService.GetDeltaCounterValue(INFERENCES_RUN);
757 }
758 }, std::ref(deltaCounterValue));
759
760 for (int i = 0; i < 4; ++i)
761 {
762 // Increment and decrement the INFERENCES_RUN counter 250 times
763 writers.push_back(std::thread([&profilingService]()
764 {
765 for (int i = 0; i < 250; ++i)
766 {
767 profilingService.IncrementCounterValue(INFERENCES_RUN);
768 }
769 }));
770 // Add 10 to the INFERENCES_RUN counter 200 times
771 writers.push_back(std::thread([&profilingService]()
772 {
773 for (int i = 0; i < 200; ++i)
774 {
775 profilingService.AddCounterValue(INFERENCES_RUN, 10);
776 }
777 }));
778 // Subtract 5 from the INFERENCES_RUN counter 200 times
779 writers.push_back(std::thread([&profilingService]()
780 {
781 for (int i = 0; i < 200; ++i)
782 {
783 profilingService.SubtractCounterValue(INFERENCES_RUN, 5);
784 }
785 }));
786 }
787
788 std::for_each(writers.begin(), writers.end(), mem_fn(&std::thread::join));
789 reader.join();
790
791 // Do one last read in case the reader stopped early
792 deltaCounterValue += profilingService.GetDeltaCounterValue(INFERENCES_RUN);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100793 CHECK(deltaCounterValue == 5000);
Finn Williamsf3fcf322020-05-11 14:38:02 +0100794
Colm Donelan2ba48d22019-11-29 09:10:59 +0000795 // Reset the profiling service to stop any running thread
796 options.m_EnableProfiling = false;
797 profilingService.ResetExternalProfilingOptions(options, true);
FinnWilliamsArmf6e534a2019-09-16 15:45:42 +0100798}
799
Sadik Armagan1625efc2021-06-10 18:24:34 +0100800TEST_CASE("CheckProfilingObjectUids")
Matteo Martincighab173e92019-09-05 12:02:04 +0100801{
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100802 uint16_t uid = 0;
Sadik Armagan1625efc2021-06-10 18:24:34 +0100803 CHECK_NOTHROW(uid = GetNextUid());
804 CHECK(uid >= 1);
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100805
806 uint16_t nextUid = 0;
Sadik Armagan1625efc2021-06-10 18:24:34 +0100807 CHECK_NOTHROW(nextUid = GetNextUid());
808 CHECK(nextUid > uid);
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100809
810 std::vector<uint16_t> counterUids;
Sadik Armagan1625efc2021-06-10 18:24:34 +0100811 CHECK_NOTHROW(counterUids = GetNextCounterUids(uid,0));
812 CHECK(counterUids.size() == 1);
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100813
814 std::vector<uint16_t> nextCounterUids;
Sadik Armagan1625efc2021-06-10 18:24:34 +0100815 CHECK_NOTHROW(nextCounterUids = GetNextCounterUids(nextUid, 2));
816 CHECK(nextCounterUids.size() == 2);
817 CHECK(nextCounterUids[0] > counterUids[0]);
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100818
819 std::vector<uint16_t> counterUidsMultiCore;
Francis Murtagh1e5afee2021-05-11 09:37:47 +0100820 uint16_t thirdUid = nextCounterUids[0];
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100821 uint16_t numberOfCores = 13;
Sadik Armagan1625efc2021-06-10 18:24:34 +0100822 CHECK_NOTHROW(counterUidsMultiCore = GetNextCounterUids(thirdUid, numberOfCores));
823 CHECK(counterUidsMultiCore.size() == numberOfCores);
824 CHECK(counterUidsMultiCore.front() >= nextCounterUids[0]);
Keith Davis3201eea2019-10-24 17:30:41 +0100825 for (size_t i = 1; i < numberOfCores; i++)
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100826 {
Sadik Armagan1625efc2021-06-10 18:24:34 +0100827 CHECK(counterUidsMultiCore[i] == counterUidsMultiCore[i - 1] + 1);
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100828 }
Sadik Armagan1625efc2021-06-10 18:24:34 +0100829 CHECK(counterUidsMultiCore.back() == counterUidsMultiCore.front() + numberOfCores - 1);
Matteo Martincighab173e92019-09-05 12:02:04 +0100830}
831
Sadik Armagan1625efc2021-06-10 18:24:34 +0100832TEST_CASE("CheckCounterDirectoryRegisterCategory")
Matteo Martincighab173e92019-09-05 12:02:04 +0100833{
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100834 CounterDirectory counterDirectory;
Sadik Armagan1625efc2021-06-10 18:24:34 +0100835 CHECK(counterDirectory.GetCategoryCount() == 0);
836 CHECK(counterDirectory.GetDeviceCount() == 0);
837 CHECK(counterDirectory.GetCounterSetCount() == 0);
838 CHECK(counterDirectory.GetCounterCount() == 0);
Matteo Martincighab173e92019-09-05 12:02:04 +0100839
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100840 // Register a category with an invalid name
841 const Category* noCategory = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +0100842 CHECK_THROWS_AS(noCategory = counterDirectory.RegisterCategory(""), armnn::InvalidArgumentException);
843 CHECK(counterDirectory.GetCategoryCount() == 0);
844 CHECK(!noCategory);
Matteo Martincighab173e92019-09-05 12:02:04 +0100845
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100846 // Register a category with an invalid name
Sadik Armagan1625efc2021-06-10 18:24:34 +0100847 CHECK_THROWS_AS(noCategory = counterDirectory.RegisterCategory("invalid category"),
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100848 armnn::InvalidArgumentException);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100849 CHECK(counterDirectory.GetCategoryCount() == 0);
850 CHECK(!noCategory);
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100851
852 // Register a new category
853 const std::string categoryName = "some_category";
Keith Davis3201eea2019-10-24 17:30:41 +0100854 const Category* category = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +0100855 CHECK_NOTHROW(category = counterDirectory.RegisterCategory(categoryName));
856 CHECK(counterDirectory.GetCategoryCount() == 1);
857 CHECK(category);
858 CHECK(category->m_Name == categoryName);
859 CHECK(category->m_Counters.empty());
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100860
861 // Get the registered category
862 const Category* registeredCategory = counterDirectory.GetCategory(categoryName);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100863 CHECK(counterDirectory.GetCategoryCount() == 1);
864 CHECK(registeredCategory);
865 CHECK(registeredCategory == category);
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100866
867 // Try to get a category not registered
868 const Category* notRegisteredCategory = counterDirectory.GetCategory("not_registered_category");
Sadik Armagan1625efc2021-06-10 18:24:34 +0100869 CHECK(counterDirectory.GetCategoryCount() == 1);
870 CHECK(!notRegisteredCategory);
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100871
872 // Register a category already registered
873 const Category* anotherCategory = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +0100874 CHECK_THROWS_AS(anotherCategory = counterDirectory.RegisterCategory(categoryName),
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100875 armnn::InvalidArgumentException);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100876 CHECK(counterDirectory.GetCategoryCount() == 1);
877 CHECK(!anotherCategory);
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100878
879 // Register a device for testing
880 const std::string deviceName = "some_device";
Keith Davis3201eea2019-10-24 17:30:41 +0100881 const Device* device = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +0100882 CHECK_NOTHROW(device = counterDirectory.RegisterDevice(deviceName));
883 CHECK(counterDirectory.GetDeviceCount() == 1);
884 CHECK(device);
885 CHECK(device->m_Uid >= 1);
886 CHECK(device->m_Name == deviceName);
887 CHECK(device->m_Cores == 0);
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100888
889 // Register a new category not associated to any device
890 const std::string categoryWoDeviceName = "some_category_without_device";
Keith Davis3201eea2019-10-24 17:30:41 +0100891 const Category* categoryWoDevice = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +0100892 CHECK_NOTHROW(categoryWoDevice = counterDirectory.RegisterCategory(categoryWoDeviceName));
893 CHECK(counterDirectory.GetCategoryCount() == 2);
894 CHECK(categoryWoDevice);
895 CHECK(categoryWoDevice->m_Name == categoryWoDeviceName);
896 CHECK(categoryWoDevice->m_Counters.empty());
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100897
Sadik Armagan4c998992020-02-25 12:44:44 +0000898 // Register a new category associated to an invalid device name (already exist)
899 const Category* categoryInvalidDeviceName = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +0100900 CHECK_THROWS_AS(categoryInvalidDeviceName =
Sadik Armagan4c998992020-02-25 12:44:44 +0000901 counterDirectory.RegisterCategory(categoryWoDeviceName),
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100902 armnn::InvalidArgumentException);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100903 CHECK(counterDirectory.GetCategoryCount() == 2);
904 CHECK(!categoryInvalidDeviceName);
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100905
906 // Register a new category associated to a valid device
907 const std::string categoryWValidDeviceName = "some_category_with_valid_device";
Keith Davis3201eea2019-10-24 17:30:41 +0100908 const Category* categoryWValidDevice = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +0100909 CHECK_NOTHROW(categoryWValidDevice =
Sadik Armagan4c998992020-02-25 12:44:44 +0000910 counterDirectory.RegisterCategory(categoryWValidDeviceName));
Sadik Armagan1625efc2021-06-10 18:24:34 +0100911 CHECK(counterDirectory.GetCategoryCount() == 3);
912 CHECK(categoryWValidDevice);
913 CHECK(categoryWValidDevice != category);
914 CHECK(categoryWValidDevice->m_Name == categoryWValidDeviceName);
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100915
916 // Register a counter set for testing
917 const std::string counterSetName = "some_counter_set";
Keith Davis3201eea2019-10-24 17:30:41 +0100918 const CounterSet* counterSet = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +0100919 CHECK_NOTHROW(counterSet = counterDirectory.RegisterCounterSet(counterSetName));
920 CHECK(counterDirectory.GetCounterSetCount() == 1);
921 CHECK(counterSet);
922 CHECK(counterSet->m_Uid >= 1);
923 CHECK(counterSet->m_Name == counterSetName);
924 CHECK(counterSet->m_Count == 0);
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100925
926 // Register a new category not associated to any counter set
927 const std::string categoryWoCounterSetName = "some_category_without_counter_set";
Keith Davis3201eea2019-10-24 17:30:41 +0100928 const Category* categoryWoCounterSet = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +0100929 CHECK_NOTHROW(categoryWoCounterSet =
Sadik Armagan4c998992020-02-25 12:44:44 +0000930 counterDirectory.RegisterCategory(categoryWoCounterSetName));
Sadik Armagan1625efc2021-06-10 18:24:34 +0100931 CHECK(counterDirectory.GetCategoryCount() == 4);
932 CHECK(categoryWoCounterSet);
933 CHECK(categoryWoCounterSet->m_Name == categoryWoCounterSetName);
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100934
935 // Register a new category associated to a valid counter set
936 const std::string categoryWValidCounterSetName = "some_category_with_valid_counter_set";
Keith Davis3201eea2019-10-24 17:30:41 +0100937 const Category* categoryWValidCounterSet = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +0100938 CHECK_NOTHROW(categoryWValidCounterSet = counterDirectory.RegisterCategory(categoryWValidCounterSetName));
939 CHECK(counterDirectory.GetCategoryCount() == 5);
940 CHECK(categoryWValidCounterSet);
941 CHECK(categoryWValidCounterSet != category);
942 CHECK(categoryWValidCounterSet->m_Name == categoryWValidCounterSetName);
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100943
944 // Register a new category associated to a valid device and counter set
945 const std::string categoryWValidDeviceAndValidCounterSetName = "some_category_with_valid_device_and_counter_set";
Keith Davis3201eea2019-10-24 17:30:41 +0100946 const Category* categoryWValidDeviceAndValidCounterSet = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +0100947 CHECK_NOTHROW(categoryWValidDeviceAndValidCounterSet = counterDirectory.RegisterCategory(
Sadik Armagan4c998992020-02-25 12:44:44 +0000948 categoryWValidDeviceAndValidCounterSetName));
Sadik Armagan1625efc2021-06-10 18:24:34 +0100949 CHECK(counterDirectory.GetCategoryCount() == 6);
950 CHECK(categoryWValidDeviceAndValidCounterSet);
951 CHECK(categoryWValidDeviceAndValidCounterSet != category);
952 CHECK(categoryWValidDeviceAndValidCounterSet->m_Name == categoryWValidDeviceAndValidCounterSetName);
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100953}
954
Sadik Armagan1625efc2021-06-10 18:24:34 +0100955TEST_CASE("CheckCounterDirectoryRegisterDevice")
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100956{
957 CounterDirectory counterDirectory;
Sadik Armagan1625efc2021-06-10 18:24:34 +0100958 CHECK(counterDirectory.GetCategoryCount() == 0);
959 CHECK(counterDirectory.GetDeviceCount() == 0);
960 CHECK(counterDirectory.GetCounterSetCount() == 0);
961 CHECK(counterDirectory.GetCounterCount() == 0);
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100962
963 // Register a device with an invalid name
964 const Device* noDevice = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +0100965 CHECK_THROWS_AS(noDevice = counterDirectory.RegisterDevice(""), armnn::InvalidArgumentException);
966 CHECK(counterDirectory.GetDeviceCount() == 0);
967 CHECK(!noDevice);
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100968
969 // Register a device with an invalid name
Sadik Armagan1625efc2021-06-10 18:24:34 +0100970 CHECK_THROWS_AS(noDevice = counterDirectory.RegisterDevice("inv@lid nam€"), armnn::InvalidArgumentException);
971 CHECK(counterDirectory.GetDeviceCount() == 0);
972 CHECK(!noDevice);
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100973
974 // Register a new device with no cores or parent category
975 const std::string deviceName = "some_device";
Keith Davis3201eea2019-10-24 17:30:41 +0100976 const Device* device = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +0100977 CHECK_NOTHROW(device = counterDirectory.RegisterDevice(deviceName));
978 CHECK(counterDirectory.GetDeviceCount() == 1);
979 CHECK(device);
980 CHECK(device->m_Name == deviceName);
981 CHECK(device->m_Uid >= 1);
982 CHECK(device->m_Cores == 0);
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100983
Matteo Martincigh657ab2d2019-09-18 10:53:24 +0100984 // Try getting an unregistered device
985 const Device* unregisteredDevice = counterDirectory.GetDevice(9999);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100986 CHECK(!unregisteredDevice);
Matteo Martincigh657ab2d2019-09-18 10:53:24 +0100987
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100988 // Get the registered device
989 const Device* registeredDevice = counterDirectory.GetDevice(device->m_Uid);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100990 CHECK(counterDirectory.GetDeviceCount() == 1);
991 CHECK(registeredDevice);
992 CHECK(registeredDevice == device);
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100993
Matteo Martincigh657ab2d2019-09-18 10:53:24 +0100994 // Register a device with the name of a device already registered
995 const Device* deviceSameName = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +0100996 CHECK_THROWS_AS(deviceSameName = counterDirectory.RegisterDevice(deviceName), armnn::InvalidArgumentException);
997 CHECK(counterDirectory.GetDeviceCount() == 1);
998 CHECK(!deviceSameName);
Matteo Martincigh657ab2d2019-09-18 10:53:24 +0100999
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001000 // Register a new device with cores and no parent category
1001 const std::string deviceWCoresName = "some_device_with_cores";
Keith Davis3201eea2019-10-24 17:30:41 +01001002 const Device* deviceWCores = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001003 CHECK_NOTHROW(deviceWCores = counterDirectory.RegisterDevice(deviceWCoresName, 2));
1004 CHECK(counterDirectory.GetDeviceCount() == 2);
1005 CHECK(deviceWCores);
1006 CHECK(deviceWCores->m_Name == deviceWCoresName);
1007 CHECK(deviceWCores->m_Uid >= 1);
1008 CHECK(deviceWCores->m_Uid > device->m_Uid);
1009 CHECK(deviceWCores->m_Cores == 2);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001010
1011 // Get the registered device
1012 const Device* registeredDeviceWCores = counterDirectory.GetDevice(deviceWCores->m_Uid);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001013 CHECK(counterDirectory.GetDeviceCount() == 2);
1014 CHECK(registeredDeviceWCores);
1015 CHECK(registeredDeviceWCores == deviceWCores);
1016 CHECK(registeredDeviceWCores != device);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001017
1018 // Register a new device with cores and invalid parent category
1019 const std::string deviceWCoresWInvalidParentCategoryName = "some_device_with_cores_with_invalid_parent_category";
Keith Davis3201eea2019-10-24 17:30:41 +01001020 const Device* deviceWCoresWInvalidParentCategory = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001021 CHECK_THROWS_AS(deviceWCoresWInvalidParentCategory =
Keith Davis3201eea2019-10-24 17:30:41 +01001022 counterDirectory.RegisterDevice(deviceWCoresWInvalidParentCategoryName, 3, std::string("")),
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001023 armnn::InvalidArgumentException);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001024 CHECK(counterDirectory.GetDeviceCount() == 2);
1025 CHECK(!deviceWCoresWInvalidParentCategory);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001026
1027 // Register a new device with cores and invalid parent category
1028 const std::string deviceWCoresWInvalidParentCategoryName2 = "some_device_with_cores_with_invalid_parent_category2";
Keith Davis3201eea2019-10-24 17:30:41 +01001029 const Device* deviceWCoresWInvalidParentCategory2 = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001030 CHECK_THROWS_AS(deviceWCoresWInvalidParentCategory2 = counterDirectory.RegisterDevice(
Keith Davis3201eea2019-10-24 17:30:41 +01001031 deviceWCoresWInvalidParentCategoryName2, 3, std::string("invalid_parent_category")),
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001032 armnn::InvalidArgumentException);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001033 CHECK(counterDirectory.GetDeviceCount() == 2);
1034 CHECK(!deviceWCoresWInvalidParentCategory2);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001035
1036 // Register a category for testing
1037 const std::string categoryName = "some_category";
Keith Davis3201eea2019-10-24 17:30:41 +01001038 const Category* category = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001039 CHECK_NOTHROW(category = counterDirectory.RegisterCategory(categoryName));
1040 CHECK(counterDirectory.GetCategoryCount() == 1);
1041 CHECK(category);
1042 CHECK(category->m_Name == categoryName);
1043 CHECK(category->m_Counters.empty());
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001044
1045 // Register a new device with cores and valid parent category
1046 const std::string deviceWCoresWValidParentCategoryName = "some_device_with_cores_with_valid_parent_category";
Keith Davis3201eea2019-10-24 17:30:41 +01001047 const Device* deviceWCoresWValidParentCategory = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001048 CHECK_NOTHROW(deviceWCoresWValidParentCategory =
Keith Davis3201eea2019-10-24 17:30:41 +01001049 counterDirectory.RegisterDevice(deviceWCoresWValidParentCategoryName, 4, categoryName));
Sadik Armagan1625efc2021-06-10 18:24:34 +01001050 CHECK(counterDirectory.GetDeviceCount() == 3);
1051 CHECK(deviceWCoresWValidParentCategory);
1052 CHECK(deviceWCoresWValidParentCategory->m_Name == deviceWCoresWValidParentCategoryName);
1053 CHECK(deviceWCoresWValidParentCategory->m_Uid >= 1);
1054 CHECK(deviceWCoresWValidParentCategory->m_Uid > device->m_Uid);
1055 CHECK(deviceWCoresWValidParentCategory->m_Uid > deviceWCores->m_Uid);
1056 CHECK(deviceWCoresWValidParentCategory->m_Cores == 4);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001057}
1058
Sadik Armagan1625efc2021-06-10 18:24:34 +01001059TEST_CASE("CheckCounterDirectoryRegisterCounterSet")
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001060{
1061 CounterDirectory counterDirectory;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001062 CHECK(counterDirectory.GetCategoryCount() == 0);
1063 CHECK(counterDirectory.GetDeviceCount() == 0);
1064 CHECK(counterDirectory.GetCounterSetCount() == 0);
1065 CHECK(counterDirectory.GetCounterCount() == 0);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001066
1067 // Register a counter set with an invalid name
1068 const CounterSet* noCounterSet = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001069 CHECK_THROWS_AS(noCounterSet = counterDirectory.RegisterCounterSet(""), armnn::InvalidArgumentException);
1070 CHECK(counterDirectory.GetCounterSetCount() == 0);
1071 CHECK(!noCounterSet);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001072
1073 // Register a counter set with an invalid name
Sadik Armagan1625efc2021-06-10 18:24:34 +01001074 CHECK_THROWS_AS(noCounterSet = counterDirectory.RegisterCounterSet("invalid name"),
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001075 armnn::InvalidArgumentException);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001076 CHECK(counterDirectory.GetCounterSetCount() == 0);
1077 CHECK(!noCounterSet);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001078
1079 // Register a new counter set with no count or parent category
1080 const std::string counterSetName = "some_counter_set";
Keith Davis3201eea2019-10-24 17:30:41 +01001081 const CounterSet* counterSet = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001082 CHECK_NOTHROW(counterSet = counterDirectory.RegisterCounterSet(counterSetName));
1083 CHECK(counterDirectory.GetCounterSetCount() == 1);
1084 CHECK(counterSet);
1085 CHECK(counterSet->m_Name == counterSetName);
1086 CHECK(counterSet->m_Uid >= 1);
1087 CHECK(counterSet->m_Count == 0);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001088
Matteo Martincigh657ab2d2019-09-18 10:53:24 +01001089 // Try getting an unregistered counter set
1090 const CounterSet* unregisteredCounterSet = counterDirectory.GetCounterSet(9999);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001091 CHECK(!unregisteredCounterSet);
Matteo Martincigh657ab2d2019-09-18 10:53:24 +01001092
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001093 // Get the registered counter set
1094 const CounterSet* registeredCounterSet = counterDirectory.GetCounterSet(counterSet->m_Uid);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001095 CHECK(counterDirectory.GetCounterSetCount() == 1);
1096 CHECK(registeredCounterSet);
1097 CHECK(registeredCounterSet == counterSet);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001098
Matteo Martincigh657ab2d2019-09-18 10:53:24 +01001099 // Register a counter set with the name of a counter set already registered
1100 const CounterSet* counterSetSameName = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001101 CHECK_THROWS_AS(counterSetSameName = counterDirectory.RegisterCounterSet(counterSetName),
Matteo Martincigh657ab2d2019-09-18 10:53:24 +01001102 armnn::InvalidArgumentException);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001103 CHECK(counterDirectory.GetCounterSetCount() == 1);
1104 CHECK(!counterSetSameName);
Matteo Martincigh657ab2d2019-09-18 10:53:24 +01001105
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001106 // Register a new counter set with count and no parent category
1107 const std::string counterSetWCountName = "some_counter_set_with_count";
Keith Davis3201eea2019-10-24 17:30:41 +01001108 const CounterSet* counterSetWCount = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001109 CHECK_NOTHROW(counterSetWCount = counterDirectory.RegisterCounterSet(counterSetWCountName, 37));
1110 CHECK(counterDirectory.GetCounterSetCount() == 2);
1111 CHECK(counterSetWCount);
1112 CHECK(counterSetWCount->m_Name == counterSetWCountName);
1113 CHECK(counterSetWCount->m_Uid >= 1);
1114 CHECK(counterSetWCount->m_Uid > counterSet->m_Uid);
1115 CHECK(counterSetWCount->m_Count == 37);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001116
1117 // Get the registered counter set
1118 const CounterSet* registeredCounterSetWCount = counterDirectory.GetCounterSet(counterSetWCount->m_Uid);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001119 CHECK(counterDirectory.GetCounterSetCount() == 2);
1120 CHECK(registeredCounterSetWCount);
1121 CHECK(registeredCounterSetWCount == counterSetWCount);
1122 CHECK(registeredCounterSetWCount != counterSet);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001123
1124 // Register a new counter set with count and invalid parent category
1125 const std::string counterSetWCountWInvalidParentCategoryName = "some_counter_set_with_count_"
1126 "with_invalid_parent_category";
1127 const CounterSet* counterSetWCountWInvalidParentCategory = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001128 CHECK_THROWS_AS(counterSetWCountWInvalidParentCategory = counterDirectory.RegisterCounterSet(
Keith Davis3201eea2019-10-24 17:30:41 +01001129 counterSetWCountWInvalidParentCategoryName, 42, std::string("")),
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001130 armnn::InvalidArgumentException);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001131 CHECK(counterDirectory.GetCounterSetCount() == 2);
1132 CHECK(!counterSetWCountWInvalidParentCategory);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001133
1134 // Register a new counter set with count and invalid parent category
1135 const std::string counterSetWCountWInvalidParentCategoryName2 = "some_counter_set_with_count_"
1136 "with_invalid_parent_category2";
1137 const CounterSet* counterSetWCountWInvalidParentCategory2 = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001138 CHECK_THROWS_AS(counterSetWCountWInvalidParentCategory2 = counterDirectory.RegisterCounterSet(
Keith Davis3201eea2019-10-24 17:30:41 +01001139 counterSetWCountWInvalidParentCategoryName2, 42, std::string("invalid_parent_category")),
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001140 armnn::InvalidArgumentException);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001141 CHECK(counterDirectory.GetCounterSetCount() == 2);
1142 CHECK(!counterSetWCountWInvalidParentCategory2);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001143
1144 // Register a category for testing
1145 const std::string categoryName = "some_category";
Keith Davis3201eea2019-10-24 17:30:41 +01001146 const Category* category = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001147 CHECK_NOTHROW(category = counterDirectory.RegisterCategory(categoryName));
1148 CHECK(counterDirectory.GetCategoryCount() == 1);
1149 CHECK(category);
1150 CHECK(category->m_Name == categoryName);
1151 CHECK(category->m_Counters.empty());
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001152
1153 // Register a new counter set with count and valid parent category
1154 const std::string counterSetWCountWValidParentCategoryName = "some_counter_set_with_count_"
1155 "with_valid_parent_category";
1156 const CounterSet* counterSetWCountWValidParentCategory = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001157 CHECK_NOTHROW(counterSetWCountWValidParentCategory = counterDirectory.RegisterCounterSet(
Keith Davis3201eea2019-10-24 17:30:41 +01001158 counterSetWCountWValidParentCategoryName, 42, categoryName));
Sadik Armagan1625efc2021-06-10 18:24:34 +01001159 CHECK(counterDirectory.GetCounterSetCount() == 3);
1160 CHECK(counterSetWCountWValidParentCategory);
1161 CHECK(counterSetWCountWValidParentCategory->m_Name == counterSetWCountWValidParentCategoryName);
1162 CHECK(counterSetWCountWValidParentCategory->m_Uid >= 1);
1163 CHECK(counterSetWCountWValidParentCategory->m_Uid > counterSet->m_Uid);
1164 CHECK(counterSetWCountWValidParentCategory->m_Uid > counterSetWCount->m_Uid);
1165 CHECK(counterSetWCountWValidParentCategory->m_Count == 42);
Matteo Martincigh657ab2d2019-09-18 10:53:24 +01001166
Sadik Armagan4c998992020-02-25 12:44:44 +00001167 // Register a counter set associated to a category with invalid name
Matteo Martincigh657ab2d2019-09-18 10:53:24 +01001168 const std::string counterSetSameCategoryName = "some_counter_set_with_invalid_parent_category";
Sadik Armagan4c998992020-02-25 12:44:44 +00001169 const std::string invalidCategoryName = "";
Keith Davis3201eea2019-10-24 17:30:41 +01001170 const CounterSet* counterSetSameCategory = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001171 CHECK_THROWS_AS(counterSetSameCategory =
Sadik Armagan4c998992020-02-25 12:44:44 +00001172 counterDirectory.RegisterCounterSet(counterSetSameCategoryName, 0, invalidCategoryName),
Matteo Martincigh657ab2d2019-09-18 10:53:24 +01001173 armnn::InvalidArgumentException);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001174 CHECK(counterDirectory.GetCounterSetCount() == 3);
1175 CHECK(!counterSetSameCategory);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001176}
1177
Sadik Armagan1625efc2021-06-10 18:24:34 +01001178TEST_CASE("CheckCounterDirectoryRegisterCounter")
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001179{
1180 CounterDirectory counterDirectory;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001181 CHECK(counterDirectory.GetCategoryCount() == 0);
1182 CHECK(counterDirectory.GetDeviceCount() == 0);
1183 CHECK(counterDirectory.GetCounterSetCount() == 0);
1184 CHECK(counterDirectory.GetCounterCount() == 0);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001185
1186 // Register a counter with an invalid parent category name
1187 const Counter* noCounter = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001188 CHECK_THROWS_AS(noCounter =
Keith Davise394bd92019-12-02 15:12:19 +00001189 counterDirectory.RegisterCounter(armnn::profiling::BACKEND_ID,
1190 0,
1191 "",
1192 0,
1193 1,
1194 123.45f,
1195 "valid ",
1196 "name"),
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001197 armnn::InvalidArgumentException);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001198 CHECK(counterDirectory.GetCounterCount() == 0);
1199 CHECK(!noCounter);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001200
1201 // Register a counter with an invalid parent category name
Sadik Armagan1625efc2021-06-10 18:24:34 +01001202 CHECK_THROWS_AS(noCounter = counterDirectory.RegisterCounter(armnn::profiling::BACKEND_ID,
Keith Davise394bd92019-12-02 15:12:19 +00001203 1,
1204 "invalid parent category",
1205 0,
1206 1,
1207 123.45f,
1208 "valid name",
1209 "valid description"),
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001210 armnn::InvalidArgumentException);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001211 CHECK(counterDirectory.GetCounterCount() == 0);
1212 CHECK(!noCounter);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001213
1214 // Register a counter with an invalid class
Sadik Armagan1625efc2021-06-10 18:24:34 +01001215 CHECK_THROWS_AS(noCounter = counterDirectory.RegisterCounter(armnn::profiling::BACKEND_ID,
Keith Davise394bd92019-12-02 15:12:19 +00001216 2,
1217 "valid_parent_category",
1218 2,
1219 1,
1220 123.45f,
1221 "valid "
1222 "name",
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001223 "valid description"),
1224 armnn::InvalidArgumentException);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001225 CHECK(counterDirectory.GetCounterCount() == 0);
1226 CHECK(!noCounter);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001227
1228 // Register a counter with an invalid interpolation
Sadik Armagan1625efc2021-06-10 18:24:34 +01001229 CHECK_THROWS_AS(noCounter = counterDirectory.RegisterCounter(armnn::profiling::BACKEND_ID,
Keith Davise394bd92019-12-02 15:12:19 +00001230 4,
1231 "valid_parent_category",
1232 0,
1233 3,
1234 123.45f,
1235 "valid "
1236 "name",
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001237 "valid description"),
1238 armnn::InvalidArgumentException);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001239 CHECK(counterDirectory.GetCounterCount() == 0);
1240 CHECK(!noCounter);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001241
1242 // Register a counter with an invalid multiplier
Sadik Armagan1625efc2021-06-10 18:24:34 +01001243 CHECK_THROWS_AS(noCounter = counterDirectory.RegisterCounter(armnn::profiling::BACKEND_ID,
Keith Davise394bd92019-12-02 15:12:19 +00001244 5,
1245 "valid_parent_category",
1246 0,
1247 1,
1248 .0f,
1249 "valid "
1250 "name",
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001251 "valid description"),
1252 armnn::InvalidArgumentException);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001253 CHECK(counterDirectory.GetCounterCount() == 0);
1254 CHECK(!noCounter);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001255
1256 // Register a counter with an invalid name
Sadik Armagan1625efc2021-06-10 18:24:34 +01001257 CHECK_THROWS_AS(
Keith Davise394bd92019-12-02 15:12:19 +00001258 noCounter = counterDirectory.RegisterCounter(armnn::profiling::BACKEND_ID,
1259 6,
1260 "valid_parent_category",
1261 0,
1262 1,
1263 123.45f,
1264 "",
1265 "valid description"),
Keith Davis3201eea2019-10-24 17:30:41 +01001266 armnn::InvalidArgumentException);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001267 CHECK(counterDirectory.GetCounterCount() == 0);
1268 CHECK(!noCounter);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001269
1270 // Register a counter with an invalid name
Sadik Armagan1625efc2021-06-10 18:24:34 +01001271 CHECK_THROWS_AS(noCounter = counterDirectory.RegisterCounter(armnn::profiling::BACKEND_ID,
Keith Davise394bd92019-12-02 15:12:19 +00001272 7,
1273 "valid_parent_category",
1274 0,
1275 1,
1276 123.45f,
1277 "invalid nam€",
1278 "valid description"),
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001279 armnn::InvalidArgumentException);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001280 CHECK(counterDirectory.GetCounterCount() == 0);
1281 CHECK(!noCounter);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001282
1283 // Register a counter with an invalid description
Sadik Armagan1625efc2021-06-10 18:24:34 +01001284 CHECK_THROWS_AS(noCounter =
Keith Davise394bd92019-12-02 15:12:19 +00001285 counterDirectory.RegisterCounter(armnn::profiling::BACKEND_ID,
1286 8,
1287 "valid_parent_category",
1288 0,
1289 1,
1290 123.45f,
1291 "valid name",
1292 ""),
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001293 armnn::InvalidArgumentException);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001294 CHECK(counterDirectory.GetCounterCount() == 0);
1295 CHECK(!noCounter);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001296
1297 // Register a counter with an invalid description
Sadik Armagan1625efc2021-06-10 18:24:34 +01001298 CHECK_THROWS_AS(noCounter = counterDirectory.RegisterCounter(armnn::profiling::BACKEND_ID,
Keith Davise394bd92019-12-02 15:12:19 +00001299 9,
1300 "valid_parent_category",
1301 0,
1302 1,
1303 123.45f,
1304 "valid "
1305 "name",
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001306 "inv@lid description"),
1307 armnn::InvalidArgumentException);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001308 CHECK(counterDirectory.GetCounterCount() == 0);
1309 CHECK(!noCounter);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001310
1311 // Register a counter with an invalid unit2
Sadik Armagan1625efc2021-06-10 18:24:34 +01001312 CHECK_THROWS_AS(noCounter = counterDirectory.RegisterCounter(armnn::profiling::BACKEND_ID,
Keith Davise394bd92019-12-02 15:12:19 +00001313 10,
1314 "valid_parent_category",
1315 0,
1316 1,
1317 123.45f,
1318 "valid name",
1319 "valid description",
1320 std::string("Mb/s2")),
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001321 armnn::InvalidArgumentException);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001322 CHECK(counterDirectory.GetCounterCount() == 0);
1323 CHECK(!noCounter);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001324
1325 // Register a counter with a non-existing parent category name
Sadik Armagan1625efc2021-06-10 18:24:34 +01001326 CHECK_THROWS_AS(noCounter = counterDirectory.RegisterCounter(armnn::profiling::BACKEND_ID,
Keith Davise394bd92019-12-02 15:12:19 +00001327 11,
1328 "invalid_parent_category",
1329 0,
1330 1,
1331 123.45f,
1332 "valid name",
1333 "valid description"),
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001334 armnn::InvalidArgumentException);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001335 CHECK(counterDirectory.GetCounterCount() == 0);
1336 CHECK(!noCounter);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001337
Matteo Martincigh657ab2d2019-09-18 10:53:24 +01001338 // Try getting an unregistered counter
1339 const Counter* unregisteredCounter = counterDirectory.GetCounter(9999);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001340 CHECK(!unregisteredCounter);
Matteo Martincigh657ab2d2019-09-18 10:53:24 +01001341
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001342 // Register a category for testing
1343 const std::string categoryName = "some_category";
Keith Davis3201eea2019-10-24 17:30:41 +01001344 const Category* category = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001345 CHECK_NOTHROW(category = counterDirectory.RegisterCategory(categoryName));
1346 CHECK(counterDirectory.GetCategoryCount() == 1);
1347 CHECK(category);
1348 CHECK(category->m_Name == categoryName);
1349 CHECK(category->m_Counters.empty());
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001350
1351 // Register a counter with a valid parent category name
1352 const Counter* counter = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001353 CHECK_NOTHROW(
Keith Davise394bd92019-12-02 15:12:19 +00001354 counter = counterDirectory.RegisterCounter(armnn::profiling::BACKEND_ID,
1355 12,
1356 categoryName,
1357 0,
1358 1,
1359 123.45f,
1360 "valid name",
1361 "valid description"));
Sadik Armagan1625efc2021-06-10 18:24:34 +01001362 CHECK(counterDirectory.GetCounterCount() == 1);
1363 CHECK(counter);
1364 CHECK(counter->m_MaxCounterUid == counter->m_Uid);
1365 CHECK(counter->m_Class == 0);
1366 CHECK(counter->m_Interpolation == 1);
1367 CHECK(counter->m_Multiplier == 123.45f);
1368 CHECK(counter->m_Name == "valid name");
1369 CHECK(counter->m_Description == "valid description");
1370 CHECK(counter->m_Units == "");
1371 CHECK(counter->m_DeviceUid == 0);
1372 CHECK(counter->m_CounterSetUid == 0);
1373 CHECK(category->m_Counters.size() == 1);
1374 CHECK(category->m_Counters.back() == counter->m_Uid);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001375
Matteo Martincigh657ab2d2019-09-18 10:53:24 +01001376 // Register a counter with a name of a counter already registered for the given parent category name
1377 const Counter* counterSameName = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001378 CHECK_THROWS_AS(counterSameName =
Keith Davise394bd92019-12-02 15:12:19 +00001379 counterDirectory.RegisterCounter(armnn::profiling::BACKEND_ID,
1380 13,
1381 categoryName,
1382 0,
1383 0,
1384 1.0f,
1385 "valid name",
1386 "valid description",
1387 std::string("description")),
Matteo Martincigh657ab2d2019-09-18 10:53:24 +01001388 armnn::InvalidArgumentException);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001389 CHECK(counterDirectory.GetCounterCount() == 1);
1390 CHECK(!counterSameName);
Matteo Martincigh657ab2d2019-09-18 10:53:24 +01001391
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001392 // Register a counter with a valid parent category name and units
1393 const Counter* counterWUnits = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001394 CHECK_NOTHROW(counterWUnits = counterDirectory.RegisterCounter(armnn::profiling::BACKEND_ID,
Keith Davise394bd92019-12-02 15:12:19 +00001395 14,
1396 categoryName,
1397 0,
1398 1,
1399 123.45f,
1400 "valid name 2",
1401 "valid description",
1402 std::string("Mnnsq2"))); // Units
Sadik Armagan1625efc2021-06-10 18:24:34 +01001403 CHECK(counterDirectory.GetCounterCount() == 2);
1404 CHECK(counterWUnits);
1405 CHECK(counterWUnits->m_Uid > counter->m_Uid);
1406 CHECK(counterWUnits->m_MaxCounterUid == counterWUnits->m_Uid);
1407 CHECK(counterWUnits->m_Class == 0);
1408 CHECK(counterWUnits->m_Interpolation == 1);
1409 CHECK(counterWUnits->m_Multiplier == 123.45f);
1410 CHECK(counterWUnits->m_Name == "valid name 2");
1411 CHECK(counterWUnits->m_Description == "valid description");
1412 CHECK(counterWUnits->m_Units == "Mnnsq2");
1413 CHECK(counterWUnits->m_DeviceUid == 0);
1414 CHECK(counterWUnits->m_CounterSetUid == 0);
1415 CHECK(category->m_Counters.size() == 2);
1416 CHECK(category->m_Counters.back() == counterWUnits->m_Uid);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001417
1418 // Register a counter with a valid parent category name and not associated with a device
1419 const Counter* counterWoDevice = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001420 CHECK_NOTHROW(counterWoDevice = counterDirectory.RegisterCounter(armnn::profiling::BACKEND_ID,
Jim Flynnbbfe6032020-07-20 16:57:44 +01001421 26,
1422 categoryName,
1423 0,
1424 1,
1425 123.45f,
1426 "valid name 3",
1427 "valid description",
1428 armnn::EmptyOptional(),// Units
1429 armnn::EmptyOptional(),// Number of cores
1430 0)); // Device UID
Sadik Armagan1625efc2021-06-10 18:24:34 +01001431 CHECK(counterDirectory.GetCounterCount() == 3);
1432 CHECK(counterWoDevice);
1433 CHECK(counterWoDevice->m_Uid > counter->m_Uid);
1434 CHECK(counterWoDevice->m_MaxCounterUid == counterWoDevice->m_Uid);
1435 CHECK(counterWoDevice->m_Class == 0);
1436 CHECK(counterWoDevice->m_Interpolation == 1);
1437 CHECK(counterWoDevice->m_Multiplier == 123.45f);
1438 CHECK(counterWoDevice->m_Name == "valid name 3");
1439 CHECK(counterWoDevice->m_Description == "valid description");
1440 CHECK(counterWoDevice->m_Units == "");
1441 CHECK(counterWoDevice->m_DeviceUid == 0);
1442 CHECK(counterWoDevice->m_CounterSetUid == 0);
1443 CHECK(category->m_Counters.size() == 3);
1444 CHECK(category->m_Counters.back() == counterWoDevice->m_Uid);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001445
1446 // Register a counter with a valid parent category name and associated to an invalid device
Sadik Armagan1625efc2021-06-10 18:24:34 +01001447 CHECK_THROWS_AS(noCounter = counterDirectory.RegisterCounter(armnn::profiling::BACKEND_ID,
Keith Davise394bd92019-12-02 15:12:19 +00001448 15,
1449 categoryName,
1450 0,
1451 1,
1452 123.45f,
1453 "valid name 4",
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001454 "valid description",
Keith Davis3201eea2019-10-24 17:30:41 +01001455 armnn::EmptyOptional(), // Units
1456 armnn::EmptyOptional(), // Number of cores
1457 100), // Device UID
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001458 armnn::InvalidArgumentException);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001459 CHECK(counterDirectory.GetCounterCount() == 3);
1460 CHECK(!noCounter);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001461
1462 // Register a device for testing
1463 const std::string deviceName = "some_device";
Keith Davis3201eea2019-10-24 17:30:41 +01001464 const Device* device = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001465 CHECK_NOTHROW(device = counterDirectory.RegisterDevice(deviceName));
1466 CHECK(counterDirectory.GetDeviceCount() == 1);
1467 CHECK(device);
1468 CHECK(device->m_Name == deviceName);
1469 CHECK(device->m_Uid >= 1);
1470 CHECK(device->m_Cores == 0);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001471
1472 // Register a counter with a valid parent category name and associated to a device
1473 const Counter* counterWDevice = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001474 CHECK_NOTHROW(counterWDevice = counterDirectory.RegisterCounter(armnn::profiling::BACKEND_ID,
Keith Davise394bd92019-12-02 15:12:19 +00001475 16,
1476 categoryName,
1477 0,
1478 1,
1479 123.45f,
1480 "valid name 5",
1481 std::string("valid description"),
Jim Flynnbbfe6032020-07-20 16:57:44 +01001482 armnn::EmptyOptional(), // Units
1483 armnn::EmptyOptional(), // Number of cores
1484 device->m_Uid)); // Device UID
Sadik Armagan1625efc2021-06-10 18:24:34 +01001485 CHECK(counterDirectory.GetCounterCount() == 4);
1486 CHECK(counterWDevice);
1487 CHECK(counterWDevice->m_Uid > counter->m_Uid);
1488 CHECK(counterWDevice->m_MaxCounterUid == counterWDevice->m_Uid);
1489 CHECK(counterWDevice->m_Class == 0);
1490 CHECK(counterWDevice->m_Interpolation == 1);
1491 CHECK(counterWDevice->m_Multiplier == 123.45f);
1492 CHECK(counterWDevice->m_Name == "valid name 5");
1493 CHECK(counterWDevice->m_Description == "valid description");
1494 CHECK(counterWDevice->m_Units == "");
1495 CHECK(counterWDevice->m_DeviceUid == device->m_Uid);
1496 CHECK(counterWDevice->m_CounterSetUid == 0);
1497 CHECK(category->m_Counters.size() == 4);
1498 CHECK(category->m_Counters.back() == counterWDevice->m_Uid);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001499
1500 // Register a counter with a valid parent category name and not associated with a counter set
1501 const Counter* counterWoCounterSet = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001502 CHECK_NOTHROW(counterWoCounterSet = counterDirectory.RegisterCounter(armnn::profiling::BACKEND_ID,
Keith Davise394bd92019-12-02 15:12:19 +00001503 17,
1504 categoryName,
1505 0,
1506 1,
1507 123.45f,
1508 "valid name 6",
1509 "valid description",
1510 armnn::EmptyOptional(),// Units
1511 armnn::EmptyOptional(),// No of cores
1512 armnn::EmptyOptional(),// Device UID
Jim Flynnbbfe6032020-07-20 16:57:44 +01001513 0)); // CounterSet UID
Sadik Armagan1625efc2021-06-10 18:24:34 +01001514 CHECK(counterDirectory.GetCounterCount() == 5);
1515 CHECK(counterWoCounterSet);
1516 CHECK(counterWoCounterSet->m_Uid > counter->m_Uid);
1517 CHECK(counterWoCounterSet->m_MaxCounterUid == counterWoCounterSet->m_Uid);
1518 CHECK(counterWoCounterSet->m_Class == 0);
1519 CHECK(counterWoCounterSet->m_Interpolation == 1);
1520 CHECK(counterWoCounterSet->m_Multiplier == 123.45f);
1521 CHECK(counterWoCounterSet->m_Name == "valid name 6");
1522 CHECK(counterWoCounterSet->m_Description == "valid description");
1523 CHECK(counterWoCounterSet->m_Units == "");
1524 CHECK(counterWoCounterSet->m_DeviceUid == 0);
1525 CHECK(counterWoCounterSet->m_CounterSetUid == 0);
1526 CHECK(category->m_Counters.size() == 5);
1527 CHECK(category->m_Counters.back() == counterWoCounterSet->m_Uid);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001528
1529 // Register a counter with a valid parent category name and associated to an invalid counter set
Sadik Armagan1625efc2021-06-10 18:24:34 +01001530 CHECK_THROWS_AS(noCounter = counterDirectory.RegisterCounter(armnn::profiling::BACKEND_ID,
Keith Davise394bd92019-12-02 15:12:19 +00001531 18,
1532 categoryName,
1533 0,
1534 1,
1535 123.45f,
1536 "valid ",
1537 "name 7",
1538 std::string("valid description"),
Keith Davis3201eea2019-10-24 17:30:41 +01001539 armnn::EmptyOptional(), // Units
1540 armnn::EmptyOptional(), // Number of cores
Keith Davise394bd92019-12-02 15:12:19 +00001541 100), // Counter set UID
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001542 armnn::InvalidArgumentException);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001543 CHECK(counterDirectory.GetCounterCount() == 5);
1544 CHECK(!noCounter);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001545
1546 // Register a counter with a valid parent category name and with a given number of cores
1547 const Counter* counterWNumberOfCores = nullptr;
Keith Davis3201eea2019-10-24 17:30:41 +01001548 uint16_t numberOfCores = 15;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001549 CHECK_NOTHROW(counterWNumberOfCores = counterDirectory.RegisterCounter(
Keith Davise394bd92019-12-02 15:12:19 +00001550 armnn::profiling::BACKEND_ID, 50,
Keith Davis3201eea2019-10-24 17:30:41 +01001551 categoryName, 0, 1, 123.45f, "valid name 8", "valid description",
1552 armnn::EmptyOptional(), // Units
1553 numberOfCores, // Number of cores
1554 armnn::EmptyOptional(), // Device UID
1555 armnn::EmptyOptional())); // Counter set UID
Sadik Armagan1625efc2021-06-10 18:24:34 +01001556 CHECK(counterDirectory.GetCounterCount() == 20);
1557 CHECK(counterWNumberOfCores);
1558 CHECK(counterWNumberOfCores->m_Uid > counter->m_Uid);
1559 CHECK(counterWNumberOfCores->m_MaxCounterUid == counterWNumberOfCores->m_Uid + numberOfCores - 1);
1560 CHECK(counterWNumberOfCores->m_Class == 0);
1561 CHECK(counterWNumberOfCores->m_Interpolation == 1);
1562 CHECK(counterWNumberOfCores->m_Multiplier == 123.45f);
1563 CHECK(counterWNumberOfCores->m_Name == "valid name 8");
1564 CHECK(counterWNumberOfCores->m_Description == "valid description");
1565 CHECK(counterWNumberOfCores->m_Units == "");
1566 CHECK(counterWNumberOfCores->m_DeviceUid == 0);
1567 CHECK(counterWNumberOfCores->m_CounterSetUid == 0);
1568 CHECK(category->m_Counters.size() == 20);
Keith Davis3201eea2019-10-24 17:30:41 +01001569 for (size_t i = 0; i < numberOfCores; i++)
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001570 {
Sadik Armagan1625efc2021-06-10 18:24:34 +01001571 CHECK(category->m_Counters[category->m_Counters.size() - numberOfCores + i] ==
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001572 counterWNumberOfCores->m_Uid + i);
1573 }
1574
1575 // Register a multi-core device for testing
1576 const std::string multiCoreDeviceName = "some_multi_core_device";
Keith Davis3201eea2019-10-24 17:30:41 +01001577 const Device* multiCoreDevice = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001578 CHECK_NOTHROW(multiCoreDevice = counterDirectory.RegisterDevice(multiCoreDeviceName, 4));
1579 CHECK(counterDirectory.GetDeviceCount() == 2);
1580 CHECK(multiCoreDevice);
1581 CHECK(multiCoreDevice->m_Name == multiCoreDeviceName);
1582 CHECK(multiCoreDevice->m_Uid >= 1);
1583 CHECK(multiCoreDevice->m_Cores == 4);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001584
1585 // Register a counter with a valid parent category name and associated to the multi-core device
1586 const Counter* counterWMultiCoreDevice = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001587 CHECK_NOTHROW(counterWMultiCoreDevice = counterDirectory.RegisterCounter(
Keith Davise394bd92019-12-02 15:12:19 +00001588 armnn::profiling::BACKEND_ID, 19, categoryName, 0, 1,
1589 123.45f, "valid name 9", "valid description",
Keith Davis3201eea2019-10-24 17:30:41 +01001590 armnn::EmptyOptional(), // Units
1591 armnn::EmptyOptional(), // Number of cores
1592 multiCoreDevice->m_Uid, // Device UID
1593 armnn::EmptyOptional())); // Counter set UID
Sadik Armagan1625efc2021-06-10 18:24:34 +01001594 CHECK(counterDirectory.GetCounterCount() == 24);
1595 CHECK(counterWMultiCoreDevice);
1596 CHECK(counterWMultiCoreDevice->m_Uid > counter->m_Uid);
1597 CHECK(counterWMultiCoreDevice->m_MaxCounterUid ==
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001598 counterWMultiCoreDevice->m_Uid + multiCoreDevice->m_Cores - 1);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001599 CHECK(counterWMultiCoreDevice->m_Class == 0);
1600 CHECK(counterWMultiCoreDevice->m_Interpolation == 1);
1601 CHECK(counterWMultiCoreDevice->m_Multiplier == 123.45f);
1602 CHECK(counterWMultiCoreDevice->m_Name == "valid name 9");
1603 CHECK(counterWMultiCoreDevice->m_Description == "valid description");
1604 CHECK(counterWMultiCoreDevice->m_Units == "");
1605 CHECK(counterWMultiCoreDevice->m_DeviceUid == multiCoreDevice->m_Uid);
1606 CHECK(counterWMultiCoreDevice->m_CounterSetUid == 0);
1607 CHECK(category->m_Counters.size() == 24);
Keith Davis3201eea2019-10-24 17:30:41 +01001608 for (size_t i = 0; i < 4; i++)
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001609 {
Sadik Armagan1625efc2021-06-10 18:24:34 +01001610 CHECK(category->m_Counters[category->m_Counters.size() - 4 + i] == counterWMultiCoreDevice->m_Uid + i);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001611 }
1612
Matteo Martincigh657ab2d2019-09-18 10:53:24 +01001613 // Register a multi-core device associate to a parent category for testing
1614 const std::string multiCoreDeviceNameWParentCategory = "some_multi_core_device_with_parent_category";
Keith Davis3201eea2019-10-24 17:30:41 +01001615 const Device* multiCoreDeviceWParentCategory = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001616 CHECK_NOTHROW(multiCoreDeviceWParentCategory =
Keith Davis3201eea2019-10-24 17:30:41 +01001617 counterDirectory.RegisterDevice(multiCoreDeviceNameWParentCategory, 2, categoryName));
Sadik Armagan1625efc2021-06-10 18:24:34 +01001618 CHECK(counterDirectory.GetDeviceCount() == 3);
1619 CHECK(multiCoreDeviceWParentCategory);
1620 CHECK(multiCoreDeviceWParentCategory->m_Name == multiCoreDeviceNameWParentCategory);
1621 CHECK(multiCoreDeviceWParentCategory->m_Uid >= 1);
1622 CHECK(multiCoreDeviceWParentCategory->m_Cores == 2);
Matteo Martincigh657ab2d2019-09-18 10:53:24 +01001623
1624 // Register a counter with a valid parent category name and getting the number of cores of the multi-core device
1625 // associated to that category
1626 const Counter* counterWMultiCoreDeviceWParentCategory = nullptr;
Sadik Armagan4c998992020-02-25 12:44:44 +00001627 uint16_t numberOfCourse = multiCoreDeviceWParentCategory->m_Cores;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001628 CHECK_NOTHROW(counterWMultiCoreDeviceWParentCategory =
Jim Flynnbbfe6032020-07-20 16:57:44 +01001629 counterDirectory.RegisterCounter(
1630 armnn::profiling::BACKEND_ID,
1631 100,
1632 categoryName,
1633 0,
1634 1,
1635 123.45f,
1636 "valid name 10",
1637 "valid description",
1638 armnn::EmptyOptional(), // Units
1639 numberOfCourse, // Number of cores
1640 armnn::EmptyOptional(), // Device UID
1641 armnn::EmptyOptional()));// Counter set UID
Sadik Armagan1625efc2021-06-10 18:24:34 +01001642 CHECK(counterDirectory.GetCounterCount() == 26);
1643 CHECK(counterWMultiCoreDeviceWParentCategory);
1644 CHECK(counterWMultiCoreDeviceWParentCategory->m_Uid > counter->m_Uid);
1645 CHECK(counterWMultiCoreDeviceWParentCategory->m_MaxCounterUid ==
Matteo Martincigh657ab2d2019-09-18 10:53:24 +01001646 counterWMultiCoreDeviceWParentCategory->m_Uid + multiCoreDeviceWParentCategory->m_Cores - 1);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001647 CHECK(counterWMultiCoreDeviceWParentCategory->m_Class == 0);
1648 CHECK(counterWMultiCoreDeviceWParentCategory->m_Interpolation == 1);
1649 CHECK(counterWMultiCoreDeviceWParentCategory->m_Multiplier == 123.45f);
1650 CHECK(counterWMultiCoreDeviceWParentCategory->m_Name == "valid name 10");
1651 CHECK(counterWMultiCoreDeviceWParentCategory->m_Description == "valid description");
1652 CHECK(counterWMultiCoreDeviceWParentCategory->m_Units == "");
1653 CHECK(category->m_Counters.size() == 26);
Keith Davis3201eea2019-10-24 17:30:41 +01001654 for (size_t i = 0; i < 2; i++)
Matteo Martincigh657ab2d2019-09-18 10:53:24 +01001655 {
Sadik Armagan1625efc2021-06-10 18:24:34 +01001656 CHECK(category->m_Counters[category->m_Counters.size() - 2 + i] ==
Matteo Martincigh657ab2d2019-09-18 10:53:24 +01001657 counterWMultiCoreDeviceWParentCategory->m_Uid + i);
1658 }
1659
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001660 // Register a counter set for testing
1661 const std::string counterSetName = "some_counter_set";
Keith Davis3201eea2019-10-24 17:30:41 +01001662 const CounterSet* counterSet = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001663 CHECK_NOTHROW(counterSet = counterDirectory.RegisterCounterSet(counterSetName));
1664 CHECK(counterDirectory.GetCounterSetCount() == 1);
1665 CHECK(counterSet);
1666 CHECK(counterSet->m_Name == counterSetName);
1667 CHECK(counterSet->m_Uid >= 1);
1668 CHECK(counterSet->m_Count == 0);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001669
1670 // Register a counter with a valid parent category name and associated to a counter set
1671 const Counter* counterWCounterSet = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001672 CHECK_NOTHROW(counterWCounterSet = counterDirectory.RegisterCounter(
Keith Davise394bd92019-12-02 15:12:19 +00001673 armnn::profiling::BACKEND_ID, 300,
Keith Davis3201eea2019-10-24 17:30:41 +01001674 categoryName, 0, 1, 123.45f, "valid name 11", "valid description",
1675 armnn::EmptyOptional(), // Units
1676 0, // Number of cores
1677 armnn::EmptyOptional(), // Device UID
1678 counterSet->m_Uid)); // Counter set UID
Sadik Armagan1625efc2021-06-10 18:24:34 +01001679 CHECK(counterDirectory.GetCounterCount() == 27);
1680 CHECK(counterWCounterSet);
1681 CHECK(counterWCounterSet->m_Uid > counter->m_Uid);
1682 CHECK(counterWCounterSet->m_MaxCounterUid == counterWCounterSet->m_Uid);
1683 CHECK(counterWCounterSet->m_Class == 0);
1684 CHECK(counterWCounterSet->m_Interpolation == 1);
1685 CHECK(counterWCounterSet->m_Multiplier == 123.45f);
1686 CHECK(counterWCounterSet->m_Name == "valid name 11");
1687 CHECK(counterWCounterSet->m_Description == "valid description");
1688 CHECK(counterWCounterSet->m_Units == "");
1689 CHECK(counterWCounterSet->m_DeviceUid == 0);
1690 CHECK(counterWCounterSet->m_CounterSetUid == counterSet->m_Uid);
1691 CHECK(category->m_Counters.size() == 27);
1692 CHECK(category->m_Counters.back() == counterWCounterSet->m_Uid);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001693
1694 // Register a counter with a valid parent category name and associated to a device and a counter set
1695 const Counter* counterWDeviceWCounterSet = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001696 CHECK_NOTHROW(counterWDeviceWCounterSet = counterDirectory.RegisterCounter(
Keith Davise394bd92019-12-02 15:12:19 +00001697 armnn::profiling::BACKEND_ID, 23,
Keith Davis3201eea2019-10-24 17:30:41 +01001698 categoryName, 0, 1, 123.45f, "valid name 12", "valid description",
1699 armnn::EmptyOptional(), // Units
1700 1, // Number of cores
1701 device->m_Uid, // Device UID
1702 counterSet->m_Uid)); // Counter set UID
Sadik Armagan1625efc2021-06-10 18:24:34 +01001703 CHECK(counterDirectory.GetCounterCount() == 28);
1704 CHECK(counterWDeviceWCounterSet);
1705 CHECK(counterWDeviceWCounterSet->m_Uid > counter->m_Uid);
1706 CHECK(counterWDeviceWCounterSet->m_MaxCounterUid == counterWDeviceWCounterSet->m_Uid);
1707 CHECK(counterWDeviceWCounterSet->m_Class == 0);
1708 CHECK(counterWDeviceWCounterSet->m_Interpolation == 1);
1709 CHECK(counterWDeviceWCounterSet->m_Multiplier == 123.45f);
1710 CHECK(counterWDeviceWCounterSet->m_Name == "valid name 12");
1711 CHECK(counterWDeviceWCounterSet->m_Description == "valid description");
1712 CHECK(counterWDeviceWCounterSet->m_Units == "");
1713 CHECK(counterWDeviceWCounterSet->m_DeviceUid == device->m_Uid);
1714 CHECK(counterWDeviceWCounterSet->m_CounterSetUid == counterSet->m_Uid);
1715 CHECK(category->m_Counters.size() == 28);
1716 CHECK(category->m_Counters.back() == counterWDeviceWCounterSet->m_Uid);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001717
1718 // Register another category for testing
1719 const std::string anotherCategoryName = "some_other_category";
Keith Davis3201eea2019-10-24 17:30:41 +01001720 const Category* anotherCategory = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001721 CHECK_NOTHROW(anotherCategory = counterDirectory.RegisterCategory(anotherCategoryName));
1722 CHECK(counterDirectory.GetCategoryCount() == 2);
1723 CHECK(anotherCategory);
1724 CHECK(anotherCategory != category);
1725 CHECK(anotherCategory->m_Name == anotherCategoryName);
1726 CHECK(anotherCategory->m_Counters.empty());
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001727
1728 // Register a counter to the other category
1729 const Counter* anotherCounter = nullptr;
Sadik Armagan1625efc2021-06-10 18:24:34 +01001730 CHECK_NOTHROW(anotherCounter = counterDirectory.RegisterCounter(armnn::profiling::BACKEND_ID, 24,
Keith Davise394bd92019-12-02 15:12:19 +00001731 anotherCategoryName, 1, 0, .00043f,
Keith Davis3201eea2019-10-24 17:30:41 +01001732 "valid name", "valid description",
Jim Flynnbbfe6032020-07-20 16:57:44 +01001733 armnn::EmptyOptional(), // Units
1734 armnn::EmptyOptional(), // Number of cores
1735 device->m_Uid, // Device UID
1736 counterSet->m_Uid)); // Counter set UID
Sadik Armagan1625efc2021-06-10 18:24:34 +01001737 CHECK(counterDirectory.GetCounterCount() == 29);
1738 CHECK(anotherCounter);
1739 CHECK(anotherCounter->m_MaxCounterUid == anotherCounter->m_Uid);
1740 CHECK(anotherCounter->m_Class == 1);
1741 CHECK(anotherCounter->m_Interpolation == 0);
1742 CHECK(anotherCounter->m_Multiplier == .00043f);
1743 CHECK(anotherCounter->m_Name == "valid name");
1744 CHECK(anotherCounter->m_Description == "valid description");
1745 CHECK(anotherCounter->m_Units == "");
1746 CHECK(anotherCounter->m_DeviceUid == device->m_Uid);
1747 CHECK(anotherCounter->m_CounterSetUid == counterSet->m_Uid);
1748 CHECK(anotherCategory->m_Counters.size() == 1);
1749 CHECK(anotherCategory->m_Counters.back() == anotherCounter->m_Uid);
Matteo Martincighab173e92019-09-05 12:02:04 +01001750}
1751
Sadik Armagan1625efc2021-06-10 18:24:34 +01001752TEST_CASE("CounterSelectionCommandHandlerParseData")
Ferran Balaguer1b941722019-08-28 16:57:18 +01001753{
Matteo Martincigh5d737fb2019-10-07 13:05:13 +01001754 ProfilingStateMachine profilingStateMachine;
1755
Ferran Balaguer1b941722019-08-28 16:57:18 +01001756 class TestCaptureThread : public IPeriodicCounterCapture
1757 {
Keith Davis3201eea2019-10-24 17:30:41 +01001758 void Start() override
1759 {}
1760 void Stop() override
1761 {}
Ferran Balaguer1b941722019-08-28 16:57:18 +01001762 };
1763
Matteo Martincighe8485382019-10-10 14:08:21 +01001764 class TestReadCounterValues : public IReadCounterValues
1765 {
Keith Davis3201eea2019-10-24 17:30:41 +01001766 bool IsCounterRegistered(uint16_t counterUid) const override
1767 {
Jan Eilers8eb25602020-03-09 12:13:48 +00001768 armnn::IgnoreUnused(counterUid);
Keith Davis3201eea2019-10-24 17:30:41 +01001769 return true;
1770 }
1771 uint16_t GetCounterCount() const override
1772 {
1773 return 0;
1774 }
Finn Williamsf3fcf322020-05-11 14:38:02 +01001775 uint32_t GetAbsoluteCounterValue(uint16_t counterUid) const override
1776 {
1777 armnn::IgnoreUnused(counterUid);
1778 return 0;
1779 }
1780 uint32_t GetDeltaCounterValue(uint16_t counterUid) override
Keith Davis3201eea2019-10-24 17:30:41 +01001781 {
Jan Eilers8eb25602020-03-09 12:13:48 +00001782 armnn::IgnoreUnused(counterUid);
Keith Davis3201eea2019-10-24 17:30:41 +01001783 return 0;
1784 }
Matteo Martincighe8485382019-10-10 14:08:21 +01001785 };
Jim Flynn397043f2019-10-17 17:37:10 +01001786 const uint32_t familyId = 0;
Ferran Balaguer1b941722019-08-28 16:57:18 +01001787 const uint32_t packetId = 0x40000;
1788
1789 uint32_t version = 1;
Finn Williams032bc742020-02-12 11:02:34 +00001790 const std::unordered_map<armnn::BackendId,
1791 std::shared_ptr<armnn::profiling::IBackendProfilingContext>> backendProfilingContext;
1792 CounterIdMap counterIdMap;
Ferran Balaguer1b941722019-08-28 16:57:18 +01001793 Holder holder;
1794 TestCaptureThread captureThread;
Matteo Martincighe8485382019-10-10 14:08:21 +01001795 TestReadCounterValues readCounterValues;
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01001796 MockBufferManager mockBuffer(512);
Sadik Armagan3896b472020-02-10 12:24:15 +00001797 SendCounterPacket sendCounterPacket(mockBuffer);
1798 SendThread sendThread(profilingStateMachine, mockBuffer, sendCounterPacket);
Ferran Balaguer1b941722019-08-28 16:57:18 +01001799
Matthew Sloyan371b70e2020-09-11 10:14:57 +01001800 uint32_t sizeOfUint32 = armnn::numeric_cast<uint32_t>(sizeof(uint32_t));
1801 uint32_t sizeOfUint16 = armnn::numeric_cast<uint32_t>(sizeof(uint16_t));
Ferran Balaguer1b941722019-08-28 16:57:18 +01001802
1803 // Data with period and counters
Colm Donelan02705242019-11-14 14:19:07 +00001804 uint32_t period1 = armnn::LOWEST_CAPTURE_PERIOD;
Ferran Balaguer1b941722019-08-28 16:57:18 +01001805 uint32_t dataLength1 = 8;
Keith Davis3201eea2019-10-24 17:30:41 +01001806 uint32_t offset = 0;
Ferran Balaguer1b941722019-08-28 16:57:18 +01001807
Matteo Martincigh67ef2a52019-10-10 13:29:02 +01001808 std::unique_ptr<unsigned char[]> uniqueData1 = std::make_unique<unsigned char[]>(dataLength1);
Keith Davis3201eea2019-10-24 17:30:41 +01001809 unsigned char* data1 = reinterpret_cast<unsigned char*>(uniqueData1.get());
FinnWilliamsArma0c78712019-09-16 12:06:47 +01001810
Ferran Balaguer1b941722019-08-28 16:57:18 +01001811 WriteUint32(data1, offset, period1);
1812 offset += sizeOfUint32;
1813 WriteUint16(data1, offset, 4000);
1814 offset += sizeOfUint16;
1815 WriteUint16(data1, offset, 5000);
1816
Jim Flynnbbfe6032020-07-20 16:57:44 +01001817 arm::pipe::Packet packetA(packetId, dataLength1, uniqueData1);
Ferran Balaguer1b941722019-08-28 16:57:18 +01001818
Finn Williams032bc742020-02-12 11:02:34 +00001819 PeriodicCounterSelectionCommandHandler commandHandler(familyId, packetId, version, backendProfilingContext,
1820 counterIdMap, holder, 10000u, captureThread,
Keith Davis3201eea2019-10-24 17:30:41 +01001821 readCounterValues, sendCounterPacket, profilingStateMachine);
Ferran Balaguer1b941722019-08-28 16:57:18 +01001822
Matteo Martincighe8485382019-10-10 14:08:21 +01001823 profilingStateMachine.TransitionToState(ProfilingState::Uninitialised);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001824 CHECK_THROWS_AS(commandHandler(packetA), armnn::RuntimeException);
Matteo Martincighe8485382019-10-10 14:08:21 +01001825 profilingStateMachine.TransitionToState(ProfilingState::NotConnected);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001826 CHECK_THROWS_AS(commandHandler(packetA), armnn::RuntimeException);
Matteo Martincighe8485382019-10-10 14:08:21 +01001827 profilingStateMachine.TransitionToState(ProfilingState::WaitingForAck);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001828 CHECK_THROWS_AS(commandHandler(packetA), armnn::RuntimeException);
Matteo Martincighe8485382019-10-10 14:08:21 +01001829 profilingStateMachine.TransitionToState(ProfilingState::Active);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001830 CHECK_NOTHROW(commandHandler(packetA));
Matteo Martincighe8485382019-10-10 14:08:21 +01001831
1832 const std::vector<uint16_t> counterIdsA = holder.GetCaptureData().GetCounterIds();
Ferran Balaguer1b941722019-08-28 16:57:18 +01001833
Sadik Armagan1625efc2021-06-10 18:24:34 +01001834 CHECK(holder.GetCaptureData().GetCapturePeriod() == period1);
1835 CHECK(counterIdsA.size() == 2);
1836 CHECK(counterIdsA[0] == 4000);
1837 CHECK(counterIdsA[1] == 5000);
Ferran Balaguer1b941722019-08-28 16:57:18 +01001838
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01001839 auto readBuffer = mockBuffer.GetReadableBuffer();
Ferran Balaguer1b941722019-08-28 16:57:18 +01001840
1841 offset = 0;
1842
1843 uint32_t headerWord0 = ReadUint32(readBuffer, offset);
1844 offset += sizeOfUint32;
1845 uint32_t headerWord1 = ReadUint32(readBuffer, offset);
1846 offset += sizeOfUint32;
1847 uint32_t period = ReadUint32(readBuffer, offset);
1848
Sadik Armagan1625efc2021-06-10 18:24:34 +01001849 CHECK(((headerWord0 >> 26) & 0x3F) == 0); // packet family
1850 CHECK(((headerWord0 >> 16) & 0x3FF) == 4); // packet id
1851 CHECK(headerWord1 == 8); // data length
1852 CHECK(period == armnn::LOWEST_CAPTURE_PERIOD); // capture period
Ferran Balaguer1b941722019-08-28 16:57:18 +01001853
1854 uint16_t counterId = 0;
1855 offset += sizeOfUint32;
1856 counterId = ReadUint16(readBuffer, offset);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001857 CHECK(counterId == 4000);
Ferran Balaguer1b941722019-08-28 16:57:18 +01001858 offset += sizeOfUint16;
1859 counterId = ReadUint16(readBuffer, offset);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001860 CHECK(counterId == 5000);
Ferran Balaguer1b941722019-08-28 16:57:18 +01001861
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01001862 mockBuffer.MarkRead(readBuffer);
1863
Ferran Balaguer1b941722019-08-28 16:57:18 +01001864 // Data with period only
Colm Donelan02705242019-11-14 14:19:07 +00001865 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 +01001866 uint32_t dataLength2 = 4;
Ferran Balaguer1b941722019-08-28 16:57:18 +01001867
Matteo Martincigh67ef2a52019-10-10 13:29:02 +01001868 std::unique_ptr<unsigned char[]> uniqueData2 = std::make_unique<unsigned char[]>(dataLength2);
Ferran Balaguer1b941722019-08-28 16:57:18 +01001869
FinnWilliamsArma0c78712019-09-16 12:06:47 +01001870 WriteUint32(reinterpret_cast<unsigned char*>(uniqueData2.get()), 0, period2);
1871
Jim Flynnbbfe6032020-07-20 16:57:44 +01001872 arm::pipe::Packet packetB(packetId, dataLength2, uniqueData2);
Ferran Balaguer1b941722019-08-28 16:57:18 +01001873
1874 commandHandler(packetB);
1875
Matteo Martincighe8485382019-10-10 14:08:21 +01001876 const std::vector<uint16_t> counterIdsB = holder.GetCaptureData().GetCounterIds();
Ferran Balaguer1b941722019-08-28 16:57:18 +01001877
Colm Donelan02705242019-11-14 14:19:07 +00001878 // Value should have been pulled up from 9000 to LOWEST_CAPTURE_PERIOD.
Sadik Armagan1625efc2021-06-10 18:24:34 +01001879 CHECK(holder.GetCaptureData().GetCapturePeriod() == armnn::LOWEST_CAPTURE_PERIOD);
1880 CHECK(counterIdsB.size() == 0);
Ferran Balaguer1b941722019-08-28 16:57:18 +01001881
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01001882 readBuffer = mockBuffer.GetReadableBuffer();
Ferran Balaguer1b941722019-08-28 16:57:18 +01001883
1884 offset = 0;
1885
1886 headerWord0 = ReadUint32(readBuffer, offset);
1887 offset += sizeOfUint32;
1888 headerWord1 = ReadUint32(readBuffer, offset);
1889 offset += sizeOfUint32;
1890 period = ReadUint32(readBuffer, offset);
1891
Sadik Armagan1625efc2021-06-10 18:24:34 +01001892 CHECK(((headerWord0 >> 26) & 0x3F) == 0); // packet family
1893 CHECK(((headerWord0 >> 16) & 0x3FF) == 4); // packet id
1894 CHECK(headerWord1 == 4); // data length
1895 CHECK(period == armnn::LOWEST_CAPTURE_PERIOD); // capture period
Ferran Balaguer1b941722019-08-28 16:57:18 +01001896}
1897
Sadik Armagan1625efc2021-06-10 18:24:34 +01001898TEST_CASE("CheckTimelineActivationAndDeactivation")
Keith Davis33ed2212020-03-30 10:43:41 +01001899{
1900 class TestReportStructure : public IReportStructure
1901 {
1902 public:
1903 virtual void ReportStructure() override
1904 {
1905 m_ReportStructureCalled = true;
1906 }
1907
1908 bool m_ReportStructureCalled = false;
1909 };
1910
1911 class TestNotifyBackends : public INotifyBackends
1912 {
1913 public:
1914 TestNotifyBackends() : m_timelineReporting(false) {}
1915 virtual void NotifyBackendsForTimelineReporting() override
1916 {
1917 m_TestNotifyBackendsCalled = m_timelineReporting.load();
1918 }
1919
1920 bool m_TestNotifyBackendsCalled = false;
1921 std::atomic<bool> m_timelineReporting;
1922 };
1923
Jim Flynnbbfe6032020-07-20 16:57:44 +01001924 arm::pipe::PacketVersionResolver packetVersionResolver;
Keith Davis33ed2212020-03-30 10:43:41 +01001925
1926 BufferManager bufferManager(512);
1927 SendTimelinePacket sendTimelinePacket(bufferManager);
1928 ProfilingStateMachine stateMachine;
1929 TestReportStructure testReportStructure;
1930 TestNotifyBackends testNotifyBackends;
1931
1932 profiling::ActivateTimelineReportingCommandHandler activateTimelineReportingCommandHandler(0,
1933 6,
1934 packetVersionResolver.ResolvePacketVersion(0, 6)
1935 .GetEncodedValue(),
1936 sendTimelinePacket,
1937 stateMachine,
1938 testReportStructure,
1939 testNotifyBackends.m_timelineReporting,
1940 testNotifyBackends);
1941
1942 // Write an "ActivateTimelineReporting" packet into the mock profiling connection, to simulate an input from an
1943 // external profiling service
1944 const uint32_t packetFamily1 = 0;
1945 const uint32_t packetId1 = 6;
1946 uint32_t packetHeader1 = ConstructHeader(packetFamily1, packetId1);
1947
1948 // Create the ActivateTimelineReportingPacket
Jim Flynnbbfe6032020-07-20 16:57:44 +01001949 arm::pipe::Packet ActivateTimelineReportingPacket(packetHeader1); // Length == 0
Keith Davis33ed2212020-03-30 10:43:41 +01001950
Sadik Armagan1625efc2021-06-10 18:24:34 +01001951 CHECK_THROWS_AS(
Keith Davis33ed2212020-03-30 10:43:41 +01001952 activateTimelineReportingCommandHandler.operator()(ActivateTimelineReportingPacket), armnn::Exception);
1953
1954 stateMachine.TransitionToState(ProfilingState::NotConnected);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001955 CHECK_THROWS_AS(
Keith Davis33ed2212020-03-30 10:43:41 +01001956 activateTimelineReportingCommandHandler.operator()(ActivateTimelineReportingPacket), armnn::Exception);
1957
1958 stateMachine.TransitionToState(ProfilingState::WaitingForAck);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001959 CHECK_THROWS_AS(
Keith Davis33ed2212020-03-30 10:43:41 +01001960 activateTimelineReportingCommandHandler.operator()(ActivateTimelineReportingPacket), armnn::Exception);
1961
1962 stateMachine.TransitionToState(ProfilingState::Active);
1963 activateTimelineReportingCommandHandler.operator()(ActivateTimelineReportingPacket);
1964
Sadik Armagan1625efc2021-06-10 18:24:34 +01001965 CHECK(testReportStructure.m_ReportStructureCalled);
1966 CHECK(testNotifyBackends.m_TestNotifyBackendsCalled);
1967 CHECK(testNotifyBackends.m_timelineReporting.load());
Keith Davis33ed2212020-03-30 10:43:41 +01001968
1969 DeactivateTimelineReportingCommandHandler deactivateTimelineReportingCommandHandler(0,
1970 7,
1971 packetVersionResolver.ResolvePacketVersion(0, 7).GetEncodedValue(),
1972 testNotifyBackends.m_timelineReporting,
1973 stateMachine,
1974 testNotifyBackends);
1975
1976 const uint32_t packetFamily2 = 0;
1977 const uint32_t packetId2 = 7;
1978 uint32_t packetHeader2 = ConstructHeader(packetFamily2, packetId2);
1979
1980 // Create the DeactivateTimelineReportingPacket
Jim Flynnbbfe6032020-07-20 16:57:44 +01001981 arm::pipe::Packet deactivateTimelineReportingPacket(packetHeader2); // Length == 0
Keith Davis33ed2212020-03-30 10:43:41 +01001982
1983 stateMachine.Reset();
Sadik Armagan1625efc2021-06-10 18:24:34 +01001984 CHECK_THROWS_AS(
Keith Davis33ed2212020-03-30 10:43:41 +01001985 deactivateTimelineReportingCommandHandler.operator()(deactivateTimelineReportingPacket), armnn::Exception);
1986
1987 stateMachine.TransitionToState(ProfilingState::NotConnected);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001988 CHECK_THROWS_AS(
Keith Davis33ed2212020-03-30 10:43:41 +01001989 deactivateTimelineReportingCommandHandler.operator()(deactivateTimelineReportingPacket), armnn::Exception);
1990
1991 stateMachine.TransitionToState(ProfilingState::WaitingForAck);
Sadik Armagan1625efc2021-06-10 18:24:34 +01001992 CHECK_THROWS_AS(
Keith Davis33ed2212020-03-30 10:43:41 +01001993 deactivateTimelineReportingCommandHandler.operator()(deactivateTimelineReportingPacket), armnn::Exception);
1994
1995 stateMachine.TransitionToState(ProfilingState::Active);
1996 deactivateTimelineReportingCommandHandler.operator()(deactivateTimelineReportingPacket);
1997
Sadik Armagan1625efc2021-06-10 18:24:34 +01001998 CHECK(!testNotifyBackends.m_TestNotifyBackendsCalled);
1999 CHECK(!testNotifyBackends.m_timelineReporting.load());
Keith Davis33ed2212020-03-30 10:43:41 +01002000}
2001
Sadik Armagan1625efc2021-06-10 18:24:34 +01002002TEST_CASE("CheckProfilingServiceNotActive")
Keith Davis33ed2212020-03-30 10:43:41 +01002003{
2004 using namespace armnn;
2005 using namespace armnn::profiling;
2006
2007 // Create runtime in which the test will run
2008 armnn::IRuntime::CreationOptions options;
2009 options.m_ProfilingOptions.m_EnableProfiling = true;
2010
Kevin Mayd92a6e42021-02-04 10:27:41 +00002011 armnn::RuntimeImpl runtime(options);
Keith Davis33ed2212020-03-30 10:43:41 +01002012 profiling::ProfilingServiceRuntimeHelper profilingServiceHelper(GetProfilingService(&runtime));
2013 profilingServiceHelper.ForceTransitionToState(ProfilingState::NotConnected);
2014 profilingServiceHelper.ForceTransitionToState(ProfilingState::WaitingForAck);
2015 profilingServiceHelper.ForceTransitionToState(ProfilingState::Active);
2016
2017 profiling::BufferManager& bufferManager = profilingServiceHelper.GetProfilingBufferManager();
2018 auto readableBuffer = bufferManager.GetReadableBuffer();
2019
2020 // Profiling is enabled, the post-optimisation structure should be created
Sadik Armagan1625efc2021-06-10 18:24:34 +01002021 CHECK(readableBuffer == nullptr);
Keith Davis33ed2212020-03-30 10:43:41 +01002022}
2023
Sadik Armagan1625efc2021-06-10 18:24:34 +01002024TEST_CASE("CheckConnectionAcknowledged")
Sadik Armaganb5f01b22019-09-18 17:29:00 +01002025{
Keith Davis3201eea2019-10-24 17:30:41 +01002026 const uint32_t packetFamilyId = 0;
Sadik Armaganb5f01b22019-09-18 17:29:00 +01002027 const uint32_t connectionPacketId = 0x10000;
Keith Davis3201eea2019-10-24 17:30:41 +01002028 const uint32_t version = 1;
Sadik Armaganb5f01b22019-09-18 17:29:00 +01002029
Matthew Sloyan371b70e2020-09-11 10:14:57 +01002030 uint32_t sizeOfUint32 = armnn::numeric_cast<uint32_t>(sizeof(uint32_t));
2031 uint32_t sizeOfUint16 = armnn::numeric_cast<uint32_t>(sizeof(uint16_t));
Sadik Armaganb5f01b22019-09-18 17:29:00 +01002032
2033 // Data with period and counters
Keith Davis3201eea2019-10-24 17:30:41 +01002034 uint32_t period1 = 10;
Sadik Armaganb5f01b22019-09-18 17:29:00 +01002035 uint32_t dataLength1 = 8;
Keith Davis3201eea2019-10-24 17:30:41 +01002036 uint32_t offset = 0;
Sadik Armaganb5f01b22019-09-18 17:29:00 +01002037
Matteo Martincigh67ef2a52019-10-10 13:29:02 +01002038 std::unique_ptr<unsigned char[]> uniqueData1 = std::make_unique<unsigned char[]>(dataLength1);
Keith Davis3201eea2019-10-24 17:30:41 +01002039 unsigned char* data1 = reinterpret_cast<unsigned char*>(uniqueData1.get());
Sadik Armaganb5f01b22019-09-18 17:29:00 +01002040
2041 WriteUint32(data1, offset, period1);
2042 offset += sizeOfUint32;
2043 WriteUint16(data1, offset, 4000);
2044 offset += sizeOfUint16;
2045 WriteUint16(data1, offset, 5000);
2046
Jim Flynnbbfe6032020-07-20 16:57:44 +01002047 arm::pipe::Packet packetA(connectionPacketId, dataLength1, uniqueData1);
Sadik Armaganb5f01b22019-09-18 17:29:00 +01002048
2049 ProfilingStateMachine profilingState(ProfilingState::Uninitialised);
Sadik Armagan1625efc2021-06-10 18:24:34 +01002050 CHECK(profilingState.GetCurrentState() == ProfilingState::Uninitialised);
Keith Davis3201eea2019-10-24 17:30:41 +01002051 CounterDirectory counterDirectory;
2052 MockBufferManager mockBuffer(1024);
Sadik Armagan3896b472020-02-10 12:24:15 +00002053 SendCounterPacket sendCounterPacket(mockBuffer);
2054 SendThread sendThread(profilingState, mockBuffer, sendCounterPacket);
Matteo Martincighcdfb9412019-11-08 11:23:06 +00002055 SendTimelinePacket sendTimelinePacket(mockBuffer);
Jim Flynn6398a982020-05-27 17:05:21 +01002056 MockProfilingServiceStatus mockProfilingServiceStatus;
Sadik Armaganb5f01b22019-09-18 17:29:00 +01002057
Jim Flynn6398a982020-05-27 17:05:21 +01002058 ConnectionAcknowledgedCommandHandler commandHandler(packetFamilyId,
2059 connectionPacketId,
2060 version,
2061 counterDirectory,
2062 sendCounterPacket,
2063 sendTimelinePacket,
2064 profilingState,
2065 mockProfilingServiceStatus);
Sadik Armaganb5f01b22019-09-18 17:29:00 +01002066
2067 // command handler received packet on ProfilingState::Uninitialised
Sadik Armagan1625efc2021-06-10 18:24:34 +01002068 CHECK_THROWS_AS(commandHandler(packetA), armnn::Exception);
Sadik Armaganb5f01b22019-09-18 17:29:00 +01002069
2070 profilingState.TransitionToState(ProfilingState::NotConnected);
Sadik Armagan1625efc2021-06-10 18:24:34 +01002071 CHECK(profilingState.GetCurrentState() == ProfilingState::NotConnected);
Sadik Armaganb5f01b22019-09-18 17:29:00 +01002072 // command handler received packet on ProfilingState::NotConnected
Sadik Armagan1625efc2021-06-10 18:24:34 +01002073 CHECK_THROWS_AS(commandHandler(packetA), armnn::Exception);
Sadik Armaganb5f01b22019-09-18 17:29:00 +01002074
2075 profilingState.TransitionToState(ProfilingState::WaitingForAck);
Sadik Armagan1625efc2021-06-10 18:24:34 +01002076 CHECK(profilingState.GetCurrentState() == ProfilingState::WaitingForAck);
Sadik Armaganb5f01b22019-09-18 17:29:00 +01002077 // command handler received packet on ProfilingState::WaitingForAck
Sadik Armagan1625efc2021-06-10 18:24:34 +01002078 CHECK_NOTHROW(commandHandler(packetA));
2079 CHECK(profilingState.GetCurrentState() == ProfilingState::Active);
Sadik Armaganb5f01b22019-09-18 17:29:00 +01002080
2081 // command handler received packet on ProfilingState::Active
Sadik Armagan1625efc2021-06-10 18:24:34 +01002082 CHECK_NOTHROW(commandHandler(packetA));
2083 CHECK(profilingState.GetCurrentState() == ProfilingState::Active);
Sadik Armaganb5f01b22019-09-18 17:29:00 +01002084
2085 // command handler received different packet
2086 const uint32_t differentPacketId = 0x40000;
Jim Flynnbbfe6032020-07-20 16:57:44 +01002087 arm::pipe::Packet packetB(differentPacketId, dataLength1, uniqueData1);
Matteo Martincighd0613b52019-10-09 16:47:04 +01002088 profilingState.TransitionToState(ProfilingState::NotConnected);
2089 profilingState.TransitionToState(ProfilingState::WaitingForAck);
Jim Flynn6398a982020-05-27 17:05:21 +01002090 ConnectionAcknowledgedCommandHandler differentCommandHandler(packetFamilyId,
2091 differentPacketId,
2092 version,
2093 counterDirectory,
2094 sendCounterPacket,
2095 sendTimelinePacket,
2096 profilingState,
2097 mockProfilingServiceStatus);
Sadik Armagan1625efc2021-06-10 18:24:34 +01002098 CHECK_THROWS_AS(differentCommandHandler(packetB), armnn::Exception);
Sadik Armaganb5f01b22019-09-18 17:29:00 +01002099}
2100
Sadik Armagan1625efc2021-06-10 18:24:34 +01002101TEST_CASE("CheckSocketConnectionException")
Teresa Charlin9bab4962019-09-06 12:28:35 +01002102{
Sadik Armagana97a0be2020-03-03 10:44:56 +00002103 // Check that creating a SocketProfilingConnection armnnProfiling in an exception as the Gator UDS doesn't exist.
Sadik Armagan1625efc2021-06-10 18:24:34 +01002104 CHECK_THROWS_AS(new SocketProfilingConnection(), arm::pipe::SocketConnectionException);
Sadik Armagana97a0be2020-03-03 10:44:56 +00002105}
2106
Sadik Armagan1625efc2021-06-10 18:24:34 +01002107TEST_CASE("CheckSocketConnectionException2")
Sadik Armagana97a0be2020-03-03 10:44:56 +00002108{
2109 try
2110 {
2111 new SocketProfilingConnection();
2112 }
Jim Flynnbbfe6032020-07-20 16:57:44 +01002113 catch (const arm::pipe::SocketConnectionException& ex)
Sadik Armagana97a0be2020-03-03 10:44:56 +00002114 {
Sadik Armagan1625efc2021-06-10 18:24:34 +01002115 CHECK(ex.GetSocketFd() == 0);
2116 CHECK(ex.GetErrorNo() == ECONNREFUSED);
2117 CHECK(ex.what()
Sadik Armagana97a0be2020-03-03 10:44:56 +00002118 == std::string("SocketProfilingConnection: Cannot connect to stream socket: Connection refused"));
2119 }
Teresa Charlin9bab4962019-09-06 12:28:35 +01002120}
2121
Sadik Armagan1625efc2021-06-10 18:24:34 +01002122TEST_CASE("SwTraceIsValidCharTest")
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01002123{
2124 // Only ASCII 7-bit encoding supported
2125 for (unsigned char c = 0; c < 128; c++)
2126 {
Sadik Armagan1625efc2021-06-10 18:24:34 +01002127 CHECK(arm::pipe::SwTraceCharPolicy::IsValidChar(c));
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01002128 }
2129
2130 // Not ASCII
2131 for (unsigned char c = 255; c >= 128; c++)
2132 {
Sadik Armagan1625efc2021-06-10 18:24:34 +01002133 CHECK(!arm::pipe::SwTraceCharPolicy::IsValidChar(c));
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01002134 }
2135}
2136
Sadik Armagan1625efc2021-06-10 18:24:34 +01002137TEST_CASE("SwTraceIsValidNameCharTest")
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01002138{
2139 // Only alpha-numeric and underscore ASCII 7-bit encoding supported
2140 const unsigned char validChars[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_";
2141 for (unsigned char i = 0; i < sizeof(validChars) / sizeof(validChars[0]) - 1; i++)
2142 {
Sadik Armagan1625efc2021-06-10 18:24:34 +01002143 CHECK(arm::pipe::SwTraceNameCharPolicy::IsValidChar(validChars[i]));
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01002144 }
2145
2146 // Non alpha-numeric chars
2147 for (unsigned char c = 0; c < 48; c++)
2148 {
Sadik Armagan1625efc2021-06-10 18:24:34 +01002149 CHECK(!arm::pipe::SwTraceNameCharPolicy::IsValidChar(c));
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01002150 }
2151 for (unsigned char c = 58; c < 65; c++)
2152 {
Sadik Armagan1625efc2021-06-10 18:24:34 +01002153 CHECK(!arm::pipe::SwTraceNameCharPolicy::IsValidChar(c));
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01002154 }
2155 for (unsigned char c = 91; c < 95; c++)
2156 {
Sadik Armagan1625efc2021-06-10 18:24:34 +01002157 CHECK(!arm::pipe::SwTraceNameCharPolicy::IsValidChar(c));
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01002158 }
2159 for (unsigned char c = 96; c < 97; c++)
2160 {
Sadik Armagan1625efc2021-06-10 18:24:34 +01002161 CHECK(!arm::pipe::SwTraceNameCharPolicy::IsValidChar(c));
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01002162 }
2163 for (unsigned char c = 123; c < 128; c++)
2164 {
Sadik Armagan1625efc2021-06-10 18:24:34 +01002165 CHECK(!arm::pipe::SwTraceNameCharPolicy::IsValidChar(c));
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01002166 }
2167
2168 // Not ASCII
2169 for (unsigned char c = 255; c >= 128; c++)
2170 {
Sadik Armagan1625efc2021-06-10 18:24:34 +01002171 CHECK(!arm::pipe::SwTraceNameCharPolicy::IsValidChar(c));
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01002172 }
2173}
2174
Sadik Armagan1625efc2021-06-10 18:24:34 +01002175TEST_CASE("IsValidSwTraceStringTest")
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01002176{
2177 // Valid SWTrace strings
Sadik Armagan1625efc2021-06-10 18:24:34 +01002178 CHECK(arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceCharPolicy>(""));
2179 CHECK(arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceCharPolicy>("_"));
2180 CHECK(arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceCharPolicy>("0123"));
2181 CHECK(arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceCharPolicy>("valid_string"));
2182 CHECK(arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceCharPolicy>("VALID_string_456"));
2183 CHECK(arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceCharPolicy>(" "));
2184 CHECK(arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceCharPolicy>("valid string"));
2185 CHECK(arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceCharPolicy>("!$%"));
2186 CHECK(arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceCharPolicy>("valid|\\~string#123"));
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01002187
2188 // Invalid SWTrace strings
Sadik Armagan1625efc2021-06-10 18:24:34 +01002189 CHECK(!arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceCharPolicy>("€£"));
2190 CHECK(!arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceCharPolicy>("invalid‡string"));
2191 CHECK(!arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceCharPolicy>("12Ž34"));
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01002192}
2193
Sadik Armagan1625efc2021-06-10 18:24:34 +01002194TEST_CASE("IsValidSwTraceNameStringTest")
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01002195{
2196 // Valid SWTrace name strings
Sadik Armagan1625efc2021-06-10 18:24:34 +01002197 CHECK(arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceNameCharPolicy>(""));
2198 CHECK(arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceNameCharPolicy>("_"));
2199 CHECK(arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceNameCharPolicy>("0123"));
2200 CHECK(arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceNameCharPolicy>("valid_string"));
2201 CHECK(arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceNameCharPolicy>("VALID_string_456"));
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01002202
2203 // Invalid SWTrace name strings
Sadik Armagan1625efc2021-06-10 18:24:34 +01002204 CHECK(!arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceNameCharPolicy>(" "));
2205 CHECK(!arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceNameCharPolicy>("invalid string"));
2206 CHECK(!arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceNameCharPolicy>("!$%"));
2207 CHECK(!arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceNameCharPolicy>("invalid|\\~string#123"));
2208 CHECK(!arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceNameCharPolicy>("€£"));
2209 CHECK(!arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceNameCharPolicy>("invalid‡string"));
2210 CHECK(!arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceNameCharPolicy>("12Ž34"));
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01002211}
2212
2213template <typename SwTracePolicy>
2214void StringToSwTraceStringTestHelper(const std::string& testString, std::vector<uint32_t> buffer, size_t expectedSize)
2215{
2216 // Convert the test string to a SWTrace string
Sadik Armagan1625efc2021-06-10 18:24:34 +01002217 CHECK(arm::pipe::StringToSwTraceString<SwTracePolicy>(testString, buffer));
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01002218
2219 // The buffer must contain at least the length of the string
Sadik Armagan1625efc2021-06-10 18:24:34 +01002220 CHECK(!buffer.empty());
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01002221
2222 // The buffer must be of the expected size (in words)
Sadik Armagan1625efc2021-06-10 18:24:34 +01002223 CHECK(buffer.size() == expectedSize);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01002224
2225 // The first word of the byte must be the length of the string including the null-terminator
Sadik Armagan1625efc2021-06-10 18:24:34 +01002226 CHECK(buffer[0] == testString.size() + 1);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01002227
2228 // The contents of the buffer must match the test string
Sadik Armagan1625efc2021-06-10 18:24:34 +01002229 CHECK(std::memcmp(testString.data(), buffer.data() + 1, testString.size()) == 0);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01002230
2231 // The buffer must include the null-terminator at the end of the string
2232 size_t nullTerminatorIndex = sizeof(uint32_t) + testString.size();
Sadik Armagan1625efc2021-06-10 18:24:34 +01002233 CHECK(reinterpret_cast<unsigned char*>(buffer.data())[nullTerminatorIndex] == '\0');
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01002234}
2235
Sadik Armagan1625efc2021-06-10 18:24:34 +01002236TEST_CASE("StringToSwTraceStringTest")
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01002237{
2238 std::vector<uint32_t> buffer;
2239
2240 // Valid SWTrace strings (expected size in words)
Jim Flynnbbfe6032020-07-20 16:57:44 +01002241 StringToSwTraceStringTestHelper<arm::pipe::SwTraceCharPolicy>("", buffer, 2);
2242 StringToSwTraceStringTestHelper<arm::pipe::SwTraceCharPolicy>("_", buffer, 2);
2243 StringToSwTraceStringTestHelper<arm::pipe::SwTraceCharPolicy>("0123", buffer, 3);
2244 StringToSwTraceStringTestHelper<arm::pipe::SwTraceCharPolicy>("valid_string", buffer, 5);
2245 StringToSwTraceStringTestHelper<arm::pipe::SwTraceCharPolicy>("VALID_string_456", buffer, 6);
2246 StringToSwTraceStringTestHelper<arm::pipe::SwTraceCharPolicy>(" ", buffer, 2);
2247 StringToSwTraceStringTestHelper<arm::pipe::SwTraceCharPolicy>("valid string", buffer, 5);
2248 StringToSwTraceStringTestHelper<arm::pipe::SwTraceCharPolicy>("!$%", buffer, 2);
2249 StringToSwTraceStringTestHelper<arm::pipe::SwTraceCharPolicy>("valid|\\~string#123", buffer, 6);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01002250
2251 // Invalid SWTrace strings
Sadik Armagan1625efc2021-06-10 18:24:34 +01002252 CHECK(!arm::pipe::StringToSwTraceString<arm::pipe::SwTraceCharPolicy>("€£", buffer));
2253 CHECK(buffer.empty());
2254 CHECK(!arm::pipe::StringToSwTraceString<arm::pipe::SwTraceCharPolicy>("invalid‡string", buffer));
2255 CHECK(buffer.empty());
2256 CHECK(!arm::pipe::StringToSwTraceString<arm::pipe::SwTraceCharPolicy>("12Ž34", buffer));
2257 CHECK(buffer.empty());
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01002258}
2259
Sadik Armagan1625efc2021-06-10 18:24:34 +01002260TEST_CASE("StringToSwTraceNameStringTest")
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01002261{
2262 std::vector<uint32_t> buffer;
2263
2264 // Valid SWTrace namestrings (expected size in words)
Jim Flynnbbfe6032020-07-20 16:57:44 +01002265 StringToSwTraceStringTestHelper<arm::pipe::SwTraceNameCharPolicy>("", buffer, 2);
2266 StringToSwTraceStringTestHelper<arm::pipe::SwTraceNameCharPolicy>("_", buffer, 2);
2267 StringToSwTraceStringTestHelper<arm::pipe::SwTraceNameCharPolicy>("0123", buffer, 3);
2268 StringToSwTraceStringTestHelper<arm::pipe::SwTraceNameCharPolicy>("valid_string", buffer, 5);
2269 StringToSwTraceStringTestHelper<arm::pipe::SwTraceNameCharPolicy>("VALID_string_456", buffer, 6);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01002270
2271 // Invalid SWTrace namestrings
Sadik Armagan1625efc2021-06-10 18:24:34 +01002272 CHECK(!arm::pipe::StringToSwTraceString<arm::pipe::SwTraceNameCharPolicy>(" ", buffer));
2273 CHECK(buffer.empty());
2274 CHECK(!arm::pipe::StringToSwTraceString<arm::pipe::SwTraceNameCharPolicy>("invalid string", buffer));
2275 CHECK(buffer.empty());
2276 CHECK(!arm::pipe::StringToSwTraceString<arm::pipe::SwTraceNameCharPolicy>("!$%", buffer));
2277 CHECK(buffer.empty());
2278 CHECK(!arm::pipe::StringToSwTraceString<arm::pipe::SwTraceNameCharPolicy>("invalid|\\~string#123", buffer));
2279 CHECK(buffer.empty());
2280 CHECK(!arm::pipe::StringToSwTraceString<arm::pipe::SwTraceNameCharPolicy>("€£", buffer));
2281 CHECK(buffer.empty());
2282 CHECK(!arm::pipe::StringToSwTraceString<arm::pipe::SwTraceNameCharPolicy>("invalid‡string", buffer));
2283 CHECK(buffer.empty());
2284 CHECK(!arm::pipe::StringToSwTraceString<arm::pipe::SwTraceNameCharPolicy>("12Ž34", buffer));
2285 CHECK(buffer.empty());
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01002286}
2287
Sadik Armagan1625efc2021-06-10 18:24:34 +01002288TEST_CASE("CheckPeriodicCounterCaptureThread")
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002289{
Matteo Martincighe0e6efc2019-10-04 17:17:42 +01002290 class CaptureReader : public IReadCounterValues
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002291 {
2292 public:
Finn Williamsf4d59a62019-10-14 15:55:18 +01002293 CaptureReader(uint16_t counterSize)
2294 {
Keith Davis3201eea2019-10-24 17:30:41 +01002295 for (uint16_t i = 0; i < counterSize; ++i)
Finn Williamsf4d59a62019-10-14 15:55:18 +01002296 {
2297 m_Data[i] = 0;
2298 }
2299 m_CounterSize = counterSize;
2300 }
2301 //not used
Matteo Martincighe8485382019-10-10 14:08:21 +01002302 bool IsCounterRegistered(uint16_t counterUid) const override
2303 {
Jan Eilers8eb25602020-03-09 12:13:48 +00002304 armnn::IgnoreUnused(counterUid);
Finn Williamsf4d59a62019-10-14 15:55:18 +01002305 return false;
Matteo Martincighe8485382019-10-10 14:08:21 +01002306 }
2307
Matteo Martincighe0e6efc2019-10-04 17:17:42 +01002308 uint16_t GetCounterCount() const override
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002309 {
Finn Williamsf4d59a62019-10-14 15:55:18 +01002310 return m_CounterSize;
Matteo Martincighe0e6efc2019-10-04 17:17:42 +01002311 }
2312
Finn Williamsf3fcf322020-05-11 14:38:02 +01002313 uint32_t GetAbsoluteCounterValue(uint16_t counterUid) const override
2314 {
2315 if (counterUid > m_CounterSize)
2316 {
Sadik Armagan1625efc2021-06-10 18:24:34 +01002317 FAIL("Invalid counter Uid");
Finn Williamsf3fcf322020-05-11 14:38:02 +01002318 }
2319 return m_Data.at(counterUid).load();
2320 }
2321
2322 uint32_t GetDeltaCounterValue(uint16_t counterUid) override
Matteo Martincighe0e6efc2019-10-04 17:17:42 +01002323 {
Keith Davis3201eea2019-10-24 17:30:41 +01002324 if (counterUid > m_CounterSize)
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002325 {
Sadik Armagan1625efc2021-06-10 18:24:34 +01002326 FAIL("Invalid counter Uid");
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002327 }
Matteo Martincighe8485382019-10-10 14:08:21 +01002328 return m_Data.at(counterUid).load();
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002329 }
2330
Matteo Martincighe8485382019-10-10 14:08:21 +01002331 void SetCounterValue(uint16_t counterUid, uint32_t value)
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002332 {
Keith Davis3201eea2019-10-24 17:30:41 +01002333 if (counterUid > m_CounterSize)
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002334 {
Sadik Armagan1625efc2021-06-10 18:24:34 +01002335 FAIL("Invalid counter Uid");
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002336 }
Finn Williamsf4d59a62019-10-14 15:55:18 +01002337 m_Data.at(counterUid).store(value);
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002338 }
2339
2340 private:
Matteo Martincighe8485382019-10-10 14:08:21 +01002341 std::unordered_map<uint16_t, std::atomic<uint32_t>> m_Data;
Finn Williamsf4d59a62019-10-14 15:55:18 +01002342 uint16_t m_CounterSize;
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002343 };
2344
Matteo Martincigh5d737fb2019-10-07 13:05:13 +01002345 ProfilingStateMachine profilingStateMachine;
2346
Finn Williams032bc742020-02-12 11:02:34 +00002347 const std::unordered_map<armnn::BackendId,
2348 std::shared_ptr<armnn::profiling::IBackendProfilingContext>> backendProfilingContext;
2349 CounterIdMap counterIdMap;
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002350 Holder data;
2351 std::vector<uint16_t> captureIds1 = { 0, 1 };
2352 std::vector<uint16_t> captureIds2;
2353
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01002354 MockBufferManager mockBuffer(512);
Sadik Armagan3896b472020-02-10 12:24:15 +00002355 SendCounterPacket sendCounterPacket(mockBuffer);
2356 SendThread sendThread(profilingStateMachine, mockBuffer, sendCounterPacket);
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002357
2358 std::vector<uint16_t> counterIds;
Finn Williamsf4d59a62019-10-14 15:55:18 +01002359 CaptureReader captureReader(2);
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002360
Keith Davis3201eea2019-10-24 17:30:41 +01002361 unsigned int valueA = 10;
2362 unsigned int valueB = 15;
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002363 unsigned int numSteps = 5;
2364
Finn Williams032bc742020-02-12 11:02:34 +00002365 PeriodicCounterCapture periodicCounterCapture(std::ref(data), std::ref(sendCounterPacket), captureReader,
2366 counterIdMap, backendProfilingContext);
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002367
Matteo Martincighe0e6efc2019-10-04 17:17:42 +01002368 for (unsigned int i = 0; i < numSteps; ++i)
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002369 {
Finn Williams032bc742020-02-12 11:02:34 +00002370 data.SetCaptureData(1, captureIds1, {});
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002371 captureReader.SetCounterValue(0, valueA * (i + 1));
2372 captureReader.SetCounterValue(1, valueB * (i + 1));
2373
2374 periodicCounterCapture.Start();
Finn Williamsf4d59a62019-10-14 15:55:18 +01002375 periodicCounterCapture.Stop();
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002376 }
2377
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01002378 auto buffer = mockBuffer.GetReadableBuffer();
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002379
2380 uint32_t headerWord0 = ReadUint32(buffer, 0);
2381 uint32_t headerWord1 = ReadUint32(buffer, 4);
2382
Sadik Armagan1625efc2021-06-10 18:24:34 +01002383 CHECK(((headerWord0 >> 26) & 0x0000003F) == 3); // packet family
2384 CHECK(((headerWord0 >> 19) & 0x0000007F) == 0); // packet class
2385 CHECK(((headerWord0 >> 16) & 0x00000007) == 0); // packet type
2386 CHECK(headerWord1 == 20);
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002387
Keith Davis3201eea2019-10-24 17:30:41 +01002388 uint32_t offset = 16;
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002389 uint16_t readIndex = ReadUint16(buffer, offset);
Sadik Armagan1625efc2021-06-10 18:24:34 +01002390 CHECK(0 == readIndex);
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002391
2392 offset += 2;
2393 uint32_t readValue = ReadUint32(buffer, offset);
Sadik Armagan1625efc2021-06-10 18:24:34 +01002394 CHECK((valueA * numSteps) == readValue);
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002395
2396 offset += 4;
2397 readIndex = ReadUint16(buffer, offset);
Sadik Armagan1625efc2021-06-10 18:24:34 +01002398 CHECK(1 == readIndex);
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002399
2400 offset += 2;
2401 readValue = ReadUint32(buffer, offset);
Sadik Armagan1625efc2021-06-10 18:24:34 +01002402 CHECK((valueB * numSteps) == readValue);
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002403}
2404
Sadik Armagan1625efc2021-06-10 18:24:34 +01002405TEST_CASE("RequestCounterDirectoryCommandHandlerTest1")
Narumol Prangnawarat48033692019-09-20 12:04:55 +01002406{
Jim Flynn397043f2019-10-17 17:37:10 +01002407 const uint32_t familyId = 0;
Matteo Martincigh8efc5002019-10-10 14:30:29 +01002408 const uint32_t packetId = 3;
Keith Davis3201eea2019-10-24 17:30:41 +01002409 const uint32_t version = 1;
Matteo Martincigh8efc5002019-10-10 14:30:29 +01002410 ProfilingStateMachine profilingStateMachine;
2411 CounterDirectory counterDirectory;
Matteo Martincigh9723d022019-11-13 10:56:41 +00002412 MockBufferManager mockBuffer1(1024);
Sadik Armagan3896b472020-02-10 12:24:15 +00002413 SendCounterPacket sendCounterPacket(mockBuffer1);
2414 SendThread sendThread(profilingStateMachine, mockBuffer1, sendCounterPacket);
Matteo Martincigh9723d022019-11-13 10:56:41 +00002415 MockBufferManager mockBuffer2(1024);
2416 SendTimelinePacket sendTimelinePacket(mockBuffer2);
Keith Davis3201eea2019-10-24 17:30:41 +01002417 RequestCounterDirectoryCommandHandler commandHandler(familyId, packetId, version, counterDirectory,
Matteo Martincigh9723d022019-11-13 10:56:41 +00002418 sendCounterPacket, sendTimelinePacket, profilingStateMachine);
Narumol Prangnawarat48033692019-09-20 12:04:55 +01002419
Matteo Martincigh8efc5002019-10-10 14:30:29 +01002420 const uint32_t wrongPacketId = 47;
Keith Davis3201eea2019-10-24 17:30:41 +01002421 const uint32_t wrongHeader = (wrongPacketId & 0x000003FF) << 16;
Narumol Prangnawarat48033692019-09-20 12:04:55 +01002422
Jim Flynnbbfe6032020-07-20 16:57:44 +01002423 arm::pipe::Packet wrongPacket(wrongHeader);
Matteo Martincigh8efc5002019-10-10 14:30:29 +01002424
2425 profilingStateMachine.TransitionToState(ProfilingState::Uninitialised);
Sadik Armagan1625efc2021-06-10 18:24:34 +01002426 CHECK_THROWS_AS(commandHandler(wrongPacket), armnn::RuntimeException); // Wrong profiling state
Matteo Martincigh8efc5002019-10-10 14:30:29 +01002427 profilingStateMachine.TransitionToState(ProfilingState::NotConnected);
Sadik Armagan1625efc2021-06-10 18:24:34 +01002428 CHECK_THROWS_AS(commandHandler(wrongPacket), armnn::RuntimeException); // Wrong profiling state
Matteo Martincigh8efc5002019-10-10 14:30:29 +01002429 profilingStateMachine.TransitionToState(ProfilingState::WaitingForAck);
Sadik Armagan1625efc2021-06-10 18:24:34 +01002430 CHECK_THROWS_AS(commandHandler(wrongPacket), armnn::RuntimeException); // Wrong profiling state
Matteo Martincigh8efc5002019-10-10 14:30:29 +01002431 profilingStateMachine.TransitionToState(ProfilingState::Active);
Sadik Armagan1625efc2021-06-10 18:24:34 +01002432 CHECK_THROWS_AS(commandHandler(wrongPacket), armnn::InvalidArgumentException); // Wrong packet
Matteo Martincigh8efc5002019-10-10 14:30:29 +01002433
2434 const uint32_t rightHeader = (packetId & 0x000003FF) << 16;
2435
Jim Flynnbbfe6032020-07-20 16:57:44 +01002436 arm::pipe::Packet rightPacket(rightHeader);
Matteo Martincigh8efc5002019-10-10 14:30:29 +01002437
Sadik Armagan1625efc2021-06-10 18:24:34 +01002438 CHECK_NOTHROW(commandHandler(rightPacket)); // Right packet
Narumol Prangnawarat48033692019-09-20 12:04:55 +01002439
Matteo Martincigh9723d022019-11-13 10:56:41 +00002440 auto readBuffer1 = mockBuffer1.GetReadableBuffer();
Narumol Prangnawarat48033692019-09-20 12:04:55 +01002441
Matteo Martincigh9723d022019-11-13 10:56:41 +00002442 uint32_t header1Word0 = ReadUint32(readBuffer1, 0);
2443 uint32_t header1Word1 = ReadUint32(readBuffer1, 4);
Narumol Prangnawarat48033692019-09-20 12:04:55 +01002444
Matteo Martincigh9723d022019-11-13 10:56:41 +00002445 // Counter directory packet
Sadik Armagan1625efc2021-06-10 18:24:34 +01002446 CHECK(((header1Word0 >> 26) & 0x0000003F) == 0); // packet family
2447 CHECK(((header1Word0 >> 16) & 0x000003FF) == 2); // packet id
2448 CHECK(header1Word1 == 24); // data length
Narumol Prangnawarat48033692019-09-20 12:04:55 +01002449
Matteo Martincigh9723d022019-11-13 10:56:41 +00002450 uint32_t bodyHeader1Word0 = ReadUint32(readBuffer1, 8);
Matthew Sloyan371b70e2020-09-11 10:14:57 +01002451 uint16_t deviceRecordCount = armnn::numeric_cast<uint16_t>(bodyHeader1Word0 >> 16);
Sadik Armagan1625efc2021-06-10 18:24:34 +01002452 CHECK(deviceRecordCount == 0); // device_records_count
Matteo Martincigh9723d022019-11-13 10:56:41 +00002453
2454 auto readBuffer2 = mockBuffer2.GetReadableBuffer();
2455
2456 uint32_t header2Word0 = ReadUint32(readBuffer2, 0);
2457 uint32_t header2Word1 = ReadUint32(readBuffer2, 4);
2458
2459 // Timeline message directory packet
Sadik Armagan1625efc2021-06-10 18:24:34 +01002460 CHECK(((header2Word0 >> 26) & 0x0000003F) == 1); // packet family
2461 CHECK(((header2Word0 >> 16) & 0x000003FF) == 0); // packet id
2462 CHECK(header2Word1 == 443); // data length
Narumol Prangnawarat48033692019-09-20 12:04:55 +01002463}
2464
Sadik Armagan1625efc2021-06-10 18:24:34 +01002465TEST_CASE("RequestCounterDirectoryCommandHandlerTest2")
Narumol Prangnawarat48033692019-09-20 12:04:55 +01002466{
Jim Flynn397043f2019-10-17 17:37:10 +01002467 const uint32_t familyId = 0;
Matteo Martincigh8efc5002019-10-10 14:30:29 +01002468 const uint32_t packetId = 3;
Keith Davis3201eea2019-10-24 17:30:41 +01002469 const uint32_t version = 1;
Matteo Martincigh8efc5002019-10-10 14:30:29 +01002470 ProfilingStateMachine profilingStateMachine;
2471 CounterDirectory counterDirectory;
Matteo Martincigh9723d022019-11-13 10:56:41 +00002472 MockBufferManager mockBuffer1(1024);
Sadik Armagan3896b472020-02-10 12:24:15 +00002473 SendCounterPacket sendCounterPacket(mockBuffer1);
2474 SendThread sendThread(profilingStateMachine, mockBuffer1, sendCounterPacket);
Matteo Martincigh9723d022019-11-13 10:56:41 +00002475 MockBufferManager mockBuffer2(1024);
2476 SendTimelinePacket sendTimelinePacket(mockBuffer2);
Keith Davis3201eea2019-10-24 17:30:41 +01002477 RequestCounterDirectoryCommandHandler commandHandler(familyId, packetId, version, counterDirectory,
Matteo Martincigh9723d022019-11-13 10:56:41 +00002478 sendCounterPacket, sendTimelinePacket, profilingStateMachine);
Matteo Martincigh8efc5002019-10-10 14:30:29 +01002479 const uint32_t header = (packetId & 0x000003FF) << 16;
Jim Flynnbbfe6032020-07-20 16:57:44 +01002480 const arm::pipe::Packet packet(header);
Narumol Prangnawarat48033692019-09-20 12:04:55 +01002481
Matteo Martincigh9723d022019-11-13 10:56:41 +00002482 const Device* device = counterDirectory.RegisterDevice("deviceA", 1);
Sadik Armagan1625efc2021-06-10 18:24:34 +01002483 CHECK(device != nullptr);
Narumol Prangnawarat48033692019-09-20 12:04:55 +01002484 const CounterSet* counterSet = counterDirectory.RegisterCounterSet("countersetA");
Sadik Armagan1625efc2021-06-10 18:24:34 +01002485 CHECK(counterSet != nullptr);
Sadik Armagan4c998992020-02-25 12:44:44 +00002486 counterDirectory.RegisterCategory("categoryA");
Keith Davise394bd92019-12-02 15:12:19 +00002487 counterDirectory.RegisterCounter(armnn::profiling::BACKEND_ID, 24,
2488 "categoryA", 0, 1, 2.0f, "counterA", "descA");
2489 counterDirectory.RegisterCounter(armnn::profiling::BACKEND_ID, 25,
2490 "categoryA", 1, 1, 3.0f, "counterB", "descB");
Narumol Prangnawarat48033692019-09-20 12:04:55 +01002491
Matteo Martincigh8efc5002019-10-10 14:30:29 +01002492 profilingStateMachine.TransitionToState(ProfilingState::Uninitialised);
Sadik Armagan1625efc2021-06-10 18:24:34 +01002493 CHECK_THROWS_AS(commandHandler(packet), armnn::RuntimeException); // Wrong profiling state
Matteo Martincigh8efc5002019-10-10 14:30:29 +01002494 profilingStateMachine.TransitionToState(ProfilingState::NotConnected);
Sadik Armagan1625efc2021-06-10 18:24:34 +01002495 CHECK_THROWS_AS(commandHandler(packet), armnn::RuntimeException); // Wrong profiling state
Matteo Martincigh8efc5002019-10-10 14:30:29 +01002496 profilingStateMachine.TransitionToState(ProfilingState::WaitingForAck);
Sadik Armagan1625efc2021-06-10 18:24:34 +01002497 CHECK_THROWS_AS(commandHandler(packet), armnn::RuntimeException); // Wrong profiling state
Matteo Martincigh8efc5002019-10-10 14:30:29 +01002498 profilingStateMachine.TransitionToState(ProfilingState::Active);
Sadik Armagan1625efc2021-06-10 18:24:34 +01002499 CHECK_NOTHROW(commandHandler(packet));
Narumol Prangnawarat48033692019-09-20 12:04:55 +01002500
Matteo Martincigh9723d022019-11-13 10:56:41 +00002501 auto readBuffer1 = mockBuffer1.GetReadableBuffer();
Narumol Prangnawarat48033692019-09-20 12:04:55 +01002502
Finn Williams985fecf2020-04-30 11:06:43 +01002503 const uint32_t header1Word0 = ReadUint32(readBuffer1, 0);
2504 const uint32_t header1Word1 = ReadUint32(readBuffer1, 4);
Narumol Prangnawarat48033692019-09-20 12:04:55 +01002505
Sadik Armagan1625efc2021-06-10 18:24:34 +01002506 CHECK(((header1Word0 >> 26) & 0x0000003F) == 0); // packet family
2507 CHECK(((header1Word0 >> 16) & 0x000003FF) == 2); // packet id
2508 CHECK(header1Word1 == 236); // data length
Narumol Prangnawarat48033692019-09-20 12:04:55 +01002509
Finn Williams985fecf2020-04-30 11:06:43 +01002510 const uint32_t bodyHeaderSizeBytes = bodyHeaderSize * sizeof(uint32_t);
Narumol Prangnawarat48033692019-09-20 12:04:55 +01002511
Finn Williams985fecf2020-04-30 11:06:43 +01002512 const uint32_t bodyHeader1Word0 = ReadUint32(readBuffer1, 8);
2513 const uint32_t bodyHeader1Word1 = ReadUint32(readBuffer1, 12);
2514 const uint32_t bodyHeader1Word2 = ReadUint32(readBuffer1, 16);
2515 const uint32_t bodyHeader1Word3 = ReadUint32(readBuffer1, 20);
2516 const uint32_t bodyHeader1Word4 = ReadUint32(readBuffer1, 24);
2517 const uint32_t bodyHeader1Word5 = ReadUint32(readBuffer1, 28);
Matthew Sloyan371b70e2020-09-11 10:14:57 +01002518 const uint16_t deviceRecordCount = armnn::numeric_cast<uint16_t>(bodyHeader1Word0 >> 16);
2519 const uint16_t counterSetRecordCount = armnn::numeric_cast<uint16_t>(bodyHeader1Word2 >> 16);
2520 const uint16_t categoryRecordCount = armnn::numeric_cast<uint16_t>(bodyHeader1Word4 >> 16);
Sadik Armagan1625efc2021-06-10 18:24:34 +01002521 CHECK(deviceRecordCount == 1); // device_records_count
2522 CHECK(bodyHeader1Word1 == 0 + bodyHeaderSizeBytes); // device_records_pointer_table_offset
2523 CHECK(counterSetRecordCount == 1); // counter_set_count
2524 CHECK(bodyHeader1Word3 == 4 + bodyHeaderSizeBytes); // counter_set_pointer_table_offset
2525 CHECK(categoryRecordCount == 1); // categories_count
2526 CHECK(bodyHeader1Word5 == 8 + bodyHeaderSizeBytes); // categories_pointer_table_offset
Finn Williams985fecf2020-04-30 11:06:43 +01002527
2528 const uint32_t deviceRecordOffset = ReadUint32(readBuffer1, 32);
Sadik Armagan1625efc2021-06-10 18:24:34 +01002529 CHECK(deviceRecordOffset == 12);
Narumol Prangnawarat48033692019-09-20 12:04:55 +01002530
Finn Williams985fecf2020-04-30 11:06:43 +01002531 const uint32_t counterSetRecordOffset = ReadUint32(readBuffer1, 36);
Sadik Armagan1625efc2021-06-10 18:24:34 +01002532 CHECK(counterSetRecordOffset == 28);
Narumol Prangnawarat48033692019-09-20 12:04:55 +01002533
Finn Williams985fecf2020-04-30 11:06:43 +01002534 const uint32_t categoryRecordOffset = ReadUint32(readBuffer1, 40);
Sadik Armagan1625efc2021-06-10 18:24:34 +01002535 CHECK(categoryRecordOffset == 48);
Matteo Martincigh9723d022019-11-13 10:56:41 +00002536
2537 auto readBuffer2 = mockBuffer2.GetReadableBuffer();
2538
Finn Williams985fecf2020-04-30 11:06:43 +01002539 const uint32_t header2Word0 = ReadUint32(readBuffer2, 0);
2540 const uint32_t header2Word1 = ReadUint32(readBuffer2, 4);
Matteo Martincigh9723d022019-11-13 10:56:41 +00002541
2542 // Timeline message directory packet
Sadik Armagan1625efc2021-06-10 18:24:34 +01002543 CHECK(((header2Word0 >> 26) & 0x0000003F) == 1); // packet family
2544 CHECK(((header2Word0 >> 16) & 0x000003FF) == 0); // packet id
2545 CHECK(header2Word1 == 443); // data length
Narumol Prangnawarat48033692019-09-20 12:04:55 +01002546}
2547
Sadik Armagan1625efc2021-06-10 18:24:34 +01002548TEST_CASE("CheckProfilingServiceGoodConnectionAcknowledgedPacket")
Matteo Martincigh54fb9572019-10-02 12:50:57 +01002549{
Finn Williamsa0de0562020-04-22 12:27:37 +01002550 unsigned int streamMetadataPacketsize = GetStreamMetaDataPacketSize();
Matteo Martincigh54fb9572019-10-02 12:50:57 +01002551
Jim Flynn53e46992019-10-14 12:31:10 +01002552 // Reset the profiling service to the uninitialized state
Kevin Mayd92a6e42021-02-04 10:27:41 +00002553 armnn::IRuntime::CreationOptions::ExternalProfilingOptions options;
Keith Davis3201eea2019-10-24 17:30:41 +01002554 options.m_EnableProfiling = true;
Sadik Armagan3184c902020-03-18 10:57:30 +00002555 armnn::profiling::ProfilingService profilingService;
Matteo Martincigh54fb9572019-10-02 12:50:57 +01002556 profilingService.ResetExternalProfilingOptions(options, true);
2557
Sadik Armagan3184c902020-03-18 10:57:30 +00002558 // Swap the profiling connection factory in the profiling service instance with our mock one
2559 SwapProfilingConnectionFactoryHelper helper(profilingService);
2560
Matteo Martincigh54fb9572019-10-02 12:50:57 +01002561 // Bring the profiling service to the "WaitingForAck" state
Sadik Armagan1625efc2021-06-10 18:24:34 +01002562 CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
Keith Davis3201eea2019-10-24 17:30:41 +01002563 profilingService.Update(); // Initialize the counter directory
Sadik Armagan1625efc2021-06-10 18:24:34 +01002564 CHECK(profilingService.GetCurrentState() == ProfilingState::NotConnected);
Keith Davis3201eea2019-10-24 17:30:41 +01002565 profilingService.Update(); // Create the profiling connection
Matteo Martincigh54fb9572019-10-02 12:50:57 +01002566
Matteo Martincighd0613b52019-10-09 16:47:04 +01002567 // Get the mock profiling connection
2568 MockProfilingConnection* mockProfilingConnection = helper.GetMockProfilingConnection();
Sadik Armagan1625efc2021-06-10 18:24:34 +01002569 CHECK(mockProfilingConnection);
Matteo Martincighd0613b52019-10-09 16:47:04 +01002570
Matteo Martincighe8485382019-10-10 14:08:21 +01002571 // Remove the packets received so far
2572 mockProfilingConnection->Clear();
2573
Sadik Armagan1625efc2021-06-10 18:24:34 +01002574 CHECK(profilingService.GetCurrentState() == ProfilingState::WaitingForAck);
Keith Davis3201eea2019-10-24 17:30:41 +01002575 profilingService.Update(); // Start the command handler and the send thread
Matteo Martincighe8485382019-10-10 14:08:21 +01002576
2577 // Wait for the Stream Metadata packet to be sent
Sadik Armagan1625efc2021-06-10 18:24:34 +01002578 CHECK(helper.WaitForPacketsSent(
Finn Williams09ad6f92019-12-19 17:05:18 +00002579 mockProfilingConnection, PacketType::StreamMetaData, streamMetadataPacketsize) >= 1);
Matteo Martincigh54fb9572019-10-02 12:50:57 +01002580
2581 // Write a valid "Connection Acknowledged" packet into the mock profiling connection, to simulate a valid
2582 // reply from an external profiling service
2583
2584 // Connection Acknowledged Packet header (word 0, word 1 is always zero):
2585 // 26:31 [6] packet_family: Control Packet Family, value 0b000000
2586 // 16:25 [10] packet_id: Packet identifier, value 0b0000000001
2587 // 8:15 [8] reserved: Reserved, value 0b00000000
2588 // 0:7 [8] reserved: Reserved, value 0b00000000
2589 uint32_t packetFamily = 0;
2590 uint32_t packetId = 1;
Keith Davis3201eea2019-10-24 17:30:41 +01002591 uint32_t header = ((packetFamily & 0x0000003F) << 26) | ((packetId & 0x000003FF) << 16);
Matteo Martincigh54fb9572019-10-02 12:50:57 +01002592
Matteo Martincighd0613b52019-10-09 16:47:04 +01002593 // Create the Connection Acknowledged Packet
Jim Flynnbbfe6032020-07-20 16:57:44 +01002594 arm::pipe::Packet connectionAcknowledgedPacket(header);
Matteo Martincigh54fb9572019-10-02 12:50:57 +01002595
2596 // Write the packet to the mock profiling connection
2597 mockProfilingConnection->WritePacket(std::move(connectionAcknowledgedPacket));
2598
Colm Donelan2ba48d22019-11-29 09:10:59 +00002599 // Wait for the counter directory packet to ensure the ConnectionAcknowledgedCommandHandler has run.
Sadik Armagan1625efc2021-06-10 18:24:34 +01002600 CHECK(helper.WaitForPacketsSent(mockProfilingConnection, PacketType::CounterDirectory) == 1);
Matteo Martincigh54fb9572019-10-02 12:50:57 +01002601
2602 // The Connection Acknowledged Command Handler should have updated the profiling state accordingly
Sadik Armagan1625efc2021-06-10 18:24:34 +01002603 CHECK(profilingService.GetCurrentState() == ProfilingState::Active);
Matteo Martincighd0613b52019-10-09 16:47:04 +01002604
2605 // Reset the profiling service to stop any running thread
2606 options.m_EnableProfiling = false;
2607 profilingService.ResetExternalProfilingOptions(options, true);
Matteo Martincigh54fb9572019-10-02 12:50:57 +01002608}
2609
Sadik Armagan1625efc2021-06-10 18:24:34 +01002610TEST_CASE("CheckProfilingServiceGoodRequestCounterDirectoryPacket")
Matteo Martincigh8efc5002019-10-10 14:30:29 +01002611{
Matteo Martincigh8efc5002019-10-10 14:30:29 +01002612 // Reset the profiling service to the uninitialized state
Kevin Mayd92a6e42021-02-04 10:27:41 +00002613 armnn::IRuntime::CreationOptions::ExternalProfilingOptions options;
Keith Davis3201eea2019-10-24 17:30:41 +01002614 options.m_EnableProfiling = true;
Sadik Armagan3184c902020-03-18 10:57:30 +00002615 armnn::profiling::ProfilingService profilingService;
Matteo Martincigh8efc5002019-10-10 14:30:29 +01002616 profilingService.ResetExternalProfilingOptions(options, true);
2617
Sadik Armagan3184c902020-03-18 10:57:30 +00002618 // Swap the profiling connection factory in the profiling service instance with our mock one
2619 SwapProfilingConnectionFactoryHelper helper(profilingService);
2620
Matteo Martincigh8efc5002019-10-10 14:30:29 +01002621 // Bring the profiling service to the "Active" state
Sadik Armagan1625efc2021-06-10 18:24:34 +01002622 CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
Keith Davis3201eea2019-10-24 17:30:41 +01002623 profilingService.Update(); // Initialize the counter directory
Sadik Armagan1625efc2021-06-10 18:24:34 +01002624 CHECK(profilingService.GetCurrentState() == ProfilingState::NotConnected);
Keith Davis3201eea2019-10-24 17:30:41 +01002625 profilingService.Update(); // Create the profiling connection
Sadik Armagan1625efc2021-06-10 18:24:34 +01002626 CHECK(profilingService.GetCurrentState() == ProfilingState::WaitingForAck);
Keith Davis3201eea2019-10-24 17:30:41 +01002627 profilingService.Update(); // Start the command handler and the send thread
Matteo Martincighe8485382019-10-10 14:08:21 +01002628
Colm Donelan2ba48d22019-11-29 09:10:59 +00002629 // Get the mock profiling connection
2630 MockProfilingConnection* mockProfilingConnection = helper.GetMockProfilingConnection();
Sadik Armagan1625efc2021-06-10 18:24:34 +01002631 CHECK(mockProfilingConnection);
Colm Donelan2ba48d22019-11-29 09:10:59 +00002632
Matteo Martincighe8485382019-10-10 14:08:21 +01002633 // Force the profiling service to the "Active" state
Matteo Martincigh8efc5002019-10-10 14:30:29 +01002634 helper.ForceTransitionToState(ProfilingState::Active);
Sadik Armagan1625efc2021-06-10 18:24:34 +01002635 CHECK(profilingService.GetCurrentState() == ProfilingState::Active);
Matteo Martincigh8efc5002019-10-10 14:30:29 +01002636
Matteo Martincigh8efc5002019-10-10 14:30:29 +01002637 // Write a valid "Request Counter Directory" packet into the mock profiling connection, to simulate a valid
2638 // reply from an external profiling service
2639
2640 // Request Counter Directory packet header (word 0, word 1 is always zero):
2641 // 26:31 [6] packet_family: Control Packet Family, value 0b000000
2642 // 16:25 [10] packet_id: Packet identifier, value 0b0000000011
2643 // 8:15 [8] reserved: Reserved, value 0b00000000
2644 // 0:7 [8] reserved: Reserved, value 0b00000000
2645 uint32_t packetFamily = 0;
2646 uint32_t packetId = 3;
Keith Davis3201eea2019-10-24 17:30:41 +01002647 uint32_t header = ((packetFamily & 0x0000003F) << 26) | ((packetId & 0x000003FF) << 16);
Matteo Martincigh8efc5002019-10-10 14:30:29 +01002648
2649 // Create the Request Counter Directory packet
Jim Flynnbbfe6032020-07-20 16:57:44 +01002650 arm::pipe::Packet requestCounterDirectoryPacket(header);
Matteo Martincigh8efc5002019-10-10 14:30:29 +01002651
2652 // Write the packet to the mock profiling connection
2653 mockProfilingConnection->WritePacket(std::move(requestCounterDirectoryPacket));
2654
Sadik Armagan4c998992020-02-25 12:44:44 +00002655 // Expecting one CounterDirectory Packet of length 652
Jim Flynn6398a982020-05-27 17:05:21 +01002656 // and one TimelineMessageDirectory packet of length 451
Sadik Armagan1625efc2021-06-10 18:24:34 +01002657 CHECK(helper.WaitForPacketsSent(mockProfilingConnection, PacketType::CounterDirectory, 652) == 1);
2658 CHECK(helper.WaitForPacketsSent(mockProfilingConnection, PacketType::TimelineMessageDirectory, 451) == 1);
Matteo Martincighe8485382019-10-10 14:08:21 +01002659
2660 // The Request Counter Directory Command Handler should not have updated the profiling state
Sadik Armagan1625efc2021-06-10 18:24:34 +01002661 CHECK(profilingService.GetCurrentState() == ProfilingState::Active);
Matteo Martincighe8485382019-10-10 14:08:21 +01002662
2663 // Reset the profiling service to stop any running thread
2664 options.m_EnableProfiling = false;
2665 profilingService.ResetExternalProfilingOptions(options, true);
2666}
2667
Sadik Armagan1625efc2021-06-10 18:24:34 +01002668TEST_CASE("CheckProfilingServiceBadPeriodicCounterSelectionPacketInvalidCounterUid")
Matteo Martincighe8485382019-10-10 14:08:21 +01002669{
Matteo Martincighe8485382019-10-10 14:08:21 +01002670 // Reset the profiling service to the uninitialized state
Kevin Mayd92a6e42021-02-04 10:27:41 +00002671 armnn::IRuntime::CreationOptions::ExternalProfilingOptions options;
Keith Davis3201eea2019-10-24 17:30:41 +01002672 options.m_EnableProfiling = true;
Sadik Armagan3184c902020-03-18 10:57:30 +00002673 armnn::profiling::ProfilingService profilingService;
Matteo Martincighe8485382019-10-10 14:08:21 +01002674 profilingService.ResetExternalProfilingOptions(options, true);
2675
Sadik Armagan3184c902020-03-18 10:57:30 +00002676 // Swap the profiling connection factory in the profiling service instance with our mock one
2677 SwapProfilingConnectionFactoryHelper helper(profilingService);
2678
Matteo Martincighe8485382019-10-10 14:08:21 +01002679 // Bring the profiling service to the "Active" state
Sadik Armagan1625efc2021-06-10 18:24:34 +01002680 CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
Keith Davis3201eea2019-10-24 17:30:41 +01002681 profilingService.Update(); // Initialize the counter directory
Sadik Armagan1625efc2021-06-10 18:24:34 +01002682 CHECK(profilingService.GetCurrentState() == ProfilingState::NotConnected);
Keith Davis3201eea2019-10-24 17:30:41 +01002683 profilingService.Update(); // Create the profiling connection
Sadik Armagan1625efc2021-06-10 18:24:34 +01002684 CHECK(profilingService.GetCurrentState() == ProfilingState::WaitingForAck);
Keith Davis3201eea2019-10-24 17:30:41 +01002685 profilingService.Update(); // Start the command handler and the send thread
Matteo Martincighe8485382019-10-10 14:08:21 +01002686
Colm Donelan2ba48d22019-11-29 09:10:59 +00002687 // Get the mock profiling connection
2688 MockProfilingConnection* mockProfilingConnection = helper.GetMockProfilingConnection();
Sadik Armagan1625efc2021-06-10 18:24:34 +01002689 CHECK(mockProfilingConnection);
Colm Donelan2ba48d22019-11-29 09:10:59 +00002690
Matteo Martincighe8485382019-10-10 14:08:21 +01002691 // Force the profiling service to the "Active" state
2692 helper.ForceTransitionToState(ProfilingState::Active);
Sadik Armagan1625efc2021-06-10 18:24:34 +01002693 CHECK(profilingService.GetCurrentState() == ProfilingState::Active);
Matteo Martincighe8485382019-10-10 14:08:21 +01002694
Matteo Martincighe8485382019-10-10 14:08:21 +01002695 // Remove the packets received so far
2696 mockProfilingConnection->Clear();
2697
2698 // Write a "Periodic Counter Selection" packet into the mock profiling connection, to simulate an input from an
2699 // external profiling service
2700
2701 // Periodic Counter Selection packet header:
2702 // 26:31 [6] packet_family: Control Packet Family, value 0b000000
2703 // 16:25 [10] packet_id: Packet identifier, value 0b0000000100
2704 // 8:15 [8] reserved: Reserved, value 0b00000000
2705 // 0:7 [8] reserved: Reserved, value 0b00000000
2706 uint32_t packetFamily = 0;
2707 uint32_t packetId = 4;
Keith Davis3201eea2019-10-24 17:30:41 +01002708 uint32_t header = ((packetFamily & 0x0000003F) << 26) | ((packetId & 0x000003FF) << 16);
Matteo Martincighe8485382019-10-10 14:08:21 +01002709
Keith Davis3201eea2019-10-24 17:30:41 +01002710 uint32_t capturePeriod = 123456; // Some capture period (microseconds)
Matteo Martincighe8485382019-10-10 14:08:21 +01002711
2712 // Get the first valid counter UID
2713 const ICounterDirectory& counterDirectory = profilingService.GetCounterDirectory();
Keith Davis3201eea2019-10-24 17:30:41 +01002714 const Counters& counters = counterDirectory.GetCounters();
Sadik Armagan1625efc2021-06-10 18:24:34 +01002715 CHECK(counters.size() > 1);
Keith Davis3201eea2019-10-24 17:30:41 +01002716 uint16_t counterUidA = counters.begin()->first; // First valid counter UID
2717 uint16_t counterUidB = 9999; // Second invalid counter UID
Matteo Martincighe8485382019-10-10 14:08:21 +01002718
2719 uint32_t length = 8;
2720
2721 auto data = std::make_unique<unsigned char[]>(length);
2722 WriteUint32(data.get(), 0, capturePeriod);
2723 WriteUint16(data.get(), 4, counterUidA);
2724 WriteUint16(data.get(), 6, counterUidB);
2725
2726 // Create the Periodic Counter Selection packet
Jim Flynnbbfe6032020-07-20 16:57:44 +01002727 // Length > 0, this will start the Period Counter Capture thread
2728 arm::pipe::Packet periodicCounterSelectionPacket(header, length, data);
2729
Matteo Martincighe8485382019-10-10 14:08:21 +01002730
2731 // Write the packet to the mock profiling connection
2732 mockProfilingConnection->WritePacket(std::move(periodicCounterSelectionPacket));
2733
Finn Williams09ad6f92019-12-19 17:05:18 +00002734 // Expecting one Periodic Counter Selection packet of length 14
2735 // and at least one Periodic Counter Capture packet of length 22
Sadik Armagan1625efc2021-06-10 18:24:34 +01002736 CHECK(helper.WaitForPacketsSent(mockProfilingConnection, PacketType::PeriodicCounterSelection, 14) == 1);
2737 CHECK(helper.WaitForPacketsSent(mockProfilingConnection, PacketType::PeriodicCounterCapture, 22) >= 1);
Matteo Martincighe8485382019-10-10 14:08:21 +01002738
2739 // The Periodic Counter Selection Handler should not have updated the profiling state
Sadik Armagan1625efc2021-06-10 18:24:34 +01002740 CHECK(profilingService.GetCurrentState() == ProfilingState::Active);
Matteo Martincighe8485382019-10-10 14:08:21 +01002741
2742 // Reset the profiling service to stop any running thread
2743 options.m_EnableProfiling = false;
2744 profilingService.ResetExternalProfilingOptions(options, true);
2745}
2746
Sadik Armagan1625efc2021-06-10 18:24:34 +01002747TEST_CASE("CheckProfilingServiceGoodPeriodicCounterSelectionPacketNoCounters")
Matteo Martincighe8485382019-10-10 14:08:21 +01002748{
Matteo Martincighe8485382019-10-10 14:08:21 +01002749 // Reset the profiling service to the uninitialized state
Kevin Mayd92a6e42021-02-04 10:27:41 +00002750 armnn::IRuntime::CreationOptions::ExternalProfilingOptions options;
Keith Davis3201eea2019-10-24 17:30:41 +01002751 options.m_EnableProfiling = true;
Sadik Armagan3184c902020-03-18 10:57:30 +00002752 armnn::profiling::ProfilingService profilingService;
Matteo Martincighe8485382019-10-10 14:08:21 +01002753 profilingService.ResetExternalProfilingOptions(options, true);
2754
Sadik Armagan3184c902020-03-18 10:57:30 +00002755 // Swap the profiling connection factory in the profiling service instance with our mock one
2756 SwapProfilingConnectionFactoryHelper helper(profilingService);
2757
Matteo Martincighe8485382019-10-10 14:08:21 +01002758 // Bring the profiling service to the "Active" state
Sadik Armagan1625efc2021-06-10 18:24:34 +01002759 CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
Keith Davis3201eea2019-10-24 17:30:41 +01002760 profilingService.Update(); // Initialize the counter directory
Sadik Armagan1625efc2021-06-10 18:24:34 +01002761 CHECK(profilingService.GetCurrentState() == ProfilingState::NotConnected);
Keith Davis3201eea2019-10-24 17:30:41 +01002762 profilingService.Update(); // Create the profiling connection
Sadik Armagan1625efc2021-06-10 18:24:34 +01002763 CHECK(profilingService.GetCurrentState() == ProfilingState::WaitingForAck);
Keith Davis3201eea2019-10-24 17:30:41 +01002764 profilingService.Update(); // Start the command handler and the send thread
Matteo Martincighe8485382019-10-10 14:08:21 +01002765
Colm Donelan2ba48d22019-11-29 09:10:59 +00002766 // Get the mock profiling connection
2767 MockProfilingConnection* mockProfilingConnection = helper.GetMockProfilingConnection();
Sadik Armagan1625efc2021-06-10 18:24:34 +01002768 CHECK(mockProfilingConnection);
Colm Donelan2ba48d22019-11-29 09:10:59 +00002769
Matteo Martincighe8485382019-10-10 14:08:21 +01002770 // Wait for the Stream Metadata packet the be sent
2771 // (we are not testing the connection acknowledgement here so it will be ignored by this test)
Finn Williams09ad6f92019-12-19 17:05:18 +00002772 helper.WaitForPacketsSent(mockProfilingConnection, PacketType::StreamMetaData);
Matteo Martincighe8485382019-10-10 14:08:21 +01002773
2774 // Force the profiling service to the "Active" state
2775 helper.ForceTransitionToState(ProfilingState::Active);
Sadik Armagan1625efc2021-06-10 18:24:34 +01002776 CHECK(profilingService.GetCurrentState() == ProfilingState::Active);
Matteo Martincighe8485382019-10-10 14:08:21 +01002777
Matteo Martincighe8485382019-10-10 14:08:21 +01002778 // Write a "Periodic Counter Selection" packet into the mock profiling connection, to simulate an input from an
2779 // external profiling service
2780
2781 // Periodic Counter Selection packet header:
2782 // 26:31 [6] packet_family: Control Packet Family, value 0b000000
2783 // 16:25 [10] packet_id: Packet identifier, value 0b0000000100
2784 // 8:15 [8] reserved: Reserved, value 0b00000000
2785 // 0:7 [8] reserved: Reserved, value 0b00000000
2786 uint32_t packetFamily = 0;
2787 uint32_t packetId = 4;
Keith Davis3201eea2019-10-24 17:30:41 +01002788 uint32_t header = ((packetFamily & 0x0000003F) << 26) | ((packetId & 0x000003FF) << 16);
Matteo Martincighe8485382019-10-10 14:08:21 +01002789
2790 // Create the Periodic Counter Selection packet
Jim Flynnbbfe6032020-07-20 16:57:44 +01002791 // Length == 0, this will disable the collection of counters
2792 arm::pipe::Packet periodicCounterSelectionPacket(header);
Matteo Martincighe8485382019-10-10 14:08:21 +01002793
2794 // Write the packet to the mock profiling connection
2795 mockProfilingConnection->WritePacket(std::move(periodicCounterSelectionPacket));
2796
Finn Williams09ad6f92019-12-19 17:05:18 +00002797 // Wait for the Periodic Counter Selection packet of length 12 to be sent
2798 // The size of the expected Periodic Counter Selection (echos the sent one)
Sadik Armagan1625efc2021-06-10 18:24:34 +01002799 CHECK(helper.WaitForPacketsSent(mockProfilingConnection, PacketType::PeriodicCounterSelection, 12) == 1);
Matteo Martincighe8485382019-10-10 14:08:21 +01002800
2801 // The Periodic Counter Selection Handler should not have updated the profiling state
Sadik Armagan1625efc2021-06-10 18:24:34 +01002802 CHECK(profilingService.GetCurrentState() == ProfilingState::Active);
Matteo Martincighe8485382019-10-10 14:08:21 +01002803
Finn Williams09ad6f92019-12-19 17:05:18 +00002804 // No Periodic Counter packets are expected
Sadik Armagan1625efc2021-06-10 18:24:34 +01002805 CHECK(helper.WaitForPacketsSent(mockProfilingConnection, PacketType::PeriodicCounterCapture, 0, 0) == 0);
Matteo Martincighe8485382019-10-10 14:08:21 +01002806
2807 // Reset the profiling service to stop any running thread
2808 options.m_EnableProfiling = false;
2809 profilingService.ResetExternalProfilingOptions(options, true);
2810}
2811
Sadik Armagan1625efc2021-06-10 18:24:34 +01002812TEST_CASE("CheckProfilingServiceGoodPeriodicCounterSelectionPacketSingleCounter")
Matteo Martincighe8485382019-10-10 14:08:21 +01002813{
Matteo Martincighe8485382019-10-10 14:08:21 +01002814 // Reset the profiling service to the uninitialized state
Kevin Mayd92a6e42021-02-04 10:27:41 +00002815 armnn::IRuntime::CreationOptions::ExternalProfilingOptions options;
Keith Davis3201eea2019-10-24 17:30:41 +01002816 options.m_EnableProfiling = true;
Sadik Armagan3184c902020-03-18 10:57:30 +00002817 armnn::profiling::ProfilingService profilingService;
Matteo Martincighe8485382019-10-10 14:08:21 +01002818 profilingService.ResetExternalProfilingOptions(options, true);
2819
Sadik Armagan3184c902020-03-18 10:57:30 +00002820 // Swap the profiling connection factory in the profiling service instance with our mock one
2821 SwapProfilingConnectionFactoryHelper helper(profilingService);
2822
Matteo Martincighe8485382019-10-10 14:08:21 +01002823 // Bring the profiling service to the "Active" state
Sadik Armagan1625efc2021-06-10 18:24:34 +01002824 CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
Keith Davis3201eea2019-10-24 17:30:41 +01002825 profilingService.Update(); // Initialize the counter directory
Sadik Armagan1625efc2021-06-10 18:24:34 +01002826 CHECK(profilingService.GetCurrentState() == ProfilingState::NotConnected);
Keith Davis3201eea2019-10-24 17:30:41 +01002827 profilingService.Update(); // Create the profiling connection
Sadik Armagan1625efc2021-06-10 18:24:34 +01002828 CHECK(profilingService.GetCurrentState() == ProfilingState::WaitingForAck);
Keith Davis3201eea2019-10-24 17:30:41 +01002829 profilingService.Update(); // Start the command handler and the send thread
Matteo Martincighe8485382019-10-10 14:08:21 +01002830
Colm Donelan2ba48d22019-11-29 09:10:59 +00002831 // Get the mock profiling connection
2832 MockProfilingConnection* mockProfilingConnection = helper.GetMockProfilingConnection();
Sadik Armagan1625efc2021-06-10 18:24:34 +01002833 CHECK(mockProfilingConnection);
Colm Donelan2ba48d22019-11-29 09:10:59 +00002834
Finn Williams09ad6f92019-12-19 17:05:18 +00002835 // Wait for the Stream Metadata packet to be sent
Matteo Martincighe8485382019-10-10 14:08:21 +01002836 // (we are not testing the connection acknowledgement here so it will be ignored by this test)
Finn Williams09ad6f92019-12-19 17:05:18 +00002837 helper.WaitForPacketsSent(mockProfilingConnection, PacketType::StreamMetaData);
Matteo Martincighe8485382019-10-10 14:08:21 +01002838
2839 // Force the profiling service to the "Active" state
2840 helper.ForceTransitionToState(ProfilingState::Active);
Sadik Armagan1625efc2021-06-10 18:24:34 +01002841 CHECK(profilingService.GetCurrentState() == ProfilingState::Active);
Matteo Martincighe8485382019-10-10 14:08:21 +01002842
Matteo Martincighe8485382019-10-10 14:08:21 +01002843 // Write a "Periodic Counter Selection" packet into the mock profiling connection, to simulate an input from an
2844 // external profiling service
2845
2846 // Periodic Counter Selection packet header:
2847 // 26:31 [6] packet_family: Control Packet Family, value 0b000000
2848 // 16:25 [10] packet_id: Packet identifier, value 0b0000000100
2849 // 8:15 [8] reserved: Reserved, value 0b00000000
2850 // 0:7 [8] reserved: Reserved, value 0b00000000
2851 uint32_t packetFamily = 0;
2852 uint32_t packetId = 4;
Keith Davis3201eea2019-10-24 17:30:41 +01002853 uint32_t header = ((packetFamily & 0x0000003F) << 26) | ((packetId & 0x000003FF) << 16);
Matteo Martincighe8485382019-10-10 14:08:21 +01002854
Keith Davis3201eea2019-10-24 17:30:41 +01002855 uint32_t capturePeriod = 123456; // Some capture period (microseconds)
Matteo Martincighe8485382019-10-10 14:08:21 +01002856
2857 // Get the first valid counter UID
2858 const ICounterDirectory& counterDirectory = profilingService.GetCounterDirectory();
Keith Davis3201eea2019-10-24 17:30:41 +01002859 const Counters& counters = counterDirectory.GetCounters();
Sadik Armagan1625efc2021-06-10 18:24:34 +01002860 CHECK(!counters.empty());
Keith Davis3201eea2019-10-24 17:30:41 +01002861 uint16_t counterUid = counters.begin()->first; // Valid counter UID
Matteo Martincighe8485382019-10-10 14:08:21 +01002862
2863 uint32_t length = 6;
2864
2865 auto data = std::make_unique<unsigned char[]>(length);
2866 WriteUint32(data.get(), 0, capturePeriod);
2867 WriteUint16(data.get(), 4, counterUid);
2868
2869 // Create the Periodic Counter Selection packet
Jim Flynnbbfe6032020-07-20 16:57:44 +01002870 // Length > 0, this will start the Period Counter Capture thread
2871 arm::pipe::Packet periodicCounterSelectionPacket(header, length, data);
Matteo Martincighe8485382019-10-10 14:08:21 +01002872
2873 // Write the packet to the mock profiling connection
2874 mockProfilingConnection->WritePacket(std::move(periodicCounterSelectionPacket));
2875
Finn Williams09ad6f92019-12-19 17:05:18 +00002876 // Expecting one Periodic Counter Selection packet of length 14
2877 // and at least one Periodic Counter Capture packet of length 22
Sadik Armagan1625efc2021-06-10 18:24:34 +01002878 CHECK(helper.WaitForPacketsSent(mockProfilingConnection, PacketType::PeriodicCounterSelection, 14) == 1);
2879 CHECK(helper.WaitForPacketsSent(mockProfilingConnection, PacketType::PeriodicCounterCapture, 22) >= 1);
Matteo Martincighe8485382019-10-10 14:08:21 +01002880
2881 // The Periodic Counter Selection Handler should not have updated the profiling state
Sadik Armagan1625efc2021-06-10 18:24:34 +01002882 CHECK(profilingService.GetCurrentState() == ProfilingState::Active);
Matteo Martincighe8485382019-10-10 14:08:21 +01002883
2884 // Reset the profiling service to stop any running thread
2885 options.m_EnableProfiling = false;
2886 profilingService.ResetExternalProfilingOptions(options, true);
2887}
2888
Sadik Armagan1625efc2021-06-10 18:24:34 +01002889TEST_CASE("CheckProfilingServiceGoodPeriodicCounterSelectionPacketMultipleCounters")
Matteo Martincighe8485382019-10-10 14:08:21 +01002890{
Matteo Martincighe8485382019-10-10 14:08:21 +01002891 // Reset the profiling service to the uninitialized state
Kevin Mayd92a6e42021-02-04 10:27:41 +00002892 armnn::IRuntime::CreationOptions::ExternalProfilingOptions options;
Keith Davis3201eea2019-10-24 17:30:41 +01002893 options.m_EnableProfiling = true;
Sadik Armagan3184c902020-03-18 10:57:30 +00002894 armnn::profiling::ProfilingService profilingService;
Matteo Martincighe8485382019-10-10 14:08:21 +01002895 profilingService.ResetExternalProfilingOptions(options, true);
2896
Sadik Armagan3184c902020-03-18 10:57:30 +00002897 // Swap the profiling connection factory in the profiling service instance with our mock one
2898 SwapProfilingConnectionFactoryHelper helper(profilingService);
2899
Matteo Martincighe8485382019-10-10 14:08:21 +01002900 // Bring the profiling service to the "Active" state
Sadik Armagan1625efc2021-06-10 18:24:34 +01002901 CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
Keith Davis3201eea2019-10-24 17:30:41 +01002902 profilingService.Update(); // Initialize the counter directory
Sadik Armagan1625efc2021-06-10 18:24:34 +01002903 CHECK(profilingService.GetCurrentState() == ProfilingState::NotConnected);
Keith Davis3201eea2019-10-24 17:30:41 +01002904 profilingService.Update(); // Create the profiling connection
Sadik Armagan1625efc2021-06-10 18:24:34 +01002905 CHECK(profilingService.GetCurrentState() == ProfilingState::WaitingForAck);
Keith Davis3201eea2019-10-24 17:30:41 +01002906 profilingService.Update(); // Start the command handler and the send thread
Matteo Martincighe8485382019-10-10 14:08:21 +01002907
Colm Donelan2ba48d22019-11-29 09:10:59 +00002908 // Get the mock profiling connection
2909 MockProfilingConnection* mockProfilingConnection = helper.GetMockProfilingConnection();
Sadik Armagan1625efc2021-06-10 18:24:34 +01002910 CHECK(mockProfilingConnection);
Colm Donelan2ba48d22019-11-29 09:10:59 +00002911
Matteo Martincighe8485382019-10-10 14:08:21 +01002912 // Wait for the Stream Metadata packet the be sent
2913 // (we are not testing the connection acknowledgement here so it will be ignored by this test)
Finn Williams09ad6f92019-12-19 17:05:18 +00002914 helper.WaitForPacketsSent(mockProfilingConnection, PacketType::StreamMetaData);
Matteo Martincighe8485382019-10-10 14:08:21 +01002915
2916 // Force the profiling service to the "Active" state
2917 helper.ForceTransitionToState(ProfilingState::Active);
Sadik Armagan1625efc2021-06-10 18:24:34 +01002918 CHECK(profilingService.GetCurrentState() == ProfilingState::Active);
Matteo Martincighe8485382019-10-10 14:08:21 +01002919
Matteo Martincighe8485382019-10-10 14:08:21 +01002920 // Write a "Periodic Counter Selection" packet into the mock profiling connection, to simulate an input from an
2921 // external profiling service
2922
2923 // Periodic Counter Selection packet header:
2924 // 26:31 [6] packet_family: Control Packet Family, value 0b000000
2925 // 16:25 [10] packet_id: Packet identifier, value 0b0000000100
2926 // 8:15 [8] reserved: Reserved, value 0b00000000
2927 // 0:7 [8] reserved: Reserved, value 0b00000000
2928 uint32_t packetFamily = 0;
2929 uint32_t packetId = 4;
Keith Davis3201eea2019-10-24 17:30:41 +01002930 uint32_t header = ((packetFamily & 0x0000003F) << 26) | ((packetId & 0x000003FF) << 16);
Matteo Martincighe8485382019-10-10 14:08:21 +01002931
Keith Davis3201eea2019-10-24 17:30:41 +01002932 uint32_t capturePeriod = 123456; // Some capture period (microseconds)
Matteo Martincighe8485382019-10-10 14:08:21 +01002933
2934 // Get the first valid counter UID
2935 const ICounterDirectory& counterDirectory = profilingService.GetCounterDirectory();
Keith Davis3201eea2019-10-24 17:30:41 +01002936 const Counters& counters = counterDirectory.GetCounters();
Sadik Armagan1625efc2021-06-10 18:24:34 +01002937 CHECK(counters.size() > 1);
Keith Davis3201eea2019-10-24 17:30:41 +01002938 uint16_t counterUidA = counters.begin()->first; // First valid counter UID
2939 uint16_t counterUidB = (counters.begin()++)->first; // Second valid counter UID
Matteo Martincighe8485382019-10-10 14:08:21 +01002940
2941 uint32_t length = 8;
2942
2943 auto data = std::make_unique<unsigned char[]>(length);
2944 WriteUint32(data.get(), 0, capturePeriod);
2945 WriteUint16(data.get(), 4, counterUidA);
2946 WriteUint16(data.get(), 6, counterUidB);
2947
2948 // Create the Periodic Counter Selection packet
Jim Flynnbbfe6032020-07-20 16:57:44 +01002949 // Length > 0, this will start the Period Counter Capture thread
2950 arm::pipe::Packet periodicCounterSelectionPacket(header, length, data);
Matteo Martincighe8485382019-10-10 14:08:21 +01002951
2952 // Write the packet to the mock profiling connection
2953 mockProfilingConnection->WritePacket(std::move(periodicCounterSelectionPacket));
2954
Finn Williams09ad6f92019-12-19 17:05:18 +00002955 // Expecting one PeriodicCounterSelection Packet with a length of 16
2956 // And at least one PeriodicCounterCapture Packet with a length of 28
Sadik Armagan1625efc2021-06-10 18:24:34 +01002957 CHECK(helper.WaitForPacketsSent(mockProfilingConnection, PacketType::PeriodicCounterSelection, 16) == 1);
2958 CHECK(helper.WaitForPacketsSent(mockProfilingConnection, PacketType::PeriodicCounterCapture, 28) >= 1);
Matteo Martincighe8485382019-10-10 14:08:21 +01002959
2960 // The Periodic Counter Selection Handler should not have updated the profiling state
Sadik Armagan1625efc2021-06-10 18:24:34 +01002961 CHECK(profilingService.GetCurrentState() == ProfilingState::Active);
Matteo Martincigh8efc5002019-10-10 14:30:29 +01002962
2963 // Reset the profiling service to stop any running thread
2964 options.m_EnableProfiling = false;
2965 profilingService.ResetExternalProfilingOptions(options, true);
2966}
2967
Sadik Armagan1625efc2021-06-10 18:24:34 +01002968TEST_CASE("CheckProfilingServiceDisconnect")
Jim Flynn53e46992019-10-14 12:31:10 +01002969{
Jim Flynn53e46992019-10-14 12:31:10 +01002970 // Reset the profiling service to the uninitialized state
Kevin Mayd92a6e42021-02-04 10:27:41 +00002971 armnn::IRuntime::CreationOptions::ExternalProfilingOptions options;
Keith Davis3201eea2019-10-24 17:30:41 +01002972 options.m_EnableProfiling = true;
Sadik Armagan3184c902020-03-18 10:57:30 +00002973 armnn::profiling::ProfilingService profilingService;
Jim Flynn53e46992019-10-14 12:31:10 +01002974 profilingService.ResetExternalProfilingOptions(options, true);
2975
Sadik Armagan3184c902020-03-18 10:57:30 +00002976 // Swap the profiling connection factory in the profiling service instance with our mock one
2977 SwapProfilingConnectionFactoryHelper helper(profilingService);
2978
Jim Flynn53e46992019-10-14 12:31:10 +01002979 // Try to disconnect the profiling service while in the "Uninitialised" state
Sadik Armagan1625efc2021-06-10 18:24:34 +01002980 CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
Jim Flynn53e46992019-10-14 12:31:10 +01002981 profilingService.Disconnect();
Sadik Armagan1625efc2021-06-10 18:24:34 +01002982 CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised); // The state should not change
Jim Flynn53e46992019-10-14 12:31:10 +01002983
2984 // Try to disconnect the profiling service while in the "NotConnected" state
Keith Davis3201eea2019-10-24 17:30:41 +01002985 profilingService.Update(); // Initialize the counter directory
Sadik Armagan1625efc2021-06-10 18:24:34 +01002986 CHECK(profilingService.GetCurrentState() == ProfilingState::NotConnected);
Jim Flynn53e46992019-10-14 12:31:10 +01002987 profilingService.Disconnect();
Sadik Armagan1625efc2021-06-10 18:24:34 +01002988 CHECK(profilingService.GetCurrentState() == ProfilingState::NotConnected); // The state should not change
Jim Flynn53e46992019-10-14 12:31:10 +01002989
2990 // Try to disconnect the profiling service while in the "WaitingForAck" state
Keith Davis3201eea2019-10-24 17:30:41 +01002991 profilingService.Update(); // Create the profiling connection
Sadik Armagan1625efc2021-06-10 18:24:34 +01002992 CHECK(profilingService.GetCurrentState() == ProfilingState::WaitingForAck);
Jim Flynn53e46992019-10-14 12:31:10 +01002993 profilingService.Disconnect();
Sadik Armagan1625efc2021-06-10 18:24:34 +01002994 CHECK(profilingService.GetCurrentState() == ProfilingState::WaitingForAck); // The state should not change
Jim Flynn53e46992019-10-14 12:31:10 +01002995
2996 // Try to disconnect the profiling service while in the "Active" state
Keith Davis3201eea2019-10-24 17:30:41 +01002997 profilingService.Update(); // Start the command handler and the send thread
Jim Flynn53e46992019-10-14 12:31:10 +01002998
Colm Donelan2ba48d22019-11-29 09:10:59 +00002999 // Get the mock profiling connection
3000 MockProfilingConnection* mockProfilingConnection = helper.GetMockProfilingConnection();
Sadik Armagan1625efc2021-06-10 18:24:34 +01003001 CHECK(mockProfilingConnection);
Colm Donelan2ba48d22019-11-29 09:10:59 +00003002
Jim Flynn53e46992019-10-14 12:31:10 +01003003 // Wait for the Stream Metadata packet the be sent
3004 // (we are not testing the connection acknowledgement here so it will be ignored by this test)
Finn Williams09ad6f92019-12-19 17:05:18 +00003005 helper.WaitForPacketsSent(mockProfilingConnection, PacketType::StreamMetaData);
Jim Flynn53e46992019-10-14 12:31:10 +01003006
3007 // Force the profiling service to the "Active" state
3008 helper.ForceTransitionToState(ProfilingState::Active);
Sadik Armagan1625efc2021-06-10 18:24:34 +01003009 CHECK(profilingService.GetCurrentState() == ProfilingState::Active);
Jim Flynn53e46992019-10-14 12:31:10 +01003010
Jim Flynn53e46992019-10-14 12:31:10 +01003011 // Check that the profiling connection is open
Sadik Armagan1625efc2021-06-10 18:24:34 +01003012 CHECK(mockProfilingConnection->IsOpen());
Jim Flynn53e46992019-10-14 12:31:10 +01003013
3014 profilingService.Disconnect();
Sadik Armagan1625efc2021-06-10 18:24:34 +01003015 CHECK(profilingService.GetCurrentState() == ProfilingState::NotConnected); // The state should have changed
Jim Flynn53e46992019-10-14 12:31:10 +01003016
3017 // Check that the profiling connection has been reset
3018 mockProfilingConnection = helper.GetMockProfilingConnection();
Sadik Armagan1625efc2021-06-10 18:24:34 +01003019 CHECK(mockProfilingConnection == nullptr);
Jim Flynn53e46992019-10-14 12:31:10 +01003020
3021 // Reset the profiling service to stop any running thread
3022 options.m_EnableProfiling = false;
3023 profilingService.ResetExternalProfilingOptions(options, true);
3024}
3025
Sadik Armagan1625efc2021-06-10 18:24:34 +01003026TEST_CASE("CheckProfilingServiceGoodPerJobCounterSelectionPacket")
Matteo Martincigh994b5342019-10-11 17:19:56 +01003027{
Matteo Martincigh994b5342019-10-11 17:19:56 +01003028 // Reset the profiling service to the uninitialized state
Kevin Mayd92a6e42021-02-04 10:27:41 +00003029 armnn::IRuntime::CreationOptions::ExternalProfilingOptions options;
Keith Davis3201eea2019-10-24 17:30:41 +01003030 options.m_EnableProfiling = true;
Sadik Armagan3184c902020-03-18 10:57:30 +00003031 armnn::profiling::ProfilingService profilingService;
Matteo Martincigh994b5342019-10-11 17:19:56 +01003032 profilingService.ResetExternalProfilingOptions(options, true);
3033
Sadik Armagan3184c902020-03-18 10:57:30 +00003034 // Swap the profiling connection factory in the profiling service instance with our mock one
3035 SwapProfilingConnectionFactoryHelper helper(profilingService);
3036
Matteo Martincigh994b5342019-10-11 17:19:56 +01003037 // Bring the profiling service to the "Active" state
Sadik Armagan1625efc2021-06-10 18:24:34 +01003038 CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
Keith Davis3201eea2019-10-24 17:30:41 +01003039 profilingService.Update(); // Initialize the counter directory
Sadik Armagan1625efc2021-06-10 18:24:34 +01003040 CHECK(profilingService.GetCurrentState() == ProfilingState::NotConnected);
Keith Davis3201eea2019-10-24 17:30:41 +01003041 profilingService.Update(); // Create the profiling connection
Sadik Armagan1625efc2021-06-10 18:24:34 +01003042 CHECK(profilingService.GetCurrentState() == ProfilingState::WaitingForAck);
Keith Davis3201eea2019-10-24 17:30:41 +01003043 profilingService.Update(); // Start the command handler and the send thread
Matteo Martincigh994b5342019-10-11 17:19:56 +01003044
Colm Donelan2ba48d22019-11-29 09:10:59 +00003045 // Get the mock profiling connection
3046 MockProfilingConnection* mockProfilingConnection = helper.GetMockProfilingConnection();
Sadik Armagan1625efc2021-06-10 18:24:34 +01003047 CHECK(mockProfilingConnection);
Colm Donelan2ba48d22019-11-29 09:10:59 +00003048
Matteo Martincigh994b5342019-10-11 17:19:56 +01003049 // Wait for the Stream Metadata packet the be sent
3050 // (we are not testing the connection acknowledgement here so it will be ignored by this test)
Finn Williams09ad6f92019-12-19 17:05:18 +00003051 helper.WaitForPacketsSent(mockProfilingConnection, PacketType::StreamMetaData);
Matteo Martincigh994b5342019-10-11 17:19:56 +01003052
3053 // Force the profiling service to the "Active" state
3054 helper.ForceTransitionToState(ProfilingState::Active);
Sadik Armagan1625efc2021-06-10 18:24:34 +01003055 CHECK(profilingService.GetCurrentState() == ProfilingState::Active);
Matteo Martincigh994b5342019-10-11 17:19:56 +01003056
Matteo Martincigh994b5342019-10-11 17:19:56 +01003057 // Write a "Per-Job Counter Selection" packet into the mock profiling connection, to simulate an input from an
3058 // external profiling service
3059
3060 // Per-Job Counter Selection packet header:
3061 // 26:31 [6] packet_family: Control Packet Family, value 0b000000
3062 // 16:25 [10] packet_id: Packet identifier, value 0b0000000100
3063 // 8:15 [8] reserved: Reserved, value 0b00000000
3064 // 0:7 [8] reserved: Reserved, value 0b00000000
3065 uint32_t packetFamily = 0;
3066 uint32_t packetId = 5;
Keith Davis3201eea2019-10-24 17:30:41 +01003067 uint32_t header = ((packetFamily & 0x0000003F) << 26) | ((packetId & 0x000003FF) << 16);
Matteo Martincigh994b5342019-10-11 17:19:56 +01003068
3069 // Create the Per-Job Counter Selection packet
Jim Flynnbbfe6032020-07-20 16:57:44 +01003070 // Length == 0, this will disable the collection of counters
3071 arm::pipe::Packet periodicCounterSelectionPacket(header);
Matteo Martincigh994b5342019-10-11 17:19:56 +01003072
3073 // Write the packet to the mock profiling connection
3074 mockProfilingConnection->WritePacket(std::move(periodicCounterSelectionPacket));
3075
3076 // Wait for a bit (must at least be the delay value of the mock profiling connection) to make sure that
3077 // the Per-Job Counter Selection packet gets processed by the profiling service
Colm Donelan2ba48d22019-11-29 09:10:59 +00003078 std::this_thread::sleep_for(std::chrono::milliseconds(5));
Matteo Martincigh994b5342019-10-11 17:19:56 +01003079
Matteo Martincigh994b5342019-10-11 17:19:56 +01003080 // The Per-Job Counter Selection Command Handler should not have updated the profiling state
Sadik Armagan1625efc2021-06-10 18:24:34 +01003081 CHECK(profilingService.GetCurrentState() == ProfilingState::Active);
Matteo Martincigh994b5342019-10-11 17:19:56 +01003082
Finn Williams09ad6f92019-12-19 17:05:18 +00003083 // The Per-Job Counter Selection packets are dropped silently, so there should be no reply coming
3084 // from the profiling service
3085 const auto StreamMetaDataSize = static_cast<unsigned long>(
3086 helper.WaitForPacketsSent(mockProfilingConnection, PacketType::StreamMetaData, 0, 0));
Sadik Armagan1625efc2021-06-10 18:24:34 +01003087 CHECK(StreamMetaDataSize == mockProfilingConnection->GetWrittenDataSize());
Finn Williams09ad6f92019-12-19 17:05:18 +00003088
Matteo Martincigh994b5342019-10-11 17:19:56 +01003089 // Reset the profiling service to stop any running thread
3090 options.m_EnableProfiling = false;
3091 profilingService.ResetExternalProfilingOptions(options, true);
3092}
3093
Sadik Armagan1625efc2021-06-10 18:24:34 +01003094TEST_CASE("CheckConfigureProfilingServiceOn")
Jim Flynn672d06e2019-10-15 10:18:11 +01003095{
Kevin Mayd92a6e42021-02-04 10:27:41 +00003096 armnn::IRuntime::CreationOptions::ExternalProfilingOptions options;
Keith Davis3201eea2019-10-24 17:30:41 +01003097 options.m_EnableProfiling = true;
Sadik Armagan3184c902020-03-18 10:57:30 +00003098 armnn::profiling::ProfilingService profilingService;
Sadik Armagan1625efc2021-06-10 18:24:34 +01003099 CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
Jim Flynn672d06e2019-10-15 10:18:11 +01003100 profilingService.ConfigureProfilingService(options);
3101 // should get as far as NOT_CONNECTED
Sadik Armagan1625efc2021-06-10 18:24:34 +01003102 CHECK(profilingService.GetCurrentState() == ProfilingState::NotConnected);
Jim Flynn672d06e2019-10-15 10:18:11 +01003103 // Reset the profiling service to stop any running thread
3104 options.m_EnableProfiling = false;
3105 profilingService.ResetExternalProfilingOptions(options, true);
3106}
3107
Sadik Armagan1625efc2021-06-10 18:24:34 +01003108TEST_CASE("CheckConfigureProfilingServiceOff")
Jim Flynn672d06e2019-10-15 10:18:11 +01003109{
Kevin Mayd92a6e42021-02-04 10:27:41 +00003110 armnn::IRuntime::CreationOptions::ExternalProfilingOptions options;
Sadik Armagan3184c902020-03-18 10:57:30 +00003111 armnn::profiling::ProfilingService profilingService;
Sadik Armagan1625efc2021-06-10 18:24:34 +01003112 CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
Jim Flynn672d06e2019-10-15 10:18:11 +01003113 profilingService.ConfigureProfilingService(options);
3114 // should not move from Uninitialised
Sadik Armagan1625efc2021-06-10 18:24:34 +01003115 CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
Jim Flynn672d06e2019-10-15 10:18:11 +01003116 // Reset the profiling service to stop any running thread
3117 options.m_EnableProfiling = false;
3118 profilingService.ResetExternalProfilingOptions(options, true);
3119}
3120
Sadik Armagan1625efc2021-06-10 18:24:34 +01003121TEST_CASE("CheckProfilingServiceEnabled")
Colm Donelan2ba48d22019-11-29 09:10:59 +00003122{
3123 // Locally reduce log level to "Warning", as this test needs to parse a warning message from the standard output
3124 LogLevelSwapper logLevelSwapper(armnn::LogSeverity::Warning);
Kevin Mayd92a6e42021-02-04 10:27:41 +00003125 armnn::IRuntime::CreationOptions::ExternalProfilingOptions options;
Colm Donelan2ba48d22019-11-29 09:10:59 +00003126 options.m_EnableProfiling = true;
Sadik Armagan3184c902020-03-18 10:57:30 +00003127 armnn::profiling::ProfilingService profilingService;
Colm Donelan2ba48d22019-11-29 09:10:59 +00003128 profilingService.ResetExternalProfilingOptions(options, true);
Sadik Armagan1625efc2021-06-10 18:24:34 +01003129 CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
Colm Donelan2ba48d22019-11-29 09:10:59 +00003130 profilingService.Update();
Sadik Armagan1625efc2021-06-10 18:24:34 +01003131 CHECK(profilingService.GetCurrentState() == ProfilingState::NotConnected);
Colm Donelan2ba48d22019-11-29 09:10:59 +00003132
3133 // Redirect the output to a local stream so that we can parse the warning message
3134 std::stringstream ss;
3135 StreamRedirector streamRedirector(std::cout, ss.rdbuf());
3136 profilingService.Update();
Finn Williams09ad6f92019-12-19 17:05:18 +00003137
3138 // Reset the profiling service to stop any running thread
3139 options.m_EnableProfiling = false;
3140 profilingService.ResetExternalProfilingOptions(options, true);
3141
Colm Donelan2ba48d22019-11-29 09:10:59 +00003142 streamRedirector.CancelRedirect();
3143
3144 // Check that the expected error has occurred and logged to the standard output
David Monahana8837bf2020-04-16 10:01:56 +01003145 if (ss.str().find("Cannot connect to stream socket: Connection refused") == std::string::npos)
Colm Donelan2ba48d22019-11-29 09:10:59 +00003146 {
3147 std::cout << ss.str();
Sadik Armagan1625efc2021-06-10 18:24:34 +01003148 FAIL("Expected string not found.");
Colm Donelan2ba48d22019-11-29 09:10:59 +00003149 }
Colm Donelan2ba48d22019-11-29 09:10:59 +00003150}
3151
Sadik Armagan1625efc2021-06-10 18:24:34 +01003152TEST_CASE("CheckProfilingServiceEnabledRuntime")
Colm Donelan2ba48d22019-11-29 09:10:59 +00003153{
3154 // Locally reduce log level to "Warning", as this test needs to parse a warning message from the standard output
3155 LogLevelSwapper logLevelSwapper(armnn::LogSeverity::Warning);
Kevin Mayd92a6e42021-02-04 10:27:41 +00003156 armnn::IRuntime::CreationOptions::ExternalProfilingOptions options;
Sadik Armagan3184c902020-03-18 10:57:30 +00003157 armnn::profiling::ProfilingService profilingService;
Colm Donelan2ba48d22019-11-29 09:10:59 +00003158 profilingService.ResetExternalProfilingOptions(options, true);
Sadik Armagan1625efc2021-06-10 18:24:34 +01003159 CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
Colm Donelan2ba48d22019-11-29 09:10:59 +00003160 profilingService.Update();
Sadik Armagan1625efc2021-06-10 18:24:34 +01003161 CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
Colm Donelan2ba48d22019-11-29 09:10:59 +00003162 options.m_EnableProfiling = true;
3163 profilingService.ResetExternalProfilingOptions(options);
Sadik Armagan1625efc2021-06-10 18:24:34 +01003164 CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
Colm Donelan2ba48d22019-11-29 09:10:59 +00003165 profilingService.Update();
Sadik Armagan1625efc2021-06-10 18:24:34 +01003166 CHECK(profilingService.GetCurrentState() == ProfilingState::NotConnected);
Colm Donelan2ba48d22019-11-29 09:10:59 +00003167
3168 // Redirect the output to a local stream so that we can parse the warning message
3169 std::stringstream ss;
3170 StreamRedirector streamRedirector(std::cout, ss.rdbuf());
3171 profilingService.Update();
3172
Finn Williams09ad6f92019-12-19 17:05:18 +00003173 // Reset the profiling service to stop any running thread
3174 options.m_EnableProfiling = false;
3175 profilingService.ResetExternalProfilingOptions(options, true);
3176
Colm Donelan2ba48d22019-11-29 09:10:59 +00003177 streamRedirector.CancelRedirect();
3178
3179 // Check that the expected error has occurred and logged to the standard output
David Monahana8837bf2020-04-16 10:01:56 +01003180 if (ss.str().find("Cannot connect to stream socket: Connection refused") == std::string::npos)
Colm Donelan2ba48d22019-11-29 09:10:59 +00003181 {
3182 std::cout << ss.str();
Sadik Armagan1625efc2021-06-10 18:24:34 +01003183 FAIL("Expected string not found.");
Colm Donelan2ba48d22019-11-29 09:10:59 +00003184 }
Colm Donelan2ba48d22019-11-29 09:10:59 +00003185}
3186
Sadik Armagan1625efc2021-06-10 18:24:34 +01003187TEST_CASE("CheckProfilingServiceBadConnectionAcknowledgedPacket")
Colm Donelan2ba48d22019-11-29 09:10:59 +00003188{
3189 // Locally reduce log level to "Warning", as this test needs to parse a warning message from the standard output
3190 LogLevelSwapper logLevelSwapper(armnn::LogSeverity::Warning);
Sadik Armagan3184c902020-03-18 10:57:30 +00003191
Colm Donelan2ba48d22019-11-29 09:10:59 +00003192
3193 // Redirect the standard output to a local stream so that we can parse the warning message
3194 std::stringstream ss;
3195 StreamRedirector streamRedirector(std::cout, ss.rdbuf());
3196
Colm Donelan2ba48d22019-11-29 09:10:59 +00003197 // Reset the profiling service to the uninitialized state
Kevin Mayd92a6e42021-02-04 10:27:41 +00003198 armnn::IRuntime::CreationOptions::ExternalProfilingOptions options;
Colm Donelan2ba48d22019-11-29 09:10:59 +00003199 options.m_EnableProfiling = true;
Sadik Armagan3184c902020-03-18 10:57:30 +00003200 armnn::profiling::ProfilingService profilingService;
Colm Donelan2ba48d22019-11-29 09:10:59 +00003201 profilingService.ResetExternalProfilingOptions(options, true);
3202
Sadik Armagan3184c902020-03-18 10:57:30 +00003203 // Swap the profiling connection factory in the profiling service instance with our mock one
3204 SwapProfilingConnectionFactoryHelper helper(profilingService);
3205
Colm Donelan2ba48d22019-11-29 09:10:59 +00003206 // Bring the profiling service to the "WaitingForAck" state
Sadik Armagan1625efc2021-06-10 18:24:34 +01003207 CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
Colm Donelan2ba48d22019-11-29 09:10:59 +00003208 profilingService.Update(); // Initialize the counter directory
Sadik Armagan1625efc2021-06-10 18:24:34 +01003209 CHECK(profilingService.GetCurrentState() == ProfilingState::NotConnected);
Colm Donelan2ba48d22019-11-29 09:10:59 +00003210 profilingService.Update(); // Create the profiling connection
3211
3212 // Get the mock profiling connection
3213 MockProfilingConnection* mockProfilingConnection = helper.GetMockProfilingConnection();
Sadik Armagan1625efc2021-06-10 18:24:34 +01003214 CHECK(mockProfilingConnection);
Colm Donelan2ba48d22019-11-29 09:10:59 +00003215
Sadik Armagan1625efc2021-06-10 18:24:34 +01003216 CHECK(profilingService.GetCurrentState() == ProfilingState::WaitingForAck);
Colm Donelan2ba48d22019-11-29 09:10:59 +00003217
3218 // Connection Acknowledged Packet header (word 0, word 1 is always zero):
3219 // 26:31 [6] packet_family: Control Packet Family, value 0b000000
3220 // 16:25 [10] packet_id: Packet identifier, value 0b0000000001
3221 // 8:15 [8] reserved: Reserved, value 0b00000000
3222 // 0:7 [8] reserved: Reserved, value 0b00000000
3223 uint32_t packetFamily = 0;
3224 uint32_t packetId = 37; // Wrong packet id!!!
3225 uint32_t header = ((packetFamily & 0x0000003F) << 26) | ((packetId & 0x000003FF) << 16);
3226
3227 // Create the Connection Acknowledged Packet
Jim Flynnbbfe6032020-07-20 16:57:44 +01003228 arm::pipe::Packet connectionAcknowledgedPacket(header);
Finn Williams09ad6f92019-12-19 17:05:18 +00003229 // Write an invalid "Connection Acknowledged" packet into the mock profiling connection, to simulate an invalid
3230 // reply from an external profiling service
Colm Donelan2ba48d22019-11-29 09:10:59 +00003231 mockProfilingConnection->WritePacket(std::move(connectionAcknowledgedPacket));
3232
Finn Williams09ad6f92019-12-19 17:05:18 +00003233 // Start the command thread
3234 profilingService.Update();
3235
3236 // Wait for the command thread to join
3237 options.m_EnableProfiling = false;
3238 profilingService.ResetExternalProfilingOptions(options, true);
Colm Donelan2ba48d22019-11-29 09:10:59 +00003239
3240 streamRedirector.CancelRedirect();
3241
3242 // Check that the expected error has occurred and logged to the standard output
David Monahana8837bf2020-04-16 10:01:56 +01003243 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 +00003244 {
3245 std::cout << ss.str();
Sadik Armagan1625efc2021-06-10 18:24:34 +01003246 FAIL("Expected string not found.");
Colm Donelan2ba48d22019-11-29 09:10:59 +00003247 }
Colm Donelan2ba48d22019-11-29 09:10:59 +00003248}
3249
Sadik Armagan1625efc2021-06-10 18:24:34 +01003250TEST_CASE("CheckProfilingServiceBadRequestCounterDirectoryPacket")
Colm Donelan2ba48d22019-11-29 09:10:59 +00003251{
3252 // Locally reduce log level to "Warning", as this test needs to parse a warning message from the standard output
3253 LogLevelSwapper logLevelSwapper(armnn::LogSeverity::Warning);
Colm Donelan2ba48d22019-11-29 09:10:59 +00003254
3255 // Redirect the standard output to a local stream so that we can parse the warning message
3256 std::stringstream ss;
3257 StreamRedirector streamRedirector(std::cout, ss.rdbuf());
3258
3259 // Reset the profiling service to the uninitialized state
Kevin Mayd92a6e42021-02-04 10:27:41 +00003260 armnn::IRuntime::CreationOptions::ExternalProfilingOptions options;
Colm Donelan2ba48d22019-11-29 09:10:59 +00003261 options.m_EnableProfiling = true;
Sadik Armagan3184c902020-03-18 10:57:30 +00003262 armnn::profiling::ProfilingService profilingService;
Colm Donelan2ba48d22019-11-29 09:10:59 +00003263 profilingService.ResetExternalProfilingOptions(options, true);
3264
Sadik Armagan3184c902020-03-18 10:57:30 +00003265 // Swap the profiling connection factory in the profiling service instance with our mock one
3266 SwapProfilingConnectionFactoryHelper helper(profilingService);
3267
Colm Donelan2ba48d22019-11-29 09:10:59 +00003268 // Bring the profiling service to the "Active" state
Sadik Armagan1625efc2021-06-10 18:24:34 +01003269 CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
Colm Donelan2ba48d22019-11-29 09:10:59 +00003270 helper.ForceTransitionToState(ProfilingState::NotConnected);
Sadik Armagan1625efc2021-06-10 18:24:34 +01003271 CHECK(profilingService.GetCurrentState() == ProfilingState::NotConnected);
Colm Donelan2ba48d22019-11-29 09:10:59 +00003272 profilingService.Update(); // Create the profiling connection
Sadik Armagan1625efc2021-06-10 18:24:34 +01003273 CHECK(profilingService.GetCurrentState() == ProfilingState::WaitingForAck);
Colm Donelan2ba48d22019-11-29 09:10:59 +00003274
3275 // Get the mock profiling connection
3276 MockProfilingConnection* mockProfilingConnection = helper.GetMockProfilingConnection();
Sadik Armagan1625efc2021-06-10 18:24:34 +01003277 CHECK(mockProfilingConnection);
Colm Donelan2ba48d22019-11-29 09:10:59 +00003278
Colm Donelan2ba48d22019-11-29 09:10:59 +00003279 // Write a valid "Request Counter Directory" packet into the mock profiling connection, to simulate a valid
3280 // reply from an external profiling service
3281
3282 // Request Counter Directory packet header (word 0, word 1 is always zero):
3283 // 26:31 [6] packet_family: Control Packet Family, value 0b000000
3284 // 16:25 [10] packet_id: Packet identifier, value 0b0000000011
3285 // 8:15 [8] reserved: Reserved, value 0b00000000
3286 // 0:7 [8] reserved: Reserved, value 0b00000000
3287 uint32_t packetFamily = 0;
3288 uint32_t packetId = 123; // Wrong packet id!!!
3289 uint32_t header = ((packetFamily & 0x0000003F) << 26) | ((packetId & 0x000003FF) << 16);
3290
3291 // Create the Request Counter Directory packet
Jim Flynnbbfe6032020-07-20 16:57:44 +01003292 arm::pipe::Packet requestCounterDirectoryPacket(header);
Colm Donelan2ba48d22019-11-29 09:10:59 +00003293
3294 // Write the packet to the mock profiling connection
3295 mockProfilingConnection->WritePacket(std::move(requestCounterDirectoryPacket));
3296
Finn Williams09ad6f92019-12-19 17:05:18 +00003297 // Start the command handler and the send thread
3298 profilingService.Update();
3299
3300 // Reset the profiling service to stop and join any running thread
3301 options.m_EnableProfiling = false;
3302 profilingService.ResetExternalProfilingOptions(options, true);
Colm Donelan2ba48d22019-11-29 09:10:59 +00003303
3304 streamRedirector.CancelRedirect();
3305
3306 // Check that the expected error has occurred and logged to the standard output
David Monahana8837bf2020-04-16 10:01:56 +01003307 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 +00003308 {
3309 std::cout << ss.str();
Sadik Armagan1625efc2021-06-10 18:24:34 +01003310 FAIL("Expected string not found.");
Colm Donelan2ba48d22019-11-29 09:10:59 +00003311 }
Colm Donelan2ba48d22019-11-29 09:10:59 +00003312}
3313
Sadik Armagan1625efc2021-06-10 18:24:34 +01003314TEST_CASE("CheckProfilingServiceBadPeriodicCounterSelectionPacket")
Colm Donelan2ba48d22019-11-29 09:10:59 +00003315{
3316 // Locally reduce log level to "Warning", as this test needs to parse a warning message from the standard output
3317 LogLevelSwapper logLevelSwapper(armnn::LogSeverity::Warning);
Colm Donelan2ba48d22019-11-29 09:10:59 +00003318
3319 // Redirect the standard output to a local stream so that we can parse the warning message
3320 std::stringstream ss;
3321 StreamRedirector streamRedirector(std::cout, ss.rdbuf());
3322
3323 // Reset the profiling service to the uninitialized state
Kevin Mayd92a6e42021-02-04 10:27:41 +00003324 armnn::IRuntime::CreationOptions::ExternalProfilingOptions options;
Colm Donelan2ba48d22019-11-29 09:10:59 +00003325 options.m_EnableProfiling = true;
Sadik Armagan3184c902020-03-18 10:57:30 +00003326 armnn::profiling::ProfilingService profilingService;
Colm Donelan2ba48d22019-11-29 09:10:59 +00003327 profilingService.ResetExternalProfilingOptions(options, true);
3328
Sadik Armagan3184c902020-03-18 10:57:30 +00003329 // Swap the profiling connection factory in the profiling service instance with our mock one
3330 SwapProfilingConnectionFactoryHelper helper(profilingService);
3331
Colm Donelan2ba48d22019-11-29 09:10:59 +00003332 // Bring the profiling service to the "Active" state
Sadik Armagan1625efc2021-06-10 18:24:34 +01003333 CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised);
Colm Donelan2ba48d22019-11-29 09:10:59 +00003334 profilingService.Update(); // Initialize the counter directory
Sadik Armagan1625efc2021-06-10 18:24:34 +01003335 CHECK(profilingService.GetCurrentState() == ProfilingState::NotConnected);
Colm Donelan2ba48d22019-11-29 09:10:59 +00003336 profilingService.Update(); // Create the profiling connection
Sadik Armagan1625efc2021-06-10 18:24:34 +01003337 CHECK(profilingService.GetCurrentState() == ProfilingState::WaitingForAck);
Colm Donelan2ba48d22019-11-29 09:10:59 +00003338 profilingService.Update(); // Start the command handler and the send thread
3339
3340 // Get the mock profiling connection
3341 MockProfilingConnection* mockProfilingConnection = helper.GetMockProfilingConnection();
Sadik Armagan1625efc2021-06-10 18:24:34 +01003342 CHECK(mockProfilingConnection);
Colm Donelan2ba48d22019-11-29 09:10:59 +00003343
Colm Donelan2ba48d22019-11-29 09:10:59 +00003344 // Write a "Periodic Counter Selection" packet into the mock profiling connection, to simulate an input from an
3345 // external profiling service
3346
3347 // Periodic Counter Selection packet header:
3348 // 26:31 [6] packet_family: Control Packet Family, value 0b000000
3349 // 16:25 [10] packet_id: Packet identifier, value 0b0000000100
3350 // 8:15 [8] reserved: Reserved, value 0b00000000
3351 // 0:7 [8] reserved: Reserved, value 0b00000000
3352 uint32_t packetFamily = 0;
3353 uint32_t packetId = 999; // Wrong packet id!!!
3354 uint32_t header = ((packetFamily & 0x0000003F) << 26) | ((packetId & 0x000003FF) << 16);
3355
3356 // Create the Periodic Counter Selection packet
Jim Flynnbbfe6032020-07-20 16:57:44 +01003357 // Length == 0, this will disable the collection of counters
3358 arm::pipe::Packet periodicCounterSelectionPacket(header);
Colm Donelan2ba48d22019-11-29 09:10:59 +00003359
3360 // Write the packet to the mock profiling connection
3361 mockProfilingConnection->WritePacket(std::move(periodicCounterSelectionPacket));
Finn Williams09ad6f92019-12-19 17:05:18 +00003362 profilingService.Update();
Colm Donelan2ba48d22019-11-29 09:10:59 +00003363
Finn Williams09ad6f92019-12-19 17:05:18 +00003364 // Reset the profiling service to stop any running thread
3365 options.m_EnableProfiling = false;
3366 profilingService.ResetExternalProfilingOptions(options, true);
Colm Donelan2ba48d22019-11-29 09:10:59 +00003367
3368 // Check that the expected error has occurred and logged to the standard output
3369 streamRedirector.CancelRedirect();
3370
3371 // Check that the expected error has occurred and logged to the standard output
David Monahana8837bf2020-04-16 10:01:56 +01003372 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 +00003373 {
3374 std::cout << ss.str();
Sadik Armagan1625efc2021-06-10 18:24:34 +01003375 FAIL("Expected string not found.");
Colm Donelan2ba48d22019-11-29 09:10:59 +00003376 }
Colm Donelan2ba48d22019-11-29 09:10:59 +00003377}
Jim Flynn97897022020-02-02 12:52:59 +00003378
Sadik Armagan1625efc2021-06-10 18:24:34 +01003379TEST_CASE("CheckCounterIdMap")
David Monahande803072020-01-30 12:44:23 +00003380{
3381 CounterIdMap counterIdMap;
Sadik Armagan1625efc2021-06-10 18:24:34 +01003382 CHECK_THROWS_AS(counterIdMap.GetBackendId(0), armnn::Exception);
3383 CHECK_THROWS_AS(counterIdMap.GetGlobalId(0, armnn::profiling::BACKEND_ID), armnn::Exception);
David Monahande803072020-01-30 12:44:23 +00003384
3385 uint16_t globalCounterIds = 0;
3386
3387 armnn::BackendId cpuRefId(armnn::Compute::CpuRef);
3388 armnn::BackendId cpuAccId(armnn::Compute::CpuAcc);
3389
3390 std::vector<uint16_t> cpuRefCounters = {0, 1, 2, 3};
3391 std::vector<uint16_t> cpuAccCounters = {0, 1};
3392
3393 for (uint16_t backendCounterId : cpuRefCounters)
3394 {
3395 counterIdMap.RegisterMapping(globalCounterIds, backendCounterId, cpuRefId);
3396 ++globalCounterIds;
3397 }
3398 for (uint16_t backendCounterId : cpuAccCounters)
3399 {
3400 counterIdMap.RegisterMapping(globalCounterIds, backendCounterId, cpuAccId);
3401 ++globalCounterIds;
3402 }
3403
Sadik Armagan1625efc2021-06-10 18:24:34 +01003404 CHECK(counterIdMap.GetBackendId(0) == (std::pair<uint16_t, armnn::BackendId>(0, cpuRefId)));
3405 CHECK(counterIdMap.GetBackendId(1) == (std::pair<uint16_t, armnn::BackendId>(1, cpuRefId)));
3406 CHECK(counterIdMap.GetBackendId(2) == (std::pair<uint16_t, armnn::BackendId>(2, cpuRefId)));
3407 CHECK(counterIdMap.GetBackendId(3) == (std::pair<uint16_t, armnn::BackendId>(3, cpuRefId)));
3408 CHECK(counterIdMap.GetBackendId(4) == (std::pair<uint16_t, armnn::BackendId>(0, cpuAccId)));
3409 CHECK(counterIdMap.GetBackendId(5) == (std::pair<uint16_t, armnn::BackendId>(1, cpuAccId)));
David Monahande803072020-01-30 12:44:23 +00003410
Sadik Armagan1625efc2021-06-10 18:24:34 +01003411 CHECK(counterIdMap.GetGlobalId(0, cpuRefId) == 0);
3412 CHECK(counterIdMap.GetGlobalId(1, cpuRefId) == 1);
3413 CHECK(counterIdMap.GetGlobalId(2, cpuRefId) == 2);
3414 CHECK(counterIdMap.GetGlobalId(3, cpuRefId) == 3);
3415 CHECK(counterIdMap.GetGlobalId(0, cpuAccId) == 4);
3416 CHECK(counterIdMap.GetGlobalId(1, cpuAccId) == 5);
David Monahande803072020-01-30 12:44:23 +00003417}
Colm Donelan2ba48d22019-11-29 09:10:59 +00003418
Sadik Armagan1625efc2021-06-10 18:24:34 +01003419TEST_CASE("CheckRegisterBackendCounters")
Jim Flynn97897022020-02-02 12:52:59 +00003420{
3421 uint16_t globalCounterIds = armnn::profiling::INFERENCES_RUN;
3422 armnn::BackendId cpuRefId(armnn::Compute::CpuRef);
3423
Jim Flynn97897022020-02-02 12:52:59 +00003424 // Reset the profiling service to the uninitialized state
Kevin Mayd92a6e42021-02-04 10:27:41 +00003425 armnn::IRuntime::CreationOptions::ExternalProfilingOptions options;
Jim Flynn97897022020-02-02 12:52:59 +00003426 options.m_EnableProfiling = true;
Sadik Armagan3184c902020-03-18 10:57:30 +00003427 ProfilingService profilingService;
Jim Flynn97897022020-02-02 12:52:59 +00003428 profilingService.ResetExternalProfilingOptions(options, true);
3429
Sadik Armagan3184c902020-03-18 10:57:30 +00003430 RegisterBackendCounters registerBackendCounters(globalCounterIds, cpuRefId, profilingService);
3431
3432
3433
Sadik Armagan1625efc2021-06-10 18:24:34 +01003434 CHECK(profilingService.GetCounterDirectory().GetCategories().empty());
Jim Flynn97897022020-02-02 12:52:59 +00003435 registerBackendCounters.RegisterCategory("categoryOne");
3436 auto categoryOnePtr = profilingService.GetCounterDirectory().GetCategory("categoryOne");
Sadik Armagan1625efc2021-06-10 18:24:34 +01003437 CHECK(categoryOnePtr);
Jim Flynn97897022020-02-02 12:52:59 +00003438
Sadik Armagan1625efc2021-06-10 18:24:34 +01003439 CHECK(profilingService.GetCounterDirectory().GetDevices().empty());
Jim Flynn97897022020-02-02 12:52:59 +00003440 globalCounterIds = registerBackendCounters.RegisterDevice("deviceOne");
3441 auto deviceOnePtr = profilingService.GetCounterDirectory().GetDevice(globalCounterIds);
Sadik Armagan1625efc2021-06-10 18:24:34 +01003442 CHECK(deviceOnePtr);
3443 CHECK(deviceOnePtr->m_Name == "deviceOne");
Jim Flynn97897022020-02-02 12:52:59 +00003444
Sadik Armagan1625efc2021-06-10 18:24:34 +01003445 CHECK(profilingService.GetCounterDirectory().GetCounterSets().empty());
Jim Flynn97897022020-02-02 12:52:59 +00003446 globalCounterIds = registerBackendCounters.RegisterCounterSet("counterSetOne");
3447 auto counterSetOnePtr = profilingService.GetCounterDirectory().GetCounterSet(globalCounterIds);
Sadik Armagan1625efc2021-06-10 18:24:34 +01003448 CHECK(counterSetOnePtr);
3449 CHECK(counterSetOnePtr->m_Name == "counterSetOne");
Jim Flynn97897022020-02-02 12:52:59 +00003450
3451 uint16_t newGlobalCounterId = registerBackendCounters.RegisterCounter(0,
3452 "categoryOne",
3453 0,
3454 0,
3455 1.f,
3456 "CounterOne",
3457 "first test counter");
Sadik Armagan1625efc2021-06-10 18:24:34 +01003458 CHECK((newGlobalCounterId = armnn::profiling::INFERENCES_RUN + 1));
Jim Flynn97897022020-02-02 12:52:59 +00003459 uint16_t mappedGlobalId = profilingService.GetCounterMappings().GetGlobalId(0, cpuRefId);
Sadik Armagan1625efc2021-06-10 18:24:34 +01003460 CHECK(mappedGlobalId == newGlobalCounterId);
Jim Flynn97897022020-02-02 12:52:59 +00003461 auto backendMapping = profilingService.GetCounterMappings().GetBackendId(newGlobalCounterId);
Sadik Armagan1625efc2021-06-10 18:24:34 +01003462 CHECK(backendMapping.first == 0);
3463 CHECK(backendMapping.second == cpuRefId);
Jim Flynn97897022020-02-02 12:52:59 +00003464
3465 // Reset the profiling service to stop any running thread
3466 options.m_EnableProfiling = false;
3467 profilingService.ResetExternalProfilingOptions(options, true);
3468}
3469
Sadik Armagan1625efc2021-06-10 18:24:34 +01003470TEST_CASE("CheckCounterStatusQuery")
James Conroy2dcd3fe2020-02-06 18:34:52 +00003471{
3472 armnn::IRuntime::CreationOptions options;
3473 options.m_ProfilingOptions.m_EnableProfiling = true;
3474
3475 // Reset the profiling service to the uninitialized state
Sadik Armagan3184c902020-03-18 10:57:30 +00003476 ProfilingService profilingService;
James Conroy2dcd3fe2020-02-06 18:34:52 +00003477 profilingService.ResetExternalProfilingOptions(options.m_ProfilingOptions, true);
3478
3479 const armnn::BackendId cpuRefId(armnn::Compute::CpuRef);
3480 const armnn::BackendId cpuAccId(armnn::Compute::CpuAcc);
3481
3482 // Create BackendProfiling for each backend
3483 BackendProfiling backendProfilingCpuRef(options, profilingService, cpuRefId);
3484 BackendProfiling backendProfilingCpuAcc(options, profilingService, cpuAccId);
3485
3486 uint16_t initialNumGlobalCounterIds = armnn::profiling::INFERENCES_RUN;
3487
3488 // Create RegisterBackendCounters for CpuRef
Sadik Armagan3184c902020-03-18 10:57:30 +00003489 RegisterBackendCounters registerBackendCountersCpuRef(initialNumGlobalCounterIds, cpuRefId, profilingService);
James Conroy2dcd3fe2020-02-06 18:34:52 +00003490
3491 // Create 'testCategory' in CounterDirectory (backend agnostic)
Sadik Armagan1625efc2021-06-10 18:24:34 +01003492 CHECK(profilingService.GetCounterDirectory().GetCategories().empty());
James Conroy2dcd3fe2020-02-06 18:34:52 +00003493 registerBackendCountersCpuRef.RegisterCategory("testCategory");
3494 auto categoryOnePtr = profilingService.GetCounterDirectory().GetCategory("testCategory");
Sadik Armagan1625efc2021-06-10 18:24:34 +01003495 CHECK(categoryOnePtr);
James Conroy2dcd3fe2020-02-06 18:34:52 +00003496
3497 // Counters:
3498 // Global | Local | Backend
3499 // 5 | 0 | CpuRef
3500 // 6 | 1 | CpuRef
3501 // 7 | 1 | CpuAcc
3502
3503 std::vector<uint16_t> cpuRefCounters = {0, 1};
3504 std::vector<uint16_t> cpuAccCounters = {0};
3505
3506 // Register the backend counters for CpuRef and validate GetGlobalId and GetBackendId
3507 uint16_t currentNumGlobalCounterIds = registerBackendCountersCpuRef.RegisterCounter(
3508 0, "testCategory", 0, 0, 1.f, "CpuRefCounter0", "Zeroth CpuRef Counter");
Sadik Armagan1625efc2021-06-10 18:24:34 +01003509 CHECK(currentNumGlobalCounterIds == initialNumGlobalCounterIds + 1);
James Conroy2dcd3fe2020-02-06 18:34:52 +00003510 uint16_t mappedGlobalId = profilingService.GetCounterMappings().GetGlobalId(0, cpuRefId);
Sadik Armagan1625efc2021-06-10 18:24:34 +01003511 CHECK(mappedGlobalId == currentNumGlobalCounterIds);
James Conroy2dcd3fe2020-02-06 18:34:52 +00003512 auto backendMapping = profilingService.GetCounterMappings().GetBackendId(currentNumGlobalCounterIds);
Sadik Armagan1625efc2021-06-10 18:24:34 +01003513 CHECK(backendMapping.first == 0);
3514 CHECK(backendMapping.second == cpuRefId);
James Conroy2dcd3fe2020-02-06 18:34:52 +00003515
3516 currentNumGlobalCounterIds = registerBackendCountersCpuRef.RegisterCounter(
3517 1, "testCategory", 0, 0, 1.f, "CpuRefCounter1", "First CpuRef Counter");
Sadik Armagan1625efc2021-06-10 18:24:34 +01003518 CHECK(currentNumGlobalCounterIds == initialNumGlobalCounterIds + 2);
James Conroy2dcd3fe2020-02-06 18:34:52 +00003519 mappedGlobalId = profilingService.GetCounterMappings().GetGlobalId(1, cpuRefId);
Sadik Armagan1625efc2021-06-10 18:24:34 +01003520 CHECK(mappedGlobalId == currentNumGlobalCounterIds);
James Conroy2dcd3fe2020-02-06 18:34:52 +00003521 backendMapping = profilingService.GetCounterMappings().GetBackendId(currentNumGlobalCounterIds);
Sadik Armagan1625efc2021-06-10 18:24:34 +01003522 CHECK(backendMapping.first == 1);
3523 CHECK(backendMapping.second == cpuRefId);
James Conroy2dcd3fe2020-02-06 18:34:52 +00003524
3525 // Create RegisterBackendCounters for CpuAcc
Sadik Armagan3184c902020-03-18 10:57:30 +00003526 RegisterBackendCounters registerBackendCountersCpuAcc(currentNumGlobalCounterIds, cpuAccId, profilingService);
James Conroy2dcd3fe2020-02-06 18:34:52 +00003527
3528 // Register the backend counter for CpuAcc and validate GetGlobalId and GetBackendId
3529 currentNumGlobalCounterIds = registerBackendCountersCpuAcc.RegisterCounter(
3530 0, "testCategory", 0, 0, 1.f, "CpuAccCounter0", "Zeroth CpuAcc Counter");
Sadik Armagan1625efc2021-06-10 18:24:34 +01003531 CHECK(currentNumGlobalCounterIds == initialNumGlobalCounterIds + 3);
James Conroy2dcd3fe2020-02-06 18:34:52 +00003532 mappedGlobalId = profilingService.GetCounterMappings().GetGlobalId(0, cpuAccId);
Sadik Armagan1625efc2021-06-10 18:24:34 +01003533 CHECK(mappedGlobalId == currentNumGlobalCounterIds);
James Conroy2dcd3fe2020-02-06 18:34:52 +00003534 backendMapping = profilingService.GetCounterMappings().GetBackendId(currentNumGlobalCounterIds);
Sadik Armagan1625efc2021-06-10 18:24:34 +01003535 CHECK(backendMapping.first == 0);
3536 CHECK(backendMapping.second == cpuAccId);
James Conroy2dcd3fe2020-02-06 18:34:52 +00003537
3538 // Create vectors for active counters
3539 const std::vector<uint16_t> activeGlobalCounterIds = {5}; // CpuRef(0) activated
3540 const std::vector<uint16_t> newActiveGlobalCounterIds = {6, 7}; // CpuRef(0) and CpuAcc(1) activated
3541
3542 const uint32_t capturePeriod = 200;
3543 const uint32_t newCapturePeriod = 100;
3544
3545 // Set capture period and active counters in CaptureData
Finn Williams032bc742020-02-12 11:02:34 +00003546 profilingService.SetCaptureData(capturePeriod, activeGlobalCounterIds, {});
James Conroy2dcd3fe2020-02-06 18:34:52 +00003547
3548 // Get vector of active counters for CpuRef and CpuAcc backends
3549 std::vector<CounterStatus> cpuRefCounterStatus = backendProfilingCpuRef.GetActiveCounters();
3550 std::vector<CounterStatus> cpuAccCounterStatus = backendProfilingCpuAcc.GetActiveCounters();
Sadik Armagan1625efc2021-06-10 18:24:34 +01003551 CHECK_EQ(cpuRefCounterStatus.size(), 1);
3552 CHECK_EQ(cpuAccCounterStatus.size(), 0);
James Conroy2dcd3fe2020-02-06 18:34:52 +00003553
3554 // Check active CpuRef counter
Sadik Armagan1625efc2021-06-10 18:24:34 +01003555 CHECK_EQ(cpuRefCounterStatus[0].m_GlobalCounterId, activeGlobalCounterIds[0]);
3556 CHECK_EQ(cpuRefCounterStatus[0].m_BackendCounterId, cpuRefCounters[0]);
3557 CHECK_EQ(cpuRefCounterStatus[0].m_SamplingRateInMicroseconds, capturePeriod);
3558 CHECK_EQ(cpuRefCounterStatus[0].m_Enabled, true);
James Conroy2dcd3fe2020-02-06 18:34:52 +00003559
3560 // Check inactive CpuRef counter
3561 CounterStatus inactiveCpuRefCounter = backendProfilingCpuRef.GetCounterStatus(cpuRefCounters[1]);
Sadik Armagan1625efc2021-06-10 18:24:34 +01003562 CHECK_EQ(inactiveCpuRefCounter.m_GlobalCounterId, 6);
3563 CHECK_EQ(inactiveCpuRefCounter.m_BackendCounterId, cpuRefCounters[1]);
3564 CHECK_EQ(inactiveCpuRefCounter.m_SamplingRateInMicroseconds, 0);
3565 CHECK_EQ(inactiveCpuRefCounter.m_Enabled, false);
James Conroy2dcd3fe2020-02-06 18:34:52 +00003566
3567 // Check inactive CpuAcc counter
3568 CounterStatus inactiveCpuAccCounter = backendProfilingCpuAcc.GetCounterStatus(cpuAccCounters[0]);
Sadik Armagan1625efc2021-06-10 18:24:34 +01003569 CHECK_EQ(inactiveCpuAccCounter.m_GlobalCounterId, 7);
3570 CHECK_EQ(inactiveCpuAccCounter.m_BackendCounterId, cpuAccCounters[0]);
3571 CHECK_EQ(inactiveCpuAccCounter.m_SamplingRateInMicroseconds, 0);
3572 CHECK_EQ(inactiveCpuAccCounter.m_Enabled, false);
James Conroy2dcd3fe2020-02-06 18:34:52 +00003573
3574 // Set new capture period and new active counters in CaptureData
Finn Williams032bc742020-02-12 11:02:34 +00003575 profilingService.SetCaptureData(newCapturePeriod, newActiveGlobalCounterIds, {});
James Conroy2dcd3fe2020-02-06 18:34:52 +00003576
3577 // Get vector of active counters for CpuRef and CpuAcc backends
3578 cpuRefCounterStatus = backendProfilingCpuRef.GetActiveCounters();
3579 cpuAccCounterStatus = backendProfilingCpuAcc.GetActiveCounters();
Sadik Armagan1625efc2021-06-10 18:24:34 +01003580 CHECK_EQ(cpuRefCounterStatus.size(), 1);
3581 CHECK_EQ(cpuAccCounterStatus.size(), 1);
James Conroy2dcd3fe2020-02-06 18:34:52 +00003582
3583 // Check active CpuRef counter
Sadik Armagan1625efc2021-06-10 18:24:34 +01003584 CHECK_EQ(cpuRefCounterStatus[0].m_GlobalCounterId, newActiveGlobalCounterIds[0]);
3585 CHECK_EQ(cpuRefCounterStatus[0].m_BackendCounterId, cpuRefCounters[1]);
3586 CHECK_EQ(cpuRefCounterStatus[0].m_SamplingRateInMicroseconds, newCapturePeriod);
3587 CHECK_EQ(cpuRefCounterStatus[0].m_Enabled, true);
James Conroy2dcd3fe2020-02-06 18:34:52 +00003588
3589 // Check active CpuAcc counter
Sadik Armagan1625efc2021-06-10 18:24:34 +01003590 CHECK_EQ(cpuAccCounterStatus[0].m_GlobalCounterId, newActiveGlobalCounterIds[1]);
3591 CHECK_EQ(cpuAccCounterStatus[0].m_BackendCounterId, cpuAccCounters[0]);
3592 CHECK_EQ(cpuAccCounterStatus[0].m_SamplingRateInMicroseconds, newCapturePeriod);
3593 CHECK_EQ(cpuAccCounterStatus[0].m_Enabled, true);
James Conroy2dcd3fe2020-02-06 18:34:52 +00003594
3595 // Check inactive CpuRef counter
3596 inactiveCpuRefCounter = backendProfilingCpuRef.GetCounterStatus(cpuRefCounters[0]);
Sadik Armagan1625efc2021-06-10 18:24:34 +01003597 CHECK_EQ(inactiveCpuRefCounter.m_GlobalCounterId, 5);
3598 CHECK_EQ(inactiveCpuRefCounter.m_BackendCounterId, cpuRefCounters[0]);
3599 CHECK_EQ(inactiveCpuRefCounter.m_SamplingRateInMicroseconds, 0);
3600 CHECK_EQ(inactiveCpuRefCounter.m_Enabled, false);
James Conroy2dcd3fe2020-02-06 18:34:52 +00003601
3602 // Reset the profiling service to stop any running thread
3603 options.m_ProfilingOptions.m_EnableProfiling = false;
3604 profilingService.ResetExternalProfilingOptions(options.m_ProfilingOptions, true);
3605}
3606
Sadik Armagan1625efc2021-06-10 18:24:34 +01003607TEST_CASE("CheckRegisterCounters")
Sadik Armagancab588a2020-02-17 11:33:31 +00003608{
Kevin Mayd92a6e42021-02-04 10:27:41 +00003609 armnn::IRuntime::CreationOptions options;
Sadik Armagancab588a2020-02-17 11:33:31 +00003610 options.m_ProfilingOptions.m_EnableProfiling = true;
3611 MockBufferManager mockBuffer(1024);
Sadik Armagan3184c902020-03-18 10:57:30 +00003612
Sadik Armagancab588a2020-02-17 11:33:31 +00003613 CaptureData captureData;
Keith Davis33ed2212020-03-30 10:43:41 +01003614 MockProfilingService mockProfilingService(mockBuffer, options.m_ProfilingOptions.m_EnableProfiling, captureData);
Sadik Armagancab588a2020-02-17 11:33:31 +00003615 armnn::BackendId cpuRefId(armnn::Compute::CpuRef);
3616
3617 mockProfilingService.RegisterMapping(6, 0, cpuRefId);
3618 mockProfilingService.RegisterMapping(7, 1, cpuRefId);
3619 mockProfilingService.RegisterMapping(8, 2, cpuRefId);
3620
3621 armnn::profiling::BackendProfiling backendProfiling(options,
3622 mockProfilingService,
3623 cpuRefId);
3624
3625 armnn::profiling::Timestamp timestamp;
3626 timestamp.timestamp = 1000998;
3627 timestamp.counterValues.emplace_back(0, 700);
3628 timestamp.counterValues.emplace_back(2, 93);
3629 std::vector<armnn::profiling::Timestamp> timestamps;
3630 timestamps.push_back(timestamp);
3631 backendProfiling.ReportCounters(timestamps);
3632
3633 auto readBuffer = mockBuffer.GetReadableBuffer();
3634
3635 uint32_t headerWord0 = ReadUint32(readBuffer, 0);
3636 uint32_t headerWord1 = ReadUint32(readBuffer, 4);
3637 uint64_t readTimestamp = ReadUint64(readBuffer, 8);
3638
Sadik Armagan1625efc2021-06-10 18:24:34 +01003639 CHECK(((headerWord0 >> 26) & 0x0000003F) == 3); // packet family
3640 CHECK(((headerWord0 >> 19) & 0x0000007F) == 0); // packet class
3641 CHECK(((headerWord0 >> 16) & 0x00000007) == 0); // packet type
3642 CHECK(headerWord1 == 20); // data length
3643 CHECK(1000998 == readTimestamp); // capture period
Sadik Armagancab588a2020-02-17 11:33:31 +00003644
3645 uint32_t offset = 16;
3646 // Check Counter Index
3647 uint16_t readIndex = ReadUint16(readBuffer, offset);
Sadik Armagan1625efc2021-06-10 18:24:34 +01003648 CHECK(6 == readIndex);
Sadik Armagancab588a2020-02-17 11:33:31 +00003649
3650 // Check Counter Value
3651 offset += 2;
3652 uint32_t readValue = ReadUint32(readBuffer, offset);
Sadik Armagan1625efc2021-06-10 18:24:34 +01003653 CHECK(700 == readValue);
Sadik Armagancab588a2020-02-17 11:33:31 +00003654
3655 // Check Counter Index
3656 offset += 4;
3657 readIndex = ReadUint16(readBuffer, offset);
Sadik Armagan1625efc2021-06-10 18:24:34 +01003658 CHECK(8 == readIndex);
Sadik Armagancab588a2020-02-17 11:33:31 +00003659
3660 // Check Counter Value
3661 offset += 2;
3662 readValue = ReadUint32(readBuffer, offset);
Sadik Armagan1625efc2021-06-10 18:24:34 +01003663 CHECK(93 == readValue);
Sadik Armagancab588a2020-02-17 11:33:31 +00003664}
3665
Sadik Armagan1625efc2021-06-10 18:24:34 +01003666TEST_CASE("CheckFileFormat") {
Isabella Gottardia0687ee2020-03-11 18:04:20 +00003667 // Locally reduce log level to "Warning", as this test needs to parse a warning message from the standard output
3668 LogLevelSwapper logLevelSwapper(armnn::LogSeverity::Warning);
3669
3670 // Create profiling options.
Kevin Mayd92a6e42021-02-04 10:27:41 +00003671 armnn::IRuntime::CreationOptions::ExternalProfilingOptions options;
Isabella Gottardia0687ee2020-03-11 18:04:20 +00003672 options.m_EnableProfiling = true;
3673 // Check the default value set to binary
Sadik Armagan1625efc2021-06-10 18:24:34 +01003674 CHECK(options.m_FileFormat == "binary");
Isabella Gottardia0687ee2020-03-11 18:04:20 +00003675
3676 // Change file format to an unsupported value
3677 options.m_FileFormat = "json";
3678 // Enable the profiling service
3679 armnn::profiling::ProfilingService profilingService;
3680 profilingService.ResetExternalProfilingOptions(options, true);
3681 // Start the command handler and the send thread
3682 profilingService.Update();
Sadik Armagan1625efc2021-06-10 18:24:34 +01003683 CHECK(profilingService.GetCurrentState()==ProfilingState::NotConnected);
Isabella Gottardia0687ee2020-03-11 18:04:20 +00003684
3685 // Redirect the output to a local stream so that we can parse the warning message
3686 std::stringstream ss;
3687 StreamRedirector streamRedirector(std::cout, ss.rdbuf());
3688
3689 // When Update is called and the current state is ProfilingState::NotConnected
3690 // an exception will be raised from GetProfilingConnection and displayed as warning in the output local stream
3691 profilingService.Update();
3692
3693 streamRedirector.CancelRedirect();
3694
3695 // Check that the expected error has occurred and logged to the standard output
David Monahana8837bf2020-04-16 10:01:56 +01003696 if (ss.str().find("Unsupported profiling file format, only binary is supported") == std::string::npos)
Isabella Gottardia0687ee2020-03-11 18:04:20 +00003697 {
3698 std::cout << ss.str();
Sadik Armagan1625efc2021-06-10 18:24:34 +01003699 FAIL("Expected string not found.");
Isabella Gottardia0687ee2020-03-11 18:04:20 +00003700 }
3701}
3702
Sadik Armagan1625efc2021-06-10 18:24:34 +01003703}