• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright © 2020-2023 Arm Ltd and Contributors. All rights reserved.
3 // SPDX-License-Identifier: MIT
4 //
5 
6 #include <DelegateOptions.hpp>
7 #include <armnn/utility/NumericCast.hpp>
8 #include <armnn/utility/StringUtils.hpp>
9 
10 namespace armnnDelegate
11 {
12 
13 struct DelegateOptionsImpl
14 {
15     ~DelegateOptionsImpl() = default;
16     DelegateOptionsImpl() = default;
17 
DelegateOptionsImplarmnnDelegate::DelegateOptionsImpl18     explicit DelegateOptionsImpl(armnn::Compute computeDevice,
19                         const std::vector<armnn::BackendOptions>& backendOptions,
20                         const armnn::Optional<armnn::LogSeverity> logSeverityLevel)
21                         : p_Backends({computeDevice}), p_RuntimeOptions(), m_LoggingSeverity(logSeverityLevel)
22     {
23         p_RuntimeOptions.m_BackendOptions = backendOptions;
24     }
25 
DelegateOptionsImplarmnnDelegate::DelegateOptionsImpl26     explicit DelegateOptionsImpl(const std::vector<armnn::BackendId>& backends,
27                                  const std::vector<armnn::BackendOptions>& backendOptions,
28                                  const armnn::Optional<armnn::LogSeverity> logSeverityLevel)
29             : p_Backends(backends), p_RuntimeOptions(), m_LoggingSeverity(logSeverityLevel)
30     {
31         p_RuntimeOptions.m_BackendOptions = backendOptions;
32     }
33 
DelegateOptionsImplarmnnDelegate::DelegateOptionsImpl34     explicit DelegateOptionsImpl(armnn::Compute computeDevice,
35                                  const armnn::OptimizerOptionsOpaque& optimizerOptions,
36                                  const armnn::Optional<armnn::LogSeverity>& logSeverityLevel,
37                                  const armnn::Optional<armnn::DebugCallbackFunction>& func)
38             : p_Backends({computeDevice}),
39               p_RuntimeOptions(),
40               p_OptimizerOptions(optimizerOptions),
41               m_LoggingSeverity(logSeverityLevel),
42               p_DebugCallbackFunc(func)
43     {
44     }
45 
DelegateOptionsImplarmnnDelegate::DelegateOptionsImpl46     explicit DelegateOptionsImpl(const std::vector<armnn::BackendId>& backends,
47                                  const armnn::OptimizerOptionsOpaque& optimizerOptions,
48                                  const armnn::Optional<armnn::LogSeverity>& logSeverityLevel,
49                                  const armnn::Optional<armnn::DebugCallbackFunction>& func)
50             : p_Backends(backends),
51               p_RuntimeOptions(),
52               p_OptimizerOptions(optimizerOptions),
53               m_LoggingSeverity(logSeverityLevel),
54               p_DebugCallbackFunc(func)
55     {
56     }
57 
58     /// Which backend to run Delegate on.
59     /// Examples of possible values are: CpuRef, CpuAcc, GpuAcc.
60     /// CpuRef as default.
61     std::vector<armnn::BackendId> p_Backends = {armnn::Compute::CpuRef };
62 
63     /// Creation options for the ArmNN runtime
64     /// Contains options for global settings that are valid for the whole lifetime of ArmNN
65     /// i.e. BackendOptions, DynamicBackendPath, ExternalProfilingOptions and more
66     armnn::IRuntime::CreationOptions p_RuntimeOptions;
67 
68     /// Options for the optimization step for the network
69     armnn::OptimizerOptionsOpaque p_OptimizerOptions;
70 
71     /// Internal profiling options. Written to INetworkProperties during model load.
72     /// Indicates whether internal profiling is enabled or not.
73     bool m_InternalProfilingEnabled = false;
74 
75     /// Sets the level of detail output by the profiling. Options are DetailsWithEvents = 1 and DetailsOnly = 2
76     armnn::ProfilingDetailsMethod p_InternalProfilingDetail = armnn::ProfilingDetailsMethod::DetailsWithEvents;
77 
78     /// Severity level for logging within ArmNN that will be used on creation of the delegate
79     armnn::Optional<armnn::LogSeverity> m_LoggingSeverity;
80 
81     /// A callback function to debug layers performing custom computations on intermediate tensors.
82     /// If a function is not registered, and debug is enabled in OptimizerOptions,
83     /// debug will print information of the intermediate tensors.
84     armnn::Optional<armnn::DebugCallbackFunction> p_DebugCallbackFunc;
85 
86     /// If not empty then the optimized model will be serialized to a file with this file name in "dot" format.
87     std::string m_SerializeToDot = "";
88 
89     /// Option to disable TfLite Runtime fallback for unsupported operators.
90     bool m_DisableTfLiteRuntimeFallback = false;
91 
92 };
93 
94 DelegateOptions::~DelegateOptions() = default;
95 
DelegateOptions()96 DelegateOptions::DelegateOptions()
97     : p_DelegateOptionsImpl(std::make_unique<DelegateOptionsImpl>())
98 {
99 }
100 
DelegateOptions(DelegateOptions const & other)101 DelegateOptions::DelegateOptions(DelegateOptions const &other)
102     : p_DelegateOptionsImpl(std::make_unique<DelegateOptionsImpl>(*other.p_DelegateOptionsImpl))
103 {
104 }
105 
DelegateOptions(armnn::Compute computeDevice,const std::vector<armnn::BackendOptions> & backendOptions,const armnn::Optional<armnn::LogSeverity> logSeverityLevel)106 DelegateOptions::DelegateOptions(armnn::Compute computeDevice,
107                                  const std::vector<armnn::BackendOptions>& backendOptions,
108                                  const armnn::Optional<armnn::LogSeverity> logSeverityLevel)
109     : p_DelegateOptionsImpl(std::make_unique<DelegateOptionsImpl>(computeDevice, backendOptions, logSeverityLevel))
110 {
111 }
112 
DelegateOptions(const std::vector<armnn::BackendId> & backends,const std::vector<armnn::BackendOptions> & backendOptions,const armnn::Optional<armnn::LogSeverity> logSeverityLevel)113 DelegateOptions::DelegateOptions(const std::vector<armnn::BackendId>& backends,
114                                  const std::vector<armnn::BackendOptions>& backendOptions,
115                                  const armnn::Optional<armnn::LogSeverity> logSeverityLevel)
116     : p_DelegateOptionsImpl(std::make_unique<DelegateOptionsImpl>(backends, backendOptions, logSeverityLevel))
117 {
118 }
119 
DelegateOptions(armnn::Compute computeDevice,const armnn::OptimizerOptionsOpaque & optimizerOptions,const armnn::Optional<armnn::LogSeverity> & logSeverityLevel,const armnn::Optional<armnn::DebugCallbackFunction> & func)120 DelegateOptions::DelegateOptions(armnn::Compute computeDevice,
121                                  const armnn::OptimizerOptionsOpaque& optimizerOptions,
122                                  const armnn::Optional<armnn::LogSeverity>& logSeverityLevel,
123                                  const armnn::Optional<armnn::DebugCallbackFunction>& func)
124     : p_DelegateOptionsImpl(std::make_unique<DelegateOptionsImpl>(computeDevice, optimizerOptions,
125                                                                   logSeverityLevel, func))
126 {
127 }
128 
DelegateOptions(const std::vector<armnn::BackendId> & backends,const armnn::OptimizerOptionsOpaque & optimizerOptions,const armnn::Optional<armnn::LogSeverity> & logSeverityLevel,const armnn::Optional<armnn::DebugCallbackFunction> & func)129 DelegateOptions::DelegateOptions(const std::vector<armnn::BackendId>& backends,
130                                  const armnn::OptimizerOptionsOpaque& optimizerOptions,
131                                  const armnn::Optional<armnn::LogSeverity>& logSeverityLevel,
132                                  const armnn::Optional<armnn::DebugCallbackFunction>& func)
133     : p_DelegateOptionsImpl(std::make_unique<DelegateOptionsImpl>(backends, optimizerOptions,
134                                                                   logSeverityLevel, func))
135 {
136 }
137 
DelegateOptions(char const * const * options_keys,char const * const * options_values,size_t num_options,void (* report_error)(const char *))138 DelegateOptions::DelegateOptions(char const* const* options_keys,
139                                  char const* const* options_values,
140                                  size_t num_options,
141                                  void (*report_error)(const char*))
142     : p_DelegateOptionsImpl(std::make_unique<DelegateOptionsImpl>())
143 {
144     armnn::IRuntime::CreationOptions runtimeOptions;
145     armnn::OptimizerOptionsOpaque optimizerOptions;
146     bool internalProfilingState = false;
147     armnn::ProfilingDetailsMethod internalProfilingDetail = armnn::ProfilingDetailsMethod::DetailsWithEvents;
148     for (size_t i = 0; i < num_options; ++i)
149     {
150         // Process backends
151         if (std::string(options_keys[i]) == std::string("backends"))
152         {
153             // The backend option is a comma separated string of backendIDs that needs to be split
154             std::vector<armnn::BackendId> backends;
155             char* dup = strdup(options_values[i]);
156             char* pch = std::strtok(dup, ",");
157             while (pch != NULL)
158             {
159                 backends.push_back(pch);
160                 pch = strtok (NULL, ",");
161             }
162             SetBackends(backends);
163         }
164             // Process dynamic-backends-path
165         else if (std::string(options_keys[i]) == std::string("dynamic-backends-path"))
166         {
167             runtimeOptions.m_DynamicBackendsPath = std::string(options_values[i]);
168         }
169             // Process logging level
170         else if (std::string(options_keys[i]) == std::string("logging-severity"))
171         {
172             SetLoggingSeverity(options_values[i]);
173         }
174             // Process GPU backend options
175         else if (std::string(options_keys[i]) == std::string("gpu-tuning-level"))
176         {
177             armnn::BackendOptions option("GpuAcc", {{"TuningLevel",
178                                                      atoi(options_values[i])}});
179             runtimeOptions.m_BackendOptions.push_back(option);
180         }
181         else if (std::string(options_keys[i]) == std::string("gpu-mlgo-tuning-file"))
182         {
183             armnn::BackendOptions option("GpuAcc", {{"MLGOTuningFilePath",
184                                                      std::string(options_values[i])}});
185             optimizerOptions.AddModelOption(option);
186         }
187         else if (std::string(options_keys[i]) == std::string("gpu-tuning-file"))
188         {
189             armnn::BackendOptions option("GpuAcc", {{"TuningFile",
190                                                      std::string(options_values[i])}});
191             runtimeOptions.m_BackendOptions.push_back(option);
192         }
193         else if (std::string(options_keys[i]) == std::string("gpu-enable-profiling"))
194         {
195             runtimeOptions.m_EnableGpuProfiling = (*options_values[i] != '0');
196         }
197         else if (std::string(options_keys[i]) == std::string("gpu-kernel-profiling-enabled"))
198         {
199             armnn::BackendOptions option("GpuAcc", {{"KernelProfilingEnabled",
200                                                      armnn::stringUtils::StringToBool(options_values[i])}});
201             runtimeOptions.m_BackendOptions.push_back(option);
202         }
203         else if (std::string(options_keys[i]) == std::string("save-cached-network"))
204         {
205             armnn::BackendOptions option("GpuAcc", {{"SaveCachedNetwork",
206                                                      armnn::stringUtils::StringToBool(options_values[i])}});
207             optimizerOptions.AddModelOption(option);
208         }
209         else if (std::string(options_keys[i]) == std::string("cached-network-filepath"))
210         {
211             armnn::BackendOptions option("GpuAcc", {{"CachedNetworkFilePath",
212                                                      std::string(options_values[i])}});
213             optimizerOptions.AddModelOption(option);
214         }
215             // Process GPU & CPU backend options
216         else if (std::string(options_keys[i]) == std::string("enable-fast-math"))
217         {
218             armnn::BackendOptions modelOptionGpu("GpuAcc", {{"FastMathEnabled",
219                                                  armnn::stringUtils::StringToBool(options_values[i])}});
220             optimizerOptions.AddModelOption(modelOptionGpu);
221 
222             armnn::BackendOptions modelOptionCpu("CpuAcc", {{"FastMathEnabled",
223                                                  armnn::stringUtils::StringToBool(options_values[i])}});
224             optimizerOptions.AddModelOption(modelOptionCpu);
225         }
226             // Process CPU backend options
227         else if (std::string(options_keys[i]) == std::string("number-of-threads"))
228         {
229             unsigned int numberOfThreads = armnn::numeric_cast<unsigned int>(atoi(options_values[i]));
230             armnn::BackendOptions modelOption("CpuAcc",
231                                               {{"NumberOfThreads", numberOfThreads}});
232             optimizerOptions.AddModelOption(modelOption);
233         }
234             // Process reduce-fp32-to-fp16 option
235         else if (std::string(options_keys[i]) == std::string("reduce-fp32-to-fp16"))
236         {
237             optimizerOptions.SetReduceFp32ToFp16(armnn::stringUtils::StringToBool(options_values[i]));
238         }
239             // Process debug-data
240         else if (std::string(options_keys[i]) == std::string("debug-data"))
241         {
242             optimizerOptions.SetDebugEnabled(armnn::stringUtils::StringToBool(options_values[i]));
243         }
244             // Infer output-shape
245         else if (std::string(options_keys[i]) == std::string("infer-output-shape"))
246         {
247             armnn::BackendOptions backendOption("ShapeInferenceMethod",
248             {
249                 { "InferAndValidate", armnn::stringUtils::StringToBool(options_values[i]) }
250             });
251             optimizerOptions.AddModelOption(backendOption);
252         }
253             // Allow expanded dims
254         else if (std::string(options_keys[i]) == std::string("allow-expanded-dims"))
255         {
256             armnn::BackendOptions backendOption("AllowExpandedDims",
257             {
258                 { "AllowExpandedDims", armnn::stringUtils::StringToBool(options_values[i]) }
259             });
260             optimizerOptions.AddModelOption(backendOption);
261         }
262             // Process memory-import
263         else if (std::string(options_keys[i]) == std::string("memory-import"))
264         {
265             optimizerOptions.SetImportEnabled(armnn::stringUtils::StringToBool(options_values[i]));
266         }
267             // Process enable-internal-profiling
268         else if (std::string(options_keys[i]) == std::string("enable-internal-profiling"))
269         {
270             internalProfilingState = *options_values[i] != '0';
271             optimizerOptions.SetProfilingEnabled(internalProfilingState);
272         }
273             // Process internal-profiling-detail
274         else if (std::string(options_keys[i]) == std::string("internal-profiling-detail"))
275         {
276             uint32_t detailLevel = static_cast<uint32_t>(std::stoul(options_values[i]));
277             switch (detailLevel)
278             {
279                 case 1:
280                     internalProfilingDetail = armnn::ProfilingDetailsMethod::DetailsWithEvents;
281                     break;
282                 case 2:
283                     internalProfilingDetail = armnn::ProfilingDetailsMethod::DetailsOnly;
284                     break;
285                 default:
286                     internalProfilingDetail = armnn::ProfilingDetailsMethod::Undefined;
287                     break;
288             }
289         }
290             // Process enable-external-profiling
291         else if (std::string(options_keys[i]) == std::string("enable-external-profiling"))
292         {
293             runtimeOptions.m_ProfilingOptions.m_EnableProfiling =
294                 armnn::stringUtils::StringToBool(options_values[i]);
295         }
296         // Process timeline-profiling
297         else if (std::string(options_keys[i]) == std::string("timeline-profiling"))
298         {
299             runtimeOptions.m_ProfilingOptions.m_TimelineEnabled =
300                 armnn::stringUtils::StringToBool(options_values[i]);
301         }
302         // Process outgoing-capture-file
303         else if (std::string(options_keys[i]) == std::string("outgoing-capture-file"))
304         {
305             runtimeOptions.m_ProfilingOptions.m_OutgoingCaptureFile = options_values[i];
306         }
307         // Process incoming-capture-file
308         else if (std::string(options_keys[i]) == std::string("incoming-capture-file"))
309         {
310             runtimeOptions.m_ProfilingOptions.m_IncomingCaptureFile = options_values[i];
311         }
312         // Process file-only-external-profiling
313         else if (std::string(options_keys[i]) == std::string("file-only-external-profiling"))
314         {
315             runtimeOptions.m_ProfilingOptions.m_FileOnly =
316                     armnn::stringUtils::StringToBool(options_values[i]);
317         }
318         // Process counter-capture-period
319         else if (std::string(options_keys[i]) == std::string("counter-capture-period"))
320         {
321             runtimeOptions.m_ProfilingOptions.m_CapturePeriod =
322                     static_cast<uint32_t>(std::stoul(options_values[i]));
323         }
324         // Process profiling-file-format
325         else if (std::string(options_keys[i]) == std::string("profiling-file-format"))
326         {
327             runtimeOptions.m_ProfilingOptions.m_FileFormat = options_values[i];
328         }
329         // Process serialize-to-dot
330         else if (std::string(options_keys[i]) == std::string("serialize-to-dot"))
331         {
332             SetSerializeToDot(options_values[i]);
333         }
334 
335         // Process disable-tflite-runtime-fallback
336         else if (std::string(options_keys[i]) == std::string("disable-tflite-runtime-fallback"))
337         {
338             this->DisableTfLiteRuntimeFallback(armnn::stringUtils::StringToBool(options_values[i]));
339         }
340         else
341         {
342             throw armnn::Exception("Unknown option for the ArmNN Delegate given: " +
343                 std::string(options_keys[i]));
344         }
345     }
346 
347     SetRuntimeOptions(runtimeOptions);
348     SetOptimizerOptions(optimizerOptions);
349     SetInternalProfilingParams(internalProfilingState, internalProfilingDetail);
350 }
351 
GetBackends() const352 const std::vector<armnn::BackendId>& DelegateOptions::GetBackends() const
353 {
354     return p_DelegateOptionsImpl->p_Backends;
355 }
356 
SetBackends(const std::vector<armnn::BackendId> & backends)357 void DelegateOptions::SetBackends(const std::vector<armnn::BackendId>& backends)
358 {
359     p_DelegateOptionsImpl->p_Backends = backends;
360 }
361 
SetDynamicBackendsPath(const std::string & dynamicBackendsPath)362 void DelegateOptions::SetDynamicBackendsPath(const std::string& dynamicBackendsPath)
363 {
364     p_DelegateOptionsImpl->p_RuntimeOptions.m_DynamicBackendsPath = dynamicBackendsPath;
365 }
366 
GetDynamicBackendsPath() const367 const std::string& DelegateOptions::GetDynamicBackendsPath() const
368 {
369     return p_DelegateOptionsImpl->p_RuntimeOptions.m_DynamicBackendsPath;
370 }
371 
SetGpuProfilingState(bool gpuProfilingState)372 void DelegateOptions::SetGpuProfilingState(bool gpuProfilingState)
373 {
374     p_DelegateOptionsImpl->p_RuntimeOptions.m_EnableGpuProfiling = gpuProfilingState;
375 }
376 
GetGpuProfilingState()377 bool DelegateOptions::GetGpuProfilingState()
378 {
379     return p_DelegateOptionsImpl->p_RuntimeOptions.m_EnableGpuProfiling;
380 }
381 
GetBackendOptions() const382 const std::vector<armnn::BackendOptions>& DelegateOptions::GetBackendOptions() const
383 {
384     return p_DelegateOptionsImpl->p_RuntimeOptions.m_BackendOptions;
385 }
386 
AddBackendOption(const armnn::BackendOptions & option)387 void DelegateOptions::AddBackendOption(const armnn::BackendOptions& option)
388 {
389     p_DelegateOptionsImpl->p_RuntimeOptions.m_BackendOptions.push_back(option);
390 }
391 
SetLoggingSeverity(const armnn::LogSeverity & level)392 void DelegateOptions::SetLoggingSeverity(const armnn::LogSeverity& level)
393 {
394     p_DelegateOptionsImpl->m_LoggingSeverity = level;
395 }
396 
SetLoggingSeverity(const std::string & level)397 void DelegateOptions::SetLoggingSeverity(const std::string& level)
398 {
399     p_DelegateOptionsImpl->m_LoggingSeverity = armnn::StringToLogLevel(level);
400 }
401 
GetLoggingSeverity()402 armnn::LogSeverity DelegateOptions::GetLoggingSeverity()
403 {
404     return p_DelegateOptionsImpl->m_LoggingSeverity.value();
405 }
406 
IsLoggingEnabled()407 bool DelegateOptions::IsLoggingEnabled()
408 {
409     return p_DelegateOptionsImpl->m_LoggingSeverity.has_value();
410 }
411 
GetOptimizerOptions() const412 const armnn::OptimizerOptionsOpaque& DelegateOptions::GetOptimizerOptions() const
413 {
414     return p_DelegateOptionsImpl->p_OptimizerOptions;
415 }
416 
SetOptimizerOptions(const armnn::OptimizerOptionsOpaque & optimizerOptions)417 void DelegateOptions::SetOptimizerOptions(const armnn::OptimizerOptionsOpaque& optimizerOptions)
418 {
419     p_DelegateOptionsImpl->p_OptimizerOptions = optimizerOptions;
420 }
421 
GetDebugCallbackFunction() const422 const armnn::Optional<armnn::DebugCallbackFunction>& DelegateOptions::GetDebugCallbackFunction() const
423 {
424     return p_DelegateOptionsImpl->p_DebugCallbackFunc;
425 }
426 
SetInternalProfilingParams(bool internalProfilingState,const armnn::ProfilingDetailsMethod & internalProfilingDetail)427 void DelegateOptions::SetInternalProfilingParams(bool internalProfilingState,
428                                 const armnn::ProfilingDetailsMethod& internalProfilingDetail)
429 {
430     p_DelegateOptionsImpl->m_InternalProfilingEnabled = internalProfilingState;
431     p_DelegateOptionsImpl->p_InternalProfilingDetail = internalProfilingDetail;
432 }
433 
GetInternalProfilingState() const434 bool DelegateOptions::GetInternalProfilingState() const
435 {
436     return p_DelegateOptionsImpl->m_InternalProfilingEnabled;
437 }
438 
GetInternalProfilingDetail() const439 const armnn::ProfilingDetailsMethod& DelegateOptions::GetInternalProfilingDetail() const
440 {
441     return p_DelegateOptionsImpl->p_InternalProfilingDetail;
442 }
443 
SetSerializeToDot(const std::string & serializeToDotFile)444 void DelegateOptions::SetSerializeToDot(const std::string& serializeToDotFile)
445 {
446     p_DelegateOptionsImpl->m_SerializeToDot = serializeToDotFile;
447 }
448 
GetSerializeToDot() const449 const std::string& DelegateOptions::GetSerializeToDot() const
450 {
451     return p_DelegateOptionsImpl->m_SerializeToDot;
452 }
453 
SetRuntimeOptions(const armnn::IRuntime::CreationOptions & runtimeOptions)454 void DelegateOptions::SetRuntimeOptions(const armnn::IRuntime::CreationOptions& runtimeOptions)
455 {
456     p_DelegateOptionsImpl->p_RuntimeOptions = runtimeOptions;
457 }
458 
GetRuntimeOptions()459 const armnn::IRuntime::CreationOptions& DelegateOptions::GetRuntimeOptions()
460 {
461     return p_DelegateOptionsImpl->p_RuntimeOptions;
462 }
463 
DisableTfLiteRuntimeFallback(bool fallbackState)464 void DelegateOptions::DisableTfLiteRuntimeFallback(bool fallbackState)
465 {
466     p_DelegateOptionsImpl->m_DisableTfLiteRuntimeFallback = fallbackState;
467 }
468 
TfLiteRuntimeFallbackDisabled()469 bool DelegateOptions::TfLiteRuntimeFallbackDisabled()
470 {
471     return p_DelegateOptionsImpl->m_DisableTfLiteRuntimeFallback;
472 }
473 
474 } // namespace armnnDelegate
475