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