ArmNN
 20.08
NetworkExecutionUtils.hpp File Reference
#include <armnn/ArmNN.hpp>
#include <armnn/TypesUtils.hpp>
#include <armnn/utility/Timer.hpp>
#include "CsvReader.hpp"
#include "../InferenceTest.hpp"
#include <Profiling.hpp>
#include <ResolveType.hpp>
#include <boost/program_options.hpp>
#include <boost/variant.hpp>
#include <iostream>
#include <fstream>
#include <functional>
#include <future>
#include <algorithm>
#include <iterator>

Go to the source code of this file.

Classes

struct  ExecuteNetworkParams
 

Functions

template<typename TParser , typename TDataType >
int MainImpl (const ExecuteNetworkParams &params, const std::shared_ptr< armnn::IRuntime > &runtime=nullptr, size_t iterations=1)
 
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, bool inferOutputShape=false, const size_t iterations=1, const std::shared_ptr< armnn::IRuntime > &runtime=nullptr)
 
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, bool inferOutputShape=false)
 
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, bool inferOutputShape=false)
 

Variables

bool generateTensorData = true
 

Function Documentation

◆ MainImpl()

int MainImpl ( const ExecuteNetworkParams params,
const std::shared_ptr< armnn::IRuntime > &  runtime = nullptr,
size_t  iterations = 1 
)

Definition at line 382 of file NetworkExecutionUtils.hpp.

References ARMNN_LOG, InferenceModel< IParser, TDataType >::GetInputQuantizationParams(), InferenceModel< IParser, TDataType >::GetInputSize(), InferenceModel< IParser, TDataType >::GetOutputBindingInfos(), InferenceModel< IParser, TDataType >::GetOutputSize(), Params::m_ComputeDevices, ExecuteNetworkParams::m_ComputeDevices, ExecuteNetworkParams::m_DequantizeOutput, Params::m_DynamicBackendsPath, ExecuteNetworkParams::m_DynamicBackendsPath, Params::m_EnableBf16TurboMode, ExecuteNetworkParams::m_EnableBf16TurboMode, Params::m_EnableFp16TurboMode, ExecuteNetworkParams::m_EnableFp16TurboMode, ExecuteNetworkParams::m_EnableLayerDetails, ExecuteNetworkParams::m_EnableProfiling, ExecuteNetworkParams::m_GenerateTensorData, Params::m_InferOutputShape, ExecuteNetworkParams::m_InferOutputShape, Params::m_InputBindings, ExecuteNetworkParams::m_InputNames, Params::m_InputShapes, ExecuteNetworkParams::m_InputTensorDataFilePaths, ExecuteNetworkParams::m_InputTensorShapes, ExecuteNetworkParams::m_InputTypes, Params::m_IsModelBinary, ExecuteNetworkParams::m_IsModelBinary, Params::m_ModelPath, ExecuteNetworkParams::m_ModelPath, Params::m_OutputBindings, ExecuteNetworkParams::m_OutputNames, ExecuteNetworkParams::m_OutputTensorFiles, ExecuteNetworkParams::m_OutputTypes, Params::m_ParseUnsupported, ExecuteNetworkParams::m_ParseUnsupported, ExecuteNetworkParams::m_PrintIntermediate, Params::m_PrintIntermediateLayers, ExecuteNetworkParams::m_QuantizeInput, Params::m_SubgraphId, ExecuteNetworkParams::m_SubgraphId, ExecuteNetworkParams::m_ThresholdTime, Params::m_VisualizePostOptimizationModel, InferenceModel< IParser, TDataType >::Run(), and Exception::what().

