ArmNN
 20.05
ExecuteNetwork.cpp File Reference

Go to the source code of this file.

Functions

int main (int argc, const char *argv[])
 

Function Documentation

◆ main()

int main ( int  argc,
const char *  argv[] 
)

Definition at line 9 of file ExecuteNetwork.cpp.

References ARMNN_ASSERT_MSG, ARMNN_LOG, armnn::BackendRegistryInstance(), armnn::ConfigureLogging(), IRuntime::Create(), armnn::Debug, BackendRegistry::GetBackendIdsAsString(), armnn::Info, IRuntime::CreationOptions::m_BackendOptions, IRuntime::CreationOptions::ExternalProfilingOptions::m_CapturePeriod, IRuntime::CreationOptions::m_DynamicBackendsPath, IRuntime::CreationOptions::m_EnableGpuProfiling, IRuntime::CreationOptions::ExternalProfilingOptions::m_EnableProfiling, IRuntime::CreationOptions::ExternalProfilingOptions::m_FileFormat, IRuntime::CreationOptions::ExternalProfilingOptions::m_FileOnly, IRuntime::CreationOptions::ExternalProfilingOptions::m_IncomingCaptureFile, IRuntime::CreationOptions::ExternalProfilingOptions::m_OutgoingCaptureFile, IRuntime::CreationOptions::m_ProfilingOptions, IRuntime::CreationOptions::ExternalProfilingOptions::m_TimelineEnabled, options, CsvReader::ParseFile(), RunCLTuning(), RunCsvTest(), and RunTest().

