ArmNN
 24.02
ClBackendContext.cpp
Go to the documentation of this file.
1 //
2 // Copyright © 2017, 2023 Arm Ltd and Contributors. All rights reserved.
3 // SPDX-License-Identifier: MIT
4 //
5 
6 #include "ClBackendContext.hpp"
7 #include "ClContextControl.hpp"
8 
9 #include <armnn/Logging.hpp>
10 #include <armnn/utility/Assert.hpp>
12 
13 #include <arm_compute/core/CL/OpenCL.h>
14 #include <arm_compute/core/CL/CLKernelLibrary.h>
15 #include <arm_compute/runtime/CL/CLScheduler.h>
16 #include <arm_compute/runtime/CL/CLTunerTypes.h>
17 
18 namespace armnn
19 {
20 
21 struct ClBackendContext::ClContextControlWrapper
22 {
23  ClContextControlWrapper(arm_compute::CLTuner* tuner,
24  arm_compute::CLGEMMHeuristicsHandle* heuristicsHandle,
25  bool profilingEnabled)
26  : m_ClContextControl(tuner, heuristicsHandle, profilingEnabled)
27  {}
28 
29  bool Sync()
30  {
31  if (arm_compute::CLScheduler::get().context()() != NULL)
32  {
33  // Waits for all queued CL requests to finish before unloading the network they may be using.
34  try
35  {
36  // Coverity fix: arm_compute::CLScheduler::sync() may throw an exception of type cl::Error.
37  arm_compute::CLScheduler::get().sync();
38  }
39  catch (const cl::Error&)
40  {
41  ARMNN_LOG(warning) << "Runtime::UnloadNetwork(): an error occurred while waiting for "
42  "the queued CL requests to finish";
43  return false;
44  }
45  }
46 
47  return true;
48  }
49 
50  void ClearClCache()
51  {
52  if (arm_compute::CLScheduler::get().context()() != NULL)
53  {
54  // There are no loaded networks left, so clear the CL cache to free up memory
55  m_ClContextControl.ClearClCache();
56  }
57  }
58 
59  ClContextControl m_ClContextControl;
60 };
61 
63  : IBackendContext(options)
64  , m_TuningFile()
65 {
66  bool kernelProfiling = options.m_EnableGpuProfiling;
67 
68  arm_compute::CLTuner* tuner = nullptr;
69  arm_compute::CLGEMMHeuristicsHandle* mlgoTuner = nullptr;
70  bool useLegacyTunerAPI = options.m_GpuAccTunedParameters.get() != nullptr;
71  if (useLegacyTunerAPI)
72  {
73  auto clTunerParams = PolymorphicDowncast<ClTunedParameters*>(
74  options.m_GpuAccTunedParameters.get());
75  tuner = &clTunerParams->m_Tuner;
76 
77  if (tuner)
78  {
79  auto ConvertTuningLevel = [](IGpuAccTunedParameters::TuningLevel level,
81  {
83  {
84  return TuningLevel::None;
85  }
86 
87  switch(level)
88  {
90  return TuningLevel::Rapid;
92  return TuningLevel::Normal;
95  default:
96  {
97  ARMNN_ASSERT_MSG(false, "Tuning level not recognised.");
98  return TuningLevel::None;
99  }
100  }
101  };
102 
103  TuningLevel tuningLevel = ConvertTuningLevel(clTunerParams->m_TuningLevel, clTunerParams->m_Mode);
104  ConfigureTuner(*tuner, tuningLevel);
105  }
106  }
107  else //New backend options API
108  {
109  const TuningLevel defaultTuningLevel = TuningLevel::None;
110  auto tuningLevel = defaultTuningLevel;
111 
112  ParseOptions(options.m_BackendOptions, "GpuAcc", [&](std::string name, const BackendOptions::Var& value)
113  {
114  if (name == "KernelProfilingEnabled")
115  {
116  kernelProfiling |= ParseBooleanBackendOption(value, false);
117  } else if (name == "TuningFile")
118  {
119  m_TuningFile = ParseStringBackendOption(value, "");
120  } else if (name == "TuningLevel")
121  {
122  tuningLevel = ParseTuningLevel(value, defaultTuningLevel);
123  }
124  else if (name == "MLGOTuningFilePath")
125  {
127  }
128  });
129 
130  // Create the tuner, in tuning mode initially.
131  m_Tuner = std::make_unique<arm_compute::CLTuner>(true);
132 
133  ConfigureTuner(*(m_Tuner.get()), tuningLevel);
134 
135  if (!m_TuningFile.empty())
136  {
137  try
138  {
139  ARMNN_LOG(info) << "Loading Gpu tuning data from file: " << m_TuningFile;
140  m_Tuner->load_from_file(m_TuningFile.c_str());
141  }
142  catch (const std::exception& e)
143  {
144  // Warn if not tuning, otherwise tuning will generate new params
145  if (tuningLevel == TuningLevel::None)
146  {
147  ARMNN_LOG(warning) << "Could not load GpuAcc tuner data file.";
148  }
149  }
150  }
151 
152  if (!m_MLGOTuningFile.empty())
153  {
154  try
155  {
156  ARMNN_LOG(info) << "Loading Gpu MLGO tuning data from file: " << m_TuningFile;
157  if(m_MLGOTuner.reload_from_file(m_MLGOTuningFile.c_str()))
158  {
159  mlgoTuner = &m_MLGOTuner;
160  }
161  }
162  catch (const std::exception& e)
163  {
164  ARMNN_LOG(warning) << "Could not load GpuAcc MLGO tuner data file.";
165  }
166  }
167 
168  tuner = m_Tuner.get();
169  }
170 
171  m_ClContextControlWrapper = std::make_unique<ClContextControlWrapper>(
172  tuner,
173  mlgoTuner,
174  kernelProfiling
175  );
176 }
177 
178 bool ClBackendContext::BeforeLoadNetwork(NetworkId)
179 {
180  return true;
181 }
182 
183 bool ClBackendContext::AfterLoadNetwork(NetworkId networkId)
184 {
185  {
186  std::lock_guard<std::mutex> lockGuard(m_Mutex);
187  m_NetworkIds.insert(networkId);
188  }
189  return true;
190 }
191 
192 bool ClBackendContext::BeforeUnloadNetwork(NetworkId)
193 {
194  return m_ClContextControlWrapper->Sync();
195 }
196 
197 bool ClBackendContext::AfterUnloadNetwork(NetworkId networkId)
198 {
199  bool clearCache = false;
200  {
201  std::lock_guard<std::mutex> lockGuard(m_Mutex);
202  m_NetworkIds.erase(networkId);
203  clearCache = m_NetworkIds.empty();
204  }
205 
206  if (clearCache)
207  {
208  m_ClContextControlWrapper->ClearClCache();
209  }
210 
211  return true;
212 }
213 
214 bool ClBackendContext::AfterEnqueueWorkload(NetworkId)
215 {
216  return m_ClContextControlWrapper->Sync();
217 }
218 
219 ClBackendContext::~ClBackendContext()
220 {
221  if (m_Tuner && !m_TuningFile.empty())
222  {
223  try
224  {
225  m_Tuner->save_to_file(m_TuningFile.c_str());
226  }
227  catch(const std::exception& e)
228  {
229  ARMNN_LOG(warning) << "Could not save GpuAcc tuner data to file " << m_TuningFile;
230  }
231  }
232 }
233 
234 } // namespace armnn
armnn::TuningLevel::Exhaustive
@ Exhaustive
armnn::IGpuAccTunedParameters::Mode
Mode
Definition: IRuntime.hpp:316
armnn::IGpuAccTunedParameters::TuningLevel::Rapid
@ Rapid
armnn::TuningLevel::None
@ None
armnn::ParseStringBackendOption
std::string ParseStringBackendOption(const armnn::BackendOptions::Var &value, std::string defaultValue)
Definition: BackendOptions.hpp:321
armnn::IGpuAccTunedParameters::TuningLevel
TuningLevel
Definition: IRuntime.hpp:322
ARMNN_ASSERT_MSG
#define ARMNN_ASSERT_MSG(COND, MSG)
Definition: Assert.hpp:15
armnn::IGpuAccTunedParameters::TuningLevel::Exhaustive
@ Exhaustive
ARMNN_LOG
#define ARMNN_LOG(severity)
Definition: Logging.hpp:212
Assert.hpp
armnn::IGpuAccTunedParameters::Mode::UseTunedParameters
@ UseTunedParameters
armnn::ClBackendContext::m_MLGOTuningFile
std::string m_MLGOTuningFile
Definition: ClBackendContext.hpp:44
armnn::NetworkId
int NetworkId
Definition: IRuntime.hpp:35
armnn::IRuntime::CreationOptions::m_BackendOptions
std::vector< BackendOptions > m_BackendOptions
Pass backend specific options.
Definition: IRuntime.hpp:190
Logging.hpp
PolymorphicDowncast.hpp
armnn::ParseTuningLevel
TuningLevel ParseTuningLevel(const BackendOptions::Var &value, TuningLevel defaultValue)
Definition: ArmComputeTuningUtils.hpp:26
armnn::ConfigureTuner
void ConfigureTuner(arm_compute::CLTuner &tuner, TuningLevel level)
Definition: ArmComputeTuningUtils.hpp:44
armnn::IGpuAccTunedParameters::TuningLevel::Normal
@ Normal
armnn::IBackendContext
Definition: IBackendContext.hpp:14
armnn::BoostLogSeverityMapping::info
@ info
ClContextControl.hpp
armnn::ParseOptions
void ParseOptions(const std::vector< BackendOptions > &options, BackendId backend, F f)
Definition: BackendOptions.hpp:297
armnn::ClBackendContext::m_MLGOTuner
arm_compute::CLGEMMHeuristicsHandle m_MLGOTuner
Definition: ClBackendContext.hpp:43
armnn::TuningLevel::Rapid
@ Rapid
armnn::TuningLevel::Normal
@ Normal
ClBackendContext.hpp
armnn::IRuntime::CreationOptions
Definition: IRuntime.hpp:78
armnn::BackendOptions::Var
Very basic type safe variant.
Definition: BackendOptions.hpp:38
armnn
Copyright (c) 2021 ARM Limited and Contributors.
Definition: 01_00_quick_start.dox:6
armnn::BoostLogSeverityMapping::warning
@ warning
armnn::TuningLevel
TuningLevel
Definition: ArmComputeTuningUtils.hpp:18
armnn::IRuntime::CreationOptions::m_GpuAccTunedParameters
std::shared_ptr< IGpuAccTunedParameters > m_GpuAccTunedParameters
If set, uses the GpuAcc tuned parameters from the given object when executing GPU workloads.
Definition: IRuntime.hpp:91
armnn::ClBackendContext::ClBackendContext
ClBackendContext(const IRuntime::CreationOptions &options)
Definition: ClBackendContext.cpp:62
armnn::IRuntime::CreationOptions::m_EnableGpuProfiling
bool m_EnableGpuProfiling
Setting this flag will allow the user to obtain GPU profiling information from the runtime.
Definition: IRuntime.hpp:94