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