ArmNN
 20.02
ProfilerTests.cpp File Reference
#include <armnn/IRuntime.hpp>
#include <armnn/TypesUtils.hpp>
#include <armnn/utility/IgnoreUnused.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/test/tools/output_test_stream.hpp>
#include <boost/algorithm/string.hpp>
#include <memory>
#include <thread>
#include <ostream>
#include <Profiling.hpp>

Go to the source code of this file.

Namespaces

 armnn
 Copyright (c) 2020 ARM Limited.
 

Functions

size_t GetProfilerEventSequenceSize (armnn::Profiler *profiler)
 
 BOOST_AUTO_TEST_CASE (EnableDisableProfiling)
 
 BOOST_AUTO_TEST_CASE (RegisterUnregisterProfilerSingleThread)
 
 BOOST_AUTO_TEST_CASE (RegisterUnregisterProfilerMultipleThreads)
 
 BOOST_AUTO_TEST_CASE (ProfilingMacros)
 
 BOOST_AUTO_TEST_CASE (WriteEventResults)
 
 BOOST_AUTO_TEST_CASE (ProfilerJsonPrinter)
 
 BOOST_AUTO_TEST_SUITE_END ()
 

Function Documentation

◆ BOOST_AUTO_TEST_CASE() [1/6]

BOOST_AUTO_TEST_CASE ( EnableDisableProfiling  )

Definition at line 66 of file ProfilerTests.cpp.

67 {
68  std::unique_ptr<armnn::Profiler> profiler = std::make_unique<armnn::Profiler>();
69 
70  // Check that profiling is disabled by default.
71  BOOST_TEST(!profiler->IsProfilingEnabled());
72 
73  // Enable profiling.
74  profiler->EnableProfiling(true);
75 
76  // Check that profiling is enabled.
77  BOOST_TEST(profiler->IsProfilingEnabled());
78 
79  // Disable profiling.
80  profiler->EnableProfiling(false);
81 
82  // Check that profiling is disabled.
83  BOOST_TEST(!profiler->IsProfilingEnabled());
84 }

◆ BOOST_AUTO_TEST_CASE() [2/6]

BOOST_AUTO_TEST_CASE ( RegisterUnregisterProfilerSingleThread  )

Definition at line 86 of file ProfilerTests.cpp.

87 {
88  bool res = false;
89  RegisterUnregisterProfilerSingleThreadImpl(res);
90  BOOST_TEST(res);
91 }

◆ BOOST_AUTO_TEST_CASE() [3/6]

BOOST_AUTO_TEST_CASE ( RegisterUnregisterProfilerMultipleThreads  )

Definition at line 93 of file ProfilerTests.cpp.

94 {
95  bool res[3] = {false, false, false};
96  std::thread thread1([&res]() { RegisterUnregisterProfilerSingleThreadImpl(res[0]); });
97  std::thread thread2([&res]() { RegisterUnregisterProfilerSingleThreadImpl(res[1]); });
98  std::thread thread3([&res]() { RegisterUnregisterProfilerSingleThreadImpl(res[2]); });
99 
100  thread1.join();
101  thread2.join();
102  thread3.join();
103 
104  for (int i = 0 ; i < 3 ; i++)
105  {
106  BOOST_TEST(res[i]);
107  }
108 }

◆ BOOST_AUTO_TEST_CASE() [4/6]

BOOST_AUTO_TEST_CASE ( ProfilingMacros  )

Definition at line 110 of file ProfilerTests.cpp.

References ARMNN_SCOPED_PROFILING_EVENT, armnn::BOOST_AUTO_TEST_CASE(), armnn::CpuAcc, armnn::CpuRef, INetwork::Create(), IRuntime::Create(), ProfilerManager::GetInstance(), ProfilerManager::GetProfiler(), armnn::GetProfilerEventSequenceSize(), armnn::Optimize(), options, and ProfilerManager::RegisterProfiler().

