blob: a4958c10e0036156f5a3956195c6e924ed0f755f [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
Jan Eilers8eb25602020-03-09 12:13:48 +00008#include <armnn/utility/IgnoreUnused.hpp>
9
telsoa01c577f2c2018-08-31 09:22:23 +010010#include <string>
11#include <sstream>
12
Derek Lamberti901ea112019-12-10 22:07:09 +000013
telsoa01c577f2c2018-08-31 09:22:23 +010014namespace armnn
15{
16
17OpenClTimer::OpenClTimer()
18{
19}
20
21void OpenClTimer::Start()
22{
23 m_Kernels.clear();
24
25 auto interceptor = [this]( cl_command_queue command_queue,
26 cl_kernel kernel,
27 cl_uint work_dim,
28 const size_t *gwo,
29 const size_t *gws,
30 const size_t *lws,
31 cl_uint num_events_in_wait_list,
32 const cl_event * event_wait_list,
33 cl_event * event)
34 {
Jan Eilers8eb25602020-03-09 12:13:48 +000035 IgnoreUnused(event);
telsoa01c577f2c2018-08-31 09:22:23 +010036 cl_int retVal = 0;
37
38 // Get the name of the kernel
39 cl::Kernel retainedKernel(kernel, true);
40 std::stringstream ss;
41 ss << retainedKernel.getInfo<CL_KERNEL_FUNCTION_NAME>();
42
43 // Embed workgroup sizes into the name
44 if(gws != nullptr)
45 {
46 ss << " GWS[" << gws[0] << "," << gws[1] << "," << gws[2] << "]";
47 }
48 if(lws != nullptr)
49 {
50 ss << " LWS[" << lws[0] << "," << lws[1] << "," << lws[2] << "]";
51 }
52
53 cl_event customEvent;
54
55 // Forward to original OpenCl function
56 retVal = m_OriginalEnqueueFunction( command_queue,
57 kernel,
58 work_dim,
59 gwo,
60 gws,
61 lws,
62 num_events_in_wait_list,
63 event_wait_list,
64 &customEvent);
65
66 // Store the Kernel info for later GetMeasurements() call
67 m_Kernels.emplace_back(ss.str(), customEvent);
68
Sadik Armagan94c91b22022-01-11 12:14:28 +000069 if(event != nullptr)
70 {
71 //return cl_event from the intercepted call
72 clRetainEvent(customEvent);
73 *event = customEvent;
74 }
75
telsoa01c577f2c2018-08-31 09:22:23 +010076 return retVal;
77 };
78
79 m_OriginalEnqueueFunction = CLSymbols::get().clEnqueueNDRangeKernel_ptr;
80 CLSymbols::get().clEnqueueNDRangeKernel_ptr = interceptor;
81}
82
83void OpenClTimer::Stop()
84{
85 CLSymbols::get().clEnqueueNDRangeKernel_ptr = m_OriginalEnqueueFunction;
86}
87
88std::vector<Measurement> OpenClTimer::GetMeasurements() const
89{
90 std::vector<Measurement> measurements;
91
92 cl_command_queue_properties clQueueProperties = CLScheduler::get().queue().getInfo<CL_QUEUE_PROPERTIES>();
93
94 int idx = 0;
95 for (auto& kernel : m_Kernels)
96 {
97 std::string name = std::string(this->GetName()) + "/" + std::to_string(idx++) + ": " + kernel.m_Name;
98
99 double timeUs = 0.0;
100 if((clQueueProperties & CL_QUEUE_PROFILING_ENABLE) != 0)
101 {
102 // Wait for the event to finish before accessing profile results.
103 kernel.m_Event.wait();
104
105 cl_ulong start = kernel.m_Event.getProfilingInfo<CL_PROFILING_COMMAND_START>();
106 cl_ulong end = kernel.m_Event.getProfilingInfo<CL_PROFILING_COMMAND_END>();
107 timeUs = static_cast<double>(end - start) / 1000.0;
108 }
109
110 measurements.emplace_back(name, timeUs, Measurement::Unit::TIME_US);
111 }
112
113 return measurements;
114}
115
116} //namespace armnn