• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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