10 {
11  // Configures logging for both the ARMNN library and this test program.
12 #ifdef NDEBUG
14 #else
16 #endif
17  armnn::ConfigureLogging(true, true, level);
18 
19  std::string testCasesFile;
20 
21  std::string modelFormat;
22  std::string modelPath;
23  std::string inputNames;
24  std::string inputTensorShapes;
25  std::string inputTensorDataFilePaths;
26  std::string outputNames;
27  std::string inputTypes;
28  std::string outputTypes;
29  std::string dynamicBackendsPath;
30  std::string outputTensorFiles;
31 
32  // external profiling parameters
33  std::string outgoingCaptureFile;
34  std::string incomingCaptureFile;
35  uint32_t counterCapturePeriod;
36  std::string fileFormat;
37 
38  size_t iterations = 1;
39  int tuningLevel = 0;
40  std::string tuningPath;
41 
42  double thresholdTime = 0.0;
43 
44  size_t subgraphId = 0;
45 
46  const std::string backendsMessage = "REQUIRED: Which device to run layers on by default. Possible choices: "
48  po::options_description desc("Options");
49  try
50  {
51  desc.add_options()
52  ("help", "Display usage information")
53  ("compute,c", po::value<std::vector<std::string>>()->multitoken()->required(),
54  backendsMessage.c_str())
55  ("test-cases,t", po::value(&testCasesFile), "Path to a CSV file containing test cases to run. "
56  "If set, further parameters -- with the exception of compute device and concurrency -- will be ignored, "
57  "as they are expected to be defined in the file for each test in particular.")
58  ("concurrent,n", po::bool_switch()->default_value(false),
59  "Whether or not the test cases should be executed in parallel")
60  ("model-format,f", po::value(&modelFormat)->required(),
61  "armnn-binary, caffe-binary, caffe-text, onnx-binary, onnx-text, tflite-binary, tensorflow-binary or "
62  "tensorflow-text.")
63  ("model-path,m", po::value(&modelPath)->required(), "Path to model file, e.g. .armnn, .caffemodel, "
64  ".prototxt, .tflite, .onnx")
65  ("dynamic-backends-path,b", po::value(&dynamicBackendsPath),
66  "Path where to load any available dynamic backend from. "
67  "If left empty (the default), dynamic backends will not be used.")
68  ("input-name,i", po::value(&inputNames),
69  "Identifier of the input tensors in the network separated by comma.")
70  ("subgraph-number,x", po::value<size_t>(&subgraphId)->default_value(0), "Id of the subgraph to be executed."
71  "Defaults to 0")
72  ("input-tensor-shape,s", po::value(&inputTensorShapes),
73  "The shape of the input tensors in the network as a flat array of integers separated by comma."
74  "Several shapes can be passed by separating them with a colon (:)."
75  "This parameter is optional, depending on the network.")
76  ("input-tensor-data,d", po::value(&inputTensorDataFilePaths)->default_value(""),
77  "Path to files containing the input data as a flat array separated by whitespace. "
78  "Several paths can be passed by separating them with a comma. If not specified, the network will be run "
79  "with dummy data (useful for profiling).")
80  ("input-type,y",po::value(&inputTypes), "The type of the input tensors in the network separated by comma. "
81  "If unset, defaults to \"float\" for all defined inputs. "
82  "Accepted values (float, int or qasymm8)")
83  ("quantize-input,q",po::bool_switch()->default_value(false),
84  "If this option is enabled, all float inputs will be quantized to qasymm8. "
85  "If unset, default to not quantized. "
86  "Accepted values (true or false)")
87  ("output-type,z",po::value(&outputTypes),
88  "The type of the output tensors in the network separated by comma. "
89  "If unset, defaults to \"float\" for all defined outputs. "
90  "Accepted values (float, int or qasymm8).")
91  ("dequantize-output,l",po::bool_switch()->default_value(false),
92  "If this option is enabled, all quantized outputs will be dequantized to float. "
93  "If unset, default to not get dequantized. "
94  "Accepted values (true or false)")
95  ("output-name,o", po::value(&outputNames),
96  "Identifier of the output tensors in the network separated by comma.")
97  ("write-outputs-to-file,w", po::value(&outputTensorFiles),
98  "Comma-separated list of output file paths keyed with the binding-id of the output slot. "
99  "If left empty (the default), the output tensors will not be written to a file.")
100  ("event-based-profiling,e", po::bool_switch()->default_value(false),
101  "Enables built in profiler. If unset, defaults to off.")
102  ("visualize-optimized-model,v", po::bool_switch()->default_value(false),
103  "Enables built optimized model visualizer. If unset, defaults to off.")
104  ("bf16-turbo-mode", po::bool_switch()->default_value(false), "If this option is enabled, FP32 layers, "
105  "weights and biases will be converted to BFloat16 where the backend supports it")
106  ("fp16-turbo-mode,h", po::bool_switch()->default_value(false), "If this option is enabled, FP32 layers, "
107  "weights and biases will be converted to FP16 where the backend supports it")
108  ("threshold-time,r", po::value<double>(&thresholdTime)->default_value(0.0),
109  "Threshold time is the maximum allowed time for inference measured in milliseconds. If the actual "
110  "inference time is greater than the threshold time, the test will fail. By default, no threshold "
111  "time is used.")
112  ("print-intermediate-layers,p", po::bool_switch()->default_value(false),
113  "If this option is enabled, the output of every graph layer will be printed.")
114  ("enable-external-profiling,a", po::bool_switch()->default_value(false),
115  "If enabled external profiling will be switched on")
116  ("timeline-profiling", po::bool_switch()->default_value(false),
117  "If enabled timeline profiling will be switched on, requires external profiling")
118  ("outgoing-capture-file,j", po::value(&outgoingCaptureFile),
119  "If specified the outgoing external profiling packets will be captured in this binary file")
120  ("incoming-capture-file,k", po::value(&incomingCaptureFile),
121  "If specified the incoming external profiling packets will be captured in this binary file")
122  ("file-only-external-profiling,g", po::bool_switch()->default_value(false),
123  "If enabled then the 'file-only' test mode of external profiling will be enabled")
124  ("counter-capture-period,u", po::value<uint32_t>(&counterCapturePeriod)->default_value(150u),
125  "If profiling is enabled in 'file-only' mode this is the capture period that will be used in the test")
126  ("file-format", po::value(&fileFormat)->default_value("binary"),
127  "If profiling is enabled specifies the output file format")
128  ("iterations", po::value<size_t>(&iterations)->default_value(1),
129  "Number of iterations to run the network for, default is set to 1")
130  ("tuning-path", po::value(&tuningPath),
131  "Path to tuning file. Enables use of CL tuning")
132  ("tuning-level", po::value<int>(&tuningLevel)->default_value(0),
133  "Sets the tuning level which enables a tuning run which will update/create a tuning file. "
134  "Available options are: 1 (Rapid), 2 (Normal), 3 (Exhaustive). "
135  "Requires tuning-path to be set, default is set to 0 (No tuning run)")
136  ("parse-unsupported", po::bool_switch()->default_value(false),
137  "Add unsupported operators as stand-in layers (where supported by parser)");
138  }
139  catch (const std::exception& e)
140  {
141  // Coverity points out that default_value(...) can throw a bad_lexical_cast,
142  // and that desc.add_options() can throw boost::io::too_few_args.
143  // They really won't in any of these cases.
144  ARMNN_ASSERT_MSG(false, "Caught unexpected exception");
145  ARMNN_LOG(fatal) << "Fatal internal error: " << e.what();
146  return EXIT_FAILURE;
147  }
148 
149  // Parses the command-line.
150  po::variables_map vm;
151  try
152  {
153  po::store(po::parse_command_line(argc, argv, desc), vm);
154 
155  if (CheckOption(vm, "help") || argc <= 1)
156  {
157  std::cout << "Executes a neural network model using the provided input tensor. " << std::endl;
158  std::cout << "Prints the resulting output tensor." << std::endl;
159  std::cout << std::endl;
160  std::cout << desc << std::endl;
161  return EXIT_SUCCESS;
162  }
163 
164  po::notify(vm);
165  }
166  catch (const po::error& e)
167  {
168  std::cerr << e.what() << std::endl << std::endl;
169  std::cerr << desc << std::endl;
170  return EXIT_FAILURE;
171  }
172 
173  // Get the value of the switch arguments.
174  bool concurrent = vm["concurrent"].as<bool>();
175  bool enableProfiling = vm["event-based-profiling"].as<bool>();
176  bool enableLayerDetails = vm["visualize-optimized-model"].as<bool>();
177  bool enableBf16TurboMode = vm["bf16-turbo-mode"].as<bool>();
178  bool enableFp16TurboMode = vm["fp16-turbo-mode"].as<bool>();
179  bool quantizeInput = vm["quantize-input"].as<bool>();
180  bool dequantizeOutput = vm["dequantize-output"].as<bool>();
181  bool printIntermediate = vm["print-intermediate-layers"].as<bool>();
182  bool enableExternalProfiling = vm["enable-external-profiling"].as<bool>();
183  bool fileOnlyExternalProfiling = vm["file-only-external-profiling"].as<bool>();
184  bool parseUnsupported = vm["parse-unsupported"].as<bool>();
185  bool timelineEnabled = vm["timeline-profiling"].as<bool>();
186 
187  if (enableBf16TurboMode && enableFp16TurboMode)
188  {
189  ARMNN_LOG(fatal) << "BFloat16 and Float16 turbo mode cannot be enabled at the same time.";
190  return EXIT_FAILURE;
191  }
192 
193  // Create runtime
195  options.m_EnableGpuProfiling = enableProfiling;
196  options.m_DynamicBackendsPath = dynamicBackendsPath;
197  options.m_ProfilingOptions.m_EnableProfiling = enableExternalProfiling;
198  options.m_ProfilingOptions.m_IncomingCaptureFile = incomingCaptureFile;
199  options.m_ProfilingOptions.m_OutgoingCaptureFile = outgoingCaptureFile;
200  options.m_ProfilingOptions.m_FileOnly = fileOnlyExternalProfiling;
201  options.m_ProfilingOptions.m_CapturePeriod = counterCapturePeriod;
202  options.m_ProfilingOptions.m_FileFormat = fileFormat;
203  options.m_ProfilingOptions.m_TimelineEnabled = timelineEnabled;
204 
205  if (timelineEnabled && !enableExternalProfiling)
206  {
207  ARMNN_LOG(fatal) << "Timeline profiling requires external profiling to be turned on";
208  return EXIT_FAILURE;
209  }
210 
211  // Check whether we have to load test cases from a file.
212  if (CheckOption(vm, "test-cases"))
213  {
214  // Check that the file exists.
215  if (!boost::filesystem::exists(testCasesFile))
216  {
217  ARMNN_LOG(fatal) << "Given file \"" << testCasesFile << "\" does not exist";
218  return EXIT_FAILURE;
219  }
220 
221  // Parse CSV file and extract test cases
222  armnnUtils::CsvReader reader;
223  std::vector<armnnUtils::CsvRow> testCases = reader.ParseFile(testCasesFile);
224 
225  // Check that there is at least one test case to run
226  if (testCases.empty())
227  {
228  ARMNN_LOG(fatal) << "Given file \"" << testCasesFile << "\" has no test cases";
229  return EXIT_FAILURE;
230  }
231  // Create runtime
232  std::shared_ptr<armnn::IRuntime> runtime(armnn::IRuntime::Create(options));
233 
234  const std::string executableName("ExecuteNetwork");
235 
236  // Check whether we need to run the test cases concurrently
237  if (concurrent)
238  {
239  std::vector<std::future<int>> results;
240  results.reserve(testCases.size());
241 
242  // Run each test case in its own thread
243  for (auto& testCase : testCases)
244  {
245  testCase.values.insert(testCase.values.begin(), executableName);
246  results.push_back(std::async(std::launch::async, RunCsvTest, std::cref(testCase), std::cref(runtime),
247  enableProfiling, enableFp16TurboMode, enableBf16TurboMode, thresholdTime,
248  printIntermediate, enableLayerDetails, parseUnsupported));
249  }
250 
251  // Check results
252  for (auto& result : results)
253  {
254  if (result.get() != EXIT_SUCCESS)
255  {
256  return EXIT_FAILURE;
257  }
258  }
259  }
260  else
261  {
262  // Run tests sequentially
263  for (auto& testCase : testCases)
264  {
265  testCase.values.insert(testCase.values.begin(), executableName);
266  if (RunCsvTest(testCase, runtime, enableProfiling,
267  enableFp16TurboMode, enableBf16TurboMode, thresholdTime, printIntermediate,
268  enableLayerDetails, parseUnsupported) != EXIT_SUCCESS)
269  {
270  return EXIT_FAILURE;
271  }
272  }
273  }
274 
275  return EXIT_SUCCESS;
276  }
277  else // Run single test
278  {
279  // Get the preferred order of compute devices. If none are specified, default to using CpuRef
280  const std::string computeOption("compute");
281  std::vector<std::string> computeDevicesAsStrings =
282  CheckOption(vm, computeOption.c_str()) ?
283  vm[computeOption].as<std::vector<std::string>>() :
284  std::vector<std::string>();
285  std::vector<armnn::BackendId> computeDevices(computeDevicesAsStrings.begin(), computeDevicesAsStrings.end());
286 
287  // Remove duplicates from the list of compute devices.
288  RemoveDuplicateDevices(computeDevices);
289 
290 #if defined(ARMCOMPUTECL_ENABLED)
291  std::shared_ptr<armnn::IGpuAccTunedParameters> tuned_params;
292 
293  if (tuningPath != "")
294  {
295  if (tuningLevel != 0)
296  {
297  RunCLTuning(tuningPath, tuningLevel, modelFormat, inputTensorShapes, computeDevices,
298  dynamicBackendsPath, modelPath, inputNames, inputTensorDataFilePaths, inputTypes, quantizeInput,
299  outputTypes, outputNames, outputTensorFiles, dequantizeOutput, enableProfiling,
300  enableFp16TurboMode, enableBf16TurboMode, thresholdTime, printIntermediate, subgraphId,
301  enableLayerDetails, parseUnsupported);
302  }
303  ARMNN_LOG(info) << "Using tuning params: " << tuningPath << "\n";
304  options.m_BackendOptions.emplace_back(
306  {
307  "GpuAcc",
308  {
309  {"TuningLevel", 0},
310  {"TuningFile", tuningPath.c_str()},
311  {"KernelProfilingEnabled", enableProfiling}
312  }
313  }
314  );
315  }
316 #endif
317  try
318  {
319  CheckOptionDependencies(vm);
320  }
321  catch (const po::error& e)
322  {
323  std::cerr << e.what() << std::endl << std::endl;
324  std::cerr << desc << std::endl;
325  return EXIT_FAILURE;
326  }
327  // Create runtime
328  std::shared_ptr<armnn::IRuntime> runtime(armnn::IRuntime::Create(options));
329 
330  return RunTest(modelFormat, inputTensorShapes, computeDevices, dynamicBackendsPath, modelPath,
331  inputNames, inputTensorDataFilePaths, inputTypes, quantizeInput, outputTypes, outputNames,
332  outputTensorFiles, dequantizeOutput, enableProfiling, enableFp16TurboMode, enableBf16TurboMode,
333  thresholdTime, printIntermediate, subgraphId, enableLayerDetails, parseUnsupported, iterations, runtime);
334  }
335 }
static IRuntimePtr Create(const CreationOptions &options)
Definition: Runtime.cpp:31
int RunCsvTest(const armnnUtils::CsvRow &csvRow, const std::shared_ptr< armnn::IRuntime > &runtime, const bool enableProfiling, const bool enableFp16TurboMode, const bool enableBf16TurboMode, const double &thresholdTime, const bool printIntermediate, bool enableLayerDetails=false, bool parseUnuspported=false)
void ConfigureLogging(bool printToStandardOutput, bool printToDebugOutput, LogSeverity severity)
Configures the logging behaviour of the ARMNN library.
Definition: Utils.cpp:10
#define ARMNN_LOG(severity)
Definition: Logging.hpp:163
BackendRegistry & BackendRegistryInstance()
std::string GetBackendIdsAsString() const
int RunTest(const std::string &format, const std::string &inputTensorShapesStr, const vector< armnn::BackendId > &computeDevices, const std::string &dynamicBackendsPath, const std::string &path, const std::string &inputNames, const std::string &inputTensorDataFilePaths, const std::string &inputTypes, bool quantizeInput, const std::string &outputTypes, const std::string &outputNames, const std::string &outputTensorFiles, bool dequantizeOuput, bool enableProfiling, bool enableFp16TurboMode, bool enableBf16TurboMode, const double &thresholdTime, bool printIntermediate, const size_t subgraphId, bool enableLayerDetails=false, bool parseUnsupported=false, const size_t iterations=1, const std::shared_ptr< armnn::IRuntime > &runtime=nullptr)
std::vector< BackendOptions > m_BackendOptions
Pass backend specific options.
Definition: IRuntime.hpp:115
#define ARMNN_ASSERT_MSG(COND, MSG)
Definition: Assert.hpp:15
Struct for the users to pass backend specific options.
std::string m_DynamicBackendsPath
Setting this value will override the paths set by the DYNAMIC_BACKEND_PATHS compiler directive Only a...
Definition: IRuntime.hpp:59
bool m_EnableGpuProfiling
Setting this flag will allow the user to obtain GPU profiling information from the runtime...
Definition: IRuntime.hpp:55
int RunCLTuning(const std::string &tuningPath, const int tuningLevel, const std::string &modelFormat, const std::string &inputTensorShapes, const vector< armnn::BackendId > &computeDevices, const std::string &dynamicBackendsPath, const std::string &modelPath, const std::string &inputNames, const std::string &inputTensorDataFilePaths, const std::string &inputTypes, bool quantizeInput, const std::string &outputTypes, const std::string &outputNames, const std::string &outputTensorFiles, bool dequantizeOutput, bool enableProfiling, bool enableFp16TurboMode, bool enableBf16TurboMode, const double &thresholdTime, bool printIntermediate, const size_t subgraphId, bool enableLayerDetails=false, bool parseUnsupported=false)
static std::vector< CsvRow > ParseFile(const std::string &csvFile)
Definition: CsvReader.cpp:32
armnn::Runtime::CreationOptions::ExternalProfilingOptions options
ExternalProfilingOptions m_ProfilingOptions
Definition: IRuntime.hpp:83
LogSeverity
Definition: Utils.hpp:12