ArmNN
 21.08
ExecuteNetworkParams.cpp
Go to the documentation of this file.
1 //
2 // Copyright © 2020 Arm Ltd and Contributors. All rights reserved.
3 // SPDX-License-Identifier: MIT
4 //
5 
7 
9 #include <InferenceModel.hpp>
10 #include <armnn/Logging.hpp>
11 
12 #include <fmt/format.h>
13 
14 bool IsModelBinary(const std::string& modelFormat)
15 {
16  // Parse model binary flag from the model-format string we got from the command-line
17  if (modelFormat.find("binary") != std::string::npos)
18  {
19  return true;
20  }
21  else if (modelFormat.find("txt") != std::string::npos || modelFormat.find("text") != std::string::npos)
22  {
23  return false;
24  }
25  else
26  {
27  throw armnn::InvalidArgumentException(fmt::format("Unknown model format: '{}'. "
28  "Please include 'binary' or 'text'",
29  modelFormat));
30  }
31 }
32 
33 void CheckModelFormat(const std::string& modelFormat)
34 {
35  // Forward to implementation based on the parser type
36  if (modelFormat.find("armnn") != std::string::npos)
37  {
38 #if defined(ARMNN_SERIALIZER)
39 #else
40  throw armnn::InvalidArgumentException("Can't run model in armnn format without a "
41  "built with serialization support.");
42 #endif
43  }
44  else if (modelFormat.find("onnx") != std::string::npos)
45  {
46 #if defined(ARMNN_ONNX_PARSER)
47 #else
48  throw armnn::InvalidArgumentException("Can't run model in onnx format without a "
49  "built with Onnx parser support.");
50 #endif
51  }
52  else if (modelFormat.find("tflite") != std::string::npos)
53  {
54 #if defined(ARMNN_TF_LITE_PARSER)
55  if (!IsModelBinary(modelFormat))
56  {
57  throw armnn::InvalidArgumentException(fmt::format("Unknown model format: '{}'. Only 'binary' "
58  "format supported for tflite files",
59  modelFormat));
60  }
61 #elif defined(ARMNN_TFLITE_DELEGATE)
62 #else
63  throw armnn::InvalidArgumentException("Can't run model in tflite format without a "
64  "built with Tensorflow Lite parser support.");
65 #endif
66  }
67  else
68  {
69  throw armnn::InvalidArgumentException(fmt::format("Unknown model format: '{}'. "
70  "Please include 'tflite' or 'onnx'",
71  modelFormat));
72  }
73 }
74 
75 void CheckClTuningParameter(const int& tuningLevel,
76  const std::string& tuningPath,
77  const std::vector<armnn::BackendId> computeDevices)
78 {
79  if (!tuningPath.empty())
80  {
81  if (tuningLevel == 0)
82  {
83  ARMNN_LOG(info) << "Using cl tuning file: " << tuningPath << "\n";
84  if (!ValidatePath(tuningPath, true))
85  {
86  throw armnn::InvalidArgumentException("The tuning path is not valid");
87  }
88  }
89  else if ((1 <= tuningLevel) && (tuningLevel <= 3))
90  {
91  ARMNN_LOG(info) << "Starting execution to generate a cl tuning file: " << tuningPath << "\n"
92  << "Tuning level in use: " << tuningLevel << "\n";
93  }
94  else if ((0 < tuningLevel) || (tuningLevel > 3))
95  {
96  throw armnn::InvalidArgumentException(fmt::format("The tuning level {} is not valid.",
97  tuningLevel));
98  }
99 
100  // Ensure that a GpuAcc is enabled. Otherwise no tuning data are used or genereted
101  // Only warn if it's not enabled
102  auto it = std::find(computeDevices.begin(), computeDevices.end(), "GpuAcc");
103  if (it == computeDevices.end())
104  {
105  ARMNN_LOG(warning) << "To use Cl Tuning the compute device GpuAcc needs to be active.";
106  }
107  }
108 
109 }
110 
112 {
113  if (m_DynamicBackendsPath == "")
114  {
115  // Check compute devices are valid unless they are dynamically loaded at runtime
116  std::string invalidBackends;
117  if (!CheckRequestedBackendsAreValid(m_ComputeDevices, armnn::Optional<std::string&>(invalidBackends)))
118  {
119  ARMNN_LOG(fatal) << "The list of preferred devices contains invalid backend IDs: "
120  << invalidBackends;
121  }
122  }
123 
125 
127  {
128  throw armnn::InvalidArgumentException("BFloat16 and Float16 turbo mode cannot be "
129  "enabled at the same time.");
130  }
131 
133 
135 
136  // Check input tensor shapes
137  if ((m_InputTensorShapes.size() != 0) &&
138  (m_InputTensorShapes.size() != m_InputNames.size()))
139  {
140  throw armnn::InvalidArgumentException("input-name and input-tensor-shape must have "
141  "the same amount of elements. ");
142  }
143 
144  if (m_InputTensorDataFilePaths.size() != 0)
145  {
147  {
148  throw armnn::InvalidArgumentException("One or more input data file paths are not valid.");
149  }
150 
151  if (m_InputTensorDataFilePaths.size() < m_InputNames.size())
152  {
154  fmt::format("According to the number of input names the user provided the network has {} "
155  "inputs. But only {} input-tensor-data file paths were provided. Each input of the "
156  "model is expected to be stored in it's own file.",
157  m_InputNames.size(),
159  }
160  else if (m_InputTensorDataFilePaths.size() % m_InputNames.size() != 0)
161  {
163  fmt::format("According to the number of input names the user provided the network has {} "
164  "inputs. The user specified {} input-tensor-data file paths which is not "
165  "divisible by the number of inputs.",
166  m_InputNames.size(),
168  }
169  }
170 
171  if (m_InputTypes.size() == 0)
172  {
173  //Defaults the value of all inputs to "float"
174  m_InputTypes.assign(m_InputNames.size(), "float");
175  }
176  else if ((m_InputTypes.size() != 0) &&
177  (m_InputTypes.size() != m_InputNames.size()))
178  {
179  throw armnn::InvalidArgumentException("input-name and input-type must have the same amount of elements.");
180  }
181 
182  // Make sure that the number of input files given is divisible by the number of inputs of the model
183  if (!(m_InputTensorDataFilePaths.size() % m_InputNames.size() == 0))
184  {
186  fmt::format("The number of input-tensor-data files ({0}) is not divisible by the "
187  "number of inputs ({1} according to the number of input names).",
189  m_InputNames.size()));
190  }
191 
192  if (m_OutputTypes.size() == 0)
193  {
194  //Defaults the value of all outputs to "float"
195  m_OutputTypes.assign(m_OutputNames.size(), "float");
196  }
197  else if ((m_OutputTypes.size() != 0) &&
198  (m_OutputTypes.size() != m_OutputNames.size()))
199  {
200  throw armnn::InvalidArgumentException("output-name and output-type must have the same amount of elements.");
201  }
202 
203  // Make sure that the number of output files given is equal to the number of outputs of the model
204  // or equal to the number of outputs of the model multiplied with the number of iterations
205  if (!m_OutputTensorFiles.empty())
206  {
207  if ((m_OutputTensorFiles.size() != m_OutputNames.size()) &&
208  (m_OutputTensorFiles.size() != m_OutputNames.size() * m_Iterations))
209  {
210  std::stringstream errmsg;
211  auto numOutputs = m_OutputNames.size();
213  fmt::format("The user provided {0} output-tensor files. The only allowed number of output-tensor "
214  "files is the number of outputs of the network ({1} according to the number of "
215  "output names) or the number of outputs multiplied with the number of times the "
216  "network should be executed (NumOutputs * NumIterations = {1} * {2} = {3}).",
217  m_OutputTensorFiles.size(),
218  numOutputs,
219  m_Iterations,
220  numOutputs*m_Iterations));
221  }
222  }
223 
224  // Check that threshold time is not less than zero
225  if (m_ThresholdTime < 0)
226  {
227  throw armnn::InvalidArgumentException("Threshold time supplied as a command line argument is less than zero.");
228  }
229 
230  // Warn if ExecuteNetwork will generate dummy input data
232  {
233  ARMNN_LOG(warning) << "No input files provided, input tensors will be filled with 0s.";
234  }
235 }
std::vector< std::string > m_InputTypes
std::vector< TensorShapePtr > m_InputTensorShapes
#define ARMNN_LOG(severity)
Definition: Logging.hpp:202
std::vector< std::string > m_OutputNames
std::vector< std::string > m_OutputTensorFiles
void CheckClTuningParameter(const int &tuningLevel, const std::string &tuningPath, const std::vector< armnn::BackendId > computeDevices)
std::vector< armnn::BackendId > m_ComputeDevices
std::vector< std::string > m_OutputTypes
std::vector< std::string > m_InputNames
void CheckModelFormat(const std::string &modelFormat)
bool ValidatePaths(const std::vector< std::string > &fileVec, const bool expectFile)
Verifies if a given vector of strings are valid paths.
std::vector< std::string > m_InputTensorDataFilePaths
bool IsModelBinary(const std::string &modelFormat)
bool ValidatePath(const std::string &file, const bool expectFile)
Verifies if the given string is a valid path.