ArmNN
 25.11
Loading...
Searching...
No Matches
ClContextControl.cpp
Go to the documentation of this file.
1//
2// Copyright © 2017, 2024 Arm Ltd and Contributors. All rights reserved.
3// SPDX-License-Identifier: MIT
4//
5
7
9
10#include <LeakChecking.hpp>
11
12#include <arm_compute/core/CL/CLKernelLibrary.h>
13#include <arm_compute/runtime/CL/CLScheduler.h>
14
15#include <fmt/format.h>
16
17namespace cl
18{
19class Context;
20class CommandQueue;
21class Device;
22}
23
24namespace armnn
25{
26
27ClContextControl::ClContextControl(arm_compute::CLTuner *tuner,
28 arm_compute::CLGEMMHeuristicsHandle* heuristicsHandle,
29 bool profilingEnabled)
30 : m_Tuner(tuner)
31 , m_HeuristicsHandle(heuristicsHandle)
32 , m_ProfilingEnabled(profilingEnabled)
33{
34 try
35 {
36 std::vector<cl::Platform> platforms;
37 cl::Platform::get(&platforms);
38
39 // Selects default platform for the first element.
40 cl::Platform::setDefault(platforms[0]);
41
42 std::vector<cl::Device> devices;
43 platforms[0].getDevices(CL_DEVICE_TYPE_GPU, &devices);
44
45 // Selects default device for the first element.
46 cl::Device::setDefault(devices[0]);
47 }
48 catch (const cl::Error& clError)
49 {
50 throw ClRuntimeUnavailableException(fmt::format(
51 "Could not initialize the CL runtime. Error description: {0}. CL error code: {1}",
52 clError.what(), clError.err()));
53 }
54
55 // Removes the use of global CL context.
56 cl::Context::setDefault(cl::Context{});
57
58 // Removes the use of global CL command queue.
59 cl::CommandQueue::setDefault(cl::CommandQueue{});
60
61 // Always load the OpenCL runtime.
63}
64
66{
67 // Load the OpencCL runtime without the tuned parameters to free the memory for them.
68 try
69 {
71 }
72 catch (const cl::Error& clError)
73 {
74 // This should not happen, it is ignored if it does.
75
76 // Coverity fix: BOOST_LOG_TRIVIAL (previously used here to report the error) may throw an
77 // exception of type std::length_error.
78 // Using stderr instead in this context as there is no point in nesting try-catch blocks here.
79 std::cerr << "A CL error occurred unloading the runtime tuner parameters: "
80 << clError.what() << ". CL error code is: " << clError.err() << std::endl;
81 }
82}
83
85{
86 DoLoadOpenClRuntime(true);
87}
88
90{
91 DoLoadOpenClRuntime(false);
92}
93
94void ClContextControl::DoLoadOpenClRuntime(bool updateTunedParameters)
95{
96 cl::Device device = cl::Device::getDefault();
97 cl::Context context;
98 cl::CommandQueue commandQueue;
99
100 if (arm_compute::CLScheduler::get().is_initialised() && arm_compute::CLScheduler::get().context()() != NULL)
101 {
102 // Wait for all queued CL requests to finish before reinitialising it.
103 arm_compute::CLScheduler::get().sync();
104 }
105
106 try
107 {
108 arm_compute::CLKernelLibrary::get().clear_programs_cache();
109 // Initialise the scheduler with a dummy context to release the LLVM data (which only happens when there are no
110 // context references); it is initialised again, with a proper context, later.
111 arm_compute::CLScheduler::get().init(context, commandQueue, device);
112 arm_compute::CLKernelLibrary::get().init(".", context, device);
113
114 {
115 //
116 // Here we replace the context with a new one in which
117 // the memory leak checks show it as an extra allocation but
118 // because of the scope of the leak checks, it doesn't count
119 // the disposal of the original object. On the other hand it
120 // does count the creation of this context which it flags
121 // as a memory leak. By adding the following line we prevent
122 // this to happen.
123 //
125 context = cl::Context(device);
126 }
127
128 // NOTE: In this specific case profiling has to be enabled on the command queue
129 // in order for the CLTuner to work.
130 bool profilingNeededForClTuner = updateTunedParameters && m_Tuner &&
131 m_Tuner->tune_new_kernels();
132
133 if (m_ProfilingEnabled || profilingNeededForClTuner)
134 {
135 // Create a new queue with profiling enabled.
136 commandQueue = cl::CommandQueue(context, device, CL_QUEUE_PROFILING_ENABLE);
137 }
138 else
139 {
140 // Use default queue.
141 commandQueue = cl::CommandQueue(context, device);
142 }
143 }
144 catch (const cl::Error& clError)
145 {
146 throw ClRuntimeUnavailableException(fmt::format(
147 "Could not initialize the CL runtime. Error description: {0}. CL error code: {1}",
148 clError.what(), clError.err()));
149 }
150
151 // Note the first argument (path to cl source code) will be ignored as they should be embedded in the armcompute.
152 arm_compute::CLKernelLibrary::get().init(".", context, device);
153 arm_compute::CLScheduler::get().init(context, commandQueue, device, m_Tuner, m_HeuristicsHandle);
154}
155
157{
158 DoLoadOpenClRuntime(true);
159}
160
161} // namespace armnn
#define ARMNN_DISABLE_LEAK_CHECKING_IN_SCOPE()
ClContextControl(arm_compute::CLTuner *=nullptr, arm_compute::CLGEMMHeuristicsHandle *=nullptr, bool profilingEnabled=false)
Copyright (c) 2021 ARM Limited and Contributors.