111 {
112  // Get a reference to the profiler manager.
114 
115  { // --- No profiler ---
116 
117  // Check that there's no profiler registered for this thread.
118  BOOST_TEST(!profilerManager.GetProfiler());
119 
120  // Test scoped event.
122 
123  // Check that we still cannot get a profiler for this thread.
124  BOOST_TEST(!profilerManager.GetProfiler());
125  }
126 
127  // Create and register a profiler for this thread.
128  std::unique_ptr<armnn::Profiler> profiler = std::make_unique<armnn::Profiler>();
129  profilerManager.RegisterProfiler(profiler.get());
130 
131  { // --- Profiler, but profiling disabled ---
132 
133  // Get current event sequence size.
134  size_t eventSequenceSizeBefore = armnn::GetProfilerEventSequenceSize(profiler.get());
135 
136  // Test scoped macro.
138 
139  // Check that no profiling event has been added to the sequence.
140  size_t eventSequenceSizeAfter = armnn::GetProfilerEventSequenceSize(profiler.get());
141  BOOST_TEST(eventSequenceSizeBefore == eventSequenceSizeAfter);
142  }
143 
144  // Enable profiling.
145  profiler->EnableProfiling(true);
146 
147  { // --- Profiler, and profiling enabled ---
148 
149  // Get current event sequence size.
150  size_t eventSequenceSizeBefore = armnn::GetProfilerEventSequenceSize(profiler.get());
151 
152  // Test scoped macro.
154 
155  // Check that a profiling event has been added to the sequence.
156  size_t eventSequenceSizeAfter = armnn::GetProfilerEventSequenceSize(profiler.get());
157  BOOST_TEST(eventSequenceSizeAfter == eventSequenceSizeBefore + 1);
158  }
159 
160  // Disable profiling here to not print out anything on stdout.
161  profiler->EnableProfiling(false);
162 }
size_t GetProfilerEventSequenceSize(armnn::Profiler *profiler)
void RegisterProfiler(Profiler *profiler)
Definition: Profiling.cpp:494
static ProfilerManager & GetInstance()
Definition: Profiling.cpp:487
#define ARMNN_SCOPED_PROFILING_EVENT(backendId, name)
Definition: Profiling.hpp:169
Profiler * GetProfiler()
Definition: Profiling.cpp:499
CPU Execution: NEON: ArmCompute.

◆ BOOST_AUTO_TEST_CASE() [5/6]

BOOST_AUTO_TEST_CASE ( WriteEventResults  )

Definition at line 197 of file ProfilerTests.cpp.

References BOOST_CHECK(), armnn::CpuAcc, ProfilerManager::GetInstance(), armnn::GetProfilerEventSequenceSize(), and ProfilerManager::RegisterProfiler().

198 {
199  // Get a reference to the profiler manager.
201 
202  // Create and register a profiler for this thread.
203  std::unique_ptr<armnn::Profiler> profiler = std::make_unique<armnn::Profiler>();
204  profileManager.RegisterProfiler(profiler.get());
205 
206  // Enable profiling.
207  profiler->EnableProfiling(true);
208 
209  { // --- Profiler, and profiling enabled ---
210 
211  // Get current event sequence size.
212  size_t eventSequenceSizeBefore = armnn::GetProfilerEventSequenceSize(profiler.get());
213 
214  // Test scoped macro.
215  {
216  // Need to directly create a ScopedProfilingEvent as the one created by the macro falls out of scope
217  // immediately causing the Event.Stop() function method to be called immediately after the Event.Start()
218  // function resulting in periodic test failures on the Dent and Smith HiKeys
220  std::this_thread::sleep_for(std::chrono::milliseconds(10));
221  }
222 
223  // Check that a profiling event has been added to the sequence.
224  size_t eventSequenceSizeAfter = armnn::GetProfilerEventSequenceSize(profiler.get());
225  BOOST_TEST(eventSequenceSizeAfter == eventSequenceSizeBefore + 1);
226 
227  boost::test_tools::output_test_stream output;
228  profiler->AnalyzeEventsAndWriteResults(output);
229  BOOST_TEST(!output.is_empty(false));
230 
231  // output should contain event name 'test'
232  BOOST_CHECK(boost::contains(output.str(), "test"));
233 
234  // output should contain headers
235  BOOST_CHECK(boost::contains(output.str(), "Event Sequence - Name"));
236  BOOST_CHECK(boost::contains(output.str(), "Event Stats - Name"));
237  BOOST_CHECK(boost::contains(output.str(), "Total"));
238  BOOST_CHECK(boost::contains(output.str(), "Device"));
239  // output should contain compute device 'CpuAcc'
240  BOOST_CHECK(boost::contains(output.str(), "CpuAcc"));
241  // output should not contain un-readable numbers
242  BOOST_CHECK(!(boost::contains(output.str(), "e+")));
243  // output should not contain un-readable numbers
244  BOOST_CHECK(!(boost::contains(output.str(), "+")));
245  // output should not contain zero value
246  BOOST_CHECK(!(boost::contains(output.str(), " 0 ")));
247  }
248 
249  // Disable profiling here to not print out anything on stdout.
250  profiler->EnableProfiling(false);
251 }
size_t GetProfilerEventSequenceSize(armnn::Profiler *profiler)
void RegisterProfiler(Profiler *profiler)
Definition: Profiling.cpp:494
static ProfilerManager & GetInstance()
Definition: Profiling.cpp:487
BOOST_CHECK(profilingService.GetCurrentState()==ProfilingState::WaitingForAck)
CPU Execution: NEON: ArmCompute.

