ArmNN
 24.11
WorkloadData.cpp
Go to the documentation of this file.
1 //
2 // Copyright © 2017-2024 Arm Ltd and Contributors. All rights reserved.
3 // SPDX-License-Identifier: MIT
4 //
5 
11 #include <armnnUtils/Permute.hpp>
13 #include <armnn/Logging.hpp>
14 
15 #include <algorithm>
16 #include <iomanip>
17 #include <string>
18 #include <sstream>
19 
20 #include <fmt/format.h>
21 
22 using namespace armnnUtils;
23 
24 namespace armnn
25 {
26 
27 //---------------------------------------------------------------
29 {
30  switch (inputDataType)
31  {
32  case DataType::Float16:
33  return DataType::Float16;
34  case DataType::BFloat16:
35  case DataType::Float32:
36  return DataType::Float32;
37  case DataType::QAsymmS8:
38  case DataType::QAsymmU8:
39  case DataType::QSymmS8:
40  case DataType::QSymmS16:
41  return DataType::Signed32;
42  default:
43  throw InvalidArgumentException("GetBiasDataType(): Unsupported data type.");
44  }
45 }
46 
47 namespace
48 {
49 
50 //---------------------------------------------------------------
51 //android ndk does not support std::to_string function.
52 template <typename T>
53 std::string to_string(T value)
54 {
55  std::ostringstream os;
56  os << value;
57  return os.str();
58 }
59 
60 //---------------------------------------------------------------
61 void ValidatePointer(const void* ptr, std::string const& descName, std::string const& paramName)
62 {
63  if (!ptr)
64  {
65  throw InvalidArgumentException(descName + ": Invalid null pointer. The " +
66  paramName + " parameter must be set.");
67  }
68 }
69 
70 //---------------------------------------------------------------
71 void ValidateTensorShapesMatch(const TensorInfo& first,
72  const TensorInfo& second,
73  std::string const& descName,
74  std::string const& firstName,
75  std::string const& secondName)
76 {
77  if (first.GetShape() != second.GetShape())
78  {
79  throw InvalidArgumentException(descName + ": "
80  + firstName + " & " + secondName + " must have identical shapes");
81  }
82 }
83 
84 //---------------------------------------------------------------
85 void ValidateNumInputs(const WorkloadInfo& workloadInfo, std::string const& descName, const unsigned int expectedSize)
86 {
87  if (workloadInfo.m_InputTensorInfos.size() != expectedSize)
88  {
89  throw InvalidArgumentException(descName +
90  ": Requires exactly " + to_string(expectedSize) + "input(s). " +
91  to_string(workloadInfo.m_InputTensorInfos.size()) + " have been provided.");
92  }
93 }
94 
95 //---------------------------------------------------------------
96 void ValidateNumOutputs(const WorkloadInfo& workloadInfo, std::string const& descName, const unsigned int expectedSize)
97 {
98  if (workloadInfo.m_OutputTensorInfos.size() != expectedSize)
99  {
100  throw InvalidArgumentException(descName +
101  ": Requires exactly " + to_string(expectedSize) + " output(s). " +
102  to_string(workloadInfo.m_OutputTensorInfos.size()) + " has been provided.");
103  }
104 }
105 
106 //---------------------------------------------------------------
107 
108 //---------------------------------------------------------------
109 void ValidateTensorNumElements(const TensorInfo& tensor,
110  std::string const& descName,
111  unsigned int numElements,
112  std::string const& tensorName)
113 {
114  if (tensor.GetNumElements() != numElements)
115  {
116  throw InvalidArgumentException(descName + ": Expected " + to_string(numElements) + " but got " +
117  to_string(tensor.GetNumElements()) + " elements for " +
118  tensorName + " tensor.");
119  }
120 }
121 
122 //---------------------------------------------------------------
123 void ValidateTensorDataType(const TensorInfo& tensor, DataType dataType,
124  const std::string& descName, std::string const& tensorName)
125 {
126  if (tensor.GetDataType() != dataType)
127  {
128  throw InvalidArgumentException(descName + ": Expected data type " + GetDataTypeName(dataType) + " but got " +
129  GetDataTypeName(tensor.GetDataType()) + " for " + tensorName + " tensor.");
130  }
131 }
132 
133 void ValidPerAxisQuantizedDataType(const TensorInfo& tensor, const std::string& descName, const std::string& tensorName)
134 {
135  if (tensor.GetDataType() != DataType::QSymmS8)
136  {
137  throw InvalidArgumentException(descName +
138  ": Expected data type which supports per-axis quantization scheme but got " +
139  GetDataTypeName(tensor.GetDataType()) + " for " + tensorName + " tensor.");
140  }
141 }
142 
143 //---------------------------------------------------------------
144 void ValidateTensorQuantizationSpace(const TensorInfo& first,
145  const TensorInfo& second,
146  const std::string& descName,
147  std::string const& firstName,
148  std::string const& secondName)
149 {
150  if (!first.IsQuantized() ||
151  !second.IsQuantized())
152  {
153  // Not a quantized type, ignore the validation
154  return;
155  }
156 
157  DataType firstDataType = first.GetDataType();
158  DataType secondDataType = second.GetDataType();
159 
160  if (firstDataType != secondDataType)
161  {
162  throw InvalidArgumentException(descName + ": " + firstName + " and " + secondName +
163  " must be of the same quantized type, " +
164  firstName + " is " + GetDataTypeName(firstDataType) + ", " +
165  secondName + " is " + GetDataTypeName(secondDataType));
166  }
167 
168  if (!first.IsTypeSpaceMatch(second))
169  {
170  throw InvalidArgumentException(descName + ": " + firstName + " and " + secondName +
171  " must have the same quantization space, " +
172  firstName + " has offset " + to_string(first.GetQuantizationOffset()) +
173  " and scale " + to_string(first.GetQuantizationScale()) + ", " +
174  secondName + " has offset " + to_string(second.GetQuantizationOffset()) +
175  " and scale " + to_string(second.GetQuantizationScale()));
176  }
177 }
178 
179 //---------------------------------------------------------------
180 void ValidateBiasTensorQuantization(const TensorInfo& biasTensor,
181  const TensorInfo& weightsTensorInfo,
182  const std::string& descName)
183 {
184  if (biasTensor.GetQuantizationOffset() != 0)
185  {
186  throw InvalidArgumentException(descName + ": Expected zero quantization offset for bias tensor but got " +
187  to_string(biasTensor.GetQuantizationOffset()));
188  }
189 
190  if (biasTensor.HasMultipleQuantizationScales() || weightsTensorInfo.HasMultipleQuantizationScales())
191  {
192  // Validate per-axis quantization scales
193  const std::vector<float>& weightScales = weightsTensorInfo.GetQuantizationScales();
194  const std::vector<float>& biasScales = biasTensor.GetQuantizationScales();
195 
196  if (weightScales.size() != biasScales.size())
197  {
198  std::stringstream msg;
199  msg << descName << ": Expected matching number of per-axis quantization scales for weights and bias, "
200  << "but got different values. This is currently unsupported: weights=" << weightScales.size()
201  << ", biases=" << biasScales.size();
202  throw InvalidArgumentException(msg.str(), CHECK_LOCATION());
203  }
204  }
205 }
206 
207 //---------------------------------------------------------------
208 void ValidateTensors(const std::vector<ITensorHandle*>& vec,
209  unsigned int numExpected,
210  const std::string& descName,
211  const std::string& varName)
212 {
213  if (vec.empty() && numExpected > 0)
214  {
215  throw InvalidArgumentException(descName + ": Invalid empty " + varName + " array.");
216  }
217 
218  for (unsigned int i = 0; i < numExpected; ++i)
219  {
220  if (!vec[i])
221  {
222  throw InvalidArgumentException(descName + ": Invalid NULL for " + varName + to_string(i));
223  }
224  }
225 }
226 
227 //---------------------------------------------------------------
228 void ValidateBroadcastTensorShapesMatch(const TensorInfo& first,
229  const TensorInfo& second,
230  const TensorInfo& output,
231  std::string const& descName,
232  std::string const& firstName,
233  std::string const& secondName)
234 {
235  // Tensors must have the same number of dimensions in order to be explicit about which dimensions will get
236  // broadcasted.
237  // NOTE: This check is dependent on the AddBroadcastReshapeLayerImpl optimization having been applied to the layer.
238  if (first.GetNumDimensions() != second.GetNumDimensions())
239  {
240  throw InvalidArgumentException(descName + ": Tensors "
241  + firstName + " & " + secondName
242  + " must have the same number of dimensions in order to be broadcasted");
243  }
244  uint32_t numDims = first.GetNumDimensions();
245  std::vector<uint32_t> outputDims(numDims, 0u);
246  for (uint32_t i = 0; i < numDims; i++)
247  {
248  const bool dimsNotEqual = first.GetShape()[i] != second.GetShape()[i];
249  const bool dimsNotOne = (first.GetShape()[i] != 1) && (second.GetShape()[i] != 1);
250  if (dimsNotEqual && dimsNotOne)
251  {
252  throw InvalidArgumentException("Broadcasting is not possible for incompatible shapes");
253  }
254  outputDims[i] = std::max(first.GetShape()[i], second.GetShape()[i]);
255  }
256  TensorShape broadcastShape = TensorShape(armnn::numeric_cast<unsigned int>(outputDims.size()), outputDims.data());
257  if (broadcastShape != output.GetShape())
258  {
259  throw InvalidArgumentException(descName + ": The tensor shape resulting from adding "
260  + firstName + " & " + secondName
261  + " does not match the output shape");
262  }
263 }
264 
265 //---------------------------------------------------------------
266 void ValidateDataTypes(const TensorInfo& info,
267  const std::vector<armnn::DataType>& supportedTypes,
268  std::string const& descName)
269 {
270  auto iterator = std::find(supportedTypes.begin(), supportedTypes.end(), info.GetDataType());
271  if (iterator == supportedTypes.end())
272  {
273  throw InvalidArgumentException(descName + ": " + " Tensor type " + GetDataTypeName(info.GetDataType()) +
274  " is not supported.");
275  }
276 }
277 
278 //---------------------------------------------------------------
279 void ValidateTensorDataTypesMatch(const TensorInfo& first,
280  const TensorInfo& second,
281  std::string const& descName,
282  std::string const& firstName,
283  std::string const& secondName)
284 {
285  if (first.GetDataType() != second.GetDataType())
286  {
287  throw InvalidArgumentException(descName + ": " + firstName + " & " + secondName +
288  " must have identical data types.");
289  }
290 }
291 
292 //---------------------------------------------------------------
293 void ValidateTensorNumElementsMatch(const TensorInfo& first,
294  const TensorInfo& second,
295  std::string const& descName,
296  std::string const& firstName,
297  std::string const& secondName)
298 {
299  if (first.GetNumElements() != second.GetNumElements())
300  {
301  throw InvalidArgumentException(descName + ": " + firstName + " & " + secondName +
302  " must have the same number of elements.");
303  }
304 }
305 
306 void ValidateWeightDataType(const TensorInfo& inputInfo,
307  const TensorInfo& weightInfo,
308  const std::string& descName)
309 {
310  const DataType inputType = inputInfo.GetDataType();
311  if (IsQuantized8BitType(inputType))
312  {
313  const std::vector<DataType> validTypes =
314  {
315  DataType::QAsymmS8,
316  DataType::QAsymmU8,
317  DataType::QSymmS8
318  };
319 
320  ValidateDataTypes(weightInfo, validTypes, descName);
321  }
322  else
323  {
324  ValidateTensorDataTypesMatch(inputInfo, weightInfo, descName, "input", "weight");
325  }
326 }
327 
328 void ValidatePerAxisQuantizationDimension(const TensorInfo& tensorInfo,
329  const std::string& descName,
330  const std::string& tensorName)
331 {
332  const Optional<unsigned int>& quantizationDim = tensorInfo.GetQuantizationDim();
333  if (!quantizationDim.has_value())
334  {
335  throw InvalidArgumentException(fmt::format("{0}: Quantization dimension for per-axis quantization "
336  "not set on tensor {1}.", descName, tensorName));
337  }
338 }
339 
340 void ValidatePerAxisQuantizationOffset(const TensorInfo& tensorInfo,
341  const std::string& descName,
342  const std::string& tensorName)
343 {
344  int32_t quantizationOffset = tensorInfo.GetQuantizationOffset();
345  if (quantizationOffset != 0)
346  {
347  throw InvalidArgumentException(fmt::format(
348  "{0}: Quantization offset for per-axis quantization expected to be 0 on tensor {1}, but got: {2}",
349  descName, tensorName, quantizationOffset));
350  }
351 }
352 
353 void ValidatePerAxisQuantization(const TensorInfo& inputInfo,
354  const TensorInfo& outputInfo,
355  const TensorInfo& weightInfo,
356  const Optional<TensorInfo>& optionalBiasInfo,
357  const std::string& descName)
358 {
359  if (weightInfo.HasPerAxisQuantization())
360  {
361  const DataType inputDataType = inputInfo.GetDataType();
362  const DataType outputDataType = outputInfo.GetDataType();
363 
364  const bool canHavePerAxisQuantization = (IsQuantized8BitType(inputDataType)) && inputDataType == outputDataType;
365 
366  if (!canHavePerAxisQuantization)
367  {
368  throw InvalidArgumentException(fmt::format(
369  "{0}: Per-axis quantization parameters set on tensor {1}, but data type does not support "
370  "per-axis quantization.", descName, "weight"));
371  }
372 
373 
374  ValidPerAxisQuantizedDataType(weightInfo, descName, "weight");
375  ValidatePerAxisQuantizationDimension(weightInfo, descName, "weight");
376  ValidatePerAxisQuantizationOffset(weightInfo, descName, "weight");
377 
378  if (optionalBiasInfo.has_value())
379  {
380  const TensorInfo& biasInfo = optionalBiasInfo.value();
381  if (!biasInfo.HasPerAxisQuantization())
382  {
383  throw InvalidArgumentException(fmt::format(
384  "{}: Per-axis quantization parameters not set on bias tensor, "
385  "despite being set on weight tensor.", descName));
386  }
387 
388  ValidateTensorDataType(biasInfo, DataType::Signed32, descName, "bias");
389  ValidatePerAxisQuantizationDimension(biasInfo, descName, "bias");
390  ValidatePerAxisQuantizationOffset(biasInfo, descName, "bias");
391  }
392  }
393 }
394 
395 } // anonymous namespace
396 
397 //---------------------------------------------------------------
399  std::string const& descName,
400  unsigned int numDimensions,
401  std::string const& tensorName) const
402 {
403  // If we're allowing expanded dimensions then numDimensions becomes the minimum number of Dimensions we can allow.
404  // Throw an Exception if the tensors has fewer than numDimensions or if the squeezed dimensions are greater than
405  // numDimensions.
407  {
408  unsigned int squeezedDims = 0;
409 
410  for (unsigned int i = 0; i < tensor.GetNumDimensions(); ++i)
411  {
412  if (tensor.GetShape()[i] != 1)
413  {
414  ++squeezedDims;
415  }
416  }
417  if (tensor.GetNumDimensions() < numDimensions || squeezedDims > numDimensions)
418  {
419  throw InvalidArgumentException(descName + ": Expected " + to_string(numDimensions) + " or less but got " +
420  to_string(tensor.GetNumDimensions()) + " dimensions for " +
421  tensorName + " tensor.");
422  }
423  }
424  else
425  {
426  if (tensor.GetNumDimensions() != numDimensions)
427  {
428  throw InvalidArgumentException(descName + ": Expected " + to_string(numDimensions) + " but got " +
429  to_string(tensor.GetNumDimensions()) + " dimensions for " +
430  tensorName + " tensor.");
431  }
432  }
433 }
434 
435 //---------------------------------------------------------------
437  unsigned int numDimension,
438  unsigned int numElements,
439  std::string const& tensorName) const
440 {
441  const std::string functionName{"ValidateTensorNumDimNumElem"};
442  ValidateTensorNumDimensions(tensorInfo, functionName, numDimension, tensorName);
443  ValidateTensorNumElements(tensorInfo, functionName, numElements, tensorName);
444 }
445 
446 //---------------------------------------------------------------
447 void QueueDescriptor::ValidateInputsOutputs(const std::string& descName,
448  unsigned int numExpectedIn, unsigned int numExpectedOut) const
449 {
450  ValidateTensors(m_Inputs, numExpectedIn, descName, "input");
451  ValidateTensors(m_Outputs, numExpectedOut, descName, "output");
452 }
453 
454 //---------------------------------------------------------------
455 void MapQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
456 {
457  const std::string descriptorName{"MapQueueDescriptor"};
458 
459  ValidateNumInputs(workloadInfo, descriptorName, 1);
460  ValidateNumOutputs(workloadInfo, descriptorName, 0);
461 
462  for (unsigned int i = 0; i < m_Inputs.size(); ++i)
463  {
464  if (!m_Inputs[i])
465  {
467  fmt::format("{}: Invalid NULL input {}.", descriptorName, static_cast<int>(i)));
468  }
469  }
470 }
471 
472 //---------------------------------------------------------------
473 void UnmapQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
474 {
475  const std::string descriptorName{"UnmapQueueDescriptor"};
476 
477  ValidateNumInputs(workloadInfo, descriptorName, 1);
478  ValidateNumOutputs(workloadInfo, descriptorName, 0);
479 
480  for (unsigned int i = 0; i < m_Inputs.size(); ++i)
481  {
482  if (!m_Inputs[i])
483  {
485  fmt::format("{}: Invalid NULL input {}.", descriptorName, static_cast<int>(i)));
486  }
487  }
488 }
489 
490 //---------------------------------------------------------------
491 void MemCopyQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
492 {
493  const std::string descriptorName{"MemCopyQueueDescriptor"};
494 
495  ValidateNumInputs(workloadInfo, descriptorName, 1);
496  ValidateNumOutputs(workloadInfo, descriptorName , 1);
497 
498  const TensorInfo& inputTensorInfo = workloadInfo.m_InputTensorInfos[0];
499  const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];
500 
501  ValidateTensorNumElementsMatch(inputTensorInfo, outputTensorInfo, descriptorName, "input", "output");
502  ValidateTensorDataTypesMatch(inputTensorInfo, outputTensorInfo, descriptorName, "input", "output");
503 
504  if (m_Inputs.size() != m_Outputs.size())
505  {
506  throw InvalidArgumentException(fmt::format(
507  "{0}: Number of inputs ({1}) does not match the number of outputs ({2}).",
508  descriptorName, m_Inputs.size(), m_Outputs.size()));
509  }
510 
511  for (unsigned int i = 0; i < m_Inputs.size(); ++i)
512  {
513  if (!m_Inputs[i])
514  {
515  throw InvalidArgumentException(fmt::format(
516  "{0}: Invalid NULL input {1}.", descriptorName, i));
517  }
518 
519  if (!m_Outputs[i])
520  {
521  throw InvalidArgumentException(fmt::format("{0}: Invalid NULL output {1}", descriptorName, i));
522  }
523  }
524 }
525 
526 //---------------------------------------------------------------
527 void MemImportQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
528 {
529  ValidateNumInputs(workloadInfo, "MemImportQueueDescriptor", 1);
530  ValidateNumOutputs(workloadInfo, "MemImportQueueDescriptor" , 1);
531 
532  if (workloadInfo.m_InputTensorInfos.size() != 1)
533  {
534  throw InvalidArgumentException(fmt::format("Number of input infos ({}) is not 1.",
535  workloadInfo.m_InputTensorInfos.size()));
536 
537  }
538 
539  if (workloadInfo.m_InputTensorInfos.size() != workloadInfo.m_OutputTensorInfos.size())
540  {
541  throw InvalidArgumentException(fmt::format(
542  "Number of input infos ({0}) does not match the number of output infos ({1})",
543  workloadInfo.m_InputTensorInfos.size(), workloadInfo.m_OutputTensorInfos.size()));
544  }
545 
546  for (std::size_t i = 0; i < workloadInfo.m_InputTensorInfos.size(); ++i)
547  {
548  if (workloadInfo.m_InputTensorInfos[i].GetNumElements() !=
549  workloadInfo.m_OutputTensorInfos[i].GetNumElements())
550  {
551  throw InvalidArgumentException(fmt::format(
552  "Number of elements for tensor input and output {} does not match", i ));
553  }
554  }
555 
556  if (m_Inputs.size() != 1)
557  {
558  throw InvalidArgumentException(fmt::format("Number of inputs ({}) is not 1.", m_Inputs.size()));
559  }
560 
561  if (m_Inputs.size() != m_Outputs.size())
562  {
563  throw InvalidArgumentException(fmt::format(
564  "Number of inputs ({0}) does not match the number of outputs ({1})",
565  m_Inputs.size(), m_Outputs.size()));
566  }
567 
568  for (unsigned int i = 0; i < m_Inputs.size(); ++i)
569  {
570  if (!m_Inputs[i])
571  {
572  throw InvalidArgumentException(fmt::format("Invalid null input {}", i));
573  }
574 
575  if (!m_Outputs[i])
576  {
577  throw InvalidArgumentException(fmt::format("Invalid null output {}", i));
578  }
579  }
580 }
581 
582 //---------------------------------------------------------------
583 void MemSyncQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
584 {
585  ValidateNumInputs(workloadInfo, "MemSyncQueueDescriptor", 1);
586 
587  if (m_Inputs.size() != 1)
588  {
589  throw InvalidArgumentException(fmt::format("Number of inputs ({}) is not 1.", m_Inputs.size()));
590  }
591 
592  if (m_Outputs.size() != 0)
593  {
594  throw InvalidArgumentException(fmt::format("Number of outputs ({}) is not 0.", m_Outputs.size()));
595  }
596 
597  if (!m_Inputs[0])
598  {
599  throw InvalidArgumentException(fmt::format("Invalid null input 0"));
600  }
601 }
602 
603 //---------------------------------------------------------------
604 void ActivationQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
605 {
606  const std::string descriptorName{"ActivationQueueDescriptor"};
607 
608  ValidateNumInputs(workloadInfo, descriptorName, 1);
609  ValidateNumOutputs(workloadInfo, descriptorName, 1);
610 
611  const TensorInfo& inputTensorInfo = workloadInfo.m_InputTensorInfos[0];
612  const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];
613 
614  std::vector<DataType> supportedTypes =
615  {
622  };
623 
624  ValidateDataTypes(inputTensorInfo, supportedTypes, descriptorName);
625  ValidateTensorDataTypesMatch(inputTensorInfo, outputTensorInfo, descriptorName, "input", "output");
626  ValidateTensorShapesMatch(inputTensorInfo, outputTensorInfo, descriptorName, "input", "output");
627 }
628 
629 void ArgMinMaxQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
630 {
631  const std::string descriptorName{"ArgMinMaxQueueDescriptor"};
632 
633  ValidateNumInputs(workloadInfo, descriptorName, 1);
634  ValidateNumOutputs(workloadInfo, descriptorName, 1);
635 
636  const TensorInfo& inputTensorInfo = workloadInfo.m_InputTensorInfos[0];
637  const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];
638 
639  if (outputTensorInfo.GetDataType() != DataType::Signed32 &&
640  outputTensorInfo.GetDataType() != DataType::Signed64)
641  {
642  throw InvalidArgumentException(descriptorName + ": Output of ArgMinMax layer must be Int32 or Int64.");
643  }
644 
645  std::vector<DataType> supportedInputTypes =
646  {
655  };
656 
657  ValidateDataTypes(inputTensorInfo, supportedInputTypes, descriptorName);
658 
659  auto inputShape = inputTensorInfo.GetShape();
660  auto outputShape = outputTensorInfo.GetShape();
661 
662  auto inputNumDimensions = inputShape.GetNumDimensions();
663  auto unsignedAxis = armnnUtils::GetUnsignedAxis(inputNumDimensions, m_Parameters.m_Axis);
664 
665  const std::string outputShapeError{": Output tensor shape does not match shape inferred from input tensor."};
666 
667  // 1D input shape results in scalar output shape
668  if (inputShape.GetNumDimensions() == 1)
669  {
670  if (outputShape.GetNumDimensions() != 1 && outputShape[0] != 1)
671  {
672  throw InvalidArgumentException(descriptorName + outputShapeError);
673  }
674  }
675  else
676  {
677  for (unsigned int i = 0; i < unsignedAxis; ++i)
678  {
679  if (outputShape[i] != inputShape[i])
680  {
681  throw InvalidArgumentException(descriptorName + outputShapeError);
682  }
683  }
684 
685  for (auto i = unsignedAxis + 1; i < inputNumDimensions; ++i)
686  {
687  if (outputShape[i - 1] != inputShape[i])
688  {
689  throw InvalidArgumentException(descriptorName + outputShapeError);
690  }
691  }
692  }
693 }
694 
695 void CastQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
696 {
697  const std::string descriptorName{"CastQueueDescriptor"};
698 
699  ValidateNumInputs(workloadInfo, descriptorName, 1);
700  ValidateNumOutputs(workloadInfo, descriptorName, 1);
701 
702  const TensorInfo& inputTensorInfo = workloadInfo.m_InputTensorInfos[0];
703  const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];
704 
705  std::vector<DataType> supportedTypes =
706  {
717  };
718 
719  ValidateDataTypes(inputTensorInfo, supportedTypes, descriptorName);
720  ValidateTensorShapesMatch(inputTensorInfo, outputTensorInfo, descriptorName, "input", "output");
721 }
722 
723 void SoftmaxQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
724 {
725  const std::string descriptorName{"SoftmaxQueueDescriptor"};
726 
727  ValidateNumInputs(workloadInfo, descriptorName, 1);
728  ValidateNumOutputs(workloadInfo, descriptorName, 1);
729 
730  const TensorInfo& inputTensorInfo = workloadInfo.m_InputTensorInfos[0];
731  const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];
732 
733  std::vector<DataType> supportedTypes =
734  {
741  };
742 
743  ValidateDataTypes(inputTensorInfo, supportedTypes, descriptorName);
744  ValidateTensorDataTypesMatch(inputTensorInfo, outputTensorInfo, descriptorName, "input", "output");
745  ValidateTensorShapesMatch(inputTensorInfo, outputTensorInfo, descriptorName, "input", "output");
746 }
747 
748 void SplitterQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
749 {
750  const std::string descriptorName{"SplitterQueueDescriptor"};
751 
752  ValidateNumInputs(workloadInfo, descriptorName, 1);
753 
754  // Check the supported data types
755  std::vector<DataType> supportedTypes =
756  {
765  };
766 
767  const TensorInfo& inputTensorInfo = workloadInfo.m_InputTensorInfos[0];
768  for (unsigned long i = 0ul; i < workloadInfo.m_OutputTensorInfos.size(); ++i)
769  {
770  const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[i];
771  ValidateDataTypes(outputTensorInfo, supportedTypes, descriptorName);
772 
773  const std::string outputName = "output_" + std::to_string(i);
774  ValidateTensorDataTypesMatch(inputTensorInfo, outputTensorInfo, descriptorName, "input", outputName);
775  }
776 
777  if (workloadInfo.m_OutputTensorInfos.size() <= 0)
778  {
779  throw InvalidArgumentException(descriptorName + ": At least one output needs to be provided.");
780  }
781 
782  if (workloadInfo.m_OutputTensorInfos.size() != m_ViewOrigins.size())
783  {
785  descriptorName + ": Number of split windows "
786  "has to match number of workloadInfo.m_OutputTensorInfos. "
787  "Number of windows: " +
788  to_string(m_ViewOrigins.size()) +
789  ". Number of workloadInfo.m_OutputTensorInfos: " + to_string(workloadInfo.m_OutputTensorInfos.size()));
790  }
791 
792  //The dimensionality of all the windows has to match the dimensionality (not shape) of the input.
793  std::size_t inputDims = workloadInfo.m_InputTensorInfos[0].GetNumDimensions();
794  for(unsigned int w = 0; w < m_ViewOrigins.size(); ++w )
795  {
796  //Checks that the dimensionality of input is same as the split windows.
797  ViewOrigin const& e = m_ViewOrigins[w];
798  if (e.m_Origin.size() != inputDims)
799  {
800  throw InvalidArgumentException(descriptorName + ": Window origin have to "
801  "have the same dimensionality as the input tensor. "
802  "Window origin (index: " +
803  to_string(w) + ") has " + to_string(e.m_Origin.size()) +
804  " dimensions, the input "
805  "tensor has " +
806  to_string(inputDims) + " dimensions.");
807  }
808  for (unsigned int i = 0; i < e.m_Origin.size(); ++i)
809  {
810  if (e.m_Origin[i] + workloadInfo.m_OutputTensorInfos[w].GetShape()[i] >
811  workloadInfo.m_InputTensorInfos[0].GetShape()[i])
812  {
813  throw InvalidArgumentException(descriptorName + ": Window extent coordinates have to "
814  "be smaller or equal than the size of the input in that coord.");
815  }
816  }
817  }
818 }
819 
820 void ConcatQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
821 {
822  const std::string descriptorName{"ConcatQueueDescriptor"};
823 
824  ValidateNumOutputs(workloadInfo, descriptorName, 1);
825 
826  if (m_Inputs.size() <= 0)
827  {
828  throw InvalidArgumentException(descriptorName + ": At least one input needs to be provided.");
829  }
830  if (m_Outputs.size() <= 0)
831  {
832  throw InvalidArgumentException(descriptorName + ": At least one output needs to be provided.");
833  }
834 
835  if (workloadInfo.m_InputTensorInfos.size() <= 0)
836  {
837  throw InvalidArgumentException(descriptorName + ": At least one TensorInfo input needs to be provided.");
838  }
839  if (workloadInfo.m_OutputTensorInfos.size() <= 0)
840  {
841  throw InvalidArgumentException(descriptorName + ": At least one TensorInfo output needs to be provided.");
842  }
843 
844  if(m_Parameters.GetConcatAxis() > workloadInfo.m_InputTensorInfos[0].GetShape().GetNumDimensions())
845  {
846  throw InvalidArgumentException(descriptorName + ": Invalid concatenation axis provided.");
847  }
848 
849  if (workloadInfo.m_InputTensorInfos[0].GetShape().GetNumDimensions() - m_Parameters.GetConcatAxis() == 1)
850  {
851  return;
852  }
853 
854  if (workloadInfo.m_InputTensorInfos.size() != m_ViewOrigins.size())
855  {
857  descriptorName + ": Number of split windows "
858  "has to match number of workloadInfo.m_InputTensorInfos. "
859  "Number of windows: " +
860  to_string(m_ViewOrigins.size()) +
861  ". Number of workloadInfo.m_InputTensorInfos: " + to_string(workloadInfo.m_InputTensorInfos.size()));
862  }
863 
864  //The dimensionality of all the windows has to match the dimensionality (not shape) of the output.
865  std::size_t outputDims = workloadInfo.m_OutputTensorInfos[0].GetNumDimensions();
866  for(unsigned int w = 0; w < m_ViewOrigins.size(); ++w )
867  {
868  //Checks that the dimensionality of output is same as the split windows.
869  ViewOrigin const& e = m_ViewOrigins[w];
870  if (e.m_Origin.size() != outputDims)
871  {
872  throw InvalidArgumentException(descriptorName + ": Window origin have to "
873  "have the same dimensionality as the output tensor. "
874  "Window origin (index: " +
875  to_string(w) + ") has " + to_string(e.m_Origin.size()) +
876  " dimensions, the output "
877  "tensor has " +
878  to_string(outputDims) + " dimensions.");
879  }
880  //Checks that the merge windows are within the output tensor.
881  for (unsigned int i = 0; i < e.m_Origin.size(); ++i)
882  {
883  if (e.m_Origin[i] + workloadInfo.m_InputTensorInfos[w].GetShape()[i]
884  > workloadInfo.m_OutputTensorInfos[0].GetShape()[i])
885  {
886  throw InvalidArgumentException(descriptorName + ": Window extent coordinates have to "
887  "be smaller or equal than the size of the output in that coord.");
888  }
889  }
890  }
891 
892  // Check the supported data types
893  std::vector<DataType> supportedTypes =
894  {
903  };
904 
905  const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];
906  for (unsigned long i = 0ul; i < workloadInfo.m_InputTensorInfos.size(); ++i)
907  {
908  const TensorInfo& inputTensorInfo = workloadInfo.m_InputTensorInfos[i];
909  ValidateDataTypes(inputTensorInfo, supportedTypes, descriptorName);
910 
911  const std::string inputName = "input_" + std::to_string(i);
912  ValidateTensorDataTypesMatch(inputTensorInfo, outputTensorInfo, descriptorName, inputName, "output");
913  }
914 }
915 
916 void StackQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
917 {
918  const std::string descriptorName{"StackQueueDescriptor"};
919 
920  ValidateNumOutputs(workloadInfo, descriptorName, 1);
921 
922  if (m_Parameters.m_NumInputs != workloadInfo.m_InputTensorInfos.size())
923  {
924  throw InvalidArgumentException(descriptorName + ": Must have the defined number of input tensors.");
925  }
926 
927  // All inputs must have the same shape, which is defined in parameters
928  const TensorShape& inputShape = m_Parameters.m_InputShape;
929  for (unsigned int i = 0; i < workloadInfo.m_InputTensorInfos.size(); ++i)
930  {
931  if (workloadInfo.m_InputTensorInfos[i].GetShape() != inputShape)
932  {
933  throw InvalidArgumentException(descriptorName + ": All input tensor shapes must match the defined shape.");
934  }
935  }
936 
937  if (inputShape.GetNumDimensions() > 4)
938  {
939  throw InvalidArgumentException(descriptorName + ": Input tensor may have up to 4 dimensions.");
940  }
941 
942  // m_Axis is 0-based and may take values from 0 to the number of input dimensions (inclusive),
943  // since the output tensor has an additional dimension.
944  if (m_Parameters.m_Axis > inputShape.GetNumDimensions())
945  {
946  throw InvalidArgumentException(descriptorName + ": Axis may not be greater "
947  "than the number of input dimensions.");
948  }
949 
950  // Output shape must be as inferred from the input shape
951  const TensorShape& outputShape = workloadInfo.m_OutputTensorInfos[0].GetShape();
952  for (unsigned int i = 0; i < m_Parameters.m_Axis; ++i)
953  {
954  if (outputShape[i] != inputShape[i])
955  {
956  throw InvalidArgumentException(descriptorName + ": Output tensor must "
957  "match shape inferred from input tensor.");
958  }
959  }
960 
961  if (outputShape[m_Parameters.m_Axis] != m_Parameters.m_NumInputs)
962  {
963  throw InvalidArgumentException(descriptorName + ": Output tensor must "
964  "match shape inferred from input tensor.");
965  }
966 
967  for (unsigned int i = m_Parameters.m_Axis + 1; i < inputShape.GetNumDimensions() + 1; ++i)
968  {
969  if (outputShape[i] != inputShape[i-1])
970  {
971  throw InvalidArgumentException(descriptorName + ": Output tensor must "
972  "match shape inferred from input tensor.");
973  }
974  }
975 
976  if (outputShape.GetNumDimensions() > 5)
977  {
978  throw InvalidArgumentException(descriptorName + ": Output tensor may have up to 5 dimensions.");
979  }
980 
981  // Check the supported data types
982  std::vector<DataType> supportedTypes =
983  {
993  };
994 
995  ValidateDataTypes(workloadInfo.m_InputTensorInfos[0], supportedTypes, descriptorName);
996 
997  for (unsigned int i = 1ul; i < workloadInfo.m_InputTensorInfos.size(); ++i)
998  {
999  ValidateTensorDataTypesMatch(workloadInfo.m_InputTensorInfos[0],
1000  workloadInfo.m_InputTensorInfos[i],
1001  descriptorName,
1002  "input_0",
1003  "input_" + std::to_string(i));
1004  }
1005 
1006  ValidateTensorDataTypesMatch(workloadInfo.m_InputTensorInfos[0],
1007  workloadInfo.m_OutputTensorInfos[0],
1008  descriptorName,
1009  "input_0",
1010  "output");
1011 }
1012 
1013 void FillQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
1014 {
1015  const std::string descriptorName{"FillQueueDescriptor"};
1016 
1017  ValidateNumInputs(workloadInfo, descriptorName, 1);
1018  ValidateNumOutputs(workloadInfo, descriptorName, 1);
1019 
1020  const TensorInfo& inputTensorInfo = workloadInfo.m_InputTensorInfos[0];
1021  const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];
1022 
1023  ValidateTensorNumDimensions(inputTensorInfo, descriptorName, 1, "input");
1024 
1025  std::vector<DataType> supportedTypes =
1026  {
1031  };
1032 
1033  ValidateDataTypes(outputTensorInfo, supportedTypes, descriptorName);
1034 }
1035 
1037 {
1038  const std::string descriptorName{"FullyConnectedQueueDescriptor"};
1039 
1040  uint32_t numInputs = 2;
1042  {
1043  numInputs = 3;
1044  }
1045 
1046  ValidateNumInputs(workloadInfo, descriptorName, numInputs);
1047  ValidateNumOutputs(workloadInfo, descriptorName, 1);
1048 
1049  const TensorInfo& inputTensorInfo = workloadInfo.m_InputTensorInfos[0];
1050  const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];
1051 
1052  ValidateTensorNumDimensions(outputTensorInfo, descriptorName, 2, "output");
1053 
1054  if (!(inputTensorInfo.GetNumDimensions() == 2 || inputTensorInfo.GetNumDimensions() == 4))
1055  {
1056  throw InvalidArgumentException(descriptorName + ": Input tensor must have 2 or 4 dimensions.");
1057  }
1058 
1059  TensorInfo weightTensorInfo = workloadInfo.m_InputTensorInfos[1];
1060  ValidateTensorNumDimensions(weightTensorInfo, descriptorName, 2, "weight");
1061 
1063  {
1064  TensorInfo biasTensorInfo = workloadInfo.m_InputTensorInfos[2];
1065  // Validates type and quantization values.
1066  ValidateBiasTensorQuantization(biasTensorInfo, weightTensorInfo, descriptorName);
1067  ValidateTensorDataType(biasTensorInfo, GetBiasDataType(inputTensorInfo.GetDataType()), descriptorName, "bias");
1068  ValidateTensorNumDimensions(biasTensorInfo, descriptorName, 1, "bias");
1069  }
1070 
1071  // Check the supported data types
1072  std::vector<DataType> supportedTypes =
1073  {
1081  };
1082 
1083  ValidateDataTypes(inputTensorInfo, supportedTypes, descriptorName);
1084 
1085  // For FullyConnected, we allow to have BFloat16 input with Float32 output for optimization.
1086  if (inputTensorInfo.GetDataType() == DataType::BFloat16)
1087  {
1088  if (outputTensorInfo.GetDataType() != DataType::BFloat16 && outputTensorInfo.GetDataType() != DataType::Float32)
1089  {
1090  throw InvalidArgumentException(descriptorName + ": " + " Output tensor type must be BFloat16 or Float32 "
1091  "for BFloat16 input.");
1092  }
1093  }
1094  else
1095  {
1096  ValidateTensorDataTypesMatch(inputTensorInfo, outputTensorInfo, descriptorName, "input", "output");
1097  }
1098 }
1099 
1100 void FusedQueueDescriptor::Validate(const WorkloadInfo& /*workloadInfo*/) const
1101 {
1102  // This is internally generated, so it should not need validation.
1103 }
1104 
1106 {
1107  const std::string descriptorName{"NormalizationQueueDescriptor"};
1108 
1109  ValidateNumInputs(workloadInfo, descriptorName, 1);
1110  ValidateNumOutputs(workloadInfo, descriptorName, 1);
1111 
1112  const TensorInfo& inputTensorInfo = workloadInfo.m_InputTensorInfos[0];
1113  const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];
1114 
1115  // Check the supported data types
1116  std::vector<DataType> supportedTypes =
1117  {
1124  };
1125 
1126  ValidateDataTypes(inputTensorInfo, supportedTypes, descriptorName);
1127 
1128  ValidateTensorDataTypesMatch(inputTensorInfo, outputTensorInfo, descriptorName, "input", "output");
1129 
1130  ValidateTensorShapesMatch(inputTensorInfo, outputTensorInfo, descriptorName, "input", "output");
1131 }
1132 
1133 void AdditionQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
1134 {
1135  const std::string descriptorName{"AdditionQueueDescriptor"};
1136 
1137  ValidateNumInputs(workloadInfo, descriptorName, 2);
1138  ValidateNumOutputs(workloadInfo, descriptorName, 1);
1139 
1140  const TensorInfo& inputTensorInfo0 = workloadInfo.m_InputTensorInfos[0];
1141  const TensorInfo& inputTensorInfo1 = workloadInfo.m_InputTensorInfos[1];
1142  const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];
1143 
1144  std::vector<DataType> supportedTypes =
1145  {
1153  };
1154 
1155  ValidateDataTypes(inputTensorInfo0, supportedTypes, descriptorName);
1156  ValidateDataTypes(inputTensorInfo1, supportedTypes, descriptorName);
1157  ValidateDataTypes(outputTensorInfo, supportedTypes, descriptorName);
1158 
1159  ValidateTensorDataTypesMatch(inputTensorInfo0, inputTensorInfo1, descriptorName, "input_0", "input_1");
1160  ValidateTensorDataTypesMatch(inputTensorInfo1, outputTensorInfo, descriptorName, "input_1", "output");
1161 
1162  ValidateBroadcastTensorShapesMatch(inputTensorInfo0,
1163  inputTensorInfo1,
1164  outputTensorInfo,
1165  descriptorName,
1166  "input_0",
1167  "input_1");
1168 }
1169 
1171 {
1172  const std::string descriptorName{"MultiplicationQueueDescriptor"};
1173 
1174  ValidateNumInputs(workloadInfo, descriptorName, 2);
1175  ValidateNumOutputs(workloadInfo, descriptorName, 1);
1176 
1177  const TensorInfo& inputTensorInfo0 = workloadInfo.m_InputTensorInfos[0];
1178  const TensorInfo& inputTensorInfo1 = workloadInfo.m_InputTensorInfos[1];
1179  const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];
1180 
1181  std::vector<DataType> supportedTypes =
1182  {
1190  };
1191 
1192  ValidateDataTypes(inputTensorInfo0, supportedTypes, descriptorName);
1193  ValidateDataTypes(inputTensorInfo1, supportedTypes, descriptorName);
1194  ValidateDataTypes(outputTensorInfo, supportedTypes, descriptorName);
1195 
1196  ValidateTensorDataTypesMatch(inputTensorInfo0, inputTensorInfo1, descriptorName, "input_0", "input_1");
1197  ValidateTensorDataTypesMatch(inputTensorInfo1, outputTensorInfo, descriptorName, "input_1", "output");
1198 
1199  ValidateBroadcastTensorShapesMatch(inputTensorInfo0,
1200  inputTensorInfo1,
1201  outputTensorInfo,
1202  descriptorName,
1203  "input_0",
1204  "input_1");
1205 }
1206 
1208 {
1209  const std::string descriptorName{"BatchNormalizationQueueDescriptor"};
1210 
1211  ValidateNumInputs(workloadInfo, descriptorName, 1);
1212  ValidateNumOutputs(workloadInfo, descriptorName, 1);
1213 
1214  const TensorInfo& inputTensorInfo = workloadInfo.m_InputTensorInfos[0];
1215  const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];
1216 
1217  std::vector<DataType> supportedTypes =
1218  {
1225  };
1226 
1227  ValidateDataTypes(inputTensorInfo, supportedTypes, descriptorName);
1228  ValidateDataTypes(outputTensorInfo, supportedTypes, descriptorName);
1229 
1230  ValidateTensorDataTypesMatch(inputTensorInfo, outputTensorInfo, descriptorName, "input", "output");
1231  ValidateTensorShapesMatch(inputTensorInfo, outputTensorInfo, descriptorName, "input", "output");
1232 
1233  ValidatePointer(m_Mean, descriptorName, "mean");
1234  ValidatePointer(m_Variance, descriptorName, "variance");
1235  ValidatePointer(m_Beta, descriptorName, "beta");
1236  ValidatePointer(m_Gamma, descriptorName, "gamma");
1237 
1238  const TensorInfo& mean = m_Mean->GetTensorInfo();
1239  const TensorInfo& variance = m_Variance->GetTensorInfo();
1240  const TensorInfo& beta = m_Beta->GetTensorInfo();
1241  const TensorInfo& gamma = m_Gamma->GetTensorInfo();
1242 
1243  ValidateTensorNumDimensions(mean, descriptorName, 1, "mean");
1244  ValidateTensorNumDimensions(variance, descriptorName, 1, "variance");
1245  ValidateTensorNumDimensions(beta, descriptorName, 1, "beta");
1246  ValidateTensorNumDimensions(gamma, descriptorName, 1, "gamma");
1247 
1248  ValidateTensorShapesMatch(mean, variance, descriptorName, "mean", "variance");
1249  ValidateTensorShapesMatch(mean, beta, descriptorName, "mean", "beta");
1250  ValidateTensorShapesMatch(mean, gamma, descriptorName, "mean", "gamma");
1251 }
1252 
1254 {
1255  const std::string descriptorName{"Convolution2dQueueDescriptor"};
1256 
1257  uint32_t numInputs = 2;
1259  {
1260  numInputs = 3;
1261  }
1262 
1263  ValidateNumInputs(workloadInfo, descriptorName, numInputs);
1264  ValidateNumOutputs(workloadInfo, descriptorName, 1);
1265 
1266  const TensorInfo& inputTensorInfo = workloadInfo.m_InputTensorInfos[0];
1267  const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];
1268 
1269  ValidateTensorNumDimensions(inputTensorInfo, descriptorName, 4, "input");
1270  ValidateTensorNumDimensions(outputTensorInfo, descriptorName, 4, "output");
1271 
1272  const TensorInfo& weightTensorInfo = workloadInfo.m_InputTensorInfos[1];
1273 
1274  ValidateTensorNumDimensions(weightTensorInfo, descriptorName, 4, "weight");
1275 
1276  ValidateWeightDataType(inputTensorInfo, weightTensorInfo, descriptorName);
1277 
1278  Optional<TensorInfo> optionalBiasTensorInfo;
1280  {
1281  optionalBiasTensorInfo = MakeOptional<TensorInfo>(workloadInfo.m_InputTensorInfos[2]);
1282  const TensorInfo& biasTensorInfo = optionalBiasTensorInfo.value();
1283 
1284  ValidateTensorDataType(biasTensorInfo, GetBiasDataType(inputTensorInfo.GetDataType()), descriptorName, "bias");
1285  ValidateBiasTensorQuantization(biasTensorInfo, weightTensorInfo, descriptorName);
1286  }
1287 
1288  if (m_Parameters.m_StrideX <= 0 || m_Parameters.m_StrideY <= 0 )
1289  {
1291  fmt::format("{}: strideX (provided {}) and strideY (provided {}) "
1292  "cannot be either negative or 0.",
1293  descriptorName, m_Parameters.m_StrideX, m_Parameters.m_StrideY));
1294  }
1295 
1296  ValidatePerAxisQuantization(inputTensorInfo,
1297  outputTensorInfo,
1298  weightTensorInfo,
1299  optionalBiasTensorInfo,
1300  descriptorName);
1301 
1302  std::vector<DataType> supportedTypes =
1303  {
1311  };
1312 
1313  ValidateDataTypes(inputTensorInfo, supportedTypes, descriptorName);
1314 
1315  // For Convolution2d, we allow to have BFloat16 input with Float32 output for optimization.
1316  if (inputTensorInfo.GetDataType() == DataType::BFloat16)
1317  {
1318  if (outputTensorInfo.GetDataType() != DataType::BFloat16 && outputTensorInfo.GetDataType() != DataType::Float32)
1319  {
1320  throw InvalidArgumentException(descriptorName + ": " + " Output tensor type must be BFloat16 or Float32 "
1321  "for BFloat16 input.");
1322  }
1323  }
1324  else
1325  {
1326  ValidateTensorDataTypesMatch(inputTensorInfo, outputTensorInfo, descriptorName, "input", "output");
1327  }
1328 }
1329 
1331 {
1332  const std::string descriptorName{"Convolution3dQueueDescriptor"};
1333 
1334  uint32_t numInputs = 2;
1336  {
1337  numInputs = 3;
1338  }
1339  ValidateNumInputs(workloadInfo, descriptorName, numInputs);
1340  ValidateNumOutputs(workloadInfo, descriptorName, 1);
1341 
1342  const TensorInfo& inputTensorInfo = workloadInfo.m_InputTensorInfos[0];
1343  const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];
1344 
1345  ValidateTensorNumDimensions(inputTensorInfo, descriptorName, 5, "input");
1346  ValidateTensorNumDimensions(outputTensorInfo, descriptorName, 5, "output");
1347 
1348  const TensorInfo& weightTensorInfo = workloadInfo.m_InputTensorInfos[1];
1349  ValidateTensorNumDimensions(weightTensorInfo, descriptorName, 5, "weight");
1350 
1351  ValidateWeightDataType(inputTensorInfo, weightTensorInfo, descriptorName);
1352 
1353  Optional<TensorInfo> optionalBiasTensorInfo;
1355  {
1356  optionalBiasTensorInfo = MakeOptional<TensorInfo>(workloadInfo.m_InputTensorInfos[2]);
1357  const TensorInfo& biasTensorInfo = optionalBiasTensorInfo.value();
1358 
1359  ValidateTensorDataType(biasTensorInfo, GetBiasDataType(inputTensorInfo.GetDataType()), descriptorName, "bias");
1360  ValidateBiasTensorQuantization(biasTensorInfo, weightTensorInfo, descriptorName);
1361  }
1362 
1364  {
1366  fmt::format("{}: strideX (provided {}), strideY (provided {}) or strideZ (provided {})"
1367  "cannot be either negative or 0.",
1369  }
1370 
1371  ValidatePerAxisQuantization(inputTensorInfo,
1372  outputTensorInfo,
1373  weightTensorInfo,
1374  optionalBiasTensorInfo,
1375  descriptorName);
1376 
1377  std::vector<DataType> supportedTypes =
1378  {
1386  };
1387 
1388  ValidateDataTypes(inputTensorInfo, supportedTypes, descriptorName);
1389  ValidateTensorDataTypesMatch(inputTensorInfo, outputTensorInfo, descriptorName, "input", "output");
1390 }
1391 
1393 {
1394  const std::string descriptorName{"DepthwiseConvolution2dQueueDescriptor"};
1395 
1396  uint32_t numInputs = 2;
1398  {
1399  numInputs = 3;
1400  }
1401 
1402  ValidateNumInputs(workloadInfo, descriptorName, numInputs);
1403  ValidateNumOutputs(workloadInfo, descriptorName, 1);
1404 
1405  const TensorInfo& inputTensorInfo = workloadInfo.m_InputTensorInfos[0];
1406  const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];
1407 
1408  ValidateTensorNumDimensions(inputTensorInfo, descriptorName, 4, "input");
1409  ValidateTensorNumDimensions(outputTensorInfo, descriptorName, 4, "output");
1410 
1411  const TensorInfo& weightTensorInfo = workloadInfo.m_InputTensorInfos[1];
1412  ValidateTensorNumDimensions(weightTensorInfo, descriptorName, 4, "weight");
1413 
1415  {
1417  fmt::format("{}: dilationX (provided {}) and dilationY (provided {}) "
1418  "cannot be smaller than 1.",
1419  descriptorName, m_Parameters.m_DilationX, m_Parameters.m_DilationX));
1420  }
1421 
1422  if (m_Parameters.m_StrideX <= 0 || m_Parameters.m_StrideY <= 0 )
1423  {
1425  fmt::format("{}: strideX (provided {}) and strideY (provided {}) "
1426  "cannot be either negative or 0.",
1427  descriptorName, m_Parameters.m_StrideX, m_Parameters.m_StrideY));
1428  }
1429 
1430  if (weightTensorInfo.GetShape()[0] != 1)
1431  {
1432  throw InvalidArgumentException(fmt::format(
1433  "{0}: The weight format in armnn is expected to be [1, H, W, Cout]."
1434  "But first dimension is not equal to 1. Provided weight shape: [{1}, {2}, {3}, {4}]",
1435  descriptorName,
1436  weightTensorInfo.GetShape()[0],
1437  weightTensorInfo.GetShape()[1],
1438  weightTensorInfo.GetShape()[2],
1439  weightTensorInfo.GetShape()[3]));
1440  }
1441 
1442  const unsigned int channelIndex = (m_Parameters.m_DataLayout == DataLayout::NCHW) ? 1 : 3;
1443  const unsigned int numWeightOutputChannelsRefFormat = weightTensorInfo.GetShape()[3];
1444  const unsigned int numWeightOutputChannelsAclFormat = weightTensorInfo.GetShape()[1];
1445  const unsigned int numOutputChannels = outputTensorInfo.GetShape()[channelIndex];
1446 
1447  // Weights format has two valid options: [1, H, W, Cout] (CpuRef) or [1, Cout, H, W] (CpuAcc/GpuAcc).
1448  bool validRefFormat = (numWeightOutputChannelsRefFormat == numOutputChannels);
1449  bool validAclFormat = (numWeightOutputChannelsAclFormat == numOutputChannels);
1450 
1451  if (!(validRefFormat || validAclFormat))
1452  {
1453  throw InvalidArgumentException(fmt::format(
1454  "{0}: The weight format in armnn is expected to be [1, H, W, Cout] (CpuRef) or [1, Cout, H, W] "
1455  "(CpuAcc/GpuAcc). But neither the 4th (CpuRef) or 2nd (CpuAcc/GpuAcc) dimension is equal to Cout."
1456  "Cout = {1} Provided weight shape: [{2}, {3}, {4}, {5}]",
1457  descriptorName,
1458  numOutputChannels,
1459  weightTensorInfo.GetShape()[0],
1460  weightTensorInfo.GetShape()[1],
1461  weightTensorInfo.GetShape()[2],
1462  weightTensorInfo.GetShape()[3]));
1463  }
1464 
1465  ValidateWeightDataType(inputTensorInfo, weightTensorInfo, descriptorName);
1466 
1467  Optional<TensorInfo> optionalBiasTensorInfo;
1469  {
1470  optionalBiasTensorInfo = MakeOptional<TensorInfo>(workloadInfo.m_InputTensorInfos[2]);
1471  const TensorInfo& biasTensorInfo = optionalBiasTensorInfo.value();
1472 
1473  ValidateBiasTensorQuantization(biasTensorInfo, weightTensorInfo, descriptorName);
1474  ValidateTensorDataType(biasTensorInfo, GetBiasDataType(inputTensorInfo.GetDataType()), descriptorName, "bias");
1475  }
1476  ValidatePerAxisQuantization(inputTensorInfo,
1477  outputTensorInfo,
1478  weightTensorInfo,
1479  optionalBiasTensorInfo,
1480  descriptorName);
1481 
1482  std::vector<DataType> supportedTypes =
1483  {
1490  };
1491 
1492  ValidateDataTypes(inputTensorInfo, supportedTypes, descriptorName);
1493  ValidateTensorDataTypesMatch(inputTensorInfo, outputTensorInfo, descriptorName, "input", "output");
1494 }
1495 
1496 void PermuteQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
1497 {
1498  const std::string descriptorName{"PermuteQueueDescriptor"};
1499 
1500  ValidateNumInputs(workloadInfo, descriptorName, 1);
1501  ValidateNumOutputs(workloadInfo, descriptorName, 1);
1502 
1503  const PermutationVector& mapping = m_Parameters.m_DimMappings;
1504 
1505  const TensorInfo& inputTensorInfo = workloadInfo.m_InputTensorInfos[0];
1506  const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];
1507 
1508  ValidateTensorNumDimensions(inputTensorInfo, descriptorName, mapping.GetSize(), "input");
1509  ValidateTensorNumDimensions(outputTensorInfo, descriptorName, mapping.GetSize(), "output");
1510 
1511  for (unsigned int i = 0u; i < mapping.GetSize(); ++i)
1512  {
1513  if (inputTensorInfo.GetShape()[i] != outputTensorInfo.GetShape()[mapping[i]])
1514  {
1515  throw InvalidArgumentException(descriptorName + ": src dimension " + to_string(i) +
1516  " (=" + to_string(inputTensorInfo.GetShape()[i]) + ") " +
1517  "must match dst dimension " + to_string(mapping[i]) +
1518  " (=" + to_string(outputTensorInfo.GetShape()[mapping[i]]) + ")");
1519  }
1520  }
1521 
1522  ValidateTensorDataTypesMatch(inputTensorInfo, outputTensorInfo, descriptorName, "input", "output");
1523 }
1524 
1525 void Pooling2dQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
1526 {
1527  const std::string descriptorName{"Pooling2dQueueDescriptor"};
1528 
1529  ValidateNumInputs(workloadInfo, descriptorName, 1);
1530  ValidateNumOutputs(workloadInfo, descriptorName, 1);
1531 
1532  const TensorInfo& inputTensorInfo = workloadInfo.m_InputTensorInfos[0];
1533  const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];
1534 
1535  ValidateTensorNumDimensions(inputTensorInfo, descriptorName, 4, "input");
1536  ValidateTensorNumDimensions(outputTensorInfo, descriptorName, 4, "output");
1537 
1538  std::vector<DataType> supportedTypes =
1539  {
1546  };
1547 
1548  ValidateDataTypes(inputTensorInfo, supportedTypes, descriptorName);
1549  ValidateTensorDataTypesMatch(inputTensorInfo, outputTensorInfo, descriptorName, "input", "output");
1550 }
1551 
1552 void Pooling3dQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
1553 {
1554  const std::string descriptorName{"Pooling3dQueueDescriptor"};
1555 
1556  ValidateNumInputs(workloadInfo, descriptorName, 1);
1557  ValidateNumOutputs(workloadInfo, descriptorName, 1);
1558 
1559  const TensorInfo& inputTensorInfo = workloadInfo.m_InputTensorInfos[0];
1560  const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];
1561 
1562  ValidateTensorNumDimensions(inputTensorInfo, descriptorName, 5, "input");
1563  ValidateTensorNumDimensions(outputTensorInfo, descriptorName, 5, "output");
1564 
1565  std::vector<DataType> supportedTypes =
1566  {
1573  };
1574 
1575  ValidateDataTypes(inputTensorInfo, supportedTypes, descriptorName);
1576  ValidateTensorDataTypesMatch(inputTensorInfo, outputTensorInfo, descriptorName, "input", "output");
1577 }
1578 
1579 void ResizeQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
1580 {
1581  const std::string descriptorName{"ResizeQueueDescriptor"};
1582 
1583  ValidateNumInputs(workloadInfo, descriptorName, 1);
1584  ValidateNumOutputs(workloadInfo, descriptorName, 1);
1585 
1586  const TensorInfo& inputTensorInfo = workloadInfo.m_InputTensorInfos[0];
1587  const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];
1588 
1589  ValidateTensorNumDimensions(inputTensorInfo, descriptorName, 4, "input");
1590  ValidateTensorNumDimensions(outputTensorInfo, descriptorName, 4, "output");
1591 
1592  std::vector<DataType> supportedTypes =
1593  {
1601  };
1602 
1603  ValidateDataTypes(inputTensorInfo, supportedTypes, descriptorName);
1604  ValidateTensorDataTypesMatch(inputTensorInfo, outputTensorInfo, descriptorName, "input", "output");
1605 
1606  // Resize only changes width and height: batch and channel count must match.
1607  const unsigned int inputBatchSize = inputTensorInfo.GetShape()[0];
1608  const unsigned int outputBatchSize = outputTensorInfo.GetShape()[0];
1609  if (inputBatchSize != outputBatchSize)
1610  {
1612  fmt::format("{}: Input batch size ({}) does not match output batch size ({})",
1613  descriptorName, inputBatchSize, outputBatchSize));
1614  }
1615 
1616  DataLayoutIndexed dimensionIndices(m_Parameters.m_DataLayout);
1617  const unsigned int inputChannelCount = inputTensorInfo.GetShape()[dimensionIndices.GetChannelsIndex()];
1618  const unsigned int outputChannelCount = outputTensorInfo.GetShape()[dimensionIndices.GetChannelsIndex()];
1619  if (inputChannelCount != outputChannelCount)
1620  {
1622  fmt::format("{}: Input channel count ({}) does not match output channel count ({})",
1623  descriptorName, inputChannelCount, outputChannelCount));
1624  }
1625 }
1626 
1627 void ReverseV2QueueDescriptor::Validate(const WorkloadInfo &workloadInfo) const
1628 {
1629  const std::string descriptorName{"ReverseV2QueueDescriptor"};
1630 
1631  // Backend restriction
1632  const unsigned int maxDimensions = 4;
1633 
1634  ValidateNumInputs(workloadInfo, descriptorName, 2);
1635  ValidateNumOutputs(workloadInfo, descriptorName, 1);
1636 
1637  const TensorInfo& inputTensorInfo = workloadInfo.m_InputTensorInfos[0];
1638  const TensorInfo& axisTensorInfo = workloadInfo.m_InputTensorInfos[1];
1639  const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];
1640 
1641  const auto inputTensorNumDimensions = inputTensorInfo.GetNumDimensions();
1642  if (inputTensorNumDimensions > maxDimensions)
1643  {
1644  throw InvalidArgumentException(descriptorName +
1645  ": Input tensors with rank greater than " +
1646  std::to_string(maxDimensions) + " are not supported.");
1647  }
1648 
1649  const auto axisTensorNumDimensions = axisTensorInfo.GetNumDimensions();
1650  if (axisTensorNumDimensions > maxDimensions)
1651  {
1652  throw InvalidArgumentException(descriptorName +
1653  ": More than " + std::to_string(maxDimensions) + " axes cannot be specified.");
1654  }
1655 
1656  if (axisTensorNumDimensions > inputTensorNumDimensions)
1657  {
1658  throw InvalidArgumentException(descriptorName +
1659  ": More axes specified than the number of axes on the input tensor.");
1660  }
1661 
1662  std::vector<DataType> supportedTypes =
1663  {
1673  };
1674 
1675  ValidateDataTypes(inputTensorInfo, supportedTypes, descriptorName);
1676 
1677  std::vector<DataType> axisSupportedTypes =
1678  {
1680  };
1681 
1682  ValidateDataTypes(axisTensorInfo, axisSupportedTypes, descriptorName);
1683 
1684  ValidateTensorShapesMatch(inputTensorInfo, outputTensorInfo, descriptorName, "input", "output");
1685  ValidateTensorDataTypesMatch(inputTensorInfo, outputTensorInfo, descriptorName, "input", "output");
1686 }
1687 
1689 {
1690  const std::string descriptorName{"FakeQuantizationQueueDescriptor"};
1691 
1692  ValidateNumInputs(workloadInfo, descriptorName, 1);
1693  ValidateNumOutputs(workloadInfo, descriptorName, 1);
1694 
1695  const TensorInfo& inputTensorInfo = workloadInfo.m_InputTensorInfos[0];
1696  const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];
1697 
1698  ValidateTensorNumDimensions(inputTensorInfo, descriptorName, 2, "input");
1699  ValidateTensorNumDimensions(outputTensorInfo, descriptorName, 2, "output");
1700 
1701  ValidateTensorShapesMatch(inputTensorInfo, outputTensorInfo, descriptorName, "input", "output");
1702 
1704  {
1705  throw InvalidArgumentException(descriptorName + ": min cannot be greater than max");
1706  }
1707 }
1708 
1710 {
1711  const std::string descriptorName{"InstanceNormalizationQueueDescriptor"};
1712 
1713  ValidateNumInputs(workloadInfo, descriptorName, 1);
1714  ValidateNumOutputs(workloadInfo, descriptorName, 1);
1715 
1716  const TensorInfo& inputTensorInfo = workloadInfo.m_InputTensorInfos[0];
1717  const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];
1718 
1719  if (inputTensorInfo.GetNumDimensions() > 4)
1720  {
1721  throw InvalidArgumentException(descriptorName + ": Input tensors with rank greater than 4 are not supported.");
1722  }
1723 
1724  ValidateTensorShapesMatch(inputTensorInfo, outputTensorInfo, descriptorName, "input", "output");
1725 
1726  // Check the supported data types
1727  std::vector<DataType> supportedTypes =
1728  {
1732  };
1733 
1734  ValidateDataTypes(inputTensorInfo, supportedTypes, descriptorName);
1735  ValidateTensorDataTypesMatch(inputTensorInfo, outputTensorInfo, descriptorName, "input", "output");
1736 }
1737 
1739 {
1740  const std::string descriptorName{"L2NormalizationQueueDescriptor"};
1741 
1742  ValidateNumInputs(workloadInfo, descriptorName, 1);
1743  ValidateNumOutputs(workloadInfo, descriptorName, 1);
1744 
1745  const TensorInfo& inputTensorInfo = workloadInfo.m_InputTensorInfos[0];
1746  const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];
1747 
1748  if (inputTensorInfo.GetNumDimensions() > 4)
1749  {
1750  throw InvalidArgumentException(descriptorName + ": Input tensors with rank greater than 4 are not supported.");
1751  }
1752 
1753  ValidateTensorShapesMatch(inputTensorInfo, outputTensorInfo, descriptorName, "input", "output");
1754 
1755  // Check the supported data types
1756  std::vector<DataType> supportedTypes =
1757  {
1764  };
1765 
1766  ValidateDataTypes(inputTensorInfo, supportedTypes, descriptorName);
1767  ValidateTensorDataTypesMatch(inputTensorInfo, outputTensorInfo, descriptorName, "input", "output");
1768 }
1769 
1770 void LogSoftmaxQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
1771 {
1772  const std::string descriptorName{"LogSoftmaxQueueDescriptor"};
1773 
1774  ValidateNumInputs(workloadInfo, descriptorName, 1);
1775  ValidateNumOutputs(workloadInfo, descriptorName, 1);
1776 
1777  const TensorInfo& inputTensorInfo = workloadInfo.m_InputTensorInfos[0];
1778  const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];
1779 
1780  ValidateTensorShapesMatch(inputTensorInfo, outputTensorInfo, descriptorName, "input", "output");
1781 
1782  std::vector<DataType> supportedTypes =
1783  {
1789  };
1790 
1791  ValidateDataTypes(inputTensorInfo, supportedTypes, descriptorName);
1792  ValidateTensorDataTypesMatch(inputTensorInfo, outputTensorInfo, descriptorName, "input", "output");
1793 }
1794 
1795 void ConstantQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
1796 {
1797  const std::string descriptorName{"ConstantQueueDescriptor"};
1798 
1799  ValidateNumInputs(workloadInfo, descriptorName, 0);
1800  ValidateNumOutputs(workloadInfo, descriptorName, 1);
1801 
1802  if (!m_LayerOutput)
1803  {
1804  throw InvalidArgumentException(descriptorName + ": No const input specified.");
1805  }
1806 
1807  const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];
1808  ValidateTensorShapesMatch(m_LayerOutput->GetTensorInfo(), outputTensorInfo, descriptorName, "constant", "output");
1809 
1810  // Check the supported data types
1811  std::vector<DataType> supportedTypes =
1812  {
1822  };
1823 
1824  ValidateDataTypes(outputTensorInfo, supportedTypes, descriptorName);
1825 }
1826 
1827 void ReshapeQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
1828 {
1829  const std::string descriptorName{"ReshapeQueueDescriptor"};
1830 
1831  ValidateNumInputs(workloadInfo, descriptorName, 1);
1832  ValidateNumOutputs(workloadInfo, descriptorName, 1);
1833 
1834  const TensorInfo& inputTensorInfo = workloadInfo.m_InputTensorInfos[0];
1835  const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];
1836 
1837  ValidateTensorNumElementsMatch(inputTensorInfo, outputTensorInfo, descriptorName, "input", "output");
1838 
1839  // Check the supported data types
1840  std::vector<DataType> supportedTypes =
1841  {
1850  };
1851 
1852  ValidateDataTypes(inputTensorInfo, supportedTypes, descriptorName);
1853  ValidateTensorDataTypesMatch(inputTensorInfo, outputTensorInfo, descriptorName, "input", "output");
1854 }
1855 
1857 {
1858  const std::string descriptorName{"SpaceToBatchNdQueueDescriptor"};
1859 
1860  ValidateNumInputs(workloadInfo, descriptorName, 1);
1861  ValidateNumOutputs(workloadInfo, descriptorName, 1);
1862 
1863  const TensorInfo& inputTensorInfo = workloadInfo.m_InputTensorInfos[0];
1864  const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];
1865 
1866  if (m_Parameters.m_BlockShape.size() != m_Parameters.m_PadList.size())
1867  {
1868  throw InvalidArgumentException(descriptorName + ": Pad List must contain the same number of "
1869  "dimensions as Block Shape.");
1870  }
1871 
1872  if (m_Parameters.m_BlockShape.size() == 2)
1873  {
1874  ValidateTensorNumDimensions(inputTensorInfo, descriptorName, 4, "input");
1875  ValidateTensorNumDimensions(outputTensorInfo, descriptorName, 4, "output");
1876  }
1877  else if (m_Parameters.m_BlockShape.size() == 1)
1878  {
1879  ValidateTensorNumDimensions(inputTensorInfo, descriptorName, 3, "input");
1880  ValidateTensorNumDimensions(outputTensorInfo, descriptorName, 3, "output");
1881  }
1882  else
1883  {
1884  throw InvalidArgumentException(descriptorName + ": Invalid Block and Crops size.");
1885  }
1886 
1887  // Check input + padding and output have the same number of elements
1888  DataLayoutIndexed dimensionIndices(m_Parameters.m_DataLayout);
1889  const unsigned int inputHeight = inputTensorInfo.GetShape()[dimensionIndices.GetHeightIndex()] +
1890  m_Parameters.m_PadList[0].first + m_Parameters.m_PadList[0].second;
1891  const unsigned int inputWidth = (inputTensorInfo.GetNumDimensions() == 3) ? 1 :
1892  inputTensorInfo.GetShape()[dimensionIndices.GetWidthIndex()] +
1893  m_Parameters.m_PadList[1].first + m_Parameters.m_PadList[1].second;
1894 
1895  const int channelsIndex_int = (m_Parameters.m_DataLayout == DataLayout::NCHW) ? 1 : -1;
1896  const unsigned int channelsIndex = channelsIndex_int < 0 ?
1897  static_cast<unsigned int>(channelsIndex_int) + inputTensorInfo.GetNumDimensions()
1898  : static_cast<unsigned int>(channelsIndex_int);
1899 
1900  const unsigned int numInputElements = inputTensorInfo.GetShape()[0] *
1901  inputHeight *
1902  inputWidth *
1903  inputTensorInfo.GetShape()[channelsIndex];
1904 
1905  if (outputTensorInfo.GetNumElements() != numInputElements)
1906  {
1907  throw InvalidArgumentException(descriptorName + ": Input tensor has " +
1908  to_string(numInputElements) + " after padding but output tensor has " +
1909  to_string(outputTensorInfo.GetNumElements()) + " elements.");
1910  }
1911 
1912  // In a 4D tensor, there will be 2 spatialDimensions (H and W), and the for loop will run twice.
1913  // In a 3D tensor, there will be 1 spatialDimensions, and the for loop will run once.
1914  unsigned int firstSpatialDimension = m_Parameters.m_DataLayout == DataLayout::NCHW ? 2 : 1;
1915  for (unsigned int i = 0; i < m_Parameters.m_BlockShape.size(); ++i)
1916  {
1917  unsigned int spatialDimension = firstSpatialDimension + i;
1918  auto inputSize = inputTensorInfo.GetShape()[spatialDimension] +
1919  m_Parameters.m_PadList[i].first +
1920  m_Parameters.m_PadList[i].second;
1921  if (inputSize % m_Parameters.m_BlockShape[i] != 0)
1922  {
1923  throw InvalidArgumentException(descriptorName + ": Input dimension size after padding must be "
1924  "divisible by Block Shape in dimension: " + to_string(spatialDimension) + ".");
1925  }
1926  }
1927 
1928  std::vector<DataType> supportedTypes =
1929  {
1936  };
1937 
1938  ValidateDataTypes(inputTensorInfo, supportedTypes, descriptorName);
1939  ValidateTensorDataTypesMatch(inputTensorInfo, outputTensorInfo, descriptorName, "input", "output");
1940 }
1941 
1943 {
1944  const std::string descriptorName{"SpaceToDepthQueueDescriptor"};
1945 
1946  ValidateNumInputs(workloadInfo, descriptorName, 1);
1947  ValidateNumOutputs(workloadInfo, descriptorName, 1);
1948 
1949  const TensorInfo& inputTensorInfo = workloadInfo.m_InputTensorInfos[0];
1950  const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];
1951 
1952  ValidateTensorNumDimensions(inputTensorInfo, descriptorName, 4, "input");
1953  ValidateTensorNumDimensions(outputTensorInfo, descriptorName, 4, "output");
1954 
1955  std::vector<DataType> supportedTypes =
1956  {
1965  };
1966 
1967  ValidateDataTypes(inputTensorInfo, supportedTypes, descriptorName);
1968  ValidateDataTypes(outputTensorInfo, supportedTypes, descriptorName);
1969 
1970  ValidateTensorNumElementsMatch(inputTensorInfo, outputTensorInfo, descriptorName, "input", "output");
1971 
1972  if (m_Parameters.m_BlockSize == 0)
1973  {
1974  throw InvalidArgumentException(descriptorName + ": Block size cannot be 0.");
1975  }
1976 
1977  DataLayoutIndexed dimensionIndices(m_Parameters.m_DataLayout);
1978  const unsigned int wIndex = dimensionIndices.GetWidthIndex();
1979  const unsigned int hIndex = dimensionIndices.GetHeightIndex();
1980  const unsigned int cIndex = dimensionIndices.GetChannelsIndex();
1981 
1982  const TensorShape& inputShape = inputTensorInfo.GetShape();
1983  if (inputShape[hIndex] % m_Parameters.m_BlockSize != 0 || inputShape[wIndex] % m_Parameters.m_BlockSize != 0)
1984  {
1985  throw InvalidArgumentException(descriptorName + ": Input shape must be divisible "
1986  "by block size in all spatial dimensions");
1987  }
1988 
1989  const TensorShape& outputShape = outputTensorInfo.GetShape();
1990  if (outputShape[cIndex] % (m_Parameters.m_BlockSize * m_Parameters.m_BlockSize) != 0)
1991  {
1992  throw InvalidArgumentException(descriptorName + ": The depth of the output tensor"
1993  "must be divisible by the square of block size." );
1994  }
1995 }
1996 
1997 void FloorQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
1998 {
1999  const std::string descriptorName{"FloorQueueDescriptor"};
2000 
2001  ValidateNumInputs(workloadInfo, descriptorName, 1);
2002  ValidateNumOutputs(workloadInfo, descriptorName, 1);
2003 
2004  const TensorInfo& inputTensorInfo = workloadInfo.m_InputTensorInfos[0];
2005  const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];
2006 
2007  std::vector<DataType> supportedTypes =
2008  {
2013  };
2014 
2015  ValidateDataTypes(inputTensorInfo, supportedTypes, descriptorName);
2016  ValidateTensorDataTypesMatch(inputTensorInfo, outputTensorInfo, descriptorName, "input", "output");
2017  ValidateTensorShapesMatch(inputTensorInfo, outputTensorInfo, descriptorName, "input", "output");
2018  ValidateTensorQuantizationSpace(inputTensorInfo, outputTensorInfo, descriptorName, "input", "output");
2019 }
2020 
2021 void LstmQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
2022 {
2023  // ported from android/ml/nn/common/operations/LSTM.cpp CheckInputTensorDimensions()
2024 
2025  const std::string descriptorName{"LstmQueueDescriptor"};
2026 
2027  // check dimensions of all inputs and outputs
2028  if (workloadInfo.m_InputTensorInfos.size() != 3)
2029  {
2030  throw InvalidArgumentException(descriptorName + ": Invalid number of inputs.");
2031  }
2032  if (workloadInfo.m_OutputTensorInfos.size() != 4)
2033  {
2034  throw InvalidArgumentException(descriptorName + ": Invalid number of outputs.");
2035  }
2036 
2037  std::vector<DataType> supportedTypes =
2038  {
2043  };
2044 
2045  // check for supported type of one input and match them with all the other input and output
2046  ValidateDataTypes(workloadInfo.m_InputTensorInfos[0], supportedTypes, descriptorName);
2047 
2048  // type matches all other inputs
2049  for (uint32_t i = 1u; i < workloadInfo.m_InputTensorInfos.size(); ++i)
2050  {
2051  ValidateTensorDataTypesMatch(workloadInfo.m_InputTensorInfos[0],
2052  workloadInfo.m_InputTensorInfos[i],
2053  descriptorName,
2054  "input_0",
2055  "input_" + std::to_string(i));
2056  }
2057  // type matches all other outputs
2058  for (uint32_t i = 0u; i < workloadInfo.m_OutputTensorInfos.size(); ++i)
2059  {
2060  ValidateTensorDataTypesMatch(workloadInfo.m_InputTensorInfos[0],
2061  workloadInfo.m_OutputTensorInfos[i],
2062  "LstmQueueDescriptor",
2063  "input_0",
2064  "output_" + std::to_string(i));
2065  }
2066 
2067  // Making sure clipping parameters have valid values.
2068  // == 0 means no clipping
2069  // > 0 means clipping
2070  if (m_Parameters.m_ClippingThresCell < 0.0f)
2071  {
2072  throw InvalidArgumentException(descriptorName + ": negative cell clipping threshold is invalid");
2073  }
2074  if (m_Parameters.m_ClippingThresProj < 0.0f)
2075  {
2076  throw InvalidArgumentException(descriptorName + ": negative projection clipping threshold is invalid");
2077  }
2078 
2079  // Inferring batch size, number of outputs and number of cells from the inputs.
2080  const uint32_t n_input = workloadInfo.m_InputTensorInfos[0].GetShape()[1];
2081  const uint32_t n_batch = workloadInfo.m_InputTensorInfos[0].GetShape()[0];
2082  ValidatePointer(m_InputToOutputWeights, "Null pointer check", "InputToOutputWeights");
2083  const uint32_t n_cell = m_InputToOutputWeights->GetShape()[0];
2084  ValidatePointer(m_RecurrentToOutputWeights, "Null pointer check", "RecurrentToOutputWeights");
2085  const uint32_t n_output = m_RecurrentToOutputWeights->GetShape()[1];
2086 
2087  // input tensor
2088  ValidateTensorNumDimNumElem(workloadInfo.m_InputTensorInfos[0], 2, (n_batch * n_input),
2089  descriptorName + " input_0");
2090  // outputStateInTensor
2091  ValidateTensorNumDimNumElem(workloadInfo.m_InputTensorInfos[1], 2, (n_batch * n_output),
2092  descriptorName + " input_1");
2093  // outputStateInTensor
2094  ValidateTensorNumDimNumElem(workloadInfo.m_InputTensorInfos[2], 2, (n_batch * n_cell),
2095  descriptorName + " input_2");
2096  // scratchBufferTensor
2097  unsigned int scratchBufferSize = m_Parameters.m_CifgEnabled ? n_cell * 3 : n_cell * 4;
2098  ValidateTensorNumDimNumElem(workloadInfo.m_OutputTensorInfos[0], 2, (n_batch * scratchBufferSize),
2099  descriptorName + " output_0");
2100  // outputStateOutTensor
2101  ValidateTensorNumDimNumElem(workloadInfo.m_OutputTensorInfos[1], 2, (n_batch * n_output),
2102  descriptorName + " output_1");
2103  // cellStateOutTensor
2104  ValidateTensorNumDimNumElem(workloadInfo.m_OutputTensorInfos[2], 2, (n_batch * n_cell),
2105  descriptorName + " output_2");
2106  // outputTensor
2107  ValidateTensorNumDimNumElem(workloadInfo.m_OutputTensorInfos[3], 2, (n_batch * n_output),
2108  descriptorName + " output_3");
2109 
2110  // check that dimensions of inputs/outputs and QueueDescriptor data match with each other
2111  if ( m_InputToInputWeights )
2112  {
2114  (n_cell * n_input), "InputLayerNormWeights");
2115  }
2116 
2117  ValidatePointer(m_InputToForgetWeights, "Null pointer check", "InputToForgetWeights");
2119  (n_cell * n_input), "InputToForgetWeights");
2120 
2121  ValidatePointer(m_InputToCellWeights, "Null pointer check", "InputToCellWeights");
2123  (n_cell * n_input), "InputToCellWeights");
2124 
2126  {
2128  (n_cell * n_output), "RecurrentToInputWeights");
2129  }
2130 
2131  ValidatePointer(m_RecurrentToForgetWeights, "Null pointer check", "RecurrentToForgetWeights");
2133  (n_cell * n_output), "RecurrentToForgetWeights");
2134 
2135  ValidatePointer(m_RecurrentToCellWeights, "Null pointer check", "RecurrentToCellWeights");
2137  (n_cell * n_output), "RecurrentToCellWeights");
2138 
2139  // Make sure the input-gate's parameters are either both present (regular
2140  // LSTM) or not at all (CIFG-LSTM). And CifgEnable is set accordingly.
2141  bool cifg_weights_all_or_none = ((m_InputToInputWeights && m_RecurrentToInputWeights &&
2145  if (!cifg_weights_all_or_none)
2146  {
2147  throw InvalidArgumentException(descriptorName + ": Input-Gate's parameters InputToInputWeights and "
2148  "RecurrentToInputWeights must either both be present (regular LSTM) "
2149  "or both not present (CIFG-LSTM). In addition CifgEnable must be set "
2150  "accordingly.");
2151  }
2152 
2153  if ( m_CellToInputWeights )
2154  {
2156  n_cell, "CellToInputWeights");
2157  }
2158  if ( m_CellToForgetWeights )
2159  {
2161  n_cell, "CellToForgetWeights");
2162  }
2163  if ( m_CellToOutputWeights )
2164  {
2166  n_cell, "CellToOutputWeights");
2167  }
2168 
2169  // Making sure the peephole weights are there all or none. And PeepholeEnable is set accordingly.
2170  bool peephole_weights_all_or_none =
2175  if (!peephole_weights_all_or_none)
2176  {
2177  throw InvalidArgumentException(descriptorName + ": Invalid combination of peephole parameters.");
2178  }
2179 
2180  // Make sure the input gate bias is present only when not a CIFG-LSTM.
2182  {
2183  if (m_InputGateBias)
2184  {
2185  throw InvalidArgumentException(descriptorName + ": InputGateBias is present and CIFG-LSTM is enabled.");
2186  }
2187  }
2188  else
2189  {
2190  if (!m_InputGateBias)
2191  {
2192  throw InvalidArgumentException(descriptorName + ": If CIFG-LSTM is disabled InputGateBias "
2193  "must be present.");
2194  }
2196  n_cell, "InputGateBias");
2197  }
2198 
2199  ValidatePointer(m_ForgetGateBias, "Null pointer check", "ForgetGateBias");
2200  ValidateTensorNumDimNumElem(m_ForgetGateBias->GetTensorInfo(), 1, n_cell, "ForgetGateBias");
2201 
2202  ValidatePointer(m_CellBias, "Null pointer check", "CellBias");
2203  ValidateTensorNumDimNumElem(m_CellBias->GetTensorInfo(), 1, n_cell, "CellBias");
2204 
2205  ValidatePointer(m_OutputGateBias, "Null pointer check", "OutputGateBias");
2206  ValidateTensorNumDimNumElem(m_OutputGateBias->GetTensorInfo(), 1, n_cell, "OutputGateBias");
2207 
2208  if (m_ProjectionWeights)
2209  {
2211  (n_cell * n_output), "ProjectionWeights");
2212  }
2213  if (m_ProjectionBias)
2214  {
2215  ValidateTensorNumDimNumElem(m_ProjectionBias->GetTensorInfo(), 1, n_output, "ProjectionBias");
2216  }
2217 
2218  // Making sure the projection tensors are consistent:
2219  // 1) If projection weight is not present, then projection bias should not be
2220  // present.
2221  // 2) If projection weight is present, then projection bias is optional.
2222  bool projecton_tensors_consistent = ((!m_ProjectionWeights && !m_ProjectionBias &&
2228  if (!projecton_tensors_consistent)
2229  {
2230  throw InvalidArgumentException(descriptorName + ": Projection tensors are inconsistent.");
2231  }
2232 
2233  // The four layer normalization weights either all have values or none of them have values. Additionally, if
2234  // CIFG is used, input layer normalization weights tensor is omitted and the other layer normalization weights
2235  // either all have values or none of them have values. Layer normalization is used when the values of all the
2236  // layer normalization weights are present
2238  {
2239  ValidateTensorNumDimNumElem(m_InputLayerNormWeights->GetTensorInfo(), 1, n_cell, "InputLayerNormWeights");
2240  }
2242  {
2243  ValidateTensorNumDimNumElem(m_ForgetLayerNormWeights->GetTensorInfo(), 1, n_cell, "ForgetLayerNormWeights");
2244  }
2246  {
2247  ValidateTensorNumDimNumElem(m_CellLayerNormWeights->GetTensorInfo(), 1, n_cell, "CellLayerNormWeights");
2248  }
2250  {
2251  ValidateTensorNumDimNumElem(m_OutputLayerNormWeights->GetTensorInfo(), 1, n_cell, "OutputLayerNormWeights");
2252  }
2253 
2255  {
2257  {
2259  {
2260  throw InvalidArgumentException(descriptorName + ": Layer normalisation is enabled and CIFG-LSTM is "
2261  "disabled but InputLayerNormWeights are not present");
2262  }
2264  1, n_cell, "InputLayerNormWeights");
2265  }
2266  else if (m_InputLayerNormWeights)
2267  {
2268  throw InvalidArgumentException(descriptorName + ":InputLayerNormWeights are present while CIFG is "
2269  "enabled");
2270  }
2271 
2272  ValidatePointer(m_ForgetLayerNormWeights, "Null pointer check layer normalisation enabled",
2273  "ForgetLayerNormWeights");
2274  ValidateTensorNumDimNumElem(m_ForgetLayerNormWeights->GetTensorInfo(), 1, n_cell, "ForgetLayerNormWeights");
2275 
2276  ValidatePointer(m_OutputLayerNormWeights, "Null pointer check layer normalisation enabled",
2277  "OutputLayerNormWeights");
2278  ValidateTensorNumDimNumElem(m_OutputLayerNormWeights->GetTensorInfo(), 1, n_cell, "OutputLayerNormWeights");
2279 
2280  ValidatePointer(m_CellLayerNormWeights, "Null pointer check layer normalisation enabled",
2281  "CellLayerNormWeights");
2282  ValidateTensorNumDimNumElem(m_CellLayerNormWeights->GetTensorInfo(), 1, n_cell, "CellLayerNormWeights");
2283  }
2285  {
2286  throw InvalidArgumentException(descriptorName + ": Layer normalisation is disabled but one or more layer "
2287  "normalisation weights are present.");
2288  }
2289 }
2290 
2292 {
2293  const std::string descriptorName{"ConvertFp32ToFp16QueueDescriptor"};
2294 
2295  ValidateNumInputs(workloadInfo, descriptorName, 1);
2296  ValidateNumOutputs(workloadInfo, descriptorName, 1);
2297 
2298  const TensorInfo& inputTensorInfo = workloadInfo.m_InputTensorInfos[0];
2299  const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];
2300 
2301  if (inputTensorInfo.GetDataType() != DataType::Float32)
2302  {
2303  throw InvalidArgumentException(descriptorName + ": Input tensor type must be Float32.");
2304  }
2305 
2306  if (outputTensorInfo.GetDataType() != DataType::Float16)
2307  {
2308  throw InvalidArgumentException(descriptorName + ": Output tensor type must be Float16.");
2309  }
2310 
2311  ValidateTensorShapesMatch(inputTensorInfo, outputTensorInfo, descriptorName, "input", "output");
2312 }
2313 
2315 {
2316  const std::string descriptorName{"ConvertFp16ToFp32QueueDescriptor"};
2317 
2318  ValidateNumInputs(workloadInfo, descriptorName, 1);
2319  ValidateNumOutputs(workloadInfo, descriptorName, 1);
2320 
2321  const TensorInfo& inputTensorInfo = workloadInfo.m_InputTensorInfos[0];
2322  const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];
2323 
2324  if (inputTensorInfo.GetDataType() != DataType::Float16)
2325  {
2326  throw InvalidArgumentException(descriptorName + ": Input tensor type must be Float16.");
2327  }
2328 
2329  if (outputTensorInfo.GetDataType() != DataType::Float32)
2330  {
2331  throw InvalidArgumentException(descriptorName + ": Output tensor type must be Float32.");
2332  }
2333 
2334  ValidateTensorShapesMatch(inputTensorInfo, outputTensorInfo, descriptorName, "input", "output");
2335 }
2336 
2337 void DivisionQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
2338 {
2339  const std::string descriptorName{"DivisionQueueDescriptor"};
2340 
2341  ValidateNumInputs(workloadInfo, descriptorName, 2);
2342  ValidateNumOutputs(workloadInfo, descriptorName, 1);
2343 
2344  const TensorInfo& inputTensorInfo0 = workloadInfo.m_InputTensorInfos[0];
2345  const TensorInfo& inputTensorInfo1 = workloadInfo.m_InputTensorInfos[1];
2346  const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];
2347 
2348  std::vector<DataType> supportedTypes =
2349  {
2357  };
2358 
2359  ValidateDataTypes(inputTensorInfo0, supportedTypes, descriptorName);
2360  ValidateDataTypes(inputTensorInfo1, supportedTypes, descriptorName);
2361  ValidateDataTypes(outputTensorInfo, supportedTypes, descriptorName);
2362 
2363  ValidateBroadcastTensorShapesMatch(inputTensorInfo0,
2364  inputTensorInfo1,
2365  outputTensorInfo,
2366  descriptorName,
2367  "input_0",
2368  "input_1");
2369 }
2370 
2372 {
2373  const std::string descriptorName{"SubtractionQueueDescriptor"};
2374 
2375  ValidateNumInputs(workloadInfo, descriptorName, 2);
2376  ValidateNumOutputs(workloadInfo, descriptorName, 1);
2377 
2378  const TensorInfo& inputTensorInfo0 = workloadInfo.m_InputTensorInfos[0];
2379  const TensorInfo& inputTensorInfo1 = workloadInfo.m_InputTensorInfos[1];
2380  const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];
2381 
2382  std::vector<DataType> supportedTypes =
2383  {
2391  };
2392 
2393  ValidateDataTypes(inputTensorInfo0, supportedTypes, descriptorName);
2394  ValidateDataTypes(inputTensorInfo1, supportedTypes, descriptorName);
2395  ValidateDataTypes(outputTensorInfo, supportedTypes, descriptorName);
2396 
2397  ValidateBroadcastTensorShapesMatch(inputTensorInfo0,
2398  inputTensorInfo1,
2399  outputTensorInfo,
2400  descriptorName,
2401  "input_0",
2402  "input_1");
2403 }
2404 
2405 void MaximumQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
2406 {
2407  const std::string descriptorName{"MaximumQueueDescriptor"};
2408 
2409  ValidateNumInputs(workloadInfo, descriptorName, 2);
2410  ValidateNumOutputs(workloadInfo, descriptorName, 1);
2411 
2412  const TensorInfo& inputTensorInfo0 = workloadInfo.m_InputTensorInfos[0];
2413  const TensorInfo& inputTensorInfo1 = workloadInfo.m_InputTensorInfos[1];
2414  const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];
2415 
2416  std::vector<DataType> supportedTypes =
2417  {
2425  };
2426 
2427  ValidateDataTypes(inputTensorInfo0, supportedTypes, descriptorName);
2428  ValidateDataTypes(inputTensorInfo1, supportedTypes, descriptorName);
2429  ValidateDataTypes(outputTensorInfo, supportedTypes, descriptorName);
2430 
2431  ValidateBroadcastTensorShapesMatch(inputTensorInfo0,
2432  inputTensorInfo1,
2433  outputTensorInfo,
2434  descriptorName,
2435  "input_0",
2436  "input_1");
2437 }
2438 
2439 void MeanQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
2440 {
2441  const std::string descriptorName{"MeanQueueDescriptor"};
2442 
2443  ValidateNumInputs(workloadInfo, descriptorName, 1);
2444  ValidateNumOutputs(workloadInfo, descriptorName, 1);
2445 
2446  const TensorInfo& inputTensorInfo = workloadInfo.m_InputTensorInfos[0];
2447  const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];
2448 
2449  std::vector<DataType> supportedTypes =
2450  {
2458  };
2459 
2460  // First check if input tensor data type is supported, then
2461  // check if this data type matches the output tensor data type
2462  ValidateDataTypes(inputTensorInfo, supportedTypes, descriptorName);
2463  ValidateTensorDataTypesMatch(inputTensorInfo, outputTensorInfo, descriptorName, "input", "output");
2464 
2466  {
2467  ValidateTensorNumDimensions(outputTensorInfo, descriptorName, inputTensorInfo.GetNumDimensions(), "output");
2468  }
2469  else if (m_Parameters.m_Axis.empty())
2470  {
2471  ValidateTensorNumDimensions(outputTensorInfo, descriptorName, 1, "output");
2472  }
2473  else
2474  {
2475  unsigned int outputDim =
2476  inputTensorInfo.GetNumDimensions() - armnn::numeric_cast<unsigned int>(m_Parameters.m_Axis.size());
2477  ValidateTensorNumDimensions(outputTensorInfo,
2478  descriptorName,
2479  outputDim > 0 ? outputDim : 1,
2480  "output");
2481  }
2482 }
2483 
2484 void PadQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
2485 {
2486  const std::string descriptorName{"PadQueueDescriptor"};
2487 
2488  ValidateNumInputs(workloadInfo, descriptorName, 1);
2489  ValidateNumOutputs(workloadInfo, descriptorName, 1);
2490 
2491  const TensorInfo& inputTensorInfo = workloadInfo.m_InputTensorInfos[0];
2492  const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];
2493 
2494  // input and output should have the same number of dimensions
2495  ValidateTensorNumDimensions(outputTensorInfo, descriptorName, inputTensorInfo.GetNumDimensions(), "output");
2496 
2497  // there should be entry in the pad list for each dimension in the input tensor
2498  if (m_Parameters.m_PadList.size() != inputTensorInfo.GetNumDimensions()) {
2499  throw InvalidArgumentException(descriptorName + ":Pad List should contain the same number of entries "
2500  "as there are dimensions in the input tensor that is " +
2501  std::to_string(inputTensorInfo.GetNumDimensions()) + " entries " +
2502  " not " + std::to_string(m_Parameters.m_PadList.size()) + " entries.");
2503  }
2504 }
2505 
2506 void QuantizeQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
2507 {
2508  const std::string descriptorName{"QuantizeQueueDescriptor"};
2509 
2510  ValidateNumInputs(workloadInfo, descriptorName, 1);
2511  ValidateNumOutputs(workloadInfo, descriptorName, 1);
2512 
2513  const TensorInfo& inputTensorInfo = workloadInfo.m_InputTensorInfos[0];
2514  const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];
2515 
2516  std::vector<DataType> supportedTypes =
2517  {
2525  };
2526 
2527  ValidateDataTypes(inputTensorInfo, supportedTypes, descriptorName);
2528 
2529  if (!IsQuantizedType(outputTensorInfo.GetDataType()))
2530  {
2531  throw InvalidArgumentException(descriptorName + ": Output of quantized layer must be quantized type.");
2532  }
2533 }
2534 
2536 {
2537  const std::string descriptorName{"BatchToSpaceNdQueueDescriptor"};
2538 
2539  ValidateNumInputs(workloadInfo, descriptorName, 1);
2540  ValidateNumOutputs(workloadInfo, descriptorName, 1);
2541 
2542  const TensorInfo& inputTensorInfo = workloadInfo.m_InputTensorInfos[0];
2543  const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];
2544 
2545  if (m_Parameters.m_BlockShape.size() != m_Parameters.m_Crops.size())
2546  {
2547  throw InvalidArgumentException(descriptorName + ": Crops must contain the same number of "
2548  "dimensions as Block Shape.");
2549  }
2550 
2551  if (m_Parameters.m_BlockShape.size() == 2)
2552  {
2553  ValidateTensorNumDimensions(inputTensorInfo, descriptorName, 4, "input");
2554  ValidateTensorNumDimensions(outputTensorInfo, descriptorName, 4, "output");
2555  }
2556  else if (m_Parameters.m_BlockShape.size() == 1)
2557  {
2558  ValidateTensorNumDimensions(inputTensorInfo, descriptorName, 3, "input");
2559  ValidateTensorNumDimensions(outputTensorInfo, descriptorName, 3, "output");
2560  }
2561  else
2562  {
2563  throw InvalidArgumentException(descriptorName + ": Invalid Block and Crops size.");
2564  }
2565 
2566  // In a 4D tensor, there will be 2 spatialDimensions (H and W), and the for loop will run twice.
2567  // In a 3D tensor, there will be 1 spatialDimensions, and the for loop will run once.
2568  unsigned int firstSpatialDimension = m_Parameters.m_DataLayout == DataLayout::NCHW ? 2 : 1;
2569  for (unsigned int i = 0; i < m_Parameters.m_BlockShape.size(); ++i)
2570  {
2571  unsigned int spatialDimension = firstSpatialDimension + i;
2572  unsigned int cropSize = m_Parameters.m_Crops[i].first + m_Parameters.m_Crops[i].second;
2573  unsigned int outputSize = inputTensorInfo.GetShape()[spatialDimension] * m_Parameters.m_BlockShape[i];
2574  if (cropSize > outputSize)
2575  {
2576  throw InvalidArgumentException(descriptorName + ": CropSize must be less than or equal to the uncropped"
2577  "outputSize in dimension: " + to_string(spatialDimension) + ".");
2578  }
2579  }
2580 
2581  std::vector<DataType> supportedTypes =
2582  {
2589  };
2590 
2591  ValidateDataTypes(inputTensorInfo, supportedTypes, descriptorName);
2592  ValidateTensorDataTypesMatch(inputTensorInfo, outputTensorInfo, descriptorName, "input", "output");
2593 }
2594 
2596 {
2597  const std::string descriptorName{"StridedSliceQueueDescriptor"};
2598 
2599  ValidateNumInputs(workloadInfo, descriptorName, 1);
2600  ValidateNumOutputs(workloadInfo, descriptorName, 1);
2601 
2602  const TensorInfo& inputTensorInfo = workloadInfo.m_InputTensorInfos[0];
2603  const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];
2604 
2605  std::vector<DataType> supportedTypes =
2606  {
2614  };
2615 
2616  ValidateDataTypes(inputTensorInfo, supportedTypes, descriptorName);
2617  ValidateTensorDataTypesMatch(inputTensorInfo, outputTensorInfo, descriptorName, "input", "output");
2618 
2619  ValidateTensorQuantizationSpace(inputTensorInfo, outputTensorInfo, descriptorName, "input", "output");
2620 
2621  const uint32_t rank = inputTensorInfo.GetNumDimensions();
2622  if (rank > 4)
2623  {
2624  throw InvalidArgumentException(descriptorName + ": Input tensors with rank greater than 4 are not supported.");
2625  }
2626 
2627  // Begin, End & Stride length must be of rank(input0)
2628  if (m_Parameters.m_Begin.size() != rank)
2629  {
2630  throw InvalidArgumentException(descriptorName + ": Begin length must be of rank " + std::to_string(rank));
2631  }
2632 
2633  if (m_Parameters.m_End.size() != rank)
2634  {
2635  throw InvalidArgumentException(descriptorName + ": End length must be of rank " + std::to_string(rank));
2636  }
2637 
2638  if (m_Parameters.m_Stride.size() != rank)
2639  {
2640  throw InvalidArgumentException(descriptorName + ": Stride length must be of rank " + std::to_string(rank));
2641  }
2642 
2643  // Stride entries must be non-zero
2644  for (auto& stride : m_Parameters.m_Stride)
2645  {
2646  if (stride == 0)
2647  {
2648  throw InvalidArgumentException(descriptorName + ": Stride entries must be non-zero.");
2649  }
2650  }
2651 }
2652 
2653 void MinimumQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
2654 {
2655  const std::string descriptorName{"MinimumQueueDescriptor"};
2656 
2657  ValidateNumInputs(workloadInfo, descriptorName, 2);
2658  ValidateNumOutputs(workloadInfo, descriptorName, 1);
2659 
2660  const TensorInfo& inputTensorInfo0 = workloadInfo.m_InputTensorInfos[0];
2661  const TensorInfo& inputTensorInfo1 = workloadInfo.m_InputTensorInfos[1];
2662  const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];
2663 
2664  std::vector<DataType> supportedTypes =
2665  {
2673  };
2674 
2675  ValidateDataTypes(inputTensorInfo0, supportedTypes, descriptorName);
2676  ValidateDataTypes(inputTensorInfo1, supportedTypes, descriptorName);
2677  ValidateDataTypes(outputTensorInfo, supportedTypes, descriptorName);
2678 
2679  ValidateBroadcastTensorShapesMatch(inputTensorInfo0,
2680  inputTensorInfo1,
2681  outputTensorInfo,
2682  descriptorName,
2683  "input_0",
2684  "input_1");
2685 }
2686 
2687 void DebugQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
2688 {
2689  const std::string descriptorName{"DebugQueueDescriptor"};
2690 
2691  ValidateNumInputs(workloadInfo, descriptorName, 1);
2692  ValidateNumOutputs(workloadInfo, descriptorName, 1);
2693 }
2694 
2695 void EqualQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
2696 {
2697  const std::string descriptorName{"EqualQueueDescriptor"};
2698 
2699  ValidateNumInputs(workloadInfo, descriptorName, 2);
2700  ValidateNumOutputs(workloadInfo, descriptorName, 1);
2701 
2702  const TensorInfo& inputTensorInfo0 = workloadInfo.m_InputTensorInfos[0];
2703  const TensorInfo& inputTensorInfo1 = workloadInfo.m_InputTensorInfos[1];
2704  const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];
2705 
2706  ValidateBroadcastTensorShapesMatch(inputTensorInfo0,
2707  inputTensorInfo1,
2708  outputTensorInfo,
2709  descriptorName,
2710  "input_0",
2711  "input_1");
2712 
2713  if (outputTensorInfo.GetDataType() != DataType::Boolean)
2714  {
2715  throw InvalidArgumentException(descriptorName + ": Output tensor type must be Boolean.");
2716  }
2717 }
2718 
2719 void GreaterQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
2720 {
2721  const std::string descriptorName{"GreaterQueueDescriptor"};
2722 
2723  ValidateNumInputs(workloadInfo, descriptorName, 2);
2724  ValidateNumOutputs(workloadInfo, descriptorName, 1);
2725 
2726  const TensorInfo& inputTensorInfo0 = workloadInfo.m_InputTensorInfos[0];
2727  const TensorInfo& inputTensorInfo1 = workloadInfo.m_InputTensorInfos[1];
2728  const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];
2729 
2730  ValidateBroadcastTensorShapesMatch(inputTensorInfo0,
2731  inputTensorInfo1,
2732  outputTensorInfo,
2733  descriptorName,
2734  "input_0",
2735  "input_1");
2736 
2737  if (outputTensorInfo.GetDataType() != DataType::Boolean)
2738  {
2739  throw InvalidArgumentException(descriptorName + ": Output tensor type must be Boolean.");
2740  }
2741 }
2742 
2743 void RsqrtQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
2744 {
2745  const std::string descriptorName{"RsqrtQueueDescriptor"};
2746 
2747  ValidateNumInputs(workloadInfo, descriptorName, 1);
2748  ValidateNumOutputs(workloadInfo, descriptorName, 1);
2749 
2750  const TensorInfo& inputTensorInfo = workloadInfo.m_InputTensorInfos[0];
2751  const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];
2752 
2753  ValidateTensorShapesMatch(inputTensorInfo, outputTensorInfo, descriptorName, "input", "output");
2754 
2755  std::vector<DataType> supportedTypes =
2756  {
2763  };
2764 
2765  ValidateDataTypes(inputTensorInfo, supportedTypes, descriptorName);
2766  ValidateTensorDataTypesMatch(inputTensorInfo, outputTensorInfo, descriptorName, "input", "output");
2767 }
2768 
2769 void GatherNdQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
2770 {
2771  const std::string descriptorName{"GatherNdQueueDescriptor"};
2772 
2773  ValidateNumInputs(workloadInfo, descriptorName, 2);
2774  ValidateNumOutputs(workloadInfo, descriptorName, 1);
2775 
2776  const TensorInfo& indicesTensorInfo = workloadInfo.m_InputTensorInfos[1];
2777  if (indicesTensorInfo.GetDataType() != DataType::Signed32)
2778  {
2779  throw InvalidArgumentException(descriptorName + ": Indices tensor type must be Int32.");
2780  }
2781 
2782  const TensorInfo& inputTensorInfo = workloadInfo.m_InputTensorInfos[0];
2783  const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];
2784 
2785  std::vector<DataType> supportedTypes =
2786  {
2795  };
2796 
2797  ValidateDataTypes(inputTensorInfo, supportedTypes, descriptorName);
2798 
2799  ValidateTensorDataTypesMatch(inputTensorInfo, outputTensorInfo, descriptorName, "input", "output");
2800 
2801  unsigned int outputDim = outputTensorInfo.GetNumDimensions();
2802  ValidateTensorNumDimensions(outputTensorInfo, descriptorName, outputDim, "output");
2803 }
2804 
2805 void GatherQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
2806 {
2807  const std::string descriptorName{"GatherQueueDescriptor"};
2808 
2809  ValidateNumInputs(workloadInfo, descriptorName, 2);
2810  ValidateNumOutputs(workloadInfo, descriptorName, 1);
2811 
2812  const TensorInfo& indicesTensorInfo = workloadInfo.m_InputTensorInfos[1];
2813  if (indicesTensorInfo.GetDataType() != DataType::Signed32)
2814  {
2815  throw InvalidArgumentException(descriptorName + ": Indices tensor type must be Int32.");
2816  }
2817 
2818  const TensorInfo& inputTensorInfo = workloadInfo.m_InputTensorInfos[0];
2819  const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];
2820 
2821  std::vector<DataType> supportedTypes =
2822  {
2831  };
2832 
2833  ValidateDataTypes(inputTensorInfo, supportedTypes, descriptorName);
2834 
2835  ValidateTensorDataTypesMatch(inputTensorInfo, outputTensorInfo, descriptorName, "input", "output");
2836 
2837  unsigned int outputDim = inputTensorInfo.GetNumDimensions() + indicesTensorInfo.GetNumDimensions() - 1;
2838  ValidateTensorNumDimensions(outputTensorInfo, descriptorName, outputDim, "output");
2839 }
2840 
2842 {
2843  const std::string& descriptorName{"DetectionPostProcessQueueDescriptor"};
2844 
2845  ValidateNumInputs(workloadInfo, descriptorName, 2);
2846 
2847  if (workloadInfo.m_OutputTensorInfos.size() != 4)
2848  {
2849  throw InvalidArgumentException(descriptorName + ": Requires exactly four outputs. " +
2850  to_string(workloadInfo.m_OutputTensorInfos.size()) + " has been provided.");
2851  }
2852 
2853  if (m_Anchors == nullptr)
2854  {
2855  throw InvalidArgumentException(descriptorName + ": Anchors tensor descriptor is missing.");
2856  }
2857 
2858  const TensorInfo& boxEncodingsInfo = workloadInfo.m_InputTensorInfos[0];
2859  const TensorInfo& scoresInfo = workloadInfo.m_InputTensorInfos[1];
2860  const TensorInfo& anchorsInfo = m_Anchors->GetTensorInfo();
2861 
2862  const TensorInfo& detectionBoxesInfo = workloadInfo.m_OutputTensorInfos[0];
2863  const TensorInfo& detectionClassesInfo = workloadInfo.m_OutputTensorInfos[1];
2864  const TensorInfo& detectionScoresInfo = workloadInfo.m_OutputTensorInfos[2];
2865  const TensorInfo& numDetectionsInfo = workloadInfo.m_OutputTensorInfos[3];
2866 
2867  ValidateTensorNumDimensions(boxEncodingsInfo, descriptorName, 3, "box encodings");
2868  ValidateTensorNumDimensions(scoresInfo, descriptorName, 3, "scores");
2869  ValidateTensorNumDimensions(anchorsInfo, descriptorName, 2, "anchors");
2870 
2871  const std::vector<DataType> supportedInputTypes =
2872  {
2879  };
2880 
2881  ValidateDataTypes(boxEncodingsInfo, supportedInputTypes, descriptorName);
2882  ValidateDataTypes(scoresInfo, supportedInputTypes, descriptorName);
2883  ValidateDataTypes(anchorsInfo, supportedInputTypes, descriptorName);
2884 
2885  ValidateTensorNumDimensions(detectionBoxesInfo, descriptorName, 3, "detection boxes");
2886  ValidateTensorNumDimensions(detectionScoresInfo, descriptorName, 2, "detection scores");
2887  ValidateTensorNumDimensions(detectionClassesInfo, descriptorName, 2, "detection classes");
2888  ValidateTensorNumDimensions(numDetectionsInfo, descriptorName, 1, "num detections");
2889 
2890  // NOTE: Output is always Float32 regardless of input type
2891  ValidateTensorDataType(detectionBoxesInfo, DataType::Float32, descriptorName, "detection boxes");
2892  ValidateTensorDataType(detectionScoresInfo, DataType::Float32, descriptorName, "detection scores");
2893  ValidateTensorDataType(detectionClassesInfo, DataType::Float32, descriptorName, "detection classes");
2894  ValidateTensorDataType(numDetectionsInfo, DataType::Float32, descriptorName, "num detections");
2895 
2897  {
2898  throw InvalidArgumentException(descriptorName + ": Intersection over union threshold "
2899  "must be positive and less than or equal to 1.");
2900  }
2901 
2902  if (scoresInfo.GetShape()[2] != m_Parameters.m_NumClasses + 1)
2903  {
2904  throw InvalidArgumentException(descriptorName + ": Number of classes with background "
2905  "should be equal to number of classes + 1.");
2906  }
2907 }
2908 
2909 void DequantizeQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
2910 {
2911  const std::string& descriptorName{"DequantizeQueueDescriptor"};
2912 
2913  ValidateNumInputs(workloadInfo, descriptorName, 1);
2914  ValidateNumOutputs(workloadInfo, descriptorName, 1);
2915 
2916  const TensorInfo& inputTensorInfo = workloadInfo.m_InputTensorInfos[0];
2917  const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];
2918 
2919  std::vector<DataType> inputSupportedTypes =
2920  {
2926  };
2927  ValidateDataTypes(inputTensorInfo, inputSupportedTypes, descriptorName);
2928 
2929  std::vector<DataType> outputSupportedTypes =
2930  {
2934  };
2935 
2936  ValidateDataTypes(outputTensorInfo, outputSupportedTypes, descriptorName);
2937 }
2938 
2939 void MergeQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
2940 {
2941  const std::string& descriptorName{"MergeQueueDescriptor"};
2942 
2943  ValidateNumInputs(workloadInfo, descriptorName, 2);
2944  ValidateNumOutputs(workloadInfo, descriptorName, 1);
2945 
2946  const TensorInfo& inputTensorInfo0 = workloadInfo.m_InputTensorInfos[0];
2947  const TensorInfo& inputTensorInfo1 = workloadInfo.m_InputTensorInfos[1];
2948  const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];
2949 
2950  ValidateTensorShapesMatch(inputTensorInfo0, inputTensorInfo1, descriptorName, "input_0", "input_1");
2951  ValidateTensorShapesMatch(inputTensorInfo0, outputTensorInfo, descriptorName, "input_0", "output");
2952 
2953  ValidateTensorDataTypesMatch(inputTensorInfo0, inputTensorInfo1, descriptorName, "input_0", "input_1");
2954  ValidateTensorDataTypesMatch(inputTensorInfo0, outputTensorInfo, descriptorName, "input_0", "output");
2955 }
2956 
2957 void ShapeQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
2958 {
2959  const std::string& descriptorName{"ShapeQueueDescriptor"};
2960 
2961  ValidateNumInputs(workloadInfo, descriptorName, 1);
2962  ValidateNumOutputs(workloadInfo, descriptorName, 1);
2963 
2964  const TensorInfo& inputTensorInfo = workloadInfo.m_InputTensorInfos[0];
2965  const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];
2966 
2967  std::vector<DataType> supportedTypes =
2968  {
2977  };
2978 
2979  ValidateDataTypes(inputTensorInfo, supportedTypes, descriptorName);
2980  ValidateDataTypes(outputTensorInfo, {DataType::Signed32}, descriptorName);
2981 }
2982 
2983 void SwitchQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
2984 {
2985  const std::string& descriptorName{"SwitchQueueDescriptor"};
2986 
2987  ValidateNumInputs(workloadInfo, descriptorName, 2);
2988  ValidateNumOutputs(workloadInfo, descriptorName, 2);
2989 
2990  const TensorInfo& inputTensorInfo0 = workloadInfo.m_InputTensorInfos[0];
2991  const TensorInfo& inputTensorInfo1 = workloadInfo.m_InputTensorInfos[1];
2992 
2993  const TensorInfo& outputTensorInfo0 = workloadInfo.m_OutputTensorInfos[0];
2994  const TensorInfo& outputTensorInfo1 = workloadInfo.m_OutputTensorInfos[1];
2995 
2996  std::vector<DataType> supportedTypes =
2997  {
3003  };
3004 
3005  ValidateDataTypes(inputTensorInfo0, supportedTypes, descriptorName);
3006  ValidateDataTypes(inputTensorInfo1, supportedTypes, descriptorName);
3007 
3008  ValidateDataTypes(outputTensorInfo0, supportedTypes, descriptorName);
3009  ValidateDataTypes(outputTensorInfo1, supportedTypes, descriptorName);
3010 
3011  ValidateTensorShapesMatch(inputTensorInfo0,
3012  outputTensorInfo0,
3013  descriptorName,
3014  "input_0",
3015  "output_0");
3016 
3017  ValidateTensorShapesMatch(inputTensorInfo0,
3018  outputTensorInfo1,
3019  descriptorName,
3020  "input_0",
3021  "output_1");
3022 }
3023 
3024 void PreCompiledQueueDescriptor::Validate(const WorkloadInfo& /*workloadInfo*/) const
3025 {
3026  // This is internally generated, so it should not need validation.
3027 }
3028 
3029 void PreluQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
3030 {
3031  const std::string& descriptorName{"PreluQueueDescriptor"};
3032 
3033  ValidateNumInputs(workloadInfo, descriptorName, 2);
3034  ValidateNumOutputs(workloadInfo, descriptorName, 1);
3035 
3036  const TensorInfo& inputTensorInfo = workloadInfo.m_InputTensorInfos[0];
3037  const TensorInfo& alphaTensorInfo = workloadInfo.m_InputTensorInfos[1];
3038  const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];
3039 
3040  std::vector<DataType> supportedTypes
3041  {
3048  };
3049 
3050  ValidateDataTypes(inputTensorInfo, supportedTypes, descriptorName);
3051  ValidateDataTypes(alphaTensorInfo, supportedTypes, descriptorName);
3052 
3053  ValidateDataTypes(outputTensorInfo, supportedTypes, descriptorName);
3054 
3055  ValidateTensorDataTypesMatch(inputTensorInfo, alphaTensorInfo, descriptorName, "input", "alpha");
3056  ValidateTensorDataTypesMatch(inputTensorInfo, outputTensorInfo, descriptorName, "input", "ouptut");
3057 
3058  ValidateBroadcastTensorShapesMatch(inputTensorInfo,
3059  alphaTensorInfo,
3060  outputTensorInfo,
3061  descriptorName,
3062  "input",
3063  "alpha");
3064 }
3065 
3067 {
3068  const std::string descriptorName{"TransposeConvolution2dQueueDescriptor"};
3069 
3070  ValidateNumInputs(workloadInfo, descriptorName, 1);
3071  ValidateNumOutputs(workloadInfo, descriptorName, 1);
3072 
3073  const TensorInfo& inputTensorInfo = workloadInfo.m_InputTensorInfos[0];
3074  const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];
3075 
3076  ValidateTensorNumDimensions(inputTensorInfo, descriptorName, 4, "input");
3077  ValidateTensorNumDimensions(outputTensorInfo, descriptorName, 4, "output");
3078 
3079  ValidatePointer(m_Weight, descriptorName, "weight");
3080 
3081  const TensorInfo& weightTensorInfo = m_Weight->GetTensorInfo();
3082  ValidateTensorNumDimensions(weightTensorInfo, descriptorName, 4, "weight");
3083 
3084  ValidateWeightDataType(inputTensorInfo, weightTensorInfo, descriptorName);
3085 
3086  Optional<TensorInfo> optionalBiasTensorInfo;
3088  {
3089  ValidatePointer(m_Bias, descriptorName, "bias");
3090 
3091  optionalBiasTensorInfo = MakeOptional<TensorInfo>(m_Bias->GetTensorInfo());
3092  const TensorInfo& biasTensorInfo = optionalBiasTensorInfo.value();
3093 
3094  ValidateTensorDataType(biasTensorInfo, GetBiasDataType(inputTensorInfo.GetDataType()), descriptorName, "bias");
3095  ValidateBiasTensorQuantization(biasTensorInfo, weightTensorInfo, descriptorName);
3096  }
3097 
3098  ValidatePerAxisQuantization(inputTensorInfo,
3099  outputTensorInfo,
3100  weightTensorInfo,
3101  optionalBiasTensorInfo,
3102  descriptorName);
3103 
3104  std::vector<DataType> supportedTypes =
3105  {
3112  };
3113 
3114  ValidateDataTypes(inputTensorInfo, supportedTypes, descriptorName);
3115  ValidateTensorDataTypesMatch(inputTensorInfo, outputTensorInfo, descriptorName, "input", "output");
3116 }
3117 
3118 void TransposeQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
3119 {
3120  const std::string descriptorName{"TransposeQueueDescriptor"};
3121 
3122  ValidateNumInputs(workloadInfo, descriptorName, 1);
3123  ValidateNumOutputs(workloadInfo, descriptorName, 1);
3124 
3125  const PermutationVector& mapping = m_Parameters.m_DimMappings;
3126 
3127  const TensorInfo& inputTensorInfo = workloadInfo.m_InputTensorInfos[0];
3128  const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];
3129 
3130  ValidateTensorNumDimensions(inputTensorInfo, descriptorName, mapping.GetSize(), "input");
3131  ValidateTensorNumDimensions(outputTensorInfo, descriptorName, mapping.GetSize(), "output");
3132 
3133  for (unsigned int i = 0u; i < mapping.GetSize(); ++i)
3134  {
3135  if (inputTensorInfo.GetShape()[mapping[i]] != outputTensorInfo.GetShape()[i])
3136  {
3137  throw InvalidArgumentException(descriptorName + ": src dimension " + to_string(mapping[i]) +
3138  " (=" + to_string(inputTensorInfo.GetShape()[mapping[i]]) + ") " +
3139  "must match dst dimension " + to_string(i) +
3140  " (=" + to_string(outputTensorInfo.GetShape()[i]) + ")");
3141  }
3142  }
3143 
3144  ValidateTensorDataTypesMatch(inputTensorInfo, outputTensorInfo, descriptorName, "input", "output");
3145 }
3146 
3148 {
3149  const std::string descriptorName{"TransposeQueueDescriptor"};
3150 
3151  ValidateNumInputs(workloadInfo, descriptorName, 1);
3152  ValidateNumOutputs(workloadInfo, descriptorName, 1);
3153 
3154  const TensorInfo& inputTensorInfo = workloadInfo.m_InputTensorInfos[0];
3155  const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];
3156 
3157  ValidateTensorDataTypesMatch(inputTensorInfo, outputTensorInfo, descriptorName, "input", "output");
3158 }
3159 
3160 void QLstmQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
3161 {
3162  const std::string descriptorName{"QLstmQueueDescriptor"};
3163 
3164  // Validate number of inputs/outputs
3165  ValidateNumInputs(workloadInfo, descriptorName, 3);
3166  ValidateNumOutputs(workloadInfo, descriptorName, 3);
3167 
3168  // Input/output tensor info
3169  auto inputInfo = workloadInfo.m_InputTensorInfos[0];
3170  auto outputStateInInfo = workloadInfo.m_InputTensorInfos[1];
3171  auto cellStateInInfo = workloadInfo.m_InputTensorInfos[2];
3172 
3173  auto outputStateOutInfo = workloadInfo.m_OutputTensorInfos[0];
3174  auto cellStateOutInfo = workloadInfo.m_OutputTensorInfos[1];
3175  auto outputInfo = workloadInfo.m_OutputTensorInfos[2];
3176 
3177  // Supported types for various tensors in QLSTM
3178  std::vector<DataType> inputOutputSupportedTypes =
3179  {
3181  };
3182 
3183  std::vector<DataType> cellStateSupportedTypes =
3184  {
3186  };
3187 
3188  std::vector<DataType> weightsSupportedTypes =
3189  {
3191  };
3192 
3193  std::vector<DataType> layerNormPeepholeWeightsSupportedTypes =
3194  {
3196  };
3197 
3198  std::vector<DataType> biasSupportedTypes =
3199  {
3201  };
3202 
3203  // Validate types of input/output tensors
3204  ValidateDataTypes(inputInfo, inputOutputSupportedTypes, descriptorName);
3205  ValidateDataTypes(outputStateInInfo, inputOutputSupportedTypes, descriptorName);
3206  ValidateDataTypes(cellStateInInfo, cellStateSupportedTypes, descriptorName);
3207 
3208  ValidateDataTypes(outputStateOutInfo, inputOutputSupportedTypes, descriptorName);
3209  ValidateDataTypes(cellStateOutInfo, cellStateSupportedTypes, descriptorName);
3210  ValidateDataTypes(outputInfo, inputOutputSupportedTypes, descriptorName);
3211 
3212  // Validate matching types of input/output tensors
3213  ValidateTensorDataTypesMatch(inputInfo, outputStateInInfo, descriptorName, "input", "outputStateIn");
3214  ValidateTensorDataTypesMatch(outputStateInInfo, outputStateOutInfo, descriptorName,
3215  "outputStateIn", "outputStateOut");
3216  ValidateTensorDataTypesMatch(cellStateInInfo, cellStateOutInfo, descriptorName, "cellStateIn", "cellStateOut");
3217 
3218  // Infer number of batches, number of units, input size and output size from tensor dimensions
3219  const uint32_t numBatches = inputInfo.GetShape()[0];
3220  const uint32_t inputSize = inputInfo.GetShape()[1];
3221  const uint32_t outputSize = outputStateInInfo.GetShape()[1];
3222  const uint32_t numUnits = cellStateInInfo.GetShape()[1];
3223 
3224  // Validate number of dimensions and number of elements for input/output tensors
3225  ValidateTensorNumDimNumElem(inputInfo, 2, (numBatches * inputSize), descriptorName + " input");
3226  ValidateTensorNumDimNumElem(outputStateInInfo, 2, (numBatches * outputSize), descriptorName + " outputStateIn");
3227  ValidateTensorNumDimNumElem(cellStateInInfo, 2, (numBatches * numUnits), descriptorName + " cellStateIn");
3228 
3229  ValidateTensorNumDimNumElem(outputStateOutInfo, 2, (numBatches * outputSize), descriptorName + " outputStateOut");
3230  ValidateTensorNumDimNumElem(cellStateOutInfo, 2, (numBatches * numUnits), descriptorName + " cellStateOut");
3231  ValidateTensorNumDimNumElem(outputInfo, 2, (numBatches * outputSize), descriptorName + " output");
3232 
3233  // Validate number of dimensions and number of elements for MANDATORY weight tensors
3234  ValidatePointer(m_InputToForgetWeights, descriptorName, "InputToForgetWeights");
3235  auto inputToForgetWeightsInfo = m_InputToForgetWeights->GetTensorInfo();
3236  ValidateTensorNumDimNumElem(inputToForgetWeightsInfo, 2, (numUnits * inputSize), " InputToForgetWeights");
3237 
3238  ValidatePointer(m_InputToCellWeights, descriptorName, "InputToCellWeights");
3239  auto inputToCellWeightsInfo = m_InputToCellWeights->GetTensorInfo();
3240  ValidateTensorNumDimNumElem(inputToCellWeightsInfo, 2, (numUnits * inputSize), " InputToCellWeights");
3241 
3242  ValidatePointer(m_InputToOutputWeights, descriptorName, "InputToOutputWeights");
3243  auto inputToOutputWeightsInfo = m_InputToOutputWeights->GetTensorInfo();
3244  ValidateTensorNumDimNumElem(inputToOutputWeightsInfo, 2, (numUnits * inputSize), " InputToOutputWeights");
3245 
3246  ValidatePointer(m_RecurrentToForgetWeights, descriptorName, "RecurrentToForgetWeights");
3247  auto recurrentToForgetWeightsInfo = m_RecurrentToForgetWeights->GetTensorInfo();
3248  ValidateTensorNumDimNumElem(recurrentToForgetWeightsInfo, 2, (numUnits * outputSize),
3249  " RecurrentToForgetWeights");
3250 
3251  ValidatePointer(m_RecurrentToCellWeights, descriptorName, "RecurrentToCellWeights");
3252  auto recurrentToCellWeightsInfo = m_RecurrentToCellWeights->GetTensorInfo();
3253  ValidateTensorNumDimNumElem(recurrentToCellWeightsInfo, 2, (numUnits * outputSize), " RecurrentToCellWeights");
3254 
3255  ValidatePointer(m_RecurrentToOutputWeights, descriptorName, "RecurrentToOutputWeights");
3256  auto recurrentToOutputWeightsInfo = m_RecurrentToOutputWeights->GetTensorInfo();
3257  ValidateTensorNumDimNumElem(recurrentToOutputWeightsInfo, 2, (numUnits * outputSize), " RecurrentToCellWeights");
3258 
3259  // Validate data types for MANDATORY weights tensors (all should match each other)
3260  ValidateDataTypes(inputToForgetWeightsInfo, weightsSupportedTypes, descriptorName);
3261 
3262  ValidateTensorDataTypesMatch(inputToForgetWeightsInfo, inputToCellWeightsInfo, descriptorName,
3263  "inputToForgetWeights", "inputToCellWeights");
3264  ValidateTensorDataTypesMatch(inputToForgetWeightsInfo, inputToOutputWeightsInfo, descriptorName,
3265  "inputToForgetWeights", "inputToOutputWeights");
3266 
3267  ValidateTensorDataTypesMatch(inputToForgetWeightsInfo, recurrentToForgetWeightsInfo, descriptorName,
3268  "inputToForgetWeights", "recurrentToForgeteights");
3269  ValidateTensorDataTypesMatch(inputToForgetWeightsInfo, recurrentToCellWeightsInfo, descriptorName,
3270  "inputToForgetWeights", "recurrentToCellWeights");
3271  ValidateTensorDataTypesMatch(inputToForgetWeightsInfo, recurrentToOutputWeightsInfo, descriptorName,
3272  "inputToForgetWeights", "recurrentToOutputWeights");
3273 
3274  // Validate number of dimensions and number of elements for MANDATORY bias tensors
3275  ValidatePointer(m_ForgetGateBias, descriptorName, "ForgetGateBias");
3276  auto forgetGateBiasInfo = m_ForgetGateBias->GetTensorInfo();
3277  ValidateTensorNumDimNumElem(forgetGateBiasInfo, 1, numUnits, " ForgetGateBias");
3278 
3279  ValidatePointer(m_CellBias, descriptorName, "CellBias");
3280  auto cellBiasInfo = m_CellBias->GetTensorInfo();
3281  ValidateTensorNumDimNumElem(cellBiasInfo, 1, numUnits, " CellBias");
3282 
3283  ValidatePointer(m_OutputGateBias, descriptorName, "OutputGateBias");
3284  auto outputGateBiasInfo = m_OutputGateBias->GetTensorInfo();
3285  ValidateTensorNumDimNumElem(outputGateBiasInfo, 1, numUnits, " OutputGateBias");
3286 
3287  // Validate data types for MANDATORY bias tensors
3288  ValidateDataTypes(forgetGateBiasInfo, biasSupportedTypes, descriptorName);
3289 
3290  ValidateTensorDataTypesMatch(forgetGateBiasInfo, cellBiasInfo, descriptorName,
3291  "forgetGateBias", "cellBias");
3292  ValidateTensorDataTypesMatch(forgetGateBiasInfo, outputGateBiasInfo, descriptorName,
3293  "forgetGateBias", "outputGateBias");
3294 
3295  // Validate OPTIONAL params: CIFG (inputToInputWeights, recurrentToInputWeights, inputGateBias)
3296  const bool allCifgParamsPresentOrNot = ((m_InputToInputWeights && m_RecurrentToInputWeights && m_InputGateBias &&
3300 
3301  if (!allCifgParamsPresentOrNot)
3302  {
3303  throw InvalidArgumentException(descriptorName +
3304  ": InputToInputWeights, RecurrentToInputWeights and InputGateBias must either all be present "
3305  "(CIFG disabled) or not be present at all (CIFG enabled). m_Parameters.m_CifgEnabled should be "
3306  "set appropriately.");
3307  }
3308 
3310  {
3311  // Validate number of dimensions and number of elements
3312  auto inputToInputWeightsInfo = m_InputToInputWeights->GetTensorInfo();
3313  ValidateTensorNumDimNumElem(inputToInputWeightsInfo, 2, (numUnits * inputSize), " InputToInputWeights");
3314 
3315  auto recurrentToInputWeightsInfo = m_RecurrentToInputWeights->GetTensorInfo();
3316  ValidateTensorNumDimNumElem(recurrentToInputWeightsInfo, 2, (numUnits * outputSize),
3317  " RecurrentToInputWeights");
3318 
3319  auto inputGateBiasInfo = m_InputGateBias->GetTensorInfo();
3320  ValidateTensorNumDimNumElem(inputGateBiasInfo, 1, numUnits, " InputGateBias");
3321 
3322  // Validate data types
3323  ValidateTensorDataTypesMatch(inputToForgetWeightsInfo, inputToInputWeightsInfo, descriptorName,
3324  "inputToForgetWeights", "inputToInputWeights");
3325  ValidateTensorDataTypesMatch(inputToForgetWeightsInfo, recurrentToInputWeightsInfo, descriptorName,
3326  "inputToForgetWeights", "recurrentToInputWeights");
3327  ValidateTensorDataTypesMatch(forgetGateBiasInfo, inputGateBiasInfo, descriptorName,
3328  "forgetGateBias", "inputGateBias");
3329  }
3330 
3331  // Validate OPTIONAL params: Peephole (cellToInputWeights, cellToForgetWeights, cellToOutputWeights)
3332  bool allPeepholeWeightsPresentOrNot =
3337 
3338  if (!allPeepholeWeightsPresentOrNot)
3339  {
3340  throw InvalidArgumentException(descriptorName +
3341  ": CellToInputWeights, CellToForgetWeights and CellToOutputWeights should all be present (Peephole "
3342  "enabled) or not be present at all (Peephole disabled). CellToInputWeights should only be present "
3343  "when Peephole is enabled and CIFG is disabled. m_Parameters.m_PeepholeEnabled should be set "
3344  "appropriately.");
3345  }
3346 
3348  {
3349  auto cellToForgetWeightsInfo = m_CellToForgetWeights->GetTensorInfo();
3350  ValidateTensorNumDimNumElem(cellToForgetWeightsInfo, 1, numUnits, " cellToForgetWeights");
3351  ValidateDataTypes(cellToForgetWeightsInfo, layerNormPeepholeWeightsSupportedTypes, descriptorName);
3352 
3353  auto cellToOutputWeightsInfo = m_CellToOutputWeights->GetTensorInfo();
3354  ValidateTensorNumDimNumElem(cellToOutputWeightsInfo, 1, numUnits, " cellToOutputWeights");
3355  ValidateTensorDataTypesMatch(cellToForgetWeightsInfo, cellToOutputWeightsInfo, descriptorName,
3356  "cellToForgetWeight", "cellToOutputWeights");
3357 
3359  {
3360  auto cellToInputWeightsInfo = m_CellToInputWeights->GetTensorInfo();
3361  ValidateTensorNumDimNumElem(cellToInputWeightsInfo, 1, numUnits, " cellToInputWeights");
3362  ValidateTensorDataTypesMatch(cellToForgetWeightsInfo, cellToInputWeightsInfo, descriptorName,
3363  "cellToForgetWeights", "cellToInputWeights");
3364  }
3365  }
3366 
3367  // Validate OPTIONAL params: Layer Norm Weights
3368  bool allLayerNormWeightsPresentOrNot =
3373 
3374  if (!allLayerNormWeightsPresentOrNot)
3375  {
3376  throw InvalidArgumentException(descriptorName +
3377  ": InputLayerNormWeights, ForgetLayerNormWeights, m_OutputLayerNormWeights "
3378  "and CellLayerNormWeights should all be present (Layer Norm enabled) or not "
3379  "be present at all (Layer Norm disabled). InputLayerNormWeights should "
3380  "only be present when Layer Norm is enabled and CIFG is disabled. "
3381  "m_Parameters.m_LayerNormEnabled should be set appropriately.");
3382  }
3383 
3385  {
3386  auto forgetLayerNormWeightsInfo = m_ForgetLayerNormWeights->GetTensorInfo();
3387  ValidateTensorNumDimNumElem(forgetLayerNormWeightsInfo, 1, numUnits, " forgetLayerNormWeights");
3388  ValidateDataTypes(forgetLayerNormWeightsInfo, layerNormPeepholeWeightsSupportedTypes, descriptorName);
3389 
3390  auto cellLayerNormWeightsInfo = m_CellLayerNormWeights->GetTensorInfo();
3391  ValidateTensorNumDimNumElem(cellLayerNormWeightsInfo, 1, numUnits, " cellLayerNormWeights");
3392  ValidateTensorDataTypesMatch(forgetLayerNormWeightsInfo, cellLayerNormWeightsInfo, descriptorName,
3393  "forgetLayerNormWeights", "cellLayerNormWeights");
3394 
3395  auto outputLayerNormWeightsInfo = m_OutputLayerNormWeights->GetTensorInfo();
3396  ValidateTensorNumDimNumElem(outputLayerNormWeightsInfo, 1, numUnits, " outputLayerNormWeights");
3397  ValidateTensorDataTypesMatch(forgetLayerNormWeightsInfo, outputLayerNormWeightsInfo, descriptorName,
3398  "forgetLayerNormWeights", "outputLayerNormWeights");
3399 
3401  {
3402  auto inputLayerNormWeightsInfo = m_InputLayerNormWeights->GetTensorInfo();
3403  ValidateTensorNumDimNumElem(inputLayerNormWeightsInfo, 1, numUnits, " inputLayerNormWeights");
3404  ValidateTensorDataTypesMatch(forgetLayerNormWeightsInfo, inputLayerNormWeightsInfo, descriptorName,
3405  "forgetLayerNormWeights", "inputLayerNormWeights");
3406  }
3407  }
3408 
3409  // Validate OPTIONAL params: Projection (projectionWeights, projectionBias)
3410  bool correctProjectionTensorsPresent =
3414 
3415  if (!correctProjectionTensorsPresent)
3416  {
3417  throw InvalidArgumentException(descriptorName +
3418  ": If projection is enabled, ProjectionWeights should be present and "
3419  "ProjectionBias is optional. If projection is disabled, neither "
3420  "ProjectionWeights nor ProjectionBias should be present.");
3421  }
3422 
3424  {
3425  auto projectionWeightsInfo = m_ProjectionWeights->GetTensorInfo();
3426  ValidateTensorNumDimNumElem(projectionWeightsInfo, 2, (numUnits * outputSize), "ProjectionWeights");
3427  ValidateDataTypes(projectionWeightsInfo, weightsSupportedTypes, descriptorName);
3428 
3429  if (m_ProjectionBias)
3430  {
3431  auto projectionBiasInfo = m_ProjectionBias->GetTensorInfo();
3432  ValidateTensorNumDimNumElem(projectionBiasInfo, 1, outputSize, "ProjectionBias");
3433  ValidateDataTypes(projectionBiasInfo, biasSupportedTypes, descriptorName);
3434  }
3435 
3436  }
3437  else if ((outputInfo.GetQuantizationScale() != m_Parameters.m_HiddenStateScale) &&
3439  throw InvalidArgumentException(descriptorName +
3440  ": If projection is disabled, output quantization info (scale, offset) "
3441  "should match HiddenStateScale and HiddenStateZeroPoint.");
3442  }
3443 
3444 }
3445 
3447 {
3448  const std::string descriptorName{"QuantizedLstmQueueDescriptor"};
3449 
3450  // Validate number of inputs/outputs
3451  ValidateNumInputs(workloadInfo, descriptorName, 3);
3452  ValidateNumOutputs(workloadInfo, descriptorName, 2);
3453 
3454  // Input/output tensor infos
3455  auto inputInfo = workloadInfo.m_InputTensorInfos[0];
3456  auto cellStateInInfo = workloadInfo.m_InputTensorInfos[1];
3457  auto outputStateInInfo = workloadInfo.m_InputTensorInfos[2];
3458 
3459  auto cellStateOutInfo = workloadInfo.m_OutputTensorInfos[0];
3460  auto outputStateOutInfo = workloadInfo.m_OutputTensorInfos[1];
3461 
3462  std::vector<DataType> inputOutputSupportedTypes =
3463  {
3465  };
3466 
3467  std::vector<DataType> cellStateSupportedTypes =
3468  {
3470  };
3471 
3472  std::vector<DataType> weightsSupportedTypes =
3473  {
3475  };
3476 
3477  std::vector<DataType> biasSupportedTypes =
3478  {
3480  };
3481 
3482  // Validate types of input/output tensors
3483  ValidateDataTypes(inputInfo, inputOutputSupportedTypes, descriptorName);
3484  ValidateDataTypes(cellStateInInfo, cellStateSupportedTypes, descriptorName);
3485  ValidateDataTypes(outputStateInInfo, inputOutputSupportedTypes, descriptorName);
3486 
3487  ValidateDataTypes(cellStateOutInfo, cellStateSupportedTypes, descriptorName);
3488  ValidateDataTypes(outputStateOutInfo, inputOutputSupportedTypes, descriptorName);
3489 
3490  // Validate matching types of input/output tensors
3491  ValidateTensorDataTypesMatch(inputInfo, outputStateInInfo, descriptorName, "input", "outputStateIn");
3492  ValidateTensorDataTypesMatch(outputStateInInfo, outputStateOutInfo, descriptorName,
3493  "outputStateIn", "outputStateOut");
3494  ValidateTensorDataTypesMatch(cellStateInInfo, cellStateOutInfo, descriptorName, "cellStateIn", "cellStateOut");
3495 
3496  // Validate matching quantization info for input/output tensors
3497  ValidateTensorQuantizationSpace(inputInfo, outputStateInInfo, descriptorName, "input", "outputStateIn");
3498  ValidateTensorQuantizationSpace(inputInfo, outputStateOutInfo, descriptorName, "input", "outputStateOut");
3499  ValidateTensorQuantizationSpace(cellStateInInfo, cellStateOutInfo, descriptorName, "cellStateIn", "cellStateOut");
3500 
3501  // Infer number of batches, input size and output size from tensor dimensions
3502  const uint32_t numBatches = inputInfo.GetShape()[0];
3503  const uint32_t inputSize = inputInfo.GetShape()[1];
3504  const uint32_t outputSize = cellStateInInfo.GetShape()[1];
3505 
3506  // Validate number of dimensions and number of elements for input/output tensors
3507  ValidateTensorNumDimNumElem(inputInfo, 2, (numBatches * inputSize), descriptorName + " input");
3508  ValidateTensorNumDimNumElem(cellStateInInfo, 2, (numBatches * outputSize), descriptorName + " cellStateIn");
3509  ValidateTensorNumDimNumElem(outputStateInInfo, 2, (numBatches * outputSize), descriptorName + " outputStateIn");
3510  ValidateTensorNumDimNumElem(cellStateOutInfo, 2, (numBatches * outputSize), descriptorName + " cellStateOut");
3511  ValidateTensorNumDimNumElem(outputStateOutInfo, 2, (numBatches * outputSize), descriptorName + " outputStateOut");
3512 
3513  // Validate number of dimensions and number of elements for weights tensors
3514  ValidatePointer(m_InputToInputWeights, descriptorName, "InputToInputWeights");
3515  auto inputToInputWeightsInfo = m_InputToInputWeights->GetTensorInfo();
3516  ValidateTensorNumDimNumElem(inputToInputWeightsInfo, 2, (outputSize * inputSize), " InputToInputWeights");
3517 
3518  ValidatePointer(m_InputToForgetWeights, descriptorName, "InputToForgetWeights");
3519  auto inputToForgetWeightsInfo = m_InputToForgetWeights->GetTensorInfo();
3520  ValidateTensorNumDimNumElem(inputToForgetWeightsInfo, 2, (outputSize * inputSize), " InputToForgetWeights");
3521 
3522  ValidatePointer(m_InputToCellWeights, descriptorName, "InputToCellWeights");
3523  auto inputToCellWeightsInfo = m_InputToCellWeights->GetTensorInfo();
3524  ValidateTensorNumDimNumElem(inputToCellWeightsInfo, 2, (outputSize * inputSize), " InputToCellWeights");
3525 
3526  ValidatePointer(m_InputToOutputWeights, descriptorName, "InputToOutputWeights");
3527  auto inputToOutputWeightsInfo = m_InputToOutputWeights->GetTensorInfo();
3528  ValidateTensorNumDimNumElem(inputToOutputWeightsInfo, 2, (outputSize * inputSize), " InputToOutputWeights");
3529 
3530  ValidatePointer(m_RecurrentToInputWeights, descriptorName, "RecurrentToInputWeights");
3531  auto recurrentToInputWeightsInfo = m_RecurrentToInputWeights->GetTensorInfo();
3532  ValidateTensorNumDimNumElem(recurrentToInputWeightsInfo, 2, (outputSize * outputSize), " RecurrentToInputWeights");
3533 
3534  ValidatePointer(m_RecurrentToForgetWeights, descriptorName, "RecurrentToForgetWeights");
3535  auto recurrentToForgetWeightsInfo = m_RecurrentToForgetWeights->GetTensorInfo();
3536  ValidateTensorNumDimNumElem(recurrentToForgetWeightsInfo, 2, (outputSize * outputSize),
3537  " RecurrentToForgetWeights");
3538 
3539  ValidatePointer(m_RecurrentToCellWeights, descriptorName, "RecurrentToCellWeights");
3540  auto recurrentToCellWeightsInfo = m_RecurrentToCellWeights->GetTensorInfo();
3541  ValidateTensorNumDimNumElem(recurrentToCellWeightsInfo, 2, (outputSize * outputSize), " RecurrentToCellWeights");
3542 
3543  ValidatePointer(m_RecurrentToOutputWeights, descriptorName, "RecurrentToOutputWeights");
3544  auto recurrentToOutputWeightsInfo = m_RecurrentToOutputWeights->GetTensorInfo();
3545  ValidateTensorNumDimNumElem(recurrentToOutputWeightsInfo, 2, (outputSize * outputSize), " RecurrentToCellWeights");
3546 
3547  // Validate data types for weights tensors (all should match each other)
3548  ValidateDataTypes(inputToInputWeightsInfo, weightsSupportedTypes, descriptorName);
3549 
3550  ValidateTensorDataTypesMatch(inputToInputWeightsInfo, inputToForgetWeightsInfo, descriptorName,
3551  "inputToInputWeights", "inputToForgetWeights");
3552  ValidateTensorDataTypesMatch(inputToInputWeightsInfo, inputToCellWeightsInfo, descriptorName,
3553  "inputToInputWeights", "inputToCellWeights");
3554  ValidateTensorDataTypesMatch(inputToInputWeightsInfo, inputToOutputWeightsInfo, descriptorName,
3555  "inputToInputWeights", "inputToOutputWeights");
3556 
3557  ValidateTensorDataTypesMatch(inputToInputWeightsInfo, recurrentToInputWeightsInfo, descriptorName,
3558  "inputToInputWeights", "recurrentToInputWeights");
3559  ValidateTensorDataTypesMatch(inputToInputWeightsInfo, recurrentToForgetWeightsInfo, descriptorName,
3560  "inputToInputWeights", "recurrentToForgeteights");
3561  ValidateTensorDataTypesMatch(inputToInputWeightsInfo, recurrentToCellWeightsInfo, descriptorName,
3562  "inputToInputWeights", "recurrentToCellWeights");
3563  ValidateTensorDataTypesMatch(inputToInputWeightsInfo, recurrentToOutputWeightsInfo, descriptorName,
3564  "inputToInputWeights", "recurrentToOutputWeights");
3565 
3566  // Validate matching quantization info for weight tensors (all should match each other)
3567  ValidateTensorQuantizationSpace(inputToInputWeightsInfo, inputToForgetWeightsInfo,
3568  descriptorName, "inputToInputWeights", "inputToForgetWeights");
3569  ValidateTensorQuantizationSpace(inputToInputWeightsInfo, inputToCellWeightsInfo,
3570  descriptorName, "inputToInputWeights", "inputToCellWeights");
3571  ValidateTensorQuantizationSpace(inputToInputWeightsInfo, inputToOutputWeightsInfo,
3572  descriptorName, "inputToInputWeights", "inputToOutputWeights");
3573 
3574  ValidateTensorQuantizationSpace(inputToInputWeightsInfo, recurrentToInputWeightsInfo,
3575  descriptorName, "inputToInputWeights", "recurrentToInputWeights");
3576  ValidateTensorQuantizationSpace(inputToInputWeightsInfo, recurrentToForgetWeightsInfo,
3577  descriptorName, "inputToInputWeights", "recurrentToForgetWeights");
3578  ValidateTensorQuantizationSpace(inputToInputWeightsInfo, recurrentToCellWeightsInfo,
3579  descriptorName, "inputToInputWeights", "recurrentToCellWeights");
3580  ValidateTensorQuantizationSpace(inputToInputWeightsInfo, recurrentToOutputWeightsInfo,
3581  descriptorName, "inputToInputWeights", "recurrentToOutputWeights");
3582 
3583  // Validate number of dimensions and number of elements in bias tensors
3584  ValidatePointer(m_InputGateBias, descriptorName, "InputGateBias");
3585  auto inputGateBiasInfo = m_InputGateBias->GetTensorInfo();
3586  ValidateTensorNumDimNumElem(inputGateBiasInfo, 1, outputSize, " InputGateBias");
3587 
3588  ValidatePointer(m_ForgetGateBias, descriptorName, "ForgetGateBias");
3589  auto forgetGateBiasInfo = m_ForgetGateBias->GetTensorInfo();
3590  ValidateTensorNumDimNumElem(forgetGateBiasInfo, 1, outputSize, " ForgetGateBias");
3591 
3592  ValidatePointer(m_CellBias, descriptorName, "CellBias");
3593  auto cellBiasInfo = m_CellBias->GetTensorInfo();
3594  ValidateTensorNumDimNumElem(cellBiasInfo, 1, outputSize, " CellBias");
3595 
3596  ValidatePointer(m_OutputGateBias, descriptorName, "OutputGateBias");
3597  auto outputGateBiasInfo = m_OutputGateBias->GetTensorInfo();
3598  ValidateTensorNumDimNumElem(outputGateBiasInfo, 1, outputSize, " OutputGateBias");
3599 
3600  // Validate data types for bias tensors (all should match each other)
3601  ValidateDataTypes(inputGateBiasInfo, biasSupportedTypes, descriptorName);
3602 
3603  ValidateTensorDataTypesMatch(inputGateBiasInfo, forgetGateBiasInfo, descriptorName,
3604  "inputGateBias", "forgetGateBias");
3605  ValidateTensorDataTypesMatch(inputGateBiasInfo, cellBiasInfo, descriptorName,
3606  "inputGateBias", "cellBias");
3607  ValidateTensorDataTypesMatch(inputGateBiasInfo, outputGateBiasInfo, descriptorName,
3608  "inputGateBias", "outputGateBias");
3609 
3610  // Validate bias tensor quantization info
3611  ValidateBiasTensorQuantization(inputGateBiasInfo, inputToInputWeightsInfo, descriptorName);
3612  ValidateBiasTensorQuantization(forgetGateBiasInfo, inputToInputWeightsInfo, descriptorName);
3613  ValidateBiasTensorQuantization(cellBiasInfo, inputToInputWeightsInfo, descriptorName);
3614  ValidateBiasTensorQuantization(outputGateBiasInfo, inputToInputWeightsInfo, descriptorName);
3615 }
3616 
3617 void AbsQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
3618 {
3619  const std::string descriptorName{"AbsQueueDescriptor"};
3620 
3621  ValidateNumInputs(workloadInfo, descriptorName, 1);
3622  ValidateNumOutputs(workloadInfo, descriptorName, 1);
3623 
3624  const TensorInfo& inputTensorInfo = workloadInfo.m_InputTensorInfos[0];
3625  const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];
3626 
3627  ValidateTensorShapesMatch(inputTensorInfo, outputTensorInfo, descriptorName, "input", "output");
3628 
3629  std::vector<DataType> supportedTypes =
3630  {
3638  };
3639 
3640  ValidateDataTypes(inputTensorInfo, supportedTypes, descriptorName);
3641  ValidateTensorDataTypesMatch(inputTensorInfo, outputTensorInfo, descriptorName, "input", "output");
3642 }
3643 
3644 void SliceQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
3645 {
3646  const std::string descriptorName{"SliceQueueDescriptor"};
3647 
3648  ValidateNumInputs(workloadInfo, descriptorName, 1);
3649  ValidateNumOutputs(workloadInfo, descriptorName, 1);
3650 
3651  const TensorInfo& inputTensorInfo = workloadInfo.m_InputTensorInfos[0];
3652  const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];
3653 
3654  ValidateTensorDataTypesMatch(inputTensorInfo, outputTensorInfo, descriptorName, "input", "output");
3655 
3656  const unsigned int rank = inputTensorInfo.GetNumDimensions();
3657  if (rank > 5)
3658  {
3659  throw InvalidArgumentException(descriptorName + ": Input tensors with rank greater than 5 are not supported.");
3660  }
3661 
3662  ValidateTensorNumDimensions(outputTensorInfo, descriptorName, rank, "output");
3663 
3664  // Check if m_Begin and m_Size have the expected length
3665  if (m_Parameters.m_Begin.size() != rank)
3666  {
3667  throw InvalidArgumentException(descriptorName +
3668  ": Length of begin offset descriptor must equal rank " + std::to_string(rank));
3669  }
3670  if (m_Parameters.m_Size.size() != rank)
3671  {
3672  throw InvalidArgumentException(descriptorName +
3673  ": Length of size descriptor must equal rank " + std::to_string(rank));
3674  }
3675 
3676  // Check if the shape of the output tensor matches m_Size
3677  const TensorShape& outputShape = outputTensorInfo.GetShape();
3678  for (unsigned int i = 0u; i < rank; ++i)
3679  {
3680  if (m_Parameters.m_Size[i] != outputShape[i])
3681  {
3682  throw InvalidArgumentException(descriptorName + ": Size descriptor does not match output tensor.");
3683  }
3684  }
3685 
3686  // Check if the sum of begin offset and size in a given dimension
3687  // does not exceed the size of corresponding input
3688  const TensorShape& inputShape = inputTensorInfo.GetShape();
3689  for(unsigned int i = 0u; i < rank; ++i)
3690  {
3691  if (m_Parameters.m_Begin[i] + m_Parameters.m_Size[i] > inputShape[i])
3692  {
3693  throw InvalidArgumentException(descriptorName + ": Sum of begin offset and size for dimension " +
3694  std::to_string(i) + " exceeds input size.");
3695  }
3696  }
3697 }
3698 
3700 {
3701  const std::string descriptorName{"DepthToSpaceQueueDescriptor"};
3702 
3703  ValidateNumInputs(workloadInfo, descriptorName, 1);
3704  ValidateNumOutputs(workloadInfo, descriptorName, 1);
3705 
3706  const TensorInfo& inputInfo = workloadInfo.m_InputTensorInfos[0];
3707  const TensorInfo& outputInfo = workloadInfo.m_OutputTensorInfos[0];
3708 
3709  ValidateTensorNumDimensions(inputInfo, descriptorName, 4, "input");
3710  ValidateTensorNumDimensions(outputInfo, descriptorName, 4, "output");
3711 
3712  std::vector<DataType> supportedTypes =
3713  {
3721  };
3722 
3723  ValidateDataTypes(inputInfo, supportedTypes, descriptorName);
3724  ValidateDataTypes(outputInfo, supportedTypes, descriptorName);
3725 
3726  ValidateTensorNumElementsMatch(inputInfo, outputInfo, descriptorName, "input", "output");
3727 
3728  if (m_Parameters.m_BlockSize == 0)
3729  {
3730  throw InvalidArgumentException(descriptorName + ": Block size cannot be 0.");
3731  }
3732 
3733  DataLayoutIndexed dimensionIndices(m_Parameters.m_DataLayout);
3734  const unsigned int wIndex = dimensionIndices.GetWidthIndex();
3735  const unsigned int hIndex = dimensionIndices.GetHeightIndex();
3736  const unsigned int cIndex = dimensionIndices.GetChannelsIndex();
3737 
3738  const TensorShape& outputShape = outputInfo.GetShape();
3739  if (outputShape[hIndex] % m_Parameters.m_BlockSize != 0 || outputShape[wIndex] % m_Parameters.m_BlockSize != 0)
3740  {
3741  throw InvalidArgumentException(descriptorName + ": Output width and height shape"
3742  "must be divisible by block size.");
3743  }
3744 
3745  const TensorShape& inputShape = inputInfo.GetShape();
3746  if (inputShape[cIndex] % (m_Parameters.m_BlockSize * m_Parameters.m_BlockSize) != 0)
3747  {
3748  throw InvalidArgumentException(descriptorName + ": The depth of the input tensor"
3749  "must be divisible by the square of block size." );
3750  }
3751 }
3752 
3753 void ComparisonQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
3754 {
3755  const std::string descriptorName{"ComparisonQueueDescriptor"};
3756 
3757  ValidateNumInputs(workloadInfo, descriptorName, 2);
3758  ValidateNumOutputs(workloadInfo, descriptorName, 1);
3759 
3760  const TensorInfo& inputTensorInfo0 = workloadInfo.m_InputTensorInfos[0];
3761  const TensorInfo& inputTensorInfo1 = workloadInfo.m_InputTensorInfos[1];
3762  const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];
3763 
3764  ValidateBroadcastTensorShapesMatch(inputTensorInfo0,
3765  inputTensorInfo1,
3766  outputTensorInfo,
3767  descriptorName,
3768  "input_0",
3769  "input_1");
3770 
3771  if (outputTensorInfo.GetDataType() != DataType::Boolean)
3772  {
3773  throw InvalidArgumentException(descriptorName + ": Output tensor type must be Boolean.");
3774  }
3775 }
3776 
3778 {
3779  const std::string descriptorName{"ElementwiseBinaryQueueDescriptor"};
3780 
3781  ValidateNumInputs(workloadInfo, descriptorName, 2);
3782  ValidateNumOutputs(workloadInfo, descriptorName, 1);
3783 
3784  const TensorInfo& inputTensorInfo0 = workloadInfo.m_InputTensorInfos[0];
3785  const TensorInfo& inputTensorInfo1 = workloadInfo.m_InputTensorInfos[1];
3786  const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];
3787 
3788  std::vector<DataType> supportedTypes =
3789  {
3797  };
3798 
3799  ValidateDataTypes(inputTensorInfo0, supportedTypes, descriptorName);
3800  ValidateDataTypes(inputTensorInfo1, supportedTypes, descriptorName);
3801 
3802  ValidateTensorDataTypesMatch(inputTensorInfo0, outputTensorInfo, descriptorName, "input", "output");
3803  ValidateTensorDataTypesMatch(inputTensorInfo1, outputTensorInfo, descriptorName, "input", "output");
3804 }
3805 
3807 {
3808  const std::string descriptorName{"ElementwiseUnaryQueueDescriptor"};
3809 
3810  ValidateNumInputs(workloadInfo, descriptorName, 1);
3811  ValidateNumOutputs(workloadInfo, descriptorName, 1);
3812 
3813  const TensorInfo& inputTensorInfo = workloadInfo.m_InputTensorInfos[0];
3814  const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];
3815 
3816  ValidateTensorShapesMatch(inputTensorInfo, outputTensorInfo, descriptorName, "input", "output");
3817 
3818  std::vector<DataType> supportedTypes =
3819  {
3827  };
3828 
3829  std::vector<DataType> logicalSupportedTypes =
3830  {
3832  };
3833 
3835  {
3836  ValidateDataTypes(inputTensorInfo, logicalSupportedTypes, descriptorName);
3837  }
3838  else
3839  {
3840  ValidateDataTypes(inputTensorInfo, supportedTypes, descriptorName);
3841  }
3842 
3843 
3844  ValidateTensorDataTypesMatch(inputTensorInfo, outputTensorInfo, descriptorName, "input", "output");
3845 }
3846 
3847 void RankQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
3848 {
3849  const std::string descriptorName{"RankQueueDescriptor"};
3850 
3851  ValidateNumInputs(workloadInfo, descriptorName, 1);
3852  ValidateNumOutputs(workloadInfo, descriptorName, 1);
3853 
3854  const TensorInfo& inputTensorInfo = workloadInfo.m_InputTensorInfos[0];
3855  const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];
3856 
3857  ValidateTensorNumDimensions(outputTensorInfo, descriptorName, 1, "output");
3858  ValidateTensorNumElements(outputTensorInfo, descriptorName, 1, "output");
3859 
3860  std::vector<DataType> supportedTypes =
3861  {
3870  };
3871 
3872  ValidateDataTypes(inputTensorInfo, supportedTypes, descriptorName);
3873  ValidateDataTypes(outputTensorInfo, { DataType::Signed32 }, descriptorName);
3874 }
3875 
3877 {
3878  const std::string descriptorName{"LogicalBinaryQueueDescriptor"};
3879 
3880  ValidateNumInputs(workloadInfo, descriptorName, 2);
3881  ValidateNumOutputs(workloadInfo, descriptorName, 1);
3882 
3883  const TensorInfo& inputTensorInfo0 = workloadInfo.m_InputTensorInfos[0];
3884  const TensorInfo& inputTensorInfo1 = workloadInfo.m_InputTensorInfos[1];
3885  const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];
3886 
3887  ValidateBroadcastTensorShapesMatch(inputTensorInfo0,
3888  inputTensorInfo1,
3889  outputTensorInfo,
3890  descriptorName,
3891  "input_0",
3892  "input_1");
3893 
3894  if (inputTensorInfo0.GetDataType() != DataType::Boolean)
3895  {
3896  throw InvalidArgumentException(descriptorName + ": Input tensor 0 type must be Boolean.");
3897  }
3898 
3899  if (inputTensorInfo1.GetDataType() != DataType::Boolean)
3900  {
3901  throw InvalidArgumentException(descriptorName + ": Input tensor 1 type must be Boolean.");
3902  }
3903 
3904  if (outputTensorInfo.GetDataType() != DataType::Boolean)
3905  {
3906  throw InvalidArgumentException(descriptorName + ": Output tensor type must be Boolean.");
3907  }
3908 }
3909 
3910 void ReduceQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
3911 {
3912  const std::string descriptorName{"ReduceQueueDescriptor"};
3913 
3914  ValidateNumInputs(workloadInfo, descriptorName, 1);
3915  ValidateNumOutputs(workloadInfo, descriptorName, 1);
3916 
3917  const TensorInfo& inputTensorInfo = workloadInfo.m_InputTensorInfos[0];
3918  const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];
3919 
3920  std::vector<DataType> supportedTypes =
3921  {
3929  };
3930 
3931  ValidateDataTypes(inputTensorInfo, supportedTypes, descriptorName);
3932  ValidateTensorDataTypesMatch(inputTensorInfo, outputTensorInfo, descriptorName, "input", "output");
3933 }
3934 
3936 {
3937  // Modified from LstmQueueDescriptor::Validate to support UnidirectionalSequenceLstm
3938 
3939  const std::string descriptorName{"UnidirectionalSequenceLstmQueueDescriptor"};
3940 
3941  // check dimensions of all inputs and outputs
3942  if (workloadInfo.m_InputTensorInfos.size() != 3)
3943  {
3944  throw InvalidArgumentException(descriptorName + ": Invalid number of inputs.");
3945  }
3946  if (workloadInfo.m_OutputTensorInfos.size() != 3)
3947  {
3948  throw InvalidArgumentException(descriptorName + ": Invalid number of outputs.");
3949  }
3950 
3951  std::vector<DataType> supportedTypes =
3952  {
3955  };
3956 
3957  // check for supported type of one input and match them with all the other input and output
3958  ValidateDataTypes(workloadInfo.m_InputTensorInfos[0], supportedTypes, descriptorName);
3959 
3960  // Making sure clipping parameters have valid values.
3961  // == 0 means no clipping
3962  // > 0 means clipping
3963  if (m_Parameters.m_ClippingThresCell < 0.0f)
3964  {
3965  throw InvalidArgumentException(descriptorName + ": negative cell clipping threshold is invalid");
3966  }
3967  if (m_Parameters.m_ClippingThresProj < 0.0f)
3968  {
3969  throw InvalidArgumentException(descriptorName + ": negative projection clipping threshold is invalid");
3970  }
3971 
3972  unsigned int batchIndx = 0;
3973  unsigned int inputIndx = 1;
3974  uint32_t timeStep = 1;
3975  unsigned int timeIndx = 1;
3976  inputIndx = 2;
3978  {
3979  batchIndx = 1;
3980  timeIndx = 0;
3981 
3982  }
3983  timeStep = workloadInfo.m_InputTensorInfos[0].GetShape()[timeIndx];
3984 
3985  // Inferring batch size, number of outputs and number of cells from the inputs.
3986  const uint32_t n_input = workloadInfo.m_InputTensorInfos[0].GetShape()[inputIndx];
3987  const uint32_t n_batch = workloadInfo.m_InputTensorInfos[0].GetShape()[batchIndx];
3988  ValidatePointer(m_InputToOutputWeights, "Null pointer check", "InputToOutputWeights");
3989  const uint32_t n_cell = m_InputToOutputWeights->GetShape()[0];
3990  ValidatePointer(m_RecurrentToOutputWeights, "Null pointer check", "RecurrentToOutputWeights");
3991  const uint32_t n_output = m_RecurrentToOutputWeights->GetShape()[1];
3992 
3993  // input tensor
3994  ValidateTensorNumDimNumElem(workloadInfo.m_InputTensorInfos[0], 3, (timeStep * n_batch * n_input),
3995  descriptorName + " input_0");
3996  // outputStateInTensor
3997  ValidateTensorNumDimNumElem(workloadInfo.m_InputTensorInfos[1], 2, (n_batch * n_output),
3998  descriptorName + " input_1");
3999  // outputStateInTensor
4000  ValidateTensorNumDimNumElem(workloadInfo.m_InputTensorInfos[2], 2, (n_batch * n_cell),
4001  descriptorName + " input_2");
4002 
4003  // outputTensor
4004  ValidateTensorNumDimNumElem(workloadInfo.m_OutputTensorInfos[2], 3, (timeStep * n_batch * n_output),
4005  descriptorName + " output_0");
4006 
4007  // check that dimensions of inputs/outputs and QueueDescriptor data match with each other
4008  if ( m_InputToInputWeights )
4009  {
4011  (n_cell * n_input), "InputLayerNormWeights");
4012  }
4013 
4014  ValidatePointer(m_InputToForgetWeights, "Null pointer check", "InputToForgetWeights");
4016  (n_cell * n_input), "InputToForgetWeights");
4017 
4018  ValidatePointer(m_InputToCellWeights, "Null pointer check", "InputToCellWeights");
4020  (n_cell * n_input), "InputToCellWeights");
4021 
4023  {
4025  (n_cell * n_output), "RecurrentToInputWeights");
4026  }
4027 
4028  ValidatePointer(m_RecurrentToForgetWeights, "Null pointer check", "RecurrentToForgetWeights");
4030  (n_cell * n_output), "RecurrentToForgetWeights");
4031 
4032  ValidatePointer(m_RecurrentToCellWeights, "Null pointer check", "RecurrentToCellWeights");
4034  (n_cell * n_output), "RecurrentToCellWeights");
4035 
4036  // Make sure the input-gate's parameters are either both present (regular
4037  // LSTM) or not at all (CIFG-LSTM). And CifgEnable is set accordingly.
4038  bool cifg_weights_all_or_none = ((m_InputToInputWeights && m_RecurrentToInputWeights &&
4042  if (!cifg_weights_all_or_none)
4043  {
4044  throw InvalidArgumentException(descriptorName + ": Input-Gate's parameters InputToInputWeights and "
4045  "RecurrentToInputWeights must either both be present (regular LSTM) "
4046  "or both not present (CIFG-LSTM). In addition CifgEnable must be set "
4047  "accordingly.");
4048  }
4049 
4050  if ( m_CellToInputWeights )
4051  {
4053  n_cell, "CellToInputWeights");
4054  }
4055  if ( m_CellToForgetWeights )
4056  {
4058  n_cell, "CellToForgetWeights");
4059  }
4060  if ( m_CellToOutputWeights )
4061  {
4063  n_cell, "CellToOutputWeights");
4064  }
4065 
4066  // Making sure the peephole weights are there all or none. And PeepholeEnable is set accordingly.
4067  bool peephole_weights_all_or_none =
4072  if (!peephole_weights_all_or_none)
4073  {
4074  throw InvalidArgumentException(descriptorName + ": Invalid combination of peephole parameters.");
4075  }
4076 
4077  // Make sure the input gate bias is present only when not a CIFG-LSTM.
4079  {
4080  if (m_InputGateBias)
4081  {
4082  throw InvalidArgumentException(descriptorName + ": InputGateBias is present and CIFG-LSTM is enabled.");
4083  }
4084  }
4085  else
4086  {
4087  if (!m_InputGateBias)
4088  {
4089  throw InvalidArgumentException(descriptorName + ": If CIFG-LSTM is disabled InputGateBias "
4090  "must be present.");
4091  }
4093  n_cell, "InputGateBias");
4094  }
4095 
4096  ValidatePointer(m_ForgetGateBias, "Null pointer check", "ForgetGateBias");
4097  ValidateTensorNumDimNumElem(m_ForgetGateBias->GetTensorInfo(), 1, n_cell, "ForgetGateBias");
4098 
4099  ValidatePointer(m_CellBias, "Null pointer check", "CellBias");
4100  ValidateTensorNumDimNumElem(m_CellBias->GetTensorInfo(), 1, n_cell, "CellBias");
4101 
4102  ValidatePointer(m_OutputGateBias, "Null pointer check", "OutputGateBias");
4103  ValidateTensorNumDimNumElem(m_OutputGateBias->GetTensorInfo(), 1, n_cell, "OutputGateBias");
4104 
4105  if (m_ProjectionWeights)
4106  {
4108  (n_cell * n_output), "ProjectionWeights");
4109  }
4110  if (m_ProjectionBias)
4111  {
4112  ValidateTensorNumDimNumElem(m_ProjectionBias->GetTensorInfo(), 1, n_output, "ProjectionBias");
4113  }
4114 
4115  // Making sure the projection tensors are consistent:
4116  // 1) If projection weight is not present, then projection bias should not be
4117  // present.
4118  // 2) If projection weight is present, then projection bias is optional.
4119  bool projecton_tensors_consistent = ((!m_ProjectionWeights && !m_ProjectionBias &&
4125  if (!projecton_tensors_consistent)
4126  {
4127  throw InvalidArgumentException(descriptorName + ": Projection tensors are inconsistent.");
4128  }
4129 
4130  // The four layer normalization weights either all have values or none of them have values. Additionally, if
4131  // CIFG is used, input layer normalization weights tensor is omitted and the other layer normalization weights
4132  // either all have values or none of them have values. Layer normalization is used when the values of all the
4133  // layer normalization weights are present
4135  {
4136  ValidateTensorNumDimNumElem(m_InputLayerNormWeights->GetTensorInfo(), 1, n_cell, "InputLayerNormWeights");
4137  }
4139  {
4140  ValidateTensorNumDimNumElem(m_ForgetLayerNormWeights->GetTensorInfo(), 1, n_cell, "ForgetLayerNormWeights");
4141  }
4143  {
4144  ValidateTensorNumDimNumElem(m_CellLayerNormWeights->GetTensorInfo(), 1, n_cell, "CellLayerNormWeights");
4145  }
4147  {
4148  ValidateTensorNumDimNumElem(m_OutputLayerNormWeights->GetTensorInfo(), 1, n_cell, "OutputLayerNormWeights");
4149  }
4150 
4152  {
4154  {
4156  {
4157  throw InvalidArgumentException(descriptorName + ": Layer normalisation is enabled and CIFG-LSTM is "
4158  "disabled but InputLayerNormWeights are not present");
4159  }
4161  1, n_cell, "InputLayerNormWeights");
4162  }
4163  else if (m_InputLayerNormWeights)
4164  {
4165  throw InvalidArgumentException(descriptorName + ":InputLayerNormWeights are present while CIFG is "
4166  "enabled");
4167  }
4168 
4169  ValidatePointer(m_ForgetLayerNormWeights, "Null pointer check layer normalisation enabled",
4170  "ForgetLayerNormWeights");
4171  ValidateTensorNumDimNumElem(m_ForgetLayerNormWeights->GetTensorInfo(), 1, n_cell, "ForgetLayerNormWeights");
4172 
4173  ValidatePointer(m_OutputLayerNormWeights, "Null pointer check layer normalisation enabled",
4174  "OutputLayerNormWeights");
4175  ValidateTensorNumDimNumElem(m_OutputLayerNormWeights->GetTensorInfo(), 1, n_cell, "OutputLayerNormWeights");
4176 
4177  ValidatePointer(m_CellLayerNormWeights, "Null pointer check layer normalisation enabled",
4178  "CellLayerNormWeights");
4179  ValidateTensorNumDimNumElem(m_CellLayerNormWeights->GetTensorInfo(), 1, n_cell, "CellLayerNormWeights");
4180  }
4182  {
4183  throw InvalidArgumentException(descriptorName + ": Layer normalisation is disabled but one or more layer "
4184  "normalisation weights are present.");
4185  }
4186 }
4187 
4189 {
4190  const std::string descriptorName{"BatchMatMulDescriptor"};
4191 
4192  ValidateNumInputs(workloadInfo, descriptorName, 2);
4193  ValidateNumOutputs(workloadInfo, descriptorName, 1);
4194 
4195  // Inputs must be: both 2D+
4196  // For inputs X and Y whose dimensions to be multiplied are (M,N) and (I,J) respectively,
4197  // axes N and I must be the same size
4198 
4199  const auto& inputXInfoBeforeParams = workloadInfo.m_InputTensorInfos[0];
4200  const auto& inputYInfoBeforeParams = workloadInfo.m_InputTensorInfos[1];
4201  const auto& outputInfo = workloadInfo.m_OutputTensorInfos[0];
4202  // Output info has already been inferred
4203 
4204  std::vector<DataType> supportedTypes =
4205  {
4212  };
4213 
4214  ValidateDataTypes(inputXInfoBeforeParams, supportedTypes, descriptorName);
4215  ValidateDataTypes(inputYInfoBeforeParams, supportedTypes, descriptorName);
4216  ValidateDataTypes(outputInfo, supportedTypes, descriptorName);
4217 
4218  if ((inputXInfoBeforeParams.GetNumDimensions() < 2) ||
4219  (inputYInfoBeforeParams.GetNumDimensions() < 2))
4220  {
4221  throw InvalidArgumentException(descriptorName + ": Input tensors are not 2D or greater.");
4222  }
4223 
4224  TensorInfo inputXInfoAfterParams;
4225  TensorInfo inputYInfoAfterParams;
4226 
4229  {
4230  throw InvalidArgumentException(descriptorName +
4231  ": Invalid descriptor parameters - Transpose and Adjoint "
4232  "cannot both be true for a given input tensor.");
4233  }
4235  {
4236  inputXInfoAfterParams = armnnUtils::Permuted(inputXInfoBeforeParams,
4239  inputXInfoBeforeParams.GetShape()));
4240  }
4241  else if(m_Parameters.m_AdjointX)
4242  {
4244  inputXInfoBeforeParams.GetShape());
4245  if(inputXInfoBeforeParams.GetShape()[axesToMul.first] !=
4246  inputXInfoBeforeParams.GetShape()[axesToMul.second])
4247  {
4248  throw InvalidArgumentException(descriptorName +
4249  ": Adjoint is set to true for input tensor X, but the axes to be adjointed are not square." );
4250  }
4251  // Shape remains the same as it's square
4252  inputXInfoAfterParams = inputXInfoBeforeParams;
4253  }
4254  else
4255  {
4256  inputXInfoAfterParams = inputXInfoBeforeParams;
4257  }
4258 
4260  {
4261  inputYInfoAfterParams = armnnUtils::Permuted(inputYInfoBeforeParams,
4264  inputYInfoBeforeParams.GetShape()));
4265  }
4266  else if(m_Parameters.m_AdjointY)
4267  {
4269  inputYInfoBeforeParams.GetShape());
4270  if(inputYInfoBeforeParams.GetShape()[axesToMul.first] !=
4271  inputYInfoBeforeParams.GetShape()[axesToMul.second])
4272  {
4273  throw InvalidArgumentException(descriptorName +
4274  ": Adjoint is set to true for input tensor Y, but the axes to be adjointed are not square." );
4275  }
4276  // Shape remains the same as it's square
4277  inputYInfoAfterParams = inputYInfoBeforeParams;
4278  }
4279  else
4280  {
4281  inputYInfoAfterParams = inputYInfoBeforeParams;
4282  }
4283 
4284  switch(m_Parameters.m_DataLayoutX)
4285  {
4286  case DataLayout::NCDHW:
4287  case DataLayout::NDHWC:
4288  if(inputXInfoAfterParams.GetNumDimensions() < 3)
4289  {
4290  throw InvalidArgumentException(descriptorName +
4291  ": Input tensor X does not have the correct "
4292  "number of dimensions for the Data Layout that it has been assigned.");
4293  }
4294  break;
4295  case DataLayout::NCHW:
4296  case DataLayout::NHWC:
4297  default:
4298  break;
4299  }
4300 
4301  switch(m_Parameters.m_DataLayoutY)
4302  {
4303  case DataLayout::NCDHW:
4304  case DataLayout::NDHWC:
4305  if(inputYInfoAfterParams.GetNumDimensions() < 3)
4306  {
4307  throw InvalidArgumentException(descriptorName +
4308  ": Input tensor Y does not have the correct "
4309  "number of dimensions for the Data Layout that it has been assigned.");
4310  }
4311  break;
4312  case DataLayout::NCHW:
4313  case DataLayout::NHWC:
4314  default:
4315  break;
4316  }
4317 
4319  inputXInfoAfterParams.GetShape());
4321  inputYInfoBeforeParams.GetShape());
4322 
4323  if(inputXInfoAfterParams.GetShape()[axesXToMul.second]
4324  != inputYInfoAfterParams.GetShape()[axesYToMul.first])
4325  {
4326  throw InvalidArgumentException(descriptorName +
4327  ": The final axis of input tensor X must be the same size as "
4328  "the second last axis of input tensor Y.");
4329  }
4330 
4331  { // Separate scope so we don't pollute the rest of the scope with our temp variables
4332  // e.g. NHWC isnt compatible with NCHW as of now
4335 
4336  if(xLayout == DataLayout::NCHW || xLayout == DataLayout::NCDHW)
4337  {
4338  if(yLayout == DataLayout::NHWC || yLayout == DataLayout::NDHWC)
4339  {
4340  throw InvalidArgumentException(descriptorName +
4341  ": Invalid input tensor data layout combination.");
4342  }
4343  }
4344  if(yLayout == DataLayout::NCHW || yLayout == DataLayout::NCDHW)
4345  {
4346  if(xLayout == DataLayout::NHWC || xLayout == DataLayout::NDHWC)
4347  {
4348  throw InvalidArgumentException(descriptorName +
4349  ": Invalid input tensor data layout combination.");
4350  }
4351  }
4352  }
4353 
4354  // Simulate aligning the ends of the matrix dims and prepending 1's to the beginning of the shorter one
4355  unsigned int outputTensorDimSize = std::max(inputXInfoAfterParams.GetNumDimensions(),
4356  inputYInfoAfterParams.GetNumDimensions());
4357  if(outputTensorDimSize-2 > 0)
4358  {
4359  TensorInfo tiXNotMul = TensorInfo(TensorShape(outputTensorDimSize-2),
4361  TensorInfo tiYNotMul = TensorInfo(TensorShape(outputTensorDimSize-2),
4363  TensorInfo tiOutNotMul = TensorInfo(TensorShape(outputTensorDimSize-2),
4365 
4366  auto doAxisExtension = [&](std::vector<unsigned int> axisIndices, TensorInfo& ti)
4367  {
4368  auto sizeDiff = (outputTensorDimSize-2) - axisIndices.size();
4369 
4370  for(unsigned int i = 0; i < sizeDiff; i++)
4371  {
4372  axisIndices.insert(axisIndices.begin(), 1);
4373  }
4374 
4375  for(unsigned int i = 0; i < ti.GetNumDimensions(); i++)
4376  {
4377  ti.GetShape()[i] = inputXInfoAfterParams.GetShape()[i];
4378  }
4379  };
4380 
4382  inputXInfoAfterParams.GetShape());
4384  inputYInfoAfterParams.GetShape());
4385 
4386  doAxisExtension(axesXNotMul, tiXNotMul);
4387  doAxisExtension(axesYNotMul, tiYNotMul);
4388 
4389  for(unsigned int i = 0; i < tiOutNotMul.GetNumDimensions(); i++)
4390  {
4391  tiOutNotMul.GetShape()[i] = std::max(tiXNotMul.GetShape()[i],
4392  tiYNotMul.GetShape()[i]);
4393  }
4394 
4395  ValidateBroadcastTensorShapesMatch(tiXNotMul,
4396  tiYNotMul,
4397  tiOutNotMul,
4398  descriptorName,
4399  "input_X",
4400  "input_Y");
4401  }
4402 }
4403 
4404 void TileQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
4405 {
4406  const std::string& descriptorName{"TileQueueDescriptor"};
4407 
4408  ValidateNumInputs(workloadInfo, descriptorName, 1);
4409  ValidateNumOutputs(workloadInfo, descriptorName, 1);
4410 
4411  const TensorInfo& inputTensorInfo = workloadInfo.m_InputTensorInfos[0];
4412  const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];
4413 
4414  std::vector<DataType> supportedTypes =
4415  {
4424  };
4425 
4426  // Multiples length must be the same as the number of dimensions in input.
4427  if (m_Parameters.m_Multiples.size() != inputTensorInfo.GetNumDimensions())
4428  {
4429  throw InvalidArgumentException(descriptorName +
4430  ": Multiples length is not same as the number of dimensions in Input.");
4431  }
4432 
4433  ValidateDataTypes(inputTensorInfo, supportedTypes, descriptorName);
4434  ValidateDataTypes(outputTensorInfo, supportedTypes, descriptorName);
4435 }
4436 
4438 {
4439  const std::string& descriptorName{"BroadcastToQueueDescriptor"};
4440 
4441  ValidateNumInputs(workloadInfo, descriptorName, 1);
4442  ValidateNumOutputs(workloadInfo, descriptorName, 1);
4443 
4444  const TensorInfo& inputTensorInfo = workloadInfo.m_InputTensorInfos[0];
4445  const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];
4446 
4447  std::vector<DataType> supportedTypes =
4448  {
4457  };
4458 
4459  ValidateDataTypes(inputTensorInfo, supportedTypes, descriptorName);
4460  ValidateDataTypes(outputTensorInfo, supportedTypes, descriptorName);
4461 }
4462 
4463 void ScatterNdQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
4464 {
4465  const std::string& descriptorName{"ScatterQueueDescriptor"};
4466 
4467  ValidateNumInputs(workloadInfo, descriptorName, 3);
4468  ValidateNumOutputs(workloadInfo, descriptorName, 1);
4469 
4470  const TensorInfo& inputTensorInfo0 = workloadInfo.m_InputTensorInfos[0];
4471  const TensorInfo& inputTensorInfo1 = workloadInfo.m_InputTensorInfos[1];
4472  const TensorInfo& inputTensorInfo2 = workloadInfo.m_InputTensorInfos[2];
4473  const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];
4474 
4475  std::vector<DataType> supportedTypes =
4476  {
4484  };
4485 
4486  std::vector<DataType> indicesSupportedTypes =
4487  {
4489  };
4490 
4492  {
4493  ValidateDataTypes(inputTensorInfo0, supportedTypes, descriptorName);
4494  }
4495  else
4496  {
4497  ValidateDataTypes(inputTensorInfo0, indicesSupportedTypes, descriptorName);
4498  }
4499 
4500  ValidateDataTypes(inputTensorInfo1, indicesSupportedTypes, descriptorName);
4501  ValidateDataTypes(inputTensorInfo2, supportedTypes, descriptorName);
4502  ValidateDataTypes(outputTensorInfo, supportedTypes, descriptorName);
4503 }
4504 
4505 } // namespace armnn
armnn::LstmQueueDescriptor::m_ForgetLayerNormWeights
const ConstTensorHandle * m_ForgetLayerNormWeights
Definition: WorkloadData.hpp:445
armnn::LstmQueueDescriptor::m_CellBias
const ConstTensorHandle * m_CellBias
Definition: WorkloadData.hpp:440
armnn::SliceDescriptor::m_Begin
std::vector< unsigned int > m_Begin
Beginning indices of the slice in each dimension.
Definition: Descriptors.hpp:1244
armnn::QuantizedLstmQueueDescriptor::m_CellBias
const ConstTensorHandle * m_CellBias
Definition: WorkloadData.hpp:645
armnn::ShapeQueueDescriptor::Validate
void Validate(const WorkloadInfo &workloadInfo) const
Definition: WorkloadData.cpp:2957
armnn::OriginsDescriptor::GetConcatAxis
unsigned int GetConcatAxis() const
Get the concatenation axis value.
Definition: Descriptors.cpp:162
armnn::DataType::Boolean
@ Boolean
armnn::TensorInfo::GetNumElements
unsigned int GetNumElements() const
Definition: Tensor.hpp:198
armnn::BatchMatMulDescriptor::m_TransposeX
bool m_TransposeX
Transpose the slices of each input tensor Transpose and Adjoint can not both be set to true for the s...
Definition: Descriptors.hpp:1612
armnn::QuantizedLstmQueueDescriptor::m_RecurrentToInputWeights
const ConstTensorHandle * m_RecurrentToInputWeights
Definition: WorkloadData.hpp:638
armnn::ConstTensorHandle::GetShape
TensorShape GetShape() const override
Get the number of elements for each dimension ordered from slowest iterating dimension to fastest ite...
Definition: TensorHandle.hpp:56
armnn::FillQueueDescriptor::Validate
void Validate(const WorkloadInfo &workloadInfo) const
Definition: WorkloadData.cpp:1013
armnn::MinimumQueueDescriptor::Validate
void Validate(const WorkloadInfo &workloadInfo) const
Definition: WorkloadData.cpp:2653
armnn::UnidirectionalSequenceLstmQueueDescriptor::m_CellBias
const ConstTensorHandle * m_CellBias
Definition: WorkloadData.hpp:736
armnn::QuantizedLstmQueueDescriptor::m_InputToForgetWeights
const ConstTensorHandle * m_InputToForgetWeights
Definition: WorkloadData.hpp:634
armnn::Optional< unsigned int >
armnn::DataLayout::NCDHW
@ NCDHW
armnn::UnidirectionalSequenceLstmQueueDescriptor::m_RecurrentToCellWeights
const ConstTensorHandle * m_RecurrentToCellWeights
Definition: WorkloadData.hpp:729
armnn::BroadcastToQueueDescriptor::Validate
void Validate(const WorkloadInfo &workloadInfo) const
Definition: WorkloadData.cpp:4437
armnn::IsQuantized8BitType
constexpr bool IsQuantized8BitType(DataType dataType)
Definition: TypesUtils.hpp:317
armnn::QLstmDescriptor::m_ProjectionEnabled
bool m_ProjectionEnabled
Enable/disable the projection layer.
Definition: Descriptors.hpp:1422
armnn::LstmDescriptor::m_TimeMajor
bool m_TimeMajor
Enable/disable time major.
Definition: Descriptors.hpp:1154
armnn::BatchNormalizationQueueDescriptor::m_Gamma
const ConstTensorHandle * m_Gamma
Definition: WorkloadData.hpp:324
armnn::DataLayout
DataLayout
Definition: Types.hpp:62
armnn::SpaceToBatchNdDescriptor::m_DataLayout
DataLayout m_DataLayout
The data layout to be used (NCHW, NHWC).
Definition: Descriptors.hpp:1071
armnn::StridedSliceQueueDescriptor::Validate
void Validate(const WorkloadInfo &workloadInfo) const
Definition: WorkloadData.cpp:2595
WorkloadData.hpp
armnn::PreCompiledQueueDescriptor::Validate
void Validate(const WorkloadInfo &workloadInfo) const
Definition: WorkloadData.cpp:3024
armnn::DepthwiseConvolution2dDescriptor::m_BiasEnabled
bool m_BiasEnabled
Enable/disable bias.
Definition: Descriptors.hpp:708
armnn::MemCopyQueueDescriptor::Validate
void Validate(const WorkloadInfo &workloadInfo) const
Definition: WorkloadData.cpp:491
armnn::TensorInfo::GetQuantizationScales
std::vector< float > GetQuantizationScales() const
Definition: Tensor.cpp:451
armnn::StridedSliceDescriptor::m_Begin
std::vector< int > m_Begin
Begin values for the input that will be sliced.
Definition: Descriptors.hpp:1342
armnn::BatchMatMulDescriptor::m_AdjointX
bool m_AdjointX
Adjoint the slices of each input tensor Transpose and Adjoint can not both be set to true for the sam...
Definition: Descriptors.hpp:1617
armnn::DataLayout::NHWC
@ NHWC
armnn::BatchMatMulDescriptor::GetAxesToMul
static std::pair< unsigned int, unsigned int > GetAxesToMul(DataLayout dataLayout, const TensorShape &tensorShape)
Static helper to get the two axes (for each input) for multiplication.
Definition: Descriptors.cpp:485
armnn::EqualQueueDescriptor::Validate
void Validate(const WorkloadInfo &workloadInfo) const
Definition: WorkloadData.cpp:2695
armnn::LstmQueueDescriptor::m_InputToInputWeights
const ConstTensorHandle * m_InputToInputWeights
Definition: WorkloadData.hpp:427
armnn::QueueDescriptor::ValidateInputsOutputs
void ValidateInputsOutputs(const std::string &descName, unsigned int numExpectedIn, unsigned int numExpectedOut) const
Definition: WorkloadData.cpp:447
armnn::FusedQueueDescriptor::Validate
void Validate(const WorkloadInfo &workloadInfo) const
Definition: WorkloadData.cpp:1100
armnn::QLstmQueueDescriptor::m_InputToForgetWeights
const ConstTensorHandle * m_InputToForgetWeights
Definition: WorkloadData.hpp:590
armnnUtils::GetUnsignedAxis
unsigned int GetUnsignedAxis(const unsigned int inputDimension, const int axis)
Definition: TensorUtils.cpp:236
armnn::DequantizeQueueDescriptor::Validate
void Validate(const WorkloadInfo &workloadInfo) const
Definition: WorkloadData.cpp:2909
armnn::QLstmQueueDescriptor::m_InputLayerNormWeights
const ConstTensorHandle * m_InputLayerNormWeights
Definition: WorkloadData.hpp:606
armnn::LogSoftmaxQueueDescriptor::Validate
void Validate(const WorkloadInfo &workloadInfo) const
Definition: WorkloadData.cpp:1770
armnn::TensorInfo::GetQuantizationScale
float GetQuantizationScale() const
Definition: Tensor.cpp:461
armnn::DepthwiseConvolution2dDescriptor::m_DataLayout
DataLayout m_DataLayout
The data layout to be used (NCHW, NHWC).
Definition: Descriptors.hpp:710
armnn::BatchNormalizationQueueDescriptor::m_Variance
const ConstTensorHandle * m_Variance
Definition: WorkloadData.hpp:322
armnn::LstmQueueDescriptor::m_ForgetGateBias
const ConstTensorHandle * m_ForgetGateBias
Definition: WorkloadData.hpp:439
armnn::ScatterNdDescriptor::m_InputEnabled
bool m_InputEnabled
Flag to show if input tensor is accepted.
Definition: Descriptors.hpp:1722
armnn::BatchMatMulDescriptor::m_DataLayoutX
DataLayout m_DataLayoutX
Data layout of each input tensor, such as NHWC/NDHWC (leave as default for arbitrary layout)
Definition: Descriptors.hpp:1621
armnn::TensorInfo
Definition: Tensor.hpp:152
armnn::Pooling3dQueueDescriptor::Validate
void Validate(const WorkloadInfo &workloadInfo) const
Definition: WorkloadData.cpp:1552
armnn::LstmQueueDescriptor::m_InputToForgetWeights
const ConstTensorHandle * m_InputToForgetWeights
Definition: WorkloadData.hpp:428
armnn::GetDataTypeName
constexpr const char * GetDataTypeName(DataType dataType)
Definition: TypesUtils.hpp:234
armnn::FakeQuantizationDescriptor::m_Max
float m_Max
Maximum value.
Definition: Descriptors.hpp:921
armnn::QLstmQueueDescriptor::Validate
void Validate(const WorkloadInfo &workloadInfo) const
Definition: WorkloadData.cpp:3160
armnn::TensorInfo::GetNumDimensions
unsigned int GetNumDimensions() const
Definition: Tensor.hpp:197
armnn::QuantizedLstmQueueDescriptor::Validate
void Validate(const WorkloadInfo &workloadInfo) const
Definition: WorkloadData.cpp:3446
armnn::TransposeConvolution2dQueueDescriptor::m_Weight
const ConstTensorHandle * m_Weight
Definition: WorkloadData.hpp:551
armnn::BatchToSpaceNdDescriptor::m_BlockShape
std::vector< unsigned int > m_BlockShape
Block shape values.
Definition: Descriptors.hpp:898
CHECK_LOCATION
#define CHECK_LOCATION()
Definition: Exceptions.hpp:203
armnn::TransposeQueueDescriptor::Validate
void Validate(const WorkloadInfo &workloadInfo) const
Definition: WorkloadData.cpp:3118
armnnUtils::DataLayoutIndexed
Provides access to the appropriate indexes for Channels, Height and Width based on DataLayout.
Definition: DataLayoutIndexed.hpp:17
armnn::QueueDescriptor::m_AllowExpandedDims
bool m_AllowExpandedDims
Definition: WorkloadData.hpp:52
armnn::DataType::Float32
@ Float32
armnn::BatchMatMulDescriptor::GetPermuteVec
static PermutationVector GetPermuteVec(DataLayout dataLayout, const TensorShape &tensorShape)
Static helper to get the axes which will be transposed.
Definition: Descriptors.cpp:523
armnn::ResizeDescriptor::m_DataLayout
DataLayout m_DataLayout
The data layout to be used (NCHW, NHWC).
Definition: Descriptors.hpp:1014
armnn::Convolution2dDescriptor::m_StrideY
uint32_t m_StrideY
Stride value when proceeding through input for the height dimension.
Definition: Descriptors.hpp:576
armnn::UnidirectionalSequenceLstmQueueDescriptor::m_InputLayerNormWeights
const ConstTensorHandle * m_InputLayerNormWeights
Definition: WorkloadData.hpp:740
armnn::SpaceToBatchNdDescriptor::m_BlockShape
std::vector< unsigned int > m_BlockShape
Block shape value.
Definition: Descriptors.hpp:1066
armnn::BatchNormalizationQueueDescriptor::m_Mean
const ConstTensorHandle * m_Mean
Definition: WorkloadData.hpp:321
armnn::UnidirectionalSequenceLstmQueueDescriptor::m_InputToOutputWeights
const ConstTensorHandle * m_InputToOutputWeights
Definition: WorkloadData.hpp:726
armnn::BatchMatMulDescriptor::m_AdjointY
bool m_AdjointY
Definition: Descriptors.hpp:1618
armnn::UnidirectionalSequenceLstmQueueDescriptor::m_OutputLayerNormWeights
const ConstTensorHandle * m_OutputLayerNormWeights
Definition: WorkloadData.hpp:743
armnn::QuantizedLstmQueueDescriptor::m_RecurrentToOutputWeights
const ConstTensorHandle * m_RecurrentToOutputWeights
Definition: WorkloadData.hpp:641
armnn::QuantizedLstmQueueDescriptor::m_InputGateBias
const ConstTensorHandle * m_InputGateBias
Definition: WorkloadData.hpp:643
armnn::DataType::QAsymmU8
@ QAsymmU8
armnn::ConstTensorHandle::GetTensorInfo
const TensorInfo & GetTensorInfo() const
Definition: TensorHandle.hpp:40
armnn::UnidirectionalSequenceLstmQueueDescriptor::Validate
void Validate(const WorkloadInfo &workloadInfo) const
Definition: WorkloadData.cpp:3935
armnn::DataType::QSymmS8
@ QSymmS8
armnn::DepthwiseConvolution2dQueueDescriptor::Validate
void Validate(const WorkloadInfo &workloadInfo) const
Definition: WorkloadData.cpp:1392
armnn::LstmQueueDescriptor::m_InputToCellWeights
const ConstTensorHandle * m_InputToCellWeights
Definition: WorkloadData.hpp:429
armnn::ElementwiseUnaryQueueDescriptor::Validate
void Validate(const WorkloadInfo &workloadInfo) const
Definition: WorkloadData.cpp:3806
armnnUtils::Permuted
armnn::TensorShape Permuted(const armnn::TensorShape &srcShape, const armnn::PermutationVector &mappings)
Definition: Permute.cpp:125
armnn::GatherQueueDescriptor::Validate
void Validate(const WorkloadInfo &workloadInfo) const
Definition: WorkloadData.cpp:2805
armnn::ReverseV2QueueDescriptor::Validate
void Validate(const WorkloadInfo &workloadInfo) const
Definition: WorkloadData.cpp:1627
armnn::QLstmQueueDescriptor::m_InputToInputWeights
const ConstTensorHandle * m_InputToInputWeights
Definition: WorkloadData.hpp:589
armnn::BatchMatMulQueueDescriptor::Validate
void Validate(const WorkloadInfo &workloadInfo) const
Definition: WorkloadData.cpp:4188
armnn::SplitterQueueDescriptor::Validate
void Validate(const WorkloadInfo &workloadInfo) const
Definition: WorkloadData.cpp:748
armnn::BatchToSpaceNdDescriptor::m_Crops
std::vector< std::pair< unsigned int, unsigned int > > m_Crops
The values to crop from the input dimension.
Definition: Descriptors.hpp:900
armnn::TensorInfo::HasPerAxisQuantization
bool HasPerAxisQuantization() const
Definition: Tensor.cpp:446
armnn::DepthwiseConvolution2dDescriptor::m_StrideY
uint32_t m_StrideY
Stride value when proceeding through input for the height dimension.
Definition: Descriptors.hpp:702
armnn::SplitterQueueDescriptor::m_ViewOrigins
std::vector< ViewOrigin > m_ViewOrigins
Definition: WorkloadData.hpp:124
armnn::FloorQueueDescriptor::Validate
void Validate(const WorkloadInfo &workloadInfo) const
Definition: WorkloadData.cpp:1997
armnn::DetectionPostProcessQueueDescriptor::m_Anchors
const ConstTensorHandle * m_Anchors
Definition: WorkloadData.hpp:246
armnn::DataType::QSymmS16
@ QSymmS16
armnn::AbsQueueDescriptor::Validate
void Validate(const WorkloadInfo &workloadInfo) const
Definition: WorkloadData.cpp:3617
armnn::UnidirectionalSequenceLstmQueueDescriptor::m_OutputGateBias
const ConstTensorHandle * m_OutputGateBias
Definition: WorkloadData.hpp:737
NumericCast.hpp
armnn::DataType::BFloat16
@ BFloat16
armnn::QLstmQueueDescriptor::m_ProjectionWeights
const ConstTensorHandle * m_ProjectionWeights
Definition: WorkloadData.hpp:604
armnn::QLstmQueueDescriptor::m_ForgetLayerNormWeights
const ConstTensorHandle * m_ForgetLayerNormWeights
Definition: WorkloadData.hpp:607
armnn::LstmQueueDescriptor::m_CellToOutputWeights
const ConstTensorHandle * m_CellToOutputWeights
Definition: WorkloadData.hpp:437
armnn::UnidirectionalSequenceLstmQueueDescriptor::m_ForgetLayerNormWeights
const ConstTensorHandle * m_ForgetLayerNormWeights
Definition: WorkloadData.hpp:741
armnn::InstanceNormalizationQueueDescriptor::Validate
void Validate(const WorkloadInfo &workloadInfo) const
Definition: WorkloadData.cpp:1709
armnn::UnidirectionalSequenceLstmQueueDescriptor::m_InputToForgetWeights
const ConstTensorHandle * m_InputToForgetWeights
Definition: WorkloadData.hpp:724
TensorUtils.hpp
armnn::QLstmQueueDescriptor::m_RecurrentToOutputWeights
const ConstTensorHandle * m_RecurrentToOutputWeights
Definition: WorkloadData.hpp:596
armnnUtils::DataLayoutIndexed::GetHeightIndex
unsigned int GetHeightIndex() const
Definition: DataLayoutIndexed.hpp:24
armnn::MeanDescriptor::m_KeepDims
bool m_KeepDims
Enable/disable keep dimensions. If true, then the reduced dimensions that are of length 1 are kept.
Definition: Descriptors.hpp:1192
armnn::UnidirectionalSequenceLstmQueueDescriptor::m_RecurrentToOutputWeights
const ConstTensorHandle * m_RecurrentToOutputWeights
Definition: WorkloadData.hpp:730
armnn::DetectionPostProcessQueueDescriptor::Validate
void Validate(const WorkloadInfo &workloadInfo) const
Definition: WorkloadData.cpp:2841
armnn::DataLayout::NDHWC
@ NDHWC
armnn::ActivationQueueDescriptor::Validate
void Validate(const WorkloadInfo &workloadInfo) const
Definition: WorkloadData.cpp:604
armnn::UnidirectionalSequenceLstmQueueDescriptor::m_ProjectionWeights
const ConstTensorHandle * m_ProjectionWeights
Definition: WorkloadData.hpp:738
armnn::SplitterQueueDescriptor::ViewOrigin
Definition: WorkloadData.hpp:113
armnn::SpaceToBatchNdDescriptor::m_PadList
std::vector< std::pair< unsigned int, unsigned int > > m_PadList
Specifies the padding values for the input dimension: heightPad{top, bottom} widthPad{left,...
Definition: Descriptors.hpp:1069
armnn::LstmDescriptor::m_PeepholeEnabled
bool m_PeepholeEnabled
Enable/disable peephole.
Definition: Descriptors.hpp:1148
armnn::TensorShape
Definition: Tensor.hpp:20
armnn::FakeQuantizationQueueDescriptor::Validate
void Validate(const WorkloadInfo &workloadInfo) const
Definition: WorkloadData.cpp:1688
armnn::StackDescriptor::m_NumInputs
uint32_t m_NumInputs
Number of input tensors.
Definition: Descriptors.hpp:1275
armnn::QuantizedLstmQueueDescriptor::m_RecurrentToCellWeights
const ConstTensorHandle * m_RecurrentToCellWeights
Definition: WorkloadData.hpp:640
armnn::DataType::Float16
@ Float16
armnn::WorkloadInfo::m_OutputTensorInfos
std::vector< TensorInfo > m_OutputTensorInfos
Definition: WorkloadInfo.hpp:19
armnn::BatchNormalizationQueueDescriptor::Validate
void Validate(const WorkloadInfo &workloadInfo) const
Definition: WorkloadData.cpp:1207
armnn::QLstmQueueDescriptor::m_CellToOutputWeights
const ConstTensorHandle * m_CellToOutputWeights
Definition: WorkloadData.hpp:599
armnn::ConcatQueueDescriptor::ViewOrigin
Definition: WorkloadData.hpp:132
armnn::LstmDescriptor::m_ClippingThresProj
float m_ClippingThresProj
Clipping threshold value for the projection.
Definition: Descriptors.hpp:1144
armnn::QueueDescriptorWithParameters< ArgMinMaxDescriptor >::m_Parameters
ArgMinMaxDescriptor m_Parameters
Definition: WorkloadData.hpp:66
armnn::TensorShape::GetNumDimensions
unsigned int GetNumDimensions() const
Function that returns the tensor rank.
Definition: Tensor.cpp:174
armnn::DepthwiseConvolution2dDescriptor::m_DilationY
uint32_t m_DilationY
Dilation factor value for height dimension.
Definition: Descriptors.hpp:706
armnn::UnaryOperation::LogicalNot
@ LogicalNot
armnn::QLstmQueueDescriptor::m_CellToForgetWeights
const ConstTensorHandle * m_CellToForgetWeights
Definition: WorkloadData.hpp:598
armnn::PermuteQueueDescriptor::Validate
void Validate(const WorkloadInfo &workloadInfo) const
Definition: WorkloadData.cpp:1496
armnn::FullyConnectedDescriptor::m_BiasEnabled
bool m_BiasEnabled
Enable/disable bias.
Definition: Descriptors.hpp:526
armnn::MapQueueDescriptor::Validate
void Validate(const WorkloadInfo &workloadInfo) const
Definition: WorkloadData.cpp:455
armnn::MaximumQueueDescriptor::Validate
void Validate(const WorkloadInfo &workloadInfo) const
Definition: WorkloadData.cpp:2405
Logging.hpp
armnn::DebugQueueDescriptor::Validate
void Validate(const WorkloadInfo &workloadInfo) const
Definition: WorkloadData.cpp:2687
armnn::ElementwiseBinaryQueueDescriptor::Validate
void Validate(const WorkloadInfo &workloadInfo) const
Definition: WorkloadData.cpp:3777
armnn::QuantizedLstmQueueDescriptor::m_InputToInputWeights
const ConstTensorHandle * m_InputToInputWeights
Definition: WorkloadData.hpp:633
armnn::MemImportQueueDescriptor::Validate
void Validate(const WorkloadInfo &workloadInfo) const
Definition: WorkloadData.cpp:527
armnn::BatchMatMulDescriptor::m_TransposeY
bool m_TransposeY
Definition: Descriptors.hpp:1613
armnn::DetectionPostProcessDescriptor::m_NumClasses
uint32_t m_NumClasses
Number of classes.
Definition: Descriptors.hpp:755
armnn::TensorInfo::GetQuantizationDim
Optional< unsigned int > GetQuantizationDim() const
Definition: Tensor.cpp:498
armnn::WorkloadInfo
Contains information about TensorInfos of a layer.
Definition: WorkloadInfo.hpp:16
armnn::ConcatQueueDescriptor::ViewOrigin::m_Origin
std::vector< unsigned int > m_Origin
Definition: WorkloadData.hpp:138
armnn::StackDescriptor::m_Axis
uint32_t m_Axis
0-based axis along which to stack the input tensors.
Definition: Descriptors.hpp:1273
armnn::TensorInfo::HasMultipleQuantizationScales
bool HasMultipleQuantizationScales() const
Definition: Tensor.hpp:203
armnn::DataType
DataType
Definition: Types.hpp:48
armnn::TensorInfo::IsQuantized
bool IsQuantized() const
Definition: Tensor.cpp:508
armnn::DetectionPostProcessDescriptor::m_NmsIouThreshold
float m_NmsIouThreshold
Intersection over union threshold.
Definition: Descriptors.hpp:753
armnn::RankQueueDescriptor::Validate
void Validate(const WorkloadInfo &workloadInfo) const
Definition: WorkloadData.cpp:3847
armnn::TileQueueDescriptor::Validate
void Validate(const WorkloadInfo &workloadInfo) const
Definition: WorkloadData.cpp:4404
armnn::TensorInfo::IsTypeSpaceMatch
bool IsTypeSpaceMatch(const TensorInfo &other) const
Check that the types are the same and, if quantize, that the quantization parameters are the same.
Definition: Tensor.cpp:432
armnn::LogicalBinaryQueueDescriptor::Validate
void Validate(const WorkloadInfo &workloadInfo) const
Definition: WorkloadData.cpp:3876
armnn::SubtractionQueueDescriptor::Validate
void Validate(const WorkloadInfo &workloadInfo) const
Definition: WorkloadData.cpp:2371
armnn::Convolution2dDescriptor::m_BiasEnabled
bool m_BiasEnabled
Enable/disable bias.
Definition: Descriptors.hpp:582
armnn::ChannelShuffleQueueDescriptor::Validate
void Validate(const WorkloadInfo &workloadInfo) const
Definition: WorkloadData.cpp:3147
armnn::BatchMatMulDescriptor::m_DataLayoutY
DataLayout m_DataLayoutY
Definition: Descriptors.hpp:1622
armnn::MeanQueueDescriptor::Validate
void Validate(const WorkloadInfo &workloadInfo) const
Definition: WorkloadData.cpp:2439
armnn::QLstmQueueDescriptor::m_OutputLayerNormWeights
const ConstTensorHandle * m_OutputLayerNormWeights
Definition: WorkloadData.hpp:609
armnnUtils
Definition: CompatibleTypes.hpp:10
armnn::InvalidArgumentException
Definition: Exceptions.hpp:80
armnn::ConcatQueueDescriptor::Validate
void Validate(const WorkloadInfo &workloadInfo) const
Definition: WorkloadData.cpp:820
armnn::QLstmQueueDescriptor::m_InputGateBias
const ConstTensorHandle * m_InputGateBias
Definition: WorkloadData.hpp:600
armnn::BatchNormalizationQueueDescriptor::m_Beta
const ConstTensorHandle * m_Beta
Definition: WorkloadData.hpp:323
armnn::QuantizedLstmQueueDescriptor::m_RecurrentToForgetWeights
const ConstTensorHandle * m_RecurrentToForgetWeights
Definition: WorkloadData.hpp:639
armnn::QLstmQueueDescriptor::m_OutputGateBias
const ConstTensorHandle * m_OutputGateBias
Definition: WorkloadData.hpp:603
armnn::ResizeQueueDescriptor::Validate
void Validate(const WorkloadInfo &workloadInfo) const
Definition: WorkloadData.cpp:1579
armnn::UnidirectionalSequenceLstmQueueDescriptor::m_ForgetGateBias
const ConstTensorHandle * m_ForgetGateBias
Definition: WorkloadData.hpp:735
armnn::UnidirectionalSequenceLstmQueueDescriptor::m_InputGateBias
const ConstTensorHandle * m_InputGateBias
Definition: WorkloadData.hpp:734
armnn::DivisionQueueDescriptor::Validate
void Validate(const WorkloadInfo &workloadInfo) const
Definition: WorkloadData.cpp:2337
armnn::QLstmQueueDescriptor::m_ForgetGateBias
const ConstTensorHandle * m_ForgetGateBias
Definition: WorkloadData.hpp:601
armnn::Convolution3dDescriptor::m_StrideY
uint32_t m_StrideY
Stride value when proceeding through input for the height dimension.
Definition: Descriptors.hpp:643
armnn::ConstantQueueDescriptor::Validate
void Validate(const WorkloadInfo &workloadInfo) const
Definition: WorkloadData.cpp:1795
armnn::QuantizedLstmQueueDescriptor::m_InputToCellWeights
const ConstTensorHandle * m_InputToCellWeights
Definition: WorkloadData.hpp:635
armnn::Convolution3dDescriptor::m_StrideX
uint32_t m_StrideX
Stride value when proceeding through input for the width dimension.
Definition: Descriptors.hpp:641
armnn::PreluQueueDescriptor::Validate
void Validate(const WorkloadInfo &workloadInfo) const
Definition: WorkloadData.cpp:3029
armnn::LstmQueueDescriptor::m_InputGateBias
const ConstTensorHandle * m_InputGateBias
Definition: WorkloadData.hpp:438
armnn::PermutationVector
Definition: Types.hpp:319
armnn::UnidirectionalSequenceLstmQueueDescriptor::m_CellToInputWeights
const ConstTensorHandle * m_CellToInputWeights
Definition: WorkloadData.hpp:731
armnn::Pooling2dQueueDescriptor::Validate
void Validate(const WorkloadInfo &workloadInfo) const
Definition: WorkloadData.cpp:1525
armnnUtils::DataLayoutIndexed::GetWidthIndex
unsigned int GetWidthIndex() const
Definition: DataLayoutIndexed.hpp:25
armnn::UnidirectionalSequenceLstmQueueDescriptor::m_CellToOutputWeights
const ConstTensorHandle * m_CellToOutputWeights
Definition: WorkloadData.hpp:733
armnn::GreaterQueueDescriptor::Validate
void Validate(const WorkloadInfo &workloadInfo) const
Definition: WorkloadData.cpp:2719
armnn::TransposeConvolution2dQueueDescriptor::m_Bias
const ConstTensorHandle * m_Bias
Definition: WorkloadData.hpp:552
armnn::LstmQueueDescriptor::m_RecurrentToCellWeights
const ConstTensorHandle * m_RecurrentToCellWeights
Definition: WorkloadData.hpp:433
armnn::QLstmQueueDescriptor::m_RecurrentToInputWeights
const ConstTensorHandle * m_RecurrentToInputWeights
Definition: WorkloadData.hpp:593
Permute.hpp
armnn::PermuteDescriptor::m_DimMappings
PermutationVector m_DimMappings
Indicates how to translate tensor elements from a given source into the target destination,...
Definition: Descriptors.hpp:173
armnn::BoostLogSeverityMapping::info
@ info
armnn::StackDescriptor::m_InputShape
TensorShape m_InputShape
Required shape of all input tensors.
Definition: Descriptors.hpp:1277
armnn::Convolution2dDescriptor::m_StrideX
uint32_t m_StrideX
Stride value when proceeding through input for the width dimension.
Definition: Descriptors.hpp:574
armnn::TensorInfo::GetDataType
DataType GetDataType() const
Definition: Tensor.hpp:200
armnn::LstmQueueDescriptor::m_CellLayerNormWeights
const ConstTensorHandle * m_CellLayerNormWeights
Definition: WorkloadData.hpp:446
armnn::QueueDescriptor::m_Outputs
std::vector< ITensorHandle * > m_Outputs
Definition: WorkloadData.hpp:27
armnn::CastQueueDescriptor::Validate
void Validate(const WorkloadInfo &workloadInfo) const
Definition: WorkloadData.cpp:695
armnn::RsqrtQueueDescriptor::Validate
void Validate(const WorkloadInfo &workloadInfo) const
Definition: WorkloadData.cpp:2743
armnn::QuantizedLstmQueueDescriptor::m_InputToOutputWeights
const ConstTensorHandle * m_InputToOutputWeights
Definition: WorkloadData.hpp:636
armnn::DataType::Signed32
@ Signed32
armnn::QLstmQueueDescriptor::m_RecurrentToForgetWeights
const ConstTensorHandle * m_RecurrentToForgetWeights
Definition: WorkloadData.hpp:594
armnn::UnidirectionalSequenceLstmQueueDescriptor::m_RecurrentToForgetWeights
const ConstTensorHandle * m_RecurrentToForgetWeights
Definition: WorkloadData.hpp:728
armnn::UnidirectionalSequenceLstmQueueDescriptor::m_CellToForgetWeights
const ConstTensorHandle * m_CellToForgetWeights
Definition: WorkloadData.hpp:732
armnn::DataType::QAsymmS8
@ QAsymmS8
armnn::UnidirectionalSequenceLstmQueueDescriptor::m_RecurrentToInputWeights
const ConstTensorHandle * m_RecurrentToInputWeights
Definition: WorkloadData.hpp:727
armnn::ElementwiseUnaryDescriptor::m_Operation
UnaryOperation m_Operation
Specifies the elementwiseUnary operation to execute.
Definition: Descriptors.hpp:145
armnn::Convolution2dQueueDescriptor::Validate
void Validate(const WorkloadInfo &workloadInfo) const
Definition: WorkloadData.cpp:1253
armnn::FullyConnectedQueueDescriptor::Validate
void Validate(const WorkloadInfo &workloadInfo) const
Definition: WorkloadData.cpp:1036
armnn::UnidirectionalSequenceLstmQueueDescriptor::m_InputToInputWeights
const ConstTensorHandle * m_InputToInputWeights
Definition: WorkloadData.hpp:723
armnn::ConstantQueueDescriptor::m_LayerOutput
const ConstTensorHandle * m_LayerOutput
Definition: WorkloadData.hpp:375
armnn::DepthToSpaceQueueDescriptor::Validate
void Validate(const WorkloadInfo &workloadInfo) const
Definition: WorkloadData.cpp:3699
armnn::SpaceToDepthDescriptor::m_BlockSize
unsigned int m_BlockSize
Scalar specifying the input block size. It must be >= 1.
Definition: Descriptors.hpp:1092
armnn::SoftmaxQueueDescriptor::Validate
void Validate(const WorkloadInfo &workloadInfo) const
Definition: WorkloadData.cpp:723
armnn::BatchToSpaceNdQueueDescriptor::Validate
void Validate(const WorkloadInfo &workloadInfo) const
Definition: WorkloadData.cpp:2535
armnn::StridedSliceDescriptor::m_Stride
std::vector< int > m_Stride
Stride values for the input that will be sliced.
Definition: Descriptors.hpp:1346
armnn::TransposeConvolution2dQueueDescriptor::Validate
void Validate(const WorkloadInfo &workloadInfo) const
Definition: WorkloadData.cpp:3066
armnn::SpaceToDepthQueueDescriptor::Validate
void Validate(const WorkloadInfo &workloadInfo) const
Definition: WorkloadData.cpp:1942
armnn::PermutationVector::GetSize
SizeType GetSize() const
Definition: Types.hpp:362
armnn::MergeQueueDescriptor::Validate
void Validate(const WorkloadInfo &workloadInfo) const
Definition: WorkloadData.cpp:2939
armnn::TransposeDescriptor::m_DimMappings
PermutationVector m_DimMappings
Indicates how to translate tensor elements from a given source into the target destination,...
Definition: Descriptors.hpp:1514
TensorHandle.hpp
armnn::SplitterQueueDescriptor::ViewOrigin::m_Origin
std::vector< unsigned int > m_Origin
Definition: WorkloadData.hpp:119
armnn::TileDescriptor::m_Multiples
std::vector< uint32_t > m_Multiples
The vector to multiply the input shape by.
Definition: Descriptors.hpp:1656
armnn::MeanDescriptor::m_Axis
std::vector< unsigned int > m_Axis
Values for the dimensions to reduce.
Definition: Descriptors.hpp:1190
armnn::LstmDescriptor::m_CifgEnabled
bool m_CifgEnabled
Enable/disable cifg (coupled input & forget gate).
Definition: Descriptors.hpp:1146
armnn::LstmQueueDescriptor::m_RecurrentToOutputWeights
const ConstTensorHandle * m_RecurrentToOutputWeights
Definition: WorkloadData.hpp:434
armnn::ScatterNdQueueDescriptor::Validate
void Validate(const WorkloadInfo &workloadInfo) const
Definition: WorkloadData.cpp:4463
armnn::QLstmQueueDescriptor::m_InputToOutputWeights
const ConstTensorHandle * m_InputToOutputWeights
Definition: WorkloadData.hpp:592
armnn::GatherNdQueueDescriptor::Validate
void Validate(const WorkloadInfo &workloadInfo) const
Definition: WorkloadData.cpp:2769
armnn::TensorInfo::GetShape
const TensorShape & GetShape() const
Definition: Tensor.hpp:193
armnn::QLstmDescriptor::m_HiddenStateZeroPoint
int32_t m_HiddenStateZeroPoint
Hidden State zero point.
Definition: Descriptors.hpp:1434
armnn::NormalizationQueueDescriptor::Validate
void Validate(const WorkloadInfo &workloadInfo) const
Definition: WorkloadData.cpp:1105
armnn::LstmQueueDescriptor::m_InputLayerNormWeights
const ConstTensorHandle * m_InputLayerNormWeights
Definition: WorkloadData.hpp:444
armnn::GetBiasDataType
DataType GetBiasDataType(DataType inputDataType)
Definition: WorkloadData.cpp:28
armnn::PadDescriptor::m_PadList
std::vector< std::pair< unsigned int, unsigned int > > m_PadList
Specifies the padding for input dimension.
Definition: Descriptors.hpp:1218
armnn::LstmDescriptor::m_LayerNormEnabled
bool m_LayerNormEnabled
Enable/disable layer normalization.
Definition: Descriptors.hpp:1152
armnn::MemSyncQueueDescriptor::Validate
void Validate(const WorkloadInfo &workloadInfo) const
Definition: WorkloadData.cpp:583
armnn::LstmQueueDescriptor::m_RecurrentToForgetWeights
const ConstTensorHandle * m_RecurrentToForgetWeights
Definition: WorkloadData.hpp:432
armnn::SwitchQueueDescriptor::Validate
void Validate(const WorkloadInfo &workloadInfo) const
Definition: WorkloadData.cpp:2983
armnn::WorkloadInfo::m_InputTensorInfos
std::vector< TensorInfo > m_InputTensorInfos
Definition: WorkloadInfo.hpp:18
armnn::QLstmDescriptor::m_CifgEnabled
bool m_CifgEnabled
Enable/disable CIFG (coupled input & forget gate).
Definition: Descriptors.hpp:1418
armnn::UnidirectionalSequenceLstmQueueDescriptor::m_ProjectionBias
const ConstTensorHandle * m_ProjectionBias
Definition: WorkloadData.hpp:739
armnn::ConcatQueueDescriptor::m_ViewOrigins
std::vector< ViewOrigin > m_ViewOrigins
Definition: WorkloadData.hpp:143
armnn::ComparisonQueueDescriptor::Validate
void Validate(const WorkloadInfo &workloadInfo) const
Definition: WorkloadData.cpp:3753
armnn::LstmQueueDescriptor::m_ProjectionWeights
const ConstTensorHandle * m_ProjectionWeights
Definition: WorkloadData.hpp:442
armnn::LstmQueueDescriptor::m_CellToInputWeights
const ConstTensorHandle * m_CellToInputWeights
Definition: WorkloadData.hpp:435
armnn::IsQuantizedType
constexpr bool IsQuantizedType()
Definition: TypesUtils.hpp:312
armnn::SliceQueueDescriptor::Validate
void Validate(const WorkloadInfo &workloadInfo) const
Definition: WorkloadData.cpp:3644
armnn::QueueDescriptor::ValidateTensorNumDimensions
void ValidateTensorNumDimensions(const TensorInfo &tensor, std::string const &descName, unsigned int numDimensions, std::string const &tensorName) const
Definition: WorkloadData.cpp:398
armnn::SpaceToBatchNdQueueDescriptor::Validate
void Validate(const WorkloadInfo &workloadInfo) const
Definition: WorkloadData.cpp:1856
armnn
Copyright (c) 2021 ARM Limited and Contributors.
Definition: 01_00_quick_start.dox:6
armnn::Convolution3dDescriptor::m_BiasEnabled
bool m_BiasEnabled
Enable/disable bias.
Definition: Descriptors.hpp:653
armnn::ArgMinMaxDescriptor::m_Axis
int m_Axis
Axis to reduce across the input tensor.
Definition: Descriptors.hpp:83
armnnUtils::DataLayoutIndexed::GetChannelsIndex
unsigned int GetChannelsIndex() const
Definition: DataLayoutIndexed.hpp:23
armnn::Convolution3dDescriptor::m_StrideZ
uint32_t m_StrideZ
Stride value when proceeding through input for the depth dimension.
Definition: Descriptors.hpp:645
armnn::ConvertFp32ToFp16QueueDescriptor::Validate
void Validate(const WorkloadInfo &workloadInfo) const
Definition: WorkloadData.cpp:2291
armnn::ArgMinMaxQueueDescriptor::Validate
void Validate(const WorkloadInfo &workloadInfo) const
Definition: WorkloadData.cpp:629
armnn::ReduceQueueDescriptor::Validate
void Validate(const WorkloadInfo &workloadInfo) const
Definition: WorkloadData.cpp:3910
armnn::QLstmDescriptor::m_HiddenStateScale
float m_HiddenStateScale
Hidden State quantization scale.
Definition: Descriptors.hpp:1436
armnn::FakeQuantizationDescriptor::m_Min
float m_Min
Minimum value.
Definition: Descriptors.hpp:919
armnn::LstmQueueDescriptor::m_RecurrentToInputWeights
const ConstTensorHandle * m_RecurrentToInputWeights
Definition: WorkloadData.hpp:431
armnn::LstmDescriptor::m_ProjectionEnabled
bool m_ProjectionEnabled
Enable/disable the projection layer.
Definition: Descriptors.hpp:1150
armnn::UnidirectionalSequenceLstmQueueDescriptor::m_InputToCellWeights
const ConstTensorHandle * m_InputToCellWeights
Definition: WorkloadData.hpp:725
armnn::StridedSliceDescriptor::m_End
std::vector< int > m_End
End values for the input that will be sliced.
Definition: Descriptors.hpp:1344
armnn::LstmQueueDescriptor::m_ProjectionBias
const ConstTensorHandle * m_ProjectionBias
Definition: WorkloadData.hpp:443
armnn::PadQueueDescriptor::Validate
void Validate(const WorkloadInfo &workloadInfo) const
Definition: WorkloadData.cpp:2484
armnn::UnmapQueueDescriptor::Validate
void Validate(const WorkloadInfo &workloadInfo) const
Definition: WorkloadData.cpp:473
armnn::LstmQueueDescriptor::Validate
void Validate(const WorkloadInfo &workloadInfo) const
Definition: WorkloadData.cpp:2021
armnn::LstmQueueDescriptor::m_OutputGateBias
const ConstTensorHandle * m_OutputGateBias
Definition: WorkloadData.hpp:441
armnn::L2NormalizationQueueDescriptor::Validate
void Validate(const WorkloadInfo &workloadInfo) const
Definition: WorkloadData.cpp:1738
armnn::QLstmQueueDescriptor::m_ProjectionBias
const ConstTensorHandle * m_ProjectionBias
Definition: WorkloadData.hpp:605
armnn::QLstmQueueDescriptor::m_CellToInputWeights
const ConstTensorHandle * m_CellToInputWeights
Definition: WorkloadData.hpp:597
armnn::ConvertFp16ToFp32QueueDescriptor::Validate
void Validate(const WorkloadInfo &workloadInfo) const
Definition: WorkloadData.cpp:2314
armnn::TransposeConvolution2dDescriptor::m_BiasEnabled
bool m_BiasEnabled
Enable/disable bias.
Definition: Descriptors.hpp:1481
armnn::QLstmDescriptor::m_LayerNormEnabled
bool m_LayerNormEnabled
Enable/disable layer normalization.
Definition: Descriptors.hpp:1424
armnn::DataType::Signed64
@ Signed64
armnn::SliceDescriptor::m_Size
std::vector< unsigned int > m_Size
Size of the slice in each dimension.
Definition: Descriptors.hpp:1247
armnn::QLstmQueueDescriptor::m_CellBias
const ConstTensorHandle * m_CellBias
Definition: WorkloadData.hpp:602
armnn::BatchToSpaceNdDescriptor::m_DataLayout
DataLayout m_DataLayout
The data layout to be used (NCHW, NHWC).
Definition: Descriptors.hpp:902
armnn::TensorInfo::GetQuantizationOffset
int32_t GetQuantizationOffset() const
Definition: Tensor.cpp:482
armnn::QueueDescriptor::ValidateTensorNumDimNumElem
void ValidateTensorNumDimNumElem(const TensorInfo &tensorInfo, unsigned int numDimension, unsigned int numElements, std::string const &tensorName) const
Definition: WorkloadData.cpp:436
armnn::LstmQueueDescriptor::m_CellToForgetWeights
const ConstTensorHandle * m_CellToForgetWeights
Definition: WorkloadData.hpp:436
armnn::LstmQueueDescriptor::m_InputToOutputWeights
const ConstTensorHandle * m_InputToOutputWeights
Definition: WorkloadData.hpp:430
armnn::DepthwiseConvolution2dDescriptor::m_DilationX
uint32_t m_DilationX
Dilation factor value for width dimension.
Definition: Descriptors.hpp:704
armnn::QLstmQueueDescriptor::m_InputToCellWeights
const ConstTensorHandle * m_InputToCellWeights
Definition: WorkloadData.hpp:591
armnn::StackQueueDescriptor::Validate
void Validate(const WorkloadInfo &workloadInfo) const
Definition: WorkloadData.cpp:916
armnn::LstmDescriptor::m_ClippingThresCell
float m_ClippingThresCell
Clipping threshold value for the cell state.
Definition: Descriptors.hpp:1142
armnn::QuantizeQueueDescriptor::Validate
void Validate(const WorkloadInfo &workloadInfo) const
Definition: WorkloadData.cpp:2506
armnn::LstmQueueDescriptor::m_OutputLayerNormWeights
const ConstTensorHandle * m_OutputLayerNormWeights
Definition: WorkloadData.hpp:447
armnn::BatchMatMulDescriptor::GetAxesNotMul
static std::vector< unsigned int > GetAxesNotMul(DataLayout dataLayout, const TensorShape &tensorShape)
Static helper to get the axes (for each input) that will not be multiplied together.
Definition: Descriptors.cpp:506
DataLayoutIndexed.hpp
armnn::UnidirectionalSequenceLstmQueueDescriptor::m_CellLayerNormWeights
const ConstTensorHandle * m_CellLayerNormWeights
Definition: WorkloadData.hpp:742
armnn::QLstmDescriptor::m_PeepholeEnabled
bool m_PeepholeEnabled
Enable/disable peephole.
Definition: Descriptors.hpp:1420
armnn::ReshapeQueueDescriptor::Validate
void Validate(const WorkloadInfo &workloadInfo) const
Definition: WorkloadData.cpp:1827
armnn::QuantizedLstmQueueDescriptor::m_OutputGateBias
const ConstTensorHandle * m_OutputGateBias
Definition: WorkloadData.hpp:646
WorkloadInfo.hpp
armnn::OptionalReferenceSwitch< std::is_reference< T >::value, T >::value
const T & value() const
Definition: Optional.hpp:146
armnn::MultiplicationQueueDescriptor::Validate
void Validate(const WorkloadInfo &workloadInfo) const
Definition: WorkloadData.cpp:1170
armnn::QLstmQueueDescriptor::m_CellLayerNormWeights
const ConstTensorHandle * m_CellLayerNormWeights
Definition: WorkloadData.hpp:608
armnn::QueueDescriptor::m_Inputs
std::vector< ITensorHandle * > m_Inputs
Definition: WorkloadData.hpp:26
armnn::OptionalBase::has_value
bool has_value() const noexcept
Definition: Optional.hpp:53
armnn::QLstmQueueDescriptor::m_RecurrentToCellWeights
const ConstTensorHandle * m_RecurrentToCellWeights
Definition: WorkloadData.hpp:595
armnn::DataLayout::NCHW
@ NCHW
armnn::QuantizedLstmQueueDescriptor::m_ForgetGateBias
const ConstTensorHandle * m_ForgetGateBias
Definition: WorkloadData.hpp:644
armnn::Convolution3dQueueDescriptor::Validate
void Validate(const WorkloadInfo &workloadInfo) const
Definition: WorkloadData.cpp:1330
armnn::AdditionQueueDescriptor::Validate
void Validate(const WorkloadInfo &workloadInfo) const
Definition: WorkloadData.cpp:1133
armnn::SpaceToDepthDescriptor::m_DataLayout
DataLayout m_DataLayout
The data layout to be used (NCHW, NHWC).
Definition: Descriptors.hpp:1095
armnn::DepthwiseConvolution2dDescriptor::m_StrideX
uint32_t m_StrideX
Stride value when proceeding through input for the width dimension.
Definition: Descriptors.hpp:700