1 //
2 // Copyright © 2017 Arm Ltd. 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 <cassert>
21 #include <functional>
22 #include <string>
23 #include <sstream>
24
25 using namespace android;
26 using namespace std;
27
28 namespace armnn_driver
29 {
30
DriverOptions(armnn::Compute computeDevice,bool fp16Enabled)31 DriverOptions::DriverOptions(armnn::Compute computeDevice, bool fp16Enabled)
32 : m_Backends({computeDevice})
33 , m_VerboseLogging(false)
34 , m_ClTunedParametersMode(armnn::IGpuAccTunedParameters::Mode::UseTunedParameters)
35 , m_ClTuningLevel(armnn::IGpuAccTunedParameters::TuningLevel::Rapid)
36 , m_EnableGpuProfiling(false)
37 , m_fp16Enabled(fp16Enabled)
38 , m_FastMathEnabled(false)
39 {
40 }
41
DriverOptions(const std::vector<armnn::BackendId> & backends,bool fp16Enabled)42 DriverOptions::DriverOptions(const std::vector<armnn::BackendId>& backends, bool fp16Enabled)
43 : m_Backends(backends)
44 , m_VerboseLogging(false)
45 , m_ClTunedParametersMode(armnn::IGpuAccTunedParameters::Mode::UseTunedParameters)
46 , m_ClTuningLevel(armnn::IGpuAccTunedParameters::TuningLevel::Rapid)
47 , m_EnableGpuProfiling(false)
48 , m_fp16Enabled(fp16Enabled)
49 , m_FastMathEnabled(false)
50 {
51 }
52
DriverOptions(int argc,char ** argv)53 DriverOptions::DriverOptions(int argc, char** argv)
54 : m_VerboseLogging(false)
55 , m_ClTunedParametersMode(armnn::IGpuAccTunedParameters::Mode::UseTunedParameters)
56 , m_ClTuningLevel(armnn::IGpuAccTunedParameters::TuningLevel::Rapid)
57 , m_EnableGpuProfiling(false)
58 , m_fp16Enabled(false)
59 , m_FastMathEnabled(false)
60 , m_ShouldExit(false)
61 {
62 std::string unsupportedOperationsAsString;
63 std::string clTunedParametersModeAsString;
64 std::string clTuningLevelAsString;
65 std::vector<std::string> backends;
66 bool showHelp;
67 bool showVersion;
68
69 cxxopts::Options optionsDesc(argv[0], "ArmNN Android NN driver for the Android Neural Networks API. The Android NN "
70 "driver will convert Android NNAPI requests and delegate them to available "
71 "ArmNN backends.");
72 try
73 {
74 optionsDesc.add_options()
75
76 ("a,enable-fast-math", "Enables fast_math options in backends that support it. Using the fast_math flag can "
77 "lead to performance improvements but may result in reduced or different precision.",
78 cxxopts::value<bool>(m_FastMathEnabled)->default_value("false"))
79
80 ("c,compute",
81 "Comma separated list of backends to run layers on. Examples of possible values are: CpuRef, CpuAcc, GpuAcc",
82 cxxopts::value<std::vector<std::string>>(backends))
83
84 ("d,request-inputs-and-outputs-dump-dir",
85 "If non-empty, the directory where request inputs and outputs should be dumped",
86 cxxopts::value<std::string>(m_RequestInputsAndOutputsDumpDir)->default_value(""))
87
88 ("f,fp16-enabled", "Enables support for relaxed computation from Float32 to Float16",
89 cxxopts::value<bool>(m_fp16Enabled)->default_value("false"))
90
91 ("h,help", "Show this help",
92 cxxopts::value<bool>(showHelp)->default_value("false"))
93
94 ("m,cl-tuned-parameters-mode",
95 "If 'UseTunedParameters' (the default), will read CL tuned parameters from the file specified by "
96 "--cl-tuned-parameters-file. "
97 "If 'UpdateTunedParameters', will also find the optimum parameters when preparing new networks and update "
98 "the file accordingly.",
99 cxxopts::value<std::string>(clTunedParametersModeAsString)->default_value("UseTunedParameters"))
100
101 ("n,service-name",
102 "If non-empty, the driver service name to be registered",
103 cxxopts::value<std::string>(m_ServiceName)->default_value("armnn"))
104
105 ("o,cl-tuning-level",
106 "exhaustive: all lws values are tested "
107 "normal: reduced number of lws values but enough to still have the performance really close to the "
108 "exhaustive approach "
109 "rapid: only 3 lws values should be tested for each kernel ",
110 cxxopts::value<std::string>(clTuningLevelAsString)->default_value("rapid"))
111
112 ("p,gpu-profiling", "Turns GPU profiling on",
113 cxxopts::value<bool>(m_EnableGpuProfiling)->default_value("false"))
114
115 ("t,cl-tuned-parameters-file",
116 "If non-empty, the given file will be used to load/save CL tuned parameters. "
117 "See also --cl-tuned-parameters-mode",
118 cxxopts::value<std::string>(m_ClTunedParametersFile)->default_value(""))
119
120 ("u,unsupported-operations",
121 "If non-empty, a comma-separated list of operation indices which the driver will forcibly "
122 "consider unsupported",
123 cxxopts::value<std::string>(unsupportedOperationsAsString)->default_value(""))
124
125 ("v,verbose-logging", "Turns verbose logging on",
126 cxxopts::value<bool>(m_VerboseLogging)->default_value("false"))
127
128 ("V,version", "Show version information",
129 cxxopts::value<bool>(showVersion)->default_value("false"));
130 }
131 catch (const std::exception& e)
132 {
133 ALOGE("An error occurred attempting to construct options: %s", e.what());
134 std::cout << "An error occurred attempting to construct options: %s" << std::endl;
135 m_ExitCode = EXIT_FAILURE;
136 return;
137 }
138
139 try
140 {
141 cxxopts::ParseResult result = optionsDesc.parse(argc, argv);
142 }
143 catch (const cxxopts::OptionException& e)
144 {
145 ALOGW("An exception occurred attempting to parse program options: %s", e.what());
146 std::cout << optionsDesc.help() << std::endl
147 << "An exception occurred while parsing program options: " << std::endl
148 << e.what() << std::endl;
149 m_ShouldExit = true;
150 m_ExitCode = EXIT_FAILURE;
151 return;
152 }
153 if (showHelp)
154 {
155 ALOGW("Showing help and exiting");
156 std::cout << optionsDesc.help() << std::endl;
157 m_ShouldExit = true;
158 m_ExitCode = EXIT_SUCCESS;
159 return;
160 }
161 if (showVersion)
162 {
163 ALOGW("Showing version and exiting");
164 std::cout << "ArmNN Android NN driver for the Android Neural Networks API.\n"
165 "ArmNN v" << ARMNN_VERSION << std::endl;
166 m_ShouldExit = true;
167 m_ExitCode = EXIT_SUCCESS;
168 return;
169 }
170
171 // Convert the string backend names into backendId's.
172 m_Backends.reserve(backends.size());
173 for (auto&& backend : backends)
174 {
175 m_Backends.emplace_back(backend);
176 }
177
178 // If no backends have been specified then the default value is GpuAcc.
179 if (backends.empty())
180 {
181 ALOGE("No backends have been specified:");
182 std::cout << optionsDesc.help() << std::endl
183 << "Unable to start:" << std::endl
184 << "No backends have been specified" << std::endl;
185 m_ShouldExit = true;
186 m_ExitCode = EXIT_FAILURE;
187 return;
188 }
189
190 if (!unsupportedOperationsAsString.empty())
191 {
192 std::istringstream argStream(unsupportedOperationsAsString);
193
194 std::string s;
195 while (!argStream.eof())
196 {
197 std::getline(argStream, s, ',');
198 try
199 {
200 unsigned int operationIdx = std::stoi(s);
201 m_ForcedUnsupportedOperations.insert(operationIdx);
202 }
203 catch (const std::invalid_argument&)
204 {
205 ALOGW("Ignoring invalid integer argument in -u/--unsupported-operations value: %s", s.c_str());
206 }
207 }
208 }
209
210 if (!m_ClTunedParametersFile.empty())
211 {
212 // The mode is only relevant if the file path has been provided
213 if (clTunedParametersModeAsString == "UseTunedParameters")
214 {
215 m_ClTunedParametersMode = armnn::IGpuAccTunedParameters::Mode::UseTunedParameters;
216 }
217 else if (clTunedParametersModeAsString == "UpdateTunedParameters")
218 {
219 m_ClTunedParametersMode = armnn::IGpuAccTunedParameters::Mode::UpdateTunedParameters;
220 }
221 else
222 {
223 ALOGW("Requested unknown cl-tuned-parameters-mode '%s'. Defaulting to UseTunedParameters",
224 clTunedParametersModeAsString.c_str());
225 }
226
227 if (clTuningLevelAsString == "exhaustive")
228 {
229 m_ClTuningLevel = armnn::IGpuAccTunedParameters::TuningLevel::Exhaustive;
230 }
231 else if (clTuningLevelAsString == "normal")
232 {
233 m_ClTuningLevel = armnn::IGpuAccTunedParameters::TuningLevel::Normal;
234 }
235 else if (clTuningLevelAsString == "rapid")
236 {
237 m_ClTuningLevel = armnn::IGpuAccTunedParameters::TuningLevel::Rapid;
238 }
239 else
240 {
241 ALOGW("Requested unknown cl-tuner-mode '%s'. Defaulting to rapid",
242 clTuningLevelAsString.c_str());
243 }
244 }
245 }
246
247 } // namespace armnn_driver
248