385 {
386  using TContainer = boost::variant<std::vector<float>, std::vector<int>, std::vector<unsigned char>>;
387 
388  std::vector<TContainer> inputDataContainers;
389 
390  try
391  {
392  // Creates an InferenceModel, which will parse the model and load it into an IRuntime.
393  typename InferenceModel<TParser, TDataType>::Params inferenceModelParams;
394  inferenceModelParams.m_ModelPath = params.m_ModelPath;
395  inferenceModelParams.m_IsModelBinary = params.m_IsModelBinary;
396  inferenceModelParams.m_ComputeDevices = params.m_ComputeDevices;
397  inferenceModelParams.m_DynamicBackendsPath = params.m_DynamicBackendsPath;
398  inferenceModelParams.m_PrintIntermediateLayers = params.m_PrintIntermediate;
399  inferenceModelParams.m_VisualizePostOptimizationModel = params.m_EnableLayerDetails;
400  inferenceModelParams.m_ParseUnsupported = params.m_ParseUnsupported;
401  inferenceModelParams.m_InferOutputShape = params.m_InferOutputShape;
402 
403  for(const std::string& inputName: params.m_InputNames)
404  {
405  inferenceModelParams.m_InputBindings.push_back(inputName);
406  }
407 
408  for(unsigned int i = 0; i < params.m_InputTensorShapes.size(); ++i)
409  {
410  inferenceModelParams.m_InputShapes.push_back(*params.m_InputTensorShapes[i]);
411  }
412 
413  for(const std::string& outputName: params.m_OutputNames)
414  {
415  inferenceModelParams.m_OutputBindings.push_back(outputName);
416  }
417 
418  inferenceModelParams.m_SubgraphId = params.m_SubgraphId;
419  inferenceModelParams.m_EnableFp16TurboMode = params.m_EnableFp16TurboMode;
420  inferenceModelParams.m_EnableBf16TurboMode = params.m_EnableBf16TurboMode;
421 
422  InferenceModel<TParser, TDataType> model(inferenceModelParams,
423  params.m_EnableProfiling,
424  params.m_DynamicBackendsPath,
425  runtime);
426 
427  const size_t numInputs = inferenceModelParams.m_InputBindings.size();
428  for(unsigned int i = 0; i < numInputs; ++i)
429  {
431  armnn::MakeOptional<QuantizationParams>(model.GetInputQuantizationParams()) :
433 
436  armnn::MakeOptional<std::string>(params.m_InputTensorDataFilePaths[i]);
437 
438  unsigned int numElements = model.GetInputSize(i);
439  if (params.m_InputTensorShapes.size() > i && params.m_InputTensorShapes[i])
440  {
441  // If the user has provided a tensor shape for the current input,
442  // override numElements
443  numElements = params.m_InputTensorShapes[i]->GetNumElements();
444  }
445 
446  TContainer tensorData;
447  PopulateTensorWithData(tensorData,
448  numElements,
449  params.m_InputTypes[i],
450  qParams,
451  dataFile);
452 
453  inputDataContainers.push_back(tensorData);
454  }
455 
456  const size_t numOutputs = inferenceModelParams.m_OutputBindings.size();
457  std::vector<TContainer> outputDataContainers;
458 
459  for (unsigned int i = 0; i < numOutputs; ++i)
460  {
461  if (params.m_OutputTypes[i].compare("float") == 0)
462  {
463  outputDataContainers.push_back(std::vector<float>(model.GetOutputSize(i)));
464  }
465  else if (params.m_OutputTypes[i].compare("int") == 0)
466  {
467  outputDataContainers.push_back(std::vector<int>(model.GetOutputSize(i)));
468  }
469  else if (params.m_OutputTypes[i].compare("qasymm8") == 0)
470  {
471  outputDataContainers.push_back(std::vector<uint8_t>(model.GetOutputSize(i)));
472  }
473  else
474  {
475  ARMNN_LOG(fatal) << "Unsupported tensor data type \"" << params.m_OutputTypes[i] << "\". ";
476  return EXIT_FAILURE;
477  }
478  }
479 
480  for (size_t x = 0; x < iterations; x++)
481  {
482  // model.Run returns the inference time elapsed in EnqueueWorkload (in milliseconds)
483  auto inference_duration = model.Run(inputDataContainers, outputDataContainers);
484 
485  if (params.m_GenerateTensorData)
486  {
487  ARMNN_LOG(warning) << "The input data was generated, note that the output will not be useful";
488  }
489 
490  // Print output tensors
491  const auto& infosOut = model.GetOutputBindingInfos();
492  for (size_t i = 0; i < numOutputs; i++)
493  {
494  const armnn::TensorInfo& infoOut = infosOut[i].second;
495  auto outputTensorFile = params.m_OutputTensorFiles.empty() ? "" : params.m_OutputTensorFiles[i];
496 
497  TensorPrinter printer(inferenceModelParams.m_OutputBindings[i],
498  infoOut,
499  outputTensorFile,
500  params.m_DequantizeOutput);
501  boost::apply_visitor(printer, outputDataContainers[i]);
502  }
503 
504  ARMNN_LOG(info) << "\nInference time: " << std::setprecision(2)
505  << std::fixed << inference_duration.count() << " ms\n";
506 
507  // If thresholdTime == 0.0 (default), then it hasn't been supplied at command line
508  if (params.m_ThresholdTime != 0.0)
509  {
510  ARMNN_LOG(info) << "Threshold time: " << std::setprecision(2)
511  << std::fixed << params.m_ThresholdTime << " ms";
512  auto thresholdMinusInference = params.m_ThresholdTime - inference_duration.count();
513  ARMNN_LOG(info) << "Threshold time - Inference time: " << std::setprecision(2)
514  << std::fixed << thresholdMinusInference << " ms" << "\n";
515 
516  if (thresholdMinusInference < 0)
517  {
518  std::string errorMessage = "Elapsed inference time is greater than provided threshold time.";
519  ARMNN_LOG(fatal) << errorMessage;
520  }
521  }
522  }
523  }
524  catch (const armnn::Exception& e)
525  {
526  ARMNN_LOG(fatal) << "Armnn Error: " << e.what();
527  return EXIT_FAILURE;
528  }
529 
530  return EXIT_SUCCESS;
531 }
std::vector< string > m_OutputTypes
std::vector< string > m_OutputTensorFiles
std::vector< TensorShapePtr > m_InputTensorShapes
virtual const char * what() const noexcept override
Definition: Exceptions.cpp:32
#define ARMNN_LOG(severity)
Definition: Logging.hpp:163
Copyright (c) 2020 ARM Limited.
boost::variant< std::vector< float >, std::vector< int >, std::vector< unsigned char > > TContainer
std::vector< std::string > m_InputBindings
std::vector< armnn::BackendId > m_ComputeDevices
std::vector< string > m_InputNames
std::vector< armnn::TensorShape > m_InputShapes
std::vector< std::string > m_OutputBindings
std::vector< armnn::BackendId > m_ComputeDevices
std::vector< string > m_OutputNames
EmptyOptional is used to initialize the Optional class in case we want to have default value for an O...
Definition: Optional.hpp:32
Base class for all ArmNN exceptions so that users can filter to just those.
Definition: Exceptions.hpp:46
std::vector< string > m_InputTypes
Optional< T > MakeOptional(Args &&... args)
Utility template that constructs an object of type T in-place and wraps it inside an Optional<T> obje...
Definition: Optional.hpp:305