◆ BOOST_AUTO_TEST_CASE() [6/6]

BOOST_AUTO_TEST_CASE ( ProfilerJsonPrinter  )

Definition at line 253 of file ProfilerTests.cpp.

References ARMNN_SCOPED_PROFILING_EVENT_WITH_INSTRUMENTS, BOOST_AUTO_TEST_SUITE_END(), BOOST_CHECK(), armnn::CpuAcc, ProfilerManager::GetInstance(), armnn::IgnoreUnused(), and ProfilerManager::RegisterProfiler().

254 {
255  class TestInstrument : public armnn::Instrument
256  {
257  public:
258  virtual ~TestInstrument() {}
259  void Start() override {}
260  void Stop() override {}
261 
262  std::vector<armnn::Measurement> GetMeasurements() const override
263  {
264  std::vector<armnn::Measurement> measurements;
265  measurements.emplace_back(armnn::Measurement("Measurement1",
266  1.0,
267  armnn::Measurement::Unit::TIME_MS));
268  measurements.emplace_back(armnn::Measurement("Measurement2",
269  2.0,
270  armnn::Measurement::Unit::TIME_US));
271  return measurements;
272  }
273 
274  const char* GetName() const override
275  {
276  return "TestInstrument";
277  }
278  };
279 
280  // Get a reference to the profiler manager.
282 
283  // Create and register a profiler for this thread.
284  std::unique_ptr<armnn::Profiler> profiler = std::make_unique<armnn::Profiler>();
285  profilerManager.RegisterProfiler(profiler.get());
286 
287  profiler->EnableProfiling(true);
288 
289  {
290  // Test scoped macro.
291  ARMNN_SCOPED_PROFILING_EVENT_WITH_INSTRUMENTS(armnn::Compute::CpuAcc, "EnqueueWorkload", TestInstrument())
292  ARMNN_SCOPED_PROFILING_EVENT_WITH_INSTRUMENTS(armnn::Compute::CpuAcc, "Level 0", TestInstrument())
293  {
294  {
296  }
297 
298  {
300 
301  {
303  }
304  }
305  }
306  }
307 
308  std::stringbuf buffer;
309  std::ostream json(&buffer);
310  profiler->Print(json);
311 
312  std::string output = buffer.str();
313  armnn::IgnoreUnused(output);
314 
315  // Disable profiling here to not print out anything on stdout.
316  profiler->EnableProfiling(false);
317 
318  // blessed output validated by a human eyeballing the output to make sure it's ok and then copying it here.
319  // validation also included running the blessed output through an online json validation site
320  std::string blessedOutput("{\n\t\"ArmNN\": {\n\t\t\"inference_measurements_#1\": {\n\t\t\t\"type\": \""
321  "Event\",\n\t\t\t\"Measurement1_#1\": {\n\t\t\t\t\"type\": \""
322  "Measurement\",\n\t\t\t\t\"raw\": [\n\t\t\t\t\t1.000000\n\t\t\t\t],\n\t\t\t\t\""
323  "unit\": \"ms\"\n\t\t\t},\n\t\t\t\"Measurement2_#1\": {\n\t\t\t\t\"type\": \""
324  "Measurement\",\n\t\t\t\t\"raw\": [\n\t\t\t\t\t2.000000\n\t\t\t\t],\n\t\t\t\t\""
325  "unit\": \"us\"\n\t\t\t},\n\t\t\t\"Level 0_#2\": {\n\t\t\t\t\"type\": \""
326  "Event\",\n\t\t\t\t\"Measurement1_#2\": {\n\t\t\t\t\t\"type\": \""
327  "Measurement\",\n\t\t\t\t\t\"raw\": [\n\t\t\t\t\t\t1.000000\n\t\t\t\t\t],\n\t\t\t\t\t\""
328  "unit\": \"ms\"\n\t\t\t\t},\n\t\t\t\t\"Measurement2_#2\": {\n\t\t\t\t\t\"type\": \""
329  "Measurement\",\n\t\t\t\t\t\"raw\": [\n\t\t\t\t\t\t2.000000\n\t\t\t\t\t],\n\t\t\t\t\t\""
330  "unit\": \"us\"\n\t\t\t\t},\n\t\t\t\t\"Level 1A_#3\": {\n\t\t\t\t\t\"type\": \""
331  "Event\",\n\t\t\t\t\t\"Measurement1_#3\": {\n\t\t\t\t\t\t\"type\": \""
332  "Measurement\",\n\t\t\t\t\t\t\"raw\": [\n\t\t\t\t\t\t\t"
333  "1.000000\n\t\t\t\t\t\t],\n\t\t\t\t\t\t\""
334  "unit\": \"ms\"\n\t\t\t\t\t},\n\t\t\t\t\t\"Measurement2_#3\": {\n\t\t\t\t\t\t\"type\": \""
335  "Measurement\",\n\t\t\t\t\t\t\"raw\": [\n\t\t\t\t\t\t\t"
336  "2.000000\n\t\t\t\t\t\t],\n\t\t\t\t\t\t\""
337  "unit\": \"us\"\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t\"Level 1B_#4\": {\n\t\t\t\t\t\""
338  "type\": \"Event\",\n\t\t\t\t\t\"Measurement1_#4\": {\n\t\t\t\t\t\t\"type\": \""
339  "Measurement\",\n\t\t\t\t\t\t\"raw\": [\n\t\t\t\t\t\t\t"
340  "1.000000\n\t\t\t\t\t\t],\n\t\t\t\t\t\t\""
341  "unit\": \"ms\"\n\t\t\t\t\t},\n\t\t\t\t\t\"Measurement2_#4\": {\n\t\t\t\t\t\t\""
342  "type\": \"Measurement\",\n\t\t\t\t\t\t\"raw\": [\n\t\t\t\t\t\t\t"
343  "2.000000\n\t\t\t\t\t\t],\n\t\t\t\t\t\t\""
344  "unit\": \"us\"\n\t\t\t\t\t},\n\t\t\t\t\t\"Level 2A_#5\": {\n\t\t\t\t\t\t\""
345  "type\": \"Event\",\n\t\t\t\t\t\t\"Measurement1_#5\": {\n\t\t\t\t\t\t\t\"type\": \""
346  "Measurement\",\n\t\t\t\t\t\t\t\"raw\": [\n\t\t\t\t\t\t\t\t"
347  "1.000000\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\""
348  "unit\": \"ms\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t\"Measurement2_#5\": {\n\t\t\t\t\t\t\t\""
349  "type\": \"Measurement\",\n\t\t\t\t\t\t\t\"raw\": [\n\t\t\t\t\t\t\t\t"
350  "2.000000\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\""
351  "unit\": \"us\"\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n");
352 
353  BOOST_CHECK(output == blessedOutput);
354 }
void RegisterProfiler(Profiler *profiler)
Definition: Profiling.cpp:494
static ProfilerManager & GetInstance()
Definition: Profiling.cpp:487
virtual void Start()=0
Copyright (c) 2020 ARM Limited.
void IgnoreUnused(Ts &&...)
BOOST_CHECK(profilingService.GetCurrentState()==ProfilingState::WaitingForAck)
virtual std::vector< Measurement > GetMeasurements() const =0
Compute
The Compute enum is now deprecated and it is now being replaced by BackendId.
Definition: BackendId.hpp:21
#define ARMNN_SCOPED_PROFILING_EVENT_WITH_INSTRUMENTS(backendId,...)
Definition: Profiling.hpp:166
virtual const char * GetName() const =0
CPU Execution: NEON: ArmCompute.
virtual void Stop()=0

◆ BOOST_AUTO_TEST_SUITE_END()