xref: /aosp_15_r20/external/armnn/tests/ExecuteNetwork/ExecuteNetworkProgramOptions.cpp (revision 89c4ff92f2867872bb9e2354d150bf0c8c502810)
1*89c4ff92SAndroid Build Coastguard Worker //
2*89c4ff92SAndroid Build Coastguard Worker // Copyright © 2022-2023 Arm Ltd and Contributors. All rights reserved.
3*89c4ff92SAndroid Build Coastguard Worker // SPDX-License-Identifier: MIT
4*89c4ff92SAndroid Build Coastguard Worker //
5*89c4ff92SAndroid Build Coastguard Worker 
6*89c4ff92SAndroid Build Coastguard Worker #include "ExecuteNetworkProgramOptions.hpp"
7*89c4ff92SAndroid Build Coastguard Worker #include "NetworkExecutionUtils/NetworkExecutionUtils.hpp"
8*89c4ff92SAndroid Build Coastguard Worker 
9*89c4ff92SAndroid Build Coastguard Worker #include <armnn/BackendRegistry.hpp>
10*89c4ff92SAndroid Build Coastguard Worker #include <armnn/Exceptions.hpp>
11*89c4ff92SAndroid Build Coastguard Worker #include <armnn/utility/Assert.hpp>
12*89c4ff92SAndroid Build Coastguard Worker #include <armnn/utility/StringUtils.hpp>
13*89c4ff92SAndroid Build Coastguard Worker #include <armnn/Logging.hpp>
14*89c4ff92SAndroid Build Coastguard Worker 
15*89c4ff92SAndroid Build Coastguard Worker #include <fmt/format.h>
16*89c4ff92SAndroid Build Coastguard Worker 
CheckOption(const cxxopts::ParseResult & result,const char * option)17*89c4ff92SAndroid Build Coastguard Worker bool CheckOption(const cxxopts::ParseResult& result,
18*89c4ff92SAndroid Build Coastguard Worker                  const char* option)
19*89c4ff92SAndroid Build Coastguard Worker {
20*89c4ff92SAndroid Build Coastguard Worker     // Check that the given option is valid.
21*89c4ff92SAndroid Build Coastguard Worker     if (option == nullptr)
22*89c4ff92SAndroid Build Coastguard Worker     {
23*89c4ff92SAndroid Build Coastguard Worker         return false;
24*89c4ff92SAndroid Build Coastguard Worker     }
25*89c4ff92SAndroid Build Coastguard Worker 
26*89c4ff92SAndroid Build Coastguard Worker     // Check whether 'option' is provided.
27*89c4ff92SAndroid Build Coastguard Worker     return ((result.count(option)) ? true : false);
28*89c4ff92SAndroid Build Coastguard Worker }
29*89c4ff92SAndroid Build Coastguard Worker 
CheckOptionDependency(const cxxopts::ParseResult & result,const char * option,const char * required)30*89c4ff92SAndroid Build Coastguard Worker void CheckOptionDependency(const cxxopts::ParseResult& result,
31*89c4ff92SAndroid Build Coastguard Worker                            const char* option,
32*89c4ff92SAndroid Build Coastguard Worker                            const char* required)
33*89c4ff92SAndroid Build Coastguard Worker {
34*89c4ff92SAndroid Build Coastguard Worker     // Check that the given options are valid.
35*89c4ff92SAndroid Build Coastguard Worker     if (option == nullptr || required == nullptr)
36*89c4ff92SAndroid Build Coastguard Worker     {
37*89c4ff92SAndroid Build Coastguard Worker         throw cxxopts::OptionParseException("Invalid option to check dependency for");
38*89c4ff92SAndroid Build Coastguard Worker     }
39*89c4ff92SAndroid Build Coastguard Worker 
40*89c4ff92SAndroid Build Coastguard Worker     // Check that if 'option' is provided, 'required' is also provided.
41*89c4ff92SAndroid Build Coastguard Worker     if (CheckOption(result, option) && !result[option].has_default())
42*89c4ff92SAndroid Build Coastguard Worker     {
43*89c4ff92SAndroid Build Coastguard Worker         if (CheckOption(result, required) == 0 || result[required].has_default())
44*89c4ff92SAndroid Build Coastguard Worker         {
45*89c4ff92SAndroid Build Coastguard Worker             throw cxxopts::OptionParseException(
46*89c4ff92SAndroid Build Coastguard Worker                     std::string("Option '") + option + "' requires option '" + required + "'.");
47*89c4ff92SAndroid Build Coastguard Worker         }
48*89c4ff92SAndroid Build Coastguard Worker     }
49*89c4ff92SAndroid Build Coastguard Worker }
50*89c4ff92SAndroid Build Coastguard Worker 
CheckOptionDependencies(const cxxopts::ParseResult & result)51*89c4ff92SAndroid Build Coastguard Worker void CheckOptionDependencies(const cxxopts::ParseResult& result)
52*89c4ff92SAndroid Build Coastguard Worker {
53*89c4ff92SAndroid Build Coastguard Worker     CheckOptionDependency(result, "tuning-level", "tuning-path");
54*89c4ff92SAndroid Build Coastguard Worker }
55*89c4ff92SAndroid Build Coastguard Worker 
RemoveDuplicateDevices(std::vector<armnn::BackendId> & computeDevices)56*89c4ff92SAndroid Build Coastguard Worker void RemoveDuplicateDevices(std::vector<armnn::BackendId>& computeDevices)
57*89c4ff92SAndroid Build Coastguard Worker {
58*89c4ff92SAndroid Build Coastguard Worker     // Mark the duplicate devices as 'Undefined'.
59*89c4ff92SAndroid Build Coastguard Worker     for (auto i = computeDevices.begin(); i != computeDevices.end(); ++i)
60*89c4ff92SAndroid Build Coastguard Worker     {
61*89c4ff92SAndroid Build Coastguard Worker         for (auto j = std::next(i); j != computeDevices.end(); ++j)
62*89c4ff92SAndroid Build Coastguard Worker         {
63*89c4ff92SAndroid Build Coastguard Worker             if (*j == *i)
64*89c4ff92SAndroid Build Coastguard Worker             {
65*89c4ff92SAndroid Build Coastguard Worker                 *j = armnn::Compute::Undefined;
66*89c4ff92SAndroid Build Coastguard Worker             }
67*89c4ff92SAndroid Build Coastguard Worker         }
68*89c4ff92SAndroid Build Coastguard Worker     }
69*89c4ff92SAndroid Build Coastguard Worker 
70*89c4ff92SAndroid Build Coastguard Worker     // Remove 'Undefined' devices.
71*89c4ff92SAndroid Build Coastguard Worker     computeDevices.erase(std::remove(computeDevices.begin(), computeDevices.end(), armnn::Compute::Undefined),
72*89c4ff92SAndroid Build Coastguard Worker                          computeDevices.end());
73*89c4ff92SAndroid Build Coastguard Worker }
74*89c4ff92SAndroid Build Coastguard Worker 
75*89c4ff92SAndroid Build Coastguard Worker /// Takes a vector of backend strings and returns a vector of backendIDs.
76*89c4ff92SAndroid Build Coastguard Worker /// Removes duplicate entries.
77*89c4ff92SAndroid Build Coastguard Worker /// Can handle backend strings that contain multiple backends separated by comma e.g "CpuRef,CpuAcc"
GetBackendIDs(const std::vector<std::string> & backendStringsVec)78*89c4ff92SAndroid Build Coastguard Worker std::vector<armnn::BackendId> GetBackendIDs(const std::vector<std::string>& backendStringsVec)
79*89c4ff92SAndroid Build Coastguard Worker {
80*89c4ff92SAndroid Build Coastguard Worker     std::vector<armnn::BackendId> backendIDs;
81*89c4ff92SAndroid Build Coastguard Worker     for (const auto& backendStrings : backendStringsVec)
82*89c4ff92SAndroid Build Coastguard Worker     {
83*89c4ff92SAndroid Build Coastguard Worker         // Each backendStrings might contain multiple backends separated by comma e.g "CpuRef,CpuAcc"
84*89c4ff92SAndroid Build Coastguard Worker         std::vector<std::string> backendStringVec = ParseStringList(backendStrings, ",");
85*89c4ff92SAndroid Build Coastguard Worker         for (const auto& b : backendStringVec)
86*89c4ff92SAndroid Build Coastguard Worker         {
87*89c4ff92SAndroid Build Coastguard Worker             backendIDs.push_back(armnn::BackendId(b));
88*89c4ff92SAndroid Build Coastguard Worker         }
89*89c4ff92SAndroid Build Coastguard Worker     }
90*89c4ff92SAndroid Build Coastguard Worker 
91*89c4ff92SAndroid Build Coastguard Worker     RemoveDuplicateDevices(backendIDs);
92*89c4ff92SAndroid Build Coastguard Worker 
93*89c4ff92SAndroid Build Coastguard Worker     return backendIDs;
94*89c4ff92SAndroid Build Coastguard Worker }
95*89c4ff92SAndroid Build Coastguard Worker 
96*89c4ff92SAndroid Build Coastguard Worker /// Provides a segfault safe way to get cxxopts option values by checking if the option was defined.
97*89c4ff92SAndroid Build Coastguard Worker /// If the option wasn't defined it returns an empty object.
98*89c4ff92SAndroid Build Coastguard Worker template<typename optionType>
GetOptionValue(std::string && optionName,const cxxopts::ParseResult & result)99*89c4ff92SAndroid Build Coastguard Worker optionType GetOptionValue(std::string&& optionName, const cxxopts::ParseResult& result)
100*89c4ff92SAndroid Build Coastguard Worker {
101*89c4ff92SAndroid Build Coastguard Worker     optionType out;
102*89c4ff92SAndroid Build Coastguard Worker     if(result.count(optionName))
103*89c4ff92SAndroid Build Coastguard Worker     {
104*89c4ff92SAndroid Build Coastguard Worker         out = result[optionName].as<optionType>();
105*89c4ff92SAndroid Build Coastguard Worker     }
106*89c4ff92SAndroid Build Coastguard Worker     return out;
107*89c4ff92SAndroid Build Coastguard Worker }
108*89c4ff92SAndroid Build Coastguard Worker 
LogAndThrowFatal(std::string errorMessage)109*89c4ff92SAndroid Build Coastguard Worker void LogAndThrowFatal(std::string errorMessage)
110*89c4ff92SAndroid Build Coastguard Worker {
111*89c4ff92SAndroid Build Coastguard Worker     throw armnn::InvalidArgumentException (errorMessage);
112*89c4ff92SAndroid Build Coastguard Worker }
113*89c4ff92SAndroid Build Coastguard Worker 
CheckRequiredOptions(const cxxopts::ParseResult & result)114*89c4ff92SAndroid Build Coastguard Worker void CheckRequiredOptions(const cxxopts::ParseResult& result)
115*89c4ff92SAndroid Build Coastguard Worker {
116*89c4ff92SAndroid Build Coastguard Worker 
117*89c4ff92SAndroid Build Coastguard Worker     // For each option in option-group "a) Required
118*89c4ff92SAndroid Build Coastguard Worker     std::vector<std::string> requiredOptions{"compute",
119*89c4ff92SAndroid Build Coastguard Worker                                              "model-path"
120*89c4ff92SAndroid Build Coastguard Worker                                              };
121*89c4ff92SAndroid Build Coastguard Worker 
122*89c4ff92SAndroid Build Coastguard Worker     bool requiredMissing = false;
123*89c4ff92SAndroid Build Coastguard Worker     for(auto const&  str : requiredOptions)
124*89c4ff92SAndroid Build Coastguard Worker     {
125*89c4ff92SAndroid Build Coastguard Worker         if(!(result.count(str) > 0))
126*89c4ff92SAndroid Build Coastguard Worker         {
127*89c4ff92SAndroid Build Coastguard Worker             ARMNN_LOG(error) << fmt::format("The program option '{}' is mandatory but wasn't provided.", str);
128*89c4ff92SAndroid Build Coastguard Worker             requiredMissing = true;
129*89c4ff92SAndroid Build Coastguard Worker         }
130*89c4ff92SAndroid Build Coastguard Worker     }
131*89c4ff92SAndroid Build Coastguard Worker     if(requiredMissing)
132*89c4ff92SAndroid Build Coastguard Worker     {
133*89c4ff92SAndroid Build Coastguard Worker         throw armnn::InvalidArgumentException ("Some required arguments are missing");
134*89c4ff92SAndroid Build Coastguard Worker     }
135*89c4ff92SAndroid Build Coastguard Worker }
136*89c4ff92SAndroid Build Coastguard Worker 
CheckForDeprecatedOptions(const cxxopts::ParseResult & result)137*89c4ff92SAndroid Build Coastguard Worker void CheckForDeprecatedOptions(const cxxopts::ParseResult& result)
138*89c4ff92SAndroid Build Coastguard Worker {
139*89c4ff92SAndroid Build Coastguard Worker     if(result.count("armnn-tflite-delegate") > 0)
140*89c4ff92SAndroid Build Coastguard Worker     {
141*89c4ff92SAndroid Build Coastguard Worker         ARMNN_LOG(warning) << "DEPRECATED: The program option 'armnn-tflite-delegate' is deprecated and will be "
142*89c4ff92SAndroid Build Coastguard Worker                               "removed soon. Please use the option 'tflite-executor' instead.";
143*89c4ff92SAndroid Build Coastguard Worker     }
144*89c4ff92SAndroid Build Coastguard Worker     if(result.count("concurrent") > 0)
145*89c4ff92SAndroid Build Coastguard Worker     {
146*89c4ff92SAndroid Build Coastguard Worker         ARMNN_LOG(warning) << "DEPRECATED: The program option 'concurrent' is deprecated and will be "
147*89c4ff92SAndroid Build Coastguard Worker                               "removed soon. Please use the option '\"P, thread-pool-size\"' instead.";
148*89c4ff92SAndroid Build Coastguard Worker     }
149*89c4ff92SAndroid Build Coastguard Worker     if(result.count("input-type") > 0)
150*89c4ff92SAndroid Build Coastguard Worker     {
151*89c4ff92SAndroid Build Coastguard Worker         ARMNN_LOG(warning) << "DEPRECATED: The program option 'input-type' is deprecated and will be "
152*89c4ff92SAndroid Build Coastguard Worker                               "removed soon. The input-types are now automatically set.";
153*89c4ff92SAndroid Build Coastguard Worker     }
154*89c4ff92SAndroid Build Coastguard Worker     if(result.count("input-name") > 0)
155*89c4ff92SAndroid Build Coastguard Worker     {
156*89c4ff92SAndroid Build Coastguard Worker         ARMNN_LOG(warning) << "DEPRECATED: The program option 'input-name' is deprecated and will be "
157*89c4ff92SAndroid Build Coastguard Worker                               "removed soon. The input-names are now automatically set.";
158*89c4ff92SAndroid Build Coastguard Worker     }
159*89c4ff92SAndroid Build Coastguard Worker     if(result.count("output-type") > 0)
160*89c4ff92SAndroid Build Coastguard Worker     {
161*89c4ff92SAndroid Build Coastguard Worker         ARMNN_LOG(warning) << "DEPRECATED: The program option 'output-type' is deprecated and will be "
162*89c4ff92SAndroid Build Coastguard Worker                               "removed soon. The output-types are now automatically set.";
163*89c4ff92SAndroid Build Coastguard Worker     }
164*89c4ff92SAndroid Build Coastguard Worker     if(result.count("output-name") > 0)
165*89c4ff92SAndroid Build Coastguard Worker     {
166*89c4ff92SAndroid Build Coastguard Worker         ARMNN_LOG(warning) << "DEPRECATED: The program option 'output-name' is deprecated and will be "
167*89c4ff92SAndroid Build Coastguard Worker                               "removed soon. The output-names are now automatically set.";
168*89c4ff92SAndroid Build Coastguard Worker     }
169*89c4ff92SAndroid Build Coastguard Worker     if(result.count("model-format") > 0)
170*89c4ff92SAndroid Build Coastguard Worker     {
171*89c4ff92SAndroid Build Coastguard Worker         ARMNN_LOG(warning) << "DEPRECATED: The program option 'model-format' is deprecated and will be "
172*89c4ff92SAndroid Build Coastguard Worker                               "removed soon. The model-format is now automatically set.";
173*89c4ff92SAndroid Build Coastguard Worker     }
174*89c4ff92SAndroid Build Coastguard Worker 
175*89c4ff92SAndroid Build Coastguard Worker }
176*89c4ff92SAndroid Build Coastguard Worker 
ValidateExecuteNetworkParams()177*89c4ff92SAndroid Build Coastguard Worker void ProgramOptions::ValidateExecuteNetworkParams()
178*89c4ff92SAndroid Build Coastguard Worker {
179*89c4ff92SAndroid Build Coastguard Worker     m_ExNetParams.ValidateParams();
180*89c4ff92SAndroid Build Coastguard Worker }
181*89c4ff92SAndroid Build Coastguard Worker 
ValidateRuntimeOptions()182*89c4ff92SAndroid Build Coastguard Worker void ProgramOptions::ValidateRuntimeOptions()
183*89c4ff92SAndroid Build Coastguard Worker {
184*89c4ff92SAndroid Build Coastguard Worker     if (m_RuntimeOptions.m_ProfilingOptions.m_TimelineEnabled &&
185*89c4ff92SAndroid Build Coastguard Worker         !m_RuntimeOptions.m_ProfilingOptions.m_EnableProfiling)
186*89c4ff92SAndroid Build Coastguard Worker     {
187*89c4ff92SAndroid Build Coastguard Worker         LogAndThrowFatal("Timeline profiling requires external profiling to be turned on");
188*89c4ff92SAndroid Build Coastguard Worker     }
189*89c4ff92SAndroid Build Coastguard Worker }
190*89c4ff92SAndroid Build Coastguard Worker 
191*89c4ff92SAndroid Build Coastguard Worker 
ProgramOptions()192*89c4ff92SAndroid Build Coastguard Worker ProgramOptions::ProgramOptions() : m_CxxOptions{"ExecuteNetwork",
193*89c4ff92SAndroid Build Coastguard Worker                                                 "Executes a neural network model using the provided input "
194*89c4ff92SAndroid Build Coastguard Worker                                                 "tensor. Prints the resulting output tensor."}
195*89c4ff92SAndroid Build Coastguard Worker {
196*89c4ff92SAndroid Build Coastguard Worker     try
197*89c4ff92SAndroid Build Coastguard Worker     {
198*89c4ff92SAndroid Build Coastguard Worker         // cxxopts doesn't provide a mechanism to ensure required options are given. There is a
199*89c4ff92SAndroid Build Coastguard Worker         // separate function CheckRequiredOptions() for that.
200*89c4ff92SAndroid Build Coastguard Worker         m_CxxOptions.add_options("a) Required")
201*89c4ff92SAndroid Build Coastguard Worker                 ("c,compute",
202*89c4ff92SAndroid Build Coastguard Worker                  "Which device to run layers on by default. If a single device doesn't support all layers in the model "
203*89c4ff92SAndroid Build Coastguard Worker                  "you can specify a second or third to fall back on. Possible choices: "
204*89c4ff92SAndroid Build Coastguard Worker                  + armnn::BackendRegistryInstance().GetBackendIdsAsString()
205*89c4ff92SAndroid Build Coastguard Worker                  + " NOTE: Multiple compute devices need to be passed as a comma separated list without whitespaces "
206*89c4ff92SAndroid Build Coastguard Worker                    "e.g. GpuAcc,CpuAcc,CpuRef or by repeating the program option e.g. '-c CpuAcc -c CpuRef'. "
207*89c4ff92SAndroid Build Coastguard Worker                    "Duplicates are ignored.",
208*89c4ff92SAndroid Build Coastguard Worker                  cxxopts::value<std::vector<std::string>>())
209*89c4ff92SAndroid Build Coastguard Worker 
210*89c4ff92SAndroid Build Coastguard Worker                 ("f,model-format",
211*89c4ff92SAndroid Build Coastguard Worker                  "armnn-binary, onnx-binary, onnx-text, tflite-binary"
212*89c4ff92SAndroid Build Coastguard Worker                  "DEPRECATED: The program option 'model-format' is deprecated and will be "
213*89c4ff92SAndroid Build Coastguard Worker                  "removed soon. The model-format is now automatically set.",
214*89c4ff92SAndroid Build Coastguard Worker                  cxxopts::value<std::string>())
215*89c4ff92SAndroid Build Coastguard Worker 
216*89c4ff92SAndroid Build Coastguard Worker                 ("m,model-path",
217*89c4ff92SAndroid Build Coastguard Worker                  "Path to model file, e.g. .armnn, , .prototxt, .tflite, .onnx",
218*89c4ff92SAndroid Build Coastguard Worker                  cxxopts::value<std::string>(m_ExNetParams.m_ModelPath))
219*89c4ff92SAndroid Build Coastguard Worker 
220*89c4ff92SAndroid Build Coastguard Worker                 ("i,input-name",
221*89c4ff92SAndroid Build Coastguard Worker                  "Identifier of the input tensors in the network separated by comma."
222*89c4ff92SAndroid Build Coastguard Worker                  "This option is not required, but can be used to set the order of inputs",
223*89c4ff92SAndroid Build Coastguard Worker                  cxxopts::value<std::string>())
224*89c4ff92SAndroid Build Coastguard Worker 
225*89c4ff92SAndroid Build Coastguard Worker                 ("o,output-name",
226*89c4ff92SAndroid Build Coastguard Worker                  "Identifier of the output tensors in the network separated by comma."
227*89c4ff92SAndroid Build Coastguard Worker                  "This option is not required, but can be used to set the order of outputs",
228*89c4ff92SAndroid Build Coastguard Worker                  cxxopts::value<std::string>());
229*89c4ff92SAndroid Build Coastguard Worker 
230*89c4ff92SAndroid Build Coastguard Worker         m_CxxOptions.add_options("b) General")
231*89c4ff92SAndroid Build Coastguard Worker                 ("b,dynamic-backends-path",
232*89c4ff92SAndroid Build Coastguard Worker                  "Path where to load any available dynamic backend from. "
233*89c4ff92SAndroid Build Coastguard Worker                  "If left empty (the default), dynamic backends will not be used.",
234*89c4ff92SAndroid Build Coastguard Worker                  cxxopts::value<std::string>(m_RuntimeOptions.m_DynamicBackendsPath))
235*89c4ff92SAndroid Build Coastguard Worker 
236*89c4ff92SAndroid Build Coastguard Worker                 ("P, thread-pool-size",
237*89c4ff92SAndroid Build Coastguard Worker                  "Run the network using the Arm NN thread pool with the number of threads provided. ",
238*89c4ff92SAndroid Build Coastguard Worker                  cxxopts::value<size_t>(m_ExNetParams.m_ThreadPoolSize)->default_value("0"))
239*89c4ff92SAndroid Build Coastguard Worker 
240*89c4ff92SAndroid Build Coastguard Worker                 ("n,concurrent",
241*89c4ff92SAndroid Build Coastguard Worker                  "This option is for Arm NN internal asynchronous testing purposes. "
242*89c4ff92SAndroid Build Coastguard Worker                  "False by default. If set to true will use std::launch::async or the Arm NN thread pool, "
243*89c4ff92SAndroid Build Coastguard Worker                  "if 'thread-pool-size' is greater than 0, for asynchronous execution."
244*89c4ff92SAndroid Build Coastguard Worker                  "DEPRECATED: The program option 'concurrent' is deprecated and will be "
245*89c4ff92SAndroid Build Coastguard Worker                  "removed soon. Please use the option '\"P, thread-pool-size\"' instead.",
246*89c4ff92SAndroid Build Coastguard Worker                  cxxopts::value<bool>(m_ExNetParams.m_Concurrent)->default_value("false")->implicit_value("true"))
247*89c4ff92SAndroid Build Coastguard Worker 
248*89c4ff92SAndroid Build Coastguard Worker                 ("d,input-tensor-data",
249*89c4ff92SAndroid Build Coastguard Worker                  "Path to files containing the input data as a flat array separated by whitespace. "
250*89c4ff92SAndroid Build Coastguard Worker                  "Several paths can be passed by separating them with a comma if the network has multiple inputs "
251*89c4ff92SAndroid Build Coastguard Worker                  "or you wish to run the model multiple times with different input data using the 'iterations' option. "
252*89c4ff92SAndroid Build Coastguard Worker                  "If not specified, the network will be run with dummy data (useful for profiling).",
253*89c4ff92SAndroid Build Coastguard Worker                  cxxopts::value<std::string>()->default_value(""))
254*89c4ff92SAndroid Build Coastguard Worker 
255*89c4ff92SAndroid Build Coastguard Worker                 ("h,help", "Display usage information")
256*89c4ff92SAndroid Build Coastguard Worker 
257*89c4ff92SAndroid Build Coastguard Worker                 ("infer-output-shape",
258*89c4ff92SAndroid Build Coastguard Worker                  "Infers output tensor shape from input tensor shape and validate where applicable (where supported by "
259*89c4ff92SAndroid Build Coastguard Worker                  "parser)",
260*89c4ff92SAndroid Build Coastguard Worker                  cxxopts::value<bool>(m_ExNetParams.m_InferOutputShape)->default_value("false")->implicit_value("true"))
261*89c4ff92SAndroid Build Coastguard Worker 
262*89c4ff92SAndroid Build Coastguard Worker                 ("allow-expanded-dims",
263*89c4ff92SAndroid Build Coastguard Worker                  "If true will disregard dimensions with a size of 1 when validating tensor shapes. Tensor sizes must "
264*89c4ff92SAndroid Build Coastguard Worker                  "still match. This is an Experimental parameter that is incompatible with infer-output-shape. "
265*89c4ff92SAndroid Build Coastguard Worker                  "This parameter may be removed in a later update. ",
266*89c4ff92SAndroid Build Coastguard Worker                  cxxopts::value<bool>(m_ExNetParams.m_AllowExpandedDims)->default_value("false")
267*89c4ff92SAndroid Build Coastguard Worker                          ->implicit_value("true"))
268*89c4ff92SAndroid Build Coastguard Worker 
269*89c4ff92SAndroid Build Coastguard Worker                 ("I,iterations",
270*89c4ff92SAndroid Build Coastguard Worker                  "Number of iterations to run the network for, default is set to 1. "
271*89c4ff92SAndroid Build Coastguard Worker                  "If you wish to run the model with different input data for every execution you can do so by "
272*89c4ff92SAndroid Build Coastguard Worker                  "supplying more input file paths to the 'input-tensor-data' option. "
273*89c4ff92SAndroid Build Coastguard Worker                  "Note: The number of input files provided must be divisible by the number of inputs of the model. "
274*89c4ff92SAndroid Build Coastguard Worker                  "e.g. Your model has 2 inputs and you supply 4 input files. If you set 'iterations' to 6 the first "
275*89c4ff92SAndroid Build Coastguard Worker                  "run will consume the first two inputs, the second the next two and the last will begin from the "
276*89c4ff92SAndroid Build Coastguard Worker                  "start and use the first two inputs again. "
277*89c4ff92SAndroid Build Coastguard Worker                  "Note: If the 'concurrent' option is enabled all iterations will be run asynchronously.",
278*89c4ff92SAndroid Build Coastguard Worker                  cxxopts::value<size_t>(m_ExNetParams.m_Iterations)->default_value("1"))
279*89c4ff92SAndroid Build Coastguard Worker 
280*89c4ff92SAndroid Build Coastguard Worker                 ("l,dequantize-output",
281*89c4ff92SAndroid Build Coastguard Worker                  "If this option is enabled, all quantized outputs will be dequantized to float. "
282*89c4ff92SAndroid Build Coastguard Worker                  "If unset, default to not get dequantized. "
283*89c4ff92SAndroid Build Coastguard Worker                  "Accepted values (true or false)"
284*89c4ff92SAndroid Build Coastguard Worker                  " (Not available when executing ArmNNTfLiteDelegate or TfliteInterpreter)",
285*89c4ff92SAndroid Build Coastguard Worker                  cxxopts::value<bool>(m_ExNetParams.m_DequantizeOutput)->default_value("false")->implicit_value("true"))
286*89c4ff92SAndroid Build Coastguard Worker 
287*89c4ff92SAndroid Build Coastguard Worker                 ("p,print-intermediate-layers",
288*89c4ff92SAndroid Build Coastguard Worker                  "If this option is enabled, the output of every graph layer will be printed.",
289*89c4ff92SAndroid Build Coastguard Worker                  cxxopts::value<bool>(m_ExNetParams.m_PrintIntermediate)->default_value("false")
290*89c4ff92SAndroid Build Coastguard Worker                          ->implicit_value("true"))
291*89c4ff92SAndroid Build Coastguard Worker 
292*89c4ff92SAndroid Build Coastguard Worker                 ("F,print-intermediate-layers-to-file",
293*89c4ff92SAndroid Build Coastguard Worker                  "If this option is enabled, the output of every graph layer will be printed within separate files.",
294*89c4ff92SAndroid Build Coastguard Worker                  cxxopts::value<bool>(m_ExNetParams.m_PrintIntermediateOutputsToFile)->default_value("false")
295*89c4ff92SAndroid Build Coastguard Worker                          ->implicit_value("true"))
296*89c4ff92SAndroid Build Coastguard Worker 
297*89c4ff92SAndroid Build Coastguard Worker                 ("parse-unsupported",
298*89c4ff92SAndroid Build Coastguard Worker                  "Add unsupported operators as stand-in layers (where supported by parser)",
299*89c4ff92SAndroid Build Coastguard Worker                  cxxopts::value<bool>(m_ExNetParams.m_ParseUnsupported)->default_value("false")->implicit_value("true"))
300*89c4ff92SAndroid Build Coastguard Worker 
301*89c4ff92SAndroid Build Coastguard Worker                 ("N,do-not-print-output",
302*89c4ff92SAndroid Build Coastguard Worker                  "The default behaviour of ExecuteNetwork is to print the resulting outputs on the console. "
303*89c4ff92SAndroid Build Coastguard Worker                  "This behaviour can be changed by adding this flag to your command.",
304*89c4ff92SAndroid Build Coastguard Worker                  cxxopts::value<bool>(m_ExNetParams.m_DontPrintOutputs)->default_value("false")->implicit_value("true"))
305*89c4ff92SAndroid Build Coastguard Worker 
306*89c4ff92SAndroid Build Coastguard Worker                 ("q,quantize-input",
307*89c4ff92SAndroid Build Coastguard Worker                  "If this option is enabled, all float inputs will be quantized as appropriate for the model's inputs. "
308*89c4ff92SAndroid Build Coastguard Worker                  "If unset, default to not quantized. Accepted values (true or false)"
309*89c4ff92SAndroid Build Coastguard Worker                  " (Not available when executing ArmNNTfLiteDelegate or TfliteInterpreter)",
310*89c4ff92SAndroid Build Coastguard Worker                  cxxopts::value<bool>(m_ExNetParams.m_QuantizeInput)->default_value("false")->implicit_value("true"))
311*89c4ff92SAndroid Build Coastguard Worker 
312*89c4ff92SAndroid Build Coastguard Worker                 ("r,threshold-time",
313*89c4ff92SAndroid Build Coastguard Worker                  "Threshold time is the maximum allowed time for inference measured in milliseconds. If the actual "
314*89c4ff92SAndroid Build Coastguard Worker                  "inference time is greater than the threshold time, the test will fail. By default, no threshold "
315*89c4ff92SAndroid Build Coastguard Worker                  "time is used.",
316*89c4ff92SAndroid Build Coastguard Worker                  cxxopts::value<double>(m_ExNetParams.m_ThresholdTime)->default_value("0.0"))
317*89c4ff92SAndroid Build Coastguard Worker 
318*89c4ff92SAndroid Build Coastguard Worker                 ("s,input-tensor-shape",
319*89c4ff92SAndroid Build Coastguard Worker                  "The shape of the input tensors in the network as a flat array of integers separated by comma."
320*89c4ff92SAndroid Build Coastguard Worker                  "Several shapes can be passed by separating them with a colon (:).",
321*89c4ff92SAndroid Build Coastguard Worker                  cxxopts::value<std::string>())
322*89c4ff92SAndroid Build Coastguard Worker 
323*89c4ff92SAndroid Build Coastguard Worker                 ("v,visualize-optimized-model",
324*89c4ff92SAndroid Build Coastguard Worker                  "Enables built optimized model visualizer. If unset, defaults to off.",
325*89c4ff92SAndroid Build Coastguard Worker                  cxxopts::value<bool>(m_ExNetParams.m_EnableLayerDetails)->default_value("false")
326*89c4ff92SAndroid Build Coastguard Worker                          ->implicit_value("true"))
327*89c4ff92SAndroid Build Coastguard Worker 
328*89c4ff92SAndroid Build Coastguard Worker                 ("w,write-outputs-to-file",
329*89c4ff92SAndroid Build Coastguard Worker                  "Comma-separated list of output file paths keyed with the binding-id of the output slot. "
330*89c4ff92SAndroid Build Coastguard Worker                  "If left empty (the default), the output tensors will not be written to a file.",
331*89c4ff92SAndroid Build Coastguard Worker                  cxxopts::value<std::string>())
332*89c4ff92SAndroid Build Coastguard Worker 
333*89c4ff92SAndroid Build Coastguard Worker                 ("x,subgraph-number",
334*89c4ff92SAndroid Build Coastguard Worker                  "Id of the subgraph to be executed. Defaults to 0."
335*89c4ff92SAndroid Build Coastguard Worker                  " (Not available when executing ArmNNTfLiteDelegate or TfliteInterpreter)",
336*89c4ff92SAndroid Build Coastguard Worker                  cxxopts::value<size_t>(m_ExNetParams.m_SubgraphId)->default_value("0"))
337*89c4ff92SAndroid Build Coastguard Worker 
338*89c4ff92SAndroid Build Coastguard Worker                 ("y,input-type",
339*89c4ff92SAndroid Build Coastguard Worker                  "The type of the input tensors in the network separated by comma. "
340*89c4ff92SAndroid Build Coastguard Worker                  "If unset, defaults to \"float\" for all defined inputs. "
341*89c4ff92SAndroid Build Coastguard Worker                  "Accepted values (float, int, qasymms8 or qasymmu8)."
342*89c4ff92SAndroid Build Coastguard Worker                  "DEPRECATED: The program option 'input-type' is deprecated and will be "
343*89c4ff92SAndroid Build Coastguard Worker                  "removed soon. The input-types are now automatically set.",
344*89c4ff92SAndroid Build Coastguard Worker                  cxxopts::value<std::string>())
345*89c4ff92SAndroid Build Coastguard Worker 
346*89c4ff92SAndroid Build Coastguard Worker                 ("z,output-type",
347*89c4ff92SAndroid Build Coastguard Worker                  "The type of the output tensors in the network separated by comma. "
348*89c4ff92SAndroid Build Coastguard Worker                  "If unset, defaults to \"float\" for all defined outputs. "
349*89c4ff92SAndroid Build Coastguard Worker                  "Accepted values (float, int,  qasymms8 or qasymmu8)."
350*89c4ff92SAndroid Build Coastguard Worker                  "DEPRECATED: The program option 'output-type' is deprecated and will be "
351*89c4ff92SAndroid Build Coastguard Worker                  "removed soon. The output-types are now automatically set.",
352*89c4ff92SAndroid Build Coastguard Worker                  cxxopts::value<std::string>())
353*89c4ff92SAndroid Build Coastguard Worker 
354*89c4ff92SAndroid Build Coastguard Worker                 ("T,tflite-executor",
355*89c4ff92SAndroid Build Coastguard Worker                  "Set the executor for the tflite model: parser, delegate, tflite"
356*89c4ff92SAndroid Build Coastguard Worker                  "parser is the ArmNNTfLiteParser, "
357*89c4ff92SAndroid Build Coastguard Worker                  "delegate is the ArmNNTfLiteDelegate, "
358*89c4ff92SAndroid Build Coastguard Worker                  "tflite is the TfliteInterpreter",
359*89c4ff92SAndroid Build Coastguard Worker                  cxxopts::value<std::string>()->default_value("parser"))
360*89c4ff92SAndroid Build Coastguard Worker 
361*89c4ff92SAndroid Build Coastguard Worker                 ("C, compare-output",
362*89c4ff92SAndroid Build Coastguard Worker                  "Perform a per byte root mean square error calculation of the inference output with an output"
363*89c4ff92SAndroid Build Coastguard Worker                  " file that has been previously produced by running a network through ExecuteNetwork."
364*89c4ff92SAndroid Build Coastguard Worker                  " See --write-outputs-to-file to produce an output file for an execution.",
365*89c4ff92SAndroid Build Coastguard Worker                  cxxopts::value<std::string>(m_ExNetParams.m_ComparisonFile))
366*89c4ff92SAndroid Build Coastguard Worker 
367*89c4ff92SAndroid Build Coastguard Worker                 ("B, compare-output-with-backend",
368*89c4ff92SAndroid Build Coastguard Worker                  "Perform a per byte root mean square error calculation of the output of the inference with a"
369*89c4ff92SAndroid Build Coastguard Worker                  " different backend.",
370*89c4ff92SAndroid Build Coastguard Worker                  cxxopts::value<std::vector<std::string>>())
371*89c4ff92SAndroid Build Coastguard Worker 
372*89c4ff92SAndroid Build Coastguard Worker                 ("A, compare-with-tflite",
373*89c4ff92SAndroid Build Coastguard Worker                  "Perform an per byte root mean square error calculation of the output of the inference with"
374*89c4ff92SAndroid Build Coastguard Worker                  " the tflite ref model.",
375*89c4ff92SAndroid Build Coastguard Worker                  cxxopts::value<bool>(m_ExNetParams.m_CompareWithTflite)->default_value("false")
376*89c4ff92SAndroid Build Coastguard Worker                          ->implicit_value("true"));
377*89c4ff92SAndroid Build Coastguard Worker 
378*89c4ff92SAndroid Build Coastguard Worker         m_CxxOptions.add_options("c) Optimization")
379*89c4ff92SAndroid Build Coastguard Worker                 ("bf16-turbo-mode",
380*89c4ff92SAndroid Build Coastguard Worker                  "This option is no longer being used. In order to use bf16 please set enable-fast-math "
381*89c4ff92SAndroid Build Coastguard Worker                  "to true",
382*89c4ff92SAndroid Build Coastguard Worker                  cxxopts::value<bool>(m_ExNetParams.m_EnableBf16TurboMode)
383*89c4ff92SAndroid Build Coastguard Worker                          ->default_value("false")->implicit_value("true"))
384*89c4ff92SAndroid Build Coastguard Worker 
385*89c4ff92SAndroid Build Coastguard Worker                 ("enable-fast-math",
386*89c4ff92SAndroid Build Coastguard Worker                  "Enables fast_math options in backends that support it. Using the fast_math flag can lead to "
387*89c4ff92SAndroid Build Coastguard Worker                  "performance improvements but may result in reduced or different precision. ",
388*89c4ff92SAndroid Build Coastguard Worker                  cxxopts::value<bool>(m_ExNetParams.m_EnableFastMath)->default_value("false")->implicit_value("true"))
389*89c4ff92SAndroid Build Coastguard Worker 
390*89c4ff92SAndroid Build Coastguard Worker                 ("number-of-threads",
391*89c4ff92SAndroid Build Coastguard Worker                  "Assign the number of threads used by the CpuAcc backend. "
392*89c4ff92SAndroid Build Coastguard Worker                  "Input value must be between 1 and 64. "
393*89c4ff92SAndroid Build Coastguard Worker                  "Default is set to 0 (Backend will decide number of threads to use).",
394*89c4ff92SAndroid Build Coastguard Worker                  cxxopts::value<unsigned int>(m_ExNetParams.m_NumberOfThreads)->default_value("0"))
395*89c4ff92SAndroid Build Coastguard Worker 
396*89c4ff92SAndroid Build Coastguard Worker                 ("save-cached-network",
397*89c4ff92SAndroid Build Coastguard Worker                  "Enables saving of the cached network to a file given with the cached-network-filepath option. "
398*89c4ff92SAndroid Build Coastguard Worker                  "See also --cached-network-filepath",
399*89c4ff92SAndroid Build Coastguard Worker                  cxxopts::value<bool>(m_ExNetParams.m_SaveCachedNetwork)
400*89c4ff92SAndroid Build Coastguard Worker                          ->default_value("false")->implicit_value("true"))
401*89c4ff92SAndroid Build Coastguard Worker 
402*89c4ff92SAndroid Build Coastguard Worker                 ("cached-network-filepath",
403*89c4ff92SAndroid Build Coastguard Worker                  "If non-empty, the given file will be used to load/save the cached network. "
404*89c4ff92SAndroid Build Coastguard Worker                  "If save-cached-network is given then the cached network will be saved to the given file. "
405*89c4ff92SAndroid Build Coastguard Worker                  "To save the cached network a file must already exist. "
406*89c4ff92SAndroid Build Coastguard Worker                  "If save-cached-network is not given then the cached network will be loaded from the given file. "
407*89c4ff92SAndroid Build Coastguard Worker                  "This will remove initial compilation time of kernels and speed up the first execution.",
408*89c4ff92SAndroid Build Coastguard Worker                  cxxopts::value<std::string>(m_ExNetParams.m_CachedNetworkFilePath)->default_value(""))
409*89c4ff92SAndroid Build Coastguard Worker 
410*89c4ff92SAndroid Build Coastguard Worker                 ("fp16-turbo-mode",
411*89c4ff92SAndroid Build Coastguard Worker                  "If this option is enabled, FP32 layers, "
412*89c4ff92SAndroid Build Coastguard Worker                  "weights and biases will be converted to FP16 where the backend supports it",
413*89c4ff92SAndroid Build Coastguard Worker                  cxxopts::value<bool>(m_ExNetParams.m_EnableFp16TurboMode)
414*89c4ff92SAndroid Build Coastguard Worker                          ->default_value("false")->implicit_value("true"))
415*89c4ff92SAndroid Build Coastguard Worker 
416*89c4ff92SAndroid Build Coastguard Worker                 ("tuning-level",
417*89c4ff92SAndroid Build Coastguard Worker                  "Sets the tuning level which enables a tuning run which will update/create a tuning file. "
418*89c4ff92SAndroid Build Coastguard Worker                  "Available options are: 1 (Rapid), 2 (Normal), 3 (Exhaustive). "
419*89c4ff92SAndroid Build Coastguard Worker                  "Requires tuning-path to be set, default is set to 0 (No tuning run)",
420*89c4ff92SAndroid Build Coastguard Worker                  cxxopts::value<int>(m_ExNetParams.m_TuningLevel)->default_value("0"))
421*89c4ff92SAndroid Build Coastguard Worker 
422*89c4ff92SAndroid Build Coastguard Worker                 ("tuning-path",
423*89c4ff92SAndroid Build Coastguard Worker                  "Path to tuning file. Enables use of CL tuning",
424*89c4ff92SAndroid Build Coastguard Worker                  cxxopts::value<std::string>(m_ExNetParams.m_TuningPath))
425*89c4ff92SAndroid Build Coastguard Worker 
426*89c4ff92SAndroid Build Coastguard Worker                 ("MLGOTuningFilePath",
427*89c4ff92SAndroid Build Coastguard Worker                  "Path to tuning file. Enables use of CL MLGO tuning",
428*89c4ff92SAndroid Build Coastguard Worker                  cxxopts::value<std::string>(m_ExNetParams.m_MLGOTuningFilePath))
429*89c4ff92SAndroid Build Coastguard Worker 
430*89c4ff92SAndroid Build Coastguard Worker                 ("R, reuse-buffers",
431*89c4ff92SAndroid Build Coastguard Worker                  "If enabled then the IO buffers will be reused for each inference",
432*89c4ff92SAndroid Build Coastguard Worker                  cxxopts::value<bool>(m_ExNetParams.m_ReuseBuffers)->default_value("false")->implicit_value("true"));
433*89c4ff92SAndroid Build Coastguard Worker 
434*89c4ff92SAndroid Build Coastguard Worker         m_CxxOptions.add_options("d) Profiling")
435*89c4ff92SAndroid Build Coastguard Worker                 ("a,enable-external-profiling",
436*89c4ff92SAndroid Build Coastguard Worker                  "If enabled external profiling will be switched on",
437*89c4ff92SAndroid Build Coastguard Worker                  cxxopts::value<bool>(m_RuntimeOptions.m_ProfilingOptions.m_EnableProfiling)
438*89c4ff92SAndroid Build Coastguard Worker                          ->default_value("false")->implicit_value("true"))
439*89c4ff92SAndroid Build Coastguard Worker 
440*89c4ff92SAndroid Build Coastguard Worker                 ("e,event-based-profiling",
441*89c4ff92SAndroid Build Coastguard Worker                  "Enables built in profiler. If unset, defaults to off.",
442*89c4ff92SAndroid Build Coastguard Worker                  cxxopts::value<bool>(m_ExNetParams.m_EnableProfiling)->default_value("false")->implicit_value("true"))
443*89c4ff92SAndroid Build Coastguard Worker 
444*89c4ff92SAndroid Build Coastguard Worker                 ("g,file-only-external-profiling",
445*89c4ff92SAndroid Build Coastguard Worker                  "If enabled then the 'file-only' test mode of external profiling will be enabled",
446*89c4ff92SAndroid Build Coastguard Worker                  cxxopts::value<bool>(m_RuntimeOptions.m_ProfilingOptions.m_FileOnly)
447*89c4ff92SAndroid Build Coastguard Worker                          ->default_value("false")->implicit_value("true"))
448*89c4ff92SAndroid Build Coastguard Worker 
449*89c4ff92SAndroid Build Coastguard Worker                 ("file-format",
450*89c4ff92SAndroid Build Coastguard Worker                  "If profiling is enabled specifies the output file format",
451*89c4ff92SAndroid Build Coastguard Worker                  cxxopts::value<std::string>(m_RuntimeOptions.m_ProfilingOptions.m_FileFormat)->default_value("binary"))
452*89c4ff92SAndroid Build Coastguard Worker 
453*89c4ff92SAndroid Build Coastguard Worker                 ("j,outgoing-capture-file",
454*89c4ff92SAndroid Build Coastguard Worker                  "If specified the outgoing external profiling packets will be captured in this binary file",
455*89c4ff92SAndroid Build Coastguard Worker                  cxxopts::value<std::string>(m_RuntimeOptions.m_ProfilingOptions.m_OutgoingCaptureFile))
456*89c4ff92SAndroid Build Coastguard Worker 
457*89c4ff92SAndroid Build Coastguard Worker                 ("k,incoming-capture-file",
458*89c4ff92SAndroid Build Coastguard Worker                  "If specified the incoming external profiling packets will be captured in this binary file",
459*89c4ff92SAndroid Build Coastguard Worker                  cxxopts::value<std::string>(m_RuntimeOptions.m_ProfilingOptions.m_IncomingCaptureFile))
460*89c4ff92SAndroid Build Coastguard Worker 
461*89c4ff92SAndroid Build Coastguard Worker                 ("timeline-profiling",
462*89c4ff92SAndroid Build Coastguard Worker                  "If enabled timeline profiling will be switched on, requires external profiling",
463*89c4ff92SAndroid Build Coastguard Worker                  cxxopts::value<bool>(m_RuntimeOptions.m_ProfilingOptions.m_TimelineEnabled)
464*89c4ff92SAndroid Build Coastguard Worker                          ->default_value("false")->implicit_value("true"))
465*89c4ff92SAndroid Build Coastguard Worker 
466*89c4ff92SAndroid Build Coastguard Worker                 ("u,counter-capture-period",
467*89c4ff92SAndroid Build Coastguard Worker                  "If profiling is enabled in 'file-only' mode this is the capture period that will be used in the test",
468*89c4ff92SAndroid Build Coastguard Worker                  cxxopts::value<uint32_t>(m_RuntimeOptions.m_ProfilingOptions.m_CapturePeriod)->default_value("150"))
469*89c4ff92SAndroid Build Coastguard Worker 
470*89c4ff92SAndroid Build Coastguard Worker                 ("output-network-details",
471*89c4ff92SAndroid Build Coastguard Worker                  "Outputs layer tensor infos and descriptors to std out along with profiling events. Defaults to off.",
472*89c4ff92SAndroid Build Coastguard Worker                  cxxopts::value<bool>(m_ExNetParams.m_OutputDetailsToStdOut)->default_value("false")
473*89c4ff92SAndroid Build Coastguard Worker                          ->implicit_value("true"))
474*89c4ff92SAndroid Build Coastguard Worker 
475*89c4ff92SAndroid Build Coastguard Worker                 ("output-network-details-only",
476*89c4ff92SAndroid Build Coastguard Worker                  "Outputs layer tensor infos and descriptors to std out without profiling events. Defaults to off.",
477*89c4ff92SAndroid Build Coastguard Worker                  cxxopts::value<bool>(m_ExNetParams.m_OutputDetailsOnlyToStdOut)->default_value("false")
478*89c4ff92SAndroid Build Coastguard Worker                          ->implicit_value("true"))
479*89c4ff92SAndroid Build Coastguard Worker 
480*89c4ff92SAndroid Build Coastguard Worker                 ("import-inputs-if-aligned",
481*89c4ff92SAndroid Build Coastguard Worker                  "In & Out tensors will be imported per inference if the memory alignment allows. Defaults to false.",
482*89c4ff92SAndroid Build Coastguard Worker                  cxxopts::value<bool>(m_ExNetParams.m_ImportInputsIfAligned)->default_value("false")
483*89c4ff92SAndroid Build Coastguard Worker                          ->implicit_value("true"));
484*89c4ff92SAndroid Build Coastguard Worker     }
485*89c4ff92SAndroid Build Coastguard Worker     catch (const std::exception& e)
486*89c4ff92SAndroid Build Coastguard Worker     {
487*89c4ff92SAndroid Build Coastguard Worker         ARMNN_ASSERT_MSG(false, "Caught unexpected exception");
488*89c4ff92SAndroid Build Coastguard Worker         ARMNN_LOG(fatal) << "Fatal internal error: " << e.what();
489*89c4ff92SAndroid Build Coastguard Worker         exit(EXIT_FAILURE);
490*89c4ff92SAndroid Build Coastguard Worker     }
491*89c4ff92SAndroid Build Coastguard Worker }
492*89c4ff92SAndroid Build Coastguard Worker 
ProgramOptions(int ac,const char * av[])493*89c4ff92SAndroid Build Coastguard Worker ProgramOptions::ProgramOptions(int ac, const char* av[]): ProgramOptions()
494*89c4ff92SAndroid Build Coastguard Worker {
495*89c4ff92SAndroid Build Coastguard Worker     ParseOptions(ac, av);
496*89c4ff92SAndroid Build Coastguard Worker }
497*89c4ff92SAndroid Build Coastguard Worker 
ParseOptions(int ac,const char * av[])498*89c4ff92SAndroid Build Coastguard Worker void ProgramOptions::ParseOptions(int ac, const char* av[])
499*89c4ff92SAndroid Build Coastguard Worker {
500*89c4ff92SAndroid Build Coastguard Worker     // Parses the command-line.
501*89c4ff92SAndroid Build Coastguard Worker     m_CxxResult = m_CxxOptions.parse(ac, av);
502*89c4ff92SAndroid Build Coastguard Worker 
503*89c4ff92SAndroid Build Coastguard Worker     if (m_CxxResult.count("help") || ac <= 1)
504*89c4ff92SAndroid Build Coastguard Worker     {
505*89c4ff92SAndroid Build Coastguard Worker         std::cout << m_CxxOptions.help() << std::endl;
506*89c4ff92SAndroid Build Coastguard Worker         exit(EXIT_SUCCESS);
507*89c4ff92SAndroid Build Coastguard Worker     }
508*89c4ff92SAndroid Build Coastguard Worker 
509*89c4ff92SAndroid Build Coastguard Worker     CheckRequiredOptions(m_CxxResult);
510*89c4ff92SAndroid Build Coastguard Worker     CheckOptionDependencies(m_CxxResult);
511*89c4ff92SAndroid Build Coastguard Worker     CheckForDeprecatedOptions(m_CxxResult);
512*89c4ff92SAndroid Build Coastguard Worker 
513*89c4ff92SAndroid Build Coastguard Worker     if ((m_ExNetParams.m_OutputDetailsToStdOut ||
514*89c4ff92SAndroid Build Coastguard Worker          m_ExNetParams.m_OutputDetailsOnlyToStdOut) &&
515*89c4ff92SAndroid Build Coastguard Worker         !m_ExNetParams.m_EnableProfiling)
516*89c4ff92SAndroid Build Coastguard Worker     {
517*89c4ff92SAndroid Build Coastguard Worker         throw cxxopts::OptionParseException("You must enable profiling if you would like to output layer details");
518*89c4ff92SAndroid Build Coastguard Worker     }
519*89c4ff92SAndroid Build Coastguard Worker 
520*89c4ff92SAndroid Build Coastguard Worker     // Some options can't be assigned directly because they need some post-processing:
521*89c4ff92SAndroid Build Coastguard Worker     auto computeDevices = GetOptionValue<std::vector<std::string>>("compute", m_CxxResult);
522*89c4ff92SAndroid Build Coastguard Worker     m_ExNetParams.m_ComputeDevices = GetBackendIDs(computeDevices);
523*89c4ff92SAndroid Build Coastguard Worker     m_ExNetParams.m_InputNames =
524*89c4ff92SAndroid Build Coastguard Worker             ParseStringList(GetOptionValue<std::string>("input-name", m_CxxResult), ",");
525*89c4ff92SAndroid Build Coastguard Worker     m_ExNetParams.m_InputTensorDataFilePaths =
526*89c4ff92SAndroid Build Coastguard Worker             ParseStringList(GetOptionValue<std::string>("input-tensor-data", m_CxxResult), ",");
527*89c4ff92SAndroid Build Coastguard Worker     m_ExNetParams.m_OutputNames =
528*89c4ff92SAndroid Build Coastguard Worker             ParseStringList(GetOptionValue<std::string>("output-name", m_CxxResult), ",");
529*89c4ff92SAndroid Build Coastguard Worker     m_ExNetParams.m_OutputTensorFiles =
530*89c4ff92SAndroid Build Coastguard Worker             ParseStringList(GetOptionValue<std::string>("write-outputs-to-file", m_CxxResult), ",");
531*89c4ff92SAndroid Build Coastguard Worker     m_ExNetParams.m_GenerateTensorData = m_ExNetParams.m_InputTensorDataFilePaths.empty();
532*89c4ff92SAndroid Build Coastguard Worker     m_ExNetParams.m_DynamicBackendsPath = m_RuntimeOptions.m_DynamicBackendsPath;
533*89c4ff92SAndroid Build Coastguard Worker 
534*89c4ff92SAndroid Build Coastguard Worker     m_RuntimeOptions.m_EnableGpuProfiling = m_ExNetParams.m_EnableProfiling;
535*89c4ff92SAndroid Build Coastguard Worker 
536*89c4ff92SAndroid Build Coastguard Worker     std::string tfliteExecutor = GetOptionValue<std::string>("tflite-executor", m_CxxResult);
537*89c4ff92SAndroid Build Coastguard Worker 
538*89c4ff92SAndroid Build Coastguard Worker     if (tfliteExecutor.size() == 0 || tfliteExecutor == "parser")
539*89c4ff92SAndroid Build Coastguard Worker     {
540*89c4ff92SAndroid Build Coastguard Worker         m_ExNetParams.m_TfLiteExecutor = ExecuteNetworkParams::TfLiteExecutor::ArmNNTfLiteParser;
541*89c4ff92SAndroid Build Coastguard Worker     }
542*89c4ff92SAndroid Build Coastguard Worker     else if (tfliteExecutor == "delegate")
543*89c4ff92SAndroid Build Coastguard Worker     {
544*89c4ff92SAndroid Build Coastguard Worker         m_ExNetParams.m_TfLiteExecutor = ExecuteNetworkParams::TfLiteExecutor::ArmNNTfLiteDelegate;
545*89c4ff92SAndroid Build Coastguard Worker     }
546*89c4ff92SAndroid Build Coastguard Worker     else if (tfliteExecutor == "tflite")
547*89c4ff92SAndroid Build Coastguard Worker     {
548*89c4ff92SAndroid Build Coastguard Worker         m_ExNetParams.m_TfLiteExecutor = ExecuteNetworkParams::TfLiteExecutor::TfliteInterpreter;
549*89c4ff92SAndroid Build Coastguard Worker     }
550*89c4ff92SAndroid Build Coastguard Worker     else
551*89c4ff92SAndroid Build Coastguard Worker     {
552*89c4ff92SAndroid Build Coastguard Worker         ARMNN_LOG(info) << fmt::format("Invalid tflite-executor option '{}'.", tfliteExecutor);
553*89c4ff92SAndroid Build Coastguard Worker         throw armnn::InvalidArgumentException ("Invalid tflite-executor option");
554*89c4ff92SAndroid Build Coastguard Worker     }
555*89c4ff92SAndroid Build Coastguard Worker 
556*89c4ff92SAndroid Build Coastguard Worker     // For backwards compatibility when deprecated options are used
557*89c4ff92SAndroid Build Coastguard Worker     if (m_ExNetParams.m_EnableDelegate)
558*89c4ff92SAndroid Build Coastguard Worker     {
559*89c4ff92SAndroid Build Coastguard Worker         m_ExNetParams.m_TfLiteExecutor = ExecuteNetworkParams::TfLiteExecutor::ArmNNTfLiteDelegate;
560*89c4ff92SAndroid Build Coastguard Worker     }
561*89c4ff92SAndroid Build Coastguard Worker 
562*89c4ff92SAndroid Build Coastguard Worker     // Set concurrent to true if the user expects to run inferences asynchronously
563*89c4ff92SAndroid Build Coastguard Worker     if (m_ExNetParams.m_Concurrent)
564*89c4ff92SAndroid Build Coastguard Worker     {
565*89c4ff92SAndroid Build Coastguard Worker         m_ExNetParams.m_ThreadPoolSize = 1;
566*89c4ff92SAndroid Build Coastguard Worker     }
567*89c4ff92SAndroid Build Coastguard Worker 
568*89c4ff92SAndroid Build Coastguard Worker     if (m_ExNetParams.m_ThreadPoolSize > 0)
569*89c4ff92SAndroid Build Coastguard Worker     {
570*89c4ff92SAndroid Build Coastguard Worker         m_ExNetParams.m_Concurrent = true;
571*89c4ff92SAndroid Build Coastguard Worker     }
572*89c4ff92SAndroid Build Coastguard Worker 
573*89c4ff92SAndroid Build Coastguard Worker     // Parse input tensor shape from the string we got from the command-line.
574*89c4ff92SAndroid Build Coastguard Worker     std::vector<std::string> inputTensorShapesVector =
575*89c4ff92SAndroid Build Coastguard Worker             ParseStringList(GetOptionValue<std::string>("input-tensor-shape", m_CxxResult), ":");
576*89c4ff92SAndroid Build Coastguard Worker 
577*89c4ff92SAndroid Build Coastguard Worker     if (!inputTensorShapesVector.empty())
578*89c4ff92SAndroid Build Coastguard Worker     {
579*89c4ff92SAndroid Build Coastguard Worker         m_ExNetParams.m_InputTensorShapes.reserve(inputTensorShapesVector.size());
580*89c4ff92SAndroid Build Coastguard Worker 
581*89c4ff92SAndroid Build Coastguard Worker         for(const std::string& shape : inputTensorShapesVector)
582*89c4ff92SAndroid Build Coastguard Worker         {
583*89c4ff92SAndroid Build Coastguard Worker             std::stringstream ss(shape);
584*89c4ff92SAndroid Build Coastguard Worker             std::vector<unsigned int> dims = ParseArray(ss);
585*89c4ff92SAndroid Build Coastguard Worker 
586*89c4ff92SAndroid Build Coastguard Worker             m_ExNetParams.m_InputTensorShapes.push_back(
587*89c4ff92SAndroid Build Coastguard Worker                     armnn::TensorShape{static_cast<unsigned int>(dims.size()), dims.data()});
588*89c4ff92SAndroid Build Coastguard Worker         }
589*89c4ff92SAndroid Build Coastguard Worker     }
590*89c4ff92SAndroid Build Coastguard Worker 
591*89c4ff92SAndroid Build Coastguard Worker     // We have to validate ExecuteNetworkParams first so that the tuning path and level is validated
592*89c4ff92SAndroid Build Coastguard Worker     ValidateExecuteNetworkParams();
593*89c4ff92SAndroid Build Coastguard Worker 
594*89c4ff92SAndroid Build Coastguard Worker     // Parse CL tuning parameters to runtime options
595*89c4ff92SAndroid Build Coastguard Worker     if (!m_ExNetParams.m_TuningPath.empty())
596*89c4ff92SAndroid Build Coastguard Worker     {
597*89c4ff92SAndroid Build Coastguard Worker         m_RuntimeOptions.m_BackendOptions.emplace_back(
598*89c4ff92SAndroid Build Coastguard Worker             armnn::BackendOptions
599*89c4ff92SAndroid Build Coastguard Worker             {
600*89c4ff92SAndroid Build Coastguard Worker                 "GpuAcc",
601*89c4ff92SAndroid Build Coastguard Worker                 {
602*89c4ff92SAndroid Build Coastguard Worker                     {"TuningLevel", m_ExNetParams.m_TuningLevel},
603*89c4ff92SAndroid Build Coastguard Worker                     {"TuningFile", m_ExNetParams.m_TuningPath.c_str()},
604*89c4ff92SAndroid Build Coastguard Worker                     {"KernelProfilingEnabled", m_ExNetParams.m_EnableProfiling},
605*89c4ff92SAndroid Build Coastguard Worker                     {"MLGOTuningFilePath", m_ExNetParams.m_MLGOTuningFilePath}
606*89c4ff92SAndroid Build Coastguard Worker                 }
607*89c4ff92SAndroid Build Coastguard Worker             }
608*89c4ff92SAndroid Build Coastguard Worker         );
609*89c4ff92SAndroid Build Coastguard Worker     }
610*89c4ff92SAndroid Build Coastguard Worker 
611*89c4ff92SAndroid Build Coastguard Worker     ValidateRuntimeOptions();
612*89c4ff92SAndroid Build Coastguard Worker 
613*89c4ff92SAndroid Build Coastguard Worker     auto comparisonComputDevices = GetOptionValue<std::vector<std::string>>("compare-output-with-backend", m_CxxResult);
614*89c4ff92SAndroid Build Coastguard Worker 
615*89c4ff92SAndroid Build Coastguard Worker     if (!comparisonComputDevices.empty())
616*89c4ff92SAndroid Build Coastguard Worker     {
617*89c4ff92SAndroid Build Coastguard Worker         m_ExNetParams.m_ComparisonComputeDevices = GetBackendIDs(comparisonComputDevices);
618*89c4ff92SAndroid Build Coastguard Worker     }
619*89c4ff92SAndroid Build Coastguard Worker }
620*89c4ff92SAndroid Build Coastguard Worker 
621