◆ RunCLTuning()

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,
bool  inferOutputShape = false 
)

Definition at line 881 of file NetworkExecutionUtils.hpp.

References ARMNN_LOG, IRuntime::Create(), armnn::GetTimeDuration(), armnn::GetTimeNow(), IRuntime::CreationOptions::m_BackendOptions, and RunTest().

Referenced by main().

905 {
907  options.m_BackendOptions.emplace_back(
909  {
910  "GpuAcc",
911  {
912  {"TuningLevel", tuningLevel},
913  {"TuningFile", tuningPath.c_str()},
914  {"KernelProfilingEnabled", enableProfiling}
915  }
916  }
917  );
918 
919  std::shared_ptr<armnn::IRuntime> runtime(armnn::IRuntime::Create(options));
920  const auto start_time = armnn::GetTimeNow();
921 
922  ARMNN_LOG(info) << "Tuning run...\n";
923  int state = RunTest(modelFormat, inputTensorShapes, computeDevices, dynamicBackendsPath, modelPath, inputNames,
924  inputTensorDataFilePaths, inputTypes, quantizeInput, outputTypes, outputNames,
925  outputTensorFiles, dequantizeOutput, enableProfiling, enableFp16TurboMode, enableBf16TurboMode,
926  thresholdTime, printIntermediate, subgraphId, enableLayerDetails, parseUnsupported,
927  inferOutputShape, 1, runtime);
928 
929  ARMNN_LOG(info) << "Tuning time: " << std::setprecision(2)
930  << std::fixed << armnn::GetTimeDuration(start_time).count() << " ms\n";
931 
932  return state;
933 }
static IRuntimePtr Create(const CreationOptions &options)
Definition: Runtime.cpp:32
std::chrono::duration< double, std::milli > GetTimeDuration(std::chrono::high_resolution_clock::time_point start_time)
Definition: Timer.hpp:19
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, bool inferOutputShape=false, const size_t iterations=1, const std::shared_ptr< armnn::IRuntime > &runtime=nullptr)
#define ARMNN_LOG(severity)
Definition: Logging.hpp:163
std::chrono::high_resolution_clock::time_point GetTimeNow()
Definition: Timer.hpp:14
std::vector< BackendOptions > m_BackendOptions
Pass backend specific options.
Definition: IRuntime.hpp:115
Struct for the users to pass backend specific options.

