ArmNN
 20.05
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, 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)
 
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)
 

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 381 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_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().

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

Definition at line 875 of file NetworkExecutionUtils.hpp.

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

Referenced by main().

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

Definition at line 748 of file NetworkExecutionUtils.hpp.

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

Referenced by main().

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

Definition at line 532 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_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().

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