ArmNN
 24.02
DriverOptions.cpp
Go to the documentation of this file.
1 //
2 // Copyright © 2022-2023 Arm Ltd and Contributors. All rights reserved.
3 // SPDX-License-Identifier: MIT
4 //
5 
6 #define LOG_TAG "arm-armnn-sl"
7 
8 #include "DriverOptions.hpp"
9 
10 #include "CanonicalUtils.hpp"
11 
12 #include <armnn/Version.hpp>
13 #include <log/log.h>
15 
16 #include <OperationsUtils.h>
17 
18 #include <cxxopts/cxxopts.hpp>
19 
20 #include <algorithm>
21 #include <cassert>
22 #include <functional>
23 #include <string>
24 #include <sstream>
25 
26 using namespace android;
27 using namespace std;
28 
29 namespace armnn_driver
30 {
31 
32 DriverOptions::DriverOptions(armnn::Compute computeDevice, bool fp16Enabled)
33  : m_Backends({computeDevice})
34  , m_VerboseLogging(false)
35  , m_RequestInputsAndOutputsDumpDir(std::string(""))
36  , m_ServiceName(std::string("armnn_sl"))
37  , m_ForcedUnsupportedOperations({})
40  , m_EnableGpuProfiling(false)
41  , m_fp16Enabled(fp16Enabled)
42  , m_FastMathEnabled(false)
43  , m_ShouldExit(false)
44  , m_ExitCode(EXIT_SUCCESS)
45  , m_CachedNetworkFilePath(std::string(""))
46  , m_SaveCachedNetwork(false)
47  , m_NumberOfThreads(0)
48  , m_EnableAsyncModelExecution(false)
49  , m_ArmnnNumberOfThreads(1)
50 {
51 }
52 
53 DriverOptions::DriverOptions(const std::vector<armnn::BackendId>& backends, bool fp16Enabled)
54  : m_Backends(backends)
55  , m_VerboseLogging(false)
56  , m_RequestInputsAndOutputsDumpDir(std::string(""))
57  , m_ServiceName(std::string("armnn_sl"))
58  , m_ForcedUnsupportedOperations({})
61  , m_EnableGpuProfiling(false)
62  , m_fp16Enabled(fp16Enabled)
63  , m_FastMathEnabled(false)
64  , m_ShouldExit(false)
65  , m_ExitCode(EXIT_SUCCESS)
66  , m_CachedNetworkFilePath(std::string(""))
67  , m_SaveCachedNetwork(false)
68  , m_NumberOfThreads(0)
69  , m_EnableAsyncModelExecution(false)
70  , m_ArmnnNumberOfThreads(1)
71 {
72 }
73 
74 // This default constructor will example an environment variable called
75 // ARMNN_SL_OPTIONS. It will parse the parameters using the existing cxx
76 // opts mechanism.
78  : m_VerboseLogging(false)
79  , m_RequestInputsAndOutputsDumpDir(std::string(""))
80  , m_ServiceName(std::string("armnn_sl"))
81  , m_ForcedUnsupportedOperations({})
84  , m_EnableGpuProfiling(false)
85  , m_fp16Enabled(false)
86  , m_FastMathEnabled(false)
87  , m_ShouldExit(false)
88  , m_SaveCachedNetwork(false)
89  , m_NumberOfThreads(0)
90  , m_EnableAsyncModelExecution(false)
91  , m_ArmnnNumberOfThreads(1)
92 {
93  std::string unsupportedOperationsAsString;
94  std::string clTunedParametersModeAsString;
95  std::string clTuningLevelAsString;
96  std::vector<std::string> backends;
97  bool showHelp = false;
98  bool showVersion = false;
99 
100  const char* rawEnv = std::getenv("ARMNN_SL_OPTIONS");
101  // If the environment variable isn't set we'll continue as if it were an empty string.
102  if (!rawEnv)
103  {
104  rawEnv = "";
105  }
106  string optionsAsString(rawEnv);
107  regex whiteSpaceRegex("\\s+");
108  // Tokienize the string based on whitespace.
109  sregex_token_iterator iter(optionsAsString.begin(), optionsAsString.end(), whiteSpaceRegex, -1);
110  sregex_token_iterator end;
111  vector<string> cliAsVector(iter, end);
112  // As we're pretending to be a command line, argv[0] should be an executable name.
113  cliAsVector.insert(cliAsVector.begin(), "ARMNN_SL_OPTIONS");
114  // Convert the vector of string to a vector of char* backed by the existing vector.
115  std::vector<char*> argVector;
116  for (const auto& arg : cliAsVector)
117  {
118  argVector.push_back((char*)arg.data());
119  }
120  // Terminate the array.
121  argVector.push_back(nullptr);
122  // Create usable variables.
123  int argc = argVector.size() - 1; // Ignore the null pointer at the end.
124  char** argv = argVector.data();
125 
126  cxxopts::Options optionsDesc(argv[0], "Arm NN Support Library for the Android Neural Networks API."
127  "The support library will convert Android NNAPI requests "
128  "and delegate them to available ArmNN backends.");
129  try
130  {
131  optionsDesc.add_options()
132 
133  ("a,enable-fast-math",
134  "Enables fast_math options in backends that support it. Using the fast_math flag can "
135  "lead to performance improvements but may result in reduced or different precision.",
136  cxxopts::value<bool>(m_FastMathEnabled)->default_value("false"))
137 
138  ("c,compute","Comma separated list of backends to run layers on. "
139  "Examples of possible values are: CpuRef, CpuAcc, GpuAcc",
140  cxxopts::value<std::vector<std::string>>(backends))
141 
142  ("d,request-inputs-and-outputs-dump-dir",
143  "If non-empty, the directory where request inputs and outputs should be dumped",
144  cxxopts::value<std::string>(m_RequestInputsAndOutputsDumpDir)->default_value(""))
145 
146  ("f,fp16-enabled", "Enables support for relaxed computation from Float32 to Float16",
147  cxxopts::value<bool>(m_fp16Enabled)->default_value("false"))
148 
149  ("h,help", "Show this help",
150  cxxopts::value<bool>(showHelp)->default_value("false")->implicit_value("true"))
151 
152  ("m,cl-tuned-parameters-mode",
153  "If 'UseTunedParameters' (the default), will read CL tuned parameters from the file specified by "
154  "--cl-tuned-parameters-file. "
155  "If 'UpdateTunedParameters', will also find the optimum parameters when preparing new networks and update "
156  "the file accordingly.",
157  cxxopts::value<std::string>(clTunedParametersModeAsString)->default_value("UseTunedParameters"))
158 
159  ("g,mlgo-cl-tuned-parameters-file",
160  "If non-empty, the given file will be used to load/save MLGO CL tuned parameters. ",
161  cxxopts::value<std::string>(m_ClMLGOTunedParametersFile)->default_value(""))
162 
163  ("o,cl-tuning-level",
164  "exhaustive: all lws values are tested "
165  "normal: reduced number of lws values but enough to still have the performance really close to the "
166  "exhaustive approach "
167  "rapid: only 3 lws values should be tested for each kernel ",
168  cxxopts::value<std::string>(clTuningLevelAsString)->default_value("rapid"))
169 
170  ("p,gpu-profiling", "Turns GPU profiling on",
171  cxxopts::value<bool>(m_EnableGpuProfiling)->default_value("false"))
172 
173  ("q,cached-network-file", "If non-empty, the given file will be used to load/save cached network. "
174  "If save-cached-network option is given will save the cached network to given file."
175  "If save-cached-network option is not given will load the cached network from given "
176  "file.",
177  cxxopts::value<std::string>(m_CachedNetworkFilePath)->default_value(""))
178 
179  ("s,save-cached-network",
180  "Enables saving the cached network to the file given with cached-network-file option."
181  " See also --cached-network-file",
182  cxxopts::value<bool>(m_SaveCachedNetwork)->default_value("false"))
183 
184  ("number-of-threads",
185  "Assign the number of threads used by the CpuAcc backend. "
186  "Input value must be between 1 and 64. "
187  "Default is set to 0 (Backend will decide number of threads to use).",
188  cxxopts::value<unsigned int>(m_NumberOfThreads)->default_value("0"))
189 
190  ("t,cl-tuned-parameters-file",
191  "If non-empty, the given file will be used to load/save CL tuned parameters. "
192  "See also --cl-tuned-parameters-mode",
193  cxxopts::value<std::string>(m_ClTunedParametersFile)->default_value(""))
194 
195  ("u,unsupported-operations",
196  "If non-empty, a comma-separated list of operation indices which the driver will forcibly "
197  "consider unsupported",
198  cxxopts::value<std::string>(unsupportedOperationsAsString)->default_value(""))
199 
200  ("v,verbose-logging", "Turns verbose logging on",
201  cxxopts::value<bool>(m_VerboseLogging)->default_value("false")->implicit_value("true"))
202 
203  ("V,version", "Show version information",
204  cxxopts::value<bool>(showVersion)->default_value("false")->implicit_value("true"))
205  ;
206  }
207  catch (const std::exception& e)
208  {
209  VLOG(DRIVER) << "An error occurred attempting to construct options: " << e.what();
210  std::cout << "An error occurred attempting to construct options: %s" << std::endl;
211  m_ExitCode = EXIT_FAILURE;
212  return;
213  }
214 
215  try
216  {
217  cxxopts::ParseResult result = optionsDesc.parse(argc, argv);
218  }
219  catch (const cxxopts::exceptions::exception& e)
220  {
221  VLOG(DRIVER) << "An exception occurred attempting to parse program options: " << e.what();
222  std::cout << optionsDesc.help() << std::endl
223  << "An exception occurred while parsing program options: " << std::endl
224  << e.what() << std::endl;
225  m_ShouldExit = true;
226  m_ExitCode = EXIT_FAILURE;
227  return;
228  }
229  if (showHelp)
230  {
231  VLOG(DRIVER) << "Showing help and exiting";
232  std::cout << optionsDesc.help() << std::endl;
233  m_ShouldExit = true;
234  m_ExitCode = EXIT_SUCCESS;
235  return;
236  }
237  if (showVersion)
238  {
239  VLOG(DRIVER) << "Showing version and exiting";
240  std::cout << "ArmNN Android NN driver for the Android Neural Networks API.\n"
241  "ArmNN v" << ARMNN_VERSION << std::endl;
242  m_ShouldExit = true;
243  m_ExitCode = EXIT_SUCCESS;
244  return;
245  }
246 
247  // Convert the string backend names into backendId's.
248  m_Backends.reserve(backends.size());
249  for (auto&& backend : backends)
250  {
251  m_Backends.emplace_back(backend);
252  }
253 
254  // If no backends have been specified then the default value is GpuAcc.
255  if (backends.empty())
256  {
257  VLOG(DRIVER) << "No backends have been specified:";
258  std::cout << optionsDesc.help() << std::endl
259  << "Unable to start:" << std::endl
260  << "No backends have been specified" << std::endl;
261  m_ShouldExit = true;
262  m_ExitCode = EXIT_FAILURE;
263  return;
264  }
265 
266  if (!unsupportedOperationsAsString.empty())
267  {
268  std::istringstream argStream(unsupportedOperationsAsString);
269 
270  std::string s;
271  while (!argStream.eof())
272  {
273  std::getline(argStream, s, ',');
274  try
275  {
276  unsigned int operationIdx = std::stoi(s);
277  m_ForcedUnsupportedOperations.insert(operationIdx);
278  }
279  catch (const std::invalid_argument&)
280  {
281  VLOG(DRIVER) << "Ignoring invalid integer argument in -u/--unsupported-operations value: " << s.c_str();
282  }
283  }
284  }
285 
286  if (!m_ClTunedParametersFile.empty())
287  {
288  // The mode is only relevant if the file path has been provided
289  if (clTunedParametersModeAsString == "UseTunedParameters")
290  {
292  }
293  else if (clTunedParametersModeAsString == "UpdateTunedParameters")
294  {
296  }
297  else
298  {
299  VLOG(DRIVER) << "Requested unknown cl-tuned-parameters-mode "
300  << clTunedParametersModeAsString.c_str() << ". Defaulting to UseTunedParameters";
301  }
302 
303  if (clTuningLevelAsString == "exhaustive")
304  {
306  }
307  else if (clTuningLevelAsString == "normal")
308  {
310  }
311  else if (clTuningLevelAsString == "rapid")
312  {
314  }
315  else
316  {
317  VLOG(DRIVER) << "Requested unknown cl-tuner-mode '%s'. "
318  "Defaulting to rapid" << clTuningLevelAsString.c_str();
319  }
320  }
321 }
322 
323 } // namespace armnn_driver
armnn::IGpuAccTunedParameters::TuningLevel::Rapid
@ Rapid
armnn_driver::DriverOptions::DriverOptions
DriverOptions()
Definition: DriverOptions.cpp:77
armnn::IGpuAccTunedParameters::TuningLevel::Exhaustive
@ Exhaustive
armnn::Compute
Compute
The Compute enum is now deprecated and it is now being replaced by BackendId.
Definition: BackendId.hpp:21
armnn::IGpuAccTunedParameters::Mode::UseTunedParameters
@ UseTunedParameters
CanonicalUtils.hpp
Version.hpp
armnn_driver
Helper classes.
Definition: ArmnnDevice.cpp:37
armnn::IGpuAccTunedParameters::TuningLevel::Normal
@ Normal
armnn::IGpuAccTunedParameters::Mode::UpdateTunedParameters
@ UpdateTunedParameters
ARMNN_VERSION
#define ARMNN_VERSION
ARMNN_VERSION: "X.Y.Z" where: X = Major version number Y = Minor version number Z = Patch version num...
Definition: Version.hpp:22
std
Definition: BackendId.hpp:149
DriverOptions.hpp
android
Definition: support_library_service.cpp:10
SystemPropertiesUtils.hpp