blob: ee3c114ba062caa232a0b73f0eedf029a093137d [file] [log] [blame]
telsoa01c577f2c2018-08-31 09:22:23 +01001//
2// Copyright © 2017 Arm Ltd. All rights reserved.
David Beckecb56cd2018-09-05 12:52:57 +01003// SPDX-License-Identifier: MIT
telsoa01c577f2c2018-08-31 09:22:23 +01004//
5
6#include "OpenClTimer.hpp"
7
8#include <string>
9#include <sstream>
10
Derek Lamberti901ea112019-12-10 22:07:09 +000011#include <boost/core/ignore_unused.hpp>
12
telsoa01c577f2c2018-08-31 09:22:23 +010013namespace armnn
14{
15
16OpenClTimer::OpenClTimer()
17{
18}
19
20void OpenClTimer::Start()
21{
22 m_Kernels.clear();
23
24 auto interceptor = [this]( cl_command_queue command_queue,
25 cl_kernel kernel,
26 cl_uint work_dim,
27 const size_t *gwo,
28 const size_t *gws,
29 const size_t *lws,
30 cl_uint num_events_in_wait_list,
31 const cl_event * event_wait_list,
32 cl_event * event)
33 {
Derek Lamberti901ea112019-12-10 22:07:09 +000034 boost::ignore_unused(event);
telsoa01c577f2c2018-08-31 09:22:23 +010035 cl_int retVal = 0;
36
37 // Get the name of the kernel
38 cl::Kernel retainedKernel(kernel, true);
39 std::stringstream ss;
40 ss << retainedKernel.getInfo<CL_KERNEL_FUNCTION_NAME>();
41
42 // Embed workgroup sizes into the name
43 if(gws != nullptr)
44 {
45 ss << " GWS[" << gws[0] << "," << gws[1] << "," << gws[2] << "]";
46 }
47 if(lws != nullptr)
48 {
49 ss << " LWS[" << lws[0] << "," << lws[1] << "," << lws[2] << "]";
50 }
51
52 cl_event customEvent;
53
54 // Forward to original OpenCl function
55 retVal = m_OriginalEnqueueFunction( command_queue,
56 kernel,
57 work_dim,
58 gwo,
59 gws,
60 lws,
61 num_events_in_wait_list,
62 event_wait_list,
63 &customEvent);
64
65 // Store the Kernel info for later GetMeasurements() call
66 m_Kernels.emplace_back(ss.str(), customEvent);
67
68 return retVal;
69 };
70
71 m_OriginalEnqueueFunction = CLSymbols::get().clEnqueueNDRangeKernel_ptr;
72 CLSymbols::get().clEnqueueNDRangeKernel_ptr = interceptor;
73}
74
75void OpenClTimer::Stop()
76{
77 CLSymbols::get().clEnqueueNDRangeKernel_ptr = m_OriginalEnqueueFunction;
78}
79
80std::vector<Measurement> OpenClTimer::GetMeasurements() const
81{
82 std::vector<Measurement> measurements;
83
84 cl_command_queue_properties clQueueProperties = CLScheduler::get().queue().getInfo<CL_QUEUE_PROPERTIES>();
85
86 int idx = 0;
87 for (auto& kernel : m_Kernels)
88 {
89 std::string name = std::string(this->GetName()) + "/" + std::to_string(idx++) + ": " + kernel.m_Name;
90
91 double timeUs = 0.0;
92 if((clQueueProperties & CL_QUEUE_PROFILING_ENABLE) != 0)
93 {
94 // Wait for the event to finish before accessing profile results.
95 kernel.m_Event.wait();
96
97 cl_ulong start = kernel.m_Event.getProfilingInfo<CL_PROFILING_COMMAND_START>();
98 cl_ulong end = kernel.m_Event.getProfilingInfo<CL_PROFILING_COMMAND_END>();
99 timeUs = static_cast<double>(end - start) / 1000.0;
100 }
101
102 measurements.emplace_back(name, timeUs, Measurement::Unit::TIME_US);
103 }
104
105 return measurements;
106}
107
108} //namespace armnn