ArmNN  NotReleased
ProfilerTests.cpp File Reference
#include <armnn/IRuntime.hpp>
#include <armnn/TypesUtils.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
 

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 65 of file ProfilerTests.cpp.

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

◆ BOOST_AUTO_TEST_CASE() [2/6]

BOOST_AUTO_TEST_CASE ( RegisterUnregisterProfilerSingleThread  )

Definition at line 85 of file ProfilerTests.cpp.

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

◆ BOOST_AUTO_TEST_CASE() [3/6]

BOOST_AUTO_TEST_CASE ( RegisterUnregisterProfilerMultipleThreads  )

Definition at line 92 of file ProfilerTests.cpp.

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

◆ BOOST_AUTO_TEST_CASE() [4/6]

BOOST_AUTO_TEST_CASE ( ProfilingMacros  )

Definition at line 109 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().

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

◆ BOOST_AUTO_TEST_CASE() [5/6]

BOOST_AUTO_TEST_CASE ( WriteEventResults  )

Definition at line 196 of file ProfilerTests.cpp.

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

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

◆ BOOST_AUTO_TEST_CASE() [6/6]

BOOST_AUTO_TEST_CASE ( ProfilerJsonPrinter  )

Definition at line 252 of file ProfilerTests.cpp.

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

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

◆ BOOST_AUTO_TEST_SUITE_END()