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