xref: /aosp_15_r20/external/android-nn-driver/DriverOptions.cpp (revision 3e777be0405cee09af5d5785ff37f7cfb5bee59a)
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