ArmNN
 21.11
PeriodicCounterCapture.cpp
Go to the documentation of this file.
1 //
2 // Copyright © 2019 Arm Ltd. All rights reserved.
3 // SPDX-License-Identifier: MIT
4 //
5 
7 
8 #include <armnn/Logging.hpp>
9 
10 #include <iostream>
11 
12 namespace armnn
13 {
14 
15 namespace profiling
16 {
17 
19 {
20  // Check if the capture thread is already running
21  if (m_IsRunning)
22  {
23  // The capture thread is already running
24  return;
25  }
26 
27  // Mark the capture thread as running
28  m_IsRunning = true;
29 
30  // Keep the capture procedure going until the capture thread is signalled to stop
31  m_KeepRunning.store(true);
32 
33  // Start the new capture thread.
34  m_PeriodCaptureThread = std::thread(&PeriodicCounterCapture::Capture, this, std::ref(m_ReadCounterValues));
35 }
36 
38 {
39  // Signal the capture thread to stop
40  m_KeepRunning.store(false);
41 
42  // Check that the capture thread is running
43  if (m_PeriodCaptureThread.joinable())
44  {
45  // Wait for the capture thread to complete operations
46  m_PeriodCaptureThread.join();
47  }
48 
49  // Mark the capture thread as not running
50  m_IsRunning = false;
51 }
52 
53 CaptureData PeriodicCounterCapture::ReadCaptureData()
54 {
55  return m_CaptureDataHolder.GetCaptureData();
56 }
57 
58 void PeriodicCounterCapture::DispatchPeriodicCounterCapturePacket(
59  const armnn::BackendId& backendId, const std::vector<Timestamp>& timestampValues)
60 {
61  // Report counter values
62  for (const auto& timestampInfo : timestampValues)
63  {
64  std::vector<CounterValue> backendCounterValues = timestampInfo.counterValues;
65  for_each(backendCounterValues.begin(), backendCounterValues.end(), [&](CounterValue& backendCounterValue)
66  {
67  // translate the counterId to globalCounterId
68  backendCounterValue.counterId = m_CounterIdMap.GetGlobalId(backendCounterValue.counterId, backendId);
69  });
70 
71  // Send Periodic Counter Capture Packet for the Timestamp
72  m_SendCounterPacket.SendPeriodicCounterCapturePacket(timestampInfo.timestamp, backendCounterValues);
73  }
74 }
75 
76 void PeriodicCounterCapture::Capture(IReadCounterValues& readCounterValues)
77 {
78  do
79  {
80  // Check if the current capture data indicates that there's data capture
81  auto currentCaptureData = ReadCaptureData();
82  const std::vector<uint16_t>& counterIds = currentCaptureData.GetCounterIds();
83  const uint32_t capturePeriod = currentCaptureData.GetCapturePeriod();
84 
85  if (capturePeriod == 0)
86  {
87  // No data capture, wait the indicated capture period (milliseconds), if it is not zero
88  std::this_thread::sleep_for(std::chrono::milliseconds(50u));
89  continue;
90  }
91 
92  if(counterIds.size() != 0)
93  {
94  std::vector<CounterValue> counterValues;
95 
96  auto numCounters = counterIds.size();
97  counterValues.reserve(numCounters);
98 
99  // Create a vector of pairs of CounterIndexes and Values
100  for (uint16_t index = 0; index < numCounters; ++index)
101  {
102  auto requestedId = counterIds[index];
103  uint32_t counterValue = 0;
104  try
105  {
106  counterValue = readCounterValues.GetDeltaCounterValue(requestedId);
107  }
108  catch (const Exception& e)
109  {
110  // Report the error and continue
111  ARMNN_LOG(warning) << "An error has occurred when getting a counter value: "
112  << e.what();
113  continue;
114  }
115 
116  counterValues.emplace_back(CounterValue {requestedId, counterValue });
117  }
118 
119  // Send Periodic Counter Capture Packet for the Timestamp
120  m_SendCounterPacket.SendPeriodicCounterCapturePacket(GetTimestamp(), counterValues);
121  }
122 
123  // Report counter values for each active backend
124  auto activeBackends = currentCaptureData.GetActiveBackends();
125  for_each(activeBackends.begin(), activeBackends.end(), [&](const armnn::BackendId& backendId)
126  {
127  DispatchPeriodicCounterCapturePacket(
128  backendId, m_BackendProfilingContexts.at(backendId)->ReportCounterValues());
129  });
130 
131  // Wait the indicated capture period (microseconds)
132  std::this_thread::sleep_for(std::chrono::microseconds(capturePeriod));
133  }
134  while (m_KeepRunning.load());
135 }
136 
137 } // namespace profiling
138 
139 } // namespace armnn
virtual const char * what() const noexcept override
Definition: Exceptions.cpp:32
#define ARMNN_LOG(severity)
Definition: Logging.hpp:202
Copyright (c) 2021 ARM Limited and Contributors.
CaptureData GetCaptureData() const
Definition: Holder.cpp:54
virtual uint32_t GetDeltaCounterValue(uint16_t counterUid)=0
virtual void SendPeriodicCounterCapturePacket(uint64_t timestamp, const IndexValuePairsVector &values)=0
Create and write a PeriodicCounterCapturePacket from the parameters to the buffer.
Base class for all ArmNN exceptions so that users can filter to just those.
Definition: Exceptions.hpp:46
uint64_t GetTimestamp()
virtual uint16_t GetGlobalId(uint16_t backendCounterId, const armnn::BackendId &backendId) const =0