ArmNN
 21.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 <memory>
#include <thread>
#include <ostream>
#include <Profiling.hpp>

Go to the source code of this file.

Namespaces

 armnn
 Copyright (c) 2021 ARM Limited and Contributors.
 

Functions

size_t GetProfilerEventSequenceSize (armnn::IProfiler *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 67 of file ProfilerTests.cpp.

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

◆ BOOST_AUTO_TEST_CASE() [2/6]

BOOST_AUTO_TEST_CASE ( RegisterUnregisterProfilerSingleThread  )

Definition at line 87 of file ProfilerTests.cpp.

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

◆ BOOST_AUTO_TEST_CASE() [3/6]

BOOST_AUTO_TEST_CASE ( RegisterUnregisterProfilerMultipleThreads  )

Definition at line 94 of file ProfilerTests.cpp.

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

◆ BOOST_AUTO_TEST_CASE() [4/6]

BOOST_AUTO_TEST_CASE ( ProfilingMacros  )

Definition at line 111 of file ProfilerTests.cpp.

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

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

◆ BOOST_AUTO_TEST_CASE() [5/6]

BOOST_AUTO_TEST_CASE ( WriteEventResults  )

Definition at line 198 of file ProfilerTests.cpp.

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

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

◆ BOOST_AUTO_TEST_CASE() [6/6]

BOOST_AUTO_TEST_CASE ( ProfilerJsonPrinter  )

Definition at line 254 of file ProfilerTests.cpp.

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

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

◆ BOOST_AUTO_TEST_SUITE_END()

BOOST_AUTO_TEST_SUITE_END ( )