blob: 5ef9811b2cbb5bd82b0d20596a9cdd3b1b0c353f [file] [log] [blame]
Francis Murtagh1f7db452019-08-14 09:49:34 +01001//
2// Copyright © 2017 Arm Ltd. All rights reserved.
3// SPDX-License-Identifier: MIT
4//
5
Ferran Balaguer1b941722019-08-28 16:57:18 +01006#include "SendCounterPacketTests.hpp"
FinnWilliamsArm4833cea2019-09-17 16:53:53 +01007#include "../CommandThread.hpp"
Teresa Charlin9bab4962019-09-06 12:28:35 +01008
Matteo Martincigh6db5f202019-09-05 12:02:04 +01009#include <CommandHandlerKey.hpp>
10#include <CommandHandlerFunctor.hpp>
11#include <CommandHandlerRegistry.hpp>
Sadik Armaganb5f01b22019-09-18 17:29:00 +010012#include <ConnectionAcknowledgedCommandHandler.hpp>
Matteo Martincigh6db5f202019-09-05 12:02:04 +010013#include <CounterDirectory.hpp>
14#include <EncodeVersion.hpp>
15#include <Holder.hpp>
16#include <Packet.hpp>
17#include <PacketVersionResolver.hpp>
Francis Murtaghfcb8ef62019-09-20 15:40:09 +010018#include <PeriodicCounterCapture.hpp>
Matteo Martincigh6db5f202019-09-05 12:02:04 +010019#include <PeriodicCounterSelectionCommandHandler.hpp>
20#include <ProfilingStateMachine.hpp>
21#include <ProfilingService.hpp>
22#include <ProfilingUtils.hpp>
Narumol Prangnawarat48033692019-09-20 12:04:55 +010023#include <RequestCounterDirectoryCommandHandler.hpp>
Teresa Charlin9bab4962019-09-06 12:28:35 +010024#include <Runtime.hpp>
Matteo Martincigh6db5f202019-09-05 12:02:04 +010025#include <SocketProfilingConnection.hpp>
Francis Murtaghfcb8ef62019-09-20 15:40:09 +010026#include <IReadCounterValue.hpp>
Keith Davis02356de2019-08-26 18:28:17 +010027
Matteo Martincigh6db5f202019-09-05 12:02:04 +010028#include <armnn/Conversion.hpp>
Ferran Balaguer1b941722019-08-28 16:57:18 +010029
Sadik Armaganbd9e2c52019-09-26 23:13:31 +010030#include <boost/algorithm/string.hpp>
Ferran Balaguer1b941722019-08-28 16:57:18 +010031#include <boost/numeric/conversion/cast.hpp>
Sadik Armaganbd9e2c52019-09-26 23:13:31 +010032#include <boost/test/unit_test.hpp>
Francis Murtagh1f7db452019-08-14 09:49:34 +010033
Nikhil Rajbc626052019-08-15 15:49:45 +010034#include <cstdint>
35#include <cstring>
Sadik Armaganbd9e2c52019-09-26 23:13:31 +010036#include <iostream>
Aron Virginas-Tare898db92019-08-22 12:56:34 +010037#include <limits>
Francis Murtagh11f99b42019-08-16 11:28:52 +010038#include <map>
Aron Virginas-Tare898db92019-08-22 12:56:34 +010039#include <random>
Nikhil Raj3ecc5102019-09-03 15:55:33 +010040#include <thread>
Matteo Martincigh24e8f922019-09-19 11:57:46 +010041#include <chrono>
Francis Murtagh1f7db452019-08-14 09:49:34 +010042
43BOOST_AUTO_TEST_SUITE(ExternalProfiling)
44
Aron Virginas-Tare898db92019-08-22 12:56:34 +010045using namespace armnn::profiling;
46
Francis Murtagh1f7db452019-08-14 09:49:34 +010047BOOST_AUTO_TEST_CASE(CheckCommandHandlerKeyComparisons)
48{
49 CommandHandlerKey testKey0(1, 1);
50 CommandHandlerKey testKey1(1, 1);
51 CommandHandlerKey testKey2(1, 1);
52 CommandHandlerKey testKey3(0, 0);
53 CommandHandlerKey testKey4(2, 2);
54 CommandHandlerKey testKey5(0, 2);
55
56 BOOST_CHECK(testKey1<testKey4);
57 BOOST_CHECK(testKey1>testKey3);
58 BOOST_CHECK(testKey1<=testKey4);
59 BOOST_CHECK(testKey1>=testKey3);
60 BOOST_CHECK(testKey1<=testKey2);
61 BOOST_CHECK(testKey1>=testKey2);
62 BOOST_CHECK(testKey1==testKey2);
63 BOOST_CHECK(testKey1==testKey1);
64
65 BOOST_CHECK(!(testKey1==testKey5));
66 BOOST_CHECK(!(testKey1!=testKey1));
67 BOOST_CHECK(testKey1!=testKey5);
68
69 BOOST_CHECK(testKey1==testKey2 && testKey2==testKey1);
70 BOOST_CHECK(testKey0==testKey1 && testKey1==testKey2 && testKey0==testKey2);
71
72 BOOST_CHECK(testKey1.GetPacketId()==1);
73 BOOST_CHECK(testKey1.GetVersion()==1);
74
75 std::vector<CommandHandlerKey> vect =
Aron Virginas-Tare898db92019-08-22 12:56:34 +010076 {
77 CommandHandlerKey(0,1), CommandHandlerKey(2,0), CommandHandlerKey(1,0),
78 CommandHandlerKey(2,1), CommandHandlerKey(1,1), CommandHandlerKey(0,1),
79 CommandHandlerKey(2,0), CommandHandlerKey(0,0)
80 };
Francis Murtagh1f7db452019-08-14 09:49:34 +010081
82 std::sort(vect.begin(), vect.end());
83
84 std::vector<CommandHandlerKey> expectedVect =
Aron Virginas-Tare898db92019-08-22 12:56:34 +010085 {
86 CommandHandlerKey(0,0), CommandHandlerKey(0,1), CommandHandlerKey(0,1),
87 CommandHandlerKey(1,0), CommandHandlerKey(1,1), CommandHandlerKey(2,0),
88 CommandHandlerKey(2,0), CommandHandlerKey(2,1)
89 };
Francis Murtagh1f7db452019-08-14 09:49:34 +010090
91 BOOST_CHECK(vect == expectedVect);
92}
93
FinnWilliamsArm4833cea2019-09-17 16:53:53 +010094class TestProfilingConnectionBase :public IProfilingConnection
95{
96public:
97 TestProfilingConnectionBase() = default;
98 ~TestProfilingConnectionBase() = default;
99
100 bool IsOpen()
101 {
102 return true;
103 }
104
105 void Close(){}
106
Matteo Martincigh24e8f922019-09-19 11:57:46 +0100107 bool WritePacket(const unsigned char* buffer, uint32_t length)
FinnWilliamsArm4833cea2019-09-17 16:53:53 +0100108 {
109 return false;
110 }
111
112 Packet ReadPacket(uint32_t timeout)
113 {
114 std::this_thread::sleep_for(std::chrono::milliseconds(timeout));
115 std::unique_ptr<char[]> packetData;
116 //Return connection acknowledged packet
117 return {65536 ,0 , packetData};
118 }
119};
120
121class TestProfilingConnectionTimeoutError :public TestProfilingConnectionBase
122{
123 int readRequests = 0;
124public:
125 Packet ReadPacket(uint32_t timeout) {
126 if (readRequests < 3)
127 {
128 readRequests++;
129 throw armnn::TimeoutException(": Simulate a timeout");
130 }
131 std::this_thread::sleep_for(std::chrono::milliseconds(timeout));
132 std::unique_ptr<char[]> packetData;
133 //Return connection acknowledged packet after three timeouts
134 return {65536 ,0 , packetData};
135 }
136};
137
138class TestProfilingConnectionArmnnError :public TestProfilingConnectionBase
139{
140public:
141
142 Packet ReadPacket(uint32_t timeout)
143 {
144 std::this_thread::sleep_for(std::chrono::milliseconds(timeout));
145 throw armnn::Exception(": Simulate a non timeout error");
146 }
147};
148
149BOOST_AUTO_TEST_CASE(CheckCommandThread)
150{
151 PacketVersionResolver packetVersionResolver;
152 ProfilingStateMachine profilingStateMachine;
153
154 TestProfilingConnectionBase testProfilingConnectionBase;
155 TestProfilingConnectionTimeoutError testProfilingConnectionTimeOutError;
156 TestProfilingConnectionArmnnError testProfilingConnectionArmnnError;
157
158 ConnectionAcknowledgedCommandHandler connectionAcknowledgedCommandHandler(1, 4194304, profilingStateMachine);
159 CommandHandlerRegistry commandHandlerRegistry;
160
161 commandHandlerRegistry.RegisterFunctor(&connectionAcknowledgedCommandHandler, 1, 4194304);
162
163 profilingStateMachine.TransitionToState(ProfilingState::NotConnected);
164 profilingStateMachine.TransitionToState(ProfilingState::WaitingForAck);
165
166 CommandThread commandThread0(1,
167 true,
168 commandHandlerRegistry,
169 packetVersionResolver,
170 testProfilingConnectionBase);
171
172 commandThread0.Start();
173 commandThread0.Start();
174 commandThread0.Start();
175
176 commandThread0.Stop();
177 commandThread0.Join();
178
179 BOOST_CHECK(profilingStateMachine.GetCurrentState() == ProfilingState::Active);
180
181 profilingStateMachine.TransitionToState(ProfilingState::NotConnected);
182 profilingStateMachine.TransitionToState(ProfilingState::WaitingForAck);
183 //commandThread1 should give up after one timeout
184 CommandThread commandThread1(1,
185 true,
186 commandHandlerRegistry,
187 packetVersionResolver,
188 testProfilingConnectionTimeOutError);
189
190 commandThread1.Start();
191 commandThread1.Join();
192
193 BOOST_CHECK(profilingStateMachine.GetCurrentState() == ProfilingState::WaitingForAck);
194 //now commandThread1 should persist after a timeout
195 commandThread1.StopAfterTimeout(false);
196 commandThread1.Start();
197
198 for (int i = 0; i < 100; i++)
199 {
200 if (profilingStateMachine.GetCurrentState() == ProfilingState::Active)
201 {
202 break;
203 }
204 else
205 {
206 std::this_thread::sleep_for(std::chrono::milliseconds(5));
207 }
208 }
209
210 commandThread1.Stop();
211 commandThread1.Join();
212
213 BOOST_CHECK(profilingStateMachine.GetCurrentState() == ProfilingState::Active);
214
215
216 CommandThread commandThread2(1,
217 false,
218 commandHandlerRegistry,
219 packetVersionResolver,
220 testProfilingConnectionArmnnError);
221
222 commandThread2.Start();
223
224 for (int i = 0; i < 100; i++)
225 {
226 if (!commandThread2.IsRunning())
227 {
228 //commandThread2 should stop once it encounters a non timing error
229 commandThread2.Join();
230 return;
231 }
232 std::this_thread::sleep_for(std::chrono::milliseconds(5));
233 }
234
235 BOOST_ERROR("commandThread2 has failed to stop");
236}
237
Nikhil Rajd88e47c2019-08-19 10:04:23 +0100238BOOST_AUTO_TEST_CASE(CheckEncodeVersion)
239{
Aron Virginas-Tare898db92019-08-22 12:56:34 +0100240 Version version1(12);
Nikhil Rajd88e47c2019-08-19 10:04:23 +0100241
242 BOOST_CHECK(version1.GetMajor() == 0);
243 BOOST_CHECK(version1.GetMinor() == 0);
244 BOOST_CHECK(version1.GetPatch() == 12);
245
Aron Virginas-Tare898db92019-08-22 12:56:34 +0100246 Version version2(4108);
Nikhil Rajd88e47c2019-08-19 10:04:23 +0100247
248 BOOST_CHECK(version2.GetMajor() == 0);
249 BOOST_CHECK(version2.GetMinor() == 1);
250 BOOST_CHECK(version2.GetPatch() == 12);
251
Aron Virginas-Tare898db92019-08-22 12:56:34 +0100252 Version version3(4198412);
Nikhil Rajd88e47c2019-08-19 10:04:23 +0100253
254 BOOST_CHECK(version3.GetMajor() == 1);
255 BOOST_CHECK(version3.GetMinor() == 1);
256 BOOST_CHECK(version3.GetPatch() == 12);
257
Aron Virginas-Tare898db92019-08-22 12:56:34 +0100258 Version version4(0);
Nikhil Rajd88e47c2019-08-19 10:04:23 +0100259
260 BOOST_CHECK(version4.GetMajor() == 0);
261 BOOST_CHECK(version4.GetMinor() == 0);
262 BOOST_CHECK(version4.GetPatch() == 0);
263
Aron Virginas-Tare898db92019-08-22 12:56:34 +0100264 Version version5(1, 0, 0);
Nikhil Rajd88e47c2019-08-19 10:04:23 +0100265 BOOST_CHECK(version5.GetEncodedValue() == 4194304);
266}
267
Nikhil Rajbc626052019-08-15 15:49:45 +0100268BOOST_AUTO_TEST_CASE(CheckPacketClass)
269{
FinnWilliamsArma0c78712019-09-16 12:06:47 +0100270 uint32_t length = 4;
271 std::unique_ptr<char[]> packetData0 = std::make_unique<char[]>(length);
272 std::unique_ptr<char[]> packetData1 = std::make_unique<char[]>(0);
273 std::unique_ptr<char[]> nullPacketData;
Nikhil Rajbc626052019-08-15 15:49:45 +0100274
FinnWilliamsArma0c78712019-09-16 12:06:47 +0100275 Packet packetTest0(472580096, length, packetData0);
Nikhil Rajbc626052019-08-15 15:49:45 +0100276
FinnWilliamsArma0c78712019-09-16 12:06:47 +0100277 BOOST_CHECK(packetTest0.GetHeader() == 472580096);
278 BOOST_CHECK(packetTest0.GetPacketFamily() == 7);
279 BOOST_CHECK(packetTest0.GetPacketId() == 43);
280 BOOST_CHECK(packetTest0.GetLength() == length);
281 BOOST_CHECK(packetTest0.GetPacketType() == 3);
282 BOOST_CHECK(packetTest0.GetPacketClass() == 5);
Nikhil Rajbc626052019-08-15 15:49:45 +0100283
FinnWilliamsArma0c78712019-09-16 12:06:47 +0100284 BOOST_CHECK_THROW(Packet packetTest1(472580096, 0, packetData1), armnn::Exception);
285 BOOST_CHECK_NO_THROW(Packet packetTest2(472580096, 0, nullPacketData));
Nikhil Rajbc626052019-08-15 15:49:45 +0100286
FinnWilliamsArma0c78712019-09-16 12:06:47 +0100287 Packet packetTest3(472580096, 0, nullPacketData);
288 BOOST_CHECK(packetTest3.GetLength() == 0);
289 BOOST_CHECK(packetTest3.GetData() == nullptr);
290
291 const char* packetTest0Data = packetTest0.GetData();
292 Packet packetTest4(std::move(packetTest0));
293
294 BOOST_CHECK(packetTest0.GetData() == nullptr);
295 BOOST_CHECK(packetTest4.GetData() == packetTest0Data);
296
297 BOOST_CHECK(packetTest4.GetHeader() == 472580096);
298 BOOST_CHECK(packetTest4.GetPacketFamily() == 7);
299 BOOST_CHECK(packetTest4.GetPacketId() == 43);
300 BOOST_CHECK(packetTest4.GetLength() == length);
301 BOOST_CHECK(packetTest4.GetPacketType() == 3);
302 BOOST_CHECK(packetTest4.GetPacketClass() == 5);
Nikhil Rajbc626052019-08-15 15:49:45 +0100303}
304
Francis Murtagh94d79152019-08-16 17:45:07 +0100305// Create Derived Classes
306class TestFunctorA : public CommandHandlerFunctor
307{
308public:
309 using CommandHandlerFunctor::CommandHandlerFunctor;
310
311 int GetCount() { return m_Count; }
312
313 void operator()(const Packet& packet) override
314 {
315 m_Count++;
316 }
317
318private:
319 int m_Count = 0;
320};
321
322class TestFunctorB : public TestFunctorA
323{
324 using TestFunctorA::TestFunctorA;
325};
326
327class TestFunctorC : public TestFunctorA
328{
329 using TestFunctorA::TestFunctorA;
330};
331
Francis Murtagh11f99b42019-08-16 11:28:52 +0100332BOOST_AUTO_TEST_CASE(CheckCommandHandlerFunctor)
333{
Francis Murtagh11f99b42019-08-16 11:28:52 +0100334 // Hard code the version as it will be the same during a single profiling session
335 uint32_t version = 1;
336
337 TestFunctorA testFunctorA(461, version);
338 TestFunctorB testFunctorB(963, version);
339 TestFunctorC testFunctorC(983, version);
340
341 CommandHandlerKey keyA(testFunctorA.GetPacketId(), testFunctorA.GetVersion());
342 CommandHandlerKey keyB(testFunctorB.GetPacketId(), testFunctorB.GetVersion());
343 CommandHandlerKey keyC(testFunctorC.GetPacketId(), testFunctorC.GetVersion());
344
345 // Create the unwrapped map to simulate the Command Handler Registry
346 std::map<CommandHandlerKey, CommandHandlerFunctor*> registry;
347
348 registry.insert(std::make_pair(keyB, &testFunctorB));
349 registry.insert(std::make_pair(keyA, &testFunctorA));
350 registry.insert(std::make_pair(keyC, &testFunctorC));
351
352 // Check the order of the map is correct
353 auto it = registry.begin();
354 BOOST_CHECK(it->first==keyA);
355 it++;
356 BOOST_CHECK(it->first==keyB);
357 it++;
358 BOOST_CHECK(it->first==keyC);
359
FinnWilliamsArma0c78712019-09-16 12:06:47 +0100360 std::unique_ptr<char[]> packetDataA;
361 std::unique_ptr<char[]> packetDataB;
362 std::unique_ptr<char[]> packetDataC;
363
364 Packet packetA(500000000, 0, packetDataA);
365 Packet packetB(600000000, 0, packetDataB);
366 Packet packetC(400000000, 0, packetDataC);
Francis Murtagh11f99b42019-08-16 11:28:52 +0100367
368 // Check the correct operator of derived class is called
369 registry.at(CommandHandlerKey(packetA.GetPacketId(), version))->operator()(packetA);
370 BOOST_CHECK(testFunctorA.GetCount() == 1);
371 BOOST_CHECK(testFunctorB.GetCount() == 0);
372 BOOST_CHECK(testFunctorC.GetCount() == 0);
373
374 registry.at(CommandHandlerKey(packetB.GetPacketId(), version))->operator()(packetB);
375 BOOST_CHECK(testFunctorA.GetCount() == 1);
376 BOOST_CHECK(testFunctorB.GetCount() == 1);
377 BOOST_CHECK(testFunctorC.GetCount() == 0);
378
379 registry.at(CommandHandlerKey(packetC.GetPacketId(), version))->operator()(packetC);
380 BOOST_CHECK(testFunctorA.GetCount() == 1);
381 BOOST_CHECK(testFunctorB.GetCount() == 1);
382 BOOST_CHECK(testFunctorC.GetCount() == 1);
383}
384
Francis Murtagh94d79152019-08-16 17:45:07 +0100385BOOST_AUTO_TEST_CASE(CheckCommandHandlerRegistry)
386{
387 // Hard code the version as it will be the same during a single profiling session
388 uint32_t version = 1;
389
390 TestFunctorA testFunctorA(461, version);
391 TestFunctorB testFunctorB(963, version);
392 TestFunctorC testFunctorC(983, version);
393
394 // Create the Command Handler Registry
395 CommandHandlerRegistry registry;
396
397 // Register multiple different derived classes
398 registry.RegisterFunctor(&testFunctorA, testFunctorA.GetPacketId(), testFunctorA.GetVersion());
399 registry.RegisterFunctor(&testFunctorB, testFunctorB.GetPacketId(), testFunctorB.GetVersion());
400 registry.RegisterFunctor(&testFunctorC, testFunctorC.GetPacketId(), testFunctorC.GetVersion());
401
FinnWilliamsArma0c78712019-09-16 12:06:47 +0100402 std::unique_ptr<char[]> packetDataA;
403 std::unique_ptr<char[]> packetDataB;
404 std::unique_ptr<char[]> packetDataC;
405
406 Packet packetA(500000000, 0, packetDataA);
407 Packet packetB(600000000, 0, packetDataB);
408 Packet packetC(400000000, 0, packetDataC);
Francis Murtagh94d79152019-08-16 17:45:07 +0100409
410 // Check the correct operator of derived class is called
411 registry.GetFunctor(packetA.GetPacketId(), version)->operator()(packetA);
412 BOOST_CHECK(testFunctorA.GetCount() == 1);
413 BOOST_CHECK(testFunctorB.GetCount() == 0);
414 BOOST_CHECK(testFunctorC.GetCount() == 0);
415
416 registry.GetFunctor(packetB.GetPacketId(), version)->operator()(packetB);
417 BOOST_CHECK(testFunctorA.GetCount() == 1);
418 BOOST_CHECK(testFunctorB.GetCount() == 1);
419 BOOST_CHECK(testFunctorC.GetCount() == 0);
420
421 registry.GetFunctor(packetC.GetPacketId(), version)->operator()(packetC);
422 BOOST_CHECK(testFunctorA.GetCount() == 1);
423 BOOST_CHECK(testFunctorB.GetCount() == 1);
424 BOOST_CHECK(testFunctorC.GetCount() == 1);
425
426 // Re-register an existing key with a new function
427 registry.RegisterFunctor(&testFunctorC, testFunctorA.GetPacketId(), version);
428 registry.GetFunctor(packetA.GetPacketId(), version)->operator()(packetC);
429 BOOST_CHECK(testFunctorA.GetCount() == 1);
430 BOOST_CHECK(testFunctorB.GetCount() == 1);
431 BOOST_CHECK(testFunctorC.GetCount() == 2);
432
433 // Check that non-existent key returns nullptr for its functor
434 BOOST_CHECK_THROW(registry.GetFunctor(0, 0), armnn::Exception);
435}
436
Aron Virginas-Tare898db92019-08-22 12:56:34 +0100437BOOST_AUTO_TEST_CASE(CheckPacketVersionResolver)
438{
439 // Set up random number generator for generating packetId values
440 std::random_device device;
441 std::mt19937 generator(device());
442 std::uniform_int_distribution<uint32_t> distribution(std::numeric_limits<uint32_t>::min(),
443 std::numeric_limits<uint32_t>::max());
444
445 // NOTE: Expected version is always 1.0.0, regardless of packetId
446 const Version expectedVersion(1, 0, 0);
447
448 PacketVersionResolver packetVersionResolver;
449
450 constexpr unsigned int numTests = 10u;
451
452 for (unsigned int i = 0u; i < numTests; ++i)
453 {
454 const uint32_t packetId = distribution(generator);
455 Version resolvedVersion = packetVersionResolver.ResolvePacketVersion(packetId);
456
457 BOOST_TEST(resolvedVersion == expectedVersion);
458 }
459}
Nikhil Raj3ecc5102019-09-03 15:55:33 +0100460void ProfilingCurrentStateThreadImpl(ProfilingStateMachine& states)
461{
462 ProfilingState newState = ProfilingState::NotConnected;
463 states.GetCurrentState();
464 states.TransitionToState(newState);
465}
466
467BOOST_AUTO_TEST_CASE(CheckProfilingStateMachine)
468{
469 ProfilingStateMachine profilingState1(ProfilingState::Uninitialised);
470 profilingState1.TransitionToState(ProfilingState::Uninitialised);
471 BOOST_CHECK(profilingState1.GetCurrentState() == ProfilingState::Uninitialised);
472
473 ProfilingStateMachine profilingState2(ProfilingState::Uninitialised);
474 profilingState2.TransitionToState(ProfilingState::NotConnected);
475 BOOST_CHECK(profilingState2.GetCurrentState() == ProfilingState::NotConnected);
476
477 ProfilingStateMachine profilingState3(ProfilingState::NotConnected);
478 profilingState3.TransitionToState(ProfilingState::NotConnected);
479 BOOST_CHECK(profilingState3.GetCurrentState() == ProfilingState::NotConnected);
480
481 ProfilingStateMachine profilingState4(ProfilingState::NotConnected);
482 profilingState4.TransitionToState(ProfilingState::WaitingForAck);
483 BOOST_CHECK(profilingState4.GetCurrentState() == ProfilingState::WaitingForAck);
484
485 ProfilingStateMachine profilingState5(ProfilingState::WaitingForAck);
486 profilingState5.TransitionToState(ProfilingState::WaitingForAck);
487 BOOST_CHECK(profilingState5.GetCurrentState() == ProfilingState::WaitingForAck);
488
489 ProfilingStateMachine profilingState6(ProfilingState::WaitingForAck);
490 profilingState6.TransitionToState(ProfilingState::Active);
491 BOOST_CHECK(profilingState6.GetCurrentState() == ProfilingState::Active);
492
493 ProfilingStateMachine profilingState7(ProfilingState::Active);
494 profilingState7.TransitionToState(ProfilingState::NotConnected);
495 BOOST_CHECK(profilingState7.GetCurrentState() == ProfilingState::NotConnected);
496
497 ProfilingStateMachine profilingState8(ProfilingState::Active);
498 profilingState8.TransitionToState(ProfilingState::Active);
499 BOOST_CHECK(profilingState8.GetCurrentState() == ProfilingState::Active);
500
501 ProfilingStateMachine profilingState9(ProfilingState::Uninitialised);
502 BOOST_CHECK_THROW(profilingState9.TransitionToState(ProfilingState::WaitingForAck),
503 armnn::Exception);
504
505 ProfilingStateMachine profilingState10(ProfilingState::Uninitialised);
506 BOOST_CHECK_THROW(profilingState10.TransitionToState(ProfilingState::Active),
507 armnn::Exception);
508
509 ProfilingStateMachine profilingState11(ProfilingState::NotConnected);
510 BOOST_CHECK_THROW(profilingState11.TransitionToState(ProfilingState::Uninitialised),
511 armnn::Exception);
512
513 ProfilingStateMachine profilingState12(ProfilingState::NotConnected);
514 BOOST_CHECK_THROW(profilingState12.TransitionToState(ProfilingState::Active),
515 armnn::Exception);
516
517 ProfilingStateMachine profilingState13(ProfilingState::WaitingForAck);
518 BOOST_CHECK_THROW(profilingState13.TransitionToState(ProfilingState::Uninitialised),
519 armnn::Exception);
520
521 ProfilingStateMachine profilingState14(ProfilingState::WaitingForAck);
522 BOOST_CHECK_THROW(profilingState14.TransitionToState(ProfilingState::NotConnected),
523 armnn::Exception);
524
525 ProfilingStateMachine profilingState15(ProfilingState::Active);
526 BOOST_CHECK_THROW(profilingState15.TransitionToState(ProfilingState::Uninitialised),
527 armnn::Exception);
528
529 ProfilingStateMachine profilingState16(armnn::profiling::ProfilingState::Active);
530 BOOST_CHECK_THROW(profilingState16.TransitionToState(ProfilingState::WaitingForAck),
531 armnn::Exception);
532
533 ProfilingStateMachine profilingState17(ProfilingState::Uninitialised);
534
535 std::thread thread1 (ProfilingCurrentStateThreadImpl,std::ref(profilingState17));
536 std::thread thread2 (ProfilingCurrentStateThreadImpl,std::ref(profilingState17));
537 std::thread thread3 (ProfilingCurrentStateThreadImpl,std::ref(profilingState17));
538 std::thread thread4 (ProfilingCurrentStateThreadImpl,std::ref(profilingState17));
539 std::thread thread5 (ProfilingCurrentStateThreadImpl,std::ref(profilingState17));
540
541 thread1.join();
542 thread2.join();
543 thread3.join();
544 thread4.join();
545 thread5.join();
546
547 BOOST_TEST((profilingState17.GetCurrentState() == ProfilingState::NotConnected));
548}
Aron Virginas-Tare898db92019-08-22 12:56:34 +0100549
Jim Flynn8355ec92019-09-17 12:29:50 +0100550void CaptureDataWriteThreadImpl(Holder& holder, uint32_t capturePeriod, const std::vector<uint16_t>& counterIds)
Francis Murtagh68f78d82019-09-04 16:42:29 +0100551{
552 holder.SetCaptureData(capturePeriod, counterIds);
553}
554
Francis Murtaghbd707162019-09-09 11:26:44 +0100555void CaptureDataReadThreadImpl(const Holder& holder, CaptureData& captureData)
Francis Murtagh68f78d82019-09-04 16:42:29 +0100556{
557 captureData = holder.GetCaptureData();
558}
559
560BOOST_AUTO_TEST_CASE(CheckCaptureDataHolder)
561{
Francis Murtaghbd707162019-09-09 11:26:44 +0100562 std::map<uint32_t, std::vector<uint16_t>> periodIdMap;
563 std::vector<uint16_t> counterIds;
Jim Flynn8355ec92019-09-17 12:29:50 +0100564 uint32_t numThreads = 10;
565 for (uint32_t i = 0; i < numThreads; ++i)
Francis Murtaghbd707162019-09-09 11:26:44 +0100566 {
567 counterIds.emplace_back(i);
568 periodIdMap.insert(std::make_pair(i, counterIds));
569 }
Francis Murtagh68f78d82019-09-04 16:42:29 +0100570
Jim Flynn8355ec92019-09-17 12:29:50 +0100571 // Verify the read and write threads set the holder correctly
572 // and retrieve the expected values
Francis Murtagh68f78d82019-09-04 16:42:29 +0100573 Holder holder;
574 BOOST_CHECK((holder.GetCaptureData()).GetCapturePeriod() == 0);
575 BOOST_CHECK(((holder.GetCaptureData()).GetCounterIds()).empty());
576
577 // Check Holder functions
Francis Murtaghbd707162019-09-09 11:26:44 +0100578 std::thread thread1(CaptureDataWriteThreadImpl, std::ref(holder), 2, std::ref(periodIdMap[2]));
Francis Murtagh68f78d82019-09-04 16:42:29 +0100579 thread1.join();
Francis Murtaghbd707162019-09-09 11:26:44 +0100580 BOOST_CHECK((holder.GetCaptureData()).GetCapturePeriod() == 2);
581 BOOST_CHECK((holder.GetCaptureData()).GetCounterIds() == periodIdMap[2]);
Jim Flynn8355ec92019-09-17 12:29:50 +0100582 // NOTE: now that we have some initial values in the holder we don't have to worry
583 // in the multi-threaded section below about a read thread accessing the holder
584 // before any write thread has gotten to it so we read period = 0, counterIds empty
585 // instead of period = 0, counterIds = {0} as will the case when write thread 0
586 // has executed.
Francis Murtagh68f78d82019-09-04 16:42:29 +0100587
588 CaptureData captureData;
589 std::thread thread2(CaptureDataReadThreadImpl, std::ref(holder), std::ref(captureData));
590 thread2.join();
Jim Flynn8355ec92019-09-17 12:29:50 +0100591 BOOST_CHECK(captureData.GetCapturePeriod() == 2);
Francis Murtaghbd707162019-09-09 11:26:44 +0100592 BOOST_CHECK(captureData.GetCounterIds() == periodIdMap[2]);
Francis Murtagh68f78d82019-09-04 16:42:29 +0100593
Jim Flynn8355ec92019-09-17 12:29:50 +0100594 std::map<uint32_t, CaptureData> captureDataIdMap;
595 for (uint32_t i = 0; i < numThreads; ++i)
596 {
597 CaptureData perThreadCaptureData;
598 captureDataIdMap.insert(std::make_pair(i, perThreadCaptureData));
599 }
600
Francis Murtaghbd707162019-09-09 11:26:44 +0100601 std::vector<std::thread> threadsVect;
Jim Flynn8355ec92019-09-17 12:29:50 +0100602 std::vector<std::thread> readThreadsVect;
603 for (uint32_t i = 0; i < numThreads; ++i)
Francis Murtaghbd707162019-09-09 11:26:44 +0100604 {
605 threadsVect.emplace_back(std::thread(CaptureDataWriteThreadImpl,
606 std::ref(holder),
607 i,
Jim Flynn8355ec92019-09-17 12:29:50 +0100608 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
611 BOOST_CHECK(captureDataIdMap.at(i).GetCapturePeriod() == 0);
612 BOOST_CHECK(captureDataIdMap.at(i).GetCounterIds().empty());
613 readThreadsVect.emplace_back(std::thread(CaptureDataReadThreadImpl,
614 std::ref(holder),
615 std::ref(captureDataIdMap.at(i))));
Francis Murtaghbd707162019-09-09 11:26:44 +0100616 }
617
Jim Flynn8355ec92019-09-17 12:29:50 +0100618 for (uint32_t i = 0; i < numThreads; ++i)
Francis Murtaghbd707162019-09-09 11:26:44 +0100619 {
620 threadsVect[i].join();
Francis Murtaghbd707162019-09-09 11:26:44 +0100621 readThreadsVect[i].join();
622 }
Francis Murtagh68f78d82019-09-04 16:42:29 +0100623
Jim Flynn8355ec92019-09-17 12:29:50 +0100624 // Look at the CaptureData that each read thread has filled
625 // the capture period it read should match the counter ids entry
626 for (uint32_t i = 0; i < numThreads; ++i)
627 {
628 CaptureData perThreadCaptureData = captureDataIdMap.at(i);
629 BOOST_CHECK(perThreadCaptureData.GetCounterIds() == periodIdMap.at(perThreadCaptureData.GetCapturePeriod()));
630 }
Matthew Bentham46d1c622019-09-13 12:45:04 +0100631}
Francis Murtagh68f78d82019-09-04 16:42:29 +0100632
Matthew Bentham46d1c622019-09-13 12:45:04 +0100633BOOST_AUTO_TEST_CASE(CaptureDataMethods)
634{
Jim Flynn8355ec92019-09-17 12:29:50 +0100635 // Check CaptureData setter and getter functions
Matthew Bentham46d1c622019-09-13 12:45:04 +0100636 std::vector<uint16_t> counterIds = {42, 29, 13};
Jim Flynn8355ec92019-09-17 12:29:50 +0100637 CaptureData captureData;
638 BOOST_CHECK(captureData.GetCapturePeriod() == 0);
639 BOOST_CHECK((captureData.GetCounterIds()).empty());
640 captureData.SetCapturePeriod(150);
641 captureData.SetCounterIds(counterIds);
642 BOOST_CHECK(captureData.GetCapturePeriod() == 150);
643 BOOST_CHECK(captureData.GetCounterIds() == counterIds);
Francis Murtagh68f78d82019-09-04 16:42:29 +0100644
Jim Flynn8355ec92019-09-17 12:29:50 +0100645 // Check assignment operator
Francis Murtagh68f78d82019-09-04 16:42:29 +0100646 CaptureData secondCaptureData;
Francis Murtagh68f78d82019-09-04 16:42:29 +0100647
Jim Flynn8355ec92019-09-17 12:29:50 +0100648 secondCaptureData = captureData;
649 BOOST_CHECK(secondCaptureData.GetCapturePeriod() == 150);
Matthew Bentham46d1c622019-09-13 12:45:04 +0100650 BOOST_CHECK(secondCaptureData.GetCounterIds() == counterIds);
Francis Murtagh68f78d82019-09-04 16:42:29 +0100651
652 // Check copy constructor
Jim Flynn8355ec92019-09-17 12:29:50 +0100653 CaptureData copyConstructedCaptureData(captureData);
Francis Murtagh68f78d82019-09-04 16:42:29 +0100654
Jim Flynn8355ec92019-09-17 12:29:50 +0100655 BOOST_CHECK(copyConstructedCaptureData.GetCapturePeriod() == 150);
Matthew Bentham46d1c622019-09-13 12:45:04 +0100656 BOOST_CHECK(copyConstructedCaptureData.GetCounterIds() == counterIds);
Keith Davis02356de2019-08-26 18:28:17 +0100657}
Francis Murtagh68f78d82019-09-04 16:42:29 +0100658
Keith Davis02356de2019-08-26 18:28:17 +0100659BOOST_AUTO_TEST_CASE(CheckProfilingServiceDisabled)
660{
661 armnn::Runtime::CreationOptions::ExternalProfilingOptions options;
662 ProfilingService service(options);
663 BOOST_CHECK(service.GetCurrentState() == ProfilingState::Uninitialised);
664 service.Run();
665 BOOST_CHECK(service.GetCurrentState() == ProfilingState::Uninitialised);
666}
667
Sadik Armaganbd9e2c52019-09-26 23:13:31 +0100668struct cerr_redirect {
669 cerr_redirect(std::streambuf* new_buffer)
670 : old( std::cerr.rdbuf(new_buffer)) {}
671
672 ~cerr_redirect( ) {
673 std::cerr.rdbuf(old);
674 }
675
676private:
677 std::streambuf* old;
678};
679
Keith Davis02356de2019-08-26 18:28:17 +0100680BOOST_AUTO_TEST_CASE(CheckProfilingServiceEnabled)
681{
682 armnn::Runtime::CreationOptions::ExternalProfilingOptions options;
683 options.m_EnableProfiling = true;
684 ProfilingService service(options);
685 BOOST_CHECK(service.GetCurrentState() == ProfilingState::NotConnected);
Keith Davis02356de2019-08-26 18:28:17 +0100686
Sadik Armaganbd9e2c52019-09-26 23:13:31 +0100687 // As there is no daemon running a connection cannot be made so expect a std::cerr to console
688 std::stringstream ss;
689 cerr_redirect guard(ss.rdbuf());
690 service.Run();
691 BOOST_CHECK(boost::contains(ss.str(), "Cannot connect to stream socket: Connection refused"));
692}
Keith Davis02356de2019-08-26 18:28:17 +0100693
694BOOST_AUTO_TEST_CASE(CheckProfilingServiceEnabledRuntime)
695{
696 armnn::Runtime::CreationOptions::ExternalProfilingOptions options;
697 ProfilingService service(options);
698 BOOST_CHECK(service.GetCurrentState() == ProfilingState::Uninitialised);
699 service.Run();
700 BOOST_CHECK(service.GetCurrentState() == ProfilingState::Uninitialised);
FinnWilliamsArmce2d9d12019-09-18 10:28:16 +0100701 options.m_EnableProfiling = true;
702 service.ResetExternalProfilingOptions(options);
Keith Davis02356de2019-08-26 18:28:17 +0100703 BOOST_CHECK(service.GetCurrentState() == ProfilingState::NotConnected);
Sadik Armaganbd9e2c52019-09-26 23:13:31 +0100704
705 // As there is no daemon running a connection cannot be made so expect a std::cerr to console
706 std::stringstream ss;
707 cerr_redirect guard(ss.rdbuf());
Keith Davis02356de2019-08-26 18:28:17 +0100708 service.Run();
Sadik Armaganbd9e2c52019-09-26 23:13:31 +0100709 BOOST_CHECK(boost::contains(ss.str(), "Cannot connect to stream socket: Connection refused"));
Francis Murtagh68f78d82019-09-04 16:42:29 +0100710}
711
FinnWilliamsArmce2d9d12019-09-18 10:28:16 +0100712BOOST_AUTO_TEST_CASE(CheckProfilingServiceCounterDirectory)
713{
714 armnn::Runtime::CreationOptions::ExternalProfilingOptions options;
715 ProfilingService service(options);
716
717 const ICounterDirectory& counterDirectory0 = service.GetCounterDirectory();
718 BOOST_CHECK(counterDirectory0.GetCounterCount() == 0);
719
720 options.m_EnableProfiling = true;
721 service.ResetExternalProfilingOptions(options);
722
723 const ICounterDirectory& counterDirectory1 = service.GetCounterDirectory();
724 BOOST_CHECK(counterDirectory1.GetCounterCount() != 0);
725}
726
FinnWilliamsArmf6e534a2019-09-16 15:45:42 +0100727BOOST_AUTO_TEST_CASE(CheckProfilingServiceCounterValues)
728{
729 armnn::Runtime::CreationOptions::ExternalProfilingOptions options;
730 options.m_EnableProfiling = true;
731 ProfilingService profilingService(options);
732
733 ProfilingService* profilingServicePtr = &profilingService;
734 std::vector<std::thread> writers;
735
736 for(int i = 0; i < 100 ; ++i)
737 {
738 // Increment and decrement counter 0
739 writers.push_back(std::thread(&ProfilingService::IncrementCounterValue, profilingServicePtr, 0));
740 writers.push_back(std::thread(&ProfilingService::DecrementCounterValue, profilingServicePtr, 0));
741 // Add 10 to counter 0 and subtract 5 from counter 0
742 writers.push_back(std::thread(&ProfilingService::AddCounterValue, profilingServicePtr, 0, 10));
743 writers.push_back(std::thread(&ProfilingService::SubtractCounterValue, profilingServicePtr, 0, 5));
744 }
745
746 std::for_each(writers.begin(), writers.end(), mem_fn(&std::thread::join));
747
748 uint32_t counterValue;
749 profilingService.GetCounterValue(0, counterValue);
750 BOOST_CHECK(counterValue == 500);
751
752 profilingService.SetCounterValue(0, 0);
753 profilingService.GetCounterValue(0, counterValue);
754 BOOST_CHECK(counterValue == 0);
755
756 BOOST_CHECK_THROW(profilingService.SetCounterValue(profilingService.GetCounterCount(), 1), armnn::Exception);
757}
758
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100759BOOST_AUTO_TEST_CASE(CheckProfilingObjectUids)
Matteo Martincighab173e92019-09-05 12:02:04 +0100760{
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100761 uint16_t uid = 0;
762 BOOST_CHECK_NO_THROW(uid = GetNextUid());
763 BOOST_CHECK(uid >= 1);
764
765 uint16_t nextUid = 0;
766 BOOST_CHECK_NO_THROW(nextUid = GetNextUid());
767 BOOST_CHECK(nextUid > uid);
768
769 std::vector<uint16_t> counterUids;
770 BOOST_CHECK_NO_THROW(counterUids = GetNextCounterUids(0));
771 BOOST_CHECK(counterUids.size() == 1);
772 BOOST_CHECK(counterUids[0] >= 0);
773
774 std::vector<uint16_t> nextCounterUids;
775 BOOST_CHECK_NO_THROW(nextCounterUids = GetNextCounterUids(1));
776 BOOST_CHECK(nextCounterUids.size() == 1);
777 BOOST_CHECK(nextCounterUids[0] > counterUids[0]);
778
779 std::vector<uint16_t> counterUidsMultiCore;
780 uint16_t numberOfCores = 13;
781 BOOST_CHECK_NO_THROW(counterUidsMultiCore = GetNextCounterUids(numberOfCores));
782 BOOST_CHECK(counterUidsMultiCore.size() == numberOfCores);
783 BOOST_CHECK(counterUidsMultiCore.front() >= nextCounterUids[0]);
784 for (size_t i = 1; i < numberOfCores; i ++)
785 {
786 BOOST_CHECK(counterUidsMultiCore[i] == counterUidsMultiCore[i - 1] + 1);
787 }
788 BOOST_CHECK(counterUidsMultiCore.back() == counterUidsMultiCore.front() + numberOfCores - 1);
Matteo Martincighab173e92019-09-05 12:02:04 +0100789}
790
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100791BOOST_AUTO_TEST_CASE(CheckCounterDirectoryRegisterCategory)
Matteo Martincighab173e92019-09-05 12:02:04 +0100792{
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100793 CounterDirectory counterDirectory;
794 BOOST_CHECK(counterDirectory.GetCategoryCount() == 0);
795 BOOST_CHECK(counterDirectory.GetDeviceCount() == 0);
796 BOOST_CHECK(counterDirectory.GetCounterSetCount() == 0);
797 BOOST_CHECK(counterDirectory.GetCounterCount() == 0);
Matteo Martincighab173e92019-09-05 12:02:04 +0100798
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100799 // Register a category with an invalid name
800 const Category* noCategory = nullptr;
801 BOOST_CHECK_THROW(noCategory = counterDirectory.RegisterCategory(""), armnn::InvalidArgumentException);
802 BOOST_CHECK(counterDirectory.GetCategoryCount() == 0);
803 BOOST_CHECK(!noCategory);
Matteo Martincighab173e92019-09-05 12:02:04 +0100804
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100805 // Register a category with an invalid name
806 BOOST_CHECK_THROW(noCategory = counterDirectory.RegisterCategory("invalid category"),
807 armnn::InvalidArgumentException);
808 BOOST_CHECK(counterDirectory.GetCategoryCount() == 0);
809 BOOST_CHECK(!noCategory);
810
811 // Register a new category
812 const std::string categoryName = "some_category";
813 const Category* category = nullptr;
814 BOOST_CHECK_NO_THROW(category = counterDirectory.RegisterCategory(categoryName));
815 BOOST_CHECK(counterDirectory.GetCategoryCount() == 1);
816 BOOST_CHECK(category);
817 BOOST_CHECK(category->m_Name == categoryName);
818 BOOST_CHECK(category->m_Counters.empty());
819 BOOST_CHECK(category->m_DeviceUid == 0);
820 BOOST_CHECK(category->m_CounterSetUid == 0);
821
822 // Get the registered category
823 const Category* registeredCategory = counterDirectory.GetCategory(categoryName);
824 BOOST_CHECK(counterDirectory.GetCategoryCount() == 1);
825 BOOST_CHECK(registeredCategory);
826 BOOST_CHECK(registeredCategory == category);
827
828 // Try to get a category not registered
829 const Category* notRegisteredCategory = counterDirectory.GetCategory("not_registered_category");
830 BOOST_CHECK(counterDirectory.GetCategoryCount() == 1);
831 BOOST_CHECK(!notRegisteredCategory);
832
833 // Register a category already registered
834 const Category* anotherCategory = nullptr;
835 BOOST_CHECK_THROW(anotherCategory = counterDirectory.RegisterCategory(categoryName),
836 armnn::InvalidArgumentException);
837 BOOST_CHECK(counterDirectory.GetCategoryCount() == 1);
838 BOOST_CHECK(!anotherCategory);
839
840 // Register a device for testing
841 const std::string deviceName = "some_device";
842 const Device* device = nullptr;
843 BOOST_CHECK_NO_THROW(device = counterDirectory.RegisterDevice(deviceName));
844 BOOST_CHECK(counterDirectory.GetDeviceCount() == 1);
845 BOOST_CHECK(device);
846 BOOST_CHECK(device->m_Uid >= 1);
847 BOOST_CHECK(device->m_Name == deviceName);
848 BOOST_CHECK(device->m_Cores == 0);
849
850 // Register a new category not associated to any device
851 const std::string categoryWoDeviceName = "some_category_without_device";
852 const Category* categoryWoDevice = nullptr;
853 BOOST_CHECK_NO_THROW(categoryWoDevice = counterDirectory.RegisterCategory(categoryWoDeviceName, 0));
854 BOOST_CHECK(counterDirectory.GetCategoryCount() == 2);
855 BOOST_CHECK(categoryWoDevice);
856 BOOST_CHECK(categoryWoDevice->m_Name == categoryWoDeviceName);
857 BOOST_CHECK(categoryWoDevice->m_Counters.empty());
858 BOOST_CHECK(categoryWoDevice->m_DeviceUid == 0);
859 BOOST_CHECK(categoryWoDevice->m_CounterSetUid == 0);
860
861 // Register a new category associated to an invalid device
862 const std::string categoryWInvalidDeviceName = "some_category_with_invalid_device";
863
864 ARMNN_NO_CONVERSION_WARN_BEGIN
865 uint16_t invalidDeviceUid = device->m_Uid + 10;
866 ARMNN_NO_CONVERSION_WARN_END
867
868 const Category* categoryWInvalidDevice = nullptr;
869 BOOST_CHECK_THROW(categoryWInvalidDevice
870 = counterDirectory.RegisterCategory(categoryWInvalidDeviceName,
871 invalidDeviceUid),
872 armnn::InvalidArgumentException);
873 BOOST_CHECK(counterDirectory.GetCategoryCount() == 2);
874 BOOST_CHECK(!categoryWInvalidDevice);
875
876 // Register a new category associated to a valid device
877 const std::string categoryWValidDeviceName = "some_category_with_valid_device";
878 const Category* categoryWValidDevice = nullptr;
879 BOOST_CHECK_NO_THROW(categoryWValidDevice
880 = counterDirectory.RegisterCategory(categoryWValidDeviceName,
881 device->m_Uid));
882 BOOST_CHECK(counterDirectory.GetCategoryCount() == 3);
883 BOOST_CHECK(categoryWValidDevice);
884 BOOST_CHECK(categoryWValidDevice != category);
885 BOOST_CHECK(categoryWValidDevice->m_Name == categoryWValidDeviceName);
886 BOOST_CHECK(categoryWValidDevice->m_DeviceUid == device->m_Uid);
887 BOOST_CHECK(categoryWValidDevice->m_CounterSetUid == 0);
888
889 // Register a counter set for testing
890 const std::string counterSetName = "some_counter_set";
891 const CounterSet* counterSet = nullptr;
892 BOOST_CHECK_NO_THROW(counterSet = counterDirectory.RegisterCounterSet(counterSetName));
893 BOOST_CHECK(counterDirectory.GetCounterSetCount() == 1);
894 BOOST_CHECK(counterSet);
895 BOOST_CHECK(counterSet->m_Uid >= 1);
896 BOOST_CHECK(counterSet->m_Name == counterSetName);
897 BOOST_CHECK(counterSet->m_Count == 0);
898
899 // Register a new category not associated to any counter set
900 const std::string categoryWoCounterSetName = "some_category_without_counter_set";
901 const Category* categoryWoCounterSet = nullptr;
902 BOOST_CHECK_NO_THROW(categoryWoCounterSet
903 = counterDirectory.RegisterCategory(categoryWoCounterSetName,
904 armnn::EmptyOptional(),
905 0));
906 BOOST_CHECK(counterDirectory.GetCategoryCount() == 4);
907 BOOST_CHECK(categoryWoCounterSet);
908 BOOST_CHECK(categoryWoCounterSet->m_Name == categoryWoCounterSetName);
909 BOOST_CHECK(categoryWoCounterSet->m_DeviceUid == 0);
910 BOOST_CHECK(categoryWoCounterSet->m_CounterSetUid == 0);
911
912 // Register a new category associated to an invalid counter set
913 const std::string categoryWInvalidCounterSetName = "some_category_with_invalid_counter_set";
914
915 ARMNN_NO_CONVERSION_WARN_BEGIN
916 uint16_t invalidCunterSetUid = counterSet->m_Uid + 10;
917 ARMNN_NO_CONVERSION_WARN_END
918
919 const Category* categoryWInvalidCounterSet = nullptr;
920 BOOST_CHECK_THROW(categoryWInvalidCounterSet
921 = counterDirectory.RegisterCategory(categoryWInvalidCounterSetName,
922 armnn::EmptyOptional(),
923 invalidCunterSetUid),
924 armnn::InvalidArgumentException);
925 BOOST_CHECK(counterDirectory.GetCategoryCount() == 4);
926 BOOST_CHECK(!categoryWInvalidCounterSet);
927
928 // Register a new category associated to a valid counter set
929 const std::string categoryWValidCounterSetName = "some_category_with_valid_counter_set";
930 const Category* categoryWValidCounterSet = nullptr;
931 BOOST_CHECK_NO_THROW(categoryWValidCounterSet
932 = counterDirectory.RegisterCategory(categoryWValidCounterSetName,
933 armnn::EmptyOptional(),
934 counterSet->m_Uid));
935 BOOST_CHECK(counterDirectory.GetCategoryCount() == 5);
936 BOOST_CHECK(categoryWValidCounterSet);
937 BOOST_CHECK(categoryWValidCounterSet != category);
938 BOOST_CHECK(categoryWValidCounterSet->m_Name == categoryWValidCounterSetName);
939 BOOST_CHECK(categoryWValidCounterSet->m_DeviceUid == 0);
940 BOOST_CHECK(categoryWValidCounterSet->m_CounterSetUid == counterSet->m_Uid);
941
942 // Register a new category associated to a valid device and counter set
943 const std::string categoryWValidDeviceAndValidCounterSetName = "some_category_with_valid_device_and_counter_set";
944 const Category* categoryWValidDeviceAndValidCounterSet = nullptr;
945 BOOST_CHECK_NO_THROW(categoryWValidDeviceAndValidCounterSet
946 = counterDirectory.RegisterCategory(categoryWValidDeviceAndValidCounterSetName,
947 device->m_Uid,
948 counterSet->m_Uid));
949 BOOST_CHECK(counterDirectory.GetCategoryCount() == 6);
950 BOOST_CHECK(categoryWValidDeviceAndValidCounterSet);
951 BOOST_CHECK(categoryWValidDeviceAndValidCounterSet != category);
952 BOOST_CHECK(categoryWValidDeviceAndValidCounterSet->m_Name == categoryWValidDeviceAndValidCounterSetName);
953 BOOST_CHECK(categoryWValidDeviceAndValidCounterSet->m_DeviceUid == device->m_Uid);
954 BOOST_CHECK(categoryWValidDeviceAndValidCounterSet->m_CounterSetUid == counterSet->m_Uid);
955}
956
957BOOST_AUTO_TEST_CASE(CheckCounterDirectoryRegisterDevice)
958{
959 CounterDirectory counterDirectory;
960 BOOST_CHECK(counterDirectory.GetCategoryCount() == 0);
961 BOOST_CHECK(counterDirectory.GetDeviceCount() == 0);
962 BOOST_CHECK(counterDirectory.GetCounterSetCount() == 0);
963 BOOST_CHECK(counterDirectory.GetCounterCount() == 0);
964
965 // Register a device with an invalid name
966 const Device* noDevice = nullptr;
967 BOOST_CHECK_THROW(noDevice = counterDirectory.RegisterDevice(""), armnn::InvalidArgumentException);
968 BOOST_CHECK(counterDirectory.GetDeviceCount() == 0);
969 BOOST_CHECK(!noDevice);
970
971 // Register a device with an invalid name
972 BOOST_CHECK_THROW(noDevice = counterDirectory.RegisterDevice("inv@lid nam€"), armnn::InvalidArgumentException);
973 BOOST_CHECK(counterDirectory.GetDeviceCount() == 0);
974 BOOST_CHECK(!noDevice);
975
976 // Register a new device with no cores or parent category
977 const std::string deviceName = "some_device";
978 const Device* device = nullptr;
979 BOOST_CHECK_NO_THROW(device = counterDirectory.RegisterDevice(deviceName));
980 BOOST_CHECK(counterDirectory.GetDeviceCount() == 1);
981 BOOST_CHECK(device);
982 BOOST_CHECK(device->m_Name == deviceName);
983 BOOST_CHECK(device->m_Uid >= 1);
984 BOOST_CHECK(device->m_Cores == 0);
985
Matteo Martincigh657ab2d2019-09-18 10:53:24 +0100986 // Try getting an unregistered device
987 const Device* unregisteredDevice = counterDirectory.GetDevice(9999);
988 BOOST_CHECK(!unregisteredDevice);
989
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100990 // Get the registered device
991 const Device* registeredDevice = counterDirectory.GetDevice(device->m_Uid);
992 BOOST_CHECK(counterDirectory.GetDeviceCount() == 1);
993 BOOST_CHECK(registeredDevice);
994 BOOST_CHECK(registeredDevice == device);
995
Matteo Martincigh657ab2d2019-09-18 10:53:24 +0100996 // Register a device with the name of a device already registered
997 const Device* deviceSameName = nullptr;
998 BOOST_CHECK_THROW(deviceSameName = counterDirectory.RegisterDevice(deviceName), armnn::InvalidArgumentException);
999 BOOST_CHECK(counterDirectory.GetDeviceCount() == 1);
1000 BOOST_CHECK(!deviceSameName);
1001
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001002 // Register a new device with cores and no parent category
1003 const std::string deviceWCoresName = "some_device_with_cores";
1004 const Device* deviceWCores = nullptr;
1005 BOOST_CHECK_NO_THROW(deviceWCores = counterDirectory.RegisterDevice(deviceWCoresName, 2));
1006 BOOST_CHECK(counterDirectory.GetDeviceCount() == 2);
1007 BOOST_CHECK(deviceWCores);
1008 BOOST_CHECK(deviceWCores->m_Name == deviceWCoresName);
1009 BOOST_CHECK(deviceWCores->m_Uid >= 1);
1010 BOOST_CHECK(deviceWCores->m_Uid > device->m_Uid);
1011 BOOST_CHECK(deviceWCores->m_Cores == 2);
1012
1013 // Get the registered device
1014 const Device* registeredDeviceWCores = counterDirectory.GetDevice(deviceWCores->m_Uid);
1015 BOOST_CHECK(counterDirectory.GetDeviceCount() == 2);
1016 BOOST_CHECK(registeredDeviceWCores);
1017 BOOST_CHECK(registeredDeviceWCores == deviceWCores);
1018 BOOST_CHECK(registeredDeviceWCores != device);
1019
1020 // Register a new device with cores and invalid parent category
1021 const std::string deviceWCoresWInvalidParentCategoryName = "some_device_with_cores_with_invalid_parent_category";
1022 const Device* deviceWCoresWInvalidParentCategory = nullptr;
1023 BOOST_CHECK_THROW(deviceWCoresWInvalidParentCategory
1024 = counterDirectory.RegisterDevice(deviceWCoresWInvalidParentCategoryName,
1025 3,
1026 std::string("")),
1027 armnn::InvalidArgumentException);
1028 BOOST_CHECK(counterDirectory.GetDeviceCount() == 2);
1029 BOOST_CHECK(!deviceWCoresWInvalidParentCategory);
1030
1031 // Register a new device with cores and invalid parent category
1032 const std::string deviceWCoresWInvalidParentCategoryName2 = "some_device_with_cores_with_invalid_parent_category2";
1033 const Device* deviceWCoresWInvalidParentCategory2 = nullptr;
1034 BOOST_CHECK_THROW(deviceWCoresWInvalidParentCategory2
1035 = counterDirectory.RegisterDevice(deviceWCoresWInvalidParentCategoryName2,
1036 3,
1037 std::string("invalid_parent_category")),
1038 armnn::InvalidArgumentException);
1039 BOOST_CHECK(counterDirectory.GetDeviceCount() == 2);
1040 BOOST_CHECK(!deviceWCoresWInvalidParentCategory2);
1041
1042 // Register a category for testing
1043 const std::string categoryName = "some_category";
1044 const Category* category = nullptr;
1045 BOOST_CHECK_NO_THROW(category = counterDirectory.RegisterCategory(categoryName));
1046 BOOST_CHECK(counterDirectory.GetCategoryCount() == 1);
1047 BOOST_CHECK(category);
1048 BOOST_CHECK(category->m_Name == categoryName);
1049 BOOST_CHECK(category->m_Counters.empty());
1050 BOOST_CHECK(category->m_DeviceUid == 0);
1051 BOOST_CHECK(category->m_CounterSetUid == 0);
1052
1053 // Register a new device with cores and valid parent category
1054 const std::string deviceWCoresWValidParentCategoryName = "some_device_with_cores_with_valid_parent_category";
1055 const Device* deviceWCoresWValidParentCategory = nullptr;
1056 BOOST_CHECK_NO_THROW(deviceWCoresWValidParentCategory
1057 = counterDirectory.RegisterDevice(deviceWCoresWValidParentCategoryName,
1058 4,
1059 categoryName));
1060 BOOST_CHECK(counterDirectory.GetDeviceCount() == 3);
1061 BOOST_CHECK(deviceWCoresWValidParentCategory);
1062 BOOST_CHECK(deviceWCoresWValidParentCategory->m_Name == deviceWCoresWValidParentCategoryName);
1063 BOOST_CHECK(deviceWCoresWValidParentCategory->m_Uid >= 1);
1064 BOOST_CHECK(deviceWCoresWValidParentCategory->m_Uid > device->m_Uid);
1065 BOOST_CHECK(deviceWCoresWValidParentCategory->m_Uid > deviceWCores->m_Uid);
1066 BOOST_CHECK(deviceWCoresWValidParentCategory->m_Cores == 4);
1067 BOOST_CHECK(category->m_DeviceUid == deviceWCoresWValidParentCategory->m_Uid);
Matteo Martincigh657ab2d2019-09-18 10:53:24 +01001068
1069 // Register a device associated to a category already associated to a different device
1070 const std::string deviceSameCategoryName = "some_device_with_invalid_parent_category";
1071 const Device* deviceSameCategory = nullptr;
1072 BOOST_CHECK_THROW(deviceSameCategory = counterDirectory.RegisterDevice(deviceSameCategoryName, 0, categoryName),
1073 armnn::InvalidArgumentException);
1074 BOOST_CHECK(counterDirectory.GetDeviceCount() == 3);
1075 BOOST_CHECK(!deviceSameCategory);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001076}
1077
1078BOOST_AUTO_TEST_CASE(CheckCounterDirectoryRegisterCounterSet)
1079{
1080 CounterDirectory counterDirectory;
1081 BOOST_CHECK(counterDirectory.GetCategoryCount() == 0);
1082 BOOST_CHECK(counterDirectory.GetDeviceCount() == 0);
1083 BOOST_CHECK(counterDirectory.GetCounterSetCount() == 0);
1084 BOOST_CHECK(counterDirectory.GetCounterCount() == 0);
1085
1086 // Register a counter set with an invalid name
1087 const CounterSet* noCounterSet = nullptr;
1088 BOOST_CHECK_THROW(noCounterSet = counterDirectory.RegisterCounterSet(""), armnn::InvalidArgumentException);
1089 BOOST_CHECK(counterDirectory.GetCounterSetCount() == 0);
1090 BOOST_CHECK(!noCounterSet);
1091
1092 // Register a counter set with an invalid name
1093 BOOST_CHECK_THROW(noCounterSet = counterDirectory.RegisterCounterSet("invalid name"),
1094 armnn::InvalidArgumentException);
1095 BOOST_CHECK(counterDirectory.GetCounterSetCount() == 0);
1096 BOOST_CHECK(!noCounterSet);
1097
1098 // Register a new counter set with no count or parent category
1099 const std::string counterSetName = "some_counter_set";
1100 const CounterSet* counterSet = nullptr;
1101 BOOST_CHECK_NO_THROW(counterSet = counterDirectory.RegisterCounterSet(counterSetName));
1102 BOOST_CHECK(counterDirectory.GetCounterSetCount() == 1);
1103 BOOST_CHECK(counterSet);
1104 BOOST_CHECK(counterSet->m_Name == counterSetName);
1105 BOOST_CHECK(counterSet->m_Uid >= 1);
1106 BOOST_CHECK(counterSet->m_Count == 0);
1107
Matteo Martincigh657ab2d2019-09-18 10:53:24 +01001108 // Try getting an unregistered counter set
1109 const CounterSet* unregisteredCounterSet = counterDirectory.GetCounterSet(9999);
1110 BOOST_CHECK(!unregisteredCounterSet);
1111
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001112 // Get the registered counter set
1113 const CounterSet* registeredCounterSet = counterDirectory.GetCounterSet(counterSet->m_Uid);
1114 BOOST_CHECK(counterDirectory.GetCounterSetCount() == 1);
1115 BOOST_CHECK(registeredCounterSet);
1116 BOOST_CHECK(registeredCounterSet == counterSet);
1117
Matteo Martincigh657ab2d2019-09-18 10:53:24 +01001118 // Register a counter set with the name of a counter set already registered
1119 const CounterSet* counterSetSameName = nullptr;
1120 BOOST_CHECK_THROW(counterSetSameName = counterDirectory.RegisterCounterSet(counterSetName),
1121 armnn::InvalidArgumentException);
1122 BOOST_CHECK(counterDirectory.GetCounterSetCount() == 1);
1123 BOOST_CHECK(!counterSetSameName);
1124
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001125 // Register a new counter set with count and no parent category
1126 const std::string counterSetWCountName = "some_counter_set_with_count";
1127 const CounterSet* counterSetWCount = nullptr;
1128 BOOST_CHECK_NO_THROW(counterSetWCount = counterDirectory.RegisterCounterSet(counterSetWCountName, 37));
1129 BOOST_CHECK(counterDirectory.GetCounterSetCount() == 2);
1130 BOOST_CHECK(counterSetWCount);
1131 BOOST_CHECK(counterSetWCount->m_Name == counterSetWCountName);
1132 BOOST_CHECK(counterSetWCount->m_Uid >= 1);
1133 BOOST_CHECK(counterSetWCount->m_Uid > counterSet->m_Uid);
1134 BOOST_CHECK(counterSetWCount->m_Count == 37);
1135
1136 // Get the registered counter set
1137 const CounterSet* registeredCounterSetWCount = counterDirectory.GetCounterSet(counterSetWCount->m_Uid);
1138 BOOST_CHECK(counterDirectory.GetCounterSetCount() == 2);
1139 BOOST_CHECK(registeredCounterSetWCount);
1140 BOOST_CHECK(registeredCounterSetWCount == counterSetWCount);
1141 BOOST_CHECK(registeredCounterSetWCount != counterSet);
1142
1143 // Register a new counter set with count and invalid parent category
1144 const std::string counterSetWCountWInvalidParentCategoryName = "some_counter_set_with_count_"
1145 "with_invalid_parent_category";
1146 const CounterSet* counterSetWCountWInvalidParentCategory = nullptr;
1147 BOOST_CHECK_THROW(counterSetWCountWInvalidParentCategory
1148 = counterDirectory.RegisterCounterSet(counterSetWCountWInvalidParentCategoryName,
1149 42,
1150 std::string("")),
1151 armnn::InvalidArgumentException);
1152 BOOST_CHECK(counterDirectory.GetCounterSetCount() == 2);
1153 BOOST_CHECK(!counterSetWCountWInvalidParentCategory);
1154
1155 // Register a new counter set with count and invalid parent category
1156 const std::string counterSetWCountWInvalidParentCategoryName2 = "some_counter_set_with_count_"
1157 "with_invalid_parent_category2";
1158 const CounterSet* counterSetWCountWInvalidParentCategory2 = nullptr;
1159 BOOST_CHECK_THROW(counterSetWCountWInvalidParentCategory2
1160 = counterDirectory.RegisterCounterSet(counterSetWCountWInvalidParentCategoryName2,
1161 42,
1162 std::string("invalid_parent_category")),
1163 armnn::InvalidArgumentException);
1164 BOOST_CHECK(counterDirectory.GetCounterSetCount() == 2);
1165 BOOST_CHECK(!counterSetWCountWInvalidParentCategory2);
1166
1167 // Register a category for testing
1168 const std::string categoryName = "some_category";
1169 const Category* category = nullptr;
1170 BOOST_CHECK_NO_THROW(category = counterDirectory.RegisterCategory(categoryName));
1171 BOOST_CHECK(counterDirectory.GetCategoryCount() == 1);
1172 BOOST_CHECK(category);
1173 BOOST_CHECK(category->m_Name == categoryName);
1174 BOOST_CHECK(category->m_Counters.empty());
1175 BOOST_CHECK(category->m_DeviceUid == 0);
1176 BOOST_CHECK(category->m_CounterSetUid == 0);
1177
1178 // Register a new counter set with count and valid parent category
1179 const std::string counterSetWCountWValidParentCategoryName = "some_counter_set_with_count_"
1180 "with_valid_parent_category";
1181 const CounterSet* counterSetWCountWValidParentCategory = nullptr;
1182 BOOST_CHECK_NO_THROW(counterSetWCountWValidParentCategory
1183 = counterDirectory.RegisterCounterSet(counterSetWCountWValidParentCategoryName,
1184 42,
Matteo Martincigh657ab2d2019-09-18 10:53:24 +01001185 categoryName));
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001186 BOOST_CHECK(counterDirectory.GetCounterSetCount() == 3);
1187 BOOST_CHECK(counterSetWCountWValidParentCategory);
1188 BOOST_CHECK(counterSetWCountWValidParentCategory->m_Name == counterSetWCountWValidParentCategoryName);
1189 BOOST_CHECK(counterSetWCountWValidParentCategory->m_Uid >= 1);
1190 BOOST_CHECK(counterSetWCountWValidParentCategory->m_Uid > counterSet->m_Uid);
1191 BOOST_CHECK(counterSetWCountWValidParentCategory->m_Uid > counterSetWCount->m_Uid);
1192 BOOST_CHECK(counterSetWCountWValidParentCategory->m_Count == 42);
1193 BOOST_CHECK(category->m_CounterSetUid == counterSetWCountWValidParentCategory->m_Uid);
Matteo Martincigh657ab2d2019-09-18 10:53:24 +01001194
1195 // Register a counter set associated to a category already associated to a different counter set
1196 const std::string counterSetSameCategoryName = "some_counter_set_with_invalid_parent_category";
1197 const CounterSet* counterSetSameCategory = nullptr;
1198 BOOST_CHECK_THROW(counterSetSameCategory = counterDirectory.RegisterCounterSet(counterSetSameCategoryName,
1199 0,
1200 categoryName),
1201 armnn::InvalidArgumentException);
1202 BOOST_CHECK(counterDirectory.GetCounterSetCount() == 3);
1203 BOOST_CHECK(!counterSetSameCategory);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001204}
1205
1206BOOST_AUTO_TEST_CASE(CheckCounterDirectoryRegisterCounter)
1207{
1208 CounterDirectory counterDirectory;
1209 BOOST_CHECK(counterDirectory.GetCategoryCount() == 0);
1210 BOOST_CHECK(counterDirectory.GetDeviceCount() == 0);
1211 BOOST_CHECK(counterDirectory.GetCounterSetCount() == 0);
1212 BOOST_CHECK(counterDirectory.GetCounterCount() == 0);
1213
1214 // Register a counter with an invalid parent category name
1215 const Counter* noCounter = nullptr;
1216 BOOST_CHECK_THROW(noCounter = counterDirectory.RegisterCounter("",
1217 0,
1218 1,
1219 123.45f,
1220 "valid name",
1221 "valid description"),
1222 armnn::InvalidArgumentException);
1223 BOOST_CHECK(counterDirectory.GetCounterCount() == 0);
1224 BOOST_CHECK(!noCounter);
1225
1226 // Register a counter with an invalid parent category name
1227 BOOST_CHECK_THROW(noCounter = counterDirectory.RegisterCounter("invalid parent category",
1228 0,
1229 1,
1230 123.45f,
1231 "valid name",
1232 "valid description"),
1233 armnn::InvalidArgumentException);
1234 BOOST_CHECK(counterDirectory.GetCounterCount() == 0);
1235 BOOST_CHECK(!noCounter);
1236
1237 // Register a counter with an invalid class
1238 BOOST_CHECK_THROW(noCounter = counterDirectory.RegisterCounter("valid_parent_category",
1239 2,
1240 1,
1241 123.45f,
1242 "valid name",
1243 "valid description"),
1244 armnn::InvalidArgumentException);
1245 BOOST_CHECK(counterDirectory.GetCounterCount() == 0);
1246 BOOST_CHECK(!noCounter);
1247
1248 // Register a counter with an invalid interpolation
1249 BOOST_CHECK_THROW(noCounter = counterDirectory.RegisterCounter("valid_parent_category",
1250 0,
1251 3,
1252 123.45f,
1253 "valid name",
1254 "valid description"),
1255 armnn::InvalidArgumentException);
1256 BOOST_CHECK(counterDirectory.GetCounterCount() == 0);
1257 BOOST_CHECK(!noCounter);
1258
1259 // Register a counter with an invalid multiplier
1260 BOOST_CHECK_THROW(noCounter = counterDirectory.RegisterCounter("valid_parent_category",
1261 0,
1262 1,
1263 .0f,
1264 "valid name",
1265 "valid description"),
1266 armnn::InvalidArgumentException);
1267 BOOST_CHECK(counterDirectory.GetCounterCount() == 0);
1268 BOOST_CHECK(!noCounter);
1269
1270 // Register a counter with an invalid name
1271 BOOST_CHECK_THROW(noCounter = counterDirectory.RegisterCounter("valid_parent_category",
1272 0,
1273 1,
1274 123.45f,
1275 "",
1276 "valid description"),
1277 armnn::InvalidArgumentException);
1278 BOOST_CHECK(counterDirectory.GetCounterCount() == 0);
1279 BOOST_CHECK(!noCounter);
1280
1281 // Register a counter with an invalid name
1282 BOOST_CHECK_THROW(noCounter = counterDirectory.RegisterCounter("valid_parent_category",
1283 0,
1284 1,
1285 123.45f,
1286 "invalid nam€",
1287 "valid description"),
1288 armnn::InvalidArgumentException);
1289 BOOST_CHECK(counterDirectory.GetCounterCount() == 0);
1290 BOOST_CHECK(!noCounter);
1291
1292 // Register a counter with an invalid description
1293 BOOST_CHECK_THROW(noCounter = counterDirectory.RegisterCounter("valid_parent_category",
1294 0,
1295 1,
1296 123.45f,
1297 "valid name",
1298 ""),
1299 armnn::InvalidArgumentException);
1300 BOOST_CHECK(counterDirectory.GetCounterCount() == 0);
1301 BOOST_CHECK(!noCounter);
1302
1303 // Register a counter with an invalid description
1304 BOOST_CHECK_THROW(noCounter = counterDirectory.RegisterCounter("valid_parent_category",
1305 0,
1306 1,
1307 123.45f,
1308 "valid name",
1309 "inv@lid description"),
1310 armnn::InvalidArgumentException);
1311 BOOST_CHECK(counterDirectory.GetCounterCount() == 0);
1312 BOOST_CHECK(!noCounter);
1313
1314 // Register a counter with an invalid unit2
1315 BOOST_CHECK_THROW(noCounter = counterDirectory.RegisterCounter("valid_parent_category",
1316 0,
1317 1,
1318 123.45f,
1319 "valid name",
1320 "valid description",
1321 std::string("Mb/s2")),
1322 armnn::InvalidArgumentException);
1323 BOOST_CHECK(counterDirectory.GetCounterCount() == 0);
1324 BOOST_CHECK(!noCounter);
1325
1326 // Register a counter with a non-existing parent category name
1327 BOOST_CHECK_THROW(noCounter = counterDirectory.RegisterCounter("invalid_parent_category",
1328 0,
1329 1,
1330 123.45f,
1331 "valid name",
1332 "valid description"),
1333 armnn::InvalidArgumentException);
1334 BOOST_CHECK(counterDirectory.GetCounterCount() == 0);
1335 BOOST_CHECK(!noCounter);
1336
Matteo Martincigh657ab2d2019-09-18 10:53:24 +01001337 // Try getting an unregistered counter
1338 const Counter* unregisteredCounter = counterDirectory.GetCounter(9999);
1339 BOOST_CHECK(!unregisteredCounter);
1340
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001341 // Register a category for testing
1342 const std::string categoryName = "some_category";
1343 const Category* category = nullptr;
1344 BOOST_CHECK_NO_THROW(category = counterDirectory.RegisterCategory(categoryName));
1345 BOOST_CHECK(counterDirectory.GetCategoryCount() == 1);
1346 BOOST_CHECK(category);
1347 BOOST_CHECK(category->m_Name == categoryName);
1348 BOOST_CHECK(category->m_Counters.empty());
1349 BOOST_CHECK(category->m_DeviceUid == 0);
1350 BOOST_CHECK(category->m_CounterSetUid == 0);
1351
1352 // Register a counter with a valid parent category name
1353 const Counter* counter = nullptr;
1354 BOOST_CHECK_NO_THROW(counter = counterDirectory.RegisterCounter(categoryName,
1355 0,
1356 1,
1357 123.45f,
1358 "valid name",
1359 "valid description"));
1360 BOOST_CHECK(counterDirectory.GetCounterCount() == 1);
1361 BOOST_CHECK(counter);
1362 BOOST_CHECK(counter->m_Uid >= 0);
1363 BOOST_CHECK(counter->m_MaxCounterUid == counter->m_Uid);
1364 BOOST_CHECK(counter->m_Class == 0);
1365 BOOST_CHECK(counter->m_Interpolation == 1);
1366 BOOST_CHECK(counter->m_Multiplier == 123.45f);
1367 BOOST_CHECK(counter->m_Name == "valid name");
1368 BOOST_CHECK(counter->m_Description == "valid description");
1369 BOOST_CHECK(counter->m_Units == "");
1370 BOOST_CHECK(counter->m_DeviceUid == 0);
1371 BOOST_CHECK(counter->m_CounterSetUid == 0);
1372 BOOST_CHECK(category->m_Counters.size() == 1);
1373 BOOST_CHECK(category->m_Counters.back() == counter->m_Uid);
1374
Matteo Martincigh657ab2d2019-09-18 10:53:24 +01001375 // Register a counter with a name of a counter already registered for the given parent category name
1376 const Counter* counterSameName = nullptr;
1377 BOOST_CHECK_THROW(counterSameName = counterDirectory.RegisterCounter(categoryName,
1378 0,
1379 0,
1380 1.0f,
1381 "valid name",
1382 "valid description"),
1383 armnn::InvalidArgumentException);
1384 BOOST_CHECK(counterDirectory.GetCounterCount() == 1);
1385 BOOST_CHECK(!counterSameName);
1386
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001387 // Register a counter with a valid parent category name and units
1388 const Counter* counterWUnits = nullptr;
1389 BOOST_CHECK_NO_THROW(counterWUnits = counterDirectory.RegisterCounter(categoryName,
1390 0,
1391 1,
1392 123.45f,
1393 "valid name 2",
1394 "valid description",
1395 std::string("Mnnsq2"))); // Units
1396 BOOST_CHECK(counterDirectory.GetCounterCount() == 2);
1397 BOOST_CHECK(counterWUnits);
1398 BOOST_CHECK(counterWUnits->m_Uid >= 0);
1399 BOOST_CHECK(counterWUnits->m_Uid > counter->m_Uid);
1400 BOOST_CHECK(counterWUnits->m_MaxCounterUid == counterWUnits->m_Uid);
1401 BOOST_CHECK(counterWUnits->m_Class == 0);
1402 BOOST_CHECK(counterWUnits->m_Interpolation == 1);
1403 BOOST_CHECK(counterWUnits->m_Multiplier == 123.45f);
1404 BOOST_CHECK(counterWUnits->m_Name == "valid name 2");
1405 BOOST_CHECK(counterWUnits->m_Description == "valid description");
1406 BOOST_CHECK(counterWUnits->m_Units == "Mnnsq2");
1407 BOOST_CHECK(counterWUnits->m_DeviceUid == 0);
1408 BOOST_CHECK(counterWUnits->m_CounterSetUid == 0);
1409 BOOST_CHECK(category->m_Counters.size() == 2);
1410 BOOST_CHECK(category->m_Counters.back() == counterWUnits->m_Uid);
1411
1412 // Register a counter with a valid parent category name and not associated with a device
1413 const Counter* counterWoDevice = nullptr;
1414 BOOST_CHECK_NO_THROW(counterWoDevice = counterDirectory.RegisterCounter(categoryName,
1415 0,
1416 1,
1417 123.45f,
1418 "valid name 3",
1419 "valid description",
1420 armnn::EmptyOptional(), // Units
1421 armnn::EmptyOptional(), // Number of cores
1422 0)); // Device UID
1423 BOOST_CHECK(counterDirectory.GetCounterCount() == 3);
1424 BOOST_CHECK(counterWoDevice);
1425 BOOST_CHECK(counterWoDevice->m_Uid >= 0);
1426 BOOST_CHECK(counterWoDevice->m_Uid > counter->m_Uid);
1427 BOOST_CHECK(counterWoDevice->m_MaxCounterUid == counterWoDevice->m_Uid);
1428 BOOST_CHECK(counterWoDevice->m_Class == 0);
1429 BOOST_CHECK(counterWoDevice->m_Interpolation == 1);
1430 BOOST_CHECK(counterWoDevice->m_Multiplier == 123.45f);
1431 BOOST_CHECK(counterWoDevice->m_Name == "valid name 3");
1432 BOOST_CHECK(counterWoDevice->m_Description == "valid description");
1433 BOOST_CHECK(counterWoDevice->m_Units == "");
1434 BOOST_CHECK(counterWoDevice->m_DeviceUid == 0);
1435 BOOST_CHECK(counterWoDevice->m_CounterSetUid == 0);
1436 BOOST_CHECK(category->m_Counters.size() == 3);
1437 BOOST_CHECK(category->m_Counters.back() == counterWoDevice->m_Uid);
1438
1439 // Register a counter with a valid parent category name and associated to an invalid device
1440 BOOST_CHECK_THROW(noCounter = counterDirectory.RegisterCounter(categoryName,
1441 0,
1442 1,
1443 123.45f,
1444 "valid name 4",
1445 "valid description",
1446 armnn::EmptyOptional(), // Units
1447 armnn::EmptyOptional(), // Number of cores
1448 100), // Device UID
1449 armnn::InvalidArgumentException);
1450 BOOST_CHECK(counterDirectory.GetCounterCount() == 3);
1451 BOOST_CHECK(!noCounter);
1452
1453 // Register a device for testing
1454 const std::string deviceName = "some_device";
1455 const Device* device = nullptr;
1456 BOOST_CHECK_NO_THROW(device = counterDirectory.RegisterDevice(deviceName));
1457 BOOST_CHECK(counterDirectory.GetDeviceCount() == 1);
1458 BOOST_CHECK(device);
1459 BOOST_CHECK(device->m_Name == deviceName);
1460 BOOST_CHECK(device->m_Uid >= 1);
1461 BOOST_CHECK(device->m_Cores == 0);
1462
1463 // Register a counter with a valid parent category name and associated to a device
1464 const Counter* counterWDevice = nullptr;
1465 BOOST_CHECK_NO_THROW(counterWDevice = counterDirectory.RegisterCounter(categoryName,
1466 0,
1467 1,
1468 123.45f,
1469 "valid name 5",
1470 "valid description",
1471 armnn::EmptyOptional(), // Units
1472 armnn::EmptyOptional(), // Number of cores
1473 device->m_Uid)); // Device UID
1474 BOOST_CHECK(counterDirectory.GetCounterCount() == 4);
1475 BOOST_CHECK(counterWDevice);
1476 BOOST_CHECK(counterWDevice->m_Uid >= 0);
1477 BOOST_CHECK(counterWDevice->m_Uid > counter->m_Uid);
1478 BOOST_CHECK(counterWDevice->m_MaxCounterUid == counterWDevice->m_Uid);
1479 BOOST_CHECK(counterWDevice->m_Class == 0);
1480 BOOST_CHECK(counterWDevice->m_Interpolation == 1);
1481 BOOST_CHECK(counterWDevice->m_Multiplier == 123.45f);
1482 BOOST_CHECK(counterWDevice->m_Name == "valid name 5");
1483 BOOST_CHECK(counterWDevice->m_Description == "valid description");
1484 BOOST_CHECK(counterWDevice->m_Units == "");
1485 BOOST_CHECK(counterWDevice->m_DeviceUid == device->m_Uid);
1486 BOOST_CHECK(counterWDevice->m_CounterSetUid == 0);
1487 BOOST_CHECK(category->m_Counters.size() == 4);
1488 BOOST_CHECK(category->m_Counters.back() == counterWDevice->m_Uid);
1489
1490 // Register a counter with a valid parent category name and not associated with a counter set
1491 const Counter* counterWoCounterSet = nullptr;
1492 BOOST_CHECK_NO_THROW(counterWoCounterSet
1493 = counterDirectory.RegisterCounter(categoryName,
1494 0,
1495 1,
1496 123.45f,
1497 "valid name 6",
1498 "valid description",
1499 armnn::EmptyOptional(), // Units
1500 armnn::EmptyOptional(), // Number of cores
1501 armnn::EmptyOptional(), // Device UID
1502 0)); // Counter set UID
1503 BOOST_CHECK(counterDirectory.GetCounterCount() == 5);
1504 BOOST_CHECK(counterWoCounterSet);
1505 BOOST_CHECK(counterWoCounterSet->m_Uid >= 0);
1506 BOOST_CHECK(counterWoCounterSet->m_Uid > counter->m_Uid);
1507 BOOST_CHECK(counterWoCounterSet->m_MaxCounterUid == counterWoCounterSet->m_Uid);
1508 BOOST_CHECK(counterWoCounterSet->m_Class == 0);
1509 BOOST_CHECK(counterWoCounterSet->m_Interpolation == 1);
1510 BOOST_CHECK(counterWoCounterSet->m_Multiplier == 123.45f);
1511 BOOST_CHECK(counterWoCounterSet->m_Name == "valid name 6");
1512 BOOST_CHECK(counterWoCounterSet->m_Description == "valid description");
1513 BOOST_CHECK(counterWoCounterSet->m_Units == "");
1514 BOOST_CHECK(counterWoCounterSet->m_DeviceUid == 0);
1515 BOOST_CHECK(counterWoCounterSet->m_CounterSetUid == 0);
1516 BOOST_CHECK(category->m_Counters.size() == 5);
1517 BOOST_CHECK(category->m_Counters.back() == counterWoCounterSet->m_Uid);
1518
1519 // Register a counter with a valid parent category name and associated to an invalid counter set
1520 BOOST_CHECK_THROW(noCounter = counterDirectory.RegisterCounter(categoryName,
1521 0,
1522 1,
1523 123.45f,
1524 "valid name 7",
1525 "valid description",
1526 armnn::EmptyOptional(), // Units
1527 armnn::EmptyOptional(), // Number of cores
1528 armnn::EmptyOptional(), // Device UID
1529 100), // Counter set UID
1530 armnn::InvalidArgumentException);
1531 BOOST_CHECK(counterDirectory.GetCounterCount() == 5);
1532 BOOST_CHECK(!noCounter);
1533
1534 // Register a counter with a valid parent category name and with a given number of cores
1535 const Counter* counterWNumberOfCores = nullptr;
1536 uint16_t numberOfCores = 15;
1537 BOOST_CHECK_NO_THROW(counterWNumberOfCores
1538 = counterDirectory.RegisterCounter(categoryName,
1539 0,
1540 1,
1541 123.45f,
1542 "valid name 8",
1543 "valid description",
1544 armnn::EmptyOptional(), // Units
1545 numberOfCores, // Number of cores
1546 armnn::EmptyOptional(), // Device UID
1547 armnn::EmptyOptional())); // Counter set UID
1548 BOOST_CHECK(counterDirectory.GetCounterCount() == 20);
1549 BOOST_CHECK(counterWNumberOfCores);
1550 BOOST_CHECK(counterWNumberOfCores->m_Uid >= 0);
1551 BOOST_CHECK(counterWNumberOfCores->m_Uid > counter->m_Uid);
1552 BOOST_CHECK(counterWNumberOfCores->m_MaxCounterUid == counterWNumberOfCores->m_Uid + numberOfCores - 1);
1553 BOOST_CHECK(counterWNumberOfCores->m_Class == 0);
1554 BOOST_CHECK(counterWNumberOfCores->m_Interpolation == 1);
1555 BOOST_CHECK(counterWNumberOfCores->m_Multiplier == 123.45f);
1556 BOOST_CHECK(counterWNumberOfCores->m_Name == "valid name 8");
1557 BOOST_CHECK(counterWNumberOfCores->m_Description == "valid description");
1558 BOOST_CHECK(counterWNumberOfCores->m_Units == "");
1559 BOOST_CHECK(counterWNumberOfCores->m_DeviceUid == 0);
1560 BOOST_CHECK(counterWNumberOfCores->m_CounterSetUid == 0);
1561 BOOST_CHECK(category->m_Counters.size() == 20);
1562 for (size_t i = 0; i < numberOfCores; i ++)
1563 {
1564 BOOST_CHECK(category->m_Counters[category->m_Counters.size() - numberOfCores + i] ==
1565 counterWNumberOfCores->m_Uid + i);
1566 }
1567
1568 // Register a multi-core device for testing
1569 const std::string multiCoreDeviceName = "some_multi_core_device";
1570 const Device* multiCoreDevice = nullptr;
1571 BOOST_CHECK_NO_THROW(multiCoreDevice = counterDirectory.RegisterDevice(multiCoreDeviceName, 4));
1572 BOOST_CHECK(counterDirectory.GetDeviceCount() == 2);
1573 BOOST_CHECK(multiCoreDevice);
1574 BOOST_CHECK(multiCoreDevice->m_Name == multiCoreDeviceName);
1575 BOOST_CHECK(multiCoreDevice->m_Uid >= 1);
1576 BOOST_CHECK(multiCoreDevice->m_Cores == 4);
1577
1578 // Register a counter with a valid parent category name and associated to the multi-core device
1579 const Counter* counterWMultiCoreDevice = nullptr;
1580 BOOST_CHECK_NO_THROW(counterWMultiCoreDevice
1581 = counterDirectory.RegisterCounter(categoryName,
1582 0,
1583 1,
1584 123.45f,
1585 "valid name 9",
1586 "valid description",
1587 armnn::EmptyOptional(), // Units
1588 armnn::EmptyOptional(), // Number of cores
1589 multiCoreDevice->m_Uid, // Device UID
1590 armnn::EmptyOptional())); // Counter set UID
1591 BOOST_CHECK(counterDirectory.GetCounterCount() == 24);
1592 BOOST_CHECK(counterWMultiCoreDevice);
1593 BOOST_CHECK(counterWMultiCoreDevice->m_Uid >= 0);
1594 BOOST_CHECK(counterWMultiCoreDevice->m_Uid > counter->m_Uid);
1595 BOOST_CHECK(counterWMultiCoreDevice->m_MaxCounterUid ==
1596 counterWMultiCoreDevice->m_Uid + multiCoreDevice->m_Cores - 1);
1597 BOOST_CHECK(counterWMultiCoreDevice->m_Class == 0);
1598 BOOST_CHECK(counterWMultiCoreDevice->m_Interpolation == 1);
1599 BOOST_CHECK(counterWMultiCoreDevice->m_Multiplier == 123.45f);
1600 BOOST_CHECK(counterWMultiCoreDevice->m_Name == "valid name 9");
1601 BOOST_CHECK(counterWMultiCoreDevice->m_Description == "valid description");
1602 BOOST_CHECK(counterWMultiCoreDevice->m_Units == "");
1603 BOOST_CHECK(counterWMultiCoreDevice->m_DeviceUid == multiCoreDevice->m_Uid);
1604 BOOST_CHECK(counterWMultiCoreDevice->m_CounterSetUid == 0);
1605 BOOST_CHECK(category->m_Counters.size() == 24);
1606 for (size_t i = 0; i < 4; i ++)
1607 {
1608 BOOST_CHECK(category->m_Counters[category->m_Counters.size() - 4 + i] == counterWMultiCoreDevice->m_Uid + i);
1609 }
1610
Matteo Martincigh657ab2d2019-09-18 10:53:24 +01001611 // Register a multi-core device associate to a parent category for testing
1612 const std::string multiCoreDeviceNameWParentCategory = "some_multi_core_device_with_parent_category";
1613 const Device* multiCoreDeviceWParentCategory = nullptr;
1614 BOOST_CHECK_NO_THROW(multiCoreDeviceWParentCategory =
1615 counterDirectory.RegisterDevice(multiCoreDeviceNameWParentCategory, 2, categoryName));
1616 BOOST_CHECK(counterDirectory.GetDeviceCount() == 3);
1617 BOOST_CHECK(multiCoreDeviceWParentCategory);
1618 BOOST_CHECK(multiCoreDeviceWParentCategory->m_Name == multiCoreDeviceNameWParentCategory);
1619 BOOST_CHECK(multiCoreDeviceWParentCategory->m_Uid >= 1);
1620 BOOST_CHECK(multiCoreDeviceWParentCategory->m_Cores == 2);
1621
1622 // Register a counter with a valid parent category name and getting the number of cores of the multi-core device
1623 // associated to that category
1624 const Counter* counterWMultiCoreDeviceWParentCategory = nullptr;
1625 BOOST_CHECK_NO_THROW(counterWMultiCoreDeviceWParentCategory
1626 = counterDirectory.RegisterCounter(categoryName,
1627 0,
1628 1,
1629 123.45f,
1630 "valid name 10",
1631 "valid description",
1632 armnn::EmptyOptional(), // Units
1633 armnn::EmptyOptional(), // Number of cores
1634 armnn::EmptyOptional(), // Device UID
1635 armnn::EmptyOptional())); // Counter set UID
1636 BOOST_CHECK(counterDirectory.GetCounterCount() == 26);
1637 BOOST_CHECK(counterWMultiCoreDeviceWParentCategory);
1638 BOOST_CHECK(counterWMultiCoreDeviceWParentCategory->m_Uid >= 0);
1639 BOOST_CHECK(counterWMultiCoreDeviceWParentCategory->m_Uid > counter->m_Uid);
1640 BOOST_CHECK(counterWMultiCoreDeviceWParentCategory->m_MaxCounterUid ==
1641 counterWMultiCoreDeviceWParentCategory->m_Uid + multiCoreDeviceWParentCategory->m_Cores - 1);
1642 BOOST_CHECK(counterWMultiCoreDeviceWParentCategory->m_Class == 0);
1643 BOOST_CHECK(counterWMultiCoreDeviceWParentCategory->m_Interpolation == 1);
1644 BOOST_CHECK(counterWMultiCoreDeviceWParentCategory->m_Multiplier == 123.45f);
1645 BOOST_CHECK(counterWMultiCoreDeviceWParentCategory->m_Name == "valid name 10");
1646 BOOST_CHECK(counterWMultiCoreDeviceWParentCategory->m_Description == "valid description");
1647 BOOST_CHECK(counterWMultiCoreDeviceWParentCategory->m_Units == "");
1648 BOOST_CHECK(counterWMultiCoreDeviceWParentCategory->m_DeviceUid == 0);
1649 BOOST_CHECK(counterWMultiCoreDeviceWParentCategory->m_CounterSetUid == 0);
1650 BOOST_CHECK(category->m_Counters.size() == 26);
1651 for (size_t i = 0; i < 2; i ++)
1652 {
1653 BOOST_CHECK(category->m_Counters[category->m_Counters.size() - 2 + i] ==
1654 counterWMultiCoreDeviceWParentCategory->m_Uid + i);
1655 }
1656
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001657 // Register a counter set for testing
1658 const std::string counterSetName = "some_counter_set";
1659 const CounterSet* counterSet = nullptr;
1660 BOOST_CHECK_NO_THROW(counterSet = counterDirectory.RegisterCounterSet(counterSetName));
1661 BOOST_CHECK(counterDirectory.GetCounterSetCount() == 1);
1662 BOOST_CHECK(counterSet);
1663 BOOST_CHECK(counterSet->m_Name == counterSetName);
1664 BOOST_CHECK(counterSet->m_Uid >= 1);
1665 BOOST_CHECK(counterSet->m_Count == 0);
1666
1667 // Register a counter with a valid parent category name and associated to a counter set
1668 const Counter* counterWCounterSet = nullptr;
1669 BOOST_CHECK_NO_THROW(counterWCounterSet
1670 = counterDirectory.RegisterCounter(categoryName,
1671 0,
1672 1,
1673 123.45f,
Matteo Martincigh657ab2d2019-09-18 10:53:24 +01001674 "valid name 11",
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001675 "valid description",
1676 armnn::EmptyOptional(), // Units
Matteo Martincigh657ab2d2019-09-18 10:53:24 +01001677 0, // Number of cores
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001678 armnn::EmptyOptional(), // Device UID
1679 counterSet->m_Uid)); // Counter set UID
Matteo Martincigh657ab2d2019-09-18 10:53:24 +01001680 BOOST_CHECK(counterDirectory.GetCounterCount() == 27);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001681 BOOST_CHECK(counterWCounterSet);
1682 BOOST_CHECK(counterWCounterSet->m_Uid >= 0);
1683 BOOST_CHECK(counterWCounterSet->m_Uid > counter->m_Uid);
1684 BOOST_CHECK(counterWCounterSet->m_MaxCounterUid == counterWCounterSet->m_Uid);
1685 BOOST_CHECK(counterWCounterSet->m_Class == 0);
1686 BOOST_CHECK(counterWCounterSet->m_Interpolation == 1);
1687 BOOST_CHECK(counterWCounterSet->m_Multiplier == 123.45f);
Matteo Martincigh657ab2d2019-09-18 10:53:24 +01001688 BOOST_CHECK(counterWCounterSet->m_Name == "valid name 11");
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001689 BOOST_CHECK(counterWCounterSet->m_Description == "valid description");
1690 BOOST_CHECK(counterWCounterSet->m_Units == "");
1691 BOOST_CHECK(counterWCounterSet->m_DeviceUid == 0);
1692 BOOST_CHECK(counterWCounterSet->m_CounterSetUid == counterSet->m_Uid);
Matteo Martincigh657ab2d2019-09-18 10:53:24 +01001693 BOOST_CHECK(category->m_Counters.size() == 27);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001694 BOOST_CHECK(category->m_Counters.back() == counterWCounterSet->m_Uid);
1695
1696 // Register a counter with a valid parent category name and associated to a device and a counter set
1697 const Counter* counterWDeviceWCounterSet = nullptr;
1698 BOOST_CHECK_NO_THROW(counterWDeviceWCounterSet
1699 = counterDirectory.RegisterCounter(categoryName,
1700 0,
1701 1,
1702 123.45f,
Matteo Martincigh657ab2d2019-09-18 10:53:24 +01001703 "valid name 12",
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001704 "valid description",
1705 armnn::EmptyOptional(), // Units
Matteo Martincigh657ab2d2019-09-18 10:53:24 +01001706 1, // Number of cores
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001707 device->m_Uid, // Device UID
1708 counterSet->m_Uid)); // Counter set UID
Matteo Martincigh657ab2d2019-09-18 10:53:24 +01001709 BOOST_CHECK(counterDirectory.GetCounterCount() == 28);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001710 BOOST_CHECK(counterWDeviceWCounterSet);
1711 BOOST_CHECK(counterWDeviceWCounterSet->m_Uid >= 0);
1712 BOOST_CHECK(counterWDeviceWCounterSet->m_Uid > counter->m_Uid);
1713 BOOST_CHECK(counterWDeviceWCounterSet->m_MaxCounterUid == counterWDeviceWCounterSet->m_Uid);
1714 BOOST_CHECK(counterWDeviceWCounterSet->m_Class == 0);
1715 BOOST_CHECK(counterWDeviceWCounterSet->m_Interpolation == 1);
1716 BOOST_CHECK(counterWDeviceWCounterSet->m_Multiplier == 123.45f);
Matteo Martincigh657ab2d2019-09-18 10:53:24 +01001717 BOOST_CHECK(counterWDeviceWCounterSet->m_Name == "valid name 12");
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001718 BOOST_CHECK(counterWDeviceWCounterSet->m_Description == "valid description");
1719 BOOST_CHECK(counterWDeviceWCounterSet->m_Units == "");
1720 BOOST_CHECK(counterWDeviceWCounterSet->m_DeviceUid == device->m_Uid);
1721 BOOST_CHECK(counterWDeviceWCounterSet->m_CounterSetUid == counterSet->m_Uid);
Matteo Martincigh657ab2d2019-09-18 10:53:24 +01001722 BOOST_CHECK(category->m_Counters.size() == 28);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001723 BOOST_CHECK(category->m_Counters.back() == counterWDeviceWCounterSet->m_Uid);
1724
1725 // Register another category for testing
1726 const std::string anotherCategoryName = "some_other_category";
1727 const Category* anotherCategory = nullptr;
1728 BOOST_CHECK_NO_THROW(anotherCategory = counterDirectory.RegisterCategory(anotherCategoryName));
1729 BOOST_CHECK(counterDirectory.GetCategoryCount() == 2);
1730 BOOST_CHECK(anotherCategory);
1731 BOOST_CHECK(anotherCategory != category);
1732 BOOST_CHECK(anotherCategory->m_Name == anotherCategoryName);
1733 BOOST_CHECK(anotherCategory->m_Counters.empty());
1734 BOOST_CHECK(anotherCategory->m_DeviceUid == 0);
1735 BOOST_CHECK(anotherCategory->m_CounterSetUid == 0);
1736
1737 // Register a counter to the other category
1738 const Counter* anotherCounter = nullptr;
1739 BOOST_CHECK_NO_THROW(anotherCounter = counterDirectory.RegisterCounter(anotherCategoryName,
1740 1,
1741 0,
1742 .00043f,
1743 "valid name",
1744 "valid description",
1745 armnn::EmptyOptional(), // Units
1746 armnn::EmptyOptional(), // Number of cores
1747 device->m_Uid, // Device UID
1748 counterSet->m_Uid)); // Counter set UID
Matteo Martincigh657ab2d2019-09-18 10:53:24 +01001749 BOOST_CHECK(counterDirectory.GetCounterCount() == 29);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001750 BOOST_CHECK(anotherCounter);
1751 BOOST_CHECK(anotherCounter->m_Uid >= 0);
1752 BOOST_CHECK(anotherCounter->m_MaxCounterUid == anotherCounter->m_Uid);
1753 BOOST_CHECK(anotherCounter->m_Class == 1);
1754 BOOST_CHECK(anotherCounter->m_Interpolation == 0);
1755 BOOST_CHECK(anotherCounter->m_Multiplier == .00043f);
1756 BOOST_CHECK(anotherCounter->m_Name == "valid name");
1757 BOOST_CHECK(anotherCounter->m_Description == "valid description");
1758 BOOST_CHECK(anotherCounter->m_Units == "");
1759 BOOST_CHECK(anotherCounter->m_DeviceUid == device->m_Uid);
1760 BOOST_CHECK(anotherCounter->m_CounterSetUid == counterSet->m_Uid);
1761 BOOST_CHECK(anotherCategory->m_Counters.size() == 1);
1762 BOOST_CHECK(anotherCategory->m_Counters.back() == anotherCounter->m_Uid);
Matteo Martincighab173e92019-09-05 12:02:04 +01001763}
1764
Ferran Balaguer1b941722019-08-28 16:57:18 +01001765BOOST_AUTO_TEST_CASE(CounterSelectionCommandHandlerParseData)
1766{
1767 using boost::numeric_cast;
1768
1769 class TestCaptureThread : public IPeriodicCounterCapture
1770 {
1771 void Start() override {};
1772 };
1773
1774 const uint32_t packetId = 0x40000;
1775
1776 uint32_t version = 1;
1777 Holder holder;
1778 TestCaptureThread captureThread;
Matteo Martincigh24e8f922019-09-19 11:57:46 +01001779 MockProfilingConnection mockProfilingConnection;
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01001780 MockBufferManager mockBuffer(512);
Matteo Martincigh24e8f922019-09-19 11:57:46 +01001781 SendCounterPacket sendCounterPacket(mockProfilingConnection, mockBuffer);
Ferran Balaguer1b941722019-08-28 16:57:18 +01001782
1783 uint32_t sizeOfUint32 = numeric_cast<uint32_t>(sizeof(uint32_t));
1784 uint32_t sizeOfUint16 = numeric_cast<uint32_t>(sizeof(uint16_t));
1785
1786 // Data with period and counters
1787 uint32_t period1 = 10;
1788 uint32_t dataLength1 = 8;
Ferran Balaguer1b941722019-08-28 16:57:18 +01001789 uint32_t offset = 0;
1790
FinnWilliamsArma0c78712019-09-16 12:06:47 +01001791 std::unique_ptr<char[]> uniqueData1 = std::make_unique<char[]>(dataLength1);
1792 unsigned char* data1 = reinterpret_cast<unsigned char*>(uniqueData1.get());
1793
Ferran Balaguer1b941722019-08-28 16:57:18 +01001794 WriteUint32(data1, offset, period1);
1795 offset += sizeOfUint32;
1796 WriteUint16(data1, offset, 4000);
1797 offset += sizeOfUint16;
1798 WriteUint16(data1, offset, 5000);
1799
FinnWilliamsArma0c78712019-09-16 12:06:47 +01001800 Packet packetA(packetId, dataLength1, uniqueData1);
Ferran Balaguer1b941722019-08-28 16:57:18 +01001801
1802 PeriodicCounterSelectionCommandHandler commandHandler(packetId, version, holder, captureThread,
1803 sendCounterPacket);
1804 commandHandler(packetA);
1805
1806 std::vector<uint16_t> counterIds = holder.GetCaptureData().GetCounterIds();
1807
1808 BOOST_TEST(holder.GetCaptureData().GetCapturePeriod() == period1);
1809 BOOST_TEST(counterIds.size() == 2);
1810 BOOST_TEST(counterIds[0] == 4000);
1811 BOOST_TEST(counterIds[1] == 5000);
1812
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01001813 auto readBuffer = mockBuffer.GetReadableBuffer();
Ferran Balaguer1b941722019-08-28 16:57:18 +01001814
1815 offset = 0;
1816
1817 uint32_t headerWord0 = ReadUint32(readBuffer, offset);
1818 offset += sizeOfUint32;
1819 uint32_t headerWord1 = ReadUint32(readBuffer, offset);
1820 offset += sizeOfUint32;
1821 uint32_t period = ReadUint32(readBuffer, offset);
1822
1823 BOOST_TEST(((headerWord0 >> 26) & 0x3F) == 0); // packet family
1824 BOOST_TEST(((headerWord0 >> 16) & 0x3FF) == 4); // packet id
1825 BOOST_TEST(headerWord1 == 8); // data lenght
1826 BOOST_TEST(period == 10); // capture period
1827
1828 uint16_t counterId = 0;
1829 offset += sizeOfUint32;
1830 counterId = ReadUint16(readBuffer, offset);
1831 BOOST_TEST(counterId == 4000);
1832 offset += sizeOfUint16;
1833 counterId = ReadUint16(readBuffer, offset);
1834 BOOST_TEST(counterId == 5000);
1835
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01001836 mockBuffer.MarkRead(readBuffer);
1837
Ferran Balaguer1b941722019-08-28 16:57:18 +01001838 // Data with period only
1839 uint32_t period2 = 11;
1840 uint32_t dataLength2 = 4;
Ferran Balaguer1b941722019-08-28 16:57:18 +01001841
FinnWilliamsArma0c78712019-09-16 12:06:47 +01001842 std::unique_ptr<char[]> uniqueData2 = std::make_unique<char[]>(dataLength2);
Ferran Balaguer1b941722019-08-28 16:57:18 +01001843
FinnWilliamsArma0c78712019-09-16 12:06:47 +01001844 WriteUint32(reinterpret_cast<unsigned char*>(uniqueData2.get()), 0, period2);
1845
1846 Packet packetB(packetId, dataLength2, uniqueData2);
Ferran Balaguer1b941722019-08-28 16:57:18 +01001847
1848 commandHandler(packetB);
1849
1850 counterIds = holder.GetCaptureData().GetCounterIds();
1851
1852 BOOST_TEST(holder.GetCaptureData().GetCapturePeriod() == period2);
1853 BOOST_TEST(counterIds.size() == 0);
1854
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01001855 readBuffer = mockBuffer.GetReadableBuffer();
Ferran Balaguer1b941722019-08-28 16:57:18 +01001856
1857 offset = 0;
1858
1859 headerWord0 = ReadUint32(readBuffer, offset);
1860 offset += sizeOfUint32;
1861 headerWord1 = ReadUint32(readBuffer, offset);
1862 offset += sizeOfUint32;
1863 period = ReadUint32(readBuffer, offset);
1864
1865 BOOST_TEST(((headerWord0 >> 26) & 0x3F) == 0); // packet family
1866 BOOST_TEST(((headerWord0 >> 16) & 0x3FF) == 4); // packet id
1867 BOOST_TEST(headerWord1 == 4); // data lenght
1868 BOOST_TEST(period == 11); // capture period
Ferran Balaguer1b941722019-08-28 16:57:18 +01001869}
1870
Sadik Armaganb5f01b22019-09-18 17:29:00 +01001871BOOST_AUTO_TEST_CASE(CheckConnectionAcknowledged)
1872{
1873 using boost::numeric_cast;
1874
1875 const uint32_t connectionPacketId = 0x10000;
1876 const uint32_t version = 1;
1877
1878 uint32_t sizeOfUint32 = numeric_cast<uint32_t>(sizeof(uint32_t));
1879 uint32_t sizeOfUint16 = numeric_cast<uint32_t>(sizeof(uint16_t));
1880
1881 // Data with period and counters
1882 uint32_t period1 = 10;
1883 uint32_t dataLength1 = 8;
1884 uint32_t offset = 0;
1885
1886 std::unique_ptr<char[]> uniqueData1 = std::make_unique<char[]>(dataLength1);
1887 unsigned char* data1 = reinterpret_cast<unsigned char*>(uniqueData1.get());
1888
1889 WriteUint32(data1, offset, period1);
1890 offset += sizeOfUint32;
1891 WriteUint16(data1, offset, 4000);
1892 offset += sizeOfUint16;
1893 WriteUint16(data1, offset, 5000);
1894
1895 Packet packetA(connectionPacketId, dataLength1, uniqueData1);
1896
1897 ProfilingStateMachine profilingState(ProfilingState::Uninitialised);
1898 BOOST_CHECK(profilingState.GetCurrentState() == ProfilingState::Uninitialised);
1899
1900 ConnectionAcknowledgedCommandHandler commandHandler(connectionPacketId, version, profilingState);
1901
1902 // command handler received packet on ProfilingState::Uninitialised
1903 BOOST_CHECK_THROW(commandHandler(packetA), armnn::Exception);
1904
1905 profilingState.TransitionToState(ProfilingState::NotConnected);
1906 BOOST_CHECK(profilingState.GetCurrentState() == ProfilingState::NotConnected);
1907 // command handler received packet on ProfilingState::NotConnected
1908 BOOST_CHECK_THROW(commandHandler(packetA), armnn::Exception);
1909
1910 profilingState.TransitionToState(ProfilingState::WaitingForAck);
1911 BOOST_CHECK(profilingState.GetCurrentState() == ProfilingState::WaitingForAck);
1912 // command handler received packet on ProfilingState::WaitingForAck
1913 commandHandler(packetA);
1914 BOOST_CHECK(profilingState.GetCurrentState() == ProfilingState::Active);
1915
1916 // command handler received packet on ProfilingState::Active
1917 commandHandler(packetA);
1918 BOOST_CHECK(profilingState.GetCurrentState() == ProfilingState::Active);
1919
1920 // command handler received different packet
1921 const uint32_t differentPacketId = 0x40000;
1922 Packet packetB(differentPacketId, dataLength1, uniqueData1);
1923 ConnectionAcknowledgedCommandHandler differentCommandHandler(differentPacketId, version, profilingState);
1924 BOOST_CHECK_THROW(differentCommandHandler(packetB), armnn::Exception);
1925}
1926
Teresa Charlin9bab4962019-09-06 12:28:35 +01001927BOOST_AUTO_TEST_CASE(CheckSocketProfilingConnection)
1928{
1929 // Check that creating a SocketProfilingConnection results in an exception as the Gator UDS doesn't exist.
1930 BOOST_CHECK_THROW(new SocketProfilingConnection(), armnn::Exception);
1931}
1932
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001933BOOST_AUTO_TEST_CASE(SwTraceIsValidCharTest)
1934{
1935 // Only ASCII 7-bit encoding supported
1936 for (unsigned char c = 0; c < 128; c++)
1937 {
1938 BOOST_CHECK(SwTraceCharPolicy::IsValidChar(c));
1939 }
1940
1941 // Not ASCII
1942 for (unsigned char c = 255; c >= 128; c++)
1943 {
1944 BOOST_CHECK(!SwTraceCharPolicy::IsValidChar(c));
1945 }
1946}
1947
1948BOOST_AUTO_TEST_CASE(SwTraceIsValidNameCharTest)
1949{
1950 // Only alpha-numeric and underscore ASCII 7-bit encoding supported
1951 const unsigned char validChars[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_";
1952 for (unsigned char i = 0; i < sizeof(validChars) / sizeof(validChars[0]) - 1; i++)
1953 {
1954 BOOST_CHECK(SwTraceNameCharPolicy::IsValidChar(validChars[i]));
1955 }
1956
1957 // Non alpha-numeric chars
1958 for (unsigned char c = 0; c < 48; c++)
1959 {
1960 BOOST_CHECK(!SwTraceNameCharPolicy::IsValidChar(c));
1961 }
1962 for (unsigned char c = 58; c < 65; c++)
1963 {
1964 BOOST_CHECK(!SwTraceNameCharPolicy::IsValidChar(c));
1965 }
1966 for (unsigned char c = 91; c < 95; c++)
1967 {
1968 BOOST_CHECK(!SwTraceNameCharPolicy::IsValidChar(c));
1969 }
1970 for (unsigned char c = 96; c < 97; c++)
1971 {
1972 BOOST_CHECK(!SwTraceNameCharPolicy::IsValidChar(c));
1973 }
1974 for (unsigned char c = 123; c < 128; c++)
1975 {
1976 BOOST_CHECK(!SwTraceNameCharPolicy::IsValidChar(c));
1977 }
1978
1979 // Not ASCII
1980 for (unsigned char c = 255; c >= 128; c++)
1981 {
1982 BOOST_CHECK(!SwTraceNameCharPolicy::IsValidChar(c));
1983 }
1984}
1985
1986BOOST_AUTO_TEST_CASE(IsValidSwTraceStringTest)
1987{
1988 // Valid SWTrace strings
1989 BOOST_CHECK(IsValidSwTraceString<SwTraceCharPolicy>(""));
1990 BOOST_CHECK(IsValidSwTraceString<SwTraceCharPolicy>("_"));
1991 BOOST_CHECK(IsValidSwTraceString<SwTraceCharPolicy>("0123"));
1992 BOOST_CHECK(IsValidSwTraceString<SwTraceCharPolicy>("valid_string"));
1993 BOOST_CHECK(IsValidSwTraceString<SwTraceCharPolicy>("VALID_string_456"));
1994 BOOST_CHECK(IsValidSwTraceString<SwTraceCharPolicy>(" "));
1995 BOOST_CHECK(IsValidSwTraceString<SwTraceCharPolicy>("valid string"));
1996 BOOST_CHECK(IsValidSwTraceString<SwTraceCharPolicy>("!$%"));
1997 BOOST_CHECK(IsValidSwTraceString<SwTraceCharPolicy>("valid|\\~string#123"));
1998
1999 // Invalid SWTrace strings
2000 BOOST_CHECK(!IsValidSwTraceString<SwTraceCharPolicy>("€£"));
2001 BOOST_CHECK(!IsValidSwTraceString<SwTraceCharPolicy>("invalid‡string"));
2002 BOOST_CHECK(!IsValidSwTraceString<SwTraceCharPolicy>("12Ž34"));
2003}
2004
2005BOOST_AUTO_TEST_CASE(IsValidSwTraceNameStringTest)
2006{
2007 // Valid SWTrace name strings
2008 BOOST_CHECK(IsValidSwTraceString<SwTraceNameCharPolicy>(""));
2009 BOOST_CHECK(IsValidSwTraceString<SwTraceNameCharPolicy>("_"));
2010 BOOST_CHECK(IsValidSwTraceString<SwTraceNameCharPolicy>("0123"));
2011 BOOST_CHECK(IsValidSwTraceString<SwTraceNameCharPolicy>("valid_string"));
2012 BOOST_CHECK(IsValidSwTraceString<SwTraceNameCharPolicy>("VALID_string_456"));
2013
2014 // Invalid SWTrace name strings
2015 BOOST_CHECK(!IsValidSwTraceString<SwTraceNameCharPolicy>(" "));
2016 BOOST_CHECK(!IsValidSwTraceString<SwTraceNameCharPolicy>("invalid string"));
2017 BOOST_CHECK(!IsValidSwTraceString<SwTraceNameCharPolicy>("!$%"));
2018 BOOST_CHECK(!IsValidSwTraceString<SwTraceNameCharPolicy>("invalid|\\~string#123"));
2019 BOOST_CHECK(!IsValidSwTraceString<SwTraceNameCharPolicy>("€£"));
2020 BOOST_CHECK(!IsValidSwTraceString<SwTraceNameCharPolicy>("invalid‡string"));
2021 BOOST_CHECK(!IsValidSwTraceString<SwTraceNameCharPolicy>("12Ž34"));
2022}
2023
2024template <typename SwTracePolicy>
2025void StringToSwTraceStringTestHelper(const std::string& testString, std::vector<uint32_t> buffer, size_t expectedSize)
2026{
2027 // Convert the test string to a SWTrace string
2028 BOOST_CHECK(StringToSwTraceString<SwTracePolicy>(testString, buffer));
2029
2030 // The buffer must contain at least the length of the string
2031 BOOST_CHECK(!buffer.empty());
2032
2033 // The buffer must be of the expected size (in words)
2034 BOOST_CHECK(buffer.size() == expectedSize);
2035
2036 // The first word of the byte must be the length of the string including the null-terminator
2037 BOOST_CHECK(buffer[0] == testString.size() + 1);
2038
2039 // The contents of the buffer must match the test string
2040 BOOST_CHECK(std::memcmp(testString.data(), buffer.data() + 1, testString.size()) == 0);
2041
2042 // The buffer must include the null-terminator at the end of the string
2043 size_t nullTerminatorIndex = sizeof(uint32_t) + testString.size();
2044 BOOST_CHECK(reinterpret_cast<unsigned char*>(buffer.data())[nullTerminatorIndex] == '\0');
2045}
2046
2047BOOST_AUTO_TEST_CASE(StringToSwTraceStringTest)
2048{
2049 std::vector<uint32_t> buffer;
2050
2051 // Valid SWTrace strings (expected size in words)
2052 StringToSwTraceStringTestHelper<SwTraceCharPolicy>("", buffer, 2);
2053 StringToSwTraceStringTestHelper<SwTraceCharPolicy>("_", buffer, 2);
2054 StringToSwTraceStringTestHelper<SwTraceCharPolicy>("0123", buffer, 3);
2055 StringToSwTraceStringTestHelper<SwTraceCharPolicy>("valid_string", buffer, 5);
2056 StringToSwTraceStringTestHelper<SwTraceCharPolicy>("VALID_string_456", buffer, 6);
2057 StringToSwTraceStringTestHelper<SwTraceCharPolicy>(" ", buffer, 2);
2058 StringToSwTraceStringTestHelper<SwTraceCharPolicy>("valid string", buffer, 5);
2059 StringToSwTraceStringTestHelper<SwTraceCharPolicy>("!$%", buffer, 2);
2060 StringToSwTraceStringTestHelper<SwTraceCharPolicy>("valid|\\~string#123", buffer, 6);
2061
2062 // Invalid SWTrace strings
2063 BOOST_CHECK(!StringToSwTraceString<SwTraceCharPolicy>("€£", buffer));
2064 BOOST_CHECK(buffer.empty());
2065 BOOST_CHECK(!StringToSwTraceString<SwTraceCharPolicy>("invalid‡string", buffer));
2066 BOOST_CHECK(buffer.empty());
2067 BOOST_CHECK(!StringToSwTraceString<SwTraceCharPolicy>("12Ž34", buffer));
2068 BOOST_CHECK(buffer.empty());
2069}
2070
2071BOOST_AUTO_TEST_CASE(StringToSwTraceNameStringTest)
2072{
2073 std::vector<uint32_t> buffer;
2074
2075 // Valid SWTrace namestrings (expected size in words)
2076 StringToSwTraceStringTestHelper<SwTraceNameCharPolicy>("", buffer, 2);
2077 StringToSwTraceStringTestHelper<SwTraceNameCharPolicy>("_", buffer, 2);
2078 StringToSwTraceStringTestHelper<SwTraceNameCharPolicy>("0123", buffer, 3);
2079 StringToSwTraceStringTestHelper<SwTraceNameCharPolicy>("valid_string", buffer, 5);
2080 StringToSwTraceStringTestHelper<SwTraceNameCharPolicy>("VALID_string_456", buffer, 6);
2081
2082 // Invalid SWTrace namestrings
2083 BOOST_CHECK(!StringToSwTraceString<SwTraceNameCharPolicy>(" ", buffer));
2084 BOOST_CHECK(buffer.empty());
2085 BOOST_CHECK(!StringToSwTraceString<SwTraceNameCharPolicy>("invalid string", buffer));
2086 BOOST_CHECK(buffer.empty());
2087 BOOST_CHECK(!StringToSwTraceString<SwTraceNameCharPolicy>("!$%", buffer));
2088 BOOST_CHECK(buffer.empty());
2089 BOOST_CHECK(!StringToSwTraceString<SwTraceNameCharPolicy>("invalid|\\~string#123", buffer));
2090 BOOST_CHECK(buffer.empty());
2091 BOOST_CHECK(!StringToSwTraceString<SwTraceNameCharPolicy>("€£", buffer));
2092 BOOST_CHECK(buffer.empty());
2093 BOOST_CHECK(!StringToSwTraceString<SwTraceNameCharPolicy>("invalid‡string", buffer));
2094 BOOST_CHECK(buffer.empty());
2095 BOOST_CHECK(!StringToSwTraceString<SwTraceNameCharPolicy>("12Ž34", buffer));
2096 BOOST_CHECK(buffer.empty());
2097}
2098
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002099BOOST_AUTO_TEST_CASE(CheckPeriodicCounterCaptureThread)
2100{
2101 class CaptureReader : public IReadCounterValue
2102 {
2103 public:
2104 CaptureReader() {}
2105
2106 void GetCounterValue(uint16_t index, uint32_t &value) const override
2107 {
2108 if (m_Data.count(index))
2109 {
2110 value = m_Data.at(index);
2111 }
2112 else
2113 {
2114 value = 0;
2115 }
2116 }
2117
2118 void SetCounterValue(uint16_t index, uint32_t value)
2119 {
2120 if (!m_Data.count(index))
2121 {
2122 m_Data.insert(std::pair<uint16_t, uint32_t>(index, value));
2123 }
2124 else
2125 {
2126 m_Data.at(index) = value;
2127 }
2128 }
2129
2130 private:
2131 std::map<uint16_t, uint32_t> m_Data;
2132 };
2133
2134 Holder data;
2135 std::vector<uint16_t> captureIds1 = { 0, 1 };
2136 std::vector<uint16_t> captureIds2;
2137
Matteo Martincigh24e8f922019-09-19 11:57:46 +01002138 MockProfilingConnection mockProfilingConnection;
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01002139 MockBufferManager mockBuffer(512);
Matteo Martincigh24e8f922019-09-19 11:57:46 +01002140 SendCounterPacket sendCounterPacket(mockProfilingConnection, mockBuffer);
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002141
2142 std::vector<uint16_t> counterIds;
2143 CaptureReader captureReader;
2144
2145 unsigned int valueA = 10;
2146 unsigned int valueB = 15;
2147 unsigned int numSteps = 5;
2148
2149 PeriodicCounterCapture periodicCounterCapture(std::ref(data), std::ref(sendCounterPacket), captureReader);
2150
2151 for(unsigned int i = 0; i < numSteps; ++i)
2152 {
2153 data.SetCaptureData(1, captureIds1);
2154 captureReader.SetCounterValue(0, valueA * (i + 1));
2155 captureReader.SetCounterValue(1, valueB * (i + 1));
2156
2157 periodicCounterCapture.Start();
2158
2159 std::this_thread::sleep_for(std::chrono::milliseconds(200));
2160
2161 periodicCounterCapture.Start();
2162
2163 data.SetCaptureData(0, captureIds2);
2164
2165 periodicCounterCapture.Start();
2166 }
2167
2168 periodicCounterCapture.Join();
2169
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01002170 auto buffer = mockBuffer.GetReadableBuffer();
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01002171
2172 uint32_t headerWord0 = ReadUint32(buffer, 0);
2173 uint32_t headerWord1 = ReadUint32(buffer, 4);
2174
2175 BOOST_TEST(((headerWord0 >> 26) & 0x3F) == 1); // packet family
2176 BOOST_TEST(((headerWord0 >> 19) & 0x3F) == 0); // packet class
2177 BOOST_TEST(((headerWord0 >> 16) & 0x3) == 0); // packet type
2178 BOOST_TEST(headerWord1 == 20); // data length
2179
2180 uint32_t offset = 16;
2181 uint16_t readIndex = ReadUint16(buffer, offset);
2182 BOOST_TEST(0 == readIndex);
2183
2184 offset += 2;
2185 uint32_t readValue = ReadUint32(buffer, offset);
2186 BOOST_TEST((valueA * numSteps) == readValue);
2187
2188 offset += 4;
2189 readIndex = ReadUint16(buffer, offset);
2190 BOOST_TEST(1 == readIndex);
2191
2192 offset += 2;
2193 readValue = ReadUint32(buffer, offset);
2194 BOOST_TEST((valueB * numSteps) == readValue);
2195}
2196
Narumol Prangnawarat48033692019-09-20 12:04:55 +01002197BOOST_AUTO_TEST_CASE(RequestCounterDirectoryCommandHandlerTest0)
2198{
2199 using boost::numeric_cast;
2200
2201 const uint32_t packetId = 0x30000;
2202 const uint32_t version = 1;
2203
2204 std::unique_ptr<char[]> packetData;
2205
2206 Packet packetA(packetId, 0, packetData);
2207
Matteo Martincigh24e8f922019-09-19 11:57:46 +01002208 MockProfilingConnection mockProfilingConnection;
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01002209 MockBufferManager mockBuffer(1024);
Matteo Martincigh24e8f922019-09-19 11:57:46 +01002210 SendCounterPacket sendCounterPacket(mockProfilingConnection, mockBuffer);
Narumol Prangnawarat48033692019-09-20 12:04:55 +01002211
2212 CounterDirectory counterDirectory;
2213
2214 RequestCounterDirectoryCommandHandler commandHandler(packetId, version, counterDirectory, sendCounterPacket);
2215 commandHandler(packetA);
2216
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01002217 auto readBuffer = mockBuffer.GetReadableBuffer();
Narumol Prangnawarat48033692019-09-20 12:04:55 +01002218
2219 uint32_t headerWord0 = ReadUint32(readBuffer, 0);
2220 uint32_t headerWord1 = ReadUint32(readBuffer, 4);
2221
2222 BOOST_TEST(((headerWord0 >> 26) & 0x3F) == 0); // packet family
2223 BOOST_TEST(((headerWord0 >> 16) & 0x3FF) == 2); // packet id
Matteo Martincighf74ff2f2019-09-24 11:38:32 +01002224 BOOST_TEST(headerWord1 == 24); // data length
Narumol Prangnawarat48033692019-09-20 12:04:55 +01002225
2226 uint32_t bodyHeaderWord0 = ReadUint32(readBuffer, 8);
2227 uint16_t deviceRecordCount = numeric_cast<uint16_t>(bodyHeaderWord0 >> 16);
2228 BOOST_TEST(deviceRecordCount == 0); // device_records_count
2229}
2230
2231BOOST_AUTO_TEST_CASE(RequestCounterDirectoryCommandHandlerTest1)
2232{
2233 using boost::numeric_cast;
2234
2235 const uint32_t packetId = 0x30000;
2236 const uint32_t version = 1;
2237
2238 std::unique_ptr<char[]> packetData;
2239
2240 Packet packetA(packetId, 0, packetData);
2241
Matteo Martincigh24e8f922019-09-19 11:57:46 +01002242 MockProfilingConnection mockProfilingConnection;
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01002243 MockBufferManager mockBuffer(1024);
Matteo Martincigh24e8f922019-09-19 11:57:46 +01002244 SendCounterPacket sendCounterPacket(mockProfilingConnection, mockBuffer);
Narumol Prangnawarat48033692019-09-20 12:04:55 +01002245
2246 CounterDirectory counterDirectory;
2247 const Device* device = counterDirectory.RegisterDevice("deviceA", 1);
2248 const CounterSet* counterSet = counterDirectory.RegisterCounterSet("countersetA");
2249 counterDirectory.RegisterCategory("categoryA", device->m_Uid, counterSet->m_Uid);
2250 counterDirectory.RegisterCounter("categoryA", 0, 1, 2.0f, "counterA", "descA");
2251 counterDirectory.RegisterCounter("categoryA", 1, 1, 3.0f, "counterB", "descB");
2252
2253 RequestCounterDirectoryCommandHandler commandHandler(packetId, version, counterDirectory, sendCounterPacket);
2254 commandHandler(packetA);
2255
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01002256 auto readBuffer = mockBuffer.GetReadableBuffer();
Narumol Prangnawarat48033692019-09-20 12:04:55 +01002257
2258 uint32_t headerWord0 = ReadUint32(readBuffer, 0);
2259 uint32_t headerWord1 = ReadUint32(readBuffer, 4);
2260
2261 BOOST_TEST(((headerWord0 >> 26) & 0x3F) == 0); // packet family
2262 BOOST_TEST(((headerWord0 >> 16) & 0x3FF) == 2); // packet id
Matteo Martincighf74ff2f2019-09-24 11:38:32 +01002263 BOOST_TEST(headerWord1 == 240); // data length
Narumol Prangnawarat48033692019-09-20 12:04:55 +01002264
2265 uint32_t bodyHeaderWord0 = ReadUint32(readBuffer, 8);
2266 uint32_t bodyHeaderWord1 = ReadUint32(readBuffer, 12);
2267 uint32_t bodyHeaderWord2 = ReadUint32(readBuffer, 16);
2268 uint32_t bodyHeaderWord3 = ReadUint32(readBuffer, 20);
2269 uint32_t bodyHeaderWord4 = ReadUint32(readBuffer, 24);
2270 uint32_t bodyHeaderWord5 = ReadUint32(readBuffer, 28);
2271 uint16_t deviceRecordCount = numeric_cast<uint16_t>(bodyHeaderWord0 >> 16);
2272 uint16_t counterSetRecordCount = numeric_cast<uint16_t>(bodyHeaderWord2 >> 16);
2273 uint16_t categoryRecordCount = numeric_cast<uint16_t>(bodyHeaderWord4 >> 16);
2274 BOOST_TEST(deviceRecordCount == 1); // device_records_count
2275 BOOST_TEST(bodyHeaderWord1 == 0); // device_records_pointer_table_offset
2276 BOOST_TEST(counterSetRecordCount == 1); // counter_set_count
2277 BOOST_TEST(bodyHeaderWord3 == 4); // counter_set_pointer_table_offset
2278 BOOST_TEST(categoryRecordCount == 1); // categories_count
2279 BOOST_TEST(bodyHeaderWord5 == 8); // categories_pointer_table_offset
2280
2281 uint32_t deviceRecordOffset = ReadUint32(readBuffer, 32);
2282 BOOST_TEST(deviceRecordOffset == 0);
2283
2284 uint32_t counterSetRecordOffset = ReadUint32(readBuffer, 36);
2285 BOOST_TEST(counterSetRecordOffset == 20);
2286
2287 uint32_t categoryRecordOffset = ReadUint32(readBuffer, 40);
2288 BOOST_TEST(categoryRecordOffset == 44);
2289}
2290
Francis Murtagh1f7db452019-08-14 09:49:34 +01002291BOOST_AUTO_TEST_SUITE_END()