◆ RunCsvTest()

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,
bool  inferOutputShape = false 
)

Definition at line 753 of file NetworkExecutionUtils.hpp.

References ARMNN_ASSERT_MSG, ARMNN_LOG, armnn::BackendRegistryInstance(), BackendRegistry::GetBackendIdsAsString(), armnn::IgnoreUnused(), RunTest(), and CsvRow::values.

Referenced by main().

757 {
758  IgnoreUnused(runtime);
759  std::string modelFormat;
760  std::string modelPath;
761  std::string inputNames;
762  std::string inputTensorShapes;
763  std::string inputTensorDataFilePaths;
764  std::string outputNames;
765  std::string inputTypes;
766  std::string outputTypes;
767  std::string dynamicBackendsPath;
768  std::string outputTensorFiles;
769 
770  size_t subgraphId = 0;
771 
772  const std::string backendsMessage = std::string("The preferred order of devices to run layers on by default. ")
773  + std::string("Possible choices: ")
775 
776  po::options_description desc("Options");
777  try
778  {
779  desc.add_options()
780  ("model-format,f", po::value(&modelFormat),
781  "armnn-binary, caffe-binary, caffe-text, tflite-binary, onnx-binary, onnx-text, tensorflow-binary or "
782  "tensorflow-text.")
783  ("model-path,m", po::value(&modelPath), "Path to model file, e.g. .armnn, .caffemodel, .prototxt, "
784  ".tflite, .onnx")
785  ("compute,c", po::value<std::vector<armnn::BackendId>>()->multitoken(),
786  backendsMessage.c_str())
787  ("dynamic-backends-path,b", po::value(&dynamicBackendsPath),
788  "Path where to load any available dynamic backend from. "
789  "If left empty (the default), dynamic backends will not be used.")
790  ("input-name,i", po::value(&inputNames), "Identifier of the input tensors in the network separated by comma.")
791  ("subgraph-number,n", po::value<size_t>(&subgraphId)->default_value(0), "Id of the subgraph to be "
792  "executed. Defaults to 0.")
793  ("input-tensor-shape,s", po::value(&inputTensorShapes),
794  "The shape of the input tensors in the network as a flat array of integers separated by comma. "
795  "Several shapes can be passed separating them by semicolon. "
796  "This parameter is optional, depending on the network.")
797  ("input-tensor-data,d", po::value(&inputTensorDataFilePaths)->default_value(""),
798  "Path to files containing the input data as a flat array separated by whitespace. "
799  "Several paths can be passed separating them by comma. If not specified, the network will be run with dummy "
800  "data (useful for profiling).")
801  ("input-type,y",po::value(&inputTypes), "The type of the input tensors in the network separated by comma. "
802  "If unset, defaults to \"float\" for all defined inputs. "
803  "Accepted values (float, int or qasymm8).")
804  ("quantize-input,q",po::bool_switch()->default_value(false),
805  "If this option is enabled, all float inputs will be quantized to qasymm8. "
806  "If unset, default to not quantized. "
807  "Accepted values (true or false)")
808  ("output-type,z",po::value(&outputTypes), "The type of the output tensors in the network separated by comma. "
809  "If unset, defaults to \"float\" for all defined outputs. "
810  "Accepted values (float, int or qasymm8).")
811  ("output-name,o", po::value(&outputNames),
812  "Identifier of the output tensors in the network separated by comma.")
813  ("dequantize-output,l",po::bool_switch()->default_value(false),
814  "If this option is enabled, all quantized outputs will be dequantized to float. "
815  "If unset, default to not get dequantized. "
816  "Accepted values (true or false)")
817  ("write-outputs-to-file,w", po::value(&outputTensorFiles),
818  "Comma-separated list of output file paths keyed with the binding-id of the output slot. "
819  "If left empty (the default), the output tensors will not be written to a file.");
820  }
821  catch (const std::exception& e)
822  {
823  // Coverity points out that default_value(...) can throw a bad_lexical_cast,
824  // and that desc.add_options() can throw boost::io::too_few_args.
825  // They really won't in any of these cases.
826  ARMNN_ASSERT_MSG(false, "Caught unexpected exception");
827  ARMNN_LOG(fatal) << "Fatal internal error: " << e.what();
828  return EXIT_FAILURE;
829  }
830 
831  std::vector<const char*> clOptions;
832  clOptions.reserve(csvRow.values.size());
833  for (const std::string& value : csvRow.values)
834  {
835  clOptions.push_back(value.c_str());
836  }
837 
838  po::variables_map vm;
839  try
840  {
841  po::store(po::parse_command_line(static_cast<int>(clOptions.size()), clOptions.data(), desc), vm);
842 
843  po::notify(vm);
844 
845  CheckOptionDependencies(vm);
846  }
847  catch (const po::error& e)
848  {
849  std::cerr << e.what() << std::endl << std::endl;
850  std::cerr << desc << std::endl;
851  return EXIT_FAILURE;
852  }
853 
854  // Get the value of the switch arguments.
855  bool quantizeInput = vm["quantize-input"].as<bool>();
856  bool dequantizeOutput = vm["dequantize-output"].as<bool>();
857 
858  // Get the preferred order of compute devices.
859  std::vector<armnn::BackendId> computeDevices = vm["compute"].as<std::vector<armnn::BackendId>>();
860 
861  // Remove duplicates from the list of compute devices.
862  RemoveDuplicateDevices(computeDevices);
863 
864  // Check that the specified compute devices are valid.
865  std::string invalidBackends;
866  if (!CheckRequestedBackendsAreValid(computeDevices, armnn::Optional<std::string&>(invalidBackends)))
867  {
868  ARMNN_LOG(fatal) << "The list of preferred devices contains invalid backend IDs: "
869  << invalidBackends;
870  return EXIT_FAILURE;
871  }
872 
873  return RunTest(modelFormat, inputTensorShapes, computeDevices, dynamicBackendsPath, modelPath, inputNames,
874  inputTensorDataFilePaths, inputTypes, quantizeInput, outputTypes, outputNames, outputTensorFiles,
875  dequantizeOutput, enableProfiling, enableFp16TurboMode, enableBf16TurboMode,
876  thresholdTime, printIntermediate, subgraphId, enableLayerDetails, parseUnuspported,
877  inferOutputShape);
878 }
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, bool inferOutputShape=false, const size_t iterations=1, const std::shared_ptr< armnn::IRuntime > &runtime=nullptr)
std::vector< std::string > values
Definition: CsvReader.hpp:15
#define ARMNN_LOG(severity)
Definition: Logging.hpp:163
BackendRegistry & BackendRegistryInstance()
void IgnoreUnused(Ts &&...)
std::string GetBackendIdsAsString() const
#define ARMNN_ASSERT_MSG(COND, MSG)
Definition: Assert.hpp:15

