blob: adee2763ba9721fe84fdff334bfa4567ece25167 [file] [log] [blame]
David Beck1b61be52018-11-08 09:19:14 +00001//
Cathal Corbettd9e55f02023-01-11 13:03:21 +00002// Copyright © 2017, 2023 Arm Ltd and Contributors. All rights reserved.
David Beck1b61be52018-11-08 09:19:14 +00003// SPDX-License-Identifier: MIT
4//
5
6#include "ClBackendContext.hpp"
Derek Lamberti836b27b2019-11-20 10:51:57 +00007#include "ClContextControl.hpp"
Derek Lamberti08446972019-11-26 16:38:31 +00008
9#include <armnn/Logging.hpp>
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +010010#include <armnn/utility/Assert.hpp>
Jan Eilersbb446e52020-04-02 13:56:54 +010011#include <armnn/utility/PolymorphicDowncast.hpp>
Derek Lamberti08446972019-11-26 16:38:31 +000012
David Beck1b61be52018-11-08 09:19:14 +000013#include <arm_compute/core/CL/OpenCL.h>
14#include <arm_compute/core/CL/CLKernelLibrary.h>
15#include <arm_compute/runtime/CL/CLScheduler.h>
Derek Lamberti836b27b2019-11-20 10:51:57 +000016#include <arm_compute/runtime/CL/CLTunerTypes.h>
17
David Beck1b61be52018-11-08 09:19:14 +000018namespace armnn
19{
20
21struct ClBackendContext::ClContextControlWrapper
22{
TeresaARM8b4a4832022-12-20 16:28:22 +000023 ClContextControlWrapper(arm_compute::CLTuner* tuner,
24 arm_compute::CLGEMMHeuristicsHandle* heuristicsHandle,
25 bool profilingEnabled)
26 : m_ClContextControl(tuner, heuristicsHandle, profilingEnabled)
27 {}
David Beck1b61be52018-11-08 09:19:14 +000028
29 bool Sync()
30 {
David Beck1b61be52018-11-08 09:19:14 +000031 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 {
Derek Lamberti08446972019-11-26 16:38:31 +000041 ARMNN_LOG(warning) << "Runtime::UnloadNetwork(): an error occurred while waiting for "
42 "the queued CL requests to finish";
David Beck1b61be52018-11-08 09:19:14 +000043 return false;
44 }
45 }
Aron Virginas-Tard46e6472018-11-16 10:26:23 +000046
David Beck1b61be52018-11-08 09:19:14 +000047 return true;
48 }
49
50 void ClearClCache()
51 {
David Beck1b61be52018-11-08 09:19:14 +000052 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 }
David Beck1b61be52018-11-08 09:19:14 +000057 }
58
David Beck1b61be52018-11-08 09:19:14 +000059 ClContextControl m_ClContextControl;
60};
61
David Beck1b61be52018-11-08 09:19:14 +000062ClBackendContext::ClBackendContext(const IRuntime::CreationOptions& options)
63 : IBackendContext(options)
Derek Lamberti5c510f82020-02-11 12:56:52 +000064 , m_TuningFile()
David Beck1b61be52018-11-08 09:19:14 +000065{
Derek Lamberti836b27b2019-11-20 10:51:57 +000066 bool kernelProfiling = options.m_EnableGpuProfiling;
Derek Lamberti836b27b2019-11-20 10:51:57 +000067
Derek Lamberti836b27b2019-11-20 10:51:57 +000068 arm_compute::CLTuner* tuner = nullptr;
Finn Williams40646322021-02-11 16:16:42 +000069 arm_compute::CLGEMMHeuristicsHandle* mlgoTuner = nullptr;
Derek Lambertief7e6b62020-02-04 14:49:16 +000070 bool useLegacyTunerAPI = options.m_GpuAccTunedParameters.get() != nullptr;
71 if (useLegacyTunerAPI)
Derek Lamberti836b27b2019-11-20 10:51:57 +000072 {
Jan Eilersbb446e52020-04-02 13:56:54 +010073 auto clTunerParams = PolymorphicDowncast<ClTunedParameters*>(
Derek Lambertief7e6b62020-02-04 14:49:16 +000074 options.m_GpuAccTunedParameters.get());
Derek Lamberti5c510f82020-02-11 12:56:52 +000075 tuner = &clTunerParams->m_Tuner;
Derek Lamberti836b27b2019-11-20 10:51:57 +000076
Derek Lamberti5c510f82020-02-11 12:56:52 +000077 if (tuner)
Derek Lamberti836b27b2019-11-20 10:51:57 +000078 {
Derek Lamberti5c510f82020-02-11 12:56:52 +000079 auto ConvertTuningLevel = [](IGpuAccTunedParameters::TuningLevel level,
80 armnn::IGpuAccTunedParameters::Mode mode)
Derek Lamberti836b27b2019-11-20 10:51:57 +000081 {
Derek Lamberti5c510f82020-02-11 12:56:52 +000082 if (mode == armnn::IGpuAccTunedParameters::Mode::UseTunedParameters)
83 {
84 return TuningLevel::None;
85 }
86
Derek Lambertief7e6b62020-02-04 14:49:16 +000087 switch(level)
Derek Lamberti836b27b2019-11-20 10:51:57 +000088 {
Derek Lambertief7e6b62020-02-04 14:49:16 +000089 case IGpuAccTunedParameters::TuningLevel::Rapid:
Derek Lamberti5c510f82020-02-11 12:56:52 +000090 return TuningLevel::Rapid;
Derek Lambertief7e6b62020-02-04 14:49:16 +000091 case IGpuAccTunedParameters::TuningLevel::Normal:
Derek Lamberti5c510f82020-02-11 12:56:52 +000092 return TuningLevel::Normal;
Derek Lambertief7e6b62020-02-04 14:49:16 +000093 case IGpuAccTunedParameters::TuningLevel::Exhaustive:
Derek Lamberti5c510f82020-02-11 12:56:52 +000094 return TuningLevel::Exhaustive;
Derek Lambertief7e6b62020-02-04 14:49:16 +000095 default:
96 {
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +010097 ARMNN_ASSERT_MSG(false, "Tuning level not recognised.");
Derek Lamberti5c510f82020-02-11 12:56:52 +000098 return TuningLevel::None;
Derek Lambertief7e6b62020-02-04 14:49:16 +000099 }
Derek Lamberti836b27b2019-11-20 10:51:57 +0000100 }
Derek Lambertief7e6b62020-02-04 14:49:16 +0000101 };
Derek Lamberti836b27b2019-11-20 10:51:57 +0000102
Derek Lamberti5c510f82020-02-11 12:56:52 +0000103 TuningLevel tuningLevel = ConvertTuningLevel(clTunerParams->m_TuningLevel, clTunerParams->m_Mode);
104 ConfigureTuner(*tuner, tuningLevel);
Derek Lambertief7e6b62020-02-04 14:49:16 +0000105 }
106 }
107 else //New backend options API
108 {
Derek Lamberti5c510f82020-02-11 12:56:52 +0000109 const TuningLevel defaultTuningLevel = TuningLevel::None;
110 auto tuningLevel = defaultTuningLevel;
111
Derek Lambertief7e6b62020-02-04 14:49:16 +0000112 ParseOptions(options.m_BackendOptions, "GpuAcc", [&](std::string name, const BackendOptions::Var& value)
Derek Lamberti836b27b2019-11-20 10:51:57 +0000113 {
Derek Lambertief7e6b62020-02-04 14:49:16 +0000114 if (name == "KernelProfilingEnabled")
115 {
Cathal Corbettd9e55f02023-01-11 13:03:21 +0000116 kernelProfiling |= ParseBooleanBackendOption(value, false);
Derek Lambertief7e6b62020-02-04 14:49:16 +0000117 } else if (name == "TuningFile")
118 {
Cathal Corbettd9e55f02023-01-11 13:03:21 +0000119 m_TuningFile = ParseStringBackendOption(value, "");
Derek Lambertief7e6b62020-02-04 14:49:16 +0000120 } else if (name == "TuningLevel")
121 {
122 tuningLevel = ParseTuningLevel(value, defaultTuningLevel);
123 }
Finn Williams40646322021-02-11 16:16:42 +0000124 else if (name == "MLGOTuningFilePath")
125 {
Cathal Corbettd9e55f02023-01-11 13:03:21 +0000126 m_MLGOTuningFile = ParseStringBackendOption(value, "");
Finn Williams40646322021-02-11 16:16:42 +0000127 }
Derek Lambertief7e6b62020-02-04 14:49:16 +0000128 });
Derek Lamberti836b27b2019-11-20 10:51:57 +0000129
Derek Lambertief7e6b62020-02-04 14:49:16 +0000130 // Create the tuner, in tuning mode initially.
131 m_Tuner = std::make_unique<arm_compute::CLTuner>(true);
132
Derek Lamberti5c510f82020-02-11 12:56:52 +0000133 ConfigureTuner(*(m_Tuner.get()), tuningLevel);
Derek Lambertief7e6b62020-02-04 14:49:16 +0000134
Stuart Taylor06ccd712022-03-15 17:03:58 +0000135 if (!m_TuningFile.empty())
Derek Lambertief7e6b62020-02-04 14:49:16 +0000136 {
Derek Lamberti836b27b2019-11-20 10:51:57 +0000137 try
138 {
Jan Eilers2cd18472020-12-15 10:42:38 +0000139 ARMNN_LOG(info) << "Loading Gpu tuning data from file: " << m_TuningFile;
Derek Lamberti836b27b2019-11-20 10:51:57 +0000140 m_Tuner->load_from_file(m_TuningFile.c_str());
alered01a7227ac2020-05-07 14:58:29 +0100141 }
142 catch (const std::exception& e)
Derek Lamberti836b27b2019-11-20 10:51:57 +0000143 {
Stuart Taylor06ccd712022-03-15 17:03:58 +0000144 // 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 }
Derek Lamberti836b27b2019-11-20 10:51:57 +0000149 }
Derek Lamberti836b27b2019-11-20 10:51:57 +0000150 }
Finn Williams40646322021-02-11 16:16:42 +0000151
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
alered01a7227ac2020-05-07 14:58:29 +0100168 tuner = m_Tuner.get();
Derek Lamberti836b27b2019-11-20 10:51:57 +0000169 }
170
TeresaARM8b4a4832022-12-20 16:28:22 +0000171 m_ClContextControlWrapper = std::make_unique<ClContextControlWrapper>(
172 tuner,
173 mlgoTuner,
174 kernelProfiling
175 );
David Beck1b61be52018-11-08 09:19:14 +0000176}
177
178bool ClBackendContext::BeforeLoadNetwork(NetworkId)
179{
180 return true;
181}
182
183bool 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
192bool ClBackendContext::BeforeUnloadNetwork(NetworkId)
193{
194 return m_ClContextControlWrapper->Sync();
195}
196
197bool 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
Narumol Prangnawaratec5463d2022-02-04 17:50:20 +0000214bool ClBackendContext::AfterEnqueueWorkload(NetworkId)
215{
216 return m_ClContextControlWrapper->Sync();
217}
218
David Beck1b61be52018-11-08 09:19:14 +0000219ClBackendContext::~ClBackendContext()
220{
Derek Lamberti836b27b2019-11-20 10:51:57 +0000221 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 }
David Beck1b61be52018-11-08 09:19:14 +0000232}
233
234} // namespace armnn