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