◆ RunTest()

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,
bool  inferOutputShape = false,
const size_t  iterations = 1,
const std::shared_ptr< armnn::IRuntime > &  runtime = nullptr 
)

Definition at line 534 of file NetworkExecutionUtils.hpp.

References ARMNN_LOG, ExecuteNetworkParams::m_ComputeDevices, ExecuteNetworkParams::m_DequantizeOutput, ExecuteNetworkParams::m_DynamicBackendsPath, ExecuteNetworkParams::m_EnableBf16TurboMode, ExecuteNetworkParams::m_EnableFp16TurboMode, ExecuteNetworkParams::m_EnableLayerDetails, ExecuteNetworkParams::m_EnableProfiling, ExecuteNetworkParams::m_GenerateTensorData, ExecuteNetworkParams::m_InferOutputShape, ExecuteNetworkParams::m_InputNames, ExecuteNetworkParams::m_InputTensorDataFilePaths, ExecuteNetworkParams::m_InputTensorShapes, ExecuteNetworkParams::m_InputTypes, ExecuteNetworkParams::m_IsModelBinary, ExecuteNetworkParams::m_ModelPath, ExecuteNetworkParams::m_OutputNames, ExecuteNetworkParams::m_OutputTensorFiles, ExecuteNetworkParams::m_OutputTypes, ExecuteNetworkParams::m_ParseUnsupported, ExecuteNetworkParams::m_PrintIntermediate, ExecuteNetworkParams::m_QuantizeInput, ExecuteNetworkParams::m_SubgraphId, ExecuteNetworkParams::m_ThresholdTime, armnn::stringUtils::StringTrimCopy(), and Exception::what().

