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