xref: /aosp_15_r20/external/ComputeLibrary/tests/framework/instruments/MaliCounter.cpp (revision c217d954acce2dbc11938adb493fc0abd69584f3)
1*c217d954SCole Faust /*
2*c217d954SCole Faust  * Copyright (c) 2017-2019 Arm Limited.
3*c217d954SCole Faust  *
4*c217d954SCole Faust  * SPDX-License-Identifier: MIT
5*c217d954SCole Faust  *
6*c217d954SCole Faust  * Permission is hereby granted, free of charge, to any person obtaining a copy
7*c217d954SCole Faust  * of this software and associated documentation files (the "Software"), to
8*c217d954SCole Faust  * deal in the Software without restriction, including without limitation the
9*c217d954SCole Faust  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10*c217d954SCole Faust  * sell copies of the Software, and to permit persons to whom the Software is
11*c217d954SCole Faust  * furnished to do so, subject to the following conditions:
12*c217d954SCole Faust  *
13*c217d954SCole Faust  * The above copyright notice and this permission notice shall be included in all
14*c217d954SCole Faust  * copies or substantial portions of the Software.
15*c217d954SCole Faust  *
16*c217d954SCole Faust  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17*c217d954SCole Faust  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18*c217d954SCole Faust  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19*c217d954SCole Faust  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20*c217d954SCole Faust  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21*c217d954SCole Faust  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22*c217d954SCole Faust  * SOFTWARE.
23*c217d954SCole Faust  */
24*c217d954SCole Faust #include "MaliCounter.h"
25*c217d954SCole Faust 
26*c217d954SCole Faust #include "arm_compute/core/Error.h"
27*c217d954SCole Faust 
28*c217d954SCole Faust namespace arm_compute
29*c217d954SCole Faust {
30*c217d954SCole Faust namespace test
31*c217d954SCole Faust {
32*c217d954SCole Faust namespace framework
33*c217d954SCole Faust {
34*c217d954SCole Faust namespace
35*c217d954SCole Faust {
36*c217d954SCole Faust struct MaliHWInfo
37*c217d954SCole Faust {
38*c217d954SCole Faust     unsigned mp_count;
39*c217d954SCole Faust     unsigned gpu_id;
40*c217d954SCole Faust     unsigned r_value;
41*c217d954SCole Faust     unsigned p_value;
42*c217d954SCole Faust     unsigned core_mask;
43*c217d954SCole Faust };
44*c217d954SCole Faust 
get_mali_hw_info(const char * path)45*c217d954SCole Faust MaliHWInfo get_mali_hw_info(const char *path)
46*c217d954SCole Faust {
47*c217d954SCole Faust     int fd = open(path, O_RDWR); // NOLINT
48*c217d954SCole Faust 
49*c217d954SCole Faust     if(fd < 0)
50*c217d954SCole Faust     {
51*c217d954SCole Faust         ARM_COMPUTE_ERROR("Failed to get HW info.");
52*c217d954SCole Faust     }
53*c217d954SCole Faust 
54*c217d954SCole Faust     {
55*c217d954SCole Faust         mali_userspace::uku_version_check_args version_check_args;                // NOLINT
56*c217d954SCole Faust         version_check_args.header.id = mali_userspace::UKP_FUNC_ID_CHECK_VERSION; // NOLINT
57*c217d954SCole Faust         version_check_args.major     = 10;
58*c217d954SCole Faust         version_check_args.minor     = 2;
59*c217d954SCole Faust 
60*c217d954SCole Faust         if(mali_userspace::mali_ioctl(fd, version_check_args) != 0)
61*c217d954SCole Faust         {
62*c217d954SCole Faust             ARM_COMPUTE_ERROR("Failed to check version.");
63*c217d954SCole Faust             close(fd);
64*c217d954SCole Faust         }
65*c217d954SCole Faust     }
66*c217d954SCole Faust 
67*c217d954SCole Faust     {
68*c217d954SCole Faust         mali_userspace::kbase_uk_hwcnt_reader_set_flags flags; // NOLINT
69*c217d954SCole Faust         memset(&flags, 0, sizeof(flags));
70*c217d954SCole Faust         flags.header.id    = mali_userspace::KBASE_FUNC_SET_FLAGS; // NOLINT
71*c217d954SCole Faust         flags.create_flags = mali_userspace::BASE_CONTEXT_CREATE_KERNEL_FLAGS;
72*c217d954SCole Faust 
73*c217d954SCole Faust         if(mali_userspace::mali_ioctl(fd, flags) != 0)
74*c217d954SCole Faust         {
75*c217d954SCole Faust             ARM_COMPUTE_ERROR("Failed settings flags ioctl.");
76*c217d954SCole Faust             close(fd);
77*c217d954SCole Faust         }
78*c217d954SCole Faust     }
79*c217d954SCole Faust 
80*c217d954SCole Faust     {
81*c217d954SCole Faust         mali_userspace::kbase_uk_gpuprops props;                         // NOLINT
82*c217d954SCole Faust         props.header.id = mali_userspace::KBASE_FUNC_GPU_PROPS_REG_DUMP; // NOLINT
83*c217d954SCole Faust 
84*c217d954SCole Faust         if(mali_ioctl(fd, props) != 0)
85*c217d954SCole Faust         {
86*c217d954SCole Faust             ARM_COMPUTE_ERROR("Failed settings flags ioctl.");
87*c217d954SCole Faust             close(fd);
88*c217d954SCole Faust         }
89*c217d954SCole Faust 
90*c217d954SCole Faust         MaliHWInfo hw_info; // NOLINT
91*c217d954SCole Faust         memset(&hw_info, 0, sizeof(hw_info));
92*c217d954SCole Faust         hw_info.gpu_id  = props.props.core_props.product_id;
93*c217d954SCole Faust         hw_info.r_value = props.props.core_props.major_revision;
94*c217d954SCole Faust         hw_info.p_value = props.props.core_props.minor_revision;
95*c217d954SCole Faust 
96*c217d954SCole Faust         for(unsigned int i = 0; i < props.props.coherency_info.num_core_groups; ++i)
97*c217d954SCole Faust         {
98*c217d954SCole Faust             hw_info.core_mask |= props.props.coherency_info.group[i].core_mask;
99*c217d954SCole Faust         }
100*c217d954SCole Faust 
101*c217d954SCole Faust         hw_info.mp_count = __builtin_popcountll(hw_info.core_mask);
102*c217d954SCole Faust 
103*c217d954SCole Faust         close(fd);
104*c217d954SCole Faust 
105*c217d954SCole Faust         return hw_info;
106*c217d954SCole Faust     }
107*c217d954SCole Faust }
108*c217d954SCole Faust } // namespace
109*c217d954SCole Faust 
MaliCounter(ScaleFactor scale_factor)110*c217d954SCole Faust MaliCounter::MaliCounter(ScaleFactor scale_factor)
111*c217d954SCole Faust {
112*c217d954SCole Faust     _counters =
113*c217d954SCole Faust     {
114*c217d954SCole Faust         { "GPU_ACTIVE", Measurement(0, "cycles") },
115*c217d954SCole Faust     };
116*c217d954SCole Faust 
117*c217d954SCole Faust     _core_counters =
118*c217d954SCole Faust     {
119*c217d954SCole Faust         { "ARITH_WORDS", { "Arithmetic pipe", std::map<int, uint64_t>(), "instructions" } },
120*c217d954SCole Faust         { "LS_ISSUE", { "LS pipe", std::map<int, uint64_t>(), "instructions" } },
121*c217d954SCole Faust         { "TEX_ISSUE", { "Texture pipe", std::map<int, uint64_t>(), "instructions" } },
122*c217d954SCole Faust         { "COMPUTE_ACTIVE", { "Compute core", std::map<int, uint64_t>(), "cycles" } },
123*c217d954SCole Faust         { "FRAG_ACTIVE", { "Fragment core", std::map<int, uint64_t>(), "cycles" } },
124*c217d954SCole Faust     };
125*c217d954SCole Faust 
126*c217d954SCole Faust     switch(scale_factor)
127*c217d954SCole Faust     {
128*c217d954SCole Faust         case ScaleFactor::NONE:
129*c217d954SCole Faust             _scale_factor = 1;
130*c217d954SCole Faust             _unit         = "";
131*c217d954SCole Faust             break;
132*c217d954SCole Faust         case ScaleFactor::SCALE_1K:
133*c217d954SCole Faust             _scale_factor = 1000;
134*c217d954SCole Faust             _unit         = "K ";
135*c217d954SCole Faust             break;
136*c217d954SCole Faust         case ScaleFactor::SCALE_1M:
137*c217d954SCole Faust             _scale_factor = 1000000;
138*c217d954SCole Faust             _unit         = "M ";
139*c217d954SCole Faust             break;
140*c217d954SCole Faust         default:
141*c217d954SCole Faust             ARM_COMPUTE_ERROR("Invalid scale");
142*c217d954SCole Faust     }
143*c217d954SCole Faust 
144*c217d954SCole Faust     init();
145*c217d954SCole Faust }
146*c217d954SCole Faust 
~MaliCounter()147*c217d954SCole Faust MaliCounter::~MaliCounter()
148*c217d954SCole Faust {
149*c217d954SCole Faust     term();
150*c217d954SCole Faust }
151*c217d954SCole Faust 
init()152*c217d954SCole Faust void MaliCounter::init()
153*c217d954SCole Faust {
154*c217d954SCole Faust     term();
155*c217d954SCole Faust 
156*c217d954SCole Faust     MaliHWInfo hw_info = get_mali_hw_info(_device);
157*c217d954SCole Faust 
158*c217d954SCole Faust     _num_cores = hw_info.mp_count;
159*c217d954SCole Faust 
160*c217d954SCole Faust     _fd = open(_device, O_RDWR | O_CLOEXEC | O_NONBLOCK); // NOLINT
161*c217d954SCole Faust 
162*c217d954SCole Faust     if(_fd < 0)
163*c217d954SCole Faust     {
164*c217d954SCole Faust         ARM_COMPUTE_ERROR("Failed to open /dev/mali0.");
165*c217d954SCole Faust     }
166*c217d954SCole Faust 
167*c217d954SCole Faust     {
168*c217d954SCole Faust         mali_userspace::kbase_uk_hwcnt_reader_version_check_args check; // NOLINT
169*c217d954SCole Faust         memset(&check, 0, sizeof(check));
170*c217d954SCole Faust 
171*c217d954SCole Faust         if(mali_userspace::mali_ioctl(_fd, check) != 0)
172*c217d954SCole Faust         {
173*c217d954SCole Faust             ARM_COMPUTE_ERROR("Failed to get ABI version.");
174*c217d954SCole Faust         }
175*c217d954SCole Faust         else if(check.major < 10)
176*c217d954SCole Faust         {
177*c217d954SCole Faust             ARM_COMPUTE_ERROR("Unsupported ABI version 10.");
178*c217d954SCole Faust         }
179*c217d954SCole Faust     }
180*c217d954SCole Faust 
181*c217d954SCole Faust     {
182*c217d954SCole Faust         mali_userspace::kbase_uk_hwcnt_reader_set_flags flags; // NOLINT
183*c217d954SCole Faust         memset(&flags, 0, sizeof(flags));
184*c217d954SCole Faust         flags.header.id    = mali_userspace::KBASE_FUNC_SET_FLAGS; // NOLINT
185*c217d954SCole Faust         flags.create_flags = mali_userspace::BASE_CONTEXT_CREATE_KERNEL_FLAGS;
186*c217d954SCole Faust 
187*c217d954SCole Faust         if(mali_userspace::mali_ioctl(_fd, flags) != 0)
188*c217d954SCole Faust         {
189*c217d954SCole Faust             ARM_COMPUTE_ERROR("Failed settings flags ioctl.");
190*c217d954SCole Faust         }
191*c217d954SCole Faust     }
192*c217d954SCole Faust 
193*c217d954SCole Faust     {
194*c217d954SCole Faust         mali_userspace::kbase_uk_hwcnt_reader_setup setup; // NOLINT
195*c217d954SCole Faust         memset(&setup, 0, sizeof(setup));
196*c217d954SCole Faust         setup.header.id    = mali_userspace::KBASE_FUNC_HWCNT_READER_SETUP; // NOLINT
197*c217d954SCole Faust         setup.buffer_count = _buffer_count;
198*c217d954SCole Faust         setup.jm_bm        = -1;
199*c217d954SCole Faust         setup.shader_bm    = -1;
200*c217d954SCole Faust         setup.tiler_bm     = -1;
201*c217d954SCole Faust         setup.mmu_l2_bm    = -1;
202*c217d954SCole Faust         setup.fd           = -1;
203*c217d954SCole Faust 
204*c217d954SCole Faust         if(mali_userspace::mali_ioctl(_fd, setup) != 0)
205*c217d954SCole Faust         {
206*c217d954SCole Faust             ARM_COMPUTE_ERROR("Failed setting hwcnt reader ioctl.");
207*c217d954SCole Faust         }
208*c217d954SCole Faust 
209*c217d954SCole Faust         _hwc_fd = setup.fd;
210*c217d954SCole Faust     }
211*c217d954SCole Faust 
212*c217d954SCole Faust     {
213*c217d954SCole Faust         uint32_t api_version = ~mali_userspace::HWCNT_READER_API;
214*c217d954SCole Faust 
215*c217d954SCole Faust         if(ioctl(_hwc_fd, mali_userspace::KBASE_HWCNT_READER_GET_API_VERSION, &api_version) != 0) // NOLINT
216*c217d954SCole Faust         {
217*c217d954SCole Faust             ARM_COMPUTE_ERROR("Could not determine hwcnt reader API.");
218*c217d954SCole Faust         }
219*c217d954SCole Faust         else if(api_version != mali_userspace::HWCNT_READER_API)
220*c217d954SCole Faust         {
221*c217d954SCole Faust             ARM_COMPUTE_ERROR("Invalid API version.");
222*c217d954SCole Faust         }
223*c217d954SCole Faust     }
224*c217d954SCole Faust 
225*c217d954SCole Faust     if(ioctl(_hwc_fd, static_cast<int>(mali_userspace::KBASE_HWCNT_READER_GET_BUFFER_SIZE), &_buffer_size) != 0) // NOLINT
226*c217d954SCole Faust     {
227*c217d954SCole Faust         ARM_COMPUTE_ERROR("Failed to get buffer size.");
228*c217d954SCole Faust     }
229*c217d954SCole Faust 
230*c217d954SCole Faust     if(ioctl(_hwc_fd, static_cast<int>(mali_userspace::KBASE_HWCNT_READER_GET_HWVER), &_hw_ver) != 0) // NOLINT
231*c217d954SCole Faust     {
232*c217d954SCole Faust         ARM_COMPUTE_ERROR("Could not determine HW version.");
233*c217d954SCole Faust     }
234*c217d954SCole Faust 
235*c217d954SCole Faust     if(_hw_ver < 5)
236*c217d954SCole Faust     {
237*c217d954SCole Faust         ARM_COMPUTE_ERROR("Unsupported HW version.");
238*c217d954SCole Faust     }
239*c217d954SCole Faust 
240*c217d954SCole Faust     _sample_data = static_cast<uint8_t *>(mmap(nullptr, _buffer_count * _buffer_size, PROT_READ, MAP_PRIVATE, _hwc_fd, 0));
241*c217d954SCole Faust 
242*c217d954SCole Faust     if(_sample_data == MAP_FAILED) // NOLINT
243*c217d954SCole Faust     {
244*c217d954SCole Faust         ARM_COMPUTE_ERROR("Failed to map sample data.");
245*c217d954SCole Faust     }
246*c217d954SCole Faust 
247*c217d954SCole Faust     auto product = std::find_if(std::begin(mali_userspace::products), std::end(mali_userspace::products), [&](const mali_userspace::CounterMapping & cm)
248*c217d954SCole Faust     {
249*c217d954SCole Faust         return (cm.product_mask & hw_info.gpu_id) == cm.product_id;
250*c217d954SCole Faust     });
251*c217d954SCole Faust 
252*c217d954SCole Faust     if(product != std::end(mali_userspace::products))
253*c217d954SCole Faust     {
254*c217d954SCole Faust         _names_lut = product->names_lut;
255*c217d954SCole Faust     }
256*c217d954SCole Faust     else
257*c217d954SCole Faust     {
258*c217d954SCole Faust         ARM_COMPUTE_ERROR("Could not identify GPU.");
259*c217d954SCole Faust     }
260*c217d954SCole Faust 
261*c217d954SCole Faust     _raw_counter_buffer.resize(_buffer_size / sizeof(uint32_t));
262*c217d954SCole Faust 
263*c217d954SCole Faust     // Build core remap table.
264*c217d954SCole Faust     _core_index_remap.clear();
265*c217d954SCole Faust     _core_index_remap.reserve(hw_info.mp_count);
266*c217d954SCole Faust 
267*c217d954SCole Faust     unsigned int mask = hw_info.core_mask;
268*c217d954SCole Faust 
269*c217d954SCole Faust     while(mask != 0)
270*c217d954SCole Faust     {
271*c217d954SCole Faust         unsigned int bit = __builtin_ctz(mask);
272*c217d954SCole Faust         _core_index_remap.push_back(bit);
273*c217d954SCole Faust         mask &= ~(1u << bit);
274*c217d954SCole Faust     }
275*c217d954SCole Faust }
276*c217d954SCole Faust 
term()277*c217d954SCole Faust void MaliCounter::term()
278*c217d954SCole Faust {
279*c217d954SCole Faust     if(_sample_data != nullptr)
280*c217d954SCole Faust     {
281*c217d954SCole Faust         munmap(_sample_data, _buffer_count * _buffer_size);
282*c217d954SCole Faust         _sample_data = nullptr;
283*c217d954SCole Faust     }
284*c217d954SCole Faust 
285*c217d954SCole Faust     if(_hwc_fd >= 0)
286*c217d954SCole Faust     {
287*c217d954SCole Faust         close(_hwc_fd);
288*c217d954SCole Faust         _hwc_fd = -1;
289*c217d954SCole Faust     }
290*c217d954SCole Faust 
291*c217d954SCole Faust     if(_fd >= 0)
292*c217d954SCole Faust     {
293*c217d954SCole Faust         close(_fd);
294*c217d954SCole Faust         _fd = -1;
295*c217d954SCole Faust     }
296*c217d954SCole Faust }
297*c217d954SCole Faust 
sample_counters()298*c217d954SCole Faust void MaliCounter::sample_counters()
299*c217d954SCole Faust {
300*c217d954SCole Faust     if(ioctl(_hwc_fd, mali_userspace::KBASE_HWCNT_READER_DUMP, 0) != 0)
301*c217d954SCole Faust     {
302*c217d954SCole Faust         ARM_COMPUTE_ERROR("Could not sample hardware counters.");
303*c217d954SCole Faust     }
304*c217d954SCole Faust }
305*c217d954SCole Faust 
wait_next_event()306*c217d954SCole Faust void MaliCounter::wait_next_event()
307*c217d954SCole Faust {
308*c217d954SCole Faust     pollfd poll_fd; // NOLINT
309*c217d954SCole Faust     poll_fd.fd     = _hwc_fd;
310*c217d954SCole Faust     poll_fd.events = POLLIN;
311*c217d954SCole Faust 
312*c217d954SCole Faust     const int count = poll(&poll_fd, 1, -1);
313*c217d954SCole Faust 
314*c217d954SCole Faust     if(count < 0)
315*c217d954SCole Faust     {
316*c217d954SCole Faust         ARM_COMPUTE_ERROR("poll() failed.");
317*c217d954SCole Faust     }
318*c217d954SCole Faust 
319*c217d954SCole Faust     if((poll_fd.revents & POLLIN) != 0)
320*c217d954SCole Faust     {
321*c217d954SCole Faust         mali_userspace::kbase_hwcnt_reader_metadata meta; // NOLINT
322*c217d954SCole Faust 
323*c217d954SCole Faust         if(ioctl(_hwc_fd, static_cast<int>(mali_userspace::KBASE_HWCNT_READER_GET_BUFFER), &meta) != 0) // NOLINT
324*c217d954SCole Faust         {
325*c217d954SCole Faust             ARM_COMPUTE_ERROR("Failed READER_GET_BUFFER.");
326*c217d954SCole Faust         }
327*c217d954SCole Faust 
328*c217d954SCole Faust         memcpy(_raw_counter_buffer.data(), _sample_data + _buffer_size * meta.buffer_idx, _buffer_size);
329*c217d954SCole Faust         _timestamp = meta.timestamp;
330*c217d954SCole Faust 
331*c217d954SCole Faust         if(ioctl(_hwc_fd, mali_userspace::KBASE_HWCNT_READER_PUT_BUFFER, &meta) != 0) // NOLINT
332*c217d954SCole Faust         {
333*c217d954SCole Faust             ARM_COMPUTE_ERROR("Failed READER_PUT_BUFFER.");
334*c217d954SCole Faust         }
335*c217d954SCole Faust     }
336*c217d954SCole Faust     else if((poll_fd.revents & POLLHUP) != 0)
337*c217d954SCole Faust     {
338*c217d954SCole Faust         ARM_COMPUTE_ERROR("HWC hung up.");
339*c217d954SCole Faust     }
340*c217d954SCole Faust }
341*c217d954SCole Faust 
get_counters() const342*c217d954SCole Faust const uint32_t *MaliCounter::get_counters() const
343*c217d954SCole Faust {
344*c217d954SCole Faust     return _raw_counter_buffer.data();
345*c217d954SCole Faust }
346*c217d954SCole Faust 
get_counters(mali_userspace::MaliCounterBlockName block,int core) const347*c217d954SCole Faust const uint32_t *MaliCounter::get_counters(mali_userspace::MaliCounterBlockName block, int core) const
348*c217d954SCole Faust {
349*c217d954SCole Faust     switch(block)
350*c217d954SCole Faust     {
351*c217d954SCole Faust         case mali_userspace::MALI_NAME_BLOCK_JM:
352*c217d954SCole Faust             return _raw_counter_buffer.data() + mali_userspace::MALI_NAME_BLOCK_SIZE * 0;
353*c217d954SCole Faust         case mali_userspace::MALI_NAME_BLOCK_MMU:
354*c217d954SCole Faust             return _raw_counter_buffer.data() + mali_userspace::MALI_NAME_BLOCK_SIZE * 2;
355*c217d954SCole Faust         case mali_userspace::MALI_NAME_BLOCK_TILER:
356*c217d954SCole Faust             return _raw_counter_buffer.data() + mali_userspace::MALI_NAME_BLOCK_SIZE * 1;
357*c217d954SCole Faust         default:
358*c217d954SCole Faust             if(core < 0)
359*c217d954SCole Faust             {
360*c217d954SCole Faust                 ARM_COMPUTE_ERROR("Invalid core number.");
361*c217d954SCole Faust             }
362*c217d954SCole Faust 
363*c217d954SCole Faust             return _raw_counter_buffer.data() + mali_userspace::MALI_NAME_BLOCK_SIZE * (3 + _core_index_remap[core]);
364*c217d954SCole Faust     }
365*c217d954SCole Faust }
366*c217d954SCole Faust 
find_counter_index_by_name(mali_userspace::MaliCounterBlockName block,const char * name)367*c217d954SCole Faust int MaliCounter::find_counter_index_by_name(mali_userspace::MaliCounterBlockName block, const char *name)
368*c217d954SCole Faust {
369*c217d954SCole Faust     const char *const *names = &_names_lut[mali_userspace::MALI_NAME_BLOCK_SIZE * block];
370*c217d954SCole Faust 
371*c217d954SCole Faust     for(int i = 0; i < mali_userspace::MALI_NAME_BLOCK_SIZE; ++i)
372*c217d954SCole Faust     {
373*c217d954SCole Faust         if(strstr(names[i], name) != nullptr)
374*c217d954SCole Faust         {
375*c217d954SCole Faust             return i;
376*c217d954SCole Faust         }
377*c217d954SCole Faust     }
378*c217d954SCole Faust 
379*c217d954SCole Faust     return -1;
380*c217d954SCole Faust }
381*c217d954SCole Faust 
start()382*c217d954SCole Faust void MaliCounter::start()
383*c217d954SCole Faust {
384*c217d954SCole Faust     sample_counters();
385*c217d954SCole Faust     wait_next_event();
386*c217d954SCole Faust     _start_time = _timestamp;
387*c217d954SCole Faust }
388*c217d954SCole Faust 
stop()389*c217d954SCole Faust void MaliCounter::stop()
390*c217d954SCole Faust {
391*c217d954SCole Faust     sample_counters();
392*c217d954SCole Faust     wait_next_event();
393*c217d954SCole Faust 
394*c217d954SCole Faust     const uint32_t *counter    = get_counters(mali_userspace::MALI_NAME_BLOCK_JM);
395*c217d954SCole Faust     _counters.at("GPU_ACTIVE") = Measurement(counter[find_counter_index_by_name(mali_userspace::MALI_NAME_BLOCK_JM, "GPU_ACTIVE")], _counters.at("GPU_ACTIVE").unit());
396*c217d954SCole Faust 
397*c217d954SCole Faust     const int arith_index   = find_counter_index_by_name(mali_userspace::MALI_NAME_BLOCK_SHADER, "ARITH_WORDS");
398*c217d954SCole Faust     const int ls_index      = find_counter_index_by_name(mali_userspace::MALI_NAME_BLOCK_SHADER, "LS_ISSUE");
399*c217d954SCole Faust     const int tex_index     = find_counter_index_by_name(mali_userspace::MALI_NAME_BLOCK_SHADER, "TEX_ISSUE");
400*c217d954SCole Faust     const int compute_index = find_counter_index_by_name(mali_userspace::MALI_NAME_BLOCK_SHADER, "COMPUTE_ACTIVE");
401*c217d954SCole Faust     const int frag_index    = find_counter_index_by_name(mali_userspace::MALI_NAME_BLOCK_SHADER, "FRAG_ACTIVE");
402*c217d954SCole Faust 
403*c217d954SCole Faust     // Shader core counters can be averaged if desired, but here we don't.
404*c217d954SCole Faust     for(uint32_t core = 0; core < _num_cores; ++core)
405*c217d954SCole Faust     {
406*c217d954SCole Faust         const uint32_t *sc_counter = get_counters(mali_userspace::MALI_NAME_BLOCK_SHADER, core);
407*c217d954SCole Faust 
408*c217d954SCole Faust         _core_counters.at("ARITH_WORDS").values[core]    = sc_counter[arith_index];
409*c217d954SCole Faust         _core_counters.at("LS_ISSUE").values[core]       = sc_counter[ls_index];
410*c217d954SCole Faust         _core_counters.at("TEX_ISSUE").values[core]      = sc_counter[tex_index];
411*c217d954SCole Faust         _core_counters.at("COMPUTE_ACTIVE").values[core] = sc_counter[compute_index];
412*c217d954SCole Faust         _core_counters.at("FRAG_ACTIVE").values[core]    = sc_counter[frag_index];
413*c217d954SCole Faust     }
414*c217d954SCole Faust 
415*c217d954SCole Faust     _stop_time = _timestamp;
416*c217d954SCole Faust }
417*c217d954SCole Faust 
id() const418*c217d954SCole Faust std::string MaliCounter::id() const
419*c217d954SCole Faust {
420*c217d954SCole Faust     return "Mali Counter";
421*c217d954SCole Faust }
422*c217d954SCole Faust 
measurements() const423*c217d954SCole Faust Instrument::MeasurementsMap MaliCounter::measurements() const
424*c217d954SCole Faust {
425*c217d954SCole Faust     Measurement counters((_counters.at("GPU_ACTIVE").value() / _scale_factor).v.floating_point, _unit + _counters.at("GPU_ACTIVE").unit()); //NOLINT
426*c217d954SCole Faust 
427*c217d954SCole Faust     MeasurementsMap measurements
428*c217d954SCole Faust     {
429*c217d954SCole Faust         { "Timespan", Measurement(_stop_time - _start_time, "ns") },
430*c217d954SCole Faust         { "GPU active", counters },
431*c217d954SCole Faust     };
432*c217d954SCole Faust 
433*c217d954SCole Faust     for(const auto &counter : _core_counters)
434*c217d954SCole Faust     {
435*c217d954SCole Faust         for(const auto &core : counter.second.values)
436*c217d954SCole Faust         {
437*c217d954SCole Faust             measurements.emplace(counter.second.name + " #" + support::cpp11::to_string(core.first), Measurement(core.second / _scale_factor, _unit + counter.second.unit));
438*c217d954SCole Faust         }
439*c217d954SCole Faust     }
440*c217d954SCole Faust 
441*c217d954SCole Faust     return measurements;
442*c217d954SCole Faust }
443*c217d954SCole Faust } // namespace framework
444*c217d954SCole Faust } // namespace test
445*c217d954SCole Faust } // namespace arm_compute
446