Referenced by BOOST_FIXTURE_TEST_CASE(), main(), RunCLTuning(), and RunCsvTest().

558 {
559  std::string modelFormat = armnn::stringUtils::StringTrimCopy(format);
560  std::string modelPath = armnn::stringUtils::StringTrimCopy(path);
561  std::vector<std::string> inputNamesVector = ParseStringList(inputNames, ",");
562  std::vector<std::string> inputTensorShapesVector = ParseStringList(inputTensorShapesStr, ":");
563  std::vector<std::string> inputTensorDataFilePathsVector = ParseStringList(
564  inputTensorDataFilePaths, ",");
565  std::vector<std::string> outputNamesVector = ParseStringList(outputNames, ",");
566  std::vector<std::string> inputTypesVector = ParseStringList(inputTypes, ",");
567  std::vector<std::string> outputTypesVector = ParseStringList(outputTypes, ",");
568  std::vector<std::string> outputTensorFilesVector = ParseStringList(outputTensorFiles, ",");
569 
570  // Parse model binary flag from the model-format string we got from the command-line
571  bool isModelBinary;
572  if (modelFormat.find("bin") != std::string::npos)
573  {
574  isModelBinary = true;
575  }
576  else if (modelFormat.find("txt") != std::string::npos || modelFormat.find("text") != std::string::npos)
577  {
578  isModelBinary = false;
579  }
580  else
581  {
582  ARMNN_LOG(fatal) << "Unknown model format: '" << modelFormat << "'. Please include 'binary' or 'text'";
583  return EXIT_FAILURE;
584  }
585 
586  if ((inputTensorShapesVector.size() != 0) && (inputTensorShapesVector.size() != inputNamesVector.size()))
587  {
588  ARMNN_LOG(fatal) << "input-name and input-tensor-shape must have the same amount of elements.";
589  return EXIT_FAILURE;
590  }
591 
592  if ((inputTensorDataFilePathsVector.size() != 0) &&
593  (inputTensorDataFilePathsVector.size() != inputNamesVector.size()))
594  {
595  ARMNN_LOG(fatal) << "input-name and input-tensor-data must have the same amount of elements.";
596  return EXIT_FAILURE;
597  }
598 
599  if ((outputTensorFilesVector.size() != 0) &&
600  (outputTensorFilesVector.size() != outputNamesVector.size()))
601  {
602  ARMNN_LOG(fatal) << "output-name and write-outputs-to-file must have the same amount of elements.";
603  return EXIT_FAILURE;
604  }
605 
606  if (inputTypesVector.size() == 0)
607  {
608  //Defaults the value of all inputs to "float"
609  inputTypesVector.assign(inputNamesVector.size(), "float");
610  }
611  else if ((inputTypesVector.size() != 0) && (inputTypesVector.size() != inputNamesVector.size()))
612  {
613  ARMNN_LOG(fatal) << "input-name and input-type must have the same amount of elements.";
614  return EXIT_FAILURE;
615  }
616 
617  if (outputTypesVector.size() == 0)
618  {
619  //Defaults the value of all outputs to "float"
620  outputTypesVector.assign(outputNamesVector.size(), "float");
621  }
622  else if ((outputTypesVector.size() != 0) && (outputTypesVector.size() != outputNamesVector.size()))
623  {
624  ARMNN_LOG(fatal) << "output-name and output-type must have the same amount of elements.";
625  return EXIT_FAILURE;
626  }
627 
628  // Parse input tensor shape from the string we got from the command-line.
629  std::vector<std::unique_ptr<armnn::TensorShape>> inputTensorShapes;
630 
631  if (!inputTensorShapesVector.empty())
632  {
633  inputTensorShapes.reserve(inputTensorShapesVector.size());
634 
635  for(const std::string& shape : inputTensorShapesVector)
636  {
637  std::stringstream ss(shape);
638  std::vector<unsigned int> dims = ParseArray(ss);
639 
640  try
641  {
642  // Coverity fix: An exception of type armnn::InvalidArgumentException is thrown and never caught.
643  inputTensorShapes.push_back(
644  std::make_unique<armnn::TensorShape>(static_cast<unsigned int>(dims.size()), dims.data()));
645  }
646  catch (const armnn::InvalidArgumentException& e)
647  {
648  ARMNN_LOG(fatal) << "Cannot create tensor shape: " << e.what();
649  return EXIT_FAILURE;
650  }
651  }
652  }
653 
654  // Check that threshold time is not less than zero
655  if (thresholdTime < 0)
656  {
657  ARMNN_LOG(fatal) << "Threshold time supplied as a command line argument is less than zero.";
658  return EXIT_FAILURE;
659  }
660 
661  ExecuteNetworkParams params;
662  params.m_ModelPath = modelPath.c_str();
663  params.m_IsModelBinary = isModelBinary;
664  params.m_ComputeDevices = computeDevices;
665  params.m_DynamicBackendsPath = dynamicBackendsPath;
666  params.m_InputNames = inputNamesVector;
667  params.m_InputTensorShapes = std::move(inputTensorShapes);
668  params.m_InputTensorDataFilePaths = inputTensorDataFilePathsVector;
669  params.m_InputTypes = inputTypesVector;
670  params.m_QuantizeInput = quantizeInput;
671  params.m_OutputTypes = outputTypesVector;
672  params.m_OutputNames = outputNamesVector;
673  params.m_OutputTensorFiles = outputTensorFilesVector;
674  params.m_DequantizeOutput = dequantizeOuput;
675  params.m_EnableProfiling = enableProfiling;
676  params.m_EnableFp16TurboMode = enableFp16TurboMode;
677  params.m_EnableBf16TurboMode = enableBf16TurboMode;
678  params.m_ThresholdTime = thresholdTime;
679  params.m_PrintIntermediate = printIntermediate;
680  params.m_SubgraphId = subgraphId;
681  params.m_EnableLayerDetails = enableLayerDetails;
682  params.m_GenerateTensorData = inputTensorDataFilePathsVector.empty();
683  params.m_ParseUnsupported = parseUnsupported;
684  params.m_InferOutputShape = inferOutputShape;
685 
686  // Warn if ExecuteNetwork will generate dummy input data
687  if (params.m_GenerateTensorData)
688  {
689  ARMNN_LOG(warning) << "No input files provided, input tensors will be filled with 0s.";
690  }
691 
692  // Forward to implementation based on the parser type
693  if (modelFormat.find("armnn") != std::string::npos)
694  {
695 #if defined(ARMNN_SERIALIZER)
696  return MainImpl<armnnDeserializer::IDeserializer, float>(params, runtime, iterations);
697 #else
698  ARMNN_LOG(fatal) << "Not built with serialization support.";
699  return EXIT_FAILURE;
700 #endif
701  }
702  else if (modelFormat.find("caffe") != std::string::npos)
703  {
704 #if defined(ARMNN_CAFFE_PARSER)
705  return MainImpl<armnnCaffeParser::ICaffeParser, float>(params, runtime, iterations);
706 #else
707  ARMNN_LOG(fatal) << "Not built with Caffe parser support.";
708  return EXIT_FAILURE;
709 #endif
710  }
711  else if (modelFormat.find("onnx") != std::string::npos)
712  {
713 #if defined(ARMNN_ONNX_PARSER)
714  return MainImpl<armnnOnnxParser::IOnnxParser, float>(params, runtime, iterations);
715 #else
716  ARMNN_LOG(fatal) << "Not built with Onnx parser support.";
717  return EXIT_FAILURE;
718 #endif
719  }
720  else if (modelFormat.find("tensorflow") != std::string::npos)
721  {
722 #if defined(ARMNN_TF_PARSER)
723  return MainImpl<armnnTfParser::ITfParser, float>(params, runtime, iterations);
724 #else
725  ARMNN_LOG(fatal) << "Not built with Tensorflow parser support.";
726  return EXIT_FAILURE;
727 #endif
728  }
729  else if(modelFormat.find("tflite") != std::string::npos)
730  {
731 #if defined(ARMNN_TF_LITE_PARSER)
732  if (! isModelBinary)
733  {
734  ARMNN_LOG(fatal) << "Unknown model format: '" << modelFormat
735  << "'. Only 'binary' format supported for tflite files";
736  return EXIT_FAILURE;
737  }
738  return MainImpl<armnnTfLiteParser::ITfLiteParser, float>(params, runtime, iterations);
739 #else
740  ARMNN_LOG(fatal) << "Unknown model format: '" << modelFormat
741  << "'. Please include 'caffe', 'tensorflow', 'tflite' or 'onnx'";
742  return EXIT_FAILURE;
743 #endif
744  }
745  else
746  {
747  ARMNN_LOG(fatal) << "Unknown model format: '" << modelFormat
748  << "'. Please include 'caffe', 'tensorflow', 'tflite' or 'onnx'";
749  return EXIT_FAILURE;
750  }
751 }
std::vector< string > m_OutputTypes
std::vector< string > m_OutputTensorFiles
std::vector< TensorShapePtr > m_InputTensorShapes
virtual const char * what() const noexcept override
Definition: Exceptions.cpp:32
#define ARMNN_LOG(severity)
Definition: Logging.hpp:163
std::vector< armnn::BackendId > m_ComputeDevices
std::vector< string > m_InputNames
std::string StringTrimCopy(const std::string &str, const std::string &chars="\\\")
Trim from both the start and the end of a string, returns a trimmed copy of the string.
Definition: StringUtils.hpp:85
std::vector< string > m_OutputNames
std::vector< string > m_InputTensorDataFilePaths
std::vector< string > m_InputTypes

Variable Documentation

◆ generateTensorData

bool generateTensorData = true

Definition at line 350 of file NetworkExecutionUtils.hpp.