blob: 2a20aac8a42ab3cfdd05404d02dcbbb266353fc7 [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"
Teresa Charlin9bab4962019-09-06 12:28:35 +01007
Matteo Martincigh6db5f202019-09-05 12:02:04 +01008#include <CommandHandlerKey.hpp>
9#include <CommandHandlerFunctor.hpp>
10#include <CommandHandlerRegistry.hpp>
Sadik Armaganb5f01b22019-09-18 17:29:00 +010011#include <ConnectionAcknowledgedCommandHandler.hpp>
Matteo Martincigh6db5f202019-09-05 12:02:04 +010012#include <CounterDirectory.hpp>
13#include <EncodeVersion.hpp>
14#include <Holder.hpp>
15#include <Packet.hpp>
16#include <PacketVersionResolver.hpp>
Francis Murtaghfcb8ef62019-09-20 15:40:09 +010017#include <PeriodicCounterCapture.hpp>
Matteo Martincigh6db5f202019-09-05 12:02:04 +010018#include <PeriodicCounterSelectionCommandHandler.hpp>
19#include <ProfilingStateMachine.hpp>
20#include <ProfilingService.hpp>
21#include <ProfilingUtils.hpp>
Narumol Prangnawarat48033692019-09-20 12:04:55 +010022#include <RequestCounterDirectoryCommandHandler.hpp>
Teresa Charlin9bab4962019-09-06 12:28:35 +010023#include <Runtime.hpp>
Matteo Martincigh6db5f202019-09-05 12:02:04 +010024#include <SocketProfilingConnection.hpp>
Francis Murtaghfcb8ef62019-09-20 15:40:09 +010025#include <IReadCounterValue.hpp>
Keith Davis02356de2019-08-26 18:28:17 +010026
Matteo Martincigh6db5f202019-09-05 12:02:04 +010027#include <armnn/Conversion.hpp>
Ferran Balaguer1b941722019-08-28 16:57:18 +010028
Aron Virginas-Tare898db92019-08-22 12:56:34 +010029#include <boost/test/unit_test.hpp>
Ferran Balaguer1b941722019-08-28 16:57:18 +010030#include <boost/numeric/conversion/cast.hpp>
Francis Murtagh1f7db452019-08-14 09:49:34 +010031
Nikhil Rajbc626052019-08-15 15:49:45 +010032#include <cstdint>
33#include <cstring>
Aron Virginas-Tare898db92019-08-22 12:56:34 +010034#include <limits>
Francis Murtagh11f99b42019-08-16 11:28:52 +010035#include <map>
Aron Virginas-Tare898db92019-08-22 12:56:34 +010036#include <random>
Nikhil Raj3ecc5102019-09-03 15:55:33 +010037#include <thread>
Francis Murtagh1f7db452019-08-14 09:49:34 +010038
39BOOST_AUTO_TEST_SUITE(ExternalProfiling)
40
Aron Virginas-Tare898db92019-08-22 12:56:34 +010041using namespace armnn::profiling;
42
Francis Murtagh1f7db452019-08-14 09:49:34 +010043BOOST_AUTO_TEST_CASE(CheckCommandHandlerKeyComparisons)
44{
45 CommandHandlerKey testKey0(1, 1);
46 CommandHandlerKey testKey1(1, 1);
47 CommandHandlerKey testKey2(1, 1);
48 CommandHandlerKey testKey3(0, 0);
49 CommandHandlerKey testKey4(2, 2);
50 CommandHandlerKey testKey5(0, 2);
51
52 BOOST_CHECK(testKey1<testKey4);
53 BOOST_CHECK(testKey1>testKey3);
54 BOOST_CHECK(testKey1<=testKey4);
55 BOOST_CHECK(testKey1>=testKey3);
56 BOOST_CHECK(testKey1<=testKey2);
57 BOOST_CHECK(testKey1>=testKey2);
58 BOOST_CHECK(testKey1==testKey2);
59 BOOST_CHECK(testKey1==testKey1);
60
61 BOOST_CHECK(!(testKey1==testKey5));
62 BOOST_CHECK(!(testKey1!=testKey1));
63 BOOST_CHECK(testKey1!=testKey5);
64
65 BOOST_CHECK(testKey1==testKey2 && testKey2==testKey1);
66 BOOST_CHECK(testKey0==testKey1 && testKey1==testKey2 && testKey0==testKey2);
67
68 BOOST_CHECK(testKey1.GetPacketId()==1);
69 BOOST_CHECK(testKey1.GetVersion()==1);
70
71 std::vector<CommandHandlerKey> vect =
Aron Virginas-Tare898db92019-08-22 12:56:34 +010072 {
73 CommandHandlerKey(0,1), CommandHandlerKey(2,0), CommandHandlerKey(1,0),
74 CommandHandlerKey(2,1), CommandHandlerKey(1,1), CommandHandlerKey(0,1),
75 CommandHandlerKey(2,0), CommandHandlerKey(0,0)
76 };
Francis Murtagh1f7db452019-08-14 09:49:34 +010077
78 std::sort(vect.begin(), vect.end());
79
80 std::vector<CommandHandlerKey> expectedVect =
Aron Virginas-Tare898db92019-08-22 12:56:34 +010081 {
82 CommandHandlerKey(0,0), CommandHandlerKey(0,1), CommandHandlerKey(0,1),
83 CommandHandlerKey(1,0), CommandHandlerKey(1,1), CommandHandlerKey(2,0),
84 CommandHandlerKey(2,0), CommandHandlerKey(2,1)
85 };
Francis Murtagh1f7db452019-08-14 09:49:34 +010086
87 BOOST_CHECK(vect == expectedVect);
88}
89
Nikhil Rajd88e47c2019-08-19 10:04:23 +010090BOOST_AUTO_TEST_CASE(CheckEncodeVersion)
91{
Aron Virginas-Tare898db92019-08-22 12:56:34 +010092 Version version1(12);
Nikhil Rajd88e47c2019-08-19 10:04:23 +010093
94 BOOST_CHECK(version1.GetMajor() == 0);
95 BOOST_CHECK(version1.GetMinor() == 0);
96 BOOST_CHECK(version1.GetPatch() == 12);
97
Aron Virginas-Tare898db92019-08-22 12:56:34 +010098 Version version2(4108);
Nikhil Rajd88e47c2019-08-19 10:04:23 +010099
100 BOOST_CHECK(version2.GetMajor() == 0);
101 BOOST_CHECK(version2.GetMinor() == 1);
102 BOOST_CHECK(version2.GetPatch() == 12);
103
Aron Virginas-Tare898db92019-08-22 12:56:34 +0100104 Version version3(4198412);
Nikhil Rajd88e47c2019-08-19 10:04:23 +0100105
106 BOOST_CHECK(version3.GetMajor() == 1);
107 BOOST_CHECK(version3.GetMinor() == 1);
108 BOOST_CHECK(version3.GetPatch() == 12);
109
Aron Virginas-Tare898db92019-08-22 12:56:34 +0100110 Version version4(0);
Nikhil Rajd88e47c2019-08-19 10:04:23 +0100111
112 BOOST_CHECK(version4.GetMajor() == 0);
113 BOOST_CHECK(version4.GetMinor() == 0);
114 BOOST_CHECK(version4.GetPatch() == 0);
115
Aron Virginas-Tare898db92019-08-22 12:56:34 +0100116 Version version5(1, 0, 0);
Nikhil Rajd88e47c2019-08-19 10:04:23 +0100117 BOOST_CHECK(version5.GetEncodedValue() == 4194304);
118}
119
Nikhil Rajbc626052019-08-15 15:49:45 +0100120BOOST_AUTO_TEST_CASE(CheckPacketClass)
121{
FinnWilliamsArma0c78712019-09-16 12:06:47 +0100122 uint32_t length = 4;
123 std::unique_ptr<char[]> packetData0 = std::make_unique<char[]>(length);
124 std::unique_ptr<char[]> packetData1 = std::make_unique<char[]>(0);
125 std::unique_ptr<char[]> nullPacketData;
Nikhil Rajbc626052019-08-15 15:49:45 +0100126
FinnWilliamsArma0c78712019-09-16 12:06:47 +0100127 Packet packetTest0(472580096, length, packetData0);
Nikhil Rajbc626052019-08-15 15:49:45 +0100128
FinnWilliamsArma0c78712019-09-16 12:06:47 +0100129 BOOST_CHECK(packetTest0.GetHeader() == 472580096);
130 BOOST_CHECK(packetTest0.GetPacketFamily() == 7);
131 BOOST_CHECK(packetTest0.GetPacketId() == 43);
132 BOOST_CHECK(packetTest0.GetLength() == length);
133 BOOST_CHECK(packetTest0.GetPacketType() == 3);
134 BOOST_CHECK(packetTest0.GetPacketClass() == 5);
Nikhil Rajbc626052019-08-15 15:49:45 +0100135
FinnWilliamsArma0c78712019-09-16 12:06:47 +0100136 BOOST_CHECK_THROW(Packet packetTest1(472580096, 0, packetData1), armnn::Exception);
137 BOOST_CHECK_NO_THROW(Packet packetTest2(472580096, 0, nullPacketData));
Nikhil Rajbc626052019-08-15 15:49:45 +0100138
FinnWilliamsArma0c78712019-09-16 12:06:47 +0100139 Packet packetTest3(472580096, 0, nullPacketData);
140 BOOST_CHECK(packetTest3.GetLength() == 0);
141 BOOST_CHECK(packetTest3.GetData() == nullptr);
142
143 const char* packetTest0Data = packetTest0.GetData();
144 Packet packetTest4(std::move(packetTest0));
145
146 BOOST_CHECK(packetTest0.GetData() == nullptr);
147 BOOST_CHECK(packetTest4.GetData() == packetTest0Data);
148
149 BOOST_CHECK(packetTest4.GetHeader() == 472580096);
150 BOOST_CHECK(packetTest4.GetPacketFamily() == 7);
151 BOOST_CHECK(packetTest4.GetPacketId() == 43);
152 BOOST_CHECK(packetTest4.GetLength() == length);
153 BOOST_CHECK(packetTest4.GetPacketType() == 3);
154 BOOST_CHECK(packetTest4.GetPacketClass() == 5);
Nikhil Rajbc626052019-08-15 15:49:45 +0100155}
156
Francis Murtagh94d79152019-08-16 17:45:07 +0100157// Create Derived Classes
158class TestFunctorA : public CommandHandlerFunctor
159{
160public:
161 using CommandHandlerFunctor::CommandHandlerFunctor;
162
163 int GetCount() { return m_Count; }
164
165 void operator()(const Packet& packet) override
166 {
167 m_Count++;
168 }
169
170private:
171 int m_Count = 0;
172};
173
174class TestFunctorB : public TestFunctorA
175{
176 using TestFunctorA::TestFunctorA;
177};
178
179class TestFunctorC : public TestFunctorA
180{
181 using TestFunctorA::TestFunctorA;
182};
183
Francis Murtagh11f99b42019-08-16 11:28:52 +0100184BOOST_AUTO_TEST_CASE(CheckCommandHandlerFunctor)
185{
Francis Murtagh11f99b42019-08-16 11:28:52 +0100186 // Hard code the version as it will be the same during a single profiling session
187 uint32_t version = 1;
188
189 TestFunctorA testFunctorA(461, version);
190 TestFunctorB testFunctorB(963, version);
191 TestFunctorC testFunctorC(983, version);
192
193 CommandHandlerKey keyA(testFunctorA.GetPacketId(), testFunctorA.GetVersion());
194 CommandHandlerKey keyB(testFunctorB.GetPacketId(), testFunctorB.GetVersion());
195 CommandHandlerKey keyC(testFunctorC.GetPacketId(), testFunctorC.GetVersion());
196
197 // Create the unwrapped map to simulate the Command Handler Registry
198 std::map<CommandHandlerKey, CommandHandlerFunctor*> registry;
199
200 registry.insert(std::make_pair(keyB, &testFunctorB));
201 registry.insert(std::make_pair(keyA, &testFunctorA));
202 registry.insert(std::make_pair(keyC, &testFunctorC));
203
204 // Check the order of the map is correct
205 auto it = registry.begin();
206 BOOST_CHECK(it->first==keyA);
207 it++;
208 BOOST_CHECK(it->first==keyB);
209 it++;
210 BOOST_CHECK(it->first==keyC);
211
FinnWilliamsArma0c78712019-09-16 12:06:47 +0100212 std::unique_ptr<char[]> packetDataA;
213 std::unique_ptr<char[]> packetDataB;
214 std::unique_ptr<char[]> packetDataC;
215
216 Packet packetA(500000000, 0, packetDataA);
217 Packet packetB(600000000, 0, packetDataB);
218 Packet packetC(400000000, 0, packetDataC);
Francis Murtagh11f99b42019-08-16 11:28:52 +0100219
220 // Check the correct operator of derived class is called
221 registry.at(CommandHandlerKey(packetA.GetPacketId(), version))->operator()(packetA);
222 BOOST_CHECK(testFunctorA.GetCount() == 1);
223 BOOST_CHECK(testFunctorB.GetCount() == 0);
224 BOOST_CHECK(testFunctorC.GetCount() == 0);
225
226 registry.at(CommandHandlerKey(packetB.GetPacketId(), version))->operator()(packetB);
227 BOOST_CHECK(testFunctorA.GetCount() == 1);
228 BOOST_CHECK(testFunctorB.GetCount() == 1);
229 BOOST_CHECK(testFunctorC.GetCount() == 0);
230
231 registry.at(CommandHandlerKey(packetC.GetPacketId(), version))->operator()(packetC);
232 BOOST_CHECK(testFunctorA.GetCount() == 1);
233 BOOST_CHECK(testFunctorB.GetCount() == 1);
234 BOOST_CHECK(testFunctorC.GetCount() == 1);
235}
236
Francis Murtagh94d79152019-08-16 17:45:07 +0100237BOOST_AUTO_TEST_CASE(CheckCommandHandlerRegistry)
238{
239 // Hard code the version as it will be the same during a single profiling session
240 uint32_t version = 1;
241
242 TestFunctorA testFunctorA(461, version);
243 TestFunctorB testFunctorB(963, version);
244 TestFunctorC testFunctorC(983, version);
245
246 // Create the Command Handler Registry
247 CommandHandlerRegistry registry;
248
249 // Register multiple different derived classes
250 registry.RegisterFunctor(&testFunctorA, testFunctorA.GetPacketId(), testFunctorA.GetVersion());
251 registry.RegisterFunctor(&testFunctorB, testFunctorB.GetPacketId(), testFunctorB.GetVersion());
252 registry.RegisterFunctor(&testFunctorC, testFunctorC.GetPacketId(), testFunctorC.GetVersion());
253
FinnWilliamsArma0c78712019-09-16 12:06:47 +0100254 std::unique_ptr<char[]> packetDataA;
255 std::unique_ptr<char[]> packetDataB;
256 std::unique_ptr<char[]> packetDataC;
257
258 Packet packetA(500000000, 0, packetDataA);
259 Packet packetB(600000000, 0, packetDataB);
260 Packet packetC(400000000, 0, packetDataC);
Francis Murtagh94d79152019-08-16 17:45:07 +0100261
262 // Check the correct operator of derived class is called
263 registry.GetFunctor(packetA.GetPacketId(), version)->operator()(packetA);
264 BOOST_CHECK(testFunctorA.GetCount() == 1);
265 BOOST_CHECK(testFunctorB.GetCount() == 0);
266 BOOST_CHECK(testFunctorC.GetCount() == 0);
267
268 registry.GetFunctor(packetB.GetPacketId(), version)->operator()(packetB);
269 BOOST_CHECK(testFunctorA.GetCount() == 1);
270 BOOST_CHECK(testFunctorB.GetCount() == 1);
271 BOOST_CHECK(testFunctorC.GetCount() == 0);
272
273 registry.GetFunctor(packetC.GetPacketId(), version)->operator()(packetC);
274 BOOST_CHECK(testFunctorA.GetCount() == 1);
275 BOOST_CHECK(testFunctorB.GetCount() == 1);
276 BOOST_CHECK(testFunctorC.GetCount() == 1);
277
278 // Re-register an existing key with a new function
279 registry.RegisterFunctor(&testFunctorC, testFunctorA.GetPacketId(), version);
280 registry.GetFunctor(packetA.GetPacketId(), version)->operator()(packetC);
281 BOOST_CHECK(testFunctorA.GetCount() == 1);
282 BOOST_CHECK(testFunctorB.GetCount() == 1);
283 BOOST_CHECK(testFunctorC.GetCount() == 2);
284
285 // Check that non-existent key returns nullptr for its functor
286 BOOST_CHECK_THROW(registry.GetFunctor(0, 0), armnn::Exception);
287}
288
Aron Virginas-Tare898db92019-08-22 12:56:34 +0100289BOOST_AUTO_TEST_CASE(CheckPacketVersionResolver)
290{
291 // Set up random number generator for generating packetId values
292 std::random_device device;
293 std::mt19937 generator(device());
294 std::uniform_int_distribution<uint32_t> distribution(std::numeric_limits<uint32_t>::min(),
295 std::numeric_limits<uint32_t>::max());
296
297 // NOTE: Expected version is always 1.0.0, regardless of packetId
298 const Version expectedVersion(1, 0, 0);
299
300 PacketVersionResolver packetVersionResolver;
301
302 constexpr unsigned int numTests = 10u;
303
304 for (unsigned int i = 0u; i < numTests; ++i)
305 {
306 const uint32_t packetId = distribution(generator);
307 Version resolvedVersion = packetVersionResolver.ResolvePacketVersion(packetId);
308
309 BOOST_TEST(resolvedVersion == expectedVersion);
310 }
311}
Nikhil Raj3ecc5102019-09-03 15:55:33 +0100312void ProfilingCurrentStateThreadImpl(ProfilingStateMachine& states)
313{
314 ProfilingState newState = ProfilingState::NotConnected;
315 states.GetCurrentState();
316 states.TransitionToState(newState);
317}
318
319BOOST_AUTO_TEST_CASE(CheckProfilingStateMachine)
320{
321 ProfilingStateMachine profilingState1(ProfilingState::Uninitialised);
322 profilingState1.TransitionToState(ProfilingState::Uninitialised);
323 BOOST_CHECK(profilingState1.GetCurrentState() == ProfilingState::Uninitialised);
324
325 ProfilingStateMachine profilingState2(ProfilingState::Uninitialised);
326 profilingState2.TransitionToState(ProfilingState::NotConnected);
327 BOOST_CHECK(profilingState2.GetCurrentState() == ProfilingState::NotConnected);
328
329 ProfilingStateMachine profilingState3(ProfilingState::NotConnected);
330 profilingState3.TransitionToState(ProfilingState::NotConnected);
331 BOOST_CHECK(profilingState3.GetCurrentState() == ProfilingState::NotConnected);
332
333 ProfilingStateMachine profilingState4(ProfilingState::NotConnected);
334 profilingState4.TransitionToState(ProfilingState::WaitingForAck);
335 BOOST_CHECK(profilingState4.GetCurrentState() == ProfilingState::WaitingForAck);
336
337 ProfilingStateMachine profilingState5(ProfilingState::WaitingForAck);
338 profilingState5.TransitionToState(ProfilingState::WaitingForAck);
339 BOOST_CHECK(profilingState5.GetCurrentState() == ProfilingState::WaitingForAck);
340
341 ProfilingStateMachine profilingState6(ProfilingState::WaitingForAck);
342 profilingState6.TransitionToState(ProfilingState::Active);
343 BOOST_CHECK(profilingState6.GetCurrentState() == ProfilingState::Active);
344
345 ProfilingStateMachine profilingState7(ProfilingState::Active);
346 profilingState7.TransitionToState(ProfilingState::NotConnected);
347 BOOST_CHECK(profilingState7.GetCurrentState() == ProfilingState::NotConnected);
348
349 ProfilingStateMachine profilingState8(ProfilingState::Active);
350 profilingState8.TransitionToState(ProfilingState::Active);
351 BOOST_CHECK(profilingState8.GetCurrentState() == ProfilingState::Active);
352
353 ProfilingStateMachine profilingState9(ProfilingState::Uninitialised);
354 BOOST_CHECK_THROW(profilingState9.TransitionToState(ProfilingState::WaitingForAck),
355 armnn::Exception);
356
357 ProfilingStateMachine profilingState10(ProfilingState::Uninitialised);
358 BOOST_CHECK_THROW(profilingState10.TransitionToState(ProfilingState::Active),
359 armnn::Exception);
360
361 ProfilingStateMachine profilingState11(ProfilingState::NotConnected);
362 BOOST_CHECK_THROW(profilingState11.TransitionToState(ProfilingState::Uninitialised),
363 armnn::Exception);
364
365 ProfilingStateMachine profilingState12(ProfilingState::NotConnected);
366 BOOST_CHECK_THROW(profilingState12.TransitionToState(ProfilingState::Active),
367 armnn::Exception);
368
369 ProfilingStateMachine profilingState13(ProfilingState::WaitingForAck);
370 BOOST_CHECK_THROW(profilingState13.TransitionToState(ProfilingState::Uninitialised),
371 armnn::Exception);
372
373 ProfilingStateMachine profilingState14(ProfilingState::WaitingForAck);
374 BOOST_CHECK_THROW(profilingState14.TransitionToState(ProfilingState::NotConnected),
375 armnn::Exception);
376
377 ProfilingStateMachine profilingState15(ProfilingState::Active);
378 BOOST_CHECK_THROW(profilingState15.TransitionToState(ProfilingState::Uninitialised),
379 armnn::Exception);
380
381 ProfilingStateMachine profilingState16(armnn::profiling::ProfilingState::Active);
382 BOOST_CHECK_THROW(profilingState16.TransitionToState(ProfilingState::WaitingForAck),
383 armnn::Exception);
384
385 ProfilingStateMachine profilingState17(ProfilingState::Uninitialised);
386
387 std::thread thread1 (ProfilingCurrentStateThreadImpl,std::ref(profilingState17));
388 std::thread thread2 (ProfilingCurrentStateThreadImpl,std::ref(profilingState17));
389 std::thread thread3 (ProfilingCurrentStateThreadImpl,std::ref(profilingState17));
390 std::thread thread4 (ProfilingCurrentStateThreadImpl,std::ref(profilingState17));
391 std::thread thread5 (ProfilingCurrentStateThreadImpl,std::ref(profilingState17));
392
393 thread1.join();
394 thread2.join();
395 thread3.join();
396 thread4.join();
397 thread5.join();
398
399 BOOST_TEST((profilingState17.GetCurrentState() == ProfilingState::NotConnected));
400}
Aron Virginas-Tare898db92019-08-22 12:56:34 +0100401
Jim Flynn8355ec92019-09-17 12:29:50 +0100402void CaptureDataWriteThreadImpl(Holder& holder, uint32_t capturePeriod, const std::vector<uint16_t>& counterIds)
Francis Murtagh68f78d82019-09-04 16:42:29 +0100403{
404 holder.SetCaptureData(capturePeriod, counterIds);
405}
406
Francis Murtaghbd707162019-09-09 11:26:44 +0100407void CaptureDataReadThreadImpl(const Holder& holder, CaptureData& captureData)
Francis Murtagh68f78d82019-09-04 16:42:29 +0100408{
409 captureData = holder.GetCaptureData();
410}
411
412BOOST_AUTO_TEST_CASE(CheckCaptureDataHolder)
413{
Francis Murtaghbd707162019-09-09 11:26:44 +0100414 std::map<uint32_t, std::vector<uint16_t>> periodIdMap;
415 std::vector<uint16_t> counterIds;
Jim Flynn8355ec92019-09-17 12:29:50 +0100416 uint32_t numThreads = 10;
417 for (uint32_t i = 0; i < numThreads; ++i)
Francis Murtaghbd707162019-09-09 11:26:44 +0100418 {
419 counterIds.emplace_back(i);
420 periodIdMap.insert(std::make_pair(i, counterIds));
421 }
Francis Murtagh68f78d82019-09-04 16:42:29 +0100422
Jim Flynn8355ec92019-09-17 12:29:50 +0100423 // Verify the read and write threads set the holder correctly
424 // and retrieve the expected values
Francis Murtagh68f78d82019-09-04 16:42:29 +0100425 Holder holder;
426 BOOST_CHECK((holder.GetCaptureData()).GetCapturePeriod() == 0);
427 BOOST_CHECK(((holder.GetCaptureData()).GetCounterIds()).empty());
428
429 // Check Holder functions
Francis Murtaghbd707162019-09-09 11:26:44 +0100430 std::thread thread1(CaptureDataWriteThreadImpl, std::ref(holder), 2, std::ref(periodIdMap[2]));
Francis Murtagh68f78d82019-09-04 16:42:29 +0100431 thread1.join();
Francis Murtaghbd707162019-09-09 11:26:44 +0100432 BOOST_CHECK((holder.GetCaptureData()).GetCapturePeriod() == 2);
433 BOOST_CHECK((holder.GetCaptureData()).GetCounterIds() == periodIdMap[2]);
Jim Flynn8355ec92019-09-17 12:29:50 +0100434 // NOTE: now that we have some initial values in the holder we don't have to worry
435 // in the multi-threaded section below about a read thread accessing the holder
436 // before any write thread has gotten to it so we read period = 0, counterIds empty
437 // instead of period = 0, counterIds = {0} as will the case when write thread 0
438 // has executed.
Francis Murtagh68f78d82019-09-04 16:42:29 +0100439
440 CaptureData captureData;
441 std::thread thread2(CaptureDataReadThreadImpl, std::ref(holder), std::ref(captureData));
442 thread2.join();
Jim Flynn8355ec92019-09-17 12:29:50 +0100443 BOOST_CHECK(captureData.GetCapturePeriod() == 2);
Francis Murtaghbd707162019-09-09 11:26:44 +0100444 BOOST_CHECK(captureData.GetCounterIds() == periodIdMap[2]);
Francis Murtagh68f78d82019-09-04 16:42:29 +0100445
Jim Flynn8355ec92019-09-17 12:29:50 +0100446 std::map<uint32_t, CaptureData> captureDataIdMap;
447 for (uint32_t i = 0; i < numThreads; ++i)
448 {
449 CaptureData perThreadCaptureData;
450 captureDataIdMap.insert(std::make_pair(i, perThreadCaptureData));
451 }
452
Francis Murtaghbd707162019-09-09 11:26:44 +0100453 std::vector<std::thread> threadsVect;
Jim Flynn8355ec92019-09-17 12:29:50 +0100454 std::vector<std::thread> readThreadsVect;
455 for (uint32_t i = 0; i < numThreads; ++i)
Francis Murtaghbd707162019-09-09 11:26:44 +0100456 {
457 threadsVect.emplace_back(std::thread(CaptureDataWriteThreadImpl,
458 std::ref(holder),
459 i,
Jim Flynn8355ec92019-09-17 12:29:50 +0100460 std::ref(periodIdMap[i])));
Francis Murtagh06965692019-09-05 16:29:01 +0100461
Jim Flynn8355ec92019-09-17 12:29:50 +0100462 // Verify that the CaptureData goes into the thread in a virgin state
463 BOOST_CHECK(captureDataIdMap.at(i).GetCapturePeriod() == 0);
464 BOOST_CHECK(captureDataIdMap.at(i).GetCounterIds().empty());
465 readThreadsVect.emplace_back(std::thread(CaptureDataReadThreadImpl,
466 std::ref(holder),
467 std::ref(captureDataIdMap.at(i))));
Francis Murtaghbd707162019-09-09 11:26:44 +0100468 }
469
Jim Flynn8355ec92019-09-17 12:29:50 +0100470 for (uint32_t i = 0; i < numThreads; ++i)
Francis Murtaghbd707162019-09-09 11:26:44 +0100471 {
472 threadsVect[i].join();
Francis Murtaghbd707162019-09-09 11:26:44 +0100473 readThreadsVect[i].join();
474 }
Francis Murtagh68f78d82019-09-04 16:42:29 +0100475
Jim Flynn8355ec92019-09-17 12:29:50 +0100476 // Look at the CaptureData that each read thread has filled
477 // the capture period it read should match the counter ids entry
478 for (uint32_t i = 0; i < numThreads; ++i)
479 {
480 CaptureData perThreadCaptureData = captureDataIdMap.at(i);
481 BOOST_CHECK(perThreadCaptureData.GetCounterIds() == periodIdMap.at(perThreadCaptureData.GetCapturePeriod()));
482 }
Matthew Bentham46d1c622019-09-13 12:45:04 +0100483}
Francis Murtagh68f78d82019-09-04 16:42:29 +0100484
Matthew Bentham46d1c622019-09-13 12:45:04 +0100485BOOST_AUTO_TEST_CASE(CaptureDataMethods)
486{
Jim Flynn8355ec92019-09-17 12:29:50 +0100487 // Check CaptureData setter and getter functions
Matthew Bentham46d1c622019-09-13 12:45:04 +0100488 std::vector<uint16_t> counterIds = {42, 29, 13};
Jim Flynn8355ec92019-09-17 12:29:50 +0100489 CaptureData captureData;
490 BOOST_CHECK(captureData.GetCapturePeriod() == 0);
491 BOOST_CHECK((captureData.GetCounterIds()).empty());
492 captureData.SetCapturePeriod(150);
493 captureData.SetCounterIds(counterIds);
494 BOOST_CHECK(captureData.GetCapturePeriod() == 150);
495 BOOST_CHECK(captureData.GetCounterIds() == counterIds);
Francis Murtagh68f78d82019-09-04 16:42:29 +0100496
Jim Flynn8355ec92019-09-17 12:29:50 +0100497 // Check assignment operator
Francis Murtagh68f78d82019-09-04 16:42:29 +0100498 CaptureData secondCaptureData;
Francis Murtagh68f78d82019-09-04 16:42:29 +0100499
Jim Flynn8355ec92019-09-17 12:29:50 +0100500 secondCaptureData = captureData;
501 BOOST_CHECK(secondCaptureData.GetCapturePeriod() == 150);
Matthew Bentham46d1c622019-09-13 12:45:04 +0100502 BOOST_CHECK(secondCaptureData.GetCounterIds() == counterIds);
Francis Murtagh68f78d82019-09-04 16:42:29 +0100503
504 // Check copy constructor
Jim Flynn8355ec92019-09-17 12:29:50 +0100505 CaptureData copyConstructedCaptureData(captureData);
Francis Murtagh68f78d82019-09-04 16:42:29 +0100506
Jim Flynn8355ec92019-09-17 12:29:50 +0100507 BOOST_CHECK(copyConstructedCaptureData.GetCapturePeriod() == 150);
Matthew Bentham46d1c622019-09-13 12:45:04 +0100508 BOOST_CHECK(copyConstructedCaptureData.GetCounterIds() == counterIds);
Keith Davis02356de2019-08-26 18:28:17 +0100509}
Francis Murtagh68f78d82019-09-04 16:42:29 +0100510
Keith Davis02356de2019-08-26 18:28:17 +0100511BOOST_AUTO_TEST_CASE(CheckProfilingServiceDisabled)
512{
513 armnn::Runtime::CreationOptions::ExternalProfilingOptions options;
514 ProfilingService service(options);
515 BOOST_CHECK(service.GetCurrentState() == ProfilingState::Uninitialised);
516 service.Run();
517 BOOST_CHECK(service.GetCurrentState() == ProfilingState::Uninitialised);
518}
519
Keith Davis02356de2019-08-26 18:28:17 +0100520BOOST_AUTO_TEST_CASE(CheckProfilingServiceEnabled)
521{
522 armnn::Runtime::CreationOptions::ExternalProfilingOptions options;
523 options.m_EnableProfiling = true;
524 ProfilingService service(options);
525 BOOST_CHECK(service.GetCurrentState() == ProfilingState::NotConnected);
526 service.Run();
527 BOOST_CHECK(service.GetCurrentState() == ProfilingState::WaitingForAck);
528}
529
530
531BOOST_AUTO_TEST_CASE(CheckProfilingServiceEnabledRuntime)
532{
533 armnn::Runtime::CreationOptions::ExternalProfilingOptions options;
534 ProfilingService service(options);
535 BOOST_CHECK(service.GetCurrentState() == ProfilingState::Uninitialised);
536 service.Run();
537 BOOST_CHECK(service.GetCurrentState() == ProfilingState::Uninitialised);
FinnWilliamsArmce2d9d12019-09-18 10:28:16 +0100538 options.m_EnableProfiling = true;
539 service.ResetExternalProfilingOptions(options);
Keith Davis02356de2019-08-26 18:28:17 +0100540 BOOST_CHECK(service.GetCurrentState() == ProfilingState::NotConnected);
541 service.Run();
542 BOOST_CHECK(service.GetCurrentState() == ProfilingState::WaitingForAck);
Francis Murtagh68f78d82019-09-04 16:42:29 +0100543}
544
FinnWilliamsArmce2d9d12019-09-18 10:28:16 +0100545BOOST_AUTO_TEST_CASE(CheckProfilingServiceCounterDirectory)
546{
547 armnn::Runtime::CreationOptions::ExternalProfilingOptions options;
548 ProfilingService service(options);
549
550 const ICounterDirectory& counterDirectory0 = service.GetCounterDirectory();
551 BOOST_CHECK(counterDirectory0.GetCounterCount() == 0);
552
553 options.m_EnableProfiling = true;
554 service.ResetExternalProfilingOptions(options);
555
556 const ICounterDirectory& counterDirectory1 = service.GetCounterDirectory();
557 BOOST_CHECK(counterDirectory1.GetCounterCount() != 0);
558}
559
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100560BOOST_AUTO_TEST_CASE(CheckProfilingObjectUids)
Matteo Martincighab173e92019-09-05 12:02:04 +0100561{
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100562 uint16_t uid = 0;
563 BOOST_CHECK_NO_THROW(uid = GetNextUid());
564 BOOST_CHECK(uid >= 1);
565
566 uint16_t nextUid = 0;
567 BOOST_CHECK_NO_THROW(nextUid = GetNextUid());
568 BOOST_CHECK(nextUid > uid);
569
570 std::vector<uint16_t> counterUids;
571 BOOST_CHECK_NO_THROW(counterUids = GetNextCounterUids(0));
572 BOOST_CHECK(counterUids.size() == 1);
573 BOOST_CHECK(counterUids[0] >= 0);
574
575 std::vector<uint16_t> nextCounterUids;
576 BOOST_CHECK_NO_THROW(nextCounterUids = GetNextCounterUids(1));
577 BOOST_CHECK(nextCounterUids.size() == 1);
578 BOOST_CHECK(nextCounterUids[0] > counterUids[0]);
579
580 std::vector<uint16_t> counterUidsMultiCore;
581 uint16_t numberOfCores = 13;
582 BOOST_CHECK_NO_THROW(counterUidsMultiCore = GetNextCounterUids(numberOfCores));
583 BOOST_CHECK(counterUidsMultiCore.size() == numberOfCores);
584 BOOST_CHECK(counterUidsMultiCore.front() >= nextCounterUids[0]);
585 for (size_t i = 1; i < numberOfCores; i ++)
586 {
587 BOOST_CHECK(counterUidsMultiCore[i] == counterUidsMultiCore[i - 1] + 1);
588 }
589 BOOST_CHECK(counterUidsMultiCore.back() == counterUidsMultiCore.front() + numberOfCores - 1);
Matteo Martincighab173e92019-09-05 12:02:04 +0100590}
591
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100592BOOST_AUTO_TEST_CASE(CheckCounterDirectoryRegisterCategory)
Matteo Martincighab173e92019-09-05 12:02:04 +0100593{
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100594 CounterDirectory counterDirectory;
595 BOOST_CHECK(counterDirectory.GetCategoryCount() == 0);
596 BOOST_CHECK(counterDirectory.GetDeviceCount() == 0);
597 BOOST_CHECK(counterDirectory.GetCounterSetCount() == 0);
598 BOOST_CHECK(counterDirectory.GetCounterCount() == 0);
Matteo Martincighab173e92019-09-05 12:02:04 +0100599
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100600 // Register a category with an invalid name
601 const Category* noCategory = nullptr;
602 BOOST_CHECK_THROW(noCategory = counterDirectory.RegisterCategory(""), armnn::InvalidArgumentException);
603 BOOST_CHECK(counterDirectory.GetCategoryCount() == 0);
604 BOOST_CHECK(!noCategory);
Matteo Martincighab173e92019-09-05 12:02:04 +0100605
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100606 // Register a category with an invalid name
607 BOOST_CHECK_THROW(noCategory = counterDirectory.RegisterCategory("invalid category"),
608 armnn::InvalidArgumentException);
609 BOOST_CHECK(counterDirectory.GetCategoryCount() == 0);
610 BOOST_CHECK(!noCategory);
611
612 // Register a new category
613 const std::string categoryName = "some_category";
614 const Category* category = nullptr;
615 BOOST_CHECK_NO_THROW(category = counterDirectory.RegisterCategory(categoryName));
616 BOOST_CHECK(counterDirectory.GetCategoryCount() == 1);
617 BOOST_CHECK(category);
618 BOOST_CHECK(category->m_Name == categoryName);
619 BOOST_CHECK(category->m_Counters.empty());
620 BOOST_CHECK(category->m_DeviceUid == 0);
621 BOOST_CHECK(category->m_CounterSetUid == 0);
622
623 // Get the registered category
624 const Category* registeredCategory = counterDirectory.GetCategory(categoryName);
625 BOOST_CHECK(counterDirectory.GetCategoryCount() == 1);
626 BOOST_CHECK(registeredCategory);
627 BOOST_CHECK(registeredCategory == category);
628
629 // Try to get a category not registered
630 const Category* notRegisteredCategory = counterDirectory.GetCategory("not_registered_category");
631 BOOST_CHECK(counterDirectory.GetCategoryCount() == 1);
632 BOOST_CHECK(!notRegisteredCategory);
633
634 // Register a category already registered
635 const Category* anotherCategory = nullptr;
636 BOOST_CHECK_THROW(anotherCategory = counterDirectory.RegisterCategory(categoryName),
637 armnn::InvalidArgumentException);
638 BOOST_CHECK(counterDirectory.GetCategoryCount() == 1);
639 BOOST_CHECK(!anotherCategory);
640
641 // Register a device for testing
642 const std::string deviceName = "some_device";
643 const Device* device = nullptr;
644 BOOST_CHECK_NO_THROW(device = counterDirectory.RegisterDevice(deviceName));
645 BOOST_CHECK(counterDirectory.GetDeviceCount() == 1);
646 BOOST_CHECK(device);
647 BOOST_CHECK(device->m_Uid >= 1);
648 BOOST_CHECK(device->m_Name == deviceName);
649 BOOST_CHECK(device->m_Cores == 0);
650
651 // Register a new category not associated to any device
652 const std::string categoryWoDeviceName = "some_category_without_device";
653 const Category* categoryWoDevice = nullptr;
654 BOOST_CHECK_NO_THROW(categoryWoDevice = counterDirectory.RegisterCategory(categoryWoDeviceName, 0));
655 BOOST_CHECK(counterDirectory.GetCategoryCount() == 2);
656 BOOST_CHECK(categoryWoDevice);
657 BOOST_CHECK(categoryWoDevice->m_Name == categoryWoDeviceName);
658 BOOST_CHECK(categoryWoDevice->m_Counters.empty());
659 BOOST_CHECK(categoryWoDevice->m_DeviceUid == 0);
660 BOOST_CHECK(categoryWoDevice->m_CounterSetUid == 0);
661
662 // Register a new category associated to an invalid device
663 const std::string categoryWInvalidDeviceName = "some_category_with_invalid_device";
664
665 ARMNN_NO_CONVERSION_WARN_BEGIN
666 uint16_t invalidDeviceUid = device->m_Uid + 10;
667 ARMNN_NO_CONVERSION_WARN_END
668
669 const Category* categoryWInvalidDevice = nullptr;
670 BOOST_CHECK_THROW(categoryWInvalidDevice
671 = counterDirectory.RegisterCategory(categoryWInvalidDeviceName,
672 invalidDeviceUid),
673 armnn::InvalidArgumentException);
674 BOOST_CHECK(counterDirectory.GetCategoryCount() == 2);
675 BOOST_CHECK(!categoryWInvalidDevice);
676
677 // Register a new category associated to a valid device
678 const std::string categoryWValidDeviceName = "some_category_with_valid_device";
679 const Category* categoryWValidDevice = nullptr;
680 BOOST_CHECK_NO_THROW(categoryWValidDevice
681 = counterDirectory.RegisterCategory(categoryWValidDeviceName,
682 device->m_Uid));
683 BOOST_CHECK(counterDirectory.GetCategoryCount() == 3);
684 BOOST_CHECK(categoryWValidDevice);
685 BOOST_CHECK(categoryWValidDevice != category);
686 BOOST_CHECK(categoryWValidDevice->m_Name == categoryWValidDeviceName);
687 BOOST_CHECK(categoryWValidDevice->m_DeviceUid == device->m_Uid);
688 BOOST_CHECK(categoryWValidDevice->m_CounterSetUid == 0);
689
690 // Register a counter set for testing
691 const std::string counterSetName = "some_counter_set";
692 const CounterSet* counterSet = nullptr;
693 BOOST_CHECK_NO_THROW(counterSet = counterDirectory.RegisterCounterSet(counterSetName));
694 BOOST_CHECK(counterDirectory.GetCounterSetCount() == 1);
695 BOOST_CHECK(counterSet);
696 BOOST_CHECK(counterSet->m_Uid >= 1);
697 BOOST_CHECK(counterSet->m_Name == counterSetName);
698 BOOST_CHECK(counterSet->m_Count == 0);
699
700 // Register a new category not associated to any counter set
701 const std::string categoryWoCounterSetName = "some_category_without_counter_set";
702 const Category* categoryWoCounterSet = nullptr;
703 BOOST_CHECK_NO_THROW(categoryWoCounterSet
704 = counterDirectory.RegisterCategory(categoryWoCounterSetName,
705 armnn::EmptyOptional(),
706 0));
707 BOOST_CHECK(counterDirectory.GetCategoryCount() == 4);
708 BOOST_CHECK(categoryWoCounterSet);
709 BOOST_CHECK(categoryWoCounterSet->m_Name == categoryWoCounterSetName);
710 BOOST_CHECK(categoryWoCounterSet->m_DeviceUid == 0);
711 BOOST_CHECK(categoryWoCounterSet->m_CounterSetUid == 0);
712
713 // Register a new category associated to an invalid counter set
714 const std::string categoryWInvalidCounterSetName = "some_category_with_invalid_counter_set";
715
716 ARMNN_NO_CONVERSION_WARN_BEGIN
717 uint16_t invalidCunterSetUid = counterSet->m_Uid + 10;
718 ARMNN_NO_CONVERSION_WARN_END
719
720 const Category* categoryWInvalidCounterSet = nullptr;
721 BOOST_CHECK_THROW(categoryWInvalidCounterSet
722 = counterDirectory.RegisterCategory(categoryWInvalidCounterSetName,
723 armnn::EmptyOptional(),
724 invalidCunterSetUid),
725 armnn::InvalidArgumentException);
726 BOOST_CHECK(counterDirectory.GetCategoryCount() == 4);
727 BOOST_CHECK(!categoryWInvalidCounterSet);
728
729 // Register a new category associated to a valid counter set
730 const std::string categoryWValidCounterSetName = "some_category_with_valid_counter_set";
731 const Category* categoryWValidCounterSet = nullptr;
732 BOOST_CHECK_NO_THROW(categoryWValidCounterSet
733 = counterDirectory.RegisterCategory(categoryWValidCounterSetName,
734 armnn::EmptyOptional(),
735 counterSet->m_Uid));
736 BOOST_CHECK(counterDirectory.GetCategoryCount() == 5);
737 BOOST_CHECK(categoryWValidCounterSet);
738 BOOST_CHECK(categoryWValidCounterSet != category);
739 BOOST_CHECK(categoryWValidCounterSet->m_Name == categoryWValidCounterSetName);
740 BOOST_CHECK(categoryWValidCounterSet->m_DeviceUid == 0);
741 BOOST_CHECK(categoryWValidCounterSet->m_CounterSetUid == counterSet->m_Uid);
742
743 // Register a new category associated to a valid device and counter set
744 const std::string categoryWValidDeviceAndValidCounterSetName = "some_category_with_valid_device_and_counter_set";
745 const Category* categoryWValidDeviceAndValidCounterSet = nullptr;
746 BOOST_CHECK_NO_THROW(categoryWValidDeviceAndValidCounterSet
747 = counterDirectory.RegisterCategory(categoryWValidDeviceAndValidCounterSetName,
748 device->m_Uid,
749 counterSet->m_Uid));
750 BOOST_CHECK(counterDirectory.GetCategoryCount() == 6);
751 BOOST_CHECK(categoryWValidDeviceAndValidCounterSet);
752 BOOST_CHECK(categoryWValidDeviceAndValidCounterSet != category);
753 BOOST_CHECK(categoryWValidDeviceAndValidCounterSet->m_Name == categoryWValidDeviceAndValidCounterSetName);
754 BOOST_CHECK(categoryWValidDeviceAndValidCounterSet->m_DeviceUid == device->m_Uid);
755 BOOST_CHECK(categoryWValidDeviceAndValidCounterSet->m_CounterSetUid == counterSet->m_Uid);
756}
757
758BOOST_AUTO_TEST_CASE(CheckCounterDirectoryRegisterDevice)
759{
760 CounterDirectory counterDirectory;
761 BOOST_CHECK(counterDirectory.GetCategoryCount() == 0);
762 BOOST_CHECK(counterDirectory.GetDeviceCount() == 0);
763 BOOST_CHECK(counterDirectory.GetCounterSetCount() == 0);
764 BOOST_CHECK(counterDirectory.GetCounterCount() == 0);
765
766 // Register a device with an invalid name
767 const Device* noDevice = nullptr;
768 BOOST_CHECK_THROW(noDevice = counterDirectory.RegisterDevice(""), armnn::InvalidArgumentException);
769 BOOST_CHECK(counterDirectory.GetDeviceCount() == 0);
770 BOOST_CHECK(!noDevice);
771
772 // Register a device with an invalid name
773 BOOST_CHECK_THROW(noDevice = counterDirectory.RegisterDevice("inv@lid nam€"), armnn::InvalidArgumentException);
774 BOOST_CHECK(counterDirectory.GetDeviceCount() == 0);
775 BOOST_CHECK(!noDevice);
776
777 // Register a new device with no cores or parent category
778 const std::string deviceName = "some_device";
779 const Device* device = nullptr;
780 BOOST_CHECK_NO_THROW(device = counterDirectory.RegisterDevice(deviceName));
781 BOOST_CHECK(counterDirectory.GetDeviceCount() == 1);
782 BOOST_CHECK(device);
783 BOOST_CHECK(device->m_Name == deviceName);
784 BOOST_CHECK(device->m_Uid >= 1);
785 BOOST_CHECK(device->m_Cores == 0);
786
Matteo Martincigh657ab2d2019-09-18 10:53:24 +0100787 // Try getting an unregistered device
788 const Device* unregisteredDevice = counterDirectory.GetDevice(9999);
789 BOOST_CHECK(!unregisteredDevice);
790
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100791 // Get the registered device
792 const Device* registeredDevice = counterDirectory.GetDevice(device->m_Uid);
793 BOOST_CHECK(counterDirectory.GetDeviceCount() == 1);
794 BOOST_CHECK(registeredDevice);
795 BOOST_CHECK(registeredDevice == device);
796
Matteo Martincigh657ab2d2019-09-18 10:53:24 +0100797 // Register a device with the name of a device already registered
798 const Device* deviceSameName = nullptr;
799 BOOST_CHECK_THROW(deviceSameName = counterDirectory.RegisterDevice(deviceName), armnn::InvalidArgumentException);
800 BOOST_CHECK(counterDirectory.GetDeviceCount() == 1);
801 BOOST_CHECK(!deviceSameName);
802
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100803 // Register a new device with cores and no parent category
804 const std::string deviceWCoresName = "some_device_with_cores";
805 const Device* deviceWCores = nullptr;
806 BOOST_CHECK_NO_THROW(deviceWCores = counterDirectory.RegisterDevice(deviceWCoresName, 2));
807 BOOST_CHECK(counterDirectory.GetDeviceCount() == 2);
808 BOOST_CHECK(deviceWCores);
809 BOOST_CHECK(deviceWCores->m_Name == deviceWCoresName);
810 BOOST_CHECK(deviceWCores->m_Uid >= 1);
811 BOOST_CHECK(deviceWCores->m_Uid > device->m_Uid);
812 BOOST_CHECK(deviceWCores->m_Cores == 2);
813
814 // Get the registered device
815 const Device* registeredDeviceWCores = counterDirectory.GetDevice(deviceWCores->m_Uid);
816 BOOST_CHECK(counterDirectory.GetDeviceCount() == 2);
817 BOOST_CHECK(registeredDeviceWCores);
818 BOOST_CHECK(registeredDeviceWCores == deviceWCores);
819 BOOST_CHECK(registeredDeviceWCores != device);
820
821 // Register a new device with cores and invalid parent category
822 const std::string deviceWCoresWInvalidParentCategoryName = "some_device_with_cores_with_invalid_parent_category";
823 const Device* deviceWCoresWInvalidParentCategory = nullptr;
824 BOOST_CHECK_THROW(deviceWCoresWInvalidParentCategory
825 = counterDirectory.RegisterDevice(deviceWCoresWInvalidParentCategoryName,
826 3,
827 std::string("")),
828 armnn::InvalidArgumentException);
829 BOOST_CHECK(counterDirectory.GetDeviceCount() == 2);
830 BOOST_CHECK(!deviceWCoresWInvalidParentCategory);
831
832 // Register a new device with cores and invalid parent category
833 const std::string deviceWCoresWInvalidParentCategoryName2 = "some_device_with_cores_with_invalid_parent_category2";
834 const Device* deviceWCoresWInvalidParentCategory2 = nullptr;
835 BOOST_CHECK_THROW(deviceWCoresWInvalidParentCategory2
836 = counterDirectory.RegisterDevice(deviceWCoresWInvalidParentCategoryName2,
837 3,
838 std::string("invalid_parent_category")),
839 armnn::InvalidArgumentException);
840 BOOST_CHECK(counterDirectory.GetDeviceCount() == 2);
841 BOOST_CHECK(!deviceWCoresWInvalidParentCategory2);
842
843 // Register a category for testing
844 const std::string categoryName = "some_category";
845 const Category* category = nullptr;
846 BOOST_CHECK_NO_THROW(category = counterDirectory.RegisterCategory(categoryName));
847 BOOST_CHECK(counterDirectory.GetCategoryCount() == 1);
848 BOOST_CHECK(category);
849 BOOST_CHECK(category->m_Name == categoryName);
850 BOOST_CHECK(category->m_Counters.empty());
851 BOOST_CHECK(category->m_DeviceUid == 0);
852 BOOST_CHECK(category->m_CounterSetUid == 0);
853
854 // Register a new device with cores and valid parent category
855 const std::string deviceWCoresWValidParentCategoryName = "some_device_with_cores_with_valid_parent_category";
856 const Device* deviceWCoresWValidParentCategory = nullptr;
857 BOOST_CHECK_NO_THROW(deviceWCoresWValidParentCategory
858 = counterDirectory.RegisterDevice(deviceWCoresWValidParentCategoryName,
859 4,
860 categoryName));
861 BOOST_CHECK(counterDirectory.GetDeviceCount() == 3);
862 BOOST_CHECK(deviceWCoresWValidParentCategory);
863 BOOST_CHECK(deviceWCoresWValidParentCategory->m_Name == deviceWCoresWValidParentCategoryName);
864 BOOST_CHECK(deviceWCoresWValidParentCategory->m_Uid >= 1);
865 BOOST_CHECK(deviceWCoresWValidParentCategory->m_Uid > device->m_Uid);
866 BOOST_CHECK(deviceWCoresWValidParentCategory->m_Uid > deviceWCores->m_Uid);
867 BOOST_CHECK(deviceWCoresWValidParentCategory->m_Cores == 4);
868 BOOST_CHECK(category->m_DeviceUid == deviceWCoresWValidParentCategory->m_Uid);
Matteo Martincigh657ab2d2019-09-18 10:53:24 +0100869
870 // Register a device associated to a category already associated to a different device
871 const std::string deviceSameCategoryName = "some_device_with_invalid_parent_category";
872 const Device* deviceSameCategory = nullptr;
873 BOOST_CHECK_THROW(deviceSameCategory = counterDirectory.RegisterDevice(deviceSameCategoryName, 0, categoryName),
874 armnn::InvalidArgumentException);
875 BOOST_CHECK(counterDirectory.GetDeviceCount() == 3);
876 BOOST_CHECK(!deviceSameCategory);
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100877}
878
879BOOST_AUTO_TEST_CASE(CheckCounterDirectoryRegisterCounterSet)
880{
881 CounterDirectory counterDirectory;
882 BOOST_CHECK(counterDirectory.GetCategoryCount() == 0);
883 BOOST_CHECK(counterDirectory.GetDeviceCount() == 0);
884 BOOST_CHECK(counterDirectory.GetCounterSetCount() == 0);
885 BOOST_CHECK(counterDirectory.GetCounterCount() == 0);
886
887 // Register a counter set with an invalid name
888 const CounterSet* noCounterSet = nullptr;
889 BOOST_CHECK_THROW(noCounterSet = counterDirectory.RegisterCounterSet(""), armnn::InvalidArgumentException);
890 BOOST_CHECK(counterDirectory.GetCounterSetCount() == 0);
891 BOOST_CHECK(!noCounterSet);
892
893 // Register a counter set with an invalid name
894 BOOST_CHECK_THROW(noCounterSet = counterDirectory.RegisterCounterSet("invalid name"),
895 armnn::InvalidArgumentException);
896 BOOST_CHECK(counterDirectory.GetCounterSetCount() == 0);
897 BOOST_CHECK(!noCounterSet);
898
899 // Register a new counter set with no count or parent category
900 const std::string counterSetName = "some_counter_set";
901 const CounterSet* counterSet = nullptr;
902 BOOST_CHECK_NO_THROW(counterSet = counterDirectory.RegisterCounterSet(counterSetName));
903 BOOST_CHECK(counterDirectory.GetCounterSetCount() == 1);
904 BOOST_CHECK(counterSet);
905 BOOST_CHECK(counterSet->m_Name == counterSetName);
906 BOOST_CHECK(counterSet->m_Uid >= 1);
907 BOOST_CHECK(counterSet->m_Count == 0);
908
Matteo Martincigh657ab2d2019-09-18 10:53:24 +0100909 // Try getting an unregistered counter set
910 const CounterSet* unregisteredCounterSet = counterDirectory.GetCounterSet(9999);
911 BOOST_CHECK(!unregisteredCounterSet);
912
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100913 // Get the registered counter set
914 const CounterSet* registeredCounterSet = counterDirectory.GetCounterSet(counterSet->m_Uid);
915 BOOST_CHECK(counterDirectory.GetCounterSetCount() == 1);
916 BOOST_CHECK(registeredCounterSet);
917 BOOST_CHECK(registeredCounterSet == counterSet);
918
Matteo Martincigh657ab2d2019-09-18 10:53:24 +0100919 // Register a counter set with the name of a counter set already registered
920 const CounterSet* counterSetSameName = nullptr;
921 BOOST_CHECK_THROW(counterSetSameName = counterDirectory.RegisterCounterSet(counterSetName),
922 armnn::InvalidArgumentException);
923 BOOST_CHECK(counterDirectory.GetCounterSetCount() == 1);
924 BOOST_CHECK(!counterSetSameName);
925
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100926 // Register a new counter set with count and no parent category
927 const std::string counterSetWCountName = "some_counter_set_with_count";
928 const CounterSet* counterSetWCount = nullptr;
929 BOOST_CHECK_NO_THROW(counterSetWCount = counterDirectory.RegisterCounterSet(counterSetWCountName, 37));
930 BOOST_CHECK(counterDirectory.GetCounterSetCount() == 2);
931 BOOST_CHECK(counterSetWCount);
932 BOOST_CHECK(counterSetWCount->m_Name == counterSetWCountName);
933 BOOST_CHECK(counterSetWCount->m_Uid >= 1);
934 BOOST_CHECK(counterSetWCount->m_Uid > counterSet->m_Uid);
935 BOOST_CHECK(counterSetWCount->m_Count == 37);
936
937 // Get the registered counter set
938 const CounterSet* registeredCounterSetWCount = counterDirectory.GetCounterSet(counterSetWCount->m_Uid);
939 BOOST_CHECK(counterDirectory.GetCounterSetCount() == 2);
940 BOOST_CHECK(registeredCounterSetWCount);
941 BOOST_CHECK(registeredCounterSetWCount == counterSetWCount);
942 BOOST_CHECK(registeredCounterSetWCount != counterSet);
943
944 // Register a new counter set with count and invalid parent category
945 const std::string counterSetWCountWInvalidParentCategoryName = "some_counter_set_with_count_"
946 "with_invalid_parent_category";
947 const CounterSet* counterSetWCountWInvalidParentCategory = nullptr;
948 BOOST_CHECK_THROW(counterSetWCountWInvalidParentCategory
949 = counterDirectory.RegisterCounterSet(counterSetWCountWInvalidParentCategoryName,
950 42,
951 std::string("")),
952 armnn::InvalidArgumentException);
953 BOOST_CHECK(counterDirectory.GetCounterSetCount() == 2);
954 BOOST_CHECK(!counterSetWCountWInvalidParentCategory);
955
956 // Register a new counter set with count and invalid parent category
957 const std::string counterSetWCountWInvalidParentCategoryName2 = "some_counter_set_with_count_"
958 "with_invalid_parent_category2";
959 const CounterSet* counterSetWCountWInvalidParentCategory2 = nullptr;
960 BOOST_CHECK_THROW(counterSetWCountWInvalidParentCategory2
961 = counterDirectory.RegisterCounterSet(counterSetWCountWInvalidParentCategoryName2,
962 42,
963 std::string("invalid_parent_category")),
964 armnn::InvalidArgumentException);
965 BOOST_CHECK(counterDirectory.GetCounterSetCount() == 2);
966 BOOST_CHECK(!counterSetWCountWInvalidParentCategory2);
967
968 // Register a category for testing
969 const std::string categoryName = "some_category";
970 const Category* category = nullptr;
971 BOOST_CHECK_NO_THROW(category = counterDirectory.RegisterCategory(categoryName));
972 BOOST_CHECK(counterDirectory.GetCategoryCount() == 1);
973 BOOST_CHECK(category);
974 BOOST_CHECK(category->m_Name == categoryName);
975 BOOST_CHECK(category->m_Counters.empty());
976 BOOST_CHECK(category->m_DeviceUid == 0);
977 BOOST_CHECK(category->m_CounterSetUid == 0);
978
979 // Register a new counter set with count and valid parent category
980 const std::string counterSetWCountWValidParentCategoryName = "some_counter_set_with_count_"
981 "with_valid_parent_category";
982 const CounterSet* counterSetWCountWValidParentCategory = nullptr;
983 BOOST_CHECK_NO_THROW(counterSetWCountWValidParentCategory
984 = counterDirectory.RegisterCounterSet(counterSetWCountWValidParentCategoryName,
985 42,
Matteo Martincigh657ab2d2019-09-18 10:53:24 +0100986 categoryName));
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100987 BOOST_CHECK(counterDirectory.GetCounterSetCount() == 3);
988 BOOST_CHECK(counterSetWCountWValidParentCategory);
989 BOOST_CHECK(counterSetWCountWValidParentCategory->m_Name == counterSetWCountWValidParentCategoryName);
990 BOOST_CHECK(counterSetWCountWValidParentCategory->m_Uid >= 1);
991 BOOST_CHECK(counterSetWCountWValidParentCategory->m_Uid > counterSet->m_Uid);
992 BOOST_CHECK(counterSetWCountWValidParentCategory->m_Uid > counterSetWCount->m_Uid);
993 BOOST_CHECK(counterSetWCountWValidParentCategory->m_Count == 42);
994 BOOST_CHECK(category->m_CounterSetUid == counterSetWCountWValidParentCategory->m_Uid);
Matteo Martincigh657ab2d2019-09-18 10:53:24 +0100995
996 // Register a counter set associated to a category already associated to a different counter set
997 const std::string counterSetSameCategoryName = "some_counter_set_with_invalid_parent_category";
998 const CounterSet* counterSetSameCategory = nullptr;
999 BOOST_CHECK_THROW(counterSetSameCategory = counterDirectory.RegisterCounterSet(counterSetSameCategoryName,
1000 0,
1001 categoryName),
1002 armnn::InvalidArgumentException);
1003 BOOST_CHECK(counterDirectory.GetCounterSetCount() == 3);
1004 BOOST_CHECK(!counterSetSameCategory);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001005}
1006
1007BOOST_AUTO_TEST_CASE(CheckCounterDirectoryRegisterCounter)
1008{
1009 CounterDirectory counterDirectory;
1010 BOOST_CHECK(counterDirectory.GetCategoryCount() == 0);
1011 BOOST_CHECK(counterDirectory.GetDeviceCount() == 0);
1012 BOOST_CHECK(counterDirectory.GetCounterSetCount() == 0);
1013 BOOST_CHECK(counterDirectory.GetCounterCount() == 0);
1014
1015 // Register a counter with an invalid parent category name
1016 const Counter* noCounter = nullptr;
1017 BOOST_CHECK_THROW(noCounter = counterDirectory.RegisterCounter("",
1018 0,
1019 1,
1020 123.45f,
1021 "valid name",
1022 "valid description"),
1023 armnn::InvalidArgumentException);
1024 BOOST_CHECK(counterDirectory.GetCounterCount() == 0);
1025 BOOST_CHECK(!noCounter);
1026
1027 // Register a counter with an invalid parent category name
1028 BOOST_CHECK_THROW(noCounter = counterDirectory.RegisterCounter("invalid parent category",
1029 0,
1030 1,
1031 123.45f,
1032 "valid name",
1033 "valid description"),
1034 armnn::InvalidArgumentException);
1035 BOOST_CHECK(counterDirectory.GetCounterCount() == 0);
1036 BOOST_CHECK(!noCounter);
1037
1038 // Register a counter with an invalid class
1039 BOOST_CHECK_THROW(noCounter = counterDirectory.RegisterCounter("valid_parent_category",
1040 2,
1041 1,
1042 123.45f,
1043 "valid name",
1044 "valid description"),
1045 armnn::InvalidArgumentException);
1046 BOOST_CHECK(counterDirectory.GetCounterCount() == 0);
1047 BOOST_CHECK(!noCounter);
1048
1049 // Register a counter with an invalid interpolation
1050 BOOST_CHECK_THROW(noCounter = counterDirectory.RegisterCounter("valid_parent_category",
1051 0,
1052 3,
1053 123.45f,
1054 "valid name",
1055 "valid description"),
1056 armnn::InvalidArgumentException);
1057 BOOST_CHECK(counterDirectory.GetCounterCount() == 0);
1058 BOOST_CHECK(!noCounter);
1059
1060 // Register a counter with an invalid multiplier
1061 BOOST_CHECK_THROW(noCounter = counterDirectory.RegisterCounter("valid_parent_category",
1062 0,
1063 1,
1064 .0f,
1065 "valid name",
1066 "valid description"),
1067 armnn::InvalidArgumentException);
1068 BOOST_CHECK(counterDirectory.GetCounterCount() == 0);
1069 BOOST_CHECK(!noCounter);
1070
1071 // Register a counter with an invalid name
1072 BOOST_CHECK_THROW(noCounter = counterDirectory.RegisterCounter("valid_parent_category",
1073 0,
1074 1,
1075 123.45f,
1076 "",
1077 "valid description"),
1078 armnn::InvalidArgumentException);
1079 BOOST_CHECK(counterDirectory.GetCounterCount() == 0);
1080 BOOST_CHECK(!noCounter);
1081
1082 // Register a counter with an invalid name
1083 BOOST_CHECK_THROW(noCounter = counterDirectory.RegisterCounter("valid_parent_category",
1084 0,
1085 1,
1086 123.45f,
1087 "invalid nam€",
1088 "valid description"),
1089 armnn::InvalidArgumentException);
1090 BOOST_CHECK(counterDirectory.GetCounterCount() == 0);
1091 BOOST_CHECK(!noCounter);
1092
1093 // Register a counter with an invalid description
1094 BOOST_CHECK_THROW(noCounter = counterDirectory.RegisterCounter("valid_parent_category",
1095 0,
1096 1,
1097 123.45f,
1098 "valid name",
1099 ""),
1100 armnn::InvalidArgumentException);
1101 BOOST_CHECK(counterDirectory.GetCounterCount() == 0);
1102 BOOST_CHECK(!noCounter);
1103
1104 // Register a counter with an invalid description
1105 BOOST_CHECK_THROW(noCounter = counterDirectory.RegisterCounter("valid_parent_category",
1106 0,
1107 1,
1108 123.45f,
1109 "valid name",
1110 "inv@lid description"),
1111 armnn::InvalidArgumentException);
1112 BOOST_CHECK(counterDirectory.GetCounterCount() == 0);
1113 BOOST_CHECK(!noCounter);
1114
1115 // Register a counter with an invalid unit2
1116 BOOST_CHECK_THROW(noCounter = counterDirectory.RegisterCounter("valid_parent_category",
1117 0,
1118 1,
1119 123.45f,
1120 "valid name",
1121 "valid description",
1122 std::string("Mb/s2")),
1123 armnn::InvalidArgumentException);
1124 BOOST_CHECK(counterDirectory.GetCounterCount() == 0);
1125 BOOST_CHECK(!noCounter);
1126
1127 // Register a counter with a non-existing parent category name
1128 BOOST_CHECK_THROW(noCounter = counterDirectory.RegisterCounter("invalid_parent_category",
1129 0,
1130 1,
1131 123.45f,
1132 "valid name",
1133 "valid description"),
1134 armnn::InvalidArgumentException);
1135 BOOST_CHECK(counterDirectory.GetCounterCount() == 0);
1136 BOOST_CHECK(!noCounter);
1137
Matteo Martincigh657ab2d2019-09-18 10:53:24 +01001138 // Try getting an unregistered counter
1139 const Counter* unregisteredCounter = counterDirectory.GetCounter(9999);
1140 BOOST_CHECK(!unregisteredCounter);
1141
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001142 // Register a category for testing
1143 const std::string categoryName = "some_category";
1144 const Category* category = nullptr;
1145 BOOST_CHECK_NO_THROW(category = counterDirectory.RegisterCategory(categoryName));
1146 BOOST_CHECK(counterDirectory.GetCategoryCount() == 1);
1147 BOOST_CHECK(category);
1148 BOOST_CHECK(category->m_Name == categoryName);
1149 BOOST_CHECK(category->m_Counters.empty());
1150 BOOST_CHECK(category->m_DeviceUid == 0);
1151 BOOST_CHECK(category->m_CounterSetUid == 0);
1152
1153 // Register a counter with a valid parent category name
1154 const Counter* counter = nullptr;
1155 BOOST_CHECK_NO_THROW(counter = counterDirectory.RegisterCounter(categoryName,
1156 0,
1157 1,
1158 123.45f,
1159 "valid name",
1160 "valid description"));
1161 BOOST_CHECK(counterDirectory.GetCounterCount() == 1);
1162 BOOST_CHECK(counter);
1163 BOOST_CHECK(counter->m_Uid >= 0);
1164 BOOST_CHECK(counter->m_MaxCounterUid == counter->m_Uid);
1165 BOOST_CHECK(counter->m_Class == 0);
1166 BOOST_CHECK(counter->m_Interpolation == 1);
1167 BOOST_CHECK(counter->m_Multiplier == 123.45f);
1168 BOOST_CHECK(counter->m_Name == "valid name");
1169 BOOST_CHECK(counter->m_Description == "valid description");
1170 BOOST_CHECK(counter->m_Units == "");
1171 BOOST_CHECK(counter->m_DeviceUid == 0);
1172 BOOST_CHECK(counter->m_CounterSetUid == 0);
1173 BOOST_CHECK(category->m_Counters.size() == 1);
1174 BOOST_CHECK(category->m_Counters.back() == counter->m_Uid);
1175
Matteo Martincigh657ab2d2019-09-18 10:53:24 +01001176 // Register a counter with a name of a counter already registered for the given parent category name
1177 const Counter* counterSameName = nullptr;
1178 BOOST_CHECK_THROW(counterSameName = counterDirectory.RegisterCounter(categoryName,
1179 0,
1180 0,
1181 1.0f,
1182 "valid name",
1183 "valid description"),
1184 armnn::InvalidArgumentException);
1185 BOOST_CHECK(counterDirectory.GetCounterCount() == 1);
1186 BOOST_CHECK(!counterSameName);
1187
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001188 // Register a counter with a valid parent category name and units
1189 const Counter* counterWUnits = nullptr;
1190 BOOST_CHECK_NO_THROW(counterWUnits = counterDirectory.RegisterCounter(categoryName,
1191 0,
1192 1,
1193 123.45f,
1194 "valid name 2",
1195 "valid description",
1196 std::string("Mnnsq2"))); // Units
1197 BOOST_CHECK(counterDirectory.GetCounterCount() == 2);
1198 BOOST_CHECK(counterWUnits);
1199 BOOST_CHECK(counterWUnits->m_Uid >= 0);
1200 BOOST_CHECK(counterWUnits->m_Uid > counter->m_Uid);
1201 BOOST_CHECK(counterWUnits->m_MaxCounterUid == counterWUnits->m_Uid);
1202 BOOST_CHECK(counterWUnits->m_Class == 0);
1203 BOOST_CHECK(counterWUnits->m_Interpolation == 1);
1204 BOOST_CHECK(counterWUnits->m_Multiplier == 123.45f);
1205 BOOST_CHECK(counterWUnits->m_Name == "valid name 2");
1206 BOOST_CHECK(counterWUnits->m_Description == "valid description");
1207 BOOST_CHECK(counterWUnits->m_Units == "Mnnsq2");
1208 BOOST_CHECK(counterWUnits->m_DeviceUid == 0);
1209 BOOST_CHECK(counterWUnits->m_CounterSetUid == 0);
1210 BOOST_CHECK(category->m_Counters.size() == 2);
1211 BOOST_CHECK(category->m_Counters.back() == counterWUnits->m_Uid);
1212
1213 // Register a counter with a valid parent category name and not associated with a device
1214 const Counter* counterWoDevice = nullptr;
1215 BOOST_CHECK_NO_THROW(counterWoDevice = counterDirectory.RegisterCounter(categoryName,
1216 0,
1217 1,
1218 123.45f,
1219 "valid name 3",
1220 "valid description",
1221 armnn::EmptyOptional(), // Units
1222 armnn::EmptyOptional(), // Number of cores
1223 0)); // Device UID
1224 BOOST_CHECK(counterDirectory.GetCounterCount() == 3);
1225 BOOST_CHECK(counterWoDevice);
1226 BOOST_CHECK(counterWoDevice->m_Uid >= 0);
1227 BOOST_CHECK(counterWoDevice->m_Uid > counter->m_Uid);
1228 BOOST_CHECK(counterWoDevice->m_MaxCounterUid == counterWoDevice->m_Uid);
1229 BOOST_CHECK(counterWoDevice->m_Class == 0);
1230 BOOST_CHECK(counterWoDevice->m_Interpolation == 1);
1231 BOOST_CHECK(counterWoDevice->m_Multiplier == 123.45f);
1232 BOOST_CHECK(counterWoDevice->m_Name == "valid name 3");
1233 BOOST_CHECK(counterWoDevice->m_Description == "valid description");
1234 BOOST_CHECK(counterWoDevice->m_Units == "");
1235 BOOST_CHECK(counterWoDevice->m_DeviceUid == 0);
1236 BOOST_CHECK(counterWoDevice->m_CounterSetUid == 0);
1237 BOOST_CHECK(category->m_Counters.size() == 3);
1238 BOOST_CHECK(category->m_Counters.back() == counterWoDevice->m_Uid);
1239
1240 // Register a counter with a valid parent category name and associated to an invalid device
1241 BOOST_CHECK_THROW(noCounter = counterDirectory.RegisterCounter(categoryName,
1242 0,
1243 1,
1244 123.45f,
1245 "valid name 4",
1246 "valid description",
1247 armnn::EmptyOptional(), // Units
1248 armnn::EmptyOptional(), // Number of cores
1249 100), // Device UID
1250 armnn::InvalidArgumentException);
1251 BOOST_CHECK(counterDirectory.GetCounterCount() == 3);
1252 BOOST_CHECK(!noCounter);
1253
1254 // Register a device for testing
1255 const std::string deviceName = "some_device";
1256 const Device* device = nullptr;
1257 BOOST_CHECK_NO_THROW(device = counterDirectory.RegisterDevice(deviceName));
1258 BOOST_CHECK(counterDirectory.GetDeviceCount() == 1);
1259 BOOST_CHECK(device);
1260 BOOST_CHECK(device->m_Name == deviceName);
1261 BOOST_CHECK(device->m_Uid >= 1);
1262 BOOST_CHECK(device->m_Cores == 0);
1263
1264 // Register a counter with a valid parent category name and associated to a device
1265 const Counter* counterWDevice = nullptr;
1266 BOOST_CHECK_NO_THROW(counterWDevice = counterDirectory.RegisterCounter(categoryName,
1267 0,
1268 1,
1269 123.45f,
1270 "valid name 5",
1271 "valid description",
1272 armnn::EmptyOptional(), // Units
1273 armnn::EmptyOptional(), // Number of cores
1274 device->m_Uid)); // Device UID
1275 BOOST_CHECK(counterDirectory.GetCounterCount() == 4);
1276 BOOST_CHECK(counterWDevice);
1277 BOOST_CHECK(counterWDevice->m_Uid >= 0);
1278 BOOST_CHECK(counterWDevice->m_Uid > counter->m_Uid);
1279 BOOST_CHECK(counterWDevice->m_MaxCounterUid == counterWDevice->m_Uid);
1280 BOOST_CHECK(counterWDevice->m_Class == 0);
1281 BOOST_CHECK(counterWDevice->m_Interpolation == 1);
1282 BOOST_CHECK(counterWDevice->m_Multiplier == 123.45f);
1283 BOOST_CHECK(counterWDevice->m_Name == "valid name 5");
1284 BOOST_CHECK(counterWDevice->m_Description == "valid description");
1285 BOOST_CHECK(counterWDevice->m_Units == "");
1286 BOOST_CHECK(counterWDevice->m_DeviceUid == device->m_Uid);
1287 BOOST_CHECK(counterWDevice->m_CounterSetUid == 0);
1288 BOOST_CHECK(category->m_Counters.size() == 4);
1289 BOOST_CHECK(category->m_Counters.back() == counterWDevice->m_Uid);
1290
1291 // Register a counter with a valid parent category name and not associated with a counter set
1292 const Counter* counterWoCounterSet = nullptr;
1293 BOOST_CHECK_NO_THROW(counterWoCounterSet
1294 = counterDirectory.RegisterCounter(categoryName,
1295 0,
1296 1,
1297 123.45f,
1298 "valid name 6",
1299 "valid description",
1300 armnn::EmptyOptional(), // Units
1301 armnn::EmptyOptional(), // Number of cores
1302 armnn::EmptyOptional(), // Device UID
1303 0)); // Counter set UID
1304 BOOST_CHECK(counterDirectory.GetCounterCount() == 5);
1305 BOOST_CHECK(counterWoCounterSet);
1306 BOOST_CHECK(counterWoCounterSet->m_Uid >= 0);
1307 BOOST_CHECK(counterWoCounterSet->m_Uid > counter->m_Uid);
1308 BOOST_CHECK(counterWoCounterSet->m_MaxCounterUid == counterWoCounterSet->m_Uid);
1309 BOOST_CHECK(counterWoCounterSet->m_Class == 0);
1310 BOOST_CHECK(counterWoCounterSet->m_Interpolation == 1);
1311 BOOST_CHECK(counterWoCounterSet->m_Multiplier == 123.45f);
1312 BOOST_CHECK(counterWoCounterSet->m_Name == "valid name 6");
1313 BOOST_CHECK(counterWoCounterSet->m_Description == "valid description");
1314 BOOST_CHECK(counterWoCounterSet->m_Units == "");
1315 BOOST_CHECK(counterWoCounterSet->m_DeviceUid == 0);
1316 BOOST_CHECK(counterWoCounterSet->m_CounterSetUid == 0);
1317 BOOST_CHECK(category->m_Counters.size() == 5);
1318 BOOST_CHECK(category->m_Counters.back() == counterWoCounterSet->m_Uid);
1319
1320 // Register a counter with a valid parent category name and associated to an invalid counter set
1321 BOOST_CHECK_THROW(noCounter = counterDirectory.RegisterCounter(categoryName,
1322 0,
1323 1,
1324 123.45f,
1325 "valid name 7",
1326 "valid description",
1327 armnn::EmptyOptional(), // Units
1328 armnn::EmptyOptional(), // Number of cores
1329 armnn::EmptyOptional(), // Device UID
1330 100), // Counter set UID
1331 armnn::InvalidArgumentException);
1332 BOOST_CHECK(counterDirectory.GetCounterCount() == 5);
1333 BOOST_CHECK(!noCounter);
1334
1335 // Register a counter with a valid parent category name and with a given number of cores
1336 const Counter* counterWNumberOfCores = nullptr;
1337 uint16_t numberOfCores = 15;
1338 BOOST_CHECK_NO_THROW(counterWNumberOfCores
1339 = counterDirectory.RegisterCounter(categoryName,
1340 0,
1341 1,
1342 123.45f,
1343 "valid name 8",
1344 "valid description",
1345 armnn::EmptyOptional(), // Units
1346 numberOfCores, // Number of cores
1347 armnn::EmptyOptional(), // Device UID
1348 armnn::EmptyOptional())); // Counter set UID
1349 BOOST_CHECK(counterDirectory.GetCounterCount() == 20);
1350 BOOST_CHECK(counterWNumberOfCores);
1351 BOOST_CHECK(counterWNumberOfCores->m_Uid >= 0);
1352 BOOST_CHECK(counterWNumberOfCores->m_Uid > counter->m_Uid);
1353 BOOST_CHECK(counterWNumberOfCores->m_MaxCounterUid == counterWNumberOfCores->m_Uid + numberOfCores - 1);
1354 BOOST_CHECK(counterWNumberOfCores->m_Class == 0);
1355 BOOST_CHECK(counterWNumberOfCores->m_Interpolation == 1);
1356 BOOST_CHECK(counterWNumberOfCores->m_Multiplier == 123.45f);
1357 BOOST_CHECK(counterWNumberOfCores->m_Name == "valid name 8");
1358 BOOST_CHECK(counterWNumberOfCores->m_Description == "valid description");
1359 BOOST_CHECK(counterWNumberOfCores->m_Units == "");
1360 BOOST_CHECK(counterWNumberOfCores->m_DeviceUid == 0);
1361 BOOST_CHECK(counterWNumberOfCores->m_CounterSetUid == 0);
1362 BOOST_CHECK(category->m_Counters.size() == 20);
1363 for (size_t i = 0; i < numberOfCores; i ++)
1364 {
1365 BOOST_CHECK(category->m_Counters[category->m_Counters.size() - numberOfCores + i] ==
1366 counterWNumberOfCores->m_Uid + i);
1367 }
1368
1369 // Register a multi-core device for testing
1370 const std::string multiCoreDeviceName = "some_multi_core_device";
1371 const Device* multiCoreDevice = nullptr;
1372 BOOST_CHECK_NO_THROW(multiCoreDevice = counterDirectory.RegisterDevice(multiCoreDeviceName, 4));
1373 BOOST_CHECK(counterDirectory.GetDeviceCount() == 2);
1374 BOOST_CHECK(multiCoreDevice);
1375 BOOST_CHECK(multiCoreDevice->m_Name == multiCoreDeviceName);
1376 BOOST_CHECK(multiCoreDevice->m_Uid >= 1);
1377 BOOST_CHECK(multiCoreDevice->m_Cores == 4);
1378
1379 // Register a counter with a valid parent category name and associated to the multi-core device
1380 const Counter* counterWMultiCoreDevice = nullptr;
1381 BOOST_CHECK_NO_THROW(counterWMultiCoreDevice
1382 = counterDirectory.RegisterCounter(categoryName,
1383 0,
1384 1,
1385 123.45f,
1386 "valid name 9",
1387 "valid description",
1388 armnn::EmptyOptional(), // Units
1389 armnn::EmptyOptional(), // Number of cores
1390 multiCoreDevice->m_Uid, // Device UID
1391 armnn::EmptyOptional())); // Counter set UID
1392 BOOST_CHECK(counterDirectory.GetCounterCount() == 24);
1393 BOOST_CHECK(counterWMultiCoreDevice);
1394 BOOST_CHECK(counterWMultiCoreDevice->m_Uid >= 0);
1395 BOOST_CHECK(counterWMultiCoreDevice->m_Uid > counter->m_Uid);
1396 BOOST_CHECK(counterWMultiCoreDevice->m_MaxCounterUid ==
1397 counterWMultiCoreDevice->m_Uid + multiCoreDevice->m_Cores - 1);
1398 BOOST_CHECK(counterWMultiCoreDevice->m_Class == 0);
1399 BOOST_CHECK(counterWMultiCoreDevice->m_Interpolation == 1);
1400 BOOST_CHECK(counterWMultiCoreDevice->m_Multiplier == 123.45f);
1401 BOOST_CHECK(counterWMultiCoreDevice->m_Name == "valid name 9");
1402 BOOST_CHECK(counterWMultiCoreDevice->m_Description == "valid description");
1403 BOOST_CHECK(counterWMultiCoreDevice->m_Units == "");
1404 BOOST_CHECK(counterWMultiCoreDevice->m_DeviceUid == multiCoreDevice->m_Uid);
1405 BOOST_CHECK(counterWMultiCoreDevice->m_CounterSetUid == 0);
1406 BOOST_CHECK(category->m_Counters.size() == 24);
1407 for (size_t i = 0; i < 4; i ++)
1408 {
1409 BOOST_CHECK(category->m_Counters[category->m_Counters.size() - 4 + i] == counterWMultiCoreDevice->m_Uid + i);
1410 }
1411
Matteo Martincigh657ab2d2019-09-18 10:53:24 +01001412 // Register a multi-core device associate to a parent category for testing
1413 const std::string multiCoreDeviceNameWParentCategory = "some_multi_core_device_with_parent_category";
1414 const Device* multiCoreDeviceWParentCategory = nullptr;
1415 BOOST_CHECK_NO_THROW(multiCoreDeviceWParentCategory =
1416 counterDirectory.RegisterDevice(multiCoreDeviceNameWParentCategory, 2, categoryName));
1417 BOOST_CHECK(counterDirectory.GetDeviceCount() == 3);
1418 BOOST_CHECK(multiCoreDeviceWParentCategory);
1419 BOOST_CHECK(multiCoreDeviceWParentCategory->m_Name == multiCoreDeviceNameWParentCategory);
1420 BOOST_CHECK(multiCoreDeviceWParentCategory->m_Uid >= 1);
1421 BOOST_CHECK(multiCoreDeviceWParentCategory->m_Cores == 2);
1422
1423 // Register a counter with a valid parent category name and getting the number of cores of the multi-core device
1424 // associated to that category
1425 const Counter* counterWMultiCoreDeviceWParentCategory = nullptr;
1426 BOOST_CHECK_NO_THROW(counterWMultiCoreDeviceWParentCategory
1427 = counterDirectory.RegisterCounter(categoryName,
1428 0,
1429 1,
1430 123.45f,
1431 "valid name 10",
1432 "valid description",
1433 armnn::EmptyOptional(), // Units
1434 armnn::EmptyOptional(), // Number of cores
1435 armnn::EmptyOptional(), // Device UID
1436 armnn::EmptyOptional())); // Counter set UID
1437 BOOST_CHECK(counterDirectory.GetCounterCount() == 26);
1438 BOOST_CHECK(counterWMultiCoreDeviceWParentCategory);
1439 BOOST_CHECK(counterWMultiCoreDeviceWParentCategory->m_Uid >= 0);
1440 BOOST_CHECK(counterWMultiCoreDeviceWParentCategory->m_Uid > counter->m_Uid);
1441 BOOST_CHECK(counterWMultiCoreDeviceWParentCategory->m_MaxCounterUid ==
1442 counterWMultiCoreDeviceWParentCategory->m_Uid + multiCoreDeviceWParentCategory->m_Cores - 1);
1443 BOOST_CHECK(counterWMultiCoreDeviceWParentCategory->m_Class == 0);
1444 BOOST_CHECK(counterWMultiCoreDeviceWParentCategory->m_Interpolation == 1);
1445 BOOST_CHECK(counterWMultiCoreDeviceWParentCategory->m_Multiplier == 123.45f);
1446 BOOST_CHECK(counterWMultiCoreDeviceWParentCategory->m_Name == "valid name 10");
1447 BOOST_CHECK(counterWMultiCoreDeviceWParentCategory->m_Description == "valid description");
1448 BOOST_CHECK(counterWMultiCoreDeviceWParentCategory->m_Units == "");
1449 BOOST_CHECK(counterWMultiCoreDeviceWParentCategory->m_DeviceUid == 0);
1450 BOOST_CHECK(counterWMultiCoreDeviceWParentCategory->m_CounterSetUid == 0);
1451 BOOST_CHECK(category->m_Counters.size() == 26);
1452 for (size_t i = 0; i < 2; i ++)
1453 {
1454 BOOST_CHECK(category->m_Counters[category->m_Counters.size() - 2 + i] ==
1455 counterWMultiCoreDeviceWParentCategory->m_Uid + i);
1456 }
1457
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001458 // Register a counter set for testing
1459 const std::string counterSetName = "some_counter_set";
1460 const CounterSet* counterSet = nullptr;
1461 BOOST_CHECK_NO_THROW(counterSet = counterDirectory.RegisterCounterSet(counterSetName));
1462 BOOST_CHECK(counterDirectory.GetCounterSetCount() == 1);
1463 BOOST_CHECK(counterSet);
1464 BOOST_CHECK(counterSet->m_Name == counterSetName);
1465 BOOST_CHECK(counterSet->m_Uid >= 1);
1466 BOOST_CHECK(counterSet->m_Count == 0);
1467
1468 // Register a counter with a valid parent category name and associated to a counter set
1469 const Counter* counterWCounterSet = nullptr;
1470 BOOST_CHECK_NO_THROW(counterWCounterSet
1471 = counterDirectory.RegisterCounter(categoryName,
1472 0,
1473 1,
1474 123.45f,
Matteo Martincigh657ab2d2019-09-18 10:53:24 +01001475 "valid name 11",
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001476 "valid description",
1477 armnn::EmptyOptional(), // Units
Matteo Martincigh657ab2d2019-09-18 10:53:24 +01001478 0, // Number of cores
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001479 armnn::EmptyOptional(), // Device UID
1480 counterSet->m_Uid)); // Counter set UID
Matteo Martincigh657ab2d2019-09-18 10:53:24 +01001481 BOOST_CHECK(counterDirectory.GetCounterCount() == 27);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001482 BOOST_CHECK(counterWCounterSet);
1483 BOOST_CHECK(counterWCounterSet->m_Uid >= 0);
1484 BOOST_CHECK(counterWCounterSet->m_Uid > counter->m_Uid);
1485 BOOST_CHECK(counterWCounterSet->m_MaxCounterUid == counterWCounterSet->m_Uid);
1486 BOOST_CHECK(counterWCounterSet->m_Class == 0);
1487 BOOST_CHECK(counterWCounterSet->m_Interpolation == 1);
1488 BOOST_CHECK(counterWCounterSet->m_Multiplier == 123.45f);
Matteo Martincigh657ab2d2019-09-18 10:53:24 +01001489 BOOST_CHECK(counterWCounterSet->m_Name == "valid name 11");
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001490 BOOST_CHECK(counterWCounterSet->m_Description == "valid description");
1491 BOOST_CHECK(counterWCounterSet->m_Units == "");
1492 BOOST_CHECK(counterWCounterSet->m_DeviceUid == 0);
1493 BOOST_CHECK(counterWCounterSet->m_CounterSetUid == counterSet->m_Uid);
Matteo Martincigh657ab2d2019-09-18 10:53:24 +01001494 BOOST_CHECK(category->m_Counters.size() == 27);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001495 BOOST_CHECK(category->m_Counters.back() == counterWCounterSet->m_Uid);
1496
1497 // Register a counter with a valid parent category name and associated to a device and a counter set
1498 const Counter* counterWDeviceWCounterSet = nullptr;
1499 BOOST_CHECK_NO_THROW(counterWDeviceWCounterSet
1500 = counterDirectory.RegisterCounter(categoryName,
1501 0,
1502 1,
1503 123.45f,
Matteo Martincigh657ab2d2019-09-18 10:53:24 +01001504 "valid name 12",
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001505 "valid description",
1506 armnn::EmptyOptional(), // Units
Matteo Martincigh657ab2d2019-09-18 10:53:24 +01001507 1, // Number of cores
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001508 device->m_Uid, // Device UID
1509 counterSet->m_Uid)); // Counter set UID
Matteo Martincigh657ab2d2019-09-18 10:53:24 +01001510 BOOST_CHECK(counterDirectory.GetCounterCount() == 28);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001511 BOOST_CHECK(counterWDeviceWCounterSet);
1512 BOOST_CHECK(counterWDeviceWCounterSet->m_Uid >= 0);
1513 BOOST_CHECK(counterWDeviceWCounterSet->m_Uid > counter->m_Uid);
1514 BOOST_CHECK(counterWDeviceWCounterSet->m_MaxCounterUid == counterWDeviceWCounterSet->m_Uid);
1515 BOOST_CHECK(counterWDeviceWCounterSet->m_Class == 0);
1516 BOOST_CHECK(counterWDeviceWCounterSet->m_Interpolation == 1);
1517 BOOST_CHECK(counterWDeviceWCounterSet->m_Multiplier == 123.45f);
Matteo Martincigh657ab2d2019-09-18 10:53:24 +01001518 BOOST_CHECK(counterWDeviceWCounterSet->m_Name == "valid name 12");
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001519 BOOST_CHECK(counterWDeviceWCounterSet->m_Description == "valid description");
1520 BOOST_CHECK(counterWDeviceWCounterSet->m_Units == "");
1521 BOOST_CHECK(counterWDeviceWCounterSet->m_DeviceUid == device->m_Uid);
1522 BOOST_CHECK(counterWDeviceWCounterSet->m_CounterSetUid == counterSet->m_Uid);
Matteo Martincigh657ab2d2019-09-18 10:53:24 +01001523 BOOST_CHECK(category->m_Counters.size() == 28);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001524 BOOST_CHECK(category->m_Counters.back() == counterWDeviceWCounterSet->m_Uid);
1525
1526 // Register another category for testing
1527 const std::string anotherCategoryName = "some_other_category";
1528 const Category* anotherCategory = nullptr;
1529 BOOST_CHECK_NO_THROW(anotherCategory = counterDirectory.RegisterCategory(anotherCategoryName));
1530 BOOST_CHECK(counterDirectory.GetCategoryCount() == 2);
1531 BOOST_CHECK(anotherCategory);
1532 BOOST_CHECK(anotherCategory != category);
1533 BOOST_CHECK(anotherCategory->m_Name == anotherCategoryName);
1534 BOOST_CHECK(anotherCategory->m_Counters.empty());
1535 BOOST_CHECK(anotherCategory->m_DeviceUid == 0);
1536 BOOST_CHECK(anotherCategory->m_CounterSetUid == 0);
1537
1538 // Register a counter to the other category
1539 const Counter* anotherCounter = nullptr;
1540 BOOST_CHECK_NO_THROW(anotherCounter = counterDirectory.RegisterCounter(anotherCategoryName,
1541 1,
1542 0,
1543 .00043f,
1544 "valid name",
1545 "valid description",
1546 armnn::EmptyOptional(), // Units
1547 armnn::EmptyOptional(), // Number of cores
1548 device->m_Uid, // Device UID
1549 counterSet->m_Uid)); // Counter set UID
Matteo Martincigh657ab2d2019-09-18 10:53:24 +01001550 BOOST_CHECK(counterDirectory.GetCounterCount() == 29);
Matteo Martincigh6db5f202019-09-05 12:02:04 +01001551 BOOST_CHECK(anotherCounter);
1552 BOOST_CHECK(anotherCounter->m_Uid >= 0);
1553 BOOST_CHECK(anotherCounter->m_MaxCounterUid == anotherCounter->m_Uid);
1554 BOOST_CHECK(anotherCounter->m_Class == 1);
1555 BOOST_CHECK(anotherCounter->m_Interpolation == 0);
1556 BOOST_CHECK(anotherCounter->m_Multiplier == .00043f);
1557 BOOST_CHECK(anotherCounter->m_Name == "valid name");
1558 BOOST_CHECK(anotherCounter->m_Description == "valid description");
1559 BOOST_CHECK(anotherCounter->m_Units == "");
1560 BOOST_CHECK(anotherCounter->m_DeviceUid == device->m_Uid);
1561 BOOST_CHECK(anotherCounter->m_CounterSetUid == counterSet->m_Uid);
1562 BOOST_CHECK(anotherCategory->m_Counters.size() == 1);
1563 BOOST_CHECK(anotherCategory->m_Counters.back() == anotherCounter->m_Uid);
Matteo Martincighab173e92019-09-05 12:02:04 +01001564}
1565
Ferran Balaguer1b941722019-08-28 16:57:18 +01001566BOOST_AUTO_TEST_CASE(CounterSelectionCommandHandlerParseData)
1567{
1568 using boost::numeric_cast;
1569
1570 class TestCaptureThread : public IPeriodicCounterCapture
1571 {
1572 void Start() override {};
1573 };
1574
1575 const uint32_t packetId = 0x40000;
1576
1577 uint32_t version = 1;
1578 Holder holder;
1579 TestCaptureThread captureThread;
1580 MockBuffer mockBuffer(512);
1581 SendCounterPacket sendCounterPacket(mockBuffer);
1582
1583 uint32_t sizeOfUint32 = numeric_cast<uint32_t>(sizeof(uint32_t));
1584 uint32_t sizeOfUint16 = numeric_cast<uint32_t>(sizeof(uint16_t));
1585
1586 // Data with period and counters
1587 uint32_t period1 = 10;
1588 uint32_t dataLength1 = 8;
Ferran Balaguer1b941722019-08-28 16:57:18 +01001589 uint32_t offset = 0;
1590
FinnWilliamsArma0c78712019-09-16 12:06:47 +01001591 std::unique_ptr<char[]> uniqueData1 = std::make_unique<char[]>(dataLength1);
1592 unsigned char* data1 = reinterpret_cast<unsigned char*>(uniqueData1.get());
1593
Ferran Balaguer1b941722019-08-28 16:57:18 +01001594 WriteUint32(data1, offset, period1);
1595 offset += sizeOfUint32;
1596 WriteUint16(data1, offset, 4000);
1597 offset += sizeOfUint16;
1598 WriteUint16(data1, offset, 5000);
1599
FinnWilliamsArma0c78712019-09-16 12:06:47 +01001600 Packet packetA(packetId, dataLength1, uniqueData1);
Ferran Balaguer1b941722019-08-28 16:57:18 +01001601
1602 PeriodicCounterSelectionCommandHandler commandHandler(packetId, version, holder, captureThread,
1603 sendCounterPacket);
1604 commandHandler(packetA);
1605
1606 std::vector<uint16_t> counterIds = holder.GetCaptureData().GetCounterIds();
1607
1608 BOOST_TEST(holder.GetCaptureData().GetCapturePeriod() == period1);
1609 BOOST_TEST(counterIds.size() == 2);
1610 BOOST_TEST(counterIds[0] == 4000);
1611 BOOST_TEST(counterIds[1] == 5000);
1612
1613 unsigned int size = 0;
1614
1615 const unsigned char* readBuffer = mockBuffer.GetReadBuffer(size);
1616
1617 offset = 0;
1618
1619 uint32_t headerWord0 = ReadUint32(readBuffer, offset);
1620 offset += sizeOfUint32;
1621 uint32_t headerWord1 = ReadUint32(readBuffer, offset);
1622 offset += sizeOfUint32;
1623 uint32_t period = ReadUint32(readBuffer, offset);
1624
1625 BOOST_TEST(((headerWord0 >> 26) & 0x3F) == 0); // packet family
1626 BOOST_TEST(((headerWord0 >> 16) & 0x3FF) == 4); // packet id
1627 BOOST_TEST(headerWord1 == 8); // data lenght
1628 BOOST_TEST(period == 10); // capture period
1629
1630 uint16_t counterId = 0;
1631 offset += sizeOfUint32;
1632 counterId = ReadUint16(readBuffer, offset);
1633 BOOST_TEST(counterId == 4000);
1634 offset += sizeOfUint16;
1635 counterId = ReadUint16(readBuffer, offset);
1636 BOOST_TEST(counterId == 5000);
1637
1638 // Data with period only
1639 uint32_t period2 = 11;
1640 uint32_t dataLength2 = 4;
Ferran Balaguer1b941722019-08-28 16:57:18 +01001641
FinnWilliamsArma0c78712019-09-16 12:06:47 +01001642 std::unique_ptr<char[]> uniqueData2 = std::make_unique<char[]>(dataLength2);
Ferran Balaguer1b941722019-08-28 16:57:18 +01001643
FinnWilliamsArma0c78712019-09-16 12:06:47 +01001644 WriteUint32(reinterpret_cast<unsigned char*>(uniqueData2.get()), 0, period2);
1645
1646 Packet packetB(packetId, dataLength2, uniqueData2);
Ferran Balaguer1b941722019-08-28 16:57:18 +01001647
1648 commandHandler(packetB);
1649
1650 counterIds = holder.GetCaptureData().GetCounterIds();
1651
1652 BOOST_TEST(holder.GetCaptureData().GetCapturePeriod() == period2);
1653 BOOST_TEST(counterIds.size() == 0);
1654
1655 readBuffer = mockBuffer.GetReadBuffer(size);
1656
1657 offset = 0;
1658
1659 headerWord0 = ReadUint32(readBuffer, offset);
1660 offset += sizeOfUint32;
1661 headerWord1 = ReadUint32(readBuffer, offset);
1662 offset += sizeOfUint32;
1663 period = ReadUint32(readBuffer, offset);
1664
1665 BOOST_TEST(((headerWord0 >> 26) & 0x3F) == 0); // packet family
1666 BOOST_TEST(((headerWord0 >> 16) & 0x3FF) == 4); // packet id
1667 BOOST_TEST(headerWord1 == 4); // data lenght
1668 BOOST_TEST(period == 11); // capture period
Ferran Balaguer1b941722019-08-28 16:57:18 +01001669}
1670
Sadik Armaganb5f01b22019-09-18 17:29:00 +01001671BOOST_AUTO_TEST_CASE(CheckConnectionAcknowledged)
1672{
1673 using boost::numeric_cast;
1674
1675 const uint32_t connectionPacketId = 0x10000;
1676 const uint32_t version = 1;
1677
1678 uint32_t sizeOfUint32 = numeric_cast<uint32_t>(sizeof(uint32_t));
1679 uint32_t sizeOfUint16 = numeric_cast<uint32_t>(sizeof(uint16_t));
1680
1681 // Data with period and counters
1682 uint32_t period1 = 10;
1683 uint32_t dataLength1 = 8;
1684 uint32_t offset = 0;
1685
1686 std::unique_ptr<char[]> uniqueData1 = std::make_unique<char[]>(dataLength1);
1687 unsigned char* data1 = reinterpret_cast<unsigned char*>(uniqueData1.get());
1688
1689 WriteUint32(data1, offset, period1);
1690 offset += sizeOfUint32;
1691 WriteUint16(data1, offset, 4000);
1692 offset += sizeOfUint16;
1693 WriteUint16(data1, offset, 5000);
1694
1695 Packet packetA(connectionPacketId, dataLength1, uniqueData1);
1696
1697 ProfilingStateMachine profilingState(ProfilingState::Uninitialised);
1698 BOOST_CHECK(profilingState.GetCurrentState() == ProfilingState::Uninitialised);
1699
1700 ConnectionAcknowledgedCommandHandler commandHandler(connectionPacketId, version, profilingState);
1701
1702 // command handler received packet on ProfilingState::Uninitialised
1703 BOOST_CHECK_THROW(commandHandler(packetA), armnn::Exception);
1704
1705 profilingState.TransitionToState(ProfilingState::NotConnected);
1706 BOOST_CHECK(profilingState.GetCurrentState() == ProfilingState::NotConnected);
1707 // command handler received packet on ProfilingState::NotConnected
1708 BOOST_CHECK_THROW(commandHandler(packetA), armnn::Exception);
1709
1710 profilingState.TransitionToState(ProfilingState::WaitingForAck);
1711 BOOST_CHECK(profilingState.GetCurrentState() == ProfilingState::WaitingForAck);
1712 // command handler received packet on ProfilingState::WaitingForAck
1713 commandHandler(packetA);
1714 BOOST_CHECK(profilingState.GetCurrentState() == ProfilingState::Active);
1715
1716 // command handler received packet on ProfilingState::Active
1717 commandHandler(packetA);
1718 BOOST_CHECK(profilingState.GetCurrentState() == ProfilingState::Active);
1719
1720 // command handler received different packet
1721 const uint32_t differentPacketId = 0x40000;
1722 Packet packetB(differentPacketId, dataLength1, uniqueData1);
1723 ConnectionAcknowledgedCommandHandler differentCommandHandler(differentPacketId, version, profilingState);
1724 BOOST_CHECK_THROW(differentCommandHandler(packetB), armnn::Exception);
1725}
1726
Teresa Charlin9bab4962019-09-06 12:28:35 +01001727BOOST_AUTO_TEST_CASE(CheckSocketProfilingConnection)
1728{
1729 // Check that creating a SocketProfilingConnection results in an exception as the Gator UDS doesn't exist.
1730 BOOST_CHECK_THROW(new SocketProfilingConnection(), armnn::Exception);
1731}
1732
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +01001733BOOST_AUTO_TEST_CASE(SwTraceIsValidCharTest)
1734{
1735 // Only ASCII 7-bit encoding supported
1736 for (unsigned char c = 0; c < 128; c++)
1737 {
1738 BOOST_CHECK(SwTraceCharPolicy::IsValidChar(c));
1739 }
1740
1741 // Not ASCII
1742 for (unsigned char c = 255; c >= 128; c++)
1743 {
1744 BOOST_CHECK(!SwTraceCharPolicy::IsValidChar(c));
1745 }
1746}
1747
1748BOOST_AUTO_TEST_CASE(SwTraceIsValidNameCharTest)
1749{
1750 // Only alpha-numeric and underscore ASCII 7-bit encoding supported
1751 const unsigned char validChars[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_";
1752 for (unsigned char i = 0; i < sizeof(validChars) / sizeof(validChars[0]) - 1; i++)
1753 {
1754 BOOST_CHECK(SwTraceNameCharPolicy::IsValidChar(validChars[i]));
1755 }
1756
1757 // Non alpha-numeric chars
1758 for (unsigned char c = 0; c < 48; c++)
1759 {
1760 BOOST_CHECK(!SwTraceNameCharPolicy::IsValidChar(c));
1761 }
1762 for (unsigned char c = 58; c < 65; c++)
1763 {
1764 BOOST_CHECK(!SwTraceNameCharPolicy::IsValidChar(c));
1765 }
1766 for (unsigned char c = 91; c < 95; c++)
1767 {
1768 BOOST_CHECK(!SwTraceNameCharPolicy::IsValidChar(c));
1769 }
1770 for (unsigned char c = 96; c < 97; c++)
1771 {
1772 BOOST_CHECK(!SwTraceNameCharPolicy::IsValidChar(c));
1773 }
1774 for (unsigned char c = 123; c < 128; c++)
1775 {
1776 BOOST_CHECK(!SwTraceNameCharPolicy::IsValidChar(c));
1777 }
1778
1779 // Not ASCII
1780 for (unsigned char c = 255; c >= 128; c++)
1781 {
1782 BOOST_CHECK(!SwTraceNameCharPolicy::IsValidChar(c));
1783 }
1784}
1785
1786BOOST_AUTO_TEST_CASE(IsValidSwTraceStringTest)
1787{
1788 // Valid SWTrace strings
1789 BOOST_CHECK(IsValidSwTraceString<SwTraceCharPolicy>(""));
1790 BOOST_CHECK(IsValidSwTraceString<SwTraceCharPolicy>("_"));
1791 BOOST_CHECK(IsValidSwTraceString<SwTraceCharPolicy>("0123"));
1792 BOOST_CHECK(IsValidSwTraceString<SwTraceCharPolicy>("valid_string"));
1793 BOOST_CHECK(IsValidSwTraceString<SwTraceCharPolicy>("VALID_string_456"));
1794 BOOST_CHECK(IsValidSwTraceString<SwTraceCharPolicy>(" "));
1795 BOOST_CHECK(IsValidSwTraceString<SwTraceCharPolicy>("valid string"));
1796 BOOST_CHECK(IsValidSwTraceString<SwTraceCharPolicy>("!$%"));
1797 BOOST_CHECK(IsValidSwTraceString<SwTraceCharPolicy>("valid|\\~string#123"));
1798
1799 // Invalid SWTrace strings
1800 BOOST_CHECK(!IsValidSwTraceString<SwTraceCharPolicy>("€£"));
1801 BOOST_CHECK(!IsValidSwTraceString<SwTraceCharPolicy>("invalid‡string"));
1802 BOOST_CHECK(!IsValidSwTraceString<SwTraceCharPolicy>("12Ž34"));
1803}
1804
1805BOOST_AUTO_TEST_CASE(IsValidSwTraceNameStringTest)
1806{
1807 // Valid SWTrace name strings
1808 BOOST_CHECK(IsValidSwTraceString<SwTraceNameCharPolicy>(""));
1809 BOOST_CHECK(IsValidSwTraceString<SwTraceNameCharPolicy>("_"));
1810 BOOST_CHECK(IsValidSwTraceString<SwTraceNameCharPolicy>("0123"));
1811 BOOST_CHECK(IsValidSwTraceString<SwTraceNameCharPolicy>("valid_string"));
1812 BOOST_CHECK(IsValidSwTraceString<SwTraceNameCharPolicy>("VALID_string_456"));
1813
1814 // Invalid SWTrace name strings
1815 BOOST_CHECK(!IsValidSwTraceString<SwTraceNameCharPolicy>(" "));
1816 BOOST_CHECK(!IsValidSwTraceString<SwTraceNameCharPolicy>("invalid string"));
1817 BOOST_CHECK(!IsValidSwTraceString<SwTraceNameCharPolicy>("!$%"));
1818 BOOST_CHECK(!IsValidSwTraceString<SwTraceNameCharPolicy>("invalid|\\~string#123"));
1819 BOOST_CHECK(!IsValidSwTraceString<SwTraceNameCharPolicy>("€£"));
1820 BOOST_CHECK(!IsValidSwTraceString<SwTraceNameCharPolicy>("invalid‡string"));
1821 BOOST_CHECK(!IsValidSwTraceString<SwTraceNameCharPolicy>("12Ž34"));
1822}
1823
1824template <typename SwTracePolicy>
1825void StringToSwTraceStringTestHelper(const std::string& testString, std::vector<uint32_t> buffer, size_t expectedSize)
1826{
1827 // Convert the test string to a SWTrace string
1828 BOOST_CHECK(StringToSwTraceString<SwTracePolicy>(testString, buffer));
1829
1830 // The buffer must contain at least the length of the string
1831 BOOST_CHECK(!buffer.empty());
1832
1833 // The buffer must be of the expected size (in words)
1834 BOOST_CHECK(buffer.size() == expectedSize);
1835
1836 // The first word of the byte must be the length of the string including the null-terminator
1837 BOOST_CHECK(buffer[0] == testString.size() + 1);
1838
1839 // The contents of the buffer must match the test string
1840 BOOST_CHECK(std::memcmp(testString.data(), buffer.data() + 1, testString.size()) == 0);
1841
1842 // The buffer must include the null-terminator at the end of the string
1843 size_t nullTerminatorIndex = sizeof(uint32_t) + testString.size();
1844 BOOST_CHECK(reinterpret_cast<unsigned char*>(buffer.data())[nullTerminatorIndex] == '\0');
1845}
1846
1847BOOST_AUTO_TEST_CASE(StringToSwTraceStringTest)
1848{
1849 std::vector<uint32_t> buffer;
1850
1851 // Valid SWTrace strings (expected size in words)
1852 StringToSwTraceStringTestHelper<SwTraceCharPolicy>("", buffer, 2);
1853 StringToSwTraceStringTestHelper<SwTraceCharPolicy>("_", buffer, 2);
1854 StringToSwTraceStringTestHelper<SwTraceCharPolicy>("0123", buffer, 3);
1855 StringToSwTraceStringTestHelper<SwTraceCharPolicy>("valid_string", buffer, 5);
1856 StringToSwTraceStringTestHelper<SwTraceCharPolicy>("VALID_string_456", buffer, 6);
1857 StringToSwTraceStringTestHelper<SwTraceCharPolicy>(" ", buffer, 2);
1858 StringToSwTraceStringTestHelper<SwTraceCharPolicy>("valid string", buffer, 5);
1859 StringToSwTraceStringTestHelper<SwTraceCharPolicy>("!$%", buffer, 2);
1860 StringToSwTraceStringTestHelper<SwTraceCharPolicy>("valid|\\~string#123", buffer, 6);
1861
1862 // Invalid SWTrace strings
1863 BOOST_CHECK(!StringToSwTraceString<SwTraceCharPolicy>("€£", buffer));
1864 BOOST_CHECK(buffer.empty());
1865 BOOST_CHECK(!StringToSwTraceString<SwTraceCharPolicy>("invalid‡string", buffer));
1866 BOOST_CHECK(buffer.empty());
1867 BOOST_CHECK(!StringToSwTraceString<SwTraceCharPolicy>("12Ž34", buffer));
1868 BOOST_CHECK(buffer.empty());
1869}
1870
1871BOOST_AUTO_TEST_CASE(StringToSwTraceNameStringTest)
1872{
1873 std::vector<uint32_t> buffer;
1874
1875 // Valid SWTrace namestrings (expected size in words)
1876 StringToSwTraceStringTestHelper<SwTraceNameCharPolicy>("", buffer, 2);
1877 StringToSwTraceStringTestHelper<SwTraceNameCharPolicy>("_", buffer, 2);
1878 StringToSwTraceStringTestHelper<SwTraceNameCharPolicy>("0123", buffer, 3);
1879 StringToSwTraceStringTestHelper<SwTraceNameCharPolicy>("valid_string", buffer, 5);
1880 StringToSwTraceStringTestHelper<SwTraceNameCharPolicy>("VALID_string_456", buffer, 6);
1881
1882 // Invalid SWTrace namestrings
1883 BOOST_CHECK(!StringToSwTraceString<SwTraceNameCharPolicy>(" ", buffer));
1884 BOOST_CHECK(buffer.empty());
1885 BOOST_CHECK(!StringToSwTraceString<SwTraceNameCharPolicy>("invalid string", buffer));
1886 BOOST_CHECK(buffer.empty());
1887 BOOST_CHECK(!StringToSwTraceString<SwTraceNameCharPolicy>("!$%", buffer));
1888 BOOST_CHECK(buffer.empty());
1889 BOOST_CHECK(!StringToSwTraceString<SwTraceNameCharPolicy>("invalid|\\~string#123", buffer));
1890 BOOST_CHECK(buffer.empty());
1891 BOOST_CHECK(!StringToSwTraceString<SwTraceNameCharPolicy>("€£", buffer));
1892 BOOST_CHECK(buffer.empty());
1893 BOOST_CHECK(!StringToSwTraceString<SwTraceNameCharPolicy>("invalid‡string", buffer));
1894 BOOST_CHECK(buffer.empty());
1895 BOOST_CHECK(!StringToSwTraceString<SwTraceNameCharPolicy>("12Ž34", buffer));
1896 BOOST_CHECK(buffer.empty());
1897}
1898
Francis Murtaghfcb8ef62019-09-20 15:40:09 +01001899BOOST_AUTO_TEST_CASE(CheckPeriodicCounterCaptureThread)
1900{
1901 class CaptureReader : public IReadCounterValue
1902 {
1903 public:
1904 CaptureReader() {}
1905
1906 void GetCounterValue(uint16_t index, uint32_t &value) const override
1907 {
1908 if (m_Data.count(index))
1909 {
1910 value = m_Data.at(index);
1911 }
1912 else
1913 {
1914 value = 0;
1915 }
1916 }
1917
1918 void SetCounterValue(uint16_t index, uint32_t value)
1919 {
1920 if (!m_Data.count(index))
1921 {
1922 m_Data.insert(std::pair<uint16_t, uint32_t>(index, value));
1923 }
1924 else
1925 {
1926 m_Data.at(index) = value;
1927 }
1928 }
1929
1930 private:
1931 std::map<uint16_t, uint32_t> m_Data;
1932 };
1933
1934 Holder data;
1935 std::vector<uint16_t> captureIds1 = { 0, 1 };
1936 std::vector<uint16_t> captureIds2;
1937
1938 MockBuffer mockBuffer(512);
1939 SendCounterPacket sendCounterPacket(mockBuffer);
1940
1941 std::vector<uint16_t> counterIds;
1942 CaptureReader captureReader;
1943
1944 unsigned int valueA = 10;
1945 unsigned int valueB = 15;
1946 unsigned int numSteps = 5;
1947
1948 PeriodicCounterCapture periodicCounterCapture(std::ref(data), std::ref(sendCounterPacket), captureReader);
1949
1950 for(unsigned int i = 0; i < numSteps; ++i)
1951 {
1952 data.SetCaptureData(1, captureIds1);
1953 captureReader.SetCounterValue(0, valueA * (i + 1));
1954 captureReader.SetCounterValue(1, valueB * (i + 1));
1955
1956 periodicCounterCapture.Start();
1957
1958 std::this_thread::sleep_for(std::chrono::milliseconds(200));
1959
1960 periodicCounterCapture.Start();
1961
1962 data.SetCaptureData(0, captureIds2);
1963
1964 periodicCounterCapture.Start();
1965 }
1966
1967 periodicCounterCapture.Join();
1968
1969 unsigned int size = 0;
1970
1971 const unsigned char* buffer = mockBuffer.GetReadBuffer(size);
1972
1973 uint32_t headerWord0 = ReadUint32(buffer, 0);
1974 uint32_t headerWord1 = ReadUint32(buffer, 4);
1975
1976 BOOST_TEST(((headerWord0 >> 26) & 0x3F) == 1); // packet family
1977 BOOST_TEST(((headerWord0 >> 19) & 0x3F) == 0); // packet class
1978 BOOST_TEST(((headerWord0 >> 16) & 0x3) == 0); // packet type
1979 BOOST_TEST(headerWord1 == 20); // data length
1980
1981 uint32_t offset = 16;
1982 uint16_t readIndex = ReadUint16(buffer, offset);
1983 BOOST_TEST(0 == readIndex);
1984
1985 offset += 2;
1986 uint32_t readValue = ReadUint32(buffer, offset);
1987 BOOST_TEST((valueA * numSteps) == readValue);
1988
1989 offset += 4;
1990 readIndex = ReadUint16(buffer, offset);
1991 BOOST_TEST(1 == readIndex);
1992
1993 offset += 2;
1994 readValue = ReadUint32(buffer, offset);
1995 BOOST_TEST((valueB * numSteps) == readValue);
1996}
1997
Narumol Prangnawarat48033692019-09-20 12:04:55 +01001998BOOST_AUTO_TEST_CASE(RequestCounterDirectoryCommandHandlerTest0)
1999{
2000 using boost::numeric_cast;
2001
2002 const uint32_t packetId = 0x30000;
2003 const uint32_t version = 1;
2004
2005 std::unique_ptr<char[]> packetData;
2006
2007 Packet packetA(packetId, 0, packetData);
2008
2009 MockBuffer mockBuffer(1024);
2010 SendCounterPacket sendCounterPacket(mockBuffer);
2011
2012 CounterDirectory counterDirectory;
2013
2014 RequestCounterDirectoryCommandHandler commandHandler(packetId, version, counterDirectory, sendCounterPacket);
2015 commandHandler(packetA);
2016
2017 unsigned int size = 0;
2018 const unsigned char* readBuffer = mockBuffer.GetReadBuffer(size);
2019
2020 uint32_t headerWord0 = ReadUint32(readBuffer, 0);
2021 uint32_t headerWord1 = ReadUint32(readBuffer, 4);
2022
2023 BOOST_TEST(((headerWord0 >> 26) & 0x3F) == 0); // packet family
2024 BOOST_TEST(((headerWord0 >> 16) & 0x3FF) == 2); // packet id
2025 BOOST_TEST(headerWord1 == 32); // data lenght;
2026
2027 uint32_t bodyHeaderWord0 = ReadUint32(readBuffer, 8);
2028 uint16_t deviceRecordCount = numeric_cast<uint16_t>(bodyHeaderWord0 >> 16);
2029 BOOST_TEST(deviceRecordCount == 0); // device_records_count
2030}
2031
2032BOOST_AUTO_TEST_CASE(RequestCounterDirectoryCommandHandlerTest1)
2033{
2034 using boost::numeric_cast;
2035
2036 const uint32_t packetId = 0x30000;
2037 const uint32_t version = 1;
2038
2039 std::unique_ptr<char[]> packetData;
2040
2041 Packet packetA(packetId, 0, packetData);
2042
2043 MockBuffer mockBuffer(1024);
2044 SendCounterPacket sendCounterPacket(mockBuffer);
2045
2046 CounterDirectory counterDirectory;
2047 const Device* device = counterDirectory.RegisterDevice("deviceA", 1);
2048 const CounterSet* counterSet = counterDirectory.RegisterCounterSet("countersetA");
2049 counterDirectory.RegisterCategory("categoryA", device->m_Uid, counterSet->m_Uid);
2050 counterDirectory.RegisterCounter("categoryA", 0, 1, 2.0f, "counterA", "descA");
2051 counterDirectory.RegisterCounter("categoryA", 1, 1, 3.0f, "counterB", "descB");
2052
2053 RequestCounterDirectoryCommandHandler commandHandler(packetId, version, counterDirectory, sendCounterPacket);
2054 commandHandler(packetA);
2055
2056 unsigned int size = 0;
2057 const unsigned char* readBuffer = mockBuffer.GetReadBuffer(size);
2058
2059 uint32_t headerWord0 = ReadUint32(readBuffer, 0);
2060 uint32_t headerWord1 = ReadUint32(readBuffer, 4);
2061
2062 BOOST_TEST(((headerWord0 >> 26) & 0x3F) == 0); // packet family
2063 BOOST_TEST(((headerWord0 >> 16) & 0x3FF) == 2); // packet id
2064 BOOST_TEST(headerWord1 == 248); // data lenght;
2065
2066 uint32_t bodyHeaderWord0 = ReadUint32(readBuffer, 8);
2067 uint32_t bodyHeaderWord1 = ReadUint32(readBuffer, 12);
2068 uint32_t bodyHeaderWord2 = ReadUint32(readBuffer, 16);
2069 uint32_t bodyHeaderWord3 = ReadUint32(readBuffer, 20);
2070 uint32_t bodyHeaderWord4 = ReadUint32(readBuffer, 24);
2071 uint32_t bodyHeaderWord5 = ReadUint32(readBuffer, 28);
2072 uint16_t deviceRecordCount = numeric_cast<uint16_t>(bodyHeaderWord0 >> 16);
2073 uint16_t counterSetRecordCount = numeric_cast<uint16_t>(bodyHeaderWord2 >> 16);
2074 uint16_t categoryRecordCount = numeric_cast<uint16_t>(bodyHeaderWord4 >> 16);
2075 BOOST_TEST(deviceRecordCount == 1); // device_records_count
2076 BOOST_TEST(bodyHeaderWord1 == 0); // device_records_pointer_table_offset
2077 BOOST_TEST(counterSetRecordCount == 1); // counter_set_count
2078 BOOST_TEST(bodyHeaderWord3 == 4); // counter_set_pointer_table_offset
2079 BOOST_TEST(categoryRecordCount == 1); // categories_count
2080 BOOST_TEST(bodyHeaderWord5 == 8); // categories_pointer_table_offset
2081
2082 uint32_t deviceRecordOffset = ReadUint32(readBuffer, 32);
2083 BOOST_TEST(deviceRecordOffset == 0);
2084
2085 uint32_t counterSetRecordOffset = ReadUint32(readBuffer, 36);
2086 BOOST_TEST(counterSetRecordOffset == 20);
2087
2088 uint32_t categoryRecordOffset = ReadUint32(readBuffer, 40);
2089 BOOST_TEST(categoryRecordOffset == 44);
2090}
2091
Francis Murtagh1f7db452019-08-14 09:49:34 +01002092BOOST_AUTO_TEST_